October 19, 2025

Open AI Responses API

 

Open AI Responses API

  • Conversation = the long-lived thread (the big container you append to over time).

  • Response = one model run (the container for this run’s outputs).

  • Item = the atomic node (user/assistant messages, tool calls, tool results, images, structured outputs, etc.). Items can link to each other (forming a little step/tree inside a Response).

Who contains whom?

  • A Conversation stores the full history as a timeline of Items.

  • Each Response produces a set of Items (including your input item and the assistant/tool outputs) and appends them into a target Conversation when you use a conversation_id.

  • Items live inside Responses and are saved under the Conversation; tool calls and tool results are separate Items that reference each other, which is why they can look like a small tree.



Conversation and Response

Example 1 — One conversation, several responses

Conversation C-123 (long-lived thread) └── Response R-1 │ ├─ Item: user_message("What’s the weather in SF?") │ ├─ Item: tool_call(getWeather, id=tc1) │ ├─ Item: tool_result(for tc1, data="72°F, sunny") │ └─ Item: assistant_message("72°F and sunny.") │ └── Response R-2 ├─ Item: user_message("Plan a 3-hr walk.") ├─ Item: tool_call(routePlanner, id=tc2) ├─ Item: tool_result(for tc2, data="route.json") └─ Item: assistant_message("Here’s a scenic route…")
  • C-123 contains everything from R-1 and R-2.

  • Each Response groups the Items created in that single run; tool call/result Items link by ID (a small tree).

Example 2 — Two separate conversations (different threads)

Conversation TRAVEL-1 └─ Response A-1 ├─ Item: user_message("Find cheap flights to Tokyo.") ├─ Item: tool_call(searchFlights, id=tcA) ├─ Item: tool_result(for tcA, data="price list") └─ Item: assistant_message("Best options are…") Conversation WORK-1 └─ Response B-1 ├─ Item: user_message("Draft a PRD outline.") └─ Item: assistant_message("Here’s a PRD template…")
  • Items never cross between conversations; each thread is its own container.

Example 3 — Conversation and responses

E.g. 3.1 — All under the same conversation_id (shared timeline)

Conversation C-123 (long-lived thread) └── Response R-1 │ └─ (start of the thread) │ ├── Response R-2 (previous_response_id = R-1) │ └─ (branch A from R-1) │ └── Response R-3 (previous_response_id = R-1) └─ (branch B from R-1) # Now create R-4 from R-2: └── Response R-4 (previous_response_id = R-2) NOTE: Because all of these live in the same Conversation C-123, R-4 will usually "see" R-3 as well (shared context), subject to the model’s context window and truncation. 

E.g. 3.2 — No conversation_id, only chaining with previous_response_id (isolated branches)

Chain A └── Response R-1 └── Response R-2 (previous_response_id = R-1) └── Response R-4 (previous_response_id = R-2) Chain B └── Response R-3 (previous_response_id = R-1) NOTE: Here, R-4 inherits context only from its own chain (R-2 → R-1). It does NOT include the sibling branch R-3.

One-liner:

  • Same conversation → branches can see each other (within context limits).

  • Only previous_response_id chains (no conversation) → branches are isolated.

Response and Item

Example — Zoom-in on one Response’s item tree

Response R-2 (from Example 1) ├─ Item: user_message("Plan a 3-hr walk.") ├─ Item: tool_call(routePlanner, id=tc2) │ ├─ Item: tool_call(elevationAPI, id=tc2a) (optional nested step) │ │ └─ Item: tool_result(for tc2a) │ └─ Item: tool_result(for tc2) └─ Item: assistant_message("Here’s a scenic route…")
  • This is the in-Response step/tree made of Items (calls ↔ results ↔ final message). 


Why the API is designed this way (in brief)

The Responses API unifies message types as Items, supports tool use (tool calls/results as Items), and makes it easy to append state to a Conversation. It’s the recommended foundation for agent-style apps (multi-turn, tool-using).

Related Links


No comments:

Post a Comment