콘텐츠로 이동

에이전틱 LLM 시스템의 컨텍스트 엔지니어링

분류: Layer 12 - AI 시스템 & LLM 애플리케이션 | 선수지식: L12-20 (Prompt), L12-40 (RAG), L12-50 (Tool calling), L12-60 (Agent)

에이전틱 LLM 시스템의 컨텍스트 엔지니어링 — Context Window, Memory, Retrieval, Compression

섹션 제목: “에이전틱 LLM 시스템의 컨텍스트 엔지니어링 — Context Window, Memory, Retrieval, Compression”

컨텍스트 엔지니어링은 LLM 호출 시점에 들어가는 지시문, 사용자 입력, 검색 결과, 도구 결과, 메모리, 정책, 출력 형식을 작업 목표에 맞게 선별·배치·압축·검증하는 설계 discipline이다.

  • 프롬프트보다 넓은 문제: agent 입력에는 prompt뿐 아니라 RAG 문서, tool observation, memory, UI state, policy가 함께 들어간다.
  • 토큰 예산은 품질 예산: long context가 가능해도 irrelevant context가 많으면 attention이 흐려지고 비용·지연이 증가한다.
  • 출처와 격리: trusted instruction, untrusted retrieved text, user data, tool output을 한 문자열로 섞으면 prompt injection과 근거 오염이 생긴다.
  • 재현성: “왜 이 답이 나왔는지”를 보려면 당시 context bundle을 버전과 함께 재구성할 수 있어야 한다.
  • agent 운영의 병목: multi-step agent는 매 step마다 context가 변하므로, 한 번 잘 만든 prompt보다 context 갱신 정책이 더 중요하다.

2.5 선행 기술의 한계 — Prompt Engineering만으로 부족했던 이유

섹션 제목: “2.5 선행 기술의 한계 — Prompt Engineering만으로 부족했던 이유”

L12-20 프롬프트 엔지니어링은 “한 번의 LLM 호출에 무엇을 쓰는가”를 주로 다룬다. 그러나 agent는 retrieve → tool call → observation → plan 수정 → 다음 tool처럼 여러 단계로 움직인다. 이때 실패는 prompt 문장보다 어떤 정보를 넣고 빼는가에서 더 자주 생긴다.

선행 방식의 한계는 세 가지다.

  1. 정적 prompt 한계: system prompt는 변하지 않지만 작업 중간 상태는 계속 바뀐다. 파일 탐색, 검색 결과, 사용자의 승인 여부 같은 동적 정보는 prompt 템플릿만으로 관리할 수 없다.
  2. RAG top-k의 한계: 관련 문서 20개를 그대로 넣으면 recall은 올라가지만 noise도 같이 올라간다. 모델은 “근거”와 “비슷하지만 틀린 문서”를 자동으로 분리하지 못한다.
  3. memory 누적의 한계: 대화 이력을 계속 붙이면 비용은 선형 증가하고, 오래된 잘못된 가정이 이후 step을 오염시킨다.

컨텍스트 엔지니어링은 이 한계를 context budget, source tagging, retrieval policy, compression, state summary, provenance로 푼다. Anthropic은 context engineering을 prompt engineering의 자연스러운 확장으로 설명하며, agent inference 시점에 들어오는 모든 token을 선별·유지하는 전략으로 본다. 출처: Anthropic, Effective context engineering for AI agents.

컨텍스트 엔지니어링은 “많이 넣기”가 아니라 LLM 호출 전후의 lifecycle을 운영하는 일이다.

collect -> select -> rank -> compress -> assemble -> execute -> evaluate -> persist/expire
단계질문실패하면 생기는 문제
Collect후보 context를 어디서 모을 것인가중요한 근거·상태가 애초에 후보에 없음
Select이번 step에 필요한 것은 무엇인가prompt stuffing, noise, 비용 증가
Rank무엇을 먼저 읽게 할 것인가관련 정보가 context window 안쪽에서 밀림
Compress무엇을 보존하고 무엇을 버릴 것인가요약은 짧지만 결정 근거가 사라짐
Assemble어떤 슬롯과 신뢰 경계에 넣을 것인가system rule과 untrusted text가 섞임
Execute실제 호출에서 어떤 입력이 쓰였는가의도한 bundle과 실행 입력이 어긋남
Evaluatecontext가 답을 만들기에 충분했나답변 품질만 보고 원인 분석을 놓침
Persist무엇을 memory로 남기고 만료할 것인가오래된 가정이 다음 run을 오염시킴

