工具 Runtime 工程

提出问题

工具契约定义“能调用什么、参数和返回长什么样”。工具 runtime 负责“这次调用能不能执行、怎么执行、失败怎么办、谁负责”。

很多线上事故不是因为工具没有 schema,而是因为运行时缺位:

  • 模型传了合法订单号,但订单不属于当前用户。
  • 写入工具超时后被重试两次,产生重复记录。
  • 高风险动作没有确认,模型直接提交。
  • 工具失败只在模型回复里出现,系统日志没有 trace。
  • 多个客户端各自调用同一工具,权限和审计规则不一致。

工具 runtime 的目标不是增加一层复杂架构,而是把权限、确认、timeout、retry、审计和复用治理放到稳定位置。

场景

在客服后台里,用户请求:

发票如果已经开好了,就帮我重发到这个邮箱 finance@example.com

这句话看起来只是一个小动作,但 runtime 要回答很多问题:

  • 当前客服是否有权查看这个订单?
  • 用户是否有权接收这张发票?
  • 邮箱是不是当前客户组织里的邮箱?
  • 工具是先生成邮件预览,还是直接发送?
  • 如果发票系统 8 秒没有响应,要不要重试?
  • 如果发送工具超时,如何确认邮件是否已经发出?
  • 同一个请求刷新页面后会不会重复发送?
  • 日志里应该记录完整邮箱,还是脱敏邮箱?

模型可以判断“用户想重发发票”,但这些执行问题必须由 runtime 处理。

分析问题

问题类型

工具 runtime 主要处理执行类问题。

问题类型常见失败runtime 责任
权限模型拿到不该访问的订单、文件或用户数据用户、租户、角色、对象级鉴权
确认用户只是咨询,系统却执行写入或退款风险分级、预览、确认、取消
Timeout上游系统慢,模型一直等待或用户无反馈超时上限、降级、异步任务
Retry网络抖动后重复创建、重复发送、重复扣款重试策略、幂等键、不可重试错误
审计事故后不知道谁触发、为什么触发、传了什么trace、脱敏日志、版本记录
MCP 化多客户端调用工具,规则不一致统一工具暴露、能力边界和版本治理

模型适合提出候选动作、解释工具结果、在错误可恢复时追问用户。runtime 应该负责执行边界和系统可靠性。

收益和成本判断

工具 runtime 的收益包括:

  • 防止越权访问和越权执行。
  • 降低重复写入和不可逆错误。
  • 让高风险动作进入确认和审批。
  • 让失败能被重试、降级或转人工。
  • 让工具调用可以审计、回放和评估。
  • 让同一组工具被多个客户端安全复用。

成本包括:

  • 需要统一封装工具执行入口。
  • 需要接入权限、确认 UI、日志和监控。
  • 需要设计 timeout、retry、幂等和错误分类。
  • 需要处理异步任务和人工队列。
  • MCP 化还需要协议、部署、版本和客户端兼容管理。

如果工具只做低风险查询,并且调用方固定,runtime 可以轻量。只要工具会写入、影响权益、跨客户端复用或被 agent 自主选择,就需要更完整的运行时治理。

权限

权限不是 prompt 规则,也不是工具 description。权限必须在工具执行前由 runtime 和业务系统共同检查。

权限至少分四层:

权限层要检查什么示例
用户身份当前调用者是谁登录用户、客服账号、系统任务
租户边界数据属于哪个组织不能跨客户查询订单
角色能力调用者能做什么动作客服可查订单,财务可发票,主管可审批退款
对象归属参数对象是否可访问orderId 是否属于当前客户和当前客服队列

常见原则:

  • 不让模型传 tenantIdroleisAdmin 等权限字段。
  • 权限过滤发生在工具执行前,而不是回复生成后。
  • 查询工具也要鉴权,尤其是客户数据、文件和历史记录。
  • 工具返回值按权限裁剪和脱敏。
  • 权限拒绝要返回结构化错误,而不是让模型猜。

确认

确认用于处理“模型可以建议,但不能单独执行”的动作。

需要确认的典型动作:

  • 发送邮件、短信、通知。
  • 写入 CRM、工单、知识库或代码仓库。
  • 发起退款、改套餐、改权限。
  • 对外承诺 SLA、价格、合同条款。
  • 删除、覆盖、发布或部署。

确认界面应该展示:

  • 将要调用的工具和动作。
  • 关键参数和影响范围。
  • 模型调用理由。
  • 数据来源或工具依据。
  • 可取消、可编辑或转人工的入口。

确认不是让用户看一段“AI 将执行操作”的空话,而是让人能判断这个动作是否应该发生。

确认还要区分“用户确认”和“业务审批”。用户确认适合收件人、邮件内容、备注文本这类即时动作;业务审批适合退款、改套餐、改权限、发布和删除。前者通常在当前交互里完成,后者应该进入工作流,并记录审批人、审批依据和审批结果。

