Unrolling the Codex agent loop
핵심 포인트
- 1Codex CLI는 사용자, LLM 및 도구 간의 상호작용을 조율하여 고품질 소프트웨어 변경을 수행하는 OpenAI의 로컬 소프트웨어 에이전트이며, 그 핵심은 "agent loop"입니다.
- 2이 agent loop는 사용자 입력으로 프롬프트를 구성하고, 모델 추론을 통해 응답을 생성하거나 tool call을 요청하며, tool call의 결과를 프롬프트에 추가하여 모델에 재질의하는 반복적인 과정으로 작동합니다.
- 3효율성을 위해 이전 대화 내역이 프롬프트에 포함되어 길어지는 문제를 해결하고자 프롬프트 캐싱을 통한 성능 최적화를 시도하고, context window 초과 시에는 대화 압축(compaction) 기능을 사용하여 관리합니다.
이 논문은 OpenAI의 cross-platform local software agent인 Codex CLI의 핵심 로직인 agent loop를 상세히 설명합니다. agent loop는 사용자, large language model (LLM), 그리고 모델이 소프트웨어 작업을 수행하기 위해 호출하는 tool들 사이의 상호작용을 오케스트레이션하는 역할을 합니다. 본 논문은 agent loop의 작동 방식과 이와 관련된 핵심 기술적 고려사항들을 깊이 있게 다룹니다.
Agent Loop의 핵심 개념 및 동작 방식:
agent loop는 사용자 입력으로부터 시작하여 모델의 응답으로 종료되는 순환 과정입니다. 이 과정은 다음과 같은 주요 단계로 구성됩니다:
- 프롬프트 준비 (Prompt Preparation):
- Agent는 사용자 입력을 포함하여 모델에게 전달할
textual instructions인prompt를 구성합니다.
- Agent는 사용자 입력을 포함하여 모델에게 전달할
- 추론 (Inference):
- 구성된
prompt는 모델에 전송되어inference를 수행합니다. - 이때
prompt는input tokens으로 변환되고, 모델은 이를 바탕으로output tokens을 생성하며, 이들은 다시text형태의 모델 응답으로 변환됩니다.Streaming output이 지원됩니다.
- 구성된
- 모델 응답 처리 및 Tool 호출:
- 모델의 응답은 두 가지 경우 중 하나입니다:
- 최종 응답 (Final Response): 모델이 사용자에게 직접적인
assistant message를 생성하면, agent는 작업을 완료하고 제어권이 사용자에게 반환됩니다. - Tool 호출 요청 (Tool Call Request): 모델이 특정
tool의 실행을 요청하는 경우 (예: "run ls and report the output"), agent는 해당tool을 실행합니다.tool실행의 결과는 원래prompt에 추가되어 새로운 입력으로 사용되며, 모델은 이 정보를 바탕으로 다시 질의됩니다. 이 과정은 모델이tool호출을 중단하고 최종assistant message를 생성할 때까지 반복됩니다.
- 최종 응답 (Final Response): 모델이 사용자에게 직접적인
- Software agent의 경우,
tool실행을 통해 로컬 환경을 수정할 수 있으므로, 최종 산출물은assistant message에만 국한되지 않고 실제code의 작성 또는 편집일 수 있습니다.
- 모델의 응답은 두 가지 경우 중 하나입니다:
대화 턴(Conversation Turn)과 Context Management:
- 사용자 입력부터 agent 응답까지의 전체 과정을
turn또는thread라고 부르며, 단일turn내에서 여러 번의inference및tool call반복이 발생할 수 있습니다. - 새로운 대화
turn이 시작될 때, 이전 대화의message와tool call을 포함한conversation history전체가prompt의 일부로 포함됩니다. 이는 모델이 이전 대화의 맥락을 이해하도록 돕습니다. Context Window제한: 모든 LLM은context window라는 최대 토큰 길이를 가지며, 이는input과output토큰을 모두 포함합니다. 대화가 길어질수록prompt의 길이가 증가하여context window를 초과할 위험이 있습니다.context window관리는agent의 핵심 책임 중 하나입니다.
Responses API를 통한 모델 추론:
Codex CLI는 Responses API에 HTTP 요청을 전송하여 모델 추론을 수행합니다. Responses API endpoint는 구성 가능하며, ChatGPT login, OpenAI hosted models (API key), 또는 Ollama/LM Studio를 사용하는 로컬 LLM (--oss 플래그) 등 다양한 환경에서 사용할 수 있습니다.
초기 프롬프트 구성 (Building the Initial Prompt):
Codex는 Responses API에 전송되는 JSON payload의 일부로 prompt를 구성합니다. 사용자가 prompt를 직접 명시하는 대신, Responses API는 여러 입력 유형을 조합하여 모델이 소비하도록 설계된 prompt 구조를 결정합니다.
- Prompt Role:
prompt의 각 항목은role과 연관되며,system,developer,user,assistant순으로 우선순위가 높습니다. - JSON Payload의 주요 파라미터:
instructions:system또는developer메시지로, 모델의 초기 컨텍스트를 제공합니다.model_instructions_file이나 모델별base_instructions에서 가져옵니다.tools: 모델이 호출할 수 있는tool정의 목록입니다. 여기에는 Codex CLI 내장shell,update_plantool뿐만 아니라Responses API가 제공하는web_searchtool, 그리고 사용자가 구성한MCP (Model-Controller-Program) servers를 통한tool(예: 날씨 정보tool)이 포함됩니다. 각tool은name,description,parameters(JSON schema)를 가집니다.input:message목록으로,text,image,file등 다양한 유형의content를 포함할 수 있습니다. Codex는 사용자 메시지를 추가하기 전에 다음과 같은 항목들을input에 삽입합니다:- 메시지 (샌드박스 설명, 파일 권한, 네트워크 접근, 쓰기 가능한 폴더 목록 포함).
- (선택 사항)
config.toml의developer_instructions( 메시지). - (선택 사항)
user instructions( 메시지,AGENTS.override.md,AGENTS.md,project_doc_fallback_filenames,skills관련 정보 포함). - 메시지 (현재 작업 환경 설명:
cwd,shell).
- 이러한 항목들은 JSON object 형태로
type,role,content필드를 가집니다.
첫 번째 Turn과 대화 연속 (The First Turn & Continuing the Conversation):
Responses API에 대한 HTTP POST 요청은 대화의 첫 번째turn을 시작합니다.- 서버는
Server-Sent Events (SSE)스트림으로 응답하며,response.reasoning_summary_text.delta,response.output_item.added,response.output_text.delta등의 이벤트 타입을 포함합니다. - Codex는 이 이벤트 스트림을 소비하여 내부 이벤트 객체로 재발행합니다.
response.output_text.delta는 UI 스트리밍을 지원하며,response.output_item.added와 같은 이벤트는 다음Responses API호출을 위한input에 추가됩니다. tool call이 발생하면,reasoning과function_call이벤트가input배열에 추가되고,function_call_output도 뒤이어 추가됩니다. 이는 이전prompt가 새prompt의 정확한prefix가 되도록 하여prompt caching을 가능하게 합니다.- 모델이 최종
assistant message를 생성하면turn이 종료됩니다. - 새로운
turn이 시작될 때, 이전turn의assistant message와 새로운 사용자 메시지가input에 추가되어conversation history가 계속 확장됩니다.
성능 고려 사항 (Performance Considerations):
- 선형적인 Cost를 위한 Prompt Caching: 대화가 진행됨에 따라
prompt의 길이가 증가하는 것은 이론적으로quadratic한 비용을 발생시킬 수 있습니다. 그러나prompt caching을 통해cache hit가 발생하는 경우, 모델 샘플링 비용은linear하게 유지됩니다.Cache hit는prompt내에서 정확한prefix matches에 대해서만 가능합니다. 이를 위해instructions나examples와 같은static content는prompt의 시작 부분에,user-specific information과 같은variable content는 끝 부분에 배치됩니다.image나tool도 요청 간에 동일해야 합니다.
- Cache Miss를 유발하는 작업:
- 대화 중 모델에 사용 가능한
tool변경. Responses API요청의target model변경.Sandbox configuration,approval mode,current working directory변경.
- 대화 중 모델에 사용 가능한
- Cache Hit 유지 전략: Codex 팀은
prompt caching을 최적화하기 위해 노력합니다. 예를 들어,MCP tool구현 시tool목록의 일관되지 않은 순서가cache miss를 유발했던 버그를 수정했습니다. 대화 중간에 발생하는configuration change는 기존 메시지를 수정하는 대신 새로운 메시지를input에 추가하는 방식으로 처리됩니다 (예:sandbox configuration이나approval mode변경 시 새로운 메시지 삽입,cwd변경 시 새로운 메시지 삽입). - Zero Data Retention (ZDR):
Responses API는previous_response_id파라미터를 지원하여quadratic문제를 완화할 수 있지만, Codex는 요청의stateless유지와ZDR configuration지원을 위해 현재 이 파라미터를 사용하지 않습니다.ZDR고객은encrypted_content를 통해 이전turn의proprietary reasoning messages로부터 이점을 얻을 수 있습니다.
Context Window 관리 (Context Window Management):
context window소진을 피하기 위한 일반적인 전략은token수가 특정 임계값을 초과할 때 대화를compact하는 것입니다.- 초기
compaction구현은 사용자가/compact명령을 수동으로 호출하여 요약을 위한custom instructions와 함께Responses API를 질의하는 방식이었습니다. - 현재는
Responses API의/responses/compactendpoint가compaction을 더 효율적으로 수행합니다. 이endpoint는 의encrypted_content를 포함하는item목록을 반환하여, 모델의 원래 대화에 대한latent understanding을 유지하면서input을 대체하여context window를 확보합니다. - Codex는
auto_compact_limit을 초과하면 이endpoint를 자동으로 사용하여compaction을 수행합니다.
이러한 agent loop의 상세한 메커니즘과 성능 최적화, context 관리 전략은 Codex CLI가 고품질의 안정적인 소프트웨어 변경을 안전하고 효율적으로 수행하는 데 기반이 됩니다.