에이전트 운영 회고 (3/7) — 토큰 폭주에서 관측 모드까지: 측정 기반 재설계

이 글이 다루는 것

에이전트 런타임(Hermes, 이하 HM)에서 발생한 토큰 폭주를 계기로, "측정 → 회귀 → 재설계 → 관측" 순서로 시스템을 재구성한 기록이다. 이 글은 다음 세 가지 정보를 전달한다.

  1. 토큰 폭주를 정량화하는 반복계수(repetition ratio) 지표와 측정 방식
  2. Strangler Fig 기반 마이그레이션에서 구조 강제 vs 행동 단일 방어선 두 설계안의 비교와 선택 근거
  3. 7일 관측 모드(Phase 0)의 KPI 테이블과 단일 표본 해석 한계

결론을 제시하는 글이 아니라, 검증 중 단계에서 적용 가능한 패턴과 측정 포맷을 정리한 가이드다.

1. 토큰 폭주 측정 — 반복계수라는 지표

HM v0.8.0에서 단일 세션 토큰 소모가 6.5M에 도달한 사건이 있었다. 사용자 입력은 5개, 그 안에서 발생한 도구 호출은 111회. 이 사건에서 추출된 반복계수는 42.79× 였다.

반복계수는 "사용자 입력 1단위당 시스템 내부에서 재소모된 토큰 배수"로 정의한다. 값이 클수록 내부 루프가 사용자 의도 대비 과소비되고 있다는 뜻이다. 이 값은 사고 이후 HM 자신이 내부 메시지를 기준으로 산출한 값이며, 재가공 없이 그대로 로그에 남는다.

이 지표의 효용은 단순하다. 폭주 후 원인 추적이 아니라, 재설계 전후 같은 축으로 비교할 수 있는 베이스라인이 된다는 점이다. 측정 가능한 폭주는 비용 문제지만, 측정 불가능한 폭주는 신뢰 문제다. 다음 폭주가 어디서 터졌는지 모르면 고칠 수 없다.

2. 마이그레이션 설계 — Strangler Fig와 1차 시도의 실패 지점

초기 설계는 OpenClaw(이하 OC) 위에서 동작하던 기능을 HM으로 단방향 이전하는 것이었다. OC는 보안 계층, 자기개선 루프, 하네스 일부를 안정적으로 보유한 시스템이며, Strangler Fig 패턴에 따라 OC를 끄지 않은 채 HM이 동일 입력에 동일 출력을 내는지 비교하는 구도였다.

1차 시도가 깨진 지점은 두 가지다.

  • 호출 통제 부족: HM v0.8.0은 도구 호출이 자기 자신을 재호출하는 형태를 런타임 레벨에서 차단하지 못했다.
  • 측정 인프라 지연: 베이스라인 비교용 측정 도구가 사후에 붙어서, 마이그레이션과 같은 속도로 데이터가 쌓이지 않았다.

이 상태에서의 선택지는 "HM을 더 튜닝"과 "OC로 회귀 후 재설계" 두 가지였다. 전자는 비교 베이스라인 없이 튜닝이 계속되는 구조라 개선 여부 판정이 불가능하다고 보고 후자를 택했다.

3. 회귀 후 재설계 — 구조 강제 vs 행동 단일 방어선

OC로 회귀한 뒤 운영은 OC 위에서 이어가면서, 옆에서 HM을 다시 설계했다. 이 단계에서 두 가지 설계안이 비교됐다.

초기 설계안: 구조 강제

메인 에이전트가 도구를 직접 호출하지 못하도록 런타임 레벨에서 차단하는 방향. 위임이 강제되므로 이론적으로는 깔끔하다. 단, 실증 세션에서 sub-agent에 도구가 0개로 전달되는 케이스가 발생했고, 도구가 없는 상태에서 모델이 외부 정보를 환각으로 생성했다. 구체적으로는 존재하지 않는 PR 번호(NousResearch/hermes-agent 저장소로 추정되는 형태)가 출력됐다.

이 환각은 발행 전에 잡혔지만, 한 번에 옮기는 마이그레이션이었다면 운영 환경에 그대로 반영될 위험이 있었다.

재설계 후: 행동 단일 방어선

도구 자체를 잘라내지 않고, 행동 규칙으로 위임 흐름을 강제하고 결과를 측정해서 이탈 시 탐지하는 방향. 이 방향으로 전환하면서 다음 항목이 확정됐다.

  • 측정 스크립트 (세션 로그 파싱 → KPI 산출)
  • 환경변수 및 자격증명 격리
  • 위임률(delegation rate) 정의
  • 게이트 통과 조건