动作类型推荐确认方式不足时的风险
查询敏感数据权限校验 + 必要时二次确认用户看到了不该看的数据
写备注或草稿预览 + 可编辑 + 确认污染业务记录
发送邮件/通知收件人、正文、附件预览发错对象或对外承诺错误
退款/改权限/删除审批流 + 审计 + 补偿方案资金、权限或数据损失

Timeout

工具调用不能无限等待。不同工具应该有不同 timeout:

工具类型Timeout 策略处理方式
快速查询2 到 5 秒超时后提示稍后重试或转人工
慢查询 / 报表10 到 30 秒或异步返回任务 ID,完成后通知
写入动作短 timeout + 状态确认超时后查询执行状态,避免重复写
外部系统更严格预算熔断、降级、人工队列

timeout 不是单纯技术参数,它会影响用户体验和成本。核心链路里,宁可明确失败并降级,也不要让模型和用户一起等待不确定结果。

Retry

重试可以提升成功率,也可能制造事故。runtime 必须知道哪些错误可重试、哪些不能重试。

可重试:

  • 临时网络错误。
  • 上游限流后可退避。
  • 只读查询超时。
  • 幂等写入的临时失败。

不可重试:

  • 参数校验失败。
  • 无权限。
  • 对象不存在。
  • 业务规则不允许。
  • 非幂等写入且无法确认执行状态。

写入类工具必须设计幂等键。例如重发发票邮件可以使用 requestIdticketId + invoiceId + recipientEmail 作为幂等维度,避免刷新、重试或模型重复调用导致多次发送。

幂等设计要回答三个问题:

  • 同一个业务动作如何识别为“同一次”请求。
  • 上一次执行状态未知时,如何查询它是否已经生效。
  • 重复请求到来时,返回上次结果、拒绝执行,还是创建新动作。

不要把“模型不会重复调用”当作幂等策略。模型可能因为工具超时、上下文压缩、页面刷新或恢复执行而再次发起相同动作。runtime 要能用动作日志和外部系统状态判断是否安全继续。

状态不确定

工具最危险的失败不是明确失败,而是状态不确定。例如发送邮件工具超时,可能是邮件没发出,也可能是发出了但响应丢失。此时让模型自由决定“再试一次”会制造重复副作用。

状态不确定时,runtime 应该优先选择:

  • 调用查询状态工具确认动作是否生效。
  • 使用幂等键再次提交,让业务系统返回已有结果。
  • 将任务标记为 unknown,转人工处理。
  • 在最终回复里明确“操作状态未确认”,而不是让模型猜测成功或失败。

写入工具的 error schema 应该区分 FAILEDUNKNOWN_EXECUTION_STATE。前者可以按错误类型重试或降级,后者必须先查状态或转人工。

审计

审计日志要能回答六个问题:

  • 谁触发了工具调用。
  • 模型为什么选择这个工具。
  • 调用了哪个工具版本。
  • 参数是什么,哪些字段被脱敏。
  • 运行时做了哪些权限和确认检查。
  • 工具返回了什么,失败时错误类型是什么。

建议记录:

字段说明
traceId一次用户请求的全链路 ID
toolName / toolVersion工具标识和版本
caller用户、系统任务或客户端
model / promptVersion模型和提示词版本
reason模型给出的调用理由
input脱敏后的参数
permissionDecision允许、拒绝和原因
confirmation是否确认、确认人、时间
output / error脱敏结果或结构化错误
latencyMs / retryCount延迟和重试次数

日志要服务复盘,不应该成为新的泄露源。敏感字段需要脱敏或摘要化。

MCP 化

MCP 化适合把工具作为标准能力暴露给多个模型客户端。它的价值在于统一工具发现、调用协议和能力边界,而不是让每个函数都“显得更高级”。

适合 MCP 化的场景:

  • 同一组工具要被 IDE、桌面端、后台任务和 agent 复用。
  • 工具需要统一鉴权、审计和版本管理。
  • 团队希望把能力和客户端解耦。
  • 工具集合属于一个清晰领域,例如工单、订单、文档、代码仓库。

不适合 MCP 化的场景:

  • 只有一个应用内部使用。
  • 工具仍在频繁变化,契约不稳定。
  • 权限和审计还没有想清楚。
  • 只是为了 demo,把本地函数包装成协议服务。

MCP Server 也不能替代 runtime。它可以承载工具暴露方式,但权限、确认、timeout、retry 和审计仍然要设计。

列举方案

方案阶梯

第一层是直接函数调用,适合内部低风险流程。

第二层是统一执行入口,把所有工具调用经过同一个 runtime。

第三层加入权限和参数校验,防止合法 schema 下的越权对象访问。

第四层加入确认和风险分级,处理写入、高风险和模糊意图。

第五层加入 timeout、retry 和幂等,提升可靠性并避免重复副作用。

