본문으로 이동
문서 탐색컨텍스트 조립
핵심 개념레퍼런스

컨텍스트 조립

실제 시스템 프롬프트 경로와 명시적 5계층 context facade를 토큰 예산과 함께 설명합니다.

기본 AgenticLoop의 모델 컨텍스트는 레이어로 조립된 시스템 프롬프트와 대화 히스토리로 만들어집니다. 이와 별도로 GeodeRuntime은 명시적 소비자를 위한 5계층 context facade를 제공합니다. 이 페이지는 두 경계를 구분하고, 토큰 예산을 넘으면 무엇이 양보하는지 정리합니다.

명시적 facade: 메모리 계층

core/memory/context.pyContextAssembler가 5계층 메모리를 병합해 _llm_summary가 포함된 dict를 만듭니다. 이 경로는 GeodeRuntime.assemble_context()를 호출할 때만 실행되며 기본 AgenticLoop prompt에는 자동 연결되지 않습니다. 병합은 Identity, User Profile, Organization, Project, Session 순서로 흐릅니다.

계층요약 예산
Identity (SOUL.md)10%
User Profile있으면 앞부분 예산에 짧게 포함
Organization25%
Project25%
Session나머지. 최신 항목부터 채웁니다

계층 병합 뒤에는 프로젝트 타입, 최근 실행 기록, 프로젝트 저널, Vault 요약 같은 보강 블록이 붙습니다. 계층 자체의 구조와 override 규칙은 메모리 계층에서 다룹니다.

실제 모델 경로: 시스템 프롬프트 레이어

core/agent/system_prompt.py build_system_prompt(model)이 캐시 가능한 정적 prefix와 턴마다 바뀌는 동적 섹션(<dynamic_context>)을 경계 마커로 나눠 조립합니다. 레이어 구성과 모드는 프롬프트 조립, 캐시 동작은 프롬프트 캐싱을 참고합니다.

오버플로 처리: 누가 양보하는가

루프는 매 라운드 진입 시 core/agent/context_manager.py ContextWindowManager에 오버플로 점검을 위임합니다. 임계값은 core/orchestration/context_budget.py resolve_context_budget_policy가 모델의 컨텍스트 윈도에 맞춰 계산합니다. 반환된 ContextBudgetPolicy가 세 티어 중 하나를 고릅니다.

티어윈도 범위경고 임계임계
small≤ 256K50%90%
standard≤ 512K70%90%
large> 512K80%90%

퍼센트는 유효 프롬프트 예산(effective_prompt_budget_tokens = 윈도에서 출력 예비분 약 20K를 뺀 값) 기준입니다. 실제 대응은 프로바이더에 따라 갈립니다.

  • Anthropic. 경고 수준 압력은 서버 측 context management가 처리하므로 클라이언트는 개입하지 않습니다. 임계 수준에서만 클라이언트가 비상 정리(prune)를 수행합니다.
  • OpenAI / GLM. 서버 측 압축이 없어 클라이언트가 3단계 압력 대응을 순차 실행합니다. (1) 값싼 도구 압축 — 오래된 관측 마스킹(mask_stale_observations)과 큰 도구 결과 요약(summarize_tool_results, LLM 호출 없음), (2) 구조화 LLM 압축(compact_conversation), (3) 압축으로 부족하거나 실패하면 적응형 정리(adaptive_prune).
  • 컨텍스트 윈도가 200K를 넘는 모델에는 별도로 절대 200K 토큰 천장(absolute_ceiling_tokens)이 걸립니다. 퍼센트 임계와 무관하게 rate-limit 풀 분리를 피하려는 조치로, 도구 결과 요약 후 필요하면 압축을 강제합니다.
  • 전략 선택은 CONTEXT_OVERFLOW_ACTION 훅 핸들러에 위임되고, 등록된 핸들러가 없으면 해석된 policy가 폴백입니다. 임계 상태에서는 CONTEXT_CRITICAL 훅이 발화합니다.
  • 정리 후에도 임계 상태면 루프는 context_exhausted로 종료하고, 사용자 언어에 맞춘 안내문을 생성해 돌려줍니다 (core/agent/loop/models.py).
  • API가 400으로 컨텍스트 오버플로를 알리면 공격적 복구를 시도한 뒤 재시도하고, 실패하면 역시 context_exhausted입니다.

