메인 콘텐츠로 건너뛰기
OpenAI

2026년 1월 23일

엔지니어링

Codex 에이전트 루프 풀어보기

Michael Bolin, 기술 스태프 멤버

로딩 중...

Codex CLI(새 창에서 열기)는 크로스 플랫폼 로컬 소프트웨어 에이전트로, 사용자의 장치에서 안전하고 효율적으로 작동하면서도 고품질의 신뢰할 수 있는 소프트웨어 변경을 만들어내도록 설계되었습니다. 4월에 CLI를 처음 출시한 이후, 세계 수준의 소프트웨어 에이전트를 만드는 방법에 대해 정말 많은 것을 배웠습니다. 이러한 인사이트를 풀어보기 위해, 이번 글은 Codex가 어떻게 작동하는지에 대한 다양한 측면과 그 과정에서 얻은 값진 교훈들을 살펴보는 연재 시리즈의 첫 번째 글입니다. Codex CLI가 어떻게 구축되었는지를 더 세부적으로 살펴보고 싶다면 https://github.com/openai/codex(새 창에서 열기)에 있는 오픈 소스 리포지토리를 확인하세요. 설계 결정의 많은 세부 사항이 GitHub 이슈와 풀 리퀘스트에 기록되어 있으니, 더 알고 싶다면 참고하셔도 좋습니다.)

먼저, Codex CLI의 핵심 로직인 에이전트 루프에 초점을 맞추겠습니다. 에이전트 루프는 사용자가 모델과 상호작용하고, 모델이 의미 있는 소프트웨어 작업을 수행하기 위해 호출하는 툴을 오케스트레이션하는 역할을 합니다. 이 글이 LLM을 활용하는 과정에서 에이전트(또는 ‘하네스’)가 어떤 역할을 하는지 이해하는 데 도움이 되길 바랍니다.

본격적으로 들어가기 전에 용어를 간단히 정리하겠습니다. OpenAI에서 ‘Codex’는 Codex CLI, Codex Cloud, Codex VS Code 확장을 포함하는 소프트웨어 에이전트 제품군 전체를 의미합니다. 이 글은 모든 Codex 경험의 기반이 되는 핵심 에이전트 루프와 실행 로직을 제공하는 Codex 하네스에 초점을 맞추며, 이는 Codex CLI를 통해 제공됩니다. 편의를 위해 여기서는 ‘Codex’와 ‘Codex CLI’를 같은 의미로 사용하겠습니다.

에이전트 루프

모든 AI 에이전트의 중심에는 ‘에이전트 루프’라고 불리는 개념이 있습니다. 에이전트 루프를 단순화해 표현하면 다음과 같습니다.

AI 시스템이 사용자 요청을 처리하고, 툴을 호출하며, 결과를 관찰하고, 계획을 업데이트한 뒤 결과를 반환하는 과정을 보여주는 “Agent loop”라는 제목의 다이어그램 화살표는 사용자 입력, 모델의 추론, 툴 동작, 최종 응답과 같은 단계를 연결합니다.

먼저 에이전트는 사용자로부터 입력을 받아, 모델에 전달할 텍스트 지시 집합인 프롬프트에 포함시킵니다.

다음 단계는 모델에 지시를 전달하고 응답 생성을 요청하는 것으로, 이를 추론이라고 합니다. 추론 과정에서 텍스트 프롬프트는 먼저 입력 토큰(새 창에서 열기)의 시퀀스로 변환되는데, 이 토큰은 모델 어휘를 가리키는 정수 값입니다. 이 토큰들을 사용해 모델을 샘플링하고, 새로운 출력 토큰 시퀀스를 생성합니다.

출력 토큰은 다시 텍스트로 변환되며, 이것이 모델의 응답이 됩니다. 토큰은 점진적으로 생성되기 때문에, 모델이 실행되는 동안 변환이 이루어질 수 있으며, 이것이 많은 LLM 기반 애플리케이션이 스트리밍 출력을 보여주는 이유입니다. 실제 사용에서는 추론이 텍스트 단위로 동작하는 API 뒤에 캡슐화되어, 토큰화와 같은 세부 사항은 추상화됩니다.

