<?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/"><channel><title>Coding-Agent on Tarragon</title><link>https://tarrragon.github.io/blog/tags/coding-agent/</link><description>Recent content in Coding-Agent on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Tue, 12 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/coding-agent/index.xml" rel="self" type="application/rss+xml"/><item><title>Context Budget</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/context-budget/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/context-budget/</guid><description>&lt;p>Context budget 的核心概念是「&lt;strong>把 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window&lt;/a> 視為有限資源、明確規劃 system prompt / tool schema / history / file content / reasoning trace / tool result 各佔多少&lt;/strong>」。coding agent 的最大失敗模式是「context 用爆 → 模型開始遺忘關鍵指令 → 行為飄」、預算化是 harness 設計的核心責任。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>典型 coding agent 的 context 構成（以 200K 模型為例）：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">[1. System prompt + tool schema]： 固定 ~10K-30K
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> - agent 角色、輸出規則、tool 列表 + spec、subagent 路由
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> - 經常用 prompt cache 加速、見 [prompt cache 卡]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">[2. 工作歷史 / conversation history]： 動態 0-60K
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> - 過去回合的 user query + assistant answer + tool calls
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> - 越長越貴、harness 要決定何時 summarize / trim
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">[3. 當前任務 file context]： 動態 0-100K
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> - 開啟的檔案、grep 結果、@-mention 帶入的內容
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">[4. Reasoning trace（若 reasoning model）]： 動態 1K-10K / step
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl"> - &amp;lt;think&amp;gt;...&amp;lt;/think&amp;gt; 段、每次推論都會佔 context
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl">[5. Tool result]： 動態 0-50K
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl"> - file read 結果、bash output、test result
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">18&lt;/span>&lt;span class="cl">[6. Margin / safety buffer]： 保留 20-30K
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">19&lt;/span>&lt;span class="cl"> - 防止 generation 階段碰到 context limit&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>主流 coding agent 的 25% 規則（&lt;a href="https://tarrragon.github.io/blog/llm/04-applications/coding-agent-harness/" data-link-title="4.17 Coding agent harness：scaffold / context engineering / subagent" data-link-desc="Coding agent 的內部設計：scaffold vs harness 分層、context budget 25% 規則、subagent 拓樸、跟 Claude Code / Cursor / Aider 的 mapping">context engineering 慣例&lt;/a>）：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>規則&lt;/th>
 &lt;th>直覺&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Scaffold 部分（1+2） ≤ 25%&lt;/td>
 &lt;td>留 75% 給「當下任務」、避免 lost-in-the-middle 把指令吃掉&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>File content ≤ 50%&lt;/td>
 &lt;td>不全載入大檔、用 grep / chunked read 替代&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Margin ≥ 10%&lt;/td>
 &lt;td>Generation 階段才不會被 context limit 截斷&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Reasoning trace 配長 context&lt;/td>
 &lt;td>Reasoning model 至少配 64K context、見 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/reasoning-model/" data-link-title="Reasoning Model" data-link-desc="訓練成自然輸出長 reasoning trace 的 LLM 變體、o1 / DeepSeek-R1 / Claude thinking 為代表">reasoning-model 卡&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 coding agent 設計 / harness paper 看到「context budget」「context engineering」「token budgeting」就是這 framing。寫 code 場景的判讀：&lt;/p></description><content:encoded><![CDATA[<p>Context budget 的核心概念是「<strong>把 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a> 視為有限資源、明確規劃 system prompt / tool schema / history / file content / reasoning trace / tool result 各佔多少</strong>」。coding agent 的最大失敗模式是「context 用爆 → 模型開始遺忘關鍵指令 → 行為飄」、預算化是 harness 設計的核心責任。</p>
<h2 id="概念位置">概念位置</h2>
<p>典型 coding agent 的 context 構成（以 200K 模型為例）：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">[1. System prompt + tool schema]：     固定 ~10K-30K
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">   - agent 角色、輸出規則、tool 列表 + spec、subagent 路由
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">   - 經常用 prompt cache 加速、見 [prompt cache 卡]
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">[2. 工作歷史 / conversation history]：  動態 0-60K
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">   - 過去回合的 user query + assistant answer + tool calls
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">   - 越長越貴、harness 要決定何時 summarize / trim
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">[3. 當前任務 file context]：           動態 0-100K
</span></span><span class="line"><span class="ln">10</span><span class="cl">   - 開啟的檔案、grep 結果、@-mention 帶入的內容
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl">[4. Reasoning trace（若 reasoning model）]：  動態 1K-10K / step
</span></span><span class="line"><span class="ln">13</span><span class="cl">   - &lt;think&gt;...&lt;/think&gt; 段、每次推論都會佔 context
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl">[5. Tool result]：                    動態 0-50K
</span></span><span class="line"><span class="ln">16</span><span class="cl">   - file read 結果、bash output、test result
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl">[6. Margin / safety buffer]：         保留 20-30K
</span></span><span class="line"><span class="ln">19</span><span class="cl">   - 防止 generation 階段碰到 context limit</span></span></code></pre></div><p>主流 coding agent 的 25% 規則（<a href="/blog/llm/04-applications/coding-agent-harness/" data-link-title="4.17 Coding agent harness：scaffold / context engineering / subagent" data-link-desc="Coding agent 的內部設計：scaffold vs harness 分層、context budget 25% 規則、subagent 拓樸、跟 Claude Code / Cursor / Aider 的 mapping">context engineering 慣例</a>）：</p>
<table>
  <thead>
      <tr>
          <th>規則</th>
          <th>直覺</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Scaffold 部分（1+2） ≤ 25%</td>
          <td>留 75% 給「當下任務」、避免 lost-in-the-middle 把指令吃掉</td>
      </tr>
      <tr>
          <td>File content ≤ 50%</td>
          <td>不全載入大檔、用 grep / chunked read 替代</td>
      </tr>
      <tr>
          <td>Margin ≥ 10%</td>
          <td>Generation 階段才不會被 context limit 截斷</td>
      </tr>
      <tr>
          <td>Reasoning trace 配長 context</td>
          <td>Reasoning model 至少配 64K context、見 <a href="/blog/llm/knowledge-cards/reasoning-model/" data-link-title="Reasoning Model" data-link-desc="訓練成自然輸出長 reasoning trace 的 LLM 變體、o1 / DeepSeek-R1 / Claude thinking 為代表">reasoning-model 卡</a></td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 coding agent 設計 / harness paper 看到「context budget」「context engineering」「token budgeting」就是這 framing。寫 code 場景的判讀：</p>
