ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

图解函数调用:模型为什么不能自己去调接口

图解函数调用:模型为什么不能自己去调接口 版权与内容来源声明本文为原创整理。文中涉及官方文档、开源仓库、论文与公开报道的内容均在附表 A 中标注来源引用官方原文保持原样不作改写。文中命令、版本号与界面截图以本文成文时的实测/核验结果为准标注「待验证」的部分请以你本地环境实际输出为判断依据。本文不推荐任何不合规的软件获取方式也不对任何收益结果作承诺。转载请注明出处。第1章 一个常见的误会模型「自己」调了接口很多人第一次看到「模型调用了天气接口」「模型查了数据库」这类说法脑海里会浮现一个画面模型在后台真的连上了某台服务器自己发了请求、自己收到了响应、自己把结果拿了回来。这个画面是错的而且错得比较关键。模型在整个过程里真正做的事情只有一件读完你给它的上下文之后产出一段结构化的「建议」——「我建议调用某某函数参数是这些」。这段建议本身不是执行它只是一段数据和你平时接口返回的 JSON 没有什么本质区别。真正去发起网络请求、真正去读写数据库、真正去改文件状态、真正去发邮件的全部发生在你自己的代码里。把这一点先钉死后面很多听起来很玄的问题都能顺着这条线想通。比如「模型会不会自己上网」「模型会不会乱删库」「模型调用工具安不安全」——答案不在模型身上而在「谁拿着执行权」这件事上。本篇要讲的核心就是这条执行边界。顺带说一句这种「给模型接上外部能力」的思路官方把它归为给模型做增强augmentation。Anthropic 在讲智能体的文章里提到智能体系统的基本构件就是一个被检索、工具、记忆等能力增强过的大模型模型可以主动生成检索词、挑选合适的工具、决定保留哪些信息。注意是「挑选工具、生成调用」不是「替你执行」。第2章 函数调用是什么一句话 三个关键词2.1 一句话定义函数调用在英文资料里也叫 tool use中文常译作「工具调用」本质上是一套约定让大模型能够向你提供的外部系统「开口要数据」或「开口提动作」而真正的数据获取和动作执行由你的应用来完成。OpenAI 官方文档对它的定义原文是Function calling (also known as tool calling) provides a powerful and flexible way for OpenAI models to interface with external systems and access data outside their training data.用大白话说就是模型训练数据里没有的实时信息、以及训练数据里做不到的真实动作都要通过「函数调用」这座桥由你的程序去落地。模型是「提需求」的那一方你的代码是「干活」的那一方。2.2 三个关键词理解函数调用记住三个词就够了工具tool你注册给模型的一个能力定义比如「查天气」「查订单状态」。模型只知道「有这个能力、大概干什么用」完全不知道里面怎么实现。参数arguments模型决定要调用时 accompanying 给出的那串输入比如城市名、订单号。参数从模型嘴里「说」出来但是不是靠谱取决于你给它的工具描述和提示。回传tool result你的代码把真实结果算出来之后交还给模型的那段内容。模型拿到回传才会据此组织出面向用户的回答。2.3 函数与工具的关系这里有一个容易混的点官方其实讲得很清楚函数function是工具tool的一种具体形式由一份 JSON Schema 来定义。函数定义的作用是让模型能把数据「递」给你的应用你的代码再去访问数据或执行模型建议的动作。换句话说工具是更大的概念函数是最常见的、用 schema 约定参数的那一种。第3章 五步流程谁在哪一步做事3.1 五步流程官方原文OpenAI 官方把工具调用流程总结为五步原文如下Make a request to the model with tools it could callReceive a tool call from the modelExecute code on the application side with input from the tool callMake a second request to the model with the tool outputReceive a final response from the model (or more tool calls)翻译过来就是带上可调用工具向模型发一次请求 → 收到模型返回的调用请求 → 在应用侧用调用参数执行代码 → 带着工具结果再向模型发一次请求 → 收到模型的最终回答或者更多调用。注意第五步括号里那句「or more tool calls」一轮结束不一定就完事模型可能继续要求调用于是又走一轮。这是一个可以循环的过程不是一次就到头。3.2 五步流程责任表把每一步「谁在做、产出什么」摊开看执行边界一目了然步骤谁在做产出什么1. 发起请求你的应用带工具列表的请求2. 返回调用模型一个调用请求函数名 参数3. 执行代码你的应用真实结果如天气数据4. 回传结果你的应用带结果的第二轮请求5. 最终回答模型面向用户的回答或更多调用可以看到五步里有三步是「你的应用」在做模型只负责第 2 步决定调什么和第 5 步组织回答。执行这件事从头到尾不在模型手里。3.3 一张时序示意用一个最简的时序把角色串起来⚠️代码待验证用户 --提问-- 你的应用 你的应用 --带工具发请求-- 模型 模型 --返回调用请求-- 你的应用 你的应用 --执行真实代码-- 外部系统(接口/数据库) 你的应用 --回传结果-- 模型 模型 --返回最终回答-- 你的应用 你的应用 --呈现-- 用户这张图里模型只参与「返回调用请求」和「返回最终回答」两处中间那次真实的外部系统交互是应用侧绕开模型独立完成的。3.4 执行在应用侧还是平台侧Anthropic 的文档把工具分成两类这个分法恰好印证了「执行权在谁手里」维度客户端工具client tools服务端工具server tools在哪里执行你的应用里Anthropic 的基础设施上典型例子你自定义的任意工具、bash、text_editorweb_search、web_fetch、code_execution、tool_search你是否需要写执行代码需要由你的代码跑不需要直接看到结果回传方式回传 tool_result 给模型一般直接给结果除非与你的客户端工具并行调用客户端工具指在你的应用里运行的工具包括你自定义的以及 Anthropic 定义好 schema 的 bash、text_editor 等。Claude 返回stop_reason: tool_use以及一个或多个tool_use块你的代码去执行再把结果以tool_result送回去。服务端工具指在 Anthropic 服务端运行的工具如 web_search、web_fetch、code_execution、tool_search你直接拿到结果不用自己写执行逻辑——除非它和你的某个客户端工具被放在同一组并行调用里。这里第一次遇到stop_reason它解释一下这是 Anthropic 用来表示「模型这一轮为什么停下」的字段tool_use这个值表示模型停下来是在等你或平台去执行工具而不是要直接对用户说话。3.5 谁来决定「调不调、调几个」默认情况下调不调、调几个由模型自己判断。OpenAI 提供tool_choice参数来强制特定行为四种取值如下取值行为说明auto默认调零个、一个或多个模型自行决定required调一个或多个强制至少调一次指定函数恰好调某一个如 get_weather允许的工具子集限制在可用工具的一个子集内收窄可选范围把执行权留在应用侧之后你还能用tool_choice从「让模型自由发挥」切到「必须调、只能调某个」这进一步说明调不调、怎么调最终是应用侧可控的策略而不是模型单方面说了算。第4章 为什么执行权不放在模型手里4.1 安全边界如果模型能直接执行任意动作那么一段被诱导、被绕弯的提示就可能触发真实世界里的副作用发出不该发的邮件、删掉不该删的记录、调用高风险的接口。把执行放在应用侧意味着每一次真实动作都要经过你的代码、你的鉴权、你的参数校验这道门。模型提的建议可以五花八门但「要不要真干、用什么凭据干」这道闸在你的手里。4.2 权限归属权限这种东西——谁能访问哪个系统、用哪一把 token、能碰哪张表——是你应用掌握的资源不应该交给模型去持有。模型只产出「建议调用」是否放行、用什么身份去调由你决定。把凭据留在应用侧也避免把敏感信息塞进模型的上下文里到处流转。4.3 可审计因为执行发生在你的代码里每一步都有日志入了什么参、走了哪个分支、产出了什么结果。事后无论是排查问题还是满足合规要求都能逐条复盘。这一点是排错和审计的基础也是「执行权下放给模型」几乎不可接受的核心原因。OpenAI 官方也把这件事说得很直白当模型调用一个函数时必须由你来执行它并把结果返回。模型只负责「叫一声」动手的是你。第5章 参数是按 schema 来的不是模型自由发挥5.1 schema 是什么这里说的 schema指的是 JSON Schema简单讲就是你给函数写的一份「参数说明书」哪个字段叫什么名字、是什么类型、是不是必填、取值范围是什么。模型产出的参数要贴合这份说明书。模型不是凭空编参数而是在你给的结构约束里填值。5.2 一个工具定义示例下面是一份天气查询函数的工具定义。它是按官方「函数由 JSON Schema 定义」的思路写的示例⚠️代码待验证{name:get_weather,description:查询指定城市的当前天气,parameters:{type:object,properties:{location:{type:string,description:城市名如 北京},unit:{type:string,enum:[celsius,fahrenheit]}},required:[location]}}这份定义里几个字段的含义单独列一张表说清楚字段含义name函数名模型返回调用时会原样引用description给模型看的能力说明直接影响它何时调用parameters用 JSON Schema 描述的入参结构properties每个参数的类型与说明required必填字段清单缺了模型也要补上注意字段说明都放在了表格和正文里没有写进代码块内部避免被误判成别的东西。5.3 模型返回的结构模型决定调用后返回的内容长什么样官方说明响应里的output数组会包含一个type为function_call的条目每个条目带call_id之后用来提交这次调用的结果、name以及 JSON 编码后的arguments。示例结构如下⚠️代码待验证{output:[{type:function_call,call_id:call_abc,name:get_weather,arguments:{\location\: \北京\, \unit\: \celsius\}}]}这里的call_id很关键第二轮把结果回传时要靠它把「哪次调用」和「哪个结果」对上号。arguments是一段 JSON 编码的字符串你的代码解析之后才能拿去执行。把结果回传给模型的代码骨架伪代码思路大致是这样⚠️代码待验证defhandle_tool_calls(response,messages):callsresponse.outputforitemincalls:ifitem.typefunction_call:resultrun_your_code(item.name,item.arguments)messages.append({type:function_call_output,call_id:item.call_id,output:result})returnmessages这段骨架表达的是遍历模型这次返回的调用逐个在你的代码里执行再把「调用编号 结果」追加进下一轮请求。真实工程里还要补上错误处理和超时控制但主线就是这三步。5.4 严格模式让调用更稳参数贴合 schema 这件事默认是「尽力而为」。OpenAI 官方建议把strict设为true这样函数调用能可靠地贴合函数 schema而不是尽力贴合并且推荐始终开启严格模式。严格模式的底层借用了「结构化输出structured outputs」这项能力。这里解释一下结构化输出它是让模型按你给定的固定格式稳定产出数据的机制而不是自由发挥一段文本。为了支撑严格模式官方提出了两个硬性要求参数里每个 object 的additionalProperties必须设为falseproperties里的所有字段都必须标记为required。Anthropic 那边也有对应做法给自定义工具加strict: true让 Claude 的工具调用始终精确匹配你的 schema。可见「用 schema 约束、用严格模式兜底」是两家的共同思路。配套资料包这一章讲参数按 schema 走、用严格模式兜底资料包里我整理了一份「工具定义与严格模式」对照清单放在资料包里扫码即可获取第6章 三个容易踩的误解6.1 误解一模型会「猜」你没给的参数你给了一个需要location的get_weather工具用户只问「天气怎么样」却没说城市。Anthropic 文档明确指出Claude尤其是 Sonnet可能会猜你没提供的参数值。这正好说明一件事参数到底从哪来、靠不靠谱取决于你的提示和工具描述写得清不清楚——模型并不会凭空掌握真实世界的地址。把location标成必填、在描述里写清「必须询问用户城市」比指望模型不猜更可靠。6.2 误解二一轮只会返回一个调用很多人以为模型一次只调一个函数。OpenAI 官方明确说模型响应可能包含零个、一个或多个调用最佳实践是默认会有多个做好循环处理。如果想禁止并行可把parallel_tool_calls设为false这样确保只调零个或一个。换句话说「多个调用」才是常态单调用反而是被你约束出来的特例。6.3 误解三参数没写清楚就必然出错如果 schema 描述含糊、必填不标、枚举不放模型更容易猜错或填错。把字段描述写清楚、开启strict模式、明确required与enum能显著降低出错概率。另外提醒一句「工具越多越准」是错的工具数量与准确率之间没有这种正相关这条本篇只点一下不展开。6.4 常见误解澄清表把上面三处误解和开头那个大误会一起收个尾误解事实模型自己调了接口模型只产出调用请求执行在应用侧模型不会猜参数没给的参数它可能猜要靠描述约束一轮只有一个调用可能多个需按多个处理或显式关并行参数含糊也无所谓描述越清楚、约束越严出错越少工具越多越准错误认知不展开第7章 记住这条边界很多问题就通了7.1 回到那条线回到开头那条线把它浓缩成一句话模型只负责「决定调什么、参数是什么」不负责「真正去执行」。执行权留在应用侧安全、权限、可审计这三件事才落得地。当你再听到「模型自己上网」「模型自己连数据库」「模型自己发消息」就知道那只是把中间的执行环节省略着说了——真正动手的永远是你写的代码。模型是「建议者」应用是「执行者」这个分工不打破很多焦虑就消失了。7.2 几个常见疑问的通法顺着这条边界几个高频疑问可以直接套「模型会不会乱删库」——它产出的只是删除建议真正执行删除的是你的代码加一道确认或权限校验即可拦住。「模型能自己查实时数据吗」——它自己不能得靠你提供的工具去查再把结果回传。「调用失败谁负责」——执行在你这边日志、重试、降级都由你掌控这正是可审计的意义。把执行边界想清楚函数调用就不再是黑话而是一张清清楚楚的责任分工图。边界速记卡这一章把「模型只决定调什么、不负责执行」这条线收了尾资料包里有一张一页纸的速记卡放在资料包里扫码即可获取附表 A本文引用事实与出处对照表事实摘要出处含 URL本文位置函数调用又名 tool calling让模型对接外部系统、访问训练数据之外的数据OpenAI《Function calling》https://developers.openai.com/api/docs/guides/function-calling第2章工具调用是应用与模型之间的多步对话含五步流程OpenAI《Function calling》https://developers.openai.com/api/docs/guides/function-calling第3章模型调用函数时必须由你执行并返回结果响应可含零/一/多个调用OpenAI《Function calling》https://developers.openai.com/api/docs/guides/function-calling第3章、第4章函数是工具的一种由 JSON Schema 定义让模型把数据递给你的应用OpenAI《Function calling》https://developers.openai.com/api/docs/guides/function-calling第2章、第5章响应 output 数组含 function_call 条目带 call_id、name、JSON 编码的 argumentsOpenAI《Function calling》https://developers.openai.com/api/docs/guides/function-calling第5章strict 设为 true 可让调用可靠贴合 schema推荐始终开启OpenAI《Function calling》https://developers.openai.com/api/docs/guides/function-calling第5章strict 底层借 structured outputs要求 additionalProperties 为 false、字段全 requiredOpenAI《Function calling》https://developers.openai.com/api/docs/guides/function-calling第5章tool_choice 有 auto / required / 指定函数 / 允许子集四种行为OpenAI《Function calling》https://developers.openai.com/api/docs/guides/function-calling第3章parallel_tool_calls 设为 false 可禁止并行确保零或一个调用OpenAI《Function calling》https://developers.openai.com/api/docs/guides/function-calling第6章Tool use又名 function calling让 Claude 调你定义或 Anthropic 提供的函数Anthropic《Tool use with Claude》https://platform.claude.com/docs/en/agents-and-tools/tool-use/overview第2章客户端工具在你的应用里跑Claude 返回 stop_reason 为 tool_use 及 tool_use 块你回传 tool_resultAnthropic《Tool use with Claude》https://platform.claude.com/docs/en/agents-and-tools/tool-use/overview第3章服务端工具web_search 等在 Anthropic 基础设施上跑你直接看结果Anthropic《Tool use with Claude》https://platform.claude.com/docs/en/agents-and-tools/tool-use/overview第3章自定义工具加 strict: true 可让调用始终精确匹配 schemaAnthropic《Tool use with Claude》https://platform.claude.com/docs/en/agents-and-tools/tool-use/overview第5章默认 tool_choice 为 autoClaude 每轮自行决定是否调用工具Anthropic《Tool use with Claude》https://platform.claude.com/docs/en/agents-and-tools/tool-use/overview第6章未提供 location 时Claude 可能猜你没给的参数值Anthropic《Tool use with Claude》https://platform.claude.com/docs/en/agents-and-tools/tool-use/overview第6章智能体系统的基本构件是被检索、工具、记忆增强的 LLMAnthropic《Building effective agents》https://www.anthropic.com/engineering/building-effective-agents第1章、第2章附表 B术语速查表术语一句话解释函数调用function calling让模型产出「调哪个函数、参数是什么」的结构化请求的机制工具调用tool use函数调用的另一种叫法含义相同工具tool你提供给模型的能力定义模型知道能干啥但不知怎么实现参数arguments模型决定调用时给出的输入值如城市名、订单号回传tool result你的代码执行完后交还给模型的结果schemaJSON Schema给函数写的参数说明书字段名、类型、是否必填结构化输出structured outputs让模型按固定格式稳定产出数据的能力是严格模式的底层客户端工具client tools在你的应用里执行的工具需要你写执行代码并回传结果服务端工具server tools在平台基础设施上执行的工具你直接拿结果stop_reasonAnthropic 表示「模型这轮为何停下」的字段tool_use 表示等你执行strict 模式强制调用精确贴合 schema 的开关两家都推荐开启tool_choice控制模型调不调、调几个、调哪个的参数parallel_tool_calls控制是否允许一轮并行多个调用的参数call_id标识一次调用的编号回传结果时用来对号入座写在最后这篇用到的资料写这篇文章时把两家官方文档里讲工具调用的那几页原文对着看了一遍顺手也整理了几份配套的东西大模型学习路线图从零基础到能自己动手做 Agent按阶段说明每一步该学什么、哪些可以先跳过《LangChain LangGraph MCP 智能体开发实战》视频课7 个模块从私有化部署、EmbeddingRAG 到 MCPAgent 全流程AI 大模型知识库在线可查Agent Skills 从入门到落地、Claude Skills 完全指南等专题按目录浏览即可640 套 AI 大模型行业报告 经典 PDF 书籍看行业落地案例和别人怎么做的时候用得上大模型零基础到精通教学视频跟着敲一遍比只读文档快得多资料是我自己整理的放在下面这个码上扫码即可获取添加时备注「AI」优先通过。资料按「先路线、再动手、最后查漏」的顺序整理好了建议先看学习路线那一份照着它挑一条适合自己当前基础的路径再往下看。
返回列表