추론 단계의 결과로 모델은 (1) 사용자의 원래 입력에 대한 최종 응답을 생성하거나, (2) 에이전트가 수행해야 하는 툴 호출을 요청합니다(예: “ls를 실행하고 출력 결과를 보고하세요”). (2)의 경우 에이전트는 툴 호출을 실행하고, 그 결과를 원래 프롬프트에 추가합니다. 이 출력은 모델을 다시 질의하기 위한 새로운 입력을 생성하는 데 사용되며, 에이전트는 이 새로운 정보를 반영해 다시 시도할 수 있습니다.

이 과정은 모델이 더 이상 툴 호출을 생성하지 않고 사용자에게 메시지를 생성할 때까지 반복됩니다(OpenAI 모델에서는 이를 어시스턴트 메시지라고 부릅니다). 대부분의 경우 이 메시지는 사용자의 원래 요청에 직접 답하지만, 추가 질문일 수도 있습니다.

에이전트는 로컬 환경을 변경하는 툴 호출을 실행할 수 있기 때문에, 그 ‘출력’은 어시스턴트 메시지에만 국한되지 않습니다. 많은 경우 소프트웨어 에이전트의 주요 출력은 사용자의 장치에 작성하거나 수정한 코드입니다. 그럼에도 불구하고 각 턴은 항상 ‘요청하신 architecture.md를 추가했습니다’와 같은 어시스턴트 메시지로 끝나며, 이는 에이전트 루프에서의 종료 상태를 의미합니다. 에이전트의 관점에서는 작업이 완료되고 제어권이 사용자에게 돌아갑니다.

다이어그램에 표시된 사용자 입력에서 에이전트 응답까지의 흐름은 대화의 하나의 (Codex에서는 스레드 )이라고 부릅니다. 하지만 이 대화 턴에는 모델 추론툴 호출 사이의 여러 번의 반복이 포함될 수 있습니다. 기존 대화에 새 메시지를 보낼 때마다, 이전 턴의 메시지와 툴 호출을 포함한 대화 기록 전체가 새로운 턴의 프롬프트에 포함됩니다.

AI 에이전트가 사용자 입력을 반복적으로 받아 행동을 생성하고, 툴을 활용해 상태를 업데이트한 뒤 결과를 반환하는 과정을 보여주는 “Multi-turn agent loop”라는 제목의 다이어그램 에이전트의 추론 사이클을 설명하기 위해 단계 레이블, 화살표, 그리고 예시 툴 출력이 포함되어 있습니다.

즉, 대화가 길어질수록 모델을 샘플링하는 데 사용되는 프롬프트의 길이도 함께 늘어납니다. 이 길이는 중요합니다. 모든 모델에는 한 번의 추론 호출에서 사용할 수 있는 최대 토큰 수인 컨텍스트 윈도우가 있기 때문입니다. 이 컨텍스트 윈도우에는 입력 토큰 출력 토큰이 모두 포함됩니다. 짐작할 수 있듯이, 에이전트는 하나의 턴 안에서 수백 번의 툴 호출을 수행하기로 결정할 수도 있으며, 이 경우 컨텍스트 윈도우가 소진될 수 있습니다. 이 때문에 컨텍스트 윈도우 관리는 에이전트의 여러 중요한 책임 중 하나입니다. 이제 Codex가 에이전트 루프를 어떻게 실행하는지 살펴보겠습니다.

모델 추론

Codex CLI는 모델 추론을 실행하기 위해 Responses API(새 창에서 열기)로 HTTP 요청을 보냅니다. Responses API를 사용해 에이전트 루프를 구동하는 Codex 내부에서 정보가 어떻게 흐르는지 살펴보겠습니다.