<ol>
<li><strong>超出 budget 的訊號</strong>：模型開始忽略 system prompt、回答跟前文重複、tool call 重複過去步驟、reasoning trace 截斷</li>
<li><strong>節省 budget 的策略</strong>：用 <a href="/blog/llm/knowledge-cards/prompt-cache/" data-link-title="Prompt Cache" data-link-desc="重複出現的 prompt prefix 在推論伺服器或 LLM 服務端被 cache、後續 query 跳過 prefill、大幅降 cost 跟 TTFT">prompt cache</a> 把 system + tool schema 攤平、grep 取代全檔讀、tool result 限長度（如 head -100）、定期 summarize history</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/lost-in-the-middle/" data-link-title="Lost in the Middle" data-link-desc="LLM 對 long context 中段內容的 attention / recall 顯著低於開頭與結尾的現象">lost-in-the-middle</a> 的關係</strong>：context 用越多、中段內容 recall 越差、所以「能用 20K 解就別用 100K」、不是「能塞 200K 就塞滿」</li>
<li><strong>不同 task 不同 budget</strong>：autocomplete 任務 budget 小（系統 prompt + 最近 50 行 code 就夠）；refactor 任務 budget 大（多檔案）；agent loop 任務 budget 動態（每步可能 grow）</li>
</ol>
]]></content:encoded></item><item><title>Scaffold vs Harness</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/scaffold-vs-harness/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/scaffold-vs-harness/</guid><description>&lt;p>Scaffold 跟 harness 的核心概念是「&lt;strong>把 coding agent 拆成『建構時靜態結構』跟『runtime 動態邏輯』兩層&lt;/strong>」。Scaffold 是建構時就決定的：system prompt 模板、tool schema 註冊、subagent 拓樸；harness 是 runtime 動態運作：tool dispatch、context budget 管理、safety / 中斷、handoff。Claude Code、Cursor、Aider、Codex 這類 coding agent 的內部設計都遵循這個分層。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>兩層的職責劃分：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">Scaffold（建構時、static）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> ├── System prompt 模板（角色、約束、輸出格式）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> ├── Tool schema 註冊（read_file / write_file / run_bash 等的 spec）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> ├── Subagent 拓樸（main agent + 子 agent 的調用關係）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> ├── Skill / playbook 註冊
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> └── 安全 policy（什麼可寫、什麼要 confirm）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> ↓ 編譯 / 載入
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">Harness（runtime、dynamic）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> ├── Tool dispatch（接 LLM tool call、執行、回 result）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> ├── Context budget 管理（剪裁歷史、塞新內容、不超 25% 規則）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl"> ├── Safety / 中斷（confirm UI、permission boundary、可逆性檢查）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl"> ├── Error recovery（tool failed → retry / fallback / escalate）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl"> └── Telemetry（trace / metrics / cost）&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>跟既有概念的關係：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>概念&lt;/th>
 &lt;th>跟 scaffold / harness 的關係&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/system-prompt/" data-link-title="System Prompt" data-link-desc="LLM application 中由開發者預設、不直接顯示給使用者的指令層、定義模型的角色、行為規範、輸出格式">System prompt&lt;/a>&lt;/td>
 &lt;td>Scaffold 的核心元件、定義 agent 角色&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">Tool use&lt;/a>&lt;/td>
 &lt;td>Scaffold 註冊 tool spec、Harness 在 runtime dispatch&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">Agent loop&lt;/a>&lt;/td>
 &lt;td>Harness 的核心 loop（perceive / reason / act / observe / terminate）&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/function-calling/" data-link-title="Function Calling" data-link-desc="模型訓練階段建立的「呼叫工具」能力：知道何時該呼叫、傳什麼參數">Function calling&lt;/a>&lt;/td>
 &lt;td>Tool spec 的具體 protocol&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 coding agent paper / blog 看到「scaffold」「harness」「context engineering」就是這 framing。寫 code 場景的判讀：&lt;/p></description><content:encoded><![CDATA[<p>Scaffold 跟 harness 的核心概念是「<strong>把 coding agent 拆成『建構時靜態結構』跟『runtime 動態邏輯』兩層</strong>」。Scaffold 是建構時就決定的：system prompt 模板、tool schema 註冊、subagent 拓樸；harness 是 runtime 動態運作：tool dispatch、context budget 管理、safety / 中斷、handoff。Claude Code、Cursor、Aider、Codex 這類 coding agent 的內部設計都遵循這個分層。</p>
<h2 id="概念位置">概念位置</h2>
<p>兩層的職責劃分：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">Scaffold（建構時、static）：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  ├── System prompt 模板（角色、約束、輸出格式）
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  ├── Tool schema 註冊（read_file / write_file / run_bash 等的 spec）
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  ├── Subagent 拓樸（main agent + 子 agent 的調用關係）
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">  ├── Skill / playbook 註冊
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">  └── 安全 policy（什麼可寫、什麼要 confirm）
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">   ↓ 編譯 / 載入
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">Harness（runtime、dynamic）：
</span></span><span class="line"><span class="ln">11</span><span class="cl">  ├── Tool dispatch（接 LLM tool call、執行、回 result）
</span></span><span class="line"><span class="ln">12</span><span class="cl">  ├── Context budget 管理（剪裁歷史、塞新內容、不超 25% 規則）
</span></span><span class="line"><span class="ln">13</span><span class="cl">  ├── Safety / 中斷（confirm UI、permission boundary、可逆性檢查）
</span></span><span class="line"><span class="ln">14</span><span class="cl">  ├── Error recovery（tool failed → retry / fallback / escalate）
</span></span><span class="line"><span class="ln">15</span><span class="cl">  └── Telemetry（trace / metrics / cost）</span></span></code></pre></div><p>跟既有概念的關係：</p>
<table>
  <thead>
      <tr>
          <th>概念</th>
          <th>跟 scaffold / harness 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/system-prompt/" data-link-title="System Prompt" data-link-desc="LLM application 中由開發者預設、不直接顯示給使用者的指令層、定義模型的角色、行為規範、輸出格式">System prompt</a></td>
          <td>Scaffold 的核心元件、定義 agent 角色</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/tool-use/" data-link-title="Tool Use" data-link-desc="LLM 透過結構化呼叫外部工具（讀檔、查資料庫、發 API request）來擴展能力的設計、function calling 跟 MCP 是常見實作">Tool use</a></td>
          <td>Scaffold 註冊 tool spec、Harness 在 runtime dispatch</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">Agent loop</a></td>
          <td>Harness 的核心 loop（perceive / reason / act / observe / terminate）</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/function-calling/" data-link-title="Function Calling" data-link-desc="模型訓練階段建立的「呼叫工具」能力：知道何時該呼叫、傳什麼參數">Function calling</a></td>
          <td>Tool spec 的具體 protocol</td>
      </tr>
  </tbody>
</table>
<h2 id="設計責任">設計責任</h2>
<p>讀 coding agent paper / blog 看到「scaffold」「harness」「context engineering」就是這 framing。寫 code 場景的判讀：</p>
<ol>
<li><strong>看新 coding agent 時、分兩層拆解</strong>：scaffold（system prompt、tool list、subagent 結構）是「設計做了什麼」、harness（context 怎麼裁、tool 怎麼 dispatch、安全怎麼擋）是「runtime 怎麼跑」</li>
<li><strong>修改 / 客製 agent 時、看你動的是哪層</strong>：改 system prompt = 動 scaffold；改 tool 執行邏輯 = 動 harness</li>
<li><strong>跟 <a href="/blog/llm/04-applications/coding-agent-harness/" data-link-title="4.17 Coding agent harness：scaffold / context engineering / subagent" data-link-desc="Coding agent 的內部設計：scaffold vs harness 分層、context budget 25% 規則、subagent 拓樸、跟 Claude Code / Cursor / Aider 的 mapping">4.17 coding-agent harness</a> 的關係</strong>：本卡是定義、4.12 是 coding 場景的工程實務（context budget、scaffold 模式、harness pattern）</li>
</ol>
]]></content:encoded></item><item><title>Subagent</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/subagent/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/subagent/</guid><description>&lt;p>Subagent 的核心概念是「&lt;strong>把 coding agent 切成多個專責子 agent、每個有獨立 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window&lt;/a> 跟 system prompt、由 main agent 透過 handoff 機制調度&lt;/strong>」。代表設計：Claude Code 的 Task agent、OpenAI Agents SDK 的 handoff、Anthropic multi-agent research。是「context budget 不夠 + 任務跨多個 specialty」場景的工程選擇。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Single agent vs subagent 架構的對比：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">Single agent（無 subagent）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> Main agent context：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> [system prompt + tool schema + 跨所有 specialty 的 history + 所有 file content]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> ↓ 容易爆 context、specialty 互相干擾
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">Subagent 架構：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> Main agent context（路由 + 高階決策）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> [main system prompt + handoff tool spec + 高階任務歷史]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> ↓ 路由到 subagent
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> Subagent A context（如「跑測試」專家）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> [test-runner system prompt + 測試 tool + 測試相關 file]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl"> Subagent B context（如「寫 docs」專家）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl"> [docs system prompt + 寫 docs tool + 相關 docs 檔案]&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>主要好處：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Context budget 隔離&lt;/strong>：每個 subagent 只看自己 specialty 相關 context、不被別的 specialty 污染&lt;/li>
&lt;li>&lt;strong>System prompt 專門化&lt;/strong>：寫 docs 的 system prompt 跟跑測試的 system prompt 不同、各自最佳化&lt;/li>
&lt;li>&lt;strong>Specialty 路由&lt;/strong>：main agent 只決定「這個任務該交給哪個 subagent」、不直接做 specialty 工作&lt;/li>
&lt;/ol>
&lt;p>主要挑戰：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Handoff 設計&lt;/strong>：main agent 要怎麼選 subagent、怎麼傳 context、怎麼接 result&lt;/li>
&lt;li>&lt;strong>跨 subagent 共享狀態&lt;/strong>：codebase 知識、history、要避免重複 work&lt;/li>
&lt;li>&lt;strong>失敗模式&lt;/strong>：subagent 之間互相 deadlock、main agent 失去 high-level view、subagent 邊界劃錯&lt;/li>
&lt;/ol>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>讀 multi-agent / subagent paper / coding agent docs 看到「subagent」「handoff」「Task tool」「specialist agent」就是這 framing。寫 code 場景的判讀：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>何時用 subagent&lt;/strong>：單一 agent context 不夠用、specialty 邊界清楚（如 search / coding / testing / documentation）、main agent 的 system prompt 已太長&lt;/li>
&lt;li>&lt;strong>何時不用&lt;/strong>：任務簡單、specialty 邊界模糊（強行拆會增加 handoff overhead）、本地小模型（handoff 機制對小模型不穩）&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop&lt;/a> 的關係&lt;/strong>：每個 subagent 內部仍是 agent loop（perceive / reason / act / observe / terminate）、只是 loop 範圍縮窄&lt;/li>
&lt;li>&lt;strong>跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/scaffold-vs-harness/" data-link-title="Scaffold vs Harness" data-link-desc="Coding agent 的兩個工程層次：scaffold 是建構時靜態結構、harness 是 runtime 的 tool dispatch &amp;#43; context management &amp;#43; safety">scaffold vs harness&lt;/a> 的關係&lt;/strong>：subagent 註冊在 scaffold（建構時）、handoff 在 harness（runtime）執行&lt;/li>
&lt;/ol></description><content:encoded><![CDATA[<p>Subagent 的核心概念是「<strong>把 coding agent 切成多個專責子 agent、每個有獨立 <a href="/blog/llm/knowledge-cards/context-window/" data-link-title="Context Window" data-link-desc="模型一次能處理的最大 token 數量：prompt 加生成的總和上限">context window</a> 跟 system prompt、由 main agent 透過 handoff 機制調度</strong>」。代表設計：Claude Code 的 Task agent、OpenAI Agents SDK 的 handoff、Anthropic multi-agent research。是「context budget 不夠 + 任務跨多個 specialty」場景的工程選擇。</p>
<h2 id="概念位置">概念位置</h2>
<p>Single agent vs subagent 架構的對比：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">Single agent（無 subagent）：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  Main agent context：
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    [system prompt + tool schema + 跨所有 specialty 的 history + 所有 file content]
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    ↓ 容易爆 context、specialty 互相干擾
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">Subagent 架構：
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  Main agent context（路由 + 高階決策）：
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    [main system prompt + handoff tool spec + 高階任務歷史]
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">       ↓ 路由到 subagent
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">  Subagent A context（如「跑測試」專家）：
</span></span><span class="line"><span class="ln">12</span><span class="cl">    [test-runner system prompt + 測試 tool + 測試相關 file]
</span></span><span class="line"><span class="ln">13</span><span class="cl">
</span></span><span class="line"><span class="ln">14</span><span class="cl">  Subagent B context（如「寫 docs」專家）：
</span></span><span class="line"><span class="ln">15</span><span class="cl">    [docs system prompt + 寫 docs tool + 相關 docs 檔案]</span></span></code></pre></div><p>主要好處：</p>
<ol>
<li><strong>Context budget 隔離</strong>：每個 subagent 只看自己 specialty 相關 context、不被別的 specialty 污染</li>
<li><strong>System prompt 專門化</strong>：寫 docs 的 system prompt 跟跑測試的 system prompt 不同、各自最佳化</li>
<li><strong>Specialty 路由</strong>：main agent 只決定「這個任務該交給哪個 subagent」、不直接做 specialty 工作</li>
</ol>
<p>主要挑戰：</p>
<ol>
<li><strong>Handoff 設計</strong>：main agent 要怎麼選 subagent、怎麼傳 context、怎麼接 result</li>
<li><strong>跨 subagent 共享狀態</strong>：codebase 知識、history、要避免重複 work</li>
<li><strong>失敗模式</strong>：subagent 之間互相 deadlock、main agent 失去 high-level view、subagent 邊界劃錯</li>
</ol>
<h2 id="設計責任">設計責任</h2>
<p>讀 multi-agent / subagent paper / coding agent docs 看到「subagent」「handoff」「Task tool」「specialist agent」就是這 framing。寫 code 場景的判讀：</p>
<ol>
<li><strong>何時用 subagent</strong>：單一 agent context 不夠用、specialty 邊界清楚（如 search / coding / testing / documentation）、main agent 的 system prompt 已太長</li>
<li><strong>何時不用</strong>：任務簡單、specialty 邊界模糊（強行拆會增加 handoff overhead）、本地小模型（handoff 機制對小模型不穩）</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/agent-loop/" data-link-title="Agent Loop" data-link-desc="LLM agent 自我循環的工作流：LLM 規劃下一步、執行 tool、看結果、再規劃下一步、直到任務完成或停止條件觸發">agent loop</a> 的關係</strong>：每個 subagent 內部仍是 agent loop（perceive / reason / act / observe / terminate）、只是 loop 範圍縮窄</li>
<li><strong>跟 <a href="/blog/llm/knowledge-cards/scaffold-vs-harness/" data-link-title="Scaffold vs Harness" data-link-desc="Coding agent 的兩個工程層次：scaffold 是建構時靜態結構、harness 是 runtime 的 tool dispatch &#43; context management &#43; safety">scaffold vs harness</a> 的關係</strong>：subagent 註冊在 scaffold（建構時）、handoff 在 harness（runtime）執行</li>
</ol>
]]></content:encoded></item><item><title>4.17 Coding agent harness：scaffold / context engineering / subagent</title><link>https://tarrragon.github.io/blog/llm/04-applications/coding-agent-harness/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/04-applications/coding-agent-harness/</guid><description>&lt;p>教材整體 framing 是「LLM 寫 code 工程實務」、模組四前面 11 章寫的是&lt;strong>通用 LLM 應用層原理&lt;/strong>（RAG / tool use / agent / VLM 等）。本章補上「coding agent 怎麼設計」這層 — 為什麼 Claude Code / Cursor / Aider / Codex 這類工具長那樣、scaffold 跟 harness 怎麼分、context budget 怎麼配。本章把這些設計取捨從特定產品抽出來、寫成跨工具世代不變的工程原理。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本章後、你應該能：&lt;/p>
&lt;ol>
&lt;li>用 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/scaffold-vs-harness/" data-link-title="Scaffold vs Harness" data-link-desc="Coding agent 的兩個工程層次：scaffold 是建構時靜態結構、harness 是 runtime 的 tool dispatch &amp;#43; context management &amp;#43; safety">scaffold vs harness&lt;/a> 分層拆解任何 coding agent。&lt;/li>
&lt;li>對自己工作流計算 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/context-budget/" data-link-title="Context Budget" data-link-desc="Coding agent 的 context window 拆分配額：system prompt &amp;#43; tool schema &amp;#43; history &amp;#43; file content &amp;#43; reasoning &amp;#43; tool result 各佔多少、留多少 margin">context budget&lt;/a>、看到 budget 超標訊號時知道怎麼修。&lt;/li>
&lt;li>判斷何時值得拆 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/subagent/" data-link-title="Subagent" data-link-desc="Coding agent 中把特定責任拆給專門子 agent 的設計模式、各 subagent 有獨立 context、由 main agent 透過 handoff 調度">subagent&lt;/a>、何時用 single agent。&lt;/li>
&lt;li>看 Claude Code / Cursor / Aider 等 coding agent 的設計差異、能對應到本章 framing。&lt;/li>
&lt;/ol>
&lt;h2 id="scaffold-vs-harness-分層">Scaffold vs Harness 分層&lt;/h2>
&lt;p>Coding agent 的內部結構分兩層：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">Scaffold（建構時靜態結構、編譯 / 載入時就決定）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> - System prompt 模板（agent 角色、輸出約束、錯誤處理 policy）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> - Tool schema 註冊（read_file / write_file / run_bash / web_fetch 等 spec）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> - Subagent 拓樸（main agent + 子 agent 關係）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> - Skill / playbook 註冊（特定任務的 known recipe）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> - 安全 policy（permission boundary、要 confirm 的動作清單）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">Harness（runtime 動態運作、每個 query / loop iteration 跑）：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> - Tool dispatch（接 LLM tool call、call function、回 result）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> - Context budget 管理（剪裁 history、塞新內容、避免超 budget）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> - Safety / 中斷（confirm UI、permission check、可逆性判斷）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> - Error recovery（tool failed → retry / fallback / escalate）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl"> - Telemetry（trace / metrics / cost、見 [4.20 OTel tracing](/llm/04-applications/llm-tracing-and-observability/)）&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>不同 coding agent 的 scaffold / harness 比較：&lt;/p></description><content:encoded><![CDATA[<p>教材整體 framing 是「LLM 寫 code 工程實務」、模組四前面 11 章寫的是<strong>通用 LLM 應用層原理</strong>（RAG / tool use / agent / VLM 等）。本章補上「coding agent 怎麼設計」這層 — 為什麼 Claude Code / Cursor / Aider / Codex 這類工具長那樣、scaffold 跟 harness 怎麼分、context budget 怎麼配。本章把這些設計取捨從特定產品抽出來、寫成跨工具世代不變的工程原理。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本章後、你應該能：</p>
<ol>
<li>用 <a href="/blog/llm/knowledge-cards/scaffold-vs-harness/" data-link-title="Scaffold vs Harness" data-link-desc="Coding agent 的兩個工程層次：scaffold 是建構時靜態結構、harness 是 runtime 的 tool dispatch &#43; context management &#43; safety">scaffold vs harness</a> 分層拆解任何 coding agent。</li>
<li>對自己工作流計算 <a href="/blog/llm/knowledge-cards/context-budget/" data-link-title="Context Budget" data-link-desc="Coding agent 的 context window 拆分配額：system prompt &#43; tool schema &#43; history &#43; file content &#43; reasoning &#43; tool result 各佔多少、留多少 margin">context budget</a>、看到 budget 超標訊號時知道怎麼修。</li>
<li>判斷何時值得拆 <a href="/blog/llm/knowledge-cards/subagent/" data-link-title="Subagent" data-link-desc="Coding agent 中把特定責任拆給專門子 agent 的設計模式、各 subagent 有獨立 context、由 main agent 透過 handoff 調度">subagent</a>、何時用 single agent。</li>
<li>看 Claude Code / Cursor / Aider 等 coding agent 的設計差異、能對應到本章 framing。</li>
</ol>
<h2 id="scaffold-vs-harness-分層">Scaffold vs Harness 分層</h2>
<p>Coding agent 的內部結構分兩層：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">Scaffold（建構時靜態結構、編譯 / 載入時就決定）：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  - System prompt 模板（agent 角色、輸出約束、錯誤處理 policy）
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  - Tool schema 註冊（read_file / write_file / run_bash / web_fetch 等 spec）
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  - Subagent 拓樸（main agent + 子 agent 關係）
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">  - Skill / playbook 註冊（特定任務的 known recipe）
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">  - 安全 policy（permission boundary、要 confirm 的動作清單）
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">Harness（runtime 動態運作、每個 query / loop iteration 跑）：
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">  - Tool dispatch（接 LLM tool call、call function、回 result）
</span></span><span class="line"><span class="ln">10</span><span class="cl">  - Context budget 管理（剪裁 history、塞新內容、避免超 budget）
</span></span><span class="line"><span class="ln">11</span><span class="cl">  - Safety / 中斷（confirm UI、permission check、可逆性判斷）
</span></span><span class="line"><span class="ln">12</span><span class="cl">  - Error recovery（tool failed → retry / fallback / escalate）
</span></span><span class="line"><span class="ln">13</span><span class="cl">  - Telemetry（trace / metrics / cost、見 [4.20 OTel tracing](/llm/04-applications/llm-tracing-and-observability/)）</span></span></code></pre></div><p>不同 coding agent 的 scaffold / harness 比較：</p>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>Scaffold 特點</th>
          <th>Harness 特點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Claude Code</td>
          <td>Skill registry、subagent system、structured permission</td>
          <td>強 context budget 管理、explicit handoff、trace</td>
      </tr>
      <tr>
          <td>Cursor</td>
          <td>Composer + chat + tab、tool list 較簡</td>
          <td>IDE-integrated、tool dispatch 在 client + server 切</td>
      </tr>
      <tr>
          <td>Aider</td>
          <td>跟 git 緊密、edit-format spec</td>
          <td>Repl-style、自動 commit、線性 loop</td>
      </tr>
      <tr>
          <td>Codex CLI</td>
          <td>跟 OpenAI assistants API 對齊</td>
          <td>Stream-based、tool call 即時執行</td>
      </tr>
      <tr>
          <td>Continue.dev</td>
          <td>Plugin-style、provider 抽象</td>
          <td>較輕量、tool dispatch 在 plugin host</td>
      </tr>
  </tbody>
