AI Agent Token 成本怎么算:prompt_tokens、completion_tokens、usage、上下文窗口一次讲清楚
AI Agent Token 成本怎么算:prompt_tokens、completion_tokens、usage、上下文窗口一次讲清楚

学 AI Agent,第一个要搞清楚的概念就是 Token。
本文关键词:AI Agent、Token、prompt_tokens、completion_tokens、total_tokens、usage、上下文窗口、RAG 成本。
它直接影响三件事:
- 一次调用花多少钱;
- 上下文窗口到底能放多少内容;
- 多轮对话为什么越聊越贵。
很多人以为大模型按“字数”算,其实模型真正处理的是 Token。
先说结论
Token 可以简单理解成:
模型处理文本时切出来的小片段。
一次调用里,最基本的账分两部分:
- 输入 Token:你发给模型的内容;
- 输出 Token:模型生成的内容。
如果按很多 Chat Completion API 的字段来看,就是:
total_tokens = prompt_tokens + completion_tokens
这里的 prompt_tokens 是输入,completion_tokens 是输出。
一些模型还会返回缓存 Token、推理 Token、图片 Token、工具调用相关 Token。
所以做工程时,不要只记一个总数。
Token 不是字,也不是单词
Token 不等于汉字,也不等于英文单词。
比如英文里:
hello
可能是 1 个 Token。
但一个更长的单词,可能会被拆成几个 Token。
中文也一样。
你好
看起来是 2 个字,但具体是多少 Token,要看模型自己的 tokenizer。
不同模型、不同 tokenizer,结果可能不一样,所以不要靠字数硬猜。
英文里可以粗略按“1 个 Token 约等于 4 个字符”估一下,但中文、代码、JSON、日志都不适合这么粗暴地算。
真正上线时,看 API 返回的 usage。
一次调用里,哪些内容会算 Token?
很多人只盯着用户输入。
其实模型收到的东西通常比用户看到的多,比如:
- system prompt;
- 用户问题;
- 历史对话;
- RAG 检索出来的文档;
- function/tool 的定义和参数;
- 工具返回的结果;
- 模型生成的回答。
你看到用户只问了一句:
帮我看一下这个 NullPointerException 是什么原因
但服务端可能一起带了:
系统提示词:你是一个 Java 故障排查助手
历史对话:最近 5 轮排查过程
异常日志:完整 stack trace
相关代码:Controller、Service、Mapper
知识库片段:公司内部排障手册
工具定义:查询 traceId、查询订单、查询配置
这些都会进入模型上下文。用户只发了一句话,不代表这次调用很便宜。
很多 AI 应用越用越贵,不是用户话多,而是系统每次塞进去的上下文太重。
usage 字段怎么看?
Token 不用自己猜。
接口调用完,看返回里的 usage。
OpenAI、DeepSeek 这类 Chat Completion 风格的接口,常见返回长这样:
{
"usage": {
"prompt_tokens": 820,
"completion_tokens": 260,
"total_tokens": 1080
}
}
这三个字段可以先这么理解:
prompt_tokens:这次请求发给模型的内容;completion_tokens:模型这次生成的内容;total_tokens:两者加起来。
注意,prompt_tokens 不是只算用户那一句话。
system prompt、历史对话、RAG 文档、工具定义,只要这次一起发给模型,通常都会算在里面。
但也别把这三个字段当成所有平台的统一标准。
比如 Claude 文档里常见的是 input_tokens、output_tokens。
DeepSeek 的 Chat Completion 返回里,除了 prompt_tokens、completion_tokens、total_tokens,还可能看到:
prompt_cache_hit_tokens
prompt_cache_miss_tokens
completion_tokens_details.reasoning_tokens
流式返回时,有些平台还需要额外打开 usage 统计,最后才会把用量吐出来。
所以工程里更稳的做法是:
- 展示给人看时,用“输入 Token / 输出 Token / 总 Token”;
- 落日志时,把原始
usage整段也记下来。
这样以后换模型、换平台、接入缓存或推理模型,账还能对得上。
Token 和成本怎么换算?
大部分模型按百万 Token 计费。
基础公式是:
输入成本 = 输入 Token / 1_000_000 * 输入单价
输出成本 = 输出 Token / 1_000_000 * 输出单价
总成本 = 输入成本 + 输出成本
假设输入价格是 1 元 / 百万 Token,输出价格是 2 元 / 百万 Token。
一次调用消耗:
prompt_tokens = 800
completion_tokens = 300
那就是:
输入成本 = 800 / 1_000_000 * 1 = 0.0008 元
输出成本 = 300 / 1_000_000 * 2 = 0.0006 元
总成本 = 0.0014 元(约 0.14 分)
单次看起来很便宜。但如果每天 10 万次调用,就是 140 元/天,一个月就要 4200 元。
还有一个容易漏的点:缓存。
如果平台区分缓存命中和缓存未命中,价格可能不一样。比如有些 API 会把输入拆成:
prompt_cache_hit_tokens
prompt_cache_miss_tokens
这时就不要只拿 prompt_tokens 乘输入单价,要按平台价格表分别算。
上下文窗口也是按 Token 算的
模型说支持 32K、128K、1M 上下文,说的也是 Token,不是字数。
有些新模型已经把上下文窗口拉到很大,比如几十万甚至百万级 Token。但具体上下文和输出上限要以对应平台当前文档为准。
而且上下文窗口通常不是只给输入用。
它看的是:
输入内容 + 模型输出
所以不要把输入塞满。如果一个模型支持 128K,你把输入塞到接近 128K,模型就没有多少空间生成回答了。
实际开发里,一般还要设置输出上限,比如 max_tokens、max_completion_tokens 这类参数。
不同平台参数名不一定一样,但思路一样:给回答留位置。
RAG 和多轮对话为什么更容易贵?
RAG 会把检索出来的文档片段也塞给模型。
多轮对话会把历史消息一起带上。
Agent 还可能多带工具定义、工具调用结果和中间步骤。
举个更贴近 Java 项目的例子:
用户问题:120 Token
系统提示词:600 Token
历史对话:1800 Token
异常日志:2500 Token
相关代码片段:2200 Token
知识库片段 1:1500 Token
知识库片段 2:1600 Token
工具定义:900 Token
模型还没开始回答,输入就已经 11220 Token 了。
如果它再生成 800 Token 的分析结果,这次调用就是 12020 Token 左右。
这就是为什么一个“日志分析助手”看起来只是问答,账单却涨得很快。
工程里怎么控制 Token?
最实用的做法就这几条。
1. 记录 usage
每次调用都记录:
model=deepseek-v4-flash
prompt_tokens=820
completion_tokens=260
total_tokens=1080
prompt_cache_hit_tokens=600
prompt_cache_miss_tokens=220
reasoning_tokens=0
不是每个平台都会返回这些字段。返回什么,就记什么。
没有数据,就没法优化。
2. 控制历史对话
多轮对话不要无限带历史。可以只保留最近几轮,把更早的内容压缩成摘要。
3. 控制 RAG 检索结果
topK 不要一上来就设很大,先从 3 到 5 开始。能回答,就别再多塞文档。
4. 控制工具上下文
Tool Calling 不是免费的。工具定义、参数、工具返回结果,都可能进入上下文。
工具结果太长时,先截断、摘要,再交给模型。
5. 设置阈值
比如单次调用超过 1 万 Token,就打一条日志或告警。不是说 1 万一定不行,而是你要知道它发生了。
最后总结一下
Token 不是字数,它是模型真正处理文本的单位。
记住三句话就够了:
- 成本看 Token,不看字数;
- 上下文窗口也是 Token,不是字符数;
- 生产环境一定要记录
usage,而且输入、输出、缓存、推理要分开看。
把 Token 搞明白,你后面学 RAG、记忆、工具调用、Agent 工作流,都会轻松很多。
后续会继续更新 AI Agent、Spring AI、RAG、Memory、Tool Calling 等内容。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)