AI 개발

OpenAI DevDay 2026 API 업데이트 후, 기존 JSON Tool Calling 워크플로를 어떻게 옮기나

약 16분

모델 이름보다 먼저 되돌려 쓰는 모양을 바꾼다. 대상이 gpt-6-astra 또는 gpt-6.1-sol이면 도구 호출은 Chat Completions를 떠나 Responses API로 간다. 분류나 라우팅만 하는 홉은 10월 6일 공개 베타가 된 Decisions API로 옮길 수 있다. 조회는 lookup_order로 남는다. 모델은 JSON만 채운다. 실행은 호스트가 한다.

읽기 전 요약

대상 공식 사실 옮길 때 바꾸는 것
입구 Astra와 GPT-6.1 Sol의 도구 호출은 Responses. Sol과 Luna는 reasoning_effort가 none일 때만 Chat Completions에서 함수를 호출한다 POST /v1/responses로 옮기거나, none을 남긴다면 명시한다
도구 정의 Responses에서 name은 type과 같은 층. strict를 빼면 엄격 모드를 시도하고, 맞지 않으면 되돌리며 strict: false를 붙인다 strict를 명시한다. 호스트 검증은 남긴다
되돌려 쓰기 function_call과 function_call_output은 call_id로 짝을 이룬다. async: true는 실행을 모델에 넘기지 않는다 role:tool을 function_call_output으로 바꾼다
라우팅 Decisions는 2026-10-06 공개 베타. 모델은 gpt-6-luna뿐. choice는 도구를 실행하지 않는다 열거를 고르는 홉만 옮긴다

사실은 2026-10-08 기준 공식 문서. Using GPT-6, Migrate to the Responses API, Decisions, Async tool calling. 주문 A-1042는 허구. Decisions 확률은 예시 숫자.

되돌려 쓰는 모양을 먼저 바꾸고, 그다음 모델 이름을 바꾼다

DevDay 이후 옮기는 것은 필드다. Agent가 무엇인지를 다시 쓰는 글이 아니다. 공식 이전 안내는 네 줄로 모인다. 첫째, 대상이 gpt-6-astra 또는 gpt-6.1-sol이면 도구 호출은 Responses로 간다. 이 둘은 도구 없는 Chat Completions 요청을 아직 보낼 수 있다. gpt-6-sol과 gpt-6-luna는 reasoning_effort가 none일 때만 Chat Completions에서 함수를 호출한다. 추론과 함께 도구를 쓰려면 Responses. 둘째, name은 중첩된 function 밖으로 나와 type과 같은 층에 놓인다. 셋째, 되돌려 쓰는 id는 tool_calls[].id에서 call_id로 바뀐다. 넷째, 분류나 라우팅만 하는 홉은 Decisions로 옮길 수 있다. Decisions는 도구를 실행하지 않는다.

  • Astra / GPT-6.1 Sol: 도구 호출은 /v1/chat/completions를 떠난다. Responses의 추론 필드는 reasoning.effort.
  • 정의를 평평하게 하고 strict를 적는다. Chat Completions는 기본이 비엄격. Responses는 strict를 빼면 엄격 모드를 시도한다.
  • 라우팅과 조회를 나눈다. choice는 열거를 반환한다. 조회는 lookup_order로 남는다.

9월 29일에 무엇이 나왔는지는 DevDay 2026에서 무엇이 나왔는지. Responses와 Agents 입구의 차이는 Agents API와 Responses API의 차이. 이 글은 그 두 편을 다시 쓰지 않는다. 기존 JSON Tool Calling의 필드만 옮긴다.

지금 코드가 읽는 호출의 이름을 먼저 붙인다

Chat Completions 응답에서 호출은 이렇게 생긴다. id는 바깥, name은 function 안. arguments는 문자열. 허구 주문이며, 실제 비밀은 넣지 않는다:

{
  "id": "call_3c91",
  "type": "function",
  "function": {
    "name": "lookup_order",
    "arguments": "{\"order_id\":\"A-1042\"}"
  }
}

Responses 도구 정의는 name을 type과 같은 층에 둔다. strict를 빼지 않는다. 빼면 엄격 모드를 시도하고, Schema가 맞지 않으면 되돌리며 반환된 도구에 strict: false를 붙인다. 비엄격을 유지하려면 false를 명시한다. 호스트는 실행 전에 arguments를 검증한다:

