計實(shí)戰(zhàn)解析)
做了好一陣子大模型Agent相關(guān)的項目我發(fā)現(xiàn)一個特別有意思的現(xiàn)象很多人一開始追求把工具tool做得又多又全結(jié)果模型在真實(shí)任務(wù)里頻繁選錯工具、拼錯參數(shù)、中途翻車。真正讓Agent“好用”的往往不是你給它多少把螺絲刀而是你教會它“怎么修好一臺機(jī)器”——這正是我最近在整理的這套 agent-skills 技能庫方案想解決的事。簡單說agent-skills 不是又一份工具清單而是一套把“單點(diǎn)能力”升級成“可復(fù)用技能”的封裝框架。它給每個技能配上元數(shù)據(jù)、參數(shù)約束、執(zhí)行鉤子、失敗恢復(fù)邏輯讓 Agent 在接到任務(wù)時像老師傅一樣“憑經(jīng)驗干活”而不是每次從零推理。這套思路適合正在做 Agent 應(yīng)用、RAG 工作流、自動化助手的朋友參考也適合想弄明白“技能與工具到底差在哪”的開發(fā)者。我會把設(shè)計思路、落地代碼、踩坑實(shí)錄都攤開講盡量讓不同基礎(chǔ)的讀者都能拿去用。1. 內(nèi)容整體設(shè)計與思路拆解1.1 為什么 Agent 需要“技能庫”而不是一堆函數(shù)先聊一個常見場景。假設(shè)你想讓 Agent 幫你“整理一篇會議紀(jì)要”你可能會給它掛上三個工具一個做語音轉(zhuǎn)寫、一個調(diào)大模型做摘要、一個發(fā)郵件。模型確實(shí)能按順序調(diào)這三個工具但每次執(zhí)行都要重新理解任務(wù)、重新組織參數(shù)、重新處理中間結(jié)果。任務(wù)一多、上下文一變它就很容易在第二步忘了第三步的前提或者在參數(shù)上犯低級錯誤。問題不在于模型笨而在于我們只用 function calling 暴露了“零件”卻沒有給它“工序”。工具調(diào)用解決的是“單點(diǎn)動作”技能要解決的是“會做一件事”。在 agent-skills 里一個技能內(nèi)部可以包含多個工具調(diào)用、多步狀態(tài)流轉(zhuǎn)、前置條件檢查和輸出校驗。它像一個封裝好的黑盒模型只需要知道“這個技能能搞定會議紀(jì)要”至于內(nèi)部怎么轉(zhuǎn)寫、怎么摘要、怎么格式化都不需要重新決策。我常用一個比喻工具是一抽屜零件技能是一套成熟工序。給 Agent 一百個零件它未必能組裝出一臺機(jī)器給它十道工序它反而能穩(wěn)定交付結(jié)果。技能庫的價值就是把“零件”按場景組織成“工序”并且讓模型在接到任務(wù)時能快速檢索到最合適的工序。1.2 “技能”與“工具調(diào)用”的邊界在哪里我踩過不少坑之后總結(jié)出技能和工具的幾個核心區(qū)別看下面這張表比較直觀對比維度工具Tool技能Skill粒度單點(diǎn)能力如“發(fā)HTTP請求”多步驟任務(wù)如“抓取網(wǎng)頁并提煉要點(diǎn)”狀態(tài)無狀態(tài)每次調(diào)用獨(dú)立有內(nèi)部狀態(tài)支持階段流轉(zhuǎn)復(fù)用性可被不同技能引用本身是復(fù)用的最小業(yè)務(wù)單元容錯通常由調(diào)用方處理錯誤自帶前置檢查、后置校驗、降級恢復(fù)描述側(cè)重說明“我能做什么動作”說明“我適合解決什么任務(wù)”工具是技能的“底座”技能是工具的“編排層”。舉個例子一個搜索技能內(nèi)部會調(diào)用檢索 API工具但它還會做三件工具本身不做的事第一把用戶的模糊問題拆成 2-3 個具體檢索詞第二對檢索結(jié)果做相關(guān)度過濾第三如果主搜索源超時自動切到備選搜索源。這些動作疊加起來才是“會搜索”這個技能。從工程角度看把技能和工具分開還有一個現(xiàn)實(shí)好處工具的接口往往隨外部服務(wù)變動而技能的對外契約名稱、描述、入?yún)⒊鰠⒖梢员3址€(wěn)定。這樣 Agent 層面的提示詞和路由邏輯就不用頻繁改底層換了供應(yīng)商也不影響上層行為。1.3 技能庫的整體架構(gòu)分層我在設(shè)計 agent-skills 時把整個框架拆成了四層注冊中心、執(zhí)行引擎、上下文管理器、評估器。分層的核心原因只有一個——把“檢索”和“執(zhí)行”解耦把“狀態(tài)”和“邏輯”分離這樣后續(xù)加技能、調(diào)技能都不會牽一發(fā)動全身。注冊中心負(fù)責(zé)維護(hù)所有技能的元數(shù)據(jù)包括名稱、描述、標(biāo)簽、參數(shù) Schema、優(yōu)先級。Agent 接到任務(wù)后第一步不是直接執(zhí)行而是先來注冊中心“找技能”。這一步可以做成關(guān)鍵詞粗篩也可以疊加向量檢索把候選技能從幾百個縮小到三到五個。執(zhí)行引擎拿到候選技能后負(fù)責(zé)加載技能實(shí)例、執(zhí)行前置鉤子、運(yùn)行主邏輯、觸發(fā)后置校驗并且在失敗時調(diào)用恢復(fù)策略。上下文管理器比較容易被忽略它的職責(zé)是把技能執(zhí)行過程中的關(guān)鍵中間狀態(tài)暫存起來比如“當(dāng)前進(jìn)行到第幾步”“上一步產(chǎn)出了什么”這樣組合技能才能有序推進(jìn)。評估器則是一個閉環(huán)反饋模塊它記錄每次技能調(diào)用的命中率、成功率、token 消耗方便你持續(xù)優(yōu)化技能描述和執(zhí)行邏輯。這四層配合起來整體流程大概是這樣Agent 收到用戶任務(wù)向注冊中心發(fā)起檢索拿到最匹配的技能描述后把任務(wù)參數(shù)交給執(zhí)行引擎引擎按技能內(nèi)部定義好的階段逐步執(zhí)行每走一步都從上下文管理器讀寫狀態(tài)最終結(jié)果通過評估器記錄質(zhì)量再把關(guān)鍵信息寫回技能的記憶緩存作為下次執(zhí)行的參考。后面我會給一個簡化版實(shí)現(xiàn)方便你理解每個環(huán)節(jié)到底做了什么。2. 核心細(xì)節(jié)解析與實(shí)操要點(diǎn)2.1 技能描述Agent 選擇技能的“門面”如果你只能優(yōu)化一件事我會毫不猶豫地建議你打磨技能描述。因為技能實(shí)現(xiàn)得再完美模型找不到它、或者把它和別的技能搞混等于白寫。技能描述本質(zhì)上是寫給大模型看的“使用說明書”它的目標(biāo)不是讓人類看懂而是讓模型在“什么場景下該選中我”這件事上沒有歧義。我寫技能描述時會遵照一個檢查清單意圖關(guān)鍵詞、適用場景、輸入限制、輸出格式、使用禁忌。意圖關(guān)鍵詞幫助模型快速匹配比如“會議紀(jì)要”技能的描述里要有“總結(jié)、紀(jì)要、提煉、議題”這些詞適用場景要寫清楚“什么任務(wù)適合你”比如“當(dāng)用戶提供會議錄音或速記文稿需要輸出結(jié)構(gòu)化紀(jì)要時”輸入限制要寫明白“你能接收什么格式”比如“支持 txt、md不支持音視頻直接輸入”輸出格式則要說明“你返回什么東西”比如“返回包含議題列表、結(jié)論、待辦事項的 Markdown 文本”使用禁忌同樣重要用來排除邊界情況比如“用戶只要求翻譯時不要使用本技能”。這里放一個正反對比你感受一下差別。反例描述“對文本進(jìn)行摘要?!薄珜挿耗P筒恢朗裁磿r候該用。正例描述“當(dāng)用戶提供一篇文章、報告或網(wǎng)頁正文需要提煉核心觀點(diǎn)和關(guān)鍵數(shù)字時使用。輸入為純文本輸出為 200 字以內(nèi)的要點(diǎn)列表。若用戶僅要求翻譯或改寫不使用本技能。”你看后者直接幫模型把決策邊界框好了。還有一個實(shí)操細(xì)節(jié)描述不要寫實(shí)現(xiàn)細(xì)節(jié)。我見過有人把內(nèi)部調(diào)用了幾個 API、用了什么模型都寫進(jìn)技能描述里這純屬浪費(fèi) token模型根本不關(guān)心這些。描述里只需要寫“任務(wù)特征”和“契約約束”實(shí)現(xiàn)細(xì)節(jié)放到技能內(nèi)部文檔里就好。2.2 技能實(shí)現(xiàn)從需求到代碼的落地規(guī)范技能描述解決的是“模型怎么找到我”技能實(shí)現(xiàn)解決的是“找到之后怎么穩(wěn)定跑完”。我在 agent-skills 里給每個技能定義了一套標(biāo)準(zhǔn)鉤子相當(dāng)于給技能執(zhí)行流程立了個規(guī)矩環(huán)境準(zhǔn)備在前、核心邏輯居中、結(jié)果校驗在后、出錯有兜底。以 Python 為例一個技能類大致長這樣from pydantic import BaseModel class SkillInput(BaseModel): text: str max_points: int 200 class SummarySkill: name summary_skill description 當(dāng)用戶提供文章或報告需要提煉核心觀點(diǎn)時使用... def before_run(self, payload: SkillInput): # 前置檢查確認(rèn)輸入非空、長度合規(guī) if not payload.text.strip(): raise ValueError(text cannot be empty) return payload def run(self, payload: SkillInput): # 核心邏輯調(diào)用摘要模型整理要點(diǎn) points self._call_summarizer(payload.text, payload.max_points) return points def after_run(self, output): # 后置校驗確保輸出非空且是列表 if not isinstance(output, list) or len(output) 0: raise RuntimeError(summary output is invalid) return output def on_error(self, exc: Exception): # 兜底邏輯記錄錯誤并返回可讀信息 return {error: str(exc), fallback: None}這套鉤子的價值在于它把每個技能的“生命周期”固定下來執(zhí)行引擎只管按順序調(diào)用鉤子技能自己管內(nèi)部的業(yè)務(wù)細(xì)節(jié)。以后無論是加日志、加監(jiān)控還是做重試都落在框架層面而不需要改每個技能。另一個我特別想強(qiáng)調(diào)的規(guī)范是參數(shù)校驗。不要指望大模型每次都給你傳出完美的參數(shù)它經(jīng)常會把字符串傳成數(shù)字、把必填字段漏掉。所以每個技能的入?yún)⒁宦捎?Pydantic 這類 Schema 約束在 before_run 階段就校驗掉絕不要等到 run 內(nèi)部再花力氣解析臟參數(shù)。參數(shù)校驗的本質(zhì)是把“信任模型”改成“驗證模型”這是一種成本極低的防御手段。最后提一個原則技能盡量做到“冪等或可恢復(fù)”。所謂冪等就是同一個輸入跑兩次結(jié)果一致所謂可恢復(fù)就是跑到一半掛了下次可以接著跑而不是從頭再來。冪等能省掉很多重復(fù)執(zhí)行的麻煩可恢復(fù)則能避免外部副作用比如發(fā)了一封重復(fù)郵件帶來的事故。做不到冪等的時候至少要保證 on_error 里能明確告訴調(diào)用方“我已經(jīng)做到哪一步了”。2.3 技能注冊與檢索讓 Agent 快速找到技能有了技能類下一步就是把它們登記到注冊中心并且讓 Agent 在一個能接受的時延內(nèi)找到該用的那個。這里有個關(guān)鍵約束隨著技能增多你不能把所有技能描述一股腦塞進(jìn)系統(tǒng) Prompt否則上下文很快爆炸而且模型面對幾十個相似描述時會眼花繚亂。可行的方案是“粗篩 精排”兩步走。粗篩階段注冊中心根據(jù)用戶任務(wù)的文本按技能名稱、標(biāo)簽、描述里的關(guān)鍵詞做一輪快速過濾把幾百個技能縮小到 TopK我一般取 5 個。這一步速度極快不需要調(diào)用模型。精排階段把粗篩出的技能描述拼接成一段短列表交給模型做最終選擇讓它判斷哪個技能最匹配當(dāng)前任務(wù)。精排只關(guān)乎幾十個候選token 消耗可控選擇準(zhǔn)確率卻比“直接塞所有技能”高不少。如果技能數(shù)量特別大比如超過一千個我會再疊加一個 embedding 向量檢索層。你可以給每個技能描述生成向量存進(jìn)向量數(shù)據(jù)庫用戶請求進(jìn)來后用同一個 embedding 模型編碼請求文本做相似度檢索把最接近的幾十個技能送入粗排。這種做法在技能數(shù)量大時能有效提升召回率而且實(shí)現(xiàn)不難。需要注意的坑是技能描述里盡量不要出現(xiàn)和技能用途無關(guān)的“熱門詞”否則向量檢索會把無關(guān)技能拉進(jìn)來干擾后續(xù)精排。注冊中心本身建議做成輕量服務(wù)獨(dú)立于 Agent 主進(jìn)程。這樣技能更新不需要重啟主要服務(wù)注冊中心也可以單獨(dú)做緩存和監(jiān)控。我最初圖省事把技能注冊表寫死在代碼里結(jié)果每次加技能都要重新部署后來改成獨(dú)立服務(wù)之后加技能的熱更新終于順暢了。3. 實(shí)操過程與核心環(huán)節(jié)實(shí)現(xiàn)3.1 第一個技能一個關(guān)鍵詞搜索技能理論說了不少現(xiàn)在落地走一遍。我從最簡單的技能開始講關(guān)鍵詞搜索。這個技能的目標(biāo)不是“給你一個搜索鏈接”而是“根據(jù)問題自動生成檢索詞調(diào)用搜索接口并把返回結(jié)果整理成干凈列表”。拆解來看它包含四個步驟生成檢索詞、調(diào)用搜索 API、過濾無效結(jié)果、返回結(jié)構(gòu)化數(shù)據(jù)。下面是一段簡化后的實(shí)現(xiàn)骨架class SearchSkill: name search_skill description ( 當(dāng)用戶需要查找最新資料、新聞、文檔或網(wǎng)絡(luò)信息時使用。 輸入為自然語言問題我會自動生成2-3個具體檢索詞并執(zhí)行搜索 返回按相關(guān)度排序的結(jié)果列表。 ) def before_run(self, payload: SkillInput): if not payload.query.strip(): raise ValueError(query is empty) return payload def run(self, payload: SkillInput): # 1. 用輕量模型將用戶問題拆成多個具體檢索詞 keywords self._expand_queries(payload.query) # 2. 依次調(diào)用搜索API合并返回結(jié)果 raw_results [] for kw in keywords: raw_results.extend(self._call_search_api(kw, top5)) # 3. 過濾掉重復(fù)和明顯無關(guān)的條目 return self._dedup_and_filter(raw_results) def after_run(self, output): if not output: return {has_results: False, items: []} return {has_results: True, items: output[:10]}我第一次測試這個技能時發(fā)現(xiàn)模型最常犯的錯誤是“檢索詞寫得太寬泛”。比如用戶問“Agent 框架有哪些新進(jìn)展”模型直接生成一個“Agent 框架進(jìn)展”這種大而無當(dāng)?shù)臋z索詞搜出來的結(jié)果大多不是近期的有效信息。后來我在技能描述里加了一句明確指示“將檢索詞拆成 2-3 個具體的短語組合比如‘Agent 框架 2025 開源項目’、‘LangChain 新功能 發(fā)布’。”加了這一句之后搜索結(jié)果的質(zhì)量提升非常明顯。這再次印證了我在 2.1 里說的技能描述里寫清“怎么做事”往往比單純堆邏輯更能改變模型行為。測試完整鏈路時我會模擬一條用戶消息觀察 Agent 是否選中 SearchSkill以及傳給技能的 query 參數(shù)是否合理。如果模型沒選中多半是描述里的意圖關(guān)鍵詞還不夠直觀如果選中了但參數(shù)不對多半是參數(shù) Schema 寫得不夠清楚。這兩類問題在前期會反復(fù)出現(xiàn)屬于正常磨合過程。3.2 組合技能把多個原子技能編排成復(fù)雜流程單點(diǎn)技能只能解決一步操作真實(shí)任務(wù)往往需要多步配合這時候就要寫“組合技能”。組合技能的核心設(shè)計是內(nèi)部維護(hù)一個階段狀態(tài)機(jī)把多個原子技能按順序串聯(lián)起來并在每個階段落盤中間產(chǎn)物。拿“整理技術(shù)周報”來舉例。這個任務(wù)實(shí)際上要完成三件事搜索本周的技術(shù)熱點(diǎn)、對每篇熱點(diǎn)生成摘要、把所有摘要匯總成固定格式的周報。在 agent-skills 里我寫了一個 ReportSkill內(nèi)部注冊了 SearchSkill、SummarySkill、FormatSkill 三個子技能并定義了三個階段class ReportSkill: stages [search, summarize, format] def run(self, payload): state self.state_manager.new_session() # stage 1: 搜索熱點(diǎn) if state.stage search: hits self.call_sub_skill(search_skill, payload.topic) state.update({hits: hits, stage: summarize}) self.state_manager.save(state) # stage 2: 逐篇摘要 if state.stage summarize: summaries [ self.call_sub_skill(summary_skill, h[content]) for h in state.hits[:5] ] state.update({summaries: summaries, stage: format}) self.state_manager.save(state) # stage 3: 匯總輸出 if state.stage format: return self.call_sub_skill(format_skill, state.summaries)幾個關(guān)鍵點(diǎn)需要特別說明。第一階段狀態(tài)必須保存在技能實(shí)例之外最好放到獨(dú)立的 state_manager 里否則并發(fā)請求會串狀態(tài)。我最初把所有狀態(tài)都掛在技能對象上兩個請求同時進(jìn)來直接互相污染排查了半天才發(fā)現(xiàn)是這個原因。第二組合技能在描述里必須寫清楚“我會依次做什么”比如描述里寫“我會先搜索本周科技資訊再對前五篇生成摘要最后匯總為周報格式”這樣模型調(diào)用后不會對中間結(jié)果的形態(tài)產(chǎn)生錯誤預(yù)期。第三組合技能內(nèi)部調(diào)用子技能時仍要復(fù)用子技能本身的參數(shù)校驗和錯誤處理不要在組合層面重新解析一遍結(jié)果——這既浪費(fèi) token又容易把錯誤掩蓋掉。組合技能是 agent-skills 里最實(shí)用的部分。它能讓你把“多步驟任務(wù)”沉淀成可復(fù)用的經(jīng)驗而不是讓模型每次臨時規(guī)劃步驟。從工程效率看這相當(dāng)于把 Agent 的“臨場發(fā)揮”逐步變成“熟能生巧”。3.3 技能評估怎么判斷技能好不好用技能庫越擴(kuò)越大你會面臨一個更現(xiàn)實(shí)的問題怎么判斷技能到底好不好用我在早期一直憑感覺調(diào)參結(jié)果經(jīng)常是調(diào)完描述后感覺“應(yīng)該變好了”卻拿不出數(shù)據(jù)證明。后來我補(bǔ)了一套簡單的評估流程分成離線和在線兩部分。離線評估用歷史任務(wù)做回歸測試。我會收集過去一段時間內(nèi)真實(shí)用戶給 Agent 的任務(wù)請求把它們作為固定測試集。每次改完一個技能就把這批請求重跑一遍統(tǒng)計三個核心指標(biāo)技能命中率模型是否選對了技能、參數(shù)正確率傳給技能的參數(shù)是否合法、任務(wù)完成率技能是否產(chǎn)出合格結(jié)果。只要改動不導(dǎo)致這三個指標(biāo)回退我才敢放心上線。在線評估則關(guān)注技能調(diào)用鏈路上的效率。我會在日志里記錄每個技能實(shí)例的調(diào)用次數(shù)、平均耗時、平均 token 消耗、失敗次數(shù)、恢復(fù)次數(shù)。這里我特別關(guān)注一個容易被忽略的指標(biāo)單次技能調(diào)用消耗的平均 token。有些技能描述寫得過長模型每次選擇它都要閱讀大量無關(guān)文本久而久之 token 成本很高。優(yōu)化這些描述往往比換更貴的模型還劃算。我整理過一張參考速查表供你評估自己技能庫的健康度指標(biāo)健康范圍低于閾值說明技能命中率 85%描述意圖不夠清晰或檢索排序有問題參數(shù)正確率 90%參數(shù) Schema 和提示詞需要補(bǔ)強(qiáng)任務(wù)完成率 80%技能內(nèi)部邏輯或容錯策略需要迭代平均恢復(fù)率 60%on_error 兜底太弱錯誤容易直接暴露給用戶平均 token/調(diào)用越低越好描述冗余或內(nèi)部邏輯重復(fù)讀取無用信息這套評估體系不一定面面俱到但它至少能讓我在“優(yōu)化技能”這件事上不再靠感覺。每次改動技能我都能從數(shù)據(jù)里看到是命中率提升了還是 token 下降了這比“看起來不錯”要踏實(shí)得多。4. 常見問題與排查技巧實(shí)錄4.1 技能沖突與優(yōu)先級之爭技能多了之后第一個遇到的問題就是“兩個技能看起來都能解決同一個任務(wù)”。比如我既有“周報生成技能”又有“日報匯總技能”用戶說“幫我整理一下這周的工作”模型可能兩個都匹配最后選錯。這類問題的本質(zhì)是技能描述在意圖空間上發(fā)生了重疊。我的處理辦法有兩招。第一招在描述里主動加入“沖突排除條款”明確聲明自己的邊界。比如“日報匯總技能”描述里寫“僅當(dāng)用戶明確提到‘日報’或‘今日工作’時使用如果提到‘周報’‘本周’請改用周報生成技能”。這看起來像是在給別的技能做廣告但實(shí)踐證明它恰恰能降低模型的決策困惑。第二招在注冊中心給技能加一個優(yōu)先級字段當(dāng)粗篩得分相近時按優(yōu)先級排序。注意優(yōu)先級不能寫死要基于實(shí)際命中率動態(tài)調(diào)整某個技能在同類任務(wù)里命中率更高它的優(yōu)先級就自動上升。4.2 上下文爆炸與技能描述過長另一個高頻問題是技能一多系統(tǒng)提示詞越來越長。有些技能描述恨不得把用法、示例、注意事項全寫進(jìn)去結(jié)果模型在路由時反而抓不住重點(diǎn)而且每次請求都在空耗 token。這里我給自己定了一個硬性規(guī)則技能描述控制在 80 到 150 字詳細(xì)說明放到技能類內(nèi)部的一個usage字段里只在執(zhí)行時才加載。執(zhí)行引擎可以在 before_run 階段讀取 usage 字段作為技能內(nèi)部的運(yùn)行參考但不需要參與路由決策。我還踩過一個具體的坑把完整的技能源碼和調(diào)用示例直接貼在描述里。看起來信息很全但模型實(shí)際上根本不會逐字閱讀真正起作用的只有前一兩句“應(yīng)用場景描述”。后面那些代碼塊反而干擾了語義匹配讓模型對技能的能力邊界產(chǎn)生錯誤預(yù)期。刪掉冗余內(nèi)容之后命中率不但沒降反而上漲了約 7 個百分點(diǎn)。4.3 容錯與恢復(fù)技能翻車之后怎么辦技能跑得再穩(wěn)總會有翻車的時候。參數(shù)校驗失敗、外部服務(wù)超時、模型返回格式不對、下游接口報錯這些在真實(shí)環(huán)境里避無可避。我的經(jīng)驗是不要追求“永不失敗”而是追求“失敗后可理解、可恢復(fù)”。on_error 鉤子里至少要記錄錯誤類型和當(dāng)前階段讓上層 Agent 知道發(fā)生了什么以及能不能換一條路徑繼續(xù)。我總結(jié)了一張問題速查表按高頻優(yōu)先級列在下面錯誤類型常見原因解決建議參數(shù) Schema 校驗失敗模型漏傳字段或類型錯誤強(qiáng)化描述中的“需要輸入什么”并加 before_run 校驗外部服務(wù)超時第三方 API 響應(yīng)過慢在 run 里加重試機(jī)制超時閾值設(shè) 2-3 次輸出格式不合預(yù)期模型返回 Markdown 卻需要 JSON在 after_run 里做強(qiáng)校驗失敗時觸發(fā)重新生成階段狀態(tài)丟失并發(fā)會話污染或狀態(tài)未落盤狀態(tài)統(tǒng)一走 state_manager禁止掛在技能實(shí)例上子技能執(zhí)行失敗底層技能拋錯未捕獲組合技能要把子技能異常捕獲并標(biāo)記階段進(jìn)度針對超時和瞬態(tài)錯誤我的具體做法是在 run 階段包一層重試裝飾器第一次超時后重試一次并切換備選服務(wù)比如主搜索源失敗就換備用源。如果第二次仍然失敗直接走 on_error把“已經(jīng)嘗試兩次”的信息返回給上層模型讓它決定是否換一個技能或者詢問用戶。這一套下來技能庫的穩(wěn)定性提升明顯用戶面對“失敗”時至少不會看到一團(tuán)亂麻。還有一個容易忽略的點(diǎn)恢復(fù)策略要區(qū)分“可安全重試”和“不可安全重試”。比如發(fā)送郵件這種有副作用的操作重試前必須確認(rèn)上一步是否真的失敗了否則可能發(fā)兩封郵件。我在可寫操作的技能里都會加一個execution_id每次執(zhí)行生成唯一 ID下游接口用這個 ID 做去重。這樣即使框架層誤觸發(fā)重試也不會造成重復(fù)副作用。寫在最后的經(jīng)驗我把 agent-skills 這套技能庫陸續(xù)用在幾個 Agent 項目里之后最大的體會是技能描述花費(fèi)的時間比技能實(shí)現(xiàn)還要多。大多數(shù)人剛開始都急著寫邏輯、調(diào)接口真正決定一個 Agent 上限的往往是那些看起來“只是文字”的描述和約束。你花半小時打磨一段 150 字的技能描述可能比花三天優(yōu)化內(nèi)部算法更能提升整體任務(wù)成功率。另一個意外的收獲是技能庫天然幫你把散落的業(yè)務(wù)邏輯沉淀成了“組織的資產(chǎn)”——新同事接手項目時不需要讀一堆 Agent 編排代碼只看技能清單就能明白系統(tǒng)能做什么、邊界在哪里。后續(xù)我打算給技能庫加上評分反饋機(jī)制讓模型在每次成功調(diào)用后回寫一條“這個技能在什么場景好用”的經(jīng)驗記錄慢慢讓 Agent 形成自己的“手感”。這條路走通的話技能庫就不只是一個工具集而會成為 Agent 持續(xù)進(jìn)化的記憶底座。