컨텍스트 엔지니어링
컨텍스트 엔지니어링 (Context engineering · Deep Agents)
컨텍스트 엔지니어링은 내 딥 에이전트가 작업을 안정적으로 완료할 수 있도록 올바른 정보와 도구를 올바른 형식으로 제공하는 일이에요. 딥 에이전트는 여러 종류의 컨텍스트에 접근할 수 있는데, 일부는 시작 시점에 제공되고 일부는 실행 중(사용자 입력 등)에 생겨요. 딥 에이전트에는 장기 실행 세션에서 컨텍스트를 관리하는 내장 메커니즘이 있어요.
출처: 공식문서
컨텍스트의 종류
| 컨텍스트 유형 | 무엇을 제어하나 | 범위 |
|---|---|---|
| 입력 컨텍스트(Input context) | 시작 시 에이전트 프롬프트에 들어가는 것(시스템 프롬프트, 메모리, 스킬) | 정적, 각 실행에 적용 |
| 런타임 컨텍스트(Runtime context) | invoke 시 전달되는 정적 설정(사용자 메타데이터, API 키, 연결) | 실행별, 서브에이전트로 전파 |
| 컨텍스트 압축(Context compression) | 창 한도 내 유지를 위한 내장 오프로딩·요약 | 한도에 근접하면 자동 |
| 컨텍스트 격리(Context isolation) | 서브에이전트로 무거운 작업 격리, 결과만 메인 에이전트로 반환 | 위임될 때 서브에이전트별 |
| 장기 메모리(Long-term memory) | 가상 파일시스템으로 스레드 간 영속 저장 | 대화 간 영속 |
입력 컨텍스트 (Input context)
입력 컨텍스트는 시작 시 에이전트에 제공되어 시스템 프롬프트가 되는 정보예요. 최종 프롬프트는 여러 원천으로 구성돼요:
- 시스템 프롬프트: 내가 제공한 커스텀 지침 + 내장 에이전트 가이드
- 메모리: 설정 시 항상 로드되는 영속
AGENTS.md파일 - 스킬(Skills): 관련 있을 때 로드되는 온디맨드 능력(점진적 공개, progressive disclosure)
- 도구 프롬프트(Tool prompts): 내장·커스텀 도구 사용 지침
시스템 프롬프트
커스텀 시스템 프롬프트는 내장 시스템 프롬프트(파일시스템 도구·서브에이전트 가이드 포함) 앞에 붙어요. 에이전트의 역할·행동·지식을 정의하는 데 써요.
from deepagents import create_deep_agent
agent = create_deep_agent(
model="openai:gpt-5.5",
system_prompt=(
"You are a research assistant specializing in scientific literature. "
"Always cite sources. Use subagents for parallel research on different topics."
),
)
system_prompt 파라미터는 정적이라 호출마다 바뀌지 않아요. 동적 프롬프트가 필요하면(예: "admin access" vs "read-only access", 장기 메모리의 사용자 선호 삽입) @dynamic_prompt을 써서 컨텍스트 인식 지침을 만들 수 있어요. 미들웨어는 request.runtime.context와 request.runtime.store를 읽을 수 있어요. 도구만 컨텍스트·runtime.store를 쓰면 미들웨어가 필요 없고(도구가 ToolRuntime을 받아요), 시스템 프롬프트 업데이트와 함께 도구를 묶어야 할 때만 미들웨어를 추가하세요. 특정 공급자/모델에 맞추려면 harness profile의 base_system_prompt(기본 프롬프트 대체)와 system_prompt_suffix(뒤에 추가)를 써요.
메모리 (Memory)
메모리 파일(AGENTS.md)은 시스템 프롬프트에 항상 로드되는 영속 컨텍스트예요. 프로젝트 규칙, 사용자 선호, 모든 대화에 적용되어야 할 중요 지침에 사용해요.
agent = create_deep_agent(
model="openai:gpt-5.5",
memory=["/project/AGENTS.md", "~/.deepagents/preferences.md"],
)
스킬과 달리 메모리는 점진적 공개 없이 항상 주입돼요. 컨텍스트 과부하를 막으려면 메모리를 최소로 유지하고, 상세 워크플로·도메인 콘텐츠는 스킬로 옮기세요.
스킬 (Skills)
스킬은 온디맨드 능력을 제공해요. 에이전트가 시작 시 각 SKILL.md의 frontmatter를 읽고, 관련 있다고 판단될 때만 전체 스킬 콘텐츠를 로드해요. 토큰 사용을 줄이면서도 전문 워크플로를 제공해요.
agent = create_deep_agent(model="openai:gpt-5.5", skills=["/skills/"])
각 스킬은 단일 워크플로/도메인에 집중시키고, 상세 레퍼런스는 별도 파일로 옮기며, 항상 관련된 규칙은 메모리에 넣으세요.
도구 프롬프트 (Tool prompts)
도구 프롬프트는 모델이 도구를 어떻게 쓰는지 정형화하는 지침이에요. tools 파라미터로 넘긴 도구는 스키마·설명 메타데이터를 모델에 노출해요. 내장 도구는 Deep Agents 스택에 패키징되어 시스템 프롬프트에 도구 지침을 추가하는데, 파일시스템 프롬프트(ls, read_file, write_file, edit_file, delete, glob, grep, 샌드박스 백엔드 시 execute), 서브에이전트 프롬프트(task 도구), HITL 프롬프트(interrupt_on 설정 시), 로컬 컨텍스트 프롬프트(CLI만)가 있어요.
제공하는 도구에 대해 이름·설명·인자 설명을 명확히 쓰세요. @tool(parse_docstring=True) 데코레이터로 docstring을 파싱해 설명을 만들 수 있어요. unused 내장 도구는 매 턴마다 전체 스키마를 보내므로, excluded_tools로 에이전트가 절대 호출하지 않을 도구(예: read-only 에이전트의 write_file·execute)를 제거해 기본 프롬프트 크기를 줄여요.
완전한 시스템 프롬프트
에이전트가 실행 시작 시 받는 어셈블된 시스템 메시지는 다음으로 구성돼요: 커스텀 system_prompt → 기본 에이전트 프롬프트 → 메모리 프롬프트(AGENTS.md + 사용법, 메모리 제공 시) → 스킬 프롬프트(스킬 제공 시) → 가상 파일시스템 프롬프트 → 서브에이전트 프롬프트(task 도구 사용법) → 사용자 제공 미들웨어 프롬프트 → HITL 프롬프트(interrupt_on 설정 시).
런타임 컨텍스트 (Runtime context)
런타임 컨텍스트는 invoke 시 전달하는 실행별 설정이에요. 모델 프롬프트에 자동 포함되지 않고, 도구·미들웨어·로직이 읽어 메시지나 시스템 프롬프트에 추가할 때만 모델이 보게 돼요. 사용자 메타데이터(ID, 선호, 역할), API 키, DB 연결, 피처 플래그 등에 사용해요.
데이터 형태를 context_schema로 정의해요: dataclasses.dataclass 또는 typing.TypedDict 클래스. invoke/ainvoke의 context 인자로 값을 전달해요. 도구 내부에서는 주입된 ToolRuntime에서 runtime.context로 읽어요.
from dataclasses import dataclass
from deepagents import create_deep_agent
from langchain.tools import ToolRuntime, tool
@dataclass
class Context:
user_id: str
api_key: str
@tool
def fetch_user_data(query: str, runtime: ToolRuntime[Context]) -> str:
'Fetch data for the current user.'
user_id = runtime.context.user_id
return f"Data for user {user_id}: {query}"
agent = create_deep_agent(
model="openai:gpt-5.5", tools=[fetch_user_data], context_schema=Context,
)
result = agent.invoke(
{"messages": [{"role":"user","content":"Get my recent activity"}]},
context=Context(user_id="user-123", api_key="sk-..."),
)
런타임 컨텍스트는 모든 서브에이전트로 전파돼요. 서브에이전트는 부모와 같은 런타임 컨텍스트를 받아요.
커스텀 상태 스키마 (Custom state schema)
커스텀 상태 스키마는 deepagents>=0.6.6이 필요해요. 에이전트·미들웨어가 전체 실행 라이프사이클에 걸쳐 지속되고 체크포인팅에서 살아남아야 하는 데이터를 추적할 때 사용해요. 전체 실행에 걸친 상태 추적, 도구·미들웨어 간 데이터 공유, rate limiting·사용 추적·감사 로깅 같은 횡단 관심사 구현, invoke 시 초기 값 시딩이 가능해요.
state_schema를 쓰세요. 커스텀 상태 스키마는 DeepAgentState를 상속해야 해요. 이로써 messages에 내장 DeltaChannel reducer를 보존해, 대화가 길어져도 체크포인트 성장이 선형으로 유지돼요. immutable한 실행별 입력(ID, 크레덴셜, 피처 플래그)은 런타임 컨텍스트를 선호하세요.
from deepagents import DeepAgentState, create_deep_agent
from langchain.tools import ToolRuntime, tool
class ResearchState(DeepAgentState):
page_url: str
file_urls: list[str]
@tool
def cite_page(runtime: ToolRuntime) -> str:
'Return the current page URL.'
return runtime.state["page_url"]
agent = create_deep_agent(
model="openai:gpt-5.5", tools=[cite_page], state_schema=ResearchState,
)
result = agent.invoke(
{"messages":[{"role":"user","content":"Cite the current page"}],
"page_url":"https://example.com/report","file_urls":[]},
)
스키마는 미들웨어가 기여한 상태 스키마와 병합돼요. 선언적 SubAgent 스펙(subagents=로 전달)은 Deep Agents가 task 도구용으로 컴파일할 때 부모 state_schema를 상속해요. 그러나 CompiledSubAgent runnable과 원격 AsyncSubAgent 스펙은 그래프가 이미 컴파일·호스팅되어 있어 상속하지 않아요.
컨텍스트 압축 (Context compression)
모든 create_deep_agent 호출에는 내장 컨텍스트 압축이 포함돼요. 오프로딩·요약용 미들웨어를 따로 추가할 필요 없어요. 장기 실행 작업은 큰 도구 출력과 긴 대화 이력을 만들고, 컨텍스트 압축은 작업에 관련된 세부 정보를 보존하면서 에이전트 작업 메모리의 정보를 줄여요.
- 오프로딩(Offloading): 큰 도구 입력·결과를 파일시스템에 저장하고 참조로 대체.
- 요약(Summarization): 한도에 근접하면 오래된 메시지를 LLM 생성 요약으로 압축.
오프로딩
Deep Agents는 내장 파일시스템 도구로 콘텐츠를 자동 오프로딩하고 필요 시 검색·검색합니다. 도구 호출 입력·결과가 토큰 임계값(기본 20,000)을 초과하면 오프로딩이 일어나요.
- 입력이 20,000 토큰 초과: 세션 컨텍스트가 모델 창의 85%를 넘으면 딥 에이전트가 오래된 도구 호출을 잘라내고 디스크 파일 포인터로 대체.
- 결과가 20,000 토큰 초과: 응답을 설정된 백엔드로 오프로딩하고 파일 경로 참조 + 첫 10줄 미리보기로 대체.
주의: 내장 컨텍스트 압축은 이미지 크기 조정, 해상도 저하, 시각 임베딩 생성은 하지 않아요. 멀티모달 입력·도구 출력·압축은 Multimodal 문서를 참고하세요.
요약
SummarizationMiddleware가 bare stack에 포함돼요. 컨텍스트 크기가 모델 컨텍스트 창 한도(예: max_input_tokens의 85%)를 넘고 오프로딩할 컨텍스트가 더 없으면 메시지 이력을 자동 요약해요. 두 구성 요소가 있어요.
- In-context summary: 세션 의도, 생성된 아티팩트, 다음 단계를 포함한 구조화 요약 생성 → 작업 메모리의 전체 대화 이력 대체
- Filesystem preservation: 원본 대화 메시지의 텍스트 렌더링을 canonical 레코드로 파일시스템에 기록
설정: 모델 프로파일의 max_input_tokens 85%에서 트리거, 최근 컨텍스트로 토큰의 10% 유지, 프로파일 없으면 170,000 토큰 트리거·6개 메시지 유지로 폴백. ContextOverflowError가 발생하면 즉시 요약 폴백 후 요약+최근 보존 메시지로 재시도. 스트리밍 토큰에 메타데이터 lc_source == "summarization"으로 요약 단계 토큰을 필터링할 수 있어요.
온디맨드 압축 도구: 기본적으로 자동 요약이 임계값에서 실행돼요. 별도로 compact_conversation 도구를 create_summarization_tool_middleware(model, backend)로 활성화해 85%를 기다리지 않고 임의 시점(예: 작업 사이)에 압축을 트리거할 수 있어요.
서브에이전트로 컨텍스트 격리
서브에이전트는 컨텍스트 블로트 문제를 해결해요. 메인 에이전트가 큰 출력의 도구(웹 검색, 파일 읽기, DB 쿼리)를 쓰면 컨텍스트 창이 빨리 차요. 서브에이전트는 이 작업을 격리해서 메인 에이전트는 최종 결과만 받고, 수십 개의 도구 호출은 받지 않아요.
동작: 메인 에이전트가 task 도구로 위임 → 서브에이전트가 자체 신선한 컨텍스트로 실행 → 완료까지 자율 실행 → 단일 최종 보고서를 메인 에이전트로 반환 → 메인 에이전트 컨텍스트는 깨끗하게 유지.
research_subagent = {
"name": "researcher",
"description": "Conducts research on a topic",
"system_prompt": "You are a research assistant. "
"IMPORTANT: Return only the essential summary (under 500 words). "
"Do NOT include raw search results or detailed tool outputs.",
"tools": [web_search],
}
모범 사례: 복잡한 작업 위임, 서브에이전트 응답을 요약으로 지시(원시 데이터 금지), 큰 데이터는 파일시스템 사용.
장기 메모리 (Long-term memory)
기본 파일시스템 사용 시 딥 에이전트는 작업 메모리를 스레드 안에서만 유지되는 에이전트 상태에 저장해요. 장기 메모리는 스레드와 대화를 넘어 정보를 영속화하게 해줘요. CompositeBackend로 특정 경로(보통 /memories/)를 LangGraph Store로 라우팅하여 내구성 있는 크로스-스레드 영속을 얻어요. CompositeBackend는 일부 파일은 무기한, 일부는 단일 스레드에 국한되는 하이브리드 저장 시스템이에요.
from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
from langgraph.store.memory import InMemoryStore
store = InMemoryStore()
agent = create_deep_agent(
model="openai:gpt-5.5",
store=store,
backend=CompositeBackend(
default=StateBackend(),
routes={"/memories/": StoreBackend(namespace=lambda _rt: ("memories",))},
),
system_prompt="When users tell you their preferences, save them to "
"/memories/user_preferences.txt so you remember them in future conversations.",
)
/memories/를 미리 채울 필요는 없어요. 백엔드 설정, 스토어, 시스템 프롬프트 지침을 제공하면 에이전트가 write_file·edit_file로 파일을 생성해요. LangSmith에 배포할 때 Store API로 메모리를 시딩할 수 있어요.
모범 사례
- 올바른 입력 컨텍스트로 시작: 항상 관련 규칙은 메모리 최소화, 작업별 능력은 집중된 스킬로.
- 무거운 작업엔 서브에이전트 활용: 메인 에이전트 컨텍스트를 깨끗이 유지.
- 서브에이전트 출력 조정:
system_prompt로 요약·종합 지시. - 파일시스템 활용: 큰 출력을 파일로 영속화, 필요 시
read_file·grep으로 조각 로드. - 장기 메모리 구조 문서화:
/memories/에 무엇이 있는지 에이전트에 알리기. - 도구용 런타임 컨텍스트 전달: 사용자 메타데이터, API 키, 정적 설정에
context사용.
더 알아보기 (Learn more)
- Multimodal - 이미지·오디오·비디오·멀티모달 도구 출력
- Subagents - 컨텍스트 격리와 런타임 컨텍스트 전파
- Backends - 파일시스템 백엔드와 CompositeBackend