Context Engineering 기초
컨텍스트 윈도우는 에이전트의 RAM이다
섹션 제목: “컨텍스트 윈도우는 에이전트의 RAM이다”LangChain의 창업자 Harrison Chase는 에이전트 시스템을 운영체제에 비유했습니다. 이 비유에서 컨텍스트 윈도우는 RAM입니다. 아무리 강력한 CPU(모델)가 있어도 RAM 관리가 잘못되면 시스템은 느려지고, 충돌하고, 결국 실패합니다.
단순히 긴 프롬프트를 작성하는 것과 컨텍스트를 _엔지니어링_하는 것은 다릅니다. Context Engineering은 에이전트가 매 스텝에서 올바른 정보를 정확한 형식으로 받도록 시스템을 설계하는 행위입니다.
Anthropic이 정의한 컨텍스트 엔지니어링의 핵심은 다음과 같습니다:
“Context engineering is the process of dynamically assembling the right information into the context window, in the right format, at the right time.”
이를 위한 전략은 크게 네 가지로 분류됩니다.
네 가지 전략 개요
섹션 제목: “네 가지 전략 개요”| 전략 | 핵심 질문 | 대표 기법 | |------|-----------|-----------| | Write | 무엇을 기록해 두는가? | 스크래치패드, 장기 메모리 | | Select | 무엇을 가져오는가? | RAG, 메모리 검색, 도구 선택 | | Compress | 어떻게 줄이는가? | 요약, 트리밍, 출력 후처리 | | Isolate | 어떻게 분리하는가? | 멀티 에이전트, 샌드박싱 |
Write: 컨텍스트에 쓰기
섹션 제목: “Write: 컨텍스트에 쓰기”Write 전략은 에이전트가 나중에 활용할 정보를 어딘가에 저장하는 것입니다. 두 가지 형태로 나뉩니다.
스크래치패드(Scratchpad): 현재 태스크 진행 중에 에이전트가 중간 메모를 남기는 공간입니다. 추론 과정, 부분 결과, 다음 단계 계획 등을 기록합니다. Manus는 todo.md 파일을 통해 태스크 진행 상황을 실시간으로 업데이트합니다.
메모리(Memory): 세션을 넘어 지속되는 장기 저장소입니다. 사용자 선호도, 과거 결정 이력, 도메인 지식 등이 여기에 저장됩니다.
# 스크래치패드 패턴 예시scratchpad = { "task": "사용자 인증 모듈 구현", "completed": ["요구사항 분석", "DB 스키마 설계"], "in_progress": "JWT 토큰 발급 로직", "next": ["리프레시 토큰 구현", "테스트 작성"], "notes": "bcrypt 라운드는 12로 설정 결정"}Claude Code는 Write 전략을 파일 시스템 레벨에서 구현합니다. CLAUDE.md에 프로젝트 컨텍스트를 기록해두고, 에이전트는 매 세션마다 이를 읽어 지속성을 확보합니다.
# CLAUDE.md 예시 (Claude Code의 Write 전략)## 프로젝트 컨텍스트- 언어: TypeScript + Node.js- 테스트: Jest, 커버리지 80% 이상 유지- 커밋 규칙: Conventional Commits
## 결정 이력- 2024-03: ORM으로 Prisma 채택 (Drizzle 대비 마이그레이션 툴링 우수)- 2024-05: Redis 캐시 레이어 추가 (DB 부하 40% 감소)Select: 컨텍스트 선택
섹션 제목: “Select: 컨텍스트 선택”Select 전략은 방대한 저장소에서 현재 태스크에 필요한 정보만 골라내는 것입니다.
- 메모리 검색: 임베딩 유사도나 지식 그래프를 통해 관련 과거 경험을 검색
- RAG(Retrieval-Augmented Generation): 외부 문서나 코드베이스에서 관련 청크 추출
- 도구 선택(Tool Selection): 수백 개의 가용 도구 중 현재 단계에 적합한 도구만 컨텍스트에 포함
핵심은 관련성입니다. 관련 없는 정보를 컨텍스트에 포함시키면 모델이 혼란을 겪습니다(Context Distraction). 좋은 Select 전략은 신호 대 잡음비를 높입니다.
# Select 전략: 도구 목록 동적 필터링ALL_TOOLS = load_all_tools() # 수백 개
def select_tools_for_task(task_description: str) -> list[Tool]: # 태스크 유형에 따라 관련 도구만 선택 if "파일" in task_description or "코드" in task_description: return [t for t in ALL_TOOLS if t.category in ("filesystem", "code")] if "검색" in task_description or "찾기" in task_description: return [t for t in ALL_TOOLS if t.category in ("search", "browser")] # 기본: 범용 도구만 return [t for t in ALL_TOOLS if t.is_general_purpose]
# 컨텍스트에는 선택된 도구만 포함 → 토큰 절약 + 집중도 향상context_tools = select_tools_for_task(current_task)Cursor는 이 전략을 코드베이스 탐색에 적용합니다. 현재 편집 중인 파일과 의미적으로 관련된 파일만 컨텍스트에 포함시켜, 수만 줄의 코드베이스에서도 정확한 응답을 만들어냅니다.
Compress: 컨텍스트 압축
섹션 제목: “Compress: 컨텍스트 압축”Compress 전략은 컨텍스트 길이를 줄이면서 핵심 정보는 보존하는 것입니다.
- 요약(Summarization): 긴 대화 히스토리나 도구 출력을 압축. 재귀적 요약(오래된 항목부터 점진적으로 압축)과 계층적 요약(중요도에 따라 세부 수준 조정) 방식이 있습니다.
- 트리밍(Trimming): 오래된 메시지나 중복 정보를 단순 제거. 빠르지만 정보 손실 위험이 있습니다.
- 출력 후처리(Post-processing): 도구가 반환한 방대한 출력(예: 긴 검색 결과)에서 필요한 부분만 추출.
Compress 전후 비교
섹션 제목: “Compress 전후 비교”도구 출력을 그대로 컨텍스트에 넣으면 어떤 일이 생기는지 보겠습니다.
# Before: git log 원본 출력 (수백 줄)commit a3f9d2e1b4c5...Author: Alice <alice@example.com>Date: Mon Mar 25 14:32:11 2024 +0900
feat: 사용자 프로필 이미지 업로드 기능 추가
- S3 presigned URL 방식으로 구현 - 최대 5MB, jpeg/png/webp 지원 - 썸네일 자동 생성 (200x200)
commit b7e2a1f9c3d4...Author: Bob <bob@example.com>Date: Sun Mar 24 09:15:44 2024 +0900
fix: 로그인 세션 만료 시 무한 리다이렉트 버그 수정...(이하 200줄 생략)# After: 압축된 요약 (10줄로 축약)## 최근 커밋 요약 (최근 7일)- feat: 프로필 이미지 업로드 (S3, 5MB 제한) - Alice, 3/25- fix: 로그인 세션 무한 리다이렉트 수정 - Bob, 3/24- refactor: 인증 미들웨어 분리 - Carol, 3/23- feat: 이메일 인증 플로우 추가 - Alice, 3/22주요 변경 영역: auth/, user/, storage/압축 후 컨텍스트 사용량이 95% 감소하면서도 에이전트가 작업하는 데 필요한 정보는 유지됩니다.
Isolate: 컨텍스트 격리
섹션 제목: “Isolate: 컨텍스트 격리”Isolate 전략은 컨텍스트를 분리된 공간으로 나누는 것입니다.
멀티 에이전트 아키텍처는 각 서브 에이전트가 전체 히스토리 대신 자신에게 필요한 정보만 가진 독립된 컨텍스트를 사용합니다. 오케스트레이터는 세부 실행 맥락을 알 필요가 없고, 워커는 전체 태스크 컨텍스트를 알 필요가 없습니다.
샌드박싱은 특정 도구나 서브태스크의 실행이 메인 컨텍스트를 오염시키지 않도록 격리합니다.
# Isolate 전략: 서브 에이전트에게 최소한의 컨텍스트만 전달def delegate_subtask(full_context: dict, subtask: str) -> str: # 서브 에이전트는 전체 대화 히스토리가 아닌 # 해당 서브태스크 수행에 필요한 정보만 받는다 minimal_context = { "task": subtask, "constraints": full_context["global_constraints"], "relevant_files": full_context["file_index"].get(subtask), # full_context["conversation_history"] 는 전달하지 않음 } return subagent.run(minimal_context)안티패턴: 컨텍스트 엔지니어링이 없을 때
섹션 제목: “안티패턴: 컨텍스트 엔지니어링이 없을 때”전략 없이 에이전트를 만들면 흔히 이런 문제가 생깁니다.
컨텍스트 폭발(Context Explosion): 모든 도구 출력을 그대로 축적하면 수십 번의 루프 후 컨텍스트가 한계에 도달합니다. 에이전트는 오류를 반환하거나, 앞쪽 정보를 잊어버리기 시작합니다.
# 안티패턴: 압축 없이 도구 출력을 그대로 누적messages = [system_prompt]for step in agent_loop: result = tool.run(action) messages.append({"role": "tool", "content": result}) # 매번 전체 출력 추가 # 10번만 지나도 컨텍스트가 100K 토큰을 넘을 수 있음컨텍스트 오염(Context Pollution): 관련 없는 정보가 섞이면 모델이 엉뚱한 곳에 집중합니다. “파이썬 코드 작성” 요청인데 이전 대화의 SQL 스키마 정보가 가득하면, 모델은 Python과 SQL을 혼용한 답변을 생성할 수 있습니다.
컨텍스트 건망증(Context Amnesia): Compress나 Trim을 너무 공격적으로 적용하면 중요한 지시사항이 사라집니다. “절대 외부 API를 호출하지 말 것”이라는 보안 제약이 트리밍으로 제거되는 경우가 실제로 발생합니다.
전략 선택 가이드
섹션 제목: “전략 선택 가이드”어떤 상황에 어떤 전략을 쓸지 판단하는 기준입니다.
| 상황 | 권장 전략 | 이유 | |------|-----------|------| | 태스크가 여러 세션에 걸쳐 진행됨 | Write (메모리) | 세션 간 연속성 확보 | | 단일 태스크 내 중간 결과 추적 필요 | Write (스크래치패드) | 상태 유실 방지 | | 도구가 100개 이상 등록되어 있음 | Select (도구 필터링) | 관련 없는 도구가 모델을 혼란시킴 | | 대규모 코드베이스에서 작업 | Select (RAG) | 전체 코드를 넣는 것은 불가능 | | 대화가 50턴 이상으로 길어짐 | Compress (요약) | 컨텍스트 한계 도달 방지 | | 도구 출력이 10KB 이상 | Compress (후처리) | 필요한 부분만 추출 | | 병렬 서브태스크 실행 | Isolate (멀티 에이전트) | 각자 독립 컨텍스트로 효율화 | | 민감한 데이터 처리 포함 | Isolate (샌드박싱) | 메인 컨텍스트 오염 방지 |
실전 조합 사례: Claude Code와 Cursor
섹션 제목: “실전 조합 사례: Claude Code와 Cursor”실제 도구들이 이 전략을 어떻게 조합하는지 살펴보면 이해가 깊어집니다.
Claude Code는 네 전략을 모두 사용합니다.
- Write:
CLAUDE.md에 프로젝트 규칙과 결정 이력을 저장. 매 세션에서 읽어 컨텍스트 연속성 확보. - Select: 사용자 명령과 관련된 파일만 읽기. 전체 코드베이스를 컨텍스트에 올리지 않음.
- Compress: 긴 CLI 출력(빌드 로그, 테스트 결과)을 에러/경고 중심으로 압축.
- Isolate: 복잡한 리팩터링은 서브태스크로 분리해 독립 실행.
Cursor는 Select와 Compress에 특히 집중합니다.
- 열린 파일, 최근 편집 파일, 현재 커서 위치 주변 코드를 우선 선택(Select).
- 관련 없는 임포트나 타입 정의는 요약된 형태로 압축(Compress).
- 결과적으로 200K 토큰 코드베이스에서도 4K 토큰 수준의 정밀한 컨텍스트로 응답.
실습: 컨텍스트 전략 설계
섹션 제목: “실습: 컨텍스트 전략 설계”다음 시나리오를 읽고, 어떤 전략 조합을 적용할지 설계해보세요.
시나리오: 사용자가 “지난 3개월간의 이슈를 분석해서 패턴을 찾아줘”라고 요청했습니다. GitHub API로 이슈 300개를 가져올 수 있고, 각 이슈에는 댓글이 평균 10개씩 붙어 있습니다.
생각해볼 질문:
- 이슈 300개 × 댓글 10개를 모두 컨텍스트에 올릴 수 있을까요? (힌트: 토큰 계산)
- 어떤 전략으로 컨텍스트 크기를 관리하겠습니까?
- 분석 과정의 중간 결과를 어떻게 보존하겠습니까?
- 이슈 유형별로 병렬 분석이 가능하다면 어떻게 설계하겠습니까?
컨텍스트 엔지니어링은 프롬프트 작성을 넘어선 시스템 설계입니다. Write로 필요한 것을 저장하고, Select로 관련된 것만 고르고, Compress로 크기를 줄이고, Isolate로 범위를 분리하는 네 전략을 조합하면 에이전트의 성능과 안정성이 크게 향상됩니다.