Agent 工程化系列 · 第 05 篇_FunctionCall底层到底怎么实现
Agent 工程化系列 · 第 05 篇Function Call 底层到底怎么实现模型不是在调用函数而是在生成调用意图。开篇定位前面第 04 篇我们讲清楚了 Function Call 是什么它不是让大模型“真的去执行函数”而是让模型在合适的时候生成一份结构化的工具调用请求。到了这一篇我们继续往下拆Function Call 底层到底是怎么跑起来的也就是说当用户说出一句话“帮我查一下今天北京天气如果下雨就提醒我带伞。”系统内部到底发生了什么模型看到了什么应用层收到了什么函数是谁执行的工具结果又是怎么回到模型里的这一篇不讲玄学只讲工程链路。目录Function Call 的底层本质是什么一次 Function Call 请求发生了什么工具定义为什么需要 JSON Schema模型输出tool call 长什么样执行器真正执行函数的是谁多轮工具调用循环怎么跑工程里如何做安全边界最后总结01 Function Call 的底层本质是什么先记住一句话Function Call 的底层本质上是模型输出一份“结构化调用意图”。普通聊天模式下模型输出的是自然语言。比如“今天北京可能有雨建议你带伞。”但 Function Call 模式下模型可以输出一种更适合程序处理的结果{name:get_weather,arguments:{city:北京}}这段内容不是最终回答而是一份调用请求。它的意思是我判断现在需要调用get_weather这个工具参数是city北京。真正执行get_weather函数的不是模型本身而是模型外面的应用程序、Agent 框架或者工具执行器。一个关键误区很多人第一次理解 Function Call 时会以为模型真的跑了一段函数代码。但这不准确。更准确的说法是模型负责判断“该调用什么工具、传什么参数”应用程序负责真正执行工具并把结果返回给模型。所以 Function Call 不是“模型执行代码”而是“模型和外部程序之间的一种结构化协作方式”。02 一次 Function Call 请求发生了什么从工程视角看一次 Function Call 通常会经历 5 个步骤。第一步开发者注册工具。应用程序先告诉模型我这里有一个工具叫get_weather它可以查询天气。它需要一个参数city。这个参数必须是字符串。第二步用户提出任务。用户输入“帮我查一下今天北京天气。”模型拿到的不只是用户问题还会同时看到系统提供的工具定义。第三步模型选择工具。模型判断这个问题不能只靠内部知识回答因为天气是实时信息。所以需要调用外部工具。于是模型输出一份 tool call。第四步应用执行工具。应用程序读取 tool call拿到函数名和参数真正调用天气 API。第五步模型整合结果。工具返回真实天气数据后应用程序把结果发回模型。模型再把结构化结果整理成用户能读懂的自然语言。这里最重要的是“回填”Function Call 不是模型输出一次工具调用就结束。真正完整的流程是用户问题 ↓ 模型输出 tool_call ↓ 应用执行工具 ↓ 工具结果回填给模型 ↓ 模型生成最终回答没有“工具结果回填”模型就不知道工具执行结果是什么。也就无法基于真实结果继续生成答案。03 工具定义为什么需要 JSON SchemaFunction Call 之所以比普通 Prompt 稳定关键原因之一是工具不是靠一句自然语言描述而是靠结构化 schema 描述。比如一个天气工具通常会描述这几类信息信息作用工具名称模型知道要调用哪个工具工具描述模型判断什么时候该用它参数结构模型知道需要传哪些字段参数类型避免把数字、字符串、数组传错必填字段避免漏传关键参数这就是 JSON Schema 的价值。它不是给人看的“说明文档”而是给模型和程序共同使用的“接口契约”。为什么不能只写 Prompt你当然可以在 Prompt 里写如果用户问天气就调用天气接口参数是城市名。但这样会有几个问题模型可能漏参数模型可能把参数写成自然语言模型可能输出格式不稳定应用程序解析困难多工具场景下容易混乱而 JSON Schema 的作用是把“工具怎么用”变成更明确的结构。这也是为什么 Function Call 是 Agent 工具系统的基础能力之一。04 模型输出tool call 长什么样在底层交互里模型通常不会直接返回一句完整回答而是返回一个工具调用对象。一个 tool call 至少要表达三件事{id:call_01,name:get_weather,arguments:{city:北京}}这里面最关键的是字段含义id本次工具调用的唯一标识name要调用的工具名称arguments传给工具的结构化参数其中id很重要。因为真实系统里可能一次返回多个 tool call比如同时查天气、查日程、查交通。应用程序执行完每个工具后需要把结果和对应的tool_call_id对上。否则模型无法知道哪个结果对应哪个工具调用。tool call 不是最终答案tool call 更像一张“任务单”。模型写了一张任务单去调用 get_weather查北京天气。执行器拿到任务单去真正执行。执行完之后再把结果贴回到对话上下文里。模型看到结果后才继续生成最终回答。05 执行器真正执行函数的是谁Function Call 系统里通常有一个角色叫工具执行器。它可以是你自己的业务代码也可以是 Agent 框架里的 Tool Executor。它的职责不是“理解用户意图”。理解用户意图主要由模型完成。工具执行器负责的是更工程化的事情读取模型输出的工具名校验参数是否符合 schema判断用户是否有权限调用真实 API、数据库或业务系统处理超时、失败、重试记录日志把结果包装成 tool result也就是说工具执行器是模型和真实系统之间的一层边界。它不能太薄。如果只是简单写一句resulttools[name](**arguments)在 Demo 里可以跑。但在真实系统里远远不够。因为工具调用一旦接入数据库、订单系统、文件系统、支付系统就已经不只是“问答”问题而是“执行动作”问题。06 多轮工具调用循环怎么跑真实 Agent 场景里Function Call 往往不是一次完成。比如用户说“帮我安排明天去上海的行程如果下雨就优先安排室内活动。”一个 Agent 可能需要查明天上海天气查用户日程查交通时间查室内活动推荐生成行程方案这时模型可能会连续生成多次 tool call。每一次调用之后工具结果都会回填到上下文里。模型再根据新信息决定下一步。工程上必须设置退出条件多轮工具调用有一个风险模型可能一直觉得信息不够然后不断调用工具。所以真实系统里一般需要设置最大调用步数单次工具超时时间总任务超时时间工具失败重试次数是否允许并行调用是否需要人工确认这也是 Agent 工程化和普通 API 开发最大的不同之一。普通 API 调用流程是程序员写死的。Agent 工具调用流程是模型在运行时动态决定的。所以你必须给它边界。07 工程里如何做安全边界Function Call 真正危险的地方不是“模型答错”。而是模型生成了一个看起来合理、但实际有风险的工具调用。比如删除文件修改数据库发送邮件提交订单转账付款调用内部系统接口如果没有安全边界Agent 很容易从“智能助手”变成“高风险自动执行器”。一个靠谱的工具执行器至少要做这些事安全点具体作用参数校验防止模型生成错误参数权限控制判断当前用户是否有权执行风险分级区分查询、修改、删除、支付等动作人工确认高风险动作必须由人确认超时重试防止工具长时间卡住幂等设计防止重复下单、重复扣费日志审计出问题时能追踪全过程这里有一个工程原则不要把模型当成可信执行者要把它当成会生成调用建议的智能决策模块。模型可以建议调用什么工具。但能不能执行、怎么执行、执行到什么权限边界必须由系统控制。08 最后总结Function Call 的底层实现可以压缩成一句话模型生成结构化 tool call应用程序执行真实工具再把工具结果回填给模型继续生成。它不是让模型拥有了魔法。它只是把模型的语言能力接到了外部系统的真实能力上。这一层能力是 Agent 从“会聊天”走向“能办事”的关键一步。本篇重点可以记住 4 点Function Call 本质是结构化调用意图JSON Schema 是模型和程序之间的接口契约真正执行函数的是应用层或工具执行器多轮调用必须有边界、安全、日志和退出条件下一篇我们会继续进入工具与协议阶段第 06 篇MCP 是什么协议为什么它被称为 AI 应用的 USB-C参考资料OpenAI API DocsFunction Calling / Tool CallingOpenAI API DocsStructured OutputsOpenAI Agents SDKToolsAnthropic DocsTool Use with ClaudeLangChain DocsTools / Tool Calling
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2609640.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!