AI 入门指南
为什么长 AI 聊天花费更多:API 会重新发送历史记录
AI 聊天中的每条新消息都会再次发送整个历史记录,因此输入每轮都会增长。了解算术和 3 种降低花费的方法。

聊天的最初几条消息很便宜。第五十条消息的花费明显高于第十条,尽管你输入的内容量相同。这并没有出问题:聊天 API 就是这样工作的。
简短回答#
模型不会记住你之前的请求。OpenAI 的文档直接指出:“每次文本生成请求都是独立且无状态的”,对于多轮对话,你需要在下一个请求中包含之前的消息和模型之前的回答。Anthropic 的 Messages API描述了相同的模式:无状态的多轮对话,之前的轮次通过 messages 参数传入。
因此,你在应用中看到的聊天窗口是应用构建的假象。在背后,每条新消息都是一个全新的请求,携带到目前为止的整个对话。你在每次请求中都要为输入 token 付费,而历史记录就是输入的一部分。如果你对术语不熟悉,请先阅读什么是 token和输入 token 与输出 token。
OpenAI 明确说明了其响应链的计费方式:链中所有之前的输入 token 都按输入 token 计费。对于任何由你自己发送历史记录的 API,同样的原则都适用:你发送什么,就计费什么。
一个使用虚构数字的示例#
下面的数字是教学示例,不是实际测量。假设你的每条消息约为 200 token,每个回答约为 300 token。一次完成的交流会给历史记录增加 500 token。
向右滚动表格 →
| 轮次 | 重新发送的早期历史 | 新消息 | 本次请求的输入 | 输出 |
|---|---|---|---|---|
| 1 | 0 | 200 | 200 | 300 |
| 5 | 500 × 4 = 2,000 | 200 | 2,200 | 300 |
| 10 | 500 × 9 = 4,500 | 200 | 4,700 | 300 |
| 20 | 500 × 19 = 9,500 | 200 | 9,700 | 300 |
回答的长度保持不变,但第 20 轮的输入几乎是第 1 轮输入的五十倍。输出不会增长;输入会。
现在来看一个 20 轮聊天的总计。历史记录被重新发送 0、1、2……19 次交流,这是一个简单的求和:
- 重新发送的旧交流:500 × 190 = 95,000 token(190 是 0 + 1 + 2 + ... + 19)。
- 新消息:200 × 20 = 4,000 token。
- 聊天的总输入:95,000 + 4,000 = 99,000 token。
- 总输出:300 × 20 = 6,000 token。
如果模型能免费记住所有内容,输入将只有 200 × 20 = 4,000 token。其余部分是历史记录被重新发送。将轮次翻倍不会使历史记录的成本翻倍,而是大约翻四倍,因为总和随轮次数的平方增长。
按实时价格计算的花费#
以下是同样的 20 轮聊天(99,000 输入,6,000 输出)按当前价格计算的结果。该表格是实时的,会在资费变化时更新;最后一列是 OpenRouter 的参考价格,供比较。
| 模型 | 输入 $/1M | 输出 $/1M | 费用 | OpenRouter |
|---|---|---|---|---|
| GLM-5.3-Flash | $0.02 | $0.04 | $0.0022 | $0.0045 |
| DeepSeek-V4-Flash | $0.015 | $0.10 | $0.0021 | $0.0056 |
| MiniMax-M2.7 | $0.05 | $0.15 | $0.0059 | $0.0369 |
总计 99,000 个输入 token 和 6,000 个输出 token。每 100 万 token 的价格为当前价格,会随我们的资费一同变动;OpenRouter 列显示相同工作负载的参考价格。
用文字快速核对一下:在 MiniMax-M2.7 上,整个对话花费 $0.0059。对于这样输入占主导的聊天,输入价格最为重要:在 MiniMax-M2.7 上,它比 OpenRouter 的参考价格更便宜。每 1M token,MiniMax-M2.7 的输入价格为 $0.05,输出价格为 $0.15。
三种降低花费的方法#
1. 话题变化时开始新聊天#
最便宜的历史记录是空的。如果你刚调试完一个函数,现在想要一个食谱,新聊天发送 200 token 而不是 9,700。在应用中这是一个按钮;在代码中就是 history = []。只要早期上下文对下一个问题不再有帮助,就执行此操作。
2. 裁剪历史记录#
只保留最后几条消息,丢弃其余部分。假设你保留最后三次交流,因此历史记录永远不会超过 500 × 3 = 1,500 token:
- 第 1-3 轮正常增长:0 + 500 + 1,000 = 1,500 token 的历史记录。
- 第 4-20 轮每轮携带上限 1,500:1,500 × 17 = 25,500 token。
- 历史记录总计:1,500 + 25,500 = 27,000 token,加上 4,000 的新消息 = 31,000 token 的输入。
同样的 20 轮,输入是 31,000 而不是 99,000,在 MiniMax-M2.7 上花费为 $0.0025。裁剪的代价是模型会忘记聊天的早期部分,因此请将系统提示和任何不能丢失的事实保留在裁剪部分之外。
3. 用摘要替换旧轮次#
当历史记录变长时,让模型总结一次,然后用摘要代替全文继续。在上面的示例中,九次交流是 4,500 token;一个约 300 token 的摘要可以传递要点。你为编写摘要支付一次额外请求的费用,之后每次请求都更轻量。这比简单裁剪保留了更多含义,代价是损失一些细节。
上下文窗口是一个单独的限制:它限制一次请求可以容纳多少 token,包括回答。历史记录最终会触及这个上限;为什么 AI 的回答会在句子中间停止?对此进行了解释。
在你自己的代码中观察#
响应中包含一个 usage 对象,因此你可以自己观察增长情况。这是一个示例:替换密钥并从 CheapTokens 文档中获取模型 id,因为不同提供商的 id 不同。
from openai import OpenAI
client = OpenAI(base_url='https://api.cheaptokens.dev/v1', api_key='YOUR_KEY')
system = {'role': 'system', 'content': 'You are a helpful assistant.'}
history = []
KEEP = 7 # new message + last 3 exchanges (6 messages); None keeps everything
def ask(text):
history.append({'role': 'user', 'content': text})
r = client.chat.completions.create(
model='MODEL_ID_FROM_DOCS',
messages=[system] + (history[-KEEP:] if KEEP else history),
)
answer = r.choices[0].message.content
history.append({'role': 'assistant', 'content': answer})
print(r.usage.prompt_tokens, r.usage.completion_tokens)
return answer连续调用 ask() 几次并打印 prompt_tokens:使用 KEEP = None 时它每轮都会攀升,使用 KEEP = 7 时它会趋于平稳。对于循环执行许多步骤的智能体,同样的效应适用于每一步;如何估算 AI 智能体的成本展示了如何为此做预算。
在哪里运行长聊天#
长对话和智能体循环正是输入量占主导的工作负载,因此大上下文窗口和长回答的空间都很重要:
- MiniMax-M2.7:180K 上下文,每个回答最多 8,192 token,输入和输出都比 OpenRouter 的参考价格便宜。
- DeepSeek-V4-Flash:380K 上下文,每个回答最多 32,768 token,输出比 OpenRouter 的参考价格便宜。
CheapTokens 为所有模型提供一个余额,每个模型固定价格且没有高峰时段,并且 API 兼容 OpenAI Chat Completions 和 Anthropic Messages,因此上面的代码只需更改基础 URL 即可工作。按照使用 CheapTokens 的第一个 API 请求充值余额并发送你的第一个请求。