</table>
<p>關鍵理解：所有 coding agent 都遵循這個 framing、差異在「scaffold 多複雜」「harness 多強」、不是有沒有這兩層。</p>
<h2 id="context-budget-工程實務">Context Budget 工程實務</h2>
<p><a href="/blog/llm/knowledge-cards/context-budget/" data-link-title="Context Budget" data-link-desc="Coding agent 的 context window 拆分配額：system prompt &#43; tool schema &#43; history &#43; file content &#43; reasoning &#43; tool result 各佔多少、留多少 margin">Context budget</a> 是 coding agent harness 的核心責任。實務拆分（以 200K context 模型為例）：</p>
<table>
  <thead>
      <tr>
          <th>元件</th>
          <th>預算 %</th>
          <th>內容</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>System prompt + tool schema</td>
          <td>5-15%</td>
          <td>Agent 角色、輸出約束、tool spec</td>
      </tr>
      <tr>
          <td>Conversation history</td>
          <td>10-30%</td>
          <td>過去回合的 user query + assistant + tool call</td>
      </tr>
      <tr>
          <td>Current task file context</td>
          <td>30-50%</td>
          <td>開啟檔案、grep 結果、@-mention</td>
      </tr>
      <tr>
          <td>Tool result（current step）</td>
          <td>0-20%</td>
          <td>file read / bash output / test result</td>
      </tr>
      <tr>
          <td>Reasoning trace（若 reasoning model）</td>
          <td>0-15%</td>
          <td><code>&lt;think&gt;...&lt;/think&gt;</code> 段</td>
      </tr>
      <tr>
          <td>Margin / safety buffer</td>
          <td>10-20%</td>
          <td>Generation 階段不被 context limit 截斷</td>
      </tr>
  </tbody>
