AI智能體“上下文工程”實踐:來自 Manus 項目的經驗總結

轉載:https://manus.im/blog/Context-Engineering-for-AI-Agents-Lessons-from-Building-Manus

在啟動 Manus (manus.im/app) 項目之初,我的團隊面臨一個關鍵抉擇:究竟是基于開源基礎模型訓練一個端到端的智能體模型,還是在前沿大模型的“上下文學習”(In-Context Learning)能力基礎之上構建智能體?

在我從事自然語言處理 (NLP) 的第一個十年里,我們沒有這樣“奢侈”的選擇。在久遠的 BERT (arxiv.org/abs/1810.04805) 時代(沒錯,已經七年了),模型必須經過微調和評估才能遷移到新的任務上。即使當時的模型比現在的大語言模型(LLM)小得多,這個過程每迭代一次也常常需要數周時間。對于快速發展的應用,尤其是在達到產品市場契合點 (PMF) 之前,如此緩慢的反饋周期是無法接受的。這是我上一家創業公司留下的痛苦教訓,當時我從零開始訓練模型以實現開放信息提取(Open Information Extraction)和語義搜索。后來,GPT-3 (arxiv.org/abs/2005.14165) 和 Flan-T5 (arxiv.org/abs/2210.11416) 橫空出世,我內部開發的模型一夜之間便失去了競爭力。諷刺的是,正是這些模型開啟了上下文學習(In-Context Learning)的新時代,也為我們指明了新的前進方向。

這次來之不易的教訓使我們明確了選擇:Manus 將側重“上下文工程”(Context Engineering)。這讓我們能夠將改進的交付時間從數周縮短到數小時,并使我們的產品與底層模型保持獨立:如果說模型進步是水漲船高,那么我們希望 Manus 成為那艘隨波而動的船,而不是深陷海底的柱子。

盡管如此,實踐證明上下文工程絕非易事。它是一門實驗性科學——我們已經四次重構了我們的智能體框架,每一次都是在發現了更好的上下文構建方法之后進行的。我們親切地將這種架構搜索、提示詞調整和經驗性猜測的手動過程稱為“隨機梯度下降法”(Stochastic Graduate Descent)。它雖然不夠優雅,但確實有效。

本文將分享我們通過這種“隨機梯度下降法”找到的局部最優解。如果你也在構建自己的 AI智能體,我希望這些原則能幫助你更快地收斂。

圍繞 KV-緩存(KV-Cache)進行設計

如果只能選擇一個指標,我會認為 KV-緩存命中率是生產階段 AI 智能體最重要的單一指標。它直接影響延遲和成本。為了理解原因,我們來看看一個典型智能體 (arxiv.org/abs/2210.03629) 的運行方式:

智能體接收到用戶輸入后,會通過一系列工具使用來完成任務。在每次迭代中,模型會根據當前上下文從預定義的操作空間中選擇一個動作。該動作隨后在環境中執行(例如,Manus 的虛擬機沙箱)以生成一個觀察結果。動作和觀察結果會被附加到上下文中,形成下一次迭代的輸入。這個循環持續進行,直到任務完成。

可以想象,上下文會隨著每一步的執行而增長,而輸出(通常是結構化的函數調用)則相對較短。這使得智能體中的預填充(prefilling)與解碼(decoding)之間的比例,與聊天機器人相比,呈現出高度傾斜。例如,在 Manus 中,平均輸入與輸出 token 的比例大約是 100:1。

幸運的是,具有相同前綴的上下文可以利用 KV-緩存(medium.com/@joaolages/kv-caching-explained-276520203249),這大大減少了首個 token 的生成時間(TTFT)和推理成本——無論你是使用自托管模型還是調用推理 API。而且我們談論的不是節省一小部分:以 Claude Sonnet 為例,緩存的輸入 token 成本為 0.30 美元/百萬 token,而未緩存的則需要 3 美元/百萬 token——相差 10 倍。

從上下文工程的角度來看,提高 KV-緩存命中率涉及以下幾個關鍵實踐:

  1. 保持提示詞前綴的穩定性。 由于大語言模型 (LLM) 的自回歸(autoregressive)特性,即使是單個 token 的差異,也可能導致從該 token 開始的緩存失效。一個常見錯誤是在系統提示詞的開頭包含時間戳——特別是精確到秒的時間戳。當然,這可以讓模型告訴你當前時間,但也會極大地降低你的緩存命中率。

  2. 確保上下文只追加不修改。 避免修改先前的操作或觀察結果。確保你的序列化是確定性的。許多編程語言和庫在序列化 JSON 對象時無法保證鍵的順序穩定,這可能會悄無聲息地破壞緩存。

  3. 在需要時明確標記緩存斷點。 某些模型提供商或推理框架不支持自動增量前綴緩存,而是需要在上下文中手動插入緩存斷點。在設置這些斷點時,請考慮潛在的緩存過期,并且至少要確保斷點包含系統提示詞的末尾。

