下面按影响出现的顺序列出四种成本。每种成本旁边都有调节手段,而且都会“故障开放”:达到限制时,事件会未经判定直接通过,请求路径不会等待。
| 默认值 | 调节手段 | |
|---|---|---|
| 费用 | 每百万输入 token 0.042 美元,每判定 10 万个事件约 6 美元 | when、cacheKey、state |
| 速率 | 每个账号每分钟 1,200 次调用 | budget.perMinute、cacheKey |
| 延迟 | keep 事件在 drain 前最多等待 2 秒,客户端不受影响 | timeoutMs、更严格的 when |
| 出站数据 | 脱敏前的完整事件 | state、providerOptions.gateway.zeroDataRetention |
费用
Jev 只按输入 token 计费,本文撰写时的价格是每百万个 token 0.042 美元。概览中的 15 个请求成本为 0.00007 美元。一个包含 1.5k token 的事件约为 0.00006 美元,因此 10 万个判定事件约为 6 美元,一百万个约为 60 美元。价格会变化;模型页面提供当前数值。
决定账单的是到达模型的事件数量,而不是你定义了多少 signal。一个事件需要运行的所有 signal 共享一次调用,因此向已经运行的 signal 添加问题几乎不产生额外成本:
when是第一种调节手段。在status >= 400时运行的fault不会在成功请求上产生费用。cacheKey是第二种。一次故障会产生数千个相同的 502;使用path + error.name作为键可以将其合并为一次调用,其余请求从缓存获取结果。state是第三种。默认发送完整事件。只选择问题需要的六个字段可以减少 token,也能同时解决下面的出站数据问题。
速率
在费用限制之前生效的是账号速率:每个 TypeSafe 账号每分钟 1,200 个请求,即每秒约 20 个。budget.perMinute(默认值 600)是每个进程固定的一分钟窗口,因此一个账号有四个实例时应设置为 300。超过窗口后,事件会未经判定直接通过,stats().skipped 会增加。
失败调用会打开持续 budget.cooldownMs(默认 30 秒)的断路器,因此模型返回 429 或发生故障时,结果会出现 30 秒的空档,而不是形成队列。
延迟
keep signal 会在采样决策前运行并等待判定,最长等待 timeoutMs(默认 2 秒)。两点让这通常可以接受:
- 响应已经发送。
keep和enrich在请求结束后运行,因此客户端永远不会等待模型。 - 事件上的
durationMs是请求持续时间,在 keep 钩子运行前测量。判定不会抬高你的延迟图表。
它会延迟事件到达 drain 的时间,延迟量是模型往返时间。Keep signal 应该用于狭窄路径(例如 /api/checkout,而不是每个 200 响应),只有 enrich 的 signal 不会产生这种等待。
出站数据
模型读取 state 提供的内容。默认情况下,这是去掉 signals 列的完整宽事件;对于 keep signal,则是脱敏运行之前的请求上下文。如果处理程序记录了你不会粘贴到第三方 API 的内容,请设置 state 选择字段:
createSignals({
signals,
state: e => ({ status: e.status, path: e.path, durationMs: e.durationMs, error: e.error, payment: e.payment }),
providerOptions: { gateway: { zeroDataRetention: true } },
})
zeroDataRetention 会原样传递给 AI Gateway。推理在你的进程中使用你的密钥运行;evlog 不保存密钥,也不代理任何内容。
不会发生的事情
- keep signal 永远不会丢弃事件。它只会提升保留级别,头部采样仍然是确定性的。
- 判定永远不是散文。列是带概率的类型化值,除非你主动要求(
stampModel),否则不会向事件添加其他内容。 - 达到限制永远不会表现为错误。预算耗尽、断路器打开、状态过大或模型不可用时,事件仍会像没有 signals 时一样 drain,只有
stats()中的计数器会变化。