</table>
<p>關鍵 25% 規則：<strong>Scaffold 部分（system prompt + tool schema + conversation history）合計不超過 25% context</strong>。剩 75% 給「當下任務」、避免 <a href="/blog/llm/knowledge-cards/lost-in-the-middle/" data-link-title="Lost in the Middle" data-link-desc="LLM 對 long context 中段內容的 attention / recall 顯著低於開頭與結尾的現象">lost-in-the-middle</a> 把指令吃掉。</p>
<p>超標訊號跟對應策略：</p>
<table>
  <thead>
      <tr>
          <th>超標訊號</th>
          <th>緩解策略</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>模型開始忽略 system prompt 指令</td>
          <td>用 <a href="/blog/llm/knowledge-cards/prompt-cache/" data-link-title="Prompt Cache" data-link-desc="重複出現的 prompt prefix 在推論伺服器或 LLM 服務端被 cache、後續 query 跳過 prefill、大幅降 cost 跟 TTFT">prompt cache</a> 把 system prompt 攤平</td>
      </tr>
      <tr>
          <td>Tool call 重複過去步驟</td>
          <td>History 過長、需要 summarize 舊回合</td>
      </tr>
      <tr>
          <td>回答跟前文重複 / 矛盾</td>
          <td>中段 lost-in-the-middle、reorder 重要內容到末尾</td>
      </tr>
      <tr>
          <td>Generation 被截斷</td>
          <td>Margin 不夠、降低 file content 或 history</td>
      </tr>
      <tr>
          <td>Reasoning trace 截斷</td>
          <td>換更長 context 模型、或拆任務</td>
      </tr>
  </tbody>
</table>
<p>實作概要：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">每個 turn 開始時、harness 算：
</span></span><span class="line"><span class="ln">2</span><span class="cl">  available_input = context_window - reserve_margin
</span></span><span class="line"><span class="ln">3</span><span class="cl">  used = len(system + tool_schema + history + new_content)
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl">  if used &gt; available_input × 0.75：
</span></span><span class="line"><span class="ln">6</span><span class="cl">    觸發 summarize：把舊 history 壓縮成 1 段摘要
</span></span><span class="line"><span class="ln">7</span><span class="cl">    或觸發 dispatch：交給 subagent 處理特定子任務、回主 agent 時只帶 summary</span></span></code></pre></div><h2 id="subagent-設計">Subagent 設計</h2>
<p><a href="/blog/llm/knowledge-cards/subagent/" data-link-title="Subagent" data-link-desc="Coding agent 中把特定責任拆給專門子 agent 的設計模式、各 subagent 有獨立 context、由 main agent 透過 handoff 調度">Subagent</a> 把單一大 agent 拆成多個專責子 agent、各自有獨立 context。何時用：</p>
<table>
  <thead>
      <tr>
          <th>情境</th>
          <th>用 subagent？</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Single agent context 撐不住任務複雜度</td>
          <td>是</td>
      </tr>
      <tr>
          <td>Specialty 邊界清楚（test / docs / refactor 各自有專家）</td>
          <td>是</td>
      </tr>
      <tr>
          <td>任務簡單（autocomplete、單行修改）</td>
          <td>否</td>
      </tr>
      <tr>
          <td>Specialty 邊界模糊（強行拆增加 handoff overhead）</td>
          <td>否</td>
      </tr>
      <tr>
          <td>本地小模型（&lt; 14B）</td>
          <td>否（handoff 對小模型不穩）</td>
      </tr>
  </tbody>