第六层加入审计和 trace,让线上问题可以复盘。

第七层把复杂动作放入异步工作流和人工队列。

第八层在确实需要跨客户端复用时 MCP 化。

第九层上线后持续做评估和运营监控。

什么时候简单函数足够

以下情况可以保持轻量:

  • 工具只读低敏信息。
  • 调用方固定,模型不自主选择。
  • 参数来自可信后端状态。
  • 失败可以简单重试或重新加载页面。
  • 不需要跨客户端复用。
  • 普通应用日志已经足够定位问题。

例如“读取当前用户主题配置”或“根据当前页面 ID 查询公开帮助文档”通常不需要完整 runtime。

什么时候需要工程封装

以下情况应该建设工具 runtime:

  • 模型自主选择工具或组合多个工具。
  • 参数来自自然语言抽取。
  • 工具涉及租户数据、客户数据、文件、权限或财务。
  • 工具会写入、发送、发布、删除或修改状态。
  • 工具调用需要用户确认或人工审批。
  • 失败后需要重试、降级、补偿或回滚。
  • 工具要被多个客户端或 agent 复用。
  • 线上必须满足审计、合规或事故复盘要求。

runtime 的复杂度应该跟风险匹配,不必一步到位,但权限和日志通常不应该拖到最后。

决策判断

方案选型表

场景条件推荐方案不推荐方案判断理由额外成本
内部只读、低敏、固定调用普通函数 + 常规日志完整 runtime风险低,封装收益有限单元测试
模型触发低风险查询统一执行入口 + 鉴权直接调用后端 API需要记录工具调用和权限结果trace、错误 schema
查询客户或租户数据对象级权限 + 脱敏输出只靠 prompt 限制越权代价高权限适配
写入低风险备注幂等 + 审计无日志直接写库写错会污染业务记录幂等键、撤销入口
发送外部通知预览确认 + timeout模型直接发送收件人和内容都需要确认确认 UI、发送记录
退款、改权限、删除工作流 + 人工审批 + 审计自动工具调用失败代价高且责任敏感审批、补偿
多客户端使用同一组工具MCP Server + 统一 runtime每端各自封装需要一致权限和版本治理协议、部署、兼容
上游不稳定timeout + retry + 熔断无限等待或无限重试需要控制延迟和成本监控、降级

反模式

第一种反模式:把权限写在 prompt 里。

“只能查询当前用户数据”必须由系统执行。模型可以遵守,也可能误用上下文或被注入诱导。

第二种反模式:所有工具使用同一个确认策略。

查询公开信息不需要确认;退款、发邮件、删数据必须确认。确认策略应该按风险等级和影响范围设计。

第三种反模式:写入工具没有幂等。

一旦 timeout、重试或用户刷新发生,就可能重复发送、重复创建、重复扣款。写入动作必须先考虑幂等。

第四种反模式:失败后让模型自由解释。

工具失败应该返回结构化错误,由 runtime 决定重试、追问、转人工或降级。模型可以解释,但不能猜测执行状态。

第五种反模式:审计日志记录了太多敏感数据。

审计要可复盘,但不应把密码、完整 token、完整身份证、完整银行卡或敏感文档内容写入日志。

第六种反模式:为了 MCP 化而 MCP 化。

如果只有单应用内部使用,且工具契约和权限还不稳定,先做好本地 runtime 往往更重要。

工程清单

  • 执行入口:所有模型工具调用是否经过统一 runtime。
  • 权限:是否做用户、租户、角色和对象级鉴权。
  • 参数来源:是否区分模型抽取参数和可信系统参数。
  • 风险分级:工具是否标注查询、写入、高风险。
  • 确认:写入和高风险动作是否有预览、依据、确认和取消。
  • Timeout:每类工具是否有合理超时和用户反馈。
  • Retry:是否区分可重试和不可重试错误,是否有次数上限和退避。
  • 幂等:写入类工具是否有幂等键和执行状态查询。
  • 审计:是否记录 traceId、工具版本、调用理由、参数、结果、确认和错误。
  • 脱敏:日志和工具返回值是否处理敏感字段。
  • 降级:权限拒绝、上游失败、超时和确认取消时是否有明确路径。
  • MCP 化:是否真的需要跨客户端复用,是否已有稳定契约和权限策略。
  • Eval:是否评估工具选择、参数正确率、权限拦截率和高风险确认命中率。

结论收束

工具 runtime 是工具封装从 demo 走向生产的关键层。契约让工具“说得清”,runtime 让工具“跑得稳、管得住、查得到”。

低风险、内部、确定性调用可以保持简单函数。模型参与选择、参数来自自然语言、工具会写入或影响权益时,就需要权限、确认、timeout、retry、幂等和审计。MCP 化适合跨客户端复用,但它不是治理的替代品;真正的治理仍然来自清晰契约和可靠 runtime。