工具调用Function Call 与 Tool Use工具调用是 Agent 的「手」让大模型能操作外部世界。这篇讲 Function Calling 的原理、工具怎么定义、模型怎么选工具、参数怎么传、常见的工具类型以及开发中的最佳实践。大家好我是黒漂技术佬。大模型本身只能输出文字知识有截止日期、不会算精确数学、不能查数据库、发不了邮件。接上工具之后能力边界大大扩展。Function Calling函数调用也叫 Tool Use就是大模型调用外部工具的标准方式。现在主流模型都原生支持是 Agent 开发的核心技术。这篇讲工具调用的原理、工具定义、多工具选择、参数传递、常见工具类型、最佳实践。一、什么是 Function Calling概念你把工具函数的描述告诉大模型模型根据用户问题判断需不需要调用工具调用哪个工具参数填什么然后模型输出结构化的调用指令你的程序执行这个函数把结果返回给模型继续处理。为什么不用普通对话普通对话里你也可以让模型输出「调用搜索(xxx)」但格式不稳定、容易错。Function Calling 是模型专门训练过的输出是标准 JSON 格式稳定可靠。交互流程1. 你用户问题 工具定义 → 发给模型 2. 模型判断要调用工具 → 返回 tool_callsJSON格式 3. 你执行函数拿到结果 4. 你把结果发给模型 5. 模型根据结果生成最终回答多轮的话就是 2-3-4 循环跟 ReAct 对应。二、工具怎么定义JSON Schema 格式每个工具用 JSON Schema 描述名字、描述、参数类型、参数说明。{type:function,function:{name:search_web,description:搜索互联网获取实时信息回答不知道的问题,parameters:{type:object,properties:{query:{type:string,description:搜索关键词}},required:[query]}}}字段说明字段作用name函数名模型调用时返回这个名字description函数说明模型靠这个判断什么时候用parameters参数定义JSON Schema 格式properties每个参数的名字、类型、描述required必填参数列表复杂参数参数可以是嵌套对象、数组、枚举{name:send_email,description:发送邮件给指定收件人,parameters:{type:object,properties:{to:{type:string,description:收件人邮箱地址},subject:{type:string,description:邮件主题},body:{type:string,description:邮件正文},priority:{type:string,enum:[normal,high,low],description:优先级}},required:[to,subject,body]}}多个工具一次可以传多个工具定义模型自己选tools[{type:function,function:{name:search_web,...}},{type:function,function:{name:calculator,...}},{type:function,function:{name:get_weather,...}},]三、调用过程详解第一步用户提问带上工具定义messages[{role:user,content:北京今天天气怎么样}]tools[{type:function,function:{name:get_weather,description:查询指定城市的实时天气,parameters:{type:object,properties:{city:{type:string,description:城市名}},required:[city]}}}]responsellm.chat(messagesmessages,toolstools)第二步模型返回工具调用模型判断需要调用工具返回{role:assistant,tool_calls:[{id:call_abc123,type:function,function:{name:get_weather,arguments:{\city\: \北京\}}}]}tool_calls就是模型要调用的工具列表。arguments 是 JSON 字符串。第三步执行工具函数importjson tool_callresponse.tool_calls[0]func_nametool_call.function.name argsjson.loads(tool_call.function.arguments)# 执行对应的函数iffunc_nameget_weather:resultget_weather(**args)第四步把结果传回模型messages.append(response)# 把模型的tool_call消息加回去messages.append({role:tool,tool_call_id:call_abc123,content:result# 比如北京今天晴25-32℃})final_responsellm.chat(messagesmessages,toolstools)第五步模型生成最终回答模型拿到工具结果整理成自然语言回答北京今天天气晴朗气温25到32摄氏度空气质量良适合出行。多工具多轮如果需要多个工具模型可能返回多个 tool_call或者一轮一轮调用跟 ReAct 循环一样。四、模型怎么选工具靠 description模型主要看函数的 description 判断什么时候用。描述写得清楚模型就选得准。好的 description 怎么写坏例子description:搜索太简略模型不知道什么时候用。好例子description:当需要回答实时信息、新闻、未知事实时调用此工具搜索互联网。 不要用已有知识回答时效性问题。说明清楚什么时候用、什么场景用、什么情况不要用。最佳实践名字直观函数名要见名知意描述详细说明用途、适用场景、不适用场景参数说明清楚每个参数是什么、格式要求、例子工具数量适中太多了模型容易选错一般 5-10 个比较合适功能不重叠两个工具功能差不多的话模型会纠结五、常见的工具类型1. 搜索类网页搜索Google、Bing、Tavily知识库检索企业内部 RAG文档搜索2. 计算类数学计算器Python 代码执行最强大能算能画图能处理数据单位换算3. 信息查询类天气查询股票行情航班/火车查询数据库查询自然语言转 SQL4. 操作执行类发送邮件创建日历日程发送消息飞书/钉钉/微信创建工单文件读写5. 代码类执行 Python 代码代码审查运行测试6. 浏览器类打开网页截图点击/填写表单六、并行工具调用是什么模型一次返回多个 tool_call同时调用多个工具不用等一个完了再调下一个。tool_calls:[{name:get_weather,arguments:{city:北京}},{name:get_weather,arguments:{city:上海}}]好处减少轮次更快独立的查询可以并行执行省时间什么时候并行两个查询互相不依赖需要对比多个信息的时候比如「对比北京和上海的天气」就可以并行查两个城市。七、工具调用的最佳实践1. 工具描述要精准description 是模型选工具的唯一依据一定要写清楚这个工具是干嘛的什么情况下用什么情况下不要用参数的格式和含义2. 参数校验模型传的参数不一定对一定要校验必填参数有没有类型对不对枚举值在不在范围内格式合不合法邮箱、日期等不对就返回错误信息让模型重试。3. 错误处理要友好工具执行失败返回给模型的错误信息要清楚方便它修正错误城市名「火星」不支持支持的城市列表北京、上海、广州...模型看到就知道换个城市名再试。4. 结果要简洁工具返回的结果不要太长太长占 token 还干扰模型。做摘要再返回搜索结果只返回前 3 条摘要数据库查询只返回关键字段长文本先总结再给模型5. 控制工具数量工具太多模型容易选错。按场景给工具客服 Agent 给知识库工单工具数据分析 Agent 给 SQL画图工具不要把所有工具都塞进去6. 敏感操作要确认发邮件、删数据、下单这种有副作用的操作执行前要人确认Agent 生成调用请求弹给用户确认用户点确认了再真正执行7. 工具结果要标记来源RAG 搜索的结果要标来源链接方便用户查证也能追责。八、常见坑坑 1工具描述太模糊“搜索工具” → 模型不知道什么时候该搜。要写成需要实时信息、最新新闻时使用。坑 2参数没校验模型传了个不存在的参数值程序直接崩。一定要校验参数。坑 3工具返回结果太长搜索返回整篇文章token 爆了还干扰判断。要截断、摘要。坑 4工具功能重叠两个工具都能查信息模型不知道选哪个。合并或者区分清楚场景。坑 5循环调用失败工具报错了模型用同样的参数反复调。要加错误提示和重试限制。坑 6安全问题Agent 能调用删数据、发邮件这种危险操作没有确认机制。敏感操作必须人在回路。坑 7arguments 是字符串注意 tool_calls 里的 arguments 是 JSON 字符串不是对象要 json.loads 解析一下。九、一个完整的多工具示例工具定义tools[{type:function,function:{name:search_company,description:查询公司的基本信息包括成立时间、创始人、主营业务,parameters:{type:object,properties:{company_name:{type:string,description:公司名称}},required:[company_name]}}},{type:function,function:{name:get_stock_price,description:查询上市公司的当前股价和市值,parameters:{type:object,properties:{stock_code:{type:string,description:股票代码}},required:[stock_code]}}}]对话过程用户字节跳动上市了吗市值多少模型第一轮先查字节跳动的基本信息看有没有上市、股票代码是什么。tool_call: search_company(“字节跳动”)工具返回字节跳动成立于2012年创始人张一鸣旗下产品有抖音、TikTok等。 目前未上市暂无股票代码。模型第二轮字节跳动还没上市没有股票代码所以查不到市值。直接回答用户。最终回答字节跳动目前尚未上市因此没有公开的市值数据。 公司成立于2012年旗下核心产品包括抖音、TikTok等。十、本篇小结Function Calling模型原生支持的工具调用机制输出结构化的 JSON 调用指令工具定义name description parametersJSON Schema调用流程用户问题工具定义 → 模型返回 tool_calls → 执行函数 → 结果传回 → 模型生成答案模型靠 description 判断选哪个工具描述写得准不准很重要支持并行调用一次返回多个 tool_call独立任务并行执行更快常见工具类型搜索、计算、信息查询、操作执行、代码、浏览器最佳实践描述精准、参数校验、错误友好、结果简洁、控制数量、敏感操作要人确认常见坑描述模糊、不校验参数、结果太长、功能重叠、安全问题下一篇讲记忆系统短期记忆、长期记忆、向量记忆Agent 怎么记住用户和历史。我是黒漂技术佬。