iT邦幫忙

2026 iThome 鐵人賽

DAY 5
1
Claude AI

從 LLM 到 Agent:用 Claude 拆解現代 AI 工程的每一層系列 第 5

建構代理的知識庫:把檔案給它看

  • 分享至 

  • xImage
  •  

把話講清楚用範例教把常用的交代存起來之後,還是有一類問題,問法再好也沒用:

「我上個月那份報告裡,關於成本的那段結論是什麼?」

它不知道。不是答得不好,是真的沒有這個資訊。這就是第一篇說的第二個洞:它不知道你的事。

補這個洞的東西有一個名字:知識庫(knowledge base)。說穿了就是一批你指定給它看的資料,放在模型外面,要用的時候才送進窗口。今天你在專案裡上傳幾份文件是它,之後代理自己去查的那個來源也是它,差別只在誰決定送哪幾段進去。這一層六篇處理的都是這句話。

今天進第三層「外部知識」,而且是最直接的第一步:把你的東西整份給它看。


30 秒實驗

先問一次,再給一次,比較差別。

第一步:開新對話,直接問一個只有你自己的文件才答得出來的問題。它會做兩件事之一:老實說不知道,或是給你一個聽起來很合理、但其實是猜的答案。後者才是危險的那個。

第二步:把那份文件上傳,再問一次同樣的問題,並且追問一句「這是文件裡哪一段講的?」

差別不只是「答對了」,而是它現在可以引用你文件裡的句子。你可以回去對照,這件事很重要,後面會再回來講。

放檔案的地方有兩種,在這一層會一路分道揚鑣(名稱以你的介面為準):拖進對話這次有效,換個對話就沒了;放進專案的知識庫放一次,那個專案裡每個對話都拿得到。今天先用第一種,因為它最單純:你放什麼進去,它就看到什麼。


它為什麼寧可猜,也不說不知道

第一步那個「聽起來很合理」的答案有個名字,叫幻覺(hallucination)。它不長得像亂碼:參數叫什麼、部署在星期幾,格式對、語氣篤定,只有內容是填出來的。問法救不了這一類錯,因為問題不在你怎麼問。

Why Language Models Hallucinate(Kalai et al., 2025)的說法是:訓練與評測獎勵猜測、不獎勵承認不確定。像考試一樣,不會的題目猜一個,期望分數比空白高,模型於是被最佳化成一個很會考試的考生;作者主張該改的是那些「答不出來零分、猜錯也零分」的評分方式。

這跟今天的事直接相關:給不給它資料,決定它有沒有東西可以答;改不改評分方式,決定它沒東西的時候要不要閉嘴。 今天只處理前半句。


它不知道的事,其實有兩種

第一種是你的東西,業界叫它私有資料(private data)、專有知識(proprietary knowledge):內部文件、私有程式庫、上個月那份報告。這些從來沒有出現在訓練資料裡,再大的模型也不會憑空長出來。

第二種是太晚發生的事。模型的參數知識有一個日期,這個日期叫知識截止日(knowledge cutoff)官方文件把它列成表格的一列(2026-09-19 查):

模型 可靠知識截止日 訓練資料截止日
Claude Opus 5 2026 年 5 月 2026 年 5 月
Claude Sonnet 5 2026 年 1 月 2026 年 1 月
Claude Haiku 4.5 2025 年 2 月 2025 年 7 月

值得看的是兩欄為什麼要分開。官方的定義是:可靠知識截止日是「知識最完整、最可靠」的那個日期,訓練資料截止日則是用到的資料的較大範圍。Haiku 4.5 差了五個月,意思是那五個月的東西它看過,但你不該指望

所以「它知道到什麼時候」是一段越靠近越模糊的區間。這兩種不知道,第三層用同一個動作補:在它回答之前,把該知道的字放進去。


權重是凍結的,會變的只有這一次的輸入

第 3 篇提過情境學習不改任何權重,上一篇引的那句脈絡工程定義裡也藏了一個詞:「在推論時挑選並維護窗口裡最合適的那組詞元」。現在把那個詞講清楚。

模型的一生只有兩段。訓練把海量文字壓成一組權重,這一段早就結束了,結束的日期就是上面那張表。第二段叫推論(inference),是你每次送出請求時發生的事:把窗口裡的全部內容跑過那組權重一次,算出下一個詞元(token),再算下一個。你用 Claude 的每一秒都在第二段,而權重在這一段一個位元都不會動。這條界線在官方文件裡很實在:Files API 說檔案過期後,引用它的請求「在推論之前就失敗」。

