给 Agent 装上「手」——工具调用入门(Function Calling 从猜到查)
发布时间:2026/10/12 4:42:49 锦皓数字建站
`)
系列AgentScope 2.0 学习笔记 · 第 004 篇难度进阶适合谁正在做客服/导购/信息查询类 Agent 的开发者被「AI 编造答案」困扰的人前置建议先读 003《给 Agent 一张「人设卡」》阅读收获理解 Function Calling让 Agent 从「只会说」进化到「会动手」运行环境WSL Ubuntu-24.04 Python 3.11 AgentScope 2.x你有没有见过这种 AI 客服你问它「玻尿酸保湿霜多少钱」它张口就来「328 元」语气笃定、数字精确你差点就信了。结果点进商品页一看——268 元。它把价格编错了而且编得跟真的一样。这不是偶发事故这是所有「没接数据的 Agent」的通病。大模型天生是个「接话王」不是「查账本」的你问它不知道的事它会顺着你的话头编一个最像样的答案。对客服场景来说这轻则流失客户重则引发纠纷。这篇就来治这个病给 Agent 装上一只手让它学会「查」而不是「猜」。一、Agent 的困境只会说不会做前三篇我们让 Agent 学会了三件事编排001、记忆002、人设003。但有一个致命短板一直没解决——它只会「说」不会「做」。你问它「玻尿酸保湿霜多少钱」它只有两个选择凭训练记忆「猜」一个价格——可能对也可能是编的幻觉老实告诉你「我不知道」。无论哪种都不是合格客服该有的样子。真实客服面对「多少钱、有没有货」是要去系统里查的。这一步「查」就是工具的用武之地。二、没有工具Agent 只能靠猜先看一组我实测过的真实数据。在还没引入工具之前我把产品信息硬塞进 prompt结果 Agent 会「编」价格——同一款产品它一会儿说 268、一会儿说 328、一会儿说 458全是幻觉。这就是大模型的本质它是在「预测下一个词」不是「检索事实」。它没接你的数据库就只能凭概率胡诌。更麻烦的是它编得还很「自信」——语气笃定、数字精确一眼看过去跟真的一样。这种「一本正经地胡说八道」在大模型领域有个专门的名字叫幻觉Hallucination。对客服来说报错一个价格轻则流失客户重则引发纠纷。这里多解释一句幻觉为什么「治不好」。幻觉不是 bug是大模型的工作方式本身它学的是「下一个词最可能是什么」不是「事实是什么」。你没给它数据源它就用自己的「世界知识」顶上——而模型对具体价格、库存这类实时信息的「世界知识」基本为零。所以根治幻觉只有一条路别让它猜给它查的途径。靠换更大的模型、加提示词「你要诚实」都只是缓解不是根治。工具Function Calling就是来治这个病的给 Agent 一个「查产品」的函数它需要价格时就调用这个函数去你的真实数据里查再把查到的结果组织成回答。从「猜」到「查」一步之差天壤之别。三、工具是什么五件套在 AgentScope 2.x 里一个工具就是ToolBase的一个子类由五部分组成部件作用打个比方name工具名工具箱上贴的标签description用途说明使用说明书input_schema入参格式需要你递什么材料check_permissions权限要不要人工批准call执行逻辑真正干活的部分模型靠name和description判断「该不该调、调哪个」靠input_schema知道「传什么参数」靠call拿到结果。你只要把这五件事写清楚Agent 就能自己「动手」。完整的工具长什么样看第六节的QueryProductInfo。这五个部件少了哪个都会出事description写糊了模型就「该调不调」input_schema写错了模型就「传错参数」check_permissions设成 ASK每查一次都要人工点头call写错了查回来的就是错数据。所以工具不是「写个函数就行」而是「给模型写一份看得懂的说明书」。四、权限ALLOW 还是 ASK一个新手最容易踩的坑是权限。check_permissions能返回三种行为行为含义ALLOW自动放行Agent 想调就调ASK每次调用都停下来问人DENY直接拒绝如果你用老的FunctionTool默认是ASK——每查一次价格都要你手动点「同意」多轮对话会烦死。所以本文用ToolBaseALLOW查询类工具是只读、无害的直接放行Agent 才用得顺手。记住一条经验只读工具查价格、查库存放心 ALLOW会改数据的工具下单、删数据才需要谨慎甚至 ASK。这条经验往深了说就是 Agent 上生产之前必须过的一关每个工具都要问一句「它有没有副作用」。只读的放行、能改数据的收紧、危险的操作直接 DENY——权限设计不是技术细节是安全边界。尤其是电商、金融这类场景一个「下单」工具如果默认 ALLOWAgent 被恶意输入诱导触发就是真金白银的损失。工具越少越安全权限越严越稳妥这两条是并行不悖的。五、运行环境同前三篇保持一致系统WSL Ubuntu-24.04Python3.11虚拟环境venv框架AgentScope 2.xAPI KeyDeepSeek / 混元 / 百炼环境变量注入wsl-dUbuntu-24.04cd/2026_Study/agentscope/sourcevenv/bin/activateexportDEEPSEEK_API_KEYsk-xxxxexportHUNYUAN_API_KEYsk-xxxxexportBAILIAN_API_KEYsk-xxxxpython 004_tool_call.py六、完整代码单文件自包含保存为004_tool_call.py。分两步演示先直接调工具验证工具可用再让 Agent 带工具自主调用。#!/usr/bin/env python3# -*- coding: utf-8 -*- AgentScope 2.0 · 给 Agent 装上「手」——工具调用入门 演示定义一个「查产品」工具让 Agent 自主决定何时调用它。 第 1 步直接调用工具验证工具本身可用它就是「查询函数」 第 2 步Agent 带工具自主判断何时查数据而不是靠猜/编价格。 运行环境WSL Ubuntu-24.04 Python 3.11 AgentScope 2.x 运行命令python 004_tool_call.py importosimportasyncioimportgcimporttimefromagentscope.credentialimport(DeepSeekCredential,OpenAICredential,DashScopeCredential,)fromagentscope.modelimport(DeepSeekChatModel,OpenAIChatModel,DashScopeChatModel,)fromagentscope.agentimportAgentfromagentscope.messageimportMsg,TextBlockfromagentscope.toolimportToolBase,ToolChunk,Toolkitfromagentscope.permissionimportPermissionDecision,PermissionBehavior# 敏辰产品数据真实数据工具从这里查PRODUCT_DB{玻尿酸保湿霜:{price:268,stock:50,skin:干性/敏感},净颜清透洁面乳:{price:198,stock:80,skin:油性/混合},积雪草舒缓精华:{price:398,stock:30,skin:敏感/泛红},神经酰胺修护乳:{price:328,stock:45,skin:干性/敏感},美白淡斑精华:{price:458,stock:20,skin:暗沉/色斑},}classQueryProductInfo(ToolBase):查询敏辰产品的价格、库存、适合肤质。 一个「工具」由五部分组成 1. name —— 工具名模型靠它识别「该调哪个」 2. description —— 工具用途模型靠它判断「什么时候调」 3. input_schema —— 入参格式告诉模型「要传什么参数」 4. check_permissions —— 权限决定「能不能自动执行」 5. call —— 真正的执行逻辑 namequery_product_infodescription查询敏辰产品的价格、库存、适合肤质。输入产品名称关键词。input_schema{type:object,properties:{product_name:{type:string,description:产品名称或关键词如「保湿霜」「洁面乳」,},},required:[product_name],}is_concurrency_safeTrue# 可并发调用is_read_onlyTrue# 只读不改数据asyncdefcheck_permissions(self,tool_input,context)-PermissionDecision:# 关键返回 ALLOW 自动放行Agent 无需等待人工确认returnPermissionDecision(behaviorPermissionBehavior.ALLOW,message查询只读自动放行。,)asyncdefcall(self,product_name:str)-ToolChunk:查询逻辑精确匹配 → 模糊匹配 → 未找到提示。ifproduct_nameinPRODUCT_DB:infoPRODUCT_DB[product_name]resultf{product_name}{info[price]}元库存{info[stock]}件适合{info[skin]}肤质else:matches[nforninPRODUCT_DBifproduct_nameinnorninproduct_name]ifmatches:lines[f-{n}{PRODUCT_DB[n][price]}元适合{PRODUCT_DB[n][skin]}forninmatches]result未精确匹配以下是相关产品\n\n.join(lines)else:resultf未找到与「{product_name}」相关的产品returnToolChunk(content[TextBlock(textresult)])defbuild_models():三个模型统一 streamFalse —— 干净退出第一件套。deepseekDeepSeekChatModel(credentialDeepSeekCredential(api_keyos.environ[DEEPSEEK_API_KEY]),modeldeepseek-v4-flash,streamFalse,)hunyuanOpenAIChatModel(credentialOpenAICredential(api_keyos.environ[HUNYUAN_API_KEY],base_urlhttps://tokenhub.tencentmaas.com/v1,),modelhy3,streamFalse,)bailianDashScopeChatModel(credentialDashScopeCredential(api_keyos.environ[BAILIAN_API_KEY]),modelqwen-max,streamFalse,)return{DeepSeek:deepseek,混元:hunyuan,百炼:bailian}defextract_text(response):forblockinresponse.content:ifgetattr(block,type,None)text:returnblock.textreturnasyncdefclose_models(models):干净退出第二件套逐个 await self.client.close()。closed0forminmodels.values():clientgetattr(m,client,None)ifclientisNone:continuetry:awaitclient.close()closed1exceptException:passifclosed:print(f\n 已关闭{closed}个 HTTP 连接池)asyncdefdemo_manual_tool():第 1 步不经过 Agent直接调用工具——验证工具本身可用。print(f\n{*60}\n 第 1 步直接调用工具验证工具本身\n{*60})toolQueryProductInfo()fornamein[玻尿酸保湿霜,保湿,防晒霜]:chunkawaittool.call(name)textchunk.content[0].textprint(f\n 查询「{name}」→\n{text})asyncdefdemo_agent_tool(model,model_name):第 2 步Agent 带工具自主决定何时调用。print(f\n{*60}\n 第 2 步Agent 带工具自主调用模型{model_name}\n{*60})toolkitToolkit(tools[QueryProductInfo()])agentAgent(name小帮,modelmodel,system_prompt(你叫「小帮」是「敏辰」的护肤顾问。\n你可以使用工具 query_product_info 查询产品的价格、库存、肤质。\n当用户问到具体产品信息价格/库存/成分时请先调用工具查询再基于结果回答。\n绝对不要编造产品信息。),toolkittoolkit,)questions[玻尿酸保湿霜多少钱有货吗,适合敏感肌的精华有哪些,]forqinquestions:print(f\n 用户{q})msgMsg(nameuser,content[{type:text,text:q}],roleuser)responseawaitagent.reply(msg)answerextract_text(response)print(f 小帮{answer})print(\n 观察Agent 是否自主调用了工具回答是否基于真实数据而非编造)defcheck_keys():need[DEEPSEEK_API_KEY,HUNYUAN_API_KEY,BAILIAN_API_KEY]missing[kforkinneedifnotos.environ.get(k)]ifmissing:print(❌ 缺少环境变量, .join(missing))print( 请先 export 对应的 API Key)returnFalsereturnTrueasyncdefmain():ifnotcheck_keys():returnmodelsbuild_models()try:awaitdemo_manual_tool()awaitdemo_agent_tool(models[DeepSeek],DeepSeek (deepseek-v4-flash))finally:awaitclose_models(models)delmodels gc.collect()if__name____main__:asyncio.run(main())七、代码拆解三个关键点① 工具的「说明书」比「实现」更重要。name、description、input_schema这三样模型是「读」它们来决定要不要调用、怎么调用的。所以description一定要写清楚「什么时候该用我」input_schema要写清楚「参数叫什么、什么类型」。写糊了模型就会「该调不调」或「乱传参数」。②ALLOW是「自动挡」的钥匙。只读查询直接放行Agent 才会在对话里顺滑地查数据否则每次调用都卡在人工确认体验全毁。判断标准就一条这个工具会不会改数据、会不会有副作用。③ 工具的返回要「喂回」模型。call返回的ToolChunk框架会自动塞回给模型模型再基于它组织最终回答。所以call里返回的文本要信息完整、格式清晰模型才好接着写。顺带厘清一个容易混的概念工具调用 ≠ 在代码里写死 if-else。写死 if-else 是「代码决定何时查」工具调用是「模型决定何时查」——后者更灵活因为模型能理解自然语言的意图「有货吗」「多少钱」「适合我吗」都能映射到同一个查产品的工具而 if-else 只能匹配你预设的那几个关键词。八、运行结果真实输出下面是本文件在 WSL Ubuntu-24.04 里的真实运行结果。第 1 步直接调用工具—— 三个查询精确命中、模糊匹配、查无此物各归其位查询「玻尿酸保湿霜」→ 玻尿酸保湿霜268元库存50件适合干性/敏感肤质 查询「保湿」→ 未精确匹配以下是相关产品- 玻尿酸保湿霜268元适合干性/敏感 查询「防晒霜」→ 未找到与「防晒霜」相关的产品第 2 步Agent 自主调用—— 这是重点。问「玻尿酸保湿霜多少钱有货吗」Agent 没有直接编而是先调工具查真实数据再回答 用户玻尿酸保湿霜多少钱有货吗 小帮我帮您查询到「玻尿酸保湿霜」的信息如下 价格268元 库存50件有货 适合肤质干性肤质 / 敏感肤质 这款玻尿酸保湿霜目前有货哦您可以放心购买。...问「适合敏感肌的精华有哪些」Agent 再次调工具查到「积雪草舒缓精华」398 元敏感/泛红还主动判断另一款「美白淡斑精华」偏美白淡斑、不适合敏感肌优先推荐——既查了数据又做了判断 用户适合敏感肌的精华有哪些 小帮我为您查到了适合敏感肌的精华产品……这款积雪草舒缓精华是专门针对 敏感肌、泛红肌肤设计的……另外还有一款美白淡斑精华不过更偏向美白淡斑功效 建议优先考虑积雪草舒缓精华。最后一行 已关闭 3 个 HTTP 连接池程序干净退出、零收尾报错。这段结果最有价值的一点Agent 报出的 268 元、50 件、398 元全部和代码里的PRODUCT_DB一字不差——这就是「查」和「猜」的本质区别。没工具的 Agent 面对同样的问题只能编编对了是运气、编错了是事故有工具的 Agent 每一次都回真实数据库里取数这才是客服该有的样子。九、总结与下一步这一篇你给 Agent 装上了第一只「手」只会说001~003→ 会查数据本篇→ 基于真实数据回答核心就一句话工具把 Agent 从「靠猜」拉到「靠查」。name/description/input_schema是给模型看的说明书call是真正干活的地方ALLOW让这一切自动运转。下一篇《AgentScope 2.0 学习笔记给 Agent 一库「知识」——RAG 检索入门》我们把「手」升级成「脑外记忆」工具查的是结构化数据价格、库存RAG 查的是非结构化知识产品详情、成分说明、常见问答。敬请期待。十、写在最后从「猜」到「查」是 Agent 能不能落地的分水岭写到这里想多说一句。幻觉这件事看起来是个技术问题其实是产品能不能交付的问题。客户问价格你报错数一次两次是偶然三次五次就是信任崩塌——你前面立的所有专业人设都扛不住一次「编造」的翻车。所以凡是涉及真实数据的 Agent工具调用不是「进阶技巧」是上线的及格线。但工具也带出新问题你的数据在哪、怎么接、接口怎么设计、权限怎么分级、Agent 误调用怎么办——这些都不是看教程能直接学会的要对着具体业务一点点磨。如果你正在做一个需要接数据的 Agent客服、导购、订单查询、内部知识问答都算卡在工具设计或数据接入上欢迎来评论区留言。下一篇「RAG」见。本文为「AgentScope 2.0 学习笔记」系列第 004 篇代码已通过py_compile语法校验运行环境见第五节。GitHub 仓库AgentScope 2.0 Cookbook系列 : 《AgentScope 2.0 学习笔记》Agent 编排初体验零基础跑通第一个智能体多轮对话让 Agent 记住你in-token 实证记忆机制给 Agent 一张「人设卡」五件套立规矩AI 导购实测对比给 Agent 装上「手」——工具调用入门Function Calling 从猜到查给 Agent 一库「知识」——RAG 检索入门补水也能找到保湿RAG 进阶——Top-K 调优与幻觉测试让 Agent 敢说「不知道」双剑合璧——工具 RAG做一个会查会答的客服从会说到会查会答一分为多——意图路由与多 Agent 协作把客服拆成一队集思广益——多 Agent 投票与结果汇总用多数人的智慧压住随机性给 Agent 打个分——评测体系入门零成本四维质检编价格一票否决让 AI 当裁判——LLM Judge 语义评测进阶规则查不到的「答非所问」交给 AI 二审从评测到进化——把评测结果喂回 Prompt0.75 到 1.0只差一句 Prompt从 Demo 到上线——把 Agent 部署成服务四道闸把「能跑的脚本」变成「敢上线的服务」把 Agent 放到云上——容器化部署与上线运营六步运营闭环让 Agent 越上线越好用
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。