{
  "type": "function",
  "name": "lookup_order",
  "strict": true,
  "parameters": {
    "type": "object",
    "properties": {
      "order_id": { "type": "string", "pattern": "^[A-Z]-\\d{4}$" }
    },
    "required": ["order_id"],
    "additionalProperties": false
  }
}

되돌려 쓰기는 call_id만 본다

모델이 내는 것은 function_call이지 tool_calls 배열이 아니다. 파서는 이 네 필드를 읽는다:

{
  "type": "function_call",
  "call_id": "call_3c91",
  "name": "lookup_order",
  "arguments": "{\"order_id\":\"A-1042\"}"
}

호스트는 arguments를 파싱하고, Schema를 통과시키고, lookup_order를 실행한 뒤 같은 call_id로 돌려쓴다. 실패도 문자열 안의 객체다. 이력을 손으로 다시 보낼 때는 이전 턴의 reasoning 항목과 function_call을 결과와 함께 보낸다. 결과만 보내지 않는다. 더 짧은 길은 previous_response_id:

{
  "type": "function_call_output",
  "call_id": "call_3c91",
  "output": "{\"order_id\":\"A-1042\",\"status\":\"paid\"}"
}

느린 도구는 정의에 async: true를 달 수 있다. 공식 설명: 모델은 추론을 이어가거나, 그 결과에 기대지 않는 부분에 답할 수 있다. 해당 호출 항목에는 async: true가 붙는다. 나중에 원래 call_id로 function_call_output을 보낸다. 실행은 호스트가 한다. 내장 도구와 programmatic tool calling에는 async를 쓸 수 없다. Multi-agent에서는 async와 병렬 도구 호출을 겹치지 않는다. 문서가 지목하는 것은 GPT-6 Astra와 그 이후 모델이다.

다섯 루프를 한 번의 업그레이드로 합치지 않는다

지금의 되돌려 쓰기 모양별로 옮긴다. 객체 이름이 다르면 파서를 공유하지 않는다:

지금의 루프 어디로 가나
Chat Completions + tools, 대상이 Astra 또는 GPT-6.1 Sol POST /v1/responses로 옮긴다. tool_calls[].id는 call_id. name은 function 밖으로 꺼낸다.
Chat Completions + tools, gpt-6-sol 또는 gpt-6-luna에 남김 reasoning_effort가 none일 때만 남을 수 있다. 추론한 뒤 도구를 호출하려면 Responses.
이미 Responses의 function_call 루프는 남긴다. 모델 ID만 바꾼다. Astra와 GPT-6.1 Sol은 none을 받지 않는다. low를 쓴다. 추론이 none이 아니면 temperature, top_p, top_logprobs를 뺀다.
lookup / hold / escalate만 반환하는 도구 그 홉은 POST /v1/decisions로. 모델은 gpt-6-luna. 조회는 function_call로 남긴다.
Agents API session 관리되는 harness가 필요하면 Agents에 남긴다. 되돌려 쓰기는 turn_id이지 function_call_output이 아니다.

라우팅 홉은 Decisions의 choice를 쓴다. 요청은 10월 6일 공개 베타의 모양이다. 주문은 허구다. 9월 30일 글에서 직접 만든 답 계약을 그대로 /v1/decisions에 POST하지 않는다:

{
  "model": "gpt-6-luna",
  "input": "Order A-1042 is paid. What should the host do next?",
  "questions": [{
    "type": "choice",
    "name": "next_step",
    "instructions": "Pick the next host action. Do not invent a tool name.",
    "choices": [
      { "value": "lookup", "description": "Read the order. No refund." },
      { "value": "hold", "description": "Stop and wait." },
      { "value": "escalate", "description": "Hand the case to a person." }
    ]
  }]
}

예시 응답의 필드 이름은 공식 choice 예와 같다. 확률은 허구다. 호스트는 choice가 lookup일 때만 lookup_order를 보낸다. hold는 멈춘다. escalate는 사람에게 넘긴다. type이 refusal이면 도구를 호출하지 않는다. 기준값은 직접 정한다. 이미지는 인라인 base64 data URL이어야 한다. https 이미지 URL과 file_id는 이 엔드포인트에서 받지 않는다:

{
  "answers": [{
    "type": "choice",
    "name": "next_step",
    "choice": "lookup",
    "probabilities": [
      { "value": "lookup", "probability": 0.91 },
      { "value": "hold", "probability": 0.05 },
      { "value": "escalate", "probability": 0.04 }
    ],
    "confidence": 0.88
  }]
}

Ultrafast는 gpt-6-astra의 service_tier이며 값은 ultrafast다. 미국 데이터 레지던시와 글로벌 처리만 지원하고, EU와 다른 지역 엔드포인트는 지원하지 않는다. 도구 JSON은 바꾸지 않는다. GPT-6.1 Sol의 Ultrafast는 9월 29일 공식 회고에서 아직 곧 제공이었다. 이 글은 이미 나온 것으로 쓰지 않는다. Agents API는 9월 29일 OpenAI가 호스트하는 브라우저의 Computer Use를 더했다. 사이트 승인과 로그인은 앱이 처리한다. 그것은 Responses의 function_call_output을 다른 모양으로 바꿀 이유가 아니다. 어긋남 모니터링은 경고하거나 대화를 멈출 수 있다. 멈추면 같은 도구 호출을 맹목적으로 다시 보내지 않는다.

여섯 단계를 끝낸 뒤 트래픽을 바꾼다

Ultrafast를 먼저 켜지 않는다. 되돌려 쓰는 모양부터 적는다:

  1. 현재 되돌려 쓰기의 이름을 붙인다. role: tool과 tool_call_id인지, function_call_output인지, Agents의 turn_id인지. 셋이 파서를 공유하지 않는다.
  2. 입구를 고른다. Astra와 GPT-6.1 Sol의 도구 호출은 POST /v1/responses. Sol과 Luna는 reasoning_effort가 none일 때만 Chat Completions에 남을 수 있다.
  3. 도구 정의를 평평하게 하고 strict를 적는다. 엄격 모드가 거부하는 Schema면 strict: false로 두고 호스트 검증은 남긴다. 조회는 order_id만 받는다.
  4. call_id를 맞추고 샘플링 매개변수를 뺀다. arguments는 문자열로 남는다. Astra와 GPT-6.1 Sol은 none 대신 low. 추론이 none이 아니면 temperature, top_p, top_logprobs를 뺀다. Chat Completions에서는 logprobs도 뺀다. Responses의 include에서 message.output_text.logprobs를 뺀다. GPT-5.5 이하에서 옮길 때는 prompt_cache_retention을 prompt_cache_options.ttl의 30m으로 바꾼다. 대화 중에 추론을 바꾸려면 configuration_update를 보내고, 요청의 reasoning.effort는 그대로 둔다.
  5. 열거만 고르는 홉을 Decisions로 옮긴다. 모델은 gpt-6-luna. 호스트는 lookup을 lookup_order에 대응시킨다. 느린 도구에만 async: true를 달고, 되돌려 쓰기는 원래 call_id를 쓴다.
  6. 두 JSON을 Diff한 뒤 트래픽을 바꾼다. arguments와 answers[].choice를 Schema로 검증한다. 맞지 않으면 모델 ID를 바꾸지 않는다.

Schema를 문으로 두는 이야기는 Agents API + JSON Schema. 그 문을 프롬프트에만 둘 수 없는 이유는 AI가 JSON Schema를 필요로 하는 이유. Agents의 되돌려 쓰기 모양은 Agents API 도구 JSON.

트래픽을 바꾸기 전에 JSON 세 벌을 펼친다

실패는 대개 id가 어긋나거나, name이 function 안에 남거나, choice를 이미 조회한 주문으로 다룰 때 난다.

  • 옛 tool call과 새 function_call을 포맷하고, Schema 검증로 arguments와 answers[0].choice가 문을 통과하는지 본다.
  • JSONPath 추출로 $.call_id, $.name, $.answers[0].choice를 뽑는다.
  • 옮기기 전과 후의 페이로드를 JSON Diff한다. 프롬프트보다 먼저 call_id를 고친다.
  • call_3c91이 호출과 function_call_output에서 같은 id인지 확인한다.
  • 주문, 토큰, 저장소 경로를 공개 포매터에 붙이지 않는다. JSONSort는 브라우저 로컬에서 돈다.