Codex CLI가 사용하는 Responses API 엔드포인트는 구성 가능(새 창에서 열기)하므로, Responses API를 구현한(새 창에서 열기) 어떤 엔드포인트와도 함께 사용할 수 있습니다.

이제 Codex가 대화에서 첫 번째 추론 호출을 위한 프롬프트를 어떻게 생성하는지 살펴보겠습니다.

초기 프롬프트 구성하기

최종 사용자로서 Responses API를 호출할 때, 모델을 샘플링하는 데 사용되는 프롬프트를 그대로 직접 지정하지는 않습니다. 대신 쿼리의 일부로 다양한 입력 유형을 지정하면, Responses API 서버가 해당 정보를 모델이 이해할 수 있는 형태의 프롬프트로 어떻게 구성할지 결정합니다. 프롬프트는 ‘항목의 목록’으로 생각할 수 있으며, 이 섹션에서는 쿼리가 어떻게 그 목록으로 변환되는지 설명합니다.

초기 프롬프트에서 목록의 각 항목에는 역할이 할당됩니다. role은 해당 콘텐츠가 어느 정도의 중요도를 갖는지를 나타내며, 다음 값 중 하나를 가집니다(우선순위가 높은 순): system, developer, user, assistant.

Responses API(새 창에서 열기)는 여러 매개변수를 포함한 JSON 페이로드를 받습니다. 여기서는 다음 세 가지에 초점을 맞추겠습니다.

Codex에서 instructions 필드가 지정된 경우 ~/.codex/config.toml model_instructions_file(새 창에서 열기)에서 읽어오며, 그렇지 않으면 모델과 연관된 base_instructions(새 창에서 열기) 가 사용됩니다. 모델별 지침은 Codex 리포지토리에 있으며 CLI에 함께 번들로 제공됩니다(예: gpt-5.2-codex_prompt.md(새 창에서 열기)).

tools 필드는 Responses API에서 정의한 스키마를 따르는 툴 정의 목록입니다. Codex의 경우 여기에는 Codex CLI가 제공하는 툴, Codex에서 사용할 수 있도록 Responses API가 제공하는 툴, 그리고 보통 MCP 서버를 통해 사용자가 제공하는 툴이 포함됩니다.

JavaScript

1
[
2
// Codex's default shell tool for spawning new processes locally.
3
{
4
"type": "function",
5
"name": "shell",
6
"description": "Runs a shell command and returns its output...",
7
"strict": false,
8
"parameters": {
9
"type": "object",
10
"properties": {
11
"command": {"type": "array", "description": "The command to execute", ...},
12
"workdir": {"description": "The working directory...", ...},
13
"timeout_ms": {"description": "The timeout for the command...", ...},
14
...
15
},
16
"required": ["command"],
17
}
18
}
19

20
// Codex's built-in plan tool.
21
{
22
"type": "function",
23
"name": "update_plan",
24
"description": "Updates the task plan...",
25
"strict": false,
26
"parameters": {
27
"type": "object",
28
"properties": {"plan":..., "explanation":...},
29
"required": ["plan"]
30
}
31
},
32

33
// Web search tool provided by the Responses API.
34
{
35
"type": "web_search",
36
"external_web_access": false
37
},
38

39
// MCP server for getting weather as configured in the
40
// user's ~/.codex/config.toml.
41
{
42
"type": "function",
43
"name": "mcp__weather__get-forecast",
44
"description": "Get weather alerts for a US state",
45
"strict": false,
46
"parameters": {
47
"type": "object",
48
"properties": {"latitude": {...}, "longitude": {...}},
49
"required": ["latitude", "longitude"]
50
}
51
}
52
]

마지막으로 JSON 페이로드의 input 필드는 아이템의 목록입니다. Codex는 (새 창에서 열기) 사용자 메시지를 추가하기 전에 input 다음 아이템을 삽입합니다.

1. tools 섹션에 정의된 applies only to the Codex 제공 shell 툴에만 적용되는 샌드박스를 설명하는 role=developer에 대한 메시지입니다. 즉, MCP 서버에서 제공되는 툴 등과 같은 기타 툴은 Codex에 의해 샌드박싱되지 않으며 자체적인 안전 장치를 적용해야 합니다.

