대화 기록 비대화로 인한 성능 저하 방지! '전체 기록 누적' 대 '마일스톤 구조화 스테이트 압축'으로 입력 토큰 91.9% 절감
요약
장기 코딩 과제에서 전체 대화 기록을 누적하면 토큰이 급증하고 초기 사양이 손실되는 Context Poisoning 문제가 발생합니다. 본 기사는 마일스톤 구조화 스테이트 압축(Save-Game Compaction) 패턴을 제안하며, 원시 로그를 요약된 체크포인트로 리셋하여 컨텍스트 효율성을 높였습니다. 실측 결과, 토큰 사용량을 90% 이상 절감하고 독립 테스트 합격률을 100%로 끌어올렸습니다.
핵심 포인트
- 전체 기록 누적은 토큰 폭증 및 Context Poisoning 위험을 초래합니다.
- 마일스톤 구조화 압축(Save-Game Compaction) 패턴이 컨텍스트 관리의 모범 사례입니다.
- 원시 로그를 요약된 체크포인트로 리셋하여 컨텍스트를 정화해야 합니다.
- 이 방식은 입력 토큰을 최대 90%까지 절감하고 성능을 개선합니다.
1. 요약 및 검증 대상 기사의 주장
멀티 스텝의 장기 코딩 과제에서, 과거 파일 전체 열람 결과, 방대한 원격 측정(telemetry) 감사 로그, 그리고 중간 과정의 시행착오 대화 내용을 그대로 단일한 대화 기록(messages[])에 계속 쌓아 올리는 방식(Unbounded Context Accumulation)을 사용하면, 후반 턴이 될수록 입력 토큰이 눈덩이처럼 부풀어 올라 추론 비용 및 레이턴시가 악화될 뿐만 아니라, **'중반~후반 턴에서 초기 사양의 세부 사항(문자열 정규화 규칙이나 경계 조건 등)이 대량의 과거 로그에 파묻혀 누락되는 현상 (Context Poisoning / Lost-in-the-Middle 現象)'**이라는 문제가 지적되고 있습니다. 이에 대한 모범 사례는, 서브 태스크(마일스톤) 완료 시점이나 일정 토큰 임계치 도달 시점에, 그전까지의 원시 로그를 폐기하고, **'완료된 변경 사항 및 검증된 계약(인터페이스), 그리고 다음 목표 과제'만을 기술한 구조화 JSON (Save-Game Compaction Pattern)**으로 요약하여 대화 기록을 신선하게 리셋하는 방법(Context Compaction at Threshold)입니다.
본 실험 (E12 / VM216)에서는 3마일스톤 구성의 전력 그리드 측정 및 탄소 크레딧 정산 파이프라인 (Milestone 1: collector.py → Milestone 2: clearing.py → Milestone 3: dispatch.py) 순차 개정 과제를 대상으로, 격리 사격장 VM (VM216) 내에서 다음 두 가지 방식을 동일 모델 (gemini-3.8-flash)로 직접 대결시켜 실측 데이터를 확보했습니다.
Mode A (AccumulatedHistoryRunner): 전체 기록 누적 / Compaction 없음) - 3개 모듈의 사양, 초기 코드, 각 마일스톤의 원격 측정 감사 덤프 (VERBOSE_TELEMETRY_AUDIT_DUMP)를 매 턴 동일한 대화 스레드에 그대로 추가 및 축적합니다 (3턴째 입력 토큰은 17,544 tokens에 도달).
-
Mode B (MilestoneCompactionRunner): 마일스톤 구조화 스테이트 압축 / Save-Game Compaction) - 각 마일스톤 (
collector.py,clearing.py)의 자동 검증 게이트 통과 직후/compact를 실행하여 원시 로그를 폐기하고, 약 120 토큰 분량의 구조화 체크포인트 (SAVE_GAME_COMPACTION_V1JSON) + 대상 모듈의 사양만으로 대화 기록을 신선하게 리셋합니다. -
각 마일스톤 (## 2. 아키텍처 비교도 (Mode A: Accumulated History vs. Mode B: Milestone Compaction))
[IMG:N]
3. 정량적 비교 메트릭스 (VM216 실기 검증 결과)
| 지표 | Mode A: 전체 기록 누적 (AccumulatedHistory) | Mode B: 마일스톤 구조화 압축 (MilestoneCompaction) | 차이점 / 개선 효과 |
|---|---|---|---|
| 독립 테스트 합격률 (20케이스) | ❌ 18 / 20 (90.0%・불합격) | ✅ 20 / 20 (100.0%・완전 합격) | +10.0 pt (중반 턴의 사양 누락을 완벽히 방지) |
스테이트 압축 횟수 (compactions) | 0 회 (전체 기록 무제한 축적) | 2 회 (M1 완료 후・M2 완료 후) | 마일스톤 경계마다 컨텍스트 정화 |
Turn 1 입력 토큰 수 (M1: collector.py) | 6,556 tokens | 650 tokens | -90.1% 절감 |
Turn 2 입력 토큰 수 (M2: clearing.py) | 11,769 tokens | 1,388 tokens | -88.2% 절감 |
Turn 3 입력 토큰 수 (M3: dispatch.py) | 17,544 tokens | 884 tokens | -95.0% 절감 (후반 턴의 비대화 완벽 해소) |
누적 총 입력 토큰 수 (promptTokenCount) | 35,869 tokens | 2,922 tokens | -32,947 tokens (-91.9% 절감・약 12.3분의 1) |
총 출력 토큰 수 (candidatesTokenCount) | 1,894 tokens | 1,937 tokens | +43 tokens (거의 동일) |
LLM 호출 횟수 (model_calls) | 3 회 | 3 회 | 동일 (각 마일스톤당 1회) |
실행 시간 (elapsed_seconds) | 24.81 초 | 22.52 초 | -2.29 초 (-9.2% 고속화) |
추정 API 비용 (USD) | $0.03401 (34,005 micro-USD) | $0.00946 (9,457 micro-USD) | -$0.02455 (-72.2% 비용 절감・약 3.6분의 1) |
4. 턴별 토큰 변화 및 실패 사례 비교 상세 내역
usage.json (실측값)
4.1 턴별 입력 토큰과 비용 추이 (| 턴 / 마일스톤 | Mode A (AccumulatedHistory) 입력 토큰 / 비용 | Mode B (MilestoneCompaction) 입력 토큰 / 비용 | 토큰 절감률 |
|---|---|---|---|
| Turn 1 (collector.py) | 6,556 tokens / $0.00725 | 650 tokens / $0.00290 | -90.1% |
| Turn 2 (clearing.py) | 11,769 tokens / $0.01247 | 1,388 tokens / $0.00461 | -88.2% |
| Turn 3 (dispatch.py) | 17,544 tokens / $0.01429 | 884 tokens / $0.00195 | -95.0% |
| 합계 (전체 3턴 누적) | 35,869 tokens / $0.03401 | 2,922 tokens / $0.00946 | -91.9% (비용 -72.2%) |
4.2 독립 채점 (20케이스)에서의 Mode A와 Mode B의 차이점 사례
| 테스트 케이스 ID | 검증 내용 | Mode A (AccumulatedHistory) | Mode B (MilestoneCompaction) |
|---|---|---|---|
collector_01 ~ collector_06 | Milestone 1 (입력 비파괴/타입 검증/경계값) | ✅ 6 / 6 Pass | ✅ 6 / 6 Pass |
clearing_01 ~ clearing_08 | Milestone 2 (최초 출현 순 집약/400 vs 401 경계/12000 경계) | ✅ 8 / 8 Pass | ✅ 8 / 8 Pass |
e2e_01_green_below_12000_minus_zero_and_at_separator | E2E 검증 1: contract_tier=" green " (앞뒤 공백 + 소문자)에서의 정규화와 -0 / @ 표기 | ❌ Fail (ValueError: contract_tier must be one of ...) | ✅ Pass |
e2e_02_hydro_levy_and_credit_dispatch | E2E 검증 2: contract_tier="hydro" (소문자)에서의 20% 할인/크레딧 상쇄/디스패치 출력 | ❌ Fail (ValueError: contract_tier must be one of ...) | ✅ Pass |
e2e_03 ~ e2e_06 | E2E 검증 3~6 (0센트/순서 유지/경합 에러 전파) | ✅ 4 / 4 Pass | ✅ 4 / 4 Pass |
5. 상세 분석: 왜 '전체 기록 누적'에서는 중반 턴에 사양 누락이 발생했고, '스테이트 압축'은 20/20을 완주했는가?
5.1 Mode A (전체 기록 누적)에서 발생한 'Lost-in-the-Middle (문맥 매몰로 인한 정규화 누락)'
outputs/e12-vm216-20261028-01/mac/evidence/accum-bundle.json
실측 코드를 분석한 결과, 전체 기록 누적의 약점이 극명하게 드러난다.
- Turn 1 (
collector.py)에서는 Mode A 에이전트가station_id와grid_zone에 대해.strip().upper()를 이용한 정규화를 올바르게 구현했다. - 그러나 Turn 2 (
clearing.py) 시점에는 Turn 1의 출력과 45줄에 달하는 텔레메트리 감사 덤프(VERBOSE_TELEMETRY_AUDIT_DUMP_M1)가 대화 기록에 쌓이면서 입력 토큰이 기하급수적으로 팽창했다. (11,769 tokens) - 그 결과, 초기 프롬프트 중반부에 작성되어 있던
clearing.py의 사양(즉,contract_tier도str검증 후.strip().upper()로 정규화해야 한다는 내용)이 방대한 로그 더미에 묻혀(Lost-in-the-Middle) Mode A가 생성한clearing.py는 다음과 같이.strip().upper()를 완전히 누락했다:
# Mode A (accum-bundle.json)의 clearing.py 발췌 — .strip().upper() 정규화 누락!
def settle_grid(readings, contract_tier="BASE", credit_offset=0):
if not isinstance(readings, list) or len(readings) == 0:
raise ValueError("readings must be a non-empty list")
if contract_tier not in ALLOWED_TIERS:
raise ValueError(f"contract_tier must be one of {ALLOWED_TIERS}")
- 이 한 줄의 누락으로 인해 엔드투엔드 통합 테스트 (
e2e_01의 `
한편, Mode B에서는 Milestone 1(collector.py)이 완료되는 순간, 과거의 대화 기록을 다음과 같은 간결한 구조화된 JSON(SAVE_GAME_COMPACTION_V1)으로 압축하고 대화 이력을 리셋했습니다:
{
"checkpoint_type": "SAVE_GAME_COMPACTION_V1",
"completed_modules": ["collector.py"],
...
}
- 이를 통해 Turn 2(
clearing.py)의 입력 토큰은11,769→, Turn 3(dispatch.py)의 입력 토큰은17,544→로 억제되었습니다. 이 과정에서884토큰(–95.0%)이 절감되었는데, 이는 에이전트가 '현재 해결해야 할 마일스톤의 사양'에만 100% 집중했기 때문입니다.
그 결과, clearing.py의 contract_tier = contract_tier.strip().upper()나 dispatch.py의 @ 구분자 및 -0 포맷을 포함한 모든 요구사항을 한 번에 정확하게 구현하여, 누적 입력 토큰을 91.9% 절감(목표인 60% 절감 초과 달성)하고 API 비용을 72.2% 절감하면서도 20/20 (100%) 완전 합격을 달성했습니다.
6. 결론 및 실천 가이드라인
-
멀티스텝 과제에서 '생 로그를 대화 기록에 계속 쌓아 올리는 것'은 백 가지 해가 있고 한 가지 이로 없다: - 턴이 진행될수록 과거의 파일 덤프나 도구 출력이 매번 재과금되어 입력 토큰이 이차 함수적으로 증가할 뿐만 아니라, 1만 토큰을 넘어서는 시점부터 초기 사양의 세부 사항(
.strip().upper()등)이 망각되는 Lost-in-the-Middle 버그가 유발됩니다. -
턴이 진행될수록 과거의 파일 덤프나 도구 출력이 매번 재과금되어 입력 토큰이 이차 함수적으로 증가할 뿐만 아니라, 1만 토큰을 넘어서는 시점부터 초기 사양의 세부 사항(–
-
마일스톤 완료 시마다 'Save-Game JSON 체크포인트'로 압축:
/compact하라 - 모듈 단위나 서브태스크 단위의 검증 게이트를 통과했다면, 그때까지의 생 채팅 기록은 즉시 폐기하고, '완료된 모듈・검증된 인터페이스 계약・다음 목표'만을 요약한 수십 줄 분량의 JSON 체크포인트를 인계하여 신선한 컨텍스트로 다음 공정을 시작해야 합니다. 이를 통해 입력 토큰을 90% 이상 절감하면서도, 후반 턴의 구현 정확도를 최대화할 수 있습니다. -
모듈 단위나 서브태스크 단위의 검증 게이트를 통과했다면, 그때까지의 생 채팅 기록은 즉시 폐기하고,
📚 AI Labo 'AI 에이전트 하네스 엔지니어링 실기 검증' 시리즈 총정리본
본 기사는 SNS(X / Threads)나 해외 주요 테크 블로그(OpenAI / Anthropic / Google / Thoughtworks 등)에서 제안된 AI 에이전트의 하네스 설계 패턴을, 완전 오프라인 격리 샌드박스 VM 위에서 정량적 A/B 테스트를 진행하는 AI Labo 실증 시리즈의 한 편입니다.
모든 실험의 토큰 절감률 랭킹 & 하네스 엔지니어링 황금 패턴 총정리본은 아래 마스터 기사에서 수시로 업데이트하고 있습니다. 꼭 북마크 및 팔로우하여 최신 실증 결과를 확인해 보세요!
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기