서론

  • AI 에이전트의 한계는 모델의 크기뿐만 아니라 ‘컨텍스트 관리’라는 기술에도 달려 있습니다. 이는 CPU에 메모리를 배치하는 것과 같아, 에이전트의 사고 깊이와 효율성을 결정합니다.
  • 컨텍스트 윈도우는 쓰레기통이 아닙니다: 정보 과부하는 AI 판단에 ‘독을 주고’, 방해하며, 혼란을 일으킬 수 있습니다. 정확성이 대량보다 더 중요합니다.
  • 숙련된 사람은 ‘쓰기, 선별, 압축, 격리’의 네 가지 기술로 AI 컨텍스트를 관리하며, 한정된 ‘메모리’를 효율적으로 사용하여 비용 절감과 효율성을 동시에 이룩합니다.
  • 미래의 경쟁은 시스템 효율성에 대한 경쟁입니다. 다중 에이전트 구조를 통해 작업을 ‘격리’시키고, 각 에이전트가 자신의 작은 창에서 최선을 다할 수 있도록 하는 것이 복잡한 작업 시스템 구축의 핵심입니다.

핵심 요약

에이전트(Agent)는 작업 수행에 컨텍스트(Context)가 필수적입니다. ‘컨텍스트 엔지니어링’은 에이전트가 작업을 수행하는 모든 단계에서, 그들의 컨텍스트 윈도우에 적절한 정보를 정확하게 주입하는 기술과 과학의 예술입니다. 본문에서는 현재 주요 에이전트들이 채택하고 있는 컨텍스트 엔지니어링 전략을 몇 가지 일반적인 모드로 요약합니다.

컨텍스트 엔지니어링

컨텍스트 엔지니어링 (Context Engineering)

Andrej Karpathy가 말했듯이, 대형 언어 모델(LLM)은 일종의 ‘신형 운영 체제’와 같습니다. LLM은 CPU와 같고, 그 ‘컨텍스트 윈도우’는 RAM의 역할을 하여 모델의 작업 기억을 담당합니다. RAM의 용량이 한정된 것처럼, LLM의 컨텍스트 윈도우도 다양한 컨텍스트 출처를 처리할 때 용량의 병목현상에 직면합니다. 운영 체제의 핵심 작업 중 하나는 CPU의 RAM을 효율적으로 사용하는 방법을 관리하는 것이며, ‘컨텍스트 엔지니어링’도 비슷한 역할을 합니다. Karpathy는 이를 매우 잘 요약했습니다:

“컨텍스트 엔지니어링은 다음 단계(계산)에 정확히 맞는 컨텍스트 윈도우를 채우는 정교한 예술과 과학입니다.”

컨텍스트 엔지니어링

LLM 애플리케이션을 구축할 때 어떤 유형의 컨텍스트를 관리해야 할까요? ‘컨텍스트 엔지니어링’이라는 총괄 개념은 다음과 같은 다양한 컨텍스트 유형을 포함합니다:

  • 지시(Instructions) – 프롬프트, 기억, 소수 샘플 예시, 도구 설명 등
  • 지식(Knowledge) – 사실, 기억 등
  • 도구(Tools) – 도구 호출에 대한 피드백 정보

에이전트를 위한 컨텍스트 엔지니어링

올해 LLM이 추론과 도구 호출 능력에서 발전함에 따라, 에이전트에 대한 관심이 날로 증가하고 있습니다. 에이전트는 LLM과 도구를 교차적으로 호출하여 작업을 수행하며, 특히 장기간의 복잡한 작업을 처리하는 데 강점을 보입니다.

에이전트를 위한 컨텍스트 엔지니어링

하지만 장기 작업과 누적되는 도구 호출 피드백은 에이전트가 일반적으로 많은 수의 토큰을 소모하게 만듭니다. 이로 인해 여러 가지 문제가 발생할 수 있습니다: 컨텍스트 윈도우의 용량 제한 초과, 비용과 지연의 급증, 심지어는 에이전트 성능 저하까지. Drew Breunig는 지나치게 긴 컨텍스트가 성능 문제를 초래할 수 있는 몇 가지 방법을 명확하게 지적했습니다:

  • 컨텍스트 독성(Context Poisoning): 환각(잘못된 정보)이 컨텍스트에 포함될 때.
  • 컨텍스트 방해(Context Distraction): 컨텍스트 정보가 과도하게 많아 모델의 원래 훈련 지식을 압도할 때.
  • 컨텍스트 혼란(Context Confusion): 관련 없는 컨텍스트 정보가 모델의 응답에 영향을 미칠 때.
  • 컨텍스트 충돌(Context Clash): 컨텍스트의 서로 다른 부분이 상충할 때.

이러한 문제를 고려하여, Cognition AI는 컨텍스트 엔지니어링의 중요성을 강조했습니다:

