iT邦幫忙

2026 iThome 鐵人賽

DAY 4
1
AI Engineering

同一把尺,30 天橫評 AI Agent Skill:從單篇實測到一份能查的選用指南系列 第 4 篇

Day 4 | 我問 Claude「現在該怎麼寫」,結果它答的是半年前的正確答案

  • 分享至 

  • xImage
  •  

上禮拜我遇到一件小事,但後來越想越不安。

我在寫一段要打 Anthropic API 的程式碼,想省點 token 成本,就順口問了 Claude「現在要怎麼開 prompt caching」。它給了一段看起來完全正常的程式碼,語氣篤定,格式漂亮,連注解都寫好了。我照著貼進專案,跑起來也沒報錯。

問題是,那段寫法是半年前的寫法。不是錯的,是舊的——舊到剛好漏掉一個後來才加進去、會讓事情變簡單很多的捷徑。模型不是在騙我,它是真心相信自己講的是對的,因為在它的訓練資料裡,那就是最新、也是唯一的答案。它沒有說謊的意圖,但它也沒有辦法知道自己不知道。

這件事讓我想起這系列一直在講的核心提醒:任務做得順、跑得動、模型講得很有自信,都不等於答案是對的。Day 1 測 Atomic Commit,發現「任務做對」跟「Skill 被叫到」是兩回事;Day 2 測 code-review,發現「有沒有叫 Skill」跟「找得準不準」也是兩回事。今天想測的,是另一種更根本、也更容易被忽略的落差:模型自己講得再篤定,也不代表那件事現在還是對的。

這篇要聊的工具叫 context7,一個專門解決這個問題的 MCP 服務。我會把整個測試過程、兩組完整的回答、還有我自己去核對原始碼查到的答案,都攤開來講——包括我自己在測試設計上留下的一個瑕疵,也不會藏起來。

先用一張技能卡把它是什麼講清楚,後面再慢慢展開:

技能卡|context7

  • 來源:第三方 MCP 服務(Upstash 架設,context7@claude-plugins-official),不是 Anthropic 官方,但在 Claude Code 生態裡知名度很高
  • 觸發條件:不是關鍵字被動觸發,要明確呼叫——先 resolve-library-id 把套件名稱解析成標準 ID,再用 query-docs 針對一個具體問題查文件
  • 指令限制:官方文件要求「一次只問一個概念」,問太廣會答非所問
  • 輸出契約:回傳真實文件片段+來源連結,不是先幫你消化過的摘要——跟 Day 2 測的 code-review(結構化發現清單)是不同類型的輸出
  • 這次證據狀態:手動 A/B,1 個問題、盲測基線 vs context7 輔助各跑 1 輪,另外我自己也直接查了一次原始碼當 ground truth(樣本數很小,見後面「誠實交代」段落)

為什麼這件事值得認真對待

如果你平常也用 AI 寫程式,這個問題你一定遇過,只是可能沒意識到。模型的訓練資料有一個截止日期,但你用的函式庫、SDK、框架,不會因為模型不知道就停止更新。越是熱門、越是快速迭代的專案——Next.js、LangChain、各家的 SDK——版本差異就越明顯。模型不會主動告訴你「這個答案可能已經過時了」,因為它根本不知道自己落後了。它只會用一模一樣篤定的語氣,講一個可能已經不對的答案。

這正是這次要測的東西:一個宣稱能「即時查詢文件、補上訓練資料空白」的工具,實際上做不做得到。這不是抽象的疑慮,AI Engineering 這個賽道官方列出的範疇裡,就明講了「context management」是核心能力之一——怎麼幫模型補上它原本看不到的資訊,本來就是這個領域該解決的問題,不是我自己加的考題。

先搞懂 prompt caching 在幹嘛,才看得懂等一下的差異

在講測試結果之前,得先花一點篇幅講清楚 prompt caching 到底是什麼,不然接下來的比較你會看不出差異在哪裡值得在意。

每次呼叫 Claude 的 API,你送出去的內容(系統提示、對話歷史、參考文件)都要重新算一次,算得越多,花的錢跟時間就越多。如果你的系統提示很長、或者每次呼叫都會帶著同一份很大的參考文件,這些內容其實根本沒有變,重複計算是浪費。Prompt caching 做的事,是把這些「重複出現、沒有變化」的內容標記起來,讓伺服器端記住這段內容處理過的結果,下次呼叫如果開頭前綴完全一樣,就直接用快取的結果,不用重新算。

