~22 min · openai, responses-api, tool-calls, input
Level 0호기심 많은 독자
0 XP0/48 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete
OpenAI 의 요즘 API 는 Responses API 야. 옛 Chat Completions endpoint 도 아직 돌아가지만, 새로 짜는 코드는 Responses 를 겨냥해야 해 — text 와 tool, vision, structured output 에 걸쳐 모양이 훨씬 고르거든. 옛 튜토리얼을 보다 가장 많이 걸려 넘어지는 데가 여기야. 새 endpoint 는 input 을 받는데 messages 를 그대로 쓰는 거지.
흐름은 이래. tools 리스트를 만들고, user 메시지를 input 에 담아 client.responses.create 를 부르고, response 의 output 을 훑어. Tool call 은 type: "function_call" 인 항목으로 나오고, 거기에 name 과 arguments, call_id 가 실려 있어. arguments 는 JSON 문자열이야 — 진짜 문자열. 함수를 실행한 다음, 결과를 같은 call_id 를 가리키는 function_call_output 항목으로 만들어 다음 호출의 input 에 넣어줘.
OpenAI 의 tool 정의는 tool object 의 맨 위에 놓여. type: "function", name, description, parameters. (옛 Chat Completions 는 name 과 description 을 function 이라는 하위 object 안에 넣었어. 옛 예제를 보고 헷갈리지 마.) tool_choice 에는 "auto", "none", "required" 를 주거나, 특정 함수를 지목하는 object 를 줘.
Streaming 은 event 로 흘러. 조각마다 type 이 붙어서 response.created, response.output_text.delta, response.tool_calls.delta, 마지막에 response.completed 가 와. Tool call 을 streaming 으로 받을 땐 arguments 조각을 문자열로 계속 쌓아뒀다가, 호출이 끝나면 그때 JSON 으로 parse 하면 돼.
Code
OpenAI Responses 의 왕복 한 바퀴·python
import json
from openai import OpenAI
client = OpenAI()
tools = [{
"type": "function",
"name": "get_weather",
"description": "Get current weather for a city.",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string"}},
"required": ["location"],
},
}]
def get_weather(location: str) -> str:
return f"68°F and clear in {location}"
# Turn 1: 모델한테 물어봄
input_items = [{"role": "user", "content": "Weather in Seoul?"}]
resp = client.responses.create(model="gpt-4.1", tools=tools, input=input_items)
# Output 의 모든 tool call 뽑음
tool_calls = [item for item in resp.output if item.type == "function_call"]
for tc in tool_calls:
args = json.loads(tc.arguments)
result = get_weather(**args)
input_items.append({"type": "function_call", "call_id": tc.call_id, "name": tc.name, "arguments": tc.arguments})
input_items.append({"type": "function_call_output", "call_id": tc.call_id, "output": result})
# Turn 2: 결과로 계속
final = client.responses.create(model="gpt-4.1", tools=tools, input=input_items)
print(final.output_text)
Tool call 을 streaming 으로 받기·python
stream = client.responses.create(model="gpt-4.1", tools=tools, input=[...], stream=True)
buf = ""
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
elif event.type == "response.tool_calls.delta":
# arguments 가 JSON 문자열로 조각조각 도착
buf += event.delta.arguments
elif event.type == "response.completed":
print()
위 두 turn 짜리 흐름을 gpt-4.1 (또는 읽는 시점의 OpenAI 최신 모델) 로 구현해봐. Streaming response 의 event 를 전부 찍어. tool_calls.delta event 가 호출이 발동하기 전에 차곡차곡 쌓이는 걸 보고, stream 의 어느 지점에서 그게 실제로 parse 가능한 JSON 이 되는지 확인해.
Progress
Progress is local-only — sign in to sync across devices.