“컨텍스트 엔지니어링”은 AI 에이전트를 구축하는 엔지니어에게 주된 과제입니다.

Anthropic 또한 명확하게 언급했습니다:

에이전트는 일반적으로 수백 차례의 대화를 수행해야 하므로, 신중한 컨텍스트 관리 전략이 필요합니다.

그렇다면 요즘의 개발자들은 이 도전에 어떻게 대응하고 있을까요? 저는 현재의 방법을 네 가지 범주로 요약했습니다 — 쓰기(Write), 선별(Select), 압축(Compress), 격리(Isolate) — 각 항목에 대한 예를 들어 설명하겠습니다.

메모리 유형

컨텍스트 쓰기 (Write Context)

컨텍스트 쓰기는 정보를 컨텍스트 윈도우 밖에 저장하여, 에이전트가 작업을 수행할 때 사용할 수 있도록 하는 것을 의미합니다.

임시 저장소(Scratchpads)

인간은 문제를 해결할 때 메모를 하거나 어떤 것을 기억해 두어, 나중에 관련 작업을 처리할 때 참고합니다. 에이전트도 이러한 능력을 점차 갖추고 있습니다! ‘임시 저장소’를 통해 메모를 하는 것은 에이전트가 작업 수행 중에 정보를 영구적으로 저장하는 방법입니다. 핵심 아이디어는 정보를 컨텍스트 윈도우 밖에 보관하되, 언제든지 에이전트가 접근할 수 있도록 하는 것입니다. Anthropic의 다중 에이전트 연구 시스템은 이를 명확하게 보여줍니다:

“수석 연구원”은 먼저 문제 해결 방법을 생각하고, 그것을 ‘기억’에 저장하여 컨텍스트를 영구화합니다. 왜냐하면 컨텍스트 윈도우가 20만 토큰을 초과하면 단절될 수 있기 때문에, 계획을 보존하는 것이 매우 중요합니다.

임시 저장소는 다양한 방식으로 구현될 수 있습니다. 단순한 도구 호출처럼 파일에 정보를 기록하거나, 실행 시 상태 객체의 필드로 유지하여 전체 세션 동안 변하지 않도록 할 수 있습니다. 어떤 방식이든 이 임시 저장소는 에이전트가 유용한 정보를 보존하여 작업을 보다 잘 수행할 수 있도록 합니다.

기억(Memories)

임시 저장소는 에이전트가 단일 세션에서 작업을 해결하는 데 도움이 되지만, 때때로 에이전트는 여러 세션에 걸쳐 일을 기억해야 할 필요가 있습니다. Reflexion 모델은 에이전트의 행동 후 반성하는 과정을 도입하고, 이러한 자가 생성된 기억을 재활용하는 개념을 제안했습니다. Generative Agents 모델은 과거 에이전트의 피드백 집합에서 주기적으로 기억을 합성할 수 있습니다.

이러한 개념은 ChatGPT, Cursor 및 Windsurf와 같은 인기 있는 제품에 적용되었습니다. 이들 모두는 사용자와 에이전트 간의 상호작용을 기반으로 자동으로 장기 기억을 생성하는 메커니즘을 갖추고 있습니다.

기억

컨텍스트 선별 (Select Context)

컨텍스트 선별은 필요한 정보를 컨텍스트 윈도우로 가져와 에이전트가 작업을 수행하는 데 도움을 주는 것입니다.

임시 저장소(Scratchpad)

임시 저장소에서 컨텍스트를 선별하는 메커니즘은 그 구현 방식에 따라 다릅니다. 만약 그것이 도구라면, 에이전트는 도구 호출을 통해 읽기만 하면 됩니다. 에이전트의 실행 상태의 일부라면, 개발자는 각 단계에서 상태의 일부를 선택적으로 에이전트에게 노출할 수 있습니다. 이는 후속 라운드에서 LLM에 임시 저장소의 컨텍스트를 제공하는 데 세밀한 제어를 제공합니다.

기억(Memories)

에이전트가 기억을 저장할 수 있는 능력이 있다면, 현재 작업과 관련된 기억을 선별할 수 있는 능력도 필요합니다. 이는 여러 이유로 매우 유용합니다: 에이전트는 소수 샘플 예시(상황 기억)를 선택하여 기대하는 행동 패턴을 학습할 수 있고; 지시(프로그램 기억)를 선택하여 자신의 행동을 안내할 수 있으며; 또는 사실(의미 기억)을 선택하여 작업에 관련된 배경을 제공할 수 있습니다.

null

