Skip to content

Agent 是系統問題:從單次推論到一串工具呼叫|Harvard CS2680 第 1 堂

2026年10月21日1 分鐘
TL;DRCS2680 第 1 堂(2026-09-02)先說明 AI 系統和傳統系統的差別:運算分散在 CPU 與 GPU、浮點運算不保證每次一樣、狀態大到要跨 GPU 搬。接著把 agent 比作新型電腦(LLM 是 CPU、context window 是記憶體、harness 是作業系統),指出 agent 的一個請求會變成「推論 → 工具 → 推論」的長鏈,所以每秒 token 數是錯的目標,要看任務成功率、端到端延遲與每次成功的花費。本文用兩個 agent 的帳算一次這些指標怎麼用。

查詞與收藏

正在載入查詞工具…

🌏 English version

影片狀態:課程不錄影。 本文依公開投影片整理,數值例子為本站補充。來源說明

CS2680 第 1 堂在 2026 年 9 月 2 日上課,題目是課程總覽。投影片前半講課程與行政,整理在課程總覽。這篇讀後半的兩段正課(p27–45):AI 系統跟傳統系統哪裡不同,以及 agent 為什麼是系統問題。

這堂要回答一個問題:agent 好不好,為什麼不能看每秒產生多少 token?那該看什麼?讀完之後,你應該能拿一個 agent 任務,說出它會碰到哪些系統問題,也能用「每次成功的花費」比較兩個 agent。如果你的團隊正拿 API 帳單評估要不要導入 coding agent,這堂的指標就是該拿來比的那把尺。

先備:知道 LLM、token 是什麼即可。這堂會冒出很多 serving 名詞,課程到 Part II 才細講;第一節後面有一張小表,每個名詞用一句話說它在系統的哪一層。

AI 系統和傳統系統差在哪

投影片先分開兩種問題(p28)。AI/ML 問的是「用什麼模型、怎麼設計模型」,寫個 Python 腳本解題,追求準確率與能力。AI 系統問的是「怎麼大規模訓練與 serve 它」,追求的是 GPU 用滿(效能)、資源不浪費(效率)、不停機(可靠度)與低碳(永續)。這門課只談其中的 LLM 系統,而且只談推論,不談訓練(p45 的理由是推論主導了算力需求)。

接著五頁說明 LLM 系統跟傳統系統不同的地方:

面向投影片的說法一句話白話
運算(p30)tokenization、kernel 啟動、工具呼叫在 CPU,矩陣乘法在 GPU;不同世代 GPU 混用;prefill 卡算力、decode 卡記憶體頻寬;執行時間取決於輸出多長同一個請求在不同時間點卡在不同硬體上,而且你事先不知道它要跑多久
非決定性(p31)浮點加法沒有結合律,第 7 位小數的差異可以讓下一個 token 變成別的字同一個輸入不保證每次得到同樣輸出,原因在硬體與軟體層
記憶體與通訊(p32)權重從 GB 到 TB;KV cache 每個 token 數十到數百 KB;多 GPU 要靠 NCCL、NVLink、RDMA 搬資料狀態大到放不下一張卡,搬資料本身就是瓶頸
變化速度(p33)注意力架構從 MHA、GQA 到 MLA 一直換;工作負載從多輪聊天、推理、RAG 到 agent系統要追著模型和用法一起改
可靠度與電力(p34)一個 16K GPU 的叢集約每 3 小時壞一張 GPU;GPU 單張 700–1000W規模一大,硬體故障是常態,不是例外

非決定性那列最反直覺,可以自己試一次。浮點數加法的順序不同,結果就可能不同:

>>> (0.1 + 0.2) + 0.3
0.6000000000000001
>>> 0.1 + (0.2 + 0.3)
0.6

GPU 做矩陣乘法時,成千上萬個數字的加總順序取決於執行緒怎麼排程、batch 多大、用了哪種 kernel。順序一變,最後幾位小數就跟著變。平常這點差異無所謂;但模型在兩個機率幾乎一樣的 token 之間選時,它就可能讓模型選到另一個字,後面整段輸出從此分岔。投影片把來源分成三層:runtime(排程、batch 大小)、軟體(融合乘加、自動調參)、硬體(CUDA core 與 tensor core、不同世代 GPU 的低精度格式)(p31)。投影片也註明,這種近似運算一般是可以接受的;它不是要修掉的 bug,而是設計 agent 時要預設存在的條件。

這堂點名、但 Part II 才細講的名詞,先記住它在哪一層就好:

