
很多团队已经把 AI Agent 做出来了,但真正开始收费时,才会撞上一个更现实的问题:
用户每聊一句、每调用一次模型、每跑一个任务,到底该向谁收费、收多少钱、怎么进账单?
如果只卖一个固定月费,重度用户可能把模型额度打穿,轻度用户又会觉得被多收。AI Agent 的商业化不能只靠套餐页,核心是把每一次模型调用变成可计量、可归属、可开票的用量事件。
这篇文章拆的是一套相对完整的工程流水线:用 LangChain callback 捕获模型 token,用 CloudEvents 标准化事件,再接入 Kong Konnect / OpenMeter 的计量和订阅体系,把 Agent 从“能回答问题”推进到“能按用量收钱”。

AI Agent 应用侧记录输入输出 token
一、别再只卖固定套餐了:Agent 真正烧钱的地方,必须逐次记账
AI Agent 的成本并不只发生在“用户发了一条消息”这一刻。一次看似简单的对话,背后可能包括:
成本项 | 典型来源 | 为什么必须计量 |
|---|---|---|
输入 token | 用户问题、系统提示词、历史上下文、工具 schema | 上下文越长,请求成本越高 |
输出 token | 模型回复、工具调用参数、总结内容 | 多数模型输出单价高于输入 |
工具调用 | 搜索、数据库、MCP、外部 API | 可能产生第三方调用费用 |
多轮任务 | Agent 计划、执行、反思、重试 | 一个用户请求可能拆成多次模型调用 |
客户归属 | tenant、workspace、user、plan | 不归属到客户,就无法开票和限额 |
所以,一个可收费的 Agent 至少需要打通下面这条链路:
模型请求 -> 识别客户 subject -> 统计输入 / 输出 token -> 生成可去重的用量事件 -> 写入计量系统 -> 按套餐和费率聚合 -> 进入客户账单 / 发票
这不是一个“成本统计脚本”,而是一条产品化计费链路。
二、架构一眼看懂:LangChain 负责抓数,Kong 负责算账
这套方案的核心分工很清晰:
层级 | 组件 | 负责什么 |
|---|---|---|
Agent 编排层 | LangChain | 统一接入不同模型和调用生命周期 |
采集层 | Callback Handler | 在 LLM 开始和结束时读取 metadata 与 tokenUsage |
事件层 | CloudEvents | 把每次输入 / 输出 token 标准化为事件 |
计量层 | Kong Konnect / OpenMeter | 按 customer subject 聚合 token 用量 |
商业层 | Feature、Plan、Rate Card、Subscription | 定义输入输出 token 价格并生成账单 |
收款层 | Stripe 等支付提供商 | 处理真实扣款、失败重试和支付方式 |

Token 用量进入 Kong 计量和账单系统
原文示例使用 OpenAI 的 gpt-4o-mini,但关键点不在模型本身,而在 LangChain 的抽象层。只要模型调用能返回 token usage 或 estimated token usage,同一套 callback 就能继续使用。