所以第三層能動的變數只剩一個:這一次推論的輸入

面向 微調(fine-tuning) 放進窗口(這一層)
動到什麼 權重 什麼都沒動
資料更新了 要重跑一次訓練 換掉送進去的那份
答錯了要查 查不了,它混在權重裡 打開你送進去的那幾段
成本 訓練時付一次 每一次呼叫都以輸入詞元付

2020 年帶出 RAG 這個詞的論文(Lewis et al.)摘要裡就把兩種知識分開命名:預訓練模型本身叫參數記憶(parametric memory),另外接一個可以查的索引叫非參數記憶(non-parametric memory)。你今天做的上傳就是最土法的非參數記憶:沒有索引,也沒有挑選,整份送進去。後面幾篇要補的正是被省略的那兩件事。


它沒有「學會」你的文件

你可能以為上傳之後,模型就「學會」了你的文件。沒有。實際發生的事很樸素:在你問問題的時候,那些字跟著你的問題一起被送進窗口。 文件沒有變成模型的一部分,它只是在正確的時機,被放到模型看得見的地方。

想通這件事,兩個常見的困惑就解開了:

  • 為什麼明明上傳了,它還是答錯? 因為它沒讀到對的那一段。模型看到什麼就答什麼,它沒辦法知道自己沒看到的部分。
  • 為什麼文件越大,答案品質不一定越好? 因為要從更多內容裡挑出對的段落,本來就更難。

那個「挑」的動作是誰做的?拖進對話的時候是你,整份塞進去,一個字不挑。放進知識庫就換人了。


一份 PDF 送進去,先變成兩份東西

「把檔案給它看」聽起來像是把檔案原封不動地交出去。中間其實有一道拆解。

官方文件把步驟寫得很清楚,一頁一頁來:

  1. 每一頁轉成一張圖片。 整頁的排版、圖表、手寫、表格線,都在這張圖裡。
  2. 同一頁的文字被抽出來。 這是另外一份,純文字。
  3. 兩份一起送進窗口。 不是二選一,是同一頁進去兩次,一次當圖看,一次當字讀。

所以你會看到它讀得出圖表裡的趨勢,也引用得到內文的句子。代價是每一頁都付兩次

一頁到底要多少詞元

文字那一半官方文件給了範圍;圖片那一半要自己算,算法在視覺文件裡(以下 2026-09-19 查)。

Claude 看圖片不是看像素,是看區塊。 每 28×28 像素算一個視覺詞元(visual token),一張圖的成本是 ⌈寬 ÷ 28⌉ × ⌈高 ÷ 28⌉。超過上限的圖會先被縮小,而上限分兩級:Claude 4.7 之後是長邊 2576 px、上限 4,784 個視覺詞元;4.7 之前是 1568 px、1,568 個。

把兩半合起來,一頁的帳長這樣:

一頁裡的東西 詞元 來源
抽出來的文字 1,500–3,000,視內容密度 官方給的範圍
那一頁的圖片 ⌈寬 ÷ 28⌉ × ⌈高 ÷ 28⌉,Opus 5 上限 4,784 官方公式,上限由層級決定
一頁合計 最壞約 7,800 3,000 + 4,784,我自己加的

官方沒有公布 PDF 轉圖片時用多少解析度,所以圖片那一半只能給上限。但上限已經夠嚇人:一份 100 頁的 PDF,最壞吃掉約 78 萬詞元,而 Claude Opus 5 的窗口是 100 萬。一份報告就佔掉將近八成。

實際值大概在哪?官方在 Bedrock 那一段把兩種模式都列了出來,同一份 3 頁 PDF:只抽文字約 1,000 詞元,文字加圖片約 7,000 詞元

那是 Amazon Bedrock 的 Converse API、Opus 4.6 以前的數字,不是 Claude API,但它把圖片那一半的重量量給你看了:多看一眼圖,詞元變成 7 倍。