此外,如果你使用像 vLLM (github.com/vllm-project/vllm) 這樣的框架來托管模型,請確保前綴/提示詞緩存(docs.vllm.ai/en/stable/design/v1/prefix_caching.html)已啟用,并且你正在使用會話 ID 等技術來確保請求在分布式工作節點之間保持一致地路由。

遮蔽,而非移除

隨著智能體功能變得越來越強大,其操作空間自然也變得更加復雜——簡單來說,就是工具的數量呈爆炸式增長。最近 MCP(modelcontextprotocol.io/introduction)的流行更是火上澆油。如果你允許用戶配置工具,相信我:總會有人將數百個神秘工具插入到你精心策劃的操作空間中。結果就是,模型更有可能選擇錯誤的操作,或者采取低效的路徑。簡而言之,你的“全副武裝”的智能體反而變得更笨了。

一個自然的反應是設計動態動作空間——也許使用類似 RAG (en.wikipedia.org/wiki/Retrieval-augmented_generation) 的方式按需加載工具。我們在 Manus 中也嘗試過。但我們的實驗表明了一個清晰的規則:除非絕對必要,否則避免在迭代過程中動態添加或移除工具。這主要有兩個原因:

  1. 在大多數大語言模型 (LLM) 中,工具定義在序列化后位于上下文的前部,通常在系統提示詞之前或之后。因此,任何更改都將使后續所有動作和觀察結果的 KV-緩存失效。

  2. 當之前的動作和觀察結果仍然引用當前上下文中未定義的工具時,模型會感到困惑。如果沒有約束解碼(constrained decoding),這通常會導致模式(schema)違規或幻想出的動作。

為了解決這個問題,同時仍然改進操作選擇,Manus 使用了一種上下文感知的狀態機(state machine)來管理工具的可用性。它不是移除工具,而是在解碼時遮蔽(mask)token 邏輯值,以根據當前上下文阻止(或強制)選擇某些操作。