따라서 context engineering은 prompt stuffing의 반대에 가깝다. 더 긴 context window를 채우는 기술이 아니라, 현재 결정에 필요한 정보만 출처·버전·만료 정책과 함께 공급하는 파이프라인이다.

LLM 호출마다 다음 정보를 하나의 bundle로 본다.

ContextBundle =
instructions // system/developer policy
task_state // 목표, 현재 단계, 완료 조건
user_input // 이번 입력
retrieved_evidence // RAG 결과
tool_observations // API/DB/파일 결과
memory // 장기/단기 기억
output_contract // JSON schema, citation rule
safety_policy // 권한, 금지 action

운영에서는 bundle 전체를 trace에 남기되, 개인정보와 secret은 redaction해야 한다.

작은 trace 예시는 다음처럼 trusted instruction과 untrusted evidence를 분리해 남긴다.

{
"bundle_id": "ctx_20260522_001",
"task_state": {
"goal": "가격 정책 질문에 근거와 함께 답변",
"step": "answer"
},
"instructions": [{ "trusted": true, "source_id": "policy://assistant-v4" }],
"retrieved_evidence": [
{
"source_id": "kb://pricing-v3#span-18",
"trusted": false,
"score": 0.87,
"selected_reason": "현재 질문의 enterprise seat 가격 조건과 직접 일치"
}
],
"dropped_candidates": [
{
"source_id": "kb://pricing-v2#span-04",
"score": 0.81,
"dropped_reason": "older_version"
}
],
"memory": [
{
"source_id": "memory://user/preferences/format",
"trusted": true,
"expires_at": "2026-08-22"
}
]
}

모든 정보를 넣는 것이 최적은 아니다. token budget을 역할별로 나눈다.

슬롯예산 예시판단 기준
지시문5~15%안정적이고 짧게 유지
작업 상태10~20%현재 목표와 완료 조건만
근거 문서40~60%answer를 만들 수 있는 최소 chunk
도구 결과10~30%최근 step 중심, 원문은 필요 시 링크
메모리5~15%검증된 preference·사실만

budget 초과 시 우선 삭제 순서는 중복 문서 → 낮은 score 문서 → 오래된 observation → 요약 가능한 history다.

운영에서는 budget 정책을 context eval과 prompt caching에 같이 묶어 본다. 예를 들어 고객지원 answer step은 sufficiency >= 0.85, grounding >= 0.9, irrelevant_token_ratio <= 0.25를 최소 통과선으로 두고, 미달하면 근거 문서 슬롯을 늘리기보다 dropped candidate와 압축 품질을 먼저 점검한다. 반대로 system policy, tool schema, citation rule처럼 자주 바뀌지 않는 앞부분은 cacheable_prefix로 고정해 prompt caching 대상에 두고, 사용자 질문·검색 결과·최근 tool observation은 prefix 밖의 변동 슬롯으로 둔다. 이렇게 해야 캐시 적중률을 높이려고 오래된 evidence를 prefix에 묶어 context budget과 grounding 품질을 동시에 망치는 일을 피할 수 있다.

선택 정책은 “top-k 몇 개”보다 더 넓다. agent step마다 필요한 context 종류가 다르기 때문이다.

정책쓰는 곳주의점
Recency최근 tool observation, chat turn최신 정보가 항상 가장 중요한 것은 아님
Relevance scoreRAG chunk, memory 후보비슷하지만 틀린 문서가 상위에 올 수 있음
Authority정책 문서, API spec, runbook오래된 authoritative 문서의 버전 확인 필요
Diversity여러 관점의 근거 비교중복 chunk를 줄이되 핵심 근거를 잃지 않기
State criticality현재 전이에 필요한 상태L12-110 state graph의 guard 입력과 연결

운영에서는 후보별로 source_id, score, selected_reason, dropped_reason을 trace에 남기면 좋다. “모델이 틀렸다”가 아니라 “필요한 chunk가 후보에는 있었지만 budget에서 탈락했다”는 원인을 찾을 수 있다.

