
AI 辅助Function Calling 落地工具调用链路的参数校验与回滚设计一、模型会调用工具但系统必须负责后果Function Calling 让大模型从“会说”变成“能做”。它可以查订单、改配置、发通知、写数据。问题也随之出现模型生成的参数不一定可信工具执行不一定成功执行成功后也可能需要回滚。如果只把函数列表丢给模型就让模型直接触发生产动作风险非常高。工程上应该把 Function Calling 看成一层意图解析而不是最终执行器。模型负责把自然语言转成结构化意图系统负责校验权限、参数、幂等和副作用。这个分工非常重要。模型输出是概率结果生产系统需要确定性约束。常见事故包括模型把用户的“帮我看看配置”理解成“更新配置”日期格式解析错误导致查询范围扩大重复调用接口造成多次发送通知工具返回失败后模型继续生成“已完成”的回复。这些问题不是提示词能彻底解决的必须靠执行链路治理。二、工具调用链路从意图到执行的安全闸门sequenceDiagram participant User as 用户 participant LLM as 模型 participant Guard as 执行网关 participant Tool as 业务工具 participant Log as 审计日志 User-LLM: 自然语言需求 LLM-Guard: 函数名与参数 Guard-Guard: Schema 校验 Guard-Guard: 权限与幂等检查 Guard-Tool: 执行工具 Tool--Guard: 结果或错误 Guard-Log: 记录输入、输出、操作者、trace Guard--LLM: 结构化执行结果 LLM--User: 基于结果生成回复执行网关是关键。模型不能直接访问业务工具。所有函数调用都应该经过网关网关做五件事校验函数是否存在校验参数是否符合 Schema校验操作者是否有权限校验请求是否幂等记录审计日志。对于有副作用的工具还要增加确认机制。只读工具可以自动执行写操作必须分级。低风险写操作可以自动执行但保留回滚高风险写操作必须人工确认。这个分级不应该写在提示词里而应该写在工具元数据里。三、Go 侧执行网关不要信任模型参数下面是一个执行网关的简化实现。重点是先校验再执行并且所有工具都返回结构化结果。type ToolCall struct { Name string json:name Args json.RawMessage json:args RequestID string json:request_id UserID string json:user_id } type ToolResult struct { OK bool json:ok Data map[string]any json:data,omitempty Message string json:message,omitempty } type Tool interface { Name() string ReadOnly() bool Validate(args json.RawMessage) error Run(ctx context.Context, args json.RawMessage) (ToolResult, error) } func ExecuteTool(ctx context.Context, call ToolCall, registry map[string]Tool, audit AuditStore) (ToolResult, error) { tool, ok : registry[call.Name] if !ok { return ToolResult{OK: false, Message: unknown tool}, fmt.Errorf(unknown tool: %s, call.Name) } if err : tool.Validate(call.Args); err ! nil { return ToolResult{OK: false, Message: invalid args}, err } if err : checkPermission(call.UserID, tool.Name(), tool.ReadOnly()); err ! nil { return ToolResult{OK: false, Message: permission denied}, err } if !tool.ReadOnly() seenRequest(call.RequestID) { return ToolResult{OK: false, Message: duplicate request}, nil } result, err : tool.Run(ctx, call.Args) audit.Write(call, result, err) return result, err }这段代码明确了模型输出不能直接进入业务层。即使模型给出了合法 JSON也必须做业务校验。比如金额不能为负日期范围不能超过限制资源 ID 必须属于当前用户。Schema 只能保证形状不能保证语义。工具返回结果也要结构化。模型需要基于真实执行结果回复用户而不是凭空补一句“操作成功”。如果工具失败模型应该解释失败原因和下一步建议不能伪造成已完成。四、边界与权衡自动化越强审计越不能省Function Calling 的收益是降低操作摩擦代价是引入新的执行风险。只读工具风险较低适合快速接入。写操作、外部通知、资金相关、权限相关工具都必须谨慎。不要因为模型能生成参数就放弃传统后端的安全边界。幂等设计也很重要。模型可能因为网络重试、用户重复点击或上下文误判发起多次相同调用。每个有副作用的调用都应有request_id。业务工具要能识别重复请求并返回之前的结果而不是再次执行。回滚不是万能的。有些操作无法回滚比如已经发送给外部用户的通知。对这类工具应该采用“生成草稿 人工确认”的两阶段模式。模型负责草稿系统负责确认和发送。五、总结Function Calling 的工程核心是执行治理。模型负责意图解析系统负责校验、权限、幂等、审计和回滚。不要让模型直接触碰业务工具也不要把安全策略写成提示词。落地路线建议从只读工具开始建立统一网关和审计日志。随后接入低风险写操作并强制使用幂等键。高风险工具必须保留人工确认。这样才能在提升效率的同时把风险控制在工程系统能承受的范围内。