名詞一句話在哪一層
prefill/decode模型先一次讀完輸入(prefill),再一個 token 一個 token 生成(decode)serving
KV cache模型讀過的每個 token 留下的中間結果,存起來下一步就不必重算serving
prefix cache多個請求開頭相同時,共用那段已算好的 KV cacheserving
tensor/pipeline/expert parallelism模型太大放不下一張卡時,把它切開分給多張 GPU 的幾種切法serving 與 runtime
NCCL、NVLink、RDMA多張 GPU、多台機器之間搬資料用的函式庫與硬體連線runtime 與硬體
MHA、GQA、MLA注意力機制的幾種設計,差別在 KV cache 要存多少模型架構
TTFT/TPOT第一個 token 出來要多久/之後每個 token 間隔多久serving 的延遲指標

想先看細節,站內的 CMU 11-868:KV cache 與大規模 serving 講得最完整。

自我檢查:同一個 prompt、temperature 設成 0,兩次得到不同答案,可能是哪裡造成的? 判準:答得出不一定是模型本身,而是 batch 大小或 kernel 改變了浮點加總順序;temperature 0 只拿掉取樣的隨機,不拿掉運算順序的差異。

Agent 是什麼,為什麼需要它

投影片的定義是:agent 是一個自主的軟體系統,用 AI 模型針對目標推理、使用外部工具、執行多步動作直到任務完成(p36)。它分五步:

  1. plan:把任務拆成子步驟。
  2. act:呼叫外部工具(API、資料庫)。
  3. observe:解讀工具回來的結果。
  4. adapt:根據新資訊修改計畫。
  5. deliver:交出最後結果。

為什麼需要包這一層?因為 LLM 是一台奇怪的電腦,同時很強又很弱(p37,引 Andrej Karpathy 的演講)。它在知識、語言、模式比對、寫程式上贏過多數人。它的弱點是:記不住上次的事、理解 context 不穩、會幻覺、不知道自己不知道什麼,還容易被惡意輸入帶著走。照本文的讀法,agent 的工具與記憶就是拿來補這些弱點的。

投影片接著把 agent 比作一種新型電腦(p38):

傳統電腦Agent
CPULLM
記憶體(RAM)context window
周邊設備工具
作業系統agent harness
應用程式agent

投影片的重點句是:LLM 不只是更聰明的 CPU,而是一種程式寫法、壞掉方式都完全不同的電腦。照這個類比延伸(本文的讀法,本系列後面會一直借用):harness 的工作像作業系統,決定什麼放進「記憶體」(context)、哪個程式能碰哪個「周邊」(工具權限)、記憶體滿了怎麼辦(壓縮)。

自我檢查:照這個類比,context window 滿了、harness 把舊對話摘要掉,像傳統電腦的什麼?差在哪? 答:像記憶體不夠時把資料移出 RAM(swap)。差別在 swap 能原樣換回,摘要是有損壓縮,被摘掉的細節回不來。這就是 context 壓縮之後 agent 會「忘記」某個檔名的原因。

為什麼 agent 是系統問題

一般的 LLM 服務是一來一回:請求 → 推論 → 回應。agent 的一個任務卻是一長串:推論 → 工具 → 推論 → 工具 → 檢索 → 推論……,關鍵路徑橫跨 GPU、CPU、儲存、網路與外部服務(p39)。投影片列出這條鏈帶來的六個麻煩:

  • 步驟之間有依賴,下一步要等上一步的結果。
  • 每一步的延遲差很多,例如跑一次測試可能幾秒也可能幾分鐘。
  • 模型要停下來等工具。
  • 狀態(context)一路長大。
  • 可以平行或預先執行(例如先猜下一步要什麼),但猜錯就白做。
  • 軌跡上任何一步都可能失敗。

把這些放回整個系統,就是課程總覽那張五層堆疊(p40),由上到下:

  1. 應用/使用者
  2. agent/harness:規劃、context、記憶、工具、subagent(Part I)
  3. 模型 serving:batching、排程、routing、快取(Part II);外部工具(網頁、檔案、API、人)和它並列,都由 harness 呼叫
  4. runtime/kernel:CUDA、Triton、集體通訊
  5. 硬體:GPU、CPU、記憶體、網路、儲存

圖的右側還標了 co-design:agent、serving、硬體三層要一起設計。照本文的理解,這是在提醒只優化其中一層,效果常常被另一層吃掉。

這種長鏈也讓「看得見」變成一級問題(p43)。傳統分散式系統用 trace 追一個請求經過哪些服務;agent 的 trace 變成一層套一層的軌跡:

  • session
    • 一輪對話(turn)
      • agent 步驟
        • 模型請求、工具呼叫、工具結果,或再生出一個 subagent

投影片的說法是:看不到的東西就無法優化。作業 1 要你做的介面,就是把這棵軌跡畫出來。