압축 장비는 core/orchestration/compaction.py core/orchestration/context_monitor.py에 있고, 티어 경계와 임계 상수는 core/orchestration/context_budget.py가 SoT입니다. 모델별 컨텍스트 윈도 값은 core/llm/token_tracker.py MODEL_CONTEXT_WINDOW가 SoT입니다 (core/llm/model_pricing.toml이 뒷받침).

대형 도구 결과: 오프로드

모델에 전달할 도구 결과가 기본 15,000 토큰 임계값을 넘으면 core/orchestration/tool_offload.py ToolResultOffloadStore가 결과를 디스크 (.geode/tool-offload/ 아래 세션 디렉터리)로 내리고, 컨텍스트에는 요약과 ref_id만 남깁니다. 모델은 필요할 때 recall_tool_result(ref_id) 경로로 원본을 다시 가져옵니다. 오프로드 시 TOOL_RESULT_OFFLOADED 훅이 발화합니다.

MCP의 CallToolResult는 호환성을 위해 같은 값을 contentstructuredContent에 함께 담을 수 있습니다. 원본은 session timeline과 tool log에 receipt로 그대로 남기고, 모델 경계에서는 structured 값을 우선해 한 표현만 고른 뒤 오프로드와 25,000-token hard guard를 적용합니다. 따라서 증거는 보존하면서 중복 JSON을 컨텍스트에 다시 넣지 않습니다.

장기 컨텍스트 아티팩트: dreaming

메시지 트랜스크립트와 별개로, 프로젝트별 sessions.db(SQLite)에는 context_artifacts 행이 쌓입니다. 합성된 장기 컨텍스트 기록으로, 턴 경로 밖에서 만들어집니다. core/memory/dreaming.py DreamingServiceTURN_COMPLETED 훅에서 백그라운드로 동작합니다(best-effort — 포그라운드 턴을 절대 막지 않습니다). 트랜스크립트를 증거로 삼아 지속 사실, 결정, 미해결 작업, 낡은 리스크, 유용한 recall 질의, 인용을 정해진 헤딩으로 요약하고, dream 종류의 아티팩트로 되씁니다. source_end_seq 기준으로 멱등이라 새 메시지가 없으면 건너뛰고, LLM을 못 쓰면 LLM 없는 로컬 요약으로 폴백합니다.

주입은 경계가 있습니다. ContextAssembler _inject_long_context_artifacts가 최신 compaction_summary/dream 아티팩트 최대 3개를 각 500자로 잘라 _long_context_summary로 넣습니다. session_search 도구는 include_artifacts=true(선택적 artifact_kinds 필터)로 FTS5 메시지 검색과 함께 이 합성 아티팩트도 뒤집니다.

캐시를 깨지 않는 이력

날짜와 runtime rule은 system_prompt.py의 동적 시스템 영역에 한 번 조립됩니다. 라운드별 reminder message는 만들지 않으며, 대화 이력에는 실제 user, assistant, tool turn만 append합니다. 그래서 다음 요청이 이전 요청의 메시지열을 정확한 prefix로 보존하고 Anthropic·OpenAI 캐시가 재사용할 수 있습니다.

실패 모드

증상원인해법
긴 세션에서 context_exhausted 종료압축 후에도 히스토리가 임계 상태새 세션을 열거나 /compact로 미리 압축합니다
도구 결과가 요약으로만 보임15,000 토큰 임계값을 넘어 오프로드됨정상 동작입니다. recall_tool_result(ref_id)로 원본을 조회합니다
캐시 적중률이 갑자기 하락히스토리 앞부분을 변형하는 커스텀 주입턴별 메타데이터는 시스템 동적 영역에 두고, 대화에는 실제 turn만 append합니다

다음