</table>
<p>主流 subagent 模式：</p>
<h3 id="1-search-subagent">1. Search subagent</h3>
<p><strong>Specialty</strong>：在大 codebase 找相關片段、不污染 main agent context
<strong>Tool</strong>：grep / find / semantic search
<strong>Output</strong>：top-K 相關段落 + 摘要、main agent 不需要看完整 grep 結果</p>
<h3 id="2-test-runner-subagent">2. Test runner subagent</h3>
<p><strong>Specialty</strong>：跑測試、解讀失敗、提出 fix 建議
<strong>Tool</strong>：run_bash（pytest / jest 等）+ read failed test
<strong>Output</strong>：「測試結果 + 失敗根因 + 建議 fix」、不是完整 test log</p>
<h3 id="3-docs-writer-subagent">3. Docs writer subagent</h3>
<p><strong>Specialty</strong>：寫 docstring / README / commit message
<strong>System prompt</strong>：強化「寫作風格、語言、長度」、跟 main coding agent 完全不同的 system prompt
<strong>Output</strong>：寫好的 docs 文字</p>
<h3 id="4-code-review-subagent">4. Code review subagent</h3>
<p><strong>Specialty</strong>：對 PR diff 做 review、檢查 style / bug / security
<strong>Tool</strong>：git diff / grep
<strong>Output</strong>：comments 列表</p>
<h3 id="5-long-running-task-subagent">5. Long-running task subagent</h3>
<p><strong>Specialty</strong>：跑可能持續數分鐘的任務（如 large-scale refactor）、main agent 不阻塞
<strong>Tool</strong>：背景 process management
<strong>Output</strong>：階段性進度回報 + 最終結果</p>
<p>主 agent 對 subagent 的 handoff 設計：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">main agent 收到任務
</span></span><span class="line"><span class="ln">2</span><span class="cl">   ↓ 判斷 specialty
</span></span><span class="line"><span class="ln">3</span><span class="cl">   ↓ 用 dispatch_subagent tool 呼叫
</span></span><span class="line"><span class="ln">4</span><span class="cl">   tool spec：{name, task_brief, expected_output_format}
</span></span><span class="line"><span class="ln">5</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln">6</span><span class="cl">Subagent 在自己 context 內跑完
</span></span><span class="line"><span class="ln">7</span><span class="cl">   ↓ 回 summary（不是完整 trace）
</span></span><span class="line"><span class="ln">8</span><span class="cl">   ↓
</span></span><span class="line"><span class="ln">9</span><span class="cl">main agent 拿到 summary、繼續推進</span></span></code></pre></div><h2 id="跟既有概念的關係">跟既有概念的關係</h2>
<table>
  <thead>
      <tr>
          <th>既有章節</th>
          <th>跟本章的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/llm/04-applications/tool-use-principles/" data-link-title="4.3 Tool use 原理：LLM 跟外部世界互動" data-link-desc="Structured output 是 LLM 跨入工程系統的橋、function calling 取捨、為什麼本地小模型 tool use 表現崩潰">4.3 Tool use</a></td>
          <td>Tool spec 是 scaffold 的核心、tool dispatch 在 harness</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/04-applications/agent-architecture/" data-link-title="4.4 Agent 架構原理" data-link-desc="Agent loop 結構、失敗模式、什麼任務適合 vs 不適合、跟人類審查的協作模型">4.4 Agent 架構</a></td>
          <td>Agent loop 是 harness 的內部執行迴圈</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/04-applications/application-protocols/" data-link-title="4.6 應用層協議：function calling / structured output / MCP" data-link-desc="三個常被混為一談的概念：模型能力、sampling 約束、server 協議，三者的層級差異與組合方式">4.6 應用層協議</a></td>
          <td>Function calling / MCP 是 tool 跟 subagent 之間的協議</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/04-applications/long-context-engineering/" data-link-title="4.11 Long context engineering" data-link-desc="128K / 1M context 模型怎麼用：claimed vs effective context、lost-in-the-middle、context 設計策略、Long context vs RAG 取捨">4.11 Long context</a></td>
          <td>Context budget 是 long context 的工程實務面</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/04-applications/prompt-caching-engineering/" data-link-title="4.18 Prompt caching 工程實務：cost / latency 最大槓桿" data-link-desc="Prompt cache 怎麼運作、cache_control 設計、coding agent 跟 long-context 的 cache pattern、anti-pattern 跟 cache miss 訊號">4.18 Prompt caching</a></td>
          <td>是 scaffold 部分（system + tool schema）的 cost / latency 優化</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/04-applications/agent-memory-architecture/" data-link-title="4.19 Agent memory 分層架構" data-link-desc="Agent 在 context window 之外管理長期狀態的設計：working / short-term / long-term episodic / semantic / procedural 五個層次、寫入時機、retrieval 設計、失敗模式">4.19 Agent memory</a></td>
          <td>History 跟 long-term memory 是 harness 跟 storage 的界面</td>
      </tr>
  </tbody>
</table>
<h2 id="跟具體-coding-agent-的-mapping">跟具體 coding agent 的 mapping</h2>
<p>讀者實際用 / 想客製某個 coding agent 時、用本章的 framing 拆解：</p>
<h3 id="claude-code">Claude Code</h3>
<p><strong>Scaffold</strong>：CLAUDE.md（system prompt 入口）、Skills registry、SubagentTypes、tool schema
<strong>Harness</strong>：context budget management、Task tool（dispatch subagent）、permission system、trace
<strong>特色</strong>：完整 scaffold-harness 分層、強 subagent system、explicit context budget</p>
<h3 id="cursor">Cursor</h3>
<p><strong>Scaffold</strong>：System prompt 較固定、tool list 較簡、Composer mode 是 scaffold variant
<strong>Harness</strong>：IDE 整合度高、tool dispatch 跨 client / server、streaming response
<strong>特色</strong>：產品優化重於可客製、scaffold 半開放</p>
<h3 id="aider">Aider</h3>
<p><strong>Scaffold</strong>：edit-format（diff / udiff / whole）+ git integration、tool 較少（read / edit / run）
<strong>Harness</strong>：repl-style loop、自動 commit、線性對話
<strong>特色</strong>：CLI-first、scaffold 簡單、harness 圍繞 git 設計</p>
<h3 id="continuedev搭本地-llm">Continue.dev（搭本地 LLM）</h3>
<p><strong>Scaffold</strong>：Provider-agnostic、tool list 由 plugin 註冊
<strong>Harness</strong>：較輕量、tool dispatch 在 VS Code extension host
<strong>特色</strong>：適合本地 LLM、scaffold / harness 都相對開放</p>
<h2 id="失敗模式跟緩解">失敗模式跟緩解</h2>
<p>Coding agent 常見失敗：</p>
<table>
  <thead>
      <tr>
          <th>失敗</th>
          <th>根因</th>
          <th>緩解</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Context 用爆、模型失憶</td>
          <td>Budget 設計不當</td>
          <td>25% 規則、prompt cache、subagent 分擔</td>
      </tr>
      <tr>
          <td>Tool call infinite loop</td>
          <td>Harness 沒設 step 上限或 cost cap</td>
          <td>加 max_steps / max_cost、定期讓 user check</td>
      </tr>
      <tr>
          <td>Subagent 答錯仍被 main 採用</td>
          <td>Main agent 沒 verify subagent output</td>
          <td>加 verification step、let main 看 subagent trace</td>
      </tr>
      <tr>
          <td>修改檔案後 test 沒跑</td>
          <td>Scaffold 沒強制「先 test 後 commit」</td>
          <td>System prompt 加 explicit checklist、harness 加 hook</td>
      </tr>
      <tr>
          <td>Reasoning model 配短 context</td>
          <td>Reasoning trace 擠壓任務 context</td>
          <td>配 64K+ context、或拆任務</td>
      </tr>
      <tr>
          <td>Permission boundary 不夠細</td>
          <td>Scaffold 安全 policy 太寬</td>
          <td>副作用類 tool 拆細、加 confirm UI（見 <a href="/blog/llm/01-local-llm-services/hands-on/permission-boundary/" data-link-title="Hands-on：Ollama 改檔案 / 寫程式碼的權限邊界在哪" data-link-desc="四組對照實驗：Ollama 自己沒 FS / shell 權限、wrapper 才有；--dry-run / --confirm / --auto 三檔審查粒度的取捨">hands-on permission-boundary</a>）</td>
      </tr>
  </tbody>