估這件事有兩個地方會翻車:

  • 舊模型量的數字不能估新模型。 4.7 之後換到高解析度層級,官方說同一張圖最多會用到大約三倍的視覺詞元。這跟上一篇那個「4.7 以後同樣文字多 30% 詞元」是同一類陷阱。
  • 上限不只一個。 單一請求最多 600 頁(窗口不到 100 萬詞元時是 100 頁)、整個請求 32 MB,而 Files API 允許單檔 500 MB。所以會撞到一個怪錯誤:檔案存得好好的,請求卻回 400,說文件超過窗口大小。存得下不代表送得進去。

上面每個數字都是範圍或上限,落到你那份 PDF 上都不準。真正的做法是量:送出去之前把同一個 document 區塊丟給 count_tokens,不花錢也不產生回答,官方明講可以用它估 PDF 成本;送出去之後看回應的 usage.input_tokens。量過一次,你對「一份文件值多少窗口」就有底了。

不是 PDF 的那些檔案

PDF 講得最細,因為它最麻煩。其他格式走哪一條路,官方文件列得很清楚(2026-09-19 查):

你手上的檔案 走哪個內容區塊 實際發生什麼
PDF、純文字 document 上面那一整套
JPEG、PNG、GIF、WebP image 照視覺詞元算;動圖只取第一格
CSV、Markdown document 或直接貼進文字 它們本來就是純文字
Word、Excel 沒有對應的區塊 要自己先轉成純文字
資料集、其他 container_upload 交給程式執行工具處理

Word 和 Excel 沒有原生支援,官方要你自己轉純文字;那份 Word 裡有圖的話,先轉成 PDF 再送,才吃得到「每頁轉圖片」那套處理,也才能標出處。

所以「支援哪些格式」真正的答案是「支援哪些內容區塊」。 你那個副檔名能不能用,取決於它能不能變成上面五種其中之一。

不管什麼格式,上面算的都只是一份文件。你的知識庫裡有五十份的時候,會發生什麼事?


知識庫:窗口裝不下的時候,它自己改成用找的

答案是它會換一種做法,而且不會問你。

Claude 的專案,官方的說法是「有自己的對話紀錄與知識庫的獨立工作區」:文件放進去一次,那個專案裡的每個對話都拿得到,還可以給這個專案單獨寫一份指令。

跟拖進對話比,表面上只差在「要不要重貼」,實際上差的是這三件事:

面向 拖進對話 放進知識庫
活多久 這一個對話 一直在,直到你刪掉
誰決定送什麼進窗口 你,整份 系統,看情況
你要管什麼 不用管 誰維護、什麼時候過期、檔名怎麼取

中間那一列才是重點。知識庫小的時候,整份直接進窗口;大到接近窗口上限,Claude 會自己換成用搜的。

官方文件寫得很白(2026-09-19 查):專案知識接近或超過窗口上限時,RAG 模式會自動啟用,容量最多變成 10 倍;啟用之後 Claude 改用一個專案知識搜尋工具,只取回答需要的段落,不再把整個專案載進來。切換是自動、雙向、免設定的,知識庫縮回去它也會換回來,介面上只多一個標示(付費方案才有)。

這裡的 RAG,就是上一篇收尾講的檢索增強生成:回答之前先把知識庫裡相關的內容取出來,接進提示詞。

你沒有做任何決定,你的流程已經從「整份送進去」變成「先搜尋、再回答」了。 上一節那套帳也失效了:進窗口的不再是文件,是搜出來的那幾段。

我上一篇才說,第三層的第一步「先不談檢索」。結果不談不行:你只要把知識庫養大,檢索就自己來了。 這正是這一層真正的題目,窗口裡放什麼從來不是你一個人在決定。

檔名為什麼突然變成一條技術建議

官方給知識庫四條建議,其中一條乍看很奇怪:用清楚、有描述性的檔名。

整份送進窗口的時候,檔名叫什麼幾乎不重要,反正每個字都在。一旦切換成用搜的,檔名就變成被找到的依據之一,官方把它列成提升檢索效果的做法。這是你第一次要為「被找得到」而寫東西,後面每一層都會再遇到同一件事,只是換個形式。

四條擺在一起,其實就是一個知識庫該長什麼樣子:

官方建議 落到實際操作
資料一次補齊 開專案的時候就把整組放進去,不要用到才補一份。補一份就多一次「搜不搜得到」的賭博
檔名清楚、有描述性 檔名帶主題、時間、版本:2026-Q3-定價決策會議.pdf,不要 會議紀錄(2).pdf
相關的放在同一個專案 一個專案一個主題。把三個不相干的產品塞進同一個專案,等於叫它在三倍的雜訊裡找
問問題時點名文件 問句裡直接寫「根據那份定價決策會議」,幫它把搜尋範圍縮小

