OpenAI Agents API vs Responses API: 2026 개발자는 어떻게 고르나. JSON Tool Calling, Structured Output, 멀티 Agent
9월 10일 Agents API 공개 베타 이후 흔한 질문은 「어느 모델이 더 똑똑한가」가 아니다. 누가 루프를 도느냐다. Responses API는 function_call을 당신이 돌린다. Agents API는 Codex harness를 호스트한다. Tool Calling과 Structured Output에서 멀티 Agent까지 열고, 고를 수 있는 표를 준다.
읽기 전 한눈
| 입구 | 한 줄 | 무엇을 쥐나 |
|---|---|---|
| Agents API | OpenAI가 Codex harness를 돌린다 | Session / Environment |
| Responses API | 당신이 모델을 치고 루프를 돌린다 | input / output items |
| Agents SDK | 루프는 당신 프로세스에 남는다 | runner / handoff |
| JSON 사슬 | 이름, 인자, 결과는 객체로 남는다 | call_id / Schema |
먼저 주어를 고른다. 루프를 직접 쥘 것인가. 입구를 바꿔도 JSON 호출 사슬은 남는다.
고르는 것은 누가 루프를 도느냐다. 누가 더 똑똑하냐가 아니다
2026년 GPT-6 Astra의 도구 호출은 이미 Responses를 지난다. Agents API는 다른 층이다. 세션을 호스트하고 문맥을 압축하며 subagent를 보낸다. 같은 JSON 사슬. 주어가 다르다.
- 매 홉을 쥐어야 한다 — 승인, 재시도,
function_call_output을 되돌림 — Responses API. - 몇 시간짜리 일, 관리 복구, 샌드박스, subagent — Agents API.
- 루프는 자기 프로세스에 두되 runner는 필요하다 — Agents SDK. 아래는 흔히 Responses.
Agents API 자체의 도구 호출은 OpenAI Agents API 완전 해설. Agent와 Function Calling이 아직 한 단어라면 AI Agent 완전 가이드.
각 API는 한 층을 가진다
Responses는 아래층: /v1/responses. input을 보내고 typed items를 받는다. message, reasoning, function_call. GPT-6 Astra 가이드의 도구 호출은 이 길을 요구한다. Structured Output은 text.format. Chat Completions의 response_format이 아니다.
Agents API는 관리 harness: POST /v1/agents/sessions. Agent, Tools, Environment를 선언한다. OpenAI가 루프, compact, 복구를 돌린다. 함수 답이 필요하면 session이 requires_action을 낸다. 당신은 turn_id / call_id로 tool_result를 돌려준다.
Agents SDK는 세 번째 프로토콜이 아니다. 당신 프로세스의 runner다. handoff, 승인, 저장은 당신 것. 모델 호출은 흔히 Responses로 떨어진다. 공식은 Session, SDK session, Responses conversation, sandbox를 네 자원으로 본다.
Tool Calling: 한 사슬, 두 되돌림
Responses에서는 매 턴 responses.create. 도구 표와 최종 카드는 같은 요청에 둘 수 있다:
{
"model": "gpt-6-astra",
"input": "Look up order A-1042.",
"tools": [
{
"type": "function",
"name": "lookup_order",
"parameters": {
"type": "object",
"properties": {
"order_id": { "type": "string", "pattern": "^[A-Z]-\\d{4}$" }
},
"required": ["order_id"],
"additionalProperties": false
}
}
],
"text": {
"format": {
"type": "json_schema",
"name": "order_card",
"strict": true,
"schema": {
"type": "object",
"properties": {
"order_id": { "type": "string" },
"status": { "enum": ["paid", "pending", "void"] }
},
"required": ["order_id", "status"],
"additionalProperties": false
}
}
}
}
모델이 조회하면 output에 독립 item이 나온다. call_id가 호출과 결과를 고정한다:
{
"output": [
{
"type": "function_call",
"call_id": "call_3c91",
"name": "lookup_order",
"arguments": "{\"order_id\":\"A-1042\"}"
}
]
}
앱이 함수를 실행하고 결과를 다음 input item으로 되돌린다:
{
"type": "function_call_output",
"call_id": "call_3c91",
"output": "{\"status\":\"paid\",\"amount\":99.00}"
}
Agents API는 그 턴들을 session에 접는다. 생성 때 도구, 샌드박스, multi_agent를 한 번에 선언한다:
{
"agent": {
"model": "gpt-6-astra",
"tools": [
{ "type": "function", "name": "lookup_order", "parameters": {
"type": "object",
"properties": { "order_id": { "type": "string", "pattern": "^[A-Z]-\\d{4}$" } },
"required": ["order_id"],
"additionalProperties": false
}},
{ "type": "web_search" }
],
"multi_agent": { "enabled": true, "max_concurrent_subagents": 3 }
},
"environment": { "type": "hosted", "workspace_directory": "/workspace" },
"input": [{ "role": "user", "content": [{ "type": "input_text", "text": "Look up A-1042." }] }]
}
함수 차례가 오면 harness는 required_actions에서 멈춘다. 되돌림은 function_call_output이 아니다. turn_id가 있는 tool result다:
{
"type": "tool_result",
"turn_id": "turn_2",
"call_id": "call_3c91",
"success": true,
"output": "{\"status\":\"paid\"}"
}
이름은 다르다. 문은 같다. Schema가 실행 가능 여부를 정한다. MCP 행은 같은 도구 표의 다른 표기. 경계는 MCP Tool Schema vs Function Calling.
Structured Output은 최종 카드를 잠근다. 도구 인자가 아니다
Responses는 최종 모양을 text.format에 둔다. 사용자에게 보여줄 객체를 묶는다. 도구 인자는 별 Schema. 계약은 왜 AI에 JSON Schema가 필요한가.
- Responses:
text.format.json_schema+strict: true가 최종 카드를 잠근다. - Agents API: 루프는 호스트된다. 최종 산출물에도 Schema가 필요하다. function / MCP 인자는 각자 조인다.
- 양쪽: Structured Output은 문이 아니다. 금액, 확인, 배포는 호스트가 쓴다.
흔한 실수는 카드만 잠그고 lookup_order를 넓은 object로 두는 것이다. 카드는 깔끔하다. 부작용은 이미 달렸다.
멀티 Agent: 호스트된 부채꼴인가, 당신 handoff인가
「멀티 Agent 협업」은 세 번째 지능이 아니다. 누가 편성을 쥐느냐다:
- Agents API:
multi_agent.enabled. subagent는 자기 문맥을 가진다. 주 Agent는 create / wait / interrupt. 동시 실행에 상한을 둔다. - Agents SDK: handoff 객체는 runner 안. 승인과 저장은 당신 것.
- Responses: 내장 subagent가 없다.
responses.create를 직접 잇거나 상태를 Conversations에 둔다.
handoff는 감사 가능한 JSON이어야 한다. 「청구팀에 넘겨」라는 문장이 아니다. Schema로 담는 법은 JSON Schema와 Agent 워크플로.
표 하나, 입구 셋
공식 대비는 공학 질문으로 접힌다:
| 축 | Agents API | Responses API | Agents SDK |
|---|---|---|---|
| 누가 루프를 도나 | OpenAI 관리 harness | 매 create마다 당신이 돌린다 | 당신 프로세스의 runner |
| 상태가 사는 곳 | Session / turns / items | history를 짜거나 Conversations | 당신 저장소 또는 SDK session |
| 도구 되돌림 | tool_result + turn_id | function_call_output + call_id | SDK가 감싼다. 아래는 흔히 Responses |
| Structured Output | 최종 산출물에 별 Schema | text.format.json_schema | 어디에 붙일지는 당신 |
| 멀티 Agent | 내장 subagent | 당신이 편성한다 | runner 안의 handoff |
「더 나은 API」는 없다. 있는 것은 「주어가 당신 쪽에 있는가」뿐이다.
입구를 정하는 네 질문
제품 페이지에서 고르지 마라. 이 넷:
- 업무 부작용이 당신 프로세스를 떠나도 되나? 환불과 쓰기에 당신의 승낙이 필요하면 먼저 Responses 또는 SDK.
- 일이 한 문맥 창을 넘나? 넘고, 직접 compact하고 싶지 않으면 Agents API.
- 명령과 파일용 샌드박스가 필요한가? Agents API Environment는 이미 있다. Responses는 실행 세계를 당신이 준비한다.
- 병렬 subagent가 필요한가? 필요하고 편성을 직접 짜지 않으려면 Agents API multi_agent를 켜고 동시 실행 상한을 고정한다.
네 「필요」가 호스트 쪽에 떨어지면 Agents API. 한 홉이라도 당신 손에 남아야 하면 Responses부터. SDK는 세 번째: 루프는 당신 것, 접착제는 적다.
비교하기 전에 두 JSON 궤적을 펼친다
입구를 잘못 고르는 것은 대개 객체를 보지 않아서다. 두 궤적을 나란히 둔다.
- Responses의
output[]과 Agents session items를 포맷.call_id가 맞는지 본다. - JSONPath 추출로
name,arguments,text.format을 뽑는다. 문서를 눈으로 훑지 않는다. - 같은 주문을 두 입구에서 JSON Diff. 루프가 흘렀으면 먼저 되돌림 모양을 본다.
- 최종 카드 Schema와 도구 인자 Schema는 따로 심사한다. 카드만 잠그는 것은 겉만 꾸미는 일이다.
- 주문과 사내 MCP를 공개 포맷터에 붙이지 마라. JSONSort는 브라우저 로컬.
두 궤적을 다시 만들 수 있어야 입구를 고르는 것이다. 구호가 아니다.
함정
- Agents API가 Responses를 대체했다고 생각한다. 공식은 두 출발점을 적는다. Astra tool calling은 여전히 Responses.
- Session과 Conversation을 한 자원으로 본다. 하나를 지워도 다른 하나는 안 지워진다.
- 최종 카드만 Schema, 도구 인자는 넓다. 부작용은 function_call이 달릴 때 생긴다.
- multi_agent를 켜고 동시 실행 상한을 두지 않는다. 호스트된 부채꼴도 토큰을 태우고 부작용을 넓힌다.
- SDK를 쓰면서 문을 쓰지 않는다. runner는 루프를 돈다. 금액은 검증하지 않는다.
- 데모 영상으로 API를 고른다. 데모는 루프를 숨긴다. 주어가 어디에 있는지 먼저 묻는다.
FAQ
2026 새 프로젝트는 어느 API부터?
Responses부터. 매 홉이 보인다. 창을 넘는 일, 호스트 샌드박스나 subagent가 필요할 때만 루프를 Agents API에 넘긴다.
GPT-6 Astra는 Agents API만 쓰고 Responses를 건너뛸 수 있나?
Agents session만 열어도 된다. Astra tool calling 문서는 여전히 Responses를 가리킨다. 짧은 사슬, Structured Output, 직접 도는 루프는 Responses에 남긴다.
Structured Output이 Tool Calling을 대신할 수 있나?
없다. Structured Output은 최종 객체를 잠근다. Tool Calling은 부작용을 잠근다. 환불, 조회, 파일 수정은 도구 JSON. 사용자가 보는 카드는 text.format.
멀티 Agent는 Agents API가 필수인가?
아니다. SDK handoff와 직접 이은 여러 Responses도 멀티 Agent다. Agents API는 부채꼴을 호스트 능력으로 만들었을 뿐이다.
두 API를 섞을 수 있나?
된다. 자원은 섞지 마라. 구조화 카드는 Responses, 긴 일은 Agents session. Session, Conversation, sandbox는 따로 만들고 따로 지운다.
결론
Agents API와 Responses API는 두 세대가 아니다. 하나는 루프를 호스트한다. 다른 하나는 루프를 당신에게 넘긴다. Tool Calling, Structured Output, 멀티 Agent는 그 사슬 위의 다른 객체일 뿐이다.
먼저 주어를 쓴다. 이 홉이 당신 프로세스를 떠나도 되는가. 그다음 입구를 고른다. 모델은 바뀐다. call_id와 Schema를 먼저 안정시킨다.
더 읽기
- OpenAI Agents API 완전 해설 Session, Tool Calling, Schema가 어떻게 잇는지
- AI Agent란 무엇인가: 완전 가이드 런타임과 JSON 계약
- 왜 AI에 JSON Schema가 필요한가 Schema / Function Calling / Structured Output
- JSON Schema와 Agent 워크플로 도구와 상태를 Schema로
- MCP Tool Schema vs Function Calling 도구 JSON의 프로토콜 경계
- JSONSort 로컬 도구함 포맷, 검증, Diff
- 모든 글 JSON과 AI 메모
변경 기록: 최초 게시