登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  人工智能

工具调用参数校验失败后怎样安全重试

来源:17golang原创

时间:2026-09-12 12:46:49 215浏览 收藏

工具调用参数校验失败时,最安全的处理不是把原请求整段重放,而是把“解析失败、业务不满足、工具已执行”分成三种状态。先在应用侧校验模型生成的 JSON,再把带有 tool_call_id 的错误结果交回模型,让它只修正参数;真正可能修改订单、发送消息或写入数据的工具,还要用幂等键和有限重试保护。

官方地址:https://platform.openai.com/docs/guides/function-calling

要点速览
  • strict=true 负责提高 Schema 遵循度,不能替代应用侧业务校验。
  • 校验失败要回传工具错误,不要在副作用工具前盲目重放。
  • 每次修正都记录校验类型、调用 ID、幂等键和重试次数。

为什么一次参数校验失败不能直接重放工具

模型生成的参数有两类问题。第一类是 JSON 无法解析、字段缺失、类型不对或出现额外字段;第二类是 JSON 合法,但业务上不能执行,例如退款金额超过可退余额、收件人为空,或者同一个请求已经被处理。前一类适合让模型修正,后一类要把明确原因交给模型或转人工,不能靠多试几次碰运气。

尤其要注意“工具有没有真正执行”。如果服务端已经调用了扣款、发信或写库接口,再因为响应解析失败而重放整个 assistant 消息,就可能产生重复副作用。重试的对象应该是参数修正或查询型工具;写操作必须由幂等键决定是否允许再次落地。

先把校验放在副作用之前

工具定义可以启用严格 Schema。官方文档建议严格模式下对象设置 additionalProperties: false,并把字段列入 required;可选字段可以用包含 null 的类型表达。它能减少“字段名写错”这类错误,但库存、权限、金额和状态机仍然属于应用规则。

from json import JSONDecodeError

def validate_tool_call(tool_call, schema_validator):
    # 只解析和校验参数,不在这个函数里执行真实工具。
    try:
        arguments = json.loads(tool_call.function.arguments)
    except JSONDecodeError as exc:
        return None, {"kind": "invalid_json", "message": str(exc)}

    # Schema 校验拦截缺字段、类型错误和未声明字段。
    errors = list(schema_validator.iter_errors(arguments))
    if errors:
        return None, {"kind": "schema_error", "message": errors[0].message}

    # 业务校验只读数据;通过后才允许进入副作用工具。
    if arguments["amount"] 
function calling 参数从模型工具调用经过 JSON、Schema 和业务校验再连接副作用工具的静态关系示意图
图1:参数校验边界操作示意图;图中只表达组件关系,不是真实执行截图。

这段代码的关键是返回结构化错误,而不是在校验函数里偷偷调用工具。生产实现还应给写操作生成请求级幂等键,例如由业务订单号和动作类型组成,并在真正写入前检查该键是否已经成功消费。

用工具错误结果让模型修正,而不是重放副作用

校验失败后,应用应该保留原 assistant 工具调用,并使用同一个调用 ID 发送工具角色消息。消息里说明错误类型、缺失字段和可修正范围,不要把数据库内部堆栈、密钥或完整隐私数据直接暴露给模型。模型收到反馈后可以生成新的工具调用;应用仍要重新解析、重新校验,不能因为“这是第二次”就跳过检查。

def tool_error_message(tool_call, error, attempt):
    # 将错误限制在可修正信息,避免泄露内部实现细节。
    payload = {
        "ok": False,
        "error_type": error["kind"],
        "message": error["message"],
        "retryable": error["kind"] in {"invalid_json", "schema_error"},
        "attempt": attempt,
    }
    return {
        "role": "tool",
        "tool_call_id": tool_call.id,  # 必须对应这一次工具调用。
        "content": json.dumps(payload, ensure_ascii=False),
    }

对“参数字段缺失”可以允许模型修正;对“权限不足、余额不足、资源不存在”通常只反馈一次并停止自动重试。若业务工具已经成功执行,后续模型回合只能读取执行凭证,不能再次提交同一写操作。

tool_call_id、校验错误、修正参数、重试预算和工具结果之间的静态关系示意图
图2:错误反馈与修正边界结果示意图;它展示消息关联关系,不代表某次真实 API 返回。

strict Schema 和业务校验怎么分工

层次检查内容失败后的动作
生成约束字段名、类型、枚举、对象结构让模型根据错误修正参数
应用校验权限、库存、金额、资源状态给出可理解原因,必要时停止
副作用保护幂等键、执行凭证、重复提交拒绝重复落地,转查询或人工

可以把 strict 看成输入形状的护栏,而不是安全授权。OpenAI 的工具调用流程仍要求应用接收调用、执行自己的代码,再把工具输出发回模型;因此,最终执行权必须留在服务端。

上线时的重试边界要写死

建议为一次用户请求设置很小的参数修正预算,例如最多两次。预算耗尽后记录原始参数和最后错误,让用户补充信息或进入人工队列。日志至少包含 request_idtool_call_iderror_typeattemptidempotency_keyvalidated_atexecuted_at。只要看到同一幂等键出现两次成功执行,就应立即按业务预案止损,而不是继续增加重试次数。

常见问题

开启 strict 后还需要 JSON Schema 校验吗?

需要。strict 主要约束模型生成的参数形状,业务范围、权限和资源状态仍必须由应用检查。

校验失败要不要重新请求模型?

可以,但应把错误作为对应 tool_call_id 的工具结果回传,并限制次数;不要重放已经产生副作用的工具调用。

查询工具和写入工具的重试策略一样吗?

不一样。查询通常可在超时后有限重试,写入必须先确认幂等键、执行状态和服务端凭证。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>