具體怎麼標記,就是在某個內容區塊上加一個 cache_control 欄位。這個機制有幾個實際會影響你荷包跟行為的細節:

  • 快取是「前綴比對」:從對話最開頭比對到你標記的那個點,只要中間有一個字元不一樣,這個斷點就失效,等於白標記。這代表如果你的系統提示裡藏了會變動的東西(時間戳記、隨機 ID、沒排序的 JSON 鍵值),快取會悄悄失效,而且不會報錯——你只會發現帳單比預期貴,卻找不到原因。
  • 一個請求最多只能標 4 個斷點,超過會被忽略或報錯,所以怎麼選斷點的位置本身是個設計問題。
  • 寫入快取比一般 token 貴,讀取快取比一般 token 便宜很多——大約是寫入貴 1.25 倍(5 分鐘存活時間)到 2 倍(1 小時存活時間),讀取只要原價的一折左右。這代表快取只有在「同一段內容會被重複呼叫很多次」的情境下才划算,用錯地方反而更貴。
  • 回傳的 usage 物件裡有 cache_creation_input_tokens 跟 cache_read_input_tokens 兩個欄位,可以拿來確認快取到底有沒有真的命中——這是唯一能驗證「我做對了沒有」的方式,光看程式碼跑不跑得動看不出來。

這些細節本身就有一定的學習曲線,也正因為這樣,一個文件裡藏著的小改動——比如新增了一種更簡單的標記方式——很容易被漏掉,而且漏掉了也不會立刻出事,只是多花了一點不必要的力氣或成本。這正是今天要測的東西。

我怎麼設計這次測試

我請 context7 幫我查了一次 Anthropic Python SDK 關於 prompt caching 的原始文件,自己先看過一輪,確認裡面有一個具體、可以核對真假的細節:SDK 的型別定義裡,cache_control 除了原本「標在個別內容區塊上」的用法,還多了一個頂層捷徑——直接在 messages.create() 這一層帶一個 cache_control 參數,系統會自動幫你標到請求裡最後一個可以快取的區塊,不用自己一個一個去找位置標記。這是我自己先去讀 SDK 原始碼確認過的,不是聽誰說的。

有了這個「已知答案」,我就可以设计一個乾淨的對照實驗:問同一個問題——「在 Anthropic 的 Python SDK 裡,目前要怎麼在 messages.create() 開啟 prompt caching,給出具體、正確、最新的寫法」——派兩組全新、互不知情的 Claude 去答。一組完全不給任何工具,純粹憑訓練資料回答;一組明講「請先用 context7 查過文件再回答」。兩組都是全新的對話,不知道對方的存在,也不知道我已經先查過答案。

兩組完整的回答,攤開來看

先看沒有用 context7 的那組講了什麼(節錄關鍵段落):

Prompt caching 不是 messages.create() 的一個獨立參數,而是在個別的 content block(不是整個 message、也不是整個 request)上加一個 cache_control 欄位,值目前只有 {"type": "ephemeral"} 這一種。

response = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    system=[
        {
            "type": "text",
            "text": "<很長的 system prompt>",
            "cache_control": {"type": "ephemeral"}
        }
    ],
    messages=[...]
)

舊版需要在 header 加 anthropic-beta: prompt-caching-2024-07-31 才能用;印象中這個功能後來已經 GA(正式上線),不再需要這個 beta header——但我沒有把握這點在你現在用的 SDK 版本上是否還殘留需要,建議你實測一次確認會不會報錯。

這個 1 小時選項我記得當初是以 beta 功能上線的,需要額外的 beta header……這個 beta 名稱與是否已經轉正我記不準,是我印象裡最不確定的一塊,麻煩實際呼叫前自己確認一次。

這段回答其實寫得很扎實:前綴比對的機制講對了、4 個斷點上限講對了、快取成本的比例級距也講對了。而且它有一個我很欣賞的地方——它自己知道哪裡沒把握,用一整段「沒把握、建議你再核實」明講出來,沒有硬湊一個聽起來篤定的答案去掩蓋不確定。這是一個誠實的模型該有的樣子。

但誠實不等於正確。它從頭到尾都不知道「頂層捷徑」這個寫法存在,因為這是它訓練資料裡沒有的東西——不是它疏忽漏講,是它的世界裡根本沒有這個選項。再看用了 context7 的那組怎麼答:

cache_control 是一個可以標在任何內容區塊上的欄位……messages.create() 本身有一個頂層 cache_control 參數,會自動幫你標在「請求中最後一個可快取的區塊」上:

response = client.messages.create(
    model="claude-opus-5",
    max_tokens=16000,
    cache_control={"type": "ephemeral"},
    system="你是這份大型文件的專家...",
    messages=[{"role": "user", "content": "摘要重點"}]
)

cache_control(含 ttl: "1h")在目前的 SDK 是穩定功能,走一般的 client.messages.create(...),不需要任何 betas=[...] 旗標或走 client.beta.messages。

差別不是誰寫得比較有條理,是這一組確實知道多一種寫法存在,而且明確答對了「已經不需要 beta header」這件事——這正是前一組猶豫不決、最後選擇誠實承認不確定的地方。