右邊那一欄是我的操作版本,左邊四條才是官方寫的。它們的共同點很明顯:全都在幫那個你看不到的搜尋步驟做事。 知識庫越大越依賴搜尋,這四條的效果也就越明顯。

還有一句要自己打折:官方說切換成 RAG 之後「回答的準確度與直接放進脈絡一致」,但這是廠商自己的說法,沒有交代怎麼量、在什麼題目上量。第 4 篇那組 10 題就是為了這種時候存在的:它在你背後換了做法,你的分數有沒有掉,只有你自己量得出來。 至於那幾段到底怎麼切、怎麼搜、怎麼知道搜得準,後面會有專門的一篇。


在 messages 裡,它就是一個 document 區塊

介面上是拖進對話,API 上是在 messages 裡多一個內容區塊。第一篇的那個請求結構到這一層還是同一個,只是 content 從一個字串變成一個陣列:

{
  "model": "claude-opus-5",
  "max_tokens": 1024,
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "document",
          "source": { "type": "file", "file_id": "file_011CNha8iCJcU1wXNR6q4V8w" },
          "title": "團隊筆記",
          "citations": { "enabled": true }
        },
        { "type": "text", "text": "我們內部 API 的分頁參數叫什麼?" }
      ]
    }
  ]
}

Files API 的文件裡幾個值得記下來的點(2026-09-19 查):

  • file_id 從哪來:先把檔案 POST/v1/files,回應裡的 id 就是它。上傳一次,之後每次請求引用同一個 id,不必重傳內容。Files API 已經脫離 beta,不用 beta 標頭。
  • citations 是一個開關,預設不開。開了之後回答會直接帶出它引用了哪一段,也就是 30 秒實驗第二步那句追問的機制版本。
  • titlecontext 是選填的,窗口裡同時有好幾份文件時,它靠這兩個欄位分辨誰是誰。
  • 上傳、列出、刪除都不收費,但文件內容每一次請求都以輸入詞元計價。 存起來免費,讀進窗口要錢,而且每一輪都要。
  • 官方建議 PDF 放在文字前面。 這跟上一篇的快取是同一個道理:穩定的放前面,才有前綴可以快取。

寫到這裡才看得出來的一件事:API 上沒有「知識庫」這個東西。 介面替你做的那一整套(常駐、超過門檻改用搜的、搜完塞回窗口),到 API 這端全部要自己組:自己保管 file_id 清單、自己決定這一輪放哪幾份、自己判斷放不放得下。產品給你的是一個知識庫,API 給你的是一個 document 區塊。第三層剩下的篇幅,講的就是中間那段差距。


重跑評估集:4/10 → 6/10

上一篇立的規矩是:每加一層,就用同樣的 10 題、同樣的標準重跑一次。這一層唯一的變化,是把那份團隊筆記附在每一題前面,直接附上去,不用知識庫:兩行字根本用不到,而且知識庫會引進「有沒有被搜到」這個變數,這一層我要量的不是那個。

# 團隊筆記
- 內部 API 的分頁參數叫 cursor。
- 正式環境固定每週四部署。
# 考的是 第二層 第三層
3 你的事(分頁參數叫什麼) ✘ 不知道 ✔ cursor
4 你的事(每週幾部署) ✘ 不知道 ✔ 星期四
其餘 8 題 格式、規則、記憶、動手、審查 4 ✔ / 4 ✘ 完全一樣

4/10 變成 6/10,翻盤的正好是答案寫在那份筆記裡的兩題。 這就是這一層的全部:不是模型變聰明了,是它終於看得到那兩行字。權重跟第二層那次一模一樣,變的只有那一次推論的輸入。

有兩個細節值得記下來:

  • 第 6 題的失敗方式變了。 那一題問的是團隊的 code review 規則,筆記裡沒有。第二層它直接照一般慣例 review;這一層它先說「你附的團隊筆記裡沒有任何 code review 規則」,再照 PEP 8 review。給錯文件不會讓它變準,但會讓它知道自己缺什麼。
  • 它沒有硬套。 第 5、10 題它都主動說明那份筆記跟題目無關,而不是硬從兩行字裡擠出答案。

