1# Preserved reasoning
2
3> For the complete documentation index, see [llms.txt](/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.
4
5When you continue a conversation with the Responses API, a model can reuse
6reasoning items from an earlier response. To preserve that reasoning when you
7manage conversation history, keep the history that produced it intact and append
8new messages and tool results at the end. The selected model and
9[`reasoning.context` setting](https://developers.openai.com/api/docs/guides/reasoning#preserve-reasoning-across-calls)
10determine which available reasoning items the model can use.
11
12## How history changes affect reasoning
13
14For newer frontier models, the API checks the conversation history before each
15reasoning item you send back. This history is the item's _prefix_. If you edit,
16shorten, or insert a message in that prefix, the API drops the affected
17reasoning. The request can continue with the conversation you provide, and the
18model can generate new reasoning.
19
20For example, an agent calls a ledger tool and uses the returned rows to
21investigate a discrepancy. On the next request, your app replaces those rows
22with a subtotal. The model can still reuse reasoning it used to choose the tool,
23but the API drops reasoning that depended on the original rows, even if you send the
24reasoning item back unchanged.
25
26## Append new instructions
27
28When you manage history yourself, keep the previous input and the response's
29output items in their original order. Add new instructions at the point where
30they take effect.
31
32This example uses the Python SDK in stateless mode with a model that supports
33`reasoning.context` set to `all_turns`. Stateless responses
34include encrypted reasoning content by default. See
35[Preserve reasoning without stored responses](https://developers.openai.com/api/docs/guides/reasoning#preserve-reasoning-without-stored-responses).
36
37Append instructions to a conversation
38
39```python
40from openai import OpenAI
41
42client = OpenAI()
43model = "gpt-6.1-sol"
44history = [{"role": "user", "content": "Compare invoice A ($80) and B ($95)."}]
45
46first = client.responses.create(
47 model=model,
48 reasoning={"context": "all_turns"},
49 input=history,
50 store=False,
51)
52
53next_input = [
54 *history,
55 *(item.to_dict() for item in first.output),
56 {
57 "role": "developer",
58 "content": "For the reconciliation report, use a Markdown table.",
59 },
60 {"role": "user", "content": "Add invoice C ($110) and show the total."},
61]
62report = client.responses.create(
63 model=model,
64 reasoning={"context": "all_turns"},
65 input=next_input,
66 store=False,
67)
68print(report.output_text)
69```
70
71
72If you use stored responses, you can continue from the prior response with
73`previous_response_id` and send only the new input items. See
74[Conversation state](https://developers.openai.com/api/docs/guides/conversation-state).
75
76## Migrate away from prefix edits
77
78Compare two consecutive requests in a workflow that reuses reasoning. Find the
79first place your app changes an item it already sent, then choose the migration
80that matches the edit.
81
82| If your app edits… | Migrate to… |
83| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
84| Older turns during compaction | Use OpenAI compaction and continue from the returned context. If you create a portable text summary, let the model reason from it. Replacing the prefix can invalidate reasoning you replay after the summary. If the history includes `configuration_update` items, use an explicit `compaction_trigger`, then append a fresh update before the next user message. Restate every setting you changed, including the format if applicable. Automatic compaction, automatic truncation, and standalone `/responses/compact` don't support histories containing these updates. |
85| Developer instructions | Append a developer message when the instruction takes effect. If the response is already running, use mid-turn steering where supported. |
86| The tool list when switching modes | Keep known tool definitions stable. Restrict the next request with `tool_choice` of type `allowed_tools`. To introduce new tools, append an `additional_tools` input item with role `developer` and the definitions in `tools`. Replay it in its original position. |
87| A tool result the model has already seen | Filter the result before sending `function_call_output` the first time. If the data changes, append a correction or return it from a new tool call. |
88
89For more on managing long conversations, see
90[Compaction](https://developers.openai.com/api/docs/guides/compaction).