我自己回頭去翻了 SDK 原始碼裡的型別定義,cache_control 跟它的 ttl 欄位直接寫在穩定版的 MessageCreateParamsBase 裡,沒有被任何 beta 條件包住——用了 context7 那組講的是對的。

還有一個很小、但很說明問題的細節:沒用工具那組的範例程式碼裡,模型名稱寫的是 claude-sonnet-4-5。這不是打字打錯,是它訓練資料裡「最新」的模型就長這樣——這個系列現在用的是 Sonnet 5,中間已經隔了一整個世代。它不是不知道自己在講舊東西,是它根本不知道有新東西存在,這正是整篇文章想講的核心問題。

這三個差異,對你實際寫程式碼有什麼意義

把這次測出來的落差拆成三件具體的事,你自己評估用不用得上:

第一,如果你現在的程式碼還在逐個 content block 手動標記快取斷點,可以考慮改用頂層捷徑簡化。 適用情境是「你只需要快取到最後一個可快取區塊為止的所有內容」,不需要精細控制多個斷點——這種情況下頂層寫法少一層巢狀結構,維護起來更輕鬆。但如果你需要在對話中間插多個斷點(比如系統提示跟參考文件分開快取),還是得用逐區塊標記的舊寫法,頂層捷徑只能標一個點。

第二,1 小時 TTL 已經是穩定功能,不用再繞 client.beta.messages 這條路。 如果你的專案裡還留著為了這個功能特別寫的 beta 呼叫邏輯,可以檢查一下是不是已經可以簡化成一般呼叫——少一層 beta 條件分支,程式碼會乾淨一點,也少一個未來 SDK 版本升級時可能悄悄壞掉的地方。

第三,也是我覺得最容易被忽略的一點:快取失效不會報錯,只會讓你多付錢。 前綴比對這個機制代表任何一個你沒注意到的變動——系統提示裡塞了 datetime.now()、用 json.dumps() 卻沒加 sort_keys=True、工具清單每次呼叫順序不一樣——都會讓快取整個失效,而且程式照樣正常執行,只是 cache_read_input_tokens 一直是 0,你要主動去看這個數字才會發現異常。這個提醒兩組答案都沒有講得很清楚,是我自己去對照原始文件時才發現的細節,值得你在自己的程式碼裡主動加一個檢查,定期確認快取真的有命中,而不是假設「標了 cache_control 就一定有效」。

context7 這個工具本身是怎麼運作的

拆解一下 context7 到底做了什麼,讓它能講出訓練資料裡沒有的答案。它不是一個被動觸發的 Skill,不會因為你的對話裡出現某個關鍵字就自動跳出來,而是要明確呼叫,分成兩步:先用 resolve-library-id 把你講的套件名稱(例如「Anthropic Python SDK」)解析成 context7 自己的標準格式 ID(/anthropics/anthropic-sdk-python),再用這個 ID 搭配一個具體的問題去 query-docs。官方說明書特別強調每次查詢要「只問一個概念」,問題問得太廣或一次塞好幾個主題,回來的答案會答非所問,這點在我實際使用時也感覺得出來——問得越具體,回來的原始碼片段跟出處連結越精準。

它回傳的東西也跟這系列前幾天測過的工具不太一樣。Day 2 測的 code-review 回傳的是「結構化發現清單」,每條都有檔案、行號、嚴重度;context7 回傳的是「帶引用出處的原始文件片段」——直接把 GitHub 上的原始碼或官方文件連結一起附上,讓你自己去核對,而不是先幫你消化過再告訴你結論。這個設計本身就是一種誠實:它不假裝自己懂,只負責把最新的一手資料搬過來,判斷交給模型(或你)自己做。

context7 背後接的是 Upstash 公司架設的一個遠端 MCP 伺服器,不需要在本機額外裝 Node.js 或跑 npx,直接連線就能用;不登入也能用(匿名模式),如果查詢量大,可以申請一組 API key 換取更高的速率限制。在 Claude Code 裡,它是官方外掛市集裡的一個項目,透過外掛管理介面就能找到並啟用,不需要手動寫設定檔——這點我自己在這台機器上查證過,不是道聽塗說。

值得一提的是,它不是 Claude Code 專屬的東西。因為底層走的是標準的 MCP 協定,任何支援 MCP 的用戶端——Cursor、Windsurf,或是你自己寫的 agent 程式——理論上都能接上同一個遠端伺服器,設定方式大同小異:指到 https://mcp.context7.com/mcp 這個位址,要不要帶 API key 看你的用量需求。如果你平常主力用的不是 Claude Code,這個工具也不會因此用不上。

如果你想自己動手試

