工具封装专题总览
很多 AI 应用进入产品后,都会从“模型回答问题”走到“模型调用工具”。客服助手要查订单,数据助手要跑 SQL,运营助手要创建活动,研发助手要读文件、改代码、跑测试。
工具让模型连接真实系统,也把错误从“说错一句话”升级成“读错数据、写错状态、触发错误流程”。所以工具封装不是把一个函数暴露给模型这么简单,而是一次工程判断:
- 这个工具只是读信息,还是会改变业务状态?
- 参数来自用户、上下文还是模型推断?
- 工具返回值能否被模型误读?
- 失败后能否重试、回滚或转人工?
- 哪些调用需要用户确认?
- 线上出错后能不能知道模型为什么调用、用什么参数调用、工具返回了什么?
这篇总览先按场景分析查询类、写入类和高风险类工具,再给出从简单函数到工程封装的方案阶梯。核心观点很朴素:工具封装的目标不是让模型拥有更多能力,而是让能力的边界、权限、失败和责任都变得清楚。
场景
先看一个 B2B SaaS 客服后台。
用户提交工单:
我昨天买的企业版发票还没开出来,财务催得很急。订单号可能是 E20260509018,帮我查一下,如果已经开了就重发到邮箱。
客服助手可能需要三类工具:
没有 AI 时,客服会在后台手动查询订单、判断发票状态、复制模板回复,必要时发起退款或转财务审批。引入 AI 后,收益不只是减少打字,而是减少系统切换、提高处理速度、让低风险操作自动化。
但失败样本也很具体:
- 用户给了错误订单号,模型仍调用发票工具并把“未找到”解释成“尚未开票”。
- 模型从历史会话里拿到另一个客户的订单号,查询到了不该看的数据。
- 工具返回
invoiceStatus: pending_review,模型误写成“发票已经开具”。 - 用户只是问“能不能退款”,模型直接调用退款工具。
- 重试逻辑没有幂等键,同一封发票邮件被发送三次。
问题类型
工具封装通常混合了多个问题类型,不能只看“能不能调用 API”。
模型擅长理解自然语言、补齐上下文、选择候选工具和生成解释。程序应该负责工具契约、参数校验、权限、幂等、重试、错误归因和日志。人工应该负责高风险动作、模糊责任和例外处理。
收益和成本判断
工具封装的收益来自把 AI 接入真实工作流:
- 减少用户和员工在多个系统之间切换。
- 让查询、汇总、草稿生成和低风险写入自动化。
- 把工具调用过程记录下来,便于复盘。
- 用统一 schema 降低模型和业务 API 之间的耦合。
- 让工具可以被不同模型、工作流和 MCP 客户端复用。
它也会带来成本:
- 需要设计
name、description、input、output 和 error schema。 - 需要维护权限、确认、超时、重试和审计。
- 需要处理工具版本变更和兼容性。
- 需要为失败样本建立评估集。
- 写入类和高风险工具还需要幂等、回滚、人工确认和运营流程。
所以,工具封装不是越重越好。低频、低风险、只在后端内部使用的函数,可以保持普通函数。只要工具会被模型选择、参数由模型生成、结果会影响用户权益或进入自动化流程,就需要工程封装。
Function Calling、Tool Calling 和 MCP 的关系
很多团队会把普通函数、Function Calling、Tool Calling 和 MCP 混在一起讨论。它们解决的是不同层级的问题。
Function Calling 或 Tool Calling 只是“模型如何表达要调用某个工具”。它不自动提供权限、幂等、人工确认、审计和恢复。MCP 解决“工具如何被多个客户端发现和调用”,也不等于自动解决业务权限。
一个常见落地顺序是:先把高价值能力封装成窄工具契约,再接入统一 runtime;当工具需要被多个 IDE、桌面端、后台任务或 Agent 复用时,再考虑 MCP 化。反过来,如果契约、权限和风险等级还没想清楚,直接做 MCP Server 只是把不稳定能力暴露得更广。
方案阶梯
工具能力可以从简单到复杂逐级升级。
第一层是普通函数。适合后端内部确定性调用,例如页面加载时固定查询当前用户配置,模型不参与选择和参数生成。
第二层是受控工具函数。模型可以触发,但参数来源明确、风险低、返回简单,例如按当前用户 ID 查询自己的发票状态。
第三层是工具契约。工具需要清晰的 name、description、input schema、output schema 和 error schema,避免模型误用,也避免调用方靠自由文本猜返回值。
第四层是工具运行时。统一处理权限、确认、timeout、retry、限流、幂等和日志。这里开始,工具不再只是函数,而是带治理的执行单元。
第五层是确认和审计。写入类和高风险类工具要记录调用原因、参数、用户确认、工具结果和操作者,必要时支持回滚或补偿。
第六层是工作流编排。多步骤任务不应该依赖模型临场发挥,而应有状态机、失败分支、人工队列和恢复机制。
第七层是 MCP 化。当同一组工具需要被多个模型客户端、IDE、桌面应用或自动化系统复用时,可以把工具封装成 MCP Server,统一暴露能力和权限边界。
第八层是 Eval + Ops。上线后要持续评估工具选择准确率、参数错误率、权限拦截率、重试率、失败类型、延迟和成本。
什么时候简单函数足够
以下情况通常不用做完整工具封装:
- 函数只由确定性代码调用,模型不选择工具。
- 参数不来自模型推断,而来自可信后端状态。
- 函数只读低敏数据,且已经在业务 API 层完成鉴权。
- 失败不会影响用户权益,重新请求即可恢复。
- 调用链路短,团队能通过普通日志定位问题。
- 这个能力只是内部实验,还没有进入自动化流程。
例如“根据已登录用户 ID 读取当前页面配置”更像后端查询,不需要为了 AI 强行包装成工具。
什么时候需要工程封装
以下情况应该升级:
- 模型需要在多个工具之间选择。
- 工具参数来自用户自然语言、上下文或模型抽取。
- 工具返回值会被模型继续解释给用户。
- 工具会写入数据库、发消息、发起审批或触发外部系统。
- 工具涉及资金、权限、合同、医疗、法律或安全操作。
- 团队需要追踪“为什么调用了这个工具”。
- 工具要被多个应用、模型、MCP 客户端或 agent 复用。
这时应该把工具当成产品接口来设计,而不是把业务函数直接暴露给模型。
方案选型表
反模式
第一种反模式:把内部 API 原样暴露给模型。
内部 API 往往假设调用方可信、参数完整、错误有人处理。模型调用需要更窄的能力、更清晰的描述和更强的校验。
第二种反模式:工具名写得像代码缩写。
do_action、handle_user、update_data 这类名字让模型难以判断何时使用。工具名应该表达业务动作,例如 get_invoice_status 或 create_refund_request。
第三种反模式:查询、写入和高风险动作混在一个工具里。
例如 handle_invoice_issue 内部既查询发票、又重发邮件、还可能发起退款。模型看起来只调用了一次工具,实际上执行了多个风险等级不同的动作,确认和审计都会变得模糊。
第四种反模式:只记录最终回复,不记录工具调用。
线上出错时,团队需要知道模型看到什么、选择了哪个工具、传了什么参数、工具返回了什么、是否经过确认。只存最终文本无法复盘。
第五种反模式:靠 prompt 阻止高风险操作。
“不要退款,除非用户明确要求”不是权限控制。高风险工具必须在运行时做确认、权限和审计。
第六种反模式:没有错误 schema。
工具失败时只返回一段字符串,模型会自由解释错误。错误应该有稳定类型,例如 NOT_FOUND、PERMISSION_DENIED、VALIDATION_FAILED、TIMEOUT,并标明是否可重试。
工程清单
- 场景边界:工具是查询、写入还是高风险动作。
- 工具契约:
name、description、input、output、error schema 是否明确。 - 参数来源:参数来自用户、上下文、工具结果还是可信后端状态。
- 权限控制:是否在工具运行时完成用户、租户、角色和对象鉴权。
- 人工确认:哪些动作必须展示预览、依据和确认按钮。
- 幂等回滚:写入类工具是否有幂等键、补偿或撤销路径。
- Timeout 和 retry:是否有超时、重试上限、退避和不可重试错误。
- 错误处理:错误是否结构化,模型是否能区分缺参数、无权限、未找到和系统失败。
- 审计日志:是否记录调用原因、参数、结果、确认人、模型版本和工具版本。
- 可观测性:是否统计工具选择准确率、参数错误率、失败率、延迟和成本。
- 评估体系:是否有工具选择、参数抽取和风险拦截样本集。
- MCP 化判断:是否真的需要跨客户端复用,还是单应用内封装已经足够。
小结
工具封装的重点不是“让模型能调用更多函数”,而是把工具变成可描述、可校验、可授权、可确认、可审计的系统边界。
查询类工具重点是权限和返回值稳定。写入类工具重点是幂等、确认和回滚。高风险类工具重点是人工确认、审计和责任边界。
简单函数在低风险、确定性、内部调用场景里完全足够。只要模型开始选择工具、生成参数,或工具会改变业务状态,就应该升级到工具契约和运行时治理。后两篇会分别展开工具契约设计和工具 runtime 的工程细节。