自我檢查:為什麼一般 LLM 服務常用的「每個請求的延遲」,不足以描述 agent 的延遲? 判準:答出 agent 的一個任務包含很多次模型請求與工具執行,而且彼此依賴;使用者感受到的是整條鏈的端到端時間,單次請求快不代表任務快。

要最佳化什麼:從每秒 token 到每次成功的花費

投影片這頁的標題直接下結論:throughput 對 agent 是錯的目標(p41)。agent 要最大化的是任務成功率,同時受延遲、成本、資源、可靠度、安全的限制。它把指標分成兩欄:

有用但不夠真正要最佳化的
第一個 token 的延遲、每個 token 的間隔任務成功率/準確率
工具呼叫延遲端到端延遲
GPU 使用率每個任務用多少 token
每次成功的花費($/成功任務)
每次成功的耗能

投影片的提醒是:每秒 token 數更高,agent 仍然可能更慢、更貴。

算一次:兩個 agent 的帳

以下是本文的教學例子,數字是假設的。

你在比較兩個修 bug 的 agent,各跑 100 個任務:

  • Agent A:每個任務平均花 $0.50,成功 60 個。
  • Agent B:每個任務平均花 $0.80,成功 90 個。

只看每個任務的花費,A 便宜 37.5%。換成每次成功的花費:

  • A:$0.50 × 100 ÷ 60 ≈ $0.83
  • B:$0.80 × 100 ÷ 90 ≈ $0.89

A 還是便宜一點,但差距從 37.5% 縮到約 6%。改看「每次成功」的理由很直接:失敗的嘗試照樣花錢,分母變小,單價就被拉高。

再往前一步,失敗的任務不會憑空消失,要有人接手。把人工接手算進去,看 100 個任務的總帳;假設每個失敗任務要工程師花 15 分鐘、成本 $25:

  • A:40 個失敗 × $25 = $1,000,加上 agent 本身 $50,共 $1,050。
  • B:10 個失敗 × $25 = $250,加上 agent 本身 $80,共 $330。

結論翻轉,B 的總成本是 A 的三分之一左右:A 多失敗的 30 個任務,就多出 $750 的人工。這也呼應投影片把目標寫成「在成本限制下最大化成功率」,而不是單純壓低成本:成功率本身就是成本的一部分。

算一次:batching 為什麼可能讓 agent 變慢

投影片列的課程問題第一題是:batching 為什麼提升 throughput 卻傷害 agent 的延遲(p44)?可以這樣想(本文的教學例子):

現在的 serving 系統多半用 continuous batching:不等湊滿,請求隨到隨加進正在跑的批次。代價在另一個地方:同時處理的請求越多,每一步 decode 就越慢。假設伺服器為了把 GPU 用滿,把同時處理的請求從 8 個拉到 64 個,每生成一個 token 的時間從 20 毫秒變成 35 毫秒:

  • 整台機器每秒產生的 token:8 ÷ 0.020 = 400,變成 64 ÷ 0.035 ≈ 1,829,約 4.6 倍。這是 throughput 漂亮的那一面。
  • 單一請求每個 token 慢了 15 毫秒。agent 每次呼叫模型產生 100 個 token,就多 1.5 秒。

一般聊天只多等這 1.5 秒。一個要呼叫模型 30 次的 agent,每一次都要多等:30 × 1.5 = 45 秒。這 45 秒全落在關鍵路徑上,因為下一步得等上一步的結果才能開始。continuous batching 怎麼排程、怎麼兼顧兩邊,Part II 才講。

自我檢查:上面的例子裡,agent 每次呼叫只產生 20 個 token,30 次呼叫一共多等多久? 答:每次 20 × 15 毫秒 = 0.3 秒,30 次共 9 秒。輸出越短,batching 的延遲代價越小;所以後面第 8 堂會教你減少每步的輸出 token。

自我檢查:一個 agent 換了更貴的模型,每任務花費從 $0.40 變 $0.60,成功率從 50% 變 80%。每次成功的花費變高還是變低? 答:變低。$0.40 ÷ 0.5 = $0.80,$0.60 ÷ 0.8 = $0.75。

常見誤解

  • 「GPU 使用率高,agent 就好」:使用率在投影片屬於「有用但不夠」那一欄。上面的 batching 例子裡,使用率上去了,agent 卻多等了 45 秒。
  • 「temperature 設 0,每次輸出就一樣」:temperature 只管取樣;浮點加總順序的差異還在(見第一節)。
  • 「模型推論快一倍,任務就快一倍」:任務時間還包括工具執行與等待,只有模型那一段會變快(見文末綜合自我檢查第 2 題)。

Agent 的特性對應到哪些系統問題

投影片把 agent 工作負載的每個特性,對應到一個這門課要研究的系統問題(p42):

