Tool Use的三種方案:從簡(jiǎn)單循環(huán)到狀態(tài)機(jī)管理)
面試官讓我手寫(xiě)一個(gè) Tool Use我用了 3 種方案上周面試一家做 AI 應(yīng)用的公司對(duì)方讓我手寫(xiě)一個(gè) Tool Use。面試官還特意強(qiáng)調(diào)“不用真的調(diào)用外部工具把 Tool Use 的調(diào)度邏輯寫(xiě)出來(lái)就行?!蔽乙宦?tīng)就明白了這是要看我對(duì) LLM Agent 這條鏈路理解到什么程度。整個(gè)面試過(guò)程比我預(yù)期要順利因?yàn)槲抑朗謱?xiě) Tool Use 本質(zhì)上考的不是能不能記住某個(gè)框架的 API而是三個(gè)核心問(wèn)題第一你知不知道模型怎么決定調(diào)哪個(gè)工具、傳什么參數(shù)第二你拿到工具結(jié)果之后怎么繼續(xù)讓模型生成回復(fù)第三你寫(xiě)的這套調(diào)度邏輯在真實(shí)環(huán)境中能不能穩(wěn)定跑起來(lái)。這篇文章把我現(xiàn)場(chǎng)寫(xiě)的三種方案完整還原出來(lái)從最簡(jiǎn)單的循環(huán)到帶參數(shù)校驗(yàn)和狀態(tài)機(jī)管理的完整流程順便把面試官現(xiàn)場(chǎng)追問(wèn)的問(wèn)題和我的應(yīng)對(duì)思路也一并分享。1. 先拆一下 Tool Use 到底是什么不把概念先理清楚后邊手寫(xiě)代碼一定跑偏。Tool Use 在 LLM 應(yīng)用里指的是讓模型在生成回復(fù)的過(guò)程中把“調(diào)用某個(gè)外部函數(shù)”作為一個(gè)輸出動(dòng)作。我用一個(gè)生活例子說(shuō)明。你問(wèn)一個(gè)助手“明天上海天氣怎么樣”如果這個(gè)助手沒(méi)有 Tool Use它只能憑訓(xùn)練數(shù)據(jù)里的知識(shí)瞎猜或者說(shuō)“我無(wú)法獲取實(shí)時(shí)信息”。有 Tool Use 之后模型會(huì)先輸出一個(gè)結(jié)構(gòu)化的“調(diào)用請(qǐng)求”里面包含工具名和參數(shù)。系統(tǒng)收到這個(gè)請(qǐng)求去真實(shí)環(huán)境里執(zhí)行比如查天氣接口、查數(shù)據(jù)庫(kù)、執(zhí)行一段代碼再把執(zhí)行結(jié)果返回給模型。模型看到結(jié)果后生成最終面向用戶的回復(fù)。整個(gè)鏈路前前后后是這樣的模型輸出 Tool Call → 系統(tǒng)執(zhí)行工具 → 結(jié)果返回給模型 → 模型生成最終回復(fù)所以手寫(xiě) Tool Use本質(zhì)上是在寫(xiě)一個(gè)循環(huán)多輪調(diào)用、參數(shù)校驗(yàn)、錯(cuò)誤處理、終止條件全都要在這個(gè)循環(huán)里體現(xiàn)。面試官要看的通常不是你用了多復(fù)雜的框架而是你能不能把這條閉環(huán)寫(xiě)清楚。在開(kāi)始寫(xiě)方案之前有一點(diǎn)必須強(qiáng)調(diào)手寫(xiě) Tool Use 時(shí)你寫(xiě)的其實(shí)是“框架”不是一個(gè)具體業(yè)務(wù)工具。這意味著你需要自己定義內(nèi)存中的函數(shù)列表、定義調(diào)用請(qǐng)求的數(shù)據(jù)結(jié)構(gòu)、定義執(zhí)行與返回的流程??蚣艽畹煤眉佣嗌賯€(gè)工具都不亂框架搭得差寫(xiě)兩個(gè)工具你就開(kāi)始復(fù)制粘貼了。2. 方案 A最簡(jiǎn)實(shí)現(xiàn)基于 OpenAI 標(biāo)準(zhǔn)調(diào)用格式我先給面試官寫(xiě)了一個(gè)最通用、最容易解釋的方案。這個(gè)方案假設(shè)外部系統(tǒng)能拿到模型原始的 tool_calls 輸出并且執(zhí)行環(huán)境支持 OpenAI 格式這也是絕大多數(shù) LLM 應(yīng)用的標(biāo)準(zhǔn)場(chǎng)景。工具定義只需要兩步給每個(gè)工具寫(xiě)一個(gè) name、description、parameters然后實(shí)現(xiàn)一個(gè) dispatch 函數(shù)。dispatch 是整個(gè) Tool Use 框架的心臟它根據(jù)模型輸出的工具名找到對(duì)應(yīng)函數(shù)并執(zhí)行。一個(gè)精簡(jiǎn)的 dispatch 長(zhǎng)這樣def dispatch(tool_name: str, arguments: dict) - str: if tool_name not in TOOL_REGISTRY: return fError: unknown tool {tool_name} func TOOL_REGISTRY[tool_name][func] try: result func(**arguments) return json.dumps(result, ensure_asciiFalse) except TypeError as e: return fError: invalid arguments for {tool_name}: {e} except Exception as e: return fError: tool {tool_name} execution failed: {e}這里有幾個(gè)關(guān)鍵設(shè)計(jì)點(diǎn)也是我在現(xiàn)場(chǎng)重點(diǎn)跟面試官解釋的部分。第一TOOL_REGISTRY 用字典維護(hù)工具名是 key函數(shù)是 value。這樣擴(kuò)展新工具時(shí)只需要在注冊(cè)表里增加一行dispatch 本身不需要改。新增一個(gè)工具的成本極低這是 Tool Use 框架最重要的擴(kuò)展性保障。第二func(**arguments) 這種寫(xiě)法依賴 Python 的參數(shù)展開(kāi)。arguments 如果多了字段TypeError 會(huì)被捕獲并當(dāng)作錯(cuò)誤信息返回給模型如果少了必填字段同樣會(huì)拋 TypeError。這個(gè)機(jī)制保證模型輸出不合法參數(shù)時(shí)不會(huì)讓整個(gè)進(jìn)程崩潰。第三錯(cuò)誤信息一定要返回給模型而不是只打印到日志里。很多人寫(xiě) Tool Use 會(huì)把異常吞掉只 print 到終端模型根本看不到。但模型是靠這些錯(cuò)誤信息自我糾錯(cuò)的比如它發(fā)現(xiàn)參數(shù)不對(duì)可能會(huì)重新生成一次 tool_call。這是 Tool Use 優(yōu)雅失敗的關(guān)鍵。模型循環(huán)的偽代碼我也現(xiàn)場(chǎng)寫(xiě)了出來(lái)messages [{role: user, content: user_query}] for step in range(MAX_STEPS): response client.chat.completions.create( modelMODEL_NAME, messagesmessages, toolsTOOL_LIST ) msg response.choices[0].message if not msg.tool_calls: final_answer msg.content break messages.append(msg) for tc in msg.tool_calls: tool_result dispatch(tc.function.name, json.loads(tc.function.arguments)) messages.append({ role: tool, tool_call_id: tc.id, content: tool_result, }) print(final_answer)MAX_STEPS 為什么必須有因?yàn)闆](méi)有它模型可能陷入“調(diào)用工具 → 返回結(jié)果 → 再調(diào)用工具”的死循環(huán)。尤其是一個(gè)工具的執(zhí)行結(jié)果不理想時(shí)模型會(huì)產(chǎn)生連續(xù)嘗試。你可以把 MAX_STEPS 理解成一個(gè)安全閥一旦達(dá)到設(shè)定步數(shù)就強(qiáng)制終止把最后的內(nèi)容返回給用戶避免無(wú)限消耗 token 和時(shí)間。這個(gè)方案是最小可用實(shí)現(xiàn)當(dāng)場(chǎng)就能跑通適合用來(lái)給面試官展示你理解“模型輸出結(jié)構(gòu)化調(diào)用請(qǐng)求”這個(gè)核心機(jī)制。它的局限性在于所有判斷都依賴模型自動(dòng)決定調(diào)用哪個(gè)工具沒(méi)有人工干預(yù)或二次確認(rèn)的空間。3. 方案 B動(dòng)態(tài)注冊(cè) 自動(dòng)參數(shù)校驗(yàn)應(yīng)對(duì)大規(guī)模工具寫(xiě)完方案 A面試官?zèng)]有打斷我但我知道他大概率會(huì)追問(wèn)如果工具數(shù)量變多這個(gè)方案還能不能撐住所以我主動(dòng)遞進(jìn)了第二套方案。方案 A 能跑但存在一個(gè)很實(shí)際的痛點(diǎn)當(dāng)工具數(shù)量超過(guò) 10 個(gè)時(shí)你還能靠手寫(xiě)函數(shù)簽名保證參數(shù)不出錯(cuò)嗎而且模型是概率輸出arguments 里的字段名只要錯(cuò)一個(gè)字母工具就執(zhí)行失敗。方案 B 要解決的就是這兩個(gè)問(wèn)題。先看動(dòng)態(tài)工具注冊(cè)。我們把工具定義做成裝飾器業(yè)務(wù)函數(shù)只需要標(biāo)注“我是工具”系統(tǒng)自動(dòng)讀取函數(shù)的簽名和 docstring生成給模型看的工具描述。import inspect TOOL_REGISTRY {} TOOL_SCHEMAS [] def tool(name: str, description: str): def decorator(func): sig inspect.signature(func) params { p_name: { type: string, description: p_name, } for p_name in sig.parameters } schema { type: function, function: { name: name, description: description, parameters: { type: object, properties: params, required: list(sig.parameters.keys()), }, }, } TOOL_REGISTRY[name] func TOOL_SCHEMAS.append(schema) return func return decorator tool(get_weather, 獲取指定城市的當(dāng)前天氣) def get_weather(city: str): Retrieve weather for city. return {city: city, weather: sunny, temperature: 26}inspect.signature 是這里最核心的函數(shù)它能在運(yùn)行時(shí)拿到函數(shù)參數(shù)名自動(dòng)生成 JSON Schema。這樣你寫(xiě)業(yè)務(wù)函數(shù)時(shí)只需要保證類型標(biāo)注和 docstring 質(zhì)量工具接入成本幾乎為零。但動(dòng)態(tài)注冊(cè)只解決“生成 schema”的問(wèn)題沒(méi)有解決“參數(shù)校驗(yàn)”的問(wèn)題。實(shí)際上模型輸出的 arguments 可能會(huì)多出了不需要的字段缺少必填字段字段類型錯(cuò)誤比如 city 傳成了數(shù)組字段值非法比如溫度傳了 -999可靠的做法是引入 pydantic。pydantic 能從 schema 直接生成模型類用它做反序列化和校驗(yàn)錯(cuò)誤信息非常結(jié)構(gòu)化。from pydantic import create_model, ValidationError def safe_execute(tool_name: str, arguments: dict): func TOOL_REGISTRY[tool_name] schema find_schema(tool_name) Model create_model(tool_name, **generate_fields_from_schema(schema)) try: validated Model(**arguments) return func(**validated.model_dump()) except ValidationError as e: return fValidation failed: {e.errors()}這一版相比方案 A 的進(jìn)步是工具方不需要寫(xiě)任何校驗(yàn)代碼維護(hù)成本從“每個(gè)工具內(nèi)部各自防御”變成了“框架統(tǒng)一處理”。對(duì)面試官來(lái)說(shuō)這展示了你對(duì)生產(chǎn)級(jí)代碼的思考錯(cuò)誤處理不是靠運(yùn)氣而是靠機(jī)制。不過(guò)引入 pydantic 也有代價(jià)。如果你只需要 3 個(gè)工具為了校驗(yàn)引入一個(gè)重型依賴就屬于過(guò)度設(shè)計(jì)。所以我會(huì)把方案 B 定位為“工具數(shù)量超過(guò) 10 個(gè)、團(tuán)隊(duì)協(xié)作開(kāi)發(fā)的中間態(tài)方案”。它的收益曲線陡峭但前期學(xué)習(xí)成本也高。4. 方案 C用狀態(tài)機(jī)管理多輪調(diào)度和人工確認(rèn)寫(xiě)到第三個(gè)方案我開(kāi)始把 Tool Use 從“函數(shù)調(diào)用”升級(jí)到“任務(wù)狀態(tài)機(jī)”。這也是面試官最希望聽(tīng)到的進(jìn)階思路因?yàn)榍懊娴姆桨副举|(zhì)上都是“模型說(shuō)什么我做什么”沒(méi)有對(duì)任務(wù)本身的生命周期做管理。為什么要狀態(tài)機(jī)因?yàn)檎鎸?shí)場(chǎng)景里Tool Use 不是單次調(diào)用而是多次調(diào)用組合完成任務(wù)。比如一個(gè)“幫我訂機(jī)票”的任務(wù)模型需要先查日期、查目的地、查價(jià)格可能還要多次確認(rèn)乘客信息。如果只是無(wú)腦循環(huán)調(diào)用一旦中途用戶改主意、工具返回異常、某個(gè)步驟需要人工確認(rèn)整個(gè)流程就會(huì)失控。狀態(tài)機(jī)的核心是有明確的“狀態(tài)”和“遷移條件”。我把它簡(jiǎn)化成四個(gè)狀態(tài)待執(zhí)行、執(zhí)行中、等待確認(rèn)、已完成。from enum import Enum class ToolUseState(Enum): PENDING pending RUNNING running AWAITING_CONFIRMATION awaiting_confirmation COMPLETED completed class ToolUseSession: def __init__(self, session_id: str, initial_query: str): self.session_id session_id self.query initial_query self.state ToolUseState.PENDING self.tool_history [] self.result None def step(self, model_response): if self.state ToolUseState.PENDING: if model_response.tool_calls: self.state ToolUseState.RUNNING else: self.state ToolUseState.COMPLETED elif self.state ToolUseState.RUNNING: for tc in model_response.tool_calls: self.tool_history.append(tc) result dispatch(tc.function.name, json.loads(tc.function.arguments)) if result.startswith(Error): # 錯(cuò)誤時(shí)回到待執(zhí)行讓模型重試 self.state ToolUseState.PENDING return result self.state ToolUseState.AWAITING_CONFIRMATION elif self.state ToolUseState.AWAITING_CONFIRMATION: if model_response confirmed: self.state ToolUseState.COMPLETED else: self.state ToolUseState.PENDING return self.state注意我在 RUNNING 狀態(tài)里如果工具執(zhí)行出錯(cuò)會(huì)讓狀態(tài)回退到 PENDING而不是直接終止。這模擬了“模型看到錯(cuò)誤信息后重新選擇工具或調(diào)整參數(shù)”的行為。如果模型連續(xù)多次都失敗再觸發(fā) MAX_STEPS 的兜底。這個(gè)方案最大的價(jià)值不是代碼本身多復(fù)雜而是它把“工具調(diào)用”和“任務(wù)生命周期”分開(kāi)考慮。工具只是執(zhí)行者而狀態(tài)機(jī)是管理者。當(dāng)任務(wù)需要多步驟、多工具協(xié)作時(shí)這種抽象讓代碼結(jié)構(gòu)變得非常清晰。順便說(shuō)一下?tīng)顟B(tài)機(jī)方案也很容易擴(kuò)展出“權(quán)限確認(rèn)”能力。比如某個(gè)工具被標(biāo)記為高權(quán)限執(zhí)行前必須先讓用戶確認(rèn)。在 AWAITING_CONFIRMATION 狀態(tài)下系統(tǒng)暫停執(zhí)行把待確認(rèn)信息發(fā)給用戶用戶點(diǎn)了確認(rèn)之后再繼續(xù)。這在轉(zhuǎn)賬、刪除、發(fā)送消息這類高風(fēng)險(xiǎn)操作里非常有用。我在現(xiàn)場(chǎng)跟面試官特意強(qiáng)調(diào)了這個(gè)設(shè)計(jì)方案 C 的“確認(rèn)狀態(tài)”不是簡(jiǎn)單加一個(gè) if而是把人工確認(rèn)變成流程中的一等公民。模型不是單方面決定一切系統(tǒng)可以隨時(shí)把控制權(quán)交回給用戶。這一手如果能在面試中講明白基本能證明你不是只會(huì)調(diào) API而是對(duì) Agent 的運(yùn)行時(shí)架構(gòu)有體系化思考。5. 三個(gè)方案的對(duì)比與適用邊界把三個(gè)方案放到一起對(duì)比結(jié)論就很清晰了。面試官通常會(huì)讓你選一個(gè)場(chǎng)景來(lái)說(shuō)明哪個(gè)方案最合適這時(shí)候你的回答要果斷要有判斷力。方案核心思路優(yōu)點(diǎn)缺點(diǎn)適用場(chǎng)景A簡(jiǎn)單循環(huán) 注冊(cè)表實(shí)現(xiàn)最快容易理解錯(cuò)誤控制弱擴(kuò)展性一般原型驗(yàn)證、面試演示、工具數(shù)量少B動(dòng)態(tài)注冊(cè) 自動(dòng)校驗(yàn)工具接入成本低錯(cuò)誤管理規(guī)范依賴較重需要學(xué)習(xí) pydantic中大型項(xiàng)目、團(tuán)隊(duì)協(xié)作C狀態(tài)機(jī)驅(qū)動(dòng)流程可控支持多輪會(huì)話和確認(rèn)機(jī)制代碼量最大抽象成本高復(fù)雜 Agent 任務(wù)、生產(chǎn)級(jí)系統(tǒng)選擇建議只有一條先跑通再架構(gòu)。不要一上來(lái)就寫(xiě)狀態(tài)機(jī)如果你的工具只有 3 個(gè)狀態(tài)機(jī)的抽象只會(huì)浪費(fèi)時(shí)間。但如果你做的是一個(gè)需要長(zhǎng)期維護(hù)的 Agent 平臺(tái)那方案 C 一定是值得投入的方向。這里有一個(gè)我的經(jīng)驗(yàn)判斷面試時(shí)寫(xiě)方案 A 加方案 C 的組合最加分。方案 A 證明你具備快速實(shí)現(xiàn)能力方案 C 證明你有架構(gòu)思維。方案 B 更適合放在項(xiàng)目經(jīng)驗(yàn)里口頭提及因?yàn)樗鉀Q的實(shí)際痛點(diǎn)需要在有一定規(guī)模的代碼庫(kù)中才能體現(xiàn)。6. 手寫(xiě) Tool Use 時(shí)的四個(gè)常見(jiàn)坑我這些年調(diào)過(guò)不少 Agent 項(xiàng)目也在面試現(xiàn)場(chǎng)看過(guò)很多人手寫(xiě) Tool Use基本上問(wèn)題都集中在這四個(gè)地方。提前說(shuō)出來(lái)能幫你避免 90% 的返工。第一個(gè)坑忽略錯(cuò)誤信息返回。有些人的 dispatch 把異常吞了只打印到日志模型拿不到任何反饋。結(jié)果就是模型在下一輪繼續(xù)生成同樣的錯(cuò)誤調(diào)用陷入死循環(huán)。我的經(jīng)驗(yàn)是錯(cuò)誤信息必須變成 tool message 回給模型這就是模型自我糾錯(cuò)的唯一素材。你甚至可以特意在錯(cuò)誤信息里帶上正確的參數(shù)格式示例模型看到后下一輪大概率能糾正過(guò)來(lái)。第二個(gè)坑不設(shè)置最大輪數(shù)。模型一旦進(jìn)入“不斷調(diào)用工具”的狀態(tài)沒(méi)有 MAX_STEPS 兜底整個(gè)請(qǐng)求會(huì)一直掛著浪費(fèi) token 和響應(yīng)時(shí)間。這個(gè)參數(shù)不能少而且要根據(jù)真實(shí)調(diào)用情況調(diào)優(yōu)。比如簡(jiǎn)單問(wèn)答 5 步足夠復(fù)雜任務(wù)可能要到 20 步。我一般會(huì)在日志里記錄每個(gè)任務(wù)的真實(shí)步數(shù)定期分析后再調(diào)整上限避免設(shè)太大浪費(fèi)資源也避免設(shè)太小截?cái)嗾A鞒?。第三個(gè)坑工具注冊(cè)表沒(méi)有命名空間隔離。當(dāng)多個(gè)業(yè)務(wù)方同時(shí)往注冊(cè)表里加工具很容易出現(xiàn)同名覆蓋。比如兩個(gè)團(tuán)隊(duì)都定義了 get_user_info后注冊(cè)的會(huì)把前面的覆蓋掉。這在單人 demo 里不會(huì)暴露一上多人協(xié)作就出問(wèn)題。我在實(shí)踐中會(huì)給每個(gè)業(yè)務(wù)方加前綴比如 weather_get、user_query避免沖突。如果用的是 Python也可以把不同業(yè)務(wù)方的工具放在不同模塊下注冊(cè)時(shí)帶上模塊名。第四個(gè)坑忘記清理歷史消息。Tool Use 循環(huán)里messages 是持續(xù)增長(zhǎng)的。如果同一個(gè) session 內(nèi)多次任務(wù)歷史消息不清模型很快會(huì)被上下文窗口截?cái)?。一個(gè)簡(jiǎn)單的做法是每次新一輪任務(wù)開(kāi)始時(shí)重置到初始 system prompt或者只保留最近 N 輪摘要。我之前踩過(guò)這個(gè)坑用戶在一個(gè)對(duì)話里連續(xù)問(wèn)了十幾個(gè)問(wèn)題后模型突然“失憶”排查了半天才發(fā)現(xiàn)是上下文塞滿了。7. 面試官追問(wèn)的進(jìn)階問(wèn)題怎么答很多面試官在聽(tīng)完手寫(xiě)方案后會(huì)繼續(xù)追問(wèn)幾個(gè)更深的問(wèn)題。這些問(wèn)題的價(jià)值在于考察你的應(yīng)變能力和系統(tǒng)設(shè)計(jì)思維。我整理了三個(gè)最常見(jiàn)的追問(wèn)和我的應(yīng)對(duì)方式?!叭绻ぞ叻祷亟Y(jié)果特別長(zhǎng)上下文塞不下怎么辦”答做結(jié)果摘要或者只返回關(guān)鍵字段??梢栽?dispatch 返回前加一層 summarize 函數(shù)對(duì)大結(jié)果做截?cái)嗷蛱釤?。極端情況下用檢索方式把結(jié)果落庫(kù)并返回一個(gè)結(jié)果 ID模型需要時(shí)再按 ID 查詢。這種“結(jié)果外置”的思路在長(zhǎng)文檔處理里很常見(jiàn)。“你怎么保證工具調(diào)用的安全性”答三層控制。第一層是參數(shù)校驗(yàn)防止非法輸入第二層是權(quán)限機(jī)制高敏感工具需要用戶確認(rèn)第三層是操作審計(jì)所有工具調(diào)用記錄都寫(xiě)入日志方便回溯。我還會(huì)補(bǔ)充一點(diǎn)有些工具必須做“白名單”限制比如發(fā)短信接口只能發(fā)給特定號(hào)碼刪除操作必須有 delete 權(quán)限才能注冊(cè)為工具?!岸鄠€(gè)工具都可以滿足用戶請(qǐng)求時(shí)你怎么做路由”答靠模型的函數(shù)選擇能力但你可以通過(guò)工具描述的措辭影響選擇。比如把更常用工具的描述寫(xiě)得更詳細(xì)、更明確模型會(huì)更傾向于選擇它。如果要硬路由可以在 dispatch 之前加一層規(guī)則引擎人工指定某些關(guān)鍵詞走特定工具。這個(gè)方案適合工具語(yǔ)義高度重疊的場(chǎng)景比如兩個(gè)查詢庫(kù)存的工具只是數(shù)據(jù)源不同。這三個(gè)回答不追求唯一標(biāo)準(zhǔn)答案但要有結(jié)構(gòu)、有層次、有真實(shí)場(chǎng)景支撐。面試官要的是看到你思考過(guò)這些問(wèn)題而不是背答案。8. 一點(diǎn)實(shí)操心得和總結(jié)我自己踩過(guò)的最深的坑是“工具描述寫(xiě)得太敷衍”。給模型看的 description不是給自己看的注釋它決定了模型能不能在眾多工具中選對(duì)。比如 get_weather 的 description 如果是“獲取天氣”模型在用戶說(shuō)“明天出門(mén)要不要帶傘”時(shí)可能根本不會(huì)調(diào)用它。但如果描述成“獲取指定城市未來(lái)幾天的天氣數(shù)據(jù)用于回答出行建議、穿衣建議、是否需要攜帶雨具等問(wèn)題”模型就能更好地關(guān)聯(lián)用戶意圖。這個(gè)細(xì)節(jié)比多寫(xiě)幾個(gè)工具函數(shù)重要得多。另外在真實(shí)項(xiàng)目中我還習(xí)慣給每個(gè)工具加上 examples 字段在參數(shù) schema 里放一個(gè)示例參數(shù)值。這樣模型看到的不只是參數(shù)名還有具體的填法。比如 get_weather 的參數(shù)示例是 {city: 上海}模型的調(diào)用準(zhǔn)確率會(huì)明顯提升。這個(gè)小技巧是我在項(xiàng)目數(shù)據(jù)對(duì)比中發(fā)現(xiàn)的同樣的模型加了 examples 后參數(shù)錯(cuò)誤率能下降不少。手寫(xiě) Tool Use 這件事看起來(lái)考的是代碼實(shí)際上考的是工程化思維錯(cuò)誤處理、擴(kuò)展性、流程控制、上下文管理每一項(xiàng)都直接影響生產(chǎn)環(huán)境的穩(wěn)定性。把這三個(gè)方案吃透再補(bǔ)上這些避坑經(jīng)驗(yàn)應(yīng)付面試綽綽有余更重要的是你會(huì)在實(shí)際項(xiàng)目里寫(xiě)出真正能上線的 Agent 系統(tǒng)。