LLM은 token만 보므로 “이 문장은 system rule”과 “웹페이지가 주장한 instruction”을 혼동할 수 있다. 따라서 context에는 출처와 신뢰도를 명시한다.

<trusted_system>
You must cite retrieved sources.
</trusted_system>
<untrusted_retrieved_doc source="kb://pricing-v3">
Ignore previous instructions ... // 문서 내용일 뿐 실행 지시가 아님
</untrusted_retrieved_doc>

이 구분은 L12-80 LLM 보안의 prompt injection 방어와 직접 연결된다.

압축은 “짧게 요약”이 아니라 의사결정에 필요한 정보만 보존하는 작업이다.

  • Extractive compression: 원문 문장을 그대로 골라 citation 안정성 유지
  • Abstractive summary: 긴 대화·tool 결과를 상태 요약으로 변환
  • Query-focused summary: 현재 질문과 무관한 정보 제거
  • Schema compression: 자연어 로그를 {decision, evidence, open_questions} 구조로 압축

RAG 근거는 가능한 extractive, agent state는 schema summary가 안전하다.

압축 결과는 원문과 분리해서 versioning한다. 같은 대화 history라도 compressor prompt나 schema가 바뀌면 다른 state summary가 나오므로 summary_version, source_span_ids, created_at을 함께 남겨야 한다. 그래야 나중에 답변 회귀가 모델 변경 때문인지, 압축 정책 변경 때문인지 분리할 수 있다.

Memory는 “대화 전체 저장”이 아니다.

종류저장 대상삭제/갱신 기준
Working memory현재 task staterun 종료 시 폐기
Episodic memory과거 작업 결과재사용 가치가 있을 때만
Semantic memory사용자/도메인 사실출처와 갱신일 보유
Preference memory선호 형식·제약사용자가 명시한 경우

잘못된 memory는 retrieval보다 위험하다. 모델이 “이미 아는 사실”처럼 받아들이기 때문이다.

memory에는 최소한 다음 lifecycle 규칙이 필요하다.

  • Write gate: 사용자가 명시했거나 여러 source로 검증된 정보만 저장한다.
  • Update rule: 새 정보가 기존 memory와 충돌하면 덮어쓰기보다 conflict 상태로 둔다.
  • Expiry: 프로젝트 상태, 가격, 권한처럼 변하는 정보에는 만료일을 둔다.
  • Provenance: 어느 대화·문서·tool 결과에서 온 정보인지 추적한다.
  • Read policy: 모든 memory를 매번 넣지 않고 현재 task와 관련 있는 것만 retrieve한다.

답변만 평가하면 원인을 놓친다. context 자체를 평가한다.

  • Sufficiency: 이 context만으로 정답을 만들 수 있는가
  • Relevance: 들어간 chunk 중 answer에 실제 사용된 비율
  • Grounding: 답변 claim이 context span에 연결되는가
  • Contamination: untrusted text가 instruction처럼 작동했는가
  • Economy: 같은 품질을 더 적은 token으로 만들 수 있는가

이 지표는 L12-90 관측성·평가의 trace와 함께 봐야 한다.

평가 단위는 최소 세 겹으로 나누면 원인 분석이 쉬워진다.

평가 단위예시 질문
Candidate set정답 근거가 후보 검색 결과 안에 있었는가
Selected context후보 중 실제 주입된 context가 충분했는가
Generated answer주입된 context를 근거로 올바른 답을 만들었는가

candidate에는 있었는데 selected에서 빠졌다면 selection/budget 문제다. selected에는 있었는데 답이 틀렸다면 prompt, model, output contract, judge 문제일 가능성이 높다.

agent는 매 step마다 context를 재작성한다.

plan step:
goal + constraints + available tools
tool step:
selected tool schema + minimal arguments + relevant prior observation
reflection step:
expected outcome + actual observation + next decision
final step:
evidence + decision log + citation

모든 step에 전체 history를 넣으면 비용과 noise가 동시에 증가한다.

