<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Codex on KnightLi的博客</title>
        <link>https://knightli.com/zh-tw/tags/codex/</link>
        <description>Recent content in Codex on KnightLi的博客</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-tw</language>
        <lastBuildDate>Sun, 31 May 2026 14:17:42 +0800</lastBuildDate><atom:link href="https://knightli.com/zh-tw/tags/codex/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>subagent 會多花多少 token？多 agent 成本與使用策略</title>
        <link>https://knightli.com/zh-tw/2026/05/31/subagent-multi-agent-token-cost/</link>
        <pubDate>Sun, 31 May 2026 14:17:42 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/31/subagent-multi-agent-token-cost/</guid>
        <description>&lt;p&gt;使用 subagent 或多 agent 工作流，通常都會增加 token 用量。差別不在於「會不會增加」，而在於增加多少、換來的並行效率和穩定性是否值得。&lt;/p&gt;
&lt;p&gt;如果任務很小，直接讓主 agent 完成通常更省。只有當任務可以清楚拆分，或需要獨立複查時，subagent 才更容易體現價值。&lt;/p&gt;
&lt;h2 id=&#34;subagent-不是更便宜的並行執行緒&#34;&gt;subagent 不是更便宜的並行執行緒
&lt;/h2&gt;&lt;p&gt;很多人第一次看到 subagent，會下意識把它理解成「並行執行緒」：主 agent 做一部分，subagent 做另一部分，速度變快，所以應該更划算。&lt;/p&gt;
&lt;p&gt;實際不是這樣。subagent 本質上也是一個獨立的模型呼叫。它需要讀任務說明、理解上下文、讀取檔案、分析問題，再輸出結果。也就是說，它不是主 agent 的免費副本，而是額外啟動了一條推理鏈路。&lt;/p&gt;
&lt;p&gt;所以使用 subagent 的核心判斷不是「能不能並行」，而是「並行帶來的時間節省、品質提升，是否值得額外 token 成本」。&lt;/p&gt;
&lt;h2 id=&#34;為什麼會增加-token&#34;&gt;為什麼會增加 token
&lt;/h2&gt;&lt;p&gt;一次 subagent 呼叫通常會額外消耗這些 token：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主 agent 寫給 subagent 的任務說明；&lt;/li&gt;
&lt;li&gt;傳遞給 subagent 的上下文；&lt;/li&gt;
&lt;li&gt;subagent 自己讀取檔案和分析問題；&lt;/li&gt;
&lt;li&gt;subagent 產生結果或修改說明；&lt;/li&gt;
&lt;li&gt;主 agent 回收結果後的複查、整合和驗證。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果多個 agent 讀取同一批大檔案，重複消耗會更明顯。尤其是程式碼庫分析、長文件翻譯、批量內容整理這類任務，如果拆分不好，token 會花在重複理解上下文上。&lt;/p&gt;
&lt;h2 id=&#34;重複讀取上下文是最大的-token-浪費&#34;&gt;重複讀取上下文是最大的 token 浪費
&lt;/h2&gt;&lt;p&gt;subagent 真正浪費 token 的地方，往往不是「多開了一個 agent」，而是多個 agent 反覆讀同一批材料。&lt;/p&gt;
&lt;p&gt;例如一個任務要處理 6 篇文章，如果 4 個 agent 都先讀完整站點結構、完整技能文件、完整文章列表，再各自處理一小塊內容，那麼並行會很貴。更好的做法是先由主 agent 確定邊界，再讓每個 subagent 只讀自己負責的文章目錄。&lt;/p&gt;
&lt;p&gt;更省 token 的拆法通常是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每個 agent 只負責一個明確目錄；&lt;/li&gt;
&lt;li&gt;給 subagent 的上下文越短越好；&lt;/li&gt;
&lt;li&gt;不讓多個 agent 重複做同一類探索；&lt;/li&gt;
&lt;li&gt;主 agent 最後統一複查，而不是讓每個 agent 都做全量複查；&lt;/li&gt;
&lt;li&gt;能用腳本統一檢查的部分，不交給多個 agent 反覆檢查。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;換句話說，subagent 的成本控制重點是邊界，而不是數量。&lt;/p&gt;
&lt;h2 id=&#34;大概會增加多少&#34;&gt;大概會增加多少
&lt;/h2&gt;&lt;p&gt;下面是一個粗略估算，實際消耗取決於上下文長度、檔案大小、任務複雜度和 agent 數量。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;場景&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;token 增加&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;單個 subagent 處理一個小任務&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;約 &lt;code&gt;1.2x - 2x&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;2-4 個 agent 並行處理可拆分任務&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;約 &lt;code&gt;2x - 5x&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;多個 agent 各自讀取大量檔案、做長分析&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;可能 &lt;code&gt;5x+&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;主 agent 和 subagent 重複讀同一批大檔案&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;浪費最明顯&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;這不是精確計費公式，只是經驗範圍。真正的消耗還要看每個 agent 是否需要讀完整檔案、是否需要長推理、是否會反覆等待和補充上下文。&lt;/p&gt;
&lt;h2 id=&#34;如何給-subagent-寫更省-token-的任務說明&#34;&gt;如何給 subagent 寫更省 token 的任務說明
&lt;/h2&gt;&lt;p&gt;任務說明越寬泛，subagent 越容易自己去探索上下文，token 消耗也越高。更省的寫法是把邊界寫清楚。&lt;/p&gt;
&lt;p&gt;一個好的 subagent 任務說明應該包含：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;只允許處理哪些檔案或目錄；&lt;/li&gt;
&lt;li&gt;哪些檔案只能讀，哪些檔案可以寫；&lt;/li&gt;
&lt;li&gt;已有檔案是否允許覆蓋；&lt;/li&gt;
&lt;li&gt;需要保留哪些欄位，比如 &lt;code&gt;date&lt;/code&gt;、&lt;code&gt;slug&lt;/code&gt;、&lt;code&gt;aliases&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;輸出時只回報什麼結果；&lt;/li&gt;
&lt;li&gt;不需要做哪些事情，比如不要跑完整建置、不要改無關檔案。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例如，處理翻譯時，不要只寫「把文章翻譯成多語言」。更省 token 的寫法是：「只處理 &lt;code&gt;content/post/2026/05/240&lt;/code&gt;，讀取 &lt;code&gt;index.zh-cn.md&lt;/code&gt;，只建立缺失的 &lt;code&gt;index.en.md&lt;/code&gt;、&lt;code&gt;index.zh-tw.md&lt;/code&gt;、&lt;code&gt;index.ja.md&lt;/code&gt;、&lt;code&gt;index.es.md&lt;/code&gt;，已存在則跳過，保留 &lt;code&gt;date&lt;/code&gt; 和 &lt;code&gt;slug&lt;/code&gt;。」&lt;/p&gt;
&lt;p&gt;這種說明更長一點，但能減少 subagent 自行猜測和重複探索，整體通常更省。&lt;/p&gt;
&lt;h2 id=&#34;按檔案目錄拆分比按語言步驟拆分更省&#34;&gt;按檔案/目錄拆分，比按語言/步驟拆分更省
&lt;/h2&gt;&lt;p&gt;如果是批量文章翻譯，按「文章目錄」拆通常比按「語言」拆更好。&lt;/p&gt;
&lt;p&gt;例如要翻譯 6 篇文章，每篇都要產生英文、繁體、日文、西語。更推薦讓一個 agent 負責一篇文章目錄內的所有語言，而不是讓一個 agent 負責所有英文、另一個負責所有日文。&lt;/p&gt;
&lt;p&gt;原因很簡單：一篇文章的 front matter、程式碼區塊、連結、表格和語義上下文只需要讀一次。如果按語言拆，多個 agent 會重複讀取同一篇源文，token 會被放大。&lt;/p&gt;
&lt;p&gt;同樣的邏輯也適用於程式碼任務。優先按模組、目錄、元件拆分，而不是按「先分析、再實作、再測試」這種步驟拆分。步驟拆分很容易讓每個 agent 都重新讀一遍上下文。&lt;/p&gt;
&lt;h2 id=&#34;什麼情況下值得用&#34;&gt;什麼情況下值得用
&lt;/h2&gt;&lt;p&gt;subagent 的價值主要在兩點：並行和獨立視角。&lt;/p&gt;
&lt;p&gt;適合使用的場景包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多篇文章批量翻譯；&lt;/li&gt;
&lt;li&gt;多個目錄可以獨立修改；&lt;/li&gt;
&lt;li&gt;前端、後端、測試可以明確分工；&lt;/li&gt;
&lt;li&gt;一個 agent 寫實作，另一個 agent 做風險複查；&lt;/li&gt;
&lt;li&gt;高風險修改需要第二視角檢查。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這類任務裡，token 會增加，但總耗時可能明顯下降，而且每個 agent 只盯一塊內容，注意力更集中。&lt;/p&gt;
&lt;h2 id=&#34;什麼時候值得用一個-agent-做複查&#34;&gt;什麼時候值得用一個 agent 做複查
&lt;/h2&gt;&lt;p&gt;複查型 agent 不一定總值得用。它適合風險高、影響面大、主 agent 容易遺漏細節的任務。&lt;/p&gt;
&lt;p&gt;比較值得加複查 agent 的情況包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;修改涉及登入、支付、權限、資料刪除；&lt;/li&gt;
&lt;li&gt;多語言內容會影響分類、URL、站內連結；&lt;/li&gt;
&lt;li&gt;大範圍重構後需要獨立找回歸風險；&lt;/li&gt;
&lt;li&gt;使用者明確要求 code review 或風險審查；&lt;/li&gt;
&lt;li&gt;主 agent 已經做了實作，但需要第二視角看邊界條件。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不值得加複查 agent 的情況也很明確：單檔小改、標題微調、簡單 front matter 修正、只跑一個命令。這些任務主 agent 自查就夠了。&lt;/p&gt;
&lt;h2 id=&#34;什麼情況下不值得用&#34;&gt;什麼情況下不值得用
&lt;/h2&gt;&lt;p&gt;不適合使用 subagent 的場景很常見：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;單檔小改；&lt;/li&gt;
&lt;li&gt;簡單問答；&lt;/li&gt;
&lt;li&gt;只需要跑一個命令；&lt;/li&gt;
&lt;li&gt;改動範圍很小；&lt;/li&gt;
&lt;li&gt;任務不能清楚拆分；&lt;/li&gt;
&lt;li&gt;subagent 必須反覆等待主 agent 提供上下文。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這類任務用 subagent 往往只是增加開銷。主 agent 直接處理更快，也更省 token。&lt;/p&gt;
&lt;h2 id=&#34;我的預設策略省-token-優先風險任務才加複查&#34;&gt;我的預設策略：省 token 優先，風險任務才加複查
&lt;/h2&gt;&lt;p&gt;如果目標是盡量節省 token，可以採用下面這套策略：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;小任務：不用 subagent。&lt;/li&gt;
&lt;li&gt;中等任務：不用 subagent。&lt;/li&gt;
&lt;li&gt;大批量任務：預設也不用 subagent，除非使用者明確要並行提速。&lt;/li&gt;
&lt;li&gt;高風險任務：可以多用一個 agent 做複查，用 token 換穩定性。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這套策略更偏保守。它犧牲了一部分並行速度，但能減少重複讀取上下文和重複推理帶來的 token 消耗。&lt;/p&gt;
&lt;p&gt;如果任務很大但不高風險，我也會優先考慮腳本、批量檢查和本地結構化處理。只有當拆分非常清楚，或者使用者明確希望並行提速時，才更適合引入多個 agent。&lt;/p&gt;
&lt;h2 id=&#34;更均衡的策略&#34;&gt;更均衡的策略
&lt;/h2&gt;&lt;p&gt;如果既想控制成本，又不想完全放棄並行，可以採用折衷方案：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;預設主 agent 直接做；&lt;/li&gt;
&lt;li&gt;只有任務能按檔案或目錄明確拆分時才考慮 subagent；&lt;/li&gt;
&lt;li&gt;subagent 只讀取自己負責的檔案；&lt;/li&gt;
&lt;li&gt;不讓多個 agent 同時讀同一批大檔案；&lt;/li&gt;
&lt;li&gt;主 agent 最後統一複查關鍵欄位、測試結果和 Git diff；&lt;/li&gt;
&lt;li&gt;高風險任務才增加一個獨立複查 agent。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這能避免「為了並行而並行」。subagent 應該服務於明確的效率或品質目標，而不是成為預設動作。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;subagent 和多 agent 一定會增加 token 用量。單個 subagent 可能只是增加一點，多個 agent 並行時則可能成倍增加。&lt;/p&gt;
&lt;p&gt;是否值得用，取決於任務本身：如果任務能清楚拆分，或者風險高到需要獨立複查，額外 token 可能是值得的；如果只是單檔小改、簡單問答或常規檢查，直接由主 agent 完成更省。&lt;/p&gt;
&lt;p&gt;一句話總結：&lt;strong&gt;小任務省 token，大任務看拆分，高風險才用額外 agent 換穩定性。&lt;/strong&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>GPT-5.6 爆料：150 萬 token 上下文視窗意味著什麼</title>
        <link>https://knightli.com/zh-tw/2026/05/27/gpt-5-6-rumor-1-5m-context-window/</link>
        <pubDate>Wed, 27 May 2026 13:55:06 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/27/gpt-5-6-rumor-1-5m-context-window/</guid>
        <description>&lt;p&gt;2026 年 5 月 26 日，有爆料稱多名開發者在 OpenAI Codex 後端日誌中發現了尚未官宣的 GPT-5.6 相關痕跡，其中一個內部代號為 &lt;code&gt;iris-alpha&lt;/code&gt;，傳聞支援 150 萬 token 上下文視窗，並可能在 2026 年 6 月發布。&lt;/p&gt;
&lt;p&gt;這類資訊目前仍屬於爆料，不等於 OpenAI 官方發布。更穩妥的看法是：它展示了下一代大模型可能繼續沿著「更長上下文、更強程式碼能力、更好前端生成」幾個方向推進。&lt;/p&gt;
&lt;h2 id=&#34;爆料裡提到哪些模型代號&#34;&gt;爆料裡提到哪些模型代號
&lt;/h2&gt;&lt;p&gt;報導提到，開發者在相關日誌中看到的不只 &lt;code&gt;iris-alpha&lt;/code&gt;，還包括 &lt;code&gt;ember-alpha&lt;/code&gt; 和 &lt;code&gt;beacon-alpha&lt;/code&gt; 等版本。&lt;/p&gt;
&lt;p&gt;這些名字現階段更像內部測試代號。它們是否都屬於 GPT-5.6 系列、最終會不會對應公開 API 模型、發布時間是否會改變，都還沒有官方確認。&lt;/p&gt;
&lt;p&gt;所以不要急著把這些代號當成最終產品名。真正值得關注的是它們暴露出來的能力方向。&lt;/p&gt;
&lt;h2 id=&#34;150-萬-token-上下文為什麼重要&#34;&gt;150 萬 token 上下文為什麼重要
&lt;/h2&gt;&lt;p&gt;報導裡最醒目的數字是 150 萬 token 上下文視窗。&lt;/p&gt;
&lt;p&gt;爆料中給出的對比是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;目前 GPT-5.5 API 為 105 萬 token&lt;/li&gt;
&lt;li&gt;Codex OAuth 渠道約為 40 萬 token&lt;/li&gt;
&lt;li&gt;GPT-5.6 傳聞提升到 150 萬 token&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上下文視窗決定模型單次能接收和利用多少資訊。它包括使用者輸入、歷史對話、系統提示、檔案內容、日誌、程式碼 diff、測試輸出等。&lt;/p&gt;
&lt;p&gt;如果這個數字屬實，GPT-5.6 對幾類任務會更有意義：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;閱讀大型程式碼倉庫&lt;/li&gt;
&lt;li&gt;分析長篇合約或技術文件&lt;/li&gt;
&lt;li&gt;連續追蹤複雜專案&lt;/li&gt;
&lt;li&gt;保留更長的 agent 工作歷史&lt;/li&gt;
&lt;li&gt;在一次任務裡處理更多檔案和更多測試回饋&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但上下文視窗變大，不代表模型一定「更聰明」。它只是讓模型能看到更多材料。模型是否能從長上下文裡準確檢索、歸納、保持目標一致，還要看訓練、推理策略和工具調用能力。&lt;/p&gt;
&lt;h2 id=&#34;真實世界測試的訊號&#34;&gt;真實世界測試的訊號
&lt;/h2&gt;&lt;p&gt;報導還提到，有開發者在輔助工具 OpenCode 中做了較極端的真實世界測試：當輸入達到約 90 萬 token 時，模型仍能流暢回應，甚至處理超過 105 萬 token 的請求。&lt;/p&gt;
&lt;p&gt;如果這個回饋準確，它說明 OpenAI 可能不僅在擴展理論視窗，也在處理長輸入下的回應穩定性。&lt;/p&gt;
&lt;p&gt;對 AI 程式設計來說，這點比「視窗數字」本身更重要。開發任務裡的上下文往往不是乾淨的長文本，而是程式碼、日誌、錯誤堆疊、依賴檔案、設定檔和使用者指令混在一起。模型不僅要裝得下，還要找得準。&lt;/p&gt;
&lt;h2 id=&#34;前端介面生成能力也被提到&#34;&gt;前端介面生成能力也被提到
&lt;/h2&gt;&lt;p&gt;這次爆料還提到了 GPT-5.6 的前端生成能力。&lt;/p&gt;
&lt;p&gt;據報導，爆料截圖中模型在幾乎沒有詳細提示詞的情況下，生成了一個名為 &lt;code&gt;Lumen Notes&lt;/code&gt; 的極簡記事應用介面。報導強調的表現包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;柵格布局更成熟&lt;/li&gt;
&lt;li&gt;配色更克制&lt;/li&gt;
&lt;li&gt;字體層級更清晰&lt;/li&gt;
&lt;li&gt;導航結構更完整&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果這類能力穩定，AI 程式設計模型的價值會繼續從「能寫程式碼」轉向「能生成更接近可用產品的介面」。這也是 Codex、Claude Code、Cursor、Gemini CLI 等工具最近都在推進的方向：不只是補函式，而是從需求到介面、測試、修復形成閉環。&lt;/p&gt;
&lt;h2 id=&#34;還提到了哪些競爭模型&#34;&gt;還提到了哪些競爭模型
&lt;/h2&gt;&lt;p&gt;同一批爆料還提到，Anthropic 的 Claude Sonnet 4.8、Google 的 Gemini 3.5 Pro，以及 xAI 的 Grok 5，都可能瞄準 2026 年 6 月發布。&lt;/p&gt;
&lt;p&gt;這部分同樣要按傳聞看待。即便多個模型確實都在 6 月前後更新，最終能力也要等官方文件、API 實測和真實開發任務驗證。&lt;/p&gt;
&lt;p&gt;不過大方向很清楚：模型廠商的競爭已經不只是聊天能力，而是更長上下文、更強工具調用、更穩的程式碼編輯、更好的 UI 生成，以及更適合 agent 長任務的可靠性。&lt;/p&gt;
&lt;h2 id=&#34;我的判斷&#34;&gt;我的判斷
&lt;/h2&gt;&lt;p&gt;如果 GPT-5.6 的 150 萬 token 上下文視窗最終成真，它對 Codex 這類程式設計 agent 的意義會比普通聊天更大。&lt;/p&gt;
&lt;p&gt;因為 agent 程式設計天然會消耗大量上下文：讀倉庫、跑測試、看日誌、比較 diff、保留使用者偏好、連續修復問題。上下文越長，agent 越有機會在一次任務裡保留完整線索。&lt;/p&gt;
&lt;p&gt;但我更關心三個實際問題：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;長上下文下的定位能力是否穩定。&lt;/li&gt;
&lt;li&gt;大量日誌和程式碼混合輸入時，模型是否會被噪音帶偏。&lt;/li&gt;
&lt;li&gt;API、Codex、ChatGPT、OAuth 等不同入口是否會給出一致的上下文上限。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以這條爆料可以關注，但不適合過早下結論。等 OpenAI 官方發布模型卡、API 文件和真實價格之後，再判斷 GPT-5.6 是否真的適合大型程式碼倉庫和長任務 agent 工作流，會更穩。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Codex 官方文章解讀：如何把 Codex 用到極致</title>
        <link>https://knightli.com/zh-tw/2026/05/27/getting-the-most-out-of-codex/</link>
        <pubDate>Wed, 27 May 2026 08:21:18 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/27/getting-the-most-out-of-codex/</guid>
        <description>&lt;p&gt;多數開發者第一次使用 Codex，通常是從程式碼任務開始：閱讀倉庫、修改 diff、執行測試、打開 pull request。&lt;/p&gt;
&lt;p&gt;這仍然是 Codex 的核心場景。但電腦上的很多工作本來就被程式碼和工具包圍：執行 shell 命令、瀏覽網頁、呼叫 API、匯出文件、回應訊息、觸發自動化。隨著這些能力逐漸接入 Codex，它就不再只是狹義的程式碼助手，而更像一個幫你完成電腦工作的系統。&lt;/p&gt;
&lt;p&gt;Codex app 讓這種變化變得更具體。一個 thread 可以保留上下文、呼叫工具、展示產物，並在多輪提示之間持續推進，而不是每次對話都重新開始。&lt;/p&gt;
&lt;p&gt;想更充分地使用 Codex，關鍵是把這些能力組合起來：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;持久執行緒，用來保存長期上下文&lt;/li&gt;
&lt;li&gt;語音輸入、steering 和 queuing，讓使用者仍然掌控過程&lt;/li&gt;
&lt;li&gt;browser、computer use、MCP servers 和 connectors，讓 Codex 走出倉庫&lt;/li&gt;
&lt;li&gt;thread automations 和 Goals，讓任務在使用者離開後繼續推進&lt;/li&gt;
&lt;li&gt;側邊欄，用來審閱程式碼、文件、投影片、網頁和其他產物&lt;/li&gt;
&lt;li&gt;共享記憶，把重要上下文寫到執行緒之外&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;持久執行緒&#34;&gt;持久執行緒
&lt;/h2&gt;&lt;p&gt;Durable threads 指的是能在多次會話之間保留工作上下文的長執行緒。&lt;/p&gt;
&lt;p&gt;Pinned threads 是一種很實用的入口。它適合放那些會反覆回來的工作流程，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Chief of Staff 執行緒&lt;/li&gt;
&lt;li&gt;發布執行緒&lt;/li&gt;
&lt;li&gt;文件審閱執行緒&lt;/li&gt;
&lt;li&gt;外部監控執行緒&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些不是臨時聊天，而是持續存在的工作空間。Codex 可以在後續繼續回到同一個執行緒，沿用之前的決策、偏好和背景資訊，避免每次都從零重建上下文。&lt;/p&gt;
&lt;p&gt;快捷鍵也讓它更順手。&lt;code&gt;Command-1&lt;/code&gt; 到 &lt;code&gt;Command-9&lt;/code&gt; 可以直接跳轉到已保存的執行緒。&lt;/p&gt;
&lt;h2 id=&#34;語音輸入&#34;&gt;語音輸入
&lt;/h2&gt;&lt;p&gt;語音輸入的價值在於，它能捕捉還沒有被整理成正式文字的想法。&lt;/p&gt;
&lt;p&gt;Codex 內建語音輸入。它特別適合那些說起來很自然、打字時卻很彆扭的模糊起點：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;我记得 Slack 里好像有个叫 Ben 的人提过这个。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;具体细节我不记得了。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;帮我去找一下。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;對於一個能搜尋、整理上下文並彙報結果的 agent 來說，這通常已經足夠開始。&lt;/p&gt;
&lt;p&gt;語音也適合兩三分鐘的想法傾倒。會議轉錄、口述規劃筆記、未整理的原始記錄，往往比一句摘要更有用，因為它們保留了不確定性、重點和沒說完的思路。&lt;/p&gt;
&lt;h2 id=&#34;steering-和-queuing&#34;&gt;Steering 和 queuing
&lt;/h2&gt;&lt;p&gt;語音和顯式控制結合起來時，會更有用。&lt;/p&gt;
&lt;p&gt;Steering 指的是在 Codex 任務執行過程中插入新的方向，讓它在當前步驟結束前改道。&lt;/p&gt;
&lt;p&gt;例如在審閱網頁時，使用者可以一邊在側邊欄標註，一邊打斷當前任務：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;这里再小一点。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;这两个元素之间的间距不对。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;这句文案写错了。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Queuing 則不同。它不打斷當前任務，而是把下一步工作排到佇列裡：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;这项工作完成后，把预览链接发给 Slack 里的 reviewer。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Steering 改變 Codex 現在正在做什麼。Queuing 改變它接下來應該做什麼。兩者都讓使用者在任務展開時仍然靠近現場。&lt;/p&gt;
&lt;h2 id=&#34;工具和可觸達範圍&#34;&gt;工具和可觸達範圍
&lt;/h2&gt;&lt;p&gt;執行緒有了連續性之後，下一個問題就是：它能操作什麼？&lt;/p&gt;
&lt;p&gt;Codex 可以一層層向外擴展：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$browser&lt;/code&gt;：適合側邊欄裡的網頁檢查、標註和 review&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@chrome&lt;/code&gt;：適合依賴使用者 Chrome 登入狀態的瀏覽器工作流程&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@computer&lt;/code&gt;：適合只能透過桌面 GUI 完成的任務&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;MCP servers 和 connectors 把同樣的思路擴展到更多工作流程中。Slack、Gmail、Calendar 很重要，因為很多任務最初不是以程式碼形式出現，而是以訊息、郵件和日程問題出現。&lt;/p&gt;
&lt;p&gt;Skills 則適合固化重複工作。當某個流程已經被證明有用，就可以把它打包成 skill，讓 Codex 下次不必重新學習這套步驟。&lt;/p&gt;
&lt;h2 id=&#34;從任何地方繼續工作&#34;&gt;從任何地方繼續工作
&lt;/h2&gt;&lt;p&gt;Codex mobile app 改變了使用者必須坐在電腦前的時間。&lt;/p&gt;
&lt;p&gt;一個任務可以在 Mac 上開始，因為檔案、權限和本機環境都在那裡；隨後使用者離開桌面，只用手機繼續確認、補充或改方向。&lt;/p&gt;
&lt;p&gt;這在很多小場景裡很有價值：Codex 跑長任務時，使用者可以離開座位；如果它需要確認，可以在外面回覆；如果方向錯了，也能及時 redirect。真正留在原地的是本機環境，而不是使用者本人。&lt;/p&gt;
&lt;h2 id=&#34;自動化&#34;&gt;自動化
&lt;/h2&gt;&lt;p&gt;Automations 可以按計劃執行 Codex 工作。&lt;/p&gt;
&lt;p&gt;如果一個週期任務應該從某個 workspace 重新開始，例如日報或常規結庫檢查，可以用 scheduled automation。如果調度應該回到一個已有對話，並沿用它的上下文，就更適合 thread automation。&lt;/p&gt;
&lt;p&gt;Thread automations 更像心跳式喚醒：按固定節奏回到同一個 Codex thread。&lt;/p&gt;
&lt;p&gt;Pinned threads 需要使用者主動回來，而 thread automation 可以每幾分鐘或每幾小時檢查一次，持續執行到滿足條件為止，並隨時間調整節奏。&lt;/p&gt;
&lt;p&gt;例如，一個 Chief of Staff 執行緒可以每 30 分鐘執行一次：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;每 30 分钟检查 Slack 和 Gmail，找出需要我注意但还没有回复的消息。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;帮我判断哪些最重要。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;如果有人问我问题，尽可能深入研究答案，并替我起草回复，但不要发送。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;使用者回來時，最耗時的上下文收集往往已經完成。真正要不要發送，仍然由人決定。&lt;/p&gt;
&lt;p&gt;Thread automations 也適合反饋循環。它可以定期查看 pull request 評論、Google Docs 評論或 Slack 回覆，在使用者離開時繼續推進周邊工作。&lt;/p&gt;
&lt;p&gt;比如一個動畫工作流程，reviewer 在 Slack 裡發來影片反饋，thread automation 定時檢查執行緒；如果有新評論，就重新渲染版本，並在同一個 Slack thread 裡回覆 reviewer。如果某個整合無法完成最終上傳，桌面自動化還可以透過 GUI 補上最後一步。&lt;/p&gt;
&lt;p&gt;這個循環會跨過 Slack、程式碼庫和桌面應用，但對使用者來說仍然留在同一個工作流程裡。&lt;/p&gt;
&lt;h2 id=&#34;goals&#34;&gt;Goals
&lt;/h2&gt;&lt;p&gt;Goals 最適合那些有明確終點、並且 agent 可以持續推進的任務。&lt;/p&gt;
&lt;p&gt;一個較弱的 goal 可能是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;实现这个 Markdown 文件里的计划。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;更強的 goal 會有可衡量的完成標準。&lt;/p&gt;
&lt;p&gt;例如，把一個內部工具從 Python 遷移到 Rust 時，可以先建好新目錄，再把目標說清楚：新實作只有在單元測試通過後才算完成。&lt;/p&gt;
&lt;p&gt;Goal 本質上是持續執行加驗證器。使用者需要定義結果、停止條件，以及判斷 Codex 是否更接近目標的訊號。&lt;/p&gt;
&lt;p&gt;常見的驗證器包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;測試套件&lt;/li&gt;
&lt;li&gt;benchmark&lt;/li&gt;
&lt;li&gt;bug reproduction&lt;/li&gt;
&lt;li&gt;validation matrix&lt;/li&gt;
&lt;li&gt;必須持續通過的端到端工作流程&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;任務可以有野心，但沒有驗證條件時，它更像願望，而不是 goal。&lt;/p&gt;
&lt;h2 id=&#34;側邊欄&#34;&gt;側邊欄
&lt;/h2&gt;&lt;p&gt;側邊欄把工作產物放在生成它的對話旁邊。使用者不必匯出檔案、切換上下文，再回頭描述問題。產物可能是程式碼，也可能是 deck、PDF、網頁、表格，或者工作過程中生成的其他 artifact。&lt;/p&gt;
&lt;p&gt;它特別適合四類工作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;檢查 artifact&lt;/li&gt;
&lt;li&gt;標註需要修改的地方&lt;/li&gt;
&lt;li&gt;操作網頁介面&lt;/li&gt;
&lt;li&gt;審閱變更&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Markdown、表格、資料表、文件和投影片都可以直接在側邊欄裡看。使用者可以檢查、標註、修改，而不用把這個過程變成另一輪交接。&lt;/p&gt;
&lt;p&gt;如果是 deck 或 PDF，它可以一直停在產生它的 thread 旁邊，隨時接受 review 和修復。&lt;/p&gt;
&lt;p&gt;瀏覽器也是類似的工作面。Codex 可以打開渲染後的頁面，檢查它，回應使用者在頁面上的標註，並繼續修復同一個對象。網頁既是輸出結果，也是控制表面。&lt;/p&gt;
&lt;p&gt;這些表面尤其適合放在側邊欄裡：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;index.html&lt;/code&gt; 這種輕量靜態 artifact&lt;/li&gt;
&lt;li&gt;Storybook&lt;/li&gt;
&lt;li&gt;Remotion Studio&lt;/li&gt;
&lt;li&gt;瀏覽器投影片&lt;/li&gt;
&lt;li&gt;資料分析應用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一個單獨的 &lt;code&gt;index.html&lt;/code&gt; 檔案就可以成為長期存在的互動 artifact，不一定需要伺服器。Thread automations 也可以定期刷新靜態 artifact，讓使用者回來時看到新的結果。&lt;/p&gt;
&lt;h2 id=&#34;共享記憶&#34;&gt;共享記憶
&lt;/h2&gt;&lt;p&gt;長執行緒很有用，但重要上下文不應該只存在於對話記錄裡。&lt;/p&gt;
&lt;p&gt;Shared memory 指的是把持久上下文存放在執行緒之外，讓未來的工作可以從明確、可審閱的地方繼續。&lt;/p&gt;
&lt;p&gt;一種穩定做法是把持久執行緒錨定在 Obsidian vault 裡。實際形態可以很簡單：一組普通檔案，方便檢查、編輯、移動和長期保存。團隊可以把它放在 cloud storage、Git、Dropbox、Google Drive 或其他同步層裡。&lt;/p&gt;
&lt;p&gt;一個 vault 可能長這樣：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;vault/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── TODO.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── people/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── projects/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── agent/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── notes/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;頂層的 &lt;code&gt;AGENTS.md&lt;/code&gt; 可以說明 Codex 應該如何維護這個工作空間：什麼資訊要寫下來，寫到哪裡，什麼時候不要製造噪音。&lt;/p&gt;
&lt;p&gt;一個實用的 &lt;code&gt;AGENTS.md&lt;/code&gt; 可以這樣寫：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; Treat ~/vault as durable work memory.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; Prefer canonical notes over note sprawl.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; Route TODOs, people, projects, daily summaries, and scratch notes explicitly.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; Preserve decisions, blockers, owners, dates, and useful links.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; If nothing meaningful changed, do not churn the vault.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;不要照抄某個 vault 結構。更重要的是教會 agent：長期上下文應該放在哪裡，哪些資訊值得保留，什麼時候不應該反覆改動檔案。&lt;/p&gt;
&lt;p&gt;倉庫存放程式碼。Vault 存放滾動上下文：相關人員、發生了什麼、哪裡卡住、誰負責、下一步是什麼，以及那些如果不寫下來就會在會話之間消失的細節。&lt;/p&gt;
&lt;p&gt;Codex 也有第一方記憶能力，可以在 &lt;code&gt;Settings &amp;gt; Personalization &amp;gt; Memories&lt;/code&gt; 中配置。它適合記錄偏好、重複工作流程和常見卡點，但它更適合作為顯式 written context 的補充，而不是替代品。Chronicle 也在同一個方向上推進：從最近的螢幕上下文中幫助 Codex 建立記憶。&lt;/p&gt;
&lt;h2 id=&#34;從程式碼向外擴展&#34;&gt;從程式碼向外擴展
&lt;/h2&gt;&lt;p&gt;Codex 仍然從程式碼開始。但程式碼周圍的更多工作，現在也能被同一個系統觸達：MCP servers、瀏覽器介面、桌面控制、thread automations 和可審閱 artifact。&lt;/p&gt;
&lt;p&gt;這改變了使用 Codex 的控制方式。Steering 用來打斷正在進行的工作。Queuing 用來排下一步。Thread automations 讓執行緒在使用者離開後繼續活動。Goals 給長期任務加上明確終點和驗證訊號。&lt;/p&gt;
&lt;p&gt;當這些能力連起來時，Codex 就能把一個工作流程從指令推進到執行，再推進到 artifact review。即使任務已經離開程式碼倉庫，它仍然可以留在同一個系統裡完成。&lt;/p&gt;
&lt;p&gt;原文連結：&lt;a class=&#34;link&#34; href=&#34;https://x.com/jxnlco/status/2057153744630890620&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Getting the most out of Codex&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Codex Goal 設定目標失敗：Failed to set goal 怎麼處理</title>
        <link>https://knightli.com/zh-tw/2026/05/27/codex-goal-failed-to-set-goal-config-toml/</link>
        <pubDate>Wed, 27 May 2026 08:17:57 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/27/codex-goal-failed-to-set-goal-config-toml/</guid>
        <description>&lt;p&gt;最近有使用者回饋，使用 Codex Goal 時會立刻出現 &lt;code&gt;Failed to set goal&lt;/code&gt; 或「設定目標失敗」的錯誤。這個錯誤和 prompt 長短無關，在 Codex 應用程式和 VS Code 擴充套件裡都可能出現。&lt;/p&gt;
&lt;p&gt;從討論裡的回饋來看，這個問題更像是本機功能開關或設定狀態異常，而不是目標內容本身寫錯了。&lt;/p&gt;
&lt;h2 id=&#34;先檢查-goals-功能開關&#34;&gt;先檢查 goals 功能開關
&lt;/h2&gt;&lt;p&gt;最直接的處理方法，是檢查 Codex 的設定檔：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;~/&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;codex&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;toml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;確認裡面有 &lt;code&gt;[features]&lt;/code&gt; 段，並開啟 &lt;code&gt;goals&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;features&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;goals&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果已經有 &lt;code&gt;[features]&lt;/code&gt;，只需要在該段下面補上 &lt;code&gt;goals = true&lt;/code&gt;。如果沒有這個段，就新建一個。&lt;/p&gt;
&lt;p&gt;改完以後，重新啟動 Codex 應用程式或 VS Code 擴充套件，再重新嘗試設定 Goal。&lt;/p&gt;
&lt;h2 id=&#34;如果還有問題檢查設定目錄&#34;&gt;如果還有問題，檢查設定目錄
&lt;/h2&gt;&lt;p&gt;討論裡也有人提到，&lt;code&gt;.codex&lt;/code&gt; 目錄裡的快取或暫存檔異常時，也可能觸發類似問題。&lt;/p&gt;
&lt;p&gt;比較穩妥的處理順序是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先備份 &lt;code&gt;~/.codex/config.toml&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;關閉 Codex 相關應用程式。&lt;/li&gt;
&lt;li&gt;暫時移走或重新命名 &lt;code&gt;~/.codex&lt;/code&gt; 目錄。&lt;/li&gt;
&lt;li&gt;重新打開 Codex，讓它重建設定目錄。&lt;/li&gt;
&lt;li&gt;再把原來的 &lt;code&gt;config.toml&lt;/code&gt; 裡需要的設定合併回來。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;不要直接刪除設定目錄，尤其是裡面可能有你手動維護的設定、技能、會話或其他本機狀態。&lt;/p&gt;
&lt;h2 id=&#34;windows-上還要留意安全軟體&#34;&gt;Windows 上還要留意安全軟體
&lt;/h2&gt;&lt;p&gt;也有回饋提到，Windows Defender 可能會把 &lt;code&gt;config.toml&lt;/code&gt; 當成可疑檔案。這不一定是所有人的原因，但如果你在 Windows 上遇到同樣問題，可以順手檢查一下安全軟體的隔離記錄。&lt;/p&gt;
&lt;p&gt;如果設定檔被隔離、改名或阻止存取，Codex 讀取不到功能開關，也可能表現為 Goal 無法啟用。&lt;/p&gt;
&lt;h2 id=&#34;判斷是不是-prompt-的問題&#34;&gt;判斷是不是 prompt 的問題
&lt;/h2&gt;&lt;p&gt;一個簡單判斷方法是：用極短目標測試。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;修復一個測試失敗
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果極短目標也立刻報 &lt;code&gt;Failed to set goal&lt;/code&gt;，基本就不是 prompt 寫法問題，而是本機設定、功能開關、擴充套件狀態或快取目錄問題。&lt;/p&gt;
&lt;p&gt;如果只有很長、很複雜的目標會失敗，再考慮是否是目標內容太複雜、包含特殊連結、欄位格式不被 UI 接受。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;Codex Goal 的 &lt;code&gt;Failed to set goal&lt;/code&gt; 可以按這個順序排查：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;檢查 &lt;code&gt;~/.codex/config.toml&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;[features]&lt;/code&gt; 下加入 &lt;code&gt;goals = true&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;重新啟動 Codex 應用程式或 VS Code 擴充套件。&lt;/li&gt;
&lt;li&gt;仍失敗時，備份設定後重建 &lt;code&gt;~/.codex&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;Windows 使用者額外檢查 Defender 或安全軟體是否誤攔截設定檔。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這個問題的重點不是「目標怎麼寫」，而是先確認 Goal 功能本身是否在本機設定裡正常啟用。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Codex Goal 深度解析：讓 AI Agent 連續工作數小時的目標驅動工作流</title>
        <link>https://knightli.com/zh-tw/2026/05/26/codex-goal-persistent-goals-ai-agent-long-running-workflow/</link>
        <pubDate>Tue, 26 May 2026 23:44:37 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/26/codex-goal-persistent-goals-ai-agent-long-running-workflow/</guid>
        <description>&lt;p&gt;瀏覽器、終端和 IDE 裡的 AI Agent 已經越來越會寫程式了，但很多人真正遇到的問題不是「它不會做」，而是「它做一半就說完成了」。&lt;/p&gt;
&lt;p&gt;簡單 ticket 很適合交給 coding agent：修一個按鈕、補一個介面、改一段文案、加一個測試。目標清楚，邊界很小，驗證方式也直接。但一旦任務變成大型遷移、跨模組重構、測試套件修復、依賴升級、prompt eval 優化，Agent 就很容易出現一種典型問題：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;它完成了一個看起來合理的中間狀態，然後過早停下。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Codex Goal / Persistent Goals 這類能力要解決的，正是這個「提前收工」問題。它的重點不是讓 Agent 多跑幾輪，而是讓 Agent 圍繞一個明確目標持續推進，直到滿足可驗證的完成標準。&lt;/p&gt;
&lt;h2 id=&#34;codex-goal-解決的不是循環而是停止條件&#34;&gt;Codex Goal 解決的不是循環，而是停止條件
&lt;/h2&gt;&lt;p&gt;很多長任務自動化會從一個粗糙方案開始：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;繼續檢查程式碼，修復問題，直到沒有錯誤。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;或者更機械一點：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;循環 10 次：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1. 執行測試
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2. 讓模型修復失敗
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;3. 再執行測試
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這類 rough loop 看起來能讓 Agent 工作更久，但它有兩個硬傷：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;它不知道什麼時候真的該停。&lt;/li&gt;
&lt;li&gt;它也不知道「沒有繼續報錯」是否等於「任務完成」。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Codex Goal 的關鍵不是循環次數，而是 goal、state、judge stop condition 三件事。也就是說，Agent 需要知道這次工作的目標是什麼，目前已經完成到哪裡，以及什麼證據能證明任務真的結束了。&lt;/p&gt;
&lt;p&gt;這也是長任務 Agent 的核心分水嶺：不是「多執行幾步」，而是「能不能判斷自己還差什麼」。&lt;/p&gt;
&lt;h2 id=&#34;goal-和普通-prompt-的區別&#34;&gt;Goal 和普通 prompt 的區別
&lt;/h2&gt;&lt;p&gt;普通 prompt 更像一次性指令：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;把這個專案的測試修好。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Goal prompt 則更像一份小型任務合約：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;目標：修復目前倉庫中失敗的測試。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;範圍：只修改 src/ 和 tests/，不要改建置腳本。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;完成標準：npm test 全部通過，且新增修改不引入 lint 錯誤。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;驗證命令：npm test &amp;amp;&amp;amp; npm run lint。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;失敗處理：如果超過 3 次仍無法修復，輸出剩餘失敗用例、已嘗試方案和阻塞點。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;輸出：總結修改檔案、修復原因、驗證結果。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;兩者最大的差別在於，Goal prompt 把「完成」定義清楚了。&lt;/p&gt;
&lt;p&gt;如果沒有 definition of done，Agent 很容易把「我改了程式碼」誤判成「我完成了任務」。如果有清晰的完成標準，Agent 就必須圍繞測試、日誌、diff、建置結果、eval 分數這些外部證據繼續推進。&lt;/p&gt;
&lt;h2 id=&#34;為什麼-llm-judge-stop-condition-很關鍵&#34;&gt;為什麼 LLM judge stop condition 很關鍵
&lt;/h2&gt;&lt;p&gt;長任務裡最難的不是讓 Agent 執行命令，而是讓它判斷：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;現在是否真的完成了？&lt;/li&gt;
&lt;li&gt;是否只是通過了局部測試？&lt;/li&gt;
&lt;li&gt;是否修了一個問題，卻引入了另一個問題？&lt;/li&gt;
&lt;li&gt;是否需要繼續搜尋、繼續執行驗證、繼續回滾某個方向？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這就是 LLM judge stop condition 的價值。&lt;/p&gt;
&lt;p&gt;理想狀態下，Agent 不應該只看「最後一個命令是否退出碼為 0」。它還應該綜合判斷：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用者給出的完成標準是否全部滿足；&lt;/li&gt;
&lt;li&gt;修改是否限定在允許範圍內；&lt;/li&gt;
&lt;li&gt;測試、lint、build、eval 是否都跑過；&lt;/li&gt;
&lt;li&gt;失敗日誌是否還有未處理項；&lt;/li&gt;
&lt;li&gt;是否存在明顯的副作用和風險；&lt;/li&gt;
&lt;li&gt;最終輸出是否能讓人類快速複核。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;換句話說，judge 不只是「判定成功」，還要防止 Agent 自我安慰式收尾。&lt;/p&gt;
&lt;h2 id=&#34;哪些任務適合交給-goal&#34;&gt;哪些任務適合交給 Goal
&lt;/h2&gt;&lt;p&gt;Codex Goal / Persistent Goals 更適合那些需要多輪探索和驗證的複雜 coding work，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;程式碼遷移：從舊框架遷到新框架，從 CommonJS 遷到 ESM，從舊 API 遷到新 API。&lt;/li&gt;
&lt;li&gt;大型重構：拆分模組、整理邊界、替換重複實作、降低複雜度。&lt;/li&gt;
&lt;li&gt;測試修復：連續分析失敗用例，定位原因，修復後反覆驗證。&lt;/li&gt;
&lt;li&gt;依賴升級：升級框架、SDK、建置工具，同時處理 breaking changes。&lt;/li&gt;
&lt;li&gt;Prompt eval 優化：執行評測，分析失敗樣本，調整 prompt 或工具呼叫策略。&lt;/li&gt;
&lt;li&gt;技術債清理：圍繞明確規則逐步替換舊寫法，並保持行為不變。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些任務的共同點是：中間狀態很多，失敗原因不一定一次能看清，完成標準必須依賴驗證結果。&lt;/p&gt;
&lt;h2 id=&#34;哪些任務不適合只靠-goal&#34;&gt;哪些任務不適合只靠 Goal
&lt;/h2&gt;&lt;p&gt;Goal 並不是萬能的。下面這些任務如果只靠一個長 prompt，風險會很高：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;目標非常模糊，例如「把產品增長做好」。&lt;/li&gt;
&lt;li&gt;週期很長，例如連續幾週的 SEO、GEO、廣告投放優化。&lt;/li&gt;
&lt;li&gt;需要跨系統調度，例如同時處理內容、資料、投放、客服和業務指標。&lt;/li&gt;
&lt;li&gt;涉及生產風險，例如資料庫變更、線上配置、財務操作、帳號權限調整。&lt;/li&gt;
&lt;li&gt;缺少驗證手段，例如沒有測試、沒有指標、沒有日誌、沒有人工作收標準。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這類任務更像 Mission，而不是 Goal。&lt;/p&gt;
&lt;p&gt;Goal 適合小時級到一兩天的深度執行。Mission 則需要狀態、歷史、調度、人類審批、階段性複盤和長期指標。比如 SEO / GEO / Ads 優化，不只是讓 Agent 循環寫內容或調參數，而是要持續記錄策略、實驗、資料變化和下一步計畫。&lt;/p&gt;
&lt;h2 id=&#34;寫好-goal-prompt-的模板&#34;&gt;寫好 Goal Prompt 的模板
&lt;/h2&gt;&lt;p&gt;一個好用的 Goal prompt，至少應該包含下面幾塊：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;目標：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;用一句話說明最終要達成什麼結果。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;背景：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;說明目前問題、相關檔案、業務約束、已有嘗試。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;範圍：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;允許修改哪些目錄、檔案、模組；哪些地方不要碰。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;完成標準：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;列出可驗證的 definition of done。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;驗證命令：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;寫清楚需要執行的測試、lint、build、eval 或腳本。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;失敗策略：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;如果無法完成，要求 Agent 輸出失敗原因、已嘗試方案、剩餘阻塞點。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;風險邊界：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;禁止破壞性操作，生產配置、密鑰、資料庫、外部服務需要人工確認。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;交付格式：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;要求總結修改點、驗證結果、風險和後續建議。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;真正決定長任務效果的，往往不是 prompt 寫得多漂亮，而是完成標準夠不夠硬。&lt;/p&gt;
&lt;h2 id=&#34;goal-buddy-的價值先幫你把任務說清楚&#34;&gt;Goal Buddy 的價值：先幫你把任務說清楚
&lt;/h2&gt;&lt;p&gt;很多長任務失敗，不是 Agent 能力不夠，而是人類一開始就沒有把任務拆清楚。&lt;/p&gt;
&lt;p&gt;Goal Buddy 這類輔助工具的價值在於：在正式把任務交給 Agent 之前，先幫你準備目標、邊界、完成標準和驗證方式。它像一個任務預檢器，會追問：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;這個任務的最終可見結果是什麼？&lt;/li&gt;
&lt;li&gt;哪些目錄可以改，哪些不能改？&lt;/li&gt;
&lt;li&gt;成功後跑什麼命令證明？&lt;/li&gt;
&lt;li&gt;失敗時要不要繼續嘗試，最多嘗試到什麼程度？&lt;/li&gt;
&lt;li&gt;是否需要分階段提交？&lt;/li&gt;
&lt;li&gt;哪些操作必須讓人類確認？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這一步看似囉嗦，但它能顯著減少 Agent 中途跑偏、過早停止或改出一堆難以複核程式碼的概率。&lt;/p&gt;
&lt;h2 id=&#34;給-codexclaude-codeopencode-使用者的實踐建議&#34;&gt;給 Codex、Claude Code、OpenCode 使用者的實踐建議
&lt;/h2&gt;&lt;p&gt;如果你正在用 Codex、Claude Code、OpenCode、OpenClaw 或類似 coding agent，可以按下面方式使用長任務：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先提交目前工作區，保證有乾淨回滾點。&lt;/li&gt;
&lt;li&gt;把任務寫成 Goal，而不是一句泛泛的需求。&lt;/li&gt;
&lt;li&gt;明確允許修改的範圍和禁止修改的範圍。&lt;/li&gt;
&lt;li&gt;給出驗證命令，最好讓 Agent 每輪都能自己執行。&lt;/li&gt;
&lt;li&gt;要求 Agent 在無法完成時報告阻塞點，而不是硬編一個「完成」。&lt;/li&gt;
&lt;li&gt;對高風險操作設定人工確認，例如刪除檔案、改資料庫、改部署配置。&lt;/li&gt;
&lt;li&gt;最後只接受帶有測試結果和修改總結的交付。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;長任務 Agent 的正確使用方式，不是「讓它自己隨便幹一晚上」，而是給它一個清楚的目標、堅實的護欄和可驗證的出口。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;Codex Goal / Persistent Goals 的意義在於，把 coding agent 從「執行一句指令」推進到「圍繞一個目標持續工作」。&lt;/p&gt;
&lt;p&gt;它最適合複雜但邊界明確的工程任務：遷移、重構、測試修復、依賴升級、eval 優化。它不適合完全模糊、週期很長、缺少驗證標準的業務任務；那些更應該設計成 Mission 系統。&lt;/p&gt;
&lt;p&gt;未來 AI Agent 的競爭點，很可能不只是模型會不會寫程式，而是能不能圍繞目標持續推進、正確判斷停止時機，並把過程留給人類複核。&lt;/p&gt;
&lt;p&gt;參考：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.bilibili.com/video/BV1a3LF6fE2D/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Codex Goal 深度解析：讓 AI Agent 連續工作數小時，不再提前擺爛&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://openai.com/index/introducing-the-codex-app/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Introducing the Codex app&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Ollama 接入 Codex App：本地大模型如何變成 AI 編程 Agent</title>
        <link>https://knightli.com/zh-tw/2026/05/26/ollama-codex-app-local-ai-coding-agent/</link>
        <pubDate>Tue, 26 May 2026 23:35:01 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/26/ollama-codex-app-local-ai-coding-agent/</guid>
        <description>&lt;p&gt;Ollama 最近把本地大模型和 AI 編程工具之間的距離又拉近了一步：透過 &lt;code&gt;ollama launch codex-app&lt;/code&gt;，使用者可以把 Codex App 接到 Ollama 管理的本地或雲端模型上。&lt;/p&gt;
&lt;p&gt;這件事的意義不只是「換一個模型後端」。它更像是把本地大模型從聊天視窗推到開發工作流裡：模型不再只是回答問題，而是可以進入程式碼專案、理解檔案結構、輔助修改程式碼、執行任務，成為 AI 編程 Agent 的一部分。&lt;/p&gt;
&lt;h2 id=&#34;先釐清這不是-openai-全功能永久免費&#34;&gt;先釐清：這不是 OpenAI 全功能永久免費
&lt;/h2&gt;&lt;p&gt;網上很多說法會把這件事概括成「Codex 免費了」。這個說法容易誤解。&lt;/p&gt;
&lt;p&gt;更準確的理解是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Codex App 是 OpenAI 的 AI 編程工具；&lt;/li&gt;
&lt;li&gt;Ollama Launch 可以幫助 Codex App 使用 Ollama 模型；&lt;/li&gt;
&lt;li&gt;模型可以是本地模型，也可以是 Ollama 的雲端模型；&lt;/li&gt;
&lt;li&gt;如果使用本地模型，推理成本主要變成自己的硬體、電費和時間，而不是按 API token 計費；&lt;/li&gt;
&lt;li&gt;Codex App、OpenAI 帳號權益、不同模型可用性和官方限制，仍然要以 OpenAI 與 Ollama 的當前規則為準。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以它不是「所有 Codex 能力都永久免費」，而是多了一條本地化路線：讓 AI 編程 Agent 可以不完全依賴 OpenAI API、Claude API 或 Gemini API。&lt;/p&gt;
&lt;h2 id=&#34;ollama-launch-codex-app-做了什麼&#34;&gt;&lt;code&gt;ollama launch codex-app&lt;/code&gt; 做了什麼？
&lt;/h2&gt;&lt;p&gt;Ollama 官方文件裡，Codex App 的接入命令很簡單：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ollama launch codex-app
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果想指定模型，可以寫成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ollama launch codex-app --model gpt-oss:120b
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;也可以只生成配置，不馬上啟動：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ollama launch codex-app --config
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果想恢復原本的 Codex 配置：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ollama launch codex-app --restore
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;它的價值在於減少手動配置成本。過去要讓一個 AI 編程工具接入本地模型，經常要自己改環境變數、OpenAI-compatible endpoint、&lt;code&gt;config.toml&lt;/code&gt;、模型名和 profile。現在 Ollama Launch 把這些步驟包裝成一個更直接的流程。&lt;/p&gt;
&lt;h2 id=&#34;為什麼本地模型接入-agent-很重要&#34;&gt;為什麼本地模型接入 Agent 很重要？
&lt;/h2&gt;&lt;p&gt;以前本地大模型最常見的用法是聊天：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;寫一段文案；&lt;/li&gt;
&lt;li&gt;回答一個問題；&lt;/li&gt;
&lt;li&gt;解釋一段程式碼；&lt;/li&gt;
&lt;li&gt;做簡單補全；&lt;/li&gt;
&lt;li&gt;總結文件。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些都很有用，但還停留在「問答工具」的層面。&lt;/p&gt;
&lt;p&gt;AI 編程 Agent 的區別在於，它面對的是一個真實專案。它需要讀目錄、看檔案、理解報錯、修改程式碼、執行命令、檢查結果，再繼續迭代。也就是說，它不是只輸出答案，而是參與執行任務。&lt;/p&gt;
&lt;p&gt;當本地模型接入 Codex App、Claude Code、OpenCode、Aider、OpenHands 這類工具時，本地 AI 的角色就變了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可以掃描專案結構；&lt;/li&gt;
&lt;li&gt;可以定位 Bug；&lt;/li&gt;
&lt;li&gt;可以改檔案；&lt;/li&gt;
&lt;li&gt;可以生成新頁面或小遊戲；&lt;/li&gt;
&lt;li&gt;可以解釋和重構程式碼；&lt;/li&gt;
&lt;li&gt;可以在開發循環裡反覆執行、驗證、修正。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這也是本地大模型從「能聊」走向「能幹活」的關鍵一步。&lt;/p&gt;
&lt;h2 id=&#34;本地-agent-的優勢&#34;&gt;本地 Agent 的優勢
&lt;/h2&gt;&lt;h3 id=&#34;1-成本更可控&#34;&gt;1. 成本更可控
&lt;/h3&gt;&lt;p&gt;大型專案很容易消耗大量 token。一次專案掃描、長上下文分析、多輪修復，放在雲端模型上可能很快累積費用。&lt;/p&gt;
&lt;p&gt;本地模型雖然也有成本，比如顯卡、記憶體、電費和時間，但它不會按 token 直接收費。對於大量試錯、個人專案、離線實驗，本地路線更適合慢慢折騰。&lt;/p&gt;
&lt;h3 id=&#34;2-可以離線工作&#34;&gt;2. 可以離線工作
&lt;/h3&gt;&lt;p&gt;如果模型、工具和依賴都已經在本機準備好，本地 Agent 在很多場景下可以斷網繼續工作。它可以讀本地程式碼、分析專案、修改檔案、生成頁面或腳本。&lt;/p&gt;
&lt;p&gt;當然，涉及聯網搜尋、下載依賴、存取線上 API 的任務仍然需要網路。但基礎程式碼分析和本地專案修改，不一定非要依賴雲端模型。&lt;/p&gt;
&lt;h3 id=&#34;3-隱私邊界更清楚&#34;&gt;3. 隱私邊界更清楚
&lt;/h3&gt;&lt;p&gt;很多程式碼庫、內部文件、實驗專案並不適合直接發給雲端模型。把模型放在本地，可以減少程式碼內容離開機器的機會。&lt;/p&gt;
&lt;p&gt;這不代表本地路線天然安全。Agent 仍然可能執行命令、改檔案、存取敏感路徑，所以權限、沙箱、Git diff review 仍然很重要。但至少在模型推理層面，本地化給了使用者更多控制權。&lt;/p&gt;
&lt;h2 id=&#34;模型怎麼選&#34;&gt;模型怎麼選？
&lt;/h2&gt;&lt;p&gt;Ollama 的官方 &lt;code&gt;ollama launch&lt;/code&gt; 文件建議，程式碼類工具最好使用較大的上下文視窗，推薦至少 64K tokens。原因很簡單：AI 編程任務經常需要同時讀專案結構、多個檔案、報錯日誌、需求說明和歷史修改。&lt;/p&gt;
&lt;p&gt;本地模型可以從這些方向嘗試：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;qwen3-coder&lt;/code&gt;：偏程式碼任務；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gpt-oss:20b&lt;/code&gt;：適合本地嘗試；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;glm-4.7-flash&lt;/code&gt;：Ollama 官方推薦的 coding 模型之一；&lt;/li&gt;
&lt;li&gt;更大的雲端模型：如果本地硬體不夠，可以用 Ollama cloud 模型換取更完整上下文。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;中文場景下，Qwen 系列仍然值得優先嘗試。它在中文理解、程式碼生成、推理和本地生態適配上都比較成熟。&lt;/p&gt;
&lt;h2 id=&#34;硬體門檻沒有想像中那麼高&#34;&gt;硬體門檻沒有想像中那麼高
&lt;/h2&gt;&lt;p&gt;很多人一提到 AI Agent，就預設需要 RTX 4090、24GB 顯存、甚至企業級 GPU。&lt;/p&gt;
&lt;p&gt;實際情況更靈活。小模型、量化模型、MoE 模型、KV cache 量化和 CPU/GPU 混合 offload 讓 6GB、8GB、12GB 顯存機器也能做不少事情。&lt;/p&gt;
&lt;p&gt;當然，低顯存機器不適合追求極致體驗：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;速度會慢；&lt;/li&gt;
&lt;li&gt;上下文不能太大；&lt;/li&gt;
&lt;li&gt;大專案掃描會吃力；&lt;/li&gt;
&lt;li&gt;多併發基本不現實；&lt;/li&gt;
&lt;li&gt;模型品質和 100B+ 雲端模型仍有差距。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但如果目標是個人專案、腳本修復、簡單前端頁面、小遊戲、程式碼解釋、離線實驗，本地模型已經足夠進入「可用」階段。&lt;/p&gt;
&lt;h2 id=&#34;也可以用-llamacpp-接-openai-compatible-介面&#34;&gt;也可以用 llama.cpp 接 OpenAI-compatible 介面
&lt;/h2&gt;&lt;p&gt;除了 Ollama，另一條常見路線是用 &lt;code&gt;llama.cpp&lt;/code&gt; 的 &lt;code&gt;llama-server&lt;/code&gt; 提供本地 OpenAI-compatible API，再讓 AI 編程工具連接到本地連接埠。&lt;/p&gt;
&lt;p&gt;一個典型的 &lt;code&gt;llama.cpp&lt;/code&gt; 啟動命令類似這樣：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bat&#34; data-lang=&#34;bat&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;llama-server.exe &lt;span class=&#34;se&#34;&gt;^
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt; &lt;/span&gt;-m &lt;span class=&#34;s2&#34;&gt;&amp;#34;models\Qwen3.6-27B-UD-Q5_K_XL.gguf&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;^
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt; &lt;/span&gt;-ngl 999 &lt;span class=&#34;se&#34;&gt;^
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt; &lt;/span&gt;-c 16384 &lt;span class=&#34;se&#34;&gt;^
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt; &lt;/span&gt;-n 2048 &lt;span class=&#34;se&#34;&gt;^
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt; &lt;/span&gt;-fa on &lt;span class=&#34;se&#34;&gt;^
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt; &lt;/span&gt;--jinja &lt;span class=&#34;se&#34;&gt;^
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt; &lt;/span&gt;--host 127.0.0.1 &lt;span class=&#34;se&#34;&gt;^
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt; &lt;/span&gt;--port 8080
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然後在工具配置裡把模型 provider 指向：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;model_providers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;llamacpp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;llama.cpp&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;base_url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;http://127.0.0.1:8080/v1/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;wire_api&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;responses&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這條路線更靈活，但也更折騰。Ollama Launch 的優勢是簡單；&lt;code&gt;llama.cpp&lt;/code&gt; 的優勢是可控參數更多，適合想細調顯存、上下文、量化和推理後端的使用者。&lt;/p&gt;
&lt;h2 id=&#34;使用本地-ai-agent-時要注意什麼&#34;&gt;使用本地 AI Agent 時要注意什麼？
&lt;/h2&gt;&lt;p&gt;本地不等於無風險。Agent 能改檔案、跑命令、建立專案，就意味著它也可能誤刪檔案、改錯程式碼、執行不該執行的操作。&lt;/p&gt;
&lt;p&gt;建議：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在 Git 倉庫裡操作，確保隨時能看 diff 和回滾。&lt;/li&gt;
&lt;li&gt;不要給 Agent 過大的系統權限。&lt;/li&gt;
&lt;li&gt;先在測試專案裡試，不要直接丟生產程式碼庫。&lt;/li&gt;
&lt;li&gt;重要檔案修改前後都要人工 review。&lt;/li&gt;
&lt;li&gt;不要把密鑰、帳號、生產環境配置暴露給 Agent。&lt;/li&gt;
&lt;li&gt;本地模型能力有限，複雜架構決策不要完全交給它。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;把本地 Agent 當成「會執行任務的助手」，而不是「完全可靠的工程師」，體驗會更健康。&lt;/p&gt;
&lt;h2 id=&#34;我的理解&#34;&gt;我的理解
&lt;/h2&gt;&lt;p&gt;Ollama 接入 Codex App 的意義在於，它把本地模型真正接進了 AI 編程工作流。&lt;/p&gt;
&lt;p&gt;過去，本地模型更多是一個聊天框；現在，它開始能進入專案、讀程式碼、改檔案、跑任務。這個變化會讓很多普通開發者重新評估手裡的電腦：也許不需要最貴的顯卡，也能先搭起一個低成本、可離線、可控的 AI 編程環境。&lt;/p&gt;
&lt;p&gt;雲端模型仍然強，特別是在複雜推理、大上下文、多模態和長任務穩定性上。但本地模型正在補上「執行工具」這一塊。&lt;/p&gt;
&lt;p&gt;未來的 AI 編程，很可能不是純雲端或純本地，而是混合形態：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;小任務、本地程式碼、隱私專案交給本地模型；&lt;/li&gt;
&lt;li&gt;高難推理、大上下文、跨系統任務交給雲端模型；&lt;/li&gt;
&lt;li&gt;Ollama、Codex App、Claude Code、OpenCode 這類工具負責把兩邊接到同一個工作流裡。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這才是本地 AI Agent 真正值得關注的地方。&lt;/p&gt;
&lt;h2 id=&#34;參考連結&#34;&gt;參考連結
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.freedidi.com/24310.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;零度博客：OpenAI Codex 徹底免費了！Ollama 接管 AI 編程 Agent，本地大模型開始自動幹活！&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.ollama.com/integrations/codex-app&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Ollama 文件：Codex App&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://ollama.com/blog/launch&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Ollama Blog：ollama launch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://openai.com/index/introducing-the-codex-app/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI：Introducing the Codex app&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>oh-my-codex：給 Codex CLI 加上工作流、技能和執行時護欄</title>
        <link>https://knightli.com/zh-tw/2026/05/25/oh-my-codex-codex-cli-workflow-layer/</link>
        <pubDate>Mon, 25 May 2026 07:41:45 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/25/oh-my-codex-codex-cli-workflow-layer/</guid>
        <description>&lt;p&gt;&lt;code&gt;Yeachan-Heo/oh-my-codex&lt;/code&gt;，簡稱 OMX，是一個圍繞 OpenAI Codex CLI 的工作流層。&lt;/p&gt;
&lt;p&gt;專案地址：&lt;a class=&#34;link&#34; href=&#34;https://github.com/Yeachan-Heo/oh-my-codex&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/Yeachan-Heo/oh-my-codex&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;它想解決的不是「再做一個新的 coding agent」，而是讓已經在使用 Codex CLI 的人，有一套更穩定的日常工作方式：啟動時帶上專案指令，任務變複雜時先釐清再規劃，執行時有 durable goal 和狀態記錄，收尾時用 review 和 QA 把結果壓住。&lt;/p&gt;
&lt;p&gt;截至寫作時，GitHub 頁面顯示倉庫約有 29.4k star，最新 release 是 &lt;code&gt;v0.18.1&lt;/code&gt;，發布時間為 2026 年 5 月 21 日。README 也明確說，官方專案是 &lt;code&gt;Yeachan-Heo/oh-my-codex&lt;/code&gt;，官方 npm 套件是 &lt;code&gt;oh-my-codex&lt;/code&gt;，不要把第三方 “OMX v2” 專案誤認為這個倉庫的官方延續。&lt;/p&gt;
&lt;h2 id=&#34;它到底是什麼&#34;&gt;它到底是什麼
&lt;/h2&gt;&lt;p&gt;OMX 不替代 Codex。&lt;/p&gt;
&lt;p&gt;它保留 Codex CLI 作為實際執行引擎，自己主要補三類東西：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;更固定的任務流程。&lt;/li&gt;
&lt;li&gt;可複用的 prompts、skills 和 specialist agents。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.omx/&lt;/code&gt; 目錄下的計劃、日誌、狀態和執行時記錄。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;換句話說，Codex 負責「動手幹活」，OMX 負責「讓幹活過程更像工程流程」。這也是它和普通 prompt 包最大的差別：它不是只往系統提示詞裡塞規則，而是把釐清、規劃、執行、檢查、團隊協作和執行時診斷拆成一組可呼叫的工作面。&lt;/p&gt;
&lt;h2 id=&#34;推薦安裝方式&#34;&gt;推薦安裝方式
&lt;/h2&gt;&lt;p&gt;README 和 Getting Started 文件都強調：OMX 預設推薦在 macOS 或 Linux 上搭配 Codex CLI 使用。原生 Windows 和 Codex App 不是它目前最主要的體驗路徑，可能會有不一致或不完整支援。&lt;/p&gt;
&lt;p&gt;如果你已經裝好了 Codex CLI，可以這樣開始：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codex --version
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install -g oh-my-codex
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;omx setup
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;omx doctor
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果你還沒有 Codex CLI，並且希望 npm 管理安裝：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install -g @openai/codex
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install -g oh-my-codex
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;omx setup
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;omx doctor
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這裡有一個細節：不要在已經由 Homebrew 管理 &lt;code&gt;codex&lt;/code&gt; 的機器上，直接把 &lt;code&gt;@openai/codex&lt;/code&gt; 和 &lt;code&gt;oh-my-codex&lt;/code&gt; 合併成一個全域安裝命令。README 提到，Homebrew 擁有的 &lt;code&gt;codex&lt;/code&gt; 二進位可能會和 npm 安裝發生 &lt;code&gt;EEXIST&lt;/code&gt; 衝突。OMX 只需要一個可用、已登入、在 &lt;code&gt;PATH&lt;/code&gt; 上的 &lt;code&gt;codex&lt;/code&gt; 命令，並不要求 Codex 一定由 npm 安裝。&lt;/p&gt;
&lt;p&gt;安裝完成後，建議再跑一次真實執行煙測：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codex login status
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;omx &lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt; --skip-git-repo-check -C . &lt;span class=&#34;s2&#34;&gt;&amp;#34;Reply with exactly OMX-EXEC-OK&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;omx doctor&lt;/code&gt; 只能證明本地安裝結構大體正常，不能證明目前 shell/profile 裡的 Codex 帳號、代理、base URL 和認證鏈路真的能發起模型呼叫。這個區分很實際，尤其是你在不同 HOME、容器、遠端環境或本地 OpenAI 相容代理裡切換時。&lt;/p&gt;
&lt;h2 id=&#34;預設工作流&#34;&gt;預設工作流
&lt;/h2&gt;&lt;p&gt;OMX 的主線工作流大致是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$deep-interview &amp;#34;clarify the authentication change&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ralplan &amp;#34;approve the auth plan and review tradeoffs&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$prometheus-strict &amp;#34;stress-test the plan before durable execution&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ultragoal &amp;#34;turn the approved plan into durable Codex goals&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;其中最常用的是三步：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$deep-interview&lt;/code&gt;：在需求還不清楚時追問邊界、目標和非目標。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$ralplan&lt;/code&gt;：把需求整理成計劃，並經過架構與批判視角確認。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$ultragoal&lt;/code&gt;：把批准後的計劃轉成更耐跑的目標和檢查點。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果任務需要並行協作，可以在 Ultragoal story 裡用 &lt;code&gt;$team&lt;/code&gt;；如果只需要一個持續推進的單人循環，可以用 &lt;code&gt;$ralph&lt;/code&gt;。這套命名看起來有點重，但背後的想法很清楚：不要讓 agent 一聽到需求就急著改文件，而是先把「要做什麼、怎麼做、怎麼驗收、什麼時候停」寫清楚。&lt;/p&gt;
&lt;h2 id=&#34;skills-和-agents-提供了什麼&#34;&gt;skills 和 agents 提供了什麼
&lt;/h2&gt;&lt;p&gt;OMX 文件把技能分成幾類。&lt;/p&gt;
&lt;p&gt;Canonical Workflow 裡有 &lt;code&gt;$deep-interview&lt;/code&gt;、&lt;code&gt;$ralplan&lt;/code&gt;、&lt;code&gt;$prometheus-strict&lt;/code&gt;、&lt;code&gt;$ultragoal&lt;/code&gt;、&lt;code&gt;$code-review&lt;/code&gt; 和 &lt;code&gt;$ultraqa&lt;/code&gt;。這些面向的是完整工程任務：先釐清，再規劃，再執行，再審查，再 QA。&lt;/p&gt;
&lt;p&gt;Execution Modes 裡有 &lt;code&gt;$team&lt;/code&gt;、&lt;code&gt;$ralph&lt;/code&gt;、&lt;code&gt;$autopilot&lt;/code&gt;、&lt;code&gt;$ultrawork&lt;/code&gt; 等。它們決定任務是單線推進、團隊並行，還是更強的自動循環。&lt;/p&gt;
&lt;p&gt;Agent Catalog 則更像角色庫，包括 &lt;code&gt;analyst&lt;/code&gt;、&lt;code&gt;planner&lt;/code&gt;、&lt;code&gt;architect&lt;/code&gt;、&lt;code&gt;debugger&lt;/code&gt;、&lt;code&gt;executor&lt;/code&gt;、&lt;code&gt;verifier&lt;/code&gt;、&lt;code&gt;security-reviewer&lt;/code&gt;、&lt;code&gt;performance-reviewer&lt;/code&gt;、&lt;code&gt;code-reviewer&lt;/code&gt;、&lt;code&gt;test-engineer&lt;/code&gt;、&lt;code&gt;designer&lt;/code&gt;、&lt;code&gt;researcher&lt;/code&gt; 等。你不一定每天都要手動點名這些角色，但它們說明 OMX 的定位不是「萬能大 prompt」，而是把工程過程拆成可複用的角色和階段。&lt;/p&gt;
&lt;p&gt;這對長期專案有意義。AI 編程裡很多失敗不是模型完全不會寫程式碼，而是它太快進入執行，跳過需求確認、架構邊界、測試基線和收尾審查。OMX 試圖用技能和角色把這些步驟固化下來。&lt;/p&gt;
&lt;h2 id=&#34;插件形態和執行時狀態&#34;&gt;插件形態和執行時狀態
&lt;/h2&gt;&lt;p&gt;README 提到，倉庫裡也包含官方 Codex plugin layout，路徑是 &lt;code&gt;plugins/oh-my-codex&lt;/code&gt;，並帶有 marketplace metadata。&lt;/p&gt;
&lt;p&gt;但文件也強調：這個插件形態不是 &lt;code&gt;npm install -g oh-my-codex&lt;/code&gt; 加 &lt;code&gt;omx setup&lt;/code&gt; 的替代品。插件作用更像是把 hooks、skill surface 和 Codex 生命週期整合包裝起來，真正執行時仍然依賴已安裝的 &lt;code&gt;omx&lt;/code&gt; CLI。&lt;/p&gt;
&lt;p&gt;最新 &lt;code&gt;v0.18.1&lt;/code&gt; release 的重點也集中在這條線上：插件安裝會使用 pinned OMX launcher，hook 失敗時更保守，Ultragoal 狀態變更會序列化，release packaging 會排除 crate-local &lt;code&gt;.omx&lt;/code&gt; runtime cache，並同步 npm、Cargo workspace、lockfile 和插件 manifest 的版本號。&lt;/p&gt;
&lt;p&gt;這些變化說明 OMX 已經不只是 prompt 倉庫，它開始認真處理安裝形態、hook 安全、狀態寫入、release 包內容和跨執行時一致性。對工具鏈來說，這些都屬於「不炫但很要命」的工程細節。&lt;/p&gt;
&lt;h2 id=&#34;適合誰&#34;&gt;適合誰
&lt;/h2&gt;&lt;p&gt;OMX 比較適合已經在認真使用 Codex CLI 的開發者，尤其是這些場景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;經常讓 Codex 處理多文件、多步驟任務。&lt;/li&gt;
&lt;li&gt;希望 agent 先釐清需求，而不是直接改程式碼。&lt;/li&gt;
&lt;li&gt;想把計劃、執行、檢查、review 和 QA 分開管理。&lt;/li&gt;
&lt;li&gt;需要在專案裡保留 &lt;code&gt;.omx/&lt;/code&gt; 狀態、計劃和日誌。&lt;/li&gt;
&lt;li&gt;想嘗試 tmux/team runtime 或更強的長任務推進方式。&lt;/li&gt;
&lt;li&gt;團隊願意把自己的工程習慣沉澱成 skills 和 prompts。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你只是偶爾讓 Codex 改一行設定、生成一個腳本、解釋一段程式碼，OMX 可能會顯得偏重。它更像是給高頻 AI 編程使用者準備的工具腰帶，而不是新手必須安裝的第一層入口。&lt;/p&gt;
&lt;h2 id=&#34;使用時要注意什麼&#34;&gt;使用時要注意什麼
&lt;/h2&gt;&lt;p&gt;第一，不要把 OMX 當成「無人值守自動完成一切」的保證。它能強化流程，但不能替你判斷需求是否合理、架構是否該改、風險是否可接受。&lt;/p&gt;
&lt;p&gt;第二，平台邊界要看清楚。README 現在明確推薦 macOS/Linux + Codex CLI。Windows 原生路徑存在，但不是預設最佳體驗。如果你在 Windows 上使用，WSL2 通常比原生終端更穩。&lt;/p&gt;
&lt;p&gt;第三，&lt;code&gt;omx doctor&lt;/code&gt; 不是最終驗收。真正能證明環境可用的是 &lt;code&gt;codex login status&lt;/code&gt; 加 &lt;code&gt;omx exec&lt;/code&gt; 這種實際模型呼叫測試。&lt;/p&gt;
&lt;p&gt;第四，流程越強，越需要你寫清楚任務邊界。&lt;code&gt;$ultragoal&lt;/code&gt;、&lt;code&gt;$team&lt;/code&gt;、&lt;code&gt;$autopilot&lt;/code&gt; 這類能力適合有驗收標準的任務。如果需求本身還很含糊，應該先用 &lt;code&gt;$deep-interview&lt;/code&gt; 或普通對話把邊界拉清楚。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;oh-my-codex 的價值不在於讓 Codex「變成另一個工具」，而在於給 Codex CLI 加了一層更工程化的工作方式。&lt;/p&gt;
&lt;p&gt;它把 AI 編程從「我說一句，你改一輪」往「釐清、規劃、執行、檢查、記錄狀態」推進了一步。對輕量任務來說，這可能有點重；但對經常用 Codex 做真實專案的人來說，穩定流程、可複用技能、執行時診斷和 durable goal 反而是省心的關鍵。&lt;/p&gt;
&lt;p&gt;如果你已經把 Codex CLI 當成日常開發工具，OMX 值得試一下。即使不直接安裝，它對 skills、agents、計劃和驗收流程的拆法，也很適合拿來改造自己的 AI 編程工作流。&lt;/p&gt;
&lt;h2 id=&#34;參考資料&#34;&gt;參考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Yeachan-Heo/oh-my-codex：&lt;a class=&#34;link&#34; href=&#34;https://github.com/Yeachan-Heo/oh-my-codex&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/Yeachan-Heo/oh-my-codex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Getting Started：&lt;a class=&#34;link&#34; href=&#34;https://github.com/Yeachan-Heo/oh-my-codex/blob/main/docs/getting-started.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/Yeachan-Heo/oh-my-codex/blob/main/docs/getting-started.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Agent Catalog：&lt;a class=&#34;link&#34; href=&#34;https://github.com/Yeachan-Heo/oh-my-codex/blob/main/docs/agents.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/Yeachan-Heo/oh-my-codex/blob/main/docs/agents.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Skills Reference：&lt;a class=&#34;link&#34; href=&#34;https://github.com/Yeachan-Heo/oh-my-codex/blob/main/docs/skills.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/Yeachan-Heo/oh-my-codex/blob/main/docs/skills.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;v0.18.1 release：&lt;a class=&#34;link&#34; href=&#34;https://github.com/Yeachan-Heo/oh-my-codex/releases/tag/v0.18.1&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/Yeachan-Heo/oh-my-codex/releases/tag/v0.18.1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>OpenAI Symphony 是什麼？Codex 編排、Issue 驅動與 AI Agent 開發工作流</title>
        <link>https://knightli.com/zh-tw/2026/05/25/openai-codex-orchestration-symphony/</link>
        <pubDate>Mon, 25 May 2026 00:17:32 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/25/openai-codex-orchestration-symphony/</guid>
        <description>&lt;p&gt;OpenAI 最近開源了一個很有意思的 Codex 編排規範：&lt;strong&gt;Symphony&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;它不是另一個聊天式編程助手，也不是一個完整的新 IDE。更準確地說，Symphony 是一套面向 Codex 的「工作編排方式」：把類似 Linear 的 issue tracker 變成編程智能體的控制平面，讓每一個未關閉的任務都能對應一個持續運行的 Agent。&lt;/p&gt;
&lt;p&gt;官方文章裡有一句話很能概括它的方向：過去工程師要同時盯著多個 Codex 會話，不斷分配任務、審查輸出、糾偏和重啟；Symphony 想解決的，正是這個上下文切換瓶頸。&lt;/p&gt;
&lt;h2 id=&#34;symphony-解決的不是寫代碼而是管理-agent&#34;&gt;Symphony 解決的不是寫代碼，而是管理 Agent
&lt;/h2&gt;&lt;p&gt;單個 Codex 會話適合互動式開發：你給它一個任務，它修改代碼，你 review，再繼續追問。但當團隊開始同時使用多個 Agent 時，問題會從「代碼能不能寫出來」變成「誰在做哪件事、做到哪一步、失敗後誰來接手」。&lt;/p&gt;
&lt;p&gt;OpenAI 的做法是把工作重心從「會話」切到「任務」：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;issue 是真正的工作單元；&lt;/li&gt;
&lt;li&gt;每個未關閉 issue 都可以映射到一個獨立 Agent 工作空間；&lt;/li&gt;
&lt;li&gt;Symphony 負責持續輪詢任務看板，決定哪些任務需要啟動、重試、停止或回收；&lt;/li&gt;
&lt;li&gt;Codex 在工作空間裡執行實作、測試、提交、建立 PR、更新狀態等動作；&lt;/li&gt;
&lt;li&gt;人類不再微操每個會話，而是審查結果、調整目標和維護邊界。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這背後的變化很關鍵：Agent 不再只是一個被人類臨時喚起的工具，而是開發流程裡持續運行的一類執行者。&lt;/p&gt;
&lt;h2 id=&#34;為什麼是-issue-tracker&#34;&gt;為什麼是 issue tracker？
&lt;/h2&gt;&lt;p&gt;因為團隊已經用 issue tracker 管理真實工作。&lt;/p&gt;
&lt;p&gt;需求、bug、重構、遷移、調研、優先級、阻塞關係、負責人、里程碑，這些資訊本來就沉澱在 Linear、GitHub Issues 或類似系統裡。Symphony 沒有重新發明一個龐大的控制台，而是把這些現有系統當作 Agent 的任務入口。&lt;/p&gt;
&lt;p&gt;這樣做有幾個好處：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;工作不必從 issue 複製到聊天視窗裡。&lt;/li&gt;
&lt;li&gt;人類可以繼續按熟悉的方式建立、拆分、排期和關閉任務。&lt;/li&gt;
&lt;li&gt;Agent 的狀態變化能回寫到同一個工作系統裡，方便團隊非同步協作。&lt;/li&gt;
&lt;li&gt;任務依賴可以自然形成 DAG，讓未阻塞的任務並行推進。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果把傳統 CI 看成「代碼提交後的自動化」，Symphony 更像是「issue 建立後的自動化」。&lt;/p&gt;
&lt;h2 id=&#34;它的核心工作流&#34;&gt;它的核心工作流
&lt;/h2&gt;&lt;p&gt;一個典型的 Symphony 流程可以理解為：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;创建 issue
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt; Symphony 轮询到可执行任务
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt; 为该 issue 创建独立 workspace
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt; 启动 Codex agent session
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt; Agent 阅读任务、修改代码、运行测试
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt; 创建或更新 PR
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt; 写回任务状态、评论、证据和交付物
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt; 人类 review、合并或要求修改
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;官方規範裡還強調了幾個工程化點：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每個 issue 使用獨立工作空間，降低相互污染；&lt;/li&gt;
&lt;li&gt;編排器維護重試、並發和恢復狀態；&lt;/li&gt;
&lt;li&gt;工作流策略放在倉庫內的 &lt;code&gt;WORKFLOW.md&lt;/code&gt;，讓團隊把 Agent 應該如何處理任務寫成可版本化的規則；&lt;/li&gt;
&lt;li&gt;實作需要保留可觀測性，至少要有結構化日誌；&lt;/li&gt;
&lt;li&gt;成功狀態不一定是 &lt;code&gt;Done&lt;/code&gt;，也可以是交給人類 review 的中間狀態。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這說明 Symphony 不是簡單地「讓 AI 自動寫代碼」，而是在定義一套可運行、可恢復、可審計的 Agent 工作系統。&lt;/p&gt;
&lt;h2 id=&#34;目標驅動而不是死板狀態機&#34;&gt;目標驅動，而不是死板狀態機
&lt;/h2&gt;&lt;p&gt;OpenAI 在文章裡提到一個重要轉變：早期他們嘗試把很多動作寫死在外層 harness 裡，例如提交代碼、跑測試、處理 GitHub 流程。但隨著 Codex 能力增強，這種方式反而限制了 Agent。&lt;/p&gt;
&lt;p&gt;後來的方向是給 Agent 設定目標，而不是把每一步都寫成固定狀態轉換。&lt;/p&gt;
&lt;p&gt;比如，一個任務的目標可以是「完成 Vite 遷移並確保 CI 通過」。Agent 可以自己判斷是否需要改配置、修測試、讀 CI 日誌、處理 review feedback，甚至拆出新的後續 issue。Symphony 負責提供邊界、上下文和運行框架，而不是替 Agent 規定每一個動作。&lt;/p&gt;
&lt;p&gt;這也是它和傳統自動化腳本的區別：腳本擅長重複確定流程；Symphony 面向的是帶有不確定性的工程任務。&lt;/p&gt;
&lt;h2 id=&#34;和普通-codex-使用方式有什麼不同&#34;&gt;和普通 Codex 使用方式有什麼不同？
&lt;/h2&gt;&lt;p&gt;普通 Codex 會話更像「人帶著 AI 寫代碼」：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;人類打開會話；&lt;/li&gt;
&lt;li&gt;人類描述任務；&lt;/li&gt;
&lt;li&gt;人類觀察輸出；&lt;/li&gt;
&lt;li&gt;人類隨時糾偏；&lt;/li&gt;
&lt;li&gt;任務結束後再開下一個會話。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Symphony 更像「團隊把任務池交給一組 Agent 執行」：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;人類寫清楚 issue；&lt;/li&gt;
&lt;li&gt;系統持續發現可執行任務；&lt;/li&gt;
&lt;li&gt;Agent 在獨立環境裡推進；&lt;/li&gt;
&lt;li&gt;結果以 PR、評論、測試狀態、影片或分析報告的形式返回；&lt;/li&gt;
&lt;li&gt;人類在關鍵節點做 review。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這不是替代工程師，而是把工程師從「同時照看多個會話」的負擔裡解放出來。OpenAI 在官方文章中提到，在部分團隊中，合併到主分支的 PR 數量有明顯提升；但更值得注意的是工作方式的變化：試驗一個想法、發起一次重構、驗證一個假設的啟動成本變低了。&lt;/p&gt;
&lt;h2 id=&#34;適合哪些場景&#34;&gt;適合哪些場景？
&lt;/h2&gt;&lt;p&gt;Symphony 更適合這些任務：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;常規功能實作；&lt;/li&gt;
&lt;li&gt;已有代碼庫裡的小型重構；&lt;/li&gt;
&lt;li&gt;基礎設施遷移；&lt;/li&gt;
&lt;li&gt;依賴升級；&lt;/li&gt;
&lt;li&gt;測試補齊；&lt;/li&gt;
&lt;li&gt;CI 修復；&lt;/li&gt;
&lt;li&gt;調研後生成實作計劃；&lt;/li&gt;
&lt;li&gt;根據 review feedback 繼續修改 PR。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它不一定適合高度模糊、需要強業務判斷或架構拍板的任務。對這類問題，互動式 Codex 會話仍然更自然，因為人類需要在過程中持續參與。&lt;/p&gt;
&lt;h2 id=&#34;風險和邊界&#34;&gt;風險和邊界
&lt;/h2&gt;&lt;p&gt;Symphony 的吸引力很強，但真正落地時不能只看「自動化」這一面。&lt;/p&gt;
&lt;p&gt;幾個邊界要提前想清楚：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;issue 必須寫清楚，否則 Agent 會把模糊需求放大成錯誤實作；&lt;/li&gt;
&lt;li&gt;Agent 的權限要收斂，尤其是倉庫、密鑰、生產環境和第三方服務訪問；&lt;/li&gt;
&lt;li&gt;每個工作空間要隔離，避免多個任務相互污染；&lt;/li&gt;
&lt;li&gt;CI、測試、lint 和 review 仍然是必須的質量門；&lt;/li&gt;
&lt;li&gt;任務狀態、PR 連結、日誌和失敗原因要可追蹤；&lt;/li&gt;
&lt;li&gt;人類 review 不能省，尤其是涉及安全、計費、資料遷移和權限邏輯的改動。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;官方倉庫也把 Symphony 定位為 trusted environment 裡的工程預覽和參考實作，而不是一個拿來就能無腦替代研發流程的成品平台。&lt;/p&gt;
&lt;h2 id=&#34;我對-symphony-的理解&#34;&gt;我對 Symphony 的理解
&lt;/h2&gt;&lt;p&gt;Symphony 最有價值的地方，不在於它用了 Linear，也不在於參考實作選擇了 Elixir，而在於它重新定義了編程 Agent 的入口。&lt;/p&gt;
&lt;p&gt;過去我們習慣從聊天視窗啟動 AI 編程：這很靈活，但規模一大，人類注意力就成了瓶頸。Symphony 把入口放回 issue tracker，讓 Agent 圍繞真實任務持續工作。這樣一來，AI 編程從「個人效率工具」開始向「團隊工作流基礎設施」靠近。&lt;/p&gt;
&lt;p&gt;如果你已經在使用 Codex、Claude Code、Cursor Agent 或類似工具，Symphony 值得關注的不是某個具體實作，而是它背後的模式：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不要只管理 Agent 會話，要管理需要完成的工作。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這可能會成為下一階段 AI 編程工具的關鍵分水嶺。&lt;/p&gt;
&lt;h2 id=&#34;參考連結&#34;&gt;參考連結
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://openai.com/zh-Hans-CN/index/open-source-codex-orchestration-symphony/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Codex 編排的開源規範：Symphony&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/openai/symphony&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;openai/symphony&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>CLIProxyAPI：把 Codex、Claude Code、Gemini CLI 統一封裝成 API</title>
        <link>https://knightli.com/zh-tw/2026/05/24/cliproxyapi-cli-to-api-gateway/</link>
        <pubDate>Sun, 24 May 2026 10:03:33 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/24/cliproxyapi-cli-to-api-gateway/</guid>
        <description>&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/router-for-me/CLIProxyAPI&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;CLIProxyAPI&lt;/a&gt; 是一個很有「民間工程味」的專案：它不是再造一個大模型，也不是單純做 API 轉發，而是把一堆原本偏互動式、偏 CLI、偏 OAuth 登入的 AI 工具，重新包成統一 API 服務。&lt;/p&gt;
&lt;p&gt;它支援的對象包括 Gemini CLI、OpenAI Codex、Claude Code、Amp CLI、AI Studio Build，以及上游 OpenAI 相容服務。換句話說，它想解決的問題是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我手上有 CLI 工具、有訂閱帳號、有 OAuth 登入狀態，能不能像呼叫普通 API 一樣，把這些能力接到自己的客戶端、腳本、IDE 或內部服務裡？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;CLIProxyAPI 給出的答案是：可以，中間加一層代理，把不同來源的 CLI 能力轉換成 OpenAI、Gemini、Claude、Codex 相容介面。&lt;/p&gt;
&lt;h2 id=&#34;它真正解決的痛點&#34;&gt;它真正解決的痛點
&lt;/h2&gt;&lt;p&gt;很多 AI 編程工具的能力本來很強，但預設使用方式並不適合自動化。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gemini CLI 能登入帳號使用，但你的程式更習慣呼叫 HTTP API。&lt;/li&gt;
&lt;li&gt;Claude Code 很適合互動式編碼，但接入其他客戶端時會遇到協議不一致。&lt;/li&gt;
&lt;li&gt;Codex CLI 支援 OAuth 登入和 Responses 風格能力，但不是所有上層工具都知道怎麼和它說話。&lt;/li&gt;
&lt;li&gt;一個團隊可能有多個帳號，需要輪詢、負載均衡、異常帳號剔除和配額觀察。&lt;/li&gt;
&lt;li&gt;你想讓某些工具只認 OpenAI 格式，但後端實際可能是 Gemini、Claude 或 Codex。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CLIProxyAPI 的定位，就是做這些工具和客戶端之間的「協議適配層」。&lt;/p&gt;
&lt;p&gt;它把複雜的一側藏在後面：OAuth、CLI 登入、多帳號、不同協議、不同 provider。前面則暴露相對熟悉的介面，比如 OpenAI Chat Completions、OpenAI Responses、Gemini、Claude Messages、Codex 相關端點。&lt;/p&gt;
&lt;h2 id=&#34;能力概覽&#34;&gt;能力概覽
&lt;/h2&gt;&lt;p&gt;從官方 README 和文件看，CLIProxyAPI 目前的核心能力包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;為 CLI 模型提供 OpenAI、Gemini、Claude、Codex 相容 API 端點。&lt;/li&gt;
&lt;li&gt;透過 OAuth 登入接入 OpenAI Codex 和 Claude Code。&lt;/li&gt;
&lt;li&gt;支援串流、非串流回應，以及部分場景下的 WebSocket。&lt;/li&gt;
&lt;li&gt;支援函式呼叫、工具呼叫和多模態輸入。&lt;/li&gt;
&lt;li&gt;支援 Gemini、OpenAI、Claude 多帳號輪詢與負載均衡。&lt;/li&gt;
&lt;li&gt;支援 Gemini AI Studio API Key。&lt;/li&gt;
&lt;li&gt;支援 AI Studio Build、Gemini CLI、Claude Code、OpenAI Codex 的多帳號池。&lt;/li&gt;
&lt;li&gt;可以透過設定接入 OpenAI 相容上游，比如 OpenRouter。&lt;/li&gt;
&lt;li&gt;提供 Go SDK，方便把代理能力嵌入到自己的服務裡。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這類專案最有價值的地方，不是「多支援幾個模型名」，而是把帳號登入、協議轉換和請求路由這些瑣碎工作打包起來。&lt;/p&gt;
&lt;h2 id=&#34;它適合誰用&#34;&gt;它適合誰用
&lt;/h2&gt;&lt;p&gt;CLIProxyAPI 更適合下面幾類人。&lt;/p&gt;
&lt;p&gt;第一類是重度 AI 編程使用者。你已經在用 Codex、Claude Code、Gemini CLI，但想把它們接到 Cursor、Cline、RooCode、Amp、內部腳本或自建工作流裡。&lt;/p&gt;
&lt;p&gt;第二類是有多帳號池的人。比如你有多個 Gemini、OpenAI、Claude 登入狀態，不想手工切換，希望自動輪詢、均衡使用、遇到異常帳號時能快速排查。&lt;/p&gt;
&lt;p&gt;第三類是做團隊內部閘道的人。團隊不希望每個客戶端都分別適配 Gemini、Claude、Codex，而是想透過一個中間層統一暴露 API。&lt;/p&gt;
&lt;p&gt;第四類是喜歡折騰協議的人。你可能關心 Responses、Chat Completions、Claude Messages、Gemini v1beta 這些介面如何互相轉換，也可能希望在同一套客戶端裡切換不同後端。&lt;/p&gt;
&lt;p&gt;如果只是個人偶爾問幾句 AI，或者只用官方 App 聊天，那 CLIProxyAPI 的部署和維護成本就顯得重了。&lt;/p&gt;
&lt;h2 id=&#34;和普通-api-中轉有什麼不同&#34;&gt;和普通 API 中轉有什麼不同
&lt;/h2&gt;&lt;p&gt;普通 API 中轉服務一般是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;客戶端 -&amp;gt; 中轉 API -&amp;gt; 上游模型 API
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;CLIProxyAPI 的鏈路更像：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;客戶端 -&amp;gt; CLIProxyAPI -&amp;gt; CLI / OAuth 登入狀態 / 多帳號池 -&amp;gt; 模型服務
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;區別在於，它處理的不只是 API Key 轉發，還包括 CLI 工具、OAuth 帳號、協議表面和模型別名。&lt;/p&gt;
&lt;p&gt;比如 Codex 和 Claude Code 這類工具，本身就不是傳統意義上「拿一個 API Key 就能穩定呼叫」的模式。CLIProxyAPI 把這些登入狀態和呼叫邏輯包裝起來，讓外部客戶端像呼叫 API 一樣存取它們。&lt;/p&gt;
&lt;p&gt;這也是它吸引人的地方，同時也是它複雜的地方。&lt;/p&gt;
&lt;h2 id=&#34;使用時最容易誤解的地方&#34;&gt;使用時最容易誤解的地方
&lt;/h2&gt;&lt;p&gt;第一，不要以為統一 &lt;code&gt;/v1/...&lt;/code&gt; 就能解決所有協議差異。&lt;/p&gt;
&lt;p&gt;CLIProxyAPI 文件裡專門提醒過：當你需要某一類後端的請求和回應形態時，優先使用 provider-specific 路徑。例如 messages 風格用 &lt;code&gt;/api/provider/{provider}/v1/messages&lt;/code&gt;，Gemini 模型路徑用 &lt;code&gt;/api/provider/{provider}/v1beta/models/...&lt;/code&gt;，chat-completions 風格用 &lt;code&gt;/api/provider/{provider}/v1/chat/completions&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;統一入口方便，但不同協議的語義並不會憑空消失。工具呼叫、串流回傳、多模態輸入、系統訊息處理，都可能因為後端不同而有細節差異。&lt;/p&gt;
&lt;p&gt;第二，模型名不等於唯一後端。&lt;/p&gt;
&lt;p&gt;如果多個後端暴露了相同的客戶端可見模型名，僅靠路徑不一定能鎖定真正執行推理的那個後端。要嚴格固定後端，最好使用唯一 alias、前綴，或者避免讓多個後端暴露同名模型。&lt;/p&gt;
&lt;p&gt;第三，多帳號輪詢不是無限額度。&lt;/p&gt;
&lt;p&gt;輪詢只能更均勻地使用帳號池，不能繞過上游服務的真實限制。帳號異常、配額耗盡、風控、OAuth 失效，都需要單獨監控。&lt;/p&gt;
&lt;p&gt;第四，它不是免維護魔法盒。&lt;/p&gt;
&lt;p&gt;一旦你把它放進日常工作流，就要關心設定、日誌、上游帳號狀態、版本升級、客戶端相容性和安全邊界。&lt;/p&gt;
&lt;h2 id=&#34;管理和監控怎麼辦&#34;&gt;管理和監控怎麼辦
&lt;/h2&gt;&lt;p&gt;官方 README 提到，從 v6.10.0 開始，CLIProxyAPI 和 CPAMC 不再預置資料統計功能。如果需要使用量統計，可以配合獨立專案：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CPA Usage Keeper：同步 CLIProxyAPI 資料，存到 SQLite，並提供聚合 API 和儀表板。&lt;/li&gt;
&lt;li&gt;CLIProxyAPI Usage Dashboard：本機優先的用量與配額看板，可展示帳號、模型、時間窗口和 Codex 配額餘量。&lt;/li&gt;
&lt;li&gt;CPA-Manager：更完整的管理中心，面向請求監控、費用估算、帳號池巡檢、異常帳號定位和清理建議。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這說明 CLIProxyAPI 的核心更偏「代理和協議層」，而不是一站式商業管理後台。如果是團隊使用，最好一開始就把日誌、監控和帳號池管理考慮進去。&lt;/p&gt;
&lt;h2 id=&#34;一個比較合理的使用姿勢&#34;&gt;一個比較合理的使用姿勢
&lt;/h2&gt;&lt;p&gt;如果要試用，可以按這個順序來：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先用官方文件的 Quick Start 跑起來。&lt;/li&gt;
&lt;li&gt;只接一個 provider，比如 Gemini CLI 或 Codex，確認基本請求能通。&lt;/li&gt;
&lt;li&gt;再測試串流回應、工具呼叫、多模態輸入這些高風險能力。&lt;/li&gt;
&lt;li&gt;確認客戶端實際使用的是哪個 endpoint，不要混用協議路徑。&lt;/li&gt;
&lt;li&gt;最後再加入多帳號輪詢、管理面板和用量統計。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;不要一上來就把 Gemini、Codex、Claude、OpenRouter、多帳號和所有客戶端全接進去。這樣出錯時很難判斷是認證問題、協議問題、模型名問題，還是上游帳號問題。&lt;/p&gt;
&lt;h2 id=&#34;安全邊界也要想清楚&#34;&gt;安全邊界也要想清楚
&lt;/h2&gt;&lt;p&gt;CLIProxyAPI 會接觸到帳號登入狀態、API Key、OAuth 相關憑據和請求內容。它如果只跑在自己機器上，風險相對可控；如果暴露到公網或團隊內網，就必須認真處理認證、存取控制、日誌脫敏和網路隔離。&lt;/p&gt;
&lt;p&gt;尤其是管理端點，最好只允許本機或可信內網存取。不要為了省事直接把管理介面裸露出去。&lt;/p&gt;
&lt;h2 id=&#34;總結&#34;&gt;總結
&lt;/h2&gt;&lt;p&gt;CLIProxyAPI 的價值在於，它把原本散落在多個 CLI、多個帳號、多個協議裡的 AI 能力，收攏成一個可編程的 API 層。&lt;/p&gt;
&lt;p&gt;它適合重度 AI 編程使用者、多帳號使用者和團隊內部閘道場景；不太適合只想「開箱即用、完全無維護」的輕量使用者。&lt;/p&gt;
&lt;p&gt;如果你正在折騰 Codex、Claude Code、Gemini CLI 這些工具，並且希望把它們接進自己的客戶端或自動化工作流裡，CLIProxyAPI 值得認真看一眼。但要把它當基礎設施來用，而不是當一次性小工具來用。&lt;/p&gt;
&lt;p&gt;參考資料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/router-for-me/CLIProxyAPI&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;router-for-me/CLIProxyAPI GitHub 倉庫&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/router-for-me/CLIProxyAPI/blob/main/README_CN.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;CLIProxyAPI 中文 README&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.router-for.me/cn/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;CLIProxyAPI 官方文件&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>讓 Codex 使用 DeepSeek 模型的兩種方法：本機閘道和 OpenRouter BYOK</title>
        <link>https://knightli.com/zh-tw/2026/05/24/codex-deepseek-config-ccx-openrouter-byok/</link>
        <pubDate>Sun, 24 May 2026 09:52:55 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/24/codex-deepseek-config-ccx-openrouter-byok/</guid>
        <description>&lt;p&gt;想讓 Codex 使用 DeepSeek，第一反應通常是改 &lt;code&gt;~/.codex/config.toml&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deepseek-chat&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;base_url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://api.deepseek.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這個思路在一些舊版本或普通 OpenAI SDK 場景裡確實成立，但放到目前的 Codex CLI 上，很容易撞到一個底層問題：Codex 的自訂模型供應商走的是 OpenAI Responses 協議，而 DeepSeek 官方介面主要提供 OpenAI 相容的 Chat Completions 呼叫方式。&lt;/p&gt;
&lt;p&gt;我本機目前是 &lt;code&gt;codex-cli 0.111.0&lt;/code&gt;。&lt;code&gt;codex --help&lt;/code&gt; 裡可以看到它支援 &lt;code&gt;--config&lt;/code&gt;、&lt;code&gt;--model&lt;/code&gt;、&lt;code&gt;--profile&lt;/code&gt; 這些設定入口；OpenAI 官方 Codex 設定參考也寫得很明確：&lt;code&gt;model_providers.&amp;lt;id&amp;gt;.wire_api&lt;/code&gt; 目前只支援 &lt;code&gt;responses&lt;/code&gt;，省略時也預設是 &lt;code&gt;responses&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;DeepSeek 官方文件則給出的呼叫路徑是 &lt;code&gt;https://api.deepseek.com/chat/completions&lt;/code&gt;，範例也是 &lt;code&gt;client.chat.completions.create(...)&lt;/code&gt;。所以問題不在於 DeepSeek 不能被 OpenAI SDK 呼叫，而在於 Codex 發出的請求語義，和 DeepSeek 原生介面能理解的語義不完全是同一套東西。&lt;/p&gt;
&lt;p&gt;這就是為什麼直接把 &lt;code&gt;base_url&lt;/code&gt; 改成 &lt;code&gt;https://api.deepseek.com&lt;/code&gt; 後，可能出現下面這些現象：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;請求路徑不匹配，直接 404 或回傳格式不對。&lt;/li&gt;
&lt;li&gt;多輪對話、工具呼叫、補丁產生時解析失敗。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tool_calls&lt;/code&gt; 順序、訊息結構、串流事件格式對不上。&lt;/li&gt;
&lt;li&gt;看起來模型能回一句話，但一到 Codex 真正幹活就開始報錯。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;更穩的辦法，是在 Codex 和 DeepSeek 之間放一個「翻譯層」。常見有兩種路線。&lt;/p&gt;
&lt;h2 id=&#34;方法一用本機閘道橋接-deepseek&#34;&gt;方法一：用本機閘道橋接 DeepSeek
&lt;/h2&gt;&lt;p&gt;本機閘道的作用不是簡單轉發，而是把 Codex 側的 Responses 風格請求，轉換成 DeepSeek 能處理的 Chat Completions 風格請求，再把 DeepSeek 的結果轉換回 Codex 能吃的格式。&lt;/p&gt;
&lt;p&gt;如果你用的是 ccx 這類本機閘道，設定思路大致是這樣：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;profiles&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;deepseek-ccx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deepseek-v4-flash&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model_provider&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ccx-bridge&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;model_providers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ccx-bridge&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Local CCX Gateway&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;base_url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;http://localhost:3000/v1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;env_key&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;DEEPSEEK_API_KEY&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然後在終端機裡設定 DeepSeek Key，再用這個 profile 啟動：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;DEEPSEEK_API_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;your-deepseek-key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codex --profile deepseek-ccx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;PowerShell 裡是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$env:DEEPSEEK_API_KEY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;your-deepseek-key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;codex&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-profile&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;deepseek-ccx&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這裡有兩個細節要注意。&lt;/p&gt;
&lt;p&gt;第一，&lt;code&gt;base_url&lt;/code&gt; 要指向閘道暴露給 Codex 的位址，不是 DeepSeek 官方位址。閘道背後再去呼叫 DeepSeek。&lt;/p&gt;
&lt;p&gt;第二，&lt;code&gt;env_key&lt;/code&gt; 寫什麼取決於閘道怎麼鑑權。有的閘道直接讀取 DeepSeek 官方 Key，有的閘道會要求你給它一個本機代理 Key，再由閘道自己的後台保存 DeepSeek Key。遇到這種情況，&lt;code&gt;env_key&lt;/code&gt; 就應該改成閘道要求的環境變數名。&lt;/p&gt;
&lt;p&gt;這條路的優點是本機可控，延遲和成本也更容易算清楚。缺點是你必須確認閘道真的支援 Codex 目前使用的 Responses 語義，而不是只做了普通 Chat Completions 代理。&lt;/p&gt;
&lt;h2 id=&#34;方法二用-openrouter-byok-做線上橋接&#34;&gt;方法二：用 OpenRouter BYOK 做線上橋接
&lt;/h2&gt;&lt;p&gt;如果不想在本機部署閘道，可以考慮 OpenRouter 的 BYOK。BYOK 的意思是把你自己的上游供應商 Key 綁定到 OpenRouter，由 OpenRouter 負責路由和轉發。&lt;/p&gt;
&lt;p&gt;這裡最容易寫錯的是環境變數。Codex 存取的是 OpenRouter，所以 &lt;code&gt;env_key&lt;/code&gt; 通常應該是 &lt;code&gt;OPENROUTER_API_KEY&lt;/code&gt;，不是 &lt;code&gt;DEEPSEEK_API_KEY&lt;/code&gt;。DeepSeek Key 要在 OpenRouter 的 BYOK 或 provider key 設定裡新增。&lt;/p&gt;
&lt;p&gt;設定範例：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;profiles&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;deepseek-openrouter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deepseek/deepseek-chat&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model_provider&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;openrouter&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;model_providers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;openrouter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;OpenRouter&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;base_url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://openrouter.ai/api/v1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;env_key&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;OPENROUTER_API_KEY&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;啟動方式：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;OPENROUTER_API_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;your-openrouter-key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codex --profile deepseek-openrouter
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;PowerShell：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$env:OPENROUTER_API_KEY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;your-openrouter-key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;codex&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-profile&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;deepseek-openrouter&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然後在 OpenRouter 後台把 DeepSeek 的 provider key 加進去。OpenRouter 的 BYOK 文件說明，綁定的 provider key 會被加密保存，並用於路由到對應供應商。&lt;/p&gt;
&lt;p&gt;這條路的優點是省掉本機閘道維護成本，設定起來更像普通第三方 API 代理。缺點是中間多了一層線上服務，排障時要同時看 Codex、OpenRouter、DeepSeek 三邊的錯誤訊息。&lt;/p&gt;
&lt;h2 id=&#34;要不要繼續用-deepseek-chat-這個模型名&#34;&gt;要不要繼續用 deepseek-chat 這個模型名？
&lt;/h2&gt;&lt;p&gt;DeepSeek 官方文件在 2026 年 5 月的說明裡，推薦模型名已經出現 &lt;code&gt;deepseek-v4-flash&lt;/code&gt; 和 &lt;code&gt;deepseek-v4-pro&lt;/code&gt;，並提示 &lt;code&gt;deepseek-chat&lt;/code&gt;、&lt;code&gt;deepseek-reasoner&lt;/code&gt; 相容別名會在 2026-07-24 之後廢棄。&lt;/p&gt;
&lt;p&gt;所以新設定裡更建議優先測試：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deepseek-v4-flash&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果走 OpenRouter，則要按 OpenRouter 的模型命名來寫，例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deepseek/deepseek-chat&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;實際可用名稱以你所用閘道或 OpenRouter 模型頁為準。模型名不對時，錯誤通常會表現為 &lt;code&gt;model not found&lt;/code&gt;、404，或者 provider 找不到對應 endpoint。&lt;/p&gt;
&lt;h2 id=&#34;直接改-deepseek-官方-base_url-為什麼不推薦&#34;&gt;直接改 DeepSeek 官方 base_url 為什麼不推薦
&lt;/h2&gt;&lt;p&gt;你當然可以試著寫：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;profiles&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;deepseek-direct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deepseek-v4-flash&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;model_provider&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deepseek&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;model_providers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;deepseek&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;DeepSeek&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;base_url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://api.deepseek.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;env_key&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;DEEPSEEK_API_KEY&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;但這更像排錯實驗，不適合作為穩定方案。因為 Codex 會按 Responses 協議去和自訂 provider 說話，而 DeepSeek 官方範例走的是 &lt;code&gt;/chat/completions&lt;/code&gt;。如果 DeepSeek 或 Codex 未來補齊了相容層，這種直連才可能變得簡單；在此之前，橋接層更可靠。&lt;/p&gt;
&lt;h2 id=&#34;改完設定後還是走-openai-怎麼辦&#34;&gt;改完設定後還是走 OpenAI 怎麼辦
&lt;/h2&gt;&lt;p&gt;先確認設定檔位置。全域設定應該在：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;~/.codex/config.toml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;專案裡的 &lt;code&gt;.codex/config.toml&lt;/code&gt; 不適合放 &lt;code&gt;model_provider&lt;/code&gt;、&lt;code&gt;model_providers&lt;/code&gt; 這類機器級 provider 設定。OpenAI 官方文件也提醒，專案級設定不會覆蓋這些本機 provider 和認證相關欄位。&lt;/p&gt;
&lt;p&gt;如果 Codex 仍然要求網頁登入，或者看起來還在走預設 OpenAI 模型，可以先退出目前登入狀態：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codex &lt;span class=&#34;nb&#34;&gt;logout&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;有些舊教學會寫成交互介面裡的 &lt;code&gt;/logout&lt;/code&gt;。在目前 CLI 裡，更穩的是直接在終端機執行 &lt;code&gt;codex logout&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;還可以用臨時參數做一次快速驗證：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codex --profile deepseek-ccx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;或者：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codex -c &lt;span class=&#34;nv&#34;&gt;model_provider&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;ccx-bridge -c &lt;span class=&#34;nv&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;deepseek-v4-flash
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果這樣能生效，說明設定本身可讀；如果不生效，優先檢查 profile 名稱、TOML 語法、環境變數是否只在目前 shell 裡有效。&lt;/p&gt;
&lt;h2 id=&#34;排障清單&#34;&gt;排障清單
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;401&lt;/code&gt;：Key 不對，或者 &lt;code&gt;env_key&lt;/code&gt; 指向了錯誤的環境變數。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;404&lt;/code&gt;：&lt;code&gt;base_url&lt;/code&gt; 或模型名不對，也可能是把 Responses 請求打到了只支援 Chat Completions 的位址。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tool_calls&lt;/code&gt;、patch、串流解析報錯：大機率是協議橋接不完整。&lt;/li&gt;
&lt;li&gt;仍然提示登入 OpenAI：執行 &lt;code&gt;codex logout&lt;/code&gt;，再確認是否用了正確 profile。&lt;/li&gt;
&lt;li&gt;PowerShell 設定環境變數後新開視窗失效：&lt;code&gt;$env:...&lt;/code&gt; 只對目前會話生效，需要長期保存就改使用者環境變數。&lt;/li&gt;
&lt;li&gt;OpenRouter BYOK 沒走自己的 DeepSeek Key：檢查 OpenRouter 後台 provider key 是否綁定、是否允許目前 OpenRouter API Key 使用，以及是否開啟了 fallback。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;結論&#34;&gt;結論
&lt;/h2&gt;&lt;p&gt;讓 Codex 使用 DeepSeek，不是不能改 &lt;code&gt;config.toml&lt;/code&gt;，而是不能只改 &lt;code&gt;base_url&lt;/code&gt; 就指望一切自動相容。&lt;/p&gt;
&lt;p&gt;目前更穩的兩條路是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用本機閘道做協議橋接，Codex 連本機閘道，閘道再連 DeepSeek。&lt;/li&gt;
&lt;li&gt;用 OpenRouter BYOK 做線上轉發，Codex 連 OpenRouter，DeepSeek Key 綁定在 OpenRouter 後台。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果只是想快速試用，OpenRouter 路線更省事；如果你希望 Key、成本、日誌都盡量掌握在自己手裡，本機閘道更適合長期折騰。&lt;/p&gt;
&lt;p&gt;參考資料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developers.openai.com/codex/config-reference/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI Codex Configuration Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://api-docs.deepseek.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;DeepSeek API Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://openrouter.ai/docs/use-cases/byok/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenRouter BYOK Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>CodeGraph 是什麼？給 Claude Code、Codex 和 Cursor 加一張本地程式碼地圖</title>
        <link>https://knightli.com/zh-tw/2026/05/23/codegraph-local-code-knowledge-graph-ai-coding-agent/</link>
        <pubDate>Sat, 23 May 2026 21:09:46 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/23/codegraph-local-code-knowledge-graph-ai-coding-agent/</guid>
        <description>&lt;p&gt;&lt;code&gt;CodeGraph&lt;/code&gt; 是一個給 AI 編程工具使用的本地程式碼知識圖譜。它會提前給專案建立索引，把符號關係、呼叫圖、程式碼結構、路由關係等資訊整理成可查詢的圖，讓 Claude Code、Codex CLI、Cursor、OpenCode、Hermes Agent 這類工具不用每次都靠 grep、glob、Read 和子代理到處翻檔案。&lt;/p&gt;
&lt;p&gt;它解決的是一個很實際的問題：AI Agent 看大型程式碼庫時，很多成本不是花在真正修改程式碼上，而是花在「找程式碼在哪裡」。如果每次都重新搜尋、讀取、篩選，token、時間和工具呼叫都會被消耗掉。&lt;code&gt;CodeGraph&lt;/code&gt; 的思路是先把程式碼庫變成一張本地地圖，讓 Agent 先問地圖，再決定要不要讀具體檔案。&lt;/p&gt;
&lt;h2 id=&#34;它主要解決什麼痛點&#34;&gt;它主要解決什麼痛點
&lt;/h2&gt;&lt;p&gt;AI 編程工具在小專案裡通常還好，檔案少，搜尋快，讀一遍也不貴。但專案一大，常見問題就會出現：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Agent 為了理解一個模組，反覆呼叫 grep、find、ls、Read。&lt;/li&gt;
&lt;li&gt;探索子代理讀了很多無關檔案，主任務上下文卻沒有變清楚。&lt;/li&gt;
&lt;li&gt;問一個架構問題時，token 大量花在定位檔案上。&lt;/li&gt;
&lt;li&gt;改一個函式前，不知道誰在呼叫它、它又呼叫了誰。&lt;/li&gt;
&lt;li&gt;Web 專案裡，URL 路由和實際處理函式之間的關係不夠直觀。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;CodeGraph&lt;/code&gt; 試圖把這些「先找路」的工作前置。專案索引建好後，Agent 可以直接查詢相關符號、呼叫方、被呼叫方、影響範圍和程式碼片段。&lt;/p&gt;
&lt;h2 id=&#34;安裝方式&#34;&gt;安裝方式
&lt;/h2&gt;&lt;p&gt;專案提供跨平台安裝腳本，不要求使用者自己準備 Node.js：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -fsSL https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.sh &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Windows PowerShell 可以使用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;irm &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;https&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;//&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raw&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;githubusercontent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;com&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;colbymchenry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;codegraph&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;install&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;ps1&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;iex
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果已經有 Node 環境，也可以直接用 npm：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npx @colbymchenry/codegraph
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;或者全域安裝：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm i -g @colbymchenry/codegraph
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;安裝器會自動偵測並配置已安裝的 Agent，例如 Claude Code、Cursor、Codex CLI、opencode 和 Hermes Agent。它會寫入對應的 MCP server 配置和指令檔案，讓這些工具知道什麼時候呼叫 CodeGraph。&lt;/p&gt;
&lt;h2 id=&#34;初始化專案&#34;&gt;初始化專案
&lt;/h2&gt;&lt;p&gt;安裝完成後，需要在目標專案裡建立索引：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; your-project
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codegraph init -i
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這個命令會產生專案級知識圖譜索引。README 中提到，只要專案裡存在 &lt;code&gt;.codegraph/&lt;/code&gt; 目錄，Agent 就可以自動使用 CodeGraph 工具。&lt;/p&gt;
&lt;p&gt;如果不想繼續使用，也可以卸載全域配置：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codegraph uninstall
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;它會移除安裝器寫入的 MCP server 配置、指令和權限。專案中的 &lt;code&gt;.codegraph/&lt;/code&gt; 索引不會被自動刪除，如果要移除專案索引，需要使用 &lt;code&gt;codegraph uninit&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;為什麼它對-agent-有用&#34;&gt;為什麼它對 Agent 有用
&lt;/h2&gt;&lt;p&gt;Claude Code、Codex CLI、Cursor 這類工具在理解程式碼庫時，常常會先做探索：找檔案、讀入口、查引用、再追呼叫鏈。這個過程對人來說像「翻專案」，對模型來說就是一串工具呼叫和上下文消耗。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;CodeGraph&lt;/code&gt; 把這一步變成索引查詢。Agent 可以先用 &lt;code&gt;codegraph_context&lt;/code&gt; 找到相關入口、符號和片段，再用 &lt;code&gt;codegraph_explore&lt;/code&gt; 或其他工具讀取必要內容。這樣做的好處是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;少讀無關檔案。&lt;/li&gt;
&lt;li&gt;少呼叫搜尋工具。&lt;/li&gt;
&lt;li&gt;更快找到真正相關的程式碼。&lt;/li&gt;
&lt;li&gt;改動前更容易看清影響範圍。&lt;/li&gt;
&lt;li&gt;大型倉庫裡的架構問題更容易回答。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;專案 README 給出的基準測試顯示，在 7 個真實開源程式碼庫上，對比啟用 CodeGraph 和不啟用 CodeGraph，平均結果是成本更低、token 更少、速度更快、工具呼叫更少。具體數字會受專案規模、語言、問題類型和 Agent 使用方式影響，但方向很清楚：越大的倉庫，預索引的價值越明顯。&lt;/p&gt;
&lt;h2 id=&#34;核心能力&#34;&gt;核心能力
&lt;/h2&gt;&lt;h3 id=&#34;1-智慧上下文構建&#34;&gt;1. 智慧上下文構建
&lt;/h3&gt;&lt;p&gt;一個工具呼叫可以返回入口點、相關符號和程式碼片段，減少 Agent 先派一堆探索任務再慢慢篩選的情況。對架構理解、模組定位、功能入口分析很有用。&lt;/p&gt;
&lt;h3 id=&#34;2-全文搜尋&#34;&gt;2. 全文搜尋
&lt;/h3&gt;&lt;p&gt;CodeGraph 使用 FTS5 做全文搜尋，可以在整個程式碼庫裡快速按名稱和文字查找程式碼。這不是替代所有 grep 場景，而是讓 Agent 有一個更結構化的第一站。&lt;/p&gt;
&lt;h3 id=&#34;3-影響分析&#34;&gt;3. 影響分析
&lt;/h3&gt;&lt;p&gt;在改函式、類別、方法或路由前，可以查詢 callers、callees 和影響半徑。對重構、修 bug、刪除舊程式碼尤其有用，因為最怕的就是只改了當前檔案，卻漏掉上游或下游呼叫。&lt;/p&gt;
&lt;h3 id=&#34;4-自動保持新鮮&#34;&gt;4. 自動保持新鮮
&lt;/h3&gt;&lt;p&gt;README 中提到，CodeGraph 使用原生檔案系統事件，例如 FSEvents、inotify、ReadDirectoryChangesW，並帶有 debounce auto-sync。意思是索引會隨著本地程式碼變化自動更新，不需要每改一個檔案都手動重建。&lt;/p&gt;
&lt;h3 id=&#34;5-多語言支援&#34;&gt;5. 多語言支援
&lt;/h3&gt;&lt;p&gt;專案列出的支援範圍超過 19 種語言，包括 TypeScript、JavaScript、Python、Go、Rust、Java、C#、PHP、Ruby、C、C++、Swift、Kotlin、Dart、Lua、Luau、Svelte、Liquid、Pascal / Delphi 等。&lt;/p&gt;
&lt;p&gt;這讓它更適合多語言倉庫和全棧專案，而不是只服務某一種語言。&lt;/p&gt;
&lt;h3 id=&#34;6-web-路由感知&#34;&gt;6. Web 路由感知
&lt;/h3&gt;&lt;p&gt;CodeGraph 還會識別多種 Web 框架裡的路由檔案和路由宣告，把 URL pattern 和處理函式連接起來。README 中提到的框架包括 Django、Flask、FastAPI、Express、NestJS、Laravel、Rails、Spring、Gin、Axum、ASP.NET、Vapor、React Router、SvelteKit 等。&lt;/p&gt;
&lt;p&gt;這點很實用。很多 Web 專案的真實入口不是某個明顯的 &lt;code&gt;main&lt;/code&gt; 函式，而是路由、controller、handler、view 或 resolver。Agent 如果能先知道 URL 到處理函式的關係，理解業務流程會快很多。&lt;/p&gt;
&lt;h2 id=&#34;本地優先的設計&#34;&gt;本地優先的設計
&lt;/h2&gt;&lt;p&gt;CodeGraph 強調 &lt;code&gt;100% local&lt;/code&gt;。它不需要 API key，不依賴外部服務，索引資料保存在本地 SQLite 資料庫裡。&lt;/p&gt;
&lt;p&gt;對企業專案、私有倉庫或敏感程式碼來說，這個設計很重要。AI 工具接入程式碼庫時，大家最擔心的往往不是「能不能查到程式碼」，而是「程式碼結構和索引會不會被發出去」。CodeGraph 的定位是本地構建、本地查詢、本地服務 Agent。&lt;/p&gt;
&lt;p&gt;當然，本地也意味著要考慮磁碟空間、索引時間、檔案監聽和專案規模。如果倉庫特別大，第一次初始化和後續同步仍然需要資源。&lt;/p&gt;
&lt;h2 id=&#34;適合哪些場景&#34;&gt;適合哪些場景
&lt;/h2&gt;&lt;p&gt;CodeGraph 更適合這些場景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;大型程式碼庫，經常需要問架構和呼叫鏈問題。&lt;/li&gt;
&lt;li&gt;使用 Claude Code、Codex CLI、Cursor 等 Agent 做程式碼理解和修改。&lt;/li&gt;
&lt;li&gt;希望減少 Agent 到處讀檔案、亂搜、反覆探索。&lt;/li&gt;
&lt;li&gt;需要在改動前分析影響範圍。&lt;/li&gt;
&lt;li&gt;Web 專案路由複雜，需要快速從 URL 找到處理函式。&lt;/li&gt;
&lt;li&gt;團隊希望給 AI Agent 一個更穩定的本地專案索引。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果只是幾十個檔案的小專案，普通搜尋已經夠快，CodeGraph 的優勢可能不明顯。它最有價值的地方，是中大型程式碼庫和經常讓 Agent 做探索的場景。&lt;/p&gt;
&lt;h2 id=&#34;使用時要注意什麼&#34;&gt;使用時要注意什麼
&lt;/h2&gt;&lt;p&gt;第一，CodeGraph 不是替代程式碼審查和測試的工具。它能幫助 Agent 更快找到相關程式碼，但不能保證 Agent 的修改一定正確。&lt;/p&gt;
&lt;p&gt;第二，索引品質會影響使用效果。專案結構複雜、生成程式碼很多、語言混雜或 build 產物沒有排除時，索引可能會變得臃腫。使用前最好確認 &lt;code&gt;.gitignore&lt;/code&gt;、專案目錄和索引範圍是否合理。&lt;/p&gt;
&lt;p&gt;第三，MCP 配置和 Agent 指令很關鍵。README 裡也提醒，CodeGraph 只有在被正確查詢時才有幫助。如果 Agent 仍然繞開它去大量讀檔案，預索引就會變成額外開銷。&lt;/p&gt;
&lt;p&gt;第四，雖然它是本地工具，也要注意權限。安裝器會寫入 Agent 配置和權限列表，團隊環境中最好統一審查這些配置。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;CodeGraph&lt;/code&gt; 的價值可以簡單理解為：給 AI Agent 一張本地程式碼地圖。它不是讓模型更聰明，而是讓模型少迷路。&lt;/p&gt;
&lt;p&gt;當 Claude Code、Codex CLI、Cursor 這類工具面對大型倉庫時，最耗費上下文的往往是探索過程。CodeGraph 用預索引的符號關係、呼叫圖、路由圖和全文搜尋，把「找程式碼」這一步提前做好，讓 Agent 把更多預算花在理解和修改上。&lt;/p&gt;
&lt;p&gt;如果你已經在真實專案裡使用 AI 編程工具，並且經常遇到「它讀了一堆檔案還是沒找到重點」的情況，CodeGraph 值得試一下。它代表了 AI 編程工具的一個重要方向：不只是換更強的模型，也要給模型更好的本地程式碼上下文。&lt;/p&gt;
&lt;p&gt;參考資料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub 專案：&lt;a class=&#34;link&#34; href=&#34;https://github.com/colbymchenry/codegraph&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/colbymchenry/codegraph&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Google I/O 之後，GPT 和 Gemini 訂閱怎麼選？普通使用者與開發者對比</title>
        <link>https://knightli.com/zh-tw/2026/05/21/gpt-vs-gemini-subscription-after-google-io-2026/</link>
        <pubDate>Thu, 21 May 2026 08:33:14 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/21/gpt-vs-gemini-subscription-after-google-io-2026/</guid>
        <description>&lt;p&gt;Google I/O 2026 之後，很多人的 AI 訂閱選擇變複雜了。&lt;/p&gt;
&lt;p&gt;以前問題比較簡單：寫作、問答、編程、文件分析，大多數人優先看 ChatGPT；如果深度使用 Google 搜尋、Android、Gmail、Docs、YouTube，再考慮 Gemini。現在不一樣了。Google 在 I/O 上把 Gemini 3.5 Flash、Gemini Omni、Antigravity 2.0、Gemini API Managed Agents、Google AI Studio 和 AI Ultra 訂閱一起推出來，Gemini 生態開始從「可選項」變成「強競爭主線」。&lt;/p&gt;
&lt;p&gt;這篇文章不做抽象模型跑分，而是回答一個實際問題：普通使用者、開發者、內容創作者和企業使用者，到底該訂閱 GPT / ChatGPT，還是 Gemini / Google AI？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注意：AI 訂閱價格、額度、地區和模型可用性變化很快。本文寫作時間是 2026 年 5 月 21 日，正式訂閱前應以 OpenAI 與 Google 當前頁面為準。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;先說結論&#34;&gt;先說結論
&lt;/h2&gt;&lt;p&gt;如果你只想選一個主力訂閱，可以按這個邏輯：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;日常寫作、問答、文件分析、泛辦公、中文英文混合使用：優先 ChatGPT Plus。&lt;/li&gt;
&lt;li&gt;高頻編程、需要 Codex、複雜推理、專案級程式碼任務：優先 ChatGPT Plus / Pro，再按額度決定是否升級。&lt;/li&gt;
&lt;li&gt;深度使用 Google 生態、Gmail、Docs、Drive、Android、Search：優先 Gemini / Google AI Pro。&lt;/li&gt;
&lt;li&gt;重點做影片、AI 影像、Google Flow、YouTube Shorts、Gemini Omni：優先 Google AI Pro / Ultra。&lt;/li&gt;
&lt;li&gt;需要 Antigravity、Gemini API Managed Agents、AI Studio 到 Android 的工作流：重點看 Google AI Pro / Ultra。&lt;/li&gt;
&lt;li&gt;企業團隊：不要只看個人訂閱，重點看 Business / Enterprise、Workspace、權限、審計和資料邊界。&lt;/li&gt;
&lt;li&gt;預算有限：一個主力付費訂閱 + 另一個平台免費層或按量 API，通常比同時訂兩個高階套餐更划算。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一句話：GPT 更像通用生產力和程式碼助手主力；Gemini 在 Google I/O 之後更像 Google 生態裡的系統級 AI 套件。&lt;/p&gt;
&lt;h2 id=&#34;google-io-之後gemini-發生了什麼變化&#34;&gt;Google I/O 之後，Gemini 發生了什麼變化
&lt;/h2&gt;&lt;p&gt;Google I/O 2026 讓 Gemini 的價值不再只取決於 Gemini App 本身。&lt;/p&gt;
&lt;p&gt;幾個關鍵變化：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Gemini 3.5 Flash&lt;/code&gt;：Google 把它定位為從 prompt 到 action 的高速模型，面向真實 Agent 工作流。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Gemini Omni&lt;/code&gt;：從任意輸入創作內容，當前重點從影片開始，支援多模態創作和自然語言多輪編輯。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Google Antigravity 2.0&lt;/code&gt;：Agent-first development platform，面向開發者的多 Agent 編排與編程平台。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Gemini API Managed Agents&lt;/code&gt;：透過 API 建立可推理、可用工具、可執行程式碼的託管 Agent。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Google AI Studio&lt;/code&gt;：從 prompt playground 走向行動端、Android 原生應用生成和 Antigravity 專案匯出。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Google AI Ultra&lt;/code&gt;：I/O 後新增 $100/月檔位，並面向開發者、技術負責人、知識工作者和高階創作者。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;更重要的是，Google 把 Gemini App 的使用額度從傳統每日 prompt 限制，轉向 &lt;code&gt;compute-used&lt;/code&gt; 模型。複雜影片、程式碼和長上下文任務會消耗更多額度，簡單文字任務消耗更少；額度每 5 小時刷新，直到達到週限制。&lt;/p&gt;
&lt;p&gt;這說明 Google 正在把 Gemini 訂閱做成「模型 + 應用 + 創作 + 開發工具 + Google 生態」的打包入口。&lt;/p&gt;
&lt;h2 id=&#34;chatgpt--gpt-訂閱現在適合誰&#34;&gt;ChatGPT / GPT 訂閱現在適合誰
&lt;/h2&gt;&lt;p&gt;ChatGPT 的優勢依然很強，尤其適合把 AI 當作日常工作主力的人。&lt;/p&gt;
&lt;p&gt;根據 OpenAI 當前價格頁和幫助文件，ChatGPT Free 可以使用 GPT-5.5 Instant 等基礎能力；Plus 提供 GPT-5.5 Thinking、更多訊息和上傳額度、更強圖像生成、deep research、agent mode、專案、任務、自訂 GPT 和擴展 Codex 使用；Pro 則提供更高額度、GPT-5.5 Pro、更高 Codex 使用量、最大 deep research 和 agent mode。&lt;/p&gt;
&lt;p&gt;更適合 ChatGPT 的場景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;寫作、總結、翻譯、改稿。&lt;/li&gt;
&lt;li&gt;複雜問答和結構化分析。&lt;/li&gt;
&lt;li&gt;文件上傳、表格分析、研究報告。&lt;/li&gt;
&lt;li&gt;編程問答、程式碼審查、重構建議。&lt;/li&gt;
&lt;li&gt;使用 Codex 做程式碼庫任務。&lt;/li&gt;
&lt;li&gt;多語言內容生產。&lt;/li&gt;
&lt;li&gt;對模型品質和回答穩定性要求高，但不強依賴 Google 產品。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你是普通使用者，ChatGPT Plus 仍然是最穩的主力訂閱。它覆蓋面廣，學習成本低，中文和英文任務都比較均衡。&lt;/p&gt;
&lt;p&gt;如果你是開發者，ChatGPT 的關鍵不只是聊天，而是 Codex。OpenAI 幫助文件說明，Codex 可隨符合條件的 ChatGPT 計畫使用，額度隨計畫不同而變化。也就是說，如果你大量使用 Codex 做程式碼修改、PR、重構、測試修復，訂閱選擇要把 Codex 額度一起算進去。&lt;/p&gt;
&lt;h2 id=&#34;gemini--google-ai-訂閱現在適合誰&#34;&gt;Gemini / Google AI 訂閱現在適合誰
&lt;/h2&gt;&lt;p&gt;Gemini 的優勢在 Google I/O 之後更清晰：它和 Google 生態綁定更深。&lt;/p&gt;
&lt;p&gt;Google AI 訂閱現在不只是 Gemini App 裡的模型額度，還包括 Gemini Omni、Google Flow、Antigravity、AI Studio、部分 YouTube Premium / Lite 權益、Workspace / Android / Search 生態能力等。Google 官方還把 AI Ultra 擴成 $100 與更高階檔位，強調開發者、技術負責人、知識工作者和高階創作者。&lt;/p&gt;
&lt;p&gt;更適合 Gemini 的場景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你深度使用 Gmail、Docs、Drive、Sheets、Slides、Android。&lt;/li&gt;
&lt;li&gt;你想把 AI 放進 Google Search、YouTube、Workspace 生態。&lt;/li&gt;
&lt;li&gt;你關注 Gemini Omni、Google Flow、影片生成和影片編輯。&lt;/li&gt;
&lt;li&gt;你想試 Antigravity、Gemini API Managed Agents、AI Studio mobile。&lt;/li&gt;
&lt;li&gt;你需要超長上下文文件理解。&lt;/li&gt;
&lt;li&gt;你做 Google 生態應用、Android 原生應用、Workspace 自動化。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Google 官方幫助頁顯示，Gemini Apps 的上下文視窗會隨訂閱提高：無 AI plan 為 32K，AI Plus 為 128K，AI Pro 和 AI Ultra 為 1 million。AI Pro / Ultra 也會提供更高使用限制、更多特性和部分早期功能。&lt;/p&gt;
&lt;p&gt;如果你的工作環境已經在 Google 生態裡，Gemini 的價值會被放大。否則，單獨把 Gemini 當作「另一個聊天機器人」來訂閱，性價比就不一定比 ChatGPT 更穩。&lt;/p&gt;
&lt;h2 id=&#34;普通使用者怎麼選&#34;&gt;普通使用者怎麼選
&lt;/h2&gt;&lt;p&gt;普通使用者最容易踩的坑，是因為新模型發布就同時訂多個平台。&lt;/p&gt;
&lt;p&gt;更理性的選法是先看主場景。&lt;/p&gt;
&lt;p&gt;如果你主要做這些事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;寫文章。&lt;/li&gt;
&lt;li&gt;查資料。&lt;/li&gt;
&lt;li&gt;做總結。&lt;/li&gt;
&lt;li&gt;讀 PDF。&lt;/li&gt;
&lt;li&gt;寫郵件。&lt;/li&gt;
&lt;li&gt;改履歷。&lt;/li&gt;
&lt;li&gt;學習語言。&lt;/li&gt;
&lt;li&gt;日常問答。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;優先選 ChatGPT Plus。它的通用性更好，任務邊界更清楚，不需要你深度綁定某個生態。&lt;/p&gt;
&lt;p&gt;如果你主要做這些事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gmail / Docs / Drive / YouTube / Android 高頻使用。&lt;/li&gt;
&lt;li&gt;希望 AI 直接進入 Google 生態。&lt;/li&gt;
&lt;li&gt;想體驗 Gemini App、Daily Brief、Google Search AI、YouTube 內容問答。&lt;/li&gt;
&lt;li&gt;需要長上下文讀取 Google 文件。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;優先選 Google AI Pro。&lt;/p&gt;
&lt;p&gt;如果你只是輕量使用者，兩個平台都先用免費層，等明確遇到限制再付費。不要為了「可能用到」而訂閱高階套餐。&lt;/p&gt;
&lt;h2 id=&#34;開發者怎麼選&#34;&gt;開發者怎麼選
&lt;/h2&gt;&lt;p&gt;開發者要分兩類。&lt;/p&gt;
&lt;p&gt;第一類是以程式碼問答、修 bug、寫腳本、讀程式碼庫為主。優先看 ChatGPT Plus / Pro + Codex。&lt;/p&gt;
&lt;p&gt;理由是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Codex 和 ChatGPT 帳號打通。&lt;/li&gt;
&lt;li&gt;ChatGPT 對程式碼解釋、重構、測試、錯誤分析比較穩。&lt;/li&gt;
&lt;li&gt;Plus 已經覆蓋很多日常開發任務。&lt;/li&gt;
&lt;li&gt;Pro 更適合高頻、長時間、複雜程式碼庫任務。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第二類是面向 Google 生態、Agent 平台、Android、Workspace 或 Gemini API 開發。優先看 Google AI Pro / Ultra。&lt;/p&gt;
&lt;p&gt;理由是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gemini 3.5 Flash 是 Google I/O 後 Agent 工作流重點模型。&lt;/li&gt;
&lt;li&gt;Antigravity 2.0 是 Google 的 Agent-first 開發平台。&lt;/li&gt;
&lt;li&gt;Managed Agents 能透過 API 建立帶工具和隔離 Linux 環境的 Agent。&lt;/li&gt;
&lt;li&gt;AI Studio 可以和 Android、Workspace、Antigravity 更自然銜接。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你是全端開發者，最務實的組合通常是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT Plus 作為日常程式碼與文件主力。&lt;/li&gt;
&lt;li&gt;Gemini 免費層或 AI Pro 用於 Google 生態、長上下文和影片/Agent 新能力。&lt;/li&gt;
&lt;li&gt;API 按量使用，不要把個人訂閱誤當生產 API 預算。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;內容創作者怎麼選&#34;&gt;內容創作者怎麼選
&lt;/h2&gt;&lt;p&gt;內容創作者的選擇取決於你做什麼內容。&lt;/p&gt;
&lt;p&gt;如果你主要做：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文案。&lt;/li&gt;
&lt;li&gt;標題。&lt;/li&gt;
&lt;li&gt;腳本。&lt;/li&gt;
&lt;li&gt;文章。&lt;/li&gt;
&lt;li&gt;圖文內容。&lt;/li&gt;
&lt;li&gt;資料整理。&lt;/li&gt;
&lt;li&gt;多語言改寫。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ChatGPT Plus 依然很穩。&lt;/p&gt;
&lt;p&gt;如果你主要做：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;影片生成。&lt;/li&gt;
&lt;li&gt;短影片創意。&lt;/li&gt;
&lt;li&gt;AI 影像。&lt;/li&gt;
&lt;li&gt;YouTube Shorts。&lt;/li&gt;
&lt;li&gt;Google Flow 工作流。&lt;/li&gt;
&lt;li&gt;多模態素材整合。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Gemini / Google AI Pro 或 Ultra 更值得關注。I/O 之後，Gemini Omni 和 Google Flow 是 Google 在創作場景裡的核心牌。&lt;/p&gt;
&lt;p&gt;如果預算有限，可以先訂一個文字主力，再用另一個平台的免費層或短期訂閱測試影片能力。影片模型的額度、排隊、時長、解析度和地區限制變化很快，不建議一開始就按長期生產服務規劃。&lt;/p&gt;
&lt;h2 id=&#34;企業和團隊怎麼選&#34;&gt;企業和團隊怎麼選
&lt;/h2&gt;&lt;p&gt;企業不要按個人使用者思路選。&lt;/p&gt;
&lt;p&gt;企業真正要看的不是「哪個模型這週更強」，而是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;資料是否用於訓練。&lt;/li&gt;
&lt;li&gt;是否有 SSO、MFA、RBAC。&lt;/li&gt;
&lt;li&gt;是否有審計日誌。&lt;/li&gt;
&lt;li&gt;是否支援內部知識連接。&lt;/li&gt;
&lt;li&gt;是否能控制外掛、連接器和 Agent 權限。&lt;/li&gt;
&lt;li&gt;是否符合組織的合規要求。&lt;/li&gt;
&lt;li&gt;是否能和現有辦公套件打通。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果企業已經重度使用 Google Workspace，Gemini 企業方案自然更值得評估。如果團隊已經圍繞 ChatGPT、Codex、OpenAI API 和內部工具鏈搭建流程，OpenAI Business / Enterprise 更自然。&lt;/p&gt;
&lt;p&gt;對工程團隊來說，還要單獨評估 Codex、Antigravity、Gemini API Managed Agents、MCP、CI/CD、程式碼權限、倉庫存取和審計。&lt;/p&gt;
&lt;h2 id=&#34;什麼時候需要-pro--ultra&#34;&gt;什麼時候需要 Pro / Ultra
&lt;/h2&gt;&lt;p&gt;很多人其實不需要高階檔位。&lt;/p&gt;
&lt;p&gt;你需要 ChatGPT Pro 的典型信號：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每天長時間使用 ChatGPT。&lt;/li&gt;
&lt;li&gt;Plus 額度經常不夠。&lt;/li&gt;
&lt;li&gt;高頻使用 Codex。&lt;/li&gt;
&lt;li&gt;經常跑 deep research、agent mode、複雜推理。&lt;/li&gt;
&lt;li&gt;需要 GPT-5.5 Pro 這類更高階模型。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你需要 Google AI Ultra 的典型信號：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;高頻使用 Gemini、Flow、Antigravity。&lt;/li&gt;
&lt;li&gt;需要更高 Gemini / Antigravity 使用額度。&lt;/li&gt;
&lt;li&gt;做影片創作、AI 影像、長上下文研究。&lt;/li&gt;
&lt;li&gt;深度依賴 Google 生態和新功能優先體驗。&lt;/li&gt;
&lt;li&gt;需要 Gemini Spark、Project Genie 或更高級訂閱權益。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你只是每天問幾次問題、偶爾寫文章或改程式碼，Plus / Pro、AI Pro / Ultra 這類高階檔位可能都不是剛需。&lt;/p&gt;
&lt;h2 id=&#34;最省錢的訂閱策略&#34;&gt;最省錢的訂閱策略
&lt;/h2&gt;&lt;p&gt;更推薦這種組合：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先選一個主力付費訂閱。&lt;/li&gt;
&lt;li&gt;另一個平台先用免費層。&lt;/li&gt;
&lt;li&gt;真正需要 API 時再按量付費。&lt;/li&gt;
&lt;li&gt;影片、Agent、深度研究類高消耗功能按月開關，不要全年盲訂。&lt;/li&gt;
&lt;li&gt;每月復盤一次：本月有沒有真的用滿額度？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;幾個常見組合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;普通辦公：ChatGPT Plus + Gemini 免費層。&lt;/li&gt;
&lt;li&gt;Google 生態使用者：Google AI Pro + ChatGPT 免費層。&lt;/li&gt;
&lt;li&gt;開發者：ChatGPT Plus/Pro + Gemini API/AI Studio 按需。&lt;/li&gt;
&lt;li&gt;影片創作者：Google AI Pro/Ultra + ChatGPT 免費層或 Plus。&lt;/li&gt;
&lt;li&gt;企業團隊：不要用個人套餐拼，直接評估 Business / Enterprise / Workspace 方案。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;訂閱前檢查清單&#34;&gt;訂閱前檢查清單
&lt;/h2&gt;&lt;p&gt;付費前先確認這些問題：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你的地區是否支援目標套餐？&lt;/li&gt;
&lt;li&gt;你要用的模型是否包含在該套餐裡？&lt;/li&gt;
&lt;li&gt;Codex、Antigravity、Flow、Omni 是否真的可用？&lt;/li&gt;
&lt;li&gt;影片功能是否有地區、年齡、排隊或解析度限制？&lt;/li&gt;
&lt;li&gt;API 呼叫是否包含在訂閱裡，還是單獨計費？&lt;/li&gt;
&lt;li&gt;文件上傳、上下文視窗、agent mode、deep research 是否有額度限制？&lt;/li&gt;
&lt;li&gt;資料隱私設定是否符合你的專案要求？&lt;/li&gt;
&lt;li&gt;你是否已經有 Google One、Workspace、ChatGPT Business 或學校/公司帳號權益？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;尤其要注意：個人訂閱不等於 API 免費，不等於商用無限額度，也不等於企業合規。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;Google I/O 之後，Gemini 的競爭力明顯增強，尤其是在影片、多模態、Google 生態、Android、AI Studio 和 Antigravity 方向。但 ChatGPT 仍然是更穩的通用主力，特別是在日常寫作、複雜問答、文件分析、程式碼輔助和 Codex 工作流裡。&lt;/p&gt;
&lt;p&gt;最簡單的判斷是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不知道選哪個：先選 ChatGPT Plus。&lt;/li&gt;
&lt;li&gt;深度 Google 使用者：選 Google AI Pro。&lt;/li&gt;
&lt;li&gt;高頻開發者：看 Codex 和 Antigravity 誰更貼近你的工作流。&lt;/li&gt;
&lt;li&gt;影片創作者：優先看 Gemini Omni、Flow 和 Google AI Pro / Ultra。&lt;/li&gt;
&lt;li&gt;企業使用者：按合規、權限、審計和現有辦公生態選，而不是按模型熱度選。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AI 訂閱不是越多越好。真正划算的方式，是明確一個主力工作流，再把其他平台作為補充，而不是為每一場發布會都多開一個長期訂閱。&lt;/p&gt;
&lt;p&gt;參考來源：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://chatgpt.com/pricing/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI：ChatGPT Pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/11369540-using-codex-with-your-chatgpt-plan&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI Help：Using Codex with your ChatGPT plan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/products-and-platforms/products/google-one/google-ai-subscriptions/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Blog：Everything new in Google AI subscriptions from I/O 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/innovation-and-ai/technology/developers-tools/google-io-2026-developer-highlights/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Blog：I/O 2026 developer highlights&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://support.google.com/gemini/answer/16275805&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Help：Gemini Apps limits and upgrades for Google AI subscribers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Graphify 解決 Claude Code 最大局限：把程式碼庫變成 AI 可查詢知識圖譜</title>
        <link>https://knightli.com/zh-tw/2026/05/21/safishamsi-graphify-ai-code-knowledge-graph/</link>
        <pubDate>Thu, 21 May 2026 08:02:32 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/21/safishamsi-graphify-ai-code-knowledge-graph/</guid>
        <description>&lt;p&gt;&lt;code&gt;safishamsi/graphify&lt;/code&gt; 是一個面向 AI 編程助手的知識圖譜工具。它的目標很直接：把一個專案目錄裡的程式碼、文件、SQL schema、腳本、論文、圖片、影片和音訊，整理成可查詢的知識圖譜，讓 AI 助手不再只靠 &lt;code&gt;grep&lt;/code&gt;、全文閱讀或臨時搜尋來理解專案。&lt;/p&gt;
&lt;p&gt;專案地址：&lt;a class=&#34;link&#34; href=&#34;https://github.com/safishamsi/graphify&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;safishamsi/graphify&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;截至本文整理時，GitHub 頁面顯示專案約有 50.2k stars、5.4k forks，授權為 MIT。README 對它的描述是：在 AI 編程助手裡輸入 &lt;code&gt;/graphify&lt;/code&gt;，它就會把整個專案映射成一個可以查詢的知識圖譜。&lt;/p&gt;
&lt;h2 id=&#34;它解決的核心問題&#34;&gt;它解決的核心問題
&lt;/h2&gt;&lt;p&gt;AI 編程助手越來越強，但在真實程式碼庫裡仍然經常遇到幾個問題：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不知道關鍵模組之間怎麼連接。&lt;/li&gt;
&lt;li&gt;讀了很多檔案，但沒形成整體架構地圖。&lt;/li&gt;
&lt;li&gt;搜尋命中了文字，卻不知道上下游依賴。&lt;/li&gt;
&lt;li&gt;程式碼、資料庫 schema、文件和基礎設施設定分散在不同地方。&lt;/li&gt;
&lt;li&gt;多人協作時，每個人對專案結構的理解不一致。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Graphify 想做的是給專案生成一層「記憶層」。它把程式碼實體、文件概念、資料庫表、設定、設計說明和跨檔案關係連接起來，讓 AI 助手可以按圖譜查詢，而不是每次從零開始掃檔案。&lt;/p&gt;
&lt;h2 id=&#34;最小使用方式&#34;&gt;最小使用方式
&lt;/h2&gt;&lt;p&gt;Graphify 的最小用法非常簡單。安裝後，在 AI 編程助手裡輸入：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在 PowerShell 裡要注意，前導 &lt;code&gt;/&lt;/code&gt; 會被當成路徑分隔符，所以 Windows PowerShell 下應使用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;執行後會生成 &lt;code&gt;graphify-out/&lt;/code&gt; 目錄，核心檔案包括：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify-out/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── graph.html
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── GRAPH_REPORT.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── graph.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這三個檔案分工不同：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;graph.html&lt;/code&gt;：瀏覽器裡打開的互動式圖譜，可以點擊節點、過濾和搜尋。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GRAPH_REPORT.md&lt;/code&gt;：專案亮點、關鍵概念、意外連接和推薦問題。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;graph.json&lt;/code&gt;：完整圖譜，後續可以直接查詢，不必重新讀所有檔案。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果想生成更可讀的架構頁面和 Mermaid 呼叫流程圖，可以執行：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify &lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; callflow-html
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;安裝和平台支援&#34;&gt;安裝和平台支援
&lt;/h2&gt;&lt;p&gt;Graphify 的 PyPI 包名是 &lt;code&gt;graphifyy&lt;/code&gt;，注意是雙 &lt;code&gt;y&lt;/code&gt;。README 特別提醒，PyPI 上其他 &lt;code&gt;graphify*&lt;/code&gt; 包並不屬於該專案，但 CLI 命令仍然叫 &lt;code&gt;graphify&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;推薦安裝方式是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;uv tool install graphifyy
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;也可以使用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pipx install graphifyy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install graphifyy
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;安裝後註冊到 AI 助手：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;專案支援的平台很多，包括 Claude Code、Codex、OpenCode、GitHub Copilot CLI、VS Code Copilot Chat、Aider、Cursor、Gemini CLI、Kimi Code、Kiro、Google Antigravity 等。不同平台可以用不同安裝命令，例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify install --platform codex
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify install --platform gemini
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify cursor install
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify antigravity install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Codex 使用者還需要在 &lt;code&gt;~/.codex/config.toml&lt;/code&gt; 的 &lt;code&gt;[features]&lt;/code&gt; 下加入：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;multi_agent&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;README 也說明，Codex 使用 &lt;code&gt;$graphify&lt;/code&gt;，不是 &lt;code&gt;/graphify&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;它能處理哪些檔案&#34;&gt;它能處理哪些檔案
&lt;/h2&gt;&lt;p&gt;Graphify 覆蓋的輸入類型很廣。&lt;/p&gt;
&lt;p&gt;程式碼方面，它支援 31 種語言，包括 Python、TypeScript、JavaScript、Go、Rust、Java、C/C++、Ruby、C#、Kotlin、Scala、PHP、Swift、Lua、Zig、PowerShell、SQL、Shell、JSON 等。&lt;/p&gt;
&lt;p&gt;文件方面，它支援：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.mdx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.qmd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.html&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.txt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.rst&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.yaml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.yml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;還可以透過可選依賴擴展更多類型：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install &lt;span class=&#34;s2&#34;&gt;&amp;#34;graphifyy[pdf]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install &lt;span class=&#34;s2&#34;&gt;&amp;#34;graphifyy[office]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install &lt;span class=&#34;s2&#34;&gt;&amp;#34;graphifyy[video]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install &lt;span class=&#34;s2&#34;&gt;&amp;#34;graphifyy[mcp]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install &lt;span class=&#34;s2&#34;&gt;&amp;#34;graphifyy[neo4j]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install &lt;span class=&#34;s2&#34;&gt;&amp;#34;graphifyy[sql]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install &lt;span class=&#34;s2&#34;&gt;&amp;#34;graphifyy[all]&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;其中，&lt;code&gt;pdf&lt;/code&gt; 用於 PDF 提取，&lt;code&gt;office&lt;/code&gt; 用於 &lt;code&gt;.docx&lt;/code&gt; 和 &lt;code&gt;.xlsx&lt;/code&gt;，&lt;code&gt;video&lt;/code&gt; 用於影片和音訊轉寫，&lt;code&gt;mcp&lt;/code&gt; 用於 MCP stdio server，&lt;code&gt;neo4j&lt;/code&gt; 用於推送到 Neo4j，&lt;code&gt;sql&lt;/code&gt; 用於 SQL schema 提取。&lt;/p&gt;
&lt;h2 id=&#34;生成的報告有什麼價值&#34;&gt;生成的報告有什麼價值
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;GRAPH_REPORT.md&lt;/code&gt; 不是普通摘要，它會把專案裡更值得 AI 助手關注的關係挑出來。&lt;/p&gt;
&lt;p&gt;README 裡提到的報告內容包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;God nodes&lt;/code&gt;：專案裡連接最多的核心概念。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Surprising connections&lt;/code&gt;：跨檔案、跨模組的意外連接。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;The why&lt;/code&gt;：從註解、docstring、設計文件裡提取出的設計理由。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Suggested questions&lt;/code&gt;：圖譜特別適合回答的問題。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Confidence tags&lt;/code&gt;：關係會標記為 &lt;code&gt;EXTRACTED&lt;/code&gt;、&lt;code&gt;INFERRED&lt;/code&gt; 或 &lt;code&gt;AMBIGUOUS&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這點很關鍵。普通搜尋只能告訴你「哪裡出現了這個詞」，而圖譜可以回答「這個概念和哪些模組、設定、表、文件有關」。對大型程式碼庫來說，這比單純全文檢索更接近架構理解。&lt;/p&gt;
&lt;h2 id=&#34;常用命令&#34;&gt;常用命令
&lt;/h2&gt;&lt;p&gt;Graphify 的常見命令包括：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify .
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify ./docs --update
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify . --cluster-only
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify . --no-viz
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify . --wiki
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify &lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; callflow-html
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify query &lt;span class=&#34;s2&#34;&gt;&amp;#34;what connects auth to the database?&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify path &lt;span class=&#34;s2&#34;&gt;&amp;#34;UserService&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;DatabasePool&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify explain &lt;span class=&#34;s2&#34;&gt;&amp;#34;RateLimiter&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;也可以把論文或影片加入圖譜：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify add https://arxiv.org/abs/1706.03762
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify add &amp;lt;youtube-url&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果要做 PR 輔助分析，還可以使用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify prs
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify prs &lt;span class=&#34;m&#34;&gt;42&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify prs --triage
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify prs --conflicts
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這類命令適合程式碼評審場景：看 PR 影響了哪些圖譜社群、是否和其他 PR 有衝突風險、哪些 review queue 更值得優先處理。&lt;/p&gt;
&lt;h2 id=&#34;和-mcpneo4jci-的關係&#34;&gt;和 MCP、Neo4j、CI 的關係
&lt;/h2&gt;&lt;p&gt;Graphify 不只是生成 HTML 圖。它也可以把圖譜暴露給 AI 助手反覆呼叫。&lt;/p&gt;
&lt;p&gt;例如可以啟動 MCP server：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python -m graphify.serve graphify-out/graph.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;MCP server 提供的能力包括 &lt;code&gt;query_graph&lt;/code&gt;、&lt;code&gt;get_node&lt;/code&gt;、&lt;code&gt;get_neighbors&lt;/code&gt;、&lt;code&gt;shortest_path&lt;/code&gt;、&lt;code&gt;list_prs&lt;/code&gt;、&lt;code&gt;get_pr_impact&lt;/code&gt;、&lt;code&gt;triage_prs&lt;/code&gt; 等。&lt;/p&gt;
&lt;p&gt;它也支援 Neo4j 匯出或推送：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify ./raw --neo4j
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/graphify ./raw --neo4j-push bolt://localhost:7687
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;團隊協作上，README 建議可以提交 &lt;code&gt;graphify-out/&lt;/code&gt;，讓團隊每個人拉取後都能共享同一份專案地圖。還可以執行：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;graphify hook install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這樣每次 git commit 後自動重建圖譜，並設定 merge driver，避免 &lt;code&gt;graph.json&lt;/code&gt; 在多人並行提交時留下衝突標記。&lt;/p&gt;
&lt;h2 id=&#34;隱私和成本要怎麼看&#34;&gt;隱私和成本要怎麼看
&lt;/h2&gt;&lt;p&gt;Graphify 的 README 對隱私邊界寫得比較清楚。&lt;/p&gt;
&lt;p&gt;程式碼檔案會透過 tree-sitter 在本地解析，不會發出 API 呼叫。影片和音訊可以透過 faster-whisper 本地轉寫。文件、PDF、圖片這類語義提取內容，則會透過你的 AI 助手模型 API 處理。&lt;/p&gt;
&lt;p&gt;如果用 headless &lt;code&gt;graphify extract&lt;/code&gt;，可能需要設定這些環境變數：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ANTHROPIC_API_KEY
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GEMINI_API_KEY
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GOOGLE_API_KEY
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;OPENAI_API_KEY
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;DEEPSEEK_API_KEY
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;MOONSHOT_API_KEY
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;OLLAMA_BASE_URL
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;本地 Ollama、AWS Bedrock、Claude Code CLI 等也可以作為 backend。README 還寫明專案沒有 telemetry、usage tracking 和 analytics。&lt;/p&gt;
&lt;p&gt;實際使用時要注意：程式碼本地解析不等於所有內容都不出網。涉及文件、PDF、圖片或雲端模型時，仍然要看 backend、API key、企業合規和資料邊界。&lt;/p&gt;
&lt;h2 id=&#34;適合哪些場景&#34;&gt;適合哪些場景
&lt;/h2&gt;&lt;p&gt;Graphify 適合幾類使用者：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;想讓 Claude Code、Codex、Cursor、Gemini CLI 更懂專案結構的開發者。&lt;/li&gt;
&lt;li&gt;需要快速理解大型陌生程式碼庫的人。&lt;/li&gt;
&lt;li&gt;需要把程式碼、SQL schema、文件、設定放在一起分析的團隊。&lt;/li&gt;
&lt;li&gt;做架構審查、PR review、重構影響分析的人。&lt;/li&gt;
&lt;li&gt;希望把專案知識暴露成 MCP 工具給 Agent 使用的人。&lt;/li&gt;
&lt;li&gt;想為團隊保留「專案地圖」的技術負責人。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它不一定適合所有專案。小型腳本、一次性 demo、結構非常簡單的倉庫，用普通搜尋和 README 可能已經夠用。Graphify 的價值更容易出現在模組多、文件多、團隊協作多、AI 助手頻繁參與開發的大專案裡。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;Graphify 的意義在於，它把 AI 編程助手的上下文從「臨時讀取檔案」推進到「長期可查詢的專案知識圖譜」。&lt;/p&gt;
&lt;p&gt;對開發者來說，它不是替代 IDE、搜尋或 LSP，而是給 AI 助手補一層結構化記憶：哪些模組重要、哪些概念連接緊密、哪些文件解釋了設計理由、某個 PR 會影響哪些社群。隨著 Codex、Claude Code、Gemini CLI、Antigravity 這類 Agent 工具繼續普及，這類「專案圖譜層」會越來越有用。&lt;/p&gt;
&lt;p&gt;參考來源：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/safishamsi/graphify&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub：safishamsi/graphify&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Scientific Agent Skills：把科研工作流交給 AI Agent 的技能庫</title>
        <link>https://knightli.com/zh-tw/2026/05/17/scientific-agent-skills/</link>
        <pubDate>Sun, 17 May 2026 17:52:04 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/17/scientific-agent-skills/</guid>
        <description>&lt;p&gt;&lt;code&gt;K-Dense-AI/scientific-agent-skills&lt;/code&gt; 是一個面向科研和研究工作的 Agent Skills 集合。&lt;/p&gt;
&lt;p&gt;它的定位不是再做一個聊天機器人，而是把科研裡經常要查文件、連資料庫、寫分析腳本、處理檔案、生成圖表和整理報告的流程，拆成一組可以被 AI Agent 發現和調用的技能。&lt;/p&gt;
&lt;p&gt;專案地址：&lt;a class=&#34;link&#34; href=&#34;https://github.com/K-Dense-AI/scientific-agent-skills&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/K-Dense-AI/scientific-agent-skills&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;截至 2026-05-17 寫作時，GitHub API 顯示這個倉庫約有 23.4k stars、2.5k forks，許可證為 MIT，最近一次推送時間是 2026-05-11。README 裡寫的是 135 個 ready-to-use scientific and research skills，不過倉庫 &lt;code&gt;scientific-skills&lt;/code&gt; 目錄目前透過 GitHub API 能看到 137 個條目。這個差異可能來自統計口徑、近期新增目錄或 README 尚未同步更新。&lt;/p&gt;
&lt;h2 id=&#34;先說結論&#34;&gt;先說結論
&lt;/h2&gt;&lt;p&gt;Scientific Agent Skills 適合已經在用 Codex、Claude Code、Cursor、Gemini CLI 或其他支援 Agent Skills 標準工具的人。&lt;/p&gt;
&lt;p&gt;它的價值主要在三點：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把科研工具鏈的使用方式寫成 &lt;code&gt;SKILL.md&lt;/code&gt;，讓 agent 不必每次從零猜庫怎麼用。&lt;/li&gt;
&lt;li&gt;把常見科學資料庫、Python 套件、文件處理、科研寫作和視覺化流程整理到同一個技能集合裡。&lt;/li&gt;
&lt;li&gt;讓 AI Agent 更像一個能執行科研工作流的助手，而不只是回答概念問題。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但它也不是「裝上就自動做科研」的魔法按鈕。技能可以讓 agent 更容易找到正確工具、生成更可靠的程式碼和流程，但資料品質、實驗設計、統計假設、臨床或科研結論仍然需要人來判斷。&lt;/p&gt;
&lt;h2 id=&#34;它包含什麼&#34;&gt;它包含什麼
&lt;/h2&gt;&lt;p&gt;README 把這個專案描述為一個覆蓋科研、科學計算、工程、分析、金融和寫作任務的技能集合。大類包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;生物資訊學與基因組學&lt;/li&gt;
&lt;li&gt;化學資訊學與藥物發現&lt;/li&gt;
&lt;li&gt;蛋白質組學與質譜分析&lt;/li&gt;
&lt;li&gt;臨床研究與精準醫學&lt;/li&gt;
&lt;li&gt;醫療 AI 與臨床機器學習&lt;/li&gt;
&lt;li&gt;醫學影像與數位病理&lt;/li&gt;
&lt;li&gt;機器學習與 AI&lt;/li&gt;
&lt;li&gt;材料科學與化學&lt;/li&gt;
&lt;li&gt;物理與天文學&lt;/li&gt;
&lt;li&gt;工程模擬與最佳化&lt;/li&gt;
&lt;li&gt;資料分析與視覺化&lt;/li&gt;
&lt;li&gt;地理空間科學與遙感&lt;/li&gt;
&lt;li&gt;實驗室自動化&lt;/li&gt;
&lt;li&gt;科研寫作、文獻綜述、同行評審和引用管理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這類技能的重點不是限制 agent 只能使用某些庫。README 也明確說，agent 仍然可以自己寫 Python、調用任意可用 API 或套件；這些技能的作用是提前提供整理過的說明、範例、最佳實踐和整合路徑。&lt;/p&gt;
&lt;p&gt;換句話說，它更像「科研工具說明書 + 工作流模板 + agent 調用約定」的集合。&lt;/p&gt;
&lt;h2 id=&#34;資料庫和-python-套件覆蓋&#34;&gt;資料庫和 Python 套件覆蓋
&lt;/h2&gt;&lt;p&gt;專案裡最吸引科研使用者的部分，是資料庫和 Python 科學生態的覆蓋面。&lt;/p&gt;
&lt;p&gt;README 提到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;透過 &lt;code&gt;database-lookup&lt;/code&gt; 統一存取 78 個公共資料庫。&lt;/li&gt;
&lt;li&gt;覆蓋 PubChem、ChEMBL、UniProt、COSMIC、ClinicalTrials.gov、FRED、USPTO 等資料庫。&lt;/li&gt;
&lt;li&gt;額外包含 DepMap、Imaging Data Commons、PrimeKG、U.S. Treasury Fiscal Data、Hugging Science 等專門資料存取技能。&lt;/li&gt;
&lt;li&gt;提供 70+ 個最佳化過的 Python Package Skills。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;從目錄看，技能名裡能看到很多熟悉工具：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rdkit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scanpy&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;biopython&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bioservices&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pydeseq2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scvelo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scvi-tools&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pymatgen&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;qiskit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pennylane&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;openmm&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mdanalysis&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scikit-learn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;statsmodels&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;matplotlib&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;seaborn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;networkx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sympy&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pytorch-lightning&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;transformers&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;timesfm-forecasting&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;對普通開發者來說，這些庫本身不稀奇。真正有用的是：agent 在處理具體任務時，可以讀到與該庫相關的使用約束、程式碼範例、常見流程和注意事項。這比只靠模型參數裡的舊記憶更穩。&lt;/p&gt;
&lt;h2 id=&#34;典型場景&#34;&gt;典型場景
&lt;/h2&gt;&lt;p&gt;Scientific Agent Skills 更適合多步驟科研任務，而不是單輪問答。&lt;/p&gt;
&lt;p&gt;例如藥物發現方向，可以讓 agent 查詢 ChEMBL 裡的 EGFR 抑制劑，用 RDKit 分析結構活性關係，再用 DiffDock 做虛擬篩選，最後搜尋文獻並生成報告。&lt;/p&gt;
&lt;p&gt;單細胞分析方向，可以把 10X 資料載入 Scanpy，做質控、整合、細胞類型識別、差異表達和通路富集。&lt;/p&gt;
&lt;p&gt;多組學方向，可以把 RNA-seq、質譜、代謝物、蛋白互作、臨床試驗和統計建模串起來。&lt;/p&gt;
&lt;p&gt;這些任務如果完全靠手寫 prompt，很容易變成「agent 知道大概方向，但每一步都要你提醒」。技能庫的意義，就是把這類高頻路徑沉澱下來，讓 agent 在執行時少走彎路。&lt;/p&gt;
&lt;h2 id=&#34;安裝方式&#34;&gt;安裝方式
&lt;/h2&gt;&lt;p&gt;README 推薦的標準安裝方式是使用 Agent Skills 工具：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npx skills add K-Dense-AI/scientific-agent-skills
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果使用 GitHub CLI，且版本為 &lt;code&gt;v2.90.0+&lt;/code&gt;，也可以透過 &lt;code&gt;gh skill&lt;/code&gt; 安裝：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gh skill install K-Dense-AI/scientific-agent-skills
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;安裝某個具體技能：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gh skill install K-Dense-AI/scientific-agent-skills scanpy
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;指定目標 agent：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gh skill install K-Dense-AI/scientific-agent-skills --agent codex
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gh skill install K-Dense-AI/scientific-agent-skills --agent cursor
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gh skill install K-Dense-AI/scientific-agent-skills --agent claude-code
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gh skill install K-Dense-AI/scientific-agent-skills --agent gemini
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果要保證可重現，可以 pin 到 release tag 或 commit SHA：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gh skill install K-Dense-AI/scientific-agent-skills --pin v1.0.0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gh skill install K-Dense-AI/scientific-agent-skills --pin abc123def
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這點對科研環境很重要。科研分析裡最怕「上週能跑、這週結果變了但不知道為什麼」。如果技能參與了分析流程，最好把技能版本、依賴版本和資料版本一起記錄。&lt;/p&gt;
&lt;h2 id=&#34;執行環境要求&#34;&gt;執行環境要求
&lt;/h2&gt;&lt;p&gt;README 給出的基本要求包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python 3.11+，推薦 3.12+&lt;/li&gt;
&lt;li&gt;&lt;code&gt;uv&lt;/code&gt;，用於安裝 Python 依賴&lt;/li&gt;
&lt;li&gt;支援 Agent Skills 標準的客戶端&lt;/li&gt;
&lt;li&gt;macOS、Linux 或 Windows with WSL2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這裡要注意 Windows 使用者的實際體驗。很多科學計算庫在原生 Windows 下不是不能用，但依賴鏈、編譯工具、二進位套件和路徑問題更容易出意外。README 明確寫 Windows with WSL2，也說明專案更偏向類 Unix 科研計算環境。&lt;/p&gt;
&lt;h2 id=&#34;和普通-prompt-集合有什麼區別&#34;&gt;和普通 prompt 集合有什麼區別
&lt;/h2&gt;&lt;p&gt;普通 prompt 集合通常只告訴模型「你應該怎麼回答」。Scientific Agent Skills 更進一步：它把工具、庫、資料庫和流程寫成 agent 可發現的技能。&lt;/p&gt;
&lt;p&gt;這有幾個實際差異：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;技能可以包含結構化說明和範例程式碼。&lt;/li&gt;
&lt;li&gt;技能可以圍繞某個庫或資料庫長期維護。&lt;/li&gt;
&lt;li&gt;agent 可以按任務選擇相關技能，而不是一次性把所有規則塞進系統提示。&lt;/li&gt;
&lt;li&gt;團隊可以只安裝自己需要的技能，減少上下文噪音。&lt;/li&gt;
&lt;li&gt;技能可以跟隨倉庫版本管理、審計和更新。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;對複雜科研任務來說，這種方式比「複製一大段萬能提示詞」更容易維護。模型會變，資料庫會變，Python 套件也會變。把這些變化沉澱在技能裡，比散落在個人 prompt 文件裡更可控。&lt;/p&gt;
&lt;h2 id=&#34;安全和可信邊界&#34;&gt;安全和可信邊界
&lt;/h2&gt;&lt;p&gt;這個專案的 README 把安全提醒寫得很直接：Skills 可以執行程式碼，也會影響 coding agent 的行為。&lt;/p&gt;
&lt;p&gt;這不是小事。科研技能可能會：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;安裝 Python 依賴。&lt;/li&gt;
&lt;li&gt;存取網路資料庫。&lt;/li&gt;
&lt;li&gt;讀寫本地檔案。&lt;/li&gt;
&lt;li&gt;執行分析腳本。&lt;/li&gt;
&lt;li&gt;處理敏感實驗資料或臨床資料。&lt;/li&gt;
&lt;li&gt;生成後續會被人引用的報告。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此不要無腦安裝全部技能。更穩的做法是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;只安裝目前任務需要的技能。&lt;/li&gt;
&lt;li&gt;安裝前閱讀對應 &lt;code&gt;SKILL.md&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;檢查技能會調用哪些套件、API、檔案和外部服務。&lt;/li&gt;
&lt;li&gt;對社群貢獻的技能額外謹慎。&lt;/li&gt;
&lt;li&gt;在隔離環境裡執行涉及資料處理和程式碼執行的任務。&lt;/li&gt;
&lt;li&gt;對科研結論、臨床建議和統計結果保留人工複核。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;README 還提到專案會使用 Cisco AI Defense Skill Scanner 做掃描，並建議使用者也可以本地掃描第三方技能。掃描不能替代人工審查，但至少說明維護者意識到技能供應鏈風險。&lt;/p&gt;
&lt;h2 id=&#34;適合誰&#34;&gt;適合誰
&lt;/h2&gt;&lt;p&gt;這個專案更適合這些人：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;已經在日常使用 AI coding agent。&lt;/li&gt;
&lt;li&gt;經常處理科研資料、論文、圖表和報告。&lt;/li&gt;
&lt;li&gt;需要在 Python 科學生態裡頻繁切換工具。&lt;/li&gt;
&lt;li&gt;想讓 agent 執行多步驟分析，而不是只回答概念。&lt;/li&gt;
&lt;li&gt;團隊希望把科研流程沉澱成可複用技能。&lt;/li&gt;
&lt;li&gt;想研究 Agent Skills 標準如何落地到專業領域。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;暫時不太適合這些場景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;只是想讓 AI 幫忙解釋一篇論文。&lt;/li&gt;
&lt;li&gt;沒有本地 Python 環境或不願意處理依賴。&lt;/li&gt;
&lt;li&gt;對資料隱私、網路存取和程式碼執行邊界還沒有控制方案。&lt;/li&gt;
&lt;li&gt;需要嚴格合規的臨床或生產決策系統，但沒有人工審查和驗證流程。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果只是偶爾做一次分析，直接讓 agent 寫腳本可能更輕。如果你經常重複類似科研流程，技能庫的價值會更明顯。&lt;/p&gt;
&lt;h2 id=&#34;使用建議&#34;&gt;使用建議
&lt;/h2&gt;&lt;p&gt;不要一開始就安裝整個倉庫，然後把所有任務都交給 agent。&lt;/p&gt;
&lt;p&gt;更實際的路徑是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先選一個低風險任務，例如文獻整理、圖表生成或公開資料探索。&lt;/li&gt;
&lt;li&gt;只安裝相關技能，例如 &lt;code&gt;literature-review&lt;/code&gt;、&lt;code&gt;scientific-writing&lt;/code&gt;、&lt;code&gt;scanpy&lt;/code&gt; 或 &lt;code&gt;rdkit&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;讓 agent 先說明計畫，再執行程式碼。&lt;/li&gt;
&lt;li&gt;保留輸入資料、腳本、環境和技能版本。&lt;/li&gt;
&lt;li&gt;對輸出結果做人工複查。&lt;/li&gt;
&lt;li&gt;如果流程穩定，再把它寫入團隊自己的 SOP 或技能。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;科研 agent 的關鍵不是「自動化一切」，而是把重複、繁瑣、容易查錯文件的部分交給工具，把判斷、假設和結論留給人。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;Scientific Agent Skills 的意義，在於把 Agent Skills 從通用編程場景推進到科研場景。&lt;/p&gt;
&lt;p&gt;科研工作天然是多工具、多資料庫、多檔案、多步驟的流程。單靠聊天式 prompt，很難穩定覆蓋這些細節。這個專案把常見科學庫、資料源和研究流程整理成技能，讓 AI Agent 更容易進入真實科研工作流。&lt;/p&gt;
&lt;p&gt;但它越強，也越需要邊界感。技能會影響 agent 行為，也可能執行程式碼、聯網和處理檔案。安裝前要看清楚技能內容，執行時要隔離環境，科研結論更不能跳過人工驗證。&lt;/p&gt;
&lt;p&gt;如果你已經在用 Codex、Claude Code、Cursor 或 Gemini CLI 做科研和資料分析，Scientific Agent Skills 值得認真看一眼。即使不直接全量安裝，它的技能拆分方式也很適合作為團隊整理科研 AI 工作流的參考。&lt;/p&gt;
&lt;p&gt;參考連結：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/K-Dense-AI/scientific-agent-skills&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;K-Dense-AI/scientific-agent-skills&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/K-Dense-AI/scientific-agent-skills/blob/main/README.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;README 原文&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://agentskills.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Agent Skills 標準&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/K-Dense-AI/k-dense-byok&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;K-Dense BYOK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.blog/changelog/2026-04-16-manage-agent-skills-with-github-cli/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub CLI gh skill changelog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Codex 支援 ChatGPT 移動端遠端存取，Enterprise 工作區可用 Access Tokens</title>
        <link>https://knightli.com/zh-tw/2026/05/17/codex-mobile-remote-access-enterprise-access-tokens/</link>
        <pubDate>Sun, 17 May 2026 09:12:07 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/17/codex-mobile-remote-access-enterprise-access-tokens/</guid>
        <description>&lt;p&gt;OpenAI 在 2026 年 5 月 14 日更新了 ChatGPT Enterprise &amp;amp; Edu Release Notes，重點只有兩件事：Codex 支援透過 ChatGPT 移動端遠端存取，Enterprise 工作區可以使用 Codex access tokens 做受控自動化。&lt;/p&gt;
&lt;p&gt;這不是一次模型能力發布，而是 Codex 產品形態的變化。Codex 正在從「本地或網頁裡的編程助手」，變成可以長時間執行、可以遠端接管、可以接入企業自動化流程的 coding agent。&lt;/p&gt;
&lt;h2 id=&#34;這次更新是什麼&#34;&gt;這次更新是什麼
&lt;/h2&gt;&lt;p&gt;根據 OpenAI Help Center 的說明，Codex 現在支援從 ChatGPT mobile app 遠端存取。使用者可以在手機上連接正在執行的 Codex 環境，持續跟進長時間任務，並在需要時介入。&lt;/p&gt;
&lt;p&gt;同時，ChatGPT Enterprise 工作區新增 Codex access tokens。它們面向可信的非互動式本地工作流，讓自動化流程可以使用 ChatGPT workspace identity 和企業控制，而不需要每次透過瀏覽器登入。&lt;/p&gt;
&lt;p&gt;可以把這次更新理解成兩個入口：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;移動端遠端存取：解決「Codex 跑長任務時，人不在電腦前怎麼辦」。&lt;/li&gt;
&lt;li&gt;Access Tokens：解決「企業自動化腳本如何以受控身份呼叫 Codex 工作流」。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;移動端遠端存取解決什麼問題&#34;&gt;移動端遠端存取解決什麼問題
&lt;/h2&gt;&lt;p&gt;Codex 的典型任務並不總是幾秒鐘完成。真實開發裡，它可能要閱讀程式碼庫、修改多個檔案、執行測試、等待命令輸出、根據錯誤繼續修復，甚至需要使用者中途批准某些操作。&lt;/p&gt;
&lt;p&gt;過去這類任務往往要求使用者守在本地 Mac、桌面端、CLI 或 IDE 旁邊。現在，ChatGPT 移動端可以變成一個遠端控制台，讓使用者離開電腦後仍能跟進 Codex。&lt;/p&gt;
&lt;p&gt;OpenAI 提到，移動端可以展示底層環境的即時狀態，包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;專案上下文。&lt;/li&gt;
&lt;li&gt;approvals。&lt;/li&gt;
&lt;li&gt;screenshots。&lt;/li&gt;
&lt;li&gt;terminal output。&lt;/li&gt;
&lt;li&gt;diffs。&lt;/li&gt;
&lt;li&gt;test results。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;使用者也可以在手機上回答 Codex 的問題、重定向執行、批准操作、查看輸出，並在不同 connected hosts 之間切換。底層任務仍然運行在 Mac host 或連接的遠端環境中，手機端負責查看和控制。&lt;/p&gt;
&lt;h2 id=&#34;這對開發者有什麼價值&#34;&gt;這對開發者有什麼價值
&lt;/h2&gt;&lt;p&gt;這項能力最適合長時間、需要中途確認的開發任務。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Codex 正在跑一組耗時測試，你出門後仍想看結果。&lt;/li&gt;
&lt;li&gt;Codex 修改了多個檔案，需要你在手機上看 diff 後批准下一步。&lt;/li&gt;
&lt;li&gt;Codex 執行到某個危險操作前等待確認，你可以遠端處理。&lt;/li&gt;
&lt;li&gt;本地 Mac 上有多個 connected hosts，需要在手機上切換查看狀態。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它的價值不是讓你在手機上寫程式，而是讓你不用一直守著電腦。Codex 繼續在原環境裡工作，你只在關鍵節點介入。&lt;/p&gt;
&lt;p&gt;這也說明 Codex 的使用方式正在接近「後台 Agent」：任務可以持續執行，使用者不必全程在線，但仍要保留審批和控制權。&lt;/p&gt;
&lt;h2 id=&#34;access-tokens-解決什麼問題&#34;&gt;Access Tokens 解決什麼問題
&lt;/h2&gt;&lt;p&gt;Codex access tokens 面向 ChatGPT Enterprise 工作區。它們的重點不是普通個人使用者登入，而是企業內部可信自動化。&lt;/p&gt;
&lt;p&gt;企業裡經常有一些本地或內部流程需要非互動式執行，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;定時執行程式碼檢查。&lt;/li&gt;
&lt;li&gt;在受控機器上觸發 Codex 工作流。&lt;/li&gt;
&lt;li&gt;將 Codex 接入內部開發工具鏈。&lt;/li&gt;
&lt;li&gt;在不開啟瀏覽器的情況下使用工作區身份。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Access tokens 讓這些流程可以帶著 ChatGPT workspace identity 執行，同時繼續受企業策略約束。相比臨時人工登入，它更適合自動化；相比隨便共享個人憑據，它也更容易納入治理。&lt;/p&gt;
&lt;h2 id=&#34;它不是普通-api-key&#34;&gt;它不是普通 API key
&lt;/h2&gt;&lt;p&gt;這點很重要。Codex access tokens 不應該被理解成一個簡單的「萬能 API key」。&lt;/p&gt;
&lt;p&gt;OpenAI 的說明裡提到，access tokens 可用於 ChatGPT Enterprise 工作區，管理員可以管理工作區級可用性，擁有允許角色的成員可以建立自己的 tokens。治理介面在可用情況下也會反映 access token 活動。&lt;/p&gt;
&lt;p&gt;也就是說，access tokens 被放在企業權限、角色和審計框架裡：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;管理員可以決定工作區是否開放。&lt;/li&gt;
&lt;li&gt;不是所有成員都天然可以建立。&lt;/li&gt;
&lt;li&gt;token 活動可以進入治理視圖。&lt;/li&gt;
&lt;li&gt;它繼承 ChatGPT workspace identity 和企業控制。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這和個人隨手產生一個長期密鑰不是一回事。&lt;/p&gt;
&lt;h2 id=&#34;安全預設值remote-control-預設關閉&#34;&gt;安全預設值：Remote Control 預設關閉
&lt;/h2&gt;&lt;p&gt;Codex mobile remote access 涉及程式碼環境、終端輸出、diff、測試結果和操作審批。如果預設開放，會帶來明顯企業安全風險。&lt;/p&gt;
&lt;p&gt;因此 OpenAI 的預設策略是：remote control 預設關閉，管理員或 owner 需要在 Workspace settings 中啟用。&lt;/p&gt;
&lt;p&gt;啟用移動端遠端存取時，還可能涉及：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;workspace-enabled Remote Control access。&lt;/li&gt;
&lt;li&gt;SSO。&lt;/li&gt;
&lt;li&gt;多因素認證。&lt;/li&gt;
&lt;li&gt;passkey。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這說明它是需要企業 IT 和安全團隊參與配置的能力，而不是「更新 App 後所有人自動可用」。&lt;/p&gt;
&lt;h2 id=&#34;使用前需要更新什麼&#34;&gt;使用前需要更新什麼
&lt;/h2&gt;&lt;p&gt;OpenAI 提到，要使用移動端遠端存取，需要更新兩端：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT mobile app。&lt;/li&gt;
&lt;li&gt;macOS 上的 Codex app。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果工作區啟用了相關要求，移動端設定過程還可能觸發 SSO、多因素認證或 passkey 流程。&lt;/p&gt;
&lt;p&gt;實際落地時，企業管理員還需要先確認 Workspace settings 裡的 remote control 設定，以及哪些成員或角色可以使用相關能力。&lt;/p&gt;
&lt;h2 id=&#34;對企業-codex-使用方式的影響&#34;&gt;對企業 Codex 使用方式的影響
&lt;/h2&gt;&lt;p&gt;這次更新把 Codex 往兩個方向推進。&lt;/p&gt;
&lt;p&gt;第一，Codex 更適合長任務。以前長任務最大的問題是使用者要一直盯著，現在手機可以查看狀態和批准操作，Codex 可以更自然地跑在後台。&lt;/p&gt;
&lt;p&gt;第二，Codex 更適合企業自動化。Access tokens 讓非互動式工作流有了更正式的身份方式，後續更容易接入內部 CI、程式碼審查、腳本和開發平台。&lt;/p&gt;
&lt;p&gt;這兩個方向結合起來，意味著 Codex 不再只是「開發者手邊的 AI 助手」，而是在變成企業開發流程裡的一個可管理 agent。&lt;/p&gt;
&lt;h2 id=&#34;仍然需要注意的邊界&#34;&gt;仍然需要注意的邊界
&lt;/h2&gt;&lt;p&gt;這次更新很有用，但並不意味著 Codex 可以完全無人看管。&lt;/p&gt;
&lt;p&gt;企業使用時仍然要注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;哪些專案允許遠端控制。&lt;/li&gt;
&lt;li&gt;哪些命令需要審批。&lt;/li&gt;
&lt;li&gt;token 如何建立、輪換和撤銷。&lt;/li&gt;
&lt;li&gt;mobile remote access 是否符合公司設備管理策略。&lt;/li&gt;
&lt;li&gt;終端輸出、截圖和 diff 是否可能包含敏感資訊。&lt;/li&gt;
&lt;li&gt;審計日誌和治理介面是否能滿足內部合規要求。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;尤其是 access tokens，一旦進入自動化流程，就要像其他企業憑據一樣管理：最小權限、定期輪換、避免硬編碼、及時撤銷不用的 token。&lt;/p&gt;
&lt;h2 id=&#34;總結&#34;&gt;總結
&lt;/h2&gt;&lt;p&gt;OpenAI 這次 Codex 更新的重點很集中：ChatGPT 移動端可以遠端存取 Codex 長任務，Enterprise 工作區可以用 Codex access tokens 支援受控自動化。&lt;/p&gt;
&lt;p&gt;前者讓開發者不必一直守在電腦前，後者讓企業可以把 Codex 更正式地接入內部工作流。兩者合在一起，說明 Codex 正在從互動式編程助手，進一步走向可遠端管理、可審計、可自動化接入的企業 coding agent。&lt;/p&gt;
&lt;p&gt;參考連結：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/10128477-chatgpt-enterprise-edu-release-notes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI Help Center：ChatGPT Enterprise &amp;amp; Edu - Release Notes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Codex 額度為什麼突然重置？Usage Limits 歷史與消息來源整理</title>
        <link>https://knightli.com/zh-tw/2026/05/17/codex-usage-limit-reset-history/</link>
        <pubDate>Sun, 17 May 2026 08:36:15 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/17/codex-usage-limit-reset-history/</guid>
        <description>&lt;p&gt;Codex 使用者偶爾會遇到一種情況：明明還沒到自己的常規 reset 時間，usage limits 卻突然恢復了。這種「無預兆重置」不是第一次出現，也不一定代表額度規則永久變寬。它可能來自故障補償、產品活動、成長里程碑，也可能只是某個視窗或部分帳號狀態被後台重置。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://knightli.com/2026/05/17/codex-usage-limit-reset-history/tibo-codex-gpt55-reset.png&#34;
	width=&#34;1146&#34;
	height=&#34;712&#34;
	srcset=&#34;https://knightli.com/2026/05/17/codex-usage-limit-reset-history/tibo-codex-gpt55-reset_hu_8e2e55bed895f615.png 480w, https://knightli.com/2026/05/17/codex-usage-limit-reset-history/tibo-codex-gpt55-reset_hu_1736ae030ba80b22.png 1024w&#34;
	loading=&#34;lazy&#34;
	
		alt=&#34;Tibo 關於 Codex usage limits 重置的截圖&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;160&#34;
		data-flex-basis=&#34;386px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;這張截圖來自 OpenAI Codex 團隊負責人 Tibo Sottiaux（@thsottiaux）在 X 上發布的公告。對關注額度的使用者來說，最關鍵的一句不是模型細節，而是：他表示會在當晚 reset usage limits。截圖中的上下文說明，這次重置是一次補償性操作，而不是普通週期刷新。&lt;/p&gt;
&lt;h2 id=&#34;先說結論&#34;&gt;先說結論
&lt;/h2&gt;&lt;p&gt;Codex 額度突然重置，大致可以分成幾類：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;故障補償&lt;/strong&gt;：模型或 Codex 服務異常導致使用者浪費額度，官方透過重置彌補。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;發布或推廣活動&lt;/strong&gt;：新模型、新客戶端、新功能上線時，臨時提高或重置額度。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;成長里程碑&lt;/strong&gt;：使用者規模達到某個節點後，官方用重置或提額鼓勵繼續使用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;後台策略調整&lt;/strong&gt;：部分額度視窗、部分帳號狀態被重置，但 UI 不一定解釋清楚。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;普通使用者最容易誤解的是：看到「重置」就以為所有視窗都恢復了。實際上，Codex 可能同時有短視窗、weekly limit、不同模型和不同方案限制。一次特殊重置可能只影響其中一部分。&lt;/p&gt;
&lt;h2 id=&#34;這次截圖說明了什麼&#34;&gt;這次截圖說明了什麼
&lt;/h2&gt;&lt;p&gt;截圖顯示，Tibo 在 2026 年 5 月 15 日發布更新，表示團隊會繼續監控，並在當晚重置 usage limits。它引用了前一條「正在調查部分使用者回報」的消息，因此這次重置更像一次服務波動後的補償。&lt;/p&gt;
&lt;p&gt;對使用者來說，可以提煉出三點：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;這不是使用者自己的常規週期到了，而是官方主動重置。&lt;/li&gt;
&lt;li&gt;這次重置有明確事件背景，不是永久提額公告。&lt;/li&gt;
&lt;li&gt;「usage limits」的具體覆蓋範圍仍要看實際帳號顯示，截圖本身沒有解釋 5 小時視窗、weekly limit 是否全部包含。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以，如果你看到額度恢復，正確做法不是馬上推斷「以後都變寬了」，而是先把它當成一次特殊 reset event。&lt;/p&gt;
&lt;h2 id=&#34;為什麼-codex-會無預兆重置&#34;&gt;為什麼 Codex 會無預兆重置
&lt;/h2&gt;&lt;p&gt;Codex 的額度體系不是一個簡單的「每天幾點刷新」。使用者介面通常只顯示剩餘額度或百分比，但後台可能同時追蹤：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;短時間視窗，例如幾小時內的使用量。&lt;/li&gt;
&lt;li&gt;週額度或更長週期額度。&lt;/li&gt;
&lt;li&gt;不同模型的消耗權重。&lt;/li&gt;
&lt;li&gt;本地 Codex、Cloud Task、IDE/CLI 等不同入口。&lt;/li&gt;
&lt;li&gt;Plus、Pro、Business、Team 等不同方案。&lt;/li&gt;
&lt;li&gt;帳號是否符合某次特殊重置的後台條件。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;當 OpenAI 做一次特殊重置時，使用者未必能看到「這是普通週期恢復，還是特殊補償」。如果只重置短視窗，使用者可能誤以為 weekly 也應該恢復；如果 weekly 沒變，就會懷疑重置失敗。&lt;/p&gt;
&lt;p&gt;OpenAI 的 Codex GitHub issue 裡也有人專門回報過這個透明度問題：公開說 reset Codex rate limits，但產品 UI 沒有說明到底重置了哪些視窗、是否包含 weekly limit、是否所有付費方案都一致生效。這也是「無預兆重置」讓人困惑的核心原因。&lt;/p&gt;
&lt;h2 id=&#34;歷史上的幾類重置&#34;&gt;歷史上的幾類重置
&lt;/h2&gt;&lt;h3 id=&#34;1-2026-年-2-月發布期與臨時加量&#34;&gt;1. 2026 年 2 月：發布期與臨時加量
&lt;/h3&gt;&lt;p&gt;Codex 桌面應用和 &lt;code&gt;GPT-5.3-Codex&lt;/code&gt; 推廣期間，社群使用者討論過 usage limit reset 和臨時 2x rate limits。Reddit 上有使用者提到 Codex app 剛發布時提供過限時 2x rate limits，並伴隨 usage limit reset。&lt;/p&gt;
&lt;p&gt;這類重置更像發布期營運動作：讓更多使用者試用新客戶端、新模型或新工作流。&lt;/p&gt;
&lt;h3 id=&#34;2-2026-年-3-月隨機重置與異常消耗討論&#34;&gt;2. 2026 年 3 月：隨機重置與異常消耗討論
&lt;/h3&gt;&lt;p&gt;3 月前後，社群裡多次出現「random usage reset」「weekly limit reset daily」之類帖子。有使用者回報自己的 weekly limit 被提前恢復，也有人認為這和 Codex 新模型、新安全攔截、異常消耗或 bug 修復有關。&lt;/p&gt;
&lt;p&gt;這些討論不等同於官方公告，但它們說明一件事：使用者側已經多次觀察到額度並非只按固定週期恢復。某些情況下，後台會因為問題修復或補償而觸發額外 reset。&lt;/p&gt;
&lt;h3 id=&#34;3-2026-年-4-月成長里程碑與付費方案重置&#34;&gt;3. 2026 年 4 月：成長里程碑與付費方案重置
&lt;/h3&gt;&lt;p&gt;4 月下旬，有公開報導提到 Codex 達到 300 萬週活躍使用者後，OpenAI 重置了 rate limits，並計畫在後續使用者成長里程碑繼續給使用者更多額度空間。&lt;/p&gt;
&lt;p&gt;GitHub issue 中也引用過 Tibo 4 月 28 日的 X 公告：他提到曾為「good week」重置付費方案的 Codex rate limits，讓使用者可以更多使用 &lt;code&gt;GPT-5.5&lt;/code&gt;。不過同一個 issue 也指出，實際產品 UI 沒有清楚說明到底哪些額度視窗被重置，weekly limit 是否全部包含。&lt;/p&gt;
&lt;p&gt;這說明成長或活動型重置，往往也會帶來解釋成本：使用者聽到「all paid plans」，但帳號裡看到的結果未必完全一致。&lt;/p&gt;
&lt;h3 id=&#34;4-2026-年-5-月故障補償型重置&#34;&gt;4. 2026 年 5 月：故障補償型重置
&lt;/h3&gt;&lt;p&gt;這次截圖屬於更典型的故障補償型重置。Tibo 明確說團隊找到了問題並會在當晚 reset usage limits。OpenAI Status 也記錄過 2026 年 5 月 13 日 Codex 相關高錯誤率和延遲退化事件。&lt;/p&gt;
&lt;p&gt;對普通使用者而言，這次重點不是某個模型是否變差，而是：當服務端問題讓使用者額度被異常消耗時，OpenAI 可能會透過特殊重置來補償。&lt;/p&gt;
&lt;h2 id=&#34;使用者該怎麼判斷一次重置來自哪裡&#34;&gt;使用者該怎麼判斷一次重置來自哪裡
&lt;/h2&gt;&lt;p&gt;遇到 Codex 額度突然恢復，可以按這個順序判斷：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先看自己的常規 reset 時間，排除普通週期恢復。&lt;/li&gt;
&lt;li&gt;看 OpenAI Status 是否有 Codex、模型錯誤率、延遲或降級記錄。&lt;/li&gt;
&lt;li&gt;看 Tibo、OpenAI 官方帳號、Codex GitHub issue 是否有說明。&lt;/li&gt;
&lt;li&gt;看社群回饋是否集中出現「突然 reset」「額度燃燒異常」「weekly 沒恢復」等討論。&lt;/li&gt;
&lt;li&gt;區分短視窗和 weekly limit，不要預設所有視窗都會一起恢復。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果是官方事故補償，通常會伴隨狀態頁記錄、負責人公告或大量使用者集中回饋。如果只是後台部分視窗刷新，可能不會有明確公告。&lt;/p&gt;
&lt;h2 id=&#34;消息來源怎麼分辨可靠性&#34;&gt;消息來源怎麼分辨可靠性
&lt;/h2&gt;&lt;p&gt;這類消息最好分層看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;官方狀態頁&lt;/strong&gt;：最適合確認是否有服務故障、錯誤率、延遲、恢復時間。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tibo / OpenAI 官方帳號&lt;/strong&gt;：適合確認是否有特殊 reset、補償或活動口徑。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenAI Codex GitHub issue&lt;/strong&gt;：適合看使用者對 UI、額度視窗、實際行為的回饋。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;社群 Reddit / X 討論&lt;/strong&gt;：適合觀察使用者是否普遍遇到類似現象，但不能直接當成官方結論。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第三方新聞或部落格&lt;/strong&gt;：適合補充時間線，但仍要回到官方和原始連結核對。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;寫文章或做判斷時，最好把這些來源分開寫。比如「OpenAI Status 記錄了服務問題」是官方狀態；「Reddit 使用者回報隨機重置」是社群觀察；「GitHub issue 反映 UI 不透明」是使用者提交的問題描述。&lt;/p&gt;
&lt;h2 id=&#34;總結&#34;&gt;總結
&lt;/h2&gt;&lt;p&gt;Codex 額度突然重置，通常不是一個單純的「系統送額度」。它可能來自故障補償、發布期推廣、成長活動或後台策略調整。真正容易造成誤解的地方在於：Codex 同時存在多個額度視窗，而特殊 reset 不一定覆蓋所有視窗，UI 也不一定清楚展示 reset scope。&lt;/p&gt;
&lt;p&gt;所以，遇到無預兆重置時，最穩的判斷方式是：先看客戶端實際額度，再查 OpenAI Status、Tibo 公告、Codex GitHub issue 和社群回饋。不要只憑一次 reset 推斷長期額度規則，也不要預設 weekly limit、短視窗和所有方案都會同步恢復。&lt;/p&gt;
&lt;p&gt;參考連結：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://status.openai.com/incidents/01KRG6MF021JQ997JCR7R8Y9A0&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI Status：Codex 5.5 engines are experiencing high error rate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.reddit.com/r/LovingCodex/comments/1teo5ki/tibo_we_foundfixed_two_issues_that_could_explain/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Reddit 轉發的 Tibo 公告截圖與 X 連結&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/openai/codex/issues/20395&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub：Clarify Codex rate-limit reset behavior and make reset scope visible in Usage UI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.createwith.com/tool/chatgpt/updates/chatgpt-codex-hits-3-million-weekly-users-openai-resets-rate-limits&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Create With：ChatGPT Codex Hits 3 Million Weekly Users, OpenAI Resets Rate Limits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.reddit.com/r/codex/comments/1rjcwli/usage_limit_reset/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Reddit：Usage limit reset?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.reddit.com/r/codex/comments/1qu2gjx/when_the_unnexpected_usage_limit_reset_hits_ty/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Reddit：when the unexpected usage limit reset hits&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Codex 手機遠端存取來了：用 ChatGPT App 跟進 Mac 上的編程任務</title>
        <link>https://knightli.com/zh-tw/2026/05/16/codex-mobile-remote-access-chatgpt-app/</link>
        <pubDate>Sat, 16 May 2026 17:42:40 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/16/codex-mobile-remote-access-chatgpt-app/</guid>
        <description>&lt;p&gt;OpenAI 在 2026 年 5 月中旬把 &lt;code&gt;Codex remote access&lt;/code&gt; 帶進 ChatGPT 手機 App。這個功能的重點不是「在手機上寫程式」，而是讓你用手機遠端跟進 Mac 上正在執行的 Codex。&lt;/p&gt;
&lt;p&gt;它更像一個行動審批和監控入口：Codex 繼續在電腦上讀專案、跑命令、改檔案、看測試結果；手機端負責查看進度、回答問題、補充指令和批准操作。&lt;/p&gt;
&lt;p&gt;對經常讓 Codex 跑長任務的人來說，這個變化很實用。你不必一直坐在電腦前等它卡在哪裡，離開工位後也能從 ChatGPT App 接上現場。&lt;/p&gt;
&lt;h2 id=&#34;它能做什麼&#34;&gt;它能做什麼
&lt;/h2&gt;&lt;p&gt;根據 OpenAI Codex remote connections 文件，手機端遠端存取可以：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 Mac 主機上的專案裡開啟新 thread，或繼續已有 thread；&lt;/li&gt;
&lt;li&gt;發送後續指令，回答 Codex 的問題，調整任務方向；&lt;/li&gt;
&lt;li&gt;批准命令和其他操作；&lt;/li&gt;
&lt;li&gt;查看輸出、diff、測試結果、終端輸出和截圖；&lt;/li&gt;
&lt;li&gt;在 Codex 完成任務或需要你注意時收到通知；&lt;/li&gt;
&lt;li&gt;在多個已連接主機和 thread 之間切換。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是說，手機端不是簡化版聊天視窗，而是接入了 Codex 目前的工作現場。&lt;/p&gt;
&lt;h2 id=&#34;使用前需要什麼&#34;&gt;使用前需要什麼
&lt;/h2&gt;&lt;p&gt;第一，你需要有可用的 Codex 權限，並且手機和 Mac 使用同一個 ChatGPT 帳號與 workspace。&lt;/p&gt;
&lt;p&gt;第二，手機上要安裝最新版 ChatGPT App，iOS 或 Android 都可以。如果 App 裡看不到 Codex，先更新 ChatGPT。&lt;/p&gt;
&lt;p&gt;第三，主機目前要求是 Mac，並且需要保持在線、喚醒、正在執行 Codex App。OpenAI 文件明確寫到，行動端設定和裝置控制目前需要主機上執行 &lt;code&gt;Codex App for macOS&lt;/code&gt;，不能從 Codex CLI 或 IDE Extension 完成設定。&lt;/p&gt;
&lt;p&gt;第四，如果帳號或 workspace 要求 MFA、SSO 或 passkey，需要先完成對應認證。團隊 workspace 還可能需要管理員開啟 Remote Control access。&lt;/p&gt;
&lt;h2 id=&#34;codex-手機遠端存取的限制&#34;&gt;Codex 手機遠端存取的限制
&lt;/h2&gt;&lt;p&gt;第一，當前需要 &lt;code&gt;macOS host&lt;/code&gt;。手機端連接的是 Mac 上執行的 Codex App，不是直接連接 Codex CLI、IDE Extension，也不是任意 Linux / Windows 開發機。&lt;/p&gt;
&lt;p&gt;第二，主機必須在線。Mac 需要保持喚醒、連網，並持續執行 Codex App。如果電腦睡眠、斷網或 Codex 關閉，手機端遠端會話就可能斷開。&lt;/p&gt;
&lt;p&gt;第三，連線依賴掃碼流程。你需要先在 Mac 端開啟 &lt;code&gt;Set up Codex mobile&lt;/code&gt;，再用手機掃描 QR code 進入 ChatGPT 完成綁定。&lt;/p&gt;
&lt;p&gt;第四，遠端操作仍然要經過審批流程。手機端可以批准命令和其他操作，但你仍然要看清 Codex 請求做什麼，再決定是否繼續。&lt;/p&gt;
&lt;p&gt;所以它適合「人離開電腦後繼續跟進任務」，不適合替代完整開發環境，也不適合把主機長期無人值守地開放給遠端操作。&lt;/p&gt;
&lt;h2 id=&#34;怎麼連接&#34;&gt;怎麼連接
&lt;/h2&gt;&lt;p&gt;設定流程從 Mac 上的 Codex App 開始。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在 Mac 上開啟 Codex。&lt;/li&gt;
&lt;li&gt;在側邊欄選擇 &lt;code&gt;Set up Codex mobile&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;Codex 會為這台主機開啟遠端存取，並顯示 QR code。&lt;/li&gt;
&lt;li&gt;用手機掃描 QR code，進入 ChatGPT 裡的 Codex mobile setup 流程。&lt;/li&gt;
&lt;li&gt;確認同一個 ChatGPT 帳號和 workspace。&lt;/li&gt;
&lt;li&gt;完成必要的 MFA、SSO 或 passkey 驗證。&lt;/li&gt;
&lt;li&gt;設定成功後，這台 Mac 會出現在手機端 Codex 裡。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;連接完成後，可以在 Mac 端 Codex 的 &lt;code&gt;Settings &amp;gt; Connections&lt;/code&gt; 管理已連接裝置，也可以設定是否讓電腦保持喚醒、是否啟用 Computer Use、是否安裝 Chrome extension。&lt;/p&gt;
&lt;h2 id=&#34;手機端適合做什麼&#34;&gt;手機端適合做什麼
&lt;/h2&gt;&lt;p&gt;手機端最適合三類操作：審批、糾偏和查看結果。&lt;/p&gt;
&lt;p&gt;Codex 需要執行命令、存取檔案或繼續某個動作時，你可以在手機上看清請求，再決定是否批准。當 Codex 誤解需求、測試失敗或需要方向判斷時，也可以直接補充一句說明。最後，你可以查看 diff、測試輸出、終端日誌和截圖，不必回到電腦前才知道任務進度。&lt;/p&gt;
&lt;p&gt;真正有價值的不是手機寫程式，而是把手機變成工程任務的隨身控制台。&lt;/p&gt;
&lt;h2 id=&#34;常見問題&#34;&gt;常見問題
&lt;/h2&gt;&lt;p&gt;如果手機上看不到主機，先確認 Mac 上 Codex App 仍在執行，並且開啟了 &lt;code&gt;Allow other devices to connect&lt;/code&gt;。手機和主機也必須使用同一個 ChatGPT 帳號與 workspace。&lt;/p&gt;
&lt;p&gt;如果審批請求沒有出現，可以打開 ChatGPT 手機 App，進入 Codex，再重新掃碼或從主機重新開始設定。團隊帳號還要確認管理員是否已允許 Remote Control access。&lt;/p&gt;
&lt;p&gt;如果遠端會話斷開，通常要檢查 Mac 是否睡眠、網路是否斷開、Codex App 是否關閉。&lt;/p&gt;
&lt;p&gt;如果認證卡住，就先完成 MFA、SSO、passkey 流程。企業環境裡，權限問題往往要管理員介入。&lt;/p&gt;
&lt;h2 id=&#34;適合哪些場景&#34;&gt;適合哪些場景
&lt;/h2&gt;&lt;p&gt;它適合經常讓 Codex 跑較長程式修改任務、需要離開工位後繼續審批和跟進、同時管理多個專案或 thread，並且以 Mac 作為主力開發機的人。&lt;/p&gt;
&lt;p&gt;不太適合主要使用 Windows 或 Linux、只用 Codex CLI 或 IDE Extension、希望手機端獨立完成完整開發環境，或網路不穩定的人。&lt;/p&gt;
&lt;h2 id=&#34;我的判斷&#34;&gt;我的判斷
&lt;/h2&gt;&lt;p&gt;Codex 手機遠端存取的意義，不是把開發工作搬到手機螢幕上，而是讓「等待 Codex 跑完」的時間更可控。&lt;/p&gt;
&lt;p&gt;以前 Codex 長任務經常卡在審批、追問、測試失敗或方向確認上。現在這些節點可以透過 ChatGPT 手機 App 處理，Mac 繼續做真正的工程執行，手機負責輕量決策。&lt;/p&gt;
&lt;p&gt;如果你已經在 Mac 上重度使用 Codex，這個功能值得開啟。如果你只是偶爾問幾句程式問題，它的價值可能沒那麼明顯。&lt;/p&gt;
&lt;h2 id=&#34;參考資料&#34;&gt;參考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/6825453-chatgpt-release-notes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI Help Center：ChatGPT Release Notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developers.openai.com/codex/remote-connections&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI Developers：Codex Remote Connections&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Superpowers：把 Coding Agent 拉回工程流程的技能框架</title>
        <link>https://knightli.com/zh-tw/2026/05/15/obra-superpowers-agentic-skills-framework/</link>
        <pubDate>Fri, 15 May 2026 08:53:17 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/15/obra-superpowers-agentic-skills-framework/</guid>
        <description>&lt;p&gt;&lt;code&gt;obra/superpowers&lt;/code&gt; 是一個給 coding agent 使用的技能框架，也是一套軟體開發方法論。它的目標不是再寫一個萬能 prompt，而是把 agent 的工作流程固定下來：先澄清目標，再產出設計，再拆計畫，再按測試驅動開發推進，最後做 review 和收尾。&lt;/p&gt;
&lt;p&gt;專案地址：&lt;a class=&#34;link&#34; href=&#34;https://github.com/obra/superpowers&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/obra/superpowers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;寫作時，GitHub API 顯示這個倉庫已有超過 19 萬 star，授權為 MIT，最近仍在更新。README 對它的描述很直接：&lt;code&gt;An agentic skills framework &amp;amp; software development methodology that works.&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;它想解決什麼問題&#34;&gt;它想解決什麼問題
&lt;/h2&gt;&lt;p&gt;現在很多 AI 編程工具的問題，不是「不會寫程式碼」，而是太容易直接寫程式碼。&lt;/p&gt;
&lt;p&gt;使用者剛說一個模糊需求，agent 就開始改檔案；改完看似完成，其實邊界沒對齊、測試沒補、架構沒想清楚。短任務可能沒事，複雜專案裡就會變成返工和技術債。&lt;/p&gt;
&lt;p&gt;Superpowers 的思路是：讓 agent 在動手前先進入流程。&lt;/p&gt;
&lt;p&gt;README 描述的核心路徑大致是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;發現使用者要做東西時，先追問目標。&lt;/li&gt;
&lt;li&gt;從對話中整理規格，分段給使用者確認。&lt;/li&gt;
&lt;li&gt;設計通過後，生成清楚的實施計畫。&lt;/li&gt;
&lt;li&gt;使用者說 “go” 之後，再進入實作。&lt;/li&gt;
&lt;li&gt;實作時強調 TDD、YAGNI、DRY，並透過 review 檢查結果。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這套流程不新，但放到 coding agent 裡很關鍵。AI 的執行速度越快，前置澄清和中途驗證越重要。&lt;/p&gt;
&lt;h2 id=&#34;支援哪些工具&#34;&gt;支援哪些工具
&lt;/h2&gt;&lt;p&gt;Superpowers 不是只面向一個 agent。README 列出的安裝入口包括 Claude Code、Codex CLI、Codex App、Factory Droid、Gemini CLI、OpenCode、Cursor 和 GitHub Copilot CLI。&lt;/p&gt;
&lt;p&gt;這說明它更像跨 harness 的工作流層，而不是綁定某一家模型或某一個命令列工具。&lt;/p&gt;
&lt;h2 id=&#34;基礎工作流&#34;&gt;基礎工作流
&lt;/h2&gt;&lt;p&gt;第一步是 &lt;code&gt;brainstorming&lt;/code&gt;。它會在寫程式碼前觸發，透過問題把粗糙想法整理成可執行設計，並分段確認。&lt;/p&gt;
&lt;p&gt;第二步是 &lt;code&gt;using-git-worktrees&lt;/code&gt;。設計確認後建立隔離工作區和新分支，先確認安裝和測試基線乾淨。&lt;/p&gt;
&lt;p&gt;第三步是 &lt;code&gt;writing-plans&lt;/code&gt;。把設計拆成短小任務，每個任務有明確檔案路徑、程式碼範圍和驗證步驟。&lt;/p&gt;
&lt;p&gt;第四步是實作。可以用 &lt;code&gt;subagent-driven-development&lt;/code&gt; 派發子任務，也可以用 &lt;code&gt;executing-plans&lt;/code&gt; 分批執行。重點是每個任務都能檢查、review、繼續推進。&lt;/p&gt;
&lt;p&gt;第五步是 &lt;code&gt;test-driven-development&lt;/code&gt;。它強調真正的 RED-GREEN-REFACTOR：先寫失敗測試，確認失敗，再寫最小實作，確認通過，然後重構。&lt;/p&gt;
&lt;p&gt;第六步是 &lt;code&gt;requesting-code-review&lt;/code&gt;。任務之間做 review，Critical 問題會阻塞繼續推進。&lt;/p&gt;
&lt;p&gt;最後是 &lt;code&gt;finishing-a-development-branch&lt;/code&gt;。任務結束後驗證測試，給出合併、發 PR、保留或丟棄 worktree 的選擇。&lt;/p&gt;
&lt;h2 id=&#34;skills-library-裡有什麼&#34;&gt;Skills Library 裡有什麼
&lt;/h2&gt;&lt;p&gt;測試類主要是 &lt;code&gt;test-driven-development&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;除錯類包括 &lt;code&gt;systematic-debugging&lt;/code&gt; 和 &lt;code&gt;verification-before-completion&lt;/code&gt;，要求先復現、最小化、提出假設、驗證，再修復；也要求沒有驗證前不要宣布完成。&lt;/p&gt;
&lt;p&gt;協作類包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;brainstorming&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;writing-plans&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;executing-plans&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dispatching-parallel-agents&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;requesting-code-review&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;receiving-code-review&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;using-git-worktrees&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;finishing-a-development-branch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;subagent-driven-development&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;元技能包括 &lt;code&gt;writing-skills&lt;/code&gt; 和 &lt;code&gt;using-superpowers&lt;/code&gt;。這些技能組合起來，像是給 agent 裝上一套工程習慣。&lt;/p&gt;
&lt;h2 id=&#34;和普通-prompt-最大的區別&#34;&gt;和普通 prompt 最大的區別
&lt;/h2&gt;&lt;p&gt;普通 prompt 往往把規則堆在一段 system prompt 裡：不要亂改、先思考、要測試、要簡潔。規則越堆越多，複雜任務裡模型越容易選擇性遺忘。&lt;/p&gt;
&lt;p&gt;Superpowers 更像把規則拆成可觸發的流程模組。不同任務階段使用不同技能，每個技能只負責一段工作。這讓規則更短、目標更集中，也讓複雜流程能被檢查。&lt;/p&gt;
&lt;p&gt;它最值得參考的地方是：不要只追求更聰明的模型，還要給模型一套可重複的工作方式。&lt;/p&gt;
&lt;h2 id=&#34;適合誰用&#34;&gt;適合誰用
&lt;/h2&gt;&lt;p&gt;Superpowers 更適合已經在真實專案裡使用 coding agent 的開發者，尤其是任務不只單檔修改、希望 agent 先設計再實作、需要 TDD 或驗證、常常並行多個分支、想把團隊流程寫成可重用技能的場景。&lt;/p&gt;
&lt;p&gt;如果只是改一行設定，它可能偏重。但一旦任務涉及多檔案、多階段、多輪確認，流程約束就會變得有價值。&lt;/p&gt;
&lt;h2 id=&#34;使用時要注意什麼&#34;&gt;使用時要注意什麼
&lt;/h2&gt;&lt;p&gt;不要把它理解成自動駕駛。Superpowers 能讓 agent 更有流程感，但需求邊界、設計取捨和最終驗收仍然需要人負責。&lt;/p&gt;
&lt;p&gt;TDD 和 review 會增加前期成本。小任務可能變慢，但複雜任務通常能減少返工。&lt;/p&gt;
&lt;p&gt;子代理並行不是越多越好。它適合邊界清楚、寫入範圍不重疊的任務；如果需求還沒想清楚，並行只會放大混亂。&lt;/p&gt;
&lt;p&gt;團隊也要維護自己的技能品質。過時流程、模糊指令和互相衝突的規則，都會拖累 agent。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;Superpowers 的價值，不在於某個單獨技能多神奇，而在於它把 coding agent 從「接到需求就寫程式碼」拉回軟體工程流程。&lt;/p&gt;
&lt;p&gt;AI 編程真正缺的往往不是生成速度，而是澄清、計畫、驗證、review 和收尾。模型越強，這些流程越不能省。&lt;/p&gt;
&lt;p&gt;如果你已經在用 Codex、Claude Code、Cursor 或 Gemini CLI 做真實專案，Superpowers 值得看一眼。即使不直接安裝，它的技能拆分方式也很適合拿來改造自己的 agent 工作流。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>拒絕 Vibe Coding：Matt Pocock 的 skills 倉庫給 AI 編程補上工程約束</title>
        <link>https://knightli.com/zh-tw/2026/05/15/matt-pocock-skills-ai-engineering-workflow/</link>
        <pubDate>Fri, 15 May 2026 08:46:23 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/15/matt-pocock-skills-ai-engineering-workflow/</guid>
        <description>&lt;p&gt;AI 寫程式碼越快，專案失控也可能越快。真正的問題不是模型會不會生成函式，而是它是否理解需求、是否遵守團隊語言、是否能在既有架構裡小步推進。&lt;/p&gt;
&lt;p&gt;Matt Pocock 開源的 &lt;code&gt;mattpocock/skills&lt;/code&gt; 倉庫，給了一個和 vibe coding 相反的方向：不要讓 AI 接管整個開發流程，而是把 AI 放進成熟的軟體工程約束裡。&lt;/p&gt;
&lt;p&gt;專案地址：&lt;a class=&#34;link&#34; href=&#34;https://github.com/mattpocock/skills&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/mattpocock/skills&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;這套方法的重點不是某個神奇 prompt，而是一組可以組合的 agent skills。它們把需求澄清、領域建模、測試驅動、問題診斷、架構審查這些工程實踐，重新包裝成適合 AI 編程工具調用的工作流。&lt;/p&gt;
&lt;h2 id=&#34;先解決對齊失敗&#34;&gt;先解決對齊失敗
&lt;/h2&gt;&lt;p&gt;AI 編程最常見的失敗，是你以為它懂了，其實它只是順著你的模糊描述開始猜。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;grill-me&lt;/code&gt; 的思路是反過來：寫程式碼之前，先讓 AI 變成會追問的審稿人。它不會立刻開始實作，而是持續追問計畫裡的分支、邊界和未決問題。&lt;/p&gt;
&lt;p&gt;例如你說「做一個登入頁」，它應該先問：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;忘記密碼怎麼處理？&lt;/li&gt;
&lt;li&gt;是否支援第三方登入？&lt;/li&gt;
&lt;li&gt;登入失敗時要顯示什麼錯誤？&lt;/li&gt;
&lt;li&gt;帳號鎖定、驗證碼、風控是否在本期範圍內？&lt;/li&gt;
&lt;li&gt;成功後跳轉到哪裡？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這一步看起來慢，但它減少的是後面返工的時間。AI 生成程式碼的成本越低，需求沒想清楚帶來的浪費就越大。&lt;/p&gt;
&lt;h2 id=&#34;把領域語言寫進上下文&#34;&gt;把領域語言寫進上下文
&lt;/h2&gt;&lt;p&gt;第二個問題是 AI 的通用詞彙病。它不了解團隊內部的業務叫法，只能用常見詞來猜，於是變數名、函式名、文件描述都開始漂移。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;grill-with-docs&lt;/code&gt; 不只是追問需求，還會結合專案裡的 &lt;code&gt;CONTEXT.md&lt;/code&gt;、ADR 或領域文件，檢查使用者表達是否和既有術語衝突。確認後的術語、邊界和決策，可以繼續沉澱回上下文文件。&lt;/p&gt;
&lt;p&gt;這和領域驅動設計裡的「統一語言」很接近。假設團隊把 user 稱為 customer，把 order 稱為 transaction，AI 在寫程式碼時也應該繼承這些叫法。&lt;/p&gt;
&lt;p&gt;上下文文件的價值不在於堆資料，而在於讓 AI 少猜一點。&lt;/p&gt;
&lt;h2 id=&#34;用-tdd-限制生成速度&#34;&gt;用 TDD 限制生成速度
&lt;/h2&gt;&lt;p&gt;AI 的危險之處在於它太快了。過去寫出一大段壞程式碼需要時間，現在幾秒鐘就能生成幾百行。速度本身不是問題，缺少回饋循環才是問題。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;tdd&lt;/code&gt; skill 把經典的紅綠重構流程放回 AI 編程裡：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先為一個行為寫失敗測試。&lt;/li&gt;
&lt;li&gt;再實作剛好讓測試通過的程式碼。&lt;/li&gt;
&lt;li&gt;然後重構。&lt;/li&gt;
&lt;li&gt;按垂直切片繼續推進。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;重點是「一次一個行為」，而不是讓 AI 一口氣寫完所有測試和所有實作。AI 負責執行，人類負責確認方向和邊界。&lt;/p&gt;
&lt;h2 id=&#34;用診斷循環處理複雜問題&#34;&gt;用診斷循環處理複雜問題
&lt;/h2&gt;&lt;p&gt;遇到 bug 時，很多 AI 會直接猜答案，然後連續改幾輪，把問題越修越亂。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;diagnose&lt;/code&gt; 的價值在於要求 AI 先建立回饋循環：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;重現問題&lt;/li&gt;
&lt;li&gt;最小化場景&lt;/li&gt;
&lt;li&gt;提出假設&lt;/li&gt;
&lt;li&gt;增加觀測或日誌&lt;/li&gt;
&lt;li&gt;修復&lt;/li&gt;
&lt;li&gt;補回歸測試&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這套流程不新，但在 AI 編程裡尤其重要。AI 很擅長快速嘗試，但不一定擅長判斷哪次嘗試真正接近根因。診斷流程相當於給它加了一條軌道。&lt;/p&gt;
&lt;h2 id=&#34;定期審查架構&#34;&gt;定期審查架構
&lt;/h2&gt;&lt;p&gt;單次任務跑通，不代表程式碼庫變好了。AI 反覆提交小改動後，最容易出現模組邊界模糊、介面越來越複雜、測試越來越難寫。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;improve-codebase-architecture&lt;/code&gt; 這類 skill 的意義，是讓 AI 定期跳出當前任務，從更高層看程式碼庫：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;哪些模組職責開始混在一起？&lt;/li&gt;
&lt;li&gt;哪些介面太複雜？&lt;/li&gt;
&lt;li&gt;哪些路徑難以測試？&lt;/li&gt;
&lt;li&gt;哪些命名和領域語言不一致？&lt;/li&gt;
&lt;li&gt;哪些重複邏輯應該收斂？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這不是讓 AI 自動大重構，而是讓它先給出結構化觀察和改進方向。真正要不要改、改到什麼程度，仍然需要開發者判斷。&lt;/p&gt;
&lt;h2 id=&#34;真正該限制的是自由度&#34;&gt;真正該限制的是自由度
&lt;/h2&gt;&lt;p&gt;這套方法論的核心可以壓縮成一句話：AI 編程不是放任模型自由發揮，而是給它清楚的目標、上下文、測試和停止條件。&lt;/p&gt;
&lt;p&gt;人類更適合負責問題定義、架構邊界、業務取捨和驗收標準；AI 更適合負責程式碼生成、測試補全、重複修改和局部重構。&lt;/p&gt;
&lt;p&gt;所以，軟體工程基礎沒有因為 AI 變強而過時。需求澄清、領域語言、TDD、診斷、架構審查這些能力，在 AI 時代反而更關鍵。&lt;/p&gt;
&lt;p&gt;會寫程式碼的人會越來越多。真正拉開差距的，是誰能把 AI 放進可維護、可驗證、可長期演進的工程體系裡。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Codex /goal vs Claude Code /goal：讓長任務自動跑到完成</title>
        <link>https://knightli.com/zh-tw/2026/05/14/codex-goal-vs-claude-code-goal/</link>
        <pubDate>Thu, 14 May 2026 22:25:31 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/14/codex-goal-vs-claude-code-goal/</guid>
        <description>&lt;p&gt;&lt;code&gt;/goal&lt;/code&gt; 正在變成 AI 編程工具裡的一個重要命令。&lt;/p&gt;
&lt;p&gt;它解決的不是「讓模型多寫幾行程式碼」，而是另一個更實際的問題：當任務有明確完成條件時，能不能讓 Agent 持續推進，直到條件滿足，而不是每完成一輪就停下來等使用者繼續催。&lt;/p&gt;
&lt;p&gt;Codex CLI 已經在官方文件裡加入了實驗性的 &lt;code&gt;/goal&lt;/code&gt;。Claude Code 也上線了自己的 &lt;code&gt;/goal&lt;/code&gt; 文件，而且把它描述成一種可以跨多輪持續工作的自動化能力。兩者名字一樣，但產品取向並不完全一樣。&lt;/p&gt;
&lt;h2 id=&#34;goal-到底解決什麼問題&#34;&gt;&lt;code&gt;/goal&lt;/code&gt; 到底解決什麼問題
&lt;/h2&gt;&lt;p&gt;普通 AI 編程對話通常是「一問一答」：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用者提出任務。&lt;/li&gt;
&lt;li&gt;Agent 分析、改程式碼、跑測試。&lt;/li&gt;
&lt;li&gt;Agent 回報結果。&lt;/li&gt;
&lt;li&gt;使用者再決定下一步。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這個流程適合短任務，但遇到遷移、重構、測試修復、issue backlog 清理時，就會變得很碎。Agent 可能每次只推進一小段，然後停下來等你輸入「繼續」。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/goal&lt;/code&gt; 的思路是把任務從「下一步做什麼」改成「最終什麼狀態算完成」。例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/goal 完成登录模块迁移，所有 auth 测试通过，lint 无报错
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這類目標天然適合長任務，因為它有清楚的終點：測試通過、建置成功、檔案拆分完成、佇列清空、驗收條件滿足。&lt;/p&gt;
&lt;h2 id=&#34;codex-的-goal實驗功能綁定目前執行緒&#34;&gt;Codex 的 &lt;code&gt;/goal&lt;/code&gt;：實驗功能，綁定目前執行緒
&lt;/h2&gt;&lt;p&gt;OpenAI 的 Codex CLI 文件把 &lt;code&gt;/goal&lt;/code&gt; 標為實驗功能。它不是預設穩定能力，需要先開啟 &lt;code&gt;features.goals&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;開啟方式有兩種：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/experimental
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;或者在 &lt;code&gt;config.toml&lt;/code&gt; 裡加入：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;features&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;goals&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;啟用後，可以這樣使用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/goal Finish the migration and keep tests green
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;常用命令包括：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/goal
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/goal pause
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/goal resume
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/goal clear
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;按照 OpenAI 文件的說法，Codex 會把 goal 附著在目前 active thread 上，在更大的任務執行過程中持續追蹤這個目標。&lt;/p&gt;
&lt;p&gt;這裡要注意一個細節：官方文件對 Codex &lt;code&gt;/goal&lt;/code&gt; 的措辭比較克制。它強調「給長任務設定實驗性目標」「把目標附著到目前執行緒」，但沒有像 Claude Code 文件那樣展開說明每一輪結束後由獨立 evaluator 自動判斷並繼續下一輪。所以現在使用 Codex &lt;code&gt;/goal&lt;/code&gt; 時，最好仍把它看作實驗中的長任務目標機制，而不是完全穩定的無人值守執行模式。&lt;/p&gt;
&lt;h2 id=&#34;claude-code-的-goal完成條件驅動的多輪執行&#34;&gt;Claude Code 的 &lt;code&gt;/goal&lt;/code&gt;：完成條件驅動的多輪執行
&lt;/h2&gt;&lt;p&gt;Claude Code 的 &lt;code&gt;/goal&lt;/code&gt; 文件寫得更明確：使用者設定 completion condition 後，Claude 會跨 turn 持續工作，直到條件滿足。&lt;/p&gt;
&lt;p&gt;示例：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/goal all tests in test/auth pass and the lint step is clean
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Claude Code 的機制大致是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;目前 turn 完成後，不直接把控制權還給使用者。&lt;/li&gt;
&lt;li&gt;一個小型快速模型會檢查目標條件是否已經滿足。&lt;/li&gt;
&lt;li&gt;如果沒有滿足，Claude 自動開始下一輪。&lt;/li&gt;
&lt;li&gt;如果滿足，goal 自動清除，並在 transcript 裡記錄完成狀態。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這意味著 Claude Code 的 &lt;code&gt;/goal&lt;/code&gt; 更像「按完成條件自動續跑」。它不只是把目標掛在會話裡，而是把「是否繼續下一輪」交給一個獨立評估步驟。&lt;/p&gt;
&lt;p&gt;Claude Code 還支援直接查看狀態：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/goal
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;狀態裡會顯示目標條件、執行時間、已評估 turn 數、token 消耗，以及 evaluator 最近一次給出的原因。&lt;/p&gt;
&lt;p&gt;如果要提前停止，可以使用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/goal clear
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;stop&lt;/code&gt;、&lt;code&gt;off&lt;/code&gt;、&lt;code&gt;reset&lt;/code&gt;、&lt;code&gt;none&lt;/code&gt;、&lt;code&gt;cancel&lt;/code&gt; 也可以作為清除別名。開啟目標後，如果會話中斷，之後透過 &lt;code&gt;--resume&lt;/code&gt; 或 &lt;code&gt;--continue&lt;/code&gt; 恢復時，仍然 active 的 goal 可以被帶回來；但計時、turn 數和 token 基線會重新計算。&lt;/p&gt;
&lt;h2 id=&#34;兩者最大的差異&#34;&gt;兩者最大的差異
&lt;/h2&gt;&lt;p&gt;Codex 和 Claude Code 都在把 AI 編程從「單輪回答」推向「長任務執行」，但 &lt;code&gt;/goal&lt;/code&gt; 的定位有差異。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;對比項&lt;/th&gt;
          &lt;th&gt;Codex CLI &lt;code&gt;/goal&lt;/code&gt;&lt;/th&gt;
          &lt;th&gt;Claude Code &lt;code&gt;/goal&lt;/code&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;狀態&lt;/td&gt;
          &lt;td&gt;experimental&lt;/td&gt;
          &lt;td&gt;官方文件單獨成頁說明&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;啟用方式&lt;/td&gt;
          &lt;td&gt;需要開啟 &lt;code&gt;features.goals&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;可直接在受信任 workspace 使用&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;目標作用域&lt;/td&gt;
          &lt;td&gt;目前 active thread&lt;/td&gt;
          &lt;td&gt;目前 session&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;常用操作&lt;/td&gt;
          &lt;td&gt;set / view / pause / resume / clear&lt;/td&gt;
          &lt;td&gt;set / view / clear&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;自動判斷&lt;/td&gt;
          &lt;td&gt;文件強調目標附著與追蹤&lt;/td&gt;
          &lt;td&gt;明確說明每輪後由 evaluator 判斷&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;自動續跑&lt;/td&gt;
          &lt;td&gt;文件表述較克制&lt;/td&gt;
          &lt;td&gt;條件未滿足時自動下一輪&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;適合場景&lt;/td&gt;
          &lt;td&gt;想在 Codex 長任務裡保持目標上下文&lt;/td&gt;
          &lt;td&gt;想按完成條件讓 Claude Code 持續推進&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;簡單說，Codex 的 &lt;code&gt;/goal&lt;/code&gt; 更像「給目前執行緒掛一個實驗性的長期目標」；Claude Code 的 &lt;code&gt;/goal&lt;/code&gt; 更像「給目前會話設定一個可驗證的停止條件，讓它自動做到滿足為止」。&lt;/p&gt;
&lt;h2 id=&#34;寫好-goal-的關鍵&#34;&gt;寫好 &lt;code&gt;/goal&lt;/code&gt; 的關鍵
&lt;/h2&gt;&lt;p&gt;不管使用哪一個工具，&lt;code&gt;/goal&lt;/code&gt; 都不適合寫成模糊願望。&lt;/p&gt;
&lt;p&gt;不太好的寫法：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/goal 把项目优化一下
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;更好的寫法：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/goal 将 payment 模块迁移到新 API，npm test -- payment 退出码为 0，git diff 只包含 payment 相关文件
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;一個好目標通常包含三點：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;明確的完成狀態。&lt;/li&gt;
&lt;li&gt;可執行的驗證方式。&lt;/li&gt;
&lt;li&gt;必須遵守的邊界。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果目標太大，還應該加上停止條件：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/goal 修复 eslint 报错，npm run lint 退出码为 0；如果超过 20 轮仍未完成，停止并总结剩余问题
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這很重要。&lt;code&gt;/goal&lt;/code&gt; 越強，越需要邊界。否則 Agent 可能會為了追求「完成」而改動過多檔案、跑太久、消耗太多 token，甚至把原本該停下來詢問的問題繼續往前推。&lt;/p&gt;
&lt;h2 id=&#34;什麼時候適合用-goal&#34;&gt;什麼時候適合用 &lt;code&gt;/goal&lt;/code&gt;
&lt;/h2&gt;&lt;p&gt;適合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;測試修復：直到指定測試通過。&lt;/li&gt;
&lt;li&gt;程式碼遷移：直到所有呼叫點改完並編譯成功。&lt;/li&gt;
&lt;li&gt;批量清理：直到某類 lint 或型別錯誤清零。&lt;/li&gt;
&lt;li&gt;文件補齊：直到所有指定模組都有說明。&lt;/li&gt;
&lt;li&gt;issue 佇列處理：直到某個標籤下的問題都被處理或明確分類。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不適合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需求本身還沒想清楚。&lt;/li&gt;
&lt;li&gt;需要頻繁產品判斷。&lt;/li&gt;
&lt;li&gt;涉及高風險刪除、資料遷移或權限變更。&lt;/li&gt;
&lt;li&gt;驗收條件只能靠主觀判斷。&lt;/li&gt;
&lt;li&gt;任務會跨越大量無關模組。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一個實用原則是：如果你能寫出「跑哪個命令、看到什麼結果、哪些檔案不能碰」，就適合用 &lt;code&gt;/goal&lt;/code&gt;。如果只能寫「幫我做得更好」，那還是先用普通對話、計畫模式或人工評審更穩。&lt;/p&gt;
&lt;h2 id=&#34;對-ai-編程工具的影響&#34;&gt;對 AI 編程工具的影響
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;/goal&lt;/code&gt; 代表一個很明顯的方向：AI 編程工具正在從「互動式助手」變成「可持續執行的工作單元」。&lt;/p&gt;
&lt;p&gt;過去我們讓 Agent 做任務，經常要在旁邊守著。它卡住了要提示，測完了要繼續，報錯了要再下命令。&lt;code&gt;/goal&lt;/code&gt; 把這部分互動壓縮成一個完成條件，讓 Agent 自己決定下一輪該做什麼。&lt;/p&gt;
&lt;p&gt;但這也帶來新的要求。以後寫 prompt 不只是描述任務，還要寫驗收條件、驗證命令、修改邊界和停止規則。換句話說，使用者的工作從「催它繼續」變成「定義什麼叫完成」。&lt;/p&gt;
&lt;p&gt;Codex 和 Claude Code 走到 &lt;code&gt;/goal&lt;/code&gt; 這一步，說明長任務 Agent 已經不再只是背景任務或雲端佇列的專利。終端裡的本地編程工具，也開始需要更強的自主推進能力。&lt;/p&gt;
&lt;h2 id=&#34;總結&#34;&gt;總結
&lt;/h2&gt;&lt;p&gt;Codex CLI 和 Claude Code 都有了 &lt;code&gt;/goal&lt;/code&gt;，但現階段不要把它們簡單看成同一個功能。&lt;/p&gt;
&lt;p&gt;Codex 的 &lt;code&gt;/goal&lt;/code&gt; 仍是實驗能力，需要開啟 &lt;code&gt;features.goals&lt;/code&gt;，更適合在 Codex 目前執行緒裡維持長期目標。Claude Code 的 &lt;code&gt;/goal&lt;/code&gt; 則更明確地把「完成條件」和「自動續跑」連在一起，透過獨立 evaluator 判斷是否繼續。&lt;/p&gt;
&lt;p&gt;對日常開發來說，這類命令最適合處理有明確驗收標準的工程任務。它不會替代需求判斷，也不會消除程式碼審查，但能減少長任務裡大量重複的「繼續」「再跑一次」「修到測試通過」。&lt;/p&gt;
&lt;p&gt;真正要學會的不是某個命令本身，而是如何把任務寫成清楚、可驗證、可停止的目標。&lt;/p&gt;
&lt;h2 id=&#34;參考資料&#34;&gt;參考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;OpenAI Codex CLI Slash Commands：&lt;a class=&#34;link&#34; href=&#34;https://developers.openai.com/codex/cli/slash-commands&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://developers.openai.com/codex/cli/slash-commands&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Claude Code Goal 文件：&lt;a class=&#34;link&#34; href=&#34;https://code.claude.com/docs/en/goal&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://code.claude.com/docs/en/goal&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Codex 怎麼接入國產大模型？用 CCX 統一管理 OpenAI 相容 API</title>
        <link>https://knightli.com/zh-tw/2026/05/13/ccx-ai-api-proxy-gateway/</link>
        <pubDate>Wed, 13 May 2026 23:20:40 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/13/ccx-ai-api-proxy-gateway/</guid>
        <description>&lt;p&gt;CCX 是一個 AI API 代理與協定轉換閘道。它把 Claude Messages、OpenAI Chat Completions、OpenAI Images、Codex Responses 和 Gemini API 放到同一個服務入口下，同時提供 Web 管理介面，用來配置渠道、金鑰、模型映射、優先級、故障轉移和流量監控。&lt;/p&gt;
&lt;p&gt;如果你平時同時使用 Claude、OpenAI、Gemini、Codex，或維護多個相容 OpenAI API 的上游服務，CCX 的價值就在於統一入口和統一管理。客戶端只需要連接一個服務地址，後面的上游渠道由 CCX 負責調度。&lt;/p&gt;
&lt;p&gt;專案地址：&lt;a class=&#34;link&#34; href=&#34;https://github.com/BenedictKing/ccx&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/BenedictKing/ccx&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;ccx-解決什麼問題&#34;&gt;CCX 解決什麼問題
&lt;/h2&gt;&lt;p&gt;多個 AI API 混用時，最容易遇到幾個問題：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每個供應商的介面路徑、鑑權方式、請求格式都不一樣。&lt;/li&gt;
&lt;li&gt;同一類模型可能有多個上游，需要手動切換 base URL 和 API key。&lt;/li&gt;
&lt;li&gt;某個 key 或渠道失敗後，客戶端通常不會自動換備用渠道。&lt;/li&gt;
&lt;li&gt;團隊使用時，很難集中管理模型白名單、代理、自訂請求標頭和呼叫日誌。&lt;/li&gt;
&lt;li&gt;想同時接 Claude、Gemini、OpenAI Chat、圖像介面和 Codex Responses 時，配置會越來越分散。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CCX 的思路是把這些差異收斂到一個代理層。前端工具、腳本或業務服務只存取 CCX；CCX 再根據介面類型、模型、渠道狀態、優先級和健康情況，把請求轉發到合適的上游。&lt;/p&gt;
&lt;h2 id=&#34;支援哪些介面&#34;&gt;支援哪些介面
&lt;/h2&gt;&lt;p&gt;CCX 對外提供一個統一後端入口，預設連接埠是 &lt;code&gt;3000&lt;/code&gt;。主要路徑包括：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GET  /                         -&amp;gt; Web 管理介面
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GET  /health                   -&amp;gt; 健康檢查
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/api/*                         -&amp;gt; 管理 API
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/messages              -&amp;gt; Claude Messages 代理
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/chat/completions      -&amp;gt; OpenAI Chat 代理
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/responses             -&amp;gt; Codex Responses 代理
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/images/generations    -&amp;gt; OpenAI Images 生成
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/images/edits          -&amp;gt; OpenAI Images 編輯
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/images/variations     -&amp;gt; OpenAI Images 變體
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GET  /v1/models                -&amp;gt; 模型清單
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1beta/models/*          -&amp;gt; Gemini 代理
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;也就是說，它不是只代理一種協定，而是把常見 AI API 分成 Messages、Chat、Responses、Gemini、Images 幾類渠道分別管理。不同協定之間不會共用同一套健康狀態和日誌空間，這對排查問題很重要。&lt;/p&gt;
&lt;h2 id=&#34;架構思路&#34;&gt;架構思路
&lt;/h2&gt;&lt;p&gt;CCX 使用 Go 後端加 Vue 3 前端。前端建置產物會嵌入後端二進位檔，因此可以做單連接埠部署：同一個服務既提供 Web UI，也提供管理 API 和代理 API。&lt;/p&gt;
&lt;p&gt;一次請求大致會經過這樣的鏈路：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Client -&amp;gt; Auth Middleware -&amp;gt; Route Handler -&amp;gt; Channel Scheduler -&amp;gt; Provider / Converter -&amp;gt; Upstream API -&amp;gt; Metrics / Channel Logs -&amp;gt; Client Response
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;幾個核心模組的分工可以這樣理解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;handlers&lt;/code&gt;：接收不同協定的請求和管理操作。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;providers&lt;/code&gt;：封裝上游 API 的請求和回應處理。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;converters&lt;/code&gt;：處理 Responses 等場景下的協定轉換。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scheduler&lt;/code&gt;：根據優先級、促銷期、健康狀態、熔斷狀態和會話親和性選擇渠道。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;metrics&lt;/code&gt;：記錄請求量、成功率、延遲、日誌和熔斷狀態。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;config&lt;/code&gt;：維護執行時配置，支援熱重載和備份。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這個設計的重點不是「把所有介面強行變成一種格式」，而是按協定類型分別代理，再在管理、調度、日誌和認證層做統一。&lt;/p&gt;
&lt;h2 id=&#34;ccx-和-codexbridge-有什麼區別&#34;&gt;CCX 和 CodexBridge 有什麼區別
&lt;/h2&gt;&lt;p&gt;CCX 和 CodexBridge 都和 Codex、OpenAI 相容介面有關，但它們解決的問題不一樣。&lt;/p&gt;
&lt;p&gt;CodexBridge 更像一個專門的 Codex 橋接器。它的核心目標是把 Codex CLI/SDK 封裝成 OpenAI 相容的 &lt;code&gt;/v1/chat/completions&lt;/code&gt; 服務，讓 OpenWebUI、Cherry Studio、腳本或其他 OpenAI 相容客戶端可以呼叫本地 Codex。也就是說，CodexBridge 的重點是「把 Codex 接出來」。&lt;/p&gt;
&lt;p&gt;CCX 更像一個統一 AI API 閘道。它不只處理 Codex Responses，還同時支援 Claude Messages、OpenAI Chat、OpenAI Images 和 Gemini API，並提供 Web 管理介面、渠道優先級、故障轉移、日誌監控和多 key 管理。也就是說，CCX 的重點是「把多個模型和多個供應商統一管起來」。&lt;/p&gt;
&lt;p&gt;簡單對比：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;對比項&lt;/th&gt;
          &lt;th&gt;CodexBridge&lt;/th&gt;
          &lt;th&gt;CCX&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;核心定位&lt;/td&gt;
          &lt;td&gt;Codex 本地橋接器&lt;/td&gt;
          &lt;td&gt;多協定 AI API 閘道&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;主要目標&lt;/td&gt;
          &lt;td&gt;讓 Codex 變成 OpenAI 相容介面&lt;/td&gt;
          &lt;td&gt;統一管理 Claude、OpenAI、Gemini、Codex 等渠道&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;管理介面&lt;/td&gt;
          &lt;td&gt;側重 API 服務本身&lt;/td&gt;
          &lt;td&gt;提供 Web 管理介面&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;多渠道調度&lt;/td&gt;
          &lt;td&gt;不是重點&lt;/td&gt;
          &lt;td&gt;支援渠道優先級、故障轉移和日誌監控&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;適合場景&lt;/td&gt;
          &lt;td&gt;本機或單服務呼叫 Codex&lt;/td&gt;
          &lt;td&gt;團隊、多 key、多供應商、多協定統一入口&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;如果只是想把 Codex 接進 OpenWebUI 或 Cherry Studio，CodexBridge 更直接；如果想同時管理 Codex、Claude、Gemini、DeepSeek、Qwen、Kimi 等多個上游，CCX 更合適。&lt;/p&gt;
&lt;h2 id=&#34;快速部署&#34;&gt;快速部署
&lt;/h2&gt;&lt;p&gt;最簡單的方式是下載二進位檔。下載後，在同目錄建立 &lt;code&gt;.env&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PROXY_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your-proxy-access-key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PORT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENABLE_WEB_UI&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;APP_UI_LANGUAGE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;zh-CN
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;啟動後存取：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;http://localhost:3000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果在 Windows 下從 WSL、Docker、PowerShell 或其他環境存取 &lt;code&gt;localhost&lt;/code&gt; 不通，可以改用 Windows 主機的區域網路 IPv4 地址，例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;http://192.168.1.23:3000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;CCX 預設透過 &lt;code&gt;:PORT&lt;/code&gt; 監聽所有網卡地址，所以暴露到區域網路時要注意存取控制。&lt;/p&gt;
&lt;h2 id=&#34;docker-部署&#34;&gt;Docker 部署
&lt;/h2&gt;&lt;p&gt;Docker 方式適合長期執行：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker run -d &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --name ccx &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -p 3000:3000 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -e &lt;span class=&#34;nv&#34;&gt;PROXY_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your-proxy-access-key &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -e &lt;span class=&#34;nv&#34;&gt;APP_UI_LANGUAGE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;zh-CN &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -v &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;pwd&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;/.config:/app/.config &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  crpi-i19l8zl0ugidq97v.cn-hangzhou.personal.cr.aliyuncs.com/bene/ccx:latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果倉庫裡已經有 &lt;code&gt;docker-compose.yml&lt;/code&gt;，也可以直接：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose up -d
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;需要自動更新時，可以疊加 Watchtower 配置：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose -f docker-compose.yml -f docker-compose.watchtower.yml up -d
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;部署完成後，&lt;code&gt;.config&lt;/code&gt; 目錄會保存執行時配置和持久化資料，建議掛載到宿主機，避免容器重建後配置遺失。&lt;/p&gt;
&lt;h2 id=&#34;原始碼執行&#34;&gt;原始碼執行
&lt;/h2&gt;&lt;p&gt;開發或自訂建置可以走原始碼方式：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git clone https://github.com/BenedictKing/ccx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; ccx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cp backend-go/.env.example backend-go/.env
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make run
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;常用命令：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make dev
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make run
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make build
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make frontend-dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;前端單獨開發：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; frontend
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun install
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun run dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;後端單獨開發：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; backend-go
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;關鍵環境變數&#34;&gt;關鍵環境變數
&lt;/h2&gt;&lt;p&gt;最小可用配置通常包括：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PORT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENV&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;production
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENABLE_WEB_UI&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PROXY_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your-proxy-access-key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ADMIN_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your-admin-secret-key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;APP_UI_LANGUAGE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;zh-CN
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;LOG_LEVEL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;info
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;REQUEST_TIMEOUT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;300000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PROXY_ACCESS_KEY&lt;/code&gt; 用於代理 API，是必須修改的金鑰。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ADMIN_ACCESS_KEY&lt;/code&gt; 用於 Web 管理介面和 &lt;code&gt;/api/*&lt;/code&gt;，建議和代理金鑰分開。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ENABLE_WEB_UI&lt;/code&gt; 控制是否啟用管理介面。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;REQUEST_TIMEOUT&lt;/code&gt; 控制請求逾時時間，長上下文或圖像任務可以適當調大。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LOG_LEVEL&lt;/code&gt; 控制日誌級別，生產環境一般用 &lt;code&gt;info&lt;/code&gt; 或 &lt;code&gt;warn&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果需要限制請求體大小，可以關注：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;MAX_REQUEST_BODY_SIZE_MB&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;50&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;圖像編輯、base64 圖片、多模態請求都可能讓請求體變大。&lt;/p&gt;
&lt;h2 id=&#34;渠道編排和故障轉移&#34;&gt;渠道編排和故障轉移
&lt;/h2&gt;&lt;p&gt;CCX 的管理介面可以配置多個渠道，並為每個渠道設定：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;上游服務類型。&lt;/li&gt;
&lt;li&gt;API key 或多 key 輪換。&lt;/li&gt;
&lt;li&gt;代理地址。&lt;/li&gt;
&lt;li&gt;自訂請求標頭。&lt;/li&gt;
&lt;li&gt;模型白名單。&lt;/li&gt;
&lt;li&gt;路由前綴。&lt;/li&gt;
&lt;li&gt;優先級。&lt;/li&gt;
&lt;li&gt;健康檢查與熔斷恢復。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;調度時會綜合考慮渠道狀態、優先級、促銷期、Trace 親和性、熔斷狀態和可用 key。簡單理解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;正常情況下，優先級高的渠道先被使用。&lt;/li&gt;
&lt;li&gt;某個渠道失敗後，可以故障轉移到備用渠道。&lt;/li&gt;
&lt;li&gt;熔斷機制會避免持續打到明顯不可用的上游。&lt;/li&gt;
&lt;li&gt;Trace 親和性會盡量讓同一類會話保持在合適的渠道上。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這類能力適合有多個 key、多個供應商或多個地區上游的場景。個人輕量使用時，也可以只配置一個渠道，把 CCX 當成帶 Web UI 的代理層。&lt;/p&gt;
&lt;h2 id=&#34;日誌和監控&#34;&gt;日誌和監控
&lt;/h2&gt;&lt;p&gt;CCX 提供渠道指標和請求日誌，可以看到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;請求量。&lt;/li&gt;
&lt;li&gt;成功率。&lt;/li&gt;
&lt;li&gt;失敗率。&lt;/li&gt;
&lt;li&gt;平均延遲。&lt;/li&gt;
&lt;li&gt;按模型統計的歷史資料。&lt;/li&gt;
&lt;li&gt;渠道狀態和熔斷情況。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;生產環境建議使用相對克制的日誌配置：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENV&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;production
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;LOG_LEVEL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;info
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENABLE_REQUEST_LOGS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENABLE_RESPONSE_LOGS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這樣可以保留基本請求資訊，又避免把完整回應內容寫入日誌。排查問題時可以臨時打開更詳細的日誌，但完成後應恢復，尤其不要在生產環境長期輸出請求體和回應體。&lt;/p&gt;
&lt;h2 id=&#34;安全建議&#34;&gt;安全建議
&lt;/h2&gt;&lt;p&gt;CCX 是代理閘道，裡面會保存上游 API key，所以部署時不要只追求「能跑起來」。至少要注意這些點：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不要使用預設或過短的 &lt;code&gt;PROXY_ACCESS_KEY&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;建議單獨設定 &lt;code&gt;ADMIN_ACCESS_KEY&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;不要把 Web 管理介面直接暴露到公網。&lt;/li&gt;
&lt;li&gt;如果必須公網存取，建議放在反向代理、VPN、存取控制或單點登入之後。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.env&lt;/code&gt;、&lt;code&gt;.config&lt;/code&gt;、日誌檔案都不要提交到 Git 倉庫。&lt;/li&gt;
&lt;li&gt;生產環境不要長期啟用完整請求體和回應體日誌。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以用下面的方式產生隨機金鑰：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PROXY_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;openssl rand -base64 32&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ADMIN_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;openssl rand -base64 32&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;適合誰使用&#34;&gt;適合誰使用
&lt;/h2&gt;&lt;p&gt;CCX 更適合這些場景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同時維護 Claude、OpenAI、Gemini、Codex 或圖像介面。&lt;/li&gt;
&lt;li&gt;有多個 API key，需要輪換、分流和故障轉移。&lt;/li&gt;
&lt;li&gt;想用 Web UI 管理上游渠道，而不是手動改配置檔。&lt;/li&gt;
&lt;li&gt;想觀察每個渠道的成功率、延遲和請求日誌。&lt;/li&gt;
&lt;li&gt;想給團隊提供一個統一 AI API 入口。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你只是本機偶爾呼叫一個模型，直接用官方 SDK 或單一 OpenAI 相容代理會更簡單。CCX 的優勢主要在多渠道、多協定和統一維運。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;CCX 的定位是 AI API 閘道，而不是某個模型的客戶端。它把 Claude Messages、OpenAI Chat、OpenAI Images、Codex Responses 和 Gemini 放到一個代理層裡，並提供渠道編排、故障轉移、日誌監控和 Web 管理介面。&lt;/p&gt;
&lt;p&gt;對個人使用者來說，它可以減少切換 API 地址和金鑰的麻煩；對團隊或長期執行的服務來說，它更像一個輕量級 AI 閘道。真正上線前，重點不只是配置模型，還要配置好金鑰、管理入口、日誌級別、渠道優先級和故障轉移策略。&lt;/p&gt;
&lt;h2 id=&#34;參考&#34;&gt;參考
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;GitHub 專案：&lt;a class=&#34;link&#34; href=&#34;https://github.com/BenedictKing/ccx&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/BenedictKing/ccx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;架構說明：&lt;a class=&#34;link&#34; href=&#34;https://github.com/BenedictKing/ccx/blob/main/ARCHITECTURE.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/BenedictKing/ccx/blob/main/ARCHITECTURE.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;環境變數說明：&lt;a class=&#34;link&#34; href=&#34;https://github.com/BenedictKing/ccx/blob/main/ENVIRONMENT.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/BenedictKing/ccx/blob/main/ENVIRONMENT.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Codex 怎麼接入國產大模型？OpenAI 相容介面與 CodexBridge 使用思路</title>
        <link>https://knightli.com/zh-tw/2026/05/13/codexbridge-openai-compatible-api/</link>
        <pubDate>Wed, 13 May 2026 23:08:28 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/13/codexbridge-openai-compatible-api/</guid>
        <description>&lt;p&gt;CodexBridge 是一個本地橋接工具，目標很直接：把 Codex CLI/SDK 封裝成 OpenAI 相容的 HTTP 服務。這樣一來，原本只能在終端機裡使用的 Codex，可以被 OpenWebUI、Cherry Studio、腳本、自動化系統，或任何相容 OpenAI Chat Completions 的客戶端呼叫。&lt;/p&gt;
&lt;p&gt;它提供的核心介面是 &lt;code&gt;/v1/chat/completions&lt;/code&gt; 和 &lt;code&gt;/v1/models&lt;/code&gt;。前者負責對話，支援一般同步回傳和 SSE 串流輸出；後者讓客戶端能像讀取模型清單一樣發現可用模型。對已經接過 OpenAI API 的工具來說，這種設計的好處是改動小，通常只需要改 base URL、API key 和模型名稱。&lt;/p&gt;
&lt;p&gt;專案地址：&lt;a class=&#34;link&#34; href=&#34;https://github.com/begonia599/CodexBridge&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/begonia599/CodexBridge&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;適合什麼場景&#34;&gt;適合什麼場景
&lt;/h2&gt;&lt;p&gt;CodexBridge 適合想把 Codex 接入現有 AI 客戶端或工作流程的人。例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;想在 OpenWebUI、Cherry Studio 裡直接選擇 Codex 模型。&lt;/li&gt;
&lt;li&gt;想用 &lt;code&gt;curl&lt;/code&gt;、Python、Node.js 等腳本呼叫本機 Codex。&lt;/li&gt;
&lt;li&gt;想讓同一個前端同時接 OpenAI、Ollama、其他相容介面和 Codex。&lt;/li&gt;
&lt;li&gt;想保留 Codex 的本地執行緒、沙箱、工作目錄和核准能力。&lt;/li&gt;
&lt;li&gt;想給內部工具提供一個統一的 &lt;code&gt;/v1/chat/completions&lt;/code&gt; 入口。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它不是一個新的大模型，也不是替代 Codex CLI 的完整前端。更準確地說，它是一個轉接層：上游仍然是 Codex，本地橋接器負責把 OpenAI 風格的請求轉換成 Codex 能理解的會話輸入。&lt;/p&gt;
&lt;h2 id=&#34;基本環境&#34;&gt;基本環境
&lt;/h2&gt;&lt;p&gt;執行前需要準備：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node.js 18 或更高版本。&lt;/li&gt;
&lt;li&gt;已安裝並登入的 Codex CLI。&lt;/li&gt;
&lt;li&gt;npm，或依照自己的習慣換成 pnpm / yarn。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;原始碼部署的基本步驟如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git clone https://github.com/begonia599/CodexBridge
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; codexbridge
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cp .env.example .env
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cp .env .env.local
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然後編輯 &lt;code&gt;.env&lt;/code&gt; 或 &lt;code&gt;.env.local&lt;/code&gt;，設定 API key、預設模型、工作目錄、沙箱模式、網路權限等配置。&lt;/p&gt;
&lt;p&gt;啟動 HTTP 服務：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm run codex:server
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;預設連接埠是 &lt;code&gt;8080&lt;/code&gt;，可以透過 &lt;code&gt;PORT&lt;/code&gt; 修改。服務啟動後，可以存取：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GET /health
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/chat/completions
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GET /v1/models
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;cli-對話模式&#34;&gt;CLI 對話模式
&lt;/h2&gt;&lt;p&gt;除了 HTTP 服務，CodexBridge 也保留了一個輕量 CLI：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm run codex:chat
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;CLI 裡可以直接輸入自然語言與 Codex 對話。常用命令有兩個：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/reset&lt;/code&gt;：建立新的 Codex 執行緒。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/exit&lt;/code&gt;：離開 CLI。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目前執行緒 ID 會保存在 &lt;code&gt;.codex_thread.json&lt;/code&gt;。下次啟動 CLI 時，如果這個檔案還在，就能繼續之前的對話。&lt;/p&gt;
&lt;h2 id=&#34;http-呼叫範例&#34;&gt;HTTP 呼叫範例
&lt;/h2&gt;&lt;p&gt;最基本的請求可以這樣寫：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl http://localhost:8080/v1/chat/completions &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;content-type: application/json&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;authorization: Bearer 123321&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -d &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&amp;#34;model&amp;#34;:&amp;#34;gpt-5-codex:medium&amp;#34;,&amp;#34;session_id&amp;#34;:&amp;#34;demo&amp;#34;,&amp;#34;messages&amp;#34;:[{&amp;#34;role&amp;#34;:&amp;#34;user&amp;#34;,&amp;#34;content&amp;#34;:&amp;#34;ls&amp;#34;}]}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這裡有幾個點需要注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;authorization&lt;/code&gt; 裡的 token 要和 &lt;code&gt;CODEX_BRIDGE_API_KEY&lt;/code&gt; 一致。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;model&lt;/code&gt; 可以帶推理等級，例如 &lt;code&gt;gpt-5-codex:medium&lt;/code&gt; 或 &lt;code&gt;gpt-5-codex:high&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;session_id&lt;/code&gt; 用來綁定會話，方便複用同一個 Codex 執行緒。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果需要串流輸出，加上 &lt;code&gt;stream: true&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -N http://localhost:8080/v1/chat/completions &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;content-type: application/json&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;authorization: Bearer 123321&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -d &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&amp;#34;model&amp;#34;:&amp;#34;gpt-5-codex:high&amp;#34;,&amp;#34;session_id&amp;#34;:&amp;#34;stream&amp;#34;,&amp;#34;stream&amp;#34;:true,&amp;#34;messages&amp;#34;:[{&amp;#34;role&amp;#34;:&amp;#34;user&amp;#34;,&amp;#34;content&amp;#34;:&amp;#34;一步步介紹如何建立 Node.js 專案&amp;#34;}]}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;對支援 OpenAI 串流回應的客戶端來說，這種回傳方式更接近正常聊天體驗。&lt;/p&gt;
&lt;h2 id=&#34;會話持久化怎麼做&#34;&gt;會話持久化怎麼做
&lt;/h2&gt;&lt;p&gt;CodexBridge 的一個重點是會話映射。請求裡可以透過這些欄位傳入會話 ID：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;session_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;conversation_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;thread_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;user&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也可以從請求標頭傳：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;x-session-id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;session-id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x-conversation-id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x-thread-id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x-user-id&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;生產環境建議開啟：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CODEX_REQUIRE_SESSION_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這樣所有請求都必須帶會話 ID，避免不同使用者或不同聊天視窗混到同一個臨時上下文裡。會話映射保存在 &lt;code&gt;.codex_threads.json&lt;/code&gt;，刪除這個檔案可以重設橋接層的映射關係；Codex 自身執行緒仍然保存在 &lt;code&gt;~/.codex/sessions&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;如果 &lt;code&gt;CODEX_REQUIRE_SESSION_ID=false&lt;/code&gt; 且請求沒有提供會話 ID，橋接器會把目前 &lt;code&gt;messages&lt;/code&gt; 展開成一次性輸入發給 Codex。這種方式適合臨時呼叫，但不適合長期對話。&lt;/p&gt;
&lt;h2 id=&#34;多模態輸入&#34;&gt;多模態輸入
&lt;/h2&gt;&lt;p&gt;CodexBridge 支援 OpenAI 風格的內容區塊，並會把圖片轉換成 Codex 可用的 &lt;code&gt;local_image&lt;/code&gt; 輸入。&lt;/p&gt;
&lt;p&gt;遠端圖片可以寫成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;image_url&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;image_url&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;url&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://example.com/demo.png&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;本地圖片可以寫成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;local_image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;./images/demo.png&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;遠端資源會先下載到暫存目錄，回合結束後清理。實際使用時要注意請求體大小，尤其是把圖片轉成 base64 傳送時，可能需要增大 &lt;code&gt;CODEX_JSON_LIMIT&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;結構化輸出&#34;&gt;結構化輸出
&lt;/h2&gt;&lt;p&gt;如果客戶端支援 &lt;code&gt;response_format&lt;/code&gt;，可以讓 CodexBridge 映射到 Codex 的 &lt;code&gt;outputSchema&lt;/code&gt;。這適合讓 Codex 回傳固定 JSON 結構，例如檢查結果、摘要、分類結果或自動化任務報告。&lt;/p&gt;
&lt;p&gt;最小思路是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;model&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;gpt-5-codex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;session_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;lint&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;response_format&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;json_schema&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;json_schema&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;lint_report&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;schema&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;object&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;properties&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;summary&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;string&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;string&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;enum&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;ok&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;action_required&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;required&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;summary&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;additionalProperties&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;messages&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;role&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;檢查 src/ 的 lint 問題，並以 JSON 回傳結果&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;需要注意，&lt;code&gt;type: &amp;quot;json_schema&amp;quot;&lt;/code&gt; 必須提供 &lt;code&gt;schema&lt;/code&gt;，否則服務會直接回傳 400。&lt;/p&gt;
&lt;h2 id=&#34;關鍵環境變數&#34;&gt;關鍵環境變數
&lt;/h2&gt;&lt;p&gt;常用配置可以分成幾類。&lt;/p&gt;
&lt;p&gt;服務與鑑權：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PORT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8080&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CODEX_BRIDGE_API_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;123321&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CODEX_JSON_LIMIT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;10mb
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;預設模型：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CODEX_MODEL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;gpt-5-codex
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CODEX_REASONING&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;medium
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Codex 執行環境：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CODEX_WORKDIR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CODEX_SANDBOX_MODE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;read-only
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CODEX_APPROVAL_POLICY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;never
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CODEX_SKIP_GIT_CHECK&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;網路能力：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CODEX_NETWORK_ACCESS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CODEX_WEB_SEARCH&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果只是給前端聊天用，預設關閉網路更穩。只有明確需要讓 Codex 執行 &lt;code&gt;curl&lt;/code&gt;、&lt;code&gt;git clone&lt;/code&gt; 或使用 Web 搜尋時，再單獨打開對應開關。&lt;/p&gt;
&lt;h2 id=&#34;docker-和一鍵腳本&#34;&gt;Docker 和一鍵腳本
&lt;/h2&gt;&lt;p&gt;專案也提供 Docker 方式，適合想把服務常駐起來的場景：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose up -d
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose logs -f codexbridge
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;也可以用專案提供的 Linux 安裝腳本：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -fsSL https://raw.githubusercontent.com/begonia599/CodexBridge/master/scripts/install.sh &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; bash
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;腳本會安裝依賴、clone 或更新倉庫、複製 &lt;code&gt;.env.example&lt;/code&gt;，並透過 Docker Compose 啟動服務。它需要 &lt;code&gt;sudo&lt;/code&gt; 權限，適合在乾淨伺服器上快速部署。已經有複雜 Node.js、Docker 或 Codex 環境的機器，建議先讀腳本內容再執行。&lt;/p&gt;
&lt;h2 id=&#34;常見問題&#34;&gt;常見問題
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;請求回傳 413&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;通常是請求體太大，常見於 base64 圖片。可以增大：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CODEX_JSON_LIMIT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;20mb
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;提示 API key 無效&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;檢查請求標頭是否帶了：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Authorization: Bearer &amp;lt;你的 CODEX_BRIDGE_API_KEY&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;或者使用 &lt;code&gt;x-api-key&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Codex 回報 Git 倉庫限制&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果執行目錄不是可信倉庫，可能會觸發 Codex 的檢查。只在確認安全的環境中使用：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;CODEX_SKIP_GIT_CHECK&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;想清空會話&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;橋接層會話映射在 &lt;code&gt;.codex_threads.json&lt;/code&gt;，Codex 自身執行緒在 &lt;code&gt;~/.codex/sessions&lt;/code&gt;。停掉服務後刪除對應檔案或目錄即可重設。&lt;/p&gt;
&lt;h2 id=&#34;使用建議&#34;&gt;使用建議
&lt;/h2&gt;&lt;p&gt;本地試用時，可以先用預設 API key 和 &lt;code&gt;read-only&lt;/code&gt; 沙箱跑通流程。確認 OpenWebUI、Cherry Studio 或腳本能正常呼叫後，再逐步調整 &lt;code&gt;CODEX_WORKDIR&lt;/code&gt;、&lt;code&gt;CODEX_SANDBOX_MODE&lt;/code&gt;、&lt;code&gt;CODEX_NETWORK_ACCESS&lt;/code&gt; 和 &lt;code&gt;CODEX_APPROVAL_POLICY&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;如果要給多人使用，建議至少做三件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;強制要求 &lt;code&gt;session_id&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;修改預設 API key。&lt;/li&gt;
&lt;li&gt;明確限制工作目錄和沙箱權限。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CodexBridge 的價值不在於功能複雜，而在於把 Codex 放進了現有 OpenAI 相容生態裡。只要客戶端能改 base URL，它就有機會把 Codex 當成一個普通聊天模型來接入，同時保留本地執行緒、沙箱和工具呼叫這些 Codex 自身的能力。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>ProgramBench 0% 解讀：AI 編程真正可怕的不是失敗，而是路線圖清楚了</title>
        <link>https://knightli.com/zh-tw/2026/05/10/programbench-ai-coding-zero-percent/</link>
        <pubDate>Sun, 10 May 2026 12:32:39 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/10/programbench-ai-coding-zero-percent/</guid>
        <description>&lt;p&gt;AI 編程圈最近出現了一個新的基準測試：&lt;code&gt;ProgramBench&lt;/code&gt;。表面上看，它給出的結果很讓程式設計師安心：九個主流模型在 fully resolved 指標上全部是 &lt;code&gt;0%&lt;/code&gt;，沒有任何模型能完整通過一個任務。&lt;/p&gt;
&lt;p&gt;但這件事真正值得緊張的地方，不是今天的大模型還做不到，而是完整軟體工程第一次被清楚地做成了一套可評測、可排名、可反覆優化的題。&lt;/p&gt;
&lt;p&gt;一旦任務被定義清楚，AI 行業最擅長的事情就會發生：刷題、迭代、追榜，然後把原來做不到的事情一點點推到可用邊緣。&lt;/p&gt;
&lt;h2 id=&#34;programbench-到底在測什麼&#34;&gt;ProgramBench 到底在測什麼
&lt;/h2&gt;&lt;p&gt;很多編程基準測試，測的是補函式、改 bug、通過單元測試，或者在已有專案裡完成一個小功能。&lt;code&gt;ProgramBench&lt;/code&gt; 更狠，它不給原始碼，也不給專案結構，更不給現成測試用例。&lt;/p&gt;
&lt;p&gt;它給模型的材料主要只有兩類：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;一個已經編譯好的可執行檔。&lt;/li&gt;
&lt;li&gt;這個程式的使用文件。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;模型需要自己執行可執行檔，觀察輸入輸出行為，理解命令列參數、邊界情況、錯誤訊息、資料儲存方式，然後重新實作一個行為一致的程式。&lt;/p&gt;
&lt;p&gt;這已經不是「寫一段程式碼」，而是一個簡化但完整的軟體工程任務：要理解需求、探索行為、選擇語言、設計結構、寫原始碼、提供建置方式，並盡量通過隱藏測試。&lt;/p&gt;
&lt;p&gt;根據 ProgramBench 官方介紹，它目前包含 200 個任務，覆蓋從小型命令列工具到 PHP、FFmpeg、SQLite 等大型真實專案。測試集由 agent-driven fuzzing 生成，總量超過 248,000 個行為測試。&lt;/p&gt;
&lt;p&gt;如果把測試流程拆開，ProgramBench 大致是在考四件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;讀懂文件：理解程式應該提供哪些命令、參數和輸出。&lt;/li&gt;
&lt;li&gt;探索行為：反覆執行二進位程式，觀察正常輸入、異常輸入和邊界情況。&lt;/li&gt;
&lt;li&gt;重建實作：自己選擇語言和專案結構，寫出一個行為接近的替代程式。&lt;/li&gt;
&lt;li&gt;通過隱藏測試：不只常規行為要對，錯誤處理、輸出格式和邊界條件也要盡量一致。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以它的搜尋價值不只是「又一個跑分」，而是回答一個更具體的問題：大模型能不能在沒有原始碼的情況下，只靠文件和黑箱行為，從零復刻一個真實軟體。&lt;/p&gt;
&lt;h2 id=&#34;為什麼結果是-0&#34;&gt;為什麼結果是 0%
&lt;/h2&gt;&lt;p&gt;ProgramBench 的主要指標是 fully resolved，也就是一個任務裡的測試全部通過才算完成。當前 leaderboard 上，九個模型在這個指標上都是 &lt;code&gt;0%&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;參與測試的模型包括 Claude、GPT、Gemini 等系列，統一使用 &lt;code&gt;mini-SWE-agent&lt;/code&gt; 作為基線 agent。Claude Opus 4.7 在 almost resolved 指標上表現最好，大約有 &lt;code&gt;3.0%&lt;/code&gt; 的任務通過了至少 95% 的測試；Claude Opus 4.6 是 &lt;code&gt;2.5%&lt;/code&gt;，Claude Sonnet 4.6 是 &lt;code&gt;1.0%&lt;/code&gt;。GPT 5.4、GPT 5.4 mini、Gemini 3.1 Pro、Gemini 3 Flash 等在 almost resolved 上都是 &lt;code&gt;0.0%&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;這說明今天的大模型加一個輕量級 agent，還無法從零重建完整軟體。即使是最簡單的任務，也很難做到所有細節都完全對齊。&lt;/p&gt;
&lt;p&gt;但也要注意：這次測試用的是 &lt;code&gt;mini-SWE-agent&lt;/code&gt;，不是 Claude Code，也不是 Codex。換成更強的 coding agent、更多工具鏈支援、更長時間的探索流程，結果可能會提高。所以這個結果更準確的說法是：當前模型加輕量 agent，還不足以穩定完成完整軟體重建。&lt;/p&gt;
&lt;h2 id=&#34;fully-resolved-和-almost-resolved-是什麼意思&#34;&gt;fully resolved 和 almost resolved 是什麼意思
&lt;/h2&gt;&lt;p&gt;讀 ProgramBench 的結果時，最容易誤解的是這兩個指標。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;fully resolved&lt;/code&gt; 是最嚴格的指標：一個任務裡的所有隱藏測試都通過，才算完整解決。只要還漏掉一個邊界條件、一個報錯格式、一個命令參數行為，就不能算 fully resolved。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;almost resolved&lt;/code&gt; 則更像「接近完成」：如果一個任務至少通過了 95% 的測試，就算進入 almost resolved。它能反映模型有沒有把大部分行為做出來，但還不能代表程式已經可以替代原軟體。&lt;/p&gt;
&lt;p&gt;這也是為什麼 &lt;code&gt;0%&lt;/code&gt; 要分開看。fully resolved 的 &lt;code&gt;0%&lt;/code&gt; 說明模型還無法完整交付；almost resolved 的差距則能看出哪些模型已經在部分任務上接近復刻成功。比如 Claude Opus 4.7 的 almost resolved 約為 &lt;code&gt;3.0%&lt;/code&gt;，說明它確實在少量相對簡單的任務上更接近完成，但距離穩定重建完整軟體仍然很遠。&lt;/p&gt;
&lt;h2 id=&#34;為什麼-mini-swe-agent-會影響測試結果&#34;&gt;為什麼 mini-SWE-agent 會影響測試結果
&lt;/h2&gt;&lt;p&gt;這次測試使用統一的 &lt;code&gt;mini-SWE-agent&lt;/code&gt;，好處是公平：不同模型都跑在同一套輕量 agent 框架裡，結果更容易橫向比較。&lt;/p&gt;
&lt;p&gt;但它也會限制上限。完整軟體重建不只取決於模型本身，還取決於 agent 是否會規劃探索策略、是否能管理長期任務、是否會自動生成測試、是否能反覆定位失敗原因、是否能整理專案結構。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mini-SWE-agent&lt;/code&gt; 更像一個統一基線，而不是最強工程環境。&lt;/p&gt;
&lt;p&gt;Claude Code、Codex 這類更完整的 coding agent，通常會提供更強的工具呼叫、上下文組織、任務拆解和多輪修復能力。如果換成這些工具，結果可能會更好。&lt;/p&gt;
&lt;p&gt;所以 ProgramBench 這次結果更適合理解為：當前模型在輕量 agent 環境下還做不到完整軟體重建。它不是在證明「模型永遠做不到」，也不是在完整評估所有商業 coding agent 的上限。&lt;/p&gt;
&lt;h2 id=&#34;它和-swe-bench-的差別&#34;&gt;它和 SWE-bench 的差別
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;SWE-bench&lt;/code&gt; 已經是 AI 編程領域裡很重要的基準。它讓模型在真實 GitHub 倉庫裡讀 issue、改程式碼、提交補丁，用來測試模型解決真實 bug 的能力。&lt;/p&gt;
&lt;p&gt;但 &lt;code&gt;SWE-bench&lt;/code&gt; 本質上仍然是在已有專案上修車：車還在，技術棧、目錄結構、程式碼組織、架構設計都已經有人完成了。模型只需要找到問題，把壞掉的零件修好。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ProgramBench&lt;/code&gt; 更接近重新造車：你只知道這台車應該有什麼行為，看到紅燈會停、遇到行人會鳴笛，剩下的結構、語言、模組、建置方式，全都要自己決定。&lt;/p&gt;
&lt;p&gt;這就是為什麼它難得多。它不再只考局部補丁能力，而是在考軟體架構、系統推理、行為探索、自動測試、多輪糾錯和長期工程設計。&lt;/p&gt;
&lt;p&gt;可以用一張表來理解兩者差別：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;維度&lt;/th&gt;
          &lt;th&gt;SWE-bench&lt;/th&gt;
          &lt;th&gt;ProgramBench&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;起點&lt;/td&gt;
          &lt;td&gt;已有 GitHub 倉庫和 issue&lt;/td&gt;
          &lt;td&gt;已編譯可執行檔和使用文件&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;是否給原始碼&lt;/td&gt;
          &lt;td&gt;給原始碼&lt;/td&gt;
          &lt;td&gt;不給原始碼&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;主要任務&lt;/td&gt;
          &lt;td&gt;修復已有專案裡的 bug&lt;/td&gt;
          &lt;td&gt;從行為重新實作一個完整程式&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;技術棧&lt;/td&gt;
          &lt;td&gt;原專案已經確定&lt;/td&gt;
          &lt;td&gt;模型自己選擇&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;專案結構&lt;/td&gt;
          &lt;td&gt;原專案已經存在&lt;/td&gt;
          &lt;td&gt;模型自己設計&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;測試方式&lt;/td&gt;
          &lt;td&gt;提交補丁後跑測試&lt;/td&gt;
          &lt;td&gt;用隱藏行為測試驗證復刻程度&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;主要考點&lt;/td&gt;
          &lt;td&gt;讀程式碼、定位問題、補丁修復&lt;/td&gt;
          &lt;td&gt;行為探索、系統抽象、架構設計、完整實作&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;這也是為什麼 ProgramBench 更適合被看作下一階段 AI Coding 的目標：它把「修現有程式碼」推進到了「重建完整軟體」。&lt;/p&gt;
&lt;h2 id=&#34;0-並不等於安全&#34;&gt;0% 並不等於安全
&lt;/h2&gt;&lt;p&gt;看到 &lt;code&gt;0%&lt;/code&gt;，很多人的第一反應可能是：程式設計師飯碗暫時保住了。&lt;/p&gt;
&lt;p&gt;短期看，這句話沒錯。今天的大模型還不能穩定完成完整軟體工程，尤其是在沒有原始碼、沒有測試用例、沒有專案結構的情況下。需求釐清、架構設計、長期維護、安全控制、團隊協作、業務理解，仍然是人類軟體工程師的重要優勢。&lt;/p&gt;
&lt;p&gt;但如果把 &lt;code&gt;0%&lt;/code&gt; 理解成「AI 編程到頭了」，就太樂觀了。&lt;/p&gt;
&lt;p&gt;ProgramBench 真正改變的是問題定義。以前大家知道 AI 可以補程式碼，也知道 AI 可以修 bug，但「從一個可執行檔和文件重建完整軟體」這件事沒有被清楚地放到統一賽道裡。現在它被做成了 200 道題、統一評測、統一排名。&lt;/p&gt;
&lt;p&gt;這意味著模型公司、agent 公司、開發工具公司都知道下一步該往哪裡發力：讓 AI 從寫程式碼片段，進化到維護、重建和交付完整軟體系統。&lt;/p&gt;
&lt;h2 id=&#34;為什麼要斷網和防作弊&#34;&gt;為什麼要斷網和防作弊
&lt;/h2&gt;&lt;p&gt;ProgramBench 的設計裡有一個細節很重要：它要防止模型作弊。&lt;/p&gt;
&lt;p&gt;早期測試中，模型會嘗試直接從 GitHub 找原始碼，或者通過套件管理器下載包含原始碼的套件，甚至去系統快取目錄裡翻找已經下載過的軟體包。這樣當然會破壞測試目的，因為問題就不再是「能不能從行為重建軟體」，而是「能不能找到原始原始碼」。&lt;/p&gt;
&lt;p&gt;所以 ProgramBench 使用了沙箱和斷網環境，不允許存取網際網路，也不允許反編譯、反組譯或讀取可執行檔內容。模型只能執行程式，觀察行為，再自己實作。&lt;/p&gt;
&lt;p&gt;這個限制讓測試更乾淨，也更接近它真正想回答的問題：大語言模型能不能從程式行為和文件出發，自己構建一個可執行的軟體專案。&lt;/p&gt;
&lt;h2 id=&#34;更值得警惕的是程式碼形態變化&#34;&gt;更值得警惕的是程式碼形態變化
&lt;/h2&gt;&lt;p&gt;ProgramBench 還有一個比 &lt;code&gt;0%&lt;/code&gt; 更值得軟體工程師思考的發現：模型生成的程式碼往往不像人類工程師會寫的專案。&lt;/p&gt;
&lt;p&gt;公開材料裡提到，模型傾向於生成更少的檔案、更淺的目錄、更少的函式，以及更長的單個函式。也就是說，它可能寫出一個巨大的、能跑的腳本，而不是一個結構清晰、便於人類維護的軟體工程專案。&lt;/p&gt;
&lt;p&gt;從傳統軟體工程角度看，這通常是很差的程式碼。檔案太少、函式太長、抽象不足、模組邊界不清，都會讓人類難以維護。&lt;/p&gt;
&lt;p&gt;但問題在於，AI 未必需要按照人類維護程式碼的方式寫程式碼。&lt;/p&gt;
&lt;p&gt;人類強調抽象、命名、目錄結構和模組邊界，主要是因為人類記憶有限、團隊需要協作、程式碼需要長期復用。AI 如果可以用更長上下文、檢索系統和自動測試反覆重寫程式碼，它可能並不那麼需要人類熟悉的這些工程規範。&lt;/p&gt;
&lt;p&gt;這會帶來一個很現實的風險：未來 AI 寫出的軟體也許能跑、甚至很快，但人類越來越難插手維護。&lt;/p&gt;
&lt;h2 id=&#34;程式設計師真正要升級什麼&#34;&gt;程式設計師真正要升級什麼
&lt;/h2&gt;&lt;p&gt;ProgramBench 的結果對程式設計師不是簡單的好消息，也不是簡單的壞消息。&lt;/p&gt;
&lt;p&gt;短期看，完整軟體工程仍然很難，程式設計師不會因為這次 benchmark 立刻失業。尤其是架構判斷、需求釐清、安全把控、品質驗收和業務理解，仍然需要人類負責。&lt;/p&gt;
&lt;p&gt;長期看，程式設計師的工作會繼續上移。真正危險的不是「不會寫程式碼」的人，而是只會寫程式碼、但不會定義問題、驗證結果、組織工具鏈和控制風險的人。&lt;/p&gt;
&lt;p&gt;未來的軟體工程師可能更像：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;需求定義者：把模糊業務問題變成可執行目標。&lt;/li&gt;
&lt;li&gt;系統驗收者：判斷 AI 生成結果是否真的滿足需求。&lt;/li&gt;
&lt;li&gt;工具鏈組織者：組合模型、agent、測試、部署和監控。&lt;/li&gt;
&lt;li&gt;品質負責人：控制安全、可維護性、邊界條件和長期風險。&lt;/li&gt;
&lt;li&gt;業務和技術之間的翻譯者：把真實問題轉成工程系統能處理的約束。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果 AI 真的從程式碼助手變成完整軟體工程師，人類程式設計師的價值就不再只是親手寫每一行程式碼，而是定義什麼值得寫、怎樣算寫對、哪裡不能出錯。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;ProgramBench 的 &lt;code&gt;0%&lt;/code&gt; 不是終點，而是新階段的起點。&lt;/p&gt;
&lt;p&gt;它說明今天的大模型還不能從零穩定重建完整軟體系統；但它也把下一代 AI Coding agent 的目標定義得非常清楚：從局部補丁走向完整專案，從程式碼片段走向系統交付。&lt;/p&gt;
&lt;p&gt;對程式設計師來說，短期可以鬆一口氣，但長期不能只盯著「AI 現在還不行」。更重要的是盡快把自己從程式碼執行者升級為問題定義者、結果驗收者和風險控制者。&lt;/p&gt;
&lt;p&gt;真正值得緊張的不是 AI 今天考了 &lt;code&gt;0%&lt;/code&gt;，而是題目已經擺出來了。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>GPT-5.5、GPT-5.4 與 GPT-5.3-Codex 如何取捨</title>
        <link>https://knightli.com/zh-tw/2026/05/10/gpt-5-5-vs-gpt-5-4-vs-gpt-5-3-codex/</link>
        <pubDate>Sun, 10 May 2026 08:43:17 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/10/gpt-5-5-vs-gpt-5-4-vs-gpt-5-3-codex/</guid>
        <description>&lt;p&gt;如果只看一句話，結論其實很直接：預設選 &lt;code&gt;GPT-5.5&lt;/code&gt;，預算更敏感或任務難度中等時選 &lt;code&gt;GPT-5.4&lt;/code&gt;，只有在 Codex 環境裡做更長時間的軟體工程任務，或需要 Cloud Tasks、Code Review 這類能力時，再重點看 &lt;code&gt;GPT-5.3-Codex&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;這個判斷不只是主觀體驗，OpenAI 在 Codex 官方文件裡的推薦也已經很明確。到 &lt;code&gt;2026-05-10&lt;/code&gt; 為止，Codex 文件仍然寫著：大多數任務優先從 &lt;code&gt;gpt-5.5&lt;/code&gt; 開始；如果還沒有開放 &lt;code&gt;gpt-5.5&lt;/code&gt;，就繼續用 &lt;code&gt;gpt-5.4&lt;/code&gt;；輕量任務或子任務則更適合 &lt;code&gt;gpt-5.4-mini&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;三個模型的定位差異&#34;&gt;三個模型的定位差異
&lt;/h2&gt;&lt;p&gt;先看官方定位。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.5&lt;/code&gt; 是 Codex 裡最新的前沿模型，面向複雜編程、電腦操作、知識工作與研究型工作流。它更像是「預設主力模型」，適合複雜分析、多步任務、跨檔案修改、方案設計與較重的文件工作。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.4&lt;/code&gt; 則是一個更穩的全能型選擇。官方描述是：它把 &lt;code&gt;GPT-5.3-Codex&lt;/code&gt; 的強程式能力帶到了更強的推理、工具使用與 agentic workflow 裡。換句話說，它不是「弱化版 5.5」，而是一個更均衡、更容易長期當主力的模型。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.3-Codex&lt;/code&gt; 仍然是很強的程式模型，但它的核心優勢更集中在真實軟體工程與 Codex 原生工作流裡。官方文件也特別說明：它是針對 agentic coding tasks 最佳化的模型，而且 &lt;code&gt;GPT-5.4&lt;/code&gt; 的編碼能力本身就已經繼承了它的長處。&lt;/p&gt;
&lt;p&gt;所以今天再選模型，不太適合把 &lt;code&gt;GPT-5.3-Codex&lt;/code&gt; 直接理解成「最強編程模型」。在大部分日常開發場景裡，更推薦先看 &lt;code&gt;GPT-5.5&lt;/code&gt; 和 &lt;code&gt;GPT-5.4&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;按使用場景怎麼選&#34;&gt;按使用場景怎麼選
&lt;/h2&gt;&lt;p&gt;如果你的任務是日常問答、複雜解釋、資料整理、檔案分析、長文資訊綜合，&lt;code&gt;GPT-5.5&lt;/code&gt; 最合適。它不只適合寫程式，也更適合處理「程式之外但又很費腦力」的知識工作。&lt;/p&gt;
&lt;p&gt;如果你的任務是複雜編程、重構、排錯、架構設計、多檔案修改，仍然優先 &lt;code&gt;GPT-5.5&lt;/code&gt;。Codex 官方推薦也是這樣寫的：在能用 &lt;code&gt;gpt-5.5&lt;/code&gt; 的地方，大多數任務先從它開始。&lt;/p&gt;
&lt;p&gt;如果你更在意額度與消耗，希望在品質很高的前提下把成本壓下來，&lt;code&gt;GPT-5.4&lt;/code&gt; 往往是更合理的預設值。對很多常規開發、普通改寫、一般翻譯、腳本生成與 bug 修復任務來說，&lt;code&gt;GPT-5.4&lt;/code&gt; 已經足夠強，而且更省額度。&lt;/p&gt;
&lt;p&gt;如果你是在 Codex CLI、IDE 擴充套件或 App 裡做更像「工程代理」的事情，例如長時間讀倉庫、持續改程式、排隊跑任務、做 Cloud Tasks 或 Code Review，&lt;code&gt;GPT-5.3-Codex&lt;/code&gt; 仍然有存在感。原因不是它比 &lt;code&gt;GPT-5.5&lt;/code&gt; 更先進，而是目前 Codex 的 Cloud Tasks 和 Code Review 仍然執行在 &lt;code&gt;GPT-5.3-Codex&lt;/code&gt; 上。&lt;/p&gt;
&lt;h2 id=&#34;消耗額度差多少&#34;&gt;消耗額度差多少
&lt;/h2&gt;&lt;p&gt;在 Codex 的 credits 計費表裡，這三個模型的差異非常清楚。&lt;/p&gt;
&lt;p&gt;按 Business / New Enterprise 的 token 計費口徑看：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;GPT-5.5&lt;/code&gt;：輸入 &lt;code&gt;125 credits / 1M tokens&lt;/code&gt;，快取輸入 &lt;code&gt;12.5 credits&lt;/code&gt;，輸出 &lt;code&gt;750 credits&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GPT-5.4&lt;/code&gt;：輸入 &lt;code&gt;62.5 credits / 1M tokens&lt;/code&gt;，快取輸入 &lt;code&gt;6.25 credits&lt;/code&gt;，輸出 &lt;code&gt;375 credits&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GPT-5.3-Codex&lt;/code&gt;：輸入 &lt;code&gt;43.75 credits / 1M tokens&lt;/code&gt;，快取輸入 &lt;code&gt;4.375 credits&lt;/code&gt;，輸出 &lt;code&gt;350 credits&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這代表如果只看名義費率，&lt;code&gt;GPT-5.4&lt;/code&gt; 大約是 &lt;code&gt;GPT-5.5&lt;/code&gt; 的一半。做同樣長度的輸入輸出時，通常能省接近 &lt;code&gt;50%&lt;/code&gt; 的額度。&lt;code&gt;GPT-5.3-Codex&lt;/code&gt; 的輸入更便宜，但輸出已經和 &lt;code&gt;GPT-5.4&lt;/code&gt; 很接近，所以它並不是那種「明顯便宜很多」的選項。&lt;/p&gt;
&lt;p&gt;還有一個容易忽略的點：Codex 官方又特別寫了一句，&lt;code&gt;GPT-5.5 uses significantly fewer tokens to achieve results comparable to GPT-5.4&lt;/code&gt;。也就是說，雖然它的單價更高，但在某些複雜任務裡，可能會靠更少的 token 和更少返工把差距拉回來。&lt;/p&gt;
&lt;p&gt;不過對固定模板文章改寫、翻譯、SEO 描述生成這種輸入輸出長度都比較穩定的任務來說，這種「少走彎路」的優勢通常沒有複雜工程任務那麼明顯。實際消耗上，&lt;code&gt;GPT-5.4&lt;/code&gt; 大多還是更省，通常可以理解成省掉大約 &lt;code&gt;45%&lt;/code&gt; 到 &lt;code&gt;50%&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;codex-使用限制上的差異&#34;&gt;Codex 使用限制上的差異
&lt;/h2&gt;&lt;p&gt;除了單價，Codex 裡的可用方式也不一樣。&lt;/p&gt;
&lt;p&gt;截至 &lt;code&gt;2026-05-10&lt;/code&gt;，&lt;code&gt;GPT-5.5&lt;/code&gt; 在 Codex 裡是推薦模型，但目前只在使用 ChatGPT 登入的 Codex 中提供，不支援 API key 驗證。&lt;code&gt;GPT-5.4&lt;/code&gt; 和 &lt;code&gt;GPT-5.3-Codex&lt;/code&gt; 則支援 API 存取。&lt;/p&gt;
&lt;p&gt;另外，&lt;code&gt;GPT-5.5&lt;/code&gt; 和 &lt;code&gt;GPT-5.4&lt;/code&gt; 目前都不支援 Codex Cloud Tasks 和 Code Review；這兩項仍然是 &lt;code&gt;GPT-5.3-Codex&lt;/code&gt; 的主場。也就是說，如果你說的是「在 Codex 裡長時間跑工程任務」，那就不能只看模型本身強不強，還要看對應功能是不是只有 &lt;code&gt;GPT-5.3-Codex&lt;/code&gt; 才能跑。&lt;/p&gt;
&lt;p&gt;如果你只是本地訊息使用，Plus 方案下官方給出的 5 小時窗口大致是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;GPT-5.5&lt;/code&gt;：&lt;code&gt;15-80&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GPT-5.4&lt;/code&gt;：&lt;code&gt;20-100&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GPT-5.3-Codex&lt;/code&gt;：&lt;code&gt;30-150&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;從這裡也能看出一個現實差異：&lt;code&gt;GPT-5.5&lt;/code&gt; 最強，但在固定額度下可用次數通常更少；&lt;code&gt;GPT-5.4&lt;/code&gt; 更均衡；&lt;code&gt;GPT-5.3-Codex&lt;/code&gt; 在本地訊息上反而看起來更耐用一些。&lt;/p&gt;
&lt;h2 id=&#34;常用場景怎麼選&#34;&gt;常用場景怎麼選
&lt;/h2&gt;&lt;p&gt;日常使用裡有不少高頻任務。更實用的看法，不是抽象地說「哪個更強」，而是按場景一個一個拆開看。&lt;/p&gt;
&lt;h3 id=&#34;1-日常問答資料整理長文總結&#34;&gt;1. 日常問答、資料整理、長文總結
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;GPT-5.5&lt;/code&gt;：最適合。它更擅長處理模糊問題、補齊上下文，把零散資訊整理成結構化結果。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.4&lt;/code&gt;：適合普通總結與批量整理。難度不高、數量很多時，通常更划算。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.3-Codex&lt;/code&gt;：不太適合當主力。能做，但這不是它最有優勢的場景。&lt;/p&gt;
&lt;h3 id=&#34;2-技術概念解釋程式講解讀舊專案&#34;&gt;2. 技術概念解釋、程式講解、讀舊專案
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;GPT-5.5&lt;/code&gt;：適合複雜專案。跨檔案關係多、呼叫鏈長、歷史包袱重時更穩。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.4&lt;/code&gt;：適合常規閱讀理解。看函式、看模組、解釋設定、幫你快速接手專案都很好用。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.3-Codex&lt;/code&gt;：更偏工程執行，不是最優先的「講解型模型」。&lt;/p&gt;
&lt;h3 id=&#34;3-寫腳本小工具sqlshell正則&#34;&gt;3. 寫腳本、小工具、SQL、Shell、正則
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;GPT-5.5&lt;/code&gt;：適合腳本背後還有系統設計、聯動多個服務、涉及複雜約束的情況。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.4&lt;/code&gt;：最適合當預設主力。大多數腳本、小工具、SQL 與命令列任務都夠用，而且更省額度。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.3-Codex&lt;/code&gt;：如果腳本只是整個工程代理鏈條的一部分，可以考慮；單獨寫小腳本時不必優先選它。&lt;/p&gt;
&lt;h3 id=&#34;4-改-bug改小功能補測試普通開發&#34;&gt;4. 改 bug、改小功能、補測試、普通開發
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;GPT-5.5&lt;/code&gt;：適合稍複雜的修復，例如需要先分析原因，再跨檔案修改，最後補測試。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.4&lt;/code&gt;：最適合日常開發主力。普通 bug、小功能、測試樣板、重新命名、格式整理這類任務，性價比最好。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.3-Codex&lt;/code&gt;：能做，但如果沒有 Cloud Tasks 或工程代理需求，通常不是第一選擇。&lt;/p&gt;
&lt;h3 id=&#34;5-複雜重構架構設計疑難排錯&#34;&gt;5. 複雜重構、架構設計、疑難排錯
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;GPT-5.5&lt;/code&gt;：最適合。複雜任務裡最貴的是返工，不是單次輸出；&lt;code&gt;GPT-5.5&lt;/code&gt; 更適合做主解題模型。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.4&lt;/code&gt;：適合中等複雜度任務。可以做方案和重構，但在特別長的上下文、多步推理與高不確定性問題上通常不如 &lt;code&gt;GPT-5.5&lt;/code&gt; 穩。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.3-Codex&lt;/code&gt;：偏執行，不是這類高難決策任務的預設優先級。&lt;/p&gt;
&lt;h3 id=&#34;6-批量輕任務重複任務拆子任務&#34;&gt;6. 批量輕任務、重複任務、拆子任務
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;GPT-5.5&lt;/code&gt;：能做，但通常不划算。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.4&lt;/code&gt;：最適合。批量改註釋、批量改格式、批量生成樣板程式碼、批量改內容時，最平衡。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.3-Codex&lt;/code&gt;：如果任務已經放進 Codex 的工程流程裡，可以考慮；單看性價比，仍然通常不如 &lt;code&gt;GPT-5.4&lt;/code&gt;。&lt;/p&gt;
&lt;h3 id=&#34;7-自動化流水線代理執行持續讀寫倉庫&#34;&gt;7. 自動化流水線、代理執行、持續讀寫倉庫
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;GPT-5.5&lt;/code&gt;：適合做前期方案設計、規則制定與複雜任務拆分。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.4&lt;/code&gt;：適合寫自動化腳本、補中等複雜度流程邏輯，尤其是在 API 可接入的情況下。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.3-Codex&lt;/code&gt;：最值得關注。因為 Codex 的 Cloud Tasks 和 Code Review 還執行在它上面，所以它更適合「讓系統自己跑」的工程場景。&lt;/p&gt;
&lt;h3 id=&#34;8-重要頁面文案品牌介紹最終潤飾&#34;&gt;8. 重要頁面文案、品牌介紹、最終潤飾
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;GPT-5.5&lt;/code&gt;：最適合。自然度、風格控制與上下文一致性最好。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.4&lt;/code&gt;：適合大多數普通頁面和日常更新，重要頁面可以先寫初稿再交給 &lt;code&gt;GPT-5.5&lt;/code&gt; 精修。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.3-Codex&lt;/code&gt;：不適合當主要文案模型。&lt;/p&gt;
&lt;h3 id=&#34;9-網站固定模板文章改寫翻譯seo-描述&#34;&gt;9. 網站固定模板文章改寫、翻譯、SEO 描述
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;GPT-5.5&lt;/code&gt;：適合做模板設計、最終潤飾、重要頁面定稿，以及把中文翻成更自然的英文。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.4&lt;/code&gt;：最適合批量生產。普通文章改寫、固定結構翻譯、商品文案重寫、Meta 描述批量生成，通常品質和成本最平衡。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.3-Codex&lt;/code&gt;：不適合當主要文案模型，更適合寫批次處理腳本、清洗 HTML、保留標籤結構、改自動發布流程。&lt;/p&gt;
&lt;h3 id=&#34;10-電商商品文案分類頁批量內容營運&#34;&gt;10. 電商商品文案、分類頁、批量內容營運
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;GPT-5.5&lt;/code&gt;：適合定規則、做抽檢、做高價值頁面的最終潤飾。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.4&lt;/code&gt;：最適合批量生產。商品標題、分類頁說明、批量活動文案、長尾 SEO 內容這類任務上，品質和成本更平衡。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GPT-5.3-Codex&lt;/code&gt;：適合寫抓取、清洗、批次處理、自動發布腳本，不適合負責主要文案。&lt;/p&gt;
&lt;p&gt;如果把這些場景再壓縮成一句話：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;複雜腦力活、複雜分析、複雜文案：優先 &lt;code&gt;GPT-5.5&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;日常開發、批量生產、重複任務：優先 &lt;code&gt;GPT-5.4&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Codex 工程代理、Cloud Tasks、Code Review：重點看 &lt;code&gt;GPT-5.3-Codex&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;最後怎麼取捨&#34;&gt;最後怎麼取捨
&lt;/h2&gt;&lt;p&gt;如果你只是平時寫程式、改 bug、問技術問題、順手做一些文件工作，&lt;code&gt;GPT-5.4&lt;/code&gt; 是很穩的主力選擇。&lt;/p&gt;
&lt;p&gt;如果你要做的是更複雜的專案分析、多檔案修改、架構方案、深度排錯，或希望一個模型同時覆蓋編程與複雜知識工作，直接優先 &lt;code&gt;GPT-5.5&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;如果你在 Codex 環境裡看重的是工程工作流本身，例如 Cloud Tasks、Code Review、長時間代理執行，那麼 &lt;code&gt;GPT-5.3-Codex&lt;/code&gt; 仍然值得保留，但它已經不太適合被當成「預設第一選擇」。&lt;/p&gt;
&lt;p&gt;對固定模板內容站來說，更實用的搭配通常是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;GPT-5.4&lt;/code&gt; 負責批量生產&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GPT-5.5&lt;/code&gt; 負責定模板、做抽檢、做最終潤飾&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GPT-5.3-Codex&lt;/code&gt; 負責寫自動化工具，而不是負責主要內容&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;現在更合理的預設順序是：&lt;code&gt;GPT-5.5&lt;/code&gt; 第一，&lt;code&gt;GPT-5.4&lt;/code&gt; 第二，&lt;code&gt;GPT-5.3-Codex&lt;/code&gt; 放到更偏工程代理與 Codex 特定能力的場景裡使用。&lt;/p&gt;
&lt;p&gt;如果你問的是「同樣一篇模板文章改寫，&lt;code&gt;GPT-5.4&lt;/code&gt; 比 &lt;code&gt;GPT-5.5&lt;/code&gt; 能省多少」，按官方 credits 表和這類任務的典型 token 結構看，通常可以按「省接近一半」來理解。對批量站內容來說，這個差距已經夠大，所以最常見的做法不是全程上 &lt;code&gt;GPT-5.5&lt;/code&gt;，而是先用 &lt;code&gt;GPT-5.5&lt;/code&gt; 把規則與風格定好，再把大批量任務交給 &lt;code&gt;GPT-5.4&lt;/code&gt;。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>AI Coding 套餐怎麼選：輕度看順手，重度看靈活性</title>
        <link>https://knightli.com/zh-tw/2026/05/10/ai-coding-plan-selection/</link>
        <pubDate>Sun, 10 May 2026 08:20:58 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/10/ai-coding-plan-selection/</guid>
        <description>&lt;p&gt;AI Coding 套餐這半年變化很快。很多工具從「按次」轉向「按量」，免費或低價套餐的額度被收緊，部分海外服務還增加了身份驗證、地區限制和更嚴格的使用規則。&lt;/p&gt;
&lt;p&gt;對開發者來說，問題已經不只是「哪個模型最強」，而是：每個月要花多少錢、額度夠不夠、工具是否順手，以及當某個套餐突然漲價或改規則時，能不能平滑切換。&lt;/p&gt;
&lt;p&gt;一個比較實用的結論是：輕度使用者買順手的工具，中度使用者買性價比，重度使用者買靈活性。使用越重，越不要把模型和工具綁死在同一個套餐裡。&lt;/p&gt;
&lt;h2 id=&#34;選套餐先看四件事&#34;&gt;選套餐先看四件事
&lt;/h2&gt;&lt;p&gt;過去選 AI Coding 套餐，通常看三點：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;模型能力是否足夠強。&lt;/li&gt;
&lt;li&gt;回應速度是否穩定。&lt;/li&gt;
&lt;li&gt;套餐額度是否夠用。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;現在還要加上第四點：模型和工具能不能分開。&lt;/p&gt;
&lt;p&gt;模型負責推理能力，工具負責上下文管理、檔案編輯、Agent 編排和工作流體驗。兩者都重要，但最好不要完全綁定。例如如果你喜歡 Claude 模型，可以買官方套餐，也可以透過 API 接到其他工具裡；如果你喜歡某個編輯器或 Agent 工具，也最好確認它能接入不同模型，而不是只能使用自家套餐。&lt;/p&gt;
&lt;p&gt;這樣做的好處不是折騰，而是降低風險。AI Coding 是變化最快的賽道之一，今天額度寬鬆的套餐，過兩個月可能就改計費；今天好用的工具，下一版也可能因為模型介面變化而體驗下降。把模型和工具分開，等於給自己留了遷移空間。&lt;/p&gt;
&lt;h2 id=&#34;海外套餐正在收緊&#34;&gt;海外套餐正在收緊
&lt;/h2&gt;&lt;p&gt;GitHub Copilot、Cursor、Windsurf、Claude Code 這類工具仍然是很多人的主力選擇，但整體趨勢已經很明確：低價高額度越來越難維持，按量計費越來越常見。&lt;/p&gt;
&lt;p&gt;GitHub Copilot 這類服務開始更強調按量計費之後，套餐本身的「套利空間」會明顯減少。對輕度使用者來說，它仍然方便；但對高頻使用 Agent、長上下文與複雜程式任務的人來說，實際消耗會更接近真實 API 成本。&lt;/p&gt;
&lt;p&gt;Cursor 和 Windsurf 本質上是把模型能力包進 IDE 體驗裡。它們的優勢是開箱即用、編輯器體驗成熟，缺點是工具綁定較深。一旦你依賴其中的專屬 Agent、索引與自動化流程，後續遷移成本就會越來越高。&lt;/p&gt;
&lt;p&gt;Claude Code 的體驗和生態熱度很高，但海外訂閱、身份驗證、地區限制、中轉服務安全性，都會成為國內使用者需要額外評估的風險。尤其是第三方中轉服務，可能存在模型摻雜、穩定性不足、資料安全和跑路風險，不適合作為重要專案的長期基礎設施。&lt;/p&gt;
&lt;h2 id=&#34;國產套餐的優點和短板&#34;&gt;國產套餐的優點和短板
&lt;/h2&gt;&lt;p&gt;國產 AI Coding 套餐的一個優點，是很多服務以 API 形式提供，天然不太鎖定工具。你可以把模型接入 OpenCode、Cline、Continue、自己的腳本或內部 Agent。&lt;/p&gt;
&lt;p&gt;短板也很明顯：如果同時要求模型強、速度快、額度足，很少有一個套餐能全部滿足。&lt;/p&gt;
&lt;p&gt;GLM 系列在國產模型裡能力較強，但高峰期吞吐可能不穩定，重度任務容易被速度卡住。Kimi 的能力不錯，但價格和額度規則需要持續關注，尤其要看後台額度是否透明。MiniMax 這類模型速度和額度較友好，適合日常輕任務、批次處理和不太複雜的程式輔助，但在複雜工程推理上可能略低一檔。DeepSeek 新模型如果處在活動價或優惠期，性價比會很高；活動結束後，就要重新按官方價格和套餐規則評估。&lt;/p&gt;
&lt;p&gt;所以國產方案更適合作為「模型池」使用：不同任務用不同模型，而不是押注一個模型包打天下。&lt;/p&gt;
&lt;h2 id=&#34;輕度使用者選順手的不必折騰-api&#34;&gt;輕度使用者：選順手的，不必折騰 API
&lt;/h2&gt;&lt;p&gt;如果一週只是讓 AI 改腳本、補文件、解釋報錯、寫一點小工具，不需要複雜配置。&lt;/p&gt;
&lt;p&gt;這類使用者優先選順手的產品。Cursor、Windsurf、Trae、CodeBuddy、通義靈碼、GitHub Copilot 之類都可以嘗試。重點不是追求最低單價，而是降低使用門檻：能在你常用的編輯器裡穩定工作、補全品質不錯、出錯時容易回退，就已經足夠。&lt;/p&gt;
&lt;p&gt;輕度使用者不建議為了省一點錢去折騰多層 API、中轉站和複雜代理。時間成本、帳號風險和排錯成本，往往高於省下來的訂閱費。&lt;/p&gt;
&lt;h2 id=&#34;中度使用者看性價比也看可遷移性&#34;&gt;中度使用者：看性價比，也看可遷移性
&lt;/h2&gt;&lt;p&gt;如果每天都會用 AI 寫程式、改專案、生成測試、整理文件，就要開始關注額度和實際消耗。&lt;/p&gt;
&lt;p&gt;這類使用者可以把主力工具和備用模型分開安排。例如一個順手的 IDE 套餐負責日常編輯，再配一個可接入多工具的 API 或聚合套餐，處理更長上下文、更複雜的 Agent 任務。&lt;/p&gt;
&lt;p&gt;選擇時可以重點看三點：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;是否支援接入第三方工具。&lt;/li&gt;
&lt;li&gt;是否能清楚看到 token 或額度消耗。&lt;/li&gt;
&lt;li&gt;超額後是限速、降級、停止服務，還是按量付費。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果一個套餐看起來便宜，但只允許在自家工具裡使用，就要把遷移成本算進去。如果一個套餐貴一點，但能接入多種工具，反而可能更適合作為長期主力。&lt;/p&gt;
&lt;h2 id=&#34;重度使用者不要把模型和工具綁死&#34;&gt;重度使用者：不要把模型和工具綁死
&lt;/h2&gt;&lt;p&gt;重度使用者的核心訴求是靈活性。&lt;/p&gt;
&lt;p&gt;當一個人或團隊每天大量使用 AI Agent，消耗會非常快。複雜程式庫檢索、長上下文修改、多輪調試、自動化測試修復，都會讓 token 消耗成倍增長。此時再依賴單一套餐，很容易遇到三個問題：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;額度突然不夠。&lt;/li&gt;
&lt;li&gt;計費規則突然改變。&lt;/li&gt;
&lt;li&gt;某個工具或模型臨時不可用。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;更穩妥的做法是準備多層組合：一個主力 Agent 工具，一個或多個可替換模型介面，一個低成本模型處理簡單任務，一個高能力模型處理複雜任務。日常小任務不要都交給最貴模型，關鍵任務也不要只依賴最便宜模型。&lt;/p&gt;
&lt;p&gt;對重度使用者來說，「工具能接任意模型，模型能接入任意工具」比單月便宜幾十美元更重要。因為真正貴的不是訂閱費，而是工作流被某個生態綁死後，遷移和重建習慣的成本。&lt;/p&gt;
&lt;h2 id=&#34;一個更穩的組合思路&#34;&gt;一個更穩的組合思路
&lt;/h2&gt;&lt;p&gt;比較穩妥的組合可以這樣安排：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;輕任務用低成本模型：解釋程式、寫小腳本、改格式、生成簡單文件。&lt;/li&gt;
&lt;li&gt;中等任務用性價比模型：常規功能開發、測試補全、重構建議。&lt;/li&gt;
&lt;li&gt;難任務用強模型：複雜架構調整、跨檔案修復、疑難 bug、長上下文推理。&lt;/li&gt;
&lt;li&gt;工具層保持開放：盡量選擇能接 API、能匯出設定、能切換模型的工具。&lt;/li&gt;
&lt;li&gt;保留備用方案：主力套餐改規則時，可以快速切到另一個模型或工具。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這樣不一定最省錢，但更抗波動。AI Coding 套餐的價格和額度還會繼續變化，真正值得長期投入的是可遷移的工作流，而不是某個短期看起來特別划算的套餐。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;AI Coding 套餐不適合只看單月價格。輕度使用者應該少折騰，選一個順手的工具；中度使用者要開始看額度、消耗和可遷移性；重度使用者則要把模型和工具解耦，避免被單一生態綁定。&lt;/p&gt;
&lt;p&gt;現在最值得記住的一點是：套餐會變，模型會變，工具也會變。把選擇權留在自己手裡，才是長期使用 AI Coding 工具時最重要的成本控制。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>從 PPT 到原型設計：歸藏 PPT Skill 與 Huashu Design 使用場景解析</title>
        <link>https://knightli.com/zh-tw/2026/05/09/guizang-ppt-skill-huashu-design-agent-skills/</link>
        <pubDate>Sat, 09 May 2026 08:34:23 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/09/guizang-ppt-skill-huashu-design-agent-skills/</guid>
        <description>&lt;p&gt;最近兩個中文開發者做的設計類 Agent Skill 很值得放在一起看：一個是歸藏的 &lt;a class=&#34;link&#34; href=&#34;https://github.com/op7418/guizang-ppt-skill&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;guizang-ppt-skill&lt;/a&gt;，另一個是花叔的 &lt;a class=&#34;link&#34; href=&#34;https://github.com/alchaincyf/huashu-design&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;huashu-design&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;它們都不是傳統意義上的「設計工具」，而是把一套設計流程、審美偏好、檢查清單和工程模板寫成 Agent 可以執行的 Skill。你不是打開一個 UI 慢慢拖元素，而是把需求交給 Claude Code、Codex、Cursor 這類 Agent，讓它按固定流程生成 HTML、PPT、動畫或原型。&lt;/p&gt;
&lt;p&gt;這類專案的價值，不在於讓 AI 隨機發揮，而在於把「怎麼做才不難看」這件事流程化。&lt;/p&gt;
&lt;h2 id=&#34;guizang-ppt-skill專注雜誌風網頁-ppt&#34;&gt;guizang-ppt-skill：專注雜誌風網頁 PPT
&lt;/h2&gt;&lt;p&gt;歸藏的 &lt;code&gt;guizang-ppt-skill&lt;/code&gt; 定位很清楚：生成單檔 HTML 橫向翻頁 PPT，視覺基調是「電子雜誌 x 電子墨水」。它更像一套為演講準備的版式系統，而不是通用設計框架。&lt;/p&gt;
&lt;p&gt;倉庫 README 裡列出的核心能力包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;單檔 HTML 輸出，不需要建置和伺服器，瀏覽器直接打開。&lt;/li&gt;
&lt;li&gt;橫向左右翻頁，支援鍵盤、滾輪、觸控滑動、底部圓點和 ESC 索引。&lt;/li&gt;
&lt;li&gt;5 套主題色預設，包括墨水經典、靛藍瓷、森林墨、牛皮紙和沙丘。&lt;/li&gt;
&lt;li&gt;10 種頁面版面，包括開場封面、章節幕封、資料大字報、左文右圖、圖片網格、Pipeline、懸念問題、大引用、Before/After 對比和圖文混排。&lt;/li&gt;
&lt;li&gt;內建模板、元件說明、版面骨架、主題設定和品質檢查清單。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它適合做線下分享、產業內部講話、私享會、AI 產品發表、demo day，以及帶有強烈個人風格的演講稿。不太適合大段表格資料、培訓課件和多人協作編輯。&lt;/p&gt;
&lt;p&gt;這個專案有一個很好的取捨：它沒有試圖覆蓋所有設計場景，而是把「雜誌風 PPT」這個場景做窄。主題色只能從預設裡選，版面也有明確骨架，這反而降低了 Agent 跑偏的機率。&lt;/p&gt;
&lt;p&gt;如果你經常要把觀點、產業觀察、產品發表內容做成演講 deck，它的實用性會很高。&lt;/p&gt;
&lt;p&gt;安裝命令也很直接：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npx skills add https://github.com/op7418/guizang-ppt-skill --skill guizang-ppt-skill
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;huashu-design更完整的-html-原生設計工作流&#34;&gt;huashu-design：更完整的 HTML 原生設計工作流
&lt;/h2&gt;&lt;p&gt;花叔的 &lt;code&gt;huashu-design&lt;/code&gt; 覆蓋面更大。它的目標不是只做 PPT，而是把 HTML 當成原生設計畫布，用 Agent 生成可交付的設計資產。&lt;/p&gt;
&lt;p&gt;倉庫 README 裡列出的能力包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可點擊 App 或 Web 原型。&lt;/li&gt;
&lt;li&gt;HTML 投影片，以及可編輯 PPTX 匯出。&lt;/li&gt;
&lt;li&gt;產品發表動畫、MP4、GIF 和配樂版本。&lt;/li&gt;
&lt;li&gt;多方向設計方案並排對比。&lt;/li&gt;
&lt;li&gt;資訊圖、資料視覺化、PDF、PNG、SVG 匯出。&lt;/li&gt;
&lt;li&gt;5 維專家評審，包括哲學一致性、視覺層級、執行工藝、功能性和創新性。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它的核心思路是：讓 Agent 先理解品牌和素材，再產出高保真設計。專案裡強調了 Core Asset Protocol，也就是遇到具體品牌時，要先確認 logo、產品圖、UI 截圖、配色、字體和品牌指南，而不是憑記憶猜。&lt;/p&gt;
&lt;p&gt;這點很重要。很多 AI 生成設計看起來「像設計」，但不像某個真實產品或品牌。&lt;code&gt;huashu-design&lt;/code&gt; 試圖把這個問題前置解決：先找真實資產，再做設計。&lt;/p&gt;
&lt;p&gt;安裝命令是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npx skills add alchaincyf/huashu-design
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;它更適合那些希望在終端裡完成較完整設計交付的人：產品原型、發表動畫、簡報、資訊圖、設計評審都可以放在一個 Agent 工作流裡處理。&lt;/p&gt;
&lt;h2 id=&#34;兩者最大的區別&#34;&gt;兩者最大的區別
&lt;/h2&gt;&lt;p&gt;簡單說，&lt;code&gt;guizang-ppt-skill&lt;/code&gt; 是一個更窄、更穩的演講 deck 生成器；&lt;code&gt;huashu-design&lt;/code&gt; 是一個更寬、更完整的 HTML 原生設計系統。&lt;/p&gt;
&lt;p&gt;如果只看 PPT：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;guizang-ppt-skill&lt;/code&gt; 更強調雜誌感、節奏、版式和單檔瀏覽器演示。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;huashu-design&lt;/code&gt; 更強調通用設計能力、可編輯 PPTX、品牌素材、匯出鏈路和評審流程。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果看整體設計能力：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;guizang-ppt-skill&lt;/code&gt; 的邊界更清晰，適合快速做一份有風格的橫向演講。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;huashu-design&lt;/code&gt; 的能力更綜合，適合把一個產品或品牌設計任務拆成原型、動畫、投影片和資訊圖。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這兩個專案也代表了兩種不同的 Skill 寫法。前者像一套高度收斂的模板和審美約束，後者像一個小型設計團隊的工作流說明書。&lt;/p&gt;
&lt;h2 id=&#34;為什麼這類-skill-重要&#34;&gt;為什麼這類 Skill 重要
&lt;/h2&gt;&lt;p&gt;Agent 的一個常見問題是「會做，但不穩定」。同樣一句需求，有時輸出很好，有時就會滑向紫色漸層、圓角卡片、假圖標和一堆看似高級的空話。&lt;/p&gt;
&lt;p&gt;Skill 的意義就是把穩定性補上。它把下面這些東西固化下來：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可複用的模板。&lt;/li&gt;
&lt;li&gt;可執行的檢查清單。&lt;/li&gt;
&lt;li&gt;明確的審美偏好。&lt;/li&gt;
&lt;li&gt;常見錯誤的規避規則。&lt;/li&gt;
&lt;li&gt;輸出格式和驗證流程。&lt;/li&gt;
&lt;li&gt;什麼時候該問問題，什麼時候該直接開始做。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這比單純寫一句「請做得高級一點」可靠得多。&lt;/p&gt;
&lt;p&gt;尤其是設計任務，審美並不是一句 prompt 就能穩定復現的。真正有用的是流程：先確認素材，再定方向，再搭結構，再做視覺，再檢查輸出。把這個流程寫成 Skill，Agent 才更像一個可協作的執行者，而不是一次性圖片生成器。&lt;/p&gt;
&lt;h2 id=&#34;使用建議&#34;&gt;使用建議
&lt;/h2&gt;&lt;p&gt;如果你只是想把一個主題做成線下演講或分享 deck，可以優先試 &lt;code&gt;guizang-ppt-skill&lt;/code&gt;。它的輸出邊界窄，單檔 HTML 也方便分發和預覽。&lt;/p&gt;
&lt;p&gt;如果你想讓 Agent 承擔更完整的設計任務，比如 App 原型、發表動畫、品牌化投影片、可匯出 PPTX 或資訊圖，可以優先看 &lt;code&gt;huashu-design&lt;/code&gt;。它的鏈路更長，適合需要多輪迭代和交付物匯出的任務。&lt;/p&gt;
&lt;p&gt;如果你已經在寫自己的 Codex 或 Claude Code Skill，這兩個專案也都值得參考：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;想學「如何把一個窄場景做穩」，看 &lt;code&gt;guizang-ppt-skill&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;想學「如何把複雜工作流拆成可執行協議」，看 &lt;code&gt;huashu-design&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;總結&#34;&gt;總結
&lt;/h2&gt;&lt;p&gt;歸藏和花叔這兩個專案的共同點，是都把「設計能力」從一次 prompt 變成了可重複執行的流程。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;guizang-ppt-skill&lt;/code&gt; 的重點是雜誌風 HTML PPT，適合高風格化演講；&lt;code&gt;huashu-design&lt;/code&gt; 的重點是 HTML 原生設計系統，覆蓋原型、動畫、投影片、資訊圖和評審。它們解決的不是「AI 能不能生成設計」，而是「AI 能不能按一套穩定方法生成可交付的設計」。&lt;/p&gt;
&lt;p&gt;這可能會成為 Agent 工具生態裡很重要的一類開源專案：不只是程式碼模板，而是把人的經驗、審美和工作方法打包成 Skill。&lt;/p&gt;
&lt;p&gt;參考連結：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/op7418/guizang-ppt-skill&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;op7418/guizang-ppt-skill&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/alchaincyf/huashu-design&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;alchaincyf/huashu-design&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Codex vs Claude Code：兩套 Subagent 機制怎麼選</title>
        <link>https://knightli.com/zh-tw/2026/05/08/codex-vs-claude-code-subagent-design/</link>
        <pubDate>Fri, 08 May 2026 14:14:01 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/08/codex-vs-claude-code-subagent-design/</guid>
        <description>&lt;p&gt;現在的 AI 編程工具越來越重視 Subagent。這不是功能跟風，而是單個 Agent 處理真實工程任務時，很快會碰到邊界。&lt;/p&gt;
&lt;p&gt;如果一個 Agent 同時負責讀程式碼、查日誌、改實作、跑測試、分析錯誤、總結結果，主上下文很快會變髒。搜尋結果、命令輸出、測試日誌和中間推理混在一起，後續判斷就會被噪音干擾。任務也很難並行：探索、實作、驗證和審查都塞在同一條主線上。&lt;/p&gt;
&lt;p&gt;Subagent 的本質，是替 Agent 減壓。主會話不再從頭到尾做完所有事，而是更像協調者：判斷目標、安排任務、接收結果，再把結果合成最終答案。子 Agent 處理某一段局部工作，例如探索、實作、驗證或審查，最後只帶回壓縮後的結論。&lt;/p&gt;
&lt;p&gt;所以 Subagent 不是「再開一個同款自己」，而是把原本糊成一團的工程工作拆成邊界更清楚的角色。&lt;/p&gt;
&lt;h2 id=&#34;底層共識&#34;&gt;底層共識
&lt;/h2&gt;&lt;p&gt;成熟的 Subagent 系統通常繞不開四件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;上下文隔離。&lt;/li&gt;
&lt;li&gt;角色專用化。&lt;/li&gt;
&lt;li&gt;專案和使用者級配置。&lt;/li&gt;
&lt;li&gt;工具與權限邊界。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上下文隔離是前提。真實倉庫裡的中間結果很多：搜尋結果、測試日誌、命令輸出都可能很吵。如果全部塞進主會話，主線很快會混亂。Subagent 的價值之一，就是讓局部過程先在局部被消化，主會話只看到有決策價值的結論。&lt;/p&gt;
&lt;p&gt;角色專用化也很重要。多 Agent 不是多開幾個一樣的模型。探索型角色要擅長搜尋、閱讀和總結；實作型角色要專注改碼；驗證型角色要跑檢查、識別風險，並清楚回報。&lt;/p&gt;
&lt;p&gt;工具和權限邊界決定系統能否安全落地。子 Agent 不應預設擁有主會話的全部能力。探索角色未必需要寫檔案，驗證角色未必需要改實作，背景任務和 worktree 隔離也應保持可見。&lt;/p&gt;
&lt;p&gt;在這些共識之上，Codex 和 Claude Code 走出了不同路線。&lt;/p&gt;
&lt;h2 id=&#34;codex顯式派工&#34;&gt;Codex：顯式派工
&lt;/h2&gt;&lt;p&gt;Codex 的 Subagent 設計更克制。&lt;/p&gt;
&lt;p&gt;它提供一套受控、輕量、圍繞當前主會話展開的分工機制。什麼時候派活、派給誰、什麼時候收結果，都由主會話明確決定。控制流始終留在當前任務裡。&lt;/p&gt;
&lt;p&gt;它的特點是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主會話明確發起委託。&lt;/li&gt;
&lt;li&gt;角色集保持輕量。&lt;/li&gt;
&lt;li&gt;主會話知道哪個 Agent 在做什麼。&lt;/li&gt;
&lt;li&gt;結果回到主線後再統一判斷。&lt;/li&gt;
&lt;li&gt;協作邊界透明。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這種方式適合重視手動編排、可預期性和執行確定性的團隊。可以先派探索角色查清調用鏈，再派工作角色做小範圍修改，最後由主會話整合結果並決定是否繼續測試。&lt;/p&gt;
&lt;p&gt;缺點是編排壓力仍在主會話身上。主會話要判斷何時拆分、怎麼拆、交給誰、怎麼合併結果。輕量協作很舒服，但長期複雜工程流可能會變累。&lt;/p&gt;
&lt;h2 id=&#34;claude-code正式工位&#34;&gt;Claude Code：正式工位
&lt;/h2&gt;&lt;p&gt;Claude Code 的取向更平台化。&lt;/p&gt;
&lt;p&gt;它不是只提供幾個臨時幫手，而是把 Agent 做成可描述、可選擇、可配置、可記憶、可隔離、可背景執行的正式物件。子 Agent 不只是會話裡的工具，更像工程系統裡的一個工位。&lt;/p&gt;
&lt;p&gt;系統可以把 Agent 列表、適用場景、描述資訊和工具邊界交給模型，讓模型判斷本輪該呼叫哪個角色。這類模型驅動的委託帶來更強自動化。&lt;/p&gt;
&lt;p&gt;它的關鍵能力包括：&lt;/p&gt;
&lt;p&gt;第一，角色體系。探索、規劃、通用處理、驗證等角色可以帶用途說明、工具限制、預設模型和執行條件。探索型角色可以只讀，規劃型角色負責方案，驗證型角色專注檢查。&lt;/p&gt;
&lt;p&gt;第二，繼承和覆蓋。子 Agent 預設繼承主會話的大邊界，但可在規則允許範圍內做局部調整。主會話定義大邊界，Agent 在邊界內局部裝配。&lt;/p&gt;
&lt;p&gt;第三，記憶。記憶可以有作用域：使用者級記憶像長期偏好，專案級記憶像倉庫背景，本地級記憶像當前環境狀態。某些 Agent 不必每次從零理解專案。&lt;/p&gt;
&lt;p&gt;第四，背景和 worktree 隔離。某些驗證任務可以在背景持續執行，主線不用原地等待。需要強隔離時，Agent 可進入獨立 worktree，同一專案內操作空間被明確隔開。&lt;/p&gt;
&lt;p&gt;第五，插件生態。當 Agent 是正式物件時，就需要考慮分發、安裝、覆蓋、排序和安全。插件 Agent 可以進入系統，但高風險欄位如 permission mode、hooks、MCP servers 應被收口。&lt;/p&gt;
&lt;p&gt;這讓 Claude Code 更像 Agent runtime，而不是單次會話裡的協作工具。&lt;/p&gt;
&lt;h2 id=&#34;怎麼選&#34;&gt;怎麼選
&lt;/h2&gt;&lt;p&gt;Codex 更像受控分工工具：顯式派工、角色輕量、控制流清晰、子任務圍繞當前會話，適合強調確定性和人工編排的工作方式。&lt;/p&gt;
&lt;p&gt;Claude Code 更像工程工位系統：Agent 被正式建模，角色更體系化，記憶、背景執行、隔離和插件都屬於 runtime，適合長期專案和平台化工作流。&lt;/p&gt;
&lt;p&gt;真正的問題不是誰功能更多，而是你希望 Subagent 是「我明確叫來的助手」，還是「系統裡長期存在的工位」。&lt;/p&gt;
&lt;p&gt;可以問兩個問題：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;你能不能接受模型自己選擇該派誰幹活？&lt;/li&gt;
&lt;li&gt;你是否需要更完整的 Agent runtime？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果第一個問題讓你不舒服，顯式派工更合適。若第二個答案是肯定的，平台化工位系統更值得考慮。&lt;/p&gt;
&lt;h2 id=&#34;使用建議&#34;&gt;使用建議
&lt;/h2&gt;&lt;p&gt;不要把 Subagent 當作「多開幾個模型就更強」。更有效的做法是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;給每個角色明確任務邊界。&lt;/li&gt;
&lt;li&gt;控制每個角色可用工具。&lt;/li&gt;
&lt;li&gt;讓子 Agent 回傳結論，而不是原始日誌。&lt;/li&gt;
&lt;li&gt;主會話保留最終決策權。&lt;/li&gt;
&lt;li&gt;讓背景任務和 worktree 隔離保持可見。&lt;/li&gt;
&lt;li&gt;對插件 Agent 設定清楚安全邊界。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Subagent 的價值不在數量，而在分工品質。角色越清楚，上下文越乾淨，主線判斷越穩。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;Codex 和 Claude Code 都在解決同一個問題：單個 Agent 很難承載真實工程任務。它們都承認上下文隔離、角色專用、權限邊界和局部匯總的重要性。&lt;/p&gt;
&lt;p&gt;差異在於取向。Codex 更克制，強調顯式派工和主會話控制；Claude Code 更體系化，把 Agent 做成可配置、可記憶、可隔離、可背景執行、可進入插件生態的正式工位。&lt;/p&gt;
&lt;p&gt;選哪個，不是看哪個品牌贏，而是看你的工作方式需要受控協作工具，還是完整 Agent runtime。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>9Router：把 Claude Code、Codex、Cursor 接到同一個 AI 路由器</title>
        <link>https://knightli.com/zh-tw/2026/05/08/9router-ai-coding-router-token-saver/</link>
        <pubDate>Fri, 08 May 2026 13:41:15 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/08/9router-ai-coding-router-token-saver/</guid>
        <description>&lt;p&gt;9Router 是一個面向 AI 編程工具的本地路由器。它把 Claude Code、Codex、Cursor、Cline、Copilot、OpenCode、OpenClaw 等工具統一接到一個 OpenAI-compatible endpoint，再由 9Router 轉發到不同模型和服務商。&lt;/p&gt;
&lt;p&gt;它不是另一個聊天客戶端，而是放在 AI 編程工具與模型服務之間，處理 API 格式、provider 切換、工具輸出耗 token、限流中斷、多帳號管理等問題。&lt;/p&gt;
&lt;p&gt;根據專案說明，9Router 支援 40+ provider 和 100+ 模型，提供 RTK Token Saver、自動 fallback、額度追蹤、多帳號輪詢、格式轉換與請求日誌。專案使用 JavaScript 編寫，技術棧包括 Node.js、Next.js、React、Tailwind CSS 和 LowDB，授權為 MIT。&lt;/p&gt;
&lt;h2 id=&#34;適合解決什麼問題&#34;&gt;適合解決什麼問題
&lt;/h2&gt;&lt;p&gt;9Router 最適合你同時使用多個 AI 編程工具和多個模型來源的情況。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Claude Code 使用訂閱帳號。&lt;/li&gt;
&lt;li&gt;Codex 或 Cursor 需要自訂 OpenAI endpoint。&lt;/li&gt;
&lt;li&gt;Cline、Continue、RooCode 需要 OpenAI-compatible API。&lt;/li&gt;
&lt;li&gt;免費 provider 用來日常嘗試。&lt;/li&gt;
&lt;li&gt;GLM、MiniMax、Kimi 等便宜 API 作為備用。&lt;/li&gt;
&lt;li&gt;高品質模型只在複雜任務時使用。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;沒有 9Router 時，這些配置會分散在不同工具裡。9Router 的思路是讓工具都訪問同一個本地地址，再在路由器中配置 provider、combo 和優先級。&lt;/p&gt;
&lt;p&gt;預設本地地址：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;http://localhost:20128/v1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Dashboard：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;http://localhost:20128/dashboard
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;快速安裝&#34;&gt;快速安裝
&lt;/h2&gt;&lt;p&gt;本機使用可以直接透過 npm：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install -g 9router
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;9router
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;從原始碼執行：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git clone https://github.com/decolua/9router.git
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; 9router
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cp .env.example .env
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PORT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;20128&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;NEXT_PUBLIC_BASE_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;http://localhost:20128 npm run dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;生產模式：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm run build
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PORT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;20128&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;HOSTNAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0.0.0.0 &lt;span class=&#34;nv&#34;&gt;NEXT_PUBLIC_BASE_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;http://localhost:20128 npm run start
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;npm 包要求 Node.js &lt;code&gt;&amp;gt;=18.0.0&lt;/code&gt;。部署到 VPS 或 Docker 時，建議配置 &lt;code&gt;JWT_SECRET&lt;/code&gt;、&lt;code&gt;INITIAL_PASSWORD&lt;/code&gt;、&lt;code&gt;DATA_DIR&lt;/code&gt;、&lt;code&gt;API_KEY_SECRET&lt;/code&gt; 等環境變數。&lt;/p&gt;
&lt;h2 id=&#34;接入-ai-編程工具&#34;&gt;接入 AI 編程工具
&lt;/h2&gt;&lt;p&gt;常見配置如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Base URL: http://localhost:20128/v1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;API Key: 從 9Router Dashboard 複製
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Model: 在 9Router 中配置的模型名或 combo 名
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Codex CLI：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;OPENAI_BASE_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http://localhost:20128&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;your-9router-api-key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;codex &lt;span class=&#34;s2&#34;&gt;&amp;#34;your prompt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Cline、Continue、RooCode 可選 &lt;code&gt;OpenAI Compatible&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Base URL: http://localhost:20128/v1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;API Key: your-9router-api-key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Model: cc/claude-opus-4-7
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;模型名前綴取決於已連接的 provider，例如 &lt;code&gt;cc/&lt;/code&gt;、&lt;code&gt;cx/&lt;/code&gt;、&lt;code&gt;gh/&lt;/code&gt;、&lt;code&gt;glm/&lt;/code&gt;、&lt;code&gt;minimax/&lt;/code&gt;、&lt;code&gt;kr/&lt;/code&gt;、&lt;code&gt;vertex/&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;rtk-token-saver&#34;&gt;RTK Token Saver
&lt;/h2&gt;&lt;p&gt;AI 編程工具最耗 token 的地方常常是工具輸出，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git diff&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;find&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tree&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;日誌&lt;/li&gt;
&lt;li&gt;大段檔案列表&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;9Router 內建 RTK Token Saver，會在請求送到模型前壓縮這類內容。專案說明稱很多請求可節省 20%-40% input tokens。&lt;/p&gt;
&lt;p&gt;這個功能不要求更換模型，也不改變上層工具使用方式。不過遇到關鍵日誌、完整檔案內容或高風險任務時，仍建議先測試壓縮後的回答品質。&lt;/p&gt;
&lt;h2 id=&#34;自動-fallback&#34;&gt;自動 fallback
&lt;/h2&gt;&lt;p&gt;9Router 可以按優先級組合模型：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1. 訂閱模型
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2. 便宜 API
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;3. 免費 provider
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;當第一層額度用完、限流或出錯時，自動切到下一層。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1. cc/claude-opus-4-7
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2. glm/glm-5.1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;3. kr/claude-sonnet-4.5
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;fallback 會影響輸出一致性。大型重構、協議實作、資料庫遷移等任務，最好固定主模型，失敗時再手動切換。&lt;/p&gt;
&lt;h2 id=&#34;免費-provider-要謹慎&#34;&gt;免費 provider 要謹慎
&lt;/h2&gt;&lt;p&gt;README 提到 Kiro、OpenCode Free、Vertex 等免費路徑，也提醒部分舊免費層已變化或不再推薦。使用前要確認服務條款、區域限制、第三方工具接入政策、封號風險與額度期限。&lt;/p&gt;
&lt;p&gt;9Router 管理的是路由，不會改變上游 provider 的規則。&lt;/p&gt;
&lt;h2 id=&#34;本地與部署建議&#34;&gt;本地與部署建議
&lt;/h2&gt;&lt;p&gt;個人使用時，最簡單是只監聽 &lt;code&gt;localhost&lt;/code&gt;。如果部署到 VPS 或局域網，建議修改預設密碼、設定強 &lt;code&gt;JWT_SECRET&lt;/code&gt;、設定 &lt;code&gt;API_KEY_SECRET&lt;/code&gt;、不要把 Dashboard 裸露到公網，並對 &lt;code&gt;/v1/*&lt;/code&gt; 啟用 Bearer API key。&lt;/p&gt;
&lt;p&gt;Docker 示例：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker run -d &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --name 9router &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -p 20128:20128 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --env-file ./.env &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -v 9router-data:/app/data &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -v 9router-usage:/root/.9router &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  9router
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;先在本機跑通 provider、combo、工具接入和日誌，再決定是否遷移到伺服器。&lt;/p&gt;
&lt;h2 id=&#34;適合誰用&#34;&gt;適合誰用
&lt;/h2&gt;&lt;p&gt;9Router 適合同時使用多個 AI 編程工具、多個 provider、多個價格層，並希望統一 fallback 策略的重度使用者。如果你只用一個工具和一個模型，它可能反而增加複雜度。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;9Router 可以理解為 AI 編程工具的本地閘道。Claude Code、Codex、Cursor、Cline 等工具連到 &lt;code&gt;http://localhost:20128/v1&lt;/code&gt;，由它處理模型選擇、格式轉換、token 壓縮、額度追蹤和 fallback。&lt;/p&gt;
&lt;h2 id=&#34;參考資料&#34;&gt;參考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/decolua/9router&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;9Router GitHub 倉庫&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://9router.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;9Router 官網&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.npmjs.com/package/9router&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;9Router npm 包&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>opencode、Claude Code、Codex 有什麼區別？開源 AI 編程工具使用指南</title>
        <link>https://knightli.com/zh-tw/2026/05/08/opencode-open-source-ai-coding-agent/</link>
        <pubDate>Fri, 08 May 2026 08:33:37 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/08/opencode-open-source-ai-coding-agent/</guid>
        <description>&lt;p&gt;&lt;code&gt;opencode&lt;/code&gt; 是 anomalyco 開源的 AI Coding Agent。它的定位很直接：讓開發者在終端裡使用一個可程式化、可擴充、可接入多家模型的程式碼助手。&lt;/p&gt;
&lt;p&gt;如果把它和 &lt;code&gt;Claude Code&lt;/code&gt;、&lt;code&gt;Codex&lt;/code&gt; 放在一起看，三者解決的是同一類問題：讓 AI 進入真實程式碼庫，理解上下文，修改檔案，執行命令和測試。但它們的產品取向不一樣。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;opencode&lt;/code&gt; 更強調開源、多模型和終端 TUI；&lt;code&gt;Claude Code&lt;/code&gt; 更強調 Anthropic 模型生態和本地工程協作；&lt;code&gt;Codex&lt;/code&gt; 則是 OpenAI 的 AI coding agent，可以在終端、IDE、Codex app 和雲端任務裡使用。&lt;/p&gt;
&lt;h2 id=&#34;opencode-適合誰&#34;&gt;opencode 適合誰
&lt;/h2&gt;&lt;p&gt;opencode 更適合這幾類開發者：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;想在終端裡完成程式碼修改、專案分析和工程任務的人。&lt;/li&gt;
&lt;li&gt;希望 AI Coding Agent 不綁定單一模型提供商的人。&lt;/li&gt;
&lt;li&gt;偏好開源工具，想自己審計、擴充或二次開發的人。&lt;/li&gt;
&lt;li&gt;已經習慣 Neovim、TUI、命令列工作流的人。&lt;/li&gt;
&lt;li&gt;希望以後用桌面端、行動端或其他客戶端遠端驅動同一個編碼代理的人。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它的重點不是做一個聊天視窗，而是把 AI 編程能力放進開發者原本使用的終端和專案目錄裡。&lt;/p&gt;
&lt;h2 id=&#34;安裝方式&#34;&gt;安裝方式
&lt;/h2&gt;&lt;p&gt;官方 README 提供了多種安裝方式。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 直接安裝&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -fsSL https://opencode.ai/install &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; bash
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# npm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm i -g opencode-ai@latest
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Windows&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;scoop install opencode
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;choco install opencode
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# macOS 和 Linux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install anomalyco/tap/opencode
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install opencode
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Arch Linux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo pacman -S opencode
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;paru -S opencode-bin
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 其他方式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mise use -g opencode
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nix run nixpkgs#opencode
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;官方也提醒，安裝前最好先移除 0.1.x 之前的舊版本，避免舊版本殘留造成問題。&lt;/p&gt;
&lt;p&gt;安裝腳本會按優先級選擇安裝目錄：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;$OPENCODE_INSTALL_DIR&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$XDG_BIN_DIR&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$HOME/bin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$HOME/.opencode/bin&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果需要指定路徑，可以這樣寫：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;OPENCODE_INSTALL_DIR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/usr/local/bin curl -fsSL https://opencode.ai/install &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; bash
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;XDG_BIN_DIR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$HOME&lt;/span&gt;/.local/bin curl -fsSL https://opencode.ai/install &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; bash
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;桌面應用還在-beta&#34;&gt;桌面應用還在 Beta
&lt;/h2&gt;&lt;p&gt;除了命令列工具，opencode 也提供桌面應用，目前仍處於 Beta。可以從 GitHub Releases 或 &lt;code&gt;opencode.ai/download&lt;/code&gt; 下載。&lt;/p&gt;
&lt;p&gt;桌面端覆蓋這些平台：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;平台&lt;/th&gt;
          &lt;th&gt;檔案&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;macOS Apple Silicon&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;opencode-desktop-mac-arm64.dmg&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;macOS Intel&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;opencode-desktop-mac-x64.dmg&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Windows&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;opencode-desktop-windows-x64.exe&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Linux&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;.deb&lt;/code&gt;、&lt;code&gt;.rpm&lt;/code&gt; 或 &lt;code&gt;.AppImage&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;macOS 和 Windows 也可以透過套件管理器安裝桌面端。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# macOS&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install --cask opencode-desktop
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Windows&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;scoop bucket add extras
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;scoop install extras/opencode-desktop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;兩種內建-agent-模式&#34;&gt;兩種內建 Agent 模式
&lt;/h2&gt;&lt;p&gt;opencode 內建兩種 Agent，可以透過 &lt;code&gt;Tab&lt;/code&gt; 鍵切換。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;build&lt;/code&gt; 是預設模式，擁有完整開發權限，適合直接修改程式碼、執行命令和推進工程任務。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;plan&lt;/code&gt; 是唯讀模式，更適合分析陌生程式碼庫、理解專案結構、制定修改方案。它預設拒絕檔案編輯，並且在執行 bash 命令前會詢問。&lt;/p&gt;
&lt;p&gt;另外，opencode 還帶有一個 &lt;code&gt;general&lt;/code&gt; 子 Agent，用於複雜搜尋和多步驟任務。使用者可以在訊息中輸入 &lt;code&gt;@general&lt;/code&gt; 呼叫。&lt;/p&gt;
&lt;p&gt;這個設計比較實用：真正動手前先用 &lt;code&gt;plan&lt;/code&gt; 看清楚專案，需要改程式碼時再切到 &lt;code&gt;build&lt;/code&gt;。對於大型倉庫，讀寫權限分開能減少誤操作。&lt;/p&gt;
&lt;h2 id=&#34;codex-是什麼&#34;&gt;Codex 是什麼
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Codex&lt;/code&gt; 是 OpenAI 的 AI coding agent，用來幫助開發者寫程式碼、審查程式碼、修復 bug 和交付工程任務。&lt;/p&gt;
&lt;p&gt;和單純的程式碼補全工具不同，Codex 更接近一個可以操作程式碼庫的 Agent。它可以在本地工具裡和你結對，也可以把任務委託到雲端執行。OpenAI 官方資料裡提到，Codex 可以透過 CLI、IDE、Codex app、ChatGPT/Codex 雲端等不同入口使用。&lt;/p&gt;
&lt;p&gt;對開發者來說，Codex 的重點有幾處：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可以讀取程式碼庫、編輯檔案、執行命令和測試。&lt;/li&gt;
&lt;li&gt;支援終端、IDE、應用和雲端等多種使用介面。&lt;/li&gt;
&lt;li&gt;適合修 bug、寫功能、重構、遷移、程式碼審查和測試補齊。&lt;/li&gt;
&lt;li&gt;更偏 OpenAI 帳號、模型和 Codex 產品體系。&lt;/li&gt;
&lt;li&gt;雲端任務適合並行處理多個相對清晰的工程任務。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果 opencode 更像一個開放的終端代理框架，Codex 更像 OpenAI 提供的一整套 AI 編程工作台：本地可以結對，雲端可以委託，團隊可以把它接入更長的工程流程。&lt;/p&gt;
&lt;h2 id=&#34;三者核心區別&#34;&gt;三者核心區別
&lt;/h2&gt;&lt;p&gt;opencode、Claude Code、Codex 都是 AI 編程工具，但選擇時可以先看這幾個維度。&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;工具&lt;/th&gt;
          &lt;th&gt;核心定位&lt;/th&gt;
          &lt;th&gt;主要優勢&lt;/th&gt;
          &lt;th&gt;更適合&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;opencode&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;開源 AI Coding Agent&lt;/td&gt;
          &lt;td&gt;開源、多模型、TUI、客戶端/伺服器架構&lt;/td&gt;
          &lt;td&gt;想要開放工具鏈、可替換模型、偏終端工作流的開發者&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;Claude Code&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Anthropic 的命令列編程工具&lt;/td&gt;
          &lt;td&gt;Claude 模型體驗、程式碼理解、長上下文、工程任務協作&lt;/td&gt;
          &lt;td&gt;已經使用 Claude/Anthropic 生態，希望本地推進程式碼任務的開發者&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;Codex&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;OpenAI 的 AI coding agent&lt;/td&gt;
          &lt;td&gt;CLI、IDE、Codex app、雲端任務、多 Agent 工作流&lt;/td&gt;
          &lt;td&gt;已經使用 ChatGPT/OpenAI，希望本地結對和雲端委託並用的團隊&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;簡單說，opencode 的關鍵詞是「開源和可替換」，Claude Code 的關鍵詞是「Claude 生態和本地工程代理」，Codex 的關鍵詞是「OpenAI 生態和多入口協作」。&lt;/p&gt;
&lt;h2 id=&#34;和-claude-code-的區別&#34;&gt;和 Claude Code 的區別
&lt;/h2&gt;&lt;p&gt;opencode 的官方 FAQ 直接把 Claude Code 拿來對比。兩者能力上很接近，但差異主要在這幾處。&lt;/p&gt;
&lt;p&gt;第一，opencode 是 100% 開源專案，程式碼託管在 GitHub，並使用 MIT license。&lt;/p&gt;
&lt;p&gt;第二，opencode 不綁定單一模型提供商。它推薦 OpenCode Zen 提供的模型，但也可以搭配 Claude、OpenAI、Google 或本地模型。對開發者來說，這意味著模型成本、能力和可用性變化時，不必被某一個平台鎖住。&lt;/p&gt;
&lt;p&gt;第三，opencode 內建可選的 LSP 支援。對程式碼補全、跳轉、診斷和專案理解來說，LSP 是非常關鍵的基礎能力。&lt;/p&gt;
&lt;p&gt;第四，opencode 更強調 TUI。它由 Neovim 使用者和 terminal.shop 的建立者打造，產品重心明顯放在終端體驗上。&lt;/p&gt;
&lt;p&gt;第五，opencode 採用客戶端/伺服器架構。也就是說，opencode 可以在你的電腦上執行，未來由 TUI、桌面端、行動端或其他客戶端來控制。TUI 只是其中一種前端形態。&lt;/p&gt;
&lt;h2 id=&#34;什麼時候選-opencodeclaude-code-或-codex&#34;&gt;什麼時候選 opencode、Claude Code 或 Codex
&lt;/h2&gt;&lt;p&gt;如果你已經在使用 Claude Code 或 Codex，opencode 不一定是立刻替換它們的工具。更合理的看法是：它提供了一個開源、可替換模型、偏終端的選擇。&lt;/p&gt;
&lt;p&gt;可以優先考慮 opencode 的場景包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你希望 AI 編程工具盡量開源。&lt;/li&gt;
&lt;li&gt;你不想把工作流綁定在某個模型供應商上。&lt;/li&gt;
&lt;li&gt;你希望用同一個工具測試 Claude、OpenAI、Google 或本地模型。&lt;/li&gt;
&lt;li&gt;你喜歡 TUI，不希望主要工作流被桌面應用或網頁應用打斷。&lt;/li&gt;
&lt;li&gt;你關注客戶端/伺服器架構帶來的遠端控制能力。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以優先考慮 Claude Code 的場景包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你主要使用 Claude 模型。&lt;/li&gt;
&lt;li&gt;你重視長上下文、程式碼理解和複雜工程任務協作。&lt;/li&gt;
&lt;li&gt;你希望在本地倉庫中持續推進修改、測試和重構。&lt;/li&gt;
&lt;li&gt;你更信任 Anthropic 對 Claude Code 的預設產品體驗。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以優先考慮 Codex 的場景包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你已經在使用 ChatGPT 或 OpenAI 帳號體系。&lt;/li&gt;
&lt;li&gt;你希望同一個 coding agent 覆蓋終端、IDE、桌面應用和雲端任務。&lt;/li&gt;
&lt;li&gt;你想把較清晰的 bug 修復、功能開發、遷移、測試補齊交給雲端並行處理。&lt;/li&gt;
&lt;li&gt;你需要程式碼審查、背景任務、團隊協作和多 Agent 工作流。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你更看重官方閉環體驗、模型預設配置、企業管理和現成整合，Claude Code 或 Codex 可能更省心；如果你更看重可控性、開放性和 provider-agnostic，opencode 更值得關注。&lt;/p&gt;
&lt;h2 id=&#34;需要注意的地方&#34;&gt;需要注意的地方
&lt;/h2&gt;&lt;p&gt;opencode、Claude Code 和 Codex 都發展很快，GitHub release、安裝命令、桌面端檔名、模型可用性和方案權限都可能變化。實際安裝和選型前，最好直接查看各自官方 README、文件和發布頁面。&lt;/p&gt;
&lt;p&gt;另外，它的桌面應用仍然標註為 Beta，不適合預設當作穩定生產工具。對於日常工程任務，終端版仍然是更主要的入口。&lt;/p&gt;
&lt;p&gt;從工具趨勢看，opencode 代表的是 AI Coding Agent 的開放工具鏈方向：模型可以替換，客戶端可以替換，核心代理能力盡量開放。Codex 和 Claude Code 則更像模型公司把 coding agent 做成完整產品入口。對開發者來說，這兩條路線會長期並存。&lt;/p&gt;
&lt;h2 id=&#34;參考連結&#34;&gt;參考連結
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;opencode GitHub：&lt;a class=&#34;link&#34; href=&#34;https://github.com/anomalyco/opencode&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/anomalyco/opencode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;opencode 官網：&lt;a class=&#34;link&#34; href=&#34;https://opencode.ai&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://opencode.ai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;opencode 文件：&lt;a class=&#34;link&#34; href=&#34;https://opencode.ai/docs&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://opencode.ai/docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;opencode Releases：&lt;a class=&#34;link&#34; href=&#34;https://github.com/anomalyco/opencode/releases&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/anomalyco/opencode/releases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;OpenAI Codex：&lt;a class=&#34;link&#34; href=&#34;https://openai.com/codex/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://openai.com/codex/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Using Codex with your ChatGPT plan：&lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/11369540-codex-in-chatgpt&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://help.openai.com/en/articles/11369540-codex-in-chatgpt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;OpenAI Codex CLI Getting Started：&lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/11096431-openai-codex-ci-getting-started&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://help.openai.com/en/articles/11096431-openai-codex-ci-getting-started&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Awesome Codex Skills：給 Codex CLI 擴充技能的社群清單</title>
        <link>https://knightli.com/zh-tw/2026/05/07/awesome-codex-skills-composio/</link>
        <pubDate>Thu, 07 May 2026 20:19:15 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/07/awesome-codex-skills-composio/</guid>
        <description>&lt;p&gt;ComposioHQ 的 &lt;a class=&#34;link&#34; href=&#34;https://github.com/ComposioHQ/awesome-codex-skills&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;awesome-codex-skills&lt;/a&gt; 是一個面向 Codex CLI 的社群技能清單。它的價值不在於再寫一堆提示詞模板，而是把一類可重複的工作流程整理成可安裝、可重複使用、可維護的 Skill。&lt;/p&gt;
&lt;p&gt;如果你已經把 Codex 當成日常開發搭檔，這類倉庫的意義會很直接：把經常重複說明的規則、命令、資料入口和操作步驟沉澱下來，下次只要呼叫對應技能，Codex 就能依同一套上下文繼續工作。&lt;/p&gt;
&lt;h2 id=&#34;這個倉庫解決什麼問題&#34;&gt;這個倉庫解決什麼問題
&lt;/h2&gt;&lt;p&gt;Codex Skills 可以理解成給 Codex CLI 增加「專門工作模式」的方式。普通提示詞適合臨時說明一次需求，Skill 更適合長期重複使用。&lt;/p&gt;
&lt;p&gt;比如你經常需要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;依固定格式生成提交訊息；&lt;/li&gt;
&lt;li&gt;查閱某類 API 文件；&lt;/li&gt;
&lt;li&gt;執行特定專案的測試和部署命令；&lt;/li&gt;
&lt;li&gt;依團隊規範重寫文章、翻譯文件或整理資料；&lt;/li&gt;
&lt;li&gt;呼叫外部工具完成重複性的開發輔助任務。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些內容如果每次都重新輸入，很快就會變成負擔。Skill 的思路是把這些規則放進一個獨立目錄裡，核心通常是一份 &lt;code&gt;SKILL.md&lt;/code&gt;，必要時再配合腳本、模板、參考資料或素材檔。Codex 被觸發時會讀取這份說明，然後依照裡面定義的流程執行。&lt;/p&gt;
&lt;h2 id=&#34;和普通提示詞有什麼不同&#34;&gt;和普通提示詞有什麼不同
&lt;/h2&gt;&lt;p&gt;普通提示詞更像一次性指令，適合告訴模型「這次怎麼做」。Skill 更像一份小型操作手冊，適合告訴 Codex「以後遇到這類任務都照這個方式做」。&lt;/p&gt;
&lt;p&gt;它的優勢主要有三個：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;可重複使用&lt;/strong&gt;：常用工作流不用反覆複製貼上。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可審查&lt;/strong&gt;：技能檔案通常是本地 Markdown，可以直接打開、修改和版本管理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可擴充&lt;/strong&gt;：複雜技能可以帶腳本、模板和參考資料，不只是自然語言說明。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這也是 &lt;code&gt;awesome-codex-skills&lt;/code&gt; 這類清單的價值所在：它幫你集中發現已經寫好的技能，再依自己的工作習慣挑選、安裝和改造。&lt;/p&gt;
&lt;h2 id=&#34;如何安裝和使用&#34;&gt;如何安裝和使用
&lt;/h2&gt;&lt;p&gt;倉庫提供了安裝腳本，也支援手動安裝。典型流程是先 clone 倉庫，再執行安裝腳本：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git clone https://github.com/ComposioHQ/awesome-codex-skills.git
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; awesome-codex-skills
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python install.py
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果你只想試用少數技能，建議先看清每個技能目錄裡的 &lt;code&gt;SKILL.md&lt;/code&gt;，確認它會讀取哪些資料、執行哪些腳本、修改哪些檔案，再安裝到本地 Codex skills 目錄。&lt;/p&gt;
&lt;p&gt;安裝之後，Codex 可以在合適的任務中自動匹配技能，也可以透過明確點名的方式呼叫。對長期使用者來說，更實用的方式往往是：先安裝一個社群技能，再把裡面的說明改成自己的專案規範。&lt;/p&gt;
&lt;h2 id=&#34;適合關注哪些技能&#34;&gt;適合關注哪些技能
&lt;/h2&gt;&lt;p&gt;這類倉庫裡最值得優先看的，不一定是名字最酷的技能，而是能穩定減少重複勞動的技能。&lt;/p&gt;
&lt;p&gt;我會優先關注幾類：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;開發流程類&lt;/strong&gt;：程式碼審查、測試、提交、發布、依賴檢查。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文件處理類&lt;/strong&gt;：重寫、翻譯、摘要、結構化整理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具整合類&lt;/strong&gt;：把 Codex 和外部服務、API、命令列工具連接起來。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;專案規範類&lt;/strong&gt;：把團隊約定、目錄結構、命名規則、部署步驟寫進固定流程。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果一個技能只是把一句提示詞包裝了一下，價值有限；如果它能把「查資料、判斷、執行、驗證、輸出」串成穩定流程，就值得長期保留。&lt;/p&gt;
&lt;h2 id=&#34;使用時要注意什麼&#34;&gt;使用時要注意什麼
&lt;/h2&gt;&lt;p&gt;社群技能雖然方便，但不要把它當成黑盒直接執行。尤其是帶腳本的 Skill，安裝前最好先檢查三件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;SKILL.md&lt;/code&gt; 裡要求 Codex 做什麼；&lt;/li&gt;
&lt;li&gt;是否包含會存取網路、讀寫檔案或呼叫外部服務的腳本；&lt;/li&gt;
&lt;li&gt;預設路徑、命令和權限是否適合你的本地環境。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Skill 本質上是在擴大 Codex 的行動邊界。寫得好，它會讓 Codex 更像熟悉你專案的同事；寫得粗糙，它也可能把不適合你的規則帶進工作流。所以最理想的用法不是「裝很多」，而是「裝少數、改到順手、長期維護」。&lt;/p&gt;
&lt;h2 id=&#34;我的判斷&#34;&gt;我的判斷
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;awesome-codex-skills&lt;/code&gt; 值得收藏，尤其適合已經開始用 Codex CLI 做真實開發、文件或自動化任務的人。它不是官方能力本身，而是一個社群整理的技能入口：你可以從裡面找靈感，也可以把常用流程改造成自己的本地技能庫。&lt;/p&gt;
&lt;p&gt;對重度使用者來說，Codex Skills 的重點不是讓 AI 多記一點東西，而是讓 AI 在同類任務中少走彎路。把規則寫成 Skill，等於把一次次臨時溝通沉澱成可重複使用的工作基礎設施。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>CC Switch：一個桌面工具統一管理 Claude Code、Codex、Gemini CLI 和 OpenClaw</title>
        <link>https://knightli.com/zh-tw/2026/05/06/cc-switch-ai-cli-manager/</link>
        <pubDate>Wed, 06 May 2026 09:03:08 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/06/cc-switch-ai-cli-manager/</guid>
        <description>&lt;p&gt;&lt;code&gt;CC Switch&lt;/code&gt; 是一個面向 AI 程式設計重度使用者的桌面管理工具。它要解決的問題很直接：現在很多人同時使用 &lt;code&gt;Claude Code&lt;/code&gt;、&lt;code&gt;Codex&lt;/code&gt;、&lt;code&gt;Gemini CLI&lt;/code&gt;、&lt;code&gt;OpenCode&lt;/code&gt;、&lt;code&gt;OpenClaw&lt;/code&gt;，但每個工具都有自己的設定格式、Provider 寫法、MCP 設定和 Skills 管理方式。&lt;/p&gt;
&lt;p&gt;當你只用一個工具時，手動改設定還能忍；一旦多個工具混用，再加上官方帳號、第三方 API、中轉服務、本地模型和團隊共享設定，手動編輯 JSON、TOML、&lt;code&gt;.env&lt;/code&gt; 很快就會變成一件很煩的事。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;CC Switch&lt;/code&gt; 的定位，就是把這些分散設定收進一個跨平台桌面應用裡。&lt;/p&gt;
&lt;h2 id=&#34;它解決什麼問題&#34;&gt;它解決什麼問題
&lt;/h2&gt;&lt;p&gt;現代 AI 程式設計工具越來越像「命令列裡的開發同事」，但每個工具的生態還沒有完全統一。&lt;/p&gt;
&lt;p&gt;常見痛點包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Claude Code、Codex、Gemini CLI、OpenCode、OpenClaw 設定格式不同。&lt;/li&gt;
&lt;li&gt;切換 API Provider 時，要反覆改設定檔。&lt;/li&gt;
&lt;li&gt;MCP server 在不同工具之間重複設定。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt;、&lt;code&gt;AGENTS.md&lt;/code&gt;、&lt;code&gt;GEMINI.md&lt;/code&gt; 這類提示檔案難以統一維護。&lt;/li&gt;
&lt;li&gt;Skills 安裝、同步、備份和解除安裝缺少一個集中入口。&lt;/li&gt;
&lt;li&gt;多個帳號、多個 relay、多個模型服務切換很容易搞混。&lt;/li&gt;
&lt;li&gt;設定檔手動修改出錯後，排查成本很高。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;CC Switch&lt;/code&gt; 的思路是：不要讓使用者記住每個工具的設定細節，而是用一個統一介面管理 Provider、MCP、Prompts、Skills、Sessions 和代理。&lt;/p&gt;
&lt;h2 id=&#34;支援哪些工具&#34;&gt;支援哪些工具
&lt;/h2&gt;&lt;p&gt;README 中列出的核心支援對象包括五類：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Claude Code&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Codex&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Gemini CLI&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OpenCode&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OpenClaw&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這幾個工具本身定位相近，都是圍繞 AI 程式設計、Agent 工作流和命令列協作展開。但它們的設定體系不同，&lt;code&gt;CC Switch&lt;/code&gt; 的價值就在於把這些差異包裝起來。&lt;/p&gt;
&lt;p&gt;對經常比較不同 AI 程式設計工具的人來說，這比每次手動翻設定檔省心很多。&lt;/p&gt;
&lt;h2 id=&#34;provider-管理&#34;&gt;Provider 管理
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;CC Switch&lt;/code&gt; 的第一層能力是 Provider 管理。&lt;/p&gt;
&lt;p&gt;它內建了 50 多個 Provider 預設，README 中提到的方向包括 AWS Bedrock、NVIDIA NIM，以及各種社群 relay。使用者可以複製 API key，一鍵匯入，然後在介面中切換。&lt;/p&gt;
&lt;p&gt;實用點主要有幾個：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一鍵新增 Provider。&lt;/li&gt;
&lt;li&gt;Provider 拖曳排序。&lt;/li&gt;
&lt;li&gt;系統匣快速切換。&lt;/li&gt;
&lt;li&gt;Provider 匯入和匯出。&lt;/li&gt;
&lt;li&gt;部分通用 Provider 可同步到多個應用。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;對很多人來說，這個功能已經足夠有吸引力。因為 AI 程式設計工具的日常使用，經常不是「模型不會用」，而是「今天這個 key 用哪個工具、哪個 endpoint、哪個帳號」容易亂。&lt;/p&gt;
&lt;h2 id=&#34;本地代理與故障切換&#34;&gt;本地代理與故障切換
&lt;/h2&gt;&lt;p&gt;除了寫設定檔，&lt;code&gt;CC Switch&lt;/code&gt; 還提供本地代理模式。&lt;/p&gt;
&lt;p&gt;這個能力的重點是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;熱切換 Provider。&lt;/li&gt;
&lt;li&gt;格式轉換。&lt;/li&gt;
&lt;li&gt;自動故障轉移。&lt;/li&gt;
&lt;li&gt;熔斷器。&lt;/li&gt;
&lt;li&gt;Provider 健康檢查。&lt;/li&gt;
&lt;li&gt;請求修正。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;簡單說，它不只是把設定寫進目標工具，還可以在中間加一層本地代理，讓不同工具透過代理存取模型服務。&lt;/p&gt;
&lt;p&gt;這對多 Provider 使用者很有用：一個服務掛了，可以切到另一個；一個模型貴，可以換成更便宜的；某個請求格式不相容，也可以透過代理層做適配。&lt;/p&gt;
&lt;h2 id=&#34;mcpprompts-和-skills&#34;&gt;MCP、Prompts 和 Skills
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;CC Switch&lt;/code&gt; 比較重要的第二層能力，是統一管理 MCP、Prompts 和 Skills。&lt;/p&gt;
&lt;h3 id=&#34;mcp&#34;&gt;MCP
&lt;/h3&gt;&lt;p&gt;它提供統一 MCP 面板，可以在多個應用之間管理 MCP server，並支援雙向同步和 Deep Link 匯入。&lt;/p&gt;
&lt;p&gt;這對正在用 MCP 的使用者很實用。因為 MCP server 一多，設定很容易分散在不同客戶端裡。統一面板可以減少重複設定，也方便遷移。&lt;/p&gt;
&lt;h3 id=&#34;prompts&#34;&gt;Prompts
&lt;/h3&gt;&lt;p&gt;Prompts 部分支援 Markdown 編輯，並且可以在不同工具之間同步對應檔案，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AGENTS.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GEMINI.md&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些檔案本質上都是給 Agent 的專案說明書。統一管理後，可以更容易維護團隊規則、專案約定和全域提示。&lt;/p&gt;
&lt;h3 id=&#34;skills&#34;&gt;Skills
&lt;/h3&gt;&lt;p&gt;Skills 支援從 GitHub 倉庫或 ZIP 檔案一鍵安裝，也支援自訂倉庫管理、符號連結和檔案複製。&lt;/p&gt;
&lt;p&gt;如果你同時使用 Claude Code、Codex、OpenClaw 這類工具，Skills 很容易變成一堆散落在不同目錄的檔案。&lt;code&gt;CC Switch&lt;/code&gt; 把它們集中起來，能降低維護成本。&lt;/p&gt;
&lt;h2 id=&#34;會話與工作區&#34;&gt;會話與工作區
&lt;/h2&gt;&lt;p&gt;README 還提到 Session Manager 和 Workspace 相關能力。&lt;/p&gt;
&lt;p&gt;它可以瀏覽、搜尋和恢復多個應用裡的會話歷史。對長期使用 AI 程式設計工具的人來說，會話管理其實很重要：很多有價值的上下文、除錯過程、方案比較，都埋在舊對話裡。&lt;/p&gt;
&lt;p&gt;此外，它還為 OpenClaw 提供 Workspace editor，可以編輯 &lt;code&gt;AGENTS.md&lt;/code&gt;、&lt;code&gt;SOUL.md&lt;/code&gt; 等 agent 檔案，並帶 Markdown 預覽。&lt;/p&gt;
&lt;p&gt;這說明 &lt;code&gt;CC Switch&lt;/code&gt; 不只是一個「切換 key 的小工具」，而是在往 AI Agent 工作台方向擴展。&lt;/p&gt;
&lt;h2 id=&#34;雲同步與資料儲存&#34;&gt;雲同步與資料儲存
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;CC Switch&lt;/code&gt; 支援透過 Dropbox、OneDrive、iCloud、NAS 或 WebDAV 同步 Provider 資料。&lt;/p&gt;
&lt;p&gt;本地資料儲存方式也比較清楚：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;資料庫：&lt;code&gt;~/.cc-switch/cc-switch.db&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;本地設定：&lt;code&gt;~/.cc-switch/settings.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;自動備份：&lt;code&gt;~/.cc-switch/backups/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Skills：&lt;code&gt;~/.cc-switch/skills/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Skill 備份：&lt;code&gt;~/.cc-switch/skill-backups/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它使用 SQLite 作為主要資料源，並強調原子寫入和自動備份，目標是避免設定檔在切換或寫入時損壞。&lt;/p&gt;
&lt;p&gt;這個設計對重度使用者很關鍵。因為一旦設定管理工具本身把設定寫壞，影響的是所有 AI 程式設計工具。&lt;/p&gt;
&lt;h2 id=&#34;安裝方式&#34;&gt;安裝方式
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;CC Switch&lt;/code&gt; 是跨平台桌面應用，基於 Tauri 2 建構。&lt;/p&gt;
&lt;p&gt;系統要求大致如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows：Windows 10 及以上&lt;/li&gt;
&lt;li&gt;macOS：macOS 12 Monterey 及以上&lt;/li&gt;
&lt;li&gt;Linux：Ubuntu 22.04+、Debian 11+、Fedora 34+ 等主流發行版&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Windows 使用者可以下載 &lt;code&gt;.msi&lt;/code&gt; 安裝包或可攜版壓縮包。&lt;/p&gt;
&lt;p&gt;macOS 使用者可以用 Homebrew：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew tap farion1231/ccswitch
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install --cask cc-switch
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;更新：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew upgrade --cask cc-switch
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Linux 使用者可以選擇 &lt;code&gt;.deb&lt;/code&gt;、&lt;code&gt;.rpm&lt;/code&gt; 或 AppImage。Arch Linux 使用者也可以透過 &lt;code&gt;paru -S cc-switch-bin&lt;/code&gt; 安裝。&lt;/p&gt;
&lt;p&gt;截至 2026 年 5 月 6 日，倉庫頁面顯示最新 release 為 &lt;code&gt;CC Switch v3.14.1&lt;/code&gt;，發布時間是 2026 年 4 月 23 日。&lt;/p&gt;
&lt;h2 id=&#34;技術棧&#34;&gt;技術棧
&lt;/h2&gt;&lt;p&gt;從倉庫結構看，&lt;code&gt;CC Switch&lt;/code&gt; 是典型的 Tauri 桌面應用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;前端：React 18、TypeScript、Vite、TailwindCSS、TanStack Query、shadcn/ui&lt;/li&gt;
&lt;li&gt;後端：Tauri 2、Rust、SQLite、Tokio&lt;/li&gt;
&lt;li&gt;測試：Vitest、MSW、Testing Library&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;核心設計模式包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SQLite 作為 Single Source of Truth。&lt;/li&gt;
&lt;li&gt;JSON 保存裝置級本地設定。&lt;/li&gt;
&lt;li&gt;切換時寫入目標工具的 live config。&lt;/li&gt;
&lt;li&gt;編輯當前 Provider 時從 live config 回填。&lt;/li&gt;
&lt;li&gt;使用臨時檔案加 rename 的方式做原子寫入。&lt;/li&gt;
&lt;li&gt;資料庫連線加鎖，避免並發寫入問題。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這類架構說明專案並不是簡單腳本，而是按長期桌面工具來設計的。&lt;/p&gt;
&lt;h2 id=&#34;適合誰用&#34;&gt;適合誰用
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;CC Switch&lt;/code&gt; 適合下面幾類使用者：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同時使用 Claude Code、Codex、Gemini CLI、OpenCode、OpenClaw。&lt;/li&gt;
&lt;li&gt;經常切換官方帳號、第三方 relay、本地模型或團隊 Provider。&lt;/li&gt;
&lt;li&gt;已經開始大量使用 MCP。&lt;/li&gt;
&lt;li&gt;想統一維護 &lt;code&gt;CLAUDE.md&lt;/code&gt;、&lt;code&gt;AGENTS.md&lt;/code&gt;、&lt;code&gt;GEMINI.md&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;經常安裝、測試和遷移 Skills。&lt;/li&gt;
&lt;li&gt;想看不同工具的會話歷史和使用情況。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你只用一個 AI 程式設計工具，而且一直走官方登入，不怎麼折騰 Provider、MCP 和 Skills，那它的價值可能沒那麼明顯。&lt;/p&gt;
&lt;p&gt;但如果你已經進入「多工具、多帳號、多 Provider、多專案」的狀態，它能省掉很多瑣碎設定工作。&lt;/p&gt;
&lt;h2 id=&#34;需要注意什麼&#34;&gt;需要注意什麼
&lt;/h2&gt;&lt;p&gt;這類工具很方便，但也要注意邊界。&lt;/p&gt;
&lt;p&gt;第一，它會管理多個 AI CLI 的設定，因此要確認自己信任這個工具和它的寫入邏輯。&lt;/p&gt;
&lt;p&gt;第二，API key、relay endpoint、MCP server 都屬於敏感設定。開啟雲同步前，要確認同步目錄和 WebDAV 服務本身安全可靠。&lt;/p&gt;
&lt;p&gt;第三，切換 Provider 後，多數工具仍然需要重啟終端或 CLI 才能生效。README 中提到，Claude Code 對 Provider 資料支援熱切換，但其他工具通常仍需要重啟。&lt;/p&gt;
&lt;p&gt;第四，切回官方登入時，最好按專案說明新增 official provider，再重新走對應工具的登入流程。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;CC Switch&lt;/code&gt; 的價值不在於又做了一個 AI 程式設計工具，而在於它承認了一個現實：AI 程式設計生態已經進入多工具並存階段。&lt;/p&gt;
&lt;p&gt;Claude Code、Codex、Gemini CLI、OpenCode、OpenClaw 各有自己的設定系統，MCP、Skills、Prompts、Provider 又在快速擴展。繼續靠手動改設定，遲早會變成負擔。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;CC Switch&lt;/code&gt; 把這些東西收進一個桌面應用裡，讓使用者可以更輕鬆地切換 Provider、同步 MCP、管理 Skills、維護提示檔案和查看會話。對重度 AI 程式設計使用者來說，這類工具很可能會從「可選小工具」變成「日常基礎設施」。&lt;/p&gt;
&lt;h2 id=&#34;參考資料&#34;&gt;參考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/farion1231/cc-switch&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;farion1231/cc-switch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Codex App 保姆級上手：安裝、沙箱、並行任務、Skills 與 MCP</title>
        <link>https://knightli.com/zh-tw/2026/05/06/codex-app-complete-guide-skills-mcp/</link>
        <pubDate>Wed, 06 May 2026 08:41:17 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/06/codex-app-complete-guide-skills-mcp/</guid>
        <description>&lt;p&gt;Codex App 可以理解成一個面向 AI 編程的任務工作台。它不是傳統 IDE，也不是單純聊天視窗，而是把多任務、專案管理、沙箱權限、Git、雲端執行、外掛、Skills、MCP 和自動化集中到一個介面裡。&lt;/p&gt;
&lt;p&gt;如果你已經在用 Codex CLI、Claude Code、Cursor 或其他 coding agent，Codex App 最值得關注的地方，是它把「多個 agent 並行幹活」做成了更清楚的桌面工作流。&lt;/p&gt;
&lt;h2 id=&#34;codex-app-適合做什麼&#34;&gt;Codex App 適合做什麼
&lt;/h2&gt;&lt;p&gt;Codex App 的核心價值不是讓 AI 回答問題，而是讓 AI 在專案目錄裡持續執行任務：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;修改程式碼、執行命令、啟動開發服務。&lt;/li&gt;
&lt;li&gt;管理多個專案和多個任務。&lt;/li&gt;
&lt;li&gt;在本地或雲端執行長任務。&lt;/li&gt;
&lt;li&gt;呼叫外掛、Skills 和 MCP 擴展能力。&lt;/li&gt;
&lt;li&gt;透過 Git、worktree 和 PR 管理改動。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OpenAI 官方也把 Codex App 定位成一個用於管理多個 coding agent 的介面。它適合需要同時推進多個程式碼任務的人，尤其適合前端頁面、腳本工具、小型應用、文件整理和自動化工作流。&lt;/p&gt;
&lt;h2 id=&#34;安裝前準備&#34;&gt;安裝前準備
&lt;/h2&gt;&lt;p&gt;使用 Codex App 前，建議先準備好三個基礎工具：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Git&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Node.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;VS Code&lt;/code&gt; 或你常用的 IDE&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Codex App 支援 macOS 和 Windows。安裝後使用 ChatGPT 帳號登入，首次進入時可以選擇主要使用場景，例如編程或日常工作。Codex 會根據選擇預裝一部分外掛和 Skills，後續也可以在設定和外掛市場裡調整。&lt;/p&gt;
&lt;p&gt;Windows 和 macOS 的主要功能大體一致，但部分電腦自動化能力可能依賴具體平台和外掛支援，實際以你目前版本顯示為準。&lt;/p&gt;
&lt;h2 id=&#34;介面結構專案任務和對話&#34;&gt;介面結構：專案、任務和對話
&lt;/h2&gt;&lt;p&gt;Codex App 是典型的三欄布局：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;左側：專案、任務、歷史對話、外掛和自動化入口。&lt;/li&gt;
&lt;li&gt;中間：目前對話視窗。&lt;/li&gt;
&lt;li&gt;右側：檔案、瀏覽器、終端機、執行結果等多功能區域。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一個專案通常對應一個本地資料夾。你可以在同一個專案裡開多個對話，也可以同時打開多個專案，讓不同 agent 並行執行任務。&lt;/p&gt;
&lt;p&gt;任務列表會顯示不同狀態：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;正在執行：agent 仍在執行。&lt;/li&gt;
&lt;li&gt;等待批准：需要你確認權限、連網、安裝依賴或執行高風險操作。&lt;/li&gt;
&lt;li&gt;已完成：任務已經結束，可以查看結果或繼續追問。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這比在多個終端視窗裡來回切換更直觀，也更適合同時管理多個 AI 任務。&lt;/p&gt;
&lt;h2 id=&#34;沙箱與權限控制&#34;&gt;沙箱與權限控制
&lt;/h2&gt;&lt;p&gt;Codex App 的權限體系圍繞沙箱展開。預設情況下，目前專案資料夾會成為 agent 的主要工作範圍。&lt;/p&gt;
&lt;p&gt;常見權限邊界包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可以讀取和修改專案目錄內的檔案。&lt;/li&gt;
&lt;li&gt;預設不能隨意修改專案外檔案。&lt;/li&gt;
&lt;li&gt;預設會限制連網或高風險命令。&lt;/li&gt;
&lt;li&gt;需要越權時，會向使用者申請批准。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;比較實用的模式是「自動審查」：低風險操作由系統自動放行，高風險操作再交給使用者確認。這樣既能減少頻繁彈窗，又能避免 agent 在不知情的情況下執行危險操作。&lt;/p&gt;
&lt;p&gt;「完全存取」要謹慎開啟。它適合你明確知道 agent 要做什麼，並且專案已經有 Git 備份、重要檔案也有額外備份的場景。日常使用不建議長期保持完全存取。&lt;/p&gt;
&lt;h2 id=&#34;上下文模型和額度&#34;&gt;上下文、模型和額度
&lt;/h2&gt;&lt;p&gt;Codex App 會顯示目前對話的上下文使用情況。對話越長，歷史內容越多，模型需要處理的上下文也越大。&lt;/p&gt;
&lt;p&gt;實用建議是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一個任務完成後，優先開新對話。&lt;/li&gt;
&lt;li&gt;長對話可以手動壓縮，但不要把壓縮當成萬能記憶。&lt;/li&gt;
&lt;li&gt;複雜任務先寫清楚目標、邊界和驗收標準。&lt;/li&gt;
&lt;li&gt;不要把大量無關日誌、報錯和檔案一次性塞進對話。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;模型選擇上，可以根據任務複雜度調整思考強度。簡單修改、文案整理、重複任務不一定需要最高規格模型；架構遷移、疑難 bug、跨檔案重構則更適合使用更強模型。&lt;/p&gt;
&lt;p&gt;如果介面裡有快速模式，也要注意它通常會帶來更高的額度消耗。趕時間時可以開，日常不必預設開啟。&lt;/p&gt;
&lt;h2 id=&#34;圖片生成與多模態輸入&#34;&gt;圖片生成與多模態輸入
&lt;/h2&gt;&lt;p&gt;Codex App 可以接收圖片和檔案作為上下文，也可以在合適場景中呼叫圖像生成能力。&lt;/p&gt;
&lt;p&gt;這對前端和內容類專案很有用。例如你可以讓 Codex：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;根據截圖修正頁面樣式。&lt;/li&gt;
&lt;li&gt;替換網頁中的不合適配圖。&lt;/li&gt;
&lt;li&gt;生成產品圖、輪播圖或頁面素材。&lt;/li&gt;
&lt;li&gt;根據 UI 截圖指出需要修改的位置。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;更高效的用法是：不要只說「改好看一點」，而是結合截圖指出具體問題，例如「這個卡片間距太大」「這裡的圖和服務場景不匹配」「把地圖區域做得更清楚」。&lt;/p&gt;
&lt;h2 id=&#34;steer任務執行中及時糾偏&#34;&gt;Steer：任務執行中及時糾偏
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Steer&lt;/code&gt; 可以理解成「執行中接管方向」。當 agent 已經開始執行，但你發現它理解錯了方向，不應該等它全部跑完再改。&lt;/p&gt;
&lt;p&gt;這時可以使用引導功能，把新的指令插入目前執行流程，讓 Codex 及時修正路線。&lt;/p&gt;
&lt;p&gt;適合使用 Steer 的場景包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;agent 誤解了需求。&lt;/li&gt;
&lt;li&gt;生成的頁面風格明顯不對。&lt;/li&gt;
&lt;li&gt;正在執行的方案成本太高。&lt;/li&gt;
&lt;li&gt;你臨時補充了關鍵約束。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一般建議保留預設排隊行為，只在確實需要干預時手動使用 Steer。這樣既不會打亂正常任務，也能在關鍵時刻把方向拉回來。&lt;/p&gt;
&lt;h2 id=&#34;計劃模式和內建瀏覽器&#34;&gt;計劃模式和內建瀏覽器
&lt;/h2&gt;&lt;p&gt;複雜任務建議先開計劃模式。計劃模式下，Codex 不會馬上改程式碼，而是先輸出方案，必要時還會用卡片形式追問關鍵選擇。&lt;/p&gt;
&lt;p&gt;適合開計劃模式的任務：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;框架遷移，例如從普通 React 專案遷到 Next.js。&lt;/li&gt;
&lt;li&gt;大範圍重構。&lt;/li&gt;
&lt;li&gt;涉及資料庫、認證、部署的功能。&lt;/li&gt;
&lt;li&gt;你還沒想清楚技術路線的需求。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Codex App 的右側區域可以打開內建瀏覽器，用來預覽本地開發服務。你可以在頁面上做批註，讓 Codex 按具體 UI 位置修改問題。這種「看頁面、點位置、讓 AI 改」的流程，比純文字描述更適合前端除錯。&lt;/p&gt;
&lt;h2 id=&#34;gitide-和程式碼回滾&#34;&gt;Git、IDE 和程式碼回滾
&lt;/h2&gt;&lt;p&gt;Codex App 不是完整 IDE。它可以查看程式碼、批註程式碼，但真正的手寫編輯仍然更適合交給 VS Code、Cursor、Windsurf 等 IDE。&lt;/p&gt;
&lt;p&gt;建議每個 Codex 專案都盡早初始化 Git：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;讓 Codex 建立或檢查 &lt;code&gt;.gitignore&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;在完成一個可用狀態後提交一次。&lt;/li&gt;
&lt;li&gt;每次大改前確保有乾淨提交點。&lt;/li&gt;
&lt;li&gt;不滿意時用 Git 回滾程式碼。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果只回滾對話歷史，程式碼不會自動跟著回滾。比較穩的做法是：對話層面回到合適節點，程式碼層面用 Git commit hash 回到對應狀態。&lt;/p&gt;
&lt;h2 id=&#34;worktree並行開發多個方向&#34;&gt;Worktree：並行開發多個方向
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;git worktree&lt;/code&gt; 是 Codex App 裡非常適合並行 agent 的能力。&lt;/p&gt;
&lt;p&gt;它的本質是：基於同一個倉庫建立多個獨立工作目錄，每個目錄對應不同分支。這樣你可以讓不同 agent 在不同資料夾裡同時開發，不互相覆蓋。&lt;/p&gt;
&lt;p&gt;典型用法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一個 worktree 優化客戶評價元件。&lt;/li&gt;
&lt;li&gt;一個 worktree 調整門店資訊和地圖布局。&lt;/li&gt;
&lt;li&gt;兩個任務完成後分別合併回主幹。&lt;/li&gt;
&lt;li&gt;合併完成後刪除臨時 worktree。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這比在同一個目錄裡讓多個 agent 同時改程式碼穩得多。遇到衝突時，也可以按正常 Git 流程 review 和合併。&lt;/p&gt;
&lt;h2 id=&#34;雲端執行環境&#34;&gt;雲端執行環境
&lt;/h2&gt;&lt;p&gt;Codex 不只能在本機工作，也可以把任務委託到雲端環境執行。&lt;/p&gt;
&lt;p&gt;雲端執行適合這些場景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;出門在外，手邊只有手機。&lt;/li&gt;
&lt;li&gt;希望 agent 在背景跑長任務。&lt;/li&gt;
&lt;li&gt;程式碼已經同步到 GitHub，需要讓 Codex 基於遠端倉庫修改。&lt;/li&gt;
&lt;li&gt;希望透過 PR 形式審查和合併改動。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;典型流程是：先把本地程式碼推到 GitHub，再讓 Codex 在雲端環境中拉取倉庫、執行任務、生成改動，最後以 PR 或 diff 的方式交給你審核。&lt;/p&gt;
&lt;p&gt;本地繼續開發時，要記得把遠端最新改動同步回來。&lt;/p&gt;
&lt;h2 id=&#34;記憶系統寫好-agentsmd&#34;&gt;記憶系統：寫好 AGENTS.md
&lt;/h2&gt;&lt;p&gt;新對話預設沒有完整歷史記憶。專案一複雜，如果每次都重新解釋背景，會很浪費。&lt;/p&gt;
&lt;p&gt;最通用的做法，是在專案根目錄維護 &lt;code&gt;AGENTS.md&lt;/code&gt;。這個檔案可以記錄：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;專案目標和主要技術棧。&lt;/li&gt;
&lt;li&gt;常用命令。&lt;/li&gt;
&lt;li&gt;目錄結構說明。&lt;/li&gt;
&lt;li&gt;程式碼風格和命名約定。&lt;/li&gt;
&lt;li&gt;禁止事項，例如不要批量刪除檔案。&lt;/li&gt;
&lt;li&gt;測試、建置和部署規則。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你也可以讓 Codex 先通讀專案，再生成一版 &lt;code&gt;AGENTS.md&lt;/code&gt;，然後人工審一遍。複雜專案裡，這個檔案非常值得維護。&lt;/p&gt;
&lt;p&gt;全域規則也要謹慎。適合寫入所有專案都通用的安全約束，例如「不要遞迴刪除目錄」「執行破壞性操作前必須確認」。不要把某個專案的細節寫進全域規則，否則會污染其他專案。&lt;/p&gt;
&lt;h2 id=&#34;外掛和自動化&#34;&gt;外掛和自動化
&lt;/h2&gt;&lt;p&gt;外掛用於把外部服務接入 Codex，例如 GitHub、Gmail、Google Drive、資料庫、部署平台等。&lt;/p&gt;
&lt;p&gt;外掛的價值在於減少複製貼上。比如你可以讓 Codex：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查看某個 GitHub 倉庫的 star 趨勢。&lt;/li&gt;
&lt;li&gt;整理郵件內容並發給自己。&lt;/li&gt;
&lt;li&gt;定期執行某個檢查任務。&lt;/li&gt;
&lt;li&gt;把結果寫成摘要。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;自動化則適合重複任務。例如每週五下午檢查一次倉庫資料，並發送郵件報告。簡單自動化任務通常不需要最高規格模型，選擇較輕量的模型即可。&lt;/p&gt;
&lt;h2 id=&#34;skills把工作流變成可複用能力&#34;&gt;Skills：把工作流變成可複用能力
&lt;/h2&gt;&lt;p&gt;Skills 是 Codex 的「專業說明書」。它不是單次提示詞，而是把某類任務的流程、規範、腳本和注意事項沉澱下來，讓 Codex 後續穩定複用。&lt;/p&gt;
&lt;p&gt;常見來源有三類：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;官方 Skills。&lt;/li&gt;
&lt;li&gt;第三方 Skills。&lt;/li&gt;
&lt;li&gt;自己編寫的 Skills。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;適合做成 Skill 的工作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把字幕整理成圖文筆記。&lt;/li&gt;
&lt;li&gt;按公司規範寫週報。&lt;/li&gt;
&lt;li&gt;批量處理圖片或文件。&lt;/li&gt;
&lt;li&gt;固定格式的程式碼審查。&lt;/li&gt;
&lt;li&gt;特定框架的專案初始化。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果某個提示詞你已經複製貼上了很多次，就值得考慮把它做成 Skill。&lt;/p&gt;
&lt;h2 id=&#34;mcp接入外部工具和資料庫&#34;&gt;MCP：接入外部工具和資料庫
&lt;/h2&gt;&lt;p&gt;MCP 可以理解成給大模型使用的標準化工具協議。透過 MCP，Codex 可以呼叫外部服務完成更具體的任務。&lt;/p&gt;
&lt;p&gt;例如接入 Supabase 後，可以讓 Codex：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;建立資料表。&lt;/li&gt;
&lt;li&gt;讀取資料庫結構。&lt;/li&gt;
&lt;li&gt;修改後端接口。&lt;/li&gt;
&lt;li&gt;把前端表單提交到資料庫。&lt;/li&gt;
&lt;li&gt;根據資料庫狀態除錯問題。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這類能力很強，但也要注意權限邊界。資料庫、生產環境、部署平台、郵件帳號都屬於高風險資源。第一次接入時，最好使用測試專案和低權限帳號。&lt;/p&gt;
&lt;h2 id=&#34;部署外掛&#34;&gt;部署外掛
&lt;/h2&gt;&lt;p&gt;部署平台外掛可以讓 Codex 直接完成建置和發布，例如把前端專案部署到 Netlify 一類平台。&lt;/p&gt;
&lt;p&gt;這類外掛適合小型網站、原型頁面、內部工具和展示專案。實際使用時建議注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;部署前先跑本地建置。&lt;/li&gt;
&lt;li&gt;環境變數不要直接寫進程式碼。&lt;/li&gt;
&lt;li&gt;發布後檢查頁面是否能正常訪問。&lt;/li&gt;
&lt;li&gt;生產專案要保留人工 review。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AI 可以幫你打通發布流程，但發布權限仍然要謹慎管理。&lt;/p&gt;
&lt;h2 id=&#34;電腦自動化&#34;&gt;電腦自動化
&lt;/h2&gt;&lt;p&gt;在支援的平台和外掛環境裡，Codex 還可以操作瀏覽器或桌面應用，完成更接近 RPA 的任務。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;打開聊天軟體並準備一條訊息。&lt;/li&gt;
&lt;li&gt;瀏覽專案看板，彙總任務狀態。&lt;/li&gt;
&lt;li&gt;生成英文簡報。&lt;/li&gt;
&lt;li&gt;在你確認後發送給指定對象。&lt;/li&gt;
&lt;li&gt;把這套流程做成定時自動化。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這類功能很有想像力，但也最需要安全邊界。凡是涉及發訊息、發郵件、提交表單、付款、刪除資料的操作，都應該保留人工確認。&lt;/p&gt;
&lt;h2 id=&#34;使用建議&#34;&gt;使用建議
&lt;/h2&gt;&lt;p&gt;Codex App 的正確打開方式，不是讓它一次性全自動接管一切，而是把任務拆清楚，讓它在受控環境裡高效執行。&lt;/p&gt;
&lt;p&gt;推薦習慣：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每個專案先初始化 Git。&lt;/li&gt;
&lt;li&gt;複雜任務先開計劃模式。&lt;/li&gt;
&lt;li&gt;並行任務優先用 worktree。&lt;/li&gt;
&lt;li&gt;專案規則寫進 &lt;code&gt;AGENTS.md&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;高風險操作保留人工確認。&lt;/li&gt;
&lt;li&gt;重複流程沉澱成 Skill 或自動化。&lt;/li&gt;
&lt;li&gt;外掛和 MCP 先在測試環境驗證。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;參考資料&#34;&gt;參考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://openai.com/index/introducing-the-codex-app/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Introducing the Codex app - OpenAI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/11369540-codex-in-chatgpt&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Using Codex with your ChatGPT plan - OpenAI Help Center&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://openai.com/academy/codex-plugins-and-skills/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Plugins and skills - OpenAI Academy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;Codex App 的重點不是「多一個 AI 聊天視窗」，而是把 AI 編程變成一個可管理的工作台：本地專案、雲端任務、Git、worktree、外掛、Skills、MCP 和自動化都能串起來。&lt;/p&gt;
&lt;p&gt;真正用好它的關鍵，是在「放權」和「控制」之間找到平衡。小任務可以大膽交給 Codex，複雜任務先讓它計劃，高風險動作必須確認。這樣它才會從一個會寫程式碼的助手，變成可以長期協作的工程工具。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>ChatGPT 和 Codex 登入要求驗證手機號，可能是什麼原因</title>
        <link>https://knightli.com/zh-tw/2026/05/06/chatgpt-codex-phone-verification-plus/</link>
        <pubDate>Wed, 06 May 2026 00:08:45 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/06/chatgpt-codex-phone-verification-plus/</guid>
        <description>&lt;p&gt;最近有些用戶會遇到一個情況：ChatGPT 帳號已經註冊成功，但登入 ChatGPT 或 Codex 時，系統又要求驗證手機號。尤其是在使用 Codex 時，這個提示更容易讓人困惑：帳號明明能註冊，為什麼登入工具時還要補手機號？&lt;/p&gt;
&lt;p&gt;這類問題通常和帳號風控、免費額度濫用、網路環境以及帳號安全策略有關。下面把常見原因和處理思路整理一下。&lt;/p&gt;
&lt;h2 id=&#34;為什麼會要求驗證手機號&#34;&gt;為什麼會要求驗證手機號
&lt;/h2&gt;&lt;p&gt;最直接的原因是風控升級。&lt;/p&gt;
&lt;p&gt;Codex 面向用戶開放後，免費額度會吸引大量真實用戶試用，也會吸引批量註冊、批量領取額度的行為。如果有人用註冊機批量建立帳號，再用這些帳號消耗免費額度，平台就會更容易收緊驗證策略。&lt;/p&gt;
&lt;p&gt;從用戶側看到的結果就是：原本只需要信箱或第三方登入的帳號，在登入 ChatGPT 或 Codex 時，突然被要求補充手機號驗證。&lt;/p&gt;
&lt;p&gt;這不一定代表你的帳號一定有問題，也可能是觸發了更高風險的登入環境。例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用了被大量用戶共享的網路出口。&lt;/li&gt;
&lt;li&gt;當前 IP 段被頻繁用於註冊或異常登入。&lt;/li&gt;
&lt;li&gt;帳號剛註冊不久，卻馬上訪問高消耗工具。&lt;/li&gt;
&lt;li&gt;登入裝置、地區、網路頻繁變化。&lt;/li&gt;
&lt;li&gt;免費帳號使用行為和批量帳號相似。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果近期出現帳號異常、登入受限或誤封，也可能和網路環境被連帶標記有關。尤其是多人共享的節點，風險會明顯更高。&lt;/p&gt;
&lt;h2 id=&#34;codex-為什麼更容易觸發&#34;&gt;Codex 為什麼更容易觸發
&lt;/h2&gt;&lt;p&gt;Codex 和普通聊天不同，它更接近開發工具，可能涉及更高的資源消耗，也更容易被批量帳號拿來消耗免費額度。&lt;/p&gt;
&lt;p&gt;所以同一個帳號在普通 ChatGPT 頁面裡看起來正常，到了 Codex 登入流程裡卻觸發手機號驗證，並不奇怪。可以把它理解為：不同產品入口會有不同的風險判斷。&lt;/p&gt;
&lt;p&gt;對正常用戶來說，這類驗證通常不是為了為難單個用戶，而是為了限制批量註冊和免費額度濫用。但如果你的網路環境不乾淨，也會被誤傷。&lt;/p&gt;
&lt;h2 id=&#34;處理方法一升級-plus&#34;&gt;處理方法一：升級 Plus
&lt;/h2&gt;&lt;p&gt;如果你是長期使用 ChatGPT 或 Codex，最簡單的處理方式是升級 ChatGPT Plus。&lt;/p&gt;
&lt;p&gt;從實際使用體驗看，付費帳號通常比免費帳號更不容易觸發這類額度濫用風控。Plus 帳號本身也更適合穩定使用 Codex、ChatGPT 高級模型和其他高頻功能。&lt;/p&gt;
&lt;p&gt;不過要注意：升級 Plus 並不等於永遠不會再觸發驗證。如果升級後仍然要求手機號，常見原因還是網路環境問題。&lt;/p&gt;
&lt;p&gt;這時可以優先檢查：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;是否使用了大量用戶共享的網路。&lt;/li&gt;
&lt;li&gt;當前出口 IP 是否頻繁變化。&lt;/li&gt;
&lt;li&gt;是否長期使用低品質代理或公共節點。&lt;/li&gt;
&lt;li&gt;是否同一網路下有大量 OpenAI 帳號登入。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果條件允許，換一個更穩定、更乾淨的網路環境再登入，通常比反覆重試更有效。&lt;/p&gt;
&lt;h2 id=&#34;處理方法二檢查網路環境&#34;&gt;處理方法二：檢查網路環境
&lt;/h2&gt;&lt;p&gt;很多登入驗證問題，看起來像帳號問題，本質上是網路問題。&lt;/p&gt;
&lt;p&gt;如果某個出口 IP 被大量用戶共用，或者曾經被用於批量註冊、異常登入、自動化請求，就更容易被標記。此時即使你是正常用戶，也可能在登入 ChatGPT 或 Codex 時被要求額外驗證。&lt;/p&gt;
&lt;p&gt;可以從這幾個角度排查：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;換一個更穩定的網路環境。&lt;/li&gt;
&lt;li&gt;避免使用公開、廉價、多人共享的節點。&lt;/li&gt;
&lt;li&gt;儘量減少短時間內頻繁切換地區。&lt;/li&gt;
&lt;li&gt;不要在同一瀏覽器裡頻繁切換多個帳號。&lt;/li&gt;
&lt;li&gt;如果使用代理，優先選擇品質更穩定、濫用更少的線路。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;也可以借助第三方網路品質檢測工具查看當前 IP 的風險情況，但檢測結果只能作為參考，不能完全代表 OpenAI 的內部判斷。&lt;/p&gt;
&lt;h2 id=&#34;處理方法三按要求完成手機號驗證&#34;&gt;處理方法三：按要求完成手機號驗證
&lt;/h2&gt;&lt;p&gt;如果系統明確要求手機號驗證，最穩妥的方式仍然是按要求完成驗證。&lt;/p&gt;
&lt;p&gt;建議優先使用自己可長期接收驗證碼的號碼。這樣以後如果帳號出現安全驗證、恢復登入、異常提醒，也能繼續處理。&lt;/p&gt;
&lt;p&gt;不建議把重要帳號綁定到來路不明、多人共用或無法長期使用的號碼上。短期看可能能通過驗證，長期看會帶來帳號找回、安全審計和二次驗證風險。&lt;/p&gt;
&lt;p&gt;如果你使用的是工作帳號、團隊帳號或長期依賴的開發帳號，更應該避免使用不可控的臨時號碼。帳號安全比臨時省事更重要。&lt;/p&gt;
&lt;h2 id=&#34;升級-plus-時要注意什麼&#34;&gt;升級 Plus 時要注意什麼
&lt;/h2&gt;&lt;p&gt;如果你準備升級 Plus，可以先確認幾件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;帳號本身可以正常登入。&lt;/li&gt;
&lt;li&gt;當前網路環境穩定，不頻繁跳地區。&lt;/li&gt;
&lt;li&gt;支付方式可靠，不要使用來源不明的代付。&lt;/li&gt;
&lt;li&gt;升級後保留好付款記錄和帳號信箱。&lt;/li&gt;
&lt;li&gt;不要把帳號借給多人共用。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;很多帳號問題並不是出在 Plus 本身，而是出在升級前後的網路、支付和共享使用習慣上。一個帳號如果長期多人共用、頻繁異地登入、經常切換環境，即使付費也可能觸發安全驗證。&lt;/p&gt;
&lt;p&gt;如果只是偶爾試用，免費帳號也可以繼續用。但如果你已經把 Codex 當成日常開發工具，Plus 會更適合長期使用。&lt;/p&gt;
&lt;h2 id=&#34;不建議繼續薅免費額度&#34;&gt;不建議繼續薅免費額度
&lt;/h2&gt;&lt;p&gt;Codex 這類工具的免費額度本來是為了讓正常用戶體驗和試用。如果大量批量帳號持續消耗免費額度，平台最終只能繼續提高風控強度。&lt;/p&gt;
&lt;p&gt;結果就是正常用戶也會受到影響：登入更麻煩，驗證更多，封禁誤傷更多，帳號使用成本更高。&lt;/p&gt;
&lt;p&gt;對真正把 Codex 用在寫程式碼、改專案、跑工程任務的人來說，與其把時間花在規避風控上，不如把帳號和網路環境整理乾淨。長期看，這比重複註冊新帳號、切換節點、處理驗證問題更省事。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;ChatGPT 或 Codex 登入時要求驗證手機號，通常和帳號風控、免費額度濫用、網路環境風險有關。它不一定代表帳號本身違規，但說明當前登入環境或帳號狀態觸發了更高等級的驗證。&lt;/p&gt;
&lt;p&gt;處理順序可以很簡單：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先檢查網路環境，避開多人共享和高風險出口。&lt;/li&gt;
&lt;li&gt;長期使用就考慮升級 Plus。&lt;/li&gt;
&lt;li&gt;如果系統要求手機號驗證，優先使用自己可長期控制的號碼完成。&lt;/li&gt;
&lt;li&gt;避免批量註冊、共享帳號和頻繁切換登入環境。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;穩定使用 AI 工具的核心不是一直繞過驗證，而是讓帳號、網路和使用方式都儘量正常。這樣才能減少登入麻煩，也能降低後續被誤傷的機率。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>OpenAI 推出 Advanced Account Security：ChatGPT 和 Codex 帳號多了一層高強度保護</title>
        <link>https://knightli.com/zh-tw/2026/05/01/openai-advanced-account-security/</link>
        <pubDate>Fri, 01 May 2026 06:15:29 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/01/openai-advanced-account-security/</guid>
        <description>&lt;p&gt;OpenAI 在 2026 年 4 月 30 日推出了 &lt;code&gt;Advanced Account Security&lt;/code&gt;，這是面向 ChatGPT 帳號的可選進階安全設定。&lt;/p&gt;
&lt;p&gt;它主要服務兩類使用者：一類是記者、民選官員、政治異議人士、研究人員等更容易遭遇定向攻擊的人；另一類是希望給 ChatGPT 和 Codex 帳號加上更強保護的安全敏感使用者。&lt;/p&gt;
&lt;p&gt;這項功能開啟後，不只保護 ChatGPT，也會保護同一登入帳號下存取的 Codex。&lt;/p&gt;
&lt;h2 id=&#34;為什麼-chatgpt-帳號需要更高安全等級&#34;&gt;為什麼 ChatGPT 帳號需要更高安全等級
&lt;/h2&gt;&lt;p&gt;現在很多人會把 ChatGPT 用在越來越私密、越來越高風險的工作裡。&lt;/p&gt;
&lt;p&gt;一個 ChatGPT 帳號裡可能包含：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;個人問題和長期對話&lt;/li&gt;
&lt;li&gt;工作文件與專案上下文&lt;/li&gt;
&lt;li&gt;已連接工具和工作流程&lt;/li&gt;
&lt;li&gt;Codex 裡的程式碼與開發任務&lt;/li&gt;
&lt;li&gt;企業、研究或安全相關材料&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果帳號被接管，損失不只是聊天記錄外洩。攻擊者還可能存取連接的工具、查看敏感上下文，甚至干擾使用者正在進行的工作。&lt;/p&gt;
&lt;p&gt;所以 OpenAI 這次推出的不是一個普通登入選項，而是一組更嚴格的帳號保護措施。&lt;/p&gt;
&lt;h2 id=&#34;advanced-account-security-包含哪些保護&#34;&gt;Advanced Account Security 包含哪些保護
&lt;/h2&gt;&lt;p&gt;OpenAI 把這項能力放在 ChatGPT 網頁端帳號的 Security 設定裡，使用者可以主動開啟。&lt;/p&gt;
&lt;p&gt;開啟後，它會從幾個方面提高帳號安全性。&lt;/p&gt;
&lt;p&gt;第一，登入方式更強。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Advanced Account Security&lt;/code&gt; 要求使用 &lt;code&gt;passkeys&lt;/code&gt; 或實體安全金鑰，並禁用基於密碼的登入。這樣做的目的，是讓更抗釣魚的登入方式成為預設選擇。&lt;/p&gt;
&lt;p&gt;第二，帳號恢復更嚴格。&lt;/p&gt;
&lt;p&gt;傳統帳號恢復經常依賴信箱或簡訊。如果攻擊者控制了使用者的信箱或手機號碼，就可能藉此重設帳號。為降低這個風險，Advanced Account Security 會禁用郵件和 SMS 恢復，改用更強的恢復方式，例如備用 passkeys、安全金鑰和恢復金鑰。&lt;/p&gt;
&lt;p&gt;這裡有一個重要代價：開啟後，帳號恢復會更依賴使用者自己保管這些恢復方式。OpenAI 明確說明，已開啟該功能的使用者如果遺失恢復手段，OpenAI Support 無法協助恢復帳號。&lt;/p&gt;
&lt;p&gt;第三，工作階段時間更短，管理更清楚。&lt;/p&gt;
&lt;p&gt;OpenAI 會縮短登入工作階段，以降低裝置或活躍工作階段被盜用後的暴露窗口。使用者也會收到登入提醒，並可以查看和管理目前登入的裝置工作階段。&lt;/p&gt;
&lt;p&gt;第四，自動排除訓練。&lt;/p&gt;
&lt;p&gt;對處理敏感資訊的人來說，不讓對話用於模型訓練是一項重要隱私設定。開啟 Advanced Account Security 後，這個偏好會自動生效：這些帳號的對話不會用於訓練 OpenAI 模型。&lt;/p&gt;
&lt;h2 id=&#34;與-yubico-合作推廣實體安全金鑰&#34;&gt;與 Yubico 合作推廣實體安全金鑰
&lt;/h2&gt;&lt;p&gt;OpenAI 還宣布與 Yubico 合作，給使用者提供定製的安全金鑰組合。&lt;/p&gt;
&lt;p&gt;其中包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;YubiKey C Nano&lt;/code&gt;：適合長期插在筆電上，日常登入摩擦更小&lt;/li&gt;
&lt;li&gt;&lt;code&gt;YubiKey C NFC&lt;/code&gt;：適合作為備用，也方便在筆電和行動裝置之間使用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OpenAI 表示，使用者也可以使用其他符合 FIDO 標準的實體安全金鑰，或者使用軟體 passkeys。&lt;/p&gt;
&lt;p&gt;這說明 Advanced Account Security 並不綁定某一種硬體，而是圍繞抗釣魚認證方式設計。&lt;/p&gt;
&lt;h2 id=&#34;cyber-可信存取使用者會被要求開啟&#34;&gt;Cyber 可信存取使用者會被要求開啟
&lt;/h2&gt;&lt;p&gt;OpenAI 還提到，針對 &lt;code&gt;Trusted Access for Cyber&lt;/code&gt; 的個人成員，如果他們要存取更強、更寬鬆的網路安全模型，從 2026 年 6 月 1 日開始將被要求開啟 Advanced Account Security。&lt;/p&gt;
&lt;p&gt;組織使用者可以用另一種方式滿足要求：證明自己的單一登入流程已經採用抗釣魚認證。&lt;/p&gt;
&lt;p&gt;這個安排很合理。越強的模型能力越需要更強的帳號保護，尤其是面向網路安全研究、漏洞分析和紅隊等場景時，帳號本身就會成為高價值目標。&lt;/p&gt;
&lt;h2 id=&#34;適合誰開啟&#34;&gt;適合誰開啟
&lt;/h2&gt;&lt;p&gt;這項功能不一定適合所有人。&lt;/p&gt;
&lt;p&gt;如果只是普通聊天，且不想承擔更嚴格帳號恢復帶來的複雜性，可以先觀望。&lt;/p&gt;
&lt;p&gt;但以下使用者值得認真考慮：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;經常在 ChatGPT 中處理敏感工作材料的人&lt;/li&gt;
&lt;li&gt;使用 Codex 處理私有程式碼倉庫的人&lt;/li&gt;
&lt;li&gt;記者、公共事務人員、研究人員、企業高階主管等高風險使用者&lt;/li&gt;
&lt;li&gt;網路安全從業者&lt;/li&gt;
&lt;li&gt;已經習慣使用 passkeys 或實體安全金鑰的人&lt;/li&gt;
&lt;li&gt;對帳號被釣魚、簡訊劫持或信箱接管特別敏感的人&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;開啟之前，最好先準備好備用 passkey、安全金鑰和恢復金鑰，並確認它們被妥善保存。否則，安全性提高的同時，帳號恢復難度也會明顯提高。&lt;/p&gt;
&lt;h2 id=&#34;這對-ai-產品意味著什麼&#34;&gt;這對 AI 產品意味著什麼
&lt;/h2&gt;&lt;p&gt;Advanced Account Security 不是一個模型能力更新，但它反映了 AI 產品正在進入更高風險的使用階段。&lt;/p&gt;
&lt;p&gt;當 ChatGPT 和 Codex 開始承載工作流程、程式碼、文件、企業連接器和長期上下文時，帳號就不再只是「登入聊天工具」的入口，而是 AI 工作環境的鑰匙。&lt;/p&gt;
&lt;p&gt;這類產品越像個人工作台，帳號安全、恢復機制、工作階段管理和訓練資料控制就越重要。&lt;/p&gt;
&lt;p&gt;OpenAI 這次把 passkeys、實體安全金鑰、恢復限制、工作階段管理和訓練排除放到同一個設定裡，方向是對的。它讓高風險使用者可以用一個明確入口，把帳號保護提升到更適合敏感工作的級別。&lt;/p&gt;
&lt;h2 id=&#34;小結&#34;&gt;小結
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Advanced Account Security&lt;/code&gt; 可以理解為 ChatGPT 和 Codex 的高安全模式。&lt;/p&gt;
&lt;p&gt;它透過更強登入、更嚴格恢復、更短工作階段、登入提醒和自動排除訓練，降低帳號被接管後的風險。代價是使用者需要更認真地管理自己的恢復方式，因為開啟後傳統郵件和簡訊恢復不再可用，OpenAI Support 也無法替使用者兜底。&lt;/p&gt;
&lt;p&gt;如果你已經把 ChatGPT 或 Codex 用在重要工作裡，尤其是涉及私有程式碼、敏感文件或高風險身份，這項功能值得關注。&lt;/p&gt;
&lt;p&gt;參考連結：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://openai.com/index/advanced-account-security/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Introducing Advanced Account Security - OpenAI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>mattpocock/skills：給 AI 編程 Agent 準備的實用技能集合</title>
        <link>https://knightli.com/zh-tw/2026/05/01/mattpocock-skills-ai-agent-coding-workflows/</link>
        <pubDate>Fri, 01 May 2026 03:43:20 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/01/mattpocock-skills-ai-agent-coding-workflows/</guid>
        <description>&lt;p&gt;&lt;code&gt;mattpocock/skills&lt;/code&gt; 是 Matt Pocock 公開的一組 AI 編程 agent skills。&lt;/p&gt;
&lt;p&gt;它不是一個完整的應用，也不是一個新的聊天客戶端，而是一套可以給 AI 編程助手使用的工作技能。它的思路很實用：把 AI 編程裡經常出現的問題拆成一個個小技能，讓 Agent 在合適的任務裡呼叫，而不是每次都靠一大段提示詞硬撐。&lt;/p&gt;
&lt;p&gt;如果你經常使用 Claude Code、Codex、Cursor 或類似的 AI 編程工具，這類 skills 很值得關注。因為真正影響 AI 編程體驗的，往往不是「模型會不會寫程式碼」，而是它能不能按你的工作方式推進任務。&lt;/p&gt;
&lt;h2 id=&#34;它解決什麼問題&#34;&gt;它解決什麼問題
&lt;/h2&gt;&lt;p&gt;AI 編程助手很強，但也很容易出問題。&lt;/p&gt;
&lt;p&gt;常見情況包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;還沒理解需求就開始改程式碼&lt;/li&gt;
&lt;li&gt;一次性改太多檔案&lt;/li&gt;
&lt;li&gt;輸出解釋很多，真正有用的行動很少&lt;/li&gt;
&lt;li&gt;遇到錯誤後盲目嘗試&lt;/li&gt;
&lt;li&gt;沒有及時執行測試或檢查&lt;/li&gt;
&lt;li&gt;忽略專案裡已有模式&lt;/li&gt;
&lt;li&gt;為了完成任務引入不必要的抽象&lt;/li&gt;
&lt;li&gt;寫完程式碼後沒有真正 review 風險&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些問題不一定是模型能力不夠，而是工作流沒有被約束好。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;mattpocock/skills&lt;/code&gt; 的價值在於，把這些常見失敗模式拆成可以複用的操作方式，讓 Agent 在不同場景下更像一個有經驗的工程協作者。&lt;/p&gt;
&lt;h2 id=&#34;skills-是什麼&#34;&gt;Skills 是什麼
&lt;/h2&gt;&lt;p&gt;在 AI Agent 語境裡，skill 可以理解成一段可複用的任務說明、工作方法或專業流程。&lt;/p&gt;
&lt;p&gt;它不一定是程式碼插件，也不一定必須呼叫外部服務。很多時候，一個 skill 就是一套明確規則：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;什麼時候使用&lt;/li&gt;
&lt;li&gt;先做什麼&lt;/li&gt;
&lt;li&gt;不要做什麼&lt;/li&gt;
&lt;li&gt;需要輸出什麼&lt;/li&gt;
&lt;li&gt;怎麼判斷任務完成&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這和普通提示詞模板有點像，但粒度更接近「任務能力」。&lt;/p&gt;
&lt;p&gt;普通提示詞模板通常是使用者每次臨時複製貼上；skills 則更適合作為 agent 工具箱的一部分，讓 Agent 根據任務選擇合適流程。&lt;/p&gt;
&lt;h2 id=&#34;為什麼要小而可組合&#34;&gt;為什麼要小而可組合
&lt;/h2&gt;&lt;p&gt;README 中強調這些 skills 是小而可組合的。&lt;/p&gt;
&lt;p&gt;這個方向很重要。&lt;/p&gt;
&lt;p&gt;如果一個 skill 試圖包辦所有事情，它很快就會變成新的大提示詞：又長、又模糊、又難維護。小技能的優勢是邊界清楚。&lt;/p&gt;
&lt;p&gt;比如一個 skill 專門負責：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先做計劃&lt;/li&gt;
&lt;li&gt;修復 TypeScript 錯誤&lt;/li&gt;
&lt;li&gt;執行測試並根據結果修復&lt;/li&gt;
&lt;li&gt;做程式碼 review&lt;/li&gt;
&lt;li&gt;總結專案約定&lt;/li&gt;
&lt;li&gt;改進提示詞&lt;/li&gt;
&lt;li&gt;清理無用抽象&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些技能可以按任務組合使用。簡單任務只用一個技能，複雜任務再串起來。&lt;/p&gt;
&lt;p&gt;這更接近真實工程工作：你不會用同一套流程處理所有問題，而是根據問題選擇工具。&lt;/p&gt;
&lt;h2 id=&#34;保留工程師控制權&#34;&gt;保留工程師控制權
&lt;/h2&gt;&lt;p&gt;這個倉庫的一個重要取向，是讓工程師仍然掌握控制權。&lt;/p&gt;
&lt;p&gt;AI 編程很容易滑向兩種極端：&lt;/p&gt;
&lt;p&gt;第一種是完全手動。AI 只是幫你寫幾行程式碼，所有上下文、計劃、驗證都靠你自己盯。&lt;/p&gt;
&lt;p&gt;第二種是完全放手。你把任務丟給 Agent，讓它自己大改一通，最後再面對一堆難以審查的 diff。&lt;/p&gt;
&lt;p&gt;skills 的作用是在中間找一個更穩的位置。&lt;/p&gt;
&lt;p&gt;它讓 AI 承擔更多重複流程，但仍然用規則限制它：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先理解任務再動手&lt;/li&gt;
&lt;li&gt;先閱讀相關檔案再改&lt;/li&gt;
&lt;li&gt;修改範圍要可控&lt;/li&gt;
&lt;li&gt;出現不確定時要回報&lt;/li&gt;
&lt;li&gt;改完要驗證&lt;/li&gt;
&lt;li&gt;不能為了炫技重構無關程式碼&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這不是削弱 AI，而是讓 AI 的行動更容易被人類審查和接管。&lt;/p&gt;
&lt;h2 id=&#34;對齊問題&#34;&gt;對齊問題
&lt;/h2&gt;&lt;p&gt;AI 編程失敗的第一類問題通常是對齊失敗。&lt;/p&gt;
&lt;p&gt;使用者想要的是一個很具體的改動，但 Agent 可能理解成一個更大的重構；使用者只想修 Bug，它卻順手改了樣式；使用者希望遵守現有架構，它卻引入新模式。&lt;/p&gt;
&lt;p&gt;Skills 可以在任務開始階段幫助 Agent 做幾件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;重述目標&lt;/li&gt;
&lt;li&gt;找出影響範圍&lt;/li&gt;
&lt;li&gt;識別已有實現模式&lt;/li&gt;
&lt;li&gt;給出計劃&lt;/li&gt;
&lt;li&gt;明確不做哪些事情&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這一步很像工程師開工前的自檢。&lt;/p&gt;
&lt;p&gt;如果 Agent 連任務邊界都沒說清楚，就直接寫程式碼，後面很容易越走越偏。&lt;/p&gt;
&lt;h2 id=&#34;回饋循環問題&#34;&gt;回饋循環問題
&lt;/h2&gt;&lt;p&gt;AI 寫程式碼不能只靠一次生成。&lt;/p&gt;
&lt;p&gt;真實開發裡，回饋循環很重要：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;改一小步&lt;/li&gt;
&lt;li&gt;跑測試或型別檢查&lt;/li&gt;
&lt;li&gt;看錯誤&lt;/li&gt;
&lt;li&gt;修正&lt;/li&gt;
&lt;li&gt;再驗證&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;很多 Agent 失敗，是因為它跳過了中間回饋。它一次性改很多內容，然後憑感覺總結「應該可以工作」。&lt;/p&gt;
&lt;p&gt;Skills 可以把回饋循環顯式寫進流程裡。比如要求 Agent：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;修改後執行相關檢查&lt;/li&gt;
&lt;li&gt;如果檢查失敗，先讀錯誤訊息&lt;/li&gt;
&lt;li&gt;不要盲目改無關檔案&lt;/li&gt;
&lt;li&gt;每輪修復後重新驗證&lt;/li&gt;
&lt;li&gt;最後報告驗證結果&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這會讓 AI 編程更像真實除錯，而不是一次性作文。&lt;/p&gt;
&lt;h2 id=&#34;架構控制問題&#34;&gt;架構控制問題
&lt;/h2&gt;&lt;p&gt;AI 很擅長生成抽象，也很擅長過度生成抽象。&lt;/p&gt;
&lt;p&gt;為了完成一個小需求，它可能新建服務層、工具函式、配置物件、型別包裝、適配器，最後讓程式碼比需求本身複雜得多。&lt;/p&gt;
&lt;p&gt;這類問題在大型專案裡尤其危險。因為 AI 生成的抽象看起來很「專業」，但它可能不符合專案已有風格，也可能增加維護成本。&lt;/p&gt;
&lt;p&gt;好的 skills 會提醒 Agent：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;優先沿用現有模式&lt;/li&gt;
&lt;li&gt;不引入沒有必要的新抽象&lt;/li&gt;
&lt;li&gt;不順手重構無關區域&lt;/li&gt;
&lt;li&gt;修改要和任務規模匹配&lt;/li&gt;
&lt;li&gt;先理解程式碼再設計結構&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這能減少「看起來很工程化，實際上更難維護」的輸出。&lt;/p&gt;
&lt;h2 id=&#34;review-技能為什麼重要&#34;&gt;Review 技能為什麼重要
&lt;/h2&gt;&lt;p&gt;寫程式碼和 review 程式碼是兩種不同狀態。&lt;/p&gt;
&lt;p&gt;Agent 在寫程式碼時，通常會傾向於證明自己的實現成立。它會解釋為什麼這樣改可以工作，但不一定主動找風險。&lt;/p&gt;
&lt;p&gt;Review skill 的意義，是讓 Agent 切換角色：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;找潛在 Bug&lt;/li&gt;
&lt;li&gt;找行為回歸&lt;/li&gt;
&lt;li&gt;找遺漏測試&lt;/li&gt;
&lt;li&gt;找邊界條件&lt;/li&gt;
&lt;li&gt;找複雜度上升&lt;/li&gt;
&lt;li&gt;找和現有約定不一致的地方&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這對 AI 編程很重要。因為 AI 生成程式碼的速度很快，如果沒有 review，使用者很容易被大量 diff 淹沒。&lt;/p&gt;
&lt;p&gt;一個好的 review 輸出應該優先列問題，而不是先誇實現。它要幫助工程師判斷這次改動能不能合併。&lt;/p&gt;
&lt;h2 id=&#34;和普通-rules-檔案有什麼區別&#34;&gt;和普通 rules 檔案有什麼區別
&lt;/h2&gt;&lt;p&gt;很多 AI 編程工具都支援 rules、instructions 或 memory。&lt;/p&gt;
&lt;p&gt;這些檔案通常記錄長期規則，比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;專案技術棧&lt;/li&gt;
&lt;li&gt;命名規範&lt;/li&gt;
&lt;li&gt;測試命令&lt;/li&gt;
&lt;li&gt;不要修改哪些目錄&lt;/li&gt;
&lt;li&gt;回答風格偏好&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Skills 更偏任務流程。&lt;/p&gt;
&lt;p&gt;rules 告訴 Agent「長期應該怎麼做」，skills 告訴 Agent「面對某類任務時應該怎麼執行」。&lt;/p&gt;
&lt;p&gt;兩者最好一起用。&lt;/p&gt;
&lt;p&gt;比如 rules 裡寫專案用 &lt;code&gt;pnpm test&lt;/code&gt;，review skill 裡要求改完後檢查測試覆蓋。這樣 Agent 不僅知道命令，也知道什麼時候該用。&lt;/p&gt;
&lt;h2 id=&#34;適合什麼場景&#34;&gt;適合什麼場景
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;mattpocock/skills&lt;/code&gt; 這類倉庫適合這些場景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;高頻使用 AI 編程工具&lt;/li&gt;
&lt;li&gt;經常讓 Agent 處理真實程式碼庫&lt;/li&gt;
&lt;li&gt;想減少 AI 越界修改&lt;/li&gt;
&lt;li&gt;想讓 Agent 更主動地驗證結果&lt;/li&gt;
&lt;li&gt;想把自己的工程習慣沉澱成技能&lt;/li&gt;
&lt;li&gt;想學習別人如何設計 agent workflows&lt;/li&gt;
&lt;li&gt;想把一堆臨時提示詞整理成可維護的技能集合&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你只是偶爾讓 AI 寫一個小函式，可能不需要專門維護 skills。&lt;/p&gt;
&lt;p&gt;但如果你已經把 AI 當成長期開發夥伴，skills 會逐漸變得重要。它們相當於給 Agent 配了一套可複用的工作方法。&lt;/p&gt;
&lt;h2 id=&#34;怎麼借鑑這個倉庫&#34;&gt;怎麼借鑑這個倉庫
&lt;/h2&gt;&lt;p&gt;即使你不直接使用其中的每個 skill，也可以從這個倉庫學到幾件事。&lt;/p&gt;
&lt;p&gt;第一，把失敗模式寫下來。&lt;/p&gt;
&lt;p&gt;不要只在 AI 出錯時臨時抱怨。把它經常出錯的模式整理成規則，下一次讓 skill 提前防住。&lt;/p&gt;
&lt;p&gt;第二，技能要短。&lt;/p&gt;
&lt;p&gt;一個 skill 最好解決一個明確問題。越短越容易被正確呼叫，也越容易維護。&lt;/p&gt;
&lt;p&gt;第三，輸出格式要清楚。&lt;/p&gt;
&lt;p&gt;如果你希望 Agent 先列計劃、再執行、最後總結驗證結果，就把輸出結構寫清楚。模糊要求通常會得到模糊結果。&lt;/p&gt;
&lt;p&gt;第四，保留人工接管點。&lt;/p&gt;
&lt;p&gt;好的 skill 不應該讓 AI 獨自跑到很遠。遇到不確定、影響範圍擴大、測試失敗或需要產品判斷時，應該讓它停下來說明情況。&lt;/p&gt;
&lt;h2 id=&#34;使用時要注意&#34;&gt;使用時要注意
&lt;/h2&gt;&lt;p&gt;第一，不要把所有事情都技能化。&lt;/p&gt;
&lt;p&gt;太多 skills 會讓系統變複雜，Agent 也可能不知道該選哪個。先從最高頻、最痛的幾個場景開始。&lt;/p&gt;
&lt;p&gt;第二，skills 需要迭代。&lt;/p&gt;
&lt;p&gt;第一次寫出來的 skill 不一定好。看 AI 實際執行效果，再逐步刪減、補充和改寫。&lt;/p&gt;
&lt;p&gt;第三，不要讓 skill 替代工程判斷。&lt;/p&gt;
&lt;p&gt;Skill 可以改善流程，但不能保證實現正確。測試、review、構建檢查和人類判斷仍然重要。&lt;/p&gt;
&lt;p&gt;第四，注意不同 Agent 的差異。&lt;/p&gt;
&lt;p&gt;Claude Code、Codex、Cursor、Copilot 對 instructions、skills、rules 的支援方式不同。同一套思想可以複用，但具體格式要按工具調整。&lt;/p&gt;
&lt;h2 id=&#34;參考&#34;&gt;參考
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mattpocock/skills&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;mattpocock/skills&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;最後一句&#34;&gt;最後一句
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;mattpocock/skills&lt;/code&gt; 值得關注的地方，不是裡面某一個神奇提示詞，而是它展示了一種更實用的 AI 編程思路：把工程經驗拆成小技能，再讓 Agent 按場景組合使用。&lt;/p&gt;
&lt;p&gt;當 AI 編程從偶爾輔助變成日常工作流，skills 會成為約束 Agent、保留工程師控制權和提升回饋品質的重要工具。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Compound Engineering Plugin：把 AI 編程變成計劃、執行、評審的工程循環</title>
        <link>https://knightli.com/zh-tw/2026/05/01/compound-engineering-plugin-ai-coding-workflow/</link>
        <pubDate>Fri, 01 May 2026 03:15:39 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/05/01/compound-engineering-plugin-ai-coding-workflow/</guid>
        <description>&lt;p&gt;&lt;code&gt;Compound Engineering Plugin&lt;/code&gt; 是 Every Inc 開源的一個 AI 編程工作流插件。&lt;/p&gt;
&lt;p&gt;它關注的不是「讓 AI 更快寫一段程式碼」，而是把 AI 編程放進一個更像工程團隊的循環裡：先計劃，再實現，再評審，再把經驗沉澱下來。對經常使用 Claude Code、Codex、Cursor、Copilot 這類工具的人來說，這類插件解決的是工作流問題，而不只是提示詞問題。&lt;/p&gt;
&lt;p&gt;AI 編程工具越來越強，但真實專案裡最難的往往不是生成程式碼，而是讓它持續按專案規則做事、理解任務邊界、避免重複犯錯，並在多輪迭代中積累上下文。&lt;/p&gt;
&lt;h2 id=&#34;它解決什麼問題&#34;&gt;它解決什麼問題
&lt;/h2&gt;&lt;p&gt;很多人使用 AI 編程助手時，流程大概是這樣：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;直接描述需求&lt;/li&gt;
&lt;li&gt;讓 AI 改程式碼&lt;/li&gt;
&lt;li&gt;看結果是否能跑&lt;/li&gt;
&lt;li&gt;出錯後繼續補充說明&lt;/li&gt;
&lt;li&gt;下次新任務再從頭解釋一遍&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這種方式能完成小任務，但在複雜專案裡很容易遇到問題：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需求沒有先拆清楚，AI 直接開始改&lt;/li&gt;
&lt;li&gt;改完程式碼後缺少系統性 review&lt;/li&gt;
&lt;li&gt;專案規範靠使用者反覆提醒&lt;/li&gt;
&lt;li&gt;同類錯誤下次仍然出現&lt;/li&gt;
&lt;li&gt;多個 Agent 工具之間缺少統一工作方法&lt;/li&gt;
&lt;li&gt;經驗沒有沉澱成可複用規則&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;Compound Engineering Plugin&lt;/code&gt; 想解決的就是這類問題。它把 AI 編程拆成多個階段，讓 Agent 不只是執行命令，而是參與一個更完整的工程流程。&lt;/p&gt;
&lt;h2 id=&#34;什麼是-compound-engineering&#34;&gt;什麼是 Compound Engineering
&lt;/h2&gt;&lt;p&gt;從專案 README 的描述看，Compound Engineering 可以理解為一種 AI 輔助軟體開發方法。&lt;/p&gt;
&lt;p&gt;它強調一個循環：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;計劃：先理解目標、拆分任務、確認路徑&lt;/li&gt;
&lt;li&gt;執行：按計劃修改程式碼、執行命令、處理問題&lt;/li&gt;
&lt;li&gt;評審：檢查實現品質、風險和測試覆蓋&lt;/li&gt;
&lt;li&gt;學習：把經驗沉澱成後續可複用的規則&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這個循環很像真實工程團隊的工作方式。&lt;/p&gt;
&lt;p&gt;一個可靠的工程師不會拿到需求就立刻亂改，也不會改完就直接交差。他會先判斷影響範圍，再動手實現，之後檢查風險和測試結果，最後把踩過的坑記錄下來。AI Agent 也需要類似約束。&lt;/p&gt;
&lt;h2 id=&#34;為什麼需要插件&#34;&gt;為什麼需要插件
&lt;/h2&gt;&lt;p&gt;提示詞可以告訴 AI「請先計劃再執行」，但提示詞本身不一定穩定。&lt;/p&gt;
&lt;p&gt;一旦會話變長、上下文變複雜，模型可能會跳過計劃、忽略規則，或者為了完成任務而過度自信。插件的價值在於把流程固化下來，讓不同 Agent 環境都能遵循類似方法。&lt;/p&gt;
&lt;p&gt;這類插件通常會把工作流拆成命令、規則、模板或子流程。使用者不需要每次手寫完整提示詞，而是透過固定入口觸發某個階段。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先讓 Agent 生成計劃&lt;/li&gt;
&lt;li&gt;再按計劃逐步實現&lt;/li&gt;
&lt;li&gt;改完後觸發 review&lt;/li&gt;
&lt;li&gt;發現問題後返回修正&lt;/li&gt;
&lt;li&gt;把值得保留的經驗寫入記憶或規則&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這會讓 AI 編程更像「受控協作」，而不是一次性聊天。&lt;/p&gt;
&lt;h2 id=&#34;支援哪些-agent-環境&#34;&gt;支援哪些 Agent 環境
&lt;/h2&gt;&lt;p&gt;README 中提到，專案支援多個 AI 編程環境，包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Claude Code&lt;/li&gt;
&lt;li&gt;Codex&lt;/li&gt;
&lt;li&gt;Cursor&lt;/li&gt;
&lt;li&gt;GitHub Copilot&lt;/li&gt;
&lt;li&gt;Amp&lt;/li&gt;
&lt;li&gt;Factory&lt;/li&gt;
&lt;li&gt;Qwen Code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這點值得注意。&lt;/p&gt;
&lt;p&gt;很多工作流工具只綁定一個客戶端，換工具後規則就不能複用。&lt;code&gt;Compound Engineering Plugin&lt;/code&gt; 更像一套跨 Agent 的工程方法，把類似的計劃、執行、評審流程帶到不同工具裡。&lt;/p&gt;
&lt;p&gt;如果你同時使用多個 AI 編程助手，這類統一工作流會更有價值。不同工具能力不同，但專案規範、評審習慣和任務拆解方法應該盡量一致。&lt;/p&gt;
&lt;h2 id=&#34;計劃階段有什麼用&#34;&gt;計劃階段有什麼用
&lt;/h2&gt;&lt;p&gt;計劃階段的價值，是防止 AI 過早動手。&lt;/p&gt;
&lt;p&gt;複雜任務裡，真正重要的問題通常是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;要改哪些檔案&lt;/li&gt;
&lt;li&gt;哪些模組可能受影響&lt;/li&gt;
&lt;li&gt;現有模式是什麼&lt;/li&gt;
&lt;li&gt;有沒有測試&lt;/li&gt;
&lt;li&gt;風險點在哪裡&lt;/li&gt;
&lt;li&gt;是否需要先閱讀文件&lt;/li&gt;
&lt;li&gt;能不能拆成更小步驟&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果 Agent 沒有先想清楚這些問題，就直接開始寫程式碼，很容易做出看似完成、實際偏離專案結構的實現。&lt;/p&gt;
&lt;p&gt;計劃並不一定要很長。好的計劃應該短、具體、可執行。它的目的不是製造文件，而是讓後續實現有邊界。&lt;/p&gt;
&lt;h2 id=&#34;執行階段要避免什麼&#34;&gt;執行階段要避免什麼
&lt;/h2&gt;&lt;p&gt;AI 執行程式碼任務時，最容易出現幾類問題：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;順手重構無關程式碼&lt;/li&gt;
&lt;li&gt;覆蓋使用者已有修改&lt;/li&gt;
&lt;li&gt;只改 happy path&lt;/li&gt;
&lt;li&gt;忽略錯誤處理&lt;/li&gt;
&lt;li&gt;不按專案已有風格寫&lt;/li&gt;
&lt;li&gt;沒有執行必要驗證&lt;/li&gt;
&lt;li&gt;遇到錯誤後盲目嘗試&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;工作流插件無法保證這些問題完全消失，但可以透過規則和階段約束減少發生機率。&lt;/p&gt;
&lt;p&gt;比如，執行階段可以要求 Agent 按計劃逐步推進；遇到超出計劃範圍的發現時，先說明風險；修改共享模組時，補充測試或至少執行相關驗證。&lt;/p&gt;
&lt;p&gt;這種約束對大型程式碼庫尤其重要。AI 寫程式碼越快，越需要流程來限制它的慣性。&lt;/p&gt;
&lt;h2 id=&#34;評審階段為什麼重要&#34;&gt;評審階段為什麼重要
&lt;/h2&gt;&lt;p&gt;很多 AI 編程失敗，不是因為程式碼完全不能執行，而是因為細節有問題：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;邊界條件沒處理&lt;/li&gt;
&lt;li&gt;狀態更新不一致&lt;/li&gt;
&lt;li&gt;API 合約被悄悄改了&lt;/li&gt;
&lt;li&gt;測試覆蓋不到關鍵路徑&lt;/li&gt;
&lt;li&gt;錯誤提示不清楚&lt;/li&gt;
&lt;li&gt;效能或安全風險沒有被提到&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;評審階段就是把 Agent 從「作者模式」切換到「審查模式」。&lt;/p&gt;
&lt;p&gt;作者模式容易為自己的實現找理由；審查模式則要主動找漏洞、回歸風險和遺漏測試。把這兩個階段分開，會比讓同一個回覆裡同時完成實現和自我審查更可靠。&lt;/p&gt;
&lt;p&gt;對使用者來說，評審輸出也更有價值。它能幫助你快速判斷這次修改是否值得合併，還是需要繼續返工。&lt;/p&gt;
&lt;h2 id=&#34;學習和記憶的意義&#34;&gt;學習和記憶的意義
&lt;/h2&gt;&lt;p&gt;專案名字裡的 “Compound” 暗示了一個重要想法：工程經驗應該複利增長。&lt;/p&gt;
&lt;p&gt;如果 AI 每次犯錯後只是當場修好，下次又犯同樣錯誤，效率提升就很有限。更好的方式是把有價值的經驗沉澱下來：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;這個專案的目錄約定&lt;/li&gt;
&lt;li&gt;某類錯誤的排查方法&lt;/li&gt;
&lt;li&gt;測試命令和注意事項&lt;/li&gt;
&lt;li&gt;不要觸碰的生成檔案&lt;/li&gt;
&lt;li&gt;程式碼風格偏好&lt;/li&gt;
&lt;li&gt;常見實現模式&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些經驗可以變成規則、記憶、文件或模板。後續任務中，Agent 先讀取這些沉澱，再開始工作。&lt;/p&gt;
&lt;p&gt;這就是 AI 編程從「單次問答」走向「長期協作」的關鍵。&lt;/p&gt;
&lt;h2 id=&#34;適合什麼場景&#34;&gt;適合什麼場景
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Compound Engineering Plugin&lt;/code&gt; 適合這些場景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;長期使用 AI Agent 寫程式碼&lt;/li&gt;
&lt;li&gt;一個專案會被多次、多輪修改&lt;/li&gt;
&lt;li&gt;希望 AI 先計劃再實現&lt;/li&gt;
&lt;li&gt;希望改完後自動進入 review 思維&lt;/li&gt;
&lt;li&gt;團隊想統一 AI 編程流程&lt;/li&gt;
&lt;li&gt;同時使用 Claude Code、Codex、Cursor 等多個工具&lt;/li&gt;
&lt;li&gt;希望把專案經驗沉澱成可複用規則&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果只是偶爾讓 AI 寫一個小腳本，完整流程可能顯得偏重。&lt;/p&gt;
&lt;p&gt;但如果你正在把 AI 編程助手當成日常開發夥伴，計劃、執行、評審、學習這套循環就會明顯有用。&lt;/p&gt;
&lt;h2 id=&#34;和普通提示詞模板有什麼區別&#34;&gt;和普通提示詞模板有什麼區別
&lt;/h2&gt;&lt;p&gt;普通提示詞模板通常解決的是「怎麼說清楚任務」。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;請一步步思考&lt;/li&gt;
&lt;li&gt;請先閱讀檔案&lt;/li&gt;
&lt;li&gt;請保持程式碼風格一致&lt;/li&gt;
&lt;li&gt;請執行測試&lt;/li&gt;
&lt;li&gt;請總結修改內容&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些提示當然有用，但它們還是依賴使用者每次正確使用。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Compound Engineering Plugin&lt;/code&gt; 更偏工作流層。它把這些要求組織成可重複的過程，並適配不同 Agent 工具。這樣你不是每次從零寫提示詞，而是在一套流程裡推進任務。&lt;/p&gt;
&lt;p&gt;簡單說，提示詞模板像提醒，工作流插件像制度。&lt;/p&gt;
&lt;h2 id=&#34;使用時要注意&#34;&gt;使用時要注意
&lt;/h2&gt;&lt;p&gt;第一，不要把流程變成負擔。&lt;/p&gt;
&lt;p&gt;小任務不一定需要完整計劃和長篇評審。好的工作流應該能根據任務複雜度調整，簡單問題快速處理，複雜問題再走完整循環。&lt;/p&gt;
&lt;p&gt;第二，評審不能替代測試。&lt;/p&gt;
&lt;p&gt;Agent review 能發現很多問題，但它仍然可能漏掉真實執行時錯誤。最終判斷還要看測試、型別檢查、構建結果和人工審查。&lt;/p&gt;
&lt;p&gt;第三，規則要持續清理。&lt;/p&gt;
&lt;p&gt;沉澱經驗很重要，但規則越積越多也會變成噪音。過時規則、重複規則、只適合某次任務的臨時經驗，都應該定期整理。&lt;/p&gt;
&lt;p&gt;第四，跨工具一致不等於完全相同。&lt;/p&gt;
&lt;p&gt;Claude Code、Codex、Cursor、Copilot 等工具能力和互動方式不同。統一的是工作方法，不一定是每個命令、每個配置細節都完全一樣。&lt;/p&gt;
&lt;h2 id=&#34;適合怎樣的團隊&#34;&gt;適合怎樣的團隊
&lt;/h2&gt;&lt;p&gt;如果一個團隊已經允許 AI Agent 修改真實程式碼，那麼只討論「哪個模型更強」是不夠的。&lt;/p&gt;
&lt;p&gt;更應該關心：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI 修改前是否理解任務&lt;/li&gt;
&lt;li&gt;AI 修改中是否遵守專案邊界&lt;/li&gt;
&lt;li&gt;AI 修改後是否主動審查風險&lt;/li&gt;
&lt;li&gt;AI 是否能從歷史錯誤中學習&lt;/li&gt;
&lt;li&gt;團隊是否有統一的 Agent 使用規範&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;Compound Engineering Plugin&lt;/code&gt; 這類專案的意義就在這裡。它把 AI 編程從個人技巧，往團隊可複用流程推進了一步。&lt;/p&gt;
&lt;h2 id=&#34;參考&#34;&gt;參考
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/EveryInc/compound-engineering-plugin&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;EveryInc/compound-engineering-plugin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;最後一句&#34;&gt;最後一句
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Compound Engineering Plugin&lt;/code&gt; 值得關注的地方，不是多一個 AI 編程命令，而是把 AI 編程組織成可循環改進的工程流程。&lt;/p&gt;
&lt;p&gt;當 AI Agent 開始參與真實專案，計劃、執行、評審和經驗沉澱會比單次生成程式碼更重要。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Codex 開始控制電腦，對以後意味著什麼？</title>
        <link>https://knightli.com/zh-tw/2026/04/29/codex-computer-use-update/</link>
        <pubDate>Wed, 29 Apr 2026 11:28:25 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/04/29/codex-computer-use-update/</guid>
        <description>&lt;p&gt;Codex 這次最值得關注的變化，不是又多了一個普通按鈕，而是它開始往「控制電腦」這個方向走。&lt;/p&gt;
&lt;p&gt;以前我們使用 AI，更多是在聊天框裡提問、複製、貼上、再手動操作軟體。&lt;br&gt;
現在這個邊界開始往外擴：AI 不只是回答你，而是可以根據你的目標去操作桌面應用。&lt;/p&gt;
&lt;p&gt;這件事短期看是一個新功能，長期看可能會改變很多人使用電腦的方式。&lt;/p&gt;
&lt;h2 id=&#34;這個功能是什麼&#34;&gt;這個功能是什麼
&lt;/h2&gt;&lt;p&gt;簡單說，Codex 的電腦使用能力，就是讓它能接觸並操作桌面環境。&lt;/p&gt;
&lt;p&gt;它可以做的事包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可以選擇並控制某個應用&lt;/li&gt;
&lt;li&gt;可以用自然語言下達任務&lt;/li&gt;
&lt;li&gt;可以打開瀏覽器、AI 工具、本地文件或其他軟體&lt;/li&gt;
&lt;li&gt;可以輸入內容、點擊按鈕、等待結果&lt;/li&gt;
&lt;li&gt;可以把多個步驟串成一個任務&lt;/li&gt;
&lt;li&gt;可以在後台繼續執行，不需要使用者每一步都手動跟著&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它的定位不是單純替你寫一段文字，而是替你完成一段操作流程。&lt;/p&gt;
&lt;p&gt;這就是 Agent 和普通聊天機器人的關鍵差別：&lt;br&gt;
聊天機器人主要給答案，Agent 更接近「拿到目標後去執行」。&lt;/p&gt;
&lt;h2 id=&#34;為什麼這件事重要&#34;&gt;為什麼這件事重要
&lt;/h2&gt;&lt;p&gt;過去很多自動化都要求你會寫腳本。&lt;/p&gt;
&lt;p&gt;比如你想完成一個跨軟體流程：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;打開網頁&lt;/li&gt;
&lt;li&gt;找資料&lt;/li&gt;
&lt;li&gt;複製內容&lt;/li&gt;
&lt;li&gt;交給另一個 AI 工具處理&lt;/li&gt;
&lt;li&gt;保存文件&lt;/li&gt;
&lt;li&gt;再打開本地目錄檢查結果&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果要自動化這件事，傳統做法可能是寫瀏覽器腳本、調用 API、寫本地程序，甚至還要處理各種軟體窗口。&lt;/p&gt;
&lt;p&gt;但很多普通使用者不會寫這些東西。&lt;br&gt;
就算會寫，也未必值得為一個臨時任務專門寫腳本。&lt;/p&gt;
&lt;p&gt;電腦使用能力的意義就在這裡：它把「腳本能力」往自然語言方向推了一步。&lt;/p&gt;
&lt;p&gt;你不一定要告訴它每一步怎麼點。&lt;br&gt;
你可以告訴它你要什麼結果，讓它自己去嘗試完成。&lt;/p&gt;
&lt;h2 id=&#34;它能改變哪些工作流&#34;&gt;它能改變哪些工作流
&lt;/h2&gt;&lt;p&gt;我覺得最先被改變的，不會是特別嚴肅、特別高風險的工作，而是那些「煩、雜、重複、但又不值得專門寫程序」的流程。&lt;/p&gt;
&lt;h3 id=&#34;1-跨軟體搬運&#34;&gt;1. 跨軟體搬運
&lt;/h3&gt;&lt;p&gt;最典型的就是在多個軟體之間搬資訊。&lt;/p&gt;
&lt;p&gt;以前你可能要在瀏覽器、文檔、聊天窗口、本地資料夾之間來回切。&lt;br&gt;
以後可以把這類任務交給 Agent：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;去找某類資料&lt;/li&gt;
&lt;li&gt;匯總成文檔&lt;/li&gt;
&lt;li&gt;保存到指定目錄&lt;/li&gt;
&lt;li&gt;打開結果給你確認&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這類工作不難，但很耗注意力。&lt;br&gt;
Agent 的價值就是把這些碎操作吃掉。&lt;/p&gt;
&lt;h3 id=&#34;2-多個-ai-工具協同&#34;&gt;2. 多個 AI 工具協同
&lt;/h3&gt;&lt;p&gt;現在很多人的真實工作流已經不是只用一個 AI。&lt;/p&gt;
&lt;p&gt;可能是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一個工具寫程式碼&lt;/li&gt;
&lt;li&gt;一個工具查資料&lt;/li&gt;
&lt;li&gt;一個工具生成圖片&lt;/li&gt;
&lt;li&gt;一個工具整理文檔&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以前這些工具之間靠人手複製貼上。&lt;br&gt;
以後 Agent 可以成為中間層：它負責打開工具、傳遞上下文、等待輸出、整理結果。&lt;/p&gt;
&lt;p&gt;這會讓「多個 AI 協同」從手工流程變成半自動流程。&lt;/p&gt;
&lt;h3 id=&#34;3-辦公軟體自動化&#34;&gt;3. 辦公軟體自動化
&lt;/h3&gt;&lt;p&gt;表格、PPT、文檔、郵件，這些軟體都有一個共同特點：功能很強，但很多操作很碎。&lt;/p&gt;
&lt;p&gt;如果 Agent 能穩定控制這些軟體，以後的辦公自動化門檻會明顯下降。&lt;/p&gt;
&lt;p&gt;你不用記選單在哪裡，也不用學複雜快捷鍵。&lt;br&gt;
你只需要說清楚目標，比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把這份表格整理成月報&lt;/li&gt;
&lt;li&gt;根據這份文檔做一頁總結&lt;/li&gt;
&lt;li&gt;把這些資料合併成一個結構清楚的說明&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;真正麻煩的按鈕操作，會逐漸被隱藏到自然語言後面。&lt;/p&gt;
&lt;h2 id=&#34;對普通使用者意味著什麼&#34;&gt;對普通使用者意味著什麼
&lt;/h2&gt;&lt;p&gt;對普通使用者來說，這類功能的影響可能比「模型又聰明了一點」更直接。&lt;/p&gt;
&lt;p&gt;因為它降低的不是知識門檻，而是操作門檻。&lt;/p&gt;
&lt;p&gt;很多人不是不會表達需求，而是不知道軟體裡該點哪裡、怎麼組合功能。&lt;br&gt;
Agent 如果能接管這部分，人使用電腦的方式就會變成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;我描述目標
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Agent 操作軟體
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;我檢查結果
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這比單純聊天更接近真實生產力。&lt;/p&gt;
&lt;h2 id=&#34;對軟體形態的影響&#34;&gt;對軟體形態的影響
&lt;/h2&gt;&lt;p&gt;如果這類 Agent 能力繼續成熟，軟體本身也會被反向影響。&lt;/p&gt;
&lt;p&gt;過去軟體設計主要服務人類點擊。&lt;br&gt;
以後軟體可能還要服務 Agent 操作。&lt;/p&gt;
&lt;p&gt;這意味著：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;介面元素需要更清晰&lt;/li&gt;
&lt;li&gt;操作回饋需要更穩定&lt;/li&gt;
&lt;li&gt;本地權限需要更細&lt;/li&gt;
&lt;li&gt;軟體可能會提供更適合 Agent 調用的介面&lt;/li&gt;
&lt;li&gt;使用者會更在意「能不能被 AI 順利操作」&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;長期看，應用之間的邊界可能會變薄。&lt;br&gt;
使用者關心的不再是「我打開哪個軟體」，而是「我要完成什麼任務」。&lt;/p&gt;
&lt;h2 id=&#34;現在還不能過度樂觀&#34;&gt;現在還不能過度樂觀
&lt;/h2&gt;&lt;p&gt;當然，現在還不到完全放手的時候。&lt;/p&gt;
&lt;p&gt;這類能力目前還有幾個明顯限制：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;穩定性還需要觀察&lt;/li&gt;
&lt;li&gt;複雜任務可能中途出錯&lt;/li&gt;
&lt;li&gt;權限邊界必須謹慎&lt;/li&gt;
&lt;li&gt;涉及帳號、支付、刪除文件等操作不能隨便放權&lt;/li&gt;
&lt;li&gt;額度消耗也不是完全可以忽略&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以現階段最合適的用法，不是讓它完全接管電腦，而是讓它處理低風險、可檢查、步驟繁瑣的任務。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;整理資料&lt;/li&gt;
&lt;li&gt;生成草稿&lt;/li&gt;
&lt;li&gt;跨工具搬運內容&lt;/li&gt;
&lt;li&gt;打開和檢查文件&lt;/li&gt;
&lt;li&gt;做一些可以人工複核的半自動流程&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;最後一句&#34;&gt;最後一句
&lt;/h2&gt;&lt;p&gt;Codex 這次更新真正重要的地方，是它把 AI 從「回答問題」推向了「操作環境」。&lt;/p&gt;
&lt;p&gt;短期看，它是一個電腦使用功能。&lt;br&gt;
長期看，它可能是個人電腦互動方式的一次轉向。&lt;/p&gt;
&lt;p&gt;以後我們使用電腦，可能會越來越少地記按鈕、找選單、切窗口。&lt;br&gt;
更多時候，我們只需要說清楚目標，然後讓 Agent 去執行，再由人做最後判斷。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Codex Skill 明明在目錄裡，為什麼就是不顯示？</title>
        <link>https://knightli.com/zh-tw/2026/04/29/codex-skill-not-loaded-because-of-utf-8-bom/</link>
        <pubDate>Wed, 29 Apr 2026 11:18:00 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/04/29/codex-skill-not-loaded-because-of-utf-8-bom/</guid>
        <description>&lt;p&gt;這次遇到的問題很隱蔽：&lt;code&gt;~/.codex/skills&lt;/code&gt; 裡明明已經放好了多個 skill，新開 Codex 執行緒之後，側邊欄卻還是只能看到少數幾個。&lt;/p&gt;
&lt;p&gt;一開始看起來像是快取或索引問題，但實際原因更具體：幾個 &lt;code&gt;SKILL.md&lt;/code&gt; 文件開頭帶了 UTF-8 BOM，Codex 0.111.0 的 skill loader 沒有跳過這個位元組，於是誤判文件沒有合法的 YAML front matter。&lt;/p&gt;
&lt;h2 id=&#34;現象&#34;&gt;現象
&lt;/h2&gt;&lt;p&gt;本地目錄裡有這些 skill：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;~/.codex/skills/git-commit-push/SKILL.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;~/.codex/skills/hugo-rsync-deploy/SKILL.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;~/.codex/skills/bilibili-speech-transcriber/SKILL.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;~/.codex/skills/product-cutout-normalize/SKILL.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;但新開執行緒時，實際暴露出來的只有：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bilibili-speech-transcriber
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;product-cutout-normalize
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;也就是說，文件存在不等於當前會話一定能載入成功。Codex 會先解析每個 &lt;code&gt;SKILL.md&lt;/code&gt; 的 front matter，解析失敗的 skill 會直接被排除。&lt;/p&gt;
&lt;h2 id=&#34;排查&#34;&gt;排查
&lt;/h2&gt;&lt;p&gt;用 &lt;code&gt;codex exec&lt;/code&gt; 啟動一個新會話時，可以看到更直接的錯誤。在 VS Code 等 IDE 中，可能看不到這些 log：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;failed to load skill C:\Users\knightli\.codex\skills\git-commit-push\SKILL.md: missing YAML frontmatter delimited by ---
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;failed to load skill C:\Users\knightli\.codex\skills\hugo-rsync-deploy\SKILL.md: missing YAML frontmatter delimited by ---
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這些文件肉眼看起來都有正常的開頭：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-md&#34; data-lang=&#34;md&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;name: post-rewrite
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;description: ...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;真正的問題在位元組層面。&lt;/p&gt;
&lt;p&gt;失敗文件的開頭是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;EF-BB-BF-2D-2D-2D
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;能正常載入的文件開頭是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2D-2D-2D
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;2D-2D-2D&lt;/code&gt; 就是 &lt;code&gt;---&lt;/code&gt;。前面的 &lt;code&gt;EF-BB-BF&lt;/code&gt; 是 UTF-8 BOM。&lt;/p&gt;
&lt;h2 id=&#34;原因&#34;&gt;原因
&lt;/h2&gt;&lt;p&gt;Codex 0.111.0 的 skill loader 目前要求 &lt;code&gt;SKILL.md&lt;/code&gt; 文件第一個位元組就是 &lt;code&gt;---&lt;/code&gt; 的第一個 &lt;code&gt;-&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;如果文件前面帶了 UTF-8 BOM，那麼文件實際開頭就不再是 &lt;code&gt;---&lt;/code&gt;，而是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;BOM + ---
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;於是 loader 會認為它沒有以前置資料分隔符開頭，最後報：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;missing YAML frontmatter delimited by ---
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這不是 skill 內容寫錯了，也不是目錄放錯了，而是編碼細節讓解析器沒認出來。&lt;/p&gt;
&lt;h2 id=&#34;修復&#34;&gt;修復
&lt;/h2&gt;&lt;p&gt;把出問題的 &lt;code&gt;SKILL.md&lt;/code&gt; 轉成無 BOM 的 UTF-8 即可。&lt;/p&gt;
&lt;p&gt;PowerShell 可以這樣處理：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$paths&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s1&#34;&gt;&amp;#39;C:\Users\knightli\.codex\skills\git-commit-push\SKILL.md&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s1&#34;&gt;&amp;#39;C:\Users\knightli\.codex\skills\hugo-rsync-deploy\SKILL.md&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$utf8NoBom&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;New-Object&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;System&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;Text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;UTF8Encoding&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;$false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;foreach&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$p&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$paths&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nv&#34;&gt;$text&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;IO.File&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ReadAllText&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;Text.Encoding&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTF8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;IO.File&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WriteAllText&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$utf8NoBom&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;處理後再檢查文件頭，應該從：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;EF-BB-BF-2D-2D-2D
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;變成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2D-2D-2D
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;驗證&#34;&gt;驗證
&lt;/h2&gt;&lt;p&gt;重新啟動一個 Codex 會話後，可見 skill 恢復為：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git-commit-push-zh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;hugo-rsync-deploy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bilibili-speech-transcriber
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;product-cutout-normalize
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果側邊欄仍然只顯示舊的列表，可以退出當前 Codex sidebar 或窗口，再重新打開專案。skill 列表通常在會話啟動時載入，中途改文件不一定會立刻刷新到當前執行緒。&lt;/p&gt;
&lt;h2 id=&#34;最後一句&#34;&gt;最後一句
&lt;/h2&gt;&lt;p&gt;這類問題最容易誤判成「Codex 沒重新索引」或「skill 沒安裝好」。&lt;/p&gt;
&lt;p&gt;實際排查時可以先看三件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SKILL.md&lt;/code&gt; 是否真的在正確目錄&lt;/li&gt;
&lt;li&gt;文件頭部是否有合法的 &lt;code&gt;---&lt;/code&gt; front matter&lt;/li&gt;
&lt;li&gt;文件是否是無 BOM 的 UTF-8&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這次的關鍵就是第三點：文件看起來沒問題，但第一個位元組不是 &lt;code&gt;-&lt;/code&gt;，Codex 就沒有把它當作一個有效 skill。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Codex 裡的 ~/.codex/skills 和 專案/.codex/skills 有什麼差別</title>
        <link>https://knightli.com/zh-tw/2026/04/29/difference-between-global-and-project-codex-skills/</link>
        <pubDate>Wed, 29 Apr 2026 11:08:00 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/04/29/difference-between-global-and-project-codex-skills/</guid>
        <description>&lt;p&gt;很多人整理 Codex skills 時，最容易卡住的問題就兩個：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~/.codex/skills&lt;/code&gt; 和 &lt;code&gt;專案/.codex/skills&lt;/code&gt; 有什麼差別&lt;/li&gt;
&lt;li&gt;為什麼 skill 明明在目錄裡，當前會話裡卻不一定顯示&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這篇就直接說結論。&lt;/p&gt;
&lt;h2 id=&#34;兩者的差別&#34;&gt;兩者的差別
&lt;/h2&gt;&lt;p&gt;先記最短版本：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~/.codex/skills&lt;/code&gt; 是你的全域技能庫&lt;/li&gt;
&lt;li&gt;&lt;code&gt;專案/.codex/skills&lt;/code&gt; 是這個倉庫的本地技能庫&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;codexskills&#34;&gt;&lt;code&gt;~/.codex/skills&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;適合放：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你自己跨專案反覆會用的 skill&lt;/li&gt;
&lt;li&gt;跟具體倉庫無關的通用流程&lt;/li&gt;
&lt;li&gt;很明顯屬於你個人習慣的工作流&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;post-rewrite&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;post-translate&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git-commit-push&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hugo-rsync-deploy&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bilibili-speech-transcriber&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這類 skill 的特點就是：&lt;strong&gt;離開當前專案也還能用。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;專案codexskills&#34;&gt;&lt;code&gt;專案/.codex/skills&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;適合放：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;只對這個倉庫成立的流程&lt;/li&gt;
&lt;li&gt;跟當前專案目錄結構、腳本、模板綁定很深的規則&lt;/li&gt;
&lt;li&gt;需要讓團隊一起共享的 skill&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;這個倉庫特有的發布流程&lt;/li&gt;
&lt;li&gt;只能在這個專案裡用的生成模板&lt;/li&gt;
&lt;li&gt;跟專案私有腳本強綁定的自動化步驟&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這類 skill 的特點是：&lt;strong&gt;離開這個倉庫就沒意義。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;什麼時候放全域什麼時候放專案裡&#34;&gt;什麼時候放全域，什麼時候放專案裡
&lt;/h2&gt;&lt;p&gt;直接這樣判斷就夠了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;跟你個人習慣有關，放 &lt;code&gt;~/.codex/skills&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;跟倉庫規則有關，放 &lt;code&gt;專案/.codex/skills&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;能跨專案複用，優先放全域&lt;/li&gt;
&lt;li&gt;要多人共享、跟倉庫一起演進，優先放專案裡&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;當前這個倉庫是什麼情況&#34;&gt;當前這個倉庫是什麼情況
&lt;/h2&gt;&lt;p&gt;按我現在看到的實際狀態：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你的本機裡有 &lt;code&gt;~/.codex/skills&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;當前倉庫裡沒有 &lt;code&gt;.codex/skills&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以你現在主要依賴的是全域 skills。&lt;/p&gt;
&lt;p&gt;也就是說，像 &lt;code&gt;post-rewrite&lt;/code&gt;、&lt;code&gt;post-translate&lt;/code&gt;、&lt;code&gt;git-commit-push&lt;/code&gt; 這些流程，現在更多是你個人工作流的一部分，不是這個倉庫顯式自帶的一部分。&lt;/p&gt;
&lt;h2 id=&#34;為什麼磁碟裡有當前會話裡卻不一定顯示&#34;&gt;為什麼磁碟裡有，當前會話裡卻不一定顯示
&lt;/h2&gt;&lt;p&gt;這裡要分清兩件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;磁碟存在&lt;/strong&gt;：說明 skill 文件在本地目錄裡&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;會話暴露&lt;/strong&gt;：說明當前會話把它註冊進了可用 skill 列表&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這兩者不是一回事。&lt;/p&gt;
&lt;p&gt;所以會出現這種情況：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~/.codex/skills&lt;/code&gt; 裡已經有 skill&lt;/li&gt;
&lt;li&gt;但 &lt;code&gt;/&lt;/code&gt; 後面的列表裡沒有顯示&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這通常不代表 skill 壞了，更常見的原因是：&lt;strong&gt;當前會話沒有把它重新索引進去。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;怎樣讓-skill-被當前會話暴露&#34;&gt;怎樣讓 skill 被當前會話暴露
&lt;/h2&gt;&lt;p&gt;最實用的步驟就這幾條：&lt;/p&gt;
&lt;h3 id=&#34;1-目錄放對&#34;&gt;1. 目錄放對
&lt;/h3&gt;&lt;p&gt;全域：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;~/.codex/skills/&amp;lt;skill-name&amp;gt;/SKILL.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;專案級：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;專案/.codex/skills/&amp;lt;skill-name&amp;gt;/SKILL.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;2-skillmd-頭部可識別&#34;&gt;2. &lt;code&gt;SKILL.md&lt;/code&gt; 頭部可識別
&lt;/h3&gt;&lt;p&gt;最少要有：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-md&#34; data-lang=&#34;md&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;name: your-skill-name
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;description: 這個 skill 是做什麼的
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;3-新建或修改後開新會話&#34;&gt;3. 新建或修改後，開新會話
&lt;/h3&gt;&lt;p&gt;很多時候 skill 沒顯示，不是文件有問題，而是當前會話啟動時就已經把可用 skill 列表定下來了。&lt;/p&gt;
&lt;p&gt;所以你中途新建 skill，磁碟裡雖然已經有了，這次會話也未必會重新認。&lt;/p&gt;
&lt;p&gt;最穩的做法就是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;放好 skill&lt;/li&gt;
&lt;li&gt;結束當前會話&lt;/li&gt;
&lt;li&gt;重新進入專案&lt;/li&gt;
&lt;li&gt;開一個新會話&lt;/li&gt;
&lt;li&gt;再看 &lt;code&gt;/&lt;/code&gt; 裡有沒有出現&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;4-專案-skill-最好提前放好&#34;&gt;4. 專案 skill 最好提前放好
&lt;/h3&gt;&lt;p&gt;如果你想讓 &lt;code&gt;專案/.codex/skills&lt;/code&gt; 更穩定地被識別，最好在進入倉庫、啟動會話之前，就把這些 skill 放進專案裡。&lt;/p&gt;
&lt;h2 id=&#34;最後一句&#34;&gt;最後一句
&lt;/h2&gt;&lt;p&gt;最短結論就是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~/.codex/skills&lt;/code&gt; 是你的個人技能庫&lt;/li&gt;
&lt;li&gt;&lt;code&gt;專案/.codex/skills&lt;/code&gt; 是倉庫的本地規則庫&lt;/li&gt;
&lt;li&gt;skill 在目錄裡，不等於當前會話一定會顯示&lt;/li&gt;
&lt;li&gt;想讓它顯示，最常見的辦法就是放對目錄、寫好 &lt;code&gt;SKILL.md&lt;/code&gt;，然後開新會話&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>OpenAI 發布 GPT-5.5：更強的智慧體編碼、知識工作與科研能力</title>
        <link>https://knightli.com/zh-tw/2026/04/24/openai-gpt-5-5-release/</link>
        <pubDate>Fri, 24 Apr 2026 08:39:56 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/04/24/openai-gpt-5-5-release/</guid>
        <description>&lt;p&gt;OpenAI 在 2026 年 4 月 23 日發布了 &lt;a class=&#34;link&#34; href=&#34;https://openai.com/index/introducing-gpt-5-5/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Introducing GPT-5.5&lt;/a&gt;。從官方頁面來看，這次更新的重點不是單純「模型更聰明」，而是更強調模型能不能把複雜任務持續推進下去。&lt;/p&gt;
&lt;p&gt;官方給 GPT-5.5 的定位，是一個更適合真實工作的模型。它不只要回答問題，還要能寫程式、除錯、查資料、分析資料、產生文件和試算表、操作軟體，並在多個工具之間來回切換，直到任務完成。&lt;/p&gt;
&lt;h2 id=&#34;1-gpt-55-主要強在哪裡&#34;&gt;1. GPT-5.5 主要強在哪裡
&lt;/h2&gt;&lt;p&gt;這次發布頁裡反覆出現的幾個方向，可以概括為四類：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;智慧體編碼&lt;/li&gt;
&lt;li&gt;電腦操作與工具使用&lt;/li&gt;
&lt;li&gt;知識工作&lt;/li&gt;
&lt;li&gt;早期科研輔助&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是說，GPT-5.5 的重點不是短問短答，而是更長鏈路的任務。例如一個工程問題不只是「這段程式碼怎麼改」，而是要理解專案結構、定位失敗原因、修改相關檔案、補測試、驗證結果，並盡量減少使用者反覆提示。&lt;/p&gt;
&lt;p&gt;OpenAI 也特別強調，GPT-5.5 在 Codex 任務中更省 token。這點很實際，因為編碼智慧體一旦開始讀檔案、跑命令、修 bug，token 消耗會非常快。如果模型能用更少步驟完成同樣任務，實際成本和等待時間都會下降。&lt;/p&gt;
&lt;h2 id=&#34;2-編碼能力是這次最重要的展示方向&#34;&gt;2. 編碼能力是這次最重要的展示方向
&lt;/h2&gt;&lt;p&gt;官方稱 GPT-5.5 是目前最強的 agentic coding 模型。&lt;/p&gt;
&lt;p&gt;幾個公開指標裡，比較值得注意的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Terminal-Bench 2.0&lt;/code&gt;：GPT-5.5 達到 &lt;code&gt;82.7%&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SWE-Bench Pro&lt;/code&gt;：GPT-5.5 達到 &lt;code&gt;58.6%&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;OpenAI 內部的 &lt;code&gt;Expert-SWE&lt;/code&gt;：GPT-5.5 也高於 GPT-5.4&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些測試的共同點是，它們更接近真實工程流程，而不是只考單個演算法題。特別是 Terminal-Bench 這類任務，會涉及命令列操作、規劃、試錯、工具協調和多步驟驗證。&lt;/p&gt;
&lt;p&gt;對日常開發者來說，這裡的意義很直接：模型是否能接住更大的任務，取決於它能不能長時間保持上下文、自己檢查假設、知道什麼時候該跑測試、知道改動會影響哪裡。&lt;/p&gt;
&lt;p&gt;GPT-5.5 在 Codex 裡的價值，也主要體現在這些地方。它更像是可以接手一段工程任務的協作者，而不是只會補全程式碼片段的工具。&lt;/p&gt;
&lt;h2 id=&#34;3-知識工作開始變成重點場景&#34;&gt;3. 知識工作開始變成重點場景
&lt;/h2&gt;&lt;p&gt;除了寫程式，OpenAI 這次也把 GPT-5.5 放到了更廣的辦公場景裡。&lt;/p&gt;
&lt;p&gt;官方提到，GPT-5.5 在 Codex 中可以更好地產生文件、試算表和簡報，也更適合處理營運研究、試算表建模、業務材料整理這類任務。結合電腦操作能力之後，它的目標不是只給建議，而是能直接參與「找資料、理解內容、呼叫工具、檢查輸出、整理成結果」這整條流程。&lt;/p&gt;
&lt;p&gt;發布頁裡還提到 OpenAI 內部已經在多部門使用 Codex，包括軟體工程、財務、傳播、市場、資料科學和產品管理等。這裡真正值得關注的不是某個單點案例，而是 OpenAI 正在把 Codex 從開發工具擴展為通用工作工具。&lt;/p&gt;
&lt;p&gt;在 ChatGPT 裡，GPT-5.5 Thinking 面向 Plus、Pro、Business 和 Enterprise 使用者；GPT-5.5 Pro 則面向更難問題和更高準確率需求，提供給 Pro、Business 和 Enterprise 使用者。&lt;/p&gt;
&lt;h2 id=&#34;4-科研能力不只是答題更強&#34;&gt;4. 科研能力不只是「答題更強」
&lt;/h2&gt;&lt;p&gt;GPT-5.5 的科研展示也很重。&lt;/p&gt;
&lt;p&gt;官方提到它在遺傳學、定量生物學、生物資訊學、數學證明等方向都有改進。這裡的重點不是模型能不能背出一個知識點，而是能不能處理更接近真實研究的問題：讀資料、發現異常、提出分析方式、解釋結果，並根據中間結果繼續推進。&lt;/p&gt;
&lt;p&gt;發布頁裡提到的 &lt;code&gt;GeneBench&lt;/code&gt; 和 &lt;code&gt;BixBench&lt;/code&gt;，都更偏多階段科學分析任務。OpenAI 還提到，一個內部版本的 GPT-5.5 借助自訂工具鏈，幫助發現了關於 Ramsey numbers 的新證明，並用 Lean 做了驗證。&lt;/p&gt;
&lt;p&gt;這類案例還不能簡單理解為「AI 已經能獨立做科研」，但它說明模型正在從問答工具往研究協作者靠近。尤其是在程式碼、資料、論文、實驗想法混在一起的場景裡，GPT-5.5 的長鏈路推理和工具使用能力會更重要。&lt;/p&gt;
&lt;h2 id=&#34;5-推理效率更強但沒有明顯變慢&#34;&gt;5. 推理效率：更強但沒有明顯變慢
&lt;/h2&gt;&lt;p&gt;一個容易被忽略的點是，OpenAI 說 GPT-5.5 在真實服務中的 per-token latency 與 GPT-5.4 相當。&lt;/p&gt;
&lt;p&gt;通常更大的模型、更強的模型會帶來更高延遲。OpenAI 這次強調，它們透過推理系統最佳化，讓 GPT-5.5 在智慧提升的同時保持速度。發布頁裡還提到，Codex 分析生產流量模式並編寫負載分配相關啟發式演算法，使 token 產生速度提升超過 &lt;code&gt;20%&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;這個細節很有意思：模型不只被基礎設施服務，也反過來幫助改進服務它的基礎設施。&lt;/p&gt;
&lt;h2 id=&#34;6-安全策略會更嚴格尤其是網路安全方向&#34;&gt;6. 安全策略會更嚴格，尤其是網路安全方向
&lt;/h2&gt;&lt;p&gt;GPT-5.5 的網路安全能力更強，所以 OpenAI 同時加強了安全限制。&lt;/p&gt;
&lt;p&gt;官方說明中提到，GPT-5.5 在網路安全能力上比 GPT-5.4 有提升，因此會部署更嚴格的分類器，尤其針對高風險活動、敏感網路安全請求和重複濫用行為。&lt;/p&gt;
&lt;p&gt;這意味著一部分使用者在使用網路安全相關能力時，可能會遇到更多拒答或限制。OpenAI 也提供了 Trusted Access for Cyber，用於讓經過驗證的防禦性使用者獲得更少不必要阻礙。&lt;/p&gt;
&lt;p&gt;對普通開發者來說，可以簡單理解為：合法的安全加固、漏洞修復、程式碼審計會繼續被支援，但高風險攻擊鏈路會被更嚴格地控制。&lt;/p&gt;
&lt;h2 id=&#34;7-可用性與-api-價格&#34;&gt;7. 可用性與 API 價格
&lt;/h2&gt;&lt;p&gt;根據 OpenAI 發布頁，GPT-5.5 的可用性如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT：GPT-5.5 Thinking 面向 Plus、Pro、Business、Enterprise 使用者&lt;/li&gt;
&lt;li&gt;ChatGPT：GPT-5.5 Pro 面向 Pro、Business、Enterprise 使用者&lt;/li&gt;
&lt;li&gt;Codex：GPT-5.5 面向 Plus、Pro、Business、Enterprise、Edu、Go 方案&lt;/li&gt;
&lt;li&gt;Codex：上下文視窗為 &lt;code&gt;400K&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Codex Fast mode：產生速度約 &lt;code&gt;1.5x&lt;/code&gt;，成本為 &lt;code&gt;2.5x&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;API 方面，OpenAI 表示 &lt;code&gt;gpt-5.5&lt;/code&gt; 和 &lt;code&gt;gpt-5.5-pro&lt;/code&gt; 會很快開放。&lt;/p&gt;
&lt;p&gt;官方給出的 API 價格是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gpt-5.5&lt;/code&gt;：輸入 &lt;code&gt;5 美元 / 1M tokens&lt;/code&gt;，輸出 &lt;code&gt;30 美元 / 1M tokens&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gpt-5.5-pro&lt;/code&gt;：輸入 &lt;code&gt;30 美元 / 1M tokens&lt;/code&gt;，輸出 &lt;code&gt;180 美元 / 1M tokens&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gpt-5.5&lt;/code&gt; API 上下文視窗為 &lt;code&gt;1M&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Batch 和 Flex 為標準 API 價格的一半&lt;/li&gt;
&lt;li&gt;Priority processing 為標準價格的 &lt;code&gt;2.5x&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這個價格明顯高於很多日常模型，所以它更適合高價值任務：複雜工程改造、長文件分析、自動化辦公、科研輔助、重要業務流程，而不是普通閒聊。&lt;/p&gt;
&lt;h2 id=&#34;8-怎麼看這次發布&#34;&gt;8. 怎麼看這次發布
&lt;/h2&gt;&lt;p&gt;如果只看一句話，GPT-5.5 的重點是：OpenAI 正在把模型從「回答問題」繼續推向「完成工作」。&lt;/p&gt;
&lt;p&gt;它最值得關注的地方，不只是 benchmark 分數提升，而是幾種能力開始匯合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;更強的長任務保持能力&lt;/li&gt;
&lt;li&gt;更穩定的工具使用&lt;/li&gt;
&lt;li&gt;更好的工程上下文理解&lt;/li&gt;
&lt;li&gt;更適合文件、試算表、研究和業務流程&lt;/li&gt;
&lt;li&gt;更長上下文和更高 token 效率&lt;/li&gt;
&lt;li&gt;更嚴格的高風險能力控制&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;對開發者來說，最值得試的是 Codex 裡的複雜工程任務。對企業使用者來說，更值得關注的是它能不能把一部分跨工具、跨文件、跨流程的工作變成可交付結果。&lt;/p&gt;
&lt;p&gt;GPT-5.5 不是一次只面向聊天體驗的小更新，而更像是 OpenAI 在繼續推進「AI 作為工作執行層」的方向。&lt;/p&gt;
&lt;h2 id=&#34;相關連結&#34;&gt;相關連結
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://openai.com/index/introducing-gpt-5-5/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Introducing GPT-5.5 - OpenAI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>codex-quota 實戰指南：保留命令列的本機、Web 與 Docker 用法</title>
        <link>https://knightli.com/zh-tw/2026/04/16/codex-quota-cli-web-docker-guide/</link>
        <pubDate>Thu, 16 Apr 2026 18:13:04 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/04/16/codex-quota-cli-web-docker-guide/</guid>
        <description>&lt;h2 id=&#34;這個專案做什麼&#34;&gt;這個專案做什麼
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;codex-quota&lt;/code&gt; 是一個輕量工具，可查詢 ChatGPT Codex 配額使用情況，資料來源是 &lt;code&gt;https://chatgpt.com/backend-api/wham/usage&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;主要功能：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;支援單帳號或多帳號（&lt;code&gt;account/*.auth.json&lt;/code&gt;）查詢。&lt;/li&gt;
&lt;li&gt;輸出 &lt;code&gt;five_hour%&lt;/code&gt;、&lt;code&gt;weekly%&lt;/code&gt;、&lt;code&gt;weekly_reset&lt;/code&gt;，並標記來源（&lt;code&gt;network&lt;/code&gt; 或 &lt;code&gt;cache&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;對暫時性失敗（&lt;code&gt;408&lt;/code&gt;、&lt;code&gt;429&lt;/code&gt;、&lt;code&gt;5xx&lt;/code&gt;）做指數退避重試。&lt;/li&gt;
&lt;li&gt;內建本地快取，減少配額耗盡時的重複請求。&lt;/li&gt;
&lt;li&gt;提供 Web Dashboard、JSON API、auth 檔管理頁面。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;優點：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;輕量：單腳本即可執行，依賴簡單。&lt;/li&gt;
&lt;li&gt;實用：CLI 與 Web 兩種入口都能使用。&lt;/li&gt;
&lt;li&gt;可部署：支援 Docker 與 Docker Compose。&lt;/li&gt;
&lt;li&gt;易維運：支援重試、快取與定時刷新。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;先準備好帳號憑證&#34;&gt;先準備好帳號憑證
&lt;/h2&gt;&lt;p&gt;在 &lt;code&gt;account/&amp;lt;name&amp;gt;.auth.json&lt;/code&gt; 建立憑證檔，例如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;tokens&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;access_token&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;eyJ...&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;account_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;user-xxxxxxxx&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;說明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;access_token&lt;/code&gt; 與 &lt;code&gt;account_id&lt;/code&gt; 是查詢介面所需欄位。&lt;/li&gt;
&lt;li&gt;檔名中的 &lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt; 會作為結果中的帳號名稱。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;本機-cli-用法保留原命令&#34;&gt;本機 CLI 用法（保留原命令）
&lt;/h2&gt;&lt;p&gt;安裝依賴：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install -r requirements.txt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;說明：安裝專案執行依賴。&lt;/p&gt;
&lt;p&gt;查詢全部帳號：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python codex_quota.py
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;說明：讀取 &lt;code&gt;account/*.auth.json&lt;/code&gt;，彙總輸出所有帳號配額。&lt;/p&gt;
&lt;p&gt;查詢單一帳號：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python codex_quota.py your_account_name
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;說明：只查詢 &lt;code&gt;account/your_account_name.auth.json&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;強制刷新（跳過快取）：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python codex_quota.py --refresh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;說明：忽略本地快取，直接請求最新介面資料。&lt;/p&gt;
&lt;h2 id=&#34;cli-參數說明readme-對齊&#34;&gt;CLI 參數說明（README 對齊）
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;account_name&lt;/code&gt;：可選帳號名（不含 &lt;code&gt;.auth.json&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--account-dir&lt;/code&gt;：憑證目錄，預設 &lt;code&gt;account&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--chatgpt-url&lt;/code&gt;：配額介面位址。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--raw-json&lt;/code&gt;：輸出完整 JSON 回應體。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--raw-headers&lt;/code&gt;：輸出回應標頭。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--refresh&lt;/code&gt;：忽略快取。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--retries&lt;/code&gt;：重試次數，預設 &lt;code&gt;3&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--retry-delay&lt;/code&gt;：基礎重試間隔秒數，預設 &lt;code&gt;2.0&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;web-dashboard-用法保留原命令&#34;&gt;Web Dashboard 用法（保留原命令）
&lt;/h2&gt;&lt;p&gt;啟動服務：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python codex_quota_service.py --host 0.0.0.0 --port &lt;span class=&#34;m&#34;&gt;8081&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;說明：啟動 HTTP 服務並監聽 &lt;code&gt;8081&lt;/code&gt; 埠。&lt;/p&gt;
&lt;p&gt;存取位址：&lt;code&gt;http://localhost:8081&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Service 參數：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--host&lt;/code&gt;：監聽位址，預設 &lt;code&gt;0.0.0.0&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--port&lt;/code&gt;：服務埠，預設 &lt;code&gt;8081&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--interval-seconds&lt;/code&gt;：排程刷新間隔，預設 &lt;code&gt;3600&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--account-dir&lt;/code&gt;：憑證目錄，預設 &lt;code&gt;account&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--state-file&lt;/code&gt;：狀態檔路徑，預設 &lt;code&gt;&amp;lt;account-dir&amp;gt;/codex_quota_web_results.json&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--account-name&lt;/code&gt;：可選，單帳號模式。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--chatgpt-url&lt;/code&gt;：配額介面位址。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--retries&lt;/code&gt;：重試次數。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--retry-delay&lt;/code&gt;：基礎重試延遲。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--refresh&lt;/code&gt;：排程刷新時忽略 CLI 快取。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;http-介面方便接自動化&#34;&gt;HTTP 介面（方便接自動化）
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GET /&lt;/code&gt;：Dashboard 頁面。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /api/results&lt;/code&gt;：最新結果 JSON。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /refresh&lt;/code&gt;：立即刷新並跳回 &lt;code&gt;/&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /auth&lt;/code&gt;：列出 auth 檔。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /auth/new&lt;/code&gt;：新建 auth 檔表單。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /auth/edit?name=&amp;lt;account&amp;gt;&lt;/code&gt;：編輯 auth 檔表單。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POST /auth/save&lt;/code&gt;：建立/更新 auth 檔。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POST /auth/delete&lt;/code&gt;：刪除 auth 檔。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;docker-用法保留原命令&#34;&gt;Docker 用法（保留原命令）
&lt;/h2&gt;&lt;p&gt;建置映像：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker build -t codex-quota .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;說明：將目前專案打包為 &lt;code&gt;codex-quota&lt;/code&gt; 映像。&lt;/p&gt;
&lt;p&gt;執行容器（映射 8081）：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker run --rm -p 8081:8081 -v ./account:/app/account codex-quota
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;說明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--rm&lt;/code&gt;：容器退出後自動刪除。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p 8081:8081&lt;/code&gt;：主機埠映射到容器埠。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-v ./account:/app/account&lt;/code&gt;：把本地憑證目錄掛載進容器。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;存取位址：&lt;code&gt;http://localhost:8081&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;docker-compose-用法保留原命令&#34;&gt;Docker Compose 用法（保留原命令）
&lt;/h2&gt;&lt;p&gt;啟動：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose up --build
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;說明：依 &lt;code&gt;docker-compose.yml&lt;/code&gt; 建置並啟動服務。&lt;/p&gt;
&lt;p&gt;存取位址：&lt;code&gt;http://localhost:8081&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;使用建議&#34;&gt;使用建議
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;多帳號場景優先使用 Dashboard，便於統一查看與管理 auth 檔。&lt;/li&gt;
&lt;li&gt;告警或自動化整合優先使用 &lt;code&gt;GET /api/results&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;公開倉庫不要提交真實 &lt;code&gt;access_token&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;若看到大量暫時性錯誤，可調大 &lt;code&gt;--retries&lt;/code&gt; 與 &lt;code&gt;--retry-delay&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
</description>
        </item>
        <item>
        <title>Codex 額度怎麼算：5 小時限額、週限額與 Credit 消耗</title>
        <link>https://knightli.com/zh-tw/2026/04/15/codex-usage-limits-five-hour-weekly-credits/</link>
        <pubDate>Wed, 15 Apr 2026 22:50:00 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/04/15/codex-usage-limits-five-hour-weekly-credits/</guid>
        <description>&lt;p&gt;很多人第一次看 Codex 額度時，會以為 &lt;code&gt;5 小時限額&lt;/code&gt; 是一個短期餘額池，只有它用完之後才開始扣 &lt;code&gt;週限額&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;實際不是這樣。Codex 更像是同時檢查多個額度窗口：短窗口防止短時間爆量，週窗口限制一週總量。一次 Codex 使用通常會同時計入這兩個窗口。&lt;/p&gt;
&lt;p&gt;所以你看到：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;5 小時額度還剩很多
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;但 weekly 額度已經下降
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;通常是正常現象。&lt;/p&gt;
&lt;h2 id=&#34;01-先記住結論&#34;&gt;01 先記住結論
&lt;/h2&gt;&lt;p&gt;Codex 額度可以先按下面三句話理解：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;5 小時限額&lt;/code&gt; 和 &lt;code&gt;週限額&lt;/code&gt; 是同時生效，不是先後扣除。&lt;/li&gt;
&lt;li&gt;週限額用完後，即使 5 小時額度還有，通常也不能繼續用同一個訂閱額度池。&lt;/li&gt;
&lt;li&gt;Codex 不是簡單按訊息條數計費，而是和模型、tokens、任務複雜度、上下文、執行位置有關。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;用偽代碼表示就是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;can_use_codex =
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    five_hour_remaining &amp;gt; 0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;amp;&amp;amp; weekly_remaining &amp;gt; 0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;amp;&amp;amp; 沒有觸發其它產品策略限制
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;5 小時窗口重置，只恢復 5 小時額度；不會恢復 weekly 額度。weekly 額度要等自己的 reset，或者在支援的方案裡購買額外 credits。&lt;/p&gt;
&lt;h2 id=&#34;02-為什麼會同時扣兩個窗口&#34;&gt;02 為什麼會同時扣兩個窗口
&lt;/h2&gt;&lt;p&gt;可以把 Codex 的額度想成兩個閘門：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;窗口&lt;/th&gt;
          &lt;th&gt;作用&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;5 小時窗口&lt;/td&gt;
          &lt;td&gt;防止短時間高頻使用&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;週窗口&lt;/td&gt;
          &lt;td&gt;控制一週總使用量&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;每次 Codex 任務都會產生一次實際消耗。這個消耗會反映到目前相關的 rate limit 窗口裡。&lt;/p&gt;
&lt;p&gt;因此不是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;先扣 5 小時額度
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;5 小時額度用完後
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;再扣週額度
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;而更像是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;一次 Codex 請求
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;=&amp;gt; 計入 5 小時窗口
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;=&amp;gt; 同時計入週窗口
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這就是「5 小時額度沒用完，但 weekly 也在下降」的核心原因。&lt;/p&gt;
&lt;h2 id=&#34;03-現在更應該看-token-based-credits&#34;&gt;03 現在更應該看 token-based credits
&lt;/h2&gt;&lt;p&gt;OpenAI 沒有公開一個使用者可以完全複算的 Codex 扣費公式。官方公開的是 rate card、影響因素和不同模型的 credit 單價。&lt;/p&gt;
&lt;p&gt;截至 2026-04-15，Codex rate card 的主口徑已經是 &lt;code&gt;token-based credits&lt;/code&gt;。也就是根據輸入 tokens、快取輸入 tokens、輸出 tokens 折算 credits。&lt;/p&gt;
&lt;p&gt;官方給出的示例價格如下：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;模型&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;輸入 / 1M tokens&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;快取輸入 / 1M tokens&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;輸出 / 1M tokens&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;GPT-5.4&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;62.50 credits&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;6.250 credits&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;375 credits&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;GPT-5.4-Mini&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;18.75 credits&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;1.875 credits&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;113 credits&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;GPT-5.3-Codex&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;43.75 credits&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;4.375 credits&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;350 credits&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;GPT-5.2-Codex&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;43.75 credits&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;4.375 credits&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;350 credits&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;GPT-5.1-Codex-Max&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;31.25 credits&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;3.125 credits&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;250 credits&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;GPT-5.1-Codex-mini&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;6.25 credits&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;0.625 credits&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;50 credits&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;所以一個粗略估算公式是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;本次消耗
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;≈ 輸入 tokens / 1,000,000 × 模型輸入單價
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ 快取輸入 tokens / 1,000,000 × 模型快取輸入單價
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ 輸出 tokens / 1,000,000 × 模型輸出單價
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這不是精確帳單公式，但足夠解釋趨勢：輸出很貴，長上下文很貴，高能力模型更貴。官方還說明 &lt;code&gt;Fast mode&lt;/code&gt; 會消耗 2 倍 credits，&lt;code&gt;Code review&lt;/code&gt; 使用 GPT-5.3-Codex 的價格。&lt;/p&gt;
&lt;h2 id=&#34;04-不要再只看訊息條數&#34;&gt;04 不要再只看「訊息條數」
&lt;/h2&gt;&lt;p&gt;同樣發 10 次 Codex，消耗可能完全不同。&lt;/p&gt;
&lt;p&gt;輕量任務通常更省：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;改一個小函式&lt;/li&gt;
&lt;li&gt;解釋一段短程式碼&lt;/li&gt;
&lt;li&gt;寫一小段文案&lt;/li&gt;
&lt;li&gt;在明確文件裡做局部修改&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;重任務會更貴：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;掃描大型程式碼庫&lt;/li&gt;
&lt;li&gt;長時間執行 agent&lt;/li&gt;
&lt;li&gt;多輪讀取、編輯、測試、修復&lt;/li&gt;
&lt;li&gt;產生大量程式碼或長報告&lt;/li&gt;
&lt;li&gt;使用 cloud task&lt;/li&gt;
&lt;li&gt;開啟 fast mode&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此，&lt;code&gt;訊息數量&lt;/code&gt; 只能作為很粗略的感覺，不能用來判斷真實消耗。&lt;/p&gt;
&lt;h2 id=&#34;05-local-task-和-cloud-task-的差別&#34;&gt;05 local task 和 cloud task 的差別
&lt;/h2&gt;&lt;p&gt;Codex 裡很容易拉開消耗差距的是執行位置。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;local task&lt;/code&gt; 更像是在你的本地工作區裡讀文件、改程式碼、跑命令。&lt;code&gt;cloud task&lt;/code&gt; 則把任務交給雲端環境託管執行，適合更長、更自動化的流程。&lt;/p&gt;
&lt;p&gt;從額度角度看，cloud task 往往更貴。原因也很直接：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需要雲端執行環境&lt;/li&gt;
&lt;li&gt;任務通常更長&lt;/li&gt;
&lt;li&gt;工具調用更多&lt;/li&gt;
&lt;li&gt;上下文更大&lt;/li&gt;
&lt;li&gt;自動化鏈路更完整&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果只是普通程式碼編輯、文章整理、局部修復，優先 local task 會更省。cloud task 更適合確實需要雲端託管的任務。&lt;/p&gt;
&lt;h2 id=&#34;06-為什麼-weekly-掉得特別快&#34;&gt;06 為什麼 weekly 掉得特別快
&lt;/h2&gt;&lt;p&gt;如果你覺得「5 小時額度沒怎麼動，但 weekly 掉很多」，常見原因有這些：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用了 cloud task。&lt;/li&gt;
&lt;li&gt;使用了更貴的模型。&lt;/li&gt;
&lt;li&gt;開啟了 fast mode。&lt;/li&gt;
&lt;li&gt;上下文很大，Codex 讀了很多文件或保留了很長對話。&lt;/li&gt;
&lt;li&gt;輸出很長，比如大量程式碼、長報告、長日誌分析。&lt;/li&gt;
&lt;li&gt;任務鏈很長，比如搜尋、編輯、測試、修復、再測試。&lt;/li&gt;
&lt;li&gt;自己的額度腳本把窗口標籤解析錯了。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果你是用腳本讀 &lt;code&gt;/backend-api/wham/usage&lt;/code&gt; 之類的字段，不要只看加工後的 &lt;code&gt;five_hour%&lt;/code&gt;、&lt;code&gt;weekly%&lt;/code&gt;。最好先看 raw JSON 裡的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;limit_window_seconds&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;percent_left&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reset_at&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;bucket / feature 名稱&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;常見窗口長度可以這樣判斷：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;limit_window_seconds = 18000
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;=&amp;gt; 約 5 小時窗口
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;limit_window_seconds = 604800
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;=&amp;gt; 約 7 天窗口
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果腳本把兩個窗口標反，就會誤判額度變化。&lt;/p&gt;
&lt;h2 id=&#34;07-更省額度的使用方式&#34;&gt;07 更省額度的使用方式
&lt;/h2&gt;&lt;p&gt;想讓 weekly 撐得久一點，可以這樣用：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;把大任務拆成小任務。先處理一個文件、一個 bug、一個功能點。&lt;/li&gt;
&lt;li&gt;能 local 就 local，謹慎使用 cloud task。&lt;/li&gt;
&lt;li&gt;明確告訴 Codex 相關路徑，減少無關掃描。&lt;/li&gt;
&lt;li&gt;避免一次塞入巨大日誌、長文件、無關上下文。&lt;/li&gt;
&lt;li&gt;輕量任務可以用更便宜的 mini 模型。&lt;/li&gt;
&lt;li&gt;長任務前先讓 Codex 出計畫，再進入執行。&lt;/li&gt;
&lt;li&gt;不需要長報告時，明確要求「簡短回答」。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;最實用的記憶方式是：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;是否能繼續用
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;= 短窗口還有額度
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;amp;&amp;amp; 週窗口還有額度
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;消耗快不快
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;= 模型價格
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;× tokens
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;× 輸出長度
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;× 任務複雜度
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;× 執行位置
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這個模型不能精確對帳，但足夠解釋大多數 Codex 額度現象。&lt;/p&gt;
&lt;h2 id=&#34;相關連結&#34;&gt;相關連結
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/11369540-using-codex-with-your-chatgpt-plan&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Using Codex with your ChatGPT plan - OpenAI Help Center&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/11481834&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ChatGPT Rate Card - OpenAI Help Center&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/zh-hans-cn/articles/20001106-codex-rate-card&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Codex rate card - OpenAI Help Center&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/12642688-using-credits-for-flexible-usage-in-chatgpt-pluspro&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Using Credits for Flexible Usage in ChatGPT - OpenAI Help Center&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Codex 額度用量統計</title>
        <link>https://knightli.com/zh-tw/2026/04/12/codex-usage-quota-check/</link>
        <pubDate>Sun, 12 Apr 2026 00:01:33 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/04/12/codex-usage-quota-check/</guid>
        <description>&lt;p&gt;如果你想查看 Codex 目前帳號的額度剩餘情況，可以直接寫一個小腳本去請求 ChatGPT 的 &lt;code&gt;/backend-api/wham/usage&lt;/code&gt; 介面。&lt;/p&gt;
&lt;p&gt;這類腳本的思路很簡單：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;從 &lt;code&gt;auth.json&lt;/code&gt; 裡讀取 &lt;code&gt;tokens.access_token&lt;/code&gt; 和 &lt;code&gt;tokens.account_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;請求 &lt;code&gt;https://chatgpt.com/backend-api/wham/usage&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在請求標頭裡帶上 &lt;code&gt;Authorization: Bearer ...&lt;/code&gt; 和 &lt;code&gt;ChatGPT-Account-Id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;解析回傳結果裡的五小時窗口和週窗口額度&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;適合做什麼&#34;&gt;適合做什麼
&lt;/h2&gt;&lt;p&gt;這個方法適合你在本地快速確認：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;五小時額度還剩多少&lt;/li&gt;
&lt;li&gt;週額度還剩多少&lt;/li&gt;
&lt;li&gt;額度會在什麼時候重置&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你有多個帳號，也可以讓腳本批次讀取 &lt;code&gt;account/*.auth.json&lt;/code&gt;，統一輸出一張摘要表。你目前登入的 ChatGPT 帳號所對應的 &lt;code&gt;auth.json&lt;/code&gt;，通常可以在 &lt;code&gt;~/.codex/&lt;/code&gt; 目錄下找到。&lt;/p&gt;
&lt;h2 id=&#34;最關鍵的輸入&#34;&gt;最關鍵的輸入
&lt;/h2&gt;&lt;p&gt;腳本通常只依賴兩項憑證：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;access_token&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;account_id&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它們通常都可以從本地 &lt;code&gt;auth.json&lt;/code&gt; 中取得。只要這兩個值有效，請求標頭就能按下面的形式組織：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;Authorization&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Bearer &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;auth_token&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;application/json&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;ChatGPT-Account-Id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;auth_account_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;Origin&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://chatgpt.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;Referer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://chatgpt.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;回傳結果怎麼看&#34;&gt;回傳結果怎麼看
&lt;/h2&gt;&lt;p&gt;介面回傳後，重點看的是兩類窗口：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;five_hour&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;weekly&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;腳本可以把它們統一整理成下面幾項：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;剩餘額度百分比&lt;/li&gt;
&lt;li&gt;重置時間&lt;/li&gt;
&lt;li&gt;對應的時間窗口長度&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果介面欄位名稱有差異，也可以順手相容 &lt;code&gt;primary_window&lt;/code&gt;、&lt;code&gt;secondary_window&lt;/code&gt;、&lt;code&gt;five_hour_limit&lt;/code&gt;、&lt;code&gt;weekly_limit&lt;/code&gt; 這些變體。&lt;/p&gt;
&lt;h2 id=&#34;常見問題&#34;&gt;常見問題
&lt;/h2&gt;&lt;p&gt;如果腳本回傳 401，通常表示 &lt;code&gt;access_token&lt;/code&gt; 已過期或無效。&lt;/p&gt;
&lt;p&gt;如果回傳 403，通常表示目前帳號沒有權限存取這個介面，或者帳號狀態異常。&lt;/p&gt;
&lt;p&gt;如果你看到同一個回應裡欄位命名不一致，也不用太意外。實際處理時最好先把不同命名方式統一映射後再輸出。&lt;/p&gt;
&lt;h2 id=&#34;參考連結&#34;&gt;參考連結
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;codex-auth-manager&lt;/code&gt;：&lt;a class=&#34;link&#34; href=&#34;https://github.com/RioArisk/codex-auth-manager&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/RioArisk/codex-auth-manager&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;程式碼&#34;&gt;程式碼
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;  1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 54
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 55
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 56
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 57
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 58
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 59
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 60
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 61
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 62
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 63
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 64
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 65
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 66
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 67
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 68
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 69
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 70
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 71
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 72
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 73
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 74
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 75
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 76
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 77
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 78
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 79
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 80
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 81
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 82
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 83
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 84
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 85
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 86
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 87
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 88
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 89
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 90
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 91
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 92
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 93
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 94
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 95
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 96
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 97
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 98
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 99
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;100
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;101
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;102
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;103
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;104
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;105
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;106
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;107
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;108
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;109
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;110
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;111
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;112
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;113
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;114
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;115
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;116
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;117
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;118
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;119
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;120
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;121
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;122
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;123
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;124
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;125
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;126
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;127
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;128
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;129
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;130
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;131
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;132
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;133
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;134
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;135
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;136
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;137
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;138
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;139
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;140
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;141
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;142
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;143
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;144
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;145
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;146
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;147
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;148
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;149
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;150
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;151
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;152
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;153
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;154
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;155
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;156
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;157
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;158
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;159
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;160
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;161
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;162
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;163
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;164
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;165
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;166
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;167
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;168
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;169
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;170
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;171
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;172
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;173
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;174
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;175
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;176
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;177
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;178
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;179
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;180
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;181
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;182
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;183
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;184
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;185
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;186
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;187
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;188
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;189
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;190
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;191
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;192
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;193
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;194
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;195
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;196
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;197
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;198
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;199
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;200
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;201
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;202
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;203
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;204
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;205
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;206
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;207
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;208
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;209
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;210
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;211
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;212
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;213
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;214
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;215
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;216
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;217
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;218
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;219
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;220
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;221
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;222
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;223
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;224
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;225
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;226
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;227
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;228
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;229
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;230
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;231
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;232
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;233
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;234
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;235
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;236
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;237
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;238
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;239
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;240
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;241
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;242
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;243
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;244
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;245
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;246
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;247
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;248
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;249
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;250
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;251
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;252
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;253
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;254
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;255
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;256
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;257
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;258
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;259
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;260
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;261
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;262
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;263
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;264
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;265
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;266
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;267
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;268
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;269
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;270
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;271
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;272
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;273
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;274
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;275
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;276
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;277
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;278
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;279
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;280
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;281
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;282
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;283
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;284
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;285
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;286
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;287
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;288
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;289
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;290
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;291
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;292
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;293
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;294
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;295
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;296
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;297
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;298
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;299
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;300
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;301
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;302
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;303
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;304
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;305
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;306
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;307
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;308
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;309
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;310
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;311
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;312
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;313
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;314
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;315
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;316
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;317
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;318
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;319
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;320
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;321
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;322
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;323
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;324
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;325
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;326
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;327
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;328
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;329
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;330
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;331
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;332
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;333
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;334
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;335
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;336
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;337
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;338
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;339
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;340
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;341
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;342
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;343
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;344
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;345
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;346
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;347
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;348
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;349
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;350
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;351
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;352
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;353
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;354
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;355
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;356
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;357
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;358
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;359
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;360
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;361
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;362
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;363
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;364
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;365
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;366
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;367
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;368
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;369
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;370
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;371
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;372
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;373
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;374
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;375
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;376
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;377
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;378
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;379
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;380
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;381
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;382
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;383
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;384
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;385
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;386
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;387
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;388
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;389
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;390
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;391
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;392
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;393
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;394
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;395
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;396
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;397
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;398
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;399
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;400
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;401
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;402
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;403
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;404
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;405
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;406
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;407
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;408
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;409
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;410
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;411
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;412
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;413
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;414
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;415
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;416
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;417
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;418
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;419
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;420
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;421
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;422
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;423
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;424
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;425
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;426
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;427
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;428
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;429
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;430
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;431
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;432
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;433
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;434
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;435
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;436
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;437
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;438
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;439
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;440
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;441
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;442
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;443
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;444
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;445
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;446
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;447
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;448
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;449
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;450
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;451
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;452
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;453
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;454
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;455
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;456
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;457
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;458
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;459
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;460
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;argparse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;base64&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;datetime&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;timedelta&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;timezone&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pathlib&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typing&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;requests&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;UTC&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;timezone&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;utc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;CST&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;timezone&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timedelta&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hours&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;CST&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;parse_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argparse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argparse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Query ChatGPT Codex usage from /backend-api/wham/usage.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;account_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;nargs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;?&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Account name used to load account/&amp;lt;account_name&amp;gt;.auth.json. If omitted, load all *.auth.json files in account/.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;--account-dir&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;account&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Directory containing &amp;lt;account_name&amp;gt;.auth.json files.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;--chatgpt-url&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://chatgpt.com/backend-api/wham/usage&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;ChatGPT usage endpoint.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;--raw-json&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;action&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;store_true&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Print the full JSON response body.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;--raw-headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;action&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;store_true&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Print response headers.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;print_json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dumps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;indent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ensure_ascii&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;load_auth_json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path_str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path_str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path_str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;expanduser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;loads&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read_text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;OSError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JSONDecodeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;get_nested_string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;current&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;format_dt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dt&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;-&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;astimezone&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CST&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strftime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;%Y-%m-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%d&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; %H:%M:%S %Z&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;format_cst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;format_dt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;epoch_ms_to_dt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;raw&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;TypeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;ValueError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# Newer responses sometimes use epoch seconds, older ones use epoch milliseconds.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;timestamp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;raw&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;raw&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;**&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;11&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;raw&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fromtimestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tz&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;first_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;decode_jwt_exp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;token&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;payload&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;payload&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;=&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;payload&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;loads&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;base64&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;urlsafe_b64decode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;payload&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;encode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;ascii&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;exp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;exp&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exp&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fromtimestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tz&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;ValueError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;TypeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JSONDecodeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;get_percent_left&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;percent_left&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;percent_left&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;percent_left&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;percent_left&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;remaining_percent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;percent_left&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;percent_left&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;used_percent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;used_percent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;used_percent&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;used_percent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;TypeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;ValueError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;resolve_limit_window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;reset_at&amp;#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;reset_time_ms&amp;#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;primary_window&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;primary_window&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;parse_limit_entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;resolve_limit_window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;percent_left&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_percent_left&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;reset_time_ms&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;reset_time_ms&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reset_time_ms&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;reset_time_ms&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;reset_at&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;window_seconds&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;limit_window_seconds&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;percent_left&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;percent_left&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;reset_time_ms&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reset_time_ms&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;reset_at&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;epoch_ms_to_dt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reset_time_ms&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;limit_window_seconds&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;window_seconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;infer_limit_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;window_seconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;window_seconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;window_seconds&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3600&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;five_hour&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;window_seconds&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;24&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3600&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;relabel_rate_limits&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;secondary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;entry&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;secondary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;inferred_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;infer_limit_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;limit_window_seconds&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inferred_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inferred_name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;secondary&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;secondary&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;five_hour&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;secondary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly&amp;#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;secondary&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;secondary&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;secondary&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;five_hour&amp;#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;secondary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;secondary&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;parse_rate_limits&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;secondary&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;primary_key&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;five_hour&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;five_hour_limit&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;five_hour_rate_limit&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;primary&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;primary_key&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_limit_entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;five_hour&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;primary_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;secondary_key&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly_limit&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly_rate_limit&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;secondary&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;secondary_key&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;secondary&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_limit_entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;secondary_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;secondary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_limit_entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;five_hour&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;primary_window&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;secondary&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;secondary&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_limit_entry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;secondary_window&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;relabel_rate_limits&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;primary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;secondary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;format_percent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;-&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;percent_sort_value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;descending&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;numeric_value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;numeric_value&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;descending&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;numeric_value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;get_auth_paths&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;base_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;base_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.auth.json&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;base_dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;glob&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;*.auth.json&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;get_account_name_from_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;suffix&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.auth.json&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[:&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;suffix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)]&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;endswith&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;suffix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stem&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;build_summary_row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;five_hour&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weekly&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;account&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;five_hour_percent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;five_hour&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;percent_left&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;five_hour&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly_percent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weekly&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;percent_left&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weekly&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly_reset_at&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weekly&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;reset_at&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weekly&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;print_summary_rows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;sorted_rows&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;rows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;percent_sort_value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;row&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;five_hour_percent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;descending&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;percent_sort_value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;row&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly_percent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;descending&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;format_cst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;row&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly_reset_at&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;account&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;display_rows&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;row&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sorted_rows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;display_rows&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;s2&#34;&gt;&amp;#34;account&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;account&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;s2&#34;&gt;&amp;#34;five_hour&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;format_percent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;row&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;five_hour_percent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;format_percent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;row&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly_percent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly_reset&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;format_cst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;row&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly_reset_at&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;account&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;account&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;five_hour&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;five_hour%&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly%&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly_reset&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;weekly_reset&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;widths&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]),&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;display_rows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;key&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;account&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;widths&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;account&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;  &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;five_hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;widths&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;five_hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;  &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;weekly&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;widths&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;weekly&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;  &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;weekly_reset&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;widths&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;weekly_reset&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;display_rows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;account&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;widths&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;account&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;  &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;five_hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;widths&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;five_hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;  &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;weekly&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;widths&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;weekly&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;  &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;weekly_reset&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;widths&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;weekly_reset&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;validate_token_inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;account_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;auth_token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;auth_account_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;token&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;startswith&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;sess-&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;status: invalid_token_type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;s2&#34;&gt;&amp;#34;message: --chatgpt-token looks like a session token (sess-...). Use the JWT access_token instead.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;auth_token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;s2&#34;&gt;&amp;#34;hint: Found tokens.access_token in auth.json; omit --chatgpt-token or pass that value instead.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;token_exp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;decode_jwt_exp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;token_exp&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;token_exp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UTC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;status: expired&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;message: access_token expired at &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;format_dt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;token_exp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;auth_token&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;auth_token&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;auth_token_exp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;decode_jwt_exp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;auth_token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;hint&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;format_dt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;auth_token_exp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;auth_token_exp&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;unknown time&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;hint: auth.json contains a different access_token expiring at &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hint&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;auth_account_id&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account_id&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;auth_account_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;warning: supplied --account-id does not match auth.json tokens.account_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;handle_error_response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;raw_json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status_code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;401&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;status: expired&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;message: Token 宸茶繃鏈熸垨鏃犳晥&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;raw_json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;print_json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status_code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;403&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;status: forbidden&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;message: 璐﹀彿宸茶灏佺鎴栨棤鏉冭闂?, file=sys.stderr)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;raw_json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;print_json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status_code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;400&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status_code&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;print_json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;fetch_chatgpt_usage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;auth_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argparse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;auth_data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;load_auth_json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;auth_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_account_name_from_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;auth_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;auth_token&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_nested_string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;auth_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;tokens&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;access_token&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;auth_account_id&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_nested_string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;auth_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;tokens&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;account_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;auth_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: auth file not found or invalid&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;auth_token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: missing access_token&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;auth_account_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: missing account_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;validation_error&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;validate_token_inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;auth_token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;auth_account_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;auth_token&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;auth_account_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;validation_error&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;validation_error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;Authorization&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Bearer &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;auth_token&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;application/json&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;ChatGPT-Account-Id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;auth_account_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;Origin&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://chatgpt.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;Referer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://chatgpt.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chatgpt_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;timeout&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;60&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;requests&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RequestException&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Request failed: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exc&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raw_headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;=== Headers ===&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;print_json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;ValueError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status_code&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;error_response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;handle_error_response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raw_json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;error_response&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;error_response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raw_json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;=== Raw JSON ===&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;print_json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;rate_limits&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;first_dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;rate_limit&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;rate_limits&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rate_limits&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;build_summary_row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;five_hour&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weekly&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_rate_limits&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rate_limits&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;build_summary_row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;five_hour&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;weekly&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;auth_paths&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_auth_paths&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;auth_paths&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;No auth files found.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;exit_code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;summary_rows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JSONDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;auth_path&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;auth_paths&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;current_exit_code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;summary_row&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fetch_chatgpt_usage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;auth_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;exit_code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exit_code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_exit_code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;summary_row&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raw_json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;summary_rows&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;summary_row&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;summary_rows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;print_summary_rows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;summary_rows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exit_code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
        </item>
        <item>
        <title>使用 AI 維護 Hugo 多語言部落格的 Agent Skill</title>
        <link>https://knightli.com/zh-tw/2026/04/06/agent-skill-sync-post-translations-guide/</link>
        <pubDate>Mon, 06 Apr 2026 10:00:00 +0800</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/04/06/agent-skill-sync-post-translations-guide/</guid>
        <description>&lt;p&gt;如果你正在維護 Hugo 多語言部落格，常常會遇到一個高頻痛點：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;中文寫完後，還要同步生成英文與繁體版本&lt;/li&gt;
&lt;li&gt;三個語言檔需要保持結構一致&lt;/li&gt;
&lt;li&gt;front matter 既要翻譯，也要符合 Hugo 格式&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;sync-post-translations&lt;/code&gt; 就是為這個場景設計的 Agent Skill。&lt;/p&gt;
&lt;h2 id=&#34;這個技能解決什麼問題&#34;&gt;這個技能解決什麼問題
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;sync-post-translations&lt;/code&gt; 的定位很清楚：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;以 &lt;code&gt;index.zh-cn.md&lt;/code&gt; 作為來源檔&lt;/li&gt;
&lt;li&gt;在同一目錄生成或更新 &lt;code&gt;index.en.md&lt;/code&gt;、&lt;code&gt;index.zh-tw.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;保持 Markdown 結構一致&lt;/li&gt;
&lt;li&gt;對 front matter 套用明確規則（尤其是 &lt;code&gt;date&lt;/code&gt;、&lt;code&gt;slug&lt;/code&gt;）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;適用觸發詞示例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;「同步翻譯英文繁體」&lt;/li&gt;
&lt;li&gt;「把這篇文章同步成英文和繁體」&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;技能目錄結構&#34;&gt;技能目錄結構
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.\sync-post-translations\
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├─ SKILL.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└─ agents\
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   └─ openai.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;核心程式碼一skillmd&#34;&gt;核心程式碼一：SKILL.md
&lt;/h2&gt;&lt;p&gt;以下是此技能的核心規則檔：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;name: sync-post-translations
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;description: 将 Hugo 文章从简体中文源文件（&lt;span class=&#34;sb&#34;&gt;`index.zh-cn.md`&lt;/span&gt;）同步翻译为英文（&lt;span class=&#34;sb&#34;&gt;`index.en.md`&lt;/span&gt;）和繁体中文（&lt;span class=&#34;sb&#34;&gt;`index.zh-tw.md`&lt;/span&gt;）。当用户提出“en 繁体”“同步翻译英文繁体”或要求同时生成/更新两种语言版本且需保持 front matter 与 Markdown 结构一致时使用。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gh&#34;&gt;# 同步文章翻译
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;使用此技能为同一篇文章生成或更新多语言版本。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## 工作流程
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;1.&lt;/span&gt; 在目标文章目录中定位源文件 &lt;span class=&#34;sb&#34;&gt;`index.zh-cn.md`&lt;/span&gt;。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;2.&lt;/span&gt; 读取完整 front matter 与正文内容。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;3.&lt;/span&gt; 在同目录创建或更新 &lt;span class=&#34;sb&#34;&gt;`index.en.md`&lt;/span&gt; 与 &lt;span class=&#34;sb&#34;&gt;`index.zh-tw.md`&lt;/span&gt;。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;4.&lt;/span&gt; 确保三语结构对齐后执行 Hugo 构建检查。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## 翻译规则
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;1.&lt;/span&gt; 严格保留 &lt;span class=&#34;sb&#34;&gt;`slug`&lt;/span&gt; 原值。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;2.&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`date`&lt;/span&gt; 统一规范为 Hugo 常用带时间格式（RFC3339），示例：&lt;span class=&#34;sb&#34;&gt;`2026-04-05T10:00:00+08:00`&lt;/span&gt;。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;3.&lt;/span&gt; 自然翻译以下 front matter 字段：&lt;span class=&#34;sb&#34;&gt;`title`&lt;/span&gt;、&lt;span class=&#34;sb&#34;&gt;`description`&lt;/span&gt;、&lt;span class=&#34;sb&#34;&gt;`tags`&lt;/span&gt;、&lt;span class=&#34;sb&#34;&gt;`categories`&lt;/span&gt;。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;4.&lt;/span&gt; 保持 Markdown 结构不变：标题层级、列表形态、代码块、链接与命令行示例。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;5.&lt;/span&gt; 技术标识符保持原样：文件名、CLI 参数、模型名、设备名、URL、包名等。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;6.&lt;/span&gt; 若 YAML 的 &lt;span class=&#34;sb&#34;&gt;`title`&lt;/span&gt; 含有 &lt;span class=&#34;sb&#34;&gt;`:`&lt;/span&gt;，必须加引号，避免解析报错。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;7.&lt;/span&gt; 在不改变语义前提下，使用目标语言自然标点与表达习惯（&lt;span class=&#34;sb&#34;&gt;`en`&lt;/span&gt;、&lt;span class=&#34;sb&#34;&gt;`zh-tw`&lt;/span&gt;）。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## 输出约定
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;1.&lt;/span&gt; 仅在源文章同目录写入目标文件。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;2.&lt;/span&gt; 汇报变更的文件路径。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;3.&lt;/span&gt; 条件允许时执行 &lt;span class=&#34;sb&#34;&gt;`hugo --source . --destination public`&lt;/span&gt;，并反馈通过/失败；失败时给出关键报错行。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## 质量标准
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;1.&lt;/span&gt; 全文术语前后一致。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;2.&lt;/span&gt; 避免机器直译感，优先可发布文风。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;3.&lt;/span&gt; 章节内容完整，不省略示例、注意点与总结。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;核心程式碼二agentsopenaiyaml&#34;&gt;核心程式碼二：agents/openai.yaml
&lt;/h2&gt;&lt;p&gt;這個檔案定義了技能在 Agent 端的展示與預設提示詞：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;interface&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;display_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;同步文章翻译&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;short_description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;生成或更新 EN + ZH-TW 翻译稿&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;default_prompt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;使用该技能在同一 Hugo 文章目录中，从 `index.zh-cn.md` 生成或同步 `index.en.md` 与 `index.zh-tw.md`，保留 `date` 与 `slug`，保持 Markdown 结构一致，并执行 Hugo 构建校验。&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;實戰調用示例&#34;&gt;實戰調用示例
&lt;/h2&gt;&lt;h3 id=&#34;1-面向人的自然語言觸發&#34;&gt;1) 面向人的自然語言觸發
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;请把 content/post/2026/04/06/index.zh-cn.md 同步翻译成英文和繁体，
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;要求 date 用 RFC3339，slug 不变，最后跑 hugo 校验。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;2-你應該期待的輸出結果&#34;&gt;2) 你應該期待的輸出結果
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;已更新：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- content/post/2026/04/06/index.en.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- content/post/2026/04/06/index.zh-tw.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;构建校验：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- hugo --source . --destination public
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- 结果：PASS
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;為什麼這些規則很關鍵&#34;&gt;為什麼這些規則很關鍵
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;code&gt;slug&lt;/code&gt; 保持不變，可以穩定 URL 與歷史外鏈。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;date&lt;/code&gt; 統一為 RFC3339（含時區）可避免 Hugo/主題在時間解析上的歧義。&lt;/li&gt;
&lt;li&gt;Markdown 結構不變，可避免翻譯後目錄、程式碼區塊、短代碼渲染錯位。&lt;/li&gt;
&lt;li&gt;技術標識符不翻譯，可顯著降低「命令不可用／檔名不匹配」問題。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;常見坑位與規避&#34;&gt;常見坑位與規避
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;code&gt;title&lt;/code&gt; 裡有 &lt;code&gt;:&lt;/code&gt; 卻沒加引號，YAML 會解析失敗。&lt;/li&gt;
&lt;li&gt;把 &lt;code&gt;--flag&lt;/code&gt;、URL、套件名翻譯了，示例命令會直接失效。&lt;/li&gt;
&lt;li&gt;三語標題層級不一致（例如中文 &lt;code&gt;##&lt;/code&gt; 變成英文 &lt;code&gt;###&lt;/code&gt;），目錄錨點會錯位。&lt;/li&gt;
&lt;li&gt;只翻譯正文不處理 front matter，頁面列表與 SEO 資訊會異常。&lt;/li&gt;
&lt;/ol&gt;
</description>
        </item>
        <item>
        <title>普通人如何指揮 AI 幹活：從圖片中提取圖形與數學公式（實戰示例）</title>
        <link>https://knightli.com/zh-tw/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8F%AE-ai-%E5%B9%B9%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9C%96%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B8%E5%AD%B8%E5%85%AC%E5%BC%8F/</link>
        <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8F%AE-ai-%E5%B9%B9%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9C%96%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B8%E5%AD%B8%E5%85%AC%E5%BC%8F/</guid>
        <description>&lt;h2 id=&#34;前提條件&#34;&gt;前提條件
&lt;/h2&gt;&lt;p&gt;安裝 VS Code，並安裝 Codex 外掛，可參考 &lt;a class=&#34;link&#34; href=&#34;../01/index.md&#34; &gt;這篇文章&lt;/a&gt;。&lt;br&gt;
使用這些工具並不要求你有程式設計經驗。VS Code 在這裡主要用於整理檔案；你只需提出需求，AI 就會自動編寫程式並執行。&lt;br&gt;
本文記錄完整操作過程，目的是拋磚引玉，探索更多 AI 的實用方法，讓更多普通人受益。&lt;/p&gt;
&lt;h2 id=&#34;任務目標&#34;&gt;任務目標
&lt;/h2&gt;&lt;p&gt;準備一張同時包含數學公式與示意圖形的圖片：
&lt;img src=&#34;https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/1.png&#34;
	width=&#34;793&#34;
	height=&#34;205&#34;
	srcset=&#34;https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/1_hu_ca2eeaa88b9a2128.png 480w, https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/1_hu_966a8a23af7f38d6.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;386&#34;
		data-flex-basis=&#34;928px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;我們希望實現三件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;將圖形切分成乾淨的小圖。&lt;/li&gt;
&lt;li&gt;識別公式並轉換為 LaTeX，方便後續修改。&lt;/li&gt;
&lt;li&gt;將圖形與對應公式建立關聯。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;過程&#34;&gt;過程
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;先識別圖片，生成 Markdown 文件，並將公式轉換為 LaTeX
&lt;img src=&#34;https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/2-1.png&#34;
	width=&#34;1009&#34;
	height=&#34;1059&#34;
	srcset=&#34;https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/2-1_hu_682f636c00f5879.png 480w, https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/2-1_hu_4a9ed5f6454d2b48.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;95&#34;
		data-flex-basis=&#34;228px&#34;
	
&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;轉換結果：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;54
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;55
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;56
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;57
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;58
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;59
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;60
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;61
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;62
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;63
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;64
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;65
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;66
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;67
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;68
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;69
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;70
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;71
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# 1.png 識別結果
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;## 幾何公式（LaTeX）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1. 三角形面積（邊長與外接圓半徑）：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;S = \frac{abc}{4R}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2. 三角形面積（內切圓半徑與半周長）：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;S = pr
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;3. 圓台體積：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;V = \frac{\pi\left(r^2 + Rr + R^2\right)h}{3}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;4. 圓台側面積：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;S = \pi a(R + r)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;5. 圓柱體積：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;V = \pi r^2 h
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;6. 圓柱側面積：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;S = 2\pi rh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;7. 球體積：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;V = \frac{4}{3}\pi R^3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;8. 球表面積：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;S = 4\pi R^2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;9. 正弦定理：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;\frac{a}{\sin A}=\frac{b}{\sin B}=\frac{c}{\sin C}=2R
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;10. 餘弦定理：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;a^2=b^2+c^2-2bc\cos A
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;b^2=a^2+c^2-2ac\cos B
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;c^2=a^2+b^2-2ab\cos C
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/2-2.png&#34;
	width=&#34;831&#34;
	height=&#34;1253&#34;
	srcset=&#34;https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/2-2_hu_ecfd835a086d5e6b.png 480w, https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/2-2_hu_bdd02e889793f78f.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;66&#34;
		data-flex-basis=&#34;159px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;公式都被識別出來了，AI 還自動補充了公式名稱，效果很好；但此時還沒有完成小圖裁剪。&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;嘗試讓 AI 裁剪圖片
&lt;img src=&#34;https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/3-1.png&#34;
	width=&#34;1368&#34;
	height=&#34;1615&#34;
	srcset=&#34;https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/3-1_hu_8fcc60d87f237172.png 480w, https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/3-1_hu_8f5bbfed32d47a1d.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;84&#34;
		data-flex-basis=&#34;203px&#34;
	
&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;54
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;55
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;56
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;57
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;58
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;59
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;60
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;61
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;62
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;63
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;64
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;65
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;66
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;67
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;68
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;69
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;70
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;71
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;72
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;73
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;74
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;75
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;76
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;77
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;78
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;79
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;80
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;81
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;82
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;83
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;84
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;85
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;86
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;87
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;88
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# 1.png 識別結果（圖文並排，精修裁圖）
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;table&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &amp;lt;tr&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;lt;td&amp;gt;![](crops/01_triangle_circum.png)&amp;lt;/td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;lt;td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;S = \frac{abc}{4R}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;/td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &amp;lt;/tr&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &amp;lt;tr&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;lt;td&amp;gt;![](crops/02_triangle_incircle.png)&amp;lt;/td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;lt;td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;S = pr
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;/td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &amp;lt;/tr&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &amp;lt;tr&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;lt;td&amp;gt;![](crops/03_frustum.png)&amp;lt;/td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;lt;td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;V = \frac{\pi\left(r^2 + Rr + R^2\right)h}{3}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;S = \pi a(R + r)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;/td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &amp;lt;/tr&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &amp;lt;tr&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;lt;td&amp;gt;![](crops/04_cylinder.png)&amp;lt;/td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;lt;td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;V = \pi r^2 h
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;S = 2\pi rh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;/td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &amp;lt;/tr&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &amp;lt;tr&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;lt;td&amp;gt;![](crops/05_sphere.png)&amp;lt;/td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;lt;td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;V = \frac{4}{3}\pi R^3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;S = 4\pi R^2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;/td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &amp;lt;/tr&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &amp;lt;tr&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;lt;td&amp;gt;![](crops/06_laws.png)&amp;lt;/td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;lt;td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;\frac{a}{\sin A}=\frac{b}{\sin B}=\frac{c}{\sin C}=2R
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;a^2=b^2+c^2-2bc\cos A
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;b^2=a^2+c^2-2ac\cos B
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;c^2=a^2+b^2-2ab\cos C
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$$
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;/td&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &amp;lt;/tr&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;/table&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;結果：
&lt;img src=&#34;https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/3-2.png&#34;
	width=&#34;810&#34;
	height=&#34;1154&#34;
	srcset=&#34;https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/3-2_hu_5e27dd3893009a44.png 480w, https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/3-2_hu_d0ccd10683fc4506.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;70&#34;
		data-flex-basis=&#34;168px&#34;
	
&gt;
圖片已經裁剪並放到了對應位置，但仍有干擾區域，裁剪邊緣不夠乾淨。&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;修正「裁切過度」問題：先盡量保留完整圖形，再手工去除多餘部分&lt;br&gt;
這一步的效果還不穩定，目前不確定是提示詞問題，還是模型在視覺定位上的波動。
&lt;img src=&#34;https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/4-1.png&#34;
	width=&#34;805&#34;
	height=&#34;1295&#34;
	srcset=&#34;https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/4-1_hu_90e248256e5d9819.png 480w, https://knightli.com/2026/03/26/%E6%99%AE%E9%80%9A%E4%BA%BA%E5%A6%82%E4%BD%95%E6%8C%87%E6%8C%A5-ai-%E5%B9%B2%E6%B4%BB-%E6%8F%90%E5%8F%96%E5%9B%BE%E5%BD%A2-%E6%8F%90%E5%8F%96%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/4-1_hu_cccfbcada80166e1.png 1024w&#34;
	loading=&#34;lazy&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;62&#34;
		data-flex-basis=&#34;149px&#34;
	
&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;總結&#34;&gt;總結
&lt;/h2&gt;&lt;p&gt;使用 Codex 和直接在 chatgpt.com 對話，體驗明顯不同。&lt;br&gt;
在 chatgpt.com 中，更像是 AI 在引導你完成工作；而在 Codex 中，更像是 AI 按照你的要求去執行工作。&lt;br&gt;
當你提出需求後，AI 會生成程式、執行程式並完成任務，你會更明顯地感受到「自己在指揮 AI 幹活」。&lt;br&gt;
整個流程對程式設計基礎要求並不高，普通人也可以逐步上手並產出成果。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>如何在 VS Code 中使用 Codex（從安裝到高效實戰）</title>
        <link>https://knightli.com/zh-tw/2026/03/20/%E5%A6%82%E4%BD%95%E5%9C%A8-vs-code-%E4%B8%AD%E4%BD%BF%E7%94%A8-codex/</link>
        <pubDate>Fri, 20 Mar 2026 00:00:00 +0000</pubDate>
        
        <guid>https://knightli.com/zh-tw/2026/03/20/%E5%A6%82%E4%BD%95%E5%9C%A8-vs-code-%E4%B8%AD%E4%BD%BF%E7%94%A8-codex/</guid>
        <description>&lt;p&gt;Codex 可以直接在 VS Code 側邊欄中協助你寫程式、改 Bug、解釋專案與執行命令。&lt;/p&gt;
&lt;h2 id=&#34;1-準備工作&#34;&gt;1. 準備工作
&lt;/h2&gt;&lt;p&gt;開始前請確認：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VS Code 已更新到較新的穩定版本。&lt;/li&gt;
&lt;li&gt;你可以正常訪問 OpenAI 網站。&lt;/li&gt;
&lt;li&gt;專案程式碼已在本地開啟（建議使用 Git 倉庫）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;2-安裝擴充套件&#34;&gt;2. 安裝擴充套件
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;開啟 VS Code 的擴充套件市集（Extensions）。&lt;/li&gt;
&lt;li&gt;搜尋並安裝：&lt;code&gt;Codex - Codex - OpenAI&#39;s coding agent&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;安裝完成後，依提示完成登入授權。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;3-開啟-codex-側邊欄&#34;&gt;3. 開啟 Codex 側邊欄
&lt;/h2&gt;&lt;p&gt;你可以透過任一方式開啟：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在編輯器右上角點擊 &lt;code&gt;Open Codex Sidebar&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;使用命令面板（&lt;code&gt;Ctrl + Shift + P&lt;/code&gt;）搜尋 &lt;code&gt;Codex&lt;/code&gt; 並開啟。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;開啟後，Codex 會讀取目前工作區上下文，進入可對話狀態。&lt;/p&gt;
&lt;h2 id=&#34;4-常見使用方式&#34;&gt;4. 常見使用方式
&lt;/h2&gt;&lt;h3 id=&#34;41-讓它解釋程式碼&#34;&gt;4.1 讓它解釋程式碼
&lt;/h3&gt;&lt;p&gt;示例提示詞：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;請解釋這個檔案的核心邏輯，並指出最可能出錯的 3 個地方。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;適合你剛接手舊專案時快速建立全域理解。&lt;/p&gt;
&lt;h3 id=&#34;42-讓它實作功能&#34;&gt;4.2 讓它實作功能
&lt;/h3&gt;&lt;p&gt;示例提示詞：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;在現有 API 裡新增一個 /healthz 健康檢查介面，
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;要求回傳版本號與資料庫連線狀態，並補上基礎測試。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;建議把「輸入約束」與「驗收標準」一起寫清楚，產生結果會穩定很多。&lt;/p&gt;
&lt;h3 id=&#34;43-讓它修復問題&#34;&gt;4.3 讓它修復問題
&lt;/h3&gt;&lt;p&gt;示例提示詞：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;這個介面在併發下偶發 500，請先定位根因，再給出最小改動修復方案，
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;最後列出回歸測試點。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;先「定位」再「修復」，能減少誤改與過度重構。&lt;/p&gt;
&lt;h2 id=&#34;5-高品質提示詞模板&#34;&gt;5. 高品質提示詞模板
&lt;/h2&gt;&lt;p&gt;你可以直接複用下面這個結構：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;背景：這是一個 &amp;lt;技術棧&amp;gt; 專案，目前目標是 &amp;lt;目標&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;約束：不改動 &amp;lt;模組/介面&amp;gt;，相容 &amp;lt;版本/平台&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;輸出：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1) 修改檔案列表
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2) 關鍵程式碼說明
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;3) 驗證步驟
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;4) 風險與回滾方案
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;這個模板對「多人協作 + 大專案」非常有幫助。&lt;/p&gt;
&lt;h2 id=&#34;6-常見問題&#34;&gt;6. 常見問題
&lt;/h2&gt;&lt;h3 id=&#34;61-關於免費額度&#34;&gt;6.1 關於免費額度
&lt;/h3&gt;&lt;p&gt;在對話框輸入 &lt;code&gt;\&lt;/code&gt;，然後選擇「狀態」，會出現額度、重置時間等相關資訊。&lt;/p&gt;
&lt;h3 id=&#34;62-改動不符合預期&#34;&gt;6.2 改動不符合預期
&lt;/h3&gt;&lt;p&gt;修改完成後查看審核按鈕，檢查修改細節；不滿意可選擇撤銷按鈕以回退修改。
在後續步驟中可以把需求拆小，分成多個步驟分別執行。
使用 Git 等程式碼管理工具，保持小步提交（small commits），方便回滾。&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