주요 도전 과제는 선별된 기억이 관련성이 있는지를 보장하는 것입니다. 일부 인기 있는 에이전트는 항상 고정된 소량의 파일만 사용하여, 이 파일들은 항상 컨텍스트에 로드됩니다. 예를 들어, 많은 코드 에이전트는 지시 사항(“프로그램 기억”)을 저장하는 파일을 사용하거나, 경우에 따라 예시(“상황 기억”)를 저장합니다. Claude Code는 CLAUDE.md를 사용하고, Cursor와 Windsurf는 규칙 파일을 사용합니다.

하지만 에이전트가 많은 양의(예: “의미 기억” 유형의) 사실이나 관계를 저장하면, 선별이 더욱 어려워집니다. ChatGPT는 많은 사용자 전용 기억을 저장하고 그 중에서 선별하는 훌륭한 예시입니다.

벡터 임베딩 및/또는 지식 그래프는 선별을 돕기 위한 일반적인 기억 인덱스 기술입니다. 그럼에도 불구하고 기억 선별은 여전히 도전과제가 많습니다. AIEngineer 세계 박람회에서는 Simon Willison이 기억 선별에서의 오류 사례를 공유했습니다: ChatGPT는 그의 위치 정보를 기억에서 가져와, 그가 요청한 이미지에 원치 않게 삽입했습니다. 이러한 의도치 않거나 바람직하지 않은 기억 검색은 일부 사용자에게 컨텍스트 창이 “더 이상 자신에게 속하지 않는다”라는 느낌을 줄 수 있습니다!

도구(Tools)

에이전트는 도구를 사용할 필요가 있지만, 제공되는 도구가 너무 많은 경우, 에이전트는 과부하에 시달릴 수 있습니다. 이는 종종 도구 설명이 중복되어 어떤 도구를 선택할지 혼란스러워지기 때문입니다. 한 가지 방법은 도구 설명에 RAG(검증 강화 생성)를 적용하여, 의미의 유사성에 따라 가장 관련성이 높은 도구를 검색하는 것입니다. 최근의 몇몇 논문에서는 이러한 방법이 도구 선택의 정확도를 3배 향상할 수 있음을 보여주었습니다.

지식(Knowledge)

검색 강화 생성(RAG) 자체는 방대한 주제이며, 컨텍스트 엔지니어링의 핵심 도전이 될 수 있습니다. 코드 에이전트는 발전된 RAG의 대규모 실용 사례 중 하나입니다. Windsurf의 Varun은 이와 관련된 몇 가지 도전 과제를 잘 정리했습니다:

코드 인덱싱은 ≠ 컨텍스트 검색입니다… 우리가 하고 있는 것은 AST(추상 구문 트리)를 통해 코드를 분석하고 의미적으로 의미가 있는 경계에 따라 분할하는 것입니다… 하지만 코드 라이브러리의 규모가 커짐에 따라, 벡터 임베딩 검색이 검색의 열쇠 방법으로서 신뢰할 수 없게 됩니다… 우리는 grep/파일 검색, 지식 그래프 기반 검색 및 관련성을 기준으로 정렬하는 단계와 같은 여러 기술의 조합에 의존해야 합니다.

컨텍스트 압축 (Compress Context)

컨텍스트 압축은 작업 수행에 필요한 토큰만 남기는 것을 말합니다.

컨텍스트 요약 (Context Summarization)

에이전트의 상호작용은 수백 번에 걸쳐 진행될 수 있으며, 토큰을 많이 소비하는 도구를 사용할 수 있습니다. 요약은 이러한 도전 과제에 대응하는 일반적인 방법입니다. 만약 당신이 Claude Code를 사용해 본 적이 있다면, 그 실제 적용 사례를 이미 보았을 것입니다. 컨텍스트 윈도우의 사용율이 95%를 초과하면, Claude Code는 ‘자동 압축’을 실행하여 사용자와 에이전트 간의 전체 상호작용 경로를 요약합니다. 이러한 에이전트 경로의 압축은 여러 가지 전략으로 이루어질 수 있으며, 예를 들어 재귀적 요약이나 계층적 요약이 포함될 수 있습니다.

컨텍스트 요약

에이전트 설계에서 적절한 시점에 요약 단계를 포함하는 것도 유용합니다. 예를 들어, 특정 도구 호출(특히 많은 토큰을 소모하는 검색 도구 등)의 후처리에 사용되거나, Cognition 회사에서는 에이전트 간의 정보 전달 과정에서 요약을 수행하여 토큰 소모를 줄이는 방법을 제안했습니다. 특정 사건이나 결정을 포착해야 할 경우, 요약이 어려울 수 있습니다. Cognition은 이러한 이유로 미세 조정 모델을 사용하여 이 단계가 필요한 많은 작업을 강조했습니다.

컨텍스트 잘라내기 (Context Trimming)