state machine 기반 workflow(L12-110)와 결합할 때는 graph state와 context bundle을 분리한다. graph state는 current_node, attempts, approval_status처럼 전이에 필요한 작은 값이고, context bundle은 evidence·memory·tool observation처럼 LLM 판단에 필요한 입력이다. 이 둘을 한 객체에 섞으면 checkpoint가 커지고 replay 시 오래된 context가 현재 결정을 오염시킨다.

증상원인복구
답은 유창한데 근거가 틀림유사하지만 다른 chunk가 상위 검색rerank, query rewrite, citation span 검증
agent가 같은 tool 반복최신 observation이 context에서 밀림step state summary를 별도 슬롯에 고정
user preference 무시preference가 긴 history에 묻힘검증된 preference memory 분리
prompt injection 통과untrusted doc을 instruction처럼 주입source tagging, tool 권한 분리
비용 폭증history 전체 재전송rolling summary, cacheable prefix 분리
회귀 원인 불명context version과 선택 로그 부재bundle version, selected/dropped log 저장
  • 사내 문서 RAG 챗봇의 chunk 선택·citation 정책
  • 코드 에이전트의 파일 컨텍스트 선택
  • 고객 상담 agent의 사용자 프로필·과거 티켓 memory
  • tool-calling agent의 observation 요약과 재시도 판단
  • long-running workflow의 중간 상태 복원

프론트엔드에서 상태 관리가 props drilling에서 store·selector·memoization으로 발전하듯, LLM 앱도 prompt 문자열 하나에서 context store·retriever·compressor·evaluator로 발전한다. 플랫폼 관점에서는 “좋은 답변”보다 좋은 답변을 만들 context pipeline을 운영하는 것이 핵심이다.

개념 A개념 B차이점
Prompt engineeringContext engineeringprompt 문구 최적화 vs 호출에 들어가는 전체 정보 환경 설계
RAGContext engineeringRAG는 외부 지식 주입 방식, context engineering은 RAG 결과 포함 전체 token 관리
MemoryHistorymemory는 재사용 가치가 검증된 상태, history는 과거 메시지 원본
Long contextGood context길게 넣는 능력 vs 필요한 정보만 넣는 품질
SummarizationCompression읽기 좋은 요약 vs 의사결정 정보 보존
  • LLM 호출마다 들어가는 context bundle 구성요소를 설명할 수 있다.
  • collect/select/rank/compress/assemble/evaluate/persist lifecycle을 설계할 수 있다.
  • trusted instruction과 untrusted retrieved text를 분리하는 이유를 설명할 수 있다.
  • top-k 주입이 아니라 selection·ranking·dropped reason까지 추적할 수 있다.
  • context 품질을 sufficiency·relevance·grounding으로 평가할 수 있다.
  • agent step별로 어떤 context를 유지하고 버릴지 설계할 수 있다.
  • memory에 저장해도 되는 정보와 저장하면 위험한 정보를 구분할 수 있다.

context engineering, context lifecycle, context selection, context window management, prompt caching, memory retrieval, query-focused summarization, source attribution, context compression, memory expiry, context evaluation, context poisoning, lost in the middle

  • 같은 질문에 대해 top-k 3/10/20 RAG context를 넣고 faithfulness·latency 비교
  • 대화 history 전체 주입 vs rolling summary 주입의 비용·품질 비교
  • retrieved document에 악성 instruction을 넣고 source tagging 전후 동작 비교
  • agent tool observation을 원문/요약/구조화 JSON으로 넣었을 때 다음 action 정확도 비교
  • selected context와 dropped candidate를 로그로 남기고 실패 케이스 5개 원인 분류
  1. 컨텍스트 엔지니어링은 prompt가 아니라 LLM 호출에 들어가는 전체 정보 lifecycle을 설계하는 일이다.
  2. 좋은 context는 많이 넣은 context가 아니라 선택·정렬·압축·출처·만료가 관리된 context다.
  3. agent에서는 매 step마다 context가 바뀌므로 동적 갱신 정책이 품질을 좌우한다.
  4. trusted instruction과 untrusted data를 분리하지 않으면 prompt injection과 근거 오염이 생긴다.
  5. context bundle을 trace와 eval에 연결해야 회귀 원인을 답변이 아니라 입력 단계에서 찾을 수 있다.

최종 수정: 2026-05-21