이 메시지는 Codex CLI에 포함된 Markdown 스니펫(예: workspace_write.md(새 창에서 열기), on_request.md(새 창에서 열기))에서 핵심 콘텐츠를 가져오는 템플릿을 기반으로 생성됩니다.

일반 텍스트

1
<permissions instructions>
2
- description of the sandbox explaining file permissions and network access
3
- instructions for when to ask the user for permissions to run a shell command
4
- list of folders writable by Codex, if any
5
</permissions instructions>

2. (선택 사항) 사용자의 config.toml 파일에서 읽은 developer_instructions 값을 내용으로 하는 role=developer 메시지입니다.

3. (선택 사항) 단일 파일에서 가져오는 것이 아니라 role=user “사용자 지침”을 내용으로 하는 메시지로, 여러 소스에서 집계된(새 창에서 열기) 것입니다. 일반적으로 보다 구체적인 지침은 다음과 같이 나중에 표시됩니다.

4. 에이전트가 현재 실행 중인 로컬 환경을 설명하는 role=user 메시지입니다. 이는 현재 작업 디렉터리와 사용자의 셸(새 창에서 열기)을 지정합니다.

일반 텍스트

1
<environment_context>
2
<cwd>/Users/mbolin/code/codex5</cwd>
3
<shell>zsh</shell>
4
</environment_context>

Codex가 위의 모든 처리를 통해 input을 초기화한 후, 대화를 시작하기 위해 사용자 메시지를 추가합니다.

앞선 예시는 각 메시지의 콘텐츠에 초점을 맞췄지만, input의 각 요소는 type, role(새 창에서 열기), content를 포함하는 JSON 객체라는 점에 유의하세요.

JSON

1
{
2
"type": "message",
3
"role": "user",
4
"content": [
5
{
6
"type": "input_text",
7
"text": "Add an architecture diagram to the README.md"
8
}
9
]
10
}

Codex가 Responses API로 전송할 전체 JSON 페이로드를 구성하면, ~/.codex/config.toml에 설정된 Responses API 엔드포인트 구성에 따라 Authorization 헤더를 포함한 HTTP POST 요청을 전송합니다(지정된 경우 추가 HTTP 헤더 및 쿼리 매개변수도 함께 추가됩니다).

OpenAI Responses API 서버가 요청을 받으면, 다음과 같은 방식으로 JSON을 사용해 모델용 프롬프트를 구성합니다(물론 Responses API를 커스텀 구현한 경우에는 다른 선택을 할 수도 있습니다).

AI 에이전트 루프의 단일 단계를 보여주는 스냅샷 다이어그램 사용자 요청이 모델로 들어가면, 모델은 사고, 툴 이름이 포함된 행동, 그리고 툴 입력을 생성합니다. 이 다이어그램은 툴이 호출되기 전의 중간 추론 단계를 강조합니다.

보시다시피, 프롬프트에서 처음 세 항목의 순서는 클라이언트가 아니라 서버가 결정합니다. 다만 이 세 가지 항목 중에서 서버가 제어하는 것은 system 메시지의 콘텐츠뿐이며, toolsinstructions는 클라이언트에 의해 결정됩니다. 그 뒤에 JSON 페이로드의 input이 이어지며 프롬프트가 완성됩니다.

이제 프롬프트가 준비되었으니 모델을 샘플링할 수 있습니다.

첫 번째 턴

Responses API로 보내는 이 HTTP 요청은 Codex에서 대화의 첫 번째 ‘턴’을 시작합니다. 서버는 Server-Sent Events(SSE(새 창에서 열기)) 스트림으로 응답합니다. 각 이벤트의 data"response"로 시작하는 "type"을 가진 JSON 페이로드이며, 예시는 다음과 같습니다(전체 이벤트 목록은 API 문서(새 창에서 열기)에서 확인할 수 있습니다).