</table>
<h2 id="本地小模型跑-coding-agent-的限制">本地小模型跑 coding agent 的限制</h2>
<p>本地 &lt; 14B 模型跑完整 coding agent 通常不穩、根因（跟 <a href="/blog/llm/03-theoretical-foundations/reasoning-models/" data-link-title="3.8 Reasoning models：test-time compute paradigm" data-link-desc="Chain-of-thought 從 prompting 技巧演化成訓練 paradigm、reasoning model 的內部運作、本地可跑的選項與適用任務">3.8 reasoning-models</a> / <a href="/blog/llm/04-applications/agent-architecture/" data-link-title="4.4 Agent 架構原理" data-link-desc="Agent loop 結構、失敗模式、什麼任務適合 vs 不適合、跟人類審查的協作模型">4.4 agent-architecture</a> 已述）：</p>
<ol>
<li><strong>Tool use 不穩</strong>：小模型 function calling 訓練不足、tool call 格式錯誤率高</li>
<li><strong>Long context 退化</strong>：&lt; 14B 模型 effective context 通常 &lt; 16K、coding agent 場景容易撞 budget</li>
<li><strong>Reasoning 弱</strong>：multi-step planning、failure recovery 都需要 reasoning 能力</li>
<li><strong>Subagent handoff 失敗</strong>：小模型對「該 handoff 給誰」的判斷不穩</li>
</ol>
<p>實務組合：</p>
<ul>
<li><strong>Autocomplete + 簡單 chat</strong>：本地 7B-14B coder（Qwen3-Coder / Gemma 4 coder）可勝任</li>
<li><strong>完整 coding agent</strong>：30B+ 本地模型或雲端旗艦</li>
<li><strong>混用</strong>：本地小模型當 autocomplete + 雲端旗艦當 agent</li>
</ul>
<h2 id="何時過時--何時不過時">何時過時 / 何時不過時</h2>
<p><strong>不會過時的部分</strong>：</p>
<ul>
<li>Scaffold vs harness 分層 framing</li>
<li>Context budget 配額概念跟 25% 規則</li>
<li>Subagent 設計原則跟 handoff 機制</li>
<li>失敗模式分類（context 爆、infinite loop、permission 邊界）</li>
<li>本地小模型限制</li>
</ul>
<p><strong>會變的部分</strong>：</p>
<ul>
<li>具體 coding agent（Claude Code / Cursor / Aider 等持續演化）</li>
<li>Subagent registry 標準化（目前各家不同）</li>
<li>Tool schema 標準化（MCP 是其中一條路）</li>
<li>本地小模型的 agent 能力（會逐步追上）</li>
</ul>
<h2 id="下一章">下一章</h2>
<p>下一章：<a href="/blog/llm/04-applications/prompt-caching-engineering/" data-link-title="4.18 Prompt caching 工程實務：cost / latency 最大槓桿" data-link-desc="Prompt cache 怎麼運作、cache_control 設計、coding agent 跟 long-context 的 cache pattern、anti-pattern 跟 cache miss 訊號">4.18 Prompt caching 工程實務</a>、看 scaffold 部分的 cost / latency 優化。</p>
]]></content:encoded></item><item><title>4.18 Prompt caching 工程實務：cost / latency 最大槓桿</title><link>https://tarrragon.github.io/blog/llm/04-applications/prompt-caching-engineering/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/04-applications/prompt-caching-engineering/</guid><description>&lt;p>&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prompt-cache/" data-link-title="Prompt Cache" data-link-desc="重複出現的 prompt prefix 在推論伺服器或 LLM 服務端被 cache、後續 query 跳過 prefill、大幅降 cost 跟 TTFT">Prompt cache&lt;/a> 把重複 prefix 的計算結果在 LLM 服務端跨 request 持久化、後續 query 跳過 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prefill/" data-link-title="Prefill" data-link-desc="Prompt 首次處理時的計算階段：把整段輸入跑過模型、產生 KV cache">prefill&lt;/a> 階段。Anthropic / OpenAI / Bedrock / Gemini 都列為 cost 跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT&lt;/a> 的最大單一槓桿 — 90% cost 折扣 + 顯著 latency 改善。本章把 prompt caching 的運作機制、設計原則、coding agent / long-context 場景的 pattern、常見 anti-pattern 拆成可操作的工程實務。&lt;/p>
&lt;p>注意三層 cache 概念的層次差異（&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prompt-cache/" data-link-title="Prompt Cache" data-link-desc="重複出現的 prompt prefix 在推論伺服器或 LLM 服務端被 cache、後續 query 跳過 prefill、大幅降 cost 跟 TTFT">prompt cache 卡片&lt;/a> 有完整對比表）：&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache&lt;/a> 是單次推論內、過去 token 的 K/V 暫存（autoregressive 才省重算）；&lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prefix-cache/" data-link-title="Prefix Cache" data-link-desc="把多個請求共用的前綴 prompt 的 KV cache 重用、省下重複 prefill 算力的優化、production 多用戶服務的常見設計">prefix cache&lt;/a> 是同一推論伺服器內跨 request 共用 KV cache；&lt;strong>prompt cache（本章聚焦）&lt;/strong> 是雲端 LLM API 商業 feature、跨 request 跨時間、有 TTL。三者不同層、要區分。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>讀完本章後、你應該能：&lt;/p>
&lt;ol>
&lt;li>解釋 prompt cache 跟 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/prefix-cache/" data-link-title="Prefix Cache" data-link-desc="把多個請求共用的前綴 prompt 的 KV cache 重用、省下重複 prefill 算力的優化、production 多用戶服務的常見設計">prefix cache&lt;/a> 的層次差異。&lt;/li>
&lt;li>對 coding agent / RAG / long-conversation 場景設計 cache breakpoint。&lt;/li>
&lt;li>估算自己應用開 prompt cache 的 cost / latency 收益。&lt;/li>
&lt;li>看到「cache 不命中」訊號時、能定位 anti-pattern 並修。&lt;/li>
&lt;/ol>
&lt;h2 id="prompt-cache-怎麼運作">Prompt cache 怎麼運作&lt;/h2>
&lt;p>LLM 推論的 prefill 階段對整個 prompt 算 KV cache、是長 prompt 的主要 latency 跟 compute 成本：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">無 cache：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> Request 1：[10K system prompt] + [tool schema 5K] + [user query 500] = 15.5K prefill
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> Request 2：[10K system prompt] + [tool schema 5K] + [user query 700] = 15.7K prefill
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> → 兩次都付 15K prefill 成本&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>開 prompt cache 後：&lt;/p></description><content:encoded><![CDATA[<p><a href="/blog/llm/knowledge-cards/prompt-cache/" data-link-title="Prompt Cache" data-link-desc="重複出現的 prompt prefix 在推論伺服器或 LLM 服務端被 cache、後續 query 跳過 prefill、大幅降 cost 跟 TTFT">Prompt cache</a> 把重複 prefix 的計算結果在 LLM 服務端跨 request 持久化、後續 query 跳過 <a href="/blog/llm/knowledge-cards/prefill/" data-link-title="Prefill" data-link-desc="Prompt 首次處理時的計算階段：把整段輸入跑過模型、產生 KV cache">prefill</a> 階段。Anthropic / OpenAI / Bedrock / Gemini 都列為 cost 跟 <a href="/blog/llm/knowledge-cards/ttft/" data-link-title="TTFT" data-link-desc="Time To First Token：送出 prompt 到第一個 token 出現的等待時間">TTFT</a> 的最大單一槓桿 — 90% cost 折扣 + 顯著 latency 改善。本章把 prompt caching 的運作機制、設計原則、coding agent / long-context 場景的 pattern、常見 anti-pattern 拆成可操作的工程實務。</p>
<p>注意三層 cache 概念的層次差異（<a href="/blog/llm/knowledge-cards/prompt-cache/" data-link-title="Prompt Cache" data-link-desc="重複出現的 prompt prefix 在推論伺服器或 LLM 服務端被 cache、後續 query 跳過 prefill、大幅降 cost 跟 TTFT">prompt cache 卡片</a> 有完整對比表）：<a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> 是單次推論內、過去 token 的 K/V 暫存（autoregressive 才省重算）；<a href="/blog/llm/knowledge-cards/prefix-cache/" data-link-title="Prefix Cache" data-link-desc="把多個請求共用的前綴 prompt 的 KV cache 重用、省下重複 prefill 算力的優化、production 多用戶服務的常見設計">prefix cache</a> 是同一推論伺服器內跨 request 共用 KV cache；<strong>prompt cache（本章聚焦）</strong> 是雲端 LLM API 商業 feature、跨 request 跨時間、有 TTL。三者不同層、要區分。</p>
<h2 id="本章目標">本章目標</h2>
<p>讀完本章後、你應該能：</p>
<ol>
<li>解釋 prompt cache 跟 <a href="/blog/llm/knowledge-cards/kv-cache/" data-link-title="KV Cache" data-link-desc="已處理 token 的 attention 中間結果暫存：避免重算、加速後續生成">KV cache</a> / <a href="/blog/llm/knowledge-cards/prefix-cache/" data-link-title="Prefix Cache" data-link-desc="把多個請求共用的前綴 prompt 的 KV cache 重用、省下重複 prefill 算力的優化、production 多用戶服務的常見設計">prefix cache</a> 的層次差異。</li>
<li>對 coding agent / RAG / long-conversation 場景設計 cache breakpoint。</li>
<li>估算自己應用開 prompt cache 的 cost / latency 收益。</li>
<li>看到「cache 不命中」訊號時、能定位 anti-pattern 並修。</li>
</ol>
<h2 id="prompt-cache-怎麼運作">Prompt cache 怎麼運作</h2>
<p>LLM 推論的 prefill 階段對整個 prompt 算 KV cache、是長 prompt 的主要 latency 跟 compute 成本：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">無 cache：
</span></span><span class="line"><span class="ln">2</span><span class="cl">  Request 1：[10K system prompt] + [tool schema 5K] + [user query 500] = 15.5K prefill
</span></span><span class="line"><span class="ln">3</span><span class="cl">  Request 2：[10K system prompt] + [tool schema 5K] + [user query 700] = 15.7K prefill
</span></span><span class="line"><span class="ln">4</span><span class="cl">  → 兩次都付 15K prefill 成本</span></span></code></pre></div><p>開 prompt cache 後：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">Request 1：[10K system + 5K tool schema] | cache_control | + [user query 500]
</span></span><span class="line"><span class="ln">2</span><span class="cl">  → 算出 prefix 的 KV cache、寫進服務端 cache（付 1.25× cost）
</span></span><span class="line"><span class="ln">3</span><span class="cl">  → 後段 prefill 500 token
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl">Request 2（5 分鐘內）：[10K system + 5K tool schema] | + [user query 700]
</span></span><span class="line"><span class="ln">6</span><span class="cl">  → 服務端命中 cache、跳過 prefix 的 prefill（付 0.1× cost = 90% 折扣）
</span></span><span class="line"><span class="ln">7</span><span class="cl">  → 只 prefill 700 token
</span></span><span class="line"><span class="ln">8</span><span class="cl">  → TTFT 大幅降低</span></span></code></pre></div><p>關鍵運作細節：</p>
<ol>
<li><strong>Cache key = prefix 的 token sequence</strong>：完全相同的 token sequence 才命中、差一個 token 就 miss</li>
<li><strong>TTL（time-to-live）</strong>：cache 過一段時間（多數 5 min）自動失效、要 ext 1h 通常付額外 cost</li>
<li><strong>Write 比原價略貴、Read 大幅打折</strong>：Anthropic 模型 write 1.25×、read 0.1×；OpenAI 模型 read 0.5×</li>
<li><strong>Minimum cacheable size</strong>：通常 1K-4K token 起跳、短 prompt 不適合</li>
<li><strong>Cache 範圍</strong>：跨 request、跨 conversation、跨 session、但同一 model + 同一 region</li>
</ol>
<h2 id="cache-breakpoint-設計">Cache breakpoint 設計</h2>
<p>Anthropic 用 <code>cache_control</code> 標記顯式 breakpoint、OpenAI 用自動偵測。但設計原則一致：<strong>把不變的內容放 prefix、變動的放後面</strong>。</p>
<p>典型 coding agent 的 prompt 結構：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">[1. System prompt]：agent 角色、規則、輸出格式             ← 不變
</span></span><span class="line"><span class="ln">2</span><span class="cl">[2. Tool schema]：所有 tool 的 spec                       ← 不變（除非加新 tool）
</span></span><span class="line"><span class="ln">3</span><span class="cl">[3. Skill registry / playbook]：known recipes              ← 半變（偶爾更新）
</span></span><span class="line"><span class="ln">4</span><span class="cl">[4. Codebase context]：固定載入的核心檔案                  ← 半變
</span></span><span class="line"><span class="ln">5</span><span class="cl">       ↓ cache_control breakpoint ↑
</span></span><span class="line"><span class="ln">6</span><span class="cl">[5. Conversation history]：過去回合                       ← 變動
</span></span><span class="line"><span class="ln">7</span><span class="cl">[6. Current user query]：當前 query                       ← 變動
</span></span><span class="line"><span class="ln">8</span><span class="cl">[7. Current tool result]：剛跑完的 tool output             ← 變動</span></span></code></pre></div><p>Breakpoint 放在「不變 vs 變動」交界處、讓 [1-4] 永遠 cache hit。</p>
<p>Anthropic 最多 4 個 breakpoint、可分層：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">breakpoint 1（最早）：[system prompt] → 永久 cache
</span></span><span class="line"><span class="ln">2</span><span class="cl">breakpoint 2：       [+ tool schema] → 永久 cache
</span></span><span class="line"><span class="ln">3</span><span class="cl">breakpoint 3：       [+ skill registry] → 半永久 cache
</span></span><span class="line"><span class="ln">4</span><span class="cl">breakpoint 4（最晚）：[+ recent stable context] → 短期 cache
</span></span><span class="line"><span class="ln">5</span><span class="cl">[後段]：             variable content（不 cache）</span></span></code></pre></div><p>每個 breakpoint 各自命中 / miss、layered cache 讓「加新 skill」只 invalidate breakpoint 3 之後、不影響 breakpoint 1-2。</p>
<h2 id="場景-1coding-agent">場景 1：Coding agent</h2>
<p>Coding agent 是 prompt cache 命中區 — system prompt + tool schema 動輒 10K-30K token、每個 user turn 都重用。</p>
<p>收益估算（200K context 模型、10K scaffold、5K user query、3K answer）：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">無 cache：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">  每 turn input cost = (10K + 5K) × $3/M = $0.045
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  每 turn TTFT = 10K-15K prefill time（200-400ms）
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">開 cache：
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">  Turn 1（write）：(10K × 1.25 + 5K) × $3/M = $0.0525
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  Turn 2-N（read）：(10K × 0.1 + 5K) × $3/M = $0.018
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  TTFT：read 階段省掉 10K prefill、只剩 5K
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">10 turns 的累計 cost：
</span></span><span class="line"><span class="ln">11</span><span class="cl">  無 cache：10 × $0.045 = $0.45
</span></span><span class="line"><span class="ln">12</span><span class="cl">  開 cache：$0.0525 + 9 × $0.018 = $0.215
</span></span><span class="line"><span class="ln">13</span><span class="cl">  → 節省 52%</span></span></code></pre></div><p>長對話越長、cache 收益越大（cache write 是一次性成本）。</p>
<h2 id="場景-2rag--long-context">場景 2：RAG / long-context</h2>
<p>RAG 場景把 retrieved chunks 放 prefix、user query 放後面、可以 cache retrieved chunks：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">[system prompt]
</span></span><span class="line"><span class="ln">2</span><span class="cl">       ↓ breakpoint 1（system 永久 cache）
</span></span><span class="line"><span class="ln">3</span><span class="cl">[retrieved chunks 來自 RAG]
</span></span><span class="line"><span class="ln">4</span><span class="cl">       ↓ breakpoint 2（同 chunks 在 5min 內 cache）
</span></span><span class="line"><span class="ln">5</span><span class="cl">[user query]</span></span></code></pre></div><p>注意：每次 retrieval 不同 chunks 就 cache miss、所以 cache 適合「同個對話多輪、retrieval 結果穩定」、不適合「每 query 都 fresh retrieve」；後者要回到 <a href="/blog/llm/knowledge-cards/retrieval-cost/" data-link-title="Retrieval Cost" data-link-desc="RAG 檢索帶來的 latency、token、embedding、reranker、LLM call 與維護成本，用來判斷增強是否划算">retrieval cost</a> 評估。</p>
<h2 id="場景-3long-document-qa">場景 3：Long document Q&amp;A</h2>
<p>讀者上傳 PDF / 文件、多輪問問題：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">[system prompt]
</span></span><span class="line"><span class="ln">2</span><span class="cl">       ↓ breakpoint 1
</span></span><span class="line"><span class="ln">3</span><span class="cl">[完整文件內容（可能 100K token）]
</span></span><span class="line"><span class="ln">4</span><span class="cl">       ↓ breakpoint 2（文件永久 cache）
</span></span><span class="line"><span class="ln">5</span><span class="cl">[user query]</span></span></code></pre></div><p>第一次 query 付 1.25× 文件成本、後續 query 都 0.1×。100K 文件 + 10 個問題的場景下、節省極顯著（&gt; 80% cost）。</p>
<h2 id="常見-anti-pattern">常見 anti-pattern</h2>
<ol>
<li><strong>在 prefix 插入 timestamp / request-id</strong></li>
</ol>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">反例：System prompt: &#34;你是 coding assistant、當前時間 2026-05-12 16:30:42、...&#34;
</span></span><span class="line"><span class="ln">2</span><span class="cl">   → 每秒不同 cache key、永遠 cache miss、付 1.25× write 不回本
</span></span><span class="line"><span class="ln">3</span><span class="cl">正解：把 timestamp 放後段、或省略（多數場景模型不需要精確時間）</span></span></code></pre></div><ol start="2">
<li><strong>在 prefix 動態插入 user metadata</strong></li>
</ol>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">反例：System prompt: &#34;User: alice@example.com, plan: premium、...&#34;
</span></span><span class="line"><span class="ln">2</span><span class="cl">   → 每個 user 不同 cache、命中率低
</span></span><span class="line"><span class="ln">3</span><span class="cl">正解：User metadata 放後段、prefix 保持 user-agnostic</span></span></code></pre></div><ol start="3">
<li><strong>Tool schema 順序不固定</strong></li>
</ol>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">反例：每次 request 把 tool list 隨機 shuffle
</span></span><span class="line"><span class="ln">2</span><span class="cl">   → 同樣 tool 但 token sequence 不同、cache miss
</span></span><span class="line"><span class="ln">3</span><span class="cl">正解：Tool list 順序固定、新加 tool 都 append 到末尾</span></span></code></pre></div><ol start="4">
<li><strong>太短的 prompt 也想 cache</strong></li>
</ol>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">反例：500 token system prompt 開 cache
</span></span><span class="line"><span class="ln">2</span><span class="cl">   → 多數服務商 minimum 1K-4K、不到門檻不 cache、且 write cost 不回本
</span></span><span class="line"><span class="ln">3</span><span class="cl">正解：Cache 留給 &gt; 1K 的 prefix、短 prompt 不必開</span></span></code></pre></div><ol start="5">
<li><strong>混用 stream + cache 卻不檢查命中</strong></li>
</ol>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">反例：開 cache 後不檢查 response 的 cache_read_input_tokens 欄位
</span></span><span class="line"><span class="ln">2</span><span class="cl">   → 不知道實際命中率、可能 anti-pattern 已在燒 cost 沒察覺
</span></span><span class="line"><span class="ln">3</span><span class="cl">正解：監控 cache_read / cache_creation token 比例、低於 80% 命中率時 debug</span></span></code></pre></div><h2 id="cache-miss-訊號跟診斷">Cache miss 訊號跟診斷</h2>
<p>訊號：</p>
<ol>
<li><strong>Cost 比預期高</strong>：應該命中的場景仍付 full price</li>
<li><strong>TTFT 沒改善</strong>：cache hit 應該大幅降 TTFT、沒改善 = miss</li>
<li><strong>Response 的 usage 顯示 cache_read = 0</strong>：直接訊號</li>
</ol>
<p>診斷流程：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">1. 印出 raw request 的 prefix（cache_control 之前）
</span></span><span class="line"><span class="ln">2</span><span class="cl">2. 比對連續兩次 request 的 prefix token sequence
</span></span><span class="line"><span class="ln">3</span><span class="cl">3. 找出差異位置（diff）
</span></span><span class="line"><span class="ln">4</span><span class="cl">4. 移除 / 重構讓兩次 prefix 完全相同
</span></span><span class="line"><span class="ln">5</span><span class="cl">5. 跑 2-3 次 request、看 cache_read_input_tokens 是否上升</span></span></code></pre></div><p>常見差異：timestamp、request id、user id、tool list 順序、retrieved chunks 順序、conversation summary 變動。</p>
<h2 id="跟其他-cost-優化技巧的關係">跟其他 cost 優化技巧的關係</h2>
<table>
  <thead>
      <tr>
          <th>技巧</th>
          <th>攻擊的 cost / latency 來源</th>
          <th>跟 prompt cache 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/speculative-decoding/" data-link-title="Speculative Decoding" data-link-desc="用小模型猜未來 token、大模型並行驗證的加速技巧">Speculative decoding</a></td>
          <td>Generation 階段 token cost</td>
          <td>正交、可疊加</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/batching/" data-link-title="Batching" data-link-desc="多 request 一起跑、攤平 model load 成本：production LLM inference 的核心優化、決定 throughput vs latency 取捨">Batching</a></td>
          <td>Throughput per GPU</td>
          <td>Production 才用、跟 prompt cache 都用</td>
      </tr>
      <tr>
          <td><a href="/blog/llm/knowledge-cards/prefix-cache/" data-link-title="Prefix Cache" data-link-desc="把多個請求共用的前綴 prompt 的 KV cache 重用、省下重複 prefill 算力的優化、production 多用戶服務的常見設計">Prefix cache</a></td>
          <td>同 server 跨 request 共用 KV cache</td>
          <td>本地推論伺服器特性、prompt cache 是雲端 API 商業 feature</td>
      </tr>
      <tr>
          <td>模型量化</td>
          <td>Generation tok/s</td>
          <td>正交、可疊加</td>
      </tr>
      <tr>
          <td>RAG 而非 long context</td>
          <td>Input token 量</td>
          <td>RAG + cache 可同時用</td>
      </tr>
  </tbody>
</table>
<h2 id="本地推論伺服器有沒有類似機制">本地推論伺服器有沒有類似機制</h2>
<p>Ollama / LM Studio / llama.cpp 自身的 prompt cache：</p>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>機制</th>
          <th>範圍</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>llama.cpp</td>
          <td><code>--prompt-cache</code> flag、persistent file</td>
          <td>重複跑同樣 prompt 時跳過 prefill</td>
      </tr>
      <tr>
          <td>Ollama</td>
          <td>內建 prefix cache、跨 request 共用</td>
          <td>同 server 跨 request</td>
      </tr>
      <tr>
          <td>LM Studio</td>
          <td>同 Ollama 級別、視版本</td>
          <td>同上</td>
      </tr>
      <tr>
          <td>vLLM</td>
          <td>強 prefix cache（PagedAttention 設計支援）</td>
          <td>高併發 production</td>
      </tr>
  </tbody>
</table>
<p>本地推論的 cache 主要靠 <a href="/blog/llm/knowledge-cards/prefix-cache/" data-link-title="Prefix Cache" data-link-desc="把多個請求共用的前綴 prompt 的 KV cache 重用、省下重複 prefill 算力的優化、production 多用戶服務的常見設計">prefix cache</a> 機制、跟雲端 API 的 prompt cache 商業 feature 同源、但定價 / TTL / 顯式 control 是雲端 API 才有的 product layer。</p>
<h2 id="何時不適合用-prompt-cache">何時不適合用 prompt cache</h2>
<ol>
<li><strong>每 request prefix 必變</strong>：streaming 任務、每 query 都帶 fresh 上下文</li>
<li><strong>Single-shot 對話</strong>：用完就丟、沒有重複使用、write cost 不回本</li>
<li><strong>Prefix &lt; 1K token</strong>：不到 minimum、cache 不生效</li>
<li><strong>Cost 不敏感場景</strong>：個人小流量、cache 設計 overhead 大於收益</li>
<li><strong>本地推論為主</strong>：本地多用 prefix cache、prompt cache 是雲端 API 概念</li>
</ol>
<h2 id="何時過時--何時不過時">何時過時 / 何時不過時</h2>
<p><strong>不會過時的部分</strong>：</p>
<ul>
<li>「不變放 prefix、變動放後段」的設計原則</li>
<li>Cache breakpoint 分層（system / tool schema / skill / context）</li>
<li>Anti-pattern 分類（timestamp、user metadata、tool 順序）</li>
<li>Cache miss 診斷流程</li>
</ul>
<p><strong>會變的部分</strong>：</p>
<ul>
<li>各 vendor 的具體定價（write × / read × 折扣）</li>
<li>TTL（5min vs 1h）的可選性跟價格</li>
<li>Automatic vs explicit cache（OpenAI vs Anthropic 路線）</li>
<li>Breakpoint 上限數量</li>
<li>本地推論伺服器的 cache 功能（持續演化）</li>
</ul>
<h2 id="下一章">下一章</h2>
<p>下一章：<a href="/blog/llm/04-applications/agent-memory-architecture/" data-link-title="4.19 Agent memory 分層架構" data-link-desc="Agent 在 context window 之外管理長期狀態的設計：working / short-term / long-term episodic / semantic / procedural 五個層次、寫入時機、retrieval 設計、失敗模式">4.19 Agent memory 分層</a>、看 agent 如何在 context window 之外管理長期狀態。</p>
]]></content:encoded></item></channel></rss>