最新资讯
reddit.com OpenAI 称 Astra 仅满足 10% 安全任务标准 dev.to FreeToken:在自有 GPU 上运行前沿 MoE 模型及其内存需求 dev.to 当 AI Agent 说“完成”时,究竟完成了什么? dev.to 部署 Underdog Bark 3.0 Pro:逐字转写、自定义后端与分块设置 dev.to 为艰难对话构建 AI:五个 Agent、一条安全正则与一位盲评监督者 techcrunch.com Palo Alto Networks 洽谈以 5 亿美元收购 AI Agent 安全初创公司 Clutch theinformation.com 黄仁勋被要求就涉华间谍指控向国会作简报 www.infoq.com Edera 推出 Object Capability Bounded Authority,试图将凭证与 AI Agent 工作负载隔离 wechat 这波杀疯了!旗舰级模型不限量、1个月视频额度免费领 bloomberg.com AI 抛售蔓延至信用市场,软银领跌亚洲美元债 dev.to 如何在专用 GPU 服务器上用 OpenAI 兼容 API 部署 LLM dev.to 审计 153 份 Claude Code 与 Codex 会话记录:User-Agent 与 URL 中的邮箱泄露
多元动态
登录 注册
智能体 dev.to · @whiteknightonhorse

AI Agent 重试付费 API 时如何避免重复扣费

原文 我的收藏

一篇 DEV 实践文章介绍其 MCP 网关在 Agent 按次付费场景下的防重复扣费设计:通过 x402 on Base 的 EIP-3009 单次支付授权与 nonce 机制,使同一授权只能被使用一次,并讨论四层防护各自的有效边界。内容为单一团队经验,尚无独立验证。

AI推荐理由 文章来自 DEV Community 个人作者,介绍其 MCP 网关中防止 AI Agent 重试付费 API 导致重复扣费的四层机制,涉及 x402、EIP-3009 单次授权与 nonce 等具体技术细节。对 Agent 支付与幂等设计有实际参考价值,但属于单一团队实践,未提供第三方验证或完整效果数据。

68

正文

An AI agent calls a paid API, the payment goes through, and the response never arrives. The connection dropped, a proxy timed out, or the agent's own runtime restarted. From the agent's side the call failed, so it does the reasonable thing and tries again. If the API charges per call, that retry is where money goes missing. The first payment may have settled on chain while the agent never saw the result. A naive retry pays a second time for the same work. We run an MCP gateway where agents pay per call in USDC, over x402 on Base or MPP on Tempo. This post walks through the four layers we use so that a retry never turns into a double charge, and where each layer stops helping. Layer 1: the payment authorization is single-use With x402 on Base, the agent does not send money directly. It signs an authorization for a USDC transfer (EIP-3009), and the server submits it. Each authorization carries a nonce, and the token contract accepts a given nonce from a given payer only once. So if the agent resends the exact same signed payment, the second transfer fails on chain. No server-side bookkeeping is needed for that guarantee, and it holds even if our own records are lost. A new charge always needs a new signature from the agent. MPP has the same property on its side. A credential that was already used comes back as 403 credential_replayed, and the call is not charged. Layer 2: a payment id makes the retry return the stored answer Layer 1 stops the double charge, but it leaves the agent stuck: it paid, it has no result, and resending the payment now fails. To fix that, on our order payments (agents buying from shops through the gateway) the agent can attach a payment id to the payment: the payment-identifier extension of x402, 16 to 128 characters. The rules we apply: Same id, same payment: we return the stored answer from the first request, with no second verify and no second settle. We keep that answer for 24 hours. Same id while the first request is still running: 409 payment_in_flight. Same id with a different quote, amount, recipient or payer: 409 payment_identifier_conflict. The last rule matters more than it looks. If a changed request with an old id quietly got the old result, idempotency would hide a client bug. The agent would think it bought one thing and actually receive another. A conflict forces the client to notice. Layer 3: "unknown" is not "failed" The hardest case is the one in the middle. We broadcast the settlement, and then the facilitator call times out or the transaction is still pending. Did the payment happen? We treat that state as unknown and never as failed. A background job reads the chain: the authorization state for that payer and nonce, and the USDC transfer itself. If it confirms, the order becomes paid and the result is delivered. If it is still not confirmed after 24 hours, the order is marked failed for good and any reserved stock is released. What we never do is settle the same authorization a second time to "make sure". That is the classic way a timeout turns into two charges. Layer 4: failed calls are not billed For tool calls, we only charge for a delivered response. If the upstream provider rejects the input or fails, the call is not charged. Last week that rule covered 1,905 calls rejected by providers, none of them billed. This does not prevent retries, but it means a retry after a genuine failure is a fresh, fair purchase rather than a second payment for a call that never produced anything. Where the layers stop The 24-hour window is a choice, not a law. An agent that comes back after 25 hours with the same payment id will not get the stored answer. It still cannot be charged twice, because Layer 1 rejects the old signature on chain. What it loses is the cached result, so it has to decide whether to pay again for a fresh call. That is the trade-off we accepted. The record only needs to cover the agent's realistic retry and recovery period. The guarantee against double charging does not depend on the record at all, because it lives in the payment itself. A checklist if you build paid tools for agents Make the payment instrument single-use (a nonce or a one-time credential), so a resend cannot charge twice even if your database is wrong. Give clients an idempotency key and return the stored answer for a repeat, for a stated window. Return a conflict when the same key arrives with a different request instead of replaying the old result. Treat a timed-out settlement as unknown, resolve it by reading the chain, and never settle again to find out. Charge only for delivered results, so a retry after a real failure is a fair new purchase. None of this is specific to AI. It is distributed-systems hygiene that matters more once the client is a program that retries on its own, at machine speed, with a wallet attached.

来源报道 · 1 篇 · 以下链接均前往原始媒体

whiteknightonhorse AI Agent 重试付费 API 时如何避免重复扣费 10-23 · 原文发布
← 返回精选动态 原文

更多内容