桃子桃子快讯
返回首页
工具

Stoke:为 AI Agent 加装预算熔断与本地路由网关

Stoke 是一个约 5.5 MB 的 Rust 二进制网关,可在请求路径上为 OpenAI 兼容 Agent 强制执行…

2026.07.21 · 周二5 分钟阅读

随着 AI Agent 越来越长时段地自主运行,「凌晨两点开始循环重试、把按量计费的 API 额度烧光」成为开发者社区反复出现的事故。Stoke 给出的解法不是在事后追账单,而是在请求触达模型供应商之前就拒绝超支请求。它以一个独立的网关进程出现,对外暴露与 OpenAI 兼容的 /v1 接口,Claude Code 等客户端只需把 base_url 指向 localhost:8787/v1 即可接入。

核心问题:账单是「验尸报告」而非「控制器」

传统做法依赖计费告警或可观测性仪表盘,但它们只在花费发生后通知,而不是在发生前拦截。一个重试型 Agent 会在夜间以固定的 30 RPM 把同一个失败请求反复发出,直到天亮和 Key 额度一起醒来。Stoke 的设计哲学被概括为一句 slogan:「Enforce, don't just observe」,即在网关处直接拒绝,而不是事后记录。

在请求路径上的硬性约束

预算与速率限制并非可选项,而是 Stoke 启动时从配置加载的硬规则。

  • 美元预算上限:按 API Key 在 [[keys]] 配置表中设置美元额度,启动时生效;在调用任何供应商之前检查,超额请求直接以 HTTP 429 + Budget exceeded 拒绝。每个 Key 的实时花费通过 /v1/budget 端点查询,非流式响应附带 stoke_cost 字段;流式响应则按供应商回报的 usage 实时累计。
  • 循环熔断器:双层设计——精确的 prompt-hash 匹配加上可选的语义相似度,避免简单改写绕过。默认规则是 60 秒内出现 5 条相似请求,则该 Key 被封禁 120 秒。
  • 每 Key 滑动窗口限速:在同一 [[keys]] 表中以 rate_limit_rpm 配置,按 60 秒滑窗计算,超额同样返回 429。
  • 默认 fail-closed:未配置任何 API Key 且无 dev flag 时,所有请求一律拒绝;除 /health 外全部端点都强制鉴权,连状态端点也不例外,因为模型清单与节点负载被视为侦察信息。

本地优先:让 Agent 跑在你自己的机器上

Stoke 把 Ollama 节点当作一等公民。它后台轮询每个节点的 /api/tags(已拉取模型)和 /api/ps(已加载到内存的模型),再做以下决策:

  • 节点感知路由:优先把请求放到「模型已驻留内存」的暖节点上;同一模型分布在多台机器时按在途请求数做负载均衡,并辅以延迟 EWMA 打平;节点离线时自动剔除,恢复后重新纳入。
  • 自测量而非猜测:每个模型 × 节点的 TTFT 与 tokens/s 在真实流式请求中持续测量,上下文长度与是否支持 tool calling 从 /api/show 读取。
  • Federation:上游也可以是另一个 Stoke 实例,彼此通过 /v1/nodes 同步模型、暖机状态、负载与测速;hop 深度硬限制为 1,避免 A→B→A 环路,并附带脚本验证。
  • Auto 路由:在 auto / auto-cheap / auto-fast 模型名上,自动按预估成本、预测延迟与用户偏好对每个(模型, 节点)对打分;超上下文窗口或不支持 tool calls 的组合直接出局并写明理由。
  • Hedged dispatch:当同一模型在两台本地机器上都处于暖机状态,对小 prompt 同时向两侧发起 prefill,第一个完成的赢得请求、另一个立刻被丢弃;该机制以「零边际成本节点」为限,不会复制云端账单。

每条自动路由响应里都附 stoke_route 字段,写明选中的候选、预估成本、预测延迟,以及所有落选候选的落选原因与「不走本地将付的云端列表价」。

项目状态

Stoke 目前为预发布版本,MIT 协议,作者在 MacBook + Mac Studio + Ollama Cloud 组合上每日自用。5.5 MB 的 Rust 单一二进制即可部署,配置基于 TOML 的 [[keys]] 表,启动时加载生效,对 API Key、限速与预算做集中管控。对于需要长期运行 Agent 又不想再被凌晨告警叫醒的团队,它是一类正在出现的「Agent 成本护栏」工具的代表。

信源