일반 텍스트

1
data: {"type":"response.reasoning_summary_text.delta","delta":"ah ", ...}
2
data: {"type":"response.reasoning_summary_text.delta","delta":"ha!", ...}
3
data: {"type":"response.reasoning_summary_text.done", "item_id":...}
4
data: {"type":"response.output_item.added", "item":{...}}
5
data: {"type":"response.output_text.delta", "delta":"forty-", ...}
6
data: {"type":"response.output_text.delta", "delta":"two!", ...}
7
data: {"type":"response.completed","response":{...}}

Codex 이벤트 스트림을 수신하여(새 창에서 열기) 이를 클라이언트가 사용할 수 있는 내부 이벤트 객체로 다시 게시합니다. response.output_text.delta와 같은 이벤트는 UI에서 스트리밍을 지원하는 데 사용되며, response.output_item.added와 같은 다른 이벤트는 이후 Responses API 호출을 위해 input에 추가되는 객체로 변환됩니다.

Responses API에 대한 첫 번째 요청에 두 개의 response.output_item.done 이벤트가 포함된다고 가정합니다. 하나는 type=reasoning 이고 다른 하나는 type=function_call입니다. 이러한 이벤트들은 툴 호출에 대한 응답을 포함해 모델을 다시 쿼리할 때 JSON의 input 필드에 반드시 포함되어야 합니다.

JavaScript

1
[
2
/* ... original 5 items from the input array ... */
3
{
4
"type": "reasoning",
5
"summary": [
6
"type": "summary_text",
7
"text": "**Adding an architecture diagram for README.md**\n\nI need to..."
8
],
9
"encrypted_content": "gAAAAABpaDWNMxMeLw..."
10
},
11
{
12
"type": "function_call",
13
"name": "shell",
14
"arguments": "{\"command\":\"cat README.md\",\"workdir\":\"/Users/mbolin/code/codex5\"}",
15
"call_id": "call_8675309..."
16
},
17
{
18
"type": "function_call_output",
19
"call_id": "call_8675309...",
20
"output": "<p align=\"center\"><code>npm i -g @openai/codex</code>..."
21
}
22
]

이후 쿼리에서 모델을 샘플링하는 데 사용되는 결과 프롬프트는 다음과 같은 형태가 됩니다.

툴 호출 이후의 AI 에이전트를 보여주는 “Snapshot 2”라고 표시된 다이어그램 모델은 툴 관측 결과를 받아 새로운 사고와 행동을 생성합니다. 화살표는 입력, 관측, 출력 간의 연결을 통해 에이전트가 추론 루프를 반복하는 방식을 보여줍니다.

특히 이전 프롬프트가 새로운 프롬프트의 정확한 접두부라는 점에 주목하세요. 이는 의도된 설계로, 프롬프트 캐싱을 활용할 수 있게 해 이후 요청을 훨씬 더 효율적으로 만들기 위함입니다(이에 대해서는 다음 성능 섹션에서 다룹니다).

에이전트 루프의 첫 번째 다이어그램을 다시 보면, 추론과 툴 호출 사이에 여러 번의 반복이 발생할 수 있음을 알 수 있습니다. 프롬프트는 턴의 종료를 의미하는 어시스턴트 메시지를 최종적으로 받을 때까지 계속 커질 수 있습니다.

일반 텍스트

1
data: {"type":"response.output_text.done","text": "I added a diagram to explain...", ...}
2
data: {"type":"response.completed","response":{...}}

Codex CLI에서는 어시스턴트 메시지를 사용자에게 표시하고, 사용자가 대화를 이어갈 “차례”임을 알리기 위해 입력 창에 포커스를 둡니다. 사용자가 응답하면, 이전 턴의 어시스턴트 메시지와 사용자의 새 메시지 모두가 새로운 턴을 시작하기 위해 Responses API 요청의 input에 추가되어야 합니다.

JavaScript