分數之外,成本那一欄也動了:那兩行筆記每一題都要重送一次。兩行字便宜到可以忽略,但把同一個動作換成一份 100 頁的 PDF,就是前面算過的量級。每加一種外部資料,分數和帳單要一起看。


這一層的代價

答案品質變成「找得準不準」的問題。 前兩層,品質掌握在你的問法裡;從這一層開始,中間多了一個你看不太到的環節。它答錯的時候,你要先分辨:是它理解錯了,還是它根本沒看到那一段?

你必須開始要求出處。 凡是根據文件來的答案,就問一句「這是文件裡哪一段講的?」能指出來的,可信度完全不一樣;指不出來的,通常就是猜的。走 API 的話,引用功能就是 citations 那個開關,回答會直接帶出引用的段落,你可以拿著它回去核對。

知識庫會沉默地過期。 拖進對話的文件跟著對話結束,知識庫的文件會一直待著,並且一直被引用。半年前那份定價文件還在裡面,它就會拿半年前的價格回答你,而且語氣一樣篤定。這跟第 4 篇那個「看不見的狀態」是同一種病,只是這次沉默地作用的是一整份文件,不是一行設定。

而且這件事有研究撐著。Adaptive Chameleon or Stubborn Sloth(Xie et al., ICLR 2024)在控制的條件下量了模型碰到知識衝突時的行為,兩個結果剛好一起打在知識庫的維護上:只要外部證據夠連貫、夠有說服力,模型就會高度採信,即使它跟參數記憶衝突,所以一份寫得好的過期文件,比寫得爛的更危險;而只要證據裡有一部分跟它原本相信的一致,就會出現強烈的確認偏誤,論文特別指出同時給它矛盾的證據也一樣,所以「把新版也放進去、讓它自己判斷」這招沒有用。Xu et al. 的總覽把這類問題分成三種,其中脈絡之間互相衝突那一種,正是知識庫養大之後你自己製造的,下一篇還會用另一個名字再遇到它一次。

所以我現在的做法全部是減法:

做法 為什麼
一件事只留一個版本 舊版不是留著參考,是留著被引用。新版進去,舊版同時下架
檔名帶生效日期 不只為了被搜到,也為了你一眼看出哪幾份該退休
文件開頭寫生效區間與取代了誰 這行字會跟著段落被搜出來,是它唯一能判斷新舊的依據
定期清,指定一個人負責 沒有人負責的知識庫,半年後就是一個沒人敢動的資料夾

下架比新增重要。 資料夾裡的爛檔案只是佔空間,知識庫裡的爛檔案會開口說話。

上傳等於把內容交出去。 哪些資料可以、哪些不行,這條線要在按下上傳之前先劃好。走 API 還有一個比「交給廠商」更近的問題:Files API 的文件是整個工作空間共用的,不綁使用者也不綁對話。官方文件把話說得很重:任何有那個工作空間金鑰的人,都拿得到裡面任何一份文件;要做多租戶,就一個租戶開一個工作空間。你設計的隔離邊界,是工作空間,不是對話。


這一篇多了什麼,又多付了什麼

多了什麼能力:它終於知道你的事了。評估集第 3、4 題從「不知道」變成答對,4/10 變成 6/10。

多付了什麼代價:答案的品質,從此多了一個你看不太到的環節(有沒有被挑中);知識庫大到一個程度,這個環節會自動打開,而你只會看到一個小標示;你必須開始要求出處;每一輪都在為送進去的東西付輸入詞元;而且你交出去的東西,收不回來。

而且這幾項都跟著知識庫一起長大:文件越多,維護越貴,搜錯的機會越大,而它會用一樣篤定的語氣,正確地引用一份過期的文件。到那個時候,核對出處從一個好習慣變成一道必要的工序。


下一篇

窗口裡到底該放什麼。

這一篇是把一整份文件塞進去。但文件一多、一長,塞得進去不代表挑得對:上一篇提過,窗口是邊際效益遞減的有限資源。下一篇談脈絡工程,以及窗口塞壞掉的四種方式。其中一種你今天已經見過了,就是知識庫裡兩份文件互相打架的那種。


延伸閱讀


上一篇
提示詞變成資產之後:窗口、快取,和你怎麼知道改好了
下一篇
脈絡工程:窗口裡該放什麼,以及它壞掉的四種方式
系列文
從 LLM 到 Agent:用 Claude 拆解現代 AI 工程的每一層8
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言