Agent 的特性系統問題本系列在哪裡碰到
軌跡很長狀態與 context 管理第 2、4 堂
context 很大記憶體階層與檢索第 6 堂
開頭重複出現prefix caching第 8 堂、Part II
推理會分岔speculative execution第 8 堂、Part II
工具之間有依賴依賴感知的排程第 5 堂、第 8 堂
用到不同模型routing第 8 堂、Part II
工具延遲不固定非同步執行第 8 堂
對外有副作用安全與隔離第 4 堂(shell 的風險)
多個 agent編排與通訊第 3 堂、第 5 堂
任務跑很久checkpoint 與容錯第 6 堂

走一次:一個修 flaky test 的 agent 會碰到哪些問題

以下是本文的教學例子。你請 coding agent 修一個時好時壞的測試(flaky test),它跑了半小時,大約 40 步:讀程式、改檔、反覆跑測試確認。對照上表:

  • 軌跡很長 → 40 步之後 context 快滿了,harness 要決定壓縮哪些舊結果;壓錯了,agent 會忘記前面已經排除過的原因,又重查一次。
  • 開頭重複出現 → 40 次模型呼叫的開頭都是同一份 system prompt 與工具說明;serving 端若能重用這段(prefix caching),成本和延遲都會降。
  • 工具延遲不固定 → 測試一次可能 5 秒也可能 3 分鐘;模型乾等的話,整個任務被最慢的那次測試拖住。
  • 對外有副作用 → agent 會跑 shell 指令;沒有隔離的話,一個寫錯的刪除指令就會動到真實檔案。
  • 任務跑很久 → 第 35 步網路斷線,如果沒有 checkpoint,前面半小時全部重來。

這五個問題沒有一個是「模型不夠聰明」。同一個模型,放在處理得好與處理不好的系統裡,結果會差很多,這就是這門課說 agent 是系統問題的意思。

自我檢查:一個訂機票的 agent 要查三家航空公司的價格,再幫使用者下單。它最明顯會碰到表中哪兩列?各會怎麼壞? 判準:至少答出「工具延遲不固定」(三家查詢時間不一,循序查會被最慢的拖住,可以平行查)與「對外有副作用」(下單是真的扣款,要有確認或可撤銷的機制);答「任務跑很久」或「工具之間有依賴」並說明理由也算。

這門課要回答的九個問題

接著 p44 列出課程結束時要能「定量回答」的九個問題:

  1. batching 為什麼提升 throughput 卻傷 agent 延遲?
  2. agent 什麼時候該用大模型?
  3. KV/prefix 狀態該放在哪?
  4. 同一個 agent 的請求該怎麼排程?
  5. 工具呼叫能不能和推論重疊?
  6. 什麼時候該派 subagent?
  7. 怎麼在不同 GPU 與模型之間 routing?
  8. 跑了 30 分鐘的 agent 中途失敗,怎麼恢復?
  9. 怎麼最佳化每次成功的花費,而不是每秒 token 數?

依課表對照,Part I 碰到的主要是第 2、5、6、9 題在 harness 這一側的部分,其餘大多在 Part II。p45 則明說這門課不涵蓋訓練、模型架構設計、通訊、電力與新硬體。

綜合自我檢查

  1. 你的團隊說「我們把 GPU 使用率從 60% 拉到 90%,agent 變好了」。你要追問哪兩個數字? 判準:至少答出任務成功率與端到端延遲(或每次成功的花費);GPU 使用率在投影片屬於「有用但不夠」那一欄。
  2. 一個 agent 任務要呼叫模型 20 次、每次之間跑一個工具。把模型推論加速一倍,任務時間會減半嗎? 答:不會。工具執行與等待的時間沒變,只有模型那一段變快;能省多少取決於模型時間占整條關鍵路徑的比例。
  3. 為什麼投影片把 harness 比作作業系統,而不是比作應用程式? 判準:答出 harness 管的是資源與權限(什麼進 context、哪個工具能用、滿了怎麼辦),應用程式(agent 要完成的任務)跑在它上面。

延伸閱讀

課程影片來源

  • 課程不錄影(policy 頁:「the lectures will not be recorded」)。
  • 底本:第 1 堂投影片(PDF 頁序 p27–45),2026-10-21 讀取。投影片右下角印的頁碼比 PDF 頁序多 1,本文引用一律用 PDF 頁序。
  • 本文的兩個帳目例子與 batching 例子是本站補充,不是課堂內容。

更新紀錄

  • 2026-10-23:對照表與自我檢查答案補上第 6、8 堂的站內連結。
  • 2026-10-22:延伸閱讀補上第 2 堂、對照表補上第 3、4、5 堂的站內連結。

參考資料