AI 에이전트를 위한 효과적인 컨텍스트 엔지니어링
원문: Anthropic Engineering, Effective context engineering for AI agents
이 글은 원문을 그대로 옮긴 전문 번역이 아니라, 한국어 독자가 읽기 좋도록 핵심 논지를 충실히 옮기고 맥락을 보강한 번역·해설입니다.
프롬프트 엔지니어링 다음의 질문
지난 몇 년 동안 LLM을 잘 쓰는 방법의 중심에는 ‘프롬프트 엔지니어링’이 있었습니다. 어떤 지시문을 쓰고, 어떤 예시를 넣고, 어떤 표현을 사용해야 모델이 원하는 답을 내놓는지가 핵심 관심사였죠.
하지만 AI 시스템이 단순한 한 번의 질의응답을 넘어, 여러 단계의 추론과 도구 사용을 반복하는 에이전트로 발전하면서 질문의 중심도 바뀌고 있습니다.
이제 중요한 질문은 단지 “어떤 문장으로 지시할 것인가?”가 아닙니다.
“모델이 원하는 행동을 하도록 만들기 위해, 매 순간 어떤 정보를 컨텍스트에 넣어야 하는가?”
Anthropic은 이 문제를 **컨텍스트 엔지니어링(context engineering)**이라고 설명합니다.
여기서 컨텍스트란 LLM이 다음 토큰을 생성할 때 참고하는 모든 토큰의 집합입니다. 시스템 프롬프트, 사용자 메시지, 도구 설명, 도구 호출 결과, 외부 데이터, 이전 대화 기록, MCP를 통해 들어온 정보까지 모두 포함됩니다.
컨텍스트 엔지니어링은 이 제한된 토큰 공간을 어떻게 구성하고 유지할지에 관한 기술입니다. 목표는 단순합니다.
원하는 결과가 나올 가능성을 가장 크게 만드는, 가장 작고 신호가 높은 정보 집합을 만드는 것.
컨텍스트 엔지니어링과 프롬프트 엔지니어링의 차이
프롬프트 엔지니어링은 주로 모델에게 줄 지시문을 잘 쓰는 문제입니다. 특히 시스템 프롬프트를 어떻게 구성하고, 어떤 형식으로 예시를 주며, 어떤 출력 형식을 요구할지가 중요합니다.
반면 컨텍스트 엔지니어링은 프롬프트보다 더 넓은 범위를 다룹니다.
- 시스템 지시문
- 도구 목록과 도구 설명
- 외부 데이터
- 검색 결과
- 메시지 히스토리
- 파일 경로, 쿼리, URL 같은 참조 정보
- 에이전트가 작업 중 남긴 메모
- 이전 단계의 도구 호출 결과
에이전트는 반복 루프 안에서 계속 새로운 정보를 만들어냅니다. 도구를 호출하고, 파일을 읽고, 검색 결과를 보고, 오류를 만나고, 다시 시도합니다. 이 과정에서 다음 추론에 도움이 될 수도 있는 정보가 계속 늘어납니다.
하지만 모든 정보를 넣을 수는 없습니다. 넣을 수 있다 해도, 많이 넣는 것이 항상 좋은 것도 아닙니다. 따라서 매 추론 시점마다 “무엇을 남기고, 무엇을 버리고, 무엇을 나중에 필요할 때 가져올 것인가?”를 판단해야 합니다.
이 지점에서 컨텍스트 엔지니어링은 일회성 작업이 아니라 반복적인 큐레이션 작업이 됩니다.
왜 컨텍스트 엔지니어링이 중요한가
LLM의 컨텍스트 윈도우는 점점 커지고 있습니다. 하지만 컨텍스트가 커진다고 해서 모델이 모든 정보를 똑같이 잘 활용하는 것은 아닙니다.
Anthropic은 LLM도 사람처럼 어느 순간부터 집중력이 떨어지고 혼란을 겪는다고 설명합니다. 긴 문맥 안에서 특정 정보를 찾아내는 ‘needle-in-a-haystack’류의 벤치마크에서도 비슷한 현상이 관찰됩니다. 컨텍스트가 길어질수록, 모델이 그 안의 정보를 정확히 회상하는 능력이 떨어지는 현상입니다. 이를 흔히 **컨텍스트 부패(context rot)**라고 부릅니다.
즉, 컨텍스트는 단순히 “넣을 수 있는 공간”이 아니라 희소한 자원입니다. 토큰을 더 넣을수록 모델의 주의력 예산(attention budget)을 조금씩 소모합니다.
그 이유는 LLM의 기반 구조인 트랜스포머에 있습니다. 트랜스포머는 각 토큰이 다른 모든 토큰에 주의를 기울일 수 있도록 설계되어 있습니다. 토큰 수가 n개라면, 토큰 간 관계는 대략 n² 규모로 늘어납니다. 컨텍스트가 길어질수록 이 관계를 정밀하게 처리하기 어려워집니다.
물론 긴 컨텍스트를 다루기 위한 기술은 계속 발전하고 있습니다. 위치 인코딩 보간 같은 기법을 통해 모델은 더 긴 시퀀스를 처리할 수 있습니다. 하지만 성능 저하는 벼랑처럼 갑자기 발생하기보다, 문맥이 길어질수록 점진적으로 나타나는 경향이 있습니다.
그래서 좋은 에이전트를 만들려면 “가능한 많은 정보를 넣자”가 아니라 “정말 필요한 정보를 선별하자”는 관점이 필요합니다.
좋은 컨텍스트의 조건
좋은 컨텍스트 엔지니어링의 핵심 원칙은 다음과 같습니다.
원하는 결과를 얻는 데 필요한, 가장 작고 신호가 높은 토큰 집합을 구성한다.
말은 쉽지만 실제 구현은 어렵습니다. Anthropic은 컨텍스트를 구성하는 여러 요소별로 다음과 같은 기준을 제시합니다.
시스템 프롬프트: 적절한 고도에서 지시하기
시스템 프롬프트는 명확하고 단순해야 합니다. 여기서 중요한 표현은 **적절한 고도(right altitude)**입니다.
너무 낮은 고도의 프롬프트는 모델의 행동을 if-else 규칙처럼 과도하게 하드코딩합니다. 이런 방식은 처음에는 정확해 보일 수 있지만, 상황이 조금만 바뀌어도 쉽게 깨지고 유지보수 비용이 커집니다.
반대로 너무 높은 고도의 프롬프트는 “잘 판단하라”, “사용자에게 도움이 되게 하라”처럼 추상적인 지침만 제공합니다. 이런 지시는 모델에게 구체적인 신호를 충분히 주지 못하고, 모델과 개발자가 같은 배경지식을 공유하고 있다고 잘못 가정하기 쉽습니다.
좋은 시스템 프롬프트는 그 중간에 있습니다.
- 원하는 행동을 충분히 구체적으로 설명한다.
- 하지만 모든 상황을 규칙으로 박아 넣지는 않는다.
- 모델이 스스로 판단할 수 있는 강한 휴리스틱을 제공한다.
프롬프트 구조는 XML 태그나 마크다운 헤더를 활용해 구분할 수 있습니다.
예를 들면 다음과 같습니다.
<background_information>
...
</background_information>
<instructions>
...
</instructions>
## Tool guidance
...
## Output description
...
다만 모델이 발전할수록 정확한 포맷 자체의 중요성은 줄어들 수 있습니다. 더 중요한 것은 프롬프트가 기대 행동을 충분히 설명하면서도 불필요한 내용을 줄이는 것입니다.
Anthropic의 권장 방식은 간단합니다.
먼저 가능한 한 최소한의 프롬프트로 최고의 모델을 테스트합니다. 이후 실패 사례를 관찰하면서 명확한 지시와 예시를 추가합니다.
도구: 에이전트와 환경 사이의 계약
도구는 에이전트가 환경과 상호작용하고 새로운 정보를 가져오는 통로입니다. 따라서 도구는 단순한 기능 목록이 아니라, 에이전트와 정보·행동 공간 사이의 계약입니다.
좋은 도구는 다음 조건을 갖춰야 합니다.
- 기능이 명확하다.
- 다른 도구와 역할이 과도하게 겹치지 않는다.
- 오류에 견고하다.
- 입력 파라미터가 모호하지 않다.
- 반환 결과가 토큰 효율적이다.
- 에이전트가 효율적인 행동을 하도록 유도한다.
흔한 실패 사례는 도구가 너무 많은 기능을 포괄하거나, 비슷한 도구가 많아 어떤 도구를 써야 할지 애매해지는 것입니다.
사람 개발자도 “이 상황에서는 어떤 도구를 써야 하지?”라고 헷갈린다면, AI 에이전트가 더 잘 판단하기를 기대하기 어렵습니다.
따라서 도구 목록은 많을수록 좋은 것이 아닙니다. 에이전트가 실제로 안정적으로 사용할 수 있는 최소한의 유효 도구 집합을 유지하는 편이 장기적으로 더 좋습니다.
예시는 천 마디 설명보다 강하다
Few-shot prompting, 즉 예시 제공은 여전히 강력한 방법입니다. 하지만 Anthropic은 모든 예외 케이스를 프롬프트에 끝없이 넣는 방식을 권장하지 않습니다.
대신 다양한 상황을 대표할 수 있는 표준적이고 선명한 예시를 큐레이션하라고 말합니다.
LLM에게 예시는 그림과 비슷합니다. 잘 고른 예시 하나는 긴 설명보다 더 많은 행동 신호를 전달합니다.
중요한 것은 예시의 양이 아니라 품질입니다.
- 대표성이 있는가?
- 기대 행동을 명확히 보여주는가?
- 서로 다른 실패 모드를 커버하는가?
- 불필요한 세부 규칙을 늘리지 않는가?
런타임 컨텍스트 검색과 에이전트식 탐색
많은 AI 애플리케이션은 임베딩 기반 검색을 사용해, 모델 호출 전에 관련 문서를 미리 찾아 컨텍스트에 넣습니다. RAG가 대표적인 예입니다.
하지만 에이전트형 시스템으로 갈수록 Anthropic은 just-in-time 컨텍스트 전략이 중요해진다고 설명합니다.
이 방식은 모든 데이터를 미리 컨텍스트에 넣지 않습니다. 대신 파일 경로, 저장된 쿼리, 웹 링크 같은 가벼운 참조만 유지하고, 필요할 때 도구를 통해 데이터를 읽어옵니다.
Claude Code가 좋은 예입니다. 거대한 코드베이스나 데이터베이스 전체를 한 번에 컨텍스트에 넣지 않습니다. 모델은 필요한 파일을 찾고, 특정 쿼리를 작성하고, head, tail 같은 명령으로 큰 결과를 일부만 살펴보며 작업을 이어갑니다.
이는 사람이 일하는 방식과도 비슷합니다. 우리는 모든 문서를 머릿속에 외우지 않습니다. 대신 파일 시스템, 메일함, 북마크, 검색어, 폴더 구조를 활용해 필요할 때 필요한 정보를 찾습니다.
참조 정보 자체도 중요한 신호를 제공합니다.
예를 들어 같은 test_utils.py라는 파일이라도, tests/ 폴더에 있는지 src/core_logic/ 아래에 있는지에 따라 의미가 달라집니다. 폴더 구조, 파일명, 수정 시간은 모두 에이전트가 정보를 어떻게 사용할지 판단하는 데 도움이 됩니다.
이런 방식은 **점진적 공개(progressive disclosure)**를 가능하게 합니다. 에이전트는 처음부터 모든 정보를 보지 않고, 탐색을 통해 필요한 맥락을 단계적으로 발견합니다.
물론 단점도 있습니다. 런타임 탐색은 미리 계산된 검색 결과를 넣는 것보다 느릴 수 있습니다. 또한 에이전트가 정보를 잘 찾도록 도구와 휴리스틱을 신중하게 설계해야 합니다. 그렇지 않으면 잘못된 도구를 쓰거나, 막다른 길을 탐색하거나, 중요한 정보를 놓치면서 컨텍스트를 낭비할 수 있습니다.
따라서 실전에서는 하이브리드 전략이 유용할 수 있습니다.
- 자주 필요한 정보는 처음부터 넣는다.
- 나머지는 에이전트가 필요할 때 탐색하게 한다.
Claude Code도 이런 접근에 가깝습니다. CLAUDE.md 같은 파일은 초기에 컨텍스트에 넣고, glob, grep 같은 도구를 통해 나머지 정보는 필요할 때 가져옵니다.
긴 작업을 위한 컨텍스트 엔지니어링
긴 작업에서는 문제가 더 어려워집니다. 코드베이스 마이그레이션, 대규모 리서치, 장시간 데이터 분석처럼 수십 분에서 몇 시간 이어지는 작업은 단일 컨텍스트 윈도우를 쉽게 초과합니다.
컨텍스트 윈도우가 더 커지기를 기다리는 것만으로는 충분하지 않습니다. 큰 컨텍스트 역시 오염과 관련성 저하 문제를 겪을 수 있기 때문입니다.
Anthropic은 장기 작업을 위한 대표적인 기법으로 세 가지를 소개합니다.
- 압축(compaction)
- 구조화된 노트 작성(structured note-taking)
- 서브에이전트 아키텍처(sub-agent architectures)
압축: 대화를 요약하고 새 컨텍스트로 이어가기
압축은 컨텍스트 윈도우가 한계에 가까워졌을 때, 기존 대화와 작업 내용을 요약한 뒤 새로운 컨텍스트에서 이어가는 방식입니다.
핵심은 단순히 짧게 줄이는 것이 아니라, 이후 작업에 필요한 정보를 고충실도로 보존하는 것입니다.
Claude Code에서는 메시지 히스토리를 모델에 전달해 핵심 내용을 요약·압축하게 합니다. 이때 보존해야 할 정보는 다음과 같습니다.
- 아키텍처 결정
- 아직 해결되지 않은 버그
- 구현 세부사항
- 작업 목표와 제약
- 최근 접근한 중요 파일
반대로 오래된 도구 호출 결과나 중복 출력은 제거할 수 있습니다.
압축의 어려움은 무엇을 남기고 무엇을 버릴지 결정하는 데 있습니다. 너무 공격적으로 압축하면, 나중에 중요해질 수 있는 미묘한 맥락이 사라질 수 있습니다.
따라서 압축 프롬프트를 설계할 때는 먼저 재현율을 높이는 것이 좋습니다. 즉, 중요한 정보가 빠지지 않도록 만든 뒤, 이후 불필요한 내용을 줄여 정밀도를 높여야 합니다.
가장 안전한 압축 중 하나는 오래된 도구 호출 결과를 제거하는 것입니다. 오래전에 호출한 도구의 원시 출력 전체를 계속 볼 필요는 없는 경우가 많기 때문입니다.
구조화된 노트 작성: 컨텍스트 밖의 기억
구조화된 노트 작성, 또는 에이전트 메모리는 에이전트가 작업 중 중요한 정보를 외부 저장소에 기록해두고, 나중에 필요할 때 다시 불러오는 방식입니다.
예를 들어 Claude Code가 할 일 목록을 만들거나, 커스텀 에이전트가 NOTES.md 파일을 유지하는 패턴이 여기에 해당합니다.
이 방식은 적은 컨텍스트 비용으로 장기 기억을 제공합니다. 복잡한 작업에서 진행 상황, 의존성, 결정 사항을 추적할 수 있고, 컨텍스트 리셋 이후에도 작업 흐름을 이어갈 수 있습니다.
Anthropic은 Claude가 포켓몬을 플레이한 사례도 언급합니다. 에이전트는 수천 단계에 걸쳐 훈련 목표, 탐험한 지역, 전투 전략, 달성한 목표를 기록했고, 컨텍스트가 초기화된 뒤에도 자신의 노트를 읽고 장기 전략을 이어갔습니다.
핵심은 모든 것을 컨텍스트에 계속 넣는 것이 아니라, 필요한 기억을 외부에 구조화해서 저장하는 것입니다.
서브에이전트: 큰 문제를 깨끗한 컨텍스트로 나누기
서브에이전트 아키텍처는 컨텍스트 한계를 우회하는 또 다른 방법입니다.
하나의 에이전트가 모든 상태를 계속 들고 가는 대신, 전문화된 서브에이전트들이 특정 작업을 깨끗한 컨텍스트에서 수행합니다. 메인 에이전트는 전체 계획과 조율에 집중하고, 서브에이전트는 깊은 탐색이나 기술 작업을 수행한 뒤 압축된 요약만 반환합니다.
이 방식의 장점은 관심사의 분리입니다.
- 서브에이전트는 많은 토큰을 사용해 깊이 탐색한다.
- 메인 에이전트는 그 세부 탐색 과정을 모두 보지 않는다.
- 대신 1,000~2,000토큰 정도의 정제된 요약만 받아 종합한다.
Anthropic은 멀티에이전트 리서치 시스템에서도 이 패턴이 복잡한 연구 작업에서 단일 에이전트보다 큰 개선을 보였다고 설명합니다.
각 방식은 쓰임이 다릅니다.
- 압축은 긴 대화 흐름을 유지해야 하는 작업에 적합합니다.
- 노트 작성은 명확한 마일스톤이 있는 반복 개발에 강합니다.
- 멀티에이전트 구조는 병렬 탐색이 이득을 주는 복잡한 리서치와 분석에 적합합니다.
실무적으로 얻을 수 있는 교훈
이 글의 핵심을 실무 관점에서 정리하면 다음과 같습니다.
첫째, 컨텍스트는 무료가 아닙니다. 컨텍스트 윈도우가 커져도 모델의 주의력은 여전히 제한되어 있습니다.
둘째, 좋은 에이전트는 많은 정보를 보는 에이전트가 아니라, 필요한 정보를 적절한 시점에 보는 에이전트입니다.
셋째, 시스템 프롬프트는 과도하게 세세한 규칙과 지나치게 추상적인 원칙 사이에서 균형을 잡아야 합니다.
넷째, 도구 설계는 컨텍스트 설계의 일부입니다. 도구가 모호하면 에이전트의 판단도 흔들립니다.
다섯째, 긴 작업에서는 압축, 메모리, 서브에이전트 같은 구조적 장치가 필요합니다.
마지막으로, 모델이 더 똑똑해질수록 인간이 모든 경로를 하드코딩하기보다 모델이 스스로 탐색하고 판단할 수 있는 단순한 구조를 제공하는 방향이 중요해질 가능성이 큽니다.
마무리
컨텍스트 엔지니어링은 LLM 기반 시스템을 만드는 방식의 중요한 전환점입니다.
좋은 프롬프트를 쓰는 것만으로는 충분하지 않습니다. 에이전트가 여러 번의 추론과 도구 사용을 반복하는 환경에서는, 매 순간 어떤 정보가 모델의 주의력 예산 안에 들어갈지 설계해야 합니다.
결국 원칙은 하나로 압축됩니다.
원하는 행동을 이끌어내는 데 필요한 최소한의 고신호 컨텍스트를 유지하라.
이 원칙은 프롬프트, 도구, 검색, 메모리, 압축, 멀티에이전트 구조 전반에 적용됩니다. 모델이 더 발전하더라도 컨텍스트를 귀한 자원으로 다루는 태도는 계속 중요할 것입니다.