<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Reasoning on KbWen Blog</title>
    <link>https://www.kbwen.com/tags/reasoning/</link>
    <description>Articles and notes on AI systems, machine learning, Python, data engineering, and software development.</description>
    <generator>Hugo</generator>
    <language>zh-tw</language>
    <image>
      <url>https://www.kbwen.com/images/og-default.png</url>
      <title>KbWen Blog</title>
      <link>https://www.kbwen.com/</link>
    </image>
    
    <lastBuildDate>Mon, 02 Nov 2026 22:26:21 +0800</lastBuildDate><atom:link href="https://www.kbwen.com/tags/reasoning/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Passing back reasoning items in the OpenAI Responses API</title>
      <link>https://www.kbwen.com/openai-reasoning-models-stateful-context-management/</link>
      <pubDate>Mon, 02 Nov 2026 22:26:21 +0800</pubDate><dc:creator>KbWen</dc:creator>
      <guid>https://www.kbwen.com/openai-reasoning-models-stateful-context-management/</guid>
      <description>We look at the reasoning items the OpenAI Responses API returns during a tool loop and how to send them back.</description>
      <content:encoded><![CDATA[<p>When a reasoning model on OpenAI&rsquo;s Responses API calls a tool, the response&rsquo;s <code>output</code> array can hold items of type <code>reasoning</code> alongside the function call. With <code>store: false</code>, one of them looks roughly like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;rs_...&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;reasoning&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;summary&#34;</span><span class="p">:</span> <span class="p">[],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;encrypted_content&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;long encrypted string&gt;&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>There isn&rsquo;t much in it for your code to use. The items are opaque, the API doesn&rsquo;t return their reasoning text, and <code>summary</code> stays empty unless you opt in to summaries. So it&rsquo;s easy to write a tool loop that keeps the function call and throws the rest away.</p>
<p>But OpenAI&rsquo;s docs ask you to send these items back. The <a href="https://developers.openai.com/api/docs/guides/function-calling">function calling guide</a> says they &ldquo;must also be passed back with tool call outputs&rdquo;. The <a href="https://developers.openai.com/api/docs/guides/reasoning">reasoning guide</a> says &ldquo;we highly recommend&rdquo; it, because that &ldquo;allows the model to continue its reasoning process to produce better results in the most token-efficient manner.&rdquo; When the model calls several functions in a row, that covers every reasoning item, function call and function output since the last user message.</p>
<p>You don&rsquo;t have to work out which items matter, because the simplest option is to send all of them, and the service ignores the ones that aren&rsquo;t relevant to your functions. If you trim history to save tokens, make sure everything between the last user message and your function output goes into the next request untouched.</p>
<h2 id="sending-them-back">Sending them back</h2>
<p>How you send them depends on whether OpenAI kept the response. <a href="https://developers.openai.com/api/docs/guides/migrate-to-responses">Responses are stored by default</a>, and in that case <code>previous_response_id</code> is enough: you pass the ID along with your function output, and your code never handles the earlier items.</p>
<p>With <code>store: false</code> there is no stored response to continue from, and the same goes for organizations on Zero Data Retention, so the items have to go into <code>input</code> by hand. The function calling guide&rsquo;s Python sample does it this way:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">input_list</span> <span class="o">+=</span> <span class="n">response</span><span class="o">.</span><span class="n">output</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># after running the tool</span>
</span></span><span class="line"><span class="cl"><span class="n">input_list</span><span class="o">.</span><span class="n">append</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;function_call_output&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;call_id&#34;</span><span class="p">:</span> <span class="n">item</span><span class="o">.</span><span class="n">call_id</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;output&#34;</span><span class="p">:</span> <span class="n">horoscope</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span></code></pre></div><p>The next request depends on the <code>encrypted_content</code> string in that list. When a request includes it, the migration guide says, &ldquo;it is decrypted in memory, used for generating the next response, and then securely discarded&rdquo;, and any new reasoning tokens come back encrypted. So your code has to hold on to those strings between calls.</p>
<h2 id="earlier-turns">Earlier turns</h2>
<p>Everything so far is about one turn, the run of tool calls after a single user message. Reasoning from earlier turns has its own setting, <code>reasoning.context</code>. With <code>current_turn</code>, reasoning from the active turn is available, but reasoning from earlier turns doesn&rsquo;t go into the next sample. With <code>all_turns</code>, the available and compatible items from earlier turns go in too. Currently the GPT-5.6 models use <code>all_turns</code> by default and earlier models default to <code>current_turn</code>.</p>
<p><code>all_turns</code> only has an effect when the request can reach the earlier items, through <code>previous_response_id</code>, a conversation, or replaying the complete history yourself, which also works with <code>store: false</code>. The setting can&rsquo;t bring back items your loop already threw away.</p>
<p>This note was put together from OpenAI&rsquo;s current docs, and nothing here was run against the API, so we don&rsquo;t have a number for what a dropped reasoning item costs. If you&rsquo;ve measured it, we&rsquo;d be glad to see the numbers. For now we&rsquo;d keep the whole <code>output</code> list, and because the <code>reasoning.context</code> default already differs between model generations, look at the model&rsquo;s page before switching.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>OpenAI 的 reasoning tokens 怎麼計費</title>
      <link>https://www.kbwen.com/openai-reasoning-tokens-context-and-billing/</link>
      <pubDate>Mon, 02 Nov 2026 22:24:21 +0800</pubDate><dc:creator>KbWen</dc:creator>
      <guid>https://www.kbwen.com/openai-reasoning-tokens-context-and-billing/</guid>
      <description>我們來看看 OpenAI 的 reasoning tokens 是什麼，以及 API 的回傳用量。</description>
      <content:encoded><![CDATA[<p>OpenAI 的 reasoning 模型除了我們看到的回覆，還會多產生一些思考的 token，也就是 <a href="https://developers.openai.com/api/docs/guides/reasoning">reasoning tokens</a>，模型會用這些 token 來規劃、使用工具，以及檢視其他可能的做法。</p>
<p>這些原始內容不會出現在 API 的回傳裡（有些模型可以另外要求思考內容的摘要），但是它們仍然會佔用 context window 的空間，也會以輸出 token 計費。這有點像寫數學題時用的計算紙，雖然最後交出去的是答案，但是中途卻會用掉很多紙。因此，如果只用畫面上的字數來估算輸出費用，就會少算到這部分。</p>
<p>影響就要看問題的複雜程度，reasoning tokens 可能從幾百個到幾萬個，簡單的任務相對會比較少。</p>
<h2 id="要去哪裡看用量">要去哪裡看用量</h2>
<p>每次呼叫可以看回應裡的 <code>usage</code>，下面是 <a href="https://developers.openai.com/api/docs/guides/reasoning">OpenAI 指南</a>裡的範例：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;usage&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;input_tokens&#34;</span><span class="p">:</span> <span class="mi">75</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;input_tokens_details&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;cached_tokens&#34;</span><span class="p">:</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;output_tokens&#34;</span><span class="p">:</span> <span class="mi">1186</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;output_tokens_details&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;reasoning_tokens&#34;</span><span class="p">:</span> <span class="mi">1024</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;total_tokens&#34;</span><span class="p">:</span> <span class="mi">1261</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p><code>output_tokens</code> 是模型產生的所有 token，在這個例子裡共有 1186 個，其中 1024 個是 <code>reasoning_tokens</code>。不過要知道這兩個數字相減也不一定就等於畫面上的文字，因為<a href="https://developers.openai.com/api/docs/guides/token-counting">有些模型</a>還會產生格式用的 token，而這部分不一定會另外列出來。</p>
<h2 id="那上限要怎麼設">那上限要怎麼設</h2>
<p>如果想控制費用，可以用 <code>max_output_tokens</code> 限制模型產生的 token 總數。但是上限設得太低的話，模型可能還在思考就把額度用完了。此時回應的 <code>status</code> 會是 <code>incomplete</code>，原因（<code>incomplete_details.reason</code>）是 <code>max_output_tokens</code>，裡面可能沒有任何看得到的文字，而輸入和 reasoning tokens 還是可能要付費。碰到 context window 的上限也是同樣的結果，所以串接時也要記得檢查 <code>status</code>，並不是只看成功或是敗而已。</p>
<p>OpenAI 建議剛開始試用時，替 reasoning 和輸出預留至少 25,000 個 token，等到比較清楚自己的 prompt 大概需要多少，再來調整，這時就可以回頭參考前面的 <code>reasoning_tokens</code>。</p>
<p>如果想讓模型少想一點，也可以把 <code>reasoning.effort</code> 調低，速度會比較快，用的 token 也會比較少，但是回答可能就沒有那麼完整。我相信大家都是用這樣省token的，畢竟不是那麼的夠用。</p>
<p>其他關於 token 成本的想法，可以參考之前寫的<a href="/token-cost-and-budget-tiers/">Token 成本的真相：分級，但別分太細</a>。</p>
<p>這篇是照 OpenAI 目前的 reasoning 和 token counting 文件寫的。effort 的選項、預設值和 context window 的大小都會隨模型不同，之後應該也還會再變，所以最終還是看每次呼叫回傳的 <code>usage</code> 比較準。</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