세 객체가 Schema로 다시 조립되면 이전이 끝난 것이다. Ultrafast는 이 검사를 대신하지 않는다.

흔한 실수

  • Decisions를 새 Tool Calling으로 여긴다. 반환은 choice, probability, score다. 도구 인자는 Responses 함수 호출. 자기 Schema를 따르는 객체는 Responses의 Structured Outputs.
  • 도구 정의에 function 한 겹을 남긴다. Responses는 옛 function.name을 읽지 않는다. name은 type과 같은 층.
  • strict를 빼고도 비엄격일 것이라 생각한다. Responses는 엄격 모드를 시도하고, 맞지 않으면 되돌리며 strict: false를 붙인다. 원하는 동작을 적는다. 호스트 검증은 남긴다.
  • Astra 또는 GPT-6.1 Sol에 none이나 temperature를 남긴다. 이 둘은 none을 받지 않는다. GPT-6.1 Sol은 minimal도 받지 않는다. low를 쓴다. 추론이 none이 아니면 샘플링 매개변수를 뺀다.
  • Computer Use 때문에 Responses 루프를 Agents API로 통째로 옮긴다. 9월 29일에 더해진 것은 호스트된 브라우저다. 승인은 앱에 남는다. Agents의 되돌려 쓰기는 turn_id.
  • async: true를 모델이 직접 실행하는 것으로 읽는다. 호스트가 도구를 실행하고, 끝나지 않은 호출을 추적한다. 나중에 원래 call_id로 돌려쓴다.

FAQ

Chat Completions를 꺼야 하나?

도구가 있고 모델이 gpt-6-astra 또는 gpt-6.1-sol이면 그 호출은 Responses로 옮긴다. 이 둘의 Chat Completions는 도구 없는 요청을 아직 보낼 수 있다. gpt-6-sol과 gpt-6-luna는 reasoning_effort가 none일 때만 Chat Completions에서 함수를 호출한다. 추론과 함께 도구를 쓰려면 Responses.

Decisions가 function_call을 낼 수 있나?

낼 수 없다. 타입이 있는 답을 반환한다. predicate의 probability, choice, 또는 score. 호스트가 choice를 이미 있는 함수에 대응시킨다. 공개 베타 엔드포인트는 POST /v1/decisions이고, 현재 모델은 gpt-6-luna뿐이다. 공식은 Responses보다 약 10배 빠르다고 적는다. 그것은 분류 속도이지 주문 조회가 아니다.

strict를 빼면 어떻게 되나?

Chat Completions는 기본이 비엄격이다. Responses는 strict를 빼면 엄격 모드를 시도한다. Schema가 맞지 않으면 되돌리고, 반환된 도구는 strict: false다. 비엄격을 유지하려면 false를 명시한다. 모델 쪽이 엄격하든 아니든 호스트는 arguments를 다시 검증한다.

기존 Agents session의 되돌려 쓰기를 바꿔야 하나?

바꾸지 않는다. Agents API는 아직 공개 베타다. 되돌려 쓰기는 turn_id로 남긴다. Computer Use는 호스트된 브라우저의 별도 권한이고, 사이트 승인과 로그인은 앱이 처리한다. 매 홉을 직접 쥐려면 Responses의 function_call_output을 유지한다.

Ultrafast가 도구 JSON을 바꾸나?

바꾸지 않는다. gpt-6-astra의 service_tier: ultrafast이며, 미국 데이터 레지던시와 글로벌 처리만 지원한다. 도구 정의, call_id, Schema는 그대로다. GPT-6.1 Sol Ultrafast를 이미 쓸 수 있는 것으로 쓰지 않는다.

결론

DevDay 2026 이후 JSON Tool Calling 이전은 되돌려 쓰는 모양을 바꾸는 일이다. Astra와 GPT-6.1 Sol의 도구 호출은 Responses. name은 type과 같은 층. 결과는 call_id로 돌아온다. 열거만 고르는 홉은 Decisions로 옮길 수 있다. 조회는 호스트가 실행한다.

A-1042가 lookup_order의 arguments로 가는지, Decisions의 input으로 가는지 먼저 적는다. call_3c91과 answers[0].choice를 가리킬 수 있으면 트래픽을 바꾼다.

이어서 읽기

변경 기록: 처음 게시