:從工具編排到標準化技能庫的Agent穩(wěn)定性指南)
這兩年只要聊到Agent落地幾乎繞不開一個問題模型能力確實在漲但Agent干活的穩(wěn)定性和復雜度上限卡在技能的組織方式上。工具注冊頁幾十個函數(shù)堆在那里Prompt里塞滿各種能力說明結(jié)果模型還是經(jīng)常選錯、漏用、甚至把兩個工具的調(diào)用順序搞反。我折騰過幾輪方案之后把思路收斂到了一個名字上agent-skills。簡單說就是不再把能力當成零散工具扔給模型而是把每個能穩(wěn)定執(zhí)行的任務(wù)閉環(huán)定義成一個標準化的“技能”再交給Agent按需調(diào)度。這篇文章不是概念科普而是把我自己做技能庫設(shè)計、注冊、調(diào)度、排錯的全過程拆開講一遍。如果你正在做Agent功能開發(fā)或者剛被多工具編排的穩(wěn)定性折磨到頭疼這篇內(nèi)容可以直接拿來當參考骨架。從技能的定義標準到匹配打分公式再到一次真實任務(wù)的執(zhí)行日志我會盡量把每一步為什么這么做講清楚。1. 先想清楚Agent的“技能”到底是什么1.1 技能、工具、插件的邊界很多項目里工具、插件、技能這三個詞是混著用的。前端按鈕叫工具后端接口叫工具第三方服務(wù)接入叫插件然后模型函數(shù)調(diào)用也叫工具?;斓阶詈笥懻撜{(diào)度邏輯的時候根本說不清在調(diào)度什么。我自己的做法是先做嚴格區(qū)分。工具是最小可復用操作單元。它可以是一次API調(diào)用、一段固定算法、一個數(shù)據(jù)庫查詢。特征是輸入輸出明確不需要模型做復雜推理就能執(zhí)行。插件本質(zhì)上是適配外部系統(tǒng)能力的代理把外部系統(tǒng)暴露能力包裝成工具。技能則是面向一個具體業(yè)務(wù)目標編排出來的能力閉環(huán)它內(nèi)部可以調(diào)用多個工具也可以依賴其他技能并且包含校驗、回退、狀態(tài)處理。舉個例子發(fā)送HTTP請求是工具接入某個數(shù)據(jù)平臺是插件而“生成一份某項目的周報”就是技能。周報技能內(nèi)部可能拉取項目進展數(shù)據(jù)調(diào)用模板渲染檢查數(shù)據(jù)完整性最后產(chǎn)出Markdown。如果只把“拉取數(shù)據(jù)”“渲染模板”作為兩個工具暴露給模型模型很大概率會在拉數(shù)據(jù)之前就開始寫結(jié)論或者漏掉某個項目模塊。把整個過程封裝成技能以后模型只需要決定一件事當前請求該不該調(diào)用“生成周報”技能。我見過一個項目最初用了22個底層工具模型的工具命中率只有六成左右。后來把22個工具重新編排成了7個技能命中率提高到九成以上而且調(diào)用路徑也穩(wěn)定了。核心原因不是模型變強了而是決策維度從二十二選一變成了七選一判斷難度大幅下降。1.2 為什么需要一個獨立的技能層有人會問能力都封成技能是不是就把模型的靈活性限制住了這個擔心有一定道理但實際中遇到的更多問題是反向的靈活性太高導致行為不可控。沒有技能層時系統(tǒng)一般長這樣一個超大System Prompt里面把所有能做的事、所有工具說明、所有規(guī)則全部鋪給模型。模型每次請求都重新理解一遍導致幾類問題反復出現(xiàn)。第一Prompt過長關(guān)鍵信息被稀釋模型對低頻工具的感知會退化。第二工具間沒有約束關(guān)系模型可能調(diào)用一個應(yīng)該先預處理數(shù)據(jù)的工具。第三完全沒有評估單元你只知道模型返回了文本不知道它有沒有真的完成“收集數(shù)據(jù)、分析趨勢、生成結(jié)論”這一整套動作。第四無法復用換一個業(yè)務(wù)場景Prompt里的工具段落就得重新寫。技能層的核心作用是把不穩(wěn)定的大模型決策拆成兩層。上層是意圖路由模型只需要判斷“用戶想要什么”。下層是技能執(zhí)行對應(yīng)一系列定義好的確定性邏輯。這樣既保留了大模型的語義理解能力又把關(guān)鍵動作固定成可控流程。你可以把它理解成給一個比較有想法的新人配了一批標準作業(yè)程序新人負責判斷接哪個活具體每個活怎么做按程序來。同時技能層還帶來一個隱藏價值可測試性。普通工具函數(shù)可以寫單測但Agent行為很難寫單測。技能定義一旦完成就能對執(zhí)行結(jié)果做結(jié)構(gòu)化校驗。輸入Schema、輸出Schema、依賴列表、回退策略全部是機器可讀的這為后面的自動評估和質(zhì)量追蹤提供了基礎(chǔ)。2. 搭建技能庫從定義到落地的完整方案2.1 技能標準化定義技能標準化聽起來像是一個偏文檔的工作實際上它直接決定調(diào)度系統(tǒng)的檢索和匹配效果。技能定義不是給人看的手冊是給模型和路由模塊共同消費的數(shù)據(jù)。我最終收斂出的最小信息結(jié)構(gòu)包含四層身份層、語義層、協(xié)議層、執(zhí)行層。身份層很簡單技能ID、版本、所屬領(lǐng)域、優(yōu)先級。這是為了管理用的后續(xù)的統(tǒng)計、灰度、回滾都靠它。語義層是整個定義里最容易被忽視但最關(guān)鍵的部分。它包含技能名稱、描述、觸發(fā)條件、適用場景、反例。描述不能寫得像功能說明書要寫成“意圖說明書”。比如描述一個日報生成技能差的寫法是“生成日報”好的寫法是“當用戶需要匯總當日工作內(nèi)容、產(chǎn)出結(jié)果和明日的計劃時生成結(jié)構(gòu)化日報支持按項目、按時間段過濾”。這里的關(guān)鍵是回答兩個問題這個技能解決什么意圖什么情況下不應(yīng)該調(diào)用它。協(xié)議層用JSON Schema描述輸入和輸出。輸入字段必須有類型、必填性、約束條件輸出字段必須定義成功和失敗形態(tài)。這不僅是給模型看的也是執(zhí)行引擎用來做校驗的。協(xié)議定義得越嚴格下游做緩存、審計、重試就越簡單。執(zhí)行層是技能真正干活的部分。它定義技能內(nèi)部如何調(diào)用工具、依賴哪些其他技能、是否允許并行、失敗時怎么做。執(zhí)行層可以是代碼、工作流描述文件也可以是給模型的一段指令。我給一個實際的YAML示例這是我在項目里用到的技能定義結(jié)構(gòu)id: weekly_report name: 周報生成 version: 1.2.0 domain: report priority: high description: 當用戶需要按周匯總項目進展、分析風險并生成匯報文檔時使用。 適用于周維度的工作回顧不適用于日報或?qū)崟r狀態(tài)查詢。 triggers: - 用戶提到本周工作匯總 - 需要周報格式的報告 - 項目周例會材料準備 exclude: - 用戶只要日報 - 用戶只想查某個單條數(shù)據(jù) input_schema: type: object properties: project_names: type: array items: type: string description: 需要匯總的項目列表默認全部活躍項目 week_offset: type: integer default: 0 description: 0表示本周-1表示上周 required: - project_names output_schema: type: object properties: report_content: type: string description: 生成的Markdown格式周報 risk_items: type: array items: type: string generated_at: type: string format: date-time required: - report_content execute: engine: workflow steps: - collect_data: tool: project_data_sync params: projects: $input.project_names - analyze_risk: tool: risk_detector params: data: $steps.collect_data.result - render_report: tool: markdown_renderer params: analysis: $steps.analyze_risk.result fallback: - collect_data 失敗時嘗試使用 cache_reader 技能 - analyze_risk 失敗時跳過風險分析并標記 warning這個結(jié)構(gòu)用下來還算干凈。每個字段都指向一個明確用途沒有冗余。2.2 技能注冊與發(fā)現(xiàn)機制定義好技能之后要解決的就是注冊和發(fā)現(xiàn)。我在一開始犯過一個錯誤把技能放在一個大目錄里每次調(diào)度都去全量掃描。技能少的時候問題不大但是技能數(shù)量上了50個之后全量匹配的性能和準確性都開始出問題。后來我把注冊和發(fā)現(xiàn)拆成了兩條鏈路。第一條是元數(shù)據(jù)注冊中心負責保存技能定義、版本、狀態(tài)、健康記錄。技能上線之前要在這里做Schema校驗、依賴校驗、試運行。第二條是檢索鏈路負責在調(diào)度時快速找到候選技能。檢索鏈路會為每個技能建立語義索引、關(guān)鍵詞索引和標簽索引。語義索引用模型為技能描述生成向量匹配時把用戶請求也向量化用余弦相似度做初篩。關(guān)鍵詞索引覆蓋技能名稱、觸發(fā)詞、領(lǐng)域標簽用來做精確召回。標簽索引是人工維護的粗粒度分類比如“報告生成”“數(shù)據(jù)查詢”“任務(wù)調(diào)度”用來做領(lǐng)域過濾和權(quán)限控制。注冊中心提供統(tǒng)一的上報入口技能開發(fā)完成后調(diào)用注冊接口即可完成上線。我在項目里用的是這樣一個簡化接口內(nèi)部會完成健康檢查和索引刷新POST /skills/registry/register Content-Type: application/json { skill_file: skill_definition.yaml, source: team_a, environment: prod }注冊成功后系統(tǒng)會給技能分配一個全局唯一ID同時觸發(fā)索引構(gòu)建。索引構(gòu)建完成之前技能不會參與調(diào)度這樣避免上線半截技能被模型選到。圍繞發(fā)現(xiàn)機制我還有一個經(jīng)驗不要只依賴語義相似度做最終決策。語義相似度適合召回和排序但不適合做硬性過濾。原因是向量空間里的相近不代表業(yè)務(wù)意圖相同描述里有“日報”和“周報”兩個詞向量可能非常接近但業(yè)務(wù)上絕對不能混淆。所以最終調(diào)度要結(jié)合規(guī)則約束。3. 技能調(diào)度的核心邏輯如何讓Agent選對技能3.1 技能匹配與路由技能庫建好之后調(diào)度器就是大腦。調(diào)度器的任務(wù)是把用戶請求映射到正確的技能并在多個技能都匹配時做取舍。我的調(diào)度流程分四步。第一步請求解析把用戶原始輸入抽成結(jié)構(gòu)化意圖提取關(guān)鍵實體。第二步候選召回從索引里拉出得分最高的前N個技能。第三步打分排序綜合語義相似度、上下文匹配度、歷史成功率、成本代價計算綜合分。第四步閾值決策超過閾值的技能進入執(zhí)行隊列沒有超過則走兜底策略。打分公式我調(diào)過好幾版當前用的是這個score 0.45 * semantic_sim 0.20 * context_match 0.25 * historical_success 0.10 * cost_factorsemantic_sim是用戶請求與技能描述的語義相似度范圍0到1。context_match表示當前對話上下文與技能觸發(fā)條件的匹配程度觸發(fā)條件里有用戶剛提到的關(guān)鍵詞就給高分。historical_success是過去30天該技能的成功率用來抑制那些總執(zhí)行失敗但表面相似的技能。cost_factor則綜合計算調(diào)用該技能的預計Token消耗和延遲成本高的技能會被輕微降權(quán)。閾值我設(shè)的是0.65。低于0.65但高于0.4的請求進入“模糊候選區(qū)”系統(tǒng)會讓模型二次確認意圖或者把請求拆解后重新匹配。這個設(shè)計比直接拒絕體驗好很多因為很多請求本身就是復合意圖拆解后反而能命中多個技能。有一點要注意技能打分不能只看當前請求還要考慮會話歷史。用戶可能在前面幾輪里已經(jīng)提到了項目范圍后面只說“那生成周報吧”這時候單純看當前這句話語義匹配分不會很高。我處理的辦法是維護一個會話上下文向量每輪對話結(jié)束后把抽取到的實體和意圖合并進上下文再參與匹配打分。3.2 技能組合與編排很多任務(wù)不是單技能能搞定的。比如“把最近一周的線上事故梳理成報告并發(fā)給負責人”這里面至少包含“查詢事故記錄”“生成報告”“發(fā)送消息”三個技能。調(diào)度器需要支持技能組合。我把組合模式分成四類順序執(zhí)行、條件執(zhí)行、并行執(zhí)行、循環(huán)執(zhí)行。順序執(zhí)行最簡單前一個技能的輸出作為后一個技能的輸入。條件執(zhí)行是看前一個技能的執(zhí)行結(jié)果決定分支走向。并行執(zhí)行要求技能之間沒有數(shù)據(jù)依賴且累計成本可控。循環(huán)執(zhí)行通常用于批處理場景比如遍歷多個項目逐個生成周報。在實現(xiàn)層面技能定義里的execute字段會聲明依賴關(guān)系和數(shù)據(jù)類型。調(diào)度器執(zhí)行前會先做依賴拓撲排序確保每個技能的輸入都已經(jīng)被上游技能準備好。如果出現(xiàn)循環(huán)依賴注冊中心直接拒絕上線。組合執(zhí)行時最頭疼的是失敗處理。我見過太多工作流一條鏈路中間斷了整個任務(wù)就失敗了。實際上很多中間步驟是可以降級處理的。比如剛才說的“事故報告并發(fā)送”如果“發(fā)送消息”技能失敗報告本身已經(jīng)生成了完全可以降級成返回報告內(nèi)容提示用戶手動發(fā)送。這就是我在技能定義里增加fallback字段的原因。編排層面的另一個問題是Token消耗控制。技能一組合上下文容易變得很長。我不想為了讓模型理解流程就把所有中間結(jié)果全部塞進模型上下文。我的做法是執(zhí)行引擎自己做數(shù)據(jù)流轉(zhuǎn)只有最終呈現(xiàn)給用戶的輸出才進入模型上下文中間數(shù)據(jù)放在執(zhí)行狀態(tài)的內(nèi)部存儲里。這一步能把單次復雜任務(wù)的Token消耗降下來不少。4. 實戰(zhàn)用 agent-skills 跑通一個完整任務(wù)4.1 環(huán)境準備與初始化前面講的都是框架這節(jié)把實際操作過一次的完整流程拉出來。假設(shè)我要跑一個“站點健康巡檢”的任務(wù)核心是讓Agent每天自動檢查幾個數(shù)據(jù)源的健康狀態(tài)并生成一份巡檢報告。環(huán)境準備需要幾樣東西一個調(diào)度服務(wù)運行環(huán)境我用的是Python項目需要裝一些基礎(chǔ)依賴。一個向量索引服務(wù)用來做技能描述檢索。還有一個KV存儲用來保存會話上下文和技能執(zhí)行狀態(tài)。我給一個安裝依賴的參考命令pip install skills-sdk requests pydantic openai初始化目錄如下技能定義、執(zhí)行腳本、日志分開放后面排查問題會輕松很多。agent-skills-project/ skills/ health_check.yaml report_builder.yaml alert_dispatcher.yaml executors/ health_check_runner.py report_builder_runner.py alert_runner.py registry/ local_registry.json logs/ execution.log初始化的最后一步是啟動索引同步讓注冊中心感知到技能目錄下的所有YAML文件。啟動后會看到一行日志輸出顯示同步了3個技能定義并生成對應(yīng)向量索引。4.2 技能編寫與注冊先寫“站點健康巡檢”這個技能。這個技能做的事情是接收站點列表逐個發(fā)起探測請求記錄返回碼和響應(yīng)時間然后把結(jié)果整理成表格。技能定義如下id: site_health_check name: 站點健康巡檢 version: 1.0.0 domain: ops priority: high description: 當用戶需要檢查多個站點的可用性、響應(yīng)速度和錯誤狀態(tài)時使用。 適用于主動巡檢和定期任務(wù)不適用于分析歷史監(jiān)控數(shù)據(jù)。 triggers: - 巡檢 - 健康檢查 - 站點探測 exclude: - 用戶要分析監(jiān)控趨勢 input_schema: type: object properties: urls: type: array items: type: string format: uri description: 待檢查的站點地址 timeout: type: integer default: 5 description: 單站探測超時秒數(shù) required: - urls output_schema: type: object properties: results: type: array items: type: object properties: url: type: string status: type: integer response_ms: type: integer healthy: type: boolean summary: type: string required: - results - summary execute: engine: code ref: executors/health_check_runner.py fallback: - 單站點超時后跳過并標記異常 - 全部站點異常時調(diào)用 alert_dispatcher 技能對應(yīng)的執(zhí)行腳本核心邏輯很簡潔import asyncio import aiohttp async def run(input_data): urls input_data[urls] timeout input_data.get(timeout, 5) results [] async with aiohttp.ClientSession() as session: for url in urls: try: async with session.get(url, timeouttimeout) as resp: results.append({ url: url, status: resp.status, response_ms: round(resp.elapsed.total_seconds() * 1000, 2), healthy: resp.status 400, }) except Exception as exc: results.append({ url: url, status: 0, response_ms: None, healthy: False, }) healthy_count sum(1 for r in results if r[healthy]) summary f共檢查 {len(results)} 個站點健康 {healthy_count} 個異常 {len(results) - healthy_count} 個 return {results: results, summary: summary}寫完定義和腳本之后調(diào)用注冊接口把技能推上去curl -X POST http://localhost:8000/skills/registry/register \ -H Content-Type: application/json \ -d {skill_file: skills/health_check.yaml, source: ops_team, environment: prod}注冊成功后會收到一條包含技能ID和索引狀態(tài)的響應(yīng)我看到的是229號技能上線索引構(gòu)建耗時大概1.2秒。這時候技能庫就準備好接受調(diào)度了。4.3 任務(wù)執(zhí)行過程實錄接下來模擬一個真實請求。用戶發(fā)來一句話“幫我把首頁、訂單服務(wù)和支付網(wǎng)關(guān)都探測一下看看現(xiàn)在正常不。”調(diào)度器會先做意圖解析把這句話里的實體提取出來站點列表是首頁、訂單服務(wù)、支付網(wǎng)關(guān)意圖是站點健康巡檢。然后去技能索引里召回候選排在最前面的就是“站點健康巡檢”技能得分0.87超過閾值。執(zhí)行引擎接收技能定義里的輸入Schema自動構(gòu)造如下輸入{ urls: [ https://home.internal.example, https://order.internal.example, https://pay.internal.example ], timeout: 5 }隨后引擎調(diào)用執(zhí)行腳本得到結(jié)果{ results: [ { url: https://home.internal.example, status: 200, response_ms: 120.4, healthy: true }, { url: https://order.internal.example, status: 503, response_ms: 800.1, healthy: false }, { url: https://pay.internal.example, status: 200, response_ms: 215.9, healthy: true } ], summary: 共檢查 3 個站點健康 2 個異常 1 個 }按照fallback定義異常數(shù)大于0會額外觸發(fā)“告警分發(fā)”技能把訂單異常的信息推送到告警渠道。調(diào)度日志里能看到兩個技能先后執(zhí)行全部成功。這個流程看起來很順暢但我是踩了不少坑才跑通的。第一次跑的時候技能描述里的觸發(fā)詞寫得太具體只寫了“健康檢查”“巡檢”用戶換成“看看網(wǎng)站通不通”就匹配不到得分只有0.3直接走了兜底流程。后來我把描述改成了意圖導向加上了“可用性”“響應(yīng)速度”“正常不”這些口語化表達匹配分才上來。這個調(diào)整給我一個很深的印象技能描述是給語義模型看的要覆蓋用戶說話的正常變化而不是只寫內(nèi)部術(shù)語。5. 常見問題與排查技巧實錄5.1 技能命中率低匹配不到正確技能這是最常見的現(xiàn)象。表現(xiàn)是用戶請求明明很明確但調(diào)度器給出的最終得分很低技能沒有被觸發(fā)或者觸發(fā)了錯誤的技能。我一般按三個順序排查。第一個檢查點是技能描述。描述里如果用的全是抽象術(shù)語模型其實很難和用戶口語建立關(guān)聯(lián)。比如“獲取業(yè)務(wù)對象的關(guān)聯(lián)數(shù)據(jù)”這種描述在詞面上就和“我想看看這個訂單關(guān)聯(lián)的客戶信息”重疊度不高。解決辦法是重寫描述加入用戶視角的常見說法。第二個檢查點是召回索引。索引沒刷新會直接導致新技能和最近調(diào)整過描述的技能無法被召回。排查方法是先直接查索引里有沒有該技能的向量再看調(diào)度日志里召回階段返回的候選列表。第三個檢查點是閾值。閾值設(shè)得太高會把正常匹配殺掉。我會用一段時間的調(diào)度數(shù)據(jù)來校正閾值統(tǒng)計觸發(fā)請求得分分布找一個誤殺率和錯誤觸發(fā)率平衡的點。當前我的經(jīng)驗值是0.6到0.7之間比較穩(wěn)。還有一個很隱蔽的問題上下文匹配分權(quán)重過高導致帶上下文偏置的錯誤命中。比如用戶前面聊了幾輪“支付對賬”突然問“有哪些工具可以用”調(diào)度器可能因為上下文里反復出現(xiàn)支付而把“支付工具列表”技能排到前面。這個場景需要給上下文匹配加時間衰減只參考最近幾輪避免長期話題影響當下路由。5.2 技能沖突與依賴管理技能多了以后描述相近的情況會明顯增加?!吧芍軋蟆焙汀吧身椖恐軋蟆痹谡Z義上高度重合調(diào)度器無法精確區(qū)分時兩個都會被召回但靠前的可能不是用戶真正想要的。我的處理思路分三步。第一步盡量合并同類技能。如果兩個技能面向的核心意圖一致只是參數(shù)不同就合成一個通過輸入Schema和觸發(fā)條件細化來區(qū)分分支。第二步確實需要保留兩個技能的要在描述里寫出明確的排除條件讓語義模型能區(qū)分“日報場景”和“周報場景”。第三步在調(diào)度規(guī)則里維護一份人工的沖突消解表當兩個技能得分都超過閾值且差距小于0.05時優(yōu)先選擇優(yōu)先級高的那個。依賴管理的問題主要集中在循環(huán)依賴和幽靈依賴上。循環(huán)依賴是好查的因為拓撲排序會直接報錯。幽靈依賴更隱蔽技能B實際依賴技能A的輸出但定義文件里沒有聲明結(jié)果調(diào)度器單獨執(zhí)行技能B時數(shù)據(jù)為空。后來我強制要求在技能定義里寫明上游依賴再在注冊時掃描執(zhí)行腳本里的數(shù)據(jù)引用用自動化檢查替代人工記憶。5.3 性能與資源控制技能庫大了以后性能問題就來了。調(diào)度環(huán)節(jié)最明顯的瓶頸是語義檢索每個請求都要把請求文本向量化再和幾百個技能向量做相似度計算。優(yōu)化方向有兩個一是給向量索引建ANN索引把檢索從全量計算變成近似最近鄰但前提是技能數(shù)量確實大到全量已經(jīng)撐不住了二是在語義檢索之前先用關(guān)鍵詞索引做初篩把候選集合縮到幾十個以內(nèi)再做精確匹配。執(zhí)行環(huán)節(jié)的性能問題通常是上游工具響應(yīng)慢導致整個技能鏈路被拖住。我在前面介紹過給每個工具調(diào)用設(shè)置超時合理的超時值是上游P95響應(yīng)時間加一點緩沖而不是隨便設(shè)一個固定值。如果上游接口P95已經(jīng)到3秒超時設(shè)2秒就會頻繁觸發(fā)降級。資源控制還有一個容易被忽略的地方技能內(nèi)部如果維護了大量中間態(tài)的臨時數(shù)據(jù)比如大文件或者長文本緩存鏈路結(jié)束后必須顯式清理。我給執(zhí)行引擎加了執(zhí)行上下文池每次任務(wù)結(jié)束后統(tǒng)一回收中間數(shù)據(jù)否則跑一整天任務(wù)之后內(nèi)存會緩慢攀升直到觸發(fā)告警。我把這輪調(diào)試中遇到較多的問題整理成一張速查表供參考現(xiàn)象常見原因排查動作技能始終無法命中描述與用戶意圖語義跨度大重寫描述覆蓋口語表達新技能不參與調(diào)度索引未同步觸發(fā)索引重建檢查注冊狀態(tài)命中兩個相似技能描述邊界不清補充exclude條件設(shè)置優(yōu)先級技能鏈路中間失敗依賴聲明缺失檢查依賴列表補全上游依賴執(zhí)行結(jié)果一直重試上游響應(yīng)超時調(diào)大超時或增加緩存降級內(nèi)存緩慢上漲中間態(tài)數(shù)據(jù)未清理增加執(zhí)行上下文回收機制6. 一套沉淀下來的技能設(shè)計原則技能庫從混亂到穩(wěn)定這個過程持續(xù)了不短的時間最后沉淀出幾條我在新項目里會直接照做的原則。第一條單一職責。一個技能只完成一項業(yè)務(wù)目標不要試圖把“查數(shù)據(jù)寫報告發(fā)消息”塞進一個技能里。組合是調(diào)度器的事不是技能定義的事。集中在單個技能里的邏輯越復雜可測試性和可復用性就越差。第二條描述面向用戶意圖而不是面向?qū)崿F(xiàn)。技能描述里應(yīng)該回答“用戶什么時候需要我”而不是“我能做什么”。每次寫完描述我都會拿幾類真實的用戶請求去試召回效果看那些換了個說法的請求能不能被召回。第三條顯式聲明依賴。技能之間的數(shù)據(jù)依賴、順序依賴、沖突關(guān)系都要寫進定義不要讓調(diào)度器猜。任何隱藏的依賴都會在未來的某次調(diào)整中變成事故。第四條給每個技能設(shè)計降級路徑。所有技能都必須定義fallback動作哪怕只是返回錯誤信息和提示語。沒有降級路徑的技能在網(wǎng)絡(luò)抖動、服務(wù)異動的時候會成為整個Agent的瓶頸。現(xiàn)在再看agent-skills這個項目我覺得它的本質(zhì)不是技術(shù)框架的搭建而是把“模型能力”和“業(yè)務(wù)穩(wěn)定性”之間的邊界劃清楚了。模型做語義理解技能做行為約束兩者配合才能讓Agent既靈活又可靠。如果你也在重構(gòu)自己的Agent體系可以從定義第一批技能開始不要急著堆工具先把你最常用的幾個任務(wù)閉環(huán)寫清楚再逐步擴展。這個方向走通了以后后面接更多場景就不會慌。