1
[
2
/* ... all items from the last Responses API request ... */
3
{
4
"type": "message",
5
"role": "assistant",
6
"content": [
7
{
8
"type": "output_text",
9
"text": "I added a diagram to explain the client/server architecture."
10
}
11
]
12
},
13
{
14
"type": "message",
15
"role": "user",
16
"content": [
17
{
18
"type": "input_text",
19
"text": "That's not bad, but the diagram is missing the bike shed."
20
}
21
]
22
}
23
]

다시 말해, 대화를 계속 이어가고 있기 때문에 Responses API로 보내는 input의 길이는 계속 증가합니다.

AI 에이전트 루프의 마지막 단계를 보여주는 “Snapshot 3”라고 표시된 다이어그램 툴 결과를 받은 후, 모델은 결론적인 생각과 사용자에게 반환되는 최종 답변을 생성합니다. 화살표는 툴 출력에서 완성된 응답으로 이어지는 전환 과정을 나타냅니다.

이렇게 계속 커지는 프롬프트가 성능에 어떤 의미를 갖는지 살펴보겠습니다.

성능 고려 사항

“잠깐, 대화가 진행되는 동안 Responses API로 전송되는 JSON의 양을 기준으로 보면 에이전트 루프는 2차적이지 않나?”라고 생각할 수도 있습니다. 그 생각은 맞습니다. Responses API는 이 문제를 완화하기 위해 선택적으로 previous_response_id(새 창에서 열기) 매개변수를 지원하지만, Codex는 요청을 완전히 무상태로 유지하고 Zero Data Retention(ZDR) 구성을 지원하기 위해 현재 이를 사용하지 않습니다.

previous_response_id를 사용하지 않으면 모든 요청이 상태 없음으로 유지되므로 응답 API 제공자 입장에서는 구현이 단순해집니다. 또한 previous_response_id를 지원하는 데 필요한 데이터를 저장 하는 것은 데이터 비보존(ZDR)(새 창에서 열기)과 상충되기 때문에 ZDR을 선택한 고객을 지원하는 일도 훨씬 수월해집니다. ZDR 고객도 이전 턴의 독점적인 추론 메시지에서 얻을 수 있는 이점을 포기하지 않는데, 이는 관련 encrypted_content를 서버에서 복호화할 수 있기 때문입니다. (OpenAI는 ZDR 고객의 복호화 키는 보관하지만, 데이터 자체는 보관하지 않습니다.) Codex에서 ZDR 지원을 위한 관련 변경 사항은 #642(새 창에서 열기)#1641(새 창에서 열기) PR을 참조하세요.

일반적으로 모델 샘플링 비용이 네트워크 트래픽 비용을 압도하기 때문에, 효율화의 주요 대상은 샘플링입니다. 이 때문에 이전 추론 호출의 계산 결과를 재사용할 수 있게 해주는 프롬프트 캐싱이 매우 중요합니다. 캐시 히트가 발생하면 모델 샘플링은 2차가 아니라 선형으로 수행됩니다. 이에 대한 자세한 내용은 프롬프트 캐싱(새 창에서 열기) 문서에서 설명하고 있습니다.

캐시 히트는 프롬프트 내에서 정확히 일치하는 접두부가 있을 때만 가능합니다. 캐싱의 이점을 얻으려면 지침이나 예시 같은 정적인 콘텐츠는 프롬프트 앞부분에 두고, 사용자별 정보처럼 변하는 콘텐츠는 뒤에 배치해야 합니다. 이는 이미지와 툴에도 동일하게 적용되며, 요청 간에 완전히 동일해야 합니다.

이를 바탕으로 Codex에서 ‘캐시 미스’를 유발할 수 있는 작업 유형을 살펴보겠습니다.

  • 대화 도중 모델에서 사용할 수 있는 을 변경하는 경우.
  • Responses API 요청의 대상이 되는 모델을 변경하는 경우(실제로는 모델별 지침이 포함된 원래 프롬프트의 세 번째 항목이 변경됩니다).
  • 샌드박스 구성, 승인 모드, 또는 현재 작업 디렉터리를 변경하는 경우.

