当 AI Agent 通过 MCP(Model Context Protocol)调用数据库写入、工单创建、邮件发送、支付申请等工具时,网络超时、客户端重试、模型重复规划或服务实例切换,都可能让同一操作被执行多次。查询类工具通常影响有限,但写操作一旦重复,可能产生重复订单、重复通知和状态错乱。🔁 因此,生产级 MCP 服务不能把“请求只会到达一次”当作前提,而应通过幂等键、去重存储、状态机和结果复用,建立可验证的幂等执行机制。
一、先分清请求标识与业务幂等键
MCP 的工具调用采用请求与响应模型,调用方通过 tools/call 指定工具名称和参数;协议消息中的请求 ID 主要用于关联响应,不能自然等同于业务幂等键。连接重建、进程重启或上层重新生成调用时,请求 ID 可能发生变化,但业务意图仍然相同。相关调用结构可参考 MCP 工具规范。
业务幂等键应表示“这一次业务操作”的唯一身份,例如 tenant_id + tool_name + operation_id。其中 operation_id 最好由调用链入口生成,并在模型规划、MCP 客户端、网关和工具服务之间透传。对于“创建订单”“发送通知”等写操作,不应仅依赖时间戳或随机请求 ID 判断重复。
核心原则:传输层请求可以重试,业务副作用只能成功提交一次;重复调用应返回首次执行的结果,而不是再次执行。
二、设计稳定的幂等键与参数指纹
推荐在工具输入中显式增加 idempotency_key,并在工具描述中说明它对写操作是必填字段。服务端收到调用后,同时计算参数指纹:先对参数进行规范化排序,排除 trace_id、时间戳等非业务字段,再生成摘要。这样不仅能识别重复请求,还能防止同一幂等键被错误地用于不同参数。
- 键不存在:创建执行记录并进入处理中状态。
- 键已存在且指纹一致:直接返回已保存的结果,或告知调用仍在处理中。
- 键已存在但指纹不同:拒绝执行并返回冲突错误,避免覆盖旧结果。
- 键已过期:依据业务保留期决定重新执行还是转人工核验。
幂等键应具备租户隔离,避免不同用户之间发生碰撞。服务端还应限制键长度、字符集和有效期,不能直接信任模型生成的任意字符串。对于高风险操作,可以让业务系统生成 operation_id,再由 Agent 原样携带,而不是让语言模型自行决定唯一性。
三、用原子写入阻断并发重复执行
仅采用“先查询、再插入”的逻辑存在竞态条件:两个相同请求同时查询时都可能发现记录不存在,随后分别执行。正确做法是在数据库中为 租户、工具名、幂等键建立唯一约束,并通过原子插入、事务或条件写入争夺执行权。
- 接收调用,完成鉴权、参数校验和指纹计算。
- 原子创建状态为 PROCESSING 的幂等记录。
- 创建成功的请求成为执行者;唯一键冲突的请求成为跟随者。
- 执行者调用下游系统,并将结果更新为 SUCCEEDED 或 FAILED。
- 跟随者读取已有状态,成功时复用结果,处理中时短暂轮询或返回可查询句柄。
幂等记录至少应保存键、参数指纹、执行状态、结果摘要、错误类型、创建时间、更新时间和追踪标识。若响应内容较大,可只保存对象地址或业务资源 ID,但必须保证重复调用能够恢复与首次调用语义一致的响应。
四、正确处理超时与不确定状态
最棘手的场景不是明确失败,而是“下游已经成功,但 MCP 服务在返回结果前超时”。此时若直接把记录改为失败并重试,可能再次产生副作用。更稳妥的方式是把状态标记为 UNKNOWN 或保持处理中,随后通过下游查询接口、业务流水号或回调进行核对。
调用外部系统时,应尽量把同一个幂等键继续传递给下游;如果下游支持幂等接口,就能形成端到端保护。如果下游不支持,可采用本地事务加 Outbox:先在同一事务中写入业务记录和待发送事件,再由异步任务投递。消费者同样要按事件 ID 去重,因为消息系统通常更容易提供“至少一次”投递,而不是绝对的“仅一次”。📦
五、限制客户端重试,避免模型层重复规划
重试策略必须区分错误类型。参数无效、权限不足、幂等键冲突等确定性错误不应重试;网络中断、限流和暂时不可用可以采用指数退避,并加入随机抖动。每次重试必须沿用原幂等键,不能因为重新发起请求就生成新键。
此外,模型可能在未看到结果时再次规划同一工具调用。客户端可维护短期调用账本,记录会话、工具名、规范化参数和 operation_id,并把“已提交”“执行中”“已完成”等状态反馈给模型。对于转账、删除、发布等敏感操作,还应设置人工确认和操作摘要。MCP 规范也建议应用清晰展示工具调用,并为敏感操作提供用户确认,可参见 官方安全与交互说明。🛡️
六、可观测性与测试不能缺位
生产环境应重点监控幂等命中率、键冲突率、处理中超时数量、未知状态数量、下游重复拒绝次数和结果复用耗时。日志中记录幂等键时要注意脱敏,不应把令牌、个人信息或完整业务参数拼入键值。
测试时不能只验证正常调用,还应模拟响应丢失、客户端断线、服务进程崩溃、并发提交、数据库事务回滚以及下游成功后超时等情况。可以让数十个相同请求同时到达,最终检查业务资源是否只创建一次、所有成功响应是否指向同一个结果,以及失败恢复后是否仍保持状态一致。🧪
总结
MCP 负责规范模型与工具之间的调用方式,但业务副作用的幂等保障仍需应用自行设计。可靠方案应以稳定的业务幂等键为入口,以参数指纹识别误用,以数据库唯一约束和原子状态迁移阻断并发,再结合结果持久化、下游键透传、Outbox、有限重试和可观测性形成闭环。只有把“重复请求一定会发生”纳入架构假设,AI 工具调用才能从演示环境安全地走向生产系统。✅