在實踐中,大多數模型提供商和推理框架都支持某種形式的響應預填充,這允許你在不修改工具定義的情況下約束操作空間。函數調用通常有三種模式(我們以 NousResearch 的 Hermes 格式 [github.com/NousResearch/Hermes-Function-Calling] 為例):

  • 自動(Auto) – 模型可以選擇是否調用函數。通過僅預填充回復前綴來實現:<|im_start|>assistant

  • 必需(Required) – 模型必須調用函數,但選擇不受限制。通過預填充到工具調用 token 來實現:<|im_start|>assistant<tool_call>

  • 指定(Specified) –模型必須從特定子集中調用函數。通過預填充到函數名稱的開頭來實現:<|im_start|>assistant<tool_call>{"name": “browser\_

通過這種方式,我們直接通過遮蔽 token邏輯值來約束操作選擇。例如,當用戶提供新輸入時,Manus 必須立即回復而不是執行操作。我們還特意設計了具有一致前綴的操作名稱——例如,所有與瀏覽器相關的工具都以 browser_ 開頭,命令行工具以 shell_ 開頭。這使我們能夠輕松地在給定狀態下強制智能體只能從特定工具組中選擇,而無需使用有狀態的邏輯值處理器。

這些設計有助于確保 Manus 智能體循環保持穩定——即使在模型驅動的架構下也是如此。

將文件系統用作上下文

如今前沿的大語言模型擁有 128K token 甚至更長的上下文窗口。但在實際的智能體應用場景中,這往往不夠,有時甚至會成為一個負擔。通常有三個痛點:

  1. 觀察結果可能非常龐大,尤其是當智能體與網頁或 PDF 等非結構化數據交互時,很容易超出上下文限制。

  2. 模型性能往往在超過一定上下文長度后下降,即使窗口技術上支持更長的上下文。

  3. 長輸入成本高昂,即使有前綴緩存。你仍然需要為傳輸和預填充每個 token 付費。

為了解決這個問題,許多智能體系統會實施上下文截斷或壓縮策略。但是,過度激進的壓縮不可避免地會導致信息丟失。這是一個根本性問題:智能體天生就需要根據所有先前的狀態來預測下一個動作——而你無法可靠地預測十步之后哪一個觀察結果可能變得至關重要。從邏輯角度來看,任何不可逆的壓縮都帶有風險。

這就是為什么在 Manus 中,我們將文件系統視為終極上下文:它大小無限、本質上是持久的,并且可以直接由智能體本身操作。模型學習按需寫入和讀取文件——將文件系統不僅用作存儲,還用作結構化的外部化內存。

我們的壓縮策略總是被設計為可恢復的。例如,只要保留 URL,網頁內容就可以從上下文中刪除;如果文檔的路徑在沙箱中仍然可用,其內容就可以省略。這使得 Manus 可以在不永久丟失信息的情況下縮短上下文長度。

在開發此功能時,我發現自己一直在思考,如何才能讓狀態空間模型(SSM)在智能體環境中有效工作。與 Transformer 不同,SSM 缺乏完整的注意力機制,并且在處理長距離向后依賴方面存在困難。但如果它們能夠掌握基于文件的內存——將長期狀態外部化而不是將其保存在上下文中——那么它們的速度和效率可能會開辟一類新的智能體。智能體 SSM 可能成為神經圖靈機(Neural Turing Machines)的真正繼承者。

通過復述(Recitation)操控注意力

如果你使用過 Manus,你可能會注意到一個有趣的現象:在處理復雜任務時,它傾向于創建一個 todo.md 文件——并隨著任務的進展逐步更新,勾選已完成的項目。這不僅僅是“可愛”的行為,更是一種刻意為之的“注意力操控”機制。

在 Manus 中,一個典型的任務平均需要大約 50 次工具調用。這是一個漫長的循環——由于 Manus 依賴于大語言模型(LLM)進行決策,它很容易偏離主題或忘記早期的目標,尤其是在長上下文或復雜任務中。

通過不斷重寫待辦事項列表,Manus 將其目標重復寫入上下文的末尾。這會將全局計劃推入模型的近期注意力范圍,從而避免“迷失在中間”的問題,并減少目標錯位。實際上,它正在使用自然語言來引導自己的注意力集中在任務目標上——而無需特殊的架構更改。

將“錯誤的數據”保留在上下文中

智能體(Agent)會犯錯。這不是 Bug,而是現實。語言模型會產生幻覺,環境會返回錯誤,外部工具會表現異常,意想不到的極端情況也時常出現。在多步驟任務中,失敗并非例外,而是循環的一部分。

然而,常見的本能是隱藏這些錯誤:清理軌跡、重試操作,或重置模型狀態并將其留給神奇的“溫度(temperature)”參數。這感覺更安全、更容易控制。但這會帶來代價:抹去失敗就等于消除了證據。而沒有證據,模型就無法適應。

根據我們的經驗,改進智能體行為最有效的方法之一出奇地簡單:將錯誤的路徑保留在上下文中。當模型看到失敗的操作以及由此產生的觀察結果或堆棧跟蹤時,它會隱式地更新其內部信念。這使得它不再傾向于類似的操作,從而減少重復相同錯誤的機會。

事實上,我們相信錯誤恢復是真正智能體行為最清楚的指標之一。然而,這在大多數學術研究和公共基準測試中仍然關注不足,這些研究和測試通常側重于理想條件下的任務成功率。

警惕少樣本提示(Few-ShotPrompting)的陷阱

少樣本提示(Few-Shot Prompting)是一種常見的提高大語言模型(LLM)輸出質量的技術。但在智能體系統中,它可能以微妙的方式適得其反。

語言模型是非常優秀的模仿者;它們會模仿上下文中行為模式。如果你的上下文中充滿了相似的過去“動作-觀察”對,模型就會傾向于遵循這種模式,即使它不再是最優的。

這在涉及重復決策或動作的任務中可能很危險。例如,當使用 Manus 協助審核一批 20 份簡歷時,智能體常常會陷入一種固定的節奏——重復執行類似的操作,僅僅因為它在上下文中看到了這些模式。這會導致偏離、過度泛化,有時甚至產生幻覺。

解決方案是增加多樣性。Manus 在動作和觀察中引入少量結構化變量——不同的序列化模板、替換措辭、在順序或格式上添加微小的噪聲。這種受控的隨機性有助于打破模式,并調整模型的注意力。

換句話說,不要讓少樣本提示將你引入困境。你的上下文越統一,你的智能體就越脆弱。

總結

上下文工程仍然是一門新興科學,但對于智能體系統而言,它已經至關重要。模型可能變得越來越強大、越來越快、越來越便宜,但再多的原始能力也無法取代對記憶、環境和反饋的需求。你如何塑造上下文,最終決定了你的智能體如何表現:它運行的速度、恢復的能力以及擴展的程度。

在 Manus,我們通過反復重寫、走入死胡同以及在數百萬用戶真實世界中的測試,汲取了這些經驗教訓。我們在此分享的并非普遍真理,但這些模式對我們來說是行之有效的。如果它們能幫助你避免哪怕一次痛苦的迭代,那么這篇文章就完成了它的使命。

智能體的未來將通過一次又一次地構建上下文來實現。請精心地進行這些工程。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/92295.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/92295.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/92295.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

day19 鏈表

定義鏈式存儲的線性表頭文件相關定義 typedef int datatype;//定義數據域類型 typedef struct Node {union{int len; //頭結點數據域datatype data; //普通節點數據域};struct Node *next; //節點指針域 }Node,*Node_ptr;鏈表的函數 注意事項 1.創建節點時&#xff0c;需要初…

【第三節】Class與Style綁定

文章目錄Class與Style綁定綁定HTML Class對象語法數組語法綁定內聯樣式對象語法數組語法自動添加前綴Class與Style綁定 數據綁定一個常見需求是操作元素的 class 列表和它的內聯樣式,因為它們都是屬性&#xff0c;我們可以用 v-bind 處理它們:我們只需要計算出表達式最終的字符…

CMOS知識點 離子注入工藝

知識點8&#xff1a;離子注入是為了將摻雜劑&#xff08;如硼、磷等&#xff09;精確引入硅晶片的近表面區域&#xff0c;以改變其電學性質。工藝過程&#xff1a;電離與加速&#xff1a;摻雜劑原子在離子源中被電離&#xff08;帶電&#xff09;&#xff0c;通過高壓電場&…

從安裝到上手:Ubuntu 22.04 玩轉 Containerd 2.1.3 容器運行時

Containerd 是一款支持 OCI 規范的容器運行時&#xff0c;注重容器部署和生命周期管理的簡單性、健壯性與可移植性&#xff0c;常被嵌入到 Docker 和 Kubernetes 等系統中。本文將詳細介紹在 Ubuntu 22.04 服務器上通過二進制包手動安裝 Containerd 的完整步驟&#xff0c;包括…

Hadoop與云原生集成:彈性擴縮容與OSS存儲分離架構深度解析

Hadoop與云原生集成的必要性Hadoop在大數據領域的基石地位作為大數據處理領域的奠基性技術&#xff0c;Hadoop自2006年誕生以來已形成包含HDFS、YARN、MapReduce三大核心組件的完整生態體系。根據CSDN技術社區的分析報告&#xff0c;全球超過75%的《財富》500強企業仍在使用Had…

飛算科技:以創新科技引領數字化變革,旗下飛算 JavaAI 成開發利器

作為國家級高新技術企業&#xff0c;飛算科技專注于自主創新&#xff0c;在數字科技領域持續深耕&#xff0c;用前沿技術為各行業客戶賦能&#xff0c;助力其實現數字化轉型升級的飛躍。?飛算科技憑借深厚的技術積累&#xff0c;將互聯網科技、大數據、人工智能等技術與實際應…

多線程Python爬蟲:加速大規模學術文獻采集

1. 引言 在學術研究過程中&#xff0c;高效獲取大量文獻數據是許多科研工作者和數據分析師的需求。然而&#xff0c;傳統的單線程爬蟲在面對大規模數據采集時&#xff0c;往往效率低下&#xff0c;難以滿足快速獲取數據的要求。因此&#xff0c;利用多線程技術優化Python爬蟲&a…

NX717NX720美光固態閃存NX724NX728

美光NX系列固態閃存深度解析&#xff1a;技術、性能與市場洞察一、技術架構與核心創新美光NX系列固態閃存&#xff08;包括NX717、NX720、NX724、NX728&#xff09;的技術根基源于其先進的G9 NAND架構。該架構通過5納米制程工藝和多層3D堆疊技術&#xff0c;實現了存儲單元密度…

淺談——C++和C#差異

雖然這個話題看著似乎有些關公戰秦瓊的味道&#xff0c;但是作為游戲開發者&#xff0c;C和C#一定是繞不開的兩門語言。不過雖然說是比較二者差異&#xff0c;因為我學習的過程主要是先學C&#xff0c;所以我先基于C的認知&#xff0c;再來聊聊C#之中的不同。&#xff08;為什么…

rocky9-zabbix簡單部署

目錄 一、準備 1、&#xff08;rocky9&#xff09; 2、配置數據庫 二、配置文件 1、導入初始架構與數據 2、配置相關文件 三、啟動服務 1、瀏覽器訪問 2、解決亂碼問題 ?編輯 四、監控 ① 添加主機 1、修改配置文件 2、啟動服務 3、網頁添加 ②添加監控模塊 1…

tabBar設置底部菜單選項、iconfont圖標(圖片)庫、模擬京東app的底部導航欄

歡迎來到我的UniApp技術專欄&#xff01;&#x1f389; 在這里&#xff0c;我將與大家分享關于UniApp開發的實用技巧、最佳實踐和項目經驗。 專欄特色&#xff1a; &#x1f4f1; 跨平臺開發一站式解決方案 &#x1f680; 從入門到精通的完整學習路徑 &#x1f4a1; 實戰項目經…

7.22總結mstp,vrrp

一、MSTP技術&#xfeff;&#xfeff;MSTI和MSTI域根&#xfeff;&#xfeff;MSTP中的端口角色3. MSTP工作原理 MSTP 計算方法? CST/IST的計算和RSTP類似 ? MSTI的計算僅限于區域內 ? MSTI計算參數包含在IST BPDU中&#xff0c;和IST的計 算同步完成&#xfeff;&#xfe…

【電腦】網卡的基礎知識

網卡&#xff08;Network Interface Card, NIC&#xff09;是計算機中用于連接網絡的關鍵組件之一&#xff0c;它負責管理和發送數據包到互聯網或其他局域網設備。下面是一些關于網卡的詳細知識&#xff1a;網卡的基本結構MAC地址&#xff1a;每個網卡都有一個唯一的物理地址&a…

IPv4枯竭時代:從NAT技術到IPv6的演進之路

&#x1f50d; 開發者資源導航 &#x1f50d;&#x1f3f7;? 博客主頁&#xff1a; 個人主頁&#x1f4da; 專欄訂閱&#xff1a; JavaEE全棧專欄 IPv4&#xff08;Internet Protocol version 4&#xff09;是互聯網最核心的通信協議之一&#xff0c;自 1981 年正式標準化以來…

模式結構-微服務架構設計模式

需求&#xff08;Forces)結果上下文(Resulting context)相關模式(Related patterns)需求&#xff1a;必須解決的問題需求部分描述了必須解決的問題和圍繞這個問題的特定上下文環境。需求有時候是相互沖突的&#xff0c;所以不能指望把他們全部都解決&#xff08;必須取舍&#…

30個常用的Linux命令匯總和實戰場景示例

下面匯總常用的 30 個常用的 Linux 命令&#xff0c;每個都附有簡要說明和典型示例&#xff0c;適合日常開發、服務器維護或系統學習使用。30 個常用的 Linux 命令匯總 一、文件與目錄操作&#xff08;基礎&#xff09;命令說明示例ls列出文件和目錄ls -l 顯示詳細信息cd切換目…

Taro 網絡 API 詳解與實用案例

Taro 網絡 API 詳解與實用案例 在現代前端開發中&#xff0c;網絡通信是不可或缺的一環。Taro 作為一款多端開發框架&#xff0c;提供了豐富且統一的網絡 API&#xff0c;幫助開發者在小程序、H5、React Native 等多端環境下高效地進行數據交互。本文將詳細介紹 Taro 的四大網…

Bitbucket平臺的HTTP Access Tokens操作手冊

在Bitbucket平臺添加HTTP Access Tokens&#xff08;用于替代密碼進行認證&#xff09;。 1. 登錄Bitbucket并訪問個人設置 打開 Bitbucket 并登錄賬號。點擊右上角頭像 → 選擇 Manage account。 2. 生成Access Token 在左側菜單中選擇 Access tokens&#xff08;位于 Sec…

低成本、高泛化能力的無人機自主飛行!VLM-Nav:基于單目視覺與視覺語言模型的無地圖無人機導航

作者&#xff1a;Gobinda Chandra Sarker1^{1}1, AKM Azad2^{2}2, Sejuti Rahman1^{1}1, Md Mehedi Hasan1^{1}1單位&#xff1a;1^{1}1達卡大學&#xff0c;2^{2}2伊瑪目穆罕默德伊本沙特伊斯蘭大學論文標題&#xff1a;VLM-Nav: Mapless UAV-Navigation Using Monocular Visi…

Docker Desktop 安裝到D盤(包括wsl)

默認WSL虛擬機位置&#xff1a; C:\Users\<用戶名>\AppData\Local\Docker\wsl重裝DockerDesktop下載安裝包Docker Desktop Installer.exe在D盤創建文件夾D:\Program Files\DockerDesktopD:\Program Files\DockerDesktop\data 在cmd運行 start /w "" "Dock…