Agent 计费事件架构
三、第一刀砍在 LangChain:把每次模型调用变成两条账单事件
实现上,重点不是写一个复杂服务,而是接入 LangChain 的生命周期回调。
1. 在模型开始时保存客户归属
生产环境里,subject 不应该写死在环境变量中,而应该来自登录态、workspace、tenant 或 API key。示例里为了演示,先用 acme 作为客户标识。
async handleLLMStart(_llm: Serialized,_prompts: string[],runId: string,parentRunId?: string,_extraParams?: Record<string, unknown>,_tags?: string[],metadata: Record<string, unknown> = {},) {if (parentRunId) {const parentMetadata = this.runMetadata.get(parentRunId);if (parentMetadata) {Object.assign(metadata, parentMetadata);}}this.runMetadata.set(runId, metadata);}
这里有一个容易被忽略的点:LangChain 的 LLM 调用通常挂在 chain、agent 或 tool flow 的子运行下面。如果不把 parent metadata 合并进 child run,handleLLMEnd 里可能拿不到客户标识,最后就会出现“模型确实调用了,但不知道该向谁收费”的事故。
2. 在模型结束时读取 tokenUsage
模型返回后,callback 读取 promptTokens 和 completionTokens,分别生成输入和输出两条 CloudEvents。
async handleLLMEnd(output: LLMResult, runId: string) {const { promptTokens = 0, completionTokens = 0 } =output.llmOutput?.['tokenUsage'] ??output.llmOutput?.['estimatedTokenUsage'] ??{};if (!(promptTokens > 0 || completionTokens > 0)) return;const metadata = this.runMetadata.get(runId) ?? {};const { subject, ls_model_name, ls_provider, ls_model_type, ...data } = metadata;const inputEvent = {specversion: '1.0',id: `${runId}-input`,source: 'langchain',type: 'kong.llm_request',subject,data: {...data,type: 'input',tokens: promptTokens,model: ls_model_name,provider: ls_provider,},};const outputEvent = {specversion: '1.0',id: `${runId}-output`,source: 'langchain',type: 'kong.llm_request',subject,data: {...data,type: 'output',tokens: completionTokens,model: ls_model_name,provider: ls_provider,},};await this.ingest(inputEvent);await this.ingest(outputEvent);}
这段代码里有三个生产级细节值得保留:
设计点 | 作用 |
|---|---|
id = runId + input/output | 让重试具备幂等性,避免重复计费 |
data.type = input/output | 支持输入 token 和输出 token 分开定价 |
metadata 透传 | 可以把 region、tenant tier、模型、功能开关写入计量维度 |
3. 接入 Agent 只需要一行 callback
真正接入时,Agent 侧不需要把业务代码改成计费专用写法。
const handler = new MeteringCallbackHandler(apiUrl, apiKey);const llm = new ChatOpenAI({ model, apiKey: openaiApiKey, callbacks: [handler],});const chain = PromptTemplate.fromTemplate('{input}') .pipe(llm) .pipe(new StringOutputParser());const result = await chain.invoke( { input: userInput }, { metadata: { subject, tenantTier: 'pro', }, },);
这才是好计费系统该有的形态:业务只负责把客户身份放进 metadata,计量逻辑在统一入口里自动完成。
四、第二刀砍进 Kong:Meter、Feature、Plan、Rate Card 一个都不能少
CloudEvents 只是原始用量,不能直接等同于账单。要从“事件”变成“钱”,还需要在计量系统中配置几类对象。
1. Meter:先定义什么事件算用量
在 Kong Konnect 的 Metering & Billing 里,可以创建一个 LLM Tokens meter。

创建 LLM Tokens meter
关键配置是:
配置 | 值 | 含义 |
|---|---|---|
Event type filter | kong.llm_request | 只统计 Agent 发来的 LLM 请求事件 |
Aggregation | Sum | 把 token 数累加 |
Value property | tokens | 从事件的 data.tokens 读取数值 |
也可以用 API 创建:
curl -X POST https://us.api.konghq.tech/v3/openmeter/meters \-H "Authorization: Bearer $API_KEY" \-H "Content-Type: application/json" \-d '{"name": "LLM Tokens","key": "llm-tokens","description": "LLM token usage","event_type": "kong.llm_request","aggregation": "SUM","value_property": "$.tokens","dimensions": {"type": "$.type","provider": "$.provider","model": "$.model"}}'
2. Feature:把输入和输出拆成两个商品
同一个 meter 可以喂给多个 Feature。这里最重要的是把输入 token 和输出 token 拆开。

