在 Google Colab 中运行这个 notebook
下面每一步都是可运行的 notebook。它在钱包没有余额时也能跑,会在支付这一步停下,让你在真的花钱之前先看到整个流程。
它是怎么工作的
四个部件,其中三个不过是 HTTP:
推理本身就是一次普通的
/chat/completions 调用。唯一的区别是你发的是哪个 header。
起步要花多少钱
有两个数字很重要,而它们不是同一个数字。 最小充值金额是五美元。这是/x402/top-up 会结算的最小额度,它是在 discovery 响应里返回的,而不是在任何地方硬编码,所以要读它,而不要相信这一页的说法。
能发起一次调用的最小余额是十美分。低于这个的钱包即便还有钱,向推理发请求也会拿到一个 402。
所以五美元是一个值得充值的最小钱包额度,也就是本指南给智能体的额度。值得知道这点钱能买些什么:向 qwen3-5-9b 提一个简短问题大约要花二十七个输入 token 和二十六个输出 token,按这个模型的价格算大约是七百万分之一美元。五美元大约是七十五万个问题的量级。这里的预算不是一个紧约束,而是一个爆炸半径。
环境准备
x402 SDK 负责支付签名。不要自己手写:转账授权是 EIP-712 typed data,重用一个 nonce 会以让人非常烦的方式导致验证失败。x402 Python SDK 需要 Python 3.10 或更高版本。Colab 没问题。macOS 自带的系统 Python 未必满足要求。
agent.py,写入配置。BUDGET_USD 是智能体给自己设的上限,这里设成整个钱包的额度。调低它,智能体会在钱花完之前就停下,而这可能是你唯一会改动的旋钮。
一个属于智能体自己的钱包
智能体需要一个密钥对。在生产环境里,这是你刻意充过值、私钥存放在 secret manager 里的钱包。在开发过程中,生成一个用完就丢的钱包是正确的做法,因为一个没有钱的钱包不会不小心把事情搞得很贵。userdata.get("WALLET_KEY") 读取。
用签名而不是密钥来登录
没有 key 可发,每次请求就带一份”钱包持有者本人发起了这次请求”的证明。这份证明是一条 EIP-4361 消息,签名后再 base64 编码进SIGN-IN-WITH-X header。
消息格式是精确的。Venice 会在它那边重建这些字节,并以此校验你的签名,所以多一个空行就意味着签名会被拒绝,而不是给你一个有用的错误信息。
Issued At 起的五分钟内有效。每个 nonce 在大约五分半的时间里只能使用一次。而且签名者必须与请求路径里的钱包一致,所以一个钱包不能查看另一个的信息,试图这么做只会拿到 403。
实际后果就是你要为每次请求都签一个新的 header,而不是缓存一个来用。签名是本地操作,不花钱,所以这没什么成本。
canConsume 是分支判断该看的字段。它已经把十美分的下限考虑在内了,所以你不用自己处理。
把钱存进去
充值要两次请求。第一次问 Venice 接受什么,这次是不做身份认证的,因为还没有东西可以认证。第二次带上签过名的转账授权。amount 用的是基本单位,USDC 有六位小数,所以 5000000 是五美元,而不是五百万个什么东西。在 Solana 通道上,extra.feePayer 是一个由 Venice 运营的账户,它替你付交易 gas 费,这就是钱包不必持有 SOL 也能付款的原因。
从一个没有 USDC 的钱包结算,会拿到一个 400,body 里是 PAYMENT_VERIFICATION_FAILED。这就是失败该有的样子:签名没问题,转账没成功。
按次付费
有了余额之后,推理就是一次带着签名的普通请求。把 Venice 系统 prompt 关掉比看起来更重要:它相当于每次调用大约一千七百个输入 token,比问题本身多出两个数量级。402 当作正常结果而不是异常来处理,是整个设计的核心。一个自己付钱的智能体最终会把钱花光,而花光钱不是崩溃。
读它花了多少
账本才是权威。与其从 token 数估算,不如问一下实际扣了多少。TOP_UP 和 REFUND 行也会出现在这里,金额是正的。过滤到 CHARGE 得到的就是花费。
有预算的一次运行
现在是主循环。在每次调用之前,智能体会检查已经花了多少,并且拒绝去做它付不起的工作。到这里你手上有了什么
这个智能体持有自己的钱,用签名证明身份,也没法超出你设的上限,而且在任何地方都不存在关于它的账户。对于一个定时任务、一个 serverless 函数、或者任何你并不想把一个长期存活的 key 交给它的场景,这在安全姿态上是有实质区别的。 值得接着做的一些事:在协议里加上限
SDK 里的 spend control 是每次支付一个上限,而不是每个会话一个上限。把它和上面那个预算循环搭配起来,让其中一个出 bug 也无法绕过另一个。
没钱了自动补
捕获
402、去充值、然后重试。TypeScript 版本的 venice-x402-client 帮你做的就是这件事。在 Solana 上支付
同样的流程,另一条通道。用 Ed25519 签名,并设置返回的
feePayer,这样钱包就不需要 SOL。给它派点真正的活
把任务列表换成一个工具调用循环,账本就会开始告诉你每一个决策各自花了多少。