Codex CLI에 프롬프트 캐싱을 저해할 수 있는 새로운 기능을 도입할 때 Codex 팀은 각별히 주의해야 합니다. 예를 들어, MCP 툴에 대한 초기 지원에서는 툴을 일관된 순서로 나열하지 못하는 버그(새 창에서 열기)가 발생해 캐시 미스를 유발했습니다. MCP 서버는 notifications/tools/list_changed(새 창에서 열기) 알림을 통해 제공하는 툴 목록을 실시간으로 변경할 수 있기 때문에, MCP 툴은 특히 까다로울 수 있습니다. 긴 대화 도중 이 알림을 반영하면 비용이 큰 캐시 미스가 발생할 수 있습니다.

가능한 경우, 대화 중 발생한 구성 변경은 이전 메시지를 수정하는 대신 input새로운 메시지를 추가하는 방식으로 처리합니다.

  • 샌드박스 구성이나 승인 모드가 변경되면, 원래의 <permissions instructions> 항목과 동일한 형식의 새로운 role=developer 메시지를 삽입(새 창에서 열기)합니다.
  • 현재 작업 디렉터리가 변경되면, 새로운 role=user 메시지를 삽입(새 창에서 열기)하며, 이는 원래의 와 동일한 <environment_context> 형식입니다.

성능을 위해 캐시 히트를 보장하는 데 많은 노력을 기울이고 있습니다. 관리해야 할 또 다른 핵심 리소스는 컨텍스트 윈도우입니다.

컨텍스트 윈도우를 초과하지 않기 위한 일반적인 전략은 토큰 수가 특정 임계값을 넘으면 대화를 압축하는 것입니다. 구체적으로는, 지금까지의 대화를 대표하는 더 작고 새로운 항목 목록으로 input을 교체해 에이전트가 맥락을 이해한 채 계속 진행할 수 있도록 합니다. 초기 압축 구현(새 창에서 열기)에서는 사용자가 /compact 명령을 수동으로 실행해야 했으며, 이는 기존 대화와 요약(새 창에서 열기)을 위한 사용자 정의 지침을 함께 사용해 Responses API를 호출하는 방식이었습니다. Codex는 요약이 포함된 결과 어시스턴트 메시지를 이후 대화 턴을 위한 새로운 input(새 창에서 열기)으로 사용했습니다.

그 이후로 응답 API는 더 효율적으로 컴팩션을 수행하는 특수 /responses/compact 엔드포인트(새 창에서 열기)를 지원하도록 발전해 왔습니다. 이전 input을 대신하여 사용할 수 있는 항목 목록(새 창에서 열기)을 반환하여 컨텍스트 윈도우에 여유 공간을 주어 대화를 계속할 수 있습니다. 이 목록에는 원래 대화에 대한 모델의 잠재적 이해를 보존하는 불투명한 encrypted_content 항목과 함께 특수한 type=compaction 항목이 포함됩니다. 이제 Codex는 auto_compact_limit(새 창에서 열기)을 초과하면 이 엔드포인트를 자동으로 사용해 대화를 컴팩션합니다.

다음 내용

Codex 에이전트 루프를 소개하고, Codex가 모델을 쿼리할 때 컨텍스트를 어떻게 구성하고 관리하는지 살펴보았습니다. 또한 Responses API 위에서 에이전트 루프를 구축하는 누구에게나 적용될 수 있는 실무적인 고려 사항과 모범 사례를 짚어봤습니다.

에이전트 루프는 Codex의 기반을 이루지만, 이는 시작에 불과합니다. 이어지는 글에서는 CLI 아키텍처를 더 깊이 살펴보고, 툴 사용이 어떻게 구현되는지와 Codex의 샌드박싱 모델을 자세히 다룰 예정입니다.

작성자

Michael Bolin

감사의 말

Codex CLI를 구축한 전체 팀에 특별한 감사를 전합니다.