
에이전트를 수정하지 않고 에이전트 토큰 사용량을 89% 절감한 방법
요약
에이전트의 전체 대화 기록을 매번 전송하는 대신, 핵심 상태(State)를 요약한 SITREP를 활용하여 토큰 사용량을 89% 절감하는 방법을 소개합니다. Go 기반 프록시인 Trooper를 통해 대화의 노이즈를 제거하고 결정 사항, 제약 조건 등 필수 정보만 전달합니다.
핵심 포인트
- 전체 대화 기록 대신 구조화된 상태(SITREP)를 전달하여 효율성 극대화
- 결정 사항, 제약 조건, 미결 사항, 제외 사항 위주의 상태 관리
- Anchor, SITREP, Tail 구조를 통한 컨텍스트 최적화
- 실제 테스트 결과 토큰 사용량을 약 89% 절감 성공
에이전트가 LLM을 호출할 때마다 전체 대화 기록을 전송합니다.
20번째 턴(Turn)에는 119번째 턴이 포함됩니다. 50번째 턴에는 149번째 턴이 포함됩니다. 이는 에이전트 내부에서 모든 요청마다 조용히 일어나기 때문에 아무도 알아차리지 못합니다.
저는 에이전트와 LLM 사이에 위치하는 Go 프록시인 Trooper를 구축하면서 이 문제를 발견했습니다. 긴 디버깅 세션 동안 토큰 수가 급증하는 것을 지켜보던 중, 에이전트가 동일한 컨텍스트(Context)를 계속해서 반복 재생하고 있다는 사실을 깨달았습니다. 그중 대부분은 노이즈(Noise)였습니다.
모델에게 필요한 것은 대화 녹취록이 아니라 상태(State)였습니다.
상태(State)가 실제로 의미하는 것
몇 번의 턴이 지나면, 세션에서 중요한 요소 대부분은 다음 네 가지 범주로 분류됩니다:
- 결정된 사항 (Decisions made) — 무엇이 선택되었고 그 이유는 무엇인가
- 확정된 제약 조건 (Constraints locked) — 변경할 수 없는 것은 무엇인가
- 미결 사항 (Open loops) — 여전히 해결해야 할 과제는 무엇인가
- 제외된 사항 (Ruled out) — 시도했으나 거부된 것은 무엇인가
그게 전부입니다. 그 외의 모든 것 — 주고받는 대화, 설명을 늘어놓는 장황한 LLM 응답, 반복되는 컨텍스트 — 은 단순한 재생(Replay)일 뿐입니다. 모델은 이를 다시 필요로 하지 않습니다.
SITREP
저는 Trooper에 구조화된 세션 메모리(Structured session memory)를 추가했습니다. 충분한 턴이 지나면, Trooper의 로컬 Llama 모델이 세션 내 사용자 메시지로부터 SITREP — 상황 보고(Situation Report) — 를 생성합니다.
형태는 다음과 같습니다:
INTENT: ChromaDB와 nomic-embed-text를 사용한 RAG 파이프라인 구축
DECISIONS: MMR 대신 코사인 유사도(Cosine similarity) 사용 — 광범위한 쿼리 대신 집중된 쿼리 사용;
...
그 시점부터 LLM으로 보내는 모든 요청은 전체 기록 대신 다음과 같이 구성됩니다:
Anchor (처음 2개 턴의 원문)
+ SITREP (구조화된 상태)
+ Tail (마지막 N개 턴의 원문)
수치
실제 15개 턴의 세션 결과입니다:
전체 기록 (Full history): 요청당 10,820 토큰
Trooper 사용 시: 요청당 1,157 토큰
절감률 (Reduction): 89%
대시보드에서 실시간으로 확인할 수 있습니다.
LLM이 여전히 올바르게 답변할까요?
이것이 가장 중요한 질문이었습니다. 모델이 일관성 (Coherence)을 잃는다면 토큰 절감은 아무런 가치가 없습니다.
이를 테스트하기 위해, 저는 자동 생성된 SITREP를 가져와 대화 기록이 전혀 없는 완전히 새로운 채팅창을 열고, 원래 세션에서 내려진 결정들에 대해 질문을 던졌습니다.
질문:
- 청크 크기 (Chunk size)는 얼마인가요?
- 왜 하이브리드 검색 (Hybrid search)을 제외했나요?
- 어떤 검색 방법 (Retrieval method)을 선택했으며 그 이유는 무엇인가요?
- 아직 해결되지 않은 사항은 무엇인가요?
결과: 네 가지 질문 모두 정확하게 답변되었습니다. 모델은 오직 SITREP만을 바탕으로 작동했습니다. 대화 기록도, 컨텍스트 혼입 (Context bleed)도 없었습니다.
이것이 핵심 주장입니다. 구조화된 상태 (Structured state)만으로도 모델이 올바른 추론을 지속하기에 충분하며, 전송 비용은 89%나 저렴하다는 것입니다.
작동 원리
Trooper는 Go 언어로 작성된 프록시 (Proxy)입니다. 단일 바이너리로 구성되며, SDK나 별도의 계측 (Instrumentation)이 필요하지 않습니다. 기존 에이전트의 URL 하나만 변경하면 바로 연결할 수 있습니다.
# 이전
export ANTHROPIC_BASE_URL=https://api.anthropic.com
...
그 외에는 아무것도 변경할 필요가 없습니다. Trooper는 모든 요청을 가로채고, 세션 상태 (Session state)를 유지하며, SITREP가 준비되면 LLM으로 전달하기 전에 메시지 배열 (Messages array)을 재작성합니다.
SITREP는 Ollama를 통해 실행되는 로컬 Llama 3.1 8b 모델에 의해 구축됩니다. 빠르고, 프라이빗하며, 클라우드 비용이 들지 않습니다. 추출 작업은 백그라운드에서 비동기적으로 수행되므로, 메인 요청 경로가 차단되지 않습니다.
// GetTripleAnchor는 LLM에 전송될 내용을 조립합니다
func (s *SessionStore) GetTripleAnchor(sessionID string) []map[string]string {
payload := append([]map[string]string{}, state.Anchor...)
...
대시보드에서는 압축률을 실시간으로 보여줍니다:
HISTORY COMPRESSED 89%
TOKENS SAVED 459
CONFIDENCE 100%
대화 요약 (Conversation summarisation)과 다른 점
대부분의 요약 도구는 '말해진 내용'을 압축합니다. 반면 SITREP는 '다음 행동을 위해 중요한 내용'을 추출합니다.
Copilot의 컨텍스트 압축 (context compaction)은 전체 대화를 요약합니다. 이는 긴 채팅을 하는 인간에게 유용합니다. 반면 SITREP는 에이전트 (agent)를 위해 구체적으로 구조화되었습니다: 결정 사항, 제약 조건 (constraints), 미결 사항 (open loops), 제외된 경로 (ruled-out paths). 서사적인 요약이 아닙니다. 상태 스냅샷 (state snapshot)입니다.
그 결과, 이후의 턴 (turns)들은 노이즈를 다시 재생하지 않고도 의도 (intent)에 대해 일관성을 유지합니다. 일반적인 채팅보다는 반복적인 구조화된 워크플로 (workflows)를 실행하는 에이전트에게 더 적합합니다.
한계점
SITREP는 구조화된 에이전트 워크플로 (agentic workflows) — 디버깅 세션, 연구 파이프라인, 다단계 빌드 작업 — 에 가장 잘 작동합니다. 지엽적인 컨텍스트가 나중에 중요해질 수 있는 개방형 창의적 작업의 경우, 더 큰 테일 윈도우 (tail window) 또는 더 높은 충실도의 압축 (higher fidelity compression)이 필요할 것입니다.
테일 윈도우 (tail window)는 설정 가능합니다. 구조화되지 않은 세션의 경우 더 많은 원본 컨텍스트 (raw context)를 유지할 수 있습니다.
Trooper가 제공하는 다른 기능들
압축은 가장 최근에 추가된 기능입니다. Trooper는 또한 다음을 수행합니다:
- 클라우드 할당량 (cloud quota)에 도달하면 로컬 Ollama로 폴백 (fallback) — 전환 시에도 컨텍스트 유지
- 단순한 턴 (turns)을 Ollama로 자동 라우팅 — 클라우드에 전혀 접속하지 않음
- 개인정보 보호 라우팅 (Privacy routing) —
x_force_local을 통해 민감한 요청을 로컬에 유지 - 라이브 대시보드 (Live dashboard) — 의도 (intent), 미결 사항 (open loops), 완료된 단계, 트랜스크립트 (transcript)
- 하위 에이전트 복구 (Subagent recovery) —
/recovery/{session_id}를 통해 정확히 어디서 재개해야 하는지 알려줌
이 모든 것이 URL 하나만 변경하면 가능합니다.
더 큰 질문
우리는 대화 기록 (conversation history)을 메모리 (memory)로 취급하는 경향이 있습니다. 하지만 트랜스크립트 (transcript)는 로그 (log)입니다. 메모리는 상태 (state)입니다.
인간은 결정을 내리기 전에 이전의 모든 대화를 다시 재생하지 않습니다. 그들은 결론, 제약 조건 (constraints), 미해결 질문, 그리고 관련 컨텍스트를 전달합니다 — 전체 트랜스크립트가 아닌 구조화된 스냅샷 (structured snapshot)을 말이죠.
장기 실행되는 에이전트들도 똑같이 해야 할 수도 있습니다. 토큰 비용 때문이 아니라 — 물론 비용 절감도 도움이 되지만 — 상태 (state)가 대화 기록 (history)보다 에이전트 메모리에 더 나은 추상화 (abstraction)이기 때문입니다.
SITREP는 그 방향을 향한 실험입니다.
github.com/shouvik12/trooper — Go, MIT, Ollama 외에는 의존성 (dependencies) 없음.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기