這裡整理成一個實際可以照著做的檢查清單,不是空泛地說「你可以試試看」:

  • 先確認你的用戶端支援 MCP。 Claude Code、Cursor、Windsurf 這類主流 agentic 編輯器現在都支援,如果你用的是比較舊或比較小眾的工具,先查一下官方文件有沒有提到 MCP 相容性。
  • 在 Claude Code 裡,透過外掛市集啟用 context7@claude-plugins-official,不用自己手刻設定檔;如果你的用戶端不支援外掛市集,就手動把遠端伺服器位址加進 MCP 設定裡。
  • 匿名模式就能先試用,不用一開始就申請 API key;只有真的查詢量大、常常撞到速率限制,才需要考慮申請。
  • 問問題的時候盡量具體、一次只問一個概念——官方文件自己就講了這個限制,我在這次測試裡也感受得到,問得越窄,回來的原始碼片段跟出處連結越精準;問一句「跟我講講這個框架」通常只會換來一堆泛用的入門介紹,沒有太大意義。
  • 回來的答案還是要自己核對出處連結,不要因為它掛著「查過文件」的標籤就照單全收——這也是我自己在寫這篇的時候做的事,去翻了 SDK 原始碼的型別定義,才敢講「這個答案是對的」,不是因為工具講了就直接信。

誠實交代這次測試留下的一個漏洞

這篇文章的立場一直是「沒驗證過的話不能寫進正文」,所以這裡也要老實講一個瑕疵:負責使用 context7 的那組,除了呼叫 context7 之外,似乎也順手看了本機一份內建的 SDK 文件當作參照,不是乾乾淨淨只用 context7 一個來源回答。這代表這次「有用工具」那組的優勢,不能百分之百歸功於 context7 一個工具,也有可能是「有查過任何額外資料」這個更廣泛的行為帶來的效果。

這是我在派工指令裡沒有講清楚邊界造成的——下次要更明確限制受測那組只能用被指定的單一工具,不能自己額外決定要不要查別的地方。我沒有選擇把這個瑕疵藏起來重新包裝成一次「乾淨」的實驗,因為這系列的整個價值就建立在「沒驗證過的東西不能講成結果」這條線上,連自己踩到的線都要算數。

另外要說清楚的是,這次的樣本數是 1——一個問題、一輪一輪的比較,不是統計上有意義的規模。我能有把握講的是「這一題,這一次,context7 那組答對了訓練資料答不出來的東西」,不能直接跳到「context7 永遠比較準」這種結論。工具會不會有查錯、查到過時文件、或者查詢寫得不夠精準而查不到重點的時候,這次沒有測到,需要之後累積更多題目才看得出來。

這個問題不只發生在 prompt caching

寫到這裡我想岔開一句,講一個更大的提醒。今天挑的例子剛好是 prompt caching,是因為它有明確的版本差異、又有原始碼可以核對,方便做成一次乾淨的測試。但這件事的本質,不是「prompt caching 這個主題容易過時」,是任何一個你問 AI「現在該怎麼做」的問題,都潛在有同一個風險——只是有些主題你剛好懂、能一眼看出答案不對;有些主題你完全不熟,只能照單全收。

我自己後來養成一個習慣,遇到「現在最新、最正確的做法是什麼」這種問句時,會多問自己一句:模型有沒有機會查證,還是只能憑印象回答?如果答案關係到會不會多付錢、會不會踩到已經棄用的 API、會不會用了一個已經被取代的寫法,我會傾向多花十秒鐘讓它去查一次文件,而不是直接相信它講得多篤定。篤定的語氣從來不是正確的證據,這句話我在這系列已經講了三次,但每次測試都還是會被重新印證一次,代表它真的值得一直放在心上,不是說一次就過去的場面話。

今天的判斷

如果你也常常靠 AI 寫程式碼,這次測試想留給你的提醒很簡單:模型講得篤定,不代表答案是新的。 它沒有辦法知道自己不知道什麼,這不是它的錯,是訓練資料本身的性質決定的。context7 這類工具解決的正是這個結構性問題——不是讓模型變聰明,是讓它有機會去查一下,而不是憑印象作答。這次測出來的差異夠具體、夠可以核對:一個訓練資料裡沒有的頂層捷徑,一個被誤判成還需要 beta 資格的穩定功能,兩者都不是模糊的「感覺比較好」,是查得到來源、能被別人重新驗證的事實。

至於這個工具本身值不值得裝,這篇還不夠格下結論——一次測試、一個問題,遠遠不夠。但至少今天證明了一件事:這類「幫模型補上時效性資訊」的工具,解決的是一個真實存在、而且會悄悄發生的問題,不是廠商編出來的痛點。


上一篇
Day 3 | 接下來不測我自己做的,先講清楚為什麼、測什麼方向
下一篇
Day 5 | 我們自己在用的記憶外掛,這次換我來查它有沒有在唬爛
系列文
同一把尺,30 天橫評 AI Agent Skill:從單篇實測到一份能查的選用指南 共 11 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言