用到記憶管理的智能體能力擴展實踐)
做AI應(yīng)用這一年多我越來越強烈地感覺到一個矛盾大模型的智商越來越高但每個Agent真正能“摸到”的東西卻少得可憐。你給它一個任務(wù)它的大腦確實足夠聰明可手邊只有一把螺絲刀再聰明也只能反復(fù)擰螺絲。所謂Agent-Reach說白了就是研究怎么把這只“手”伸得足夠遠(yuǎn)、足夠準(zhǔn)——讓Agent能觸達(dá)它需要的工具、數(shù)據(jù)和協(xié)作對象。這個項目我前后迭代了三輪從最開始只能調(diào)兩三個API的小玩具做到現(xiàn)在能同時調(diào)度幾十個工具、跨多個數(shù)據(jù)源取數(shù)、還能在出錯時自己換方案的工程化系統(tǒng)。這篇文章把完整的設(shè)計思路、踩過的坑、以及我反復(fù)調(diào)整后的最終架構(gòu)都記錄下來給同樣在做Agent落地、尤其是被工具調(diào)用和上下文管理折磨的朋友一些參考。我要先說清楚一個容易被忽視的事實Agent的能力上限很多時候不是模型決定的而是它的“觸角”決定的。模型再聰明看不到的數(shù)據(jù)就是不知道調(diào)不到的工具就是干不了。Agent-Reach的核心工作就三件事讓Agent看得更廣數(shù)據(jù)接入、夠得更遠(yuǎn)工具調(diào)用、記得更牢記憶管理。下面我從頭到尾拆一遍。1. 為什么“智能體的觸角”決定能力上限1.1 一個業(yè)務(wù)員的類比想象你手底下有個特別能干的業(yè)務(wù)員口才一流、腦子轉(zhuǎn)得快、談判技巧拉滿。但如果你只給他一部通訊錄里面就三個號碼他能談成的生意注定有限。你給他加一個行業(yè)人脈庫他能約到更多客戶再給他配一個產(chǎn)品報價系統(tǒng)他能在現(xiàn)場直接給方案再讓他能隨時調(diào)用財務(wù)、法務(wù)、供應(yīng)鏈的同事他就能處理真正復(fù)雜的訂單。Agent-Rach做的就是這件事——給模型這個“超級業(yè)務(wù)員”配上足夠多的號碼、系統(tǒng)和協(xié)作通道。這個類比不是隨便打的。我見過太多團隊把精力花在調(diào)prompt、換更強模型上結(jié)果瓶頸根本不在推理能力而在Agent的外部接口太少、太脆。你讓它寫一份行業(yè)分析報告它寫得挺好你讓它去查實時行情、調(diào)內(nèi)部數(shù)據(jù)接口、把結(jié)果整理成表格發(fā)給指定郵箱它直接卡死——因為后面這些動作需要“夠得著”外部世界。1.2 我在第一版踩的跟頭我最早做的Agent-Reach原型特別簡陋五個工具兩個數(shù)據(jù)庫查詢一個HTTP請求封裝再加一個文件讀寫。當(dāng)時測試效果很不錯模型基本指哪打哪。于是我很膨脹一口氣把工具加到二十多個結(jié)果準(zhǔn)確率肉眼可見地往下掉。當(dāng)時的表現(xiàn)很典型模型開始搞混相似工具比如把“查詢用戶訂單”調(diào)成“查詢用戶資料”有時候壓根不調(diào)用工具直接憑訓(xùn)練記憶瞎編數(shù)據(jù)還有的時候它選擇了正確的工具但參數(shù)格式傳錯了。我一開始以為是模型不夠聰明后來排查才發(fā)現(xiàn)是我自己犯了個經(jīng)典錯誤——工具一多選擇難度非線性上升而我沒有任何路由機制幫模型做決策。這個經(jīng)歷讓我重新理解了Agent-Reach的真正含義不是把工具堆得越多越好而是要建立一套機制讓Agent在龐大的工具集和數(shù)據(jù)源里用最低的試錯成本找到正確的那一個。單純的“多”沒有意義“準(zhǔn)”才有。1.3 “Reach”的定義一個可度量的能力空間在工程上我給Agent-Reach下了一個可執(zhí)行的定義一個Agent實例能夠直接訪問、并通過動作影響的外部空間集合。它包含四個維度工具層能調(diào)用的API、函數(shù)、服務(wù)比如訂單查詢、天氣接口、內(nèi)部工單系統(tǒng)數(shù)據(jù)層能讀取的數(shù)據(jù)庫、文檔庫、文件系統(tǒng)、網(wǎng)頁內(nèi)容記憶層能跨會話保留和檢索的歷史信息、項目上下文、用戶偏好協(xié)作層能觸達(dá)的其他Agent或人工審核通道這個定義最大的好處是它把“這個Agent強不強”從玄學(xué)變成了可測量的問題。你可以給每個維度打分然后精準(zhǔn)定位系統(tǒng)短板如果模型經(jīng)常答非所問可能是數(shù)據(jù)層不夠如果模型推理正確但執(zhí)行失敗可能是工具層封裝有問題如果同一件事?lián)Q個時間問它就不記得了那是記憶層缺失。后續(xù)所有優(yōu)化都是圍繞這四個維度展開的。2. 從“單點Agent”到“網(wǎng)狀Reach”整體架構(gòu)拆解2.1 單體Agent為什么扛不住很多入門教程教你寫的Agent其實是單體結(jié)構(gòu)一個循環(huán)模型思考→調(diào)用工具→觀察結(jié)果→再思考。這種結(jié)構(gòu)在工具少、任務(wù)單一的時候完全夠用但一旦Reach范圍擴大就會出三個問題。第一決策與執(zhí)行耦合。模型既要決定“調(diào)哪個工具”又要負(fù)責(zé)“怎么調(diào)”兩步都擠在一個上下文里容易互相干擾。第二上下文迅速膨脹。每調(diào)用一個工具結(jié)果都要塞回對話歷史多調(diào)幾次上下文窗口就滿了早期的關(guān)鍵信息被擠掉。第三錯誤無法隔離。一個工具超時或返回臟數(shù)據(jù)會污染整個鏈條模型接下來的每一步都在錯誤的基礎(chǔ)上做推理。所以我在第二版直接推倒重來把架構(gòu)拆成了清晰的層次。2.2 Agent-Reach的最終架構(gòu)整體分五層從上往下看層級職責(zé)核心組件協(xié)調(diào)層拆解任務(wù)、決定下一步行動、判斷是否完成Planner、Orchestrator路由層從工具注冊中心里選最合適的工具、校驗參數(shù)Router、Tool Registry執(zhí)行層真實調(diào)用外部API、數(shù)據(jù)庫、腳本Tool Executor數(shù)據(jù)層統(tǒng)一各種數(shù)據(jù)源的接入方式屏蔽差異Data Adapter記憶層分層存儲和檢索會話、項目、長期知識Memory Manager數(shù)據(jù)流的走向是這樣的用戶任務(wù)進(jìn)入?yún)f(xié)調(diào)層Planner先生成一個大致的執(zhí)行計劃路由層根據(jù)當(dāng)前這一步的需求去工具注冊中心檢索候選工具選定后由執(zhí)行層真實調(diào)用調(diào)用結(jié)果經(jīng)過數(shù)據(jù)層標(biāo)準(zhǔn)化后寫回記憶層再返給協(xié)調(diào)層判斷下一步。關(guān)鍵改動在于——模型不再直接面對幾十個工具的原始描述它面對的是路由層篩選后的兩三個候選決策負(fù)擔(dān)大大減輕。2.3 為什么“決策”和“執(zhí)行”必須分離這個設(shè)計理念是我踩坑踩出來的。第一版里模型的prompt里塞了所有工具的JSON Schema讓它自己挑。工具少的時候沒事工具一多模型的選擇準(zhǔn)確率急劇下降而且每次推理都要重新“讀”一遍所有工具描述token消耗也高。把“選工具”這個動作單獨抽出來做成路由層之后有三個立竿見影的好處。第一模型上下文里只需要出現(xiàn)“這一步要做什么”而不是“所有可能的做法”信息密度更高。第二路由層可以獨立優(yōu)化比如用本地小模型做粗篩、用向量檢索做召回、再用規(guī)則校驗兜底而不用動主模型。第三路由層可以記錄每次選擇的命中率形成反饋數(shù)據(jù)慢慢調(diào)優(yōu)工具描述和權(quán)重。三層分離之后整個系統(tǒng)的可維護性上了個大臺階。以前改一個工具要重新測一整套流程現(xiàn)在只需要在注冊中心改一條元數(shù)據(jù)。3. 工具注冊與動態(tài)路由讓Agent學(xué)會“夠得遠(yuǎn)”這一層是整個Agent-Reach的地基也是我投入時間最多的部分。工具注冊中心看著不起眼但它直接決定模型能不能在關(guān)鍵時刻選對工具。3.1 用統(tǒng)一Schema描述工具拒絕自由發(fā)揮我見過很多團隊的工具描述寫得特別隨意有的寫“這個函數(shù)用來獲取用戶信息”有的干脆只貼一個函數(shù)簽名。這在工具少的時候無所謂工具一多模型根本分不清“獲取用戶信息”和“獲取用戶訂單”到底有什么區(qū)別參數(shù)也容易傳錯。我在Agent-Reach里給每個工具定義了一份結(jié)構(gòu)化元數(shù)據(jù)用JSON Schema承載包含工具名稱、一句話功能摘要、詳細(xì)描述什么時候該用、什么時候不該用、參數(shù)定義類型、必填、枚舉值、示例、返回值結(jié)構(gòu)、錯誤碼表。TOOL_SCHEMA { name: query_user_orders, summary: 查詢用戶的歷史訂單列表, description: ( 當(dāng)需要獲取某個用戶在某段時間內(nèi)的訂單記錄時使用。 注意該接口只返回已支付訂單不含未支付或已取消的單。 如果需要查詢訂單的物流狀態(tài)請使用 query_order_logistics。 ), parameters: { type: object, properties: { user_id: {type: string, description: 用戶唯一標(biāo)識}, start_date: {type: string, format: date, description: 開始日期如2024-01-01}, end_date: {type: string, format: date, description: 結(jié)束日期如2024-06-30} }, required: [user_id] }, return_schema: { type: array, items: { type: object, properties: { order_id: {type: string}, amount: {type: number}, status: {type: string, enum: [paid, refunded, shipped]} } } } }這份Schema看起來啰嗦但它至少解決三個問題一是給路由層提供了檢索和排序的依據(jù)二是給模型提供了足夠的語義信息來區(qū)分相似工具三是執(zhí)行層的參數(shù)校驗可以直接復(fù)用這套定義不用另寫一套。我建議所有工具都按這個模板補齊特別是“什么時候不該用”和“和相似工具的差異”這兩項能顯著減少模型選錯工具的概率。3.2 路由層先粗篩、再精排、最后兜底路由層的設(shè)計是我調(diào)了很久才穩(wěn)定下來的目前是三段式流水線。第一段是粗篩用關(guān)鍵詞匹配加常用工具優(yōu)先從注冊中心里快速撈出一批候選。這一步不追求精確只求別漏掉正確工具。第二段是精排把這一步的任務(wù)描述和候選工具的summary、description做向量相似度計算按分?jǐn)?shù)排序取Top 3。第三段是規(guī)則校驗檢查這Top 3里有沒有參數(shù)明顯對不上的比如任務(wù)里根本沒有user_id這個字段而某個工具必填參數(shù)就是user_id那就把分?jǐn)?shù)往下壓。粗篩和精排的代碼實現(xiàn)大概是這樣的def route_tool(task_step_description: str, registry: ToolRegistry, top_k: int 3): # 第一階段粗篩用關(guān)鍵詞和標(biāo)簽縮小范圍 candidates registry.keyword_search(task_step_description) if not candidates: candidates registry.get_default_tools() # 第二階段精排向量相似度計算 query_embedding embed(task_step_description) scored [] for tool in candidates: tool_embedding embed(tool.summary tool.description) score cosine_similarity(query_embedding, tool_embedding) # 第三階段規(guī)則兜底參數(shù)匹配度作為懲罰項 param_penalty 0.0 required_params tool.parameters.get(required, []) for p in required_params: if p not in task_step_description: param_penalty 0.1 scored.append((tool.name, score - param_penalty)) scored.sort(keylambda x: x[1], reverseTrue) return [name for name, _ in scored[:top_k]]這套三段式方案上線后工具選擇準(zhǔn)確率從之前的六成多恢復(fù)到九成以上。而且它還有一個好處每段都可以用不同的模型粗篩和精排甚至可以用不上大模型的本地算法完成只有最終把Top 3候選塞進(jìn)主模型prompt時才需要花錢推理。3.3 工具描述的藝術(shù)別寫說明書寫決策卡寫工具描述的時候大部分人容易陷入兩種極端要么太簡略比如“獲取訂單信息”要么太啰嗦把實現(xiàn)細(xì)節(jié)、歷史原因全寫進(jìn)去。我的經(jīng)驗是工具描述本質(zhì)是給模型看的“決策卡”它需要的是“什么場景選我、什么場景別選我”而不是“我內(nèi)部是怎么實現(xiàn)的”。舉個例子“查詢用戶訂單”和“查詢用戶訂單詳情”這兩個工具如果描述都只寫“查訂單”模型完全分不清。我后來把前者寫成“返回用戶訂單列表只包含訂單編號、金額、狀態(tài)等概要信息適合展示列表”把后者寫成“基于訂單ID返回單個訂單的完整詳情包括商品明細(xì)、收貨地址、支付流水適合需要完整信息的場景”。改動之后選擇準(zhǔn)確率立竿見影。我還養(yǎng)成了一個習(xí)慣每跑一批任務(wù)就把路由層選錯的case收集起來分析是描述問題還是參數(shù)問題。描述問題就改元數(shù)據(jù)參數(shù)問題就改Schema積累兩個月工具描述的迭代速度會非??臁?. 記憶與上下文擴展越過窗口限制拿數(shù)據(jù)4.1 上下文窗口是Agent最硬的物理瓶頸不管你用哪個模型上下文窗口都是有限度的。你可以說“無限上下文”是趨勢但在實際工程里塞得越多推理越慢、費用越高、準(zhǔn)確率反而下降。所以Agent-Reach的第四個重點維度是讓Agent在有限窗口內(nèi)拿到它真正需要的信息。我見過不少項目把整份對話歷史一股腦塞給模型美其名曰“保留上下文”結(jié)果幾千個token全是廢話。解決這個問題的思路不是無腦堆窗口而是把記憶分層每層各司其職。4.2 三層記憶架構(gòu)工作記憶、項目記憶、檔案記憶我最終落地的方案是三層記憶每一層的存取策略完全不同。工作記憶Short-term只放當(dāng)前任務(wù)正在處理的中間狀態(tài)比如已經(jīng)執(zhí)行完哪些工具、當(dāng)前還差哪些信息、下一步計劃是什么。它的特點是短小精悍每次迭代都會更新最多不超過當(dāng)前任務(wù)范圍。項目記憶Project-level跨會話保留某個項目的重要決策和約束。比如“這個客戶的訂單查詢必須用V2接口”“這個報表的金額字段單位是分展示時要轉(zhuǎn)成元”。項目記憶是針對性的只在下一次會話開始時注入避免每次都要重新交代背景。檔案記憶Long-term把歷史對話、文檔、工具調(diào)用日志向量化后存入數(shù)據(jù)庫按需檢索而不是全量注入。這一步本質(zhì)上是一個小型的檢索增強生成RAG系統(tǒng)只不過檢索的對象是Agent自己的歷史經(jīng)驗。class MemoryManager: def __init__(self, vector_store): self.working {} self.project ProjectMemory.load() self.archive vector_store def get_prompt_context(self, task_id: str, task_description: str): # 工作記憶當(dāng)前任務(wù)的執(zhí)行狀態(tài) working_ctx self.working.get(task_id, {}) # 項目記憶和當(dāng)前任務(wù)相關(guān)的項目約束 project_ctx self.project.get_relevant(task_description) # 檔案記憶檢索歷史相似任務(wù)的執(zhí)行經(jīng)驗和結(jié)果 archive_ctx self.archive.search(task_description, top_k5) return { working: working_ctx, project: project_ctx, archive: archive_ctx } def update_after_step(self, task_id: str, step_result: dict): self.working[task_id][last_step] step_result if self.working[task_id].should_archive(): self.archive.add(self.working[task_id])三層記憶分開管理之后我發(fā)現(xiàn)prompt的體積平均下降了百分之四十以上而任務(wù)完成率反而升了。原因是模型不再被海量無關(guān)信息干擾注意力更集中。4.3 讓Agent“忘記”有時比記住更重要這里說一個反直覺的經(jīng)驗記憶系統(tǒng)最難的其實不是“存”,而是“刪”。如果你不主動清理過期的、錯誤的、重復(fù)的信息會像垃圾一樣堆積污染每一次推理。我踩過一個具體的坑有一次系統(tǒng)把某客戶三個月前的訂單狀態(tài)當(dāng)成最新狀態(tài)返回給用戶用戶投訴之后我一查發(fā)現(xiàn)是檔案記憶里的一條舊記錄被檢索出來而且它的相關(guān)度分?jǐn)?shù)比新記錄還高。問題出在向量檢索只比相似度不比時間新鮮度。修復(fù)方案是給每條記憶加了時間字段檢索時把時間衰減系數(shù)乘進(jìn)去。這個改動看起來小但直接避免了一整類數(shù)據(jù)新鮮度事故。所以現(xiàn)在我的記憶層有一條鐵律檢索結(jié)果必須帶時間權(quán)重工作記憶必須高保真檔案記憶必須可丟棄。寧可讓模型說“我不知道”也不能讓它拿著過期數(shù)據(jù)一本正經(jīng)地胡說。5. 實戰(zhàn)踩坑工具調(diào)用超時、上下文污染與幻覺的排查記錄寫這套系統(tǒng)的過程本質(zhì)上就是一段接一段的排錯史。我覺得把這部分單獨拿出來講比直接給一個“完美架構(gòu)”更有價值因為坑才是這個項目真正的老師。5.1 工具調(diào)用超時模型為什么會在一個失敗點上反復(fù)橫跳第一次做Agent-Reach的時候我給工具調(diào)用設(shè)了一個很簡單的封裝直接調(diào)用等返回結(jié)果。有一次一個第三方API響應(yīng)特別慢超過了模型的等待閾值返回的是個超時錯誤。這里我本來以為模型會換個方案結(jié)果它做了一件特別蠢的事——用一模一樣的參數(shù)再調(diào)一次同一個工具然后又超時又調(diào)循環(huán)了好幾次白白浪費了幾分鐘和一堆token。排查下來問題不在于模型笨而在于我沒有給它足夠的信息來做出“換方案”的判斷。超時錯誤只說了“request timeout”模型不知道這個超時是暫時的還是永久的也不知道有沒有備用接口可用它只能機械地重試。修復(fù)分兩部分第一給所有工具調(diào)用包了一層統(tǒng)一的執(zhí)行器內(nèi)置超時控制和重試策略第二把異常信息轉(zhuǎn)換成對模型友好的結(jié)構(gòu)化反饋。import time import concurrent.futures def execute_with_fallback(tool_func, params, timeout10, max_retries2): for attempt in range(max_retries): try: with concurrent.futures.ThreadPoolExecutor() as pool: future pool.submit(tool_func, **params) result future.result(timeouttimeout) return {success: True, result: result} except concurrent.futures.TimeoutError: if attempt max_retries - 1: time.sleep(2) continue return { success: False, error: TIMEOUT, suggestion: 接口響應(yīng)超時??蓢L試1. 縮小查詢時間范圍2. 改用batch接口3. 直接告知用戶稍后重試。 } except Exception as e: return {success: False, error: str(e)}改動之后模型看到的是“接口超時建議縮小查詢時間范圍”它就真的會去縮小參數(shù)范圍再試而不是原地打轉(zhuǎn)。這個教訓(xùn)讓我明白了一件事給模型反饋錯誤的時候一定要帶上可執(zhí)行的下一步建議否則它只能瞎猜。5.2 上下文污染同一個Agent會話里執(zhí)行風(fēng)馬牛不相及的任務(wù)會怎樣第二個大坑和記憶層有關(guān)。早期版本里我把所有任務(wù)的中間結(jié)果都存在同一個工作記憶區(qū)想著“反正對話是連著的共享天經(jīng)地義”。結(jié)果有一次同一個會話里先讓Agent分析了一份財務(wù)報告又讓它寫了一段營銷文案。兩個任務(wù)完全不相關(guān)但寫文案的時候模型居然引用了財務(wù)報告里的數(shù)據(jù)還煞有介事地編了個用戶畫像出來。這就是很典型的上下文污染。排查之后我發(fā)現(xiàn)根源在于工作記憶分區(qū)太粗不同任務(wù)的中間狀態(tài)混在一起。模型的注意力機制天然會去關(guān)聯(lián)最近的信息一旦它發(fā)現(xiàn)“上一個任務(wù)提過這個數(shù)字”就可能把它當(dāng)成當(dāng)前任務(wù)的上下文。修復(fù)方案是把工作記憶按task_id做嚴(yán)格隔離每次任務(wù)切換時清空上一層的工作記憶只保留項目記憶里明確標(biāo)記為“全局可用”的約束。此外我在prompt里也加了一條指令“如果當(dāng)前任務(wù)和之前任務(wù)主題不同不要在推理中引用之前的任何數(shù)據(jù)”。雙重保障之后類似問題基本絕跡。5.3 幻覺出一個不存在的工具這是最讓我哭笑不得的一個bug。有段時間模型頻繁調(diào)用一個我從來沒注冊過的工具叫“search_weather_in_city”而我整個系統(tǒng)里根本沒有天氣相關(guān)接口。一開始我以為是自己注冊遺漏了翻遍代碼也沒有。后來問模型為什么選這個工具它的回答是“根據(jù)函數(shù)名推斷這個工具應(yīng)該存在”。這句話一下點醒了我當(dāng)工具庫里工具數(shù)量膨脹、描述又不夠清晰時模型會把“功能名”當(dāng)成“真實存在的東西”。它在語義上覺得天氣查詢應(yīng)該有個工具于是就在幻覺里生成了一個。這個坑的修復(fù)分三層。第一層路由層兜底任何工具調(diào)用必須經(jīng)過工具注冊中心驗證名字不在注冊表里的直接拒絕不能放行到執(zhí)行層。第二層傳遞給模型的工具列表只保留Top候選而不是全部從源頭減少“幻覺空間”。第三層在系統(tǒng)提示詞里加一條硬規(guī)則“只能調(diào)用工具列表中明確存在的工具如果列表中沒有合適工具必須明確說明無法完成不得臆造工具名。”此后這個問題從頻發(fā)變成了偶發(fā)再后來基本消失。我把這三個排查案例放在一起是想說一個共性Agent的很多“蠢行為”根源不在模型而在系統(tǒng)沒有提供足夠清晰的邊界信息。你把邊界劃清楚模型自然就走準(zhǔn)了。6. 性能與成本權(quán)衡擴大Reach的同時別讓賬單爆炸6.1 Reach范圍擴大后成本為什么失控工具越多、記憶越多、路由越復(fù)雜單次任務(wù)的token消耗和延遲都會上臺階。我有段時間只盯著功能正確率完全沒管成本結(jié)果月底看賬單嚇了一跳一個看起來并不復(fù)雜的“用戶訂單分析”任務(wù)因為反復(fù)調(diào)用工具、每次把大量歷史記錄回灌進(jìn)prompt一次就要燒掉接近兩塊錢人民幣。這在生產(chǎn)環(huán)境是根本跑不起的。后來我逼著自己把一個完整任務(wù)的成本拆開看才發(fā)現(xiàn)大頭不在于主模型的推理而在于三件事工具調(diào)用結(jié)果反復(fù)注入上下文、路由層的多次向量檢索被重復(fù)計算、以及失敗重試帶來的額外輪次。6.2 實測成本拆解一次多步驟任務(wù)的賬單明細(xì)以“查詢某個用戶的訂單統(tǒng)計每月消費金額并生成一段總結(jié)”這個任務(wù)為例我記錄了改造前后的實際token消耗和預(yù)估成本按常見商用模型價格估算粗略折算環(huán)節(jié)改造前Token消耗改造后Token消耗原因系統(tǒng)提示詞工具列表4200900只注入Top工具而非全部任務(wù)規(guī)劃600600不變工具路由1200300路由獨立到小模型不占主模型上下文工具調(diào)用結(jié)果35001500只保留結(jié)構(gòu)化摘要不塞完整原始報文歷史記憶回灌2800700按需檢索搞掂時間衰減最終生成800800不變合計131004800約節(jié)省63%這個對比不是說改造前后功能變了而是同樣的功能用更聰明的架構(gòu)省掉了那些“模型不需要看但還是塞進(jìn)去”的token。6.3 我用的四個降本手段第一提示詞緩存。系統(tǒng)提示詞和工具Schema基本是常量用支持緩存的服務(wù)端方案后這部分token不再重復(fù)計費。第二結(jié)構(gòu)化摘要替代原始報文。工具返回的原始數(shù)據(jù)往往又長又雜我在執(zhí)行層過濾一遍只保留任務(wù)相關(guān)的字段并壓縮成要點再喂給模型。第三路由分層。粗篩和精排用本地模型或純向量計算只有需要模型決策的最后一步才走大模型。第四并發(fā)與批處理。獨立工具調(diào)用之間沒有依賴關(guān)系時用并發(fā)方式一起發(fā)出去既省時間又省重試成本。這幾件事做下來同樣任務(wù)的平均成本降了大半延遲也從七八秒降到三四秒。這里我給一個建議做Agent項目一定要把token消耗分成“必要消耗”和“浪費消耗”兩類。必要消耗是模型真正推理要花的浪費消耗是信息冗余、重復(fù)注入、失敗重試造成的。你優(yōu)化的方向不是讓模型“少思考”而是把該給它的給它不該給的堅決不給。6.4 什么情況下值得擴大Reach什么情況下不應(yīng)該最后說一點關(guān)于邊界的思考。Agent-Reach不是越大越好它是有邊際效應(yīng)的。我見過有些團隊逢接口必接、逢數(shù)據(jù)必連結(jié)果工具列表幾百個路由層自己都跑不動了。我的判斷標(biāo)準(zhǔn)是一個工具或者一個數(shù)據(jù)源如果在可預(yù)見的三個月內(nèi)不會被用到三次以上就不值得接入。讓它作為可動態(tài)加載的插件留在倉庫里比塞進(jìn)在線系統(tǒng)的注冊中心要明智得多。反過來如果某個數(shù)據(jù)源是核心業(yè)務(wù)流程反復(fù)依賴的那就必須接得深一點包括緩存、監(jiān)控、降級方案都要配齊。Reach的深度應(yīng)該跟著業(yè)務(wù)價值走而不是跟著好奇心走。最后聊兩句Agent-Reach這個項目做到現(xiàn)在要說最值錢的心得不是某個架構(gòu)多優(yōu)雅而是一句很樸素的話Agent的邊界是你畫的它的能力只能在你畫的邊界里兌現(xiàn)。你想讓它觸達(dá)更多就要把觸達(dá)的路徑鋪得足夠清晰你想讓它記得更牢就要把記憶的層次分得足夠干凈。如果你也正在被工具調(diào)用不準(zhǔn)、上下文塞不下、成本越跑越高這些問題折磨不妨先別急著換更強的模型回頭把Reach這套體系重新捋一遍很多問題會自己解開。這條路我還在繼續(xù)走后面有新的進(jìn)展再來更新。