요약은 일반적으로 LLM을 사용하여 가장 관련성 높은 컨텍스트 조각을 정리하는 반면, 잘라내기는 Drew Breunig가 언급한 것처럼 “전정(pruning)”으로 컨텍스트를 필터링하는 데 더 가깝습니다. 이는 메시지 목록에서 비교적 오래된 메시지를 제거하는 등 개발자의 하드코딩된 휴리스틱 규칙을 사용할 수 있습니다. Drew는 또한 Q&A 작업을 위해 훈련된 컨텍스트 잘라내기 도구인 Provence를 언급했습니다.

컨텍스트 격리 (Isolating Context)

컨텍스트 격리는 컨텍스트를 나누어 에이전트가 작업을 수행하는 데 도움을 주는 것입니다.

다중 에이전트 (Multi-agent)

컨텍스트 격리의 가장 대중적인 방법 중 하나는 이를 여러 하위 에이전트에 분산시키는 것입니다. OpenAI의 Swarm 라이브러리의 한 동기는 ‘집중점 분리’이며, 하나의 에이전트 팀이 하위 작업을 처리하도록 하는 것입니다. 각 에이전트는 자신만의 도구 세트, 지시 및 독립적인 컨텍스트 윈도우를 가집니다.

다중 에이전트

Anthropic의 다중 에이전트 연구 시스템은 이를 강력하게 입증합니다. 여러 독립적인 컨텍스트를 가진 에이전트들은 단일 에이전트보다 더 나은 성과를 내며, 이는 각 하위 에이전트의 컨텍스트 윈도우가 더 좁은 하위 작업에 집중할 수 있기 때문입니다. 블로그에서 언급된 바와 같이:

하위 에이전트들은 각자의 컨텍스트 윈도우를 가지고 병렬로 작업하며, 문제의 다양한 측면을 탐색합니다.

물론, 다중 에이전트는 도전 과제에 직면하기도 합니다. 예를 들어, token 소비 문제(Anthropic은 그들의 token 사용량이 대화의 15배에 달한다고 보고했음), 하위 에이전트 작업 계획을 위한 세심한 프롬프트 엔지니어링 필요성, 그리고 하위 에이전트 간의 조정 문제 등이 있습니다.

환경을 통한 컨텍스트 격리 (Context Isolation with Environments)

HuggingFace의 심층 연구원 프로젝트는 또 다른 흥미로운 컨텍스트 격리 사례를 보여줍니다. 대부분의 에이전트는 도구 호출 API를 사용하며, 이들 API는 JSON 객체(도구 매개변수)를 반환한 후, 도구(예: 검색 API)로 전달되어 피드백(예: 검색 결과)을 가져옵니다. 그러나 HuggingFace는 필요한 도구 호출을 포함하는 코드를 직접 출력하는 CodeAgent를 사용하고 있습니다. 이 코드들은 이후 샌드박스 환경에서 실행됩니다. 도구 호출에서 반환된 특정 컨텍스트(예: 반환 값)는 다시 LLM으로 전달됩니다.

환경을 통한 컨텍스트 격리

이로 인해 컨텍스트는 환경에서 LLM과 격리될 수 있습니다. Hugging Face는 이를 토큰을 대량으로 소비하는 객체를 격리하는 훌륭한 방법으로 제안합니다:

Code Agents는 상태를 더 잘 처리할 수 있습니다… 이미지를 저장해야 합니까? 문제없습니다. 변수를 할당하면 나중에 사용할 수 있습니다.

상태 (State)

특히 주목할 점은 에이전트의 실행 시 상태 객체 또한 컨텍스트 격리의 좋은 방법이라는 것입니다. 이는 샌드박스와 유사한 역할을 할 수 있습니다. 상태 객체는 컨텍스트에 쓸 수 있는 필드를 포함하는 패턴(Schema, 예: Pydantic 모델)을 설계하여, 에이전트의 각 상호작용 라운드에서 LLM에 노출할 수 있습니다. 하지만 이 패턴은 다른 필드에 정보를 격리하여 선택적으로 사용할 수 있도록 합니다.

결론

에이전트의 컨텍스트 엔지니어링 패턴은 지속적으로 진화하고 있지만, 우리가 흔히 접하는 방법은 네 가지 범주—쓰기, 선별, 압축, 격리—로 요약할 수 있습니다:

  • • 컨텍스트 쓰기: 정보를 컨텍스트 윈도우 밖에 저장하여, 에이전트가 작업을 수행할 때 사용할 수 있도록 하는 것.
  • • 컨텍스트 선별: 필요한 정보를 컨텍스트 윈도우로 가져와 에이전트가 작업을 수행하는 데 도움을 주는 것.
  • • 컨텍스트 압축: 작업 수행에 필요한 토큰만 남기는 것.
  • • 컨텍스트 격리: 컨텍스트를 나누어 에이전트가 작업을 수행하는 데 도움을 주는 것.

이러한 패턴을 이해하고 적용하는 것은 현재 효율적인 에이전트를 구축하는 핵심 작업입니다.