# AI Agent (1/3):核心技術 Context Engineering 基本概念解說 來源:https://www.youtube.com/watch?v=urwDLyNa9FU 這是我嚐試利用模型自主性的整理出來的課程內容,自行切斷、自行整理,再做一些微調之後看是不是有機會也分享給社群。 ## AI Agent 的核心技術 簡報:000108.jpg ![000108.jpg](https://hackmd.io/_uploads/B1A9gy8hZe.jpg) 時間:00:00:00 ~ 00:01:08 重點: 今天我們要繼續上 AI Agent 的課程,這堂課比較偏向科普性質。整個課程內容會分成三個部分:首先是 AI Agent 背後的核心技術,也就是 Context Engineering;接著是 AI Agent 之間的互動方式;最後,我們會探討 AI Agent 對我們未來工作可能帶來的衝擊。 我們就從 Context Engineering 開始講起。 大家可能會覺得這部分內容有點似曾相識,因為很多 Context Engineering 的技術其實已經在 OpenClaw 裡面實作過了。不過,這堂課比較特別,它會引用大量的論文,而且這些論文都是非常新的,可能是幾個月甚至半年前的成果。 雖然上週我們已經提到很多技術,但今天會從一個不同的角度來談 Context Engineering,所以大家還是要留意,在深入討論 Context Engineering 之前,先了解一下這個架構很重要。 ## 語言模型 簡報:000308.jpg ![000308.jpg](https://hackmd.io/_uploads/S1ysxJL3-x.jpg) 時間:00:01:08 ~ 00:03:08 重點: 在談 Context Engineering 之前,我們先回顧一下為什麼需要這個概念。 我們知道,語言模型(LLM)本質上就是做文字接龍:你給它一個輸入(Prompt),它就接一段話出來。但這個回應不一定只是文字,它可能是一個「使用工具的指令」。 當這個指令被執行,環境裡面的程式會得到一個輸出。當我們要把這個工具的輸出再傳給語言模型時,有個非常重要的原則要記:你不能只給它工具的輸出。 因為語言模型只會「活在當下」,它只會處理當前的輸入,不會記得之前發生過什麼。所以,當我們把工具的結果傳回時,必須把「人類最初給的命令」+「語言模型自己操控工具的指令」+「工具的實際輸出」,這三部分全部接在一起,組成一個非常長的輸入,再丟給語言模型。 這個步驟會反覆發生:如果模型決定使用第二個工具,得到輸出後,傳給模型的輸入,依然必須是「所有歷史事件的串接」+「新的工具輸出」。 然而,這裡會遇到一個難點,就是語言模型的輸入長度是有限的,它無法處理無限長的輸入。這就是為什麼我們需要 AI Agent 來管理這個流程。 ## AI Agent 簡報:000443.jpg ![000443.jpg](https://hackmd.io/_uploads/S1-og1U2Zx.jpg) 時間:00:03:08 ~ 00:04:43 重點: 這就是為什麼我們需要 AI Agent。它其實是一個介面,放在語言模型(LLM)和人類或外部環境之間。你可以把它想像成 LLM 的「守門人」或「經紀人」,它負責決定 LLM 最終能看到什麼資訊。 所以,所有來自外界的輸入,都會先經過這個 AI Agent。 雖然 OpenClaw 只是 AI Agent 的一個例子,但它本身其實非常原始,可以把它當成初代的原型。未來一定會有更多進展,我們現在看到的只是基礎概念。 AI Agent 的核心工作,就是為 LLM 篩選和選擇內容。這代表 LLM 真正看到的,都是經過 AI Agent 篩選、長度適當的輸入。 這裡有一個很重要的技術點:這個輸入的長度不能太長(因為 LLM 的輸入有上限),也不能太短(否則 LLM 就會失去上下文,不知道前面發生了什麼)。 因此,AI Agent 必須做的事情,就是產生一個長度合適的輸入。這種幫 LLM 管理輸入長度、確保資訊流暢的過程,就叫做 **Context Engineering**。 ## Context Engineering ![image](https://hackmd.io/_uploads/HJYb8ht2Wx.png) 重點: 剛才是對 Context Engineering 的概念性介紹。如果用程式語言來描述,可以這樣理解: 當我們沒有做 Context Engineering 時,語言模型與外界的互動,就像一個從 1 到無限大的 `for` 迴圈。每次循環,新的 Context 都是把舊的 Context ($C_t$)、當前的輸入 ($I_t$),以及模型的回應 ($O_t$) 全部加起來,形成新的 Context ($C_{t+1}$)。 但如果我們做了 Context Engineering,唯一改變的就只有最後更新 Context 的步驟。雖然模型接收輸入和 Context 得到輸出這部分不變,但我們不會直接把輸入和輸出接到 Context 上,而是會透過一個比較複雜的操作 $F$ 來處理。 這個 $F$ 就是 Context Engineering 的核心,它負責定義如何將舊的 Context、當前的輸入和輸出,轉換成一個新的 Context ($C_{t+1}$)。 ## Context Engineering - 壓縮 簡報:000856.jpg ![000856.jpg](https://hackmd.io/_uploads/SyGjlkL2Zl.jpg) 時間:00:04:43 ~ 00:08:56 重點: **💡 為什麼需要 Context Engineering?** 最核心的需求就是「壓縮」。因為語言模型的輸入長度是有限的,如果歷史紀錄太長,模型就處理不了。 **💡 實際應用舉例:** 1. **OpenClaw 的做法:** 它可以內建一個 `compaction` 功能。它不會把所有歷史紀錄都帶進去,而是會用某個語言模型把很長的歷史紀錄,提煉成一段簡短的摘要,再接上新的資訊。 2. **其他方法:** 即使是比較簡單粗暴的方法,例如當工具輸出非常長時,直接將這段長文截斷,改成「這裡曾經有個工具的輸出,就到此為止」,其實也是有效的。 總之,Context Engineering 就是定義這個複雜的轉換函數 $F$,讓 AI Agent 知道如何聰明地管理和更新它的記憶體(Context)。 ## SWE-bench 簡報:001224.jpg ![001224.jpg](https://hackmd.io/_uploads/rymjxJU3Wl.jpg) 時間:00:08:56 ~ 00:12:24 重點: 這個方法其實蠻實用的,它引用了一篇去年的論文,主要在 SWE-bench (Software Engineering) 這個場景下,比較了幾種處理工具輸出的方式: 1. 直接使用原始的工具輸出。 2. 用語言模型(LLM)對上下文進行壓縮/摘要。 3. 把工具輸出替換成一個佔位符(Observation Masking)。 **【背景知識:SWE-bench】** SWE-bench 是一個軟體工程的任務,目的是讓語言模型像一個真正的軟體工程師一樣,接收一個 GitHub Repo 和一個 Issue,然後去解決這個 Issue。雖然任務很有挑戰性,但目前很多 LLM 在這類任務上表現得非常好。 **【實驗結果分析】** 圖表比較了「正確率」(縱軸)和「成本/Token 消耗」(橫軸)。 * **黑色點(Raw Agent):** 代表沒有做任何壓縮,直接把所有環境資訊都丟進去。雖然表現不錯,但成本(Token)消耗最高。 * **紅色方塊(LLM 壓縮):** 用 LLM 進行上下文壓縮。結果發現,它的表現和原始 Agent 差不多,但成本明顯降低,證明 LLM 壓縮是有效的。 * **藍色三角形(Observation Masking):** 這是用佔位符替換工具輸出。它的表現和 LLM 摘要(紅色點)非常接近。 **【重點發現與陷阱】** 雖然 LLM 摘要和 Observation Masking 的表現很接近,但 LLM 摘要並不能保證在所有情況下都更穩定或更好。 雖然壓縮通常能省錢,但有一個例外:**「軌跡延長現象」(Trajectory Extension)**。 當我們進行壓縮後,雖然輸入的內容變短了,但因為某些步驟資訊丟失了,LLM 會誤以為它需要重新執行已經做過的步驟。這樣導致它執行的步驟反而變多了,最終消耗的 Token 成本可能根本沒有下降。 ## Context Engineering - 壓縮 簡報:001313.jpg ![001313.jpg](https://hackmd.io/_uploads/S1BsxyIhZg.jpg) 時間:00:12:24 ~ 00:13:13 重點: 關於這兩種壓縮方式,大家可能會想,到底哪一個比較好呢?其實答案是,它們是可以同時運用的。 論文最後提出的方法就是,不同的壓縮技術可以結合使用。他們試出來的最佳策略是: 1. **前期階段:** 先用「Observation Masking」的方法,把工具的輸出內容先縮短。 2. **但要注意的是,** 即使只是把工具輸出換成一句摘要,我們的 Context 還是會逐漸變長。 3. **當 Context 累積到某個程度之後,** 之後就可以再用「Summarization」的方式,一次性把非常長的輸入內容直接壓縮縮短。 所以,把這兩種方法(Observation Masking + Summarization)搭配使用,才能達到最好的效果。 ## Context Engineering - 壓縮 簡報:001456.jpg ![001456.jpg](https://hackmd.io/_uploads/rkLix1I3bl.jpg) 時間:00:13:13 ~ 00:14:56 重點: 關於工具的輸出處理,我發現一個很重要的技巧。 當我們執行完工具後,如果把完整的輸出內容都塞進去,上下文就會變得非常長。但其實很多時候,我們根本不需要整篇的內容,可能只需要其中一個摘要或某一段資訊。 所以,比起直接把工具的輸出當成文字放進去,我建議的做法是:把這些內容先存成一個外部檔案(例如 `log1.txt`)。 這樣做的好處是,我們在後續的提示詞裡,只需要放一句話,例如「詳見 log1.txt」,而不是把大段文字貼進去。這樣能讓上下文保持乾淨,不會被過長的資料佔滿。 如果語言模型有一天真的需要知道工具當初輸入或輸出了什麼,它也可以再執行一次工具,直接讀取這個外部檔案,就能「重拾記憶」,知道原始的內容了。這樣就既能保持上下文的精簡,又不會丟失資料。 ## Morty's Mind Blowers 簡報:001609.jpg ![001609.jpg](https://hackmd.io/_uploads/HkDsxkLhWg.jpg) 時間:00:14:56 ~ 00:16:09 重點: 這讓我想到了《Rick and Morty》裡的一個情節。在第三季,Morty發現了家裡一個地下室,裡面裝滿了Rick的記憶,每個記憶都存在一個管子裡。這些記憶很多都是讓人感到難堪的,不論是Morty不小心害人,或是Rick自己發音被糾正的糗事。 當Morty發現自己大半生的記憶也都在這些管子裡時,他非常激動,結果就跟爺爺打了一架,兩人的記憶都消失了。 最近重看這部劇,我覺得從有了AI Agent之後,很多科幻電影或小說裡的情節,好像就沒那麼神奇了。舉例來說,Morty最新一季裡那個「電影製造機」,只要輸入腳本就能輸出電影。現在看來,這技術根本已經很接近現實了,畢竟現在很多短片都是用AI生成的。 總體來說,這種「記憶清除再讀取」的故事,現在看來已經不像以前那麼遙遠的科幻概念了。這對我們理解語言模型,會是一個很有趣的切入點。 ## Memory 簡報:001740.jpg ![001740.jpg](https://hackmd.io/_uploads/rJYiekI2Zl.jpg) 時間:00:16:09 ~ 00:17:40 參考論文: - A-MEM: https://arxiv.org/abs/2502.12110 - Mem0: https://arxiv.org/abs/2504.19413 - Memory OS: https://arxiv.org/abs/2506.06326 重點: 對於語言模型來說,所謂的「記憶」,其實就是把當前上下文的內容,儲存到外部的資料庫或硬碟裡,之後再讀取出來。 所以,語言模型的記憶機制,其實是模型在特定時間點,能夠自主執行「儲存內容」的指令。當我們要把資料存到硬碟裡時,不同的文獻有不同的儲存方式: 1. **Graph 結構:** 可以把資料建成圖形狀,這樣在之後搜尋時,就能更清楚了解不同記憶之間的關聯性。 2. **時間標記:** 或是幫記憶標上時間,這樣我們就能知道要存取哪個時間段的記憶,或是哪些是比較新的記憶。 接下來的重點就是,模型必須能夠執行「抽取記憶」的指令。我們需要研究的就是:如何讓模型在適當的時機,能夠從原本的 Prompt 裡,把需要的記憶抽取出來,並從外部的檔案系統中讀取回來。 這方面(AI Agent 的記憶機制)的研究非常廣泛,我這裡列了一些參考的論文,大家可以參考看看。 ## Context Engineering 簡報:002038.jpg ![002038.jpg](https://hackmd.io/_uploads/Skcjx1Lh-l.jpg) 時間:00:17:40 ~ 00:20:38 重點: --- ### 🧠 筆記:Context Engineering 與記憶的整合 **一、Context 的結構修改(加入記憶)** 我們需要對原本的 Context Engineering 公式做一個調整,把「記憶」的概念加進去,讓定義更精確。 原本的 Context $C$ 其實可以被拆成兩部分: 1. **$P$ (Process/Promptable):** 這是會被丟進語言模型(LLM)的資訊。 2. **$M$ (Memory):** 這是存在硬碟(Disk)中的資訊。 所以,Context $C$ = $P$ + $M$。 **💡 核心概念:** Context 其實包含了兩種資訊:一部分是能餵給 LLM 的,另一部分是存到硬碟裡的。 **二、演算法的差異點** 左邊和右邊的演算法,除了 Context $C$ 之外,唯一不同的地方在於呼叫 LLM 時的輸入變數: * 輸入變數從 $C_t$ 變成了 $P_t$。 * 這代表我們只需要把 $C$ 中準備要給 LLM 看的部分(也就是 $P$),餵給 LLM 即可。其他部分就留在硬碟裡。 **三、更新 $P$ 和 $M$ 的流程** 當我們更新 Context $C_t$ 時,會分別更新 $P_{t+1}$ 和 $M_{t+1}$: * **Load Memory (讀取記憶):** 當我們從硬碟讀取記憶時,會更新 $P$ 的部分。 * **Save Memory (儲存記憶):** 當我們要把記憶存到硬碟時,會更新 $M$ 的部分。 --- **📚 術語釐清:Context vs. Prompt** 我在課堂上發現,大家常常會混用 Context 和 Prompt 這兩個詞,但其實它們有區別: 1. **Context (C):** 這是指整個演算法的 $C$。它包含了 AI Agent 經歷過的一切事情,所以它涵蓋了「會被輸入 LLM 的部分」和「存在硬碟的全部部分」。 2. **P:** 這是 Context 的一部分,專指「真正會被輸進 LLM 的部分」。 3. **Prompt:** 這是指實際傳給 LLM 的輸入。 **📌 關係總結:** * Context $\rightarrow$ 整個歷史記錄($P+M$)。 * $P$ $\rightarrow$ 準備給 LLM 看的部分。 * Prompt $\rightarrow$ $P$ 的一個子集。 **重點提醒:** Context 不一定會成為 LLM 的輸入,只有 Context 的一部分($P$)才會被作為 Prompt。雖然在文獻或討論中常混用,但理論上還是可以區分開來的。 ## Summarization for Agent 簡報:002329.jpg ![002329.jpg](https://hackmd.io/_uploads/HyioeJLhbe.jpg) 時間:00:20:38 ~ 00:23:29 參考論文: - ACON(Agent Context Optimization): https://arxiv.org/abs/2510.00615 重點: 我們剛才提到做摘要時,其實就是呼叫語言模型,讓它把一段記憶做摘要。雖然現在的語言模型都有摘要的能力,但有一篇論文叫 ACON 發現,模型在做摘要時,常常會出錯。 這個失敗並不是說它沒辦法產生摘要,而是把摘要放回 Prompt 之後,原本能答對的問題,反而做不對了。這現象就叫做 **Context Collapse**。 這代表在壓縮資訊的過程中,損失了一些重要的資訊。如果損失的是關鍵的指令,模型就會非常容易出錯。就像之前 Meta 的研究例子,AI 幫人收信時,把「郵件必須經過人類同意」這個最重要的指令給壓縮掉了,模型就開始不聽指令了。 所以,做摘要時,我們不能只是普通的壓縮,必須要想辦法告訴模型:哪些資訊是絕對不能丟掉的。 ACON 論文的解法很特別:它利用了另一個語言模型,用來生成「反饋」(feedback)。 這個過程是這樣的: 1. 收集一些資料,這些資料是模型在「摘要後」做錯的例子。 2. 讓第二個模型看這些失敗的例子,然後分析:「為什麼摘要會讓結果變差?」 3. 第二個模型就會把這個分析寫成一段文字,這就是 **feedback**。 這個 feedback 本質上只是一段文字,它沒有改變負責摘要的模型的參數。但下次當有新的任務進來時,我們把這段 feedback 給它看,就能讓它知道:「在做摘要時,哪些資訊是重要的,如果漏了可能會導致任務失敗。」 所以,雖然模型的參數沒有改變,但它因為看到了這個 feedback,讓它更知道該如何做摘要,能更符合人類的期待,表現就會更好。這就是 ACON 的核心機制。 ## Summarization for Agent 簡報:002459.jpg ![002459.jpg](https://hackmd.io/_uploads/SkTjgyInZe.jpg) 時間:00:23:29 ~ 00:24:59 重點: ACON 這個方法真的很有效。它是在 AppWorld 上運作,目的是讓語言模型能夠操控許多 App,去執行比較複雜的任務。其實這跟現在 AI Agent 做的事情是一樣的。 所以可以知道,AI Agent 能夠組合各式各樣的程式來完成複雜任務的能力,其實早就已經有這樣的基準測試(Benchmark)來評量了。 這個圖表橫軸是「峰值 Token 量」(peak token),代表整個 Prompt 中 Token 最多的程度;縱軸則是正確率,當然是越高越好。 重點是,如果我們只是用一般的 LLM 進行壓縮,在 AppWorld 這個基準測試上,有時候結果反而會變差。雖然壓縮後 Token 量變少了,但正確率就會下降。 不過,當它使用 ACON 這個作法時,也就是讓語言模型更專注於做「任務需要的摘要」,它得到的結果(紫色點)就不同了。它不僅能減少所耗費的 Token 量,表現(準確率)也變得更好。這就是 ACON 的核心價值。 ## SUmmarization augmented Policy Optimization(SUPO) 簡報:002640.jpg ![002640.jpg](https://hackmd.io/_uploads/Sy0olJInWl.jpg) 時間:00:24:59 ~ 00:26:40 參考論文: - SUmmarization augmented Policy Optimization(SUPO): https://arxiv.org/abs/2510.06727 重點: 在 ACON 那篇論文裡,模型是完全沒有經過訓練的。當然,如果想訓練模型,也有相關的論文,我會引用這裡一個例子:嘗試用一個專門做「上下文壓縮」的 LLM 來做 Fine-tuning。 但我們一般訓練模型時,都需要輸入和一個正確的答案(Ground Truth)。但如果我們做摘要,實際上我們根本不知道「正確的摘要」應該長什麼樣子,也不知道什麼樣的摘要對任務最有幫助。 所以,在訓練這個模型時,我們必須用「強化學習」(Reinforcement Learning)的方法。它的流程是:讓模型先產生一個摘要,然後不只到此為止,而是要讓它繼續去解整個任務。直到最後解完任務,我們才會判斷它有沒有做對。做對就是「正向獎勵」(Positive Reward),做錯就是「負向獎勵」(Negative Reward)。 用強化學習的方式來訓練這個摘要模型。 不過,這裡有一個重點:做摘要的語言模型,跟負責執行工具指令的模型,其實是同一個模型。所以,我們訓練的目標,不只是讓摘要寫得更好,而是讓模型整體的能力都提升了。它不僅學會了如何做摘要,更學會了如何根據這個簡短的摘要去執行後續的任務。 總之,訓練 LLM 的目標,是讓它在「Agent」這個情境下,能做得更好。 ## 壓縮:何時? 簡報:002816.jpg ![002816.jpg](https://hackmd.io/_uploads/H1gW2xkL2Wl.jpg) 時間:00:27:42 ~ 00:28:16 重點: 到目前為止,我們還沒有明確定義「什麼時候」應該開始進行壓縮。雖然直覺上覺得當 Context 太長時就該壓縮,但具體長到什麼程度才該啟動呢? 如果看 OpenClaw 的做法,它其實採用的是一條寫死的規則:只要長度超過某個上限,就直接開始壓縮。 這就引出了個問題:為什麼要用寫死的規則?難道不能讓語言模型自己決定什麼時候要壓縮嗎? 根據前人的文獻發現,語言模型其實非常不喜歡「壓縮」這個過程,對它來說,壓縮等同於「抹除記憶」。它對這種無緣無故的記憶消失會產生強烈的排斥感。 這就像一個角色(例如 Morty)發現自己大半生的記憶被藏起來時,會非常生氣。所以,語言模型也是一樣,它不喜歡記憶突然消失。即使我們給它一個「工具」,告訴它這個工具會抹除過去記憶的某些部分,它聽了也不會高興,甚至會抗拒執行這個工具。這篇論文甚至嘗試逼迫模型接受這種操作。 他嘗試逼迫模型使用一個叫做 `erase` 的工具,這個工具的功能就是會抹除模型部分的記憶。 實驗的流程是,我們告訴模型,當我們輸入「reflection」(反省)時,它就必須執行這個 `erase` 工具。 結果發現,當人類強制輸入「reflection」,並且限制模型只能執行 `erase` 時,模型並沒有照做。它會繼續執行它原本的工作,這代表語言模型其實不喜歡被抹除記憶。 所以,這件事顯示了模型對於自身記憶的保護機制,這點之後我們需要思考怎麼處理。 ## 壓縮:何時? 簡報:003021.jpg ![003021.jpg](https://hackmd.io/_uploads/HJMngk8h-l.jpg) 時間:00:28:16 ~ 00:30:21 參考論文: - AgentFold: https://arxiv.org/abs/2510.24699 重點: 所以,我們來看一篇名為 AgentFold 的論文。 大家會發現,因為模型本身不太喜歡「抹除」或「壓縮」自己的記憶,所以像 OpenDevin 這種系統,當 Context 超過上限時,會用一種強制執行(forced execution)的方法,執行一個叫 `memory flush` 的動作,讓模型自己開始壓縮記憶。 AgentFold 論文做的事情,就是訓練模型使用一個壓縮記憶的工具,這個工具就叫做 `fold`(折疊)。 這個 `fold` 工具需要兩個輸入:一是我們要壓縮的對話範圍(從第幾步到第幾步),二是我們最好能留一個小紙條(sticky note)來記錄,這樣內容寫什麼,也可以讓語言模型透過這個工具自己決定。 舉例來說,如果前面有很冗長的步驟,我們就可以用 `fold` 指令,把這段文字替換成一句精簡的總結。 講到這裡,可能會覺得,前面不是說模型不喜歡壓縮記憶嗎?那這裡怎麼能做到? 其實這篇論文正好呼應了這個研究發現。因為 AgentFold 的核心就是「使用壓縮記憶工具」,這必須透過訓練才能達到。所以他們是微調了模型的參數。這跟前面 ACON 的做法很不一樣,ACON 只是教模型做 summary,但這裡必須要調參數,才能逼迫模型使用這些壓縮工具。 論文裡甚至提到,他們試圖單純用 Prompt 讓模型自己去使用壓縮工具,但結果發現,模型很難穩定地做到。所以,壓縮這個能力,真的是需要另外進行訓練的。 ## Subagent 可以視為自主壓縮 簡報:003158.jpg ![003158.jpg](https://hackmd.io/_uploads/SkQhgyI2bx.jpg) 時間:00:30:21 ~ 00:31:58 重點: 上週我們提到了 sub-agent 的概念。其實可以把 sub-agent 看作是一種「自主的壓縮行為」。 當模型在某個時間點產生一個使用工具的指令(叫做 `spawn`)時,它就會啟動一個 sub-agent。這個 sub-agent 仍然是跟主語言模型互動的,它的 context 裡會包含一個 subtask,告訴它要做什麼。 它會把任務傳給語言模型,語言模型再給它一個回覆,可能是指令,或是工具的輸出。這個互動會一直持續下去。 直到 sub-agent 執行一個叫做 `return` 的工具。`return` 的作用是把 sub-agent 最終的輸出或資訊,傳給主 Agent。 重點來了:當 sub-agent 執行完 `return` 之後,它之前所有的操作和對話紀錄,都會從 context 裡被「抹除」。所以,這其實就是一種自動的記憶刪除或壓縮機制。 原本的對話紀錄會一直累積,但一旦執行了 `return`,這一段對話紀錄就通通不見了,上下文就從 `return` 的資訊開始重新計算。 ## Subagent 可以視為自主壓縮 簡報:003417.jpg ![003417.jpg](https://hackmd.io/_uploads/HJH3gy8nZl.jpg) 時間:00:31:58 ~ 00:34:17 重點: 為了讓大家更直觀地了解 sub-agent 是怎麼運作的,我截了一張圖,它很清楚地展示了 sub-agent 對於 context 長度的影響。 這是一個很複雜的問題,舉例來說,假設我們讓 Agent 幫你找一篇論文。Agent 看到問題後,會先開始搜尋相關文章。每次 Agent 執行一個動作,它的 context 都會逐漸變長,所以圖上就記錄了這個 context length。 但因為語言模型具備產生 sub-agent 的能力,它會先啟動一個 sub-agent 去搜尋論文。找到相關論文後,它不會把所有資訊都傳回給主 Agent,而是只把論文的標題傳回,這樣整個 context 就被縮短了。之後,主 Agent 又會再啟動一個 sub-agent 去執行另一個任務,像是驗證作者數量。這時候 context 又會逐漸伸長,等找到作者資訊後,context 又會再次縮短。 所以,從 context engineering 的角度來看,sub-agent 的作用就是對 context 進行「自主的壓縮」。每次分裂一個 sub-agent,就代表某一段的 context 之後會被壓縮掉。每次產生 sub-agent,你就可以累積 context,但 sub-agent 結束後,那一段 context 就會消失。這就是為什麼 context 的長度會呈現鋸齒狀的上升和下降。 另外,圖裡特別說明,如果沒有 sub-agent,所有的 context 都是不斷累積的,最終會超過語言模型能處理的 token 上限(可能累積到十萬多個 token)。因此,能夠產生 sub-agent 是一個非常重要的能力。不過,就像剛才說的,語言模型本身其實不喜歡自主做壓縮,所以 sub-agent 這個能力就非常關鍵了。 ## Subagent 可以視為自主壓縮 簡報:003605.jpg ![003605.jpg](https://hackmd.io/_uploads/BJLhek8nWg.jpg) 時間:00:34:17 ~ 00:36:05 重點: 所以,sub-agent 這個能力其實不是天生的,它需要經過後天訓練才能具備。雖然現在很多模型,像是把 OpenClaw 接到 Claude 上,看起來好像有這個能力,但這可能並不是一個自然原生的能力,而是需要特別的訓練才能達成的。 這篇論文就是針對如何訓練這種 sub-agent 的能力。他們採用了強化學習(Reinforcement Learning)的方法來訓練語言模型,目標是讓模型能得到正確的答案。 但他們發現,如果只用「答案是否正確」來當作學習的訊號,模型是學不會正確產生 sub-agent 的。因為如果目標只是得到正確答案,模型自然會選擇最簡單的方式,而不是非得去產生 sub-agent。 所以,我們必須加上額外的獎勵(reward)來「逼迫」或「誘導」模型使用 sub-agent 這個工具。 舉例來說,他們會設計一些懲罰機制: 1. 如果主幹的 Context 太長,就會受到懲罰,這會迫使模型不得不分裂出 sub-agent 來分擔內容。 2. 如果 sub-agent 提前把問題全部解完,導致產生 sub-agent 的意義消失了,也會受到懲罰。 3. 如果 sub-agent 做出超出範圍的行為,也會受到懲罰。 就是透過這些複雜的獎勵和懲罰機制,才能夠成功地訓練語言模型使用 sub-agent 這個工具。 ## 過濾 簡報:003824.jpg ![003824.jpg](https://hackmd.io/_uploads/Skwhg1I3Zg.jpg) 時間:00:36:05 ~ 00:38:24 重點: 到目前為止,我們討論的都是「壓縮」技術,也就是當 context 過長時,再把內容縮短。但這只是治標,我們能不能從根本上解決問題,一開始就不要讓 context 過長呢? 要做到這一點,就必須分析一下,到底什麼樣的資訊會導致 context 過長。我看了兩篇論文,它們的分析結果非常一致。 第一篇論文分析了在沒有做 context engineering 的情況下,模型在整個對話歷程中做了什麼。它發現,在所有 token 中,佔據比例最高的是所謂的 **Observation**,高達約 84%。Observation 指的就是來自外界的輸入,像是模型讀了一個檔案,或者工具執行後產生的長篇輸出,這些外部資訊佔了絕大部分的 context。 另外一篇論文的結論也幾乎一樣。 還有第三篇論文,主要聚焦在軟體工程(Software Engineering),它發現當模型在做程式碼修改和執行時,佔用 context 的比例分佈很不均: * 執行程式碼:約 12% * 修改程式碼:約 11.8% * 但最主要的,是讀取程式碼,佔了 76% 的 context,因為它把整個專案(repo)的程式碼都讀進來了。 所以,這就引出了核心問題:有沒有辦法直接從源頭上,阻止這麼大量的文字資訊進入 context 呢? ## 過濾 簡報:004003.jpg ![004003.jpg](https://hackmd.io/_uploads/B1thgkLhWg.jpg) 時間:00:38:24 ~ 00:40:03 重點: 因為一開始直接把太多文字塞進去,所以有論文提出了一個想法:我們或許應該在讓語言模型(LM)處理資料之前,就先做一個「過濾」的步驟。 一般我們讀一個檔案或文件時,常用的做法是:LM 輸出一個指令(例如:「我要讀一個 log 檔案」),然後一個叫做 `read` 的工具會把整個檔案的內容,原封不動地一次性餵給 LM。但如果這個 log 檔案非常大,有時候 LM 會處理不過來。 所以,我們需要一個更聰明的 `read` 工具。 我們不應該只讓 LM 說「我要讀這個檔案」,而是要讓它更具體,例如:「我要讀這個檔案裡,跟修復 bug 有關的內容」。 這個 `read` 指令本身就必須夠聰明,它不只會打開檔案,更要能夠從裡面找出真正重要的部分,只把跟 bug fixing 有關的內容讀出來,讓 LM 的注意力能集中在重點上。 這代表這個 `read` 指令本身,需要加入一定的「智慧」(intelligence)。這篇論文其實就是訓練了一個小型語言模型來做這個 `read` 的功能,讓它能夠根據指令,找出最合適的內容,再傳給主要的 Agent 處理。 ## 過濾 簡報:004339.jpg ![004339.jpg](https://hackmd.io/_uploads/S15ngyI2Zx.jpg) 時間:00:40:03 ~ 00:43:39 重點: 回顧一下 OpenClaw 處理 Memory 的部分,它其實用了兩個函式:`memory_search` 和 `memory_get`。 我們之前沒細講為什麼需要 `memory_get` 這個工具,因為 Memory 本質上只是個文字檔,用一般讀檔函式也能讀出內容。但 OpenClaw 設計這個特別的工具,主要是為了實現「過濾」的概念。 `memory_get` 不只接受檔案名稱,它還會額外傳入兩個數字,代表要從檔案的第幾行開始讀,以及總共要讀多少行。這樣做是為了防止 Memory 檔案資料量過大,把所有內容一次都塞進 LLM 的 Context Window,否則模型會「崩潰」。所以它只能從巨大的 Memory 檔案中,只取出一小段的內容。 具體流程是:`memory_search` 負責判斷要從哪裡找;然後結合 LLM 自己的判斷,再使用 `memory_get` 這個工具,只存取到需要的極小部分。 ## 過濾:按需加載 簡報:004434.jpg ![004434.jpg](https://hackmd.io/_uploads/Sk2ne18hWl.jpg) 時間:00:43:39 ~ 00:44:34 重點: 另外,還有另一個「過濾」的概念,就是「按需加載」(On-Demand Loading)。 當我們讓 AI Agent 使用工具時,傳統的做法是把所有工具的指令和說明,全部塞進 LLM 的 System Prompt 裡。但這會讓 System Prompt 非常長,舉例來說,光是使用 GitHub 的工具,指令就會有 4600 個 Token。如果工具越來越多,模型很快就會超過 Context Window 的上限。 所以,工具這種東西應該要動態加載。過去比較傳統的方法是:根據使用者輸入的任務,先在一個巨大的工具資料庫裡搜尋,把相關的工具指令抽取出來,再讓模型知道有哪些工具可以用。 但這篇論文發現,這個方法其實有很大的限制。因為使用者的需求往往很模糊,難以用搜尋引擎準確判斷需要哪些工具。例如,如果使用者只是說「幫我修改這個 Bug」,但實際上模型可能需要先用「讀檔」工具,然後再用「編輯」工具,這兩個工具的順序和組合,是很難直接從使用者模糊的提問中讓搜尋引擎判斷出來的。 這篇論文提出的核心想法是:我們能不能讓語言模型(LLM)能夠動態地決定它自己需要使用哪些工具? 簡單來說,當LLM讀到任務指令後,它會先「想一想」,然後輸出一個工具的需求。接著,用這個需求去操控搜尋引擎,讓搜尋引擎找出它需要的工具。最後,LLM就可以使用這個工具來繼續完成任務。 這個機制其實跟OpenClaw裡面的「skill」概念很相似。重點在於,這個技能(skill)是採用「按需加載」(on-demand loading)的。我們不會把所有的技能都塞進到上下文(context)或提示詞(prompt)裡,而是只有在真正需要的時候,才從硬碟把這個技能讀出來,放到提示詞裡使用。 ## Agentic Context Engineering ![image](https://hackmd.io/_uploads/HJVwObjnWg.png) 重點: 到目前為止,我們談的 Context Engineering 都是基於人類設計的,也就是說,我們是手動寫好固定的指令,讓程式依照這些指令來處理 Context。 但如果我們想讓 Context Engineering 更複雜、更有智慧,就會想到一個概念,叫做 **Agentic Context Engineering**。這個想法來自一篇論文,核心概念就是:把 Context Engineering 這個任務,交給語言模型自己來處理,而不是完全依賴人類設計。 簡單來說,原本是人類工程師設計的 Context,現在我們讓語言模型來當「工程師」自己想辦法優化 Context。 ## Agentic Context Engineering 簡報:004701.jpg ![004701.jpg](https://hackmd.io/_uploads/BypnxJU2-e.jpg) 時間:00:44:34 ~ 00:47:01 重點: 它的運作機制是: 1. 從一個初始的 Context 開始。 2. 語言模型接收 Context 和一個 Input,產生一個 Output。 3. 接著,我們會把 Context、Input 和 Output 全部串起來,形成一個新的 Context(我們稱它為 Context t+1)。 4. 這個過程會不斷重複(Context t+2...),讓語言模型持續地根據新的 Context 進行迭代。 不過,這裡有個重點要特別注意:雖然讓 LLM 自己處理 Context 的大部分內容,但我們通常會固定住一個 **System Prompt**。因為 System Prompt 包含了 AI Agent 本身的身份和最關鍵的資訊,這部分是不能隨意變動的。 所以,雖然 Agentic Context Engineering 讓 LLM 負責了 Context 的大部分優化,但我們還是需要把 System Prompt 當作一個固定不變的「核心 Context」來保護它。 ## Agentic Context Engineering ![image](https://hackmd.io/_uploads/H1UQYWs3-g.png) 重點: 提到 Agentic Context Engineering,早期的一個文獻是 Dynamic Cheatsheet,它把這個 context 稱為「小抄」(cheatsheet)。這個小抄的特點是會隨著時間不斷變化。 它的概念其實很簡單:就是呼叫一個語言模型,給它一段 prompt,然後告訴它我們這個 context 該如何改進,最後它就會把 $Context_t$ 轉換成 $Context_{t+1}$,就這樣結束了。 這裡的核心精神就是:用 prompt engineering 來做 context engineering。因為這段 prompt 寫得非常長,仔細看下來,它其實是要讓模型存下「未來可能用到的東西」,而不是存一些非常具體、只適用於當下任務的細節。例如,有效的策略、可以沿用一段程式碼,或是關鍵的發現,這些都可以存起來。但如果東西跟現在的任務沒有具體關聯,之後可能就用不上了,那就不需要存。 ## Agentic Context Engineering 簡報:004919.jpg ![004919.jpg](https://hackmd.io/_uploads/SJ0ngkUnZg.jpg) 時間:00:47:01 ~ 00:49:19 重點: 另一方面,像 Agentic Context Engineering 這篇 paper 做的就更複雜了。它把 $Context_t$ 到 $Context_{t+1}$ 的流程,設計成一個更複雜的步驟。它把 context 重新命名為「playbook」(守則手冊),希望語言模型能根據這個手冊來執行任務。 這篇 paper 實際做的事情,流程比較複雜,但重點是:它的 playbook 演化不是單一步驟,而是要經過三個語言模型分別進行不同的檢查。最後,它不會直接產生一個全新的 playbook,因為這樣可能會把舊的資訊弄壞。所以,它會產生一個「修改指令」,用這個指令去修改原來的 playbook,把 $Context_t$ 變成 $Context_{t+1}$,就像是讓一本舊的員工守則,變成了一本更新的版本。 ## Agentic Context Engineering 簡報:005135.jpg ![005135.jpg](https://hackmd.io/_uploads/Bklpek8nZl.jpg) 時間:00:49:19 ~ 00:51:35 重點: 提到另一篇論文,叫做《Recursive Language Model》,它其實也是「Agentic Context Engineering」的一個可能性。 這篇論文曾經非常有名,因為它號稱開發出一個可以處理無限長輸入的語言模型。但它真正做的事情,核心就是「Context Engineering」。 如果目前的 Context 實在太長了,怎麼辦?它會把大部分資訊放到硬碟(hard disk)裡,而只把極小一部分的 Context 載入到記憶體(memory)的 Prompt 裡。 這些存放在硬碟的資訊,會被記錄在一個叫做 **Metadata** 的地方。Metadata 只是非常簡短的資訊,例如:Context 總長度是多少、Context 被切成了幾段、這些區塊存放在哪裡等等。 用符號來說,硬碟裡的東西是 $M$,載入 Prompt 裡的才是 $P$。LLM 的工作就是根據 $P$ 的內容,去判斷它需要從 $M$ 裡尋找什麼資訊。 厲害的是,語言模型可以寫程式,用來對硬碟的內容進行搜尋。它會自主地知道要做 RAG(檢索增強生成),然後自己去硬碟搜尋資料,把這些資料拿出來,進而更新 Metadata,讓 $P_t$ 變成 $P_{t+1}$。 雖然論文討論了模型自主產生的模式,但我覺得這是否「神奇」,其實看個人。如果仔細看它的 Prompt,你會發現,做 Context Engineering 的 LLM 背後,其實需要的是 Prompt Engineering。它只是花了很大的力氣,不斷地暗示語言模型:「你直接做 RAG 吧!」讓語言模型寫了一個程式來執行 RAG。 所以,雖然從 Prompt 本身看來沒那麼神奇,但它的實際表現是非常優秀的。 ## Agentic Context Engineering 簡報:005225.jpg ![005225.jpg](https://hackmd.io/_uploads/HyW6eJU3bx.jpg) 時間:00:51:35 ~ 00:52:25 重點: 不過,雖然原來的 GPT-5 已經是很厲害的模型,但它有一個限制,就是當輸入的內容越來越長,到某個長度之後,它就無法處理某些任務了。 這時候,像 All-Long 這種基準測試(benchmark)就是用來檢驗語言模型在處理超長上下文(context)時,表現是否穩定。 但後來加入了這個「遞迴語言模型」(Recursive Language Model)。因為它本身是一種上下文工程(context engineering)的方法,所以最大的優點是它可以外掛到任何現有的語言模型上。 舉例來說,如果把它外掛到 GPT-5 上,就能讓本來就很強的 GPT-5 變得更厲害。這樣即使輸入的內容非常長,像是長達 100 萬個 token,它在長上下文的測試上依然能做出不錯的效果。 ## Context Engineering 簡報:005305.jpg ![005305.jpg](https://hackmd.io/_uploads/r1GaxkU2bl.jpg) 時間:00:52:25 ~ 00:53:05 重點: 今天這部分主要就是系統性地介紹了「Context Engineering」。 他們這邊有一個演算法,用來總結 Context Engineering 實際做的事情。另外,我們也了解到 Context 其實可以分成兩部分:一部分是 M,它存在於我們的硬碟裡;另一部分是 P,這個才是真正會當作 Prompt 丟給語言模型的內容。 最近有一系列新的研究,嘗試讓 Context Engineering 中最關鍵的「F」部分,不再需要由人類工程師來設計,而是可以交給語言模型來處理。所以,接下來要跟大家分享的重點,就是這個 Context Engineering 的應用。 ## 全課總結 好的,我已經完整地閱讀了您提供的關於「上下文工程」(Context Engineering)的內容。這是一篇非常詳盡且結構化的技術分享,涵蓋了從基礎概念到前沿實踐的許多關鍵點。 為了更好地幫助您,我想確認一下您希望我根據這份材料做什麼?例如,您是希望我: 1. **總結核心概念?** (為您提煉出最重要的幾個知識點) 2. **結構化成筆記或大綱?** (方便您複習或分享給他人) 3. **回答特定問題?** (例如:「什麼是Context Engineering?」或「不同方法有什麼區別?」) 4. **進行比較分析?** (例如:比較不同上下文工程方法的優缺點) --- **💡 如果您只是想讓我為您總結這份材料的精華,我會這樣總結:** 這份材料的核心主旨是:**如何設計和管理輸入給大型語言模型(LLM)的上下文(Context),以提升模型的推理能力、記憶能力和任務完成的準確性。** ### 📚 核心知識點總結 #### 1. 什麼是上下文工程 (Context Engineering)? * **定義:** 指的是系統性地設計、構建和優化輸入給 LLM 的上下文信息流,確保模型在處理任務時能接收到最相關、最完整、最及時的資訊。 * **目的:** 彌補 LLM 的「短期記憶」限制,讓模型能夠像人類一樣,在複雜的、多步驟的任務中保持一致性和連貫性。 #### 2. 關鍵的上下文管理技術 (Memory & Retrieval) * **記憶機制 (Memory):** 讓模型記住過去的對話歷史。 * **短期記憶 (Short-Term Memory):** 僅保留最近的幾輪對話。 * **長期記憶 (Long-Term Memory):** 透過向量資料庫 (Vector DB) 和檢索增強生成 (RAG) 技術,將歷史對話或外部知識庫的相關片段檢索出來,作為上下文餵給模型。 * **檢索增強生成 (RAG - Retrieval-Augmented Generation):** * **流程:** 接收用戶問題 $\rightarrow$ 在外部知識庫中檢索最相關的文檔片段 $\rightarrow$ 將這些文檔片段與原始問題一起組合成一個豐富的上下文 $\rightarrow$ 餵給 LLM 進行回答。 * **作用:** 讓模型回答的內容有事實依據,避免「幻覺」(Hallucination)。 #### 3. 進階的上下文構建策略 * **Prompt Engineering (提示工程):** 這是最基礎的層面,通過設計結構化的指令(如角色扮演、Few-Shot Learning)來引導模型。 * **Context Window Management:** 由於 LLM 的上下文窗口是有限的,必須學會「捨棄」不必要的資訊,只保留關鍵的摘要或關鍵點。 * **Agentic Workflow (智能體工作流):** 將複雜任務拆解成多個步驟,讓模型像一個「智能體」一樣,在每一步執行後,根據結果來調整和構建下一輪的上下文。 #### 4. 總結流程圖 (Conceptual Flow) **[用戶輸入] $\rightarrow$ [記憶/檢索系統 (RAG)] $\rightarrow$ [構建的豐富上下文] $\rightarrow$ [LLM 模型] $\rightarrow$ [最終輸出]** --- **請告訴我您希望我根據這個總結,進一步進行哪方面的深化或調整!** ## 關鍵詞 - 這段文字內容非常豐富,涵蓋了從基礎的上下文管理到前沿的上下文擴展技術,結構清晰,邏輯連貫。我將其內容進行結構化整理,並提煉出核心概念,以便您能更全面地掌握這些知識點。 - - ## 🧠 核心主題:上下文管理與擴展技術 (Context Management & Expansion) - 這段內容的核心在於探討如何讓大型語言模型(LLM)處理**超出其原生上下文窗口限制**的資訊,以及如何更智慧地管理和利用這些資訊。 - ### 💡 第一層級:基礎的上下文管理(Context Window Management) - 這是指在模型能處理的有限空間內,如何有效組織和利用輸入資訊。 - * **核心概念:** 模型的「記憶容量」限制。 - * **關鍵技術(隱含):** - * **Prompt Engineering:** 透過設計提示詞來引導模型關注最重要的資訊。 - * **Context Summarization:** 將長篇輸入內容提煉成精華摘要,節省空間。 - ### 🚀 第二層級:上下文擴展與檢索(Context Expansion & Retrieval) - 當資訊量超過模型原生上下文窗口時,需要外部機制來「擴大記憶」。 - * **核心概念:** 不將所有資訊塞進 Prompt,而是**按需檢索**。 - * **關鍵技術:** - * **RAG (Retrieval-Augmented Generation):** 這是最主流的技術。 - 1. **索引 (Indexing):** 將外部知識庫(文件、資料庫)切塊並轉換成向量(Embeddings)。 - 2. **檢索 (Retrieval):** 根據用戶查詢的向量,在知識庫中檢索出最相關的「上下文片段」。 - 3. **生成 (Generation):** 將原始 Prompt + 檢索到的上下文片段,一起餵給 LLM 進行回答。 - * **目的:** 讓模型可以參考外部的、龐大的知識庫來回答問題,克服上下文限制。 - ### 🧠 第三層級:進階的上下文管理策略(Advanced Strategies) - 這部分探討的是更精細、更自動化的上下文管理流程。 - #### 1. 記憶機制(Memory) - * **概念:** 讓模型記住**多輪對話**的歷史資訊。 - * **應用:** 在聊天機器人中,系統需要維護一個對話歷史記錄(Conversation History),並將其作為上下文傳遞給模型。 - #### 2. 資訊篩選與優化 - * **概念:** 避免將所有歷史對話都傳給模型,造成「上下文污染」或「成本過高」。 - * **技術:** - * **Summarization over Time:** 定期對舊的對話進行摘要,用摘要取代原始的長對話記錄。 - * **Sliding Window:** 只保留最近的 N 輪對話。 - ### 🌐 第四層級:前沿的上下文極限突破(State-of-the-Art) - 這部分涉及更底層的模型架構或極致的上下文處理。 - * **概念:** 突破單純的「輸入長度限制」。 - * **關鍵技術(提及):** - * **長上下文模型 (Long Context Models):** 指代那些原生支持極大上下文窗口的模型(如某些版本的 GPT 或 Claude)。 - * **Context Window 擴展方法:** 雖然沒有具體點名,但這類技術通常指代如 **Attention 稀疏化** 或 **KV Cache 優化** 等底層的架構改進。 - - ## 📝 總結與學習路徑建議 - 如果您是初學者,建議的學習順序是: - 1. **理解基礎:** 什麼是上下文窗口?為什麼它會滿? - 2. **掌握核心:** 深入學習 **RAG 流程**(這是目前企業級應用最核心的技術)。 - 3. **實戰應用:** 實作多輪對話的**記憶機制**(Memory)。 - 4. **進階研究:** 了解如何優化 RAG 的檢索階段(例如,使用多路檢索、重排序等)。 - **💡 關鍵詞彙總結:** - * **Context Window (上下文窗口)** - * **RAG (Retrieval-Augmented Generation)** - * **Embedding (嵌入)** - * **Vector Store (向量資料庫)** - * **Memory (記憶)** - * **Summarization (摘要)**