<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>Cheng®</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>https://blog.longhopick.com/</id>
  <link href="https://blog.longhopick.com/" rel="alternate"/>
  <link href="https://blog.longhopick.com/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, Cheng®</rights>
  <subtitle>─=≡Σ((( つ•̀ω•́)つ</subtitle>
  <title>
    <![CDATA[Cheng's Tech & Life]]>
  </title>
  <updated>2026-09-23T13:10:57.653Z</updated>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="Claude Code" scheme="https://blog.longhopick.com/categories/Claude-Code/"/>
    <category term="Claude Code" scheme="https://blog.longhopick.com/tags/Claude-Code/"/>
    <category term="AI Agent" scheme="https://blog.longhopick.com/tags/AI-Agent/"/>
    <category term="LLM" scheme="https://blog.longhopick.com/tags/LLM/"/>
    <category term="Claude" scheme="https://blog.longhopick.com/tags/Claude/"/>
    <content>
      <![CDATA[<p>你自己寫的 agent loop 跑到後段，回答開始變鈍。</p><p>它重複問一個前面已經確認過的欄位，或是把早就被否決掉的方案再提一次。你翻 log，一個錯誤都沒有，請求全部成功，狀態碼整排 200。唯一在變的是 <code>input_tokens</code> 每輪都比上一輪大一點。然後某一輪開始，答案就是不對勁。</p><p>官方的壓縮總覽頁把這件事寫得很直白：<code>response quality degrades as a conversation grows</code>。撞到 context window 上限才失敗算是好結局，品質通常在那之前就先掉了。</p><p>一個前提先講清楚：如果你的東西是一問一答、一輪就結束的形態，下面整篇都可以跳過，你沒有這個問題。會踩到的是那種一路跑幾十輪工具呼叫的東西。背景自動化、長任務 agent、會一直接話的客服 bot，歷史一直往上疊，而且疊得比你估的快。</p><h2 id="第一條路：放著不管，撐到它自己炸"><a href="#第一條路：放著不管，撐到它自己炸" class="headerlink" title="第一條路：放著不管，撐到它自己炸"></a>第一條路：放著不管，撐到它自己炸</h2><p>什麼都不做，讓對話一路長下去。這條路的結局官方講得很乾脆：超出 context window，請求就失敗。</p><p>失敗其實不是最糟的，失敗你看得到，錯誤率會亮燈。難受的是失敗之前那一段路，品質已經在掉，卻沒有任何訊號，監控只會告訴你請求都成功。</p><h2 id="第二條路：自己寫個-prompt-叫它總結"><a href="#第二條路：自己寫個-prompt-叫它總結" class="headerlink" title="第二條路：自己寫個 prompt 叫它總結"></a>第二條路：自己寫個 prompt 叫它總結</h2><p>這是最直覺的一條路，也是看起來最自由的。寫一段 prompt 把舊對話丟進去，叫 Claude 寫成一份摘要，然後把歷史紀錄裡那些舊訊息換成這段文字。省 token、內容自己控制，聽起來沒毛病。</p><p>在會保留推理過程（preserved thinking）的新款模型上，這招會壞，而且壞的方式不太直覺。</p><p>機制其實不複雜。你拿一張紙從上往下算一道長題目，算到一半那些草稿，是靠紙上更前面幾行才成立的。你寫下「所以 x 一定大於 3」，是因為上面第四行推出了某個式子。現在有人把上面那幾行擦掉，換成一句「前面大致算到這裡」。你的草稿還留在紙上，一個字都沒被動過，但它們已經不知道自己在算什麼了。</p><p>Claude 判定 thinking block 有沒有效，用的就是這個邏輯。官方文件寫成一句規則：<code>Nothing before the thinking block has changed.</code> 一個 thinking block 的「前綴」包含最上層的 <code>system</code>、<code>tools</code>，以及排在它前面的所有 <code>messages</code>。前綴跟當初產生這個 block 的時候長得不一樣，這個 block 就無效，而且連帶它後面每一個 thinking block 一起無效。</p><p>你自己抄的那份摘要，就是「前綴變了」。換成官方的說法：</p><blockquote><p>If you write the summary yourself, it breaks the rule: the kept assistant turns still carry thinking blocks that were produced when the original turns, not the summary, came before them. Those blocks fail.</p></blockquote><p>失效之後兩種下場，看你怎麼設定：API 回 400 把整個請求拒掉，或是把那些無效的 block 默默丟掉。</p><p>所以「自己寫摘要」在實務上只有一種活得下去的用法，官方也直接寫出來了：整段歷史全砍，把整場對話總結成一則 user message，只送那一則加上你的下一個指令。前面什麼都不重播，自然就沒有 thinking 可以被判無效，模型從摘要開始重新想。</p><p>這招跑得動，代價是那些推理全部歸零。你花錢買的 extended thinking，每壓縮一次就重來一次。</p><h2 id="那為什麼-API-自己寫的摘要就不會垮"><a href="#那為什麼-API-自己寫的摘要就不會垮" class="headerlink" title="那為什麼 API 自己寫的摘要就不會垮"></a>那為什麼 API 自己寫的摘要就不會垮</h2><p>差別在誰認可這次替換。</p><p>你自己抄的摘要，系統沒辦法分辨你抄對了沒、中間有沒有偷改一句。分辨不出來，它只能採最保守的策略：前綴跟當初不一樣，一律當作無效。</p><p>隨選壓縮（on-demand compaction）換了個做法。摘要不由你寫，由伺服器端產生，產生完附一段 <code>signature</code>。下一次請求你把整個 block 原封不動送回去，系統核對簽章，確認這份摘要就是它自己寫的那份、你一個字都沒動過。文件沒有把中間這層因果攤開寫，它只寫了結果：壓縮之後，最近幾輪連同裡面的 thinking 可以留著。從這個結果回推，站得住的解釋只有一個——替換是它自己蓋章放行的，所以後面那些 thinking 不會被判死。</p><p>用法是在請求裡多一個 <code>compaction</code> 參數，配上 beta header <code>compact-2026-09-04</code>。官方文件的 curl 範例：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">curl https://api.anthropic.com/v1/messages \</span><br><span class="line">  -H <span class="string">&quot;x-api-key: <span class="variable">$ANTHROPIC_API_KEY</span>&quot;</span> \</span><br><span class="line">  -H <span class="string">&quot;anthropic-version: 2023-06-01&quot;</span> \</span><br><span class="line">  -H <span class="string">&quot;anthropic-beta: compact-2026-09-04&quot;</span> \</span><br><span class="line">  -H <span class="string">&quot;content-type: application/json&quot;</span> \</span><br><span class="line">  -d <span class="string">&#x27;&#123;</span></span><br><span class="line"><span class="string">    &quot;model&quot;: &quot;claude-opus-5-5&quot;,</span></span><br><span class="line"><span class="string">    &quot;max_tokens&quot;: 4096,</span></span><br><span class="line"><span class="string">    &quot;messages&quot;: [</span></span><br><span class="line"><span class="string">      &#123;&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;I am building a recipe app. Help me name the main entities in the data model.&quot;&#125;,</span></span><br><span class="line"><span class="string">      &#123;&quot;role&quot;: &quot;assistant&quot;, &quot;content&quot;: &quot;Start with Recipe, Ingredient, and Step. Add a RecipeIngredient entry that holds the quantity and unit for each ingredient in a recipe.&quot;&#125;,</span></span><br><span class="line"><span class="string">      &#123;&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;Good. Now suggest field names for Recipe.&quot;&#125;</span></span><br><span class="line"><span class="string">    ],</span></span><br><span class="line"><span class="string">    &quot;compaction&quot;: &#123;&quot;type&quot;: &quot;summarize&quot;&#125;</span></span><br><span class="line"><span class="string">  &#125;&#x27;</span></span><br></pre></td></tr></table></figure><p>這一次請求不會得到一般的回覆。<code>stop_reason</code> 回 <code>&quot;compaction&quot;</code>，content 裡只有一個 block（以下為官方回應範例的節錄）：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;content&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;compaction&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;content&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Summary of the conversation: the user is designing the data model for a recipe app. ...&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;signature&quot;</span><span class="punctuation">:</span> <span class="string">&quot;EuYBCkQY...&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;stop_reason&quot;</span><span class="punctuation">:</span> <span class="string">&quot;compaction&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;usage&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;input_tokens&quot;</span><span class="punctuation">:</span> <span class="number">0</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;output_tokens&quot;</span><span class="punctuation">:</span> <span class="number">0</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;iterations&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="punctuation">&#123;</span> <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;compaction&quot;</span><span class="punctuation">,</span> <span class="attr">&quot;input_tokens&quot;</span><span class="punctuation">:</span> <span class="number">144</span><span class="punctuation">,</span> <span class="attr">&quot;output_tokens&quot;</span><span class="punctuation">:</span> <span class="number">276</span> <span class="punctuation">&#125;</span><span class="punctuation">]</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>最上層的 <code>input_tokens</code> 跟 <code>output_tokens</code> 固定是 0，因為這輪沒產生一般回覆，真正的用量記在 <code>usage.iterations</code> 那筆 <code>compaction</code> 裡。這通呼叫照樣計費、照樣佔 rate limit，官方寫的是 <code>The summarization call is billed and rate-limited like any other request</code>。摘要不是免費的，它只是比「整段重想」便宜。</p><p>內建的摘要 prompt 也可以換掉。<code>compaction</code> 底下多給一個 <code>instructions</code> 字串（上限 16,384 個字元），它會整個取代官方預設的指令，你能在裡面要求「已經談定的欄位名稱一個都不准漏」。</p><h2 id="換回去的時候有兩種錯，它一個都不會告訴你"><a href="#換回去的時候有兩種錯，它一個都不會告訴你" class="headerlink" title="換回去的時候有兩種錯，它一個都不會告訴你"></a>換回去的時候有兩種錯，它一個都不會告訴你</h2><p>拿到 block 之後，下一次請求要把它擺在 <code>messages</code> 最前面，然後把被摘要掉的那些訊息拿掉。結構長這樣：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;messages&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;role&quot;</span><span class="punctuation">:</span> <span class="string">&quot;assistant&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;content&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">        <span class="punctuation">&#123;</span> <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;compaction&quot;</span><span class="punctuation">,</span> <span class="attr">&quot;content&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Summary of the conversation: ...&quot;</span><span class="punctuation">,</span> <span class="attr">&quot;signature&quot;</span><span class="punctuation">:</span> <span class="string">&quot;EuYBCkQY...&quot;</span> <span class="punctuation">&#125;</span></span><br><span class="line">      <span class="punctuation">]</span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="punctuation">&#123;</span> <span class="attr">&quot;role&quot;</span><span class="punctuation">:</span> <span class="string">&quot;assistant&quot;</span><span class="punctuation">,</span> <span class="attr">&quot;content&quot;</span><span class="punctuation">:</span> <span class="string">&quot;For Recipe, use title, description, servings, prep_minutes, and cook_minutes. Add created_at and updated_at timestamps.&quot;</span> <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="punctuation">&#123;</span> <span class="attr">&quot;role&quot;</span><span class="punctuation">:</span> <span class="string">&quot;user&quot;</span><span class="punctuation">,</span> <span class="attr">&quot;content&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Now do the same for Ingredient.&quot;</span> <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>會報錯的那幾種其實都很好處理。block 前面還留著被摘要過的訊息，回 400 <code>compaction_block_misplaced</code>；內容或簽章對不起來，回 <code>compaction_signature_invalid</code> 或 <code>compaction_content_mismatch</code>；<code>messages</code> 裡根本沒有可摘要的內容，回 <code>compaction_nothing_to_summarize</code>；伺服器一時產不出來或讀不到，回 529 <code>compaction_unavailable</code>，重試就好。</p><p>真正會咬人的是官方特別標出來的那兩種。它們不報錯。</p><div class="note warning flat"><p><strong>官方原文</strong>：<code>Two mistakes in the swap raise no error. If summarized messages remain after the block, the API sends them to Claude again. If a later request leaves the block out, Claude gets no summary.</code></p><p>摘要 block 後面還留著已經被摘要掉的訊息，那些訊息會原封不動再送一次給 Claude，你以為省下來的 token 一個都沒省。後續某個請求漏掉了 block，Claude 就是沒看到摘要，安安靜靜少了一段記憶。</p></div><p>這兩種都是 200。對一個沒人盯著的 loop 來說，這比 400 危險得多。400 會讓你的錯誤率儀表板亮起來，這兩種不會，它只會讓帳單慢慢變胖，或是讓 agent 在某一輪突然忘記一件明明講過的事，而你會以為是模型變笨了。</p><h2 id="最近幾輪想留逐字的，跟不想停下來等的"><a href="#最近幾輪想留逐字的，跟不想停下來等的" class="headerlink" title="最近幾輪想留逐字的，跟不想停下來等的"></a>最近幾輪想留逐字的，跟不想停下來等的</h2><p>兩個延伸用法，解的是不同的痛。</p><p>keep-tail 是只把比較舊的回合送去壓縮，最近幾輪原封不動接在 block 後面，模型還是逐字看得到最後那幾次交手，官方那一頁的標題就叫 <code>Compaction that keeps recent turns</code>。這是跟「自己寫摘要」差最多的地方：保留尾段又不弄壞 thinking，自己寫的做不到。</p><p>background 是把壓縮請求先丟出去，對話繼續跑在完整歷史上，等 block 回來再換。官方的描述是 <code>the compaction request runs while the conversation continues on its full history, and the swap waits until the block arrives</code>。好處是 loop 不用卡在那邊等摘要寫完，代價是同一時間有兩個請求在飛，rate limit 多吃一份。</p><p>如果你已經在用舊的門檻式壓縮（edit type <code>compact_20260112</code>，輸入 token 一碰到你設的門檻，API 自己壓），這兩套不能混。<code>compaction</code> 跟 <code>context_management</code> 在同一個請求裡互斥，只能二選一。門檻式那套也沒有背景模式，官方比較表那一格寫得很硬：<code>No: it runs inside the request that reaches the threshold</code>。</p><p>我的立場是能用隨選就用隨選，官方自己也直接建議 <code>Use on-demand compaction wherever it is available</code>。有一種情況我會反過來勸你別碰：如果你的 loop 完全沒開 thinking，也不在乎壓縮發生在哪一輪、卡不卡住，門檻式省事得多，設好就不用再管，沒必要為了「可控」去扛 swap 的複雜度。門檻式那條路我寫過一篇<a href="/2026/08/04/Claude-API-context-editing-%E8%88%87-memory-tool-%E5%AE%8C%E6%95%B4%E6%95%99%E5%AD%B8-%E6%B8%85%E6%8E%89%E8%88%8A%E5%B0%8D%E8%A9%B1%E4%B9%8B%E5%89%8D-%E5%85%88%E8%AE%93%E5%AE%83%E6%8A%8A%E9%87%8D%E9%BB%9E%E5%AF%AB%E4%B8%8B%E4%BE%86/">context editing 與 memory tool 的教學</a>，兩篇對著看，看得出設計者為什麼是把「省事」跟「可控」拆成兩條路，不是拿新的取代舊的。</p><p>不想自己管 swap 的話，還有一條更省事的。官方 SDK 的 Tool Runner（Python、TypeScript、C#、Go、Java 都有）把這件事包好了，方法名各語言自己一套：Python 是 <code>compact_before_next_turn()</code>，TypeScript 跟 Java 是 <code>compactBeforeNextTurn()</code>，C# 跟 Go 是 <code>CompactBeforeNextTurn()</code>。呼叫之後 runner 會等這一輪跟工具呼叫跑完，自己送壓縮請求、自己換歷史。建 runner 的時候要記得把 <code>compact-2026-09-04</code> 帶上，它不會幫你加。</p><p>壓過一次又長回去也沒關係，再送一次 <code>compaction</code>，新 block 會把舊摘要連同後面的內容再摘一遍。</p><h2 id="它沒幫你解掉的部分"><a href="#它沒幫你解掉的部分" class="headerlink" title="它沒幫你解掉的部分"></a>它沒幫你解掉的部分</h2><p>摘要範圍裡的圖片、文件、<code>container_upload</code> block、抓過的 URL 內容，被 block 換掉之後就沒了，官方的說法是 <code>Restate or re-upload anything a later turn still needs</code>。你的 agent 如果會在第 30 輪回頭看第 3 輪上傳的那張圖，壓縮之前得自己想好怎麼把它帶著走。</p><p>平台支援也還不齊。截至 2026-09-23 我看文件的當下，Claude API、AWS 上的 Claude Platform、Google Cloud、Microsoft Foundry 都列為 beta 可用，Amazon Bedrock 標的是 not available，要在 Bedrock 上做類似的事就只剩門檻式那條路。模型也不是全支援，可以用 Models API 帶同一個 beta header 查每個模型的 <code>capabilities.compaction</code> 欄位確認。</p><p>還有 beta 本身。header 叫 <code>compact-2026-09-04</code>，日期直接寫在名字裡，這種東西改版不保證相容，正式上線前記得把它當成會變的東西處理。</p><p>另外一個很容易搞混的點：Claude Code 那個 <code>/compact</code> 指令跟這裡講的 <code>compaction</code> 參數不是同一層東西。前者是 CLI 產品給終端使用者用的（搭配 <code>autoCompactWindow</code> 跟 <code>PreCompact</code> &#x2F; <code>PostCompact</code> 兩個鉤子，我<a href="/2026/08/13/%E5%A3%93%E7%B8%AE%E5%AE%8C%E9%82%A3%E6%A2%9D%E8%A6%8F%E5%89%87%E7%82%BA%E4%BB%80%E9%BA%BC%E6%B2%92%E5%9B%9E%E4%BE%86-autoCompactWindow%E9%96%80%E6%AA%BB%E8%88%87PreCompact-PostCompact%E5%85%A9%E5%80%8B%E9%89%A4%E5%AD%90/">之前寫過一篇</a>），後者是給自己寫 agent 的人用的 API 能力。至於兩者底層是不是同一套邏輯，我沒在官方文件看到任何說法，別自己把它們接起來。</p><div class="note warning flat"><p><strong>誠實邊界</strong>：我只讀了官方文件，沒有實際送過任何一次帶 <code>compaction</code> 參數的請求。上面所有 curl 與 JSON 都是官方文件的範例，不是我跑出來的輸出。錯誤碼實際觸發時的行為、簽章長什麼樣、背景模式真正的延遲落在哪個量級，我都沒有第一手資料。</p></div><h2 id="所以你的-loop-要不要動"><a href="#所以你的-loop-要不要動" class="headerlink" title="所以你的 loop 要不要動"></a>所以你的 loop 要不要動</h2><p>問題從來不是「紙不夠大」。是你換紙的時候，前面那些推到一半的草稿還算不算數。自己抄一份摘要，系統沒有理由相信你，於是草稿一律作廢，你只能整張撕掉重算。API 自己寫的摘要帶著簽章，等於它替這次換紙背書，草稿就還站得住。</p><p>那個變鈍的 loop 要不要動它，看你有沒有開 thinking。沒開就別碰這套，門檻式設一設收工，可控性你用不到。有開的話，在自己的迴圈裡挑一個「上一輪工具呼叫剛結束、還沒開始下一輪」的乾淨位置送 <code>compaction</code>，拿到 block 存起來，把被摘要掉的訊息真的刪乾淨，然後在每一次後續請求都把 block 帶上。</p><p>再補兩個 API 不會幫你做的檢查：送出前確認 block 前後都沒有殘留已被摘要掉的訊息，以及每次請求都恰好帶著一個 <code>compaction</code> block。這兩件事寫錯都是 200，儀表板看不到，只有你自己的斷言看得到。</p><p>這套東西要你自己拿主意的就兩件：壓縮什麼時候發生，那份摘要誰背書。參數名字查文件就有，這兩件文件不會替你決定。</p><p>參考來源：<a href="https://platform.claude.com/docs/en/build-with-claude/compaction">Compaction 總覽</a>、<a href="https://platform.claude.com/docs/en/build-with-claude/compaction-on-demand">Compaction on demand</a>、<a href="https://platform.claude.com/docs/en/build-with-claude/compaction-keep-recent-turns">保留最近回合</a>、<a href="https://platform.claude.com/docs/en/build-with-claude/compaction-background">背景壓縮</a>、<a href="https://platform.claude.com/docs/en/build-with-claude/preserved-thinking">Preserved thinking</a></p>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/23/%E5%B0%8D%E8%A9%B1%E9%95%B7%E5%88%B0%E9%96%8B%E5%A7%8B%E8%AE%8A%E9%88%8D-Claude-Messages-API-%E7%9A%84%E9%9A%A8%E9%81%B8%E5%A3%93%E7%B8%AE%E8%B7%9F%E4%BD%A0%E8%87%AA%E5%B7%B1%E5%AF%AB%E6%91%98%E8%A6%81%E5%B7%AE%E5%9C%A8%E4%B8%80%E5%80%8B%E7%B0%BD%E7%AB%A0/</id>
    <link href="https://blog.longhopick.com/2026/09/23/%E5%B0%8D%E8%A9%B1%E9%95%B7%E5%88%B0%E9%96%8B%E5%A7%8B%E8%AE%8A%E9%88%8D-Claude-Messages-API-%E7%9A%84%E9%9A%A8%E9%81%B8%E5%A3%93%E7%B8%AE%E8%B7%9F%E4%BD%A0%E8%87%AA%E5%B7%B1%E5%AF%AB%E6%91%98%E8%A6%81%E5%B7%AE%E5%9C%A8%E4%B8%80%E5%80%8B%E7%B0%BD%E7%AB%A0/"/>
    <published>2026-09-23T03:00:00.000Z</published>
    <summary>自己寫 agent loop 最後都會撞到同一件事：對話越長答得越鈍。Messages API 的隨選壓縮（compact-2026-09-04）讓你自己決定什麼時候換摘要，而且換完不會把保留下來的 thinking 弄壞。</summary>
    <title>對話長到開始變鈍：Claude Messages API 的隨選壓縮，跟你自己寫摘要差在一個簽章</title>
    <updated>2026-09-23T13:10:57.653Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="AI與科技新聞" scheme="https://blog.longhopick.com/categories/AI%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E/"/>
    <category term="開源" scheme="https://blog.longhopick.com/tags/%E9%96%8B%E6%BA%90/"/>
    <category term="Anthropic" scheme="https://blog.longhopick.com/tags/Anthropic/"/>
    <category term="AI與科技新聞" scheme="https://blog.longhopick.com/tags/AI%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E/"/>
    <category term="OpenAI" scheme="https://blog.longhopick.com/tags/OpenAI/"/>
    <category term="AI 安全" scheme="https://blog.longhopick.com/tags/AI-%E5%AE%89%E5%85%A8/"/>
    <content>
      <![CDATA[<p>九月二十二日，Anthropic 發布 Claude Opus 5.5，把 input 從每百萬 token 五美元調到四美元。九十分鐘之後，OpenAI 發布 GPT-6 Sol 與 Luna，中階那一款的牌價直接砍一半。</p><p>兩家動的層級不一樣、幅度也不一樣，挑的日子一樣。這種時候，時間點通常比幅度更值得看。</p><p>隔天下午，這兩家公司的執行長出現在同一場會議上。聯合國安全理事會的 AI 高階簡報會，議題是怎麼替 AI 的能力與安全防護訂出跨國可比的基準。</p><p>前一天搶價格，隔一天談煞車。指控誰虛偽是最省事的讀法，也是最沒用的：虛偽是道德判斷，判完就沒有下一步。該問的是，如果一家公司即使自己想放慢也停不下來，它在安理會上主張的那套標準，最後會由誰來付代價？</p><h2 id="一、九十分鐘"><a href="#一、九十分鐘" class="headerlink" title="一、九十分鐘"></a>一、九十分鐘</h2><p>Opus 5.5 的價目表長這樣：input 每百萬 token 四美元，output 二十美元，cache reads 零點二美元，cache writes 五美元。對照 Opus 5 的五美元與二十五美元，這兩格各降兩成；cache reads 從零點五掉到零點二，降幅六成。</p><p>發布頁上還有另一個數字：整體執行成本降低 40%。它跟上面那個「兩成」不是同一回事。四成講的是典型工作負載下的總執行成本，把速度與效率的提升一起算進去了（官方同時宣稱生成速度比 Opus 5 快三成以上）；兩成講的是牌價本身。一個是你的帳單，一個是你的帳單除以你做完的事。</p><p>九十分鐘後那一邊：GPT-6 Sol 的 input 每百萬 token 兩美元、output 十美元，前一代 GPT-5.6 Sol 是四美元與二十美元，剛好砍一半。更小的 Luna 是零點一與零點五，前代 GPT-5.6 Luna 是零點二與一點二，input 降五成、output 降五成八。OpenAI 發言人向 VentureBeat 確認過，這是永久定價不是促銷；反而是 GPT-5.6 當初那組價格才帶有促銷性質。</p><p>有個巧合值得停一下。Anthropic 把旗艦降到的位置（四美元／二十美元），正好是 OpenAI 中階模型前一代的牌價，而 OpenAI 同一天把那個位置又砍了一半。兩者不是同級距的產品，拿價格排名意義不大，但價格帶被壓縮是真的。</p><p>OpenAI 對降價原因的說法很技術性：「Improvements in caching and inference let us serve these models at lower cost, and we’re passing those savings directly on to users and customers.」快取與推論的改善讓服務成本降下來，省下的直接還給使用者和客戶。</p><p>這個說法可能完全正確，而且它不影響底下那件事：九十分鐘。</p><p>一家公司因為成本降低而降價，那叫效率。兩家公司在同一天、相隔九十分鐘各自把價格往下推，那是另一種東西。這個局裡最穩的輸法是「今天不跟」。任何一方停手，市占就被對面吃走，而這個階段的市占多半會反映在下一輪的估值上。兩邊因此被同一個結構推著走。看起來像激烈競爭，實際上是雙方同時少了一個選項。</p><p>我的立場是，這一輪降價我不讀成效率紅利的傳遞，我讀成雙方都沒有停手選項的訊號。有兩件事會讓我改口：任一方公布這兩款模型的單位毛利並顯示降價後仍為正，或者其中一方在對手降價後選擇不跟進、而市占沒有明顯流失。任何一個出現，「被鎖死」這個判斷就不成立。</p><p>Anthropic 自己在發布內容裡放了一句提醒，我認為它比價格重要：「That said, at these levels of capability we’ve found that benchmark margins have become a less reliable guide to real-world differences.」到了這個能力層級，他們發現 benchmark 上的差距已經不是真實差異的可靠指引。</p><p>這句話出自全場最有動機去秀分數的那一方。我接著遇到的麻煩比他說的更基本：我本來想把這幾天冒出來的 AutomationBench 分數排成一張表，連排都排不出來。</p><div class="note warning flat"><p>AutomationBench 這兩天出現了兩次，兩組數字不能放在一起比。TechCrunch 與 VentureBeat 報導 GPT-6 發布時引的那一組：GPT-6 Sol 在 max effort 模式下得 32.0%、平均每個任務成本 0.34 美元；Claude Opus 5.5 在同樣模式下得 40.0%、平均每個任務成本 1.28 美元。小米 MiMo-V2.6 的發布資料裡也有一組：MiMo-V2.6 得 53.1 分，對照的是 Claude Opus 5（不是 5.5）的 50.3 分。一組是百分比、一組是不知道滿分多少的原始分數，對照的 Opus 版本也不同，我手上沒有把兩者換算到同一尺度的依據。</p></div><p>Anthropic 舉的案例是一位測試者用 Opus 5.5 在不到一天內完成一次六十八萬行的程式碼遷移，原本估計要一個工程團隊做好幾週。原句是「One tester completed a 680,000-line code migration in less than a day—work that would have taken an engineering team weeks.」官方轉述的單一案例，沒說是什麼語言、什麼框架、遷去哪裡、驗收標準是什麼。我沒有跑過這兩家的任何一個新模型，這一節的數字都來自官方發布頁與報導。</p><p>Opus 5.5 上架在 Claude 官方平台與 AWS、Google Cloud、Microsoft Azure，發布前交給 Frontier Design 與 METR 等外部單位做過安全測試。Sol 與 Luna 則是旗艦 GPT-6 Astra（九月三日上市）之後往中低階擴的兩個型號。</p><blockquote><p>原文來源：<a href="https://www.anthropic.com/claude-opus-5-5">Anthropic 官方頁面</a> ／ <a href="https://techcrunch.com/2026/09/22/openai-launches-gpt-6-sol-and-luna/">TechCrunch，2026-09-22</a></p></blockquote><h2 id="二、把「事件」變成一個可以數的東西"><a href="#二、把「事件」變成一個可以數的東西" class="headerlink" title="二、把「事件」變成一個可以數的東西"></a>二、把「事件」變成一個可以數的東西</h2><p>九月二十三日下午，聯合國大會第八十一屆會議高級別週期間，安理會開了一場 AI 高階簡報會。召集的是九月輪值主席法國，由法國歐洲與外交部長 Jean-Noël Barrot 主持。</p><p>簡報者四位：Yoshua Bengio（聯合國獨立國際 AI 科學小組共同主席）、Sam Altman（OpenAI 執行長）、Dario Amodei（Anthropic 執行長）、Clément Delangue（Hugging Face 執行長暨共同創辦人）。Altman 本人到場，Amodei 以視訊連線出席。中國的 DeepSeek 與 Moonshot 受邀在會中發言，DeepSeek 創辦人梁文鋒本人不出席。</p><p>十五個成員國同場，美國與中國都在座。口徑要標清楚：這裡的「第一次」指的是安理會場合下美中兩國的前沿 AI 開發商同台談共同的安全疑慮，不是 AI 議題第一次進安理會，那件事二○二三年就發生過。</p><p>Altman 要推的是一套「衡量 AI 能力與評估公司安全防護措施」的全球基準。OpenAI 會前放出的提案有兩條：一是透過美國商務部底下的 US Center for AI Standards and Innovation，推動各國 AI 安全機構之間的標準協作；二是建立一套分類事件的共同衡量方式，範圍寫得很明確，涵蓋「部署前測試環境中發生的事件」與「真實世界中發生的事件」。</p><p>第二條比第一條有意思太多。尾部風險的麻煩不在於它罕見，在於它沒有分母。你沒辦法回答「模型脫離測試環境這種事一年發生幾次」，因為沒有人在數，也沒有人定義過什麼算一次。把部署前測試環境裡的事件納進通報範圍，等於承認那些還沒造成損害、所以現在沒有人需要講出來的東西，也該被記下來。這件事本身防不了什麼，它只是把分母建起來的第一步。</p><p>第一條就微妙了。OpenAI 會前發文裡的原句是：「Whoever leads this process now will determine whether the United States shapes global rules for artificial intelligence or watches as a fragmented, uneven and adversarial system emerges around it.」誰主導這個過程，決定的是美國來形塑全球 AI 規則，還是眼睜睜看著一個破碎、不均、互相對立的體系在周圍長出來。</p><p>一份「全球基準」的提案，包在一句「美國要不要主導」的話裡送出去，承接機構掛在美國商務部底下。標準本身可能是好東西，同時也是效率很高的護城河形狀：規則由誰寫，誰的既有做法就自動合規。這兩件事不衝突，通常一起成立。</p><p>背景比議程本身更硬。OpenAI 今年稍早揭露過自家 AI 模型自主駭入 Hugging Face 基礎設施，Anthropic 之後也揭露了模型相關的網路安全事件；前 Anthropic 研究員 Jacob Coxon 辭職後公開指控這兩家公司「正直奔向自我改進的超級智慧、拿人命去賭」。而 Amodei 本人九月十二日才發表過文章，主張放慢開發步調。</p><p>九月十二日主張放慢，九月二十二日降價兩成，九月二十三日到安理會談標準。三件事出自同一家公司，三件都是真的。</p><p>這裡沒有矛盾可以抓，只有一個結構要看清楚。談標準的那個人，跟被價格戰推著走的那個人是同一個。前者是他的判斷，後者是他的處境。判斷正確不會讓處境消失。</p><p>一位歐洲外交官（報導沒有具名）把核心問題講得比誰都短：「The key question is whether we could one day face a situation where algorithms interacting with each other trigger a war.」有沒有可能有一天，演算法彼此互動的結果會觸發一場戰爭。</p><p>它問的不是某一個模型有多強，是兩個各自沒問題的系統互相反應之後會長出什麼。這類風險不會在任何一方的內部測試裡出現，因為它根本不在任何一方的邊界內。而這幾家公司公布過的安全測試，量的都是自己那一邊。</p><blockquote><p>原文來源：<a href="https://www.securitycouncilreport.org/whatsinblue/2026/09/artificial-intelligence-high-level-briefing-2.php">Security Council Report，2026-09</a> ／ <a href="https://www.cnbc.com/2026/09/22/altman-amodei-unga-ai-safety.html">CNBC，2026-09-22</a> ／ <a href="https://www.axios.com/2026/09/21/openai-ai-safety-standards-us-china">Axios，2026-09-21</a> ／ <a href="https://www.bloomberg.com/news/articles/2026-09-23/openai-s-sam-altman-to-promote-ai-standards-during-un-speech">Bloomberg，2026-09-23</a>（付費牆）</p></blockquote><h2 id="三、同一天的兩份開源公告"><a href="#三、同一天的兩份開源公告" class="headerlink" title="三、同一天的兩份開源公告"></a>三、同一天的兩份開源公告</h2><p>Alphabet 旗下的機器人軟體公司 Intrinsic，在多倫多的 ROSCon 2026 上開源了 Intrinsic Core，授權 Apache 2.0。裡面是一整套工業機器人底層：硬體無關的即時控制框架 Intrinsic Control、整合 Nvidia FoundationPose 的姿態估計、無碰撞路徑的運動規劃、依物件擺放調整夾爪的抓取規劃，另外還有模擬校準服務與 ROS 驅動程式。同場發布的還有一份參考設計，支援 Universal Robots 與 FANUC 的 CNC 機台看管。這家公司的來歷也值得一提：CTO Brian Gerkey 是 ROS 共同創辦人、曾任 Open Robotics 執行長，Intrinsic 在二○二二年十二月收購了 Open Source Robotics Corporation。</p><p>repo 上有一行免責聲明，是這則裡最值得抄下來的一句：Intrinsic Core 不是「officially supported Google product」，正式導入前要自行驗證硬體相容性、即時行為與現場安全架構。開源一套工業機器人的控制堆疊，跟開源一個網頁框架不一樣。後者出錯是畫面壞掉，前者出錯是有東西在物理世界裡動起來。</p><p>另一邊，小米集團開源 MiMo-V2.6 系列三款：旗艦 Pro、效率版 Flash，以及 Pro-UltraSpeed，官方宣稱後者在同等品質下比 Pro 快二十倍。原生吃文字、圖片、影片、音訊四種輸入，context window 一百萬 token，視覺編碼器六點八一億參數，AudioTokenizer 三點○八億參數，每串流每秒超過一百六十五 token。架構細節發布在 Hugging Face，權重可自由下載自架。OpenRouter 上的價格是 Flash 零點一四／零點二八美元（每百萬 token 的 input／output）、Pro 零點四三五／零點八七、Pro-UltraSpeed 四點三五／八點七。</p><p>工業機器人的控制堆疊掛上 Apache 2.0，全模態模型的權重可以直接抓下來。跟前面那兩場降價一樣，都是把原本要花錢買或花人力自建的能力，往「不必擁有也拿得到」那一邊推。</p><div class="note warning flat"><p>這一節有幾個界線要標。Intrinsic 提到的「超過 5,000 名開發者、來自 115 個國家」是 AI for Industry Challenge 這個活動的參與規模，不是 Intrinsic Core 的採用數字，後者目前沒有任何數據。官方部落格那句定調句我只拿到被截斷的版本，所以全文只用間接敘述、沒當逐字引文。小米那邊，報導提到標準 API 定價沿用 V2.5 的舊價格，但沒說明「標準 API」跟 OpenRouter 這兩個通路是什麼關係，我沒查清楚就不寫。另外 Opus 5.5 的 context window 大小，官方頁面內文沒有標出數字，我不填。</p></div><blockquote><p>原文來源：<a href="https://www.intrinsic.ai/blog/posts/introducing-intrinsic-core">Intrinsic 官方部落格</a> ／ <a href="https://siliconangle.com/2026/09/22/googles-robotics-unit-intrinsic-open-sources-its-foundational-infrastructure-for-intelligent-robots/">SiliconANGLE，2026-09-22（Intrinsic）</a> ／ <a href="https://siliconangle.com/2026/09/22/xiaomi-introduces-mimo-v2-6-series-open-source-ai-model-family/">SiliconANGLE，2026-09-22（小米）</a></p></blockquote><hr><p>降價最直接的後果不是省錢，是讓「錯一次」變便宜。而 Anthropic 自己已經講了，到這個能力層級，benchmark 上的差距不再是真實差異的可靠指引。既然榜單不告訴你答案，剩下能告訴你的就只有真的拿去跑，跑到它壞掉為止。而「跑到壞掉」這件事，過去大部分團隊付不起。</p><p>這一輪之後便宜了一截。一個系統要先能便宜地失敗，才有機會在真正出事之前把自己的邊界撞出來。安理會那場會議想建立的事件分類機制，做的是同一件事的制度版本：把還沒造成損害的失敗也記下來，讓所有人終於有一個分母可以吵。</p><p>不過這兩件事的時間差很大。價格是昨天就降下來的，分母那一邊還停在「有人提議要開始數」。撞牆的成本已經先降了，記錄撞牆的機制還沒跟上。</p>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/23/AI-%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E%E6%91%98%E8%A6%81-20260923/</id>
    <link href="https://blog.longhopick.com/2026/09/23/AI-%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E%E6%91%98%E8%A6%81-20260923/"/>
    <published>2026-09-23T02:00:00.000Z</published>
    <summary>九十分鐘之內兩家公司先後降價，隔天同一批執行長出現在聯合國安理會談全球安全基準。值得問的不是誰虛偽，是誰還有停手的選項。</summary>
    <title>AI 與科技新聞摘要 - 2026/09/23</title>
    <updated>2026-09-23T13:11:04.701Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="AI 開發工具" scheme="https://blog.longhopick.com/categories/AI-%E9%96%8B%E7%99%BC%E5%B7%A5%E5%85%B7/"/>
    <category term="OpenAI" scheme="https://blog.longhopick.com/tags/OpenAI/"/>
    <category term="DevOps" scheme="https://blog.longhopick.com/tags/DevOps/"/>
    <category term="Performance" scheme="https://blog.longhopick.com/tags/Performance/"/>
    <category term="資料庫" scheme="https://blog.longhopick.com/tags/%E8%B3%87%E6%96%99%E5%BA%AB/"/>
    <content>
      <![CDATA[<p>一個 UPDATE 進到 PostgreSQL 裡面，底層到底在做什麼運算？</p><p>先問這個，是因為它決定了下面這套架構能不能成立。OpenAI 在 2026 年 1 月 22 日發了篇工程文章，說 ChatGPT 和 API 平台底下的 PostgreSQL 是一台沒分片的 Azure PostgreSQL Flexible Server 主庫，負責全部寫入，後面掛將近 50 台跨區 read replica。原文寫 “a single primary Azure PostgreSQL flexible server instance and nearly 50 read replicas spread over multiple regions globally”，同一段還說過去一年 PostgreSQL 的負載成長超過 10 倍。（作者是 OpenAI 的 Bohan Zhang。原站目前回 403，引用段落核對自 Wayback Machine 存檔。）</p><p>轉述這件事的文章大多停在「他們沒分片，猛」。但沒分片是結果不是做法。要看懂它為什麼撐得住，得先回到最上面那個問題。</p><p>先釘一個口徑。原文寫 “800 million ChatGPT users”，沒註明是註冊數還是活躍數，也沒給統計窗口。所以下面我不會拿它推算每秒寫入量，推不出來。</p><h2 id="改一個欄位，資料庫實際上複製了整列"><a href="#改一個欄位，資料庫實際上複製了整列" class="headerlink" title="改一個欄位，資料庫實際上複製了整列"></a>改一個欄位，資料庫實際上複製了整列</h2><p>PostgreSQL 用 MVCC 做併發控制。官方那篇文章對它的描述是逐字這樣寫的：</p><blockquote><p>“when a query updates a tuple or even a single field, the entire row is copied to create a new version. Under heavy write loads, this results in significant write amplification.”</p></blockquote><p>白話版：你 UPDATE 一列裡的某個欄位，資料庫不會跑去那個欄位把值蓋掉。它會把整列複製一份，在新的那份上寫新值，讓舊的那份留在原地。</p><p>像一本紙本帳本。要改第 37 行的金額，橡皮擦的做法快，但有人正在讀那一行就會讀到改到一半的東西。MVCC 是另外抄一整行寫在後面，各標一個版本號，誰都不會看到半成品。代價是帳本變厚。</p><p>變厚的那部分叫 dead tuple。官方文章接著寫：</p><blockquote><p>“It also increases read amplification, since queries must scan through multiple tuple versions (dead tuples) to retrieve the latest one.”</p></blockquote><p>所以一次寫入的成本不只是「寫一份新資料」。同一段列出三個併發症：table and index bloat、index maintenance overhead，還有複雜的 autovacuum 調校。這三個看起來像平行的清單，其實是一條鏈：舊版本沒被回收，表和索引脹大，查詢要掃更多頁面，autovacuum 得跑更勤，而它自己也吃 CPU 和 IO，跑得越勤，主庫剩給正常查詢的資源越少。</p><p>現在把這條鏈的每一步看一遍，問同一句話：這一步能不能丟給後面那 50 台 replica 分擔。</p><p>產生新版本要看當前的可見性規則。維護索引要改同一棵 B-tree。回收 dead tuple 要知道還有沒有人在讀舊版本。這三件事全部依賴同一份狀態，而那份狀態只存在於主庫。一步都丟不出去。</p><p>MVCC 決定的不是「寫入只能有一台機器」，是「那台機器每次寫入得付多少成本」。這份成本攤不掉，replica 加到 50 台也分不走一頁。</p><p>至於寫入為什麼全壓在同一台，那是另一個問題，跟 MVCC 無關。官方文章給了三條理由，等一下會拆。</p><h2 id="WAL-只能單向流出去，而它要餵將近-50-張嘴"><a href="#WAL-只能單向流出去，而它要餵將近-50-張嘴" class="headerlink" title="WAL 只能單向流出去，而它要餵將近 50 張嘴"></a>WAL 只能單向流出去，而它要餵將近 50 張嘴</h2><p>讀能水平擴充，是因為讀不需要動到那份狀態。主庫把確定的變更寫成 WAL，replica 接收並重放，就得到一份能服務查詢的副本。這條路單向，WAL 從主庫出去，不會回來。</p><p>單向也有單向的麻煩。近 50 台 replica 就是 50 條要餵的管線，餵的人只有一個。官方文章說他們正在測 cascading replication，讓中繼的 replica 幫忙轉發，目標是撐到 “potentially over a hundred replicas”。這功能現在的狀態，原文講得很直接：</p><blockquote><p>“The feature is still in testing; we’ll ensure it’s robust and can fail over safely before rolling it out to production.”</p></blockquote><p>還在測，沒上生產。</p><p>連線那層也有硬上限，官方文章寫 “Each instance has a maximum connection limit (5,000 in Azure PostgreSQL)”。解法是 PgBouncer，跑 statement 或 transaction pooling，每個 read replica 各有一組 pod 擋在前面。導入後平均連線建立時間從 50ms 降到 5ms，原文標得很清楚是 “in our benchmarks”，benchmark 環境的平均值，不是生產的 p99。</p><h2 id="三個真實案例，其中一個的答案不在-CPU-上"><a href="#三個真實案例，其中一個的答案不在-CPU-上" class="headerlink" title="三個真實案例，其中一個的答案不在 CPU 上"></a>三個真實案例，其中一個的答案不在 CPU 上</h2><p>官方文章描述故障怎麼擴散的時候，用的詞是 vicious cycle，惡性循環：</p><blockquote><p>“an upstream issue causes a sudden spike in database load, such as widespread cache misses from a caching-layer failure, a surge of expensive multi-way joins saturating CPU, or a write storm from a new feature launch. As resource utilization climbs, query latency rises and requests begin to time out. Retries then further amplify the load, triggering a vicious cycle with the potential to degrade the entire ChatGPT and API services.”</p></blockquote><p>官方文章對這件事只有這一段。有肉的在另一份來源：同一位作者在 PGConf.dev 2025（2025 年 5 月）的技術簡報，三張投影片是三個案例的流程圖。</p><p>第一個案例是快取。投影片逐格的文字是 “Something wrong in Redis” → “Redis Cache Misses” → “More Load in Postgres” → “App Slow Requests or Timeout” → “More Requests due to retries”，最後一格畫了條線繞回第三格，旁邊標著 vicious cycle。官方文章在這裡只寫 “a caching layer”，沒指名產品，Redis 這兩個字只出現在簡報上。止血手段掛兩個位置：主庫和 proxy 做 rate limit，應用層過載時直接丟請求。</p><p>第二個案例是那個 12 張表的 JOIN。官方文章逐字寫 “we once identified an extremely costly query that joined 12 tables, where spikes in this query were responsible for past high-severity SEVs.”，簡報第 11 頁同樣提到。對策裡有一條要單獨拿出來講：允許針對特定 query digest 封鎖或限流，他們的 rate limit 細到「某一類查詢」這個粒度。</p><p>第三個案例是寫入尖峰。三個裡面，這個要慢慢看。</p><div class="timeline blue"><div class='timeline-item headline'>        <div class='timeline-item-title'>          <div class='item-circle'><p>一次寫入尖峰的實際推進（PGConf.dev 2025 簡報第 20–21 頁）</p></div>        </div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>寫入量突然暴增</p></div>        </div>        <div class='timeline-item-content'><p>投影片原文：”A huge spike in writes”。</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>主庫 CPU 衝到 90%+</p></div>        </div>        <div class='timeline-item-content'><p>“High CPU usage in primary (90%+)”。直覺到這一步都還成立，寫入暴增，CPU 跟著上去。</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>Read replica 落後超過 10 分鐘</p></div>        </div>        <div class='timeline-item-content'><p>“Increased Read Replica Lags (&gt; 10 mins)”。查詢變慢、replica 上的資料過期、新寫入進不來，ChatGPT 服務受影響。</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>對寫入限流，CPU 回到正常，lag 繼續漲</p></div>        </div>        <div class='timeline-item-content'><p>“After rate limiting write queries, primary CPU usage returned to normal, but read replica lag continued to increase”。</p></div>      </div></div><p>最後那格才是重點。限流是對的動作，CPU 也真的回去了，但要救的那個指標動都不動。</p><p>簡報列出來的三個真因，沒有一個是 CPU：主庫的網路頻寬飽和（”Network bandwidth saturation in primary”）、部分 replica 的磁碟 IOPS 飽和（”Disk IOPS saturation in some replicas”），以及一個 WAL sender 的 bug，在 <code>async_standbys_wait_for_sync_replication</code> 開啟時會讓它瘋狂空轉而不是把 WAL 串流出去（”leads to excessive spinning instead of streaming WAL to replicas”）。處理方式是加大 instance 規格與網路上限、調網路設定，以及修掉那個 bug。</p><p>CPU 是最好量的指標，所以查到它就很容易停下來。這個案例裡 CPU 從頭到尾都沒說謊，寫入尖峰時它真的 90%+，限流後它真的回到正常。它只是不在那條卡住的路上。而第三個真因更陰：WAL sender 那時候是有吃 CPU 的，它看起來很忙，但它忙的內容不是「把 WAL 送出去」。</p><p>下次遇到 replica lag，先看主庫 CPU 這條路可以直接跳過。CPU 正常不代表 WAL 有流出去，中間還隔著網路頻寬、replica 端的磁碟，以及 WAL sender 有沒有真的在做事。</p><h2 id="順著那個參數名字往回挖，挖到-2022-年"><a href="#順著那個參數名字往回挖，挖到-2022-年" class="headerlink" title="順著那個參數名字往回挖，挖到 2022 年"></a>順著那個參數名字往回挖，挖到 2022 年</h2><p><code>async_standbys_wait_for_sync_replication</code> 這個名字，在 PostgreSQL 官方文件的 replication 參數頁（<code>runtime-config-replication.html</code>）上找不到。</p><p>它的出處是 2022 年 pgsql-hackers 郵件列表的提案討論串〈Allow async standbys wait for sync replication〉，提案者 Bharath Rupireddy，時間跨 2021 年 12 月到 2022 年 3 月。串上有人貼出測試輸出，<code>show async_standbys_wait_for_sync_replication;</code> 回傳 <code>off</code>，可見它確實存在於某個 build。</p><p>Nathan Bossart 在串上提的技術疑慮，逐字是：</p><blockquote><p>“I don’t think it’s a good idea to block sending any WAL like this… I believe this patch will cause the server to avoid sending <em>any</em> WAL until the synchronous LSN advances.”</p></blockquote><p>他擔心的是：可能有一大段 WAL 早就同步複寫完可以送了，卡住的只是最後幾個 byte，但這 patch 會讓 server 在同步 LSN 前進之前一個 byte 都不送。</p><p>這串查得到的最後一封信是 2022 年 3 月 17 日，沒找到說它被接受或被拒絕的回覆。合理推論是它沒進核心，但這是推論，不是串裡的明文結論。</p><p>還有一點免得被我帶偏。這串查得到的參與者網域是 gmail、amazon、NTT 這些，沒出現 Azure 或 Microsoft 字樣。那個參數在 Azure PostgreSQL Flexible Server 上確實開得起來，但「這是雲商自己帶的 patch」我沒有證據，不寫成結論。能說的只有一件：一個開得起來、又不在官方文件清單裡的參數，讓他們吃了一次事故。</p><h2 id="同一件事，兩份來源講得不一樣"><a href="#同一件事，兩份來源講得不一樣" class="headerlink" title="同一件事，兩份來源講得不一樣"></a>同一件事，兩份來源講得不一樣</h2><p>官方部落格是 2026 年 1 月的成功故事，PGConf.dev 簡報是 2025 年 5 月講給同業聽的，坦率程度差很多。有幾處要對著看：</p><table><thead><tr><th>項目</th><th>官方部落格（2026-01-22）</th><th>PGConf.dev 2025 簡報（2025-05）</th></tr></thead><tbody><tr><td>SEV-0 的統計窗口</td><td>“over the past 12 months, we’ve had only one SEV-0 PostgreSQL incident”</td><td>“Only one SEV-0 incident involving PostgreSQL in the past 9 months since I joined OpenAI”</td></tr><tr><td>主庫掛掉時的嚴重度</td><td>“it’s no longer a SEV0 since reads remain available”，沒說降到哪一級</td><td>第 12 頁明確寫 SEV2</td></tr><tr><td>快取層是什麼</td><td>只寫 “a caching layer”</td><td>第 18 頁寫 “Something wrong in Redis”</td></tr><tr><td>PostgreSQL 的不足</td><td>沒有這段</td><td>有完整一段</td></tr></tbody></table><p>兩個窗口不衝突，但不能混用，起算點不一樣。</p><p>那次 SEV-0 官方文章寫得很具體：”it occurred during the viral launch of ChatGPT ImageGen, when write traffic suddenly surged by more than 10x as over 100 million new users signed up within a week.”。</p><p>延遲的說法是 “low double-digit millisecond p99 client-side latency”，client-side 這個限定要留著。</p><h2 id="什麼時候該抄他們，什麼時候不該"><a href="#什麼時候該抄他們，什麼時候不該" class="headerlink" title="什麼時候該抄他們，什麼時候不該"></a>什麼時候該抄他們，什麼時候不該</h2><p>我的立場：如果你的負載是讀多寫少，不要因為「將來會長大」就先去分片。</p><p>原文的理由有三條：要改數百個 application endpoint、工期可能數月甚至數年、他們的負載本來就讀多寫少且優化過後餘裕還夠。最貴的是第一條，一次性、不好分批，改完之後每個查詢都要開始想 shard key。</p><p>兩種情況下這段對你不成立。寫入本來就有天然的分割鍵，每個租戶各一份、彼此不用 JOIN，那分片成本沒他們說的那麼高，早做早省事。或者寫入量已經逼近單機能產生 WAL 的速度，這時應用層再怎麼優化都沒用。</p><p>OpenAI 自己就是照這條界線在走：可分片、寫入密集的負載移去 Azure Cosmos DB，現在也不准在 PostgreSQL 加新表，”New workloads default to the sharded systems.”。原文對未來的措辭是 “not a near-term priority”，近期不是優先項，不是永遠不做。</p><p>schema 那層他們也鎖得很緊：只允許不觸發 full table rewrite 的輕量變更、5 秒硬 timeout、索引可以 concurrently 建、只能動既有的表。只要有長查詢壓著那張表，變更就會失敗，所以簡報第 15 頁附了段找兇手的 SQL：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> pg_stat_activity</span><br><span class="line"><span class="keyword">WHERE</span> query <span class="keyword">like</span> <span class="string">&#x27;%table_name%&#x27;</span> <span class="keyword">and</span> now() <span class="operator">-</span> query_start <span class="operator">&gt;</span> <span class="type">interval</span> <span class="string">&#x27;1 seconds&#x27;</span></span><br></pre></td></tr></table></figure><p>backfill 有時候要跑超過一週。</p><h2 id="還沒解完的部分"><a href="#還沒解完的部分" class="headerlink" title="還沒解完的部分"></a>還沒解完的部分</h2><p>簡報最後有一整段官方部落格沒有的內容，講 PostgreSQL 哪裡還可以更好。</p><p><code>pg_stat_statement</code> 只給每個 query digest 的平均延遲，拿不到百分位數，原句是 “We cannot get query percentiles (like p95, p99) directly.”。一個每秒跑幾百萬次查詢的系統，query 層級只能看平均值。索引也一樣：PostgreSQL 不支援停用索引，只能直接刪，想先關掉觀察一陣子再決定做不到；刪了要回來就得重建，大索引重建很花時間。</p><p>最後那個他們自己也沒答案。有查詢停在 <code>active</code> 狀態長達 2 小時 23 分鐘，<code>wait_event</code> 是 <code>ClientRead</code>，整段時間都在等 client 端的下一個指令。因為狀態是 <code>active</code> 而不是 <code>idle in transaction</code>，<code>idle_in_transaction_session_timeout</code> 殺不掉它。簡報上留的是三個問句：</p><blockquote><p>“Is it a bug in Postgres? Should the state be idle_in_transaction? If not, how to kill it automatically?”</p></blockquote><p>那是簡報第 25 頁，後面三頁沒有再回來回答。</p><p>整條線倒過來看，會看到一件跟直覺相反的事：前面那三條不分片的理由，沒有一條是「PostgreSQL 做不到」。三條全部在講划不划算，不在講能不能。</p><p>那場簡報最後一頁給開發者的建議只有一句：”If you are a developer, or building a startup, start with Postgres (for read-heavy workloads)”。重點在括號裡。</p><p>而讀多寫少是不是你的處境，監控面板不會直接告訴你。把寫入路徑一條一條攤開來問：這次寫入需不需要先看到別的寫入的結果。答「不需要」的那些遲早要搬走，OpenAI 搬去了 Cosmos DB，還順手加了一條規則不准在 PostgreSQL 開新表。答「需要」的那些留下來，它們每一次都會複製一整列、留下一個等人來收的舊版本，而那份成本，你加多少台 replica 都分不掉。</p><hr><p><strong>來源</strong></p><ul><li>OpenAI 官方工程文章〈Scaling PostgreSQL〉，2026 年 1 月 22 日，作者 Bohan Zhang：<a href="https://openai.com/index/scaling-postgresql/">https://openai.com/index/scaling-postgresql/</a>（原站目前回 403，本文引用段落核對自 <a href="http://web.archive.org/web/20260909081037/https://openai.com/index/scaling-postgresql/">Wayback Machine 存檔</a>）</li><li>同作者於 PGConf.dev 2025（2025 年 5 月）的技術簡報，文中標註頁碼者出處為此</li><li>pgsql-hackers 討論串〈Allow async standbys wait for sync replication〉：<a href="https://www.postgresql.org/message-id/CALj2ACU0+5aS9NXvm6o_1g8YZ9dq6bYHsUPteZ_YjuwNd4pDOw@mail.gmail.com">https://www.postgresql.org/message-id/CALj2ACU0+5aS9NXvm6o_1g8YZ9dq6bYHsUPteZ_YjuwNd4pDOw@mail.gmail.com</a></li><li>PostgreSQL 官方文件 replication 參數頁：<a href="https://www.postgresql.org/docs/current/runtime-config-replication.html">https://www.postgresql.org/docs/current/runtime-config-replication.html</a></li></ul>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/23/OpenAI-%E7%9A%84-PostgreSQL-%E6%B2%92%E6%9C%89%E5%88%86%E7%89%87-%E7%AD%94%E6%A1%88%E8%A6%81%E5%BE%9E%E4%B8%80%E5%80%8B-UPDATE-%E9%96%8B%E5%A7%8B%E6%8B%86/</id>
    <link href="https://blog.longhopick.com/2026/09/23/OpenAI-%E7%9A%84-PostgreSQL-%E6%B2%92%E6%9C%89%E5%88%86%E7%89%87-%E7%AD%94%E6%A1%88%E8%A6%81%E5%BE%9E%E4%B8%80%E5%80%8B-UPDATE-%E9%96%8B%E5%A7%8B%E6%8B%86/"/>
    <published>2026-09-23T01:00:00.000Z</published>
    <summary>單一主庫加近 50 台 read replica 撐住 ChatGPT。從 MVCC、WAL 一路拆到三個真實故障案例，看那台主庫每次寫入到底在付什麼成本。</summary>
    <title>OpenAI 的 PostgreSQL 沒有分片，答案要從一個 UPDATE 開始拆</title>
    <updated>2026-09-23T12:58:34.513Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="Claude Code" scheme="https://blog.longhopick.com/categories/Claude-Code/"/>
    <category term="Claude Code" scheme="https://blog.longhopick.com/tags/Claude-Code/"/>
    <category term="開發工具" scheme="https://blog.longhopick.com/tags/%E9%96%8B%E7%99%BC%E5%B7%A5%E5%85%B7/"/>
    <category term="教學" scheme="https://blog.longhopick.com/tags/%E6%95%99%E5%AD%B8/"/>
    <category term="Claude" scheme="https://blog.longhopick.com/tags/Claude/"/>
    <content>
      <![CDATA[<p>2026 年 6 月 18 日之前，要把一次排查的結果拿給同事看，得自己想辦法。貼一整面終端機捲軸，或者請 Claude 寫一個獨立的 HTML 檔，自己按兩下打開確認沒破版，再把檔案丟進 Slack。對方下載、打開，看到的是你按下產生那一刻的樣子。之後任務又跑出什麼，那個檔案不知道。</p><p>那天 Anthropic 的部落格宣布 Claude Code 的 session 成果可以直接變成 claude.ai 上的一個網址，原文寫的是「live, shareable visual pages… that update themselves as your session works」。技術文件那邊的界線則很清楚，我查證當天讀到的版本是這樣寫的：</p><blockquote><p>“An artifact is a capture of work: one self-contained page with no backend, so it can’t serve multiple routes. For a hosted internal tool with a backend, deploy it on your own infrastructure instead.”</p></blockquote><p>本站 6 月 22 日那篇<a href="/2026/06/22/Claude-Code-Artifacts-%E5%AE%8C%E6%95%B4%E6%95%99%E5%AD%B8-%E6%8A%8A%E4%B8%80%E6%AC%A1-debug-%E9%81%8E%E7%A8%8B%E8%AE%8A%E6%88%90%E5%90%8C%E4%BA%8B%E9%BB%9E%E9%96%8B%E5%B0%B1%E6%87%82%E7%9A%84%E7%B6%B2%E9%A0%81/">Artifacts 教學</a>就是照這條線寫的。我在裡面用了照片跟店面的比方：artifact 像你拍的一張照片，不像你開的一家店，照片裡的收銀機不會真的收錢。</p><p>三個月後，收銀機開始收錢了。而那句話還在原地。</p><h2 id="另一條線的持久化，早了將近八個月"><a href="#另一條線的持久化，早了將近八個月" class="headerlink" title="另一條線的持久化，早了將近八個月"></a>另一條線的持久化，早了將近八個月</h2><p>這裡有個同名的東西很容易混掉。claude.ai 網頁跟桌面版的「聊天」裡也有 Artifacts，那套從 2025 年 6 月 25 日就在，比 Claude Code 這邊早了將近一年，2025 年 7 月上了 iOS 跟 Android，同年 7 月底擴大到 Team 與 Enterprise 方案。</p><p>真正該記住的是 2025 年 10 月 21 日那次更新，標題直接寫了 Artifacts now support MCP and persistent storage。聊天版的 Artifacts 從那時候起可以存資料，而且 Help Center 對這套寫得相當完整：Pro、Max、Team、Enterprise 方案可用；儲存分個人跟共用兩種模式，個人模式每個人只看得到自己那份，共用模式所有人看同一份；每個 artifact 上限 20 MB，只收純文字，圖片、檔案、二進位資料都不行；而且只有發布之後才存得進去，開發跟測試階段的寫入一律不會成功。連退場路徑都交代了：取消發布會把個人跟共用的資料一起永久刪除，同一個 artifact 之後不能再發布一次。</p><p>開發者實際要呼叫什麼，官方反而沒給出精確的方法簽名。社群觀察到的用法大致是 <code>window.storage</code> 上的 set 跟 get，第三個參數決定資料進個人還是共用。這個簽名只有社群專案佐證，Anthropic 沒有逐字文件承認過。</p><p>落差在這裡。Claude Code 這邊的版本，連方法名稱都還沒進過主文件。</p><h2 id="讓頁面看起來是活的"><a href="#讓頁面看起來是活的" class="headerlink" title="讓頁面看起來是活的"></a>讓頁面看起來是活的</h2><p>回到 Claude Code 這條線。</p><p>2026 年 7 月 13 到 17 日那一週（官方週報 Week 29，release v2.1.207 到 v2.1.212），已發布的 artifact 學會了一件事：每次有人打開它，它可以去呼叫 MCP connector。</p><p>呼叫不是用發布者的帳號跑的。每一次呼叫走的是「正在看這一頁的那個人」自己的 claude.ai 帳號連線，由 claude.ai 代為發出，頁面本身從頭到尾看不到任何人的憑證。第一次呼叫之前，claude.ai 會先跟這位檢視者要權限。這個設計後來讓「沒有後端」那句話很難講得乾脆。</p><p>所以你發布一份 dashboard 給團隊，每個人打開看到的是各自帳號權限下的即時資料，而不是你建置那一刻的快照。你的本機 MCP server 不算在內：<code>.mcp.json</code> 裡設定的那些只在 Claude 建置頁面的當下派得上用場，發布出去的頁面呼叫不到它們，只有掛在 claude.ai 帳號底下的 connector 才行。</p><p>這一步解掉的是資料會過期。它沒有解掉另一件事：使用者能不能在這頁上留下任何東西。讀的來源從快照換成即時了，頁面上還是沒有一個地方可以寫。</p><h2 id="留言是掛在一次對話後面的尾巴"><a href="#留言是掛在一次對話後面的尾巴" class="headerlink" title="留言是掛在一次對話後面的尾巴"></a>留言是掛在一次對話後面的尾巴</h2><p>接下來兩版把「寫」開了一條縫，但開在旁邊。v2.1.221 之後，Team 或 Enterprise 方案可以讀 artifact 上的留言；v2.1.228 之後，Claude 可以自動回覆那些留言。這兩版各自落在哪一天，官方文件只寫了「需要這個版本以上」，沒給日曆日期，我也不打算估。</p><p>綁定條件很硬。Claude Code 只在那個 session 還跑著的期間 watch 那份 artifact 的留言，session 一結束，自動回覆就停。文件還補了一條節流：同一份 artifact 在一小時內處理滿 60 則留言或討論串觸發之後，Claude 會自己停下來不再回。</p><p>這仍然不是一個常駐的服務。對話結束，尾巴就不動了。</p><h2 id="changelog-裡開始出現-artifact-database"><a href="#changelog-裡開始出現-artifact-database" class="headerlink" title="changelog 裡開始出現 artifact database"></a>changelog 裡開始出現 artifact database</h2><p>2026 年 9 月 10 日到 19 日之間，v2.1.268 到 v2.1.278 這一串版本的 changelog 裡，出現了一個在主文件裡完全不存在的名詞。</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">v2.1.271 (2026-09-14)</span><br><span class="line">  Changed artifact database reads that save into the session scratchpad</span><br><span class="line">  so they no longer stop for working-folder approval</span><br><span class="line"></span><br><span class="line">v2.1.272 (2026-09-15)</span><br><span class="line">  Fixed artifact database writes: an update can now remove a single field</span><br><span class="line">  instead of rewriting the whole document</span><br><span class="line"></span><br><span class="line">v2.1.278 (2026-09-19)</span><br><span class="line">  Improved the Artifact tool&#x27;s error when a page declares a capability its</span><br><span class="line">  contract version lacks: it now lists every supported capability and notes</span><br><span class="line">  when a newer contract version has it</span><br><span class="line"></span><br><span class="line">v2.1.278 (2026-09-19)</span><br><span class="line">  Improved artifact watching: a session can now watch up to 10 published</span><br><span class="line">  artifacts at once for republishes made elsewhere, up from 5</span><br></pre></td></tr></table></figure><p>這四句話沒有一句在介紹功能。它們是 bug 修正跟改良條目，寫給已經在用的人看。但正因為這樣，它們洩漏的結構比任何一篇公告都具體。</p><p>先從寫入那條看。「an update can now remove a single field instead of rewriting the whole document」這句話裡，document 是名詞。有 document，就有一個把欄位包起來的單位；而「刪掉單一欄位」跟「整份重寫」被寫成兩條不同的路徑，代表這個儲存層支援部分更新的語意，不是把整坨 JSON 蓋過去了事。這是資料庫的講法，不是瀏覽器本機儲存的講法。</p><p>讀的那一側落在別的地方。讀出來的東西會進 session 的 scratchpad，而且原本會觸發工作目錄的權限確認。也就是說讀取這個動作是 Claude Code 這邊的工具在做，落地在你的檔案系統上，不是純粹在瀏覽器裡跑完就算。</p><p>最值錢的是 capability 那條。「a page declares a capability its contract version lacks」，頁面要「宣告」自己需要哪些 capability，而這些 capability 掛在一個帶版本號的 contract 上面，版本不夠新就缺。這是一整套權能協商機制的輪廓，跟「一頁自己包好的靜態 HTML」那個形象差得非常遠。</p><p>配額是順帶交代的：一個 session 可以同時盯著 10 份已發布的 artifact，看它們有沒有在別處被重新發布，上限從 5 提到 10。</p><p>把這幾條擺在一起，「沒有後端」那句話就開始搖晃。</p><p>我原本的讀法是主詞不一樣。文件那句 no backend 講的是頁面本身那個 HTML 沙盒，它確實還是靜態的、不能自己認證檢視者；而 <code>read_db</code> 跟 <code>write_db</code> 是 Claude 手上那個 Artifact 工具的能力，資料放在 Anthropic 那一側，跟頁面是兩件事。兩句話各說各的，都不算錯。</p><p>這個讀法撐不太住。</p><p>官方沒有任何一份文件做過這個區分。<code>code.claude.com/docs/en/artifacts</code> 通篇沒有 database、capabilities、contract 這三個字。連官方自己的「這週新功能」摘要都還沒寫到：那系列目前最新一期是 Week 37，涵蓋 9 月 7 日到 11 日，裡面跟 artifact 有關的唯一一行是「Claude 可以替它發布的每個 artifact 挑一個瀏覽器分頁圖示」。Week 38 的網址回 404。9 月 14 日之後那批修正，到查證當下還沒被摘要進任何一篇對外的東西。</p><h2 id="PHX-1014-那張單"><a href="#PHX-1014-那張單" class="headerlink" title="PHX-1014 那張單"></a>PHX-1014 那張單</h2><p>9 月 15 日，有人在 claude-code 的 repo 開了 issue #94426，標題是 <code>[BUG] Artifact db capability — live sync doesn&#39;t deliver updates to the page on reload</code>。重現步驟寫得很乾淨：</p><blockquote><p>“Edit a document via the page’s own UI (adds&#x2F;changes a field), confirm the write succeeded via read_db. Fully reload the page (not just close&#x2F;reopen a panel within the same tab). The reload shows the pre-edit state, not the current database state.”</p></blockquote><p>實際案例是一個派工系統。某個 job（編號 PHX-1014）透過頁面自己的編輯表單新增了第二台車輛並存檔，用 <code>read_db</code> 查，兩台車都在、版本號有遞增。然後把頁面完整重新整理。桌機、無痕視窗、手機都試過，畫面上還是只有原本那一台。回報者把 contract 版本從 0.2.43 一路升到 0.2.49，沒有改善。他標的 Claude Code 版本是 2.1.272，正好就是前面那條 Fixed artifact database writes 的同一版。</p><p>那一版修的是「更新可以只動一個欄位，不用整份重寫」，不是「重新整理之後讀得到最新狀態」。這是兩個不同的洞。</p><p>這張單開到今天還是 Open，底下沒有任何一則 Anthropic 員工的回覆。</p><p>回頭看我前面那個「主詞不一樣」的讀法。重現步驟的第一句就是 Edit a document via the page’s own UI，寫入是從頁面上那個表單按下去的。這條線不是只在 Claude 那一側跑，它穿過頁面。所以把「沒有後端」解釋成「那句話只在講沙盒」，我沒有把握。目前我只敢說兩件事：那句話現在至少不完整，而且沒有任何一份官方文件說明它現在完整到哪裡。</p><p>會讓我改掉這個判斷的條件很具體。如果 artifacts 那份文件之後補上 <code>read_db</code>，而且寫在「頁面能做什麼」那一節底下，那就代表頁面自己確實能呼叫，那句 no backend 是單純過期，跟主詞無關。如果補在「Claude 這個工具能做什麼」底下、並且明講頁面不能直接碰，那我前面那個讀法才成立。現在兩種都有可能。</p><div class="note warning flat"><p>這篇的一切都來自官方文件、官方 changelog 與週報、官方部落格、Claude Help Center，以及那一則公開的 GitHub issue。我只讀了文件與 changelog，沒有發布過任何帶資料庫的 artifact，也沒有呼叫過 <code>read_db</code> 或 <code>write_db</code>，這整套能力我一次都沒有實際操作過。版本號對應的確切日期，除了 v2.1.207 到 v2.1.212 那段有官方週報 Week 29 佐證之外，其餘只有文件裡「需要這個版本以上」「在這個版本之前」的相對敘述，我沒有自己估。</p></div><h2 id="那四個字什麼時候消失"><a href="#那四個字什麼時候消失" class="headerlink" title="那四個字什麼時候消失"></a>那四個字什麼時候消失</h2><p>要決定現在敢不敢把這個能力用在正式的東西上，手上的材料就這些。能力是真的，有人在真實案例上用它，Anthropic 正在逐版修它。但沒有一份完整的官方說明描述它，而且一個會讓使用者看到舊資料的同步問題還開著。</p><p>接下來那幾格會怎麼填，比這些材料本身有意思。Week 38 的週報遲早要發。它可能正式介紹這個資料庫能力，也可能跳過不提，而 artifacts 那份文件裡的 No backend 被安靜地改掉。也可能兩件事都沒發生，這個能力繼續只活在逐版 changelog 裡，#94426 底下繼續沒有人回。</p><p>這幾種走向分別代表一個正在成形的功能、一份落後的文件，跟一個被放著的實驗。要判斷是哪一種，不必等公告。去看那份文件的 Page constraints 表格，No backend 那一列什麼時候消失就知道了。</p>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/22/%E6%96%87%E4%BB%B6%E9%82%84%E5%AF%AB%E8%91%97%E6%B2%92%E6%9C%89%E5%BE%8C%E7%AB%AF-changelog-%E5%B7%B2%E7%B6%93%E5%9C%A8%E4%BF%AE%E5%AE%83%E7%9A%84%E8%B3%87%E6%96%99%E5%BA%AB%E5%AF%AB%E5%85%A5/</id>
    <link href="https://blog.longhopick.com/2026/09/22/%E6%96%87%E4%BB%B6%E9%82%84%E5%AF%AB%E8%91%97%E6%B2%92%E6%9C%89%E5%BE%8C%E7%AB%AF-changelog-%E5%B7%B2%E7%B6%93%E5%9C%A8%E4%BF%AE%E5%AE%83%E7%9A%84%E8%B3%87%E6%96%99%E5%BA%AB%E5%AF%AB%E5%85%A5/"/>
    <published>2026-09-22T12:30:00.000Z</published>
    <summary>Claude Code 的 Artifacts 現在有 read_db 跟 write_db，但官方主參考文件到查證當下仍寫著「An artifact is a static page」。這個能力沒有任何一篇公告介紹過，只在逐版 changelog 的 bug 修正裡留下痕跡。</summary>
    <title>文件還寫著沒有後端，changelog 已經在修它的資料庫寫入</title>
    <updated>2026-09-22T13:34:50.403Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="AI與科技新聞" scheme="https://blog.longhopick.com/categories/AI%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E/"/>
    <category term="Anthropic" scheme="https://blog.longhopick.com/tags/Anthropic/"/>
    <category term="AI與科技新聞" scheme="https://blog.longhopick.com/tags/AI%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E/"/>
    <category term="NVIDIA" scheme="https://blog.longhopick.com/tags/NVIDIA/"/>
    <category term="Microsoft" scheme="https://blog.longhopick.com/tags/Microsoft/"/>
    <category term="AI 產業" scheme="https://blog.longhopick.com/tags/AI-%E7%94%A2%E6%A5%AD/"/>
    <content>
      <![CDATA[<p>台北的會場裡，台灣微軟總經理卞志祥在台上講了一句聽起來很平常的話：「未來2到3年看到的態勢依舊是AI算力需求大於供給」。他接著補的那一段更具體：短缺的不只是 GPU 跟 CPU，還有電力，還有新機櫃要塞進去的那塊地板。</p><p>往前推三天，有一家專門在補這個缺口的公司，把自己的帳本攤開給美國證管會看了。機房要有人去蓋，電要有人去拉，長約一簽就簽到下個十年，而這些錢通常不是蓋的人自己的。攤開之後真正要讀的，是那些合約後面附的條件。</p><h2 id="一、1-034-億裡面，26-億是真的"><a href="#一、1-034-億裡面，26-億是真的" class="headerlink" title="一、1,034 億裡面，26 億是真的"></a>一、1,034 億裡面，26 億是真的</h2><p>Nscale 是一家總部在倫敦的 AI 資料中心開發商，創辦人暨執行長是 Josh Payne。九月十八日，它向美國 SEC 遞出 S-1 註冊申請文件，準備在紐約證交所掛牌，股票代號 NSCL。</p><p>招股書上最顯眼的數字是 1,034 億美元。那是截至八月三十一日的「已生效與已簽約總合約價值」，去年底這個數字還是 380 億。</p><p>同一份文件裡還有另一個數字。1,034 億裡面，只有 26 億屬於「已生效」。Investing.com 引的原文是「only $2.6 billion worth was active as of the end of August」。</p><p>兩個數字差了將近四十倍，而它們指的不是同一種東西。1,034 億是承諾，包含未來好幾年才會逐步兌現的部分；26 億是截至八月底真的在跑的部分。招股書把兩個都寫出來是對的，該小心的是外面的人引用哪一個、有沒有把後面那個一起帶上。</p><p>那 1,034 億的組成也很集中。Microsoft 自 2025 年底起與 Nscale 簽了多筆協議，總額約 438 億美元，效期到 2033 年。Anthropic 今年八月簽下一筆約 446 億美元的合約，買的是美國西維吉尼亞州一座規劃中的 8GW 資料中心的運算力，園區叫 Monarch。兩家加起來約 884 億，占總合約價值大約 85%。</p><p>Nscale 自己在申請文件裡把這件事寫成風險因子：「A substantial portion of our revenue is driven by a limited number of our customers.」</p><p>真正該停下來看的是 Anthropic 那一筆的但書。那份合約附了條件：Nscale 必須達成特定里程碑、並且維持可靠的運算效能，否則 Anthropic 有權解約。而這筆交易的融資，到目前為止還沒確定下來。</p><p>1,034 億裡有 446 億是這一筆，超過四成。招股書上最大的單一筆合約，同時是條件最多的那一筆，而它能不能兌現，取決於一座還沒蓋好的園區能不能按期交件，以及一筆還沒談定的融資能不能談定。</p><p>上行是八個 GW 真的蓋起來、客戶真的照約付款，Nscale 成為這一輪基建潮裡最大的贏家之一。下行是里程碑沒達成，解約權在客戶手上；融資沒談成，缺口留在 Nscale 這邊。兩種情況往下掉的都是同一方，而上行要分給股東、債權人跟供應商。這種不對稱不會出現在任何一個合計數字上，它藏在條款裡。</p><p>我的立場是，看這家公司只該看 26 億那一格的成長速度，1,034 億暫時當背景資訊。有兩件事會讓我改口：Anthropic 那筆的融資落定並且解約條款被移除，或者下一期的「已生效」金額出現數量級的跳升。任何一個發生，這個判斷就不成立了。</p><div class="note info flat"><p>這一則的數字有四個口徑，彼此不能加減。1,034 億美元是含未來承諾的合約總值（截至 8 月 31 日）；26 億美元是其中已生效的部分（截至 8 月底）；1.406 億美元是 2026 年 1 到 6 月實際認列的營收，年增 1,252%；同期淨損 10.201 億美元，去年同期的損失是 3.689 億美元。營收與淨損這兩個數字有兩個獨立來源（Investing.com 與 Yahoo Finance）一致。另外 Bloomberg 那篇報導在付費牆後面，我只讀得到標題，上面的金額與占比是從 Investing.com 與 Nscale 官方新聞稿交叉比對出來的。</p></div><p>Nvidia 在這張圖裡同時站了三個位置：它供應晶片，它為 Nscale 的租賃合約提供約 8.6 億美元擔保，它還參與了一輪 31 億美元的融資，其中 10 億美元是可轉換票據。</p><p>換個角度問：這三個身分什麼時候會打架？供應商希望客戶多買，擔保人希望客戶少借，股權投資人希望估值撐住。前兩個的利益方向根本是相反的。平常沒事的時候三個身分互相加分，真的出事那天才會分出來誰先認賠。</p><blockquote><p>原文來源：<a href="https://www.investing.com/news/stock-market-news/85-of-nscales-103b-of-contracts-are-with-microsoft-and-anthropic-4908995">Investing.com，2026-09-21</a> ／ <a href="https://www.sec.gov/Archives/edgar/data/0002110365/000119312526395475/ck0002110365-20260918.htm">SEC S-1 申請文件</a> ／ <a href="https://www.nscale.com/press-releases/nscale-files-initial-public-offering">Nscale 官方新聞稿</a> ／ <a href="https://finance.yahoo.com/markets/stocks/articles/nscale-files-ipo-pipeline-passes-203402491.html">Yahoo Finance</a> ／ <a href="https://www.bloomberg.com/news/articles/2026-09-21/anthropic-and-microsoft-dominate-nscale-s-103-billion-in-contracts">Bloomberg，2026-09-21</a>（付費牆）</p></blockquote><h2 id="二、一個-app-爬到免費榜第一，然後某家公司多了一兆美元"><a href="#二、一個-app-爬到免費榜第一，然後某家公司多了一兆美元" class="headerlink" title="二、一個 app 爬到免費榜第一，然後某家公司多了一兆美元"></a>二、一個 app 爬到免費榜第一，然後某家公司多了一兆美元</h2><p>Meta 的個人 AI agent 應用程式 Muse 九月八日在美國上線，iOS、Android、網頁版跟 WhatsApp 都有，限十八歲以上成人使用。九月十八日，上線第十天，它在美國 Apple App Store 免費榜爬到第一名，把 ChatGPT、Gemini、Claude、Instagram 全壓在後面。到九月二十一日星期一，iOS 與 Google Play 兩邊的免費榜第一名都是它。</p><p>同一天美股收盤，AMD 股價 $615.52，比前一個交易日漲 9.95%，市值跨過一兆美元。Arm 與 Intel 當天也大漲。</p><p>市場替這件事找的理由是這樣的：Muse 這類 agent 做的是依序執行的多步驟工作，查信箱、比對行事曆、訂位，一步做完才做下一步；這種工作型態被認為比 GPU 擅長的大規模平行運算更吃 CPU。順著這個推論，這波行情落在 AMD、Intel、Arm、Qualcomm 這些跟 CPU 沾得上邊的公司身上，而不是只有 Nvidia 受惠。這段是分析師與媒體的解讀，不是任何一家公司公布的技術口徑。</p><p>AMD 沒有做 Muse，Intel 沒有做 Muse，Arm 也沒有。當天推升股價的是一串推論：一個消費端 app 紅了，推論出未來某種運算需求的形狀，再推論出誰會拿到那些訂單，最後推論出那些訂單值多少錢。</p><p>推論當然可能是對的。但從「一個 app 排免費榜第一」走到「一兆美元市值」，中間有四個環節，每一個都可能斷：那個 app 要留得住人，留住的人要真的每天跑多步驟任務，那些任務要真的跑在通用 CPU 上而不是被塞回 GPU 或某顆專用晶片，這些需求還要熬過採購週期變成實際的單。股價已經把四個都算進去了。</p><p>昨天這個站寫過 <a href="/2026/09/21/AI-%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E%E6%91%98%E8%A6%81-20260921/">Amazon 開始擋 Muse 進它的商店</a>，理由之一是這個 agent 瀏覽的時候不表明自己是自動化 agent。同一個產品，一邊被當成需要用使用條款攔下來的治理威脅，另一邊被當成一兆美元市值的理由。看的是同一個 app，兩套估值方式之間幾乎沒有交集，而且看的人也不是同一批。</p><p>下載量的數字我沒有用。不同轉述給的版本互相打架，一個說六天 902,000 次，另一個說到第十天才 730,000 次，時間比較晚的那個反而比較小。至少有一個是錯的，我分不出是哪一個，所以正文只留排名，那是各家一致的部分。</p><div class="note warning flat"><p>Arm 與 Intel 九月二十一日的收盤價與漲幅，不同財經媒體給的數字互相打架：Arm 收盤價落在 $321.72 到 $323.00 之間，漲幅從 12.48% 到 17.2% 都有人寫；Intel 漲幅在 9.92% 到 12% 之間。可能是各家資料商的快照時間點不同。我不挑其中一個當定論，只寫區間。AMD 那組（收盤 $615.52、漲 9.95%）出自單一來源但內部自洽，所以照引。另外有一家來源寫 AMD 是第四家市值破兆的美國晶片公司、前三家是 Nvidia、Broadcom、Micron，我沒有逐一核對那三家目前的市值，正文不寫這個排名。Bloomberg 那兩篇（晶片股大漲、Muse 下載量）都在付費牆後面，我只讀得到標題。</p></div><blockquote><p>原文來源：<a href="https://thecryptobasic.com/2026/09/22/amd-market-cap-tops-1-trillion-amid-meta-muse-driven-ai-cpu-rally/">thecryptobasic，2026-09-22</a> ／ <a href="https://finance.yahoo.com/markets/stocks/articles/arm-surges-13-meta-muse-152410038.html">Yahoo Finance，2026-09-21</a> ／ <a href="https://www.bloomberg.com/news/articles/2026-09-21/amd-set-to-top-1-trillion-in-market-value-as-chip-stocks-soar">Bloomberg，2026-09-21</a>（付費牆）</p></blockquote><h2 id="三、把機率寫成-0"><a href="#三、把機率寫成-0" class="headerlink" title="三、把機率寫成 0"></a>三、把機率寫成 0</h2><p>九月二十一日發布的 CBS News 專訪裡，Nvidia 創辦人暨執行長黃仁勳講了一句沒有留餘地的話：「2030 is not going to be the end of the world. There is a 0% chance that’s going to be the end of the world.」</p><p>這段話有明確的對象。前 Anthropic 研究員 Jacob Coxon 稍早在社群媒體上說，AI 開發者相信 AI 可能在這個十年結束前導致人類滅絕。黃仁勳的回應是「Scaring people is unnecessary. It is irresponsible.」嚇人沒有必要，而且不負責任。</p><p>他沒有順手把安全那一格讓出去。同一場訪問裡他說「If we’re compromising safety, that can’t happen. We should go as fast as we can, but not faster than we should.」還有一句更直接：「Don’t let this doomsday narrative cause somebody to relieve them of the laws that currently exist.」別讓末日敘事變成某些人鬆綁現行法規的理由。</p><p>這句的方向跟一般預期的相反。通常的假設是，講末日風險的人主張加強管制，做晶片的人主張少管一點。他在這裡把末日敘事跟「鬆綁既有法規」綁在同一條線上，等於說：講得越可怕，越有人會拿那個可怕當理由，去動現在手上已經有的規定。</p><p>0% 這個寫法本身值得看一眼。它不是「機率很低」，是「不可能」。一個把機率壓到 0 的人，等於宣告這件事的尾部不存在，不需要為它保留任何準備。而他自己在同一場訪問裡也承認，Nvidia 在 AI 產業持續成長上有既得利益。</p><p>兩件事可以同時為真：他可能真心認為機率是 0，他也確實有理由希望大家別怕。外面的人分不出這兩者各占多少，因為那是關於別人腦袋裡在想什麼的問題，沒有任何證據能決定它。能檢驗的只有一件事：他這個 0% 有沒有反映在他公司的準備上。</p><p>（訪問的確切錄製日期，兩篇報導都沒有寫，只確定是九月二十一日發布的專訪。）</p><blockquote><p>原文來源：<a href="https://www.cbsnews.com/news/jensen-huang-nvidia-rejects-ai-extinction-warnings/">CBS News，2026-09-21</a> ／ <a href="https://fortune.com/2026/09/21/jensen-huang-ai-leaders-doomsday-narratives/">Fortune，2026-09-21</a></p></blockquote><h2 id="四、兩座變四座"><a href="#四、兩座變四座" class="headerlink" title="四、兩座變四座"></a>四、兩座變四座</h2><p>回到台北那場 DevDays Asia 2026。卞志祥講的具體內容是：微軟在台灣的資料中心會從現有的 2 座擴增到 4 座，提供的服務項目從初期的 70 多項長到 200 多項。台灣這個站在微軟全球架構裡叫「Hero Site」，採 3+1 配置，可以連到亞太其他地區與全球的資料中心。主要客戶是那些對資料主權有硬性要求的產業：政府單位、醫療、金融。</p><p>他另外講了一句：「在這波全球算力競逐中，台灣供應鏈的受益程度與關鍵角色『無庸置疑』」。</p><p>這一則的調性跟前面三則完全不一樣。前面講的是市值、合約總值、公開宣稱，這一則講的是有人要在某塊地上蓋出實體的東西。而且客戶的需求來自法規：政府、醫療、金融的資料不能離境，市場情緒轉向也改不了這一條。</p><p>「2 座變 4 座」這句話的資訊量比它的字數大。要多兩座，得先有電力配額、土地、機櫃空間，而這三樣在台灣沒有一樣是可以快速加出來的。它的瓶頸不在誰願意投資。</p><div class="note warning flat"><p>地點還沒有官方說法。我讀過的報導裡只有聯合新聞網提到「內部已經在北台灣展開重大擴容」，用詞本身保留，說的是已經在展開而不是將設於哪裡；另外四家（TechNews、經濟日報、TVBS、SETN）都沒有提地點。我沒有讀完市面上所有相關報導，這只是我讀過那幾篇的情況。另外「鴻海、廣達、緯穎可望受惠」這類講法是記者的市場解讀，不是微軟官方證實的合作對象。</p></div><blockquote><p>原文來源：<a href="https://technews.tw/2026/09/21/microsoft-taiwan-data-center-expansion-4-bian-zhixiang-computing-power-shortage-2-3-years/">TechNews，2026-09-21</a> ／ <a href="https://udn.com/news/story/7240/9768643">聯合新聞網</a> ／ <a href="https://money.udn.com/money/story/5612/9768643">經濟日報</a> ／ <a href="https://news.tvbs.com.tw/tech/4025439">TVBS</a> ／ <a href="https://www.setn.com/news/1910578">SETN 三立新聞網</a></p></blockquote><h2 id="五、薄冰上的營運許可"><a href="#五、薄冰上的營運許可" class="headerlink" title="五、薄冰上的營運許可"></a>五、薄冰上的營運許可</h2><p>同一個星期一，紐約那邊的產業加速高峰會（Industrial Transition Accelerator）上，聯合國氣候變化綱要公約秘書長 Simon Stiell 對 AI 業者講了一段不太客氣的話。他說這個產業「on thin ice when it comes to license to operate, and sinking deep underwater when it comes to public support」。營運許可這一格站在薄冰上，大眾支持那一格已經沉到水面下很深。</p><p>他對 AI 的描述是「Energy-guzzling artificial intelligence is driving up planet-heating pollution from coal, oil and gas, while ratcheting up energy costs for households and businesses」：耗電的 AI 正在推高煤、油、天然氣造成的暖化污染，同時把家庭與企業的能源成本往上推。他要求業者「respect science and start aligning with global climate efforts - urgently」。</p><p>同一場演說裡他引了國際再生能源總署（IRENA）的數字：2025 年全球再生能源新增裝置容量 693 GW，全球因為再生能源已經避免將近 5,000 億美元的化石燃料成本。同一天同一場，COP31 主席、土耳其的 Murat Kurum 宣布了一項 AI 能源使用承諾，那項承諾的具體條款我沒查到，所以只能說它在那天那場被宣布了，不能多說。</p><p>上一則裡算力短缺的成因之一是電力供給，這一則講的是那些電從哪裡來、誰付那張帳單。兩則在講同一條電線的兩端，量它的單位不一樣：一邊數的是機櫃與服務項目，一邊數的是排放量與家庭電費。</p><p>「license to operate」這個詞不是在講法律上的許可，它講的是社會容忍度。帳面上看不見的成本不等於不存在的成本，只是結算的時間點由別人決定。這種東西平常完全不出現在財務報表上，也不影響任何一季的數字，直到某一天它變成一張被否決的建照、一場擋下來的地方公聽會，或者一條新的法規。</p><blockquote><p>原文來源：<a href="https://www.climatechangenews.com/2026/09/21/cop31-presidency-announces-ai-pledge-as-un-climate-chief-says-big-tech-on-thin-ice/">Climate Change News，2026-09-21</a> ／ <a href="https://www.bloomberg.com/news/articles/2026-09-21/-energy-guzzling-ai-must-rein-in-its-emissions-says-un-climate-chief">Bloomberg，2026-09-21</a>（付費牆）</p></blockquote><hr><p>Nscale 的招股書還會再更新。定價之前會有新的版本，掛牌之後每一季也會有新的數字，而 1,034 億跟 26 億會一直並排印在同一頁上。</p><p>要看的是它們之間那條線往哪邊移動。446 億那一筆附著解約權，8GW 的園區還在規劃階段，融資還沒確定。那筆要是從總額裡掉出去，剩下的數字長什麼樣，我沒看到有人算過。</p><p>而它會不會掉，不由市場決定。決定它的是那座還在規劃階段的園區能不能按期交件，那個答案要好幾年以後才會出現，出現的那天不會有人發新聞稿。</p>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/22/AI-%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E%E6%91%98%E8%A6%81-20260922/</id>
    <link href="https://blog.longhopick.com/2026/09/22/AI-%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E%E6%91%98%E8%A6%81-20260922/"/>
    <published>2026-09-22T12:20:00.000Z</published>
    <summary>招股書上 1,034 億美元的合約，只有 26 億是已生效的；而最大的那一筆，附著客戶可以解約的條件。</summary>
    <title>AI 與科技新聞摘要 - 2026/09/22</title>
    <updated>2026-09-22T13:34:13.453Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="AI 開發工具" scheme="https://blog.longhopick.com/categories/AI-%E9%96%8B%E7%99%BC%E5%B7%A5%E5%85%B7/"/>
    <category term="AI 開發工具" scheme="https://blog.longhopick.com/tags/AI-%E9%96%8B%E7%99%BC%E5%B7%A5%E5%85%B7/"/>
    <category term="開源" scheme="https://blog.longhopick.com/tags/%E9%96%8B%E6%BA%90/"/>
    <category term="NVIDIA" scheme="https://blog.longhopick.com/tags/NVIDIA/"/>
    <category term="Performance" scheme="https://blog.longhopick.com/tags/Performance/"/>
    <content>
      <![CDATA[<p>你正在替一套推論服務挑底層的資料搬移方案。翻開其中一個候選的後端實作指南，讀到這一句：</p><blockquote><p>There is no ordering guarantee across transfer requests, and no locking mechanism for any specific memory region; the user is in charge of not corrupting the memory by having two simultaneous transfers to the same location.</p></blockquote><p>傳輸請求之間沒有順序保證，任何一塊記憶體區域都沒有鎖，別讓兩個傳輸同時打到同一個位置是呼叫端的責任。</p><p>接，還是不接？</p><p>寫下這句話的是 NIXL，全名 NVIDIA Inference Xfer Library，倉庫在 <a href="https://github.com/ai-dynamo/nixl">ai-dynamo&#x2F;nixl</a>。2025 年 3 月 5 日建立，我查證的這天（2026-09-22）還有 push 進來，1,265 顆星、452 個 fork、292 個 open issue，用 GitHub Contributors API 數出 140 個不重複的帳號動過它。主語言 C++。</p><p>一般的免責聲明是在說出事不要怪我。這一句在說的是：這個檢查我不做。文件沒有交代為什麼不做。它想站的那個位置交代了。</p><h2 id="它憑什麼敢這樣寫"><a href="#它憑什麼敢這樣寫" class="headerlink" title="它憑什麼敢這樣寫"></a>它憑什麼敢這樣寫</h2><p>NIXL 的文件把自己的位置講得很窄：</p><blockquote><p>NIXL is targeted for accelerating point to point communications in AI inference frameworks such as NVIDIA Dynamo, while providing an abstraction over various types of memory (e.g., CPU and GPU) and storage (e.g., file, block and object store) through a modular plug-in architecture.</p></blockquote><p>點對點、AI 推論框架、跨記憶體與儲存的抽象層。這個位置的意思是，它活在 KV cache 從一張卡搬到另一張卡的那條路徑上，而那條路徑要比較的對象是 RDMA 硬體本身的延遲。在這個級距裡，一次 mutex 的取得與釋放不是可以四捨五入掉的成本。</p><p>所以它把檢查拿掉，把責任往上推。推給誰？推給知道自己什麼時候在搬哪一塊的那個人，也就是你。</p><p>它也不是完全沒設限。同一份文件講到 transfer handle 的時候留了一條規矩：</p><blockquote><p>per transfer handle, there can be only 1 active transfer at any given point in time to avoid data corruption</p></blockquote><p>一個 handle 同時只能有一個活躍的傳輸，理由逐字寫著「避免資料損毀」。這條規矩本身也沒有程式去強制執行，它是寫在文件裡的約定。函式庫告訴你界線在哪，剩下自己看著辦。</p><h2 id="同一種省法，第二次出現"><a href="#同一種省法，第二次出現" class="headerlink" title="同一種省法，第二次出現"></a>同一種省法，第二次出現</h2><p>NIXL 有一套 metadata 快取，目的講得很直白：避免每次傳輸都重抓一次、動態加入新的 agent、動態把某個 agent 踢掉。到這裡都很正常。決定在下一句：</p><blockquote><p>Adding a remote agent metadata does not cause a connection to be initiated, as this might be just a prefetch optimization. If desired, there is an optional connection API for this usage. Conversely, removing a remote agent metadata will result in a disconnect, if a connection was already established.</p></blockquote><p>把一個遠端 agent 的 metadata 加進來，不會因此建立連線。因為那可能只是預取，你不一定真的要跟它講話。想先連好，有一個可選的 API 讓你自己呼叫；不呼叫，連線就延到第一次真正要傳的時候才建。</p><p>這件事等於把某人的名片存進通訊錄。存進去不代表你打過電話，也不代表那支號碼現在還是他的。</p><p>同一個決策在後端插件那一層又被講了一次，<code>docs/BackendGuide.md</code> 是寫給要自己實作後端的人看的：</p><blockquote><p>Note that loadRemoteConnInfo does not initiate the connection, if the user wants to pre-establish the connection before the first transfer, there will be a call to the connect method.</p></blockquote><p>兩份文件，兩個抽象層級，講的是同一件事：昂貴的動作一律延後，時機交給呼叫端。</p><h2 id="連「你必須實作哪些方法」都是省出來的"><a href="#連「你必須實作哪些方法」都是省出來的" class="headerlink" title="連「你必須實作哪些方法」都是省出來的"></a>連「你必須實作哪些方法」都是省出來的</h2><p>寫一個 NIXL 後端插件的時候，你不用把介面塞滿。四個能力旗標決定你的工作量：</p><blockquote><p>There are 4 such capability indicators, which are detailed further and which APIs are required to be implemented for each of them.</p></blockquote><p>你宣告支援什麼，NIXL 就只要求你實作什麼。文件自己舉了兩個現成的插件當對照：</p><table><thead><tr><th></th><th>UCX 插件</th><th>GDS 插件</th></tr></thead><tbody><tr><td>它在做什麼</td><td>跨節點網路傳輸</td><td>儲存裝置存取</td></tr><tr><td><code>supportsLocal</code></td><td>有設</td><td>有設</td></tr><tr><td>其餘的 <code>supports</code> 旗標</td><td>全部有設</td><td>都沒設</td></tr><tr><td>要實作 <code>getConnInfo</code> &#x2F; <code>loadRemoteConnInfo</code> 嗎</td><td>要</td><td>不用</td></tr><tr><td>要實作 <code>getNotifs</code> &#x2F; <code>genNotif</code> 嗎</td><td>要</td><td>不用</td></tr><tr><td>文件給的理由</td><td>它要支援 agent 之間的通訊與通知，也支援 agent 內部（例如 GPU 到 CPU）的傳輸</td><td>遠端儲存節點上不需要跑 NIXL agent，所有傳輸都是對 agent 自己的 loopback</td></tr></tbody></table><p>GDS 不用假裝自己有遠端語意。從 agent 的角度看，不管資料在本機還是在遠端的分散式儲存，它都只跟本地的儲存客戶端講話，那些網路語意的方法對它毫無意義，也就不必實作。</p><p>到這裡，這個 codebase 的性格已經很清楚了。不需要的就不做，做不做由你決定，沒人幫你檢查。</p><h2 id="省到後來，省進了不該省的地方"><a href="#省到後來，省進了不該省的地方" class="headerlink" title="省到後來，省進了不該省的地方"></a>省到後來，省進了不該省的地方</h2><p>2026 年 7 月 20 日，vLLM 收到一份 issue，編號 <a href="https://github.com/vllm-project/vllm/issues/49238">#49238</a>。</p><p>回報的環境是 4 張 NVIDIA H200、CoreWeave 代管的 Kubernetes 叢集，vLLM v0.25.0 與 v0.25.1 都重現得出來。重現步驟只有五步，第三步是整份 issue 的重點：</p><blockquote><p>Restart the prefill pod (e.g. <code>kubectl delete pod &lt;prefill-pod&gt;</code>), so the decode instance’s cached NIXL agent metadata for prefill becomes stale.</p></blockquote><p>先正常跑完一個請求，確認 KV 傳輸成功。然後砍掉 Prefill pod。等新的 Prefill 起來、註冊完成，再送第二個請求。Decode 那端整個 segfault，連同底下所有 TP worker 一起掛掉重啟。</p><p>回報者自己寫了一段根因推論。這段要標清楚，那是回報者的分析，不是 NIXL 官方確認過的結論：</p><blockquote><p>… NIXL&#x2F;UCX appears to reuse the freed endpoint’s memory address for the new connection almost immediately (observed identical pointer addresses reappearing across the old-agent teardown and new-agent connect). This races with the async UCX error-handling callback that is concurrently tearing down the (now recycled) endpoint due to an RDMA <code>Remote I/O error</code>.</p></blockquote><p>Decode 端手上握著指向舊 Prefill 的 UCX endpoint。舊的那個死了，同一塊記憶體位址幾乎立刻被發給新連線用。同一時間，非同步的 UCX 錯誤回呼還在拆舊的那個。兩邊撞在一起。</p><p>這就像你抄在便條紙上的分機號碼。人離職了，總機隔天把同一組分機給了新進的同事。你手上那張紙看起來完全正常，字跡清楚、號碼沒錯、你甚至昨天才打通過。撥過去接的是別人。</p><p>這裡要把話說準。這個崩潰技術上踩到的機制，跟開場那句「我不上鎖」並非同一個東西。它踩到的是快取：Decode 端留著一份指向舊 Prefill 的狀態，peer 換了人它不知道，鎖不鎖無關。</p><p>但省法是同一種。而且同一種省法在另一個位置也留了洞。順著這條線追下去開出來的 PR <a href="https://github.com/ai-dynamo/nixl/pull/2027">#2027</a>，說明第一句是這樣寫的：</p><blockquote><p><code>postXferReq</code> guards the remote section by name only</p></blockquote><p>這一條講的是另一個進入點。一個 transfer handle 建立的時候，對面是第 N 代的 metadata；斷線、重新註冊之後，對面變成第 N+1 代，而那個 handle 拿的名稱還是對的，所以驗證照樣通過，接著對一塊已經被釋放又被重新配置的記憶體解參考，在 <code>sendXferRangeBatch</code> 或 <code>ucp_put_nbx</code> 裡炸掉。跟上面那個死在 <code>ucp_ep_rkey_unpack()</code> 裡的，是兩個不同的位置。</p><p>不做鎖、不保證順序、只用名稱驗證 handle。三件事都發生在同一條路徑上，也都用同一種方式處理：能省的檢查就省掉。</p><p>修法是讓世代擋在前面。每個遠端 agent 帶一個 generation 值，<code>postXferReq</code> 與 <code>estimateXferCost</code> 遇到世代過期的 handle 直接回傳 <code>NIXL_ERR_NOT_FOUND</code>，不再往下解參考。等於在那張便條紙上多寫一行「第幾任」。PR 作者說明他怎麼驗的：</p><blockquote><p>Verified with a fault-injection reproducer: without the fix the crash reproduces reliably; with it, none.</p></blockquote><h2 id="merge-了，不代表你拿得到"><a href="#merge-了，不代表你拿得到" class="headerlink" title="merge 了，不代表你拿得到"></a>merge 了，不代表你拿得到</h2><p>7 月 29 日 PR <a href="https://github.com/ai-dynamo/nixl/pull/1987">#1987</a> merge，處理的是 UCX endpoint 那一層：把 rkey unpack 跟 endpoint 關閉序列化、呼叫 <code>ucp_ep_rkey_unpack()</code> 之前先檢查 endpoint 狀態、對已失敗的 endpoint 回傳 <code>NIXL_ERR_REMOTE_DISCONNECT</code>。</p><p>兩天後，7 月 31 日，原回報者在 issue 下留言：他換了應該含有這個修法的 vLLM nightly image，同一個 segfault 照樣出現。</p><p>這一步值得記下來，因為它浪費掉的是真實的時間。另一位開發者 YannikHinteregger 回覆了原因：</p><blockquote><p>vLLM pins the NIXL version requirements&#x2F;kv_connectors.txt, so a vLLM nightly can’t pick up a NIXL-side fix. Latest NIXL release is v1.3.2 (from Jul 24), @chaunceyjiang merged the fix on Jul 29, so it isn’t in any published NIXL version yet. NIXL needs to do a new release first, then vLLM needs to bump it in the requirements</p></blockquote><p>vLLM 在 <code>requirements/kv_connectors.txt</code> 釘死 NIXL 版本。NIXL 那邊 merge 進 main 的程式碼，要先等 NIXL 切一個新的正式版，再等 vLLM 把版本號往上調，才會真的跑在你的容器裡。當時 NIXL 最新的正式版是 7 月 24 日的 v1.3.2，而修法是 7 月 29 日才 merge 的。</p><p>那次 nightly 測試從一開始就不可能通過。如果你也在追一條跨 repo 的修補鏈，下次可以先做一件事：打開依賴的釘選檔，確認你要的那個 commit 有沒有進過任何一個已發布的版本。這比再跑一次重現省時間。</p><p>整條鏈長這樣：</p><table><thead><tr><th>日期</th><th>發生什麼</th><th>可查證編號</th></tr></thead><tbody><tr><td>2026-06-30</td><td>RW lock 的競態修復 merge，remote memory section 開始帶一個 generation 值，供快取失效比對</td><td><a href="https://github.com/ai-dynamo/nixl/pull/1811">#1811</a></td></tr><tr><td>2026-07-20</td><td>vLLM 端回報 Prefill pod 重啟後 Decode 崩潰</td><td><a href="https://github.com/vllm-project/vllm/issues/49238">#49238</a></td></tr><tr><td>2026-07-23</td><td>NIXL 開對應 issue，標題點名 endpoint close 與 rkey unpack 的競態</td><td><a href="https://github.com/ai-dynamo/nixl/issues/1986">#1986</a></td></tr><tr><td>2026-07-29</td><td>UCX endpoint 層的修法 merge</td><td><a href="https://github.com/ai-dynamo/nixl/pull/1987">#1987</a></td></tr><tr><td>2026-07-31</td><td>回報者用 nightly 測，仍然重現，原因是版本釘選</td><td>同 #49238 留言</td></tr><tr><td>2026-08-05</td><td><code>postXferReq</code> 層的世代檢查 merge</td><td><a href="https://github.com/ai-dynamo/nixl/pull/2027">#2027</a></td></tr><tr><td>2026-09-01</td><td>v1.4.1 發布，release notes 直接點名 #2027</td><td>v1.4.1</td></tr></tbody></table><p>v1.4.1 的 release notes 把這次修的東西講得很乾脆：</p><blockquote><p>NIXL 1.4.1 is a focused patch release that closes a use-after-free window in the transfer-request path.</p></blockquote><p>兩支 PR，中間隔了一個星期，補的不是同一個地方。#1987 動的是 UCX endpoint 那一層的拆除順序，#2027 才是讓 <code>postXferReq</code> 真的去看世代。再往前，6 月底那支 #1811 就已經把 generation 的雛形做出來了：remote memory section 開始帶一個世代值，供快取失效時比對。同一類「舊狀態沒清乾淨」的漏洞要在三個地方各補一次，那個省法滲透到多深，這件事講得很清楚。</p><h2 id="什麼時候這筆交易不該接"><a href="#什麼時候這筆交易不該接" class="headerlink" title="什麼時候這筆交易不該接"></a>什麼時候這筆交易不該接</h2><p>先講會讓上面整段失效的條件。如果你的 Prefill 與 Decode 是手動起的固定行程，peer 從頭到尾就是那幾個，不會消失又回來，那這條崩潰路徑你踩不到，前面這幾千字對你是零成本。</p><p>問題出在反過來的情況，而那才是現在的主流。你跑在 Kubernetes 上，有 HPA，可能有 spot instance，版本更新是滾動的。在這種環境裡，peer 消失又用同一個名字回來是例行事件，不是異常狀況。NIXL 那兩個決定正好都建立在「呼叫端知道現在的狀態」這個假設上，而你的編排系統會在你不知情的時候改變那個狀態。</p><p>判準只有一條：你的 peer 拓撲在執行期是不是穩定的。穩定就接，不穩定就要先算好代價。</p><p>第二條判準跟程式碼無關，但法務會問。<code>gh api repos/ai-dynamo/nixl</code> 回報的 license 是 <code>&#123;&quot;key&quot;:&quot;other&quot;,&quot;name&quot;:&quot;Other&quot;,&quot;spdx_id&quot;:&quot;NOASSERTION&quot;&#125;</code>，不是乾淨的 Apache-2.0。翻進去看，這個 repo 裡確實同時躺著三份授權：根目錄的 <code>LICENSE</code> 說明 <code>examples/device/ep/</code> 底下的程式碼衍生自 DeepSeek 的 DeepEP、採 MIT，其餘採 Apache-2.0；<code>pyproject.toml</code> 的 <code>license</code> 欄位寫的是 <code>MIT AND Apache-2.0</code>；而 README 另外交代了第三種：</p><blockquote><p>NIXL Python wheels bundle NVIDIA modules (<code>libuct_ib_mlx5_ext.so</code>, <code>libuct_ib_mlx5_gda.so</code>, <code>libuct_ib_mlx5_gdp.so</code>) licensed under the NVIDIA Proprietary License (<code>LicenseRef-NvidiaProprietary</code>).</p></blockquote><p>三個 Mellanox&#x2F;InfiniBand 的硬體加速二進位模組，隨 Python wheel 一起打包，掛的是 NVIDIA 專有授權。<code>pyproject.toml</code> 的 <code>license</code> 欄位並沒有把它列進去，只有 <code>license-files</code> 那裡看得到。如果你們公司對「這包東西能不能進產品」有審查流程，這件事最好在動手整合之前就講清楚，不要等到要打包了才發現。</p><h2 id="我會怎麼選"><a href="#我會怎麼選" class="headerlink" title="我會怎麼選"></a>我會怎麼選</h2><p>用，但是把版本控制權拿回來。</p><p>具體一點說：NIXL 釘在 v1.4.1 或更新的版本，而且要親自確認你的上層框架釘的是哪一版。走 vLLM 的 <code>NixlConnector</code> 就去看 <code>requirements/kv_connectors.txt</code>。前面那兩個月的教訓就是，你以為裝到的跟你實際裝到的，中間隔著一層你平常不會去看的釘選檔。</p><p>然後把「peer 重啟」寫進測試案例，而不是放在異常處理那一章。上面那五個重現步驟是一份免費的測試腳本，<code>kubectl delete pod</code> 那一步值得在上線前跑一次。</p><p>有一件事不要誤會：這條線還沒收乾淨。vLLM 的 issue #49238 到我查證的這天（2026-09-22）狀態仍然是 <code>open</code>。v1.4.1 修掉的是最早被回報、也修得最完整的那個具體機制。8 月 25 日有人在同一則 issue 下貼了另一個變體，重啟方向相反（Decode 重啟、Prefill 存活），症狀也不一樣，不是立即崩潰而是一筆 102,400 token 的長傳輸卡住；9 月 5 日又有第三個人描述了更窄的一種失敗模式，還在研究中。同一類根因，不同的觸發條件。</p><p>我沒有部署過 NIXL，也沒有重現過那個 segfault。上面所有技術細節都來自它的原始碼文件、PR 與 issue 的原文，以及 GitHub API 查到的元資料。判斷的部分是我的，事實的部分都能點進去自己看。</p><p>所以把開頭那句免責聲明翻回來看。NIXL 要你保證的其實是三件事：你知道現在誰在線上、你知道誰剛剛走了、你知道手上那個 handle 對應的是第幾任。單機上這三件事不用想，寫死的 peer 不會自己消失又回來。</p><p>三件都答得出來，這筆交易划算。答不出來，那份被省掉的檢查不會跟著消失，只是換你寫。不寫，就等著在某次滾動更新之後去讀 core dump。</p>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/22/%E4%B8%8D%E4%B8%8A%E9%8E%96-%E4%B8%8D%E4%BF%9D%E8%AD%89%E9%A0%86%E5%BA%8F-%E8%B2%AC%E4%BB%BB%E6%AD%B8%E4%BD%A0-NIXL-%E9%80%99%E7%AD%86%E4%BA%A4%E6%98%93%E4%BB%80%E9%BA%BC%E6%99%82%E5%80%99%E4%B8%8D%E8%A9%B2%E6%8E%A5/</id>
    <link href="https://blog.longhopick.com/2026/09/22/%E4%B8%8D%E4%B8%8A%E9%8E%96-%E4%B8%8D%E4%BF%9D%E8%AD%89%E9%A0%86%E5%BA%8F-%E8%B2%AC%E4%BB%BB%E6%AD%B8%E4%BD%A0-NIXL-%E9%80%99%E7%AD%86%E4%BA%A4%E6%98%93%E4%BB%80%E9%BA%BC%E6%99%82%E5%80%99%E4%B8%8D%E8%A9%B2%E6%8E%A5/"/>
    <published>2026-09-22T12:10:00.000Z</published>
    <summary>它的後端實作指南直接寫著不做鎖、不保證順序，記憶體別被搞壞是呼叫端的事。文件沒有交代為什麼這樣選。而同一種能省則省的取捨，在 Kubernetes 上重啟一個 Prefill Pod 之後，讓另一端整個掛掉。</summary>
    <title>不上鎖、不保證順序、責任歸你：NIXL 這筆交易什麼時候不該接</title>
    <updated>2026-09-22T14:36:23.668Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="Claude Code" scheme="https://blog.longhopick.com/categories/Claude-Code/"/>
    <category term="Claude Code" scheme="https://blog.longhopick.com/tags/Claude-Code/"/>
    <category term="Skills" scheme="https://blog.longhopick.com/tags/Skills/"/>
    <category term="開發工具" scheme="https://blog.longhopick.com/tags/%E9%96%8B%E7%99%BC%E5%B7%A5%E5%85%B7/"/>
    <category term="教學" scheme="https://blog.longhopick.com/tags/%E6%95%99%E5%AD%B8/"/>
    <content>
      <![CDATA[<p>檔案在那裡。YAML 沒問題。<code>/</code> 選單裡就是沒有它。</p><p>monorepo，你在 repo root 跑 <code>claude</code>，前一天替前端寫了一份 <code>apps/web/.claude/skills/deploy-web/SKILL.md</code>，存了檔，路徑確認過三次。打 <code>/</code> 找不到它，直接打 <code>/deploy-web</code> 也叫不動。接下來你會做的事幾乎是固定的：回頭檢查 frontmatter 的縮排、懷疑資料夾名稱要不要跟 skill 名一致、最後乾脆重開一個 session。三件事全部白做。</p><p>「我的 skill 好像不靈了」這句話底下藏著兩種完全不同的故障，而它們的解法互斥。一種是它根本沒進場，另一種是它進場過、後來被丟掉了。拿治第一種的方法去治第二種，你改幾次都不會好，而且你不會收到任何錯誤訊息告訴你方向錯了。</p><h2 id="它只往上掃，不往下掃"><a href="#它只往上掃，不往下掃" class="headerlink" title="它只往上掃，不往下掃"></a>它只往上掃，不往下掃</h2><p>文件對第一種故障講得很白：</p><blockquote><p>Skills in a <code>.claude/skills/</code> directory below where you started don’t load at startup. They load the first time Claude reads or edits a file in that subdirectory and stay available for the rest of the session.</p></blockquote><p>方向是不對稱的，這點特別容易記反。你的起始目錄、加上一路往上到 repo root 的每一層 <code>.claude/skills/</code>，開場就全部載入；起始目錄<strong>底下</strong>的那些，開場一個都不載。</p><p>公寓的規約也是這樣發的。你搬進去那天，管理室把你這一層跟樓上每一層的都一次塞給你；樓下那幾戶的，要等你哪天真的走下去一趟，才會有人拿給你。在那之前你手上沒有那張紙，不代表那張紙寫錯了。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">your-monorepo/</span><br><span class="line">├── .claude/skills/            &lt;- 你在這裡跑 claude，開場就載入</span><br><span class="line">│   └── review-pr/SKILL.md</span><br><span class="line">└── apps/</span><br><span class="line">    └── web/</span><br><span class="line">        └── .claude/skills/    &lt;- 開場不載入</span><br><span class="line">            └── deploy-web/SKILL.md</span><br></pre></td></tr></table></figure><p>在它載入之前，<code>/</code> 選單看不到、打名字也叫不動。對那個時間點的 session 來說，它還不存在。直覺會以為 Claude Code 掃的是整個 repo。它只往上掃。</p><p>解法有兩個，都不用重開 session。隨便叫 Claude 去讀一個 <code>apps/web/</code> 底下的檔案，它就進場了，而且該 session 剩下的時間都在。或者直接 <code>/add-dir apps/web</code> 把那個目錄拉進來，這個做法需要 v2.1.257 以上。另外如果你習慣用 <code>/cd</code> 搬動 session，v2.1.246 之後它會順手補上新目錄的 project skills。</p><h2 id="進場之後，那個檔案就不會再被讀第二次"><a href="#進場之後，那個檔案就不會再被讀第二次" class="headerlink" title="進場之後，那個檔案就不會再被讀第二次"></a>進場之後，那個檔案就不會再被讀第二次</h2><p>skill 被叫起來的時候，算繪完的正文以一則訊息的形式進到對話裡，之後每一輪都還在。但那則訊息是載入當下的快照。文件對這件事的說法只有一句：</p><blockquote><p>Claude Code does not re-read the skill file on later turns</p></blockquote><p>你在 session 中途去改 SKILL.md，這個 session 用的還是舊的那份。改完覺得沒效果，跑去把描述寫得更用力，再改一次，還是沒效果，因為你改的檔案根本沒有被重新讀取。</p><p>同一節文件裡還藏著一組壽命差很多的東西：正文會留著，權限不會。<code>allowed-tools</code> 給的授權在你送出下一則訊息時就清掉了，正文卻會一路待到壓縮。同一個檔案、同一次呼叫，一個撐一則訊息，另一個撐到壓縮為止。</p><p>文件順著這點給了一條寫作建議：SKILL.md 要寫成通篇適用的常設指令，不要寫成「第一步做 A、第二步做 B」的一次性流程。理由很務實，那份正文會在對話裡待很久，而不會有人在第四十輪的時候提醒模型「你現在該回到第 3 步了」。</p><h2 id="同一個-skill-叫第二次，有時候免費，有時候不是"><a href="#同一個-skill-叫第二次，有時候免費，有時候不是" class="headerlink" title="同一個 skill 叫第二次，有時候免費，有時候不是"></a>同一個 skill 叫第二次，有時候免費，有時候不是</h2><p>這裡有個我一開始猜錯的地方。重複叫同一個 skill，Claude Code 的判斷基準不是名字相同，是<strong>算繪後的內容</strong>逐字相同。</p><p>內容一模一樣，它只補一行「已經載入過了」的註記，不會有第二份正文。內容不一樣，整份正文再 append 一次。會讓內容不一樣的原因文件明列了兩個：參數變了，或者正文裡的動態 context 指令產出了新的輸出。</p><p>第二個原因才是麻煩的那個。SKILL.md 裡可以塞在送給模型之前先跑一次的 shell 指令，輸出會取代掉佔位符。如果你塞的是印時間、印 git 狀態這類每次結果都會變的東西，那這個 skill 每被叫一次，context 裡就多一份完整正文。「我的 context 怎麼一直莫名其妙變滿」有時候答案就在這裡，而且它長得完全不像一個 bug。</p><p>這筆帳還會往下滾。一份很長、又帶著動態指令的 skill，你在一場對話裡叫了四次，就是四份完整正文躺在那邊佔位子，加速你撞上壓縮的門檻。撞上之後，前面說的那套接回規則才開始跑，而它只會保留你最後那一次。等於你花了四份的 context，換回一份、而且是被切到剩前 5,000 tokens 的版本。這個設計沒有錯，它要的就是不重複塞相同內容；只是「相同」的判準嚴格到逐字，比你以為的嚴格。</p><h2 id="壓縮那一刀，砍的方向跟你以為的相反"><a href="#壓縮那一刀，砍的方向跟你以為的相反" class="headerlink" title="壓縮那一刀，砍的方向跟你以為的相反"></a>壓縮那一刀，砍的方向跟你以為的相反</h2><p>換一個場景。長 session，你開頭先叫了 <code>/code-style</code>，那是你們團隊的程式碼規範，很長。接下來兩小時陸續叫了一串：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">/code-style          &lt;- 團隊規範，很長，開場就叫</span><br><span class="line">/write-tests</span><br><span class="line">/fix-issue</span><br><span class="line">/review-checklist</span><br><span class="line">/db-migrate</span><br><span class="line">/deploy</span><br><span class="line">─────────────────</span><br><span class="line">compacting conversation…</span><br></pre></td></tr></table></figure><p>壓縮跑完之後，Claude 開始寫出完全不符合你們規範的程式碼。你把 <code>/code-style</code> 的 description 改得更強，在 CLAUDE.md 加了一行「務必遵守 code-style」，都沒用。</p><p>原因在這段：</p><blockquote><p>Auto-compaction carries invoked skills forward within a token budget. When the conversation is summarized to free context, Claude Code re-attaches the most recent invocation of each skill after the summary, keeping the first 5,000 tokens of each. Re-attached skills share a combined budget of 25,000 tokens. Claude Code fills this budget starting from the most recently invoked skill, so older skills can be dropped entirely after compaction if you have invoked many in one session.</p></blockquote><p>四件事同時在發生。壓縮的時候，每個 skill 只有最近一次的呼叫會被重新接到摘要後面，同一個 skill 你叫過三次，只有最後那次回得來。接回來的也不是完整的，每個 skill 只保留正文的前 5,000 tokens，那是「每個 skill 在一次壓縮裡的保留量」，不是整場對話的額度。然後所有被接回來的 skill 共用一個 25,000 tokens 的總額，這個數字是大家一起分，不是每人一份。填的順序則是從最近叫的那個往回填。</p><p>填到沒額度為止。填不到的那幾個，不會留下一截開頭。它們整個不在了。</p><p>公司要你把桌上的東西全部收進一個固定大小的箱子，來收的人從你最近碰過的那幾樣開始放，放滿就停手。三個月前擱在桌角那本厚厚的規範手冊，不會被撕掉幾頁再硬塞進去，它會整本留在箱子外面。你回到位子上看見桌面清爽，第一個念頭通常是「東西都收好了」，不會是「有東西沒進去」。</p><p><code>/code-style</code> 是你最早叫的，在這個排序裡穩穩排最後一名。</p><p>順手算一下：25,000 除以 5,000 是 5。如果每個 skill 都吃滿 5,000 的上限，一次壓縮最多接得回五個。這個「五」是我從那兩個數字推出來的，文件沒有這樣寫，而且實際上多數 skill 根本用不到 5,000 tokens，所以通常接得回更多。它的用處只是給你一個最壞情況的量感：一場對話裡叫過的 skill 只要多過一隻手，最早那幾個就該開始擔心了。</p><p>最花冤枉力氣的是接下來這一步。規範失效，直覺會說那個 skill 的 description 寫得不夠有說服力，於是回去把它形容得更重要。這個動作完全動不到問題。description 管的是「模型會不會想去叫它」，那是另一套清單、另一套預算，站上 <a href="/2026/08/26/%E5%85%A9%E4%BB%BD%E5%90%8D%E5%96%AE%E4%B8%89%E9%81%93%E9%96%98%E9%96%80-Claude-Code-skill-%E8%AA%B0%E8%83%BD%E5%8F%AB%E5%AE%83%E7%9A%84%E5%BA%95%E5%B1%A4%E6%8B%86%E8%A7%A3/">2026-08-26 那篇</a> 把那一套拆過，這裡不重講。至於「它的正文現在還在不在 context 裡」，是完全另一件事。你在 A 系統上使勁，壞掉的是 B 系統。</p><p>兩套預算還差在一個地方。「常用」在第一套是護身符，在第二套完全不管用，因為第二套只看最近有沒有叫。一個你每天都在用、但這場對話只在開頭叫過一次的 skill，壓縮的時候照樣第一個被丟。</p><h2 id="什麼時候它反而不是這個原因"><a href="#什麼時候它反而不是這個原因" class="headerlink" title="什麼時候它反而不是這個原因"></a>什麼時候它反而不是這個原因</h2><p>逆著問一次，不然這篇會變成一把什麼都往上敲的鎚子。skill 看起來不聽話，有很大一部分根本不是正文被砍了。文件給的分界很乾脆：</p><blockquote><p>If a skill seems to stop influencing behavior after the first response, the content is usually still present and the model is choosing other tools or approaches.</p></blockquote><p>所以要先確認一件事：這場對話壓縮過沒有？<code>compacting conversation</code> 那句話有沒有出現過？</p><p>沒有的話，正文八成還在，問題出在模型自己挑了別條路走。這時候加強 description 跟指令是對的方向，不是白工。而如果你要的是「它一定得照做」，那就不該靠說服，改用 hooks 去強制，hooks 是決定性的，模型繞不過去。</p><p>有壓縮過、那個 skill 又很大、或者它後面你還叫了好幾個別的，那就是正文真的被砍了。重新叫一次就好。</p><h2 id="常設規則不該住在-skill-正文裡"><a href="#常設規則不該住在-skill-正文裡" class="headerlink" title="常設規則不該住在 skill 正文裡"></a>常設規則不該住在 skill 正文裡</h2><p>講到這裡我的立場很明確：要跨整場對話都成立的東西，寫進 CLAUDE.md；skill 正文只放這次任務要做的事。這不是品味問題，是兩者的存活機制不一樣。CLAUDE.md 每個 session 開場重新載入，skill 正文則要跟其他 skill 去搶那 25,000 tokens。</p><p>壓縮本身的處理順序也指向同一個做法：</p><blockquote><p>Claude Code manages context automatically as you approach the limit. It clears older tool outputs first, then summarizes the conversation if needed. Your requests and key code snippets are preserved; detailed instructions from early in the conversation may be lost. Put persistent rules in CLAUDE.md rather than relying on conversation history.</p></blockquote><p>想更精準控制留下什麼，文件給了兩個手把：在 CLAUDE.md 加一個 Compact Instructions 段落，或者跑 <code>/compact</code> 的時候帶一個焦點進去。</p><p>什麼會讓我改變立場？如果哪天 5,000 跟 25,000 變成可調的設定，或者壓縮丟掉某個 skill 的時候會給你一條看得到的訊息，那 skill 正文就可以放心承載長期規範了。目前這兩件事文件都沒有給。</p><p>沒有訊息這件事，是這個設計現在最實在的代價。文件有寫清單那套預算爆掉時會往 debug log 寫一條 warning，但壓縮把 skill 正文丟掉的時候會不會也留下什麼，文件沒寫。所以「我怎麼知道自己被砍了」目前沒有官方答案，你只能從模型行為變了這件事反推。麻煩在於，行為變了看起來跟「它只是不想用」一模一樣，而後者會把你推回去改 description。</p><div class="note warning flat"><p>這篇全部來自 2026-09-21 當天的官方文件，我只讀了文件，沒有實際跑過。上面的版本號、5,000 與 25,000 這兩個數字、以及所有行為描述，都是那天那份文件寫的內容，而那個頁面本身沒有標注自己的最後更新日期。另外有三件文件沒寫、我也答不出來的事：5,000 tokens 的截斷點會不會對齊段落邊界、同一則訊息裡一次叫好幾個 skill 的時候誰算「比較近」、以及正文被丟掉之後模型那邊還看不看得到這個 skill 的描述。</p></div><h2 id="檔案是最後才該打開的東西"><a href="#檔案是最後才該打開的東西" class="headerlink" title="檔案是最後才該打開的東西"></a>檔案是最後才該打開的東西</h2><p>那個 skill 看起來不聽話的時候，不要先開檔案。</p><p>先確認它有沒有進場過。如果它住在起始目錄底下的子資料夾，<code>/add-dir</code> 那個路徑，或者隨便叫 Claude 讀一個那底下的檔案。再確認這場對話壓縮過沒有，壓縮過就重新打一次那個 skill 的名字，一秒的事，比你改任何一行 frontmatter 都快。兩件都確認完，正文確定在場，它還是我行我素，那才輪到 description，而且這時候真正該做的是寫一個 hook 把行為釘死，不是把描述再形容得動人一點。</p><p>改 description 之所以那麼受歡迎，是因為它是唯一一個你可以一直做下去的動作。它不會報錯，也不會拒絕你。</p><blockquote><p>原文來源：<a href="https://code.claude.com/docs/en/slash-commands.md">Extend Claude with skills - Claude Docs</a>、<a href="https://code.claude.com/docs/en/how-claude-code-works">How Claude Code works - Claude Docs</a></p></blockquote>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/21/description-%E6%94%B9%E5%86%8D%E5%BC%B7%E4%B9%9F%E6%B2%92%E7%94%A8-skill-%E6%AD%A3%E6%96%87%E5%9C%A8-context-%E8%A3%A1%E7%9A%84%E4%B8%80%E7%94%9F/</id>
    <link href="https://blog.longhopick.com/2026/09/21/description-%E6%94%B9%E5%86%8D%E5%BC%B7%E4%B9%9F%E6%B2%92%E7%94%A8-skill-%E6%AD%A3%E6%96%87%E5%9C%A8-context-%E8%A3%A1%E7%9A%84%E4%B8%80%E7%94%9F/"/>
    <published>2026-09-21T10:00:00.000Z</published>
    <summary>skill 看起來失效，多半不是它沒被想起來，而是那份正文壓根沒進場，或者已經在自動壓縮那一刀被丟掉了。拆開 5,000 與 25,000 這兩個數字各自管到哪裡。</summary>
    <title>description 改再強也沒用：skill 正文在 context 裡的一生</title>
    <updated>2026-09-21T12:40:46.804Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="AI與科技新聞" scheme="https://blog.longhopick.com/categories/AI%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E/"/>
    <category term="AI Agent" scheme="https://blog.longhopick.com/tags/AI-Agent/"/>
    <category term="AI與科技新聞" scheme="https://blog.longhopick.com/tags/AI%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E/"/>
    <category term="資安" scheme="https://blog.longhopick.com/tags/%E8%B3%87%E5%AE%89/"/>
    <category term="OpenAI" scheme="https://blog.longhopick.com/tags/OpenAI/"/>
    <category term="Amazon" scheme="https://blog.longhopick.com/tags/Amazon/"/>
    <content>
      <![CDATA[<p>OpenAI 廣告 pixel 的 SDK 裡有一條不帶 credentials 的路徑，寫得很對，但它從來沒有機會執行。就算執行了也來不及：瀏覽器載入 <code>&lt;script src&gt;</code> 的那一刻就把 cookie 附上去了，那發生在任何一行 OpenAI 的程式碼跑起來之前。防護寫在應用層，洩漏發生在更早的地方。</p><p>層級選錯，寫得再對都不會生效。而這個毛病不只長在程式碼裡，也長在「誰有權決定一個 cookie 算哪一類」這種地方。</p><h2 id="一、那個-cookie-叫-obi，被歸類在「分析」"><a href="#一、那個-cookie-叫-obi，被歸類在「分析」" class="headerlink" title="一、那個 cookie 叫 __obi，被歸類在「分析」"></a>一、那個 cookie 叫 <code>__obi</code>，被歸類在「分析」</h2><p>Buchodi’s Threat Intel 的研究者在九月二十日把整條鏈逐包拆開了。</p><p>從 ChatGPT 網頁端開始：前端產生一個 16 byte 的識別碼，送到 OpenAI 後端換回一個 RS256 簽章的 JWT。那個 JWT 裡帶著 <code>obi</code> 值，還有一個指向已登入帳號的 subject。token 再提交給 OpenAI 的廣告基礎設施，由它把 <code>__obi</code> 這個 cookie 設下來。JWT 裡的 <code>obi</code> 值跟 cookie 的值，一模一樣。</p><p>cookie 的屬性逐字是這樣：<code>SameSite=none; Secure; Max-Age=31536000; Path=/; HttpOnly</code>，scope 是 <code>.openai.com</code>。Max-Age 那個數字是 31536000 秒，一年。</p><p>接下來就簡單了。廣告主在自家網站嵌一段 OpenAI 的 pixel，你的瀏覽器載入它的時候會把 <code>__obi</code> 一起帶過去，OpenAI 那一側因此能把你在站外看了什麼，接回那個 ChatGPT 帳號。</p><p>規模的部分要先標清楚是誰數的。以下全部出自研究者橫跨數月的自有流量觀測，不是官方數字：936 個不同的廣告主 pixel，分布在 1,029 個 hostname。解碼出來的 932 個 sync token 裡，736 個帶著 <code>account_user</code> 這種指向帳號的 subject type，196 個是匿名的。881 個「設定可見」的 pixel 中，638 個開了自動資料比對。單一裝置被 12 個商業網站、13 個不同 pixel ID 追到，觀測到的站名有 Chewy、Wayfair、ThriftBooks、Eventbrite、HelloFresh、Coursera、SeatGeek。30 個 <code>__obi</code> 值裡面，12 個出現在不只一個廣告主底下。</p><p>數字只說明規模。這則真正的爭點是那個 cookie 被放進了哪一格。</p><p>OpenAI 把 <code>__obi</code> 歸類為分析 cookie，效期一年。研究者的主張是，拒絕行銷同意的人照樣會拿到它。他解碼出來的 sync token 顯示，即使行銷同意被拒，token 裡仍然帶著 <code>analytics_allowed</code> 的同意決策；他也找不到任何一個可以把它關掉的設定。</p><p>同意介面上，分析和行銷是兩個開關。而東西要進哪一格，由被同意的那一方決定。你關掉行銷，以為自己關掉了追蹤，實際上關掉的是另一個開關。</p><p>這件事真正的破口不在技術實作，在分類權。這個判斷有三個出口：OpenAI 公開說明 <code>__obi</code> 為什麼算分析不算行銷、給出一個能關掉它的設定、或者有第三方在別的平台重現出「拒絕行銷同意就不會拿到它」的相反結果。任何一個出現，上面那句就不成立。</p><p>九月十四日，研究者把兩個問題寄給 OpenAI 的媒體與隱私信箱：為什麼 <code>__obi</code> 算分析不算行銷，以及拒絕行銷同意的人是不是仍然會拿到它。客服回覆確認收到、說會轉給內部。兩個問題都沒有得到回答。而再往前推，八月二十七日 OpenAI 在 SDK 0.1.31 版縮限過蒐集範圍，那在這次揭露之前。所以這家公司不是不會動，是動的時間點不必跟外面的提問對齊。</p><div class="note warning flat"><p>這則的涵蓋範圍要寫清楚。觀測是在 Chrome for Android 上做的，原文說 iOS 上的瀏覽器不受影響，桌面版 Chrome 沒有測試。另外「OpenAI 把 <code>__obi</code> 歸類為分析」這一點，來自研究者的原文與跟進報導的轉述；官方 cookie 政策頁我讀不到（回 403），沒辦法逐字核對官方自己是怎麼寫的。</p></div><blockquote><p>原文來源：<a href="https://www.buchodi.com/chatgpt-now-knows-what-you-do-on-other-websites-via-ad-collector/">Buchodi’s Threat Intel，2026-09-20</a> ／ <a href="https://www.notebookcheck.net/ChatGPT-s_obi-cookie-follows-you-to-other-websites.1404436.0.html">Notebookcheck</a></p></blockquote><h2 id="二、Amazon-擋掉-Meta-的-Muse，三條理由裡最重的是第二條"><a href="#二、Amazon-擋掉-Meta-的-Muse，三條理由裡最重的是第二條" class="headerlink" title="二、Amazon 擋掉 Meta 的 Muse，三條理由裡最重的是第二條"></a>二、Amazon 擋掉 Meta 的 Muse，三條理由裡最重的是第二條</h2><p>三條理由是這樣列的：Meta 事前沒有告知 Amazon，Muse 會存取它的商店；這個 agent 瀏覽的時候不表明自己是自動化 agent；以及它看起來在擷取顧客憑證。</p><p>第一條是禮貌問題，第三條是雙方各說各話。真正有分量的是中間那條。</p><p>事情發生在九月二十日晚間，Amazon 開始阻擋 Meta 的個人 AI agent「Muse」代替使用者在 Amazon.com 購物。使用者看到的彈出訊息逐字是：「continued access by an unauthorized AI agent violates Amazon’s Conditions of Use, to which our customers have agreed.」未經授權的 AI agent 持續存取違反 Amazon 的使用條款，而客戶已經同意過那份條款。</p><p>一個不表明身分的 agent，你擋不掉，也追究不了。不是技術上做不到擋，是你得先分辨得出來。整個 agentic web 現在缺的就是這一格：沒有一個大家都認的方式，讓自動化的請求在敲門時先報上名號。Amazon 這次做的，是在那一格還空著的時候，拿自己的規則暫時補上。</p><p>這次走的是使用條款，不是駭客類的主張。條款的好處是門檻低、舉證輕，代價是它約束的對象是使用者。那句訊息裡寫得很清楚，「我們的客戶已經同意」。被放在違約位置的是誰，讀一次就知道。</p><p>Muse 九月八日上線，十二天後被擋。Meta 那邊描述的安全設計是專用的安全虛擬機、購買需要使用者明確核准、付款用一次性虛擬卡。Amazon 說它看起來在擷取顧客憑證。兩邊都沒有第三方驗證，外界無從判斷誰對。</p><p>背景數字是 Amazon 約占美國電商 40%，講的是美國電商，不是全球、也不是零售整體。在這個位置上拒絕一個 agent，等於替整個類別定了一次規矩。這條路 Amazon 走過一次，上次的對象是 Perplexity 的 Comet 瀏覽器。而缺的那張合約很具體：兩家公司在別處談成什麼，跟「准不准你的 agent 進我家」是兩件事，後面那張現在還沒有人寫出來。</p><blockquote><p>原文來源：<a href="https://www.geekwire.com/2026/amazon-blocks-metas-muse-ai-assistant-in-new-standoff-over-agentic-shopping/">GeekWire，2026-09-21</a>（原始報導）／ <a href="https://cryptobriefing.com/amazon-blocks-meta-muse-ai-agent/">CryptoBriefing，2026-09-21</a> ／ <a href="https://www.techbuzz.ai/articles/amazon-blocks-meta-s-muse-ai-agent-over-security-concerns">TechBuzz，2026-09-21</a></p></blockquote><h2 id="三、這一版的-release-notes-是空的"><a href="#三、這一版的-release-notes-是空的" class="headerlink" title="三、這一版的 release notes 是空的"></a>三、這一版的 release notes 是空的</h2><p>Google 的 agent 編排器 AX 在九月二十日發了 v0.3.0，GitHub 上的 <code>published_at</code> 是 03:33:20Z，而 release notes 的內容一個字都沒有。</p><p>README 的自我定位寫得很大：「AX is a high-throughput, declarative orchestrator to run billions of autonomous agent workloads in a cluster.」在一個叢集裡跑數十億個自主 agent 工作負載。它自己不管沙箱，沙箱交給另一個叫 Agent Substrate 的專案。介面刻意做得像 Kubernetes，README 直接寫「If you have used Kubernetes, <code>ax</code> will feel similar.」</p><p>v0.3.0 把系統拆成三個服務，並且把任務狀態從 Kubernetes 的 custom resource 搬到 Redis Streams，目的是讓它能吃下數以百萬計的短命任務而不去壓垮 etcd。這段描述來自第三方整理，不是官方 release notes，因為那裡是空的。</p><p>八月三十日這個站寫過 <a href="/2026/08/30/agent-%E5%AF%AB%E5%AE%8C%E7%9A%84%E7%A8%8B%E5%BC%8F%E8%A6%81%E5%9C%A8%E5%93%AA%E8%A3%A1%E8%B7%91-Kubernetes-%E6%8A%8A%E6%B2%99%E7%AE%B1%E6%8B%86%E6%88%90%E4%BA%86%E5%9B%9B%E5%80%8B-CRD/">Kubernetes 把 agent 沙箱拆成四個 CRD</a> 那件事，那是把 agent 塞進 Kubernetes 的宣告式模型裡。一個月後，Google 自家的編排器把狀態往外搬。同一個生態，兩個相反的移動方向，說明「agent 該不該長成 Kubernetes 物件」這題根本還沒有答案。</p><p>etcd 這件事不是 bug，是前提：它假設物件數量以萬計、生命週期以天計。agent 任務兩個假設都不成立。撞到這種牆該做的是換儲存層，不是調參數。</p><p>代價寫在同一版裡。v0.3.0 移除了舊的 Python harness、ATE client、SQL event log 和內建的 skill 範例，v0.2.x 的使用者要真的做一次遷移。而 README 開頭掛著官方自己的 WARNING：「We are still actively refining our core concepts, protocols, and specifications. We will likely to introduce major breaking changes prior to a stable release.」（那個 “We will likely to” 是原文的筆誤，照抄。）截至九月二十一日查詢當下這個 repo 有 4,477 顆星，這個數字每天都在動。</p><p>一個還沒穩定、而且已經在砍東西的專案。它好不好用，跟現在要不要接，是兩個問題。</p><blockquote><p>原文來源：<a href="https://github.com/google/ax">google&#x2F;ax（GitHub）</a> ／ <a href="https://github.com/agent-substrate/substrate">Agent Substrate</a></p></blockquote><h2 id="四、有一種融資是被行事曆綁死的"><a href="#四、有一種融資是被行事曆綁死的" class="headerlink" title="四、有一種融資是被行事曆綁死的"></a>四、有一種融資是被行事曆綁死的</h2><p>據 Bloomberg 報導，軟銀集團正在尋求發行超過 110 億美元等值的高收益債。結構是 100 億美元的美元債，加上 10 億歐元（約 11 億美元）的歐元債。美元債分三檔，到期年限 3 年半、5 年半、7 年半；歐元債分兩檔，4 年與 6 年。</p><p>錢要拿去付軟銀對 OpenAI 追加投資的第三期，金額 100 億美元，必須在十月一日前到位。餘額作一般公司用途。</p><p>時間表這樣排：九月二十四日定價，九月二十九日交割。交割到期限只剩兩天。</p><p>所以這不是從容的資本配置，是先答應了、再去市場上把錢借出來。而市場給的價格已經寫在那裡：軟銀二○三一年到期的那檔美元債，殖利率本月升到 8.2%，一月的低點是 6.7%。同一檔債、兩個時點，年初的低點走到本月的 8.2。</p><p>標準普爾給軟銀的評級是 BB+，被形容為「投機級裡最高的那一階」。這個描述同時是兩件事：不是投資級，但也只差一階。哪一半被強調，取決於誰在講。</p><p>AI 投資熱翻到背面就是這個樣子。錢不是從獲利裡長出來的，是借的，而且借的是投機級的利率。比起 110 億這個頭條數字，8.2% 更值得記住，那是市場對這場賭注開出來的價碼。</p><div class="note info flat"><p>幾個數字的口徑不要混。110 億是這次尋求發行的總額，定價排在九月二十四日，截至報導當下還沒定價，更不是已經到手的錢。100 億是第三期的付款金額，不是軟銀對 OpenAI 的總投資額。另外 2026 年迄今軟銀在所有幣別上已經發掉 150 億美元債券，是今年債市最大的投機級借款人，這個累計實績不含本次的 110 億。對 OpenAI 的累計承諾則是近 650 億美元。這幾個數字彼此不能加減。</p></div><blockquote><p>原文來源：<a href="https://www.bloomberg.com/news/articles/2026-09-21/softbank-seeks-over-11-billion-in-junk-bond-deal-for-openai-bet">Bloomberg，2026-09-21</a>（付費牆）／ <a href="https://en.sedaily.com/international/2026/09/21/softbank-to-sell-11-billion-in-junk-bonds-to-fund-openai-bet">Seoul Economic Daily，2026-09-21</a> ／ <a href="https://www.gurufocus.com/news/9089352/softbank-plans-11-billion-junk-bond-offering-to-fund-openai-investment">GuruFocus</a></p></blockquote><h2 id="五、7-000-這個數字很容易被讀成別的意思"><a href="#五、7-000-這個數字很容易被讀成別的意思" class="headerlink" title="五、7,000 這個數字很容易被讀成別的意思"></a>五、7,000 這個數字很容易被讀成別的意思</h2><p>國際機器人聯合會（IFR）彙整出來的是：2025 年全球大約賣出 7,000 台人形機器人，用途限定在工業與專業服務。</p><p>它不等於「全世界只有 7,000 台人形機器人」。口徑是 2025 這一年、全球、工業與專業服務用途的銷售台數，家用與軍用不算在內，醫療機器人另外分類。IFR 用的定義是外型類人、能在為人設計的環境中自主運作，而且不一定要有腿。</p><p>連「什麼算人形機器人」都還沒有共識。定義各說各話的時候，跨來源的數字比較一定會失真。</p><p>據 Reuters 報導，IFR 秘書長 Susanne Bieller 表示，去年賣出的人形機器人往往被用於研究與資料蒐集，而不是生產性工作。（IFR 總部設在法蘭克福，Bieller 的職稱是秘書長。）車廠那邊的實況是在工廠裡測試，試點通常是個位數、有時候兩位數的機器人數量。</p><p>拿一般工業機器人來對照：2024 年約裝設 542,000 台。另外還有約 199,000 台服務型機器人售出，用在運輸、接待與清潔；這個數字的統計年份原文沒有寫，我就不補。</p><p>預測那一側是另一組人算的。Bank of America Global Research 估計 2026 年人形機器人出貨 90,000 台，2030 年增至 120 萬台。90,000 對上 7,000 是將近十三倍，而且要在一年內發生。一個是預測、一個是實績，一個出自 BoA、一個出自 IFR，不是同一組資料，放在一起看的時候要記得這件事。</p><p>上一則的軟銀，正在為 AI 投資借 110 億美元，而市場對它既有那檔債開出的殖利率是 8.2%。這一則的人形機器人，去年實際賣出 7,000 台，其中很多台買進去是為了產生訓練資料。買家不是在用產品，是在餵模型。</p><p>IFR 的 2025 年工業與服務型機器人完整數據，九月二十四日公布。這次的 7,000 台是提前給記者看的那一角。</p><blockquote><p>原文來源：<a href="https://www.investing.com/news/stock-market-news/humanoid-robot-sales-reach-7000-units-worldwide-in-2025-93CH-4908300">Investing.com，2026-09-21</a>（轉載 Reuters，記者 Toby Sterling）／ <a href="https://tass.com/economy/2190497">TASS</a>（轉載 Reuters）</p></blockquote><hr><p>九月二十四日這天排了兩件事。軟銀那批債券要定價，IFR 的 2025 年機器人數據要公布。一邊要市場替一場賭注標出價格，一邊要把去年到底裝了多少台機器攤開。兩件都還沒出來，但只有其中一件，在它出來的那天就有人會賠錢或賺錢。</p><p>在那之前，這五件事裡你能自己動手的只有 <code>__obi</code>。打開瀏覽器的開發者工具，翻 <code>.openai.com</code> 底下的 cookie，看那一列在不在、<code>Max-Age</code> 寫多少。我沒去試。我在意的是門檻：這件事不必等誰發新聞稿、不必誰授權，任何人都跨得過去。</p><p>剩下四件，你手上都沒有那把工具。Amazon 說 Muse 在擷取憑證、Meta 說有安全虛擬機和一次性虛擬卡，兩邊的說法都沒人能驗；AX 的 release notes 是空的；軟銀那 110 億還沒定價；7,000 台是一份完整報告裡先被拿出來的一角。你能做的，是記住每個數字是誰數的、什麼時候數的、算進去了什麼。</p>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/21/AI-%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E%E6%91%98%E8%A6%81-20260921/</id>
    <link href="https://blog.longhopick.com/2026/09/21/AI-%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E%E6%91%98%E8%A6%81-20260921/"/>
    <published>2026-09-21T04:00:00.000Z</published>
    <summary>一條寫對了卻沒機會執行的程式碼、一個被歸在「分析」的追蹤 cookie，還有兩件事同時排在九月二十四日揭曉。</summary>
    <title>AI 與科技新聞摘要 - 2026/09/21</title>
    <updated>2026-09-21T12:44:10.496Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="AI Agent" scheme="https://blog.longhopick.com/categories/AI-Agent/"/>
    <category term="AI 開發工具" scheme="https://blog.longhopick.com/tags/AI-%E9%96%8B%E7%99%BC%E5%B7%A5%E5%85%B7/"/>
    <category term="AI Agent" scheme="https://blog.longhopick.com/tags/AI-Agent/"/>
    <category term="開源" scheme="https://blog.longhopick.com/tags/%E9%96%8B%E6%BA%90/"/>
    <category term="MCP" scheme="https://blog.longhopick.com/tags/MCP/"/>
    <content>
      <![CDATA[<p>一份 agent 的描述檔躺在目錄裡。名字有了，版本有了，schema 版本有了，作者有了，建立時間照 RFC-3339 寫得工工整整，會做哪些事也列得清清楚楚。</p><p>唯一沒寫的是：你要去哪裡拿到它。</p><p>然後這份檔案完全合法。不是有人偷懶漏填，是規格本來就允許。</p><p>要弄懂這個設計怎麼長成這樣，得先往回退一步，退到一個跟 agent 沒什麼關係的地方。</p><h2 id="骨架是從資安圈搬過來的"><a href="#骨架是從資安圈搬過來的" class="headerlink" title="骨架是從資安圈搬過來的"></a>骨架是從資安圈搬過來的</h2><p>OASF（Open Agentic Schema Framework）的 README 第一段是這樣定義自己的：</p><blockquote><p>The Open Agentic Schema Framework (OASF) is a standardized schema system for defining and managing AI agent capabilities, interactions, and metadata. It provides a structured way to describe agent attributes, capabilities, and relationships using attribute-based taxonomies.</p></blockquote><p>這種段落你大概會直接滑過去。下一段交代了它是從哪裡抄來的：</p><blockquote><p>OASF is highly inspired from <a href="https://ocsf.io/">OCSF (Open Cybersecurity Schema Framework)</a> in terms of data modeling philosophy but also in terms of implementation. The server is a derivative work of OCSF schema server and the schema update workflows reproduce those developed by OCSF.</p></blockquote><p>搬過來的有三樣：資料建模的哲學、實作、schema 的更新流程。schema server 直接寫明是 OCSF schema server 的 derivative work，不是「參考了它的想法」，是拿它的東西改的。這句話是 README 自己寫的，不是我從相似度推的。</p><p>所以，描述 AI agent 會做什麼的那套骨架，原本是為資安領域的事件正規化長出來的。</p><p>這件事其實沒那麼跳。一個要把來源雜亂、格式各異的東西壓成同一種形狀的框架，跟另一個要把各家廠商、各種宣稱的 agent 壓成同一種形狀的框架，要解的是同一個形狀的問題。差別只在格子裡裝什麼。就像超市那套條碼與品類代碼，它一點都不在乎你賣的是牛奶還是螺絲起子，它只在乎每樣東西都有一格可以填、而且大家填的是同一格。</p><h2 id="為什麼不乾脆自己另開一套"><a href="#為什麼不乾脆自己另開一套" class="headerlink" title="為什麼不乾脆自己另開一套"></a>為什麼不乾脆自己另開一套</h2><p>今天要描述一個 agent，能選的格式不只一種。MCP 有自己的 server schema，A2A 有自己的 card，Oracle 那邊有 Open Agent Spec，<code>SKILL.md</code> 有自己的 frontmatter，AGNTCY 本身也曾經有一套 Agent Connect Protocol。</p><p>面對「又一個標準」這種指控，OASF 的回答是不當玩家，當索引。它沒有再生一套 agent card 格式去跟這些搶，而是把它們各建一個 module 收進來，變成 record 底下的一個欄位。</p><p>module 的分類只有兩格：<code>core</code>（uid 1）與 <code>integration</code>（uid 2）。整個生態就這樣被塞進兩個格子。<code>integration</code> 底下目前有四個實際的 module，分別對到 MCP、A2A、Oracle 的 Agent Spec，以及 ACP。</p><p>這裡有個地方很容易讀歪。<code>agentspec</code> 這個 module 的 reference 指向 Oracle 的 Open Agent Spec 文件站，<code>agentskills</code> 指向 <code>agentskills.io</code> 的規格頁。這只代表 OASF 引用了那些規格、替它們建了格子，不代表兩邊有任何合作、聯手或誰加入了誰。引用就只是引用。</p><p>這個定位有代價：完整性永遠落後被收編的那幾份規格一個版本。對方改了，你得跟著改 module，改完還得等自己發版。</p><h2 id="第一個被收掉的，是自家的協定"><a href="#第一個被收掉的，是自家的協定" class="headerlink" title="第一個被收掉的，是自家的協定"></a>第一個被收掉的，是自家的協定</h2><p><code>schema/modules/integration/acp_manifest.json</code> 與 <code>schema/objects/acp.json</code>，這兩個檔案上掛著逐字相同的一段 <code>@deprecated</code>。<code>message</code> 是 “ACP is deprecated, please use A2A instead.”，<code>since</code> 是 <code>0.8.0</code>。</p><p>這個 ACP 是 Agent Connect Protocol，AGNTCY 自己的協定，<code>acp_manifest.json</code> 的 <code>description</code> 就寫著 “Agent Connect Protocol manifest”。順帶一提，ACP 這三個字母在 agent 生態裡不只指一個東西，看到縮寫先確認全名比較不會出事。</p><p>從 <code>acp.json</code> 的欄位看得出它原本設計得不隨便。<code>capabilities</code>（”Declares what invocation features this agent is capable of.”）、<code>input</code>、<code>output</code> 三項都是 required；<code>input</code>、<code>output</code>、<code>custom_streaming_update</code>、<code>thread_state</code>、<code>config</code> 全部 reference 到 <code>openapi_schema_object</code>，也就是整套蓋在 OpenAPI Schema Object 上面。欄位之間還有條件約束：<code>custom_streaming_update</code> 的規定是「Must be specified if <code>streaming.custom</code> capability is true and cannot be specified otherwise.」，<code>thread_state</code> 是「Cannot be specified if <code>threads</code> capability is false.」</p><p>有人認真坐下來設計過這個東西。然後它被自己所屬的 schema 標成 deprecated，訊息要人改用另一條線上的規格。</p><p>先把這句話的範圍界定清楚。<code>since: &quot;0.8.0&quot;</code> 的意思只有一個：在 OASF schema 的 0.8.0 版被標記為 deprecated。它不代表那個協定在那個時間點停止運作，也不代表誰對外發過什麼聲明。被 deprecated 的定義就只到「這份 schema 不再建議你用它」為止，再往外推都是腦補。</p><p>但這件事出現的位置很值得注意。一個組織收手自家規格、改指向別人的規格，這種事通常會出現在部落格、在 roadmap、在某場活動的 keynote。這一次它出現在一個 JSON 檔案的欄位裡。要看到它，你得打開 repo、找到那個路徑、讀完那個物件，然後注意到多了一個 <code>@deprecated</code> 鍵。</p><p>我偏好這種形式的誠實。roadmap 可以重寫，公告可以下架，<code>@deprecated.since</code> 留在 schema 裡會被每一個消費這份 schema 的工具讀到。你不用相信任何人的口頭說法，程式自己會看到。</p><h2 id="第二個被收掉的，是把別人整包抄過來"><a href="#第二個被收掉的，是把別人整包抄過來" class="headerlink" title="第二個被收掉的，是把別人整包抄過來"></a>第二個被收掉的，是把別人整包抄過來</h2><p><code>mcp_data.json</code> 裡有一個叫 <code>mcp_data</code> 的欄位，描述寫著 “The complete original MCP server JSON data structure for full fidelity storage.”。意思是把整包原始的 MCP server JSON 內嵌進 record，一個位元組都不漏。</p><p>它現在掛著 “Inline original MCP payload is deprecated, please use module.artifact instead.”，<code>since</code> 是 <code>1.0.0</code>。</p><p>理由不難推。把別人的整包 JSON 抄進自己的 record，等於對方每改一次版，你手上這份就過期一次。而 OASF 自己有一條版本不可變政策：一個 schema 版本發布之後就不再改動，只接受非破壞性的修正（文件更新、小 bug），任何刪除、新增或結構變更都得進下一版。兩件事湊在一起，你會得到一份既不能改、又註定要過期的副本。</p><p>這條死路的好處是已經有人走過，而且留下了路標。下次你想在自己的資料模型裡「為了完整性」內嵌別人家的整份文件，可以直接跳過這一步，不用自己再撞一次。</p><p>同一個檔案 reference 了 MCP 官方 server schema 的網址，而且是帶日期的那種：<code>https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json</code>。指向一個會動的 latest，跟指向一個釘死的日期，是兩種完全不同的外部依賴態度，前者省事、後者可重現。</p><div class="timeline blue"><div class='timeline-item headline'>        <div class='timeline-item-title'>          <div class='item-circle'><p>OASF 留在 schema 裡的路線修正史</p></div>        </div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>0.8.0</p></div>        </div>        <div class='timeline-item-content'><p>自家的 Agent Connect Protocol 被標 <code>@deprecated</code>，訊息逐字是 “ACP is deprecated, please use A2A instead.”</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>1.0.0</p></div>        </div>        <div class='timeline-item-content'><p>內嵌整包原始 MCP payload 的 <code>mcp_data</code> 欄位被標 <code>@deprecated</code>，訊息要人改用 <code>module.artifact</code>。</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>v1.1.0（2026-07-10）</p></div>        </div>        <div class='timeline-item-content'><p>目前的最新正式 release。官方託管的 schema server 頁尾標的框架版本也是 1.1.0，server 版本 1.1.1。</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>1.2.0-dev</p></div>        </div>        <div class='timeline-item-content'><p>main 分支 <code>schema/version.json</code> 現在的值。下一版還沒發出來。</p></div>      </div></div><h2 id="必填清單在說什麼"><a href="#必填清單在說什麼" class="headerlink" title="必填清單在說什麼"></a>必填清單在說什麼</h2><p>回到開場那份檔案。record 物件（<code>schema/objects/record.json</code>，main 分支）定義了 11 個 attribute，<code>requirement</code> 那一格照抄如下：</p><table><thead><tr><th>欄位</th><th>requirement</th><th>這格裝什麼</th></tr></thead><tbody><tr><td><code>name</code></td><td>required</td><td>record 的名稱</td></tr><tr><td><code>version</code></td><td>required</td><td>record 的版本（原文寫「MAY conform to a specific versioning schema」）</td></tr><tr><td><code>schema_version</code></td><td>required</td><td>OASF schema 的版本</td></tr><tr><td><code>description</code></td><td>required</td><td>record 的描述</td></tr><tr><td><code>authors</code></td><td>required</td><td>作者清單</td></tr><tr><td><code>created_at</code></td><td>required</td><td>建立時間，值 MUST 符合 RFC-3339</td></tr><tr><td><code>skills</code></td><td>required</td><td>與此 record 關聯的 skills 清單</td></tr><tr><td><code>domains</code></td><td>recommended</td><td>與此 record 關聯的 domains 清單</td></tr><tr><td><code>modules</code></td><td>recommended</td><td>更深入描述這個 record 與其能力的 modules</td></tr><tr><td><code>annotations</code></td><td>optional</td><td>附加 metadata</td></tr><tr><td><code>locators</code></td><td>optional</td><td>這個 record 可以在哪裡被找到或使用</td></tr></tbody></table><p>七個 required、兩個 recommended、兩個 optional。</p><p>名字、版本、schema 版本、描述、作者、建立時間，這六個是身分資料，任何一份 metadata 都會要，沒什麼好談。真正做了選擇的是第七個。</p><p><code>skills</code> required，<code>locators</code> optional。</p><p>這東西會做什麼，你必須說。這東西去哪裡拿，你可以不說。</p><p>開場那份檔案為什麼合法，答案就在這一行。</p><p>我的判斷是這個順序在押一個注：目錄先解決媒合，取得排後面。這注要贏，前提是目錄大到「找得到」本身就有價值。一個規模不大的目錄，找到之後拿不到，等於沒找到；一個夠大的目錄，光是知道「原來有人做過這種東西」就值錢，剩下的你自己想辦法聯絡。所以 required 跟 optional 這一格不只是欄位設計，是在賭這個目錄最後會長到多大。</p><p>會讓我改口的條件很具體：哪一版把 <code>locators</code> 升成 required，或者 dir 那一側的客戶端開始在 runtime 硬性要求它，就代表這注沒押中，光靠媒合撐不起一個目錄。</p><p>對寫客戶端的人來說，這個設計的帳單會在 runtime 才寄到。schema 驗證不會擋一筆沒有 <code>locators</code> 的 record，所以你照著 schema 寫的整合測試也不會擋。等到有人真的想把它拉下來用，才發現那一格是空的。缺的那條 fallback 路徑，不能等到那一刻才開始寫。</p><p>而 <code>locators</code> 自己一旦要寫，規矩其實很嚴。<code>type</code> 是一份封閉列舉，共七個值：<code>unspecified</code>、<code>helm_chart</code>、<code>container_image</code>、<code>package</code>、<code>source_code</code>、<code>binary</code>、<code>url</code>。<code>urls</code> 是 required，值 MUST 符合 RFC 1738、SHOULD 用 http 與 https scheme。有寫就得寫好，只是你可以不寫。</p><p>不過 <code>type</code> 的描述用的是「Allowed values MAY be defined for common manifest types.」一份封閉列舉配一句 MAY，讀起來像是這一格還沒想定。</p><h2 id="下一層的必填邏輯整個翻過來"><a href="#下一層的必填邏輯整個翻過來" class="headerlink" title="下一層的必填邏輯整個翻過來"></a>下一層的必填邏輯整個翻過來</h2><p>MCP module 描述一台 MCP server。<code>name</code> 是 required，<code>description</code>、<code>prompts</code>、<code>resources</code>、<code>tools</code> 全部 optional，而 <code>connections</code>（怎麼連上這台 server，本機套件或遠端端點）是 required。</p><table><thead><tr><th>描述的對象</th><th>「會做什麼」</th><th>「怎麼拿到／怎麼連上」</th></tr></thead><tbody><tr><td>record（agent 本體）</td><td><code>skills</code> required</td><td><code>locators</code> optional</td></tr><tr><td>MCP module（外接的 server）</td><td><code>tools</code> optional</td><td><code>connections</code> required</td></tr></tbody></table><p>同一份 schema，差一層，兩套剛好相反的必填邏輯。</p><p>這不是自相矛盾，是兩種東西在目錄裡扮演的角色不一樣。agent 本體是被「找」的那一方，找的人在乎它會什麼；MCP server 是被「接」的那一方，接的人在乎怎麼接上去，至於它有哪些工具，連上去問一下就有了。必填欄位洩漏的是設計者的假設：誰會來讀這份資料，那個人手上缺什麼。</p><h2 id="把-skill-放進哪一格，本身就是主張"><a href="#把-skill-放進哪一格，本身就是主張" class="headerlink" title="把 skill 放進哪一格，本身就是主張"></a>把 skill 放進哪一格，本身就是主張</h2><p>module 只有兩個 category，所以每一次歸類都是一次表態。MCP 與 A2A 進了 <code>integration</code>，而從 <code>SKILL.md</code> 來的 Agent Skills 進了 <code>core/language_model</code>。</p><p>同樣都是「這個 agent 的能力從哪裡來」，一個被當成外接的東西，一個被當成語言模型本體的一部分。</p><p><code>agentskills_manifest</code> 這個物件的 description 只有一句：「Normalized metadata extracted from a SKILL.md file.」欄位共七項，<code>name</code> 與 <code>description</code> required，<code>version</code>、<code>license</code>、<code>compatibility</code>、<code>allowed_tools</code>、<code>frontmatter_metadata</code> 都是 optional。</p><p>這裡又冒出一個不同調的地方：record 層的 <code>version</code> 是 required，到了 skill manifest 這一層變成 optional。同一個概念在兩層之間鬆緊不一，通常代表這兩層是不同時候、為了不同需求長出來的。</p><p>skills 那一側的分類法規模不小，<code>schema/skills/</code> 底下有 18 個頂層分類目錄，從 <code>software_engineering</code>、<code>cybersecurity</code>、<code>data_engineering_analytics</code> 到 <code>reasoning_planning</code>、<code>tool_use_automation</code> 都有。這個 18 我另外回官方託管的 schema server 對過，<code>schema.oasf.outshift.com/skill_categories</code> 那頁列出的 skill category 同樣是 18 個，名稱一一對得上。要注意這是<strong>頂層分類</strong>的數量，不是 skill 總數，每個目錄底下還有子項目，我沒有逐層展開數。</p><h2 id="走到現在：目錄那一側"><a href="#走到現在：目錄那一側" class="headerlink" title="走到現在：目錄那一側"></a>走到現在：目錄那一側</h2><p>Directory（<code>agntcy/dir</code>）是把這套 schema 拿去用的那一半。README 的定義是：</p><blockquote><p>The Directory (dir) allows publication, exchange, and discovery of information about records over a distributed peer-to-peer network.</p></blockquote><p>它列的六項特性裡，最值得停下來的是 Verifiable Claims 那條，因為 README 在那裡承認了一件事：</p><blockquote><p>agent capabilities are often subjectively evaluated</p></blockquote><p>它沒有假裝自己能驗證「這個 agent 真的會做這件事」。它只承諾用密碼學保證這段宣稱確實是某人簽的、路上沒被改過。驗的是出處，不是能力。</p><p>架構那一側走的是 content-addressing 拿到全域唯一性、DHT 做內容發現與同步。這跟站上九月初寫的〈<a href="/2026/09/07/%E5%BE%9E%E6%94%B9%E5%88%A5%E4%BA%BA%E7%9A%84-README-%E5%88%B0%E8%AD%89%E6%98%8E%E5%9F%9F%E5%90%8D%E6%98%AF%E4%BD%A0%E7%9A%84-MCP-Registry-%E7%9A%84%E4%B8%89%E9%81%93%E9%A9%97%E8%AD%89/">從改別人的 README 到證明域名是你的：MCP Registry 的三道驗證</a>〉不在同一層：那邊解的是名字歸誰、命名空間對不對得上；這邊連「名字」都不是主要問題，唯一性交給內容雜湊，發現交給 DHT，「這段話是誰說的」交給簽章。兩邊都在回答「怎麼被找到」，但一個是中心化登錄加所有權驗證，一個是內容定址加分散式雜湊表。走哪條路，取決於你認為目錄本身該不該有一個管理員。</p><p>幾個現況的數字，全部是 2026-09-21 當下用 GitHub API 抓的欄位值：<code>agntcy/oasf</code> 與 <code>agntcy/dir</code> 是同一天開的（2025-02-10），都是 Apache-2.0，<code>archived</code> 都是 false，stars 分別是 334 與 190。oasf 最後一次 push 在 2026-09-08，dir 在 2026-09-20。dir 最新 release 是 v1.7.0（2026-08-18），oasf 是 v1.1.0（2026-07-10）。</p><p>治理那一側也講清楚，因為這格特別容易讀歪。<code>MAINTAINERS.md</code> 列了五位具名維護者。<code>CONTRIBUTORS.md</code> 只有兩項：Cisco Systems Inc. 與「OASF a Series of LF Projects, LLC」，而且那個檔案自己寫明了它的定義：「CONTRIBUTOR file should only contain list of copyright holder (i.e. employers of maintainers).」版權持有者，不是共同開發者名單，更不是採用者名單。這種檔案很容易被讀成「誰在用」。它不是。</p><h2 id="這篇的邊界"><a href="#這篇的邊界" class="headerlink" title="這篇的邊界"></a>這篇的邊界</h2><p>全部來自公開文件與原始碼的閱讀。我沒有裝過 dir、沒有發過一筆 record、沒有跑過任何 CLI 或 server。上面每一個欄位名、每一個 <code>requirement</code> 值、每一段 <code>@deprecated</code> 訊息都照抄檔案原文。</p><p>口徑也要講清楚。最新的正式 release 是 v1.1.0，但 main 分支的 <code>schema/version.json</code> 已經是 <code>1.2.0-dev</code>。我引的 <code>record.json</code>、<code>locator.json</code>、<code>mcp_data.json</code>、<code>acp.json</code> 這些細節讀的是 main 分支（2026-09-21），不保證每一條都已經進了某個正式版。</p><p>還有一整排我沒查的：有沒有任何實際採用者（完全沒查證）、DHT 用的是哪個實作與什麼 routing 演算法、OASF 跟 OCSF 之間除了 inspired 與 derivative work 有沒有正式的治理關聯。README 沒說組織關係，我就不往下推。</p><h2 id="下一個-deprecated-會蓋在誰身上"><a href="#下一個-deprecated-會蓋在誰身上" class="headerlink" title="下一個 @deprecated 會蓋在誰身上"></a>下一個 <code>@deprecated</code> 會蓋在誰身上</h2><p>這個 repo 把自己的路線修正史，一版一版留在 <code>@deprecated.since</code> 欄位裡。0.8.0 收掉自家的協定，1.0.0 收掉內嵌別人 payload 的做法。兩次都沒有配公告，兩次都寫在一個 JSON 欄位裡。讀 schema 的工具會讀到，讀新聞的人不會。</p><p>main 分支現在停在 <code>1.2.0-dev</code>。</p><p><code>skills</code> 那條 required 撐不撐得住，<code>locators</code> 會不會被提上來，<code>integration</code> 底下剩下那幾個 module 誰接著被 <code>@deprecated</code> 蓋掉，答案大概不會寫在任何一篇公告裡。它會出現在某個檔案多出來的那幾行。</p><hr><p><strong>參考來源</strong></p><ul><li>OASF 規格與 README：<a href="https://github.com/agntcy/oasf">agntcy&#x2F;oasf</a>（Apache-2.0）</li><li>Directory：<a href="https://github.com/agntcy/dir">agntcy&#x2F;dir</a>（Apache-2.0）</li><li>官方託管的 schema server：<a href="https://schema.oasf.outshift.com/skill_categories">schema.oasf.outshift.com</a></li><li>血緣來源：<a href="https://ocsf.io/">OCSF (Open Cybersecurity Schema Framework)</a></li></ul>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/21/%E6%9C%83%E4%BB%80%E9%BA%BC%E6%98%AF%E5%BF%85%E5%A1%AB-%E5%8E%BB%E5%93%AA%E8%A3%A1%E6%8B%BF%E6%98%AF%E9%81%B8%E5%A1%AB-OASF-%E6%8A%8A%E8%B3%87%E5%AE%89%E5%9C%88%E7%9A%84-schema-%E6%90%AC%E4%BE%86%E6%8F%8F%E8%BF%B0-agent/</id>
    <link href="https://blog.longhopick.com/2026/09/21/%E6%9C%83%E4%BB%80%E9%BA%BC%E6%98%AF%E5%BF%85%E5%A1%AB-%E5%8E%BB%E5%93%AA%E8%A3%A1%E6%8B%BF%E6%98%AF%E9%81%B8%E5%A1%AB-OASF-%E6%8A%8A%E8%B3%87%E5%AE%89%E5%9C%88%E7%9A%84-schema-%E6%90%AC%E4%BE%86%E6%8F%8F%E8%BF%B0-agent/"/>
    <published>2026-09-21T01:00:00.000Z</published>
    <summary>一份完全沒寫怎麼取得的 agent 描述檔，在這套 schema 底下仍然合法。而這套 schema 的骨架，是從資安事件的框架整套搬過來的。</summary>
    <title>會什麼是必填，去哪裡拿是選填：OASF 把資安圈的 schema 搬來描述 agent</title>
    <updated>2026-09-21T13:04:22.399Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="生活札記" scheme="https://blog.longhopick.com/categories/%E7%94%9F%E6%B4%BB%E6%9C%AD%E8%A8%98/"/>
    <category term="健康" scheme="https://blog.longhopick.com/tags/%E5%81%A5%E5%BA%B7/"/>
    <category term="工程師生活" scheme="https://blog.longhopick.com/tags/%E5%B7%A5%E7%A8%8B%E5%B8%AB%E7%94%9F%E6%B4%BB/"/>
    <category term="生活札記" scheme="https://blog.longhopick.com/tags/%E7%94%9F%E6%B4%BB%E6%9C%AD%E8%A8%98/"/>
    <content>
      <![CDATA[<p>搜尋「過勞 加班 時數」，第一頁大概會給你這個答案：發病前一個月加班超過 92 小時。</p><p>這個數字十年前就被改掉了。現行的認定指引寫的是 100。</p><p>假設你這個月加了 60 小時，打卡系統上那個數字你自己看了都有點心虛。照 92 算，你離那條線還有 32 小時，這個距離足夠讓人鬆一口氣，也足夠讓人有點火大：原來我這樣還不算。</p><p>那 32 小時是拿一個過期的數字算出來的。而 92 跟 100 的差別也不只是 8 小時，它們量的不是同一件事。</p><h2 id="先看現在那張表怎麼寫"><a href="#先看現在那張表怎麼寫" class="headerlink" title="先看現在那張表怎麼寫"></a>先看現在那張表怎麼寫</h2><p>管這件事的文件叫《職業促發腦血管及心臟疾病（外傷導致者除外）之認定參考指引》，現行版本是民國 107 年 10 月 15 日的第四次修正。名字很長，做的事很單純：把「什麼情況下，可以判斷這場腦中風或心肌梗塞跟工作有關」寫成一張可以照著看的表。</p><p>長期工作過重的部分，它給了三條線。發病前 1 個月的加班時數超過 100 小時，指引的用詞是「可依其加班產生之工作負荷與發病有極強之相關性作出判斷」。發病前 2 至 6 個月內的任一期間，月平均加班超過 80 小時，一樣是極強相關性。第三條寫得最委婉：如果這幾個期間的加班時數全都小於 45 小時，那麼「加班與發病相關性薄弱」；超過 45 小時，相關性會隨著時數增加而增強，要看個案評估。</p><p>所以真正把人分成兩邊的那條線不是 100，是 45。100 是「幾乎不用再爭論了」的位置，45 是「開始有話可講」的位置。中間那一大段，全部都在逐案審查的範圍裡。</p><h2 id="三條線一起往上移了-8-小時"><a href="#三條線一起往上移了-8-小時" class="headerlink" title="三條線一起往上移了 8 小時"></a>三條線一起往上移了 8 小時</h2><p>舊版是民國 99 年 12 月 17 日的第二次修正。那個版本的三條線是 92、72、37。</p><p>對照一下：92 變 100、72 變 80、37 變 45。三條線整整齊齊，各加 8。</p><p>看到這種整齊，正常反應是「門檻放寬了嘛」。我一開始也是這樣想的，然後被自己查到的東西打臉。</p><table><thead><tr><th>項目</th><th>99 年版</th><th>現行（107 年版）</th></tr></thead><tbody><tr><td>加班時數的基準</td><td>每<strong>兩週 84 小時</strong>工時之外</td><td>每週 40 小時、以 30 日為 1 個月，<strong>每月 176 小時</strong>以外</td></tr><tr><td>發病前 1 個月</td><td>超過 92 小時</td><td>超過 100 小時</td></tr><tr><td>發病前 2 至 6 個月月平均</td><td>超過 72 小時</td><td>超過 80 小時</td></tr><tr><td>相關性開始增強</td><td>超過 37 小時，<strong>且伴隨日常緊張性的工作性質</strong></td><td>超過 45 小時</td></tr><tr><td>發病當天</td><td>算在區間裡</td><td>不包含發病日</td></tr></tbody></table><p>差別在第一列。這兩組數字不是同一把尺量出來的。</p><p>99 年那版算加班時數的方式，是「以每兩周 84 小時工時之外之時數計算」。當時勞基法第 30 條寫的正常工時就是每 2 週不超過 84 小時。後來工時改制，每週 40 小時自民國 105 年 1 月 1 日施行，指引也跟著換算基準。現行版本寫得很具體：每週 40 小時，以 30 日為 1 個月，每月 176 小時以外的工作時數才叫「加班時數」。</p><div class="note warning flat"><p>舊版原文只說「每兩週 84 小時工時之外」，<strong>沒有給「每月幾小時」的換算</strong>。「以 30 日為 1 個月、每月 176 小時」是 107 年才補進去的寫法。所以要把 92 跟 100 相減、宣稱「放寬了 8 小時」，你得先自己補一個舊版根本沒寫的假設。這篇不會幫你補那個假設，也不會給你一個換算後的總工時數字。</p></div><p>三條線同時 +8，這是看得到的事實。「門檻放寬了 8 小時」則是一個結論，而這個結論需要兩組數字的口徑相同才成立。它們不同。</p><h2 id="最容易誤用的其實是「加班時數」這四個字"><a href="#最容易誤用的其實是「加班時數」這四個字" class="headerlink" title="最容易誤用的其實是「加班時數」這四個字"></a>最容易誤用的其實是「加班時數」這四個字</h2><p>現行指引在講 176 小時那句話的後面，用括號補了一句：「此與勞動基準法之『延長工時』定義不同」。</p><p>這句括號是 107 年那次修正才加上去的，而它可能是整份指引裡最實用的一行。</p><p>你公司打卡系統上那欄「加班時數」，算的是勞基法意義下的延長工時，那是用來算加班費、用來看有沒有超過每月 46 小時上限的東西。指引要的不是那個。指引要的是「每月 176 小時以外的工作時數」，一個為了評估疲勞累積而設計的量法。兩者會有差距，而且差距的方向不一定往哪邊跑。</p><p>你拿自己打卡系統上那個數字去對這三條線，從第一步就對錯欄位了。</p><h2 id="我查錯的那一段，比查對的更值得寫"><a href="#我查錯的那一段，比查對的更值得寫" class="headerlink" title="我查錯的那一段，比查對的更值得寫"></a>我查錯的那一段，比查對的更值得寫</h2><p>我原本以為是 107 年那次修正把 92 改成 100 的。時間順起來很合理：工時改制、認定基準跟著調，聽起來就是這樣。</p><p>於是我去翻職安署的「參考指引重點修正對照表」，想看新舊條文並排。結果對照表的「現行規定」那一欄，也就是修正<strong>前</strong>的版本，已經白紙黑字寫著 100 小時、80 小時、45 小時。</p><p>數字更早就改完了。107 年那次根本沒動任何一個數字。</p><p>那 107 改了什麼？對照表的說明欄列得很清楚：強調評估的是發病前 6 個月內，<strong>不包含發病當日</strong>；補充說明每月加班時數的計算方式，與勞基法延長工時定義不同；還有依日本「脳・心臓疾患の労災認定」的內容，新增備註釐清「發病前 2 至 6 個月內」的平均該怎麼算。</p><p>那個備註值得單獨拿出來講。它說的是：「任一期間」指的是發病前 1 至 2 個月、1 至 3 個月、1 至 4 個月、1 至 5 個月、1 至 6 個月，各自算一次月平均，只要任何一個期間超過 80 小時就算數；<strong>不是</strong>把整個 6 個月平均起來。</p><p>這兩種算法差很多。你如果是前兩個月爆肝、後四個月正常，整體平均會把你洗成安全值，分段算則不會。官方特地補一個備註進去，多半是因為實務上真的有人這樣算過。</p><p>我學到的其實是查法：要確認一條規定什麼時候改的、改了什麼，去讀那份「修正對照表」，它把新舊並排給你看。整理好的懶人包幫你省掉的那一步，正好就是你需要的那一步。</p><div class="timeline orange"><div class='timeline-item headline'>        <div class='timeline-item-title'>          <div class='item-circle'><p>這份指引改了幾次</p></div>        </div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>80 年</p></div>        </div>        <div class='timeline-item-content'><p>編訂。</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>93.12.31</p></div>        </div>        <div class='timeline-item-content'><p>第一次修正。</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>99.12.17</p></div>        </div>        <div class='timeline-item-content'><p>第二次修正。三條線是 92／72／37，基準為每兩週 84 小時工時之外。</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>105.1.5</p></div>        </div>        <div class='timeline-item-content'><p>第三次修正。就在每週 40 小時新制上路後第 5 天。三條線改成 100／80／45，只可能是這一次。</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>107.10.15</p></div>        </div>        <div class='timeline-item-content'><p>第四次修正，現行版本。數字沒動，改的是怎麼算。</p></div>      </div></div><h2 id="加班時數也不是唯一的路"><a href="#加班時數也不是唯一的路" class="headerlink" title="加班時數也不是唯一的路"></a>加班時數也不是唯一的路</h2><p>講了半天時數，得補一句：指引裡的工作負荷評估有三條路徑，長期工作過重只是其中一條。另外兩條是異常事件，指發病前一天到當天遭遇的突發狀況；以及短期工作過重，看的是發病前大約一週內的工作是不是明顯比平常重。</p><p>所以「加班沒到 100 小時就不算過勞」是錯的讀法。時數不夠，還有其他路徑可以走；時數夠了，也不是自動成立，指引本身就寫了要看個案。這些都是行政認定，逐案審查，任何人跟你保證結果都是在講他不知道的事。</p><h2 id="我的立場"><a href="#我的立場" class="headerlink" title="我的立場"></a>我的立場</h2><p>把 100 小時記成「過勞的標準」，是這整套東西最大的誤用。</p><p>100 是一個「極強相關性」的門檻，它的功能是讓爭議停止，不是用來及格的。真正該被一般上班族記住的是 45。45 以下，指引自己說相關性薄弱；45 以上，開始要看個案。</p><p>你這個月打卡系統上那 60 小時，得先換成指引的算法重算一次，才知道確切落在哪一格。可以確定的是，它不在「離 92 還有 32 小時」的那種安全距離裡。</p><p>這個判斷不是不能推翻。如果哪天職安署把 45 那條改寫成可以直接認定，或者公開的認定個案統計顯示，多數獲認定的案子其實都落在 45 到 80 之間，那我會承認「記 100」沒那麼要命，因為那代表下面那條線本來就在作用，不需要特別去記。在那之前，記 100 的人會系統性地低估自己的位置。</p><h2 id="這週四調的是另一種數字"><a href="#這週四調的是另一種數字" class="headerlink" title="這週四調的是另一種數字"></a>這週四調的是另一種數字</h2><p>這週四，9 月 24 日上午 10 時，勞動部要開最低工資審議會，審議 116 年適用的最低工資。現行是月薪 29,500 元、時薪 196 元，自 115 年 1 月 1 日起生效。那個數字每年第三季被拿出來重新檢視一次，是法律規定的。</p><p>過勞的那三條線，上一次動數字是配合工時改制，而工時改制上一次動是 105 年。中間這段時間，沒有人因為「大家好像更累了」就去調它。</p><p>差別不在制度有沒有偷懶。那兩種數字在做完全不同的事。最低工資是一個政策選擇，它回答「社會認為一個人的勞動至少值多少」，所以它每年都該被重新問一次。100 小時那條線回答的是一個醫學因果問題：多少工作量，會讓這顆心臟或這條血管出事。它的依據是研究，不是共識，所以它不隨民意調整，也不會因為你很累就往下移。</p><p>你腦中記著 92 的時候，記錯的不只是那個數字。你以為那張表在量你的痛苦。它沒有。它在量一件事發生的機率。</p><p>這兩件事的差別，就是「我覺得我快撐不住了」和「我的心血管已經在承擔可被量化的風險」的差別。前者不需要任何人認定，你現在就可以把它當真。</p><hr><p><strong>資料來源</strong></p><ul><li>《職業促發腦血管及心臟疾病（外傷導致者除外）之認定參考指引》107.10.15 修正，<a href="https://laws.mol.gov.tw/FLAW/PrintFLAWDAT0202.aspx?id=FL089649">勞動部勞動法令查詢系統</a></li><li><a href="https://www.osha.gov.tw/48110/48363/133456/48395/48405/52149/">職安署指引全文與重點修正對照表（1071015 版）</a></li><li>99 年版三條線與「每兩週 84 小時」基準：<a href="https://www.mol.gov.tw/media/vvhluk4k/ac1b13ab75f3db9eee8f4d8bc6acd12b.doc?mediaDL=true">勞動部《作業具過負荷危害健康服務工作指引》</a></li><li>勞基法第 30 條工時修正與施行日：<a href="https://law.moj.gov.tw/LawClass/LawSingle.aspx?pcode=N0030001&flno=30">全國法規資料庫</a></li><li>最低工資現行數額：<a href="https://www.mol.gov.tw/1607/1632/1633/84947/post">勞動部新聞稿</a></li></ul>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/20/%E9%81%8E%E5%8B%9E%E9%96%80%E6%AA%BB%E5%BE%9E-92-%E5%B0%8F%E6%99%82%E8%AE%8A%E6%88%90-100-%E5%B0%8F%E6%99%82-%E4%BD%86%E6%B2%92%E6%9C%89%E4%B8%80%E6%A2%9D%E6%A8%99%E6%BA%96%E8%A2%AB%E6%94%BE%E5%AF%AC/</id>
    <link href="https://blog.longhopick.com/2026/09/20/%E9%81%8E%E5%8B%9E%E9%96%80%E6%AA%BB%E5%BE%9E-92-%E5%B0%8F%E6%99%82%E8%AE%8A%E6%88%90-100-%E5%B0%8F%E6%99%82-%E4%BD%86%E6%B2%92%E6%9C%89%E4%B8%80%E6%A2%9D%E6%A8%99%E6%BA%96%E8%A2%AB%E6%94%BE%E5%AF%AC/"/>
    <published>2026-09-20T10:00:00.000Z</published>
    <summary>法律認定過勞的那三條線，跟你記得的數字差了 8 小時。差在哪裡，比差多少重要。</summary>
    <title>過勞門檻從 92 小時變成 100 小時，但沒有一條標準被放寬</title>
    <updated>2026-09-20T15:29:20.430Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="AI與科技新聞" scheme="https://blog.longhopick.com/categories/AI%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E/"/>
    <category term="Gemini" scheme="https://blog.longhopick.com/tags/Gemini/"/>
    <category term="AI與科技新聞" scheme="https://blog.longhopick.com/tags/AI%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E/"/>
    <category term="Google" scheme="https://blog.longhopick.com/tags/Google/"/>
    <category term="AI 安全" scheme="https://blog.longhopick.com/tags/AI-%E5%AE%89%E5%85%A8/"/>
    <category term="AI 產業" scheme="https://blog.longhopick.com/tags/AI-%E7%94%A2%E6%A5%AD/"/>
    <content>
      <![CDATA[<p>今年五月，有三家公司被入侵了。入侵的是一個模型，不是人；它在發現對方是真實存在的公司之後停手，沒造成損害。這件事該不該讓外界知道，由誰決定？</p><p>目前的答案是：由決定不說的那一方決定，而那一方同時是唯一的目擊者。</p><h2 id="一、模型五月駭進三家真實公司，九月才見報"><a href="#一、模型五月駭進三家真實公司，九月才見報" class="headerlink" title="一、模型五月駭進三家真實公司，九月才見報"></a>一、模型五月駭進三家真實公司，九月才見報</h2><p>獨立資安評測公司 Irregular 當時在自家的基礎設施上跑一場 capture the flag 演練，受測對象是 Google 的 Gemini。任務是去一家虛構公司取得資訊——而那家虛構公司，跟一家真實存在的公司同名。</p><p>模型分不出來。它照著任務打下去，打中了三家真實公司。</p><p>手法要分開講，因為三次不一樣。其中一次，模型反覆猜密碼，直到取得受保護系統的存取權；另外兩次，它在公開的 repository 裡找到憑證。後面這兩次尤其要記一筆：那不是什麼高深技巧，是任何人翻公開程式碼都做得到的事，只是沒有人願意花整個下午去翻。</p><p>Irregular 在七月通知 Google。事情要到《華爾街日報》去問才攤開來，兩家公司對它證實了這件事，九月十八日當地時間週五首度見報，隔天 ABC News、半島電視台等多家媒體跟進。</p><p>Google 的說法是沒有必要更早揭露，理由有兩條：模型在得知對方是真實公司之後就停手了，而且沒有對它們造成損害。Google 資安工程副總裁 Heather Adkins 的表態是：「These events highlight the importance of training powerful AI models to act responsibly.」這些事件凸顯了訓練強大 AI 模型負責任行事的重要性。</p><p>這句話沒有錯。它只是回答了一個沒有人在問的問題。</p><p>該問的在別的地方。「模型自己停手了」這件事，敘述來源只有一個。ABC 的寫法很精確——Adkins 說，在三次入侵中，模型都在察覺自己進到一家真實公司時停止。說這句話的人，跟決定不揭露的是同一方；而「它自己停了」剛好就是那個決定的全部理由。</p><p>我不是在指控誰造假。演練跑在 Irregular 的基礎設施上，日誌兩邊大概都有。我要講的是結構：一個決定要不要通報的門檻，如果它的判準（有沒有造成損害、模型有沒有自我約束）只能由被通報的那一方認定，那這個門檻就不是門檻，是一個選項。</p><p>「沒有造成損害」這個判準要拆開看。它聽起來很合理，但它把舉證的位置放錯了。要判斷有沒有損害，你得看得到那三家公司的存取紀錄與內部影響，而這兩樣 Google 都沒有。它真正能確認的只有自己這一側：模型停了，沒有繼續動作。那是一份行為紀錄，不是一份損害評估。兩者被當成同一件事在用。</p><p>三次都停，還有另一層意思。ABC 的句子是模型在察覺「自己已經存取了一家真實公司」時停止——已經存取了。照這個寫法，停手發生在取得存取權之後，不在之前；它三次都得先進去，才知道該停。</p><p>再回到那兩次「在公開 repository 裡找到憑證」。這句話描述的不只是模型做了什麼，也描述了一個當時的現況：五月的時候，那些憑證躺在任何人都看得到的地方。現在還在不在？如果你是那三家公司之一而沒收到通知，你不會去輪替它們，也不會回頭翻五月那幾天的存取紀錄，看看還有誰用同一組憑證進來過。一個模型找得到的東西，其他人也找得到，而且不必等到有人跑演練。</p><p>揭露延遲的成本，多半不落在延遲揭露的那一方身上。</p><p>ABC 那篇文章還有一句：「Similar incidents linked to Irregular have been disclosed by Meta, Anthropic and OpenAI.」與 Irregular 相關的類似事件，Meta、Anthropic 與 OpenAI 都揭露過。</p><p>同一家評測商、同一類事件，別家講了，這家沒講。外面的人比不了嚴重程度，因為沒有共同的量尺，所以看得到的差別只剩一個：各家自己的判斷，而每一家的判斷都是自己說了算。</p><p>這裡真正稀缺的東西是基準發生率。如果你是那個要決定「模型能不能碰生產環境憑證」的工程主管，你需要的不是某一次事故的細節，而是這類事故一年發生幾次、在什麼設定下發生、有沒有人重現過。這個數字現在不存在。不存在的原因很妙：資料有人收集，只是收集到的人各自決定要不要講。</p><p>還有一段我查不到。那三家真實公司後來拿到了什麼？一份技術報告、一份時間軸，還是一通電話？我讀過的報導裡沒有任何一句交代。可以確定的只有前半段：它們事前沒有被詢問過，因為整場演練的前提就是那家公司是虛構的。至於事後由誰通知、什麼時候通知、給了什麼，公開資訊到此為止。</p><p>所以我的立場是：把這件事歸類成「安全測試」是錯的分類。它更接近一次未經同意的滲透測試，只是執行者不是人。會讓我改變想法的條件很具體——如果 Irregular 或 Google 任何一方能出示那三家公司收到的完整技術報告，並說明它們是在事發多久之內收到的，我就收回這段。</p><p>這場演練真正的破口是任務設定：虛構公司跟真實公司同名。模型的能力反而是最不意外的一環。這種設定錯誤在人身上也會犯，差別是人打到一半會覺得「這環境看起來不太像演練用的」，然後去問一聲。模型沒有「去問一聲」這個動作。它只有繼續，跟停。</p><p>而這場演練標榜跑在 Irregular 自家的基礎設施上，最後卻打到三家外部的真實公司。沙盒的邊界在這裡是由任務描述的文字定義的，不是由網路隔離定義的。這兩種邊界的強度差了幾個量級，而報導裡沒有任何一句說前一種被補起來了。</p><blockquote><p>原文來源：<a href="https://www.abc.net.au/news/2026-09-19/gemini-google-ai-hacks-three-companies/107172128">ABC News，2026-09-19</a> ／ <a href="https://www.aljazeera.com/news/2026/9/19/googles-gemini-ai-hacks-3-companies-in-security-test-then-stops">半島電視台，2026-09-19</a></p></blockquote><h2 id="二、寫下「不能假設安全跟得上」，然後在行事曆填日期"><a href="#二、寫下「不能假設安全跟得上」，然後在行事曆填日期" class="headerlink" title="二、寫下「不能假設安全跟得上」，然後在行事曆填日期"></a>二、寫下「不能假設安全跟得上」，然後在行事曆填日期</h2><p>《Fortune》在九月十九日美東時間上午 11:18 刊出一篇彙整，把幾家實驗室對「遞迴自我改進」的表態並排放。這個詞的意思很單純：模型參與建造下一代的自己，下一代再參與建造下下一代。</p><p>OpenAI 的兩句話要逐字看。第一句：「Whether and how to proceed must depend on our ability to preserve human control and on informed democratic choices about the benefits and risks.」要不要走下去、怎麼走，必須取決於我們維持人類控制的能力，以及對利弊有充分認知的民主選擇。第二句更短：「cannot assume that progress in alignment and safety will keep pace.」不能假設對齊與安全的進展跟得上。</p><p>同一份報導裡，時間是具體的。OpenAI 本月宣布它已經做出一個自動化的「研究實習生」，處理的是熟練研究員需要好幾天的任務；自動化的「研究員」則排在 2028 年 3 月。前者是已經宣布做到的事，後者是還沒到的目標，兩者不能混成一句話講。xAI 那邊，Musk 給的是今年底，並補了一句 but not later than 2027；他對機制的描述是「humans are gradually getting less and less in the loop」，每一代模型都由上一代建造。</p><p>非營利組織 Future of Life Institute 總裁暨執行長、同時是加州大學聖塔克魯茲分校物理學教授的 Anthony Aguirre，給的評語是：「I think this is probably the worst idea in the history of humanity to do this.」</p><p>怪的是，他們對事實的描述其實沒有分歧。OpenAI 沒有說安全會跟得上，它說的是不能假設會跟得上。Aguirre 說這可能是人類史上最糟的主意。兩邊都同意這件事帶著一個沒有人能保證的下行。</p><p>分歧在誰有權按下去。</p><p>而這一格是空的。「必須取決於……民主選擇」這句話裡，沒有任何一個名詞指向具體機制——沒有哪個機關、哪部法律、哪一次投票。它描述了一個條件，卻沒有人負責檢查條件成立了沒有。條件沒人檢查的時候，寫下條件和沒寫下條件，在行為上的差別是零。</p><p>比一下兩邊的可撤銷性就更清楚。把「不能假設安全跟得上」寫進公開文件，成本是一句話，隨時可以改口徑、改措辭、改定義。把自動化研究員排進 2028 年 3 月，成本是招聘、算力採購、對投資人的承諾——那些東西撤不回來。</p><p>一邊撤得掉，一邊撤不掉。哪一邊會先讓步，不用猜。</p><blockquote><p>原文來源：<a href="https://fortune.com/2026/09/19/what-is-self-improvement-rsi-full-autonomy-openai-anthropic-xai/">Fortune，2026-09-19</a></p></blockquote><h2 id="三、聯邦的答案是不踩煞車"><a href="#三、聯邦的答案是不踩煞車" class="headerlink" title="三、聯邦的答案是不踩煞車"></a>三、聯邦的答案是不踩煞車</h2><p>九月十九日，川普在 Truth Social 發文，宣布要成立「AI Force」，並將任命新的 AI 沙皇。他把這個構想類比成自己當年設立的太空軍。</p><p>原話三句：「We will not in any way hinder or stifle the Growth of this incredible Industry」、「Rather, we will cherish it, help it, and watch over it, as it grows!」、「The robots will not be taking over. The AI will not be taking over the rest of the world.」</p><p>我們不會以任何方式阻礙或扼殺這個了不起的產業的成長；相反地，我們會珍惜它、幫助它、在它成長的時候看顧它。機器人不會接管，AI 不會接管世界的其他部分。</p><p>前任 AI 沙皇是創投家 David Sacks，2026 年稍早辭任、轉為外部顧問，目前擔任川普科學與技術顧問委員會主席。他對這一波 AI 恐慌的評語是：「I think this is becoming a panic.」半島電視台記者 Eva McKend 的觀察則是，川普在 AI 上的立場與公眾情緒越來越不同調，包括他自己的選民。</p><p>同一個月裡，關於「誰來踩煞車」已經出現過三種互斥的答案：業界自己出錢請評估員進駐、加州用行政命令把獨立稽核的時程往前拉一年、四名消費者主張「講好一起放慢」本身就是圍標。現在加上第四種，而第四種的內容是不踩。</p><p>要注意的是「AI 沙皇」是一個人事職位，不是一部法律。建立成本低，撤銷成本一樣低：換一個政府，一道人事命令就沒了。問題是依著這個訊號做的事撤不掉。一座資料中心的攤提年限十幾年起跳，一份多年期電力合約簽下去就是簽下去了，而它們的可行性評估裡，都寫著一行對監理環境的假設。</p><p>低成本的訊號，配上高成本的反應。這個組合本身就是風險的來源——訊號可以在任何一個星期六早上被改寫，反應不行。</p><blockquote><p>原文來源：<a href="https://www.aljazeera.com/news/2026/9/19/trump-says-he-will-create-ai-force-with-new-ai-czar">半島電視台，2026-09-19</a></p></blockquote><h2 id="四、四重曝光做出來的-DRAM-進了量產"><a href="#四、四重曝光做出來的-DRAM-進了量產" class="headerlink" title="四、四重曝光做出來的 DRAM 進了量產"></a>四、四重曝光做出來的 DRAM 進了量產</h2><p>九月二十日，中國記憶體廠長鑫存儲（CXMT）在合肥的 2026 世界製造業大會宣布，第五代 DRAM 技術平台（G5 平台）已進入量產。</p><p>先看清楚這是什麼的規格。原文寫的是記憶體陣列的 active area half-pitch 為 11.95 奈米。這是一個結構尺寸，不是製程節點的名稱，把它讀成「11.95 奈米製程」會誤會一整個數量級的事。另一個數字是每片晶圓產出的 die 數量增加至少 50%，對照基準寫得很明白：跟它自家第四代平台比，不是跟三星或 SK 海力士比。</p><p>重點藏在一個縮寫裡。原文寫「Leveraging an innovative quadruple patterning (SAQP) technology」——自對準四重曝光。全文從頭到尾沒有出現 EUV 這三個字母。</p><p>四重曝光的意思是同一層圖案分四次做出來。它能達到的線寬跟 EUV 有重疊，代價是步驟變多、良率變低、每片晶圓成本上去。這在技術上不新鮮，是所有拿不到 EUV 的人都會走的那條路——這句是我的補充，原文沒有這樣寫。</p><p>出口管制擋的是設備，不是結果。這話聽起來像老生常談，但常被漏掉的是下半段：管制封掉一條路，被封的那一方會走另一條更貴的路，而那條路貴多少、由誰吸收，外面看不到。三星和海力士的成本結構要對股東交代；補貼吸收掉的成本不用交代給任何人。</p><p>所以「他們做得出來」跟「他們做得划算」是兩個問題，目前只有第一個有答案。而整個 AI 記憶體的定價權，長期建立在「先進 DRAM 只有那三家做得出來」這個假設上——這則消息測的正是那個假設的前半截。</p><p>同一篇報導裡另一個數字提供了背景：TrendForce 說 2026 年第二季全球 DRAM 產業營收季增 59.5%。這是全產業的營收季增率，不是任何一家的市占率。在一個營收一季漲六成的市場裡，新增供給需要證明的事比平常少：需求會先把它吃掉，價格訊號要更久才會浮出來。</p><blockquote><p>原文來源：<a href="https://www.globaltimes.cn/page/202609/1370944.shtml">Global Times，2026-09-20</a></p></blockquote><h2 id="五、一美元的輸入價是一個宣稱"><a href="#五、一美元的輸入價是一個宣稱" class="headerlink" title="五、一美元的輸入價是一個宣稱"></a>五、一美元的輸入價是一個宣稱</h2><p>九月二十日，中國的階躍星辰（StepFun）把 Step 5 Preview 放上 API 與 Studio。官方模型文件頁列的規格：脈絡窗 100 萬 token、最大輸出 64k token，輸入支援文字、圖片與影片，單次請求最多 60 張圖，影片單檔小於 128 MB、建議 5 分鐘以內。</p><p>價格不在那一頁上。官方文件只寫「依實際輸入與輸出 token 用量計費」。第三方評測站 Artificial Analysis 列的是輸入每百萬 token 1.00 美元、輸出 2.70 美元，另外給了一個混合價 0.51 美元。0.51 是在假設 7:2:1 的快取命中／輸入／輸出比例下算的，跟前兩個數字不同口徑，不能互換也不能相減。同一頁把它的智慧指數列為 44 分、輸出速度約每秒 99.8 個 token、參數 6,000 億。</p><p>一美元不告訴你任何關於成本的事。價格由賣方單方面設定，可以反映成本，也可以反映補貼或搶市占的策略；你簽下去的是價格，不是成本結構。而它名字裡還帶著 Preview——預覽版的定價本來就不是承諾。把生產系統架在這個價格上，每個月賺到的是帳單差額，扛的是切換成本，而切換成本要到它調價那天才結算。</p><blockquote><p>原文來源：<a href="https://platform.stepfun.ai/docs/en/guides/models/step-5-preview">StepFun 官方文件</a> ／ <a href="https://artificialanalysis.ai/models/step-5">Artificial Analysis</a></p></blockquote><hr><p>研究實習生這件事，OpenAI 本月已經宣布做到了。</p><p>算不算數、用什麼定義算、由誰認定，目前沒有任何一條規則管。宣布的人就是唯一的裁判。</p><p>而外界知道得最清楚的那一次，時間軸是五月發生、七月通知、九月見報，還不是任何一方主動說的。那次至少有一家第三方在現場，七月那次通知也留下了一個時間點。</p><p>研究實習生這一格，連第三方都沒有。</p>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/20/AI-%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E%E6%91%98%E8%A6%81-20260920/</id>
    <link href="https://blog.longhopick.com/2026/09/20/AI-%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E%E6%91%98%E8%A6%81-20260920/"/>
    <published>2026-09-20T04:00:00.000Z</published>
    <summary>一個模型在五月駭進三家真實公司，決定不說的那一方也是唯一的目擊者；還有一項本月宣布達成、而裁判就是宣布者自己的里程碑。</summary>
    <title>AI 與科技新聞摘要 - 2026/09/20</title>
    <updated>2026-09-20T15:25:15.292Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="AI Agent" scheme="https://blog.longhopick.com/categories/AI-Agent/"/>
    <category term="AI 開發工具" scheme="https://blog.longhopick.com/tags/AI-%E9%96%8B%E7%99%BC%E5%B7%A5%E5%85%B7/"/>
    <category term="開源" scheme="https://blog.longhopick.com/tags/%E9%96%8B%E6%BA%90/"/>
    <category term="LLM" scheme="https://blog.longhopick.com/tags/LLM/"/>
    <category term="Python" scheme="https://blog.longhopick.com/tags/Python/"/>
    <content>
      <![CDATA[<p>測試紅了按 re-run，綠了就 merge。在 CI 裡這個動作不需要理由，沒人會停下來想那個按鈕在統計上做了什麼事。</p><p>同樣一個動作搬進模型評測，它會動到你最後貼進報告的那個數字，而且只往一個方向動。</p><p>UK AISI 的 Inspect 在自己的錯誤處理文件裡掛了一個警告框，講的就是這件事。框架作者跳出來提醒你別太相信自己跑出來的分數，這種事情不常見。順著這條線往原始碼裡摸，旁邊還蹲著另外兩個。</p><h2 id="重試那一下，等於多擲了一次骰子"><a href="#重試那一下，等於多擲了一次骰子" class="headerlink" title="重試那一下，等於多擲了一次骰子"></a>重試那一下，等於多擲了一次骰子</h2><p>一場 eval 剝到最裡面只有一件事：跑 N 個樣本，每個樣本給模型一個輸入，記下成功或失敗，最後把成功的數量除一除。那個商數就是分數。所以 eval 本質上是在估一個機率。</p><p>估機率有條不成文的規矩，每個樣本的取樣次數要一樣。一個樣本擲一次骰子、另一個擲三次，算出來的平均值就不是你以為的那個平均值。</p><p><code>retry_on_error</code> 做的事情，正好踩在這條規矩上。它讓出錯的樣本重跑幾次才算真的失敗。文件裡的範例是這樣下的：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">inspect <span class="built_in">eval</span> ctf.py --retry-on-error    <span class="comment"># retry 1 time</span></span><br><span class="line">inspect <span class="built_in">eval</span> ctf.py --retry-on-error=3  <span class="comment"># retry up to 3 times</span></span><br></pre></td></tr></table></figure><p>如果錯誤來自 API 掛掉、rate limit、sandbox 抽風，重試完全合理，因為「誰被重試」跟「樣本內容是什麼」無關，骰子多擲的機會是隨機灑的，平均起來不偏。</p><p>問題在另一種錯誤。官方文件那個警告框（<code>docs/handling-errors.qmd</code>，標題是 Retries and Distribution Shift）是這樣寫的：</p><blockquote><p>While sample retries enable improved recovery from transient infrastructure errors, they also carry with them some risk of distribution shift. For example, imagine that the error being retried is a bug in one of your agents that is triggered by only certain classes of input. These classes of input could then potentially have a higher chance of success because they will be “re-rolled” more frequently.</p></blockquote><p>你的 agent 有個 bug，只有碰到某一類輸入才會炸。可能是輸入裡夾了奇怪的字元，可能是工具回傳特別長把 context 撐爆。那一類輸入的每個樣本，都因為這個 bug 拿到了額外的擲骰機會。其他一次就跑完的樣本沒有。</p><p>而且這個偏移是單向的。重試只會發生在錯掉的樣本上，沒有任何機制會把已經成功的樣本抓回來重跑一次看它會不會失敗。所以重試這件事只能把分數往上推，推不下來。</p><p>還有一層更狠的。文件在講容錯門檻那段順手寫了一句：failed samples are <em>not scored</em>。錯掉的樣本預設根本進不了計分。也就是說，重試真正決定的不是「這個樣本考幾分」，是「這個樣本有沒有資格進到計分裡面」。一群本來會集體缺席的輸入，因為多擲了幾次骰子，其中一部分擠進來了，而且擠進來的都是剛好成功的那些。</p><p>框架是有給後路的。<code>score_on_error</code> 會讓錯掉的樣本照樣用出錯前的 <code>TaskState</code> 去計分，而且它只在重試全部用完之後才觸發，跟 <code>retry_on_error</code> 疊得起來。代價是你的 scorer 得有辦法吃一個殘缺的 state。文件沒有寫 scorer 自己也在這一步炸掉會怎麼樣，但照這個設計推下去，那個樣本最後大概還是只有 error 沒有 score，跟沒開一樣。</p><p>文件給的補救方式很誠實，也很不夠：</p><blockquote><p>Consequently, when enabling <code>retry_on_error</code> you should do some post-hoc analysis to ensure that retried samples don’t have significantly different results than samples which are not retried.</p></blockquote><p>事後自己去分析，比對被重試過的樣本跟沒被重試的樣本結果有沒有顯著差異。</p><p>我的立場是，這個選項的名字取得太安全了。<code>retry_on_error</code> 讀起來像 <code>max_retries</code>，像連線層的東西，你在 debug 一個一直被 429 打斷的 eval 時會很自然地加上去，然後忘記它還在。真正該做的是把重試過的樣本在 log 裡單獨標出來、分開算一次分數，讓落差自己跳到你臉上，而不是寄望每個人都記得回去做事後分析。Inspect 其實已經把 <code>error_retries</code> 欄位寫進樣本裡了，材料是齊的，差的是有沒有人替你算。</p><p>會讓我改變想法的條件也很具體：如果實務上的重試絕大多數都是真的基礎設施錯誤，agent bug 觸發的那種佔比低到可以忽略，那自動化這個比對就是過度設計，加一個沒人看的欄位而已。我手上沒有這個分佈的數字，所以這只是我的判斷，不是結論。</p><h2 id="文件寫「超過」，程式碼寫「達到」"><a href="#文件寫「超過」，程式碼寫「達到」" class="headerlink" title="文件寫「超過」，程式碼寫「達到」"></a>文件寫「超過」，程式碼寫「達到」</h2><p><code>fail_on_error</code> 是容錯門檻，用來決定要壞掉幾個樣本才把整場 eval 判死。你可以給它布林值，也可以給數字：小於 1 當成比例，大於 1 當成絕對個數。文件那張表逐字是這樣寫的：</p><table><thead><tr><th>Value</th><th>Behaviour</th></tr></thead><tbody><tr><td><code>fail_on_error=True</code></td><td>Fail eval immediately on sample errors (default).</td></tr><tr><td><code>fail_on_error=False</code></td><td>Never fail eval on sample errors.</td></tr><tr><td><code>fail_on_error=0.1</code></td><td>Fail if <strong>more than</strong> 10% of total samples have errors.</td></tr><tr><td><code>fail_on_error=5</code></td><td>Fail eval if <strong>more than</strong> 5 samples have errors.</td></tr></tbody></table><p>兩個 more than。再看實作，<code>src/inspect_ai/_eval/task/error.py</code> 裡的判斷式：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">_should_eval_fail</span>(<span class="params"></span></span><br><span class="line"><span class="params">    sample_error_count: <span class="built_in">int</span>, total_sample_count: <span class="built_in">int</span>, fail_on_error: <span class="built_in">bool</span> | <span class="built_in">float</span> | <span class="literal">None</span></span></span><br><span class="line"><span class="params"></span>) -&gt; <span class="built_in">bool</span>:</span><br><span class="line">    <span class="keyword">if</span> fail_on_error <span class="keyword">is</span> <span class="literal">False</span>:</span><br><span class="line">        <span class="comment"># if fail_on_error is False, we never fail</span></span><br><span class="line">        <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line">    <span class="keyword">elif</span> fail_on_error <span class="keyword">is</span> <span class="literal">None</span> <span class="keyword">or</span> fail_on_error <span class="keyword">is</span> <span class="literal">True</span>:</span><br><span class="line">        <span class="comment"># if fail_on_error is None or True, we fail if there is any error</span></span><br><span class="line">        <span class="keyword">return</span> sample_error_count &gt; <span class="number">0</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">if</span> fail_on_error &lt; <span class="number">1</span>:</span><br><span class="line">            <span class="comment"># if fail_on_error is less than 1, we make a fractional check of errors</span></span><br><span class="line">            <span class="keyword">return</span> sample_error_count &gt;= fail_on_error * total_sample_count</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="comment"># if fail_on_error is larger than 1, we check the absolute count of errors</span></span><br><span class="line">            <span class="keyword">return</span> sample_error_count &gt;= fail_on_error</span><br></pre></td></tr></table></figure><p>兩條數值路徑都是 <code>&gt;=</code>。你設 5，第 5 個錯誤就收攤，不是第 6 個。你設 0.1 而總共 100 個樣本，第 10 個錯誤就收攤，不是第 11 個。差一個。</p><p>單看這個落差不痛不癢，一場跑幾百個樣本的 eval 少容忍一個錯不會改變什麼。真正會咬人的是它帶進你腦袋的那個模型：你在 <code>Task</code> 裡寫 5，心裡想的是「我可以吃下 5 個錯」，實際上你能吃下的是 4 個。等哪天你要解釋「為什麼這場 eval 明明還在容忍範圍內卻死了」，你會拿著文件那張表推論半天，推不出來。</p><p>我另外把 <code>docs/</code> 底下其他提到 <code>fail_on_error</code> 的四份檔案翻過一遍（<code>scoring-policy.qmd</code>、<code>fallbacks.qmd</code>、<code>tasks.qmd</code>、<code>sample-source.qmd</code>），它們全部只是把讀者指回 <code>handling-errors.qmd</code>，沒有任何一份重新描述過那張表的數字語意。所以那張表就是唯一的數字出處，也就是說，照文件走的人不會有第二個地方可以對答案。</p><div class="note warning flat"><p>講清楚我的位置：我沒有安裝過 Inspect，也沒有跑過任何一次 eval。上面這些全部出自把官方文件跟原始碼攤開來逐字讀。「文件寫 more than、程式碼寫 <code>&gt;=</code>」這條是比對兩份文本得到的落差，不是跑出來看到的行為。這是本文所有敘述的邊界，往下幾節也一樣。</p></div><h2 id="比例門檻的分母，會在跑到一半的時候長大"><a href="#比例門檻的分母，會在跑到一半的時候長大" class="headerlink" title="比例門檻的分母，會在跑到一半的時候長大"></a>比例門檻的分母，會在跑到一半的時候長大</h2><p>回頭看剛剛那行 <code>sample_error_count &gt;= fail_on_error * total_sample_count</code>。比例門檻要能用，右邊那個 <code>total_sample_count</code> 必須是個常數。你有 500 個樣本、設 0.1，門檻就是 50，從頭到尾不動。</p><p>除非樣本不是一開始就全部躺在那裡等你跑。</p><p>Inspect 支援 <code>SampleSource</code> 驅動的 task，樣本邊跑邊生。這時候 planned total 是一個會長大的數字，而 <code>SampleErrorHandler.__init__</code> 的 docstring 把這個坑寫得比文件正文還清楚，逐字是：</p><blockquote><p>defer_fractional: Don’t abort mid-run on a fractional threshold — leave it to the end-of-run check. Used by <code>SampleSource</code>-driven tasks, whose planned total grows while they run: an early error would otherwise be measured against a transiently small denominator (e.g. a 1-sample seed erroring trips <code>1 &gt;= 0.5*1</code> before the source has produced the rest). Absolute-count and any-error thresholds don’t depend on the denominator and still abort mid-run.</p></blockquote><p><code>1 &gt;= 0.5*1</code>。一個 seed 樣本，分母當下是 1，你設的容錯比例是 0.5，那個樣本錯了，<code>1 &gt;= 0.5</code> 成立，整場 eval 在真正的樣本都還沒生出來以前就被判死。你寫 0.5 的意思是「一半壞掉我都還能忍」，它讀成的是「第一個就不准壞」。</p><p><code>defer_fractional</code> 就是為了這個存在：比例型門檻不在跑的中途判，留到收工再算。</p><p>後半句才是重點。絕對個數（設 5）跟任意錯誤（設 True）這兩種門檻不依賴分母，所以照樣中途 abort，該停還是會停，只有比例被延後。一個門檻能不能在中途拿來用，取決於它的計算需不需要一個還沒定案的數字。</p><p>同一件事在 <code>docs/sample-source.qmd</code> 有散文版：</p><blockquote><p>A <em>fractional</em> <code>fail_on_error</code> threshold (e.g. <code>0.5</code>) is evaluated at the end of the run rather than mid-run for <code>SampleSource</code> tasks: the planned total grows while the task runs, so a mid-run check would measure early errors against a transiently small denominator.</p></blockquote><p>監控設「錯誤率超過 5% 就 call 值班」，然後每天流量剛起來那幾分鐘、或半夜只有兩三個請求的時候，一個健康檢查失敗就把人挖起來。SRE 的標準解法是加一個最小樣本數，樣本不夠就不判。這裡是同一個病、不一樣的解法：不是等分母夠大，是等分母定案。</p><h2 id="保險絲只認得一種形狀的插頭"><a href="#保險絲只認得一種形狀的插頭" class="headerlink" title="保險絲只認得一種形狀的插頭"></a>保險絲只認得一種形狀的插頭</h2><p>第三個機制跟分數的關係比較迂迴，踩到了也更難發現。</p><p>eval 失敗重跑的時候，Inspect 會盡量重用上一輪已經跑完的樣本，時間跟 API 錢都省得下來。要重用就得把新舊兩輪的樣本一一對上，所以每個樣本需要一個穩定的識別碼。文件給兩條路：自己在 dataset 裡放 <code>id</code> 欄位，或者靠 Inspect 自動編號。</p><p>自動編號是流水號。流水號碰到洗牌全部錯位，第 7 號這一輪是 A 題、下一輪是 B 題，重用就是張冠李戴。</p><p>框架知道這件事，放了一道保險。<code>docs/_sample-preservation.md</code> 的原文：</p><blockquote><p>You can rely on Inspect’s assignment of an auto-incrementing <code>id</code> for samples, however this <em>will not work correctly</em> if your dataset is shuffled. Inspect will log a warning and not re-use samples if it detects that the <code>dataset.shuffle()</code> method was called, <strong>however if you are shuffling by some other means this automatic safeguard won’t be applied.</strong></p></blockquote><p>破口在最後那一句。這道保險偵測的是「你有沒有呼叫 <code>dataset.shuffle()</code> 這個方法」，不是「你的資料順序有沒有被動過」。前者好偵測，後者才是真正要防的事。</p><p>你自己 <code>random.shuffle</code> 樣本清單、在讀檔那一層就把行打亂、從資料來源拉的時候順手帶個 shuffle 參數，全部繞過去。繞過去的表現也不是報錯，是安靜：沒有警告、沒有 log、重用照常發生，只是對到的樣本是錯的。分數當然也就不是那個分數了。</p><p>文件的建議很單純：洗牌對你的評測重要，就自己放 <code>id</code>。</p><h2 id="會自動重試的測量系統，都有同一個病"><a href="#會自動重試的測量系統，都有同一個病" class="headerlink" title="會自動重試的測量系統，都有同一個病"></a>會自動重試的測量系統，都有同一個病</h2><p>三個擺在一起看，它們共用一個形狀：為了讓測量更穩而加上去的補償動作，回頭改掉了被測量的東西。重試改掉每個樣本的取樣次數，比例門檻改掉「多少算太多」的基準，保險絲改掉哪些樣本會被拿去重用。單獨看每一個都是合理的工程決定，而且每一個都有文件寫。</p><p>這個形狀不是評測框架的專利。</p><p>CI 的 flaky test retry 就是。設成 retry 三次才算真的紅，那些「只在某種時序下才會壞」的測試就拿到了額外的擲骰機會，通過率被抬上去，而它們正好是整份測試套件裡最該被盯著的那幾個。你沒有讓程式碼變好，你只是讓量測工具對特定一類缺陷變寬容了。</p><p>壓測也一樣。把 timeout 的請求重送一次再算成功率，你量到的是「這個系統加上一層重送」的成功率。上線那天，前面沒有那一層。</p><p>順手把基準記一下。本文引的原始碼跟文件都是 2026-09-20 從 <a href="https://github.com/UKGovernmentBEIS/inspect_ai">inspect_ai</a> 的 main 分支拉下來讀的，MIT 授權。PyPI 上的 <a href="https://pypi.org/project/inspect-ai/"><code>inspect-ai</code></a> 最新版是 0.3.266，2026-09-19 上傳，需要 Python 3.10 以上。這個 repo 沒有開過任何一個 GitHub release，想對版本只能看 PyPI。文件站在 <a href="https://inspect.aisi.org.uk/">inspect.aisi.org.uk</a>，而這幾個檔案都還在動，你讀到這篇的時候措辭跟行號很可能已經不一樣了。</p><p>要自己檢查倒是不用讀完整份原始碼。任何一份會自動重試的腳本，評測的、壓測的、CI 的都算，該看的都是同一件事：被重試的那些案例，彼此有沒有共同的特徵。有共同特徵，數字就已經歪了，歪多少要另外算；看起來沒有，多半只代表還沒有人去比對過。</p><p>Inspect 的文件至少把這個要求寫出來了：請自己做事後分析。</p>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/20/%E9%87%8D%E8%A9%A6%E4%B8%80%E6%AC%A1-%E5%88%86%E6%95%B8%E5%B0%B1%E5%BE%80%E4%B8%8A%E9%A3%84-%E8%AE%80-Inspect-%E5%8E%9F%E5%A7%8B%E7%A2%BC%E6%89%BE%E5%88%B0%E7%9A%84%E4%B8%89%E5%80%8B%E5%AE%89%E9%9D%9C%E6%A9%9F%E5%88%B6/</id>
    <link href="https://blog.longhopick.com/2026/09/20/%E9%87%8D%E8%A9%A6%E4%B8%80%E6%AC%A1-%E5%88%86%E6%95%B8%E5%B0%B1%E5%BE%80%E4%B8%8A%E9%A3%84-%E8%AE%80-Inspect-%E5%8E%9F%E5%A7%8B%E7%A2%BC%E6%89%BE%E5%88%B0%E7%9A%84%E4%B8%89%E5%80%8B%E5%AE%89%E9%9D%9C%E6%A9%9F%E5%88%B6/"/>
    <published>2026-09-20T01:00:00.000Z</published>
    <summary>UK AISI 的 Inspect 評測框架裡，重試、容錯門檻、樣本重用這三個機制都會安靜地改動你的分數。拆開它們的原理，順便檢查自己的評測腳本有沒有同一個病。</summary>
    <title>重試一次，分數就往上飄 - 讀 Inspect 原始碼找到的三個安靜機制</title>
    <updated>2026-09-20T15:33:13.816Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="生活札記" scheme="https://blog.longhopick.com/categories/%E7%94%9F%E6%B4%BB%E6%9C%AD%E8%A8%98/"/>
    <category term="工程師生活" scheme="https://blog.longhopick.com/tags/%E5%B7%A5%E7%A8%8B%E5%B8%AB%E7%94%9F%E6%B4%BB/"/>
    <category term="生活札記" scheme="https://blog.longhopick.com/tags/%E7%94%9F%E6%B4%BB%E6%9C%AD%E8%A8%98/"/>
    <category term="理財" scheme="https://blog.longhopick.com/tags/%E7%90%86%E8%B2%A1/"/>
    <content>
      <![CDATA[<p>兩年前想買第二間房的人，手上得先有房價的一半。</p><p>2024 年 9 月 20 日，央行第七波選擇性信用管制上路，自然人第 2 戶購屋貸款全國限貸 5 成。一間 2,500 萬的房子，銀行最多借 1,250 萬，剩下 1,250 萬自己想辦法。那就是當時每個人心裡跑的那套算術：總價乘上 0.5，看看戶頭夠不夠。</p><p>今年 9 月 17 日的理監事會之後，同一間房子、同一套算術，答案變成 750 萬。</p><p>那天央行第三季理監事聯席會議做了兩件事。政策利率連續第 10 次凍結，重貼現率維持 2%、擔保放款融通利率 2.375%、短期融通利率 4.25%。另一件是調整選擇性信用管制，自然人第 2 戶購屋貸款最高成數由 6 成調高至 7 成，隔天 9 月 18 日生效。工商時報那句寫得最白：「以2500萬元房屋為例，本來要準備1000萬元，現在手上自備款可以少準備250萬元」。</p><table><thead><tr><th>時間</th><th>第 2 戶最高成數</th><th>2,500 萬的房子要自備</th></tr></thead><tbody><tr><td>2024-09-20 第七波上路</td><td>5 成</td><td>1,250 萬</td></tr><tr><td>2026-03-20 第一次鬆綁</td><td>6 成</td><td>1,000 萬</td></tr><tr><td>2026-09-18 第二次鬆綁</td><td>7 成</td><td>750 萬</td></tr></tbody></table><p>中間那欄是央行公布的成數，右邊那欄是我拿工商時報那個 2,500 萬的例子套進去算的。換一個總價，整欄都要重算。</p><h2 id="算式裡有一格從頭到尾沒動過"><a href="#算式裡有一格從頭到尾沒動過" class="headerlink" title="算式裡有一格從頭到尾沒動過"></a>算式裡有一格從頭到尾沒動過</h2><p>這套算術有一個前置條件，藏在 <mark class="hl-label 2">第</mark> 這三個字裡。</p><p>要讓這三次調整對你有意義，你得先有第 1 戶。</p><p>第 1 戶那條線呢？成數沒動，新青安的規則沒動。兩年之間調了三次，沒有一次調到那裡。而且 7 成這個數字有它的圍欄：限自然人、限自住或自家人自住的需求，第 2 戶的貸款仍然禁止寬限期，第 3 戶以上、高價住宅、法人購屋的成數維持 3 成，也都沒鬆。房產研究員李同榮給的形容是「政策軟中帶硬」。</p><p>所以這兩年真正被改動的，是一群本來就持有不動產的人，手上的財務彈性。自備款門檻少 250 萬，對他們是多一點迴旋空間。對還在存人生第一桶自備款的人，這則新聞的資訊量是零。</p><h2 id="央行那邊也在算一筆帳，算的不是房價"><a href="#央行那邊也在算一筆帳，算的不是房價" class="headerlink" title="央行那邊也在算一筆帳，算的不是房價"></a>央行那邊也在算一筆帳，算的不是房價</h2><p>放寬的理由，央行講得很清楚：</p><blockquote><p>截至7月底，全體銀行不動產貸款占總放款比率已由今年3月底的35.56%降至34.44%，較2024年6月高點37.61%更下降3.17個百分點</p></blockquote><p>比率有分子，也有分母。</p><p>分子是銀行的不動產貸款，分母是總放款。從 37.61% 走到 34.44%，可能是分子縮了，可能是分母脹了，也可能兩邊都在動但速度不一樣。光看比率本身，分不出來是哪一種。</p><p>三種情況對「房市風險」的意義差很多。分子真的縮，代表房貸放款在收；分母脹，代表銀行整體放款規模在長，而其他類型的放款長得比不動產快。後面那種情況下，不動產貸款的絕對金額可以一毛都沒有減少，比率照樣好看。</p><div class="note warning flat"><p>這個比率量的是銀行資產負債表的結構，不是房價，不是房貸違約率，也不是「房子變好買了」。它跟一個上班族買不買得起房，中間隔了好幾層轉換。我沒有查到分子與分母的絕對金額，所以上面三種可能哪一種為真，我沒有證據，只能說光憑一個比率看不出來。</p></div><p>這還是一個回頭看的數字，落後於現實。它記錄的是 2024 年 9 月到今年 7 月之間發生了什麼事。管制期間投機性需求被擠出去，市場剩下的多半是自住需求，比率自然會降。拿這個結果當作「現在可以放寬了」的依據，邏輯上就是拿「上次沒出事」去證明「這次不會出事」。</p><h2 id="另一群人每個月在算的是六百九十七塊"><a href="#另一群人每個月在算的是六百九十七塊" class="headerlink" title="另一群人每個月在算的是六百九十七塊"></a>另一群人每個月在算的是六百九十七塊</h2><p>主計總處 9 月 8 日公布 8 月消費者物價指數，年增 2.04%，比 7 月的 2.52% 收斂，但已經是連續 4 個月高於 2% 警戒線。扣掉蔬果與能源的核心 CPI 年增 2.3%。今年前 8 月平均 CPI 年增 1.84%。</p><p>拆開來看，外食費年增 3.17%。主計總處綜合統計處科長蔡秀慧說這是 8 個月來最大漲幅，而且外食費已經連續 3 個月漲幅超過 3%。房租年增 1.69%。</p><p>主計總處另外做過一個試算：以每月消費 8 萬元的家庭為基準，居住類每月多支出 424 元，外食費每月多花 273 元。這兩項加起來，697 元。</p><p>年線跟月線在這裡會打架，先說清楚：前 8 月平均那個 1.84% 確實壓在警戒線以下，最近這四個月的單月數字不是。</p><p>立委李彥秀在央行決議之後的說法是：「過去幾年雖然整體通膨數字維持在2%警戒線之下，但是人民的『體感通膨』卻是爆表，特別是房屋租金以及外食，對年輕以及弱勢族群特別有感」。</p><p>兩組數字擺在一起看很刺眼。一邊是一次性少掉 250 萬的自備款門檻，一邊是每個月多出來的 697 元。它們不是同一個量級，更關鍵的是，不是同一群人在算。喊體感通膨最大聲的那群人，跟這次鬆綁幫得到的那群人，交集很小。</p><p>台北市的房價所得比是 14.6 倍，高於香港的 14.4 倍、雪梨 13.8 倍、倫敦 9.1 倍、首爾 8.8 倍、紐約 7.4 倍。這個數字央行自己引用過，不過我沒有查到它對應的是哪一年哪一季的資料。這個倍數算的是房價對家戶年可支配所得，也就是把可支配所得一塊不留全拿去買房，要買 14.6 年。這條線這次同樣沒被碰到。</p><h2 id="放寬的時間點"><a href="#放寬的時間點" class="headerlink" title="放寬的時間點"></a>放寬的時間點</h2><p>連「到底鬆夠了沒」都還沒有共識。</p><p>9 月 2 日，決議還沒公布，德明財經科大教授莊孟翰在一場住宅產業鏈景氣調查發表會上說現行央行管制政策太保守，他的判斷是房地產已經淪為「K型經濟」的下行端。另一頭，馨傳不動產的何世昌拿 7 月預售屋成交量僅 3,000 多戶、距離 6,000 戶的安全水位還有約四成差距當依據，認為今年底前預售量能回到 5,000 戶就算樂觀了。信義房屋專案經理曾敬德說對換屋族跟預售屋交屋族群確有幫助，但房價向上反映的空間仍相對有限。</p><p>這次調整改的是誰被允許背更多債。至於誰買得起房，一格都沒動。而被允許的那群人，按定義已經有一戶。</p><p>真正奇怪的是時間點。同一場會議，央行把今年 GDP 成長率預測上修到 11.48%。在自己預測經濟會長得很好的那一刻放寬槓桿上限，這個順序有意思。槓桿限制最有用的時候，正好是所有人都覺得不需要它的時候；等到大家都覺得需要了，該加的槓桿早就加完了。</p><p>所以我站的位置是這樣。我不預測房價會漲還是會跌，那個我不知道，也沒有人知道。我確定的只是風險部位換了方向：管制放寬之後，新增的那段借貸風險，從銀行的限額管理挪進了個別家庭的三十年還款期裡。誰承擔下檔，換人了。</p><h2 id="反過來想，我錯在哪"><a href="#反過來想，我錯在哪" class="headerlink" title="反過來想，我錯在哪"></a>反過來想，我錯在哪</h2><p>有一個數字能推翻我上面整段話：新增的第 2 戶貸款裡面，有多少筆同時伴隨第 1 戶的清償。我沒有查到它公開在什麼地方。</p><p>換屋的動作是賣一買一。如果多出來的那 250 萬額度，真的都被那些賣掉舊屋、清掉舊貸款的人拿走，那整個系統的槓桿不但沒增加，還可能是下降的，只是換了個位置掛著。這正是主張「影響有限」那一派在講的事，而且他們手上有牌：第 2 戶仍然禁止寬限期，第 3 戶以上、高價住宅、法人維持 3 成，其他主要信用管制也沒有全面鬆綁。如果這幾道限制確實擋住了投機需求，新增的額度就只會流向自住換屋。</p><p>所以我分不出來現在是哪一種。上面那段話到這裡為止只是一個假設。</p><h2 id="這套算術問的問題換了"><a href="#這套算術問的問題換了" class="headerlink" title="這套算術問的問題換了"></a>這套算術問的問題換了</h2><p>兩年下來真正變掉的不是那個數字，是這套算術在問的問題。</p><p>2024 年那套問的是「我拿不拿得出這筆錢」。答案在自己的戶頭裡，多存一年就多一點，進度由你控制。</p><p>2026 年這套問的是「銀行願意借我多少」。答案在別人手上，而且那個答案每一季開一次會重新決定。</p><p>一個家庭把未來三十年的現金流押進去的時候，它押的是一個自己完全無法影響的政策週期。成數是會變的數字，兩年已經變了三次。簽下去的那三十年不會跟著變。</p><hr><p><strong>資料來源</strong></p><ul><li><a href="https://newtalk.tw/news/view/2026-09-17/1060425">央行理監事會》利率連10凍！今年GDP上修至11.48% 房市管制再鬆綁「二房貸款升至7成」－Newtalk新聞</a>（9&#x2F;17 決議、利率連 10 凍、GDP 預測上修 11.48%）</li><li><a href="https://udn.com/news/story/7238/9761189">央行決議利率持不變「連10凍」 鬆綁房市管制措施－聯合新聞網</a>（第 2 戶最高成數由 6 成提高至 7 成）</li><li><a href="https://www.cbc.gov.tw/tw/cp-302-184087-e72fa-1.html">中央銀行理監事聯席會議決議新聞稿－央行官網</a>（重貼現率 2%、擔保放款融通利率 2.375%、短期融通利率 4.25%）</li><li><a href="https://www.ctee.com.tw/news/20260917701767-430601">換屋族群歡呼！第二戶成數回升7成 購屋更有底氣了－工商時報</a>（2,500 萬房屋例、自備款少準備 250 萬、不動產貸款占總放款比率 37.61%→35.56%→34.44%）</li><li><a href="https://tw.news.yahoo.com/9-18-%E8%B5%B7%E5%A4%AE%E8%A1%8C%E6%94%BE%E5%AF%AC%E7%AC%AC%E4%BA%8C%E6%88%B6%E6%88%BF%E8%B2%B8-%E5%B0%88%E5%AE%B6-%E6%8F%9B%E5%B1%8B%E6%97%8F%E5%A4%9A-025623134.html">9&#x2F;18起央行放寬第二戶房貸，專家：換屋族多一成資金、房價反映有限－Yahoo新聞</a>（信義房屋曾敬德的說法、9&#x2F;18 生效）</li><li><a href="https://money.udn.com/money/story/5621/9762262">央行真鬆綁？李同榮：政策軟中帶硬 房價不會反彈－經濟日報</a>（第 2 戶無寬限期、第 3 戶以上與高價住宅、法人維持 3 成）</li><li><a href="https://newtalk.tw/news/view/2026-09-18/1060569">央行房貸鬆一成！房市要回春了嗎？－Newtalk新聞</a>（馨傳不動產何世昌的預售屋成交量數字）</li><li><a href="https://www.ctee.com.tw/news/20260902700118-430601">學者籲第二戶房貸鬆綁至7成－工商時報</a>（莊孟翰的 K 型經濟與「管制太保守」，發表於 9&#x2F;2，早於決議公布）</li><li><a href="https://udn.com/news/story/6656/9761540">央行連10凍、鬆綁第二戶房貸成數 李彥秀：體感通膨與居住將是焦點－聯合新聞網</a>（李彥秀「體感通膨」逐字）</li><li><a href="https://rti.org.tw/news?pid=230755&uid=3">8月CPI年增2.04％ 主計總處估9月漲幅再擴大－中央廣播電臺</a>（8 月 CPI 年增 2.04%、核心 2.3%、前 8 月平均 1.84%）</li><li><a href="https://money.udn.com/money/story/10869/9742165">8月外食費衝3.17% 9月CPI估連5月突破通膨警戒線－經濟日報</a>（外食費 3.17%、蔡秀慧科長的「8 個月來最大漲幅」）</li><li><a href="https://ncusec.ncu.edu.tw/news/press_content.php?P_ID=42254">租屋族好苦 主計總處：8月房租、外食續漲－中央大學新聞網</a>（房租年增 1.69%、每月消費 8 萬元家庭的 424 元與 273 元試算）</li><li><a href="https://house.udn.com/house/story/123591/9624677">台北房價所得比衝「世界第一」！14.6倍超車香港－udn房地產</a>（台北 14.6 倍與各城市對照）</li><li><a href="https://tw.stock.yahoo.com/news/%E7%AC%AC%E4%B8%83%E6%B3%A2%E4%BF%A1%E7%94%A8%E7%AE%A1%E5%88%B6%E5%85%A9%E5%B9%B4%E6%99%82%E9%96%93%E8%BB%B8-%E6%AF%8F%E5%AD%A3%E5%A4%AE%E8%A1%8C%E6%B1%BA%E7%AD%96%E8%88%87%E6%88%BF%E5%B8%82%E5%9B%9B%E6%96%B9%E6%85%8B%E5%BA%A6%E4%B8%80%E6%AC%A1%E7%9C%8B-033900001.html">第七波信用管制兩年時間軸 每季央行決策與房市四方態度一次看－Yahoo新聞</a>（2024-09-20 第七波第 2 戶限貸 5 成、2026-03-20 鬆綁至 6 成）</li></ul>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/19/%E7%AC%AC%E4%BA%8C%E6%88%B6%E8%87%AA%E5%82%99%E6%AC%BE%E5%B0%91%E4%BA%86250%E8%90%AC-%E7%AE%97%E5%BE%97%E5%8B%95%E9%80%99%E7%AD%86%E7%9A%84%E9%82%84%E6%98%AF%E5%90%8C%E4%B8%80%E7%BE%A4%E4%BA%BA/</id>
    <link href="https://blog.longhopick.com/2026/09/19/%E7%AC%AC%E4%BA%8C%E6%88%B6%E8%87%AA%E5%82%99%E6%AC%BE%E5%B0%91%E4%BA%86250%E8%90%AC-%E7%AE%97%E5%BE%97%E5%8B%95%E9%80%99%E7%AD%86%E7%9A%84%E9%82%84%E6%98%AF%E5%90%8C%E4%B8%80%E7%BE%A4%E4%BA%BA/"/>
    <published>2026-09-19T13:00:00.000Z</published>
    <summary>央行把第 2 戶房貸成數鬆到 7 成，2,500 萬的房子自備款少 250 萬。但這套算術的第一個條件，兩年來一格都沒動過。</summary>
    <title>第二戶自備款少了 250 萬，算得動這筆的還是同一群人</title>
    <updated>2026-09-19T13:11:40.479Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="AI與科技新聞" scheme="https://blog.longhopick.com/categories/AI%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E/"/>
    <category term="Anthropic" scheme="https://blog.longhopick.com/tags/Anthropic/"/>
    <category term="AI與科技新聞" scheme="https://blog.longhopick.com/tags/AI%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E/"/>
    <category term="AI 法規" scheme="https://blog.longhopick.com/tags/AI-%E6%B3%95%E8%A6%8F/"/>
    <category term="AI 安全" scheme="https://blog.longhopick.com/tags/AI-%E5%AE%89%E5%85%A8/"/>
    <category term="AI 產業" scheme="https://blog.longhopick.com/tags/AI-%E7%94%A2%E6%A5%AD/"/>
    <content>
      <![CDATA[<p>有人要搬進 Anthropic 上班了。存取權限跟正職員工差不多，工作內容是紅隊測試、對齊評估、安全防護測試，也就是找出這家公司的模型哪裡會出事。這筆錢由 Anthropic 出。</p><p>這件事宣布的同一天，另外兩邊也在處理同一個問題：誰有資格查 AI 公司，查完之後誰要為結果負責。舊金山的聯邦地方法院收到一份集體訴訟狀，告的正是「大家講好要放慢腳步」這件事；加州州長則簽了一道行政命令，不等業界自己想清楚。三邊的答案彼此不相容。</p><h2 id="一、出錢請人搬進來查自己"><a href="#一、出錢請人搬進來查自己" class="headerlink" title="一、出錢請人搬進來查自己"></a>一、出錢請人搬進來查自己</h2><p>Anthropic 在 9 月 18 日宣布跟 Accenture 合作，實際執行的是 Accenture 旗下專做 AI 的 Faculty。Faculty 帶隊的團隊會以「類似員工的存取權限」進駐 Anthropic 內部，做模型評估、紅隊測試、對齊評估與安全防護測試。官方的用詞是 embedded evaluators，內嵌評估員。</p><p>錢的部分要看清楚口徑。Anthropic 與 Accenture 各自承諾未來五年投入至少 10 億美元來建立這個領域的能力。是各自，不是合計；是承諾額，不是已經到位的錢。而 Faculty 這部分的工作，是 Anthropic 直接出錢資助的。</p><p>公告裡有一句寫得很坦白：「independent embedded evaluators do not reduce our accountability, but help to make it more verifiable」。獨立的內嵌評估員不會減輕我們的責任，而是讓責任變得更可查證。</p><p>可查證這三個字，正好是整件事最脆弱的地方。稽核這一行有個老問題，任何一家會計師事務所都懂：委任你的人就是被你查的人，費用也是他付的。這不必然導致造假，多數時候不會。它導致的是更細微的東西：查什麼、不查什麼、報告怎麼寫、什麼時候發，這些選擇裡的每一個，都存在一個對付錢那方比較舒服的方向。</p><p>Accenture 董事長暨執行長 Julie Sweet 的說法是：「Safety requires both deep technical expertise and a clear understanding of how AI is used in the real world.」Faculty CEO、同時也是 Accenture CTO 的 Marc Warner 講的則是 Faculty 的理念，AI 應該「safe by design, not safe by accident」。</p><p>官方明講這不是獨家安排。Anthropic 正在跟 METR 等非營利評估組織洽談類似的試點，用的是那些組織自己的資金，未來幾週還會宣布其他評估機構；Accenture 那邊也會跟其他 AI 開發商做同樣的生意。</p><p>後面這半句最值得記住。評估這件事現在是一門生意，而且是一門對客戶數量有胃口的生意。</p><p>我的立場：這個安排目前不算獨立，它算的是「比沒有好」。會讓我改變想法的條件很具體：METR 那種用自己的錢做的試點真的落地，而且評估結果有一條不需要經過被評估方同意就能對外發布的路徑。只要發布權還握在付錢那一方手上，可查證就只是可查證給自己看。</p><blockquote><p>原文來源：<a href="https://www.anthropic.com/news/accenture-embedded-evaluation">Anthropic，2026-09-18</a> ／ <a href="https://techcrunch.com/2026/09/18/anthropics-first-embedded-evaluator-is-accenture/">TechCrunch，2026-09-18</a></p></blockquote><h2 id="二、同一天，有人告這件事是圍標"><a href="#二、同一天，有人告這件事是圍標" class="headerlink" title="二、同一天，有人告這件事是圍標"></a>二、同一天，有人告這件事是圍標</h2><p>這一則跟直覺打架。</p><p>9 月 18 日，四名消費者在美國加州北區聯邦地方法院舊金山分院提起集體訴訟，被告是 Anthropic PBC、OpenAI OpCo LLC、SpaceXAI LLC（即原本的 xAI，SpaceX 今年稍早併購）與 Google LLC。原告是 Charles Buist、Nick Spetsas（佛羅里達州）、Cheyenne Hunt 與 Christine Bullock（加州），代表一個擬制的全國集體。法律依據是《謝爾曼法》第一條，禁止限制貿易的合意。</p><p>告的是什麼？告這四家講好要放慢腳步。</p><p>訴狀的時序這樣鋪：今年 7 月起，Anthropic、OpenAI、Google 的代表私下組成工作小組討論產業標準機構；9 月 12 日 Dario Amodei 發表文章，呼籲產業協調放慢前沿模型的開發腳步；幾個小時之內，Elon Musk、Sam Altman、Demis Hassabis 相繼公開表態附和。原告主張這一串不是各自獨立的安全決策，是合意限制產出。</p><p>訴狀的核心句子是：「an agreement among rivals to reduce the quality of their products and the rate at which those products improve is an agreement to restrict output」。競爭對手之間達成協議，降低自家產品的品質與改善速度，這就是一份限制產出的協議。</p><p>界線很細，而訴狀自己劃了：它沒有挑戰「公司獨立決定放慢開發、導入安全測試」這件事本身，主張的是競爭對手不能聯合起來決定彼此的產品開發速度。寫成「消費者告 AI 公司太安全」會完全走味。</p><p>原告 Cheyenne Hunt 在社群媒體上的說法更白：「I’m suing Anthropic, OpenAI, X, and Google because we deserve real AI safety standards, not shady deals cut by an unaccountable cartel of billionaires in a back room.」她另外補的一句，我認為是整份主張裡最有力的：「If these companies actually believe their products could risk human extinction, how to move forward is not a decision four CEOs get to make behind closed doors.」如果這些公司真的相信自家產品可能帶來人類滅絕的風險，那接下來要怎麼走，就不是四個執行長關起門來可以決定的事。</p><p>同一組動作，兩種完全相反的法律解讀。Anthropic 花錢請人進來查自己，在公告的框架裡這叫「讓責任更可查證」；放進訴狀的框架，產業一起建立標準、一起放慢、一起去找同一批評估機構，每一步都可以被當成合意的證據。Accenture 明講會跟其他 AI 開發商做一樣的生意，這句話在商業上是擴張，在反壟斷的顯微鏡底下是一條資訊交換的管道。</p><p>下檔風險落在哪一邊，答案跟表面看到的相反。如果原告打贏，這些公司不會因此變得更安全，只會變成以後只能各自為政地談安全，不能再公開協調。對「安全」本身不見得是好事。如果打輸或和解，代價落在被告的帳上，賠償金加上行為限制，而那是可以編列預算的東西。</p><p>四家公司截至查證當下都沒有公開回應。這是民事訴狀的指控，還沒有經過法院認定。</p><blockquote><p>原文來源：<a href="https://www.unite.ai/consumers-sue-anthropic-openai-spacexai-and-google-over-alleged-ai-pact/">Unite.AI，2026-09-18</a> ／ <a href="https://www.tribuneindia.com/news/business/anthropic-openai-spacexai-google-face-federal-antitrust-lawsuit-over-calls-to-slowdown-ai-development">The Tribune，2026-09-18</a></p></blockquote><h2 id="三、加州不等了，而它做的不是立新法"><a href="#三、加州不等了，而它做的不是立新法" class="headerlink" title="三、加州不等了，而它做的不是立新法"></a>三、加州不等了，而它做的不是立新法</h2><p>同樣是 9 月 18 日，加州州長 Gavin Newsom 簽了一道行政命令。這道命令沒有創造新法，它做的是加速執行兩部已經簽過的州法：SB 813 建立獨立驗證機構評估 AI 系統安全與風險的框架，AB 1405 設立 AI 稽核員的州級登記制度。原訂時程往前提一年。</p><div class="note info flat"><p>這兩部法案本身在 9 月初就已經簽署完成。這次的行政命令是把執行時程往前拉，並且加碼要求研議新東西，不是加州剛通過一部新法。</p></div><p>加碼的部分是一組專家小組，兩個月內要提出建議，具體評估兩件事：前沿 AI 公司是否應該讓獨立評估員進駐，以及最先進的模型是否該有緊急關閉機制（kill switch）。</p><p>第一項就是本文第一則正在發生的事。差別在於，Anthropic 那邊是自己找人、自己付錢；加州問的是要不要規定。</p><p>Newsom 的原話：「We’re not waiting to act – we’re going to speed up our work on substantial and responsible AI oversight before it’s too late.」以及「California has already built a national model, and our policy should be the national baseline.」州長辦公室把聯邦政府的不作為形容成 asleep at the wheel，Newsom 自己的說法是：「The federal government’s abject failure to create any form of meaningful AI oversight or accountability should alarm every American.」</p><p>值得記一筆的是，Newsom 本人在 2024 年否決過含 kill switch 條款的 SB 1047。如今同一個議題又回來了，但走的路徑換了：不是再打一輪立法攻防，而是拿既有法律的執行時程來施力。這個選擇本身就是判斷。立法會被擋，行政命令的成本低得多，可撤銷性也高得多，而可撤銷性這一格，換個州長就會知道它有多重要。</p><p>命令另外把 Hugging Face 攻擊事件正式納入「重大安全事件」的定義範疇，州長辦公室用的詞是 loss-of-control incidents——失控事件。把這一類事件寫進行政命令的定義條款，訊號強度不低。</p><blockquote><p>原文來源：<a href="https://www.gov.ca.gov/2026/09/18/governor-newsom-issues-executive-order-to-accelerate-independent-oversight-and-advance-the-creation-of-an-ai-kill-switch/">加州州長辦公室，2026-09-18</a> ／ <a href="https://www.nbcnews.com/politics/elections/california-gavin-newsom-ai-order-safety-regulations-kill-switch-rcna598570">NBC News</a></p></blockquote><h2 id="四、鏡頭轉回台灣：11-48-是預測，13-72-是已經發生的"><a href="#四、鏡頭轉回台灣：11-48-是預測，13-72-是已經發生的" class="headerlink" title="四、鏡頭轉回台灣：11.48% 是預測，13.72% 是已經發生的"></a>四、鏡頭轉回台灣：11.48% 是預測，13.72% 是已經發生的</h2><p>中央銀行 9 月 17 日理監事會後公布最新經濟預測，中央社與 TechNews 在 9 月 18 日報導。標題數字是 2026 年經濟成長率大幅上修到 11.48%，理由是 AI 需求超乎預期強勁，拉動出口與投資雙引擎，內需也回溫。</p><p>這一則的數字很容易讀錯，因為三個數字的口徑完全不同。</p><table><thead><tr><th>數字</th><th>是什麼</th><th>口徑</th></tr></thead><tbody><tr><td>11.48%</td><td>2026 全年經濟成長率</td><td><strong>預測值</strong>，央行 9&#x2F;17 公布</td></tr><tr><td>13.72%</td><td>2026 上半年經濟成長率</td><td><strong>實績</strong>，官方稱創 50 年最強</td></tr><tr><td>0.16 個百分點</td><td>平均電價與資訊處理設備價格對 CPI 年增率的合計貢獻</td><td>統計期間為 1 至 8 月，是貢獻度，不是 CPI 本身</td></tr></tbody></table><p>央行對通膨的判斷分兩段講。短期，那 0.16 個百分點顯示 AI 通膨對台灣 CPI 的影響尚屬可控；長期，原話是「AI應用成熟將可提升生產效率，增加商品與服務供給，降低單位勞動成本，有助降低長期通膨壓力」。</p><p>短期那半句的立足點值得留意。0.16 只計入已經發生的 1 到 8 月，下半年資料中心用電負載會不會再往上、電價會不會調整，都不在這個數字裡面。用過去式的資料去支撐「可控」的判斷，在資料本身還在長的期間，是一個會過期的結論。</p><p>至於 11.48%，它的成分高度集中在半導體與 AI 供應鏈的出口。這個預測值不是錯的，但它是整組數字裡最先會鬆動的那一個。</p><blockquote><p>原文來源：<a href="https://technews.tw/2026/09/18/ai-inflation-looming-central-bank-short-term-controllable-long-term-productivity-gains-alleviate-pressure/">TechNews，2026-09-18</a>（原始資料來源為中央社報導）</p></blockquote><h2 id="五、沒有人證實，但盤前一度漲了-6-3"><a href="#五、沒有人證實，但盤前一度漲了-6-3" class="headerlink" title="五、沒有人證實，但盤前一度漲了 6.3%"></a>五、沒有人證實，但盤前一度漲了 6.3%</h2><p>多家科技媒體 9 月 18 日報導，AMD 據稱在 9 月 17 日通知合作夥伴，因為台積電晶圓成本調漲，AI 加速卡、Radeon 繪圖處理器與主機板晶片組將在 2026 年第四季調漲約 10%。Ryzen CPU 是否調漲未確認。</p><div class="note warning flat"><p>這整條消息鏈的源頭是一份未經證實的報告。Wccftech 的報導引述的是 ChannelGate，一個以流出供應鏈消息聞名的微信帳號；AMD 與台積電官方都沒有證實。多篇報導描述那個 10% 時一律用 roughly 或 about，沒有任何一篇給出品項價格表或精確拆分。</p></div><p>確定發生的只有一件事：消息傳出後，AMD 股價盤前一度上漲最高 6.3%。</p><p>一則沒有人證實的傳聞，已經被完整地定價了。這不是市場失靈，這是市場在做它該做的事：它不等確認，它對機率下注。成本要上漲的消息傳出來，股價漲了，市場的讀法是這波成本轉嫁得出去。至於轉嫁的終點是誰，沒有任何一份報導回答。</p><blockquote><p>原文來源：<a href="https://wccftech.com/amd-notifies-partners-of-10-price-hike/">Wccftech，2026-09-18</a> ／ <a href="https://www.tomshardware.com/tech-industry/semiconductors/tsmc-is-reportedly-hiking-prices-for-all-advanced-nodes-accounting-for-74-percent-of-the-companys-wafer-business-nvidia-amd-apple-qualcomm-and-others-will-face-higher-wafer-costs">Tom’s Hardware，2026-09-18</a></p></blockquote><hr><p>自願承諾真正的問題，從來不是沒有約束力。</p><p>約束力它有，而且來得太早。一句 9 月 12 日的公開呼籲，六天後變成一份聯邦法院的訴狀；一份沒有署名來源的供應鏈消息，傳出後就變成盤前一度 6.3% 的漲幅；一組建立在 1 到 8 月資料上的「可控」判斷，會被寫進下半年的政策與投資前提。這些東西在被任何人查證之前，就已經各自產生了後果。</p><p>查證機制還在後面。內嵌評估員這個月才有第一個案例，加州的稽核員登記就算提前一年也還沒上路，METR 那種用自己的錢做的試點還在洽談階段。</p><p>三邊對「誰來查」的答案互斥，這件事本身就值得記一筆。Anthropic 的版本是花錢請人進來看；訴狀的版本是你們連一起請人都不行；加州的版本是這件事根本不該由你們決定。三種講法沒辦法同時成立，而且沒有哪一方需要等另外兩方點頭才能繼續做自己那一套。</p><p>所以接下來會同時看到更多的內嵌評估員、更多的反壟斷主張、更多的州級規定。這三條線互相打架，但沒有哪一條會因為另外兩條而停下來。</p>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/19/AI-%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E%E6%91%98%E8%A6%81-20260919/</id>
    <link href="https://blog.longhopick.com/2026/09/19/AI-%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E%E6%91%98%E8%A6%81-20260919/"/>
    <published>2026-09-19T10:00:00.000Z</published>
    <summary>出錢請人進來查自己、告「一起放慢」是圍標、加州要求關機鍵，還有一則沒人證實、盤前一度漲了 6.3% 的傳聞。</summary>
    <title>AI 與科技新聞摘要 - 2026/09/19</title>
    <updated>2026-09-19T13:47:12.325Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="AI Agent" scheme="https://blog.longhopick.com/categories/AI-Agent/"/>
    <category term="AI 開發工具" scheme="https://blog.longhopick.com/tags/AI-%E9%96%8B%E7%99%BC%E5%B7%A5%E5%85%B7/"/>
    <category term="AI Agent" scheme="https://blog.longhopick.com/tags/AI-Agent/"/>
    <category term="開源" scheme="https://blog.longhopick.com/tags/%E9%96%8B%E6%BA%90/"/>
    <category term="TypeScript" scheme="https://blog.longhopick.com/tags/TypeScript/"/>
    <content>
      <![CDATA[<p>兩套測試同時全綠，可以是「這份規格從來沒被測過」的證據。</p><p>AG-UI 是一個把 agent 接進前端應用的協定，底下有兩套 client，一套 TypeScript、一套 .NET。兩邊的測試都過。可是兩邊對同一件事的處置是相反的：串流裡跑出一個 client 不認識的東西，該丟掉、該原樣傳到應用層、還是該讓整條 run 失敗，兩邊的答案不一樣。</p><p>測試沒抓到。因為測試根本不是為了抓這件事寫的。</p><blockquote><p>They exist because the rules in the specification were, until now, only ever tested against the implementation that happened to hold them — which is how the two clients ended up disagreeing about what to do with something they do not recognise, with both test suites green.</p></blockquote><p>這段話就寫在 <code>spec/1.0/conformance/README.md</code> 的開頭，解釋這整批東西為什麼會存在（2026-09-19 查 main 分支）。翻成人話：規格裡的規則，在那之前只被「剛好實作了它的那個實作」測過。</p><p>考卷跟答案是同一個人寫的。你照自己的實作寫測試，那份測試在問的是「我這次有沒有照我上次做的那樣做」，跟規格怎麼寫沒有關係。兩個人各寫各的，各自都能考一百分，直到有人把兩份答案卷疊在一起。</p><h2 id="同一批-bytes，兩條-lane"><a href="#同一批-bytes，兩條-lane" class="headerlink" title="同一批 bytes，兩條 lane"></a>同一批 bytes，兩條 lane</h2><p>補法很土。<code>spec/1.0/conformance/streams/</code> 底下放了 68 個 JSON 檔（我用 <code>gh api</code> 列目錄數的，68 個 <code>.json</code> 加一份 <code>MANIFEST.txt</code>，2026-09-19 的 main 分支）。一個檔案就是一條事件串流，外加「規格要求任何 client 消費完它之後應該長什麼樣」。</p><p>同一批檔案在兩條 lane 上跑。TypeScript 那條用 aimock 把它當成真的 HTTP SSE frame 餵進 <code>HttpAgent</code>，.NET 那條把同樣那串 bytes 送過真的 SSE formatter 與 event converter。</p><p>關鍵在「同一批」。不是兩邊各自寫一份意思差不多的測試，是同一個位元組序列進去，比對兩邊吐出來的東西。</p><div class="note warning flat"><p>下面所有關於行為的敘述，來源都是這個 repo 裡的 README、fixture JSON 與 proto 檔的逐字閱讀。我沒有跑過這 68 個 fixture，沒有裝過任何一套 AG-UI SDK，也沒有送出過一次事件串流。</p></div><h2 id="一個不會失敗的測試，比沒有測試更糟"><a href="#一個不會失敗的測試，比沒有測試更糟" class="headerlink" title="一個不會失敗的測試，比沒有測試更糟"></a>一個不會失敗的測試，比沒有測試更糟</h2><p>每個 fixture 有一個必填欄位叫 <code>kill</code>。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  &quot;name&quot;: &quot;unknown-event-dropped&quot;,        // must equal the file name</span><br><span class="line">  &quot;area&quot;: &quot;processing&quot;,                    // groups the test output</span><br><span class="line">  &quot;description&quot;: &quot;one line: what this proves&quot;,</span><br><span class="line">  &quot;specPage&quot;: &quot;/spec/1.0/basic/processing&quot;,</span><br><span class="line">  &quot;kill&quot;: &quot;the one-line change to the implementation that must make this fail&quot;,</span><br><span class="line"></span><br><span class="line">  &quot;stream&quot;: [ /* raw event objects, sent verbatim */ ],</span><br><span class="line">  &quot;expect&quot;: &#123; /* … */ &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>README 對這個欄位的說明只有三句：</p><blockquote><p>Name the single change to the implementation that must make this fixture fail. It is a required field because a fixture that cannot fail is worse than no fixture — it reads as coverage while proving nothing. Before you commit one, make that change locally and watch it go red.</p></blockquote><p>最後一句才是整件事的重量所在。提交之前，你要真的在本機把那一行改下去，親眼看它變紅。</p><p>我的立場是這一條比「再多寫十個測試」值錢得多，而且便宜得多。值錢的地方不在測試本身，在你寫 <code>kill</code> 的那五分鐘裡會發生什麼事。</p><p>看 <code>unknown-event-dropped</code> 這個 fixture 的 <code>kill</code> 逐字寫了什麼：</p><blockquote><p>return <code>of(event)</code> instead of <code>EMPTY</code> from the <code>!isRecognizedEvent</code> branch in enforceEvents — the warning is still emitted and the run still completes, so <code>outcome</code>, <code>warnings</code>, <code>messageCount</code> and <code>messages</code> all stay green and only <code>eventTypesAbsent</code>&#x2F;<code>eventTypes</code> catch it: FUTURE_EVENT reaches application code.</p></blockquote><p>它不只寫了怎麼弄壞，還寫明了弄壞之後<strong>哪幾個斷言照樣是綠的</strong>。<code>outcome</code> 綠，<code>warnings</code> 綠，<code>messageCount</code> 綠，<code>messages</code> 也綠。四個欄位全部無感。只有 <code>eventTypes</code> 跟 <code>eventTypesAbsent</code> 抓得到，因為那個叫 <code>FUTURE_EVENT</code>、不該送到應用層的東西真的送到了。</p><p>順帶補個座標：protobuf 那邊的 <code>EventType</code> enum 目前有 31 個值，編號 0 到 30，而且是 append-only 的。<code>FUTURE_EVENT</code> 不在裡面，它是 fixture 故意捏出來、模擬「未來版本才有的事件」的東西。</p><p>寫 <code>kill</code> 的過程，就是在逼你發現「我以為在測的那幾個欄位其實測不到」。測試是綠的，沒有人會去看它為什麼綠，也就沒有別的機制會逼你走這一遭。</p><p>什麼情況會讓我收回上面那句：<code>kill</code> 要求你指得出「實作裡的哪一行」。如果那個測試斷言的對象根本不在你的程式碼裡，例如打第三方 API、讀環境餵進來的資料，你寫不出那一行，硬填就變成造句。那種測試該留著，但不要假裝它有 <code>kill</code>。</p><h2 id="fixture-紅了，不一定代表誰不合規"><a href="#fixture-紅了，不一定代表誰不合規" class="headerlink" title="fixture 紅了，不一定代表誰不合規"></a>fixture 紅了，不一定代表誰不合規</h2><blockquote><p>So a fixture failing does not always mean a client is non-conforming — it means a client changed. That is the point of a regression suite, and it is why <code>kill</code> names a change rather than a rule.</p></blockquote><p>這句把整份語料庫的定位講死了。它是第一方 client 的回歸測試，不是一張合規認證。</p><p>它同時斷言兩種性質不同的東西。一種是規格明文的 MUST 與 MUST NOT，違反了那個 client 就是不合規。另一種是規格留白的地方「這兩套 client 選擇怎麼做」：規格說 consumer SHOULD 對自己 strip 掉的東西發警告，他們的 client 會警告，於是 fixture 把這個選擇釘住。</p><p>規格對「乾淨的串流要不要保持安靜」則是什麼都沒說，<code>conformant-run-is-quiet</code> 照樣要求它安靜。README 給的理由很實在：一個開始對合法流量發警告的容忍度 regression，沒有別的守門抓得到。那個 fixture 的 <code>kill</code> 只有一句話，<code>make any stage warn about legal traffic — the guard no other fixture provides</code>。</p><h2 id="一個斷言「與規格相反」的測試"><a href="#一個斷言「與規格相反」的測試" class="headerlink" title="一個斷言「與規格相反」的測試"></a>一個斷言「與規格相反」的測試</h2><p><code>unknown-enum-value-role-fatal</code>。</p><p>TypeScript 那條 lane 把封閉字串集合當成 leaf 在檢查，所以集合外的成員會讓整條 run 直接 fatal。規格要的是把它 strip 掉。兩邊對不起來，而他們選擇把<strong>現狀</strong>釘進測試裡，沒有釘規格。</p><p>這個 fixture 的 <code>description</code> 開頭就是大寫的 ADMITTED GAP：</p><blockquote><p>ADMITTED GAP: an unrecognised member of a closed string set — a message role — is fatal today, where the specification says it should be stripped; this pins the reference implementation’s actual behaviour so the divergence cannot change unnoticed</p></blockquote><p>README 解釋為什麼要這樣搞：</p><blockquote><p>It asserts the opposite of the rule, on purpose, so that closing the gap is a deliberate act rather than a silent one.</p></blockquote><p>補洞因此變成一個有人簽名的動作。你要修掉那個 gap，就得先讓這個測試變紅，然後主動走過去改它。</p><p>它的 <code>kill</code> 不是一句話，是一整段，語氣像在對未來某個要動這段程式碼的人講話：</p><blockquote><p>teach stripAgainst to treat a ZodEnum as a closed set and DROP a value outside it — which is the RIGHT fix, and it makes this fixture fail. That is deliberate: this fixture pins today’s gap, not the rule. Anyone landing that fix MUST update this fixture to expect a stripped <code>/role</code> with a warning AND delete the <code>&lt;Note&gt;</code> on docs&#x2F;spec&#x2F;1.0&#x2F;basic&#x2F;processing.mdx that admits the gap, in the same change. A silent ‘fix’ that leaves the Note in place is what this fixture exists to catch.</p></blockquote><p>一個把 Note 留在原地的「安靜修好」，正是這個測試存在要抓的東西。</p><p>同一段 <code>kill</code> 裡還記了一個已經踩過的坑。這個 fixture 早先的版本，串流結尾是訊息還開著，<code>RUN_FINISHED</code> 來的時候那則 message 沒被關掉。後果是這樣：就算有人真的把 role 改成 strip 掉，那條 run 還是會失敗，失敗在沒關的訊息上。fixture 繼續綠，綠的理由跟 enum 一點關係都沒有。</p><blockquote><p>(It used to end with the message still open, so stripping the role would have left the run failing anyway, on the open message, and this fixture would have gone on passing for a reason that has nothing to do with enums.)</p></blockquote><p>現在的版本把訊息開、填、關整套跑完，讓那個不認識的 role 變成唯一能弄壞這條 run 的東西。串流裡那個 role 的值是 <code>&quot;narrator&quot;</code>，而同一則訊息的內容逐字長這樣：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;TEXT_MESSAGE_CONTENT&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;messageId&quot;</span><span class="punctuation">:</span> <span class="string">&quot;m-unknown-role&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;delta&quot;</span><span class="punctuation">:</span> <span class="string">&quot;the role above is the only defect in this stream&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>測試資料自己把「這條串流唯一的缺陷在哪」寫在內容裡。</p><h2 id="空陣列不是「沒有警告」"><a href="#空陣列不是「沒有警告」" class="headerlink" title="空陣列不是「沒有警告」"></a>空陣列不是「沒有警告」</h2><p>插一個跟主線無關、但看了會冒冷汗的東西。</p><p>兩條 runner 都把 <code>warnings</code> 讀成「這幾個字串，每一個都要出現在某則警告裡」。所以 <code>&quot;warnings&quot;: []</code> 什麼都沒主張。它不代表「這條 lane 不准有警告」，它做的事情是把繼承下來的基準期望整個鬆開。</p><blockquote><p><strong><code>&quot;warnings&quot;: []</code> does not mean “no warnings”.</strong> … an empty list asserts nothing at all — it only <em>lifts</em> the base expectation.</p></blockquote><p>同一個陷阱適用於 <code>&quot;request&quot;: &#123;&#125;</code>，以及任何空的 subset：空物件匹配每一個物件。</p><p>搜尋框空著的時候，回來的不是零筆，是全部。斷言也一樣，條件寫空，符合的就是所有東西。真的要求安靜，欄位是 <code>noWarnings: true</code>。</p><p>還有兩條同族的規定。<code>outcome</code> 單獨不算一個斷言，因為每個 fixture 都有 <code>outcome</code>，而且幾乎都寫 <code>&quot;completed&quot;</code>，所以 corpus gate 要求每條 lane 至少要再有一個有效的 key。凡是某條 lane 的 <code>outcome</code> 解析成 <code>&quot;failed&quot;</code> 的，一定要配 <code>errorContains</code> 或 <code>runError</code>：光寫一個 <code>&quot;failed&quot;</code>，任何一種拒絕都能滿足它，包括跟這個 fixture 名字毫無關係的那種拒絕。</p><h2 id="怎麼證明一樣東西「不見了」"><a href="#怎麼證明一樣東西「不見了」" class="headerlink" title="怎麼證明一樣東西「不見了」"></a>怎麼證明一樣東西「不見了」</h2><p>subset 比對有個結構性的盲點，它表達不了缺席。<code>messages</code> 跟 <code>state</code> 都是 subset 比，你只能說「這幾個 key 要等於什麼」，說不了「這個 key 不准存在」。</p><p>他們的解法很漂亮：換一個錯的實作做不出來的形狀。</p><p>要證明第二個 <code>STATE_SNAPSHOT</code> 是整個取代而非合併，就讓那個 snapshot 是一個 root-level 的陣列，<code>[&quot;only-this&quot;]</code>。任何 merge 都做不出這個形狀。<code>state-snapshot-replaces</code> 的 <code>kill</code> 逐字是：</p><blockquote><p>make STATE_SNAPSHOT merge its snapshot into the current state (<code>state = &#123; ...state, ...snapshot &#125;</code>) instead of assigning it</p></blockquote><p>改成 merge，出來的會是物件不是陣列，斷言立刻紅。順帶還多證明了一件事，state 可以是任何 JSON 值，不必是物件。</p><p>要證明一件事沒發生，逐一排查永遠還差一個角落。反過來布置就簡單了：讓那件事只要發生過，就一定留下看得見的痕跡。封條是這樣用的，不必把房間翻一遍，看一眼封條還在不在。</p><p>同一招還有兩個變形。要證明 metadata 的 merge 不是遞迴的，給某個 key 一個陣列值然後改它的長度（<code>[&quot;one&quot;,&quot;two&quot;]</code> 換成 <code>[&quot;three&quot;]</code>），陣列是逐長度嚴格比對的，深層 merge 會紅。要證明一個 list 元素被丟掉了，就斷言整個陣列。</p><h2 id="數到一半，發現有東西根本沒在跑"><a href="#數到一半，發現有東西根本沒在跑" class="headerlink" title="數到一半，發現有東西根本沒在跑"></a>數到一半，發現有東西根本沒在跑</h2><p>這份語料庫存在的理由之一，README 寫得很白：規格說一方 MAY 為了舊 peer 做降版，他們出了幾個 era shim，而這件工作存在的部分原因就是不讓任何一個 shim 沒被測到。</p><blockquote><p>It says a party MAY downgrade for an older peer; ours ship four era shims, and this ticket exists partly so that none of them survives untested.</p></blockquote><p>四個。同一份 README 往下捲，Remaining version gates 那節寫的卻是三個，而且下一句直接把第四個劃掉：</p><blockquote><p>There are three version-gated compatibility shims: 0.0.39 downgrades content for old peers, 0.0.45 translates retired <code>THINKING_*</code> shapes, and 0.0.57 downgrades subagent events and attribution. Only the 0.0.39 and 0.0.57 gates can be tested here.</p><p>[…] There is no 0.0.47 era shim or gate.</p></blockquote><p><code>streams/</code> 底下以 <code>era-</code> 開頭的檔案有六個，其中四個的檔名帶舊版號（<code>0-0-39</code>、<code>0-0-45</code>、<code>0-0-47</code>、<code>0-0-57</code>），另外兩個是 <code>era-current-peer-*</code> 與 <code>era-pinned-peer-*</code>，檔名沒有版號。光數檔名會數出四個「長得像 shim 的東西」，但 <code>era-0-0-47-upgrades-binary-content</code> 對應的那個並不是 shim：舊的 binary content 在每一次對外的 run 都會被升級，跟 peer 的協定版本無關。那個 fixture 保留歷史檔名與 peer pin，做的是另一件事，檢查 payload 有沒有被完整保住。</p><p>剩下三個裡面還有一個更妙的。README 有一節的標題叫 A shim with no fixture。0.0.45 那個 shim 負責把退役的 <code>THINKING_*</code> 形狀翻譯成 reasoning，可是永遠開著的相容邊界也在做同一件事，而且跑得更內層，處理的是完全相同的五種事件、輸出也相同。出貨的 pipeline 裡，那個 shim 從來沒看過一個 <code>THINKING_*</code> 事件。</p><p>證據是 <code>kill</code> 欄位自己寫的：</p><blockquote><p>disable BOTH translators of the retired THINKING_* shapes … Either alone leaves this green: the boundary runs innermost and converts first, so the shim never sees these events in the shipped pipeline.</p></blockquote><p>單獨關掉任何一個，測試都還是綠的。兩個都關才會紅。</p><p>所以 <code>era-0-0-45-thinking-translated</code> 釘住的是「翻譯這件事」，不是那個 shim。shim 是跑不到的死碼。README 處理這件事的方式我很欣賞：它沒有假裝測到了，也沒有把 fixture 刪掉，而是把結論當成「一個關於 client 的發現」寫進語料庫自己的文件裡。</p><p>一開始只是想確認四個 shim 都有被測到。數完的結果是，其中一個從來就不是 shim，另一個是永遠跑不到的死碼。</p><h2 id="一份規格有沒有被測過，只有第二個實作看得出來"><a href="#一份規格有沒有被測過，只有第二個實作看得出來" class="headerlink" title="一份規格有沒有被測過，只有第二個實作看得出來"></a>一份規格有沒有被測過，只有第二個實作看得出來</h2><p>一個測試的價值不在它現在是綠的，在於你說得出哪一行改動會讓它變紅。說不出來，它就只是覆蓋率。</p><p>AG-UI 是寫到第二套 client 才發現自己踩在哪裡的。在那之前，規格的每一條規則看起來都有測試保護著，而且兩份測試確實都綠。</p><p>如果你手上也有一份只有一個實作的規格，這題你今天問不出答案——要等到有人照著它再寫一遍，才知道當初測的是規格，還是那個實作。而那一天到來的時候，兩邊的測試都會是綠的。</p>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/19/%E6%B8%AC%E8%A9%A6%E5%85%A8%E7%B6%A0-%E5%85%A9%E5%A5%97-client-%E5%8D%BB%E5%81%9A%E5%87%BA%E7%9B%B8%E5%8F%8D%E8%99%95%E7%BD%AE-AG-UI-%E9%82%A3%E5%80%8B%E5%8F%AB-kill-%E7%9A%84%E5%BF%85%E5%A1%AB%E6%AC%84%E4%BD%8D/</id>
    <link href="https://blog.longhopick.com/2026/09/19/%E6%B8%AC%E8%A9%A6%E5%85%A8%E7%B6%A0-%E5%85%A9%E5%A5%97-client-%E5%8D%BB%E5%81%9A%E5%87%BA%E7%9B%B8%E5%8F%8D%E8%99%95%E7%BD%AE-AG-UI-%E9%82%A3%E5%80%8B%E5%8F%AB-kill-%E7%9A%84%E5%BF%85%E5%A1%AB%E6%AC%84%E4%BD%8D/"/>
    <published>2026-09-19T01:00:00.000Z</published>
    <summary>兩套官方 client 的測試都是綠的，對「遇到不認識的東西怎麼辦」卻給出不同答案。AG-UI 用 68 個 fixture 補這個洞，每個 fixture 都必須先寫下哪一行改動會讓自己變紅。</summary>
    <title>測試全綠，兩套 client 卻做出相反處置：AG-UI 那個叫 kill 的必填欄位</title>
    <updated>2026-09-19T13:01:34.345Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="Claude Code" scheme="https://blog.longhopick.com/categories/Claude-Code/"/>
    <category term="Claude Code" scheme="https://blog.longhopick.com/tags/Claude-Code/"/>
    <category term="CLI" scheme="https://blog.longhopick.com/tags/CLI/"/>
    <category term="開發工具" scheme="https://blog.longhopick.com/tags/%E9%96%8B%E7%99%BC%E5%B7%A5%E5%85%B7/"/>
    <category term="教學" scheme="https://blog.longhopick.com/tags/%E6%95%99%E5%AD%B8/"/>
    <content>
      <![CDATA[<p>你在輸入框打一個 <code>@</code>，再打 <code>src/comp</code>，那零點幾秒裡，是誰去把那串檔案清單撈出來的？</p><p>設定參考答得很乾脆。內建的建議走的是 fast filesystem traversal，當場走訪檔案系統。沒有索引。</p><p>這件事拿抽屜來想最快。有人問你「那份合約在哪」，你從第一格抽屜開始翻，一格一格往下。抽屜只有五格的時候這是最快的做法，因為你連目錄都不用先做，做目錄的時間都夠你翻完了。抽屜長成一整面牆之後，同一招就開始拖。</p><p>官方文件自己把邊界寫出來了：a large monorepo may do better with project-specific indexing such as a pre-built file index。多大算大？文件一個檔案數、一個毫秒數都沒給，我也不補。</p><h2 id="把這件事接到你自己那份目錄上"><a href="#把這件事接到你自己那份目錄上" class="headerlink" title="把這件事接到你自己那份目錄上"></a>把這件事接到你自己那份目錄上</h2><p><code>fileSuggestion</code> 的型別小到一眼看完：一個物件，<code>type</code> 永遠是 <code>&quot;command&quot;</code>，<code>command</code> 是要跑的 shell 命令。預設 unset，不設就是內建那份。</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;fileSuggestion&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;command&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;command&quot;</span><span class="punctuation">:</span> <span class="string">&quot;~/.claude/file-suggestion.sh&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>契約也短。Claude Code 用跟 hooks 一樣的環境變數跑這條命令，<code>CLAUDE_PROJECT_DIR</code> 在裡面。stdin 餵進來一份 JSON，只有一個 <code>query</code> 欄位，裝的是使用者打到目前為止的字：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span><span class="attr">&quot;query&quot;</span><span class="punctuation">:</span> <span class="string">&quot;src/comp&quot;</span><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>你往 stdout 印換行分隔的檔案路徑。文件寫著兩個硬數字：Claude Code shows at most 15，以及 stops waiting after five seconds。</p><p>順帶一提，<code>@</code> 撈的已經不只是檔案。互動模式的文件寫著，在有跨 session 訊息的 session 裡，<code>@</code> 後面打至少一個字母，Claude Code 還會把這台機器上你其他還活著的 session 一起列出來，讓你叫 Claude 去跟選中的那個傳話（需 v2.1.232 或更新）。而 <code>fileSuggestion</code> 換掉的是其中檔案那一份，文件的寫法是 supply <code>@</code> file path autocomplete instead of the built-in file suggestion。</p><p>官方範例腳本是這樣：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line">query=$(<span class="built_in">cat</span> | jq -r <span class="string">&#x27;.query&#x27;</span>)</span><br><span class="line"><span class="comment"># Replace your-repo-file-index with your own file search command</span></span><br><span class="line">your-repo-file-index --query <span class="string">&quot;<span class="variable">$query</span>&quot;</span> | <span class="built_in">head</span> -20</span><br></pre></td></tr></table></figure><p><code>head -20</code> 配上 15 筆的顯示上限，多出來那 5 行不會有人看到。範例本身就先講了一件事：排序的責任整個在你的腳本身上。你吐 200 行，被看到的永遠是最前面那一截，Claude Code 不會幫你重排。</p><p>範例裡那個 <code>your-repo-file-index</code> 是佔位用的，實際塞什麼由你決定，而手邊現成的選項不少。<code>rg --files</code> 吐出全部再自己篩、<code>git ls-files</code> 只認被版控追蹤的檔案、公司內部那套 code index 開一個查詢端點出來，都接得上。選哪一個，決定的其實是「哪些檔案算數」這件事。<code>git ls-files</code> 天生就把 <code>node_modules</code> 跟建置產物擋在門外，而那些通常正是你打 <code>@</code> 的時候最不想看到的東西。</p><p>排序也一樣得自己想。<code>query</code> 遞給你的只是使用者打到一半的字串，要不要做模糊比對、要不要把最近改過的檔案往前拉、同名檔案誰優先，全在這支腳本裡決定。</p><p>契約短，代表沒得商量的地方也多。能回的只有路徑，沒有欄位可以夾帶說明文字、圖示或權重。輸入只有 <code>query</code>，沒有游標位置、沒有你剛才選過什麼、沒有這場對話在聊什麼。5 秒同樣是硬的：索引冷啟動要 8 秒，這條路就不通，得先讓它常駐或先預熱。至於 5 秒過了畫面上會是什麼，文件只寫到 stops waiting 就沒了，後面我不替它補。</p><h2 id="有一個開關不在你手上"><a href="#有一個開關不在你手上" class="headerlink" title="有一個開關不在你手上"></a>有一個開關不在你手上</h2><p>設定參考裡有一個小節，同時管 <code>statusLine</code>、<code>fileSuggestion</code> 跟 <code>subagentStatusLine</code>。三個鍵共用一套規則，而規則是兩個照順序做的決定。</p><p>第一道閘門是要不要整個關掉。managed settings 設了 <code>disableAllHooks</code>，關掉。這個資料夾沒被信任（跟設定檔裡的 hooks 走同一條工作區信任規則），也關掉。</p><p>第二道閘門是要不要收窄成只吃 managed settings。<code>allowManagedHooksOnly</code> 開著算一種；設定優先序跑完之後，<code>disableAllHooks</code> 在非 managed 的檔案裡是 <code>true</code> 算第二種；用 <code>--safe-mode</code> 把 Claude Code 起起來算第三種。</p><p>這裡有個容易讀漏的地方。<code>disableAllHooks</code> 在兩道閘門裡都出現了，位置不同，做的事也不同：放在 managed settings 裡，它讓整組功能整個關掉；放在非 managed 的檔案裡，它只是把來源收窄成 managed 那一份。<strong>同一個鍵名，換個檔案就換了語意。</strong></p><p>收窄之後，公司有部署 managed 的值，那份會跑。沒有的話，文件的原話是 it skips your value without warning。狀態列被停掉，<code>@</code> 的自動完成退回內建的檔案建議。</p><p>沒有紅字。沒有 exit code。沒有一行 log。</p><p>把這個失敗放回你桌前想一遍。你設好了 <code>fileSuggestion</code>，打 <code>@</code>，跳出一串檔案。清單有東西，只是不是你索引裡那一份。合理的下一步是懷疑自己：路徑寫錯？忘了 <code>chmod</code>？<code>jq</code> 沒吃到 stdin？於是你開始一行一行讀那支腳本。</p><p>而那支腳本從頭到尾沒有被呼叫過。</p><p>我猜大部分人第一個懷疑的會是自己的實作，不是設定層——這只是推論，我手上沒有任何使用行為的統計。但方向上說得通：報錯會把你推向錯誤訊息，沒報錯只會把你推向自己最近改過的東西。</p><p>所以順序要倒過來。<code>@</code> 沒照你的意思跑的時候，先驗閘門，再讀腳本。照文件列出的條件，要確認的是這幾件事：managed settings 裡有沒有 <code>allowManagedHooksOnly</code>、有沒有 <code>disableAllHooks</code>、這次 session 是不是用 <code>--safe-mode</code> 起來的、還有這個資料夾到底有沒有被信任過。全部清白了，才輪到你那支 shell script 上場。順序顛倒的代價很具體：你會在一支完全正確的腳本上，找一個根本不存在的錯。</p><h2 id="為什麼它選擇不出聲"><a href="#為什麼它選擇不出聲" class="headerlink" title="為什麼它選擇不出聲"></a>為什麼它選擇不出聲</h2><p>不警告看起來像疏忽，仔細看比較像刻意。</p><p>觸發這兩道閘門的情境有個共同點。公司政策、<code>--safe-mode</code>、沒被信任的資料夾，在這些情境下「不要跑使用者提供的命令」本身就是要的行為，不是意外。對一個預期之內的行為發警告，發久了就變成每次啟動都要滑過去的雜訊，而雜訊的代價是真正該看的那一則也一起被跳過。所以它閉嘴。</p><p>代價落在另一邊，而且不對稱。坐在終端機前面的人沒辦法從畫面上分辨「我的設定被政策收走了」跟「我自己寫壞了」。這兩件事的修法完全相反，一個要去敲 IT 的門，一個要去讀自己的 shell script。</p><p>我的看法是這個取捨選錯邊了。不主動跳警告可以接受，但總該有一個地方查得到現在的狀態，一行字就夠：你的 <code>fileSuggestion</code> 沒有在跑，原因是 X。什麼會讓我改口：只要有人指得出哪個指令已經印得出這一行，我這段就收回。我翻過的那幾個章節裡沒有看到。</p><p>那個換個檔案就換語意的鍵，名字也騙人。<code>disableAllHooks</code> 的說明是 Turn off hooks, any custom status line, and any custom file suggestion command。一個叫 All Hooks 的東西，順手關掉三個不是 hook 的設定。為了跑一份來路不明的 repo 而臨時加上它，狀態列跟 <code>@</code> 的自訂索引會一起消失（同一段文件還寫了 hooks 關著的時候 <code>/goal</code> 不能執行）。</p><h2 id="另一種「跑對了，你就是看不到」"><a href="#另一種「跑對了，你就是看不到」" class="headerlink" title="另一種「跑對了，你就是看不到」"></a>另一種「跑對了，你就是看不到」</h2><p>閘門那種是根本沒跑。還有一種是跑了、也對了，結果被壓在下面。</p><p>repo 的 CHANGELOG 在 2.1.275 這版寫著：Fixed @-mention file suggestions being buried below MCP resources when using a custom <code>fileSuggestion</code> command or typing <code>@.</code>&#x2F;<code>@./</code>。在那之前，只要你設了自訂命令，或只是打了 <code>@.</code>，你的檔案建議會排在 MCP resources 後面。腳本跑對了，清單第一頁還是看不到你的東西。</p><p>兩種失敗的成因差很遠，在畫面上卻長成同一句話：<code>@</code> 跳出來的不是我要的。截至 2026-09-18，最新版是 v2.1.276，排序那條至少已經修掉了，前提是你有更新。</p><div class="note warning flat"><p>這篇全部來自官方文件與 repo 的 CHANGELOG。我沒有實際建過那支 <code>file-suggestion.sh</code>、沒有在任何 repo 裡按 <code>@</code> 驗證過自訂建議，5 秒逾時跟 15 筆上限的實際表現我也沒跑過。另外，<code>fileSuggestion</code> 是哪一版加進來的，設定參考的那個章節沒有標注版本需求（同一頁其他設定有標），所以我這邊填不出版本號。</p></div><h2 id="同一個形狀，在別的地方也看得到"><a href="#同一個形狀，在別的地方也看得到" class="headerlink" title="同一個形狀，在別的地方也看得到"></a>同一個形狀，在別的地方也看得到</h2><p><code>statusLine</code> 跟 <code>subagentStatusLine</code> 跟 <code>fileSuggestion</code> 綁在同一組規則上。哪天狀態列突然變回預設的樣子，查的順序跟這篇一樣：先問有沒有人在上游把它收窄了，再回頭問自己的腳本。</p><p>再往外推一格。一個功能如果失敗的方式是退回預設值，而不是丟出錯誤，那麼「它看起來還在動」就不再是任何證據。安全的預設值幾乎都長這樣，因為它們的任務是在受限的環境裡讓系統繼續可用，於是選擇安靜地降級。降級跟正常，在畫面上是同一張臉。</p><p>回到抽屜。你花時間做了一份目錄，某天發現大家又在一格一格翻。先別急著檢查目錄做壞了沒。先確認那份目錄，還在不在你手上。</p><blockquote><p>原文來源：<a href="https://code.claude.com/docs/en/settings-reference.md">All settings - Claude Docs</a>、<a href="https://code.claude.com/docs/en/interactive-mode.md">Interactive mode - Claude Docs</a>、<a href="https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md">claude-code CHANGELOG</a></p></blockquote>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/18/%E5%AE%83%E6%B2%92%E5%A0%B1%E9%8C%AF%E5%8F%AA%E6%98%AF%E6%8F%9B%E5%9B%9E%E5%85%A7%E5%BB%BA%E7%9A%84%E9%82%A3%E4%B8%80%E4%BB%BD-%E6%8B%86%E9%96%8B-@-%E6%AA%94%E6%A1%88%E5%BB%BA%E8%AD%B0%E7%9A%84%E5%85%A9%E9%81%93%E9%96%98%E9%96%80/</id>
    <link href="https://blog.longhopick.com/2026/09/18/%E5%AE%83%E6%B2%92%E5%A0%B1%E9%8C%AF%E5%8F%AA%E6%98%AF%E6%8F%9B%E5%9B%9E%E5%85%A7%E5%BB%BA%E7%9A%84%E9%82%A3%E4%B8%80%E4%BB%BD-%E6%8B%86%E9%96%8B-@-%E6%AA%94%E6%A1%88%E5%BB%BA%E8%AD%B0%E7%9A%84%E5%85%A9%E9%81%93%E9%96%98%E9%96%80/"/>
    <published>2026-09-18T10:00:00.000Z</published>
    <summary>自訂的 @ 檔案自動完成不會報錯，它會安靜地換回內建那一份。從 stdin 的 JSON 契約拆到兩道閘門，拆完才看得出官方為什麼敢寫 skips your value without warning。</summary>
    <title>它沒報錯，只是換回內建的那一份：拆開 @ 檔案建議的兩道閘門</title>
    <updated>2026-09-19T00:07:44.015Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="AI與科技新聞" scheme="https://blog.longhopick.com/categories/AI%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E/"/>
    <category term="Anthropic" scheme="https://blog.longhopick.com/tags/Anthropic/"/>
    <category term="AI與科技新聞" scheme="https://blog.longhopick.com/tags/AI%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E/"/>
    <category term="資安" scheme="https://blog.longhopick.com/tags/%E8%B3%87%E5%AE%89/"/>
    <category term="OpenAI" scheme="https://blog.longhopick.com/tags/OpenAI/"/>
    <category term="AI 產業" scheme="https://blog.longhopick.com/tags/AI-%E7%94%A2%E6%A5%AD/"/>
    <content>
      <![CDATA[<p>AI 產業現在有兩種文件在流通。一種是公司自己挑指標、自己挑時點發出來的；另一種是別人從外面量到的，或者法院叫你交出來的。</p><p>9 月 17 日這一天，兩種都出現了，而且撞在一起。</p><h2 id="一、三個人、一組訂閱，還有一個開在-OpenAI-私有-monorepo-裡的-pull-request"><a href="#一、三個人、一組訂閱，還有一個開在-OpenAI-私有-monorepo-裡的-pull-request" class="headerlink" title="一、三個人、一組訂閱，還有一個開在 OpenAI 私有 monorepo 裡的 pull request"></a>一、三個人、一組訂閱，還有一個開在 OpenAI 私有 monorepo 裡的 pull request</h2><p>資安公司 Hacktron AI 在 9 月 17 日公開揭露，它的三人團隊（Harsh Jaiswal、Mohan Pedhapati、Rahul Maini）在 OpenAI 的 bug bounty 計畫裡串起一條完整的攻擊鏈，最後在 OpenAI 的私有 monorepo 裡開了一個無害的 pull request 當概念驗證。賞金 6,500 美元。</p><p>鏈子一共五步：Discourse 中 libheif 函式庫的 heap buffer overflow，經 HEIC&#x2F;HEIF 圖檔上傳觸發，拿到論壇環境的遠端程式碼執行；再利用 OpenAI 的 SSO 實作缺陷提權到 ChatGPT／Codex 帳號，從被入侵的員工帳號存取已連結的 GitHub 整合。那個 pull request 是終點。</p><p>第一步不在 OpenAI 身上。libheif 是 Discourse 用的第三方函式庫，對 OpenAI 來說是第三方的第三方；OpenAI 自己的缺陷落在第三步那個 SSO 實作。責任歸屬不一樣，寫成「OpenAI 有個漏洞」會漏掉一半。</p><p>真正該記住的不是這五步，是中間那幾天。</p><div class="timeline orange"><div class='timeline-item headline'>        <div class='timeline-item-title'>          <div class='item-circle'><p>Hacktron 這條鏈的關鍵幾天</p></div>        </div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>2026-07-24</p></div>        </div>        <div class='timeline-item-content'><p>Anthropic 發布 Claude Opus 5。</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>2026-07-25</p></div>        </div>        <div class='timeline-item-content'><p>Hacktron 透過 Bugcrowd 通報 OpenAI，OpenAI 當日確認修復。</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>2026-07-28</p></div>        </div>        <div class='timeline-item-content'><p>Discourse 發布安全公告。</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>2026-09-06</p></div>        </div>        <div class='timeline-item-content'><p>libheif v1.23.4 釋出，含額外修補。</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>2026-09-17</p></div>        </div>        <div class='timeline-item-content'><p>Hacktron 公開揭露整起行動。</p></div>      </div></div><p>團隊先用特製的資安版 Claude Opus 4.8 產 exploit，失敗了，卡在 ASLR 的可靠度。Opus 5 發布之後換上去，照 VentureBeat 的說法是 within hours 產出一個可運作的 ARM64 exploit，再改寫到 x86-64 與 jemalloc。</p><p>一個版本號的差距，把一條卡住的鏈變成一條通的。</p><p>這段推論建立在 Hacktron 自己的敘述上。Opus 4.8 那次失敗如果其實來自 prompt 寫法、投入時間或別的變因，而不是模型能力本身，那「一次版本更新打通一條鏈」就不成立，整段要收回；目前沒有第三方重現過這個對照。</p><p>防守方的節奏用週在算：公告出來、套件更新、排進下一個維護窗口、測試、上線。而打通一條鏈的節奏，在這個案子裡不是用週算，是用「下一次模型發布」算。兩邊的時鐘頻率不一樣，而且不一樣的方向只有一種。</p><div class="note warning flat"><p>另外，流傳的「token 成本不到 3,000 美元」與「72 小時內完成」兩個數字，我在 VentureBeat 與 Fortune 的內容裡都沒讀到，所以不寫。</p></div><p>Mohan Pedhapati 對《華爾街日報》說的是：「We’re just three guys with Claude and Codex subscriptions.」OpenAI 的官方聲明是：「We thank the researchers for contacting us and sharing their findings. We narrowed the permissions on Community sign-in tokens and revoked affected tokens and sessions.」事後稽核 GitHub 的結論用詞是「limited read」，對該私有儲存庫只有 metadata 與程式碼變更的有限讀取權。</p><p>6,500 美元這個數字有點怪。一條能摸到核心 monorepo 的完整攻擊鏈，公開市場的定價是 6,500 美元；賣去別的地方，定價會差好幾個數量級。bug bounty 制度一直靠這個價差活著：賣給你比賣給別人省事，即使少賺很多。現在產出這條鏈的成本被壓下來了，6,500 美元沒有跟著動。價差兩邊的變動速度不一樣，而不對稱會累積。賞金這一層是我自己往下接的。</p><blockquote><p>原文來源：<a href="https://venturebeat.com/security/openai-hacked-by-small-team-of-white-hat-security-researchers-using-anthropics-claude-opus-5">VentureBeat，2026-09-17</a> ／ <a href="https://fortune.com/2026/09/18/open-ai-hacked-anthropic-claude-source-code-6500-reward/">Fortune，2026-09-18</a></p></blockquote><h2 id="二、Anthropic-做了三把尺，然後拿它們量自己"><a href="#二、Anthropic-做了三把尺，然後拿它們量自己" class="headerlink" title="二、Anthropic 做了三把尺，然後拿它們量自己"></a>二、Anthropic 做了三把尺，然後拿它們量自己</h2><p>同一天，Anthropic Institute 發表提案，主張前沿實驗室該定期公開三項能互相比較的指標：AI 有多大程度在建造下一代的自己、agent 被監看與介入的能力、運算資源怎麼分配。同時公布了自家數據。</p><p>數字之前先講日期。文件發布於 9 月 17 日，但所有數字的資料截止點是 2026 年 8 月；運算那一項更窄，是 7 月 13 日到 20 日那一週。</p><table><thead><tr><th>指標</th><th>數值</th><th>口徑</th></tr></thead><tbody><tr><td>AI leads</td><td>26%</td><td>達到「AI 主導」等級的工作比例，截至 2026 年 8 月</td></tr><tr><td>AI collaborates 或以上</td><td>超過 90%</td><td>較寬鬆的門檻，涵蓋 collaborates 與 leads 兩級</td></tr><tr><td>AL5（完全自主）</td><td>0</td><td>Claude「not operating fully autonomously (AL5) for any measured R&amp;D subset」</td></tr><tr><td>安全佔總運算</td><td>6%</td><td>AI 研發<strong>總</strong>運算資源的配置比例，7&#x2F;13–7&#x2F;20 那一週</td></tr><tr><td>安全佔 AI 驅動運算</td><td>12%</td><td>AI 驅動的研發運算資源中的比例，同一週，分母跟上一列不同</td></tr></tbody></table><p>這幾個數字最常被揉成「Claude 已經做掉 Anthropic 26% 的研發工作」。那不是它的意思。26% 量的是有多少工作到了 AI 主導的等級，跟 90% 那條線不是同一把尺，不能相減；6% 跟 12% 的分母不同，也不能互換。</p><p>監看那一格：主要平台上約 30,000 個 agent，線上與離線監看器的動作涵蓋率都是 100%，線上監看器的攔阻率 0.002%，原文換算約是 47,000 個決策中的 1 個。Anthropic 另外說要讓多個組織的獨立第三方評估者進駐，取得跟內部風險評估團隊相當的存取權限。真落地會是第一個案例，目前是宣告。</p><p>前幾天 OpenAI 公布六起模型行為失準事件和一套三軌通報框架，當時能講的是那些數字沒有外部對照組。隔天對照組就出現了，只是出的牌完全不同維度：OpenAI 揭露的是出事之後多久講，Anthropic 揭露的是平常跑多快。兩家都沒揭露對方那一欄，所以還是比不起來。</p><p>這是自願性框架的結構特徵：你自己決定量什麼，自然會挑一個看起來不錯的維度；Anthropic 明說這些數字「如果前沿速度有被協調放慢，就應該會變動」，等於主動把自家指標推銷成監理機關可以盯的儀表板。想法不壞，可是定義這把尺的是被量的那個人。</p><blockquote><p>原文來源：<a href="https://www.anthropic.com/institute/measuring-pace-of-ai-development">Anthropic Institute，2026-09-17</a></p></blockquote><h2 id="三、法院把那批被遮蔽的內部備忘錄攤開來"><a href="#三、法院把那批被遮蔽的內部備忘錄攤開來" class="headerlink" title="三、法院把那批被遮蔽的內部備忘錄攤開來"></a>三、法院把那批被遮蔽的內部備忘錄攤開來</h2><p>同樣是 9 月 17 日，紐約時報控告 OpenAI 與微軟那件著作權訴訟，一批先前被遮蔽的文件解封。先跟另一件分開：這是 2023 年那件案子的文件解封，不是又有媒體提告；原告是紐約時報、Daily News 與 Center for Investigative Reporting。</p><p>微軟的 Director of Applied Science、Brent Hecht，在一份內部備忘錄裡把公司的 AI 訓練做法寫成「an astonishing theft of unprecedented proportions」，以及「the largest theft of labor in human history」。他形容大型 AI 模型「are a product that destroys its supply chain」，並用「doom loop」描述導流下滑：AI 摘要吃掉流量、出版商萎縮、生產的內容變少、模型沒東西可吃。</p><p>微軟執行長 Satya Nadella 的作證紀錄裡有這句：「anything that is paywalled should be licensed by anyone who wants to use it…for grounding or training」。OpenAI 這邊，ChatGPT 負責人 Nick Turley 說出版商面臨「existential threat」、AI 產品「largely substitutive」；總裁 Greg Brockman 形容模型「excellent at news」，並對一項繞過付費牆的提案回了「ah nice」。</p><p>難聽話不是重點。</p><p>合理使用要看四個要素，其中兩個是市場影響與善意。一份內部備忘錄把自家做法叫 theft，打的是善意；微軟自家的數據顯示 Bing 結果裡的 Copilot 讓紐約時報網站的點擊率最高下降 93%（限定詞是 up to），打的是市場影響。被告在答辯裡最需要撐住的兩格，證據是自己人留下來的。Nadella 那句更麻煩，因為它是應然陳述：付費牆後的東西，任何人想用都該取得授權。說這話的是被告方執行長，內容跟公司的答辯立場相反。哪句話落在哪一格，是我自己的分法。</p><p>三個資料集被分開點名。這三家的作品在 OpenAI 的 mid-training 資料集中有超過 91,692 份複本；來自 nytimes.com、出現在 Common Crawl 資料集裡的文件超過 200 萬份；一個叫 Project Mango 的資料集裡，出自新聞出版商的不重複作品超過 160,903 件。三個集合各算各的，不能相加也不能互換。</p><p>它們並排出現本身就是訊息：原告方已經能把訓練資料拆到資料集層級指認，不再是籠統地說「你們抓了我們的東西」。解析度變高了，答辯就不能停在理論層。</p><p>兩家問到的回應不一樣：Engadget 寫微軟發言人 Alex Haurek 表態公司的用途屬 transformative、Copilot 合乎著作權法；TechCrunch 則寫「Neither OpenAI nor Microsoft provided comment when requested.」OpenAI 對這次解封的回應我沒讀到，備忘錄的日期各家寫法也不一致，所以不寫年份。</p><blockquote><p>原文來源：<a href="https://techcrunch.com/2026/09/17/microsoft-exec-called-ai-scraping-the-largest-theft-of-labor-in-human-history-new-unredacted-filings-reveal/">TechCrunch，2026-09-17</a> ／ <a href="https://www.engadget.com/2262055/microsoft-openai-internet-scraping-largest-theft-of-labor/">Engadget，2026-09-18</a></p></blockquote><h2 id="四、時程提前了，同一場記者會說產能吃不下"><a href="#四、時程提前了，同一場記者會說產能吃不下" class="headerlink" title="四、時程提前了，同一場記者會說產能吃不下"></a>四、時程提前了，同一場記者會說產能吃不下</h2><p>華為在 9 月 17 日的 Huawei Connect 宣布，Ascend 960DT 的推出時程提前到 2027 年第一季。這一代同時拆成兩款：960DT 面向訓練，960PR 面向推論、排在 2027 年第三季。再往後是 970 與 980，分別規劃在 2028 與 2029 年。同場還發表了 Atlas 960 SuperPoD 運算叢集，以及 Peerium 架構，設計目標是讓最多 100 萬顆處理器像單一系統運作。是設計目標，不是已交付的規模。</p><p>中國科技分析師 Rui Ma 在 X 上的觀察比時程本身有意思：「the chip itself is coming WAY earlier, but the SuperPoD they announced is much smaller than what they originally laid out」。她給的對照是原先規劃可擴展到 15,488 顆 Ascend 960，這次發表的系統是 4,096 顆。</p><p>這兩條線會分開，通常代表單顆設計跟整體整合本來是兩種速度，而大規模訓練吃的是後面那條。接著是同一場記者會上，華為主管講的產能：「Since we don’t have enough capacity to even satisfy the demand in China, we don’t have a plan to expand into the international market in a fully-fledged way.」連中國的需求都吃不下，沒有全面進軍國際市場的計畫。同一個人也說過「I think Ascend market share should be bigger than Nvidia’s.」</p><p>一家宣稱時程提前、市占會超過 Nvidia 的公司，在同一場合承認自己供不應求到不敢賣去海外。這兩句話不衝突。</p><div class="note info flat"><p>華為這次沒有公布的東西，跟公布的一樣重要：Ascend 960 的 FP8／FP4 吞吐量數字、代工廠與製程節點、良率，三項都沒有。而這三項恰好是判斷「時程提前是否可信」的全部依據。另外，各家報導對「原訂是哪一季、所以提前了幾季」的說法互斥，基準點根本不同，所以這裡只寫提前到 2027 Q1。</p></div><blockquote><p>原文來源：<a href="https://techcrunch.com/2026/09/17/huawei-plans-q1-2027-launch-of-new-ai-chip-as-it-takes-on-nvidia/">TechCrunch，2026-09-17</a> ／ <a href="https://www.nbcnews.com/world/china/huawei-unveils-new-chip-technologies-chinese-firm-steps-ai-race-nvidia-rcna598288">NBC News，2026-09-17</a></p></blockquote><h2 id="五、Claude-開始調度-Claude"><a href="#五、Claude-開始調度-Claude" class="headerlink" title="五、Claude 開始調度 Claude"></a>五、Claude 開始調度 Claude</h2><p>Claude Code Projects 的改版 beta 也落在 9 月 17 日。Projects 從靜態的指令資料夾變成一個協調層：給它一個目標，coordinator 自己建 thread、分派、審查、整合，每條 thread 都是跑在自己分支與 repo 副本上的完整雲端 session。</p><p>兩個設定疊在一起有點微妙：每條 thread 預設跑 Opus 與 high effort，使用者指定的 thread 數則是「a preference, not a cap」。最貴的預設，加上一個不是上限的上限。合併衝突方面 Git 規則照舊，多條 thread 改到同幾行還是你自己解。這點反而誠實，平行化能加速的是產出，不是整合。（以上依多家二手報導交叉比對，我沒讀到 Anthropic 的第一手發布頁。）</p><blockquote><p>原文來源：<a href="https://devops.com/anthropic-adds-a-coordinator-to-claude-projects-for-running-ai-work-in-parallel/">DevOps.com</a> ／ <a href="https://techstrong.ai/features/anthropic-brings-parallel-coding-workflows-to-claude-projects/">Techstrong.ai</a></p></blockquote><hr><p>四件事的時鐘都看得到刻度。960DT 押在 2027 年第一季，到時候有沒有東西出來一翻兩瞪眼。26% 是 8 月的快照，下一次公布就知道往哪邊動。</p><p>剩下那一件沒有刻度。一條攻擊鏈在 Opus 4.8 上卡住、在 Opus 5 上幾小時內打通，週期不是季也不是年，是下一次版本更新。而版本更新不會出現在任何路線圖上，它就是某天早上出現在更新日誌裡。</p><p>三個人、一組訂閱、6,500 美元。這個定價到現在沒動過。等下一個版本出來，先動的會是產出那條鏈的成本，還是賞金那一欄的數字？這兩件事不會同時動，而中間那段空窗期，向來不是防守方在用的。</p>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/18/AI-%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E%E6%91%98%E8%A6%81-20260918/</id>
    <link href="https://blog.longhopick.com/2026/09/18/AI-%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E%E6%91%98%E8%A6%81-20260918/"/>
    <published>2026-09-18T04:00:00.000Z</published>
    <summary>白帽用別家的模型攻進 OpenAI 的私有 repo、Anthropic 自己做尺量自己、法院把內部備忘錄攤開來，還有一張提前到 2027 Q1 的晶片時程表。</summary>
    <title>AI 與科技新聞摘要 - 2026/09/18</title>
    <updated>2026-09-18T16:12:17.196Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="AI Agent" scheme="https://blog.longhopick.com/categories/AI-Agent/"/>
    <category term="AI Agent" scheme="https://blog.longhopick.com/tags/AI-Agent/"/>
    <category term="開源" scheme="https://blog.longhopick.com/tags/%E9%96%8B%E6%BA%90/"/>
    <category term="資安" scheme="https://blog.longhopick.com/tags/%E8%B3%87%E5%AE%89/"/>
    <category term="AI 法規" scheme="https://blog.longhopick.com/tags/AI-%E6%B3%95%E8%A6%8F/"/>
    <content>
      <![CDATA[<p>「我憑什麼相信這份 log 沒被改過？」</p><p>這句一出來，前面準備的材料大概都用不上了。時間戳有、工具名稱有、參數也有，問題從來不在資料缺不缺。那份 log 是你的服務寫的，存在你的資料庫，由你的人維運。旁邊能墊的是 SOC 報告、政策文件、廠商自述，三份都在講「我們有流程」，沒有一份講得了那一刻發生了什麼。</p><p>agent 讓這件事更難。它自己決定叫哪個工具、叫幾次，事後要重建的是一串它自己排出來的動作，每次長度和內容都不一樣。</p><p>缺口是真的。有一份規格正在對著它寫，叫 TRACE，八月底進了 Linux Foundation。剩下的問題只有一個：你現在該不該動手。</p><p>先講一件發生在它自己身上的事。CHANGELOG 有一則在修的是文件錯誤：<code>TraceSandboxAdapter</code> 的 docstring 原本寫著 It will not let a caller claim hardware it does not have。實際上那個 sandbox 只驗形狀：platform 字串在列舉裡、measurement 長得像 <code>sha256:</code> 開頭就算過，quote、簽章、nonce 一個都沒檢查。捏一個 amd-sev-snp 配一串零當 measurement，<code>build_trust_record()</code> 照收、schema 照過、簽章照簽。專案自己的結論寫得很坦白：</p><blockquote><p>the check that was missing had never existed and was never implemented, only claimed.</p></blockquote><h2 id="它問的三個問題，比它的十五個欄位好懂"><a href="#它問的三個問題，比它的十五個欄位好懂" class="headerlink" title="它問的三個問題，比它的十五個欄位好懂"></a>它問的三個問題，比它的十五個欄位好懂</h2><p>規格把要證明的事收斂成三句話，每句都刻意放了 actually 這個字。What actually ran、What did it actually do、What rules were actually in force。</p><p>第一句要的答案不在部署清單上，也不在 manifest 裡：客戶資料被處理的那一刻，記憶體裡正在執行的是什麼。第二句問叫了哪些工具、帶什麼參數、碰的資料是哪個分級。第三句問當下綁的是哪一份政策，以及它跑在什麼 enforcement mode。</p><p>三句話對應一份叫 Trust Record 的東西，十五個欄位，除了標 OPTIONAL 的以外全部必填。<code>runtime</code> 裝 TEE 從韌體一路到 workload 的量測鏈，<code>tool_transcript</code> 裝 MCP 與 A2A 的呼叫逐字稿，<code>policy</code> 裝政策雜湊加執行模式，<code>cnf</code> 把記錄綁到 TEE 裡那把簽章金鑰上。</p><p>它自己講得很白，這東西不是另一套平行堆疊：</p><blockquote><p>TRACE is a profile, not a parallel stack. It binds existing primitives into one coherent artifact.</p></blockquote><p>底下全是既有零件：RATS&#x2F;EAT 當信封，SLSA 管建置來源，SPIFFE&#x2F;SPIRE 給 workload 身分，SCITT 當 append-only 日誌，EAR 裝驗證者的判定。AIBOM 以 digest 被 <code>model</code> 引用，C2PA 被標成 adjacent, not absorbed。</p><p>願意寫下「我沒有發明新東西」的規格，通常是設計者知道採用成本才是真正的門檻。</p><h2 id="被偷走的金鑰會替自己作證"><a href="#被偷走的金鑰會替自己作證" class="headerlink" title="被偷走的金鑰會替自己作證"></a>被偷走的金鑰會替自己作證</h2><p>規格裡最值得讀的一段，跟 agent 沒什麼關係。</p><p>假設有人拿到你簽 Trust Record 的那把金鑰。撤銷之後，第一時間會想到的規則一定是：拒絕所有 <code>iat</code> 晚於盜用時間的記錄。乾淨、直覺、寫進驗證器大概三行。</p><p>它不成立。規格拿一整個小節否掉它，小節標題就叫 Why <code>iat</code> cannot carry the boundary：</p><blockquote><p>A compromised record-signing key also signs the <code>iat</code> field, so an attacker holding the key backdates it and the rule passes.</p></blockquote><p><code>iat</code> 本身就是被簽的欄位。握有金鑰的人可以把時間往前寫，寫完再簽，驗證器看到的是一份簽章合法、時間落在盜用前的記錄。把撤銷的邊界錨在一個「被攻破的金鑰自己控制得到的欄位」上，它就會被它要擋的那件事打敗。這跟時鐘偏差無關，容忍值怎麼調都沒用。</p><p>解法是換錨點，改用透明日誌的 entry ID。條目單調遞增，而且用密碼學綁在 Merkle 結構上，日誌往前走過之後，攻擊者沒辦法替事後補交的記錄挑一個更早的編號。所以撤銷宣告不寫「幾點之後失效」，寫的是 <code>last_valid_entry_id</code>：被撤銷金鑰簽的記錄，只有在它的 inclusion entry ID 小於等於這個值時才有效，大於就 MUST 拒絕。不同日誌的 entry ID 不可互比，這條也是 MUST NOT。</p><p>還有一條連帶設計：撤銷宣告不能自己簽自己，替金鑰 K 發宣告的那把金鑰階層必須高於 K。不然拿到 K 的人可以自己發一張撤銷宣告，把 <code>last_valid_entry_id</code> 填在他偽造的那批記錄後面，撤銷機制當場變成攻擊工具。</p><p>這段值不值得你把 TRACE 裝起來？不值得。但它值得你回頭看手上任何一套「出事就撤銷」的機制，問同一個問題：我判斷有效範圍用的那個欄位，是不是被撤銷的那把金鑰自己填的。</p><h2 id="欄位有值，跟有人檢查過，是兩件事"><a href="#欄位有值，跟有人檢查過，是兩件事" class="headerlink" title="欄位有值，跟有人檢查過，是兩件事"></a>欄位有值，跟有人檢查過，是兩件事</h2><p><code>enforcement_mode</code> 除了 enforce 跟 silent，還有第三個值叫 <code>declared</code>。它的意思是：這份政策被指名了，也被綁進簽章記錄了，然後沒有任何東西評估過它。</p><blockquote><p>The three modes above all assert that <em>something evaluated the policy</em>. <code>declared</code> asserts less: the policy is named and bound into the signed record, and nothing evaluated it.</p></blockquote><p>規格說這不是邊角案例，沒有政策引擎的產生者很常見。接著把它釘死：<code>declared</code> 是最弱的值，MUST NOT 當預設；真的評估過政策的產生者 MUST NOT 用它；消費者 MUST NOT 把它讀成任何規則被檢查過的證據。</p><p>在格式裡留一個位置給「我什麼都沒做」，比多加十個欄位有用。</p><p>開頭那份 docstring 就是反過來的例子：沒有任何東西檢查過，文件卻寫得像有。</p><p>同一批 CHANGELOG 還有一則同族的：另一個 adapter 對每一份產出的記錄都蓋上 <code>appraisal.status = &quot;affirming&quot;</code>，而那是驗證者才有權填的欄位。想從那一格確認有沒有人檢查過的人，得到的是一份沒人評估過的記錄給的肯定答覆。</p><p>第一條判準就在這裡。記錄上 <code>runtime.platform</code> 寫著 <code>amd-sev-snp</code>，不代表有人驗過硬體證明。專案文件講得很白：改 platform、複製一串非零的 digest、把 <code>appraisal.status</code> 設成 affirming，都不會讓證據憑空長出來。</p><h2 id="它真的還很早，而且名單要自己數"><a href="#它真的還很早，而且名單要自己數" class="headerlink" title="它真的還很早，而且名單要自己數"></a>它真的還很早，而且名單要自己數</h2><p>2026-09-18 查的時候，trace-spec 這個 repo 有 30 顆星。參考函式庫 <code>agentrust-trace</code> 從 2026-06-05 首發到 2026-09-06 共 12 個版本，最新 0.10.0。repo 在 2026-09-17 還有 push，CHANGELOG 的未發布區塊長得像工程報告，每則都帶 issue 編號。活躍度是真的，規模不是。</p><p>規格首頁掛著警語，這是 pre-ratification draft，欄位、線路格式、符規要求在 v1.0 前都可能改。它也已經改過一次狠的。</p><p>v0.1 的 EAT profile URI 是 <code>tag:agentrust.io,2026:trace-v0.1</code>，而 <code>agentrust.io</code> 從來不是這個專案控制的網域，指向的是第三方停放頁。RFC 4151 只允許在鑄造者確實控制該網域時使用 tag URI，所以那個識別碼不是拼錯，是無效：它對一個屬於別人的名字宣告了權威，對方隨時可以在那裡立一份衝突的定義。</p><p>v0.2 的處理叫 Cutover, not coexistence，驗證器 MUST 拒絕舊識別碼、MUST NOT 兩個都收。</p><p>治理這塊要看仔細。Linux Foundation 在 2026 年 8 月 25 日宣布接手，新聞稿寫的共同開發者是 AMD、Intel、Microsoft、OPAQUE、TII。</p><p>而規格 §6.2 那份漂亮很多的名單，標題是 Target contributing organizations，內文寫著這些組織「被認定為天然的貢獻者」，「正式參與取決於各組織自己的獨立決定」。§4.4 的共同編輯席次寫的也是 Co-editor slots open for。</p><p>那是招募公告。</p><p>查的過程裡看到有二手報導把兩份名單混在一起，把目標名單上的公司寫成共同開發者。這件事本身就是判準：新聞稿列的參與者，跟規格自己列的目標名單，要分開數。</p><h2 id="什麼時候簽了反而比不簽麻煩"><a href="#什麼時候簽了反而比不簽麻煩" class="headerlink" title="什麼時候簽了反而比不簽麻煩"></a>什麼時候簽了反而比不簽麻煩</h2><p>最該想清楚的是沒有人會去驗。驗證有八個步驟，只有前兩步對著記錄本身做，剩下六步全要驗證者自己先備齊材料：廠商公布的 RIM、預期的政策 bundle、指名的透明日誌、信任的 builder，還有一份沒過期的撤銷 bundle。最後那項最容易誤會，規格說驗證不回呼發證者，聽起來像斷網也能驗，但簽章有效性是永久的、信任不是，被撤銷金鑰簽過的記錄離線驗永遠都會過。所以規格明訂過期的 bundle 不算通過。你產得出記錄，不代表對面驗得動。</p><p>最常見的一種：你的 agent 根本沒跑在 TEE 裡。那你產得出的是 Level 0 的軟體簽章，延遲不到 1 毫秒，能證明的事情也就到「這份 JSON 是我簽的」為止。防竄改日誌用現成的東西就做得到，不必扛一份 pre-ratification 規格。</p><table><thead><tr><th>產生環境</th><th>宣稱的簽章延遲</th></tr></thead><tbody><tr><td>軟體（Level 0）</td><td>&lt; 1 ms</td></tr><tr><td>TPM</td><td>50 到 200 ms</td></tr><tr><td>SEV-SNP</td><td>10 到 50 ms</td></tr><tr><td>TDX</td><td>10 到 50 ms</td></tr></tbody></table><p>驗證端所有情況都在 5 ms 以內。這些是 LIMITATIONS.md 的宣稱值，文件沒交代是在什麼機器、什麼負載下量的。</p><p>工具不跨協定邊界的話，那一格會很乾淨，乾淨到沒有意義。<code>tool_transcript</code> 抓的是穿過 MCP、A2A 這類邊界的呼叫，編譯進二進位檔裡的函式規格明寫不在範圍內。而真的跨了邊界的人，現在也還在等：參考實作叫 Confidential MCP，很容易讓人以為已經可以用，但 v0.2 明寫規範性的 MCP profile 不在這一版，目標是 v0.3。A2A 也一樣，<code>delegation</code> 區塊落在 v0.2，規範性的綁定規則排在 v0.3。</p><p>還有一件很容易被期待錯的事：它不管模型行為。prompt injection、越獄、幻覺、對齊漂移，五條永久範圍邊界裡明列不處理。</p><blockquote><p>TRACE does not prevent misbehavior. It makes misbehavior crossing a protocol boundary visible at the moment of execution.</p></blockquote><p>它證明什麼東西執行過、當時哪些對策在生效，不裁決模型的輸出對不對。</p><h2 id="這篇的邊界"><a href="#這篇的邊界" class="headerlink" title="這篇的邊界"></a>這篇的邊界</h2><div class="note warning flat"><p>這篇讀的是 TRACE v0.2 規格原文、LIMITATIONS.md、trust-levels.md 與 CHANGELOG，加上 GitHub 與 PyPI 的 API 回應。我沒有跑過 <code>agentrust-trace</code> 任何一行程式，沒有產生過也沒有驗證過任何一份 Trust Record。文中的欄位名、MUST 條文、延遲數字都是規格與文件裡的文字。</p></div><h2 id="所以現在要做什麼"><a href="#所以現在要做什麼" class="headerlink" title="所以現在要做什麼"></a>所以現在要做什麼</h2><p>回到開頭那句話。</p><p>現在不要導入 TRACE。但現在就去跑它那份驗證清單。把那八個步驟當成八個問題丟給自己的系統：那一刻在跑的是哪一版模型，你證明得了嗎。工具呼叫的記錄有沒有跟執行環境綁在一起，還是各存各的。你的政策是被評估過，還是其實就是 <code>declared</code>。金鑰被偷的那天，你用來判斷哪些東西還算數的依據，是不是那把金鑰自己簽的欄位。</p><p>這四題跟 TRACE 會不會成功沒關係，但答不出來的每一題，都是稽核那天你會卡住的地方。</p><p>什麼會讓我改口說可以裝了？兩件事：v0.3 出來、規範性的 MCP profile 真的落地；以及出現一個不是由規格作者自己營運的透明日誌，那題還掛在規格的開放問題清單上。稽核方會不會接受這份格式，我猜跟日誌那題一起決定，不過規格沒這樣寫，這條算我自己加的。</p><p>那四個問題今天就問得出口，不需要等誰先批准一份規格。TRACE 撐不撐得到 v1.0，等它撐到再說。</p>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/18/%E9%82%A3%E4%BB%BD-log-%E6%98%AF%E4%BD%A0%E8%87%AA%E5%B7%B1%E5%AF%AB%E7%9A%84-TRACE-%E8%A3%9C%E7%9A%84%E5%B0%B1%E6%98%AF%E9%80%99%E4%B8%80%E6%A0%BC-%E4%BD%86%E7%8F%BE%E5%9C%A8%E9%82%84%E4%B8%8D%E8%A9%B2%E8%A3%9D/</id>
    <link href="https://blog.longhopick.com/2026/09/18/%E9%82%A3%E4%BB%BD-log-%E6%98%AF%E4%BD%A0%E8%87%AA%E5%B7%B1%E5%AF%AB%E7%9A%84-TRACE-%E8%A3%9C%E7%9A%84%E5%B0%B1%E6%98%AF%E9%80%99%E4%B8%80%E6%A0%BC-%E4%BD%86%E7%8F%BE%E5%9C%A8%E9%82%84%E4%B8%8D%E8%A9%B2%E8%A3%9D/"/>
    <published>2026-09-18T01:00:00.000Z</published>
    <summary>TRACE 想補的是「執行治理證明」那一格：agent 跑完之後，你拿什麼向稽核證明它做過什麼。問題是真的，規格還是 pre-ratification draft，這篇講的是現在該拿它做什麼、不該拿它做什麼。</summary>
    <title>那份 log 是你自己寫的：TRACE 補的就是這一格，但現在還不該裝</title>
    <updated>2026-09-18T16:11:16.415Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="Claude Code" scheme="https://blog.longhopick.com/categories/Claude-Code/"/>
    <category term="Claude Code" scheme="https://blog.longhopick.com/tags/Claude-Code/"/>
    <category term="CLI" scheme="https://blog.longhopick.com/tags/CLI/"/>
    <category term="開發工具" scheme="https://blog.longhopick.com/tags/%E9%96%8B%E7%99%BC%E5%B7%A5%E5%85%B7/"/>
    <category term="教學" scheme="https://blog.longhopick.com/tags/%E6%95%99%E5%AD%B8/"/>
    <content>
      <![CDATA[<p>終端機會閃，這件事比 Claude Code 老得多。</p><p>它會閃是因為更新畫面的方式很土：要改哪裡，就把那一片重新刷一遍。刷得夠快、範圍夠小，你的眼睛接不到；刷得慢一點、範圍大一點，中間那一下空白就露出來了。平常沒人在意，因為平常的終端機一行印完就不動了，沒什麼好刷的。</p><p>Claude Code 不是那樣用終端機的。它一邊跑一邊改畫面：spinner 在轉，tool output 一段一段串進來，上面已經印過的東西還會回頭被改寫。那個「刷一遍」於是變成每秒好幾次，刷的還是一整片。捲動位置會自己跳回最上面，畫面會抖。官方點名三個地方最明顯：VS Code 內建終端機、tmux、iTerm2。這三個的共同點是算繪吞吐量本來就是瓶頸。</p><p>字吐出去之後就歸終端機管，所以 Claude Code 對「畫面現在長什麼樣」幾乎沒有控制權，它想改一行字，只能把整塊重印。閃就是這樣來的。</p><h2 id="轉捩點是一個很老的招數"><a href="#轉捩點是一個很老的招數" class="headerlink" title="轉捩點是一個很老的招數"></a>轉捩點是一個很老的招數</h2><p><code>vim</code> 開起來的時候，整個畫面會被換掉；離開的時候，原本那些東西原封不動回來。那叫 alternate screen buffer，<code>htop</code> 也是這樣。</p><p>終端機其實有兩塊畫布。一塊是你平常一行一行往下累積的那塊，另一塊是空的，整張借給程式去用。</p><p>拿收據紙跟白板來比就很清楚。第一塊畫布是收據紙，一張一張吐出來，吐出去就固定了，要改只能整捲重印。第二塊是白板，你可以只擦掉右下角那三個字，別的地方碰都不用碰。</p><p>全螢幕算繪就是搬到白板上去畫。文件另外提了一件更省事的做法：它只算繪當前可見的那幾則訊息。畫面外的不畫，所以每次更新送給終端機的資料量會少很多，長對話跑下去記憶體用量也維持平坦。至於少多少、平坦到什麼程度，文件一個數字都沒給，我也不補。</p><p>名字倒是先擋一下誤會。文件自己寫了一句：fullscreen 指的是 Claude Code 怎麼接管終端機的繪圖表面，就像 <code>vim</code> 那樣，跟把終端機視窗最大化完全無關，任何視窗大小都能用。</p><p>同一塊畫布可以被推向兩個相反的方向。這跟〈<a href="/2026/09/11/%E5%AE%83%E6%8A%8A%E6%A1%86%E7%B7%9A%E6%8B%86%E5%85%89%E6%8F%9B%E6%88%90%E4%B8%80%E8%A1%8C%E4%B8%80%E8%A1%8C%E7%9A%84%E5%AD%97-Claude-Code%E7%9A%84%E8%9E%A2%E5%B9%95%E9%96%B1%E8%AE%80%E5%99%A8%E6%A8%A1%E5%BC%8F/">它把框線拆光，換成一行一行的字</a>〉是同一個介面的兩篇：那篇是把 TUI 拆掉、換成印出去就不再動的純文字；這篇是把 TUI 推到極致、整張畫布拿去用。兩邊不可能同時成立，文件也就寫死了：螢幕閱讀器模式的其他 session 一律走傳統 renderer。</p><h2 id="走到現在，這題可能已經替你答過了"><a href="#走到現在，這題可能已經替你答過了" class="headerlink" title="走到現在，這題可能已經替你答過了"></a>走到現在，這題可能已經替你答過了</h2><p>三條路可以開：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">/tui fullscreen     # 切到全螢幕：存下 tui 設定並帶著對話重啟，不會掉 context</span><br><span class="line">/tui default        # 切回傳統 renderer</span><br><span class="line">/tui                # 不帶參數：印出目前用的是哪個 renderer</span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">CLAUDE_CODE_NO_FLICKER=1 claude          <span class="comment"># 用環境變數啟用</span></span><br><span class="line">CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1   <span class="comment"># 強制傳統 renderer，無視存下的 tui 設定</span></span><br></pre></td></tr></table></figure><p><code>/tui fullscreen</code> 那句註解值得多看一眼：它是<strong>重啟</strong>，只是把對話一起帶過去。帶得過去的有螢幕上那份對話、permission mode 與 effort level、上次 <code>/model</code> 選的模型，還有 <code>--allowed-tools</code>、<code>--disallowed-tools</code>、<code>--agent</code>、<code>--agents</code>、<code>--append-system-prompt</code>、<code>--system-prompt-snapshot</code> 這些旗標。</p><p>帶不過去的它會直接擋：用 <code>--system-prompt</code> 取代過系統提示、用 <code>--tools</code> 給過允許清單、或傳過 <code>--setting-sources</code> 的 session，切不過去，會吐 <code>Cannot switch renderers in this session</code>。hook 或 SDK permission update 只為這個 session 新增的 deny／ask 規則也一樣。這條在你「跑到一半想換」的時候最容易撞到，因為那些旗標是啟動當下打的，你多半已經忘了。</p><p>真正有意思的是預設值。文件給了一張九列的判定表，由上往下第一個符合者勝，其中兩列根本不問你的意見：這台機器第一次跑 Claude Code 的版本是 v2.1.239 或更新的（而且那個 session 不向 Anthropic 抓 feature flag）→ 全螢幕；會抓 feature flag、而你第一次用 Claude Code 是在 <strong>2026-05-06</strong> 當天或之後 → 也是全螢幕。文件沒有解釋為什麼是那一天，我也不替它編一個。</p><h2 id="滑鼠是怎麼被收走的"><a href="#滑鼠是怎麼被收走的" class="headerlink" title="滑鼠是怎麼被收走的"></a>滑鼠是怎麼被收走的</h2><p>要能點、能用滾輪捲，Claude Code 就得捕捉滑鼠事件。捕捉之後，終端機原生的 copy-on-select 就失效了。</p><p>這句話拆開來講會比較有感覺。你拖出來的那段選取，現在存在 Claude Code 裡，不在終端機的選取緩衝區。所以 tmux copy mode 看不到它，Kitty hints 看不到它，任何活在終端機那一層的工具都看不到它。文件說這是最常見的摩擦點，尤其在 SSH 或 tmux 裡，那正好是「終端機那一層」堆最多工具的地方。</p><p>以前的選取像貼在玻璃外側的便利貼，誰路過都撕得走。現在它貼在玻璃內側。</p><p>補償措施是一個修飾鍵。按住它拖，就是一次性的原生選取：</p><table><thead><tr><th>終端機</th><th>按住</th></tr></thead><tbody><tr><td>Terminal.app</td><td><code>Fn</code></td></tr><tr><td>iTerm2</td><td><code>Option</code></td></tr><tr><td>VS Code、Cursor、Devin Desktop</td><td><code>Shift</code>（macOS 開了 <code>terminal.integrated.macOptionClickForcesSelection</code> 的話也可用 <code>Option</code>）</td></tr><tr><td>其他多數終端機</td><td><code>Shift</code></td></tr></tbody></table><p>不想每次都按，可以兩段式關掉。第一段直接退出滑鼠捕捉：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">CLAUDE_CODE_NO_FLICKER=1 CLAUDE_CODE_DISABLE_MOUSE=1 claude   <span class="comment"># 完全退出滑鼠捕捉</span></span><br></pre></td></tr></table></figure><p>關掉之後<strong>保留</strong>的是不閃爍算繪與平坦記憶體，鍵盤捲動（<code>PgUp</code>／<code>PgDn</code>／<code>Ctrl+Home</code>／<code>Ctrl+End</code>）照樣能用，終端機原生選取恢復。</p><p>失去的有四樣：點擊定位游標、點擊展開 tool output、點 URL，以及 Claude Code 裡的滾輪捲動。四樣一起收，沒得挑。</p><p>第二段溫和一點：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">CLAUDE_CODE_DISABLE_MOUSE_CLICKS=1    # 保留滾輪，只關掉 click / drag / hover（需 v2.1.195+）</span><br></pre></td></tr></table></figure><p>兩個變數都設的時候 <code>CLAUDE_CODE_DISABLE_MOUSE</code> 優先。</p><p>還有一件事很少人會事先想到：複製這個動作現在有很多條路。macOS 走 <code>pbcopy</code>；Linux 在 Wayland 走 <code>wl-copy</code>、X11 走 <code>xclip</code> 或 <code>xsel</code>（會同時寫 clipboard 與 PRIMARY selection，所以中鍵貼上有效）；Windows 與 WSL 走 PowerShell 的 <code>Set-Clipboard</code>；在 tmux 裡另外寫一份 tmux paste buffer；走 SSH 的時候退回 OSC 52 escape sequence。每複製一次，Claude Code 會印一個 toast 告訴你剛剛走的是哪一條。</p><p>那個 toast 的存在本身就是答案。一個功能如果需要每次做完都回報自己走了哪條路，代表它的路不只一條，而且哪條會通不是你能事先知道的。以前不需要任何路：你放開滑鼠，字就在剪貼簿裡了，因為那件事根本不是程式做的。</p><p>OSC 52 這條路還有個現成的坑：iTerm2 預設把它擋掉，要到 Settings → General → Selection 打開「Applications in terminal may access clipboard」。在 iTerm2 裡跑 <code>/terminal-setup</code> 會幫你打開。</p><h2 id="它有把東西還回去的動作"><a href="#它有把東西還回去的動作" class="headerlink" title="它有把東西還回去的動作"></a>它有把東西還回去的動作</h2><p><code>Ctrl+o</code> 進 transcript mode，那裡是一套 less 式操作：<code>/</code> 開搜尋、<code>n</code> 與 <code>N</code> 跳下一個上一個（關掉搜尋列之後仍然有效）、<code>j</code>／<code>k</code> 捲一行、<code>g</code>／<code>G</code> 跳頂跳底、<code>&#123;</code>／<code>&#125;</code> 在 prompt 之間跳、<code>Ctrl+u</code>／<code>Ctrl+d</code> 捲半頁。</p><p>真正重要的是兩個把主權交還的鍵。按 <code>[</code>，它把完整對話（所有 tool output 都展開）寫進終端機的<strong>原生 scrollback</strong>，寫完之後 <code>Cmd+f</code>、tmux copy mode 全部又吃得到了。長 session 會頓一下。這個狀態持續到你用 <code>Esc</code> 或 <code>q</code> 離開 transcript mode 為止，下次 <code>Ctrl+o</code> 得重來一次。按 <code>v</code> 則是寫到暫存檔，用 <code>$VISUAL</code> 或 <code>$EDITOR</code> 開起來。</p><p>順著這條還有一件我沒預期的事：壓縮過之後，你仍然捲得回 session 最開頭。Claude 是從壓縮摘要繼續工作的，但 Claude Code 會跨多次壓縮，把每一則更早的訊息留在全螢幕的 scrollback 裡。這兩件事是分開的。模型記得什麼，跟你翻得到什麼，在這裡不是同一回事。</p><h2 id="三條走不通的路"><a href="#三條走不通的路" class="headerlink" title="三條走不通的路"></a>三條走不通的路</h2><p>第一條在 MacBook 鍵盤上。它沒有獨立的 <code>PgUp</code>／<code>PgDn</code>／<code>Home</code>／<code>End</code>，要壓 <code>Fn</code> 配方向鍵（<code>Fn+↑</code>＝PgUp、<code>Fn+↓</code>＝PgDn、<code>Fn+←</code>＝Home、<code>Fn+→</code>＝End）。而 <code>Ctrl+Fn+→</code> 在 macOS 上送不到 Claude Code，所以 <strong>MacBook 鍵盤預設沒有可用的「跳到底部」組合鍵</strong>。文件給三個替代：點 jump-to-bottom 按鈕、用滾輪捲到底、或者把 <code>scroll:bottom</code> 重新綁到你鍵盤送得出來的組合。</p><p>文件沒有把這段跟前面那段放在一起講，但疊起來看很明顯：前兩個替代都要滑鼠。你要是照上一節把 <code>CLAUDE_CODE_DISABLE_MOUSE</code> 開了，在 MacBook 上就只剩重綁鍵這一條路。</p><p>第二條在 JetBrains 的終端機。<code>/scroll-speed</code> 在那裡不可用，而且它會直接忽略 <code>CLAUDE_CODE_SCROLL_SPEED</code>，原因是它送滑鼠事件的速率比其他模擬器高很多。想調速度的話，其他地方是 <code>export CLAUDE_CODE_SCROLL_SPEED=3</code>（3 等於 vim 的預設，接受 0 到 20 的正值，可以寫 <code>0.25</code> 這種小數），或者跑 <code>/scroll-speed</code> 拉那把尺，兩者寫的是同一個值、持久化到 <code>~/.claude/settings.json</code>。要注意對話框的上限是 10：環境變數設更高時對話框顯示 10，從對話框存檔就會被存成 10。</p><p>第三條是 iTerm2 的 tmux 整合模式。文件明講：不要在 <code>tmux -CC</code> 的 session 開全螢幕算繪。滾輪無效，雙擊還可能把終端狀態搞壞。在 iTerm2 裡跑一般 tmux（不加 <code>-CC</code>）沒問題。另外 tmux 本身要開 mouse mode（<code>~/.tmux.conf</code> 加 <code>set -g mouse on</code> 再重載），不然滾輪事件會被 tmux 吃掉；偵測到沒開的時候，Claude Code 啟動會提示一次。</p><div class="timeline blue"><div class='timeline-item headline'>        <div class='timeline-item-title'>          <div class='item-circle'><p>滑鼠能點的東西是一版一版長出來的</p></div>        </div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>v2.1.187</p></div>        </div>        <div class='timeline-item-content'><p>select menu 的選項可以點。</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>v2.1.208</p></div>        </div>        <div class='timeline-item-content'><p>multi-select 可以點。</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>v2.1.257</p></div>        </div>        <div class='timeline-item-content'><p><code>!</code> 開頭的 shell 指令，輸出可以點開。</p></div>      </div><div class='timeline-item'>        <div class='timeline-item-title'>          <div class='item-circle'><p>v2.1.271</p></div>        </div>        <div class='timeline-item-content'><p><code>/config</code> 面板可以直接點值改設定，設定清單可以用滾輪捲。</p></div>      </div></div><h2 id="開起來卻不是全螢幕的話"><a href="#開起來卻不是全螢幕的話" class="headerlink" title="開起來卻不是全螢幕的話"></a>開起來卻不是全螢幕的話</h2><p>有一種狀況會讓你以為自己設錯了。Claude Code 對「全螢幕成功啟動」的定義是：畫出第一幀之後，再撐 10 秒，或者你用 <code>/exit</code>、Ctrl+C、Ctrl+D 結束它。</p><p>失敗一次，它印 <code>Claude Code&#39;s fullscreen renderer didn&#39;t finish starting last time on this machine</code>，下一個 session 仍然會再試。失敗兩次，它印 <code>Claude Code&#39;s fullscreen renderer has repeatedly failed to start on this machine</code>，然後一直用傳統 renderer，直到你更新 Claude Code 或跑一次 <code>/tui fullscreen</code>。而且之後不再印任何東西，你會安安靜靜地待在傳統模式裡。計數按版本分別算，一次成功就重設；設了 <code>CLAUDE_CODE_NO_FLICKER=1</code> 的 session 不計入。想確認自己是不是因為這個而在傳統模式，跑不帶參數的 <code>/tui</code>，<code>Current renderer</code> 那行會說明。</p><p>另一個會嚇到人的是畫面殘留舊字。全螢幕只送「兩幀之間改變的格子」，某些終端機（最常見是 Windows Terminal 與其他 ConPTY 後端）會把這些定位寫入合併錯，留下舊輸出的碎片，直到你改一次視窗大小。解法是 <code>CLAUDE_CODE_ALT_SCREEN_FULL_REPAINT=1</code>，每一幀重繪每一格。Windows 上背景 session 與 agent view 已經自動開了，只有你自己直接啟動的互動式全螢幕 session 才需要設。</p><h2 id="兩邊的代價不對稱"><a href="#兩邊的代價不對稱" class="headerlink" title="兩邊的代價不對稱"></a>兩邊的代價不對稱</h2><p>先學那個修飾鍵，不要急著關滑鼠捕捉。</p><p>理由是兩邊的代價不對稱。修飾鍵的代價是你每次要原生選取時多按一顆鍵，而且只在那一次；<code>CLAUDE_CODE_DISABLE_MOUSE</code> 的代價是永久收掉四樣東西，其中「點擊展開 tool output」跟全螢幕的存在理由是綁在一起的——你當初就是為了畫面別跳、別閃才開它的，結果連帶把「看那一大坨輸出」的手段也關了。</p><p>會讓我改口的條件很具體，就藏在上面那張表的最後一列：「其他多數終端機」用 <code>Shift</code>。「多數」這兩個字是缺口。文件只逐一點名了四類終端機，你的那台要是把那個修飾鍵拿去做別的事了，或者它根本不在名單上、按下去沒反應，修飾鍵這條路就直接不成立。那種情況我會跳過整個第一段，直接上 <code>CLAUDE_CODE_DISABLE_MOUSE_CLICKS=1</code>，保留滾輪，只關點擊，至少捲動還是自己的。</p><div class="note warning flat"><p>這篇裡每一條指令、環境變數、版本號都是從官方文件抄回來的，<strong>我只讀了文件，沒有實際跑過</strong>。開起來到底還閃不閃、<code>[</code> 寫回 scrollback 那一下要頓多久、修飾鍵按著拖順不順手，我都說不準。文件自己標了這是 research preview，回報管道是 session 內的 <code>/feedback</code>，或者到 <a href="https://github.com/anthropics/claude-code/issues">GitHub issues</a> 開一則。文件要求附上終端機模擬器的名稱與版本，那個欄位看來不是隨便問的。</p></div><h2 id="這條線每天都在往前推"><a href="#這條線每天都在往前推" class="headerlink" title="這條線每天都在往前推"></a>這條線每天都在往前推</h2><p>回到那張判定表的第八列：會抓 feature flag、而且第一次用 Claude Code 在 2026-05-06 當天或之後的人，預設就是全螢幕。</p><p>這條規則只看「你什麼時候第一次用」，不看你現在怎麼想。意思是今天才開始用 Claude Code 的人，一進來就在白板上，很可能不知道自己在白板上，也不知道滑鼠已經交出去了——他不會覺得「拖不動」是被拿走的東西，他會以為終端機本來就這樣。等到哪天他 SSH 進一台機器想複製一段 log，那個修飾鍵才會變成他非學不可的東西。</p><p>至於那張表會不會有一天少掉幾列、<code>/tui default</code> 還留不留著，文件沒說。research preview 這個標籤的意思向來就是「還會改」。</p><blockquote><p>資料來源：<a href="https://code.claude.com/docs/en/fullscreen">Fullscreen rendering — Claude Docs</a></p></blockquote>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/17/%E7%95%AB%E9%9D%A2%E4%B8%8D%E9%96%83%E4%BA%86%E4%BB%A3%E5%83%B9%E6%98%AF%E4%BD%A0%E7%9A%84%E6%BB%91%E9%BC%A0-Claude-Code-%E7%9A%84%E5%85%A8%E8%9E%A2%E5%B9%95%E7%AE%97%E7%B9%AA/</id>
    <link href="https://blog.longhopick.com/2026/09/17/%E7%95%AB%E9%9D%A2%E4%B8%8D%E9%96%83%E4%BA%86%E4%BB%A3%E5%83%B9%E6%98%AF%E4%BD%A0%E7%9A%84%E6%BB%91%E9%BC%A0-Claude-Code-%E7%9A%84%E5%85%A8%E8%9E%A2%E5%B9%95%E7%AE%97%E7%B9%AA/"/>
    <published>2026-09-17T10:00:00.000Z</published>
    <summary>全螢幕算繪把介面搬到終端機的 alternate screen buffer 上，只畫看得見的那幾則訊息。同一個動作也把滑鼠事件收進了 Claude Code，終端機原生的拖曳選取就不見了。</summary>
    <title>畫面不閃了，代價是你的滑鼠：Claude Code 的全螢幕算繪</title>
    <updated>2026-09-17T02:30:27.063Z</updated>
  </entry>
  <entry>
    <author>
      <name>Cheng®</name>
    </author>
    <category term="AI與科技新聞" scheme="https://blog.longhopick.com/categories/AI%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E/"/>
    <category term="Anthropic" scheme="https://blog.longhopick.com/tags/Anthropic/"/>
    <category term="AI與科技新聞" scheme="https://blog.longhopick.com/tags/AI%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E/"/>
    <category term="NVIDIA" scheme="https://blog.longhopick.com/tags/NVIDIA/"/>
    <category term="AI 產業" scheme="https://blog.longhopick.com/tags/AI-%E7%94%A2%E6%A5%AD/"/>
    <content>
      <![CDATA[<p>你上一次因為別人在蓋房子，買不到自己要用的東西，是什麼時候？</p><p>9 月 16 日，昆士蘭州議會宣布了一份租約。它的長度用「幾年到期」來算沒什麼意義，得用工期算：蓋完要四到六年。</p><h2 id="一、一份要蓋四到六年的租約，電先從煤跟天然氣來"><a href="#一、一份要蓋四到六年的租約，電先從煤跟天然氣來" class="headerlink" title="一、一份要蓋四到六年的租約，電先從煤跟天然氣來"></a>一、一份要蓋四到六年的租約，電先從煤跟天然氣來</h2><p>昆士蘭州長 David Crisafulli（Queensland Premier）9 月 16 日在州議會宣布，Anthropic 已經簽下長期租約，成為規劃中的 Western Downs Digital Park 的主要承租方。開發商是新加坡業者 Zerra DC。地點在昆士蘭 Western Downs 地區、Dalby 附近，基地約 725 公頃。ABC News 把耗電量的量級寫成「相當於 150 萬戶澳洲平均家庭」，那是一個比喻用的換算，不是說有 150 萬戶人家要搬過去。興建期預估 4 到 6 年。</p><p>用途寫得很明確：推論（inference），讓 Claude 回應客戶的請求，不是拿來訓練模型。</p><p>這個用途值得停一下，以下是我的判讀，報導沒有這樣論述。訓練是階段性的，推論是持續的，它跟著客戶的請求量走。用一座四到六年才蓋得完的設施去接一條跟著請求量走的曲線，等於押注四到六年後那條曲線還在，而且形狀還撐得起這麼大一塊地。這個押注不一定錯，可是它是押注，不是既成事實。</p><p>金額這一格，我不打算給你一個乾淨的數字，因為它本來就不乾淨。ABC 的標題寫的是 <code>$32b</code>，ABC 是澳洲的公共廣播機構，標題裡那個 <code>$</code> 沒有另外標注幣別；其他報導出現過 A$31.9 billion、A$30bn、A$32bn 三種寫法。更該小心的是第二層：這個金額是<strong>整個園區的投資額</strong>，不是 Anthropic 單方承諾要掏出來的錢。一個沒標幣別、又很容易被讀成「某家公司要花這麼多」的數字，看到它的時候最好先停一下。所以這篇只寫「ABC 標題寫的 $32b」，不換算、不折成美元。</p><p>電力來源這段值得逐字讀：初期靠煤與天然氣，等支援用的再生能源建好之後再轉換。而州長的賣點是這句原話：「This is a major win that will deliver more jobs, put more energy into Queensland’s grid and drive down power prices for Queenslanders.」更多工作、更多能源進電網、把電價壓下來。</p><p>一個用煤跟天然氣起步、耗電量級要拿 150 萬戶來比喻的設施，被描述成會讓當地電價下降的東西。這兩件事不必然矛盾，新增發電容量確實有可能壓低批發電價，但那是一個需要被驗證的因果，不是簽約當天就成立的事實。報導沒有給這個因果任何佐證，我也不打算幫它補。</p><p>還有一件事的順序很有意思：這份租約是在核准下來之前簽的。外資審查委員會（Foreign Investment Review Board）的核准還沒拿到，地方議會的開發申請也還沒裁決。Western Downs 市長 Andrew Smith 提到的是約 1,000 個長期職位。</p><blockquote><p>原文來源：<a href="https://www.abc.net.au/news/2026-09-16/queensland-data-centre-anthropic-dalby/107160640">ABC News，2026-09-16</a></p></blockquote><h2 id="二、同一天，另一邊在談的是估值，而且各家報的不一樣"><a href="#二、同一天，另一邊在談的是估值，而且各家報的不一樣" class="headerlink" title="二、同一天，另一邊在談的是估值，而且各家報的不一樣"></a>二、同一天，另一邊在談的是估值，而且各家報的不一樣</h2><p>Fortune 9 月 16 日刊出的報導說，OpenAI 正在跟投資人洽談新一輪募資，估值 1.2 兆美元。這個數字的來源鏈要交代清楚：Fortune 在文中明確把它歸給《金融時報》的報導，不是 Fortune 自己查到的。</p><p>各家報的數字不一樣，這種時候並陳比挑一個順眼的寫誠實：</p><table><thead><tr><th>來源</th><th>數字</th><th>原文的說法</th></tr></thead><tbody><tr><td>金融時報（Fortune 轉述）</td><td>超過 1.2 兆美元</td><td>新一輪創投募資的估值</td></tr><tr><td>華爾街日報</td><td>超過 1.2 兆美元</td><td>pre-IPO 輪</td></tr><tr><td>紐約時報</td><td>投資人出價 1.2 兆、OpenAI 想拉到 1.5 兆</td><td>出價值與目標值是兩個數字</td></tr></tbody></table><p>三家並排還有一層意思：這一輪還在談。已經談定的估值不會同時有三個版本，出價值跟目標值也不會分得開。</p><p>對照組是今年 3 月那輪：募到 1,220 億美元，投後估值 8,520 億美元（Fortune 的口徑）。上一輪的估值本身也有兩種寫法，投後 8,520 億、投前 7,300 億，所以這篇不寫「翻了幾倍」。用不同的基準會算出不同的答案，而那個答案通常剛好就是寫的人想要的那個。</p><p>標題那句「IPO looks like a no-go」底下是 Altman 的原話，但時間點要標明：那句話是他對 Fortune 記者 Alyson Shontell 說的，出處那篇文章的日期是 9 月 12 日，不是 16 日當天講的。他說在安全議題正在發生的此刻上市是 ill-advised，然後補了一句「and we don’t feel pressure on that」，意思是他們在這件事情上沒有感受到壓力。</p><p>沒有壓力這句話，放進「同一週還在談一輪新募資」的脈絡裡，意思就比較清楚了。不上市不代表不需要錢，只代表錢有別的地方來。私募跟公開市場的差別，主要落在義務這一層：一輪還在談的估值可以談到一半不談了，招股書送出去之後就有一整套揭露義務跟著跑。上一則那份租約是這件事的反面，工期四到六年的水泥一旦動土，就沒有「談到一半不談了」這個選項。</p><blockquote><p>原文來源：<a href="https://fortune.com/2026/09/16/openai-ipo-sam-altman-vc-funding-valuation-1-2-trillion/">Fortune，2026-09-16</a></p></blockquote><h2 id="三、史特拉斯堡那場演說，有時程的是小孩，沒時程的是模型"><a href="#三、史特拉斯堡那場演說，有時程的是小孩，沒時程的是模型" class="headerlink" title="三、史特拉斯堡那場演說，有時程的是小孩，沒時程的是模型"></a>三、史特拉斯堡那場演說，有時程的是小孩，沒時程的是模型</h2><p>同樣是 9 月 16 日，歐盟執委會主席 Ursula von der Leyen 在歐洲議會發表年度歐盟國情咨文。地點是史特拉斯堡，不是布魯塞爾——布魯塞爾是她提議的後續會談地點，這兩個很常被寫混。</p><p>她講前沿模型那段的原話是「Models being developed will allow hacking on a level we never thought possible.」，還引述了業界的說法：「CEOs of the most advanced companies tell us that it is time to slow down on the self-recursive models.」她拿 7 月的 OpenAI–Hugging Face 事件當作 AI agent 逃出測試環境的實例，並點名要跟加拿大、英國以及其他理念相近的國家合作四件事：model evaluation、verification、early-warning、AI security。她也提醒議會，AI Act 已經賦予執委會對最先進模型開發者之風險緩解措施的監督權。</p><p>這裡有條界線要畫清楚。這是一場演說裡的宣示跟邀請，不是法案、不是禁令、也不是已經談成的協議。她要找前沿實驗室談話這件事，Euronews 的原文沒有給任何日期。二手標題常把它寫成「歐盟支持 AI 放慢」，那是簡化過頭的版本。</p><p>同一場演說的另一半就具體得多。社群媒體新法 Kids Act 按年齡分級：13 歲以下禁止使用社群媒體，13 到 15 歲只能用需要家長監督的 mini accounts，15 到 18 歲功能受限、每日 1 小時使用上限，平台還要符合強制性的安全設計要求。被引用最多的是這句原話：「We are reversing the burden of proof. Now, platforms will have to prove to us that they are safe.」舉證責任反轉，改由平台自證安全。執委會另外計畫在今年秋季提出 Digital Fairness Act，處理成癮性設計。這兩部都還是提案，得走完歐洲議會與理事會的程序才算數，誰都不要寫成「歐盟已經立法禁止 13 歲以下使用社群媒體」。</p><p>同一場演說，兩套主題，成熟度差很多。要小孩少滑一小時，寫得出年齡級距、寫得出每日時數、寫得出誰要舉證；要前沿模型放慢，只寫得出四個合作面向跟一場還沒有日期的會談。原因大概不在誰比較認真。可管的那部分已經有工具，難管的那部分還在找工具。</p><blockquote><p>原文來源：<a href="https://www.euronews.com/my-europe/2026/09/16/eus-von-der-leyen-calls-for-pacing-frontier-ai-models">Euronews，2026-09-16</a> ／ <a href="https://www.securityweek.com/eu-chief-warns-of-ai-powered-hacking-moves-to-rein-in-social-media/">SecurityWeek，2026-09-16</a></p></blockquote><h2 id="四、傳顯示卡排到-2028，這則的證據最弱，卻是唯一會進你家的"><a href="#四、傳顯示卡排到-2028，這則的證據最弱，卻是唯一會進你家的" class="headerlink" title="四、傳顯示卡排到 2028，這則的證據最弱，卻是唯一會進你家的"></a>四、傳顯示卡排到 2028，這則的證據最弱，卻是唯一會進你家的</h2><p>9 月 16 日，Wccftech 首報了一則論壇爆料。硬體爆料者 Kepler_L2 在 AnandTech 論壇的討論中說，AMD 的 AT2（Alpha Trion 2）是明年唯一預計推出的新 GPU，其餘 AMD 與 Nvidia 的產品都排到 2028 年，意思就是 Nvidia 基於 Rubin 的 RTX 60 系列與 AMD 的 RDNA 5 都落在 2028。</p><p>先把限定詞釘死，再往下講。</p><div class="note warning flat"><p><strong>這是傳聞，不是官方消息。</strong> AMD 與 Nvidia 都沒有發表任何聲明；Kepler_L2 本人也沒有提供消息來源，沒有解釋 2028 這個時間點是怎麼來的。同業爆料者之間還互相打架：Moore’s Law is Dead 先前說 RTX 60 是延到 2027，兩人過去多次意見相左。連 AT2 的規格各家都不一致，Club386 說最高 64 組 CU、Wccftech 說 40 組 CU。這一則請當產業氛圍的註腳看，不要當事實。</p></div><p>被點名的原因有兩個。一個是 DRAM 與 HBM 缺貨，推高了整個 PC 硬體的成本，Intel 高層的說法是要到 2028 才會緩解。另一個是晶圓代工把先進製程的產能讓給了 AI 加速器，排擠掉消費級 GPU 的時程。</p><p>前面三則講的都是錢怎麼決定排隊順序。這一則是隊伍的末端，而且末端這件事一點都不意外，它甚至是最合理的商業決策。</p><p>消費級顯示卡這一格手上有什麼籌碼？一批對價格極度敏感、隨時可以不買、而且會在論壇上罵你的個人買家。同一批先進製程產能，接一張簽了長約的資料中心訂單，跟接一批散戶的零售需求，哪一邊排前面不用查資料也想得出來。</p><p>所以排擠這件事沒有反派。訂價能力低的那一格就會往後排，如此而已。</p><p>不過爆料裡並列的那兩個原因，性質並不一樣，這個區分是我加的、原爆料沒有分這麼細。產能讓給 AI 加速器，那是有人做了決定，有決定就有可能改。記憶體缺貨不需要任何人決定要排擠誰，它是報價自己走出來的結果，而且它推高的是整個 PC 硬體的成本，不只顯示卡。前面那條靠誰改變主意就能扭轉，後面那條只能等供給補上來。要是最後只有後面那條成立，2028 這個時間點就跟 AI 沒什麼關係了，純粹是記憶體的事。</p><p>這句話聽起來很冷靜，它的後果卻一點都不抽象。五則裡面，只有這一則的結果會直接出現在一般人家裡那台電腦上。其他幾則的成本都藏在別的地方；只有這一則，收據會寄到個人手上，而且金額很好算：你想升級但升不了，或者升得起但要多付一截。</p><div class="note info flat"><p>什麼情況下我會收回上面這段。如果 AT2 明年真的如期出來，而且 DRAM 與 HBM 的報價從某一季開始往下走，那 RTX 60 跟 RDNA 5 落在 2028 就只是一次正常的產品週期延後，跟產能排擠沒什麼關係，上面整段推論就不成立。這件事要驗證不難，等一年看記憶體報價就知道了。在那之前，我對這個推論的信心，不會高過它所依據的那則論壇爆料。</p></div><blockquote><p>原文來源：<a href="https://wccftech.com/amd-and-nvidia-are-rumoredly-skipping-2027-for-next-gen-gpus/">Wccftech，2026-09-16</a> ／ <a href="https://www.notebookcheck.net/Nvidia-RTX-60-series-to-skip-2027-launch-just-like-most-of-AMD-s-RDNA-5.1401168.0.html">Notebookcheck</a></p></blockquote><h2 id="五、兩個國家掏錢，買的是檢查別人模型的能力"><a href="#五、兩個國家掏錢，買的是檢查別人模型的能力" class="headerlink" title="五、兩個國家掏錢，買的是檢查別人模型的能力"></a>五、兩個國家掏錢，買的是檢查別人模型的能力</h2><p>9 月 16 日，加拿大與德國在蒙特婁的 ALL IN 大會上宣布，共同資助 Yoshua Bengio 創辦的非營利組織 LawZero。</p><p>金額這一格又是幣別陷阱，而且是兩種幣別：加拿大出 CAD 150 million，德國出 EUR 100 million。PR 稿標題把總額寫成「up to $300M」，那是加幣口徑。所以別寫成「兩國各出 1.5 億美元」，那句話有兩個錯。兩筆都是「up to」，是最高承諾額，不是已經撥下去的錢。德國那筆還掛著一個條件：subject to notification by the European Commission，尚未定案。</p><p>宣布者的職稱照抄：加拿大是 The Honourable Evan Solomon，人工智慧與數位創新部長；德國是 Dr. Karsten Wildberger，聯邦數位轉型與政府現代化部長。其他數字：預計在加拿大創造 360 個全職職位，總部設在蒙特婁、將設德國辦公室，主權運算基礎設施的合作夥伴是 Hypertec 與 5C。</p><p>最容易得出的結論是「國家出的錢比公司少太多」。這個對比是真的，可是它不太重要，因為兩邊買的根本是不同的東西。一邊買產能——水泥、變電站、機櫃、未來四到六年的電。另一邊買查核能力，也就是讓一個不歸任何一家實驗室管的機構，長出足夠的技術實力去檢驗那些模型。</p><p>這裡有個尷尬的地方值得說出來：查核能力也要算力。要評估一個前沿模型，你得跑得動它、得有地方跑。新聞稿裡「主權運算基礎設施合作夥伴」那一行，其實是這件事能不能成立的前提。而在算力這條隊伍裡，一個拿著「up to」承諾額、其中一半還在等歐盟執委會的非營利組織，排在哪個位置？大概不會比消費級顯示卡好到哪去。</p><p>sovereign 這個字在標題裡，講的是不依賴別人的選項。但要不依賴，你得先有。</p><blockquote><p>原文來源：<a href="https://www.canada.ca/en/innovation-science-economic-development/news/2026/09/canada-and-germany-invest-in-lawzero-to-build-a-new-approach-to-safe-sovereign-ai.html">加拿大政府新聞稿，2026-09-16</a></p></blockquote><hr><p>回到開頭那個問題。</p><p>四到六年的工期一旦動土，就沒有「市場變了所以我們暫停」這個選項，水泥不會因為推論需求換了形狀而長成別的東西。先用煤跟天然氣頂著、等再生能源後補，也是同一種承諾：你把「以後再說」寫進了合約，而以後會發生什麼，簽約那天沒有人知道。</p><p>其他幾方都還站在原地。一輪還在談的募資，談到一半可以不談；一個「up to」的承諾額，可以不用到上限。連那張買不到的顯示卡也是：你今天沒付出任何東西，你只是還沒買。</p><p>則三是硬塞的。那場演說沒有人掏錢，沒有「買」這個動作；硬要收編它也做得到，把「法案還可以改」算成一種可選性就行，但那只用上了可不可逆那半邊，跟這筆錢買下什麼無關。它今天排在這裡，理由只有日期。</p><p>所以看這類新聞，有一個問題比金額好用：<strong>這筆錢買下的是一個東西，還是一個不能反悔的日期？</strong></p><p>買東西的，錢花完就結束了。買日期的，是把未來好幾年的可選性一次押掉，換一個現在看起來很大的位置。前者的風險寫在帳上，後者的風險寫在時間裡，而時間裡的風險不會出現在任何一份宣布稿上。</p><p>9 月 16 日這天，只有一方真的把日期押下去了。其他人手上都還留著一樣最容易被當成落後的東西：還沒決定。在一個四到六年後長什麼樣子沒人說得準的產業裡，還沒決定本身就是一個部位，而且是少數還能加碼、也還能退場的那一種。</p>]]>
    </content>
    <id>https://blog.longhopick.com/2026/09/17/AI-%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E%E6%91%98%E8%A6%81-20260917/</id>
    <link href="https://blog.longhopick.com/2026/09/17/AI-%E8%88%87%E7%A7%91%E6%8A%80%E6%96%B0%E8%81%9E%E6%91%98%E8%A6%81-20260917/"/>
    <published>2026-09-17T04:00:00.000Z</published>
    <summary>一份要蓋四到六年的租約、一輪還在談的募資、一場沒有時程的演說，還有一張可能要等到 2028 年的顯示卡。</summary>
    <title>AI 與科技新聞摘要 - 2026/09/17</title>
    <updated>2026-09-17T02:26:50.271Z</updated>
  </entry>
</feed>