创建输入输出 token feature
Feature | 过滤条件 | 用途 |
|---|---|---|
Input Token | type = input | 统计提示词和上下文成本 |
Output Token | type = output | 统计模型生成成本 |
为什么要拆?因为大多数模型的输入和输出单价不同,输出 token 通常更贵。如果只做一个总 token meter,后面就很难按真实成本定价。
3. Plan 和 Rate Card:把 token 变成价格
下一步是在 Product Catalog 里创建套餐,比如 Pro,再分别给输入和输出 token 添加 usage-based rate card。

给输入 token 配置 usage-based rate card
演示环境可以故意把价格设得很大,例如:
计费项 | 示例价格 | 说明 |
|---|---|---|
Input Token | $1 / token | 便于在测试账单中肉眼核对 |
Output Token | $2 / token | 模拟输出更贵的模型定价结构 |
生产环境当然不会这样定价,真实值更可能是 0.0000015、0.000006 这类小数。这里要注意:price per unit 是单个 token 的价格,不是每千 token,也不是每百万 token。
4. Customer 和 Subscription:没有订阅,用量不会进发票
客户记录里的 key 必须和 CloudEvent 的 subject 对上。示例中是 acme。

创建客户并匹配 subject
之后再给客户创建订阅,把它绑定到刚才的 Pro 计划。

给客户创建订阅
只有订阅窗口开始之后进入的用量,才会进入账单。很多人第一次测试时会遇到“meter 里有数据,invoice 里没有”的情况,本质就是事件发生在订阅生效之前。

客户账单中出现 token 用量
五、最容易翻车的 5 个坑:不是代码难,是账单边界难
坑 | 表现 | 处理方式 |
|---|---|---|
输入输出 token 看起来一样 | 短 prompt 下两个数字可能碰巧相同 | 用更长 prompt 测试,理解 chat message overhead |
Meter 有事件,Invoice 没金额 | 事件早于订阅窗口 | 创建订阅后重新触发 Agent 调用 |
subject 丢失 | 日志提示找不到客户标识 | 检查 metadata 是否从 chain 传到 LLM run |
US/EU endpoint 用错 | 事件写入失败或查不到 | 按 Kong 组织区域选择 API URL |
重试导致重复计费 | 网络重试多写几次事件 | 用 runId + source 做幂等去重 |
这里最关键的不是“能不能把 token 记下来”,而是账单语义要清楚:哪个客户、哪个套餐、哪个周期、哪个价格、哪些事件可重放、哪些事件可去重。
六、上线前别省这张清单:否则你的 Agent 会越火越亏
如果要把这套方案带进生产环境,至少补齐下面几件事。
项目 | 必做要求 |
|---|---|
客户身份 | subject 来自认证系统,而不是 .env |
分模型定价 | 将 model 写入维度,不同模型走不同 rate card |
租户分层 | 把 tenant tier、region、plan 写入 metadata |
用量告警 | 接近额度时通知、限流、暂停订阅或升级套餐 |
失败重试 | ingest() 增加指数退避和最大重试次数 |
流式输出 | 对 streaming response 单独处理 token 汇总 |
审计链路 | 保存 runId、eventId、customer、invoice 的映射 |
也就是说,AI Agent 的商业化不是在网页上加一个“Pro 版”按钮,而是要让每一次模型调用都能被解释、被追踪、被结算。
七、真正的信号:Agent SaaS 的门槛正在从“会调用模型”变成“会运营用量”
今天很多 Agent 产品看起来功能很强,但商业模型仍然很脆弱:不知道每个客户的真实成本,不知道哪些请求亏钱,不知道哪个模型拖垮毛利,也不知道怎么把额度、限流、套餐和账单连起来。
这套 LangChain + CloudEvents + Kong 的方案给出的启发是:
Agent 的工程终点不是回复一次问题,而是把一次智能劳动变成可计量的商业事件。
当 token、模型、客户、订阅、发票全部连在一起,Agent 才真正从 demo 进入 SaaS。
原文链接:https://dev.to/konghq/how-to-monetize-your-ai-agents-with-langchain-and-kong-1fn0
夜雨聆风