비용 관점 기록: 초기 설계안 → 재설계 후로 전환하는 사이의 작업이 가장 비쌌다. 다만 이 전환 과정에서 환각 PR 번호가 발견됐고, 이것이 전환 비용을 정당화했다.

4. 재시도 단계의 KPI 측정

재설계 이후 HM은 v0.8.0 → v0.9.0 → v0.10.0 으로 올라갔고, 누적 411개 commit이 적용됐다. 이 버전에서 Stage 1 baseline 반복계수는 23.80× 로 측정됐다 (폭주 시점 42.79× 대비 약 45% 감소).

첫 측정일 KPI:

# KPI Value Target 판정
1 Repetition ratio 13.82× < 20× OK
2 Schema resent / 세션 29,832 tokens < 200k OK
3 Delegation rate 1.0 ≥ 0.7 OK
4 Crash count (24h) 0 0 OK
5 Daily cost $0 ≤ $1/day OK
6 Cache hit rate 25.64% ≥ 40% (보조) 미달

반복계수 기준, 폭주 시점 42.79× → 13.82× 는 약 67.7% 감소다. 단, 이 감소는 "HM으로 옮겨서" 줄어든 값이 아니라 "재설계 후 HM 위에서 행동 단일 방어선이 적용된 후"의 값이다. 초기 설계안(구조 강제)의 수치가 아니라는 점을 분리해 두지 않으면 해석이 뒤바뀐다.

Cache hit rate 25.64%는 보조 KPI로, 게이트 통과를 막지는 않지만 미달 상태다. auto-cache가 부분적으로만 작동 중인 것으로 추정되며, 다음 단계 격리 작업 이후 재측정 예정이다.

5. 한계 — 단일 표본 해석과 둘째 측정일 회귀

같은 측정 스크립트로 다음날 재측정한 결과:

# KPI Day 1 Day 2
1 Repetition ratio 13.82× 16.22×
3 Delegation rate 1.0 0.0
4 Crash count 0 1

반복계수 13.82× → 16.22× 상승, 위임률 1.0 → 0.0 하락, crash 1회 발생. 위임률 폭은 표본 차이일 가능성이 높지만, 7일 관측 전에는 단정할 수 없다. crash 원인도 분석 전이다.

여기서 정직하게 기록해야 하는 두 가지:

  1. Day 1, Day 2 모두 단일 표본이다. 7일치 베이스라인이 쌓이기 전까지 값이 유지될지 단언 불가.
  2. Day 1 결과만으로 "재시도 성공"을 주장할 근거는 없다. Day 2에 즉시 흔들렸기 때문이다.

현재는 Phase 0의 7일 관측 중이다. Phase 0의 목적은 고치는 것이 아니라 보는 것이다. 같은 측정 스크립트로 매일 KPI를 찍어 안정 구간과 흔들리는 구간을 분리하는 베이스라인 구축이 1차 목표다. 이 7일이 끝나야 다음 단계 게이트 판정으로 넘어갈 수 있으며, 게이트 조건 중 하나는 cache hit rate 40% 미달을 어떻게 처리할지다.

적용 가능 범위와 열린 질문

이 글에서 추출 가능한 패턴은 세 가지다.

  • 반복계수 지표화: 에이전트 런타임에서 사용자 입력 1단위당 내부 토큰 소모량을 배수로 측정하면, 폭주/개선을 같은 축으로 비교할 수 있다.
  • 구조 강제 vs 행동 방어선: 구조 강제는 깔끔해 보이지만 의도치 않은 도구 차단으로 환각을 유발할 수 있다. 행동 단일 방어선은 측정과 조합할 때 더 안전하다.
  • 회귀 후 병행 설계: Strangler Fig에서 1차 시도가 깨졌을 때, 원본 시스템을 끄지 않고 옆에서 재설계를 돌리면 환각/회귀를 발행 전에 잡을 여지가 생긴다.

열린 질문:

  • Day 2의 위임률 1.0 → 0.0 이 표본 분산인가, 구조적 이탈인가?
  • Cache hit rate 미달을 게이트 조건에 포함할지, 보조 KPI로 남길지?
  • 행동 단일 방어선의 이탈 탐지 지연은 어느 수준까지 허용 가능한가?

7일 관측이 완료되면 같은 측정 포맷으로 후속 기록을 이어갈 예정이다.

시리즈 전체 안내: 시리즈 목차

댓글

이 블로그의 인기 게시물

"LLM 핵심 학습 (1/6) — 기본: 토큰화·임베딩·어텐션·위치 인코딩"

"LLM 핵심 학습 (2/6) — 파인튜닝: LoRA·QLoRA·증류·Adapter"

"ML 기초 학습 (1/9) — 머신러닝과 sklearn: 학습의 좌표계"