主题
32 · 成本追踪(Cost Tracking)
Agent 发出的每一次 LLM 与 embedding 调用,Embabel 都会发出一个事件。 订阅这些事件,就能实时知道每次调用花了多少钱、用了哪个模型、以及它属于哪个 Agent 进程。
事件(The events)
有两个可用事件:
LlmInvocationEvent—— 每次 LLM 调用发出一次;EmbeddingInvocationEvent—— 每次 embedding 调用发出一次。
每个事件都暴露:
invocation.llmMetadata(或embeddingMetadata)—— 模型名与提供方;invocation.usage—— token 计数;invocation.cost()—— 本次调用的计算成本;interactionId—— 发起该交互的标识符;agentProcess—— 触发该调用的 Agent 进程(用agentProcess.id分组,用agentProcess.agent.name打标签)。
订阅成本事件
实现 AgenticEventListener,对你关心的事件做出响应。该监听器像其它 Embabel 事件监听器一样注册。
java
public class OrganizationCostTracker implements AgenticEventListener {
private final ConcurrentMap<String, DoubleAdder> costPerAgent = new ConcurrentHashMap<>();
@Override
public void onProcessEvent(AgentProcessEvent event) {
if (event instanceof LlmInvocationEvent llm) {
costPerAgent
.computeIfAbsent(llm.getAgentProcess().getAgent().getName(), k -> new DoubleAdder())
.add(llm.getInvocation().cost());
}
}
}同样的模式也适用于 EmbeddingInvocationEvent。
监听器所累计的任何状态,请使用线程安全的数据结构(如上例)—— 多个 Agent 进程可能同时发出事件。
阻断开销:预算护栏模式(Budget Guardrail)
成本事件在调用完成之后才触发,因此它们无法阻止刚刚发生的那次调用。 它们能做到的是阻止下一次。
该模式组合了两件你已经知道的东西:
- 一个负责计数的监听器:订阅
LlmInvocationEvent,按你关心的键(Agent 进程序列、租户、终端用户)累加成本或 token; - 一个负责拦截的护栏:
UserInputGuardRail在下一次 LLM 调用之前读取计数器。若超出预算,护栏返回一个CRITICAL校验错误,该调用就不会发生。
LLM call ───► LlmInvocationEvent ─┐
▼
counter(按 Agent / 租户 / 用户)
│
next call ──► UserInputGuardRail 读取计数器 ──────┘
│
超预算? ──► CRITICAL ──► 调用被阻断计数器活在监听器里,决策活在护栏里。 Embabel 会把两者都接入 Agent 进程。
关于如何注册 UserInputGuardRail、以及 CRITICAL 校验错误如何中止执行,见 Guardrails 章节。
如果你要给 Agent 进程本身设硬上限(例如"本次运行总花费超过 1 美元就停下"), 见 EarlyTerminationPolicy(Termination 章节)。它既可以单独使用,也可以与预算护栏一起作为安全网。