制實(shí)戰(zhàn):從環(huán)境搭建到多智能體工作流編排)
最近在折騰多智能體框架發(fā)現(xiàn)圈子里聊 AgentScope 的人明顯多起來(lái)了。這個(gè)框架最打動(dòng)我的地方是它把“構(gòu)建多智能體應(yīng)用”這件事的門檻降得很低尤其是它原生支持的 skills 機(jī)制——簡(jiǎn)單說(shuō)你既可以把某個(gè) Agent 當(dāng)作一個(gè)技能注入到另一個(gè) Agent 的對(duì)話流里也可以把一段自定義的 Python 函數(shù)注冊(cè)成可復(fù)用的工具讓智能體在推理過(guò)程中按需調(diào)用。這篇內(nèi)容不是我抄文檔而是我把 AgentScope 的 skills 用法從安裝到跑通、再到踩坑填坑的完整過(guò)程捋了一遍。如果你正準(zhǔn)備在項(xiàng)目里把多個(gè)模型角色組織成一條工作流或者想讓某個(gè) Agent 具備調(diào)用外部工具的能力這篇文章應(yīng)該能幫你少走不少?gòu)澛贰U麄€(gè)方案經(jīng)過(guò)我本地實(shí)測(cè)驗(yàn)證所有的參數(shù)和示例都給出了可操作的具體寫法不同基礎(chǔ)的朋友都能照著落地上手。1. 深入理解 AgentScope 的 skills 機(jī)制1.1 為什么我最終選定了 AgentScope市面上的多智能體框架并不少。我用過(guò)不少同類工具它們各有亮點(diǎn)但總有幾個(gè)讓我覺(jué)得別扭的地方要么是將 Agent 的定義和模型綁定得太死換一個(gè)模型就要改一遍邏輯要么是把多智能體的調(diào)度寫得太重本地調(diào)試?yán)щy重重要么工具調(diào)用和 Agent 的對(duì)話管理是兩條獨(dú)立的邏輯維護(hù)成本很高。AgentScope 給我的感覺(jué)是“清爽”。它自帶一套完整的多智能體調(diào)度方案同時(shí)把 Agent 的定義、模型的接入、消息的傳遞和工具的執(zhí)行拆得很開。它提供了靈活的 pipeline 編排能力你可以用幾行代碼把多個(gè) Agent 串成一條流水線甚至支持分布式部署讓不同 Agent 跑在不同的進(jìn)程或者機(jī)器上。但真正讓我下定決心在項(xiàng)目里全面使用它的還是它把 skills 組織成第一等公民的這個(gè)設(shè)計(jì)。在 AgentScope 里一個(gè) skill 可以有兩種形態(tài)一種是一個(gè)完整的 ReagentAgent它有自己獨(dú)立的系統(tǒng)提示詞、模型配置和執(zhí)行邏輯你可以把它當(dāng)作一個(gè)“子 Agent”交給另一個(gè) Agent 去調(diào)用這就實(shí)現(xiàn)了 Agent 嵌套另一種形態(tài)是更輕量的工具函數(shù)通過(guò)注冊(cè)機(jī)制掛到某個(gè) Agent 上讓它在推理時(shí)決定何時(shí)調(diào)用。這兩種形態(tài)讓我在搭建復(fù)雜應(yīng)用時(shí)不用再糾結(jié)“到底該把邏輯塞進(jìn)提示詞里還是拆成一個(gè) Agent”而是可以根據(jù)復(fù)用性和復(fù)雜度自由取舍。我在實(shí)際項(xiàng)目中體驗(yàn)下來(lái)的感受是AgentScope 最值得稱道的是它把“Agent 調(diào)度”和“工具使用”統(tǒng)一到了同一個(gè)消息協(xié)議里。Agent 之間傳遞的是 msg 對(duì)象Agent 調(diào)用工具返回的也是 msg 對(duì)象。這讓整個(gè)系統(tǒng)的數(shù)據(jù)流動(dòng)非常干凈調(diào)試的時(shí)候用內(nèi)置的打印工具可以很直觀地看到每一步發(fā)生了什么。1.2 skills 機(jī)制的三種核心形態(tài)我剛開始接觸的時(shí)候?qū)Α皊kills”這個(gè)概念有些模糊因?yàn)榭蚣芾锊](méi)有一個(gè)叫 skill 的強(qiáng)制基類而是通過(guò)幾種不同的方式來(lái)實(shí)現(xiàn)“技能”這層抽象。我用一張表來(lái)區(qū)分這三種形態(tài)理解它們各自的適用場(chǎng)景形態(tài)實(shí)現(xiàn)方式適用場(chǎng)景我實(shí)際用的感受ReagentAgent 獨(dú)立技能定義一個(gè)新的 ReagentAgent設(shè)定自己的 system prompt 和 model作為可復(fù)用單元需要獨(dú)立記憶、獨(dú)立上下文、可能被多個(gè) Agent 復(fù)用的復(fù)雜技能配置稍多但復(fù)用性極強(qiáng)適合封裝領(lǐng)域?qū)<夜ぞ吆瘮?shù)注冊(cè)用AgentScope.init_tool或函數(shù)裝飾器把 Python 函數(shù)注冊(cè)為工具掛載到 Agent 上簡(jiǎn)單、無(wú)狀態(tài)的計(jì)算或信息獲取類操作輕量直接模型能根據(jù)描述自動(dòng)判斷何時(shí)調(diào)用多 Agent 編排技能通過(guò) pipeline 將多個(gè) Agent 串成一條工作流整體作為一個(gè)大技能有明確流程順序的復(fù)合任務(wù)閱讀代碼時(shí)邏輯清晰適合流程穩(wěn)定的場(chǎng)景這三種形態(tài)并不互斥實(shí)際項(xiàng)目中經(jīng)常搭配使用。比如我在做一個(gè)信息整理類的任務(wù)時(shí)先讓一個(gè)“檢索 Agent”通過(guò)工具函數(shù)去查數(shù)據(jù)再把結(jié)果交給一個(gè)“總結(jié) Agent”輸出結(jié)論最后通過(guò)一個(gè)“審核 Agent”做質(zhì)量把關(guān)。三個(gè)階段被組織成一個(gè) pipeline整體看就是一個(gè)復(fù)合技能。值得多說(shuō)一句的是AgentScope 對(duì)工具函數(shù)的參數(shù)schema處理得很好。你不需要手動(dòng)寫 JSON Schema框架會(huì)根據(jù)函數(shù)的類型注解自動(dòng)生成。這意味著只要你寫 Python 函數(shù)的時(shí)候老老實(shí)實(shí)把類型標(biāo)注寫清楚Agent 調(diào)用工具時(shí)就能獲得非常準(zhǔn)確的參數(shù)提示幾乎不會(huì)出現(xiàn)參數(shù)幻覺(jué)。我在項(xiàng)目里實(shí)測(cè)過(guò)一個(gè)帶- str類型注解的函數(shù)被模型正確調(diào)用的成功率非常高。2. 從零搭建 AgentScope skills 開發(fā)環(huán)境2.1 環(huán)境準(zhǔn)備與安裝坑位提醒AgentScope 目前對(duì) Python 版本要求比較明確3.9 到 3.12 我都在不同環(huán)境里試過(guò)都能正常跑。安裝方式很簡(jiǎn)單直接 pip 安裝即可pip install agentscope但這里有幾個(gè)坑我要提前告訴你如果你的項(xiàng)目還需要用到分布式的功能記得額外安裝完整版依賴pip install agentscope[distribute]。這個(gè)方括號(hào)的安裝方式在我早期使用時(shí)容易漏掉結(jié)果后面要用分布式調(diào)度時(shí)發(fā)現(xiàn)缺少消息通信的庫(kù)又要回頭補(bǔ)裝。AgentScope 底層依賴了多個(gè)第三方庫(kù)包括 pydantic、numpy 等如果你所在的網(wǎng)絡(luò)環(huán)境有源限制建議用國(guó)內(nèi)鏡像源安裝速度會(huì)快很多pip install agentscope -i https://pypi.tuna.tsinghua.edu.cn/simple。如果你本機(jī)裝了多個(gè) Python 版本建議在虛擬環(huán)境里操作。我在一個(gè)舊項(xiàng)目中直接裝進(jìn)全局環(huán)境結(jié)果和另一個(gè)框架的 pydantic 版本沖突排查了大半天。后來(lái)所有 AgentScope 項(xiàng)目我都用 venv 隔離再?zèng)]出過(guò)類似問(wèn)題。安裝完成后可以跑一條簡(jiǎn)單的命令驗(yàn)證是否正常python -c import agentscope; print(agentscope.__version__)我當(dāng)時(shí)跑出版本號(hào)的那一刻才算是松了一口氣。別小看這一步環(huán)境問(wèn)題往往是新手入門的第一道坎。2.2 模型接入配置與注意事項(xiàng)AgentScope 是一個(gè)模型無(wú)關(guān)的框架它支持市面上主流的模型提供方。接入模型的方式是通過(guò)AgentScope.init來(lái)統(tǒng)一初始化而不是在創(chuàng)建 Agent 時(shí)才去指定模型。這是我的一個(gè)認(rèn)知轉(zhuǎn)變——之前用其他框架時(shí)模型配置總是散落在各個(gè) Agent 初始化參數(shù)里而 AgentScope 把這層配置收斂到了一處。下面是我常用的初始化方式import agentscope agentscope.init( model_configs[ { model_type: openai, model_name: gpt-4o-mini, api_key: sk-..., generate_args: { temperature: 0.7 } }, { model_type: openai, model_name: qwen-max, api_key: sk-..., base_url: https://dashscope.aliyuncs.com/compatible-mode/v1, } ] )這里有兩個(gè)關(guān)鍵細(xì)節(jié)第一model_type參數(shù)非常靈活。它不局限于 openai還支持anthropic、google、dashscope、ollama等多種類型。如果你本地有跑 Ollama甚至可以直接接入本地模型實(shí)現(xiàn)完全離線的智能體應(yīng)用。第二base_url的存在讓這個(gè)框架在國(guó)內(nèi)使用變得很方便。你可以把model_type設(shè)為 openai但把base_url指向任何兼容 OpenAI 協(xié)議的服務(wù)地址。很多國(guó)產(chǎn)模型服務(wù)都提供了這種兼容模式這讓 AgentScope 在模型選擇上的自由度變得極高。初始化的時(shí)候還有一個(gè)值得注意的參數(shù)是agentscope.init(seed42)這個(gè) seed 參數(shù)可以控制隨機(jī)數(shù)種子保證結(jié)果的可復(fù)現(xiàn)性。我在調(diào)試多智能體流程時(shí)非常依賴這個(gè)參數(shù)因?yàn)橛袝r(shí)候同樣的代碼跑兩次結(jié)果不一樣你根本分不清是代碼邏輯問(wèn)題還是模型隨機(jī)性問(wèn)題。設(shè)置了固定 seed 之后至少排除了一個(gè)變量。2.3 快速驗(yàn)證一個(gè)最小可運(yùn)行的 Agent環(huán)境配置完成后我先寫了一個(gè)最簡(jiǎn)單的單 Agent 程序來(lái)驗(yàn)證模型連接是否正常。這一步我強(qiáng)烈建議每個(gè)人都做不要跳過(guò)去直接寫復(fù)雜的多智能體邏輯否則出了問(wèn)題根本不知道是框架問(wèn)題還是模型配置問(wèn)題。from agentscope.agent import ReagentAgent agent ReagentAgent( nameassistant, sys_promptYou are a helpful assistant., model_config_namegpt-4o-mini ) response agent(請(qǐng)用一句話介紹你自己。) print(response)注意幾個(gè)細(xì)節(jié)name字段是整個(gè) Agent 的唯一標(biāo)識(shí)在消息傳遞中這個(gè)字段非常重要后續(xù) Agent 之間的消息路由都靠它sys_prompt是系統(tǒng)提示詞決定了這個(gè) Agent 的角色定位model_config_name必須與init時(shí)配置的model_name保持一致。如果你看到終端順利打印出了回答恭喜你環(huán)境搭建這一步已經(jīng)完成了。接下來(lái)就可以開始真正體驗(yàn) skills 的魅力了。3. 手把手實(shí)現(xiàn) skills 的注冊(cè)與調(diào)用3.1 如何把自定義函數(shù)注冊(cè)為一個(gè) skill框架的 tool 注冊(cè)機(jī)制是我最推薦新手先掌握的技能。它的使用方式非常直觀直接在一個(gè)普通 Python 函數(shù)上加上裝飾器它就被注冊(cè)成了一個(gè)可供模型調(diào)用的工具。下面是一個(gè)完整的示例模擬一個(gè)“天氣查詢”技能import agentscope from agentscope.agent import ReagentAgent agentscope.tool def get_weather(city: str) - str: 查詢指定城市的當(dāng)前天氣情況。 Args: city: 城市名稱例如“北京”、“上?!?。 Returns: 包含天氣信息的字符串。 # 這里在實(shí)際項(xiàng)目中會(huì)調(diào)用天氣 API weather_data { 北京: 晴25℃, 上海: 多云28℃, 廣州: 陣雨30℃ } return weather_data.get(city, f抱歉沒(méi)有 {city} 的天氣數(shù)據(jù)) agent ReagentAgent( nameweather_agent, sys_prompt你是一個(gè)天氣助手可以幫助用戶查詢城市的天氣情況。, model_config_namegpt-4o-mini ) # 將該工具注冊(cè)給 agent agent.register_tool(get_weather) response agent(請(qǐng)問(wèn)北京今天天氣怎么樣) print(response)整個(gè)過(guò)程不需要你手動(dòng)描述這個(gè)函數(shù)是干什么的也不需要寫參數(shù) schema。AgentScope 會(huì)自動(dòng)從函數(shù)名、函數(shù) docstring、參數(shù)類型注解、返回值類型注解中提取信息生成一個(gè)模型的工具描述。這里的訣竅是要把 docstring 寫清楚寫得像你在給一個(gè)完全不了解這個(gè)函數(shù)的人解釋怎么用它——因?yàn)槟P捅举|(zhì)上就是通過(guò)這段描述來(lái)理解工具的。我個(gè)人的經(jīng)驗(yàn)是docstring 里必須明確寫出每個(gè)參數(shù)的單位、取值范圍和默認(rèn)行為。模型對(duì)于“模糊的描述”容易產(chǎn)生幻覺(jué)性的參數(shù)值比如把字符串參數(shù)填成數(shù)字或者把布爾值含義理解反。把參數(shù)描述寫清楚能有效避免這些問(wèn)題。3.2 注冊(cè)與調(diào)用 ReagentAgent 作為技能除了工具函數(shù)把一個(gè) ReagentAgent 注冊(cè)為另一個(gè) Agent 的技能是 AgentScope 更高級(jí)也更精髓的玩法。場(chǎng)景很好理解你有一個(gè)“數(shù)據(jù)分析專家”Agent你想讓一個(gè)“項(xiàng)目管理員”Agent 在需要時(shí)調(diào)用它。這個(gè)時(shí)候可以把“數(shù)據(jù)分析專家”整個(gè) Agent 作為技能注入到“項(xiàng)目管理員”的可用工具列表中。from agentscope.agent import ReagentAgent # 創(chuàng)建一個(gè)數(shù)據(jù)分析專家 Agent data_analyst ReagentAgent( namedata_analyst, sys_prompt你是一名資深數(shù)據(jù)分析師擅長(zhǎng)分析結(jié)構(gòu)化數(shù)據(jù)并提供洞察。, model_config_namegpt-4o-mini ) # 創(chuàng)建一個(gè)項(xiàng)目經(jīng)理 Agent project_manager ReagentAgent( nameproject_manager, sys_prompt你是一個(gè)項(xiàng)目管理助手負(fù)責(zé)協(xié)調(diào)團(tuán)隊(duì)成員并匯總報(bào)告。, model_config_namegpt-4o-mini ) # 將 data_analyst 作為技能注冊(cè)給 project_manager project_manager.register_tool(data_analyst) response project_manager(請(qǐng)數(shù)據(jù)分析師幫我分析一下我們最近三個(gè)月的銷售趨勢(shì)。) print(response)這段代碼運(yùn)行時(shí)底層的邏輯是project_manager這個(gè) Agent 在收到用戶請(qǐng)求后經(jīng)過(guò)模型推理決定調(diào)用名為data_analyst的這個(gè)“工具”??蚣芡ㄟ^(guò)消息機(jī)制將請(qǐng)求轉(zhuǎn)發(fā)給data_analystAgentdata_analyst獨(dú)立完成思考后將回復(fù)結(jié)果作為工具返回值傳回給project_manager。project_manager再基于這個(gè)結(jié)果繼續(xù)組織自己的最終回答。這和多 Agent 對(duì)話的區(qū)別在于這種模式下“數(shù)據(jù)專家”沒(méi)有自主發(fā)話的主動(dòng)權(quán)它只在“項(xiàng)目經(jīng)理”召喚時(shí)才說(shuō)話。這有點(diǎn)像你在公司里項(xiàng)目經(jīng)理不會(huì)直接去找數(shù)據(jù)分析師聊天而是通過(guò)任務(wù)分配的方式讓分析師完成特定工作再拿回結(jié)果做匯總。這避免了多個(gè) Agent 之間互相“搶話”帶來(lái)的混亂是實(shí)戰(zhàn)中非常需要的控制力。3.3 權(quán)重參數(shù)與調(diào)用方式的高級(jí)配置AgentScope 的 skills 調(diào)用不是只能做“詢問(wèn)-回答”這種簡(jiǎn)單模式它還可以配置更多的執(zhí)行細(xì)節(jié)。我在實(shí)際項(xiàng)目中用到的幾個(gè)進(jìn)階參數(shù)值得分享execute_tools參數(shù)這個(gè)參數(shù)可以限制 Agent 是否在每一輪推理后都嘗試調(diào)用工具。默認(rèn)情況下Agent 會(huì)根據(jù)用戶輸入自主決定是否調(diào)用工具。但某些場(chǎng)景下你可能希望第一輪強(qiáng)制調(diào)用工具、或者完全不調(diào)用工具這個(gè)參數(shù)就能派上用場(chǎng)。它接受一個(gè)包含字符串的列表可以精確控制哪一步執(zhí)行工具調(diào)用。max_round參數(shù)定義了 Agent 在執(zhí)行一段任務(wù)時(shí)的最大交互輪數(shù)。這個(gè)參數(shù)對(duì)防止 Agent 陷入死循環(huán)或者無(wú)意義的來(lái)回拉扯很有用。在多 Agent 技能調(diào)用鏈比較深的情況下我會(huì)把這個(gè)參數(shù)調(diào)大一些比如 10在簡(jiǎn)單問(wèn)答場(chǎng)景我就保持默認(rèn)避免模型浪費(fèi) token 在無(wú)關(guān)的來(lái)回中。此外還有類似stream的參數(shù)控制是否流式輸出print_message參數(shù)控制是否在終端打印中間消息。在開發(fā)調(diào)試階段我強(qiáng)烈建議把print_messageTrue打開這樣可以非常清晰地看到整個(gè)調(diào)用鏈用戶消息傳給哪個(gè) Agent、哪個(gè) Agent 調(diào)用了哪個(gè)工具、工具返回了什么內(nèi)容、最終答案是如何生成的。我在開發(fā)早期就因?yàn)槭∈聸](méi)開這個(gè)參數(shù)結(jié)果面對(duì)一個(gè)偏離預(yù)期的輸出完全無(wú)從下手排查浪費(fèi)了很多時(shí)間。4. 實(shí)戰(zhàn)案例用 skills 搭建一個(gè)多智能體工作流4.1 案例拆解與角色設(shè)計(jì)理論講再多不如一個(gè)完整的案例。這里我分享一個(gè)我最近搭建的“文章創(chuàng)作助手”系統(tǒng)。這個(gè)系統(tǒng)的目的是用戶給定一個(gè)主題系統(tǒng)自動(dòng)完成資料整理、初稿撰寫、質(zhì)量審核三個(gè)環(huán)節(jié)最終輸出一篇結(jié)構(gòu)完整的文章初稿。整個(gè)系統(tǒng)我設(shè)計(jì)了三個(gè)角色主編 Agent負(fù)責(zé)接收用戶需求拆分創(chuàng)作任務(wù)調(diào)度其他兩個(gè) Agent。它的系統(tǒng)提示詞里明確寫了自己的職責(zé)不要自己寫文章而是把任務(wù)分配給資料員和撰稿人。資料員 Agent一個(gè)帶了搜索工具的 Agent。它的職責(zé)是根據(jù)主編提供的主題關(guān)鍵詞搜索相關(guān)資料并整理成條目。撰稿人 Agent一個(gè)負(fù)責(zé)寫作的 Agent。它接收資料員的整理結(jié)果結(jié)合自己的知識(shí)庫(kù)撰寫一篇結(jié)構(gòu)完整的初稿。我把前兩個(gè) Agent 注冊(cè)為工具掛到主編身上然后通過(guò)一輪簡(jiǎn)單的對(duì)話觸發(fā)整個(gè)流程。這個(gè)設(shè)計(jì)的巧妙之處在于主編 Agent 并不需要提前決定“先調(diào)用誰(shuí)、后調(diào)用誰(shuí)”它的調(diào)度邏輯完全由模型根據(jù)用戶需求動(dòng)態(tài)決定。當(dāng)用戶說(shuō)“寫一篇關(guān)于人工智能的科普文章”時(shí)主編會(huì)自動(dòng)判斷先讓資料員去搜集素材再讓撰稿人基于素材寫作。如果用戶只說(shuō)“幫我潤(rùn)色一段話”主編則可能直接讓撰稿人處理不經(jīng)過(guò)資料員。這種動(dòng)態(tài)調(diào)度能力在傳統(tǒng)編程里很難實(shí)現(xiàn)因?yàn)槟悴豢赡茴A(yù)先枚舉所有用戶需求路徑。而 AgentScope 的 Agent 嵌套技能讓“決策”和“執(zhí)行”分離模型負(fù)責(zé)決策工具負(fù)責(zé)執(zhí)行這種架構(gòu)模式非常適合處理開放性任務(wù)。4.2 核心代碼實(shí)現(xiàn)與參數(shù)設(shè)計(jì)我把核心代碼簡(jiǎn)化提煉如下方便你理解整個(gè)結(jié)構(gòu)import agentscope from agentscope.agent import ReagentAgent from agentscope.pipeline import pipeline agentscope.init( model_configs[ { model_type: openai, model_name: gpt-4o-mini, api_key: sk-..., } ] ) # 1. 創(chuàng)建資料員 Agent它自帶一個(gè)檢索工具 agentscope.tool def search_web(query: str) - str: 搜索網(wǎng)絡(luò)獲取資料。 Args: query: 搜索關(guān)鍵詞。 Returns: 搜索到的資料文本摘要。 # 實(shí)際項(xiàng)目中這里會(huì)調(diào)用搜索 API return f關(guān)于 {query} 的搜索結(jié)果這是一段模擬資料內(nèi)容涵蓋背景信息、發(fā)展現(xiàn)狀、未來(lái)趨勢(shì)。 researcher ReagentAgent( nameresearcher, sys_prompt你是一名資料研究員根據(jù)用戶給出的主題調(diào)用搜索工具獲取相關(guān)資料并整理成清晰的條目。, model_config_namegpt-4o-mini ) researcher.register_tool(search_web) # 2. 創(chuàng)建撰稿人 Agent writer ReagentAgent( namewriter, sys_prompt你是一名資深撰稿人擅長(zhǎng)根據(jù)資料撰寫結(jié)構(gòu)完整、觀點(diǎn)清晰的文章。, model_config_namegpt-4o-mini ) # 3. 創(chuàng)建主編 Agent把前兩個(gè) Agent 注冊(cè)為技能 editor ReagentAgent( nameeditor, sys_prompt你是一名內(nèi)容主編負(fù)責(zé)協(xié)調(diào)資源完成創(chuàng)作任務(wù)。你可以調(diào)用 researcher 獲取資料調(diào)用 writer 撰寫文章。, model_config_namegpt-4o-mini ) editor.register_tool(researcher) editor.register_tool(writer) # 4. 執(zhí)行任務(wù) result editor(請(qǐng)寫一篇關(guān)于人工智能倫理的科普文章。) print(result)注意我在這段代碼里使用了pipeline模塊的導(dǎo)入雖然在這個(gè)例子中沒(méi)有顯式使用管道編排但當(dāng)你需要將這套流程固化為一個(gè)確定的執(zhí)行順序、而不是依賴模型動(dòng)態(tài)決策時(shí)可以用 pipeline 將三個(gè) Agent 串聯(lián)形成固定的執(zhí)行流程。動(dòng)態(tài)調(diào)度和固定流水線各有優(yōu)勢(shì)動(dòng)態(tài)調(diào)度靈活適應(yīng)開放性問(wèn)題固定流水線穩(wěn)定適合流程明確的業(yè)務(wù)場(chǎng)景。兩者可以在同一個(gè)系統(tǒng)中并存。這里有個(gè)參數(shù)我沒(méi)有在前面提到但特別值得補(bǔ)充ReagentAgent創(chuàng)建時(shí)支持傳入memory參數(shù)來(lái)配置記憶。默認(rèn)情況下Agent 的記憶是對(duì)話級(jí)別的一輪對(duì)話結(jié)束就清空。但在多 Agent 協(xié)作場(chǎng)景中主編可能需要記住整個(gè)創(chuàng)作任務(wù)的上下文。我在項(xiàng)目里給它配置了共享記憶確保主編能夠感知到資料員拿回了什么、撰稿人寫了什么。這個(gè)能力在長(zhǎng)流程任務(wù)中非常關(guān)鍵否則多個(gè) Agent 各行其是最終結(jié)果就像拼圖少了關(guān)鍵幾塊邏輯上會(huì)斷。4.3 執(zhí)行鏈路分析與結(jié)果驗(yàn)證跑完上面這個(gè)例子你會(huì)在終端看到相當(dāng)清晰的消息流轉(zhuǎn)記錄如果你打開了print_messageTrue。整個(gè)鏈路是這樣的用戶消息進(jìn)入editorAgent。editor的模型經(jīng)過(guò)推理決定調(diào)用researcher技能并傳給它一個(gè)搜索請(qǐng)求??蚣軐⒄?qǐng)求打包成一條特殊的 msg發(fā)送給researcherAgent。researcher收到消息后根據(jù)自己的系統(tǒng)提示詞決定調(diào)用search_web工具。search_web返回模擬資料researcher整理成條目作為回復(fù)返回給editor。editor拿到資料后模型再次推理決定調(diào)用writer技能要求其撰寫文章。writer根據(jù)資料撰寫文章初稿返回給editor。editor將最終文章作為最終回復(fù)返回給用戶。這就是一個(gè)完整的 Agent 嵌套技能調(diào)用鏈。我在驗(yàn)證時(shí)重點(diǎn)檢查了兩點(diǎn)一是調(diào)用鏈?zhǔn)欠癜搭A(yù)期順序執(zhí)行二是返回給用戶的內(nèi)容是否完整包含了資料員整理的信息。前者通過(guò)查看打印消息確認(rèn)后者通過(guò)人工閱讀最終文章內(nèi)容確認(rèn)。這套工作流上線后我明顯感覺(jué)到創(chuàng)作類任務(wù)的自動(dòng)化程度大大提升了。以前需要用 prompt 工程小心翼翼地編排多個(gè)模型的上下文現(xiàn)在 AgentScope 把這一切變成了標(biāo)準(zhǔn)的工具調(diào)用邏輯維護(hù)起來(lái)輕松很多。5. 常見(jiàn)問(wèn)題與排查技巧實(shí)錄5.1 工具注冊(cè)后未被調(diào)用這是我遇到頻率最高的問(wèn)題工具已經(jīng)注冊(cè)了函數(shù)也沒(méi)有寫錯(cuò)但模型似乎就是“看不到”這個(gè)工具回答全靠自己的知識(shí)硬編完全不調(diào)用外部函數(shù)。排查思路有三種按出現(xiàn)概率從高到低排序第一檢查sys_prompt里是否提到了這個(gè)工具的使用方式。模型確實(shí)有從系統(tǒng)提示詞中獲取信息的傾向如果提示詞里完全沒(méi)提到可以調(diào)用工具模型更容易選擇直接回答。我后來(lái)習(xí)慣在系統(tǒng)提示詞里顯式寫一句“你可以使用以下工具來(lái)獲取信息xxx”效果立竿見(jiàn)影。第二檢查函數(shù)的 docstring 寫得是否“像人話”。如果 docstring 含糊不清模型難以判斷這個(gè)工具到底能干什么就會(huì)傾向于不調(diào)用。盡量在每個(gè)參數(shù)描述里給出具體例子比如“city: 城市名稱如‘北京’”這比干巴巴的“城市名”要好得多。第三檢查model_config_name對(duì)應(yīng)的模型是否真的支持函數(shù)調(diào)用。并不是所有模型都有良好的工具調(diào)用能力。我在某個(gè)模型上測(cè)試時(shí)發(fā)現(xiàn)它的工具調(diào)用準(zhǔn)確率明顯偏低換成一個(gè)工具調(diào)用能力更強(qiáng)的模型后問(wèn)題立刻消失了。如果你的應(yīng)用場(chǎng)景嚴(yán)重依賴工具調(diào)用我建議你在選型階段就把“工具調(diào)用成功率”作為重要指標(biāo)。5.2 Agent 技能嵌套時(shí)上下文丟失第二個(gè)常見(jiàn)問(wèn)題是外層 Agent 調(diào)用內(nèi)層 Agent 技能后內(nèi)層 Agent 返回的結(jié)果非常簡(jiǎn)潔甚至只有一句“已完成”而外層 Agent 無(wú)法從這句話中判斷具體得到了什么導(dǎo)致最終回答質(zhì)量很差。這個(gè)問(wèn)題的根源在于我沒(méi)有在內(nèi)層 Agent 的系統(tǒng)提示詞中明確要求它返回完整的執(zhí)行結(jié)果。ReagentAgent 的回復(fù)內(nèi)容完全由系統(tǒng)提示詞和模型決定如果你不告訴它“請(qǐng)完整返回所有處理后的信息”它默認(rèn)只會(huì)給一個(gè)精簡(jiǎn)的總結(jié)。我的解決方案是在內(nèi)層 Agent 的系統(tǒng)提示詞末尾統(tǒng)一加上一句“請(qǐng)確保你的回復(fù)中包含所有需要傳遞給上級(jí) Agent 的關(guān)鍵信息不要省略細(xì)節(jié)。”這個(gè)看似簡(jiǎn)單的調(diào)整對(duì)最終輸出質(zhì)量的提升非常明顯。另外如果你希望內(nèi)層 Agent 的輸出嚴(yán)格結(jié)構(gòu)化可以直接指定輸出格式writer ReagentAgent( namewriter, sys_prompt你是一名撰稿人請(qǐng)根據(jù)資料撰寫文章。, model_config_namegpt-4o-mini )你可以在 sys_prompt 里要求它用特定格式返回比如“請(qǐng)以 JSON 格式返回包含 title 和 content 字段”。AgentScope 會(huì)把模型的輸出原樣作為返回結(jié)果所以這個(gè)方法是完全可行的。5.3 參數(shù)幻覺(jué)與類型錯(cuò)誤工具調(diào)用過(guò)程中的參數(shù)幻覺(jué)問(wèn)題在模型能力較弱或者參數(shù)描述不清時(shí)非常容易出現(xiàn)。我遇到過(guò)模型把字符串參數(shù)填成數(shù)字、把枚舉值改成完全不存在的內(nèi)容等狀況。要根治這個(gè)問(wèn)題最有效的辦法是做好參數(shù)約束。我建議你在注冊(cè)工具時(shí)盡量使用Literal或Enum類型注解而不是普通的str。例如from typing import Literal agentscope.tool def send_report(channel: Literal[email, dingtalk, wecom], content: str) - str: 發(fā)送報(bào)告。 Args: channel: 發(fā)送渠道。 content: 報(bào)告內(nèi)容。 Returns: 發(fā)送結(jié)果。 ...類型約束會(huì)讓模型在生成參數(shù)時(shí)只能從枚舉值里選從根源上消除參數(shù)幻覺(jué)。還有一個(gè)細(xì)節(jié)是不要給工具函數(shù)設(shè)置過(guò)于復(fù)雜的嵌套結(jié)構(gòu)作為參數(shù)。比如讓模型傳一個(gè)多層嵌套的 dict模型的成功率會(huì)顯著下降。我調(diào)整過(guò)的最復(fù)雜工具參數(shù)只有簡(jiǎn)單的字符串和整數(shù)效果非常好。如果一個(gè)任務(wù)需要復(fù)雜參數(shù)建議拆成兩個(gè)簡(jiǎn)單工具或者讓模型先通過(guò)簡(jiǎn)單工具返回一個(gè)中間結(jié)果。5.4 常見(jiàn)錯(cuò)誤速查表整理一份我遇到的問(wèn)題和對(duì)應(yīng)解決辦法速查表供大家快速查閱錯(cuò)誤現(xiàn)象可能原因解決辦法工具函數(shù)被調(diào)用但參數(shù)報(bào)錯(cuò)參數(shù)類型注解缺失或錯(cuò)誤補(bǔ)全類型注解尤其注意 Literal 的使用Agent 嵌套調(diào)用返回空內(nèi)容內(nèi)層 Agent 輸出為空可能是模型問(wèn)題或提示詞引導(dǎo)設(shè)置max_round增大輪數(shù)檢查模型輸出模型極其頻繁調(diào)用同一個(gè)工具sys_prompt 中沒(méi)有約束工具的調(diào)用時(shí)機(jī)在系統(tǒng)提示詞中明確“只在需要時(shí)調(diào)用工具”調(diào)用工具后模型仍重復(fù)調(diào)用工具有效但沒(méi)有一次調(diào)用成功的結(jié)果檢查工具函數(shù)內(nèi)部的返回邏輯是否完備消息卡在某個(gè) Agent 不繼續(xù)流轉(zhuǎn)該 Agent 沒(méi)有register_tool或模型配置錯(cuò)誤逐一驗(yàn)證單 Agent 是否能獨(dú)立工作6. 經(jīng)驗(yàn)總結(jié)與提速技巧6.1 關(guān)于技能顆粒度的取舍我用 AgentScope 一段時(shí)間后最深的一個(gè)體會(huì)是技能的“顆粒度”設(shè)計(jì)直接決定了整個(gè)系統(tǒng)的復(fù)雜度和穩(wěn)定性。顆粒度太粗一個(gè)技能內(nèi)部包含了太多不可控環(huán)節(jié)出現(xiàn)問(wèn)題難以定位顆粒度太細(xì)則一個(gè)簡(jiǎn)單任務(wù)需要串聯(lián)十幾個(gè)技能既消耗 token 又增加延遲。我的經(jīng)驗(yàn)準(zhǔn)則是一個(gè)技能應(yīng)該只做一件“可描述清楚、可獨(dú)立驗(yàn)證”的事。比如“搜索并整理資料”是一個(gè)合理的技能“完成整個(gè)項(xiàng)目”就不是一個(gè)合理的技能因?yàn)樗膬?nèi)部還是得拆。把技能設(shè)計(jì)成類似“函數(shù)”一樣的行為——輸入明確輸出明確內(nèi)部邏輯對(duì)調(diào)用方透明——這樣整個(gè)系統(tǒng)的可維護(hù)性會(huì)非常高。6.2 資源消耗的優(yōu)化經(jīng)驗(yàn)多智能體應(yīng)用最讓人肉疼的就是 token 消耗。一套三個(gè) Agent 的流程跑下來(lái)可能消耗掉單 Agent 三到五倍的 token。我優(yōu)化資源消耗的三個(gè)方法第一用便宜的模型跑低難度環(huán)節(jié)。資料整理、簡(jiǎn)單問(wèn)答可以交給參數(shù)量較小的模型只有最終內(nèi)容生成才調(diào)用更強(qiáng)的模型。AgentScope 允許不同 Agent 使用不同的model_config_name這讓我可以很自然地做模型分層。第二精簡(jiǎn)系統(tǒng)提示詞。很多人寫 sys_prompt 喜歡長(zhǎng)篇大論但模型每次對(duì)話都會(huì)把系統(tǒng)提示詞計(jì)入 token 消耗。在保證角色定位明確的前提下提示詞越短越好。一個(gè)技巧是把不需要每輪都出現(xiàn)的細(xì)節(jié)放到用戶消息里按需提供而不是寫死在系統(tǒng)提示詞中。第三善用記憶管理。AgentScope 的記憶機(jī)制默認(rèn)會(huì)保存完整對(duì)話歷史當(dāng)對(duì)話輪數(shù)很多時(shí)token 消耗呈線性增長(zhǎng)。如果你的場(chǎng)景是“一次性任務(wù)型”的不需要每輪都參考前面的對(duì)話可以對(duì) Agent 做記憶清理。我在實(shí)際項(xiàng)目中會(huì)給每個(gè)技能 Agent 配置一個(gè)獨(dú)立的短期記憶任務(wù)完成后自動(dòng)清空避免在長(zhǎng)流程中累積無(wú)用的歷史消息。6.3 調(diào)試階段的三個(gè)獨(dú)家技巧最后分享三個(gè)調(diào)試階段我覺(jué)得特別實(shí)用的技巧第一個(gè)技巧是打印中間消息。這個(gè)建議我在前面已經(jīng)提過(guò)但重要性值得重復(fù)print_messageTrue是 AgentScope 開發(fā)者最好的朋友。它打印出來(lái)的消息流轉(zhuǎn)記錄能讓你像看劇本一樣看到每個(gè) Agent 在想什么、做了什么。我上線前調(diào)試所有流程都會(huì)開著它確認(rèn)無(wú)誤后再關(guān)閉。第二個(gè)技巧是分段驗(yàn)證技能。不要一上來(lái)就組裝完整的多步流程。我習(xí)慣先把工具函數(shù)單獨(dú)用 Python 調(diào)一遍確認(rèn)函數(shù)本身沒(méi)問(wèn)題再把工具掛到一個(gè)最小 Agent 上測(cè)試模型能否正確調(diào)用最后才把多個(gè)技能組裝成完整系統(tǒng)。每層都驗(yàn)證通過(guò)才能保證上層出問(wèn)題時(shí)能快速定位到具體環(huán)節(jié)。第三個(gè)技巧是利用seed參數(shù)做可復(fù)現(xiàn)調(diào)試。多智能體系統(tǒng)的輸出有很大隨機(jī)性但設(shè)置了agentscope.init(seed42)之后在同一個(gè)環(huán)境下多次運(yùn)行輸出的結(jié)果會(huì)趨于一致。這對(duì)于在調(diào)試時(shí)對(duì)比不同 prompt 的效果非常有價(jià)值相當(dāng)于給模型的行為裝了一個(gè)“錄回放”功能。說(shuō)實(shí)話AgentScope 的 skills 機(jī)制本身的實(shí)現(xiàn)并不復(fù)雜復(fù)雜的是如何設(shè)計(jì)出一套適合你業(yè)務(wù)場(chǎng)景的分工體系。工具注冊(cè)、Agent 嵌套、pipeline 編排這些能力給了你充分的自由但也考驗(yàn)?zāi)銓?duì)任務(wù)拆解的判斷力。我建議新手先用最小的案例把工具注冊(cè)和調(diào)用跑通再逐步疊加 Agent 嵌套和流水線編排每一步都確認(rèn)無(wú)誤再往前走。這套框架的上手曲線在同類工具里算是很平緩的只要耐下心來(lái)把每個(gè)環(huán)節(jié)捋清楚你會(huì)發(fā)現(xiàn)多智能體應(yīng)用的開發(fā)效率能比傳統(tǒng)方案高出不少。