AI 入门指南
为什么 AI 答案会在句子中间停止?max_tokens、上下文窗口和 finish_reason 详解
在句子中间停止的 AI 答案触发了限制。读取 finish_reason,区分 max_tokens 与上下文窗口已满,并检查每个模型的输出限制。

本页内容
回复在句子中间戛然而止,几乎总是被某个限制截断了。模型并没有丢失思路;是请求没有足够的空间了。响应会说明是哪个限制:读取 finish_reason。length 表示触发了限制。stop 表示模型自行结束。
有三件事决定答案能有多长。一旦你知道是哪一个限制卡住了你,修复只需一分钟。
截断答案的三个限制#
max_tokens是你在请求中设置的上限。当答案达到该上限时,生成就会停止,即使停在单词中间。DeepSeek 的 API 参考将其定义为补全中生成的最大 token 数。- 模型的输出限制 是该模型单次答案的上限。它属于模型本身,因此请将
max_tokens保持在该值或以下。我们各模型的数值见下表。 - 上下文窗口 是整个交互的空间:你的输入和答案加在一起。DeepSeek 的参考说明,输入和生成的 token 合计受模型上下文长度限制。
如果 token 对你来说还是个模糊概念,请先阅读 What is a token in AI?。本页假设你知道它是什么。
先读 finish_reason#
聊天响应中的每个 choice 都带有一个 finish_reason。紧挨着它,usage 告诉你输入和输出了多少 token。
下面是一个被截断的答案与一个已完成答案的对比。请求问的是“用一句简短的话说明什么是 token?”,第一次将 max_tokens 设为 16,然后设为 200。
示例仅作说明,并非真实记录的响应:你的计数和额外字段会有所不同。
{
"choices": [
{
"message": { "role": "assistant", "content": "A token is a small piece of text that a model reads and writes, usu" },
"finish_reason": "length"
}
],
"usage": { "prompt_tokens": 21, "completion_tokens": 16, "total_tokens": 37 }
}{
"choices": [
{
"message": { "role": "assistant", "content": "A token is a small piece of text that a model reads and writes, usually a word or part of a word." },
"finish_reason": "stop"
}
],
"usage": { "prompt_tokens": 21, "completion_tokens": 24, "total_tokens": 45 }
}在第一个响应中,completion_ 为 16,正好等于上限,文本以“usu”结尾。在第二个响应中,模型在 24 个 token 处停止,远低于 200 的上限,因为它已经完成了。
要弄清发生了什么,请按顺序执行以下步骤:
- 查看
finish_reason。 如果是stop,答案就是完整的。模型选择结束,或触发了你设置的停止序列。如果是length,则答案被某个限制截断,下一步会告诉你具体是哪一个。还存在其他值,例如content_filter和tool_calls;两者都不是长度问题。 - 将
completion_与你发送的tokens max_tokens进行比较。 如果它们相等或几乎相等,说明你触发了max_tokens。 - 如果
completion_远低于tokens max_tokens且prompt_tokens很大, 则很可能是上下文窗口已满。DeepSeek 的参考对两种情况都使用length,因此仅凭该字段无法区分它们;第 2 步中的比较就是区分方法。Anthropic 和 Z.ai 的文档将第二种情况单独命名为model_。查看你自己响应中的该字段,看看你得到的是哪个名称。context_ window_ exceeded
以上三种描述均来自开发者文档,核查于 2026 年 10 月 20 日:DeepSeek、Anthropic 和 Z.ai。
向右滚动表格 →
| 你看到的情况 | finish_reason |
原因 | 该怎么办 |
|---|---|---|---|
被截断,completion_ 等于 max_tokens |
length |
达到了 max_tokens |
提高 max_tokens,或要求分部分给出答案 |
被截断,completion_ 远低于 max_tokens,输入很长 |
length(某些 API 中为 model_) |
上下文窗口已满 | 缩短输入或历史记录,或选择窗口更大的模型 |
| 完整但比你期望的短 | stop |
模型已完成,或触发了停止序列 | 要求更多细节;检查 stop 参数 |
| 没有文本,或被拒绝 | content_filter |
响应被过滤 | 改写请求 |
| 没有文本,而是工具请求 | tool_calls |
模型想要调用工具 | 运行工具并将结果发回 |
修复 1:提高 max_tokens#
最常见的原因也是最容易修复的。自己设置 max_tokens,这样你就知道适用的是哪个上限。不要依赖默认值。
from openai import OpenAI
client = OpenAI(base_url="https://api.cheaptokens.dev/v1", api_key="YOUR_API_KEY")
resp = client.chat.completions.create(
model="deepseek-ai/DeepSeek-V4-Flash-0731",
messages=[{"role": "user", "content": "Write a detailed guide to setting up a home network."}],
max_tokens=16000, # example value: stay at or below the model's output limit
)
choice = resp.choices[0]
print(choice.finish_reason, resp.usage.completion_tokens)这展示了调用的形式。这里的密钥以 YOUR_API_KEY 形式传入;不要把真实密钥留在你分享的代码中。
提高数值只在模型自身限制以内才有帮助。以下是 CheapTokens 上的限制,核查于 2026 年 10 月 20 日,对照 CheapTokens 模型列表:
向右滚动表格 →
| 模型 | 模型 ID | 每次答案的最大输出 | 上下文 |
|---|---|---|---|
| DeepSeek-V4-Flash (0731) | deepseek- |
32,768 tokens | 380K |
| GLM-5.3-Flash | zai- |
8,192 tokens | 390K |
| MiniMax-M2.7 | MiniMaxAI/ |
8,192 tokens | 200K |
开发者会为自己的 API 发布各自的限制。例如,Z.ai 列出 GLM-5 系列最高支持 128K 输出。这些不是 GLM-5.3-Flash 在 CheapTokens 上的限制,后者每次答案为 8,192 tokens。对于你在 CheapTokens 上构建的任何东西,请使用上表。
修复 2:上下文窗口已满时#
在聊天中,每条消息都会重新发送整个历史记录,因此输入每轮都会增长。上下文窗口必须容纳该历史记录加上新答案。如果仅历史记录就几乎占满整个窗口,那么留给回复的空间就所剩无几。
这些窗口很大,一个简短的问题不会填满它们。长聊天和粘贴的文档会。有帮助的做法:
- 为新任务开启新聊天,而不是继续旧聊天。
- 让模型总结到目前为止的对话,只把摘要带下去。
- 删除不再需要的旧消息和附件。
- 如果输入本身很大,选择窗口最大的模型。在我们的模型中,GLM-5.3-Flash 以 390K 居首。它的输出限制是 8,192 tokens,因此请分部分要求长结果。
修复 3:分部分获取长答案#
当你想要的答案超过模型的输出限制时,任何设置都无法将其塞进一次回复。请分块要求:当 finish_reason 为 length 时,将部分答案发回,并让模型继续。
messages = [{"role": "user", "content": "Write a detailed guide to setting up a home network."}]
parts = []
for _ in range(4): # example limit: at most 4 rounds
resp = client.chat.completions.create(
model="zai-org/GLM-5.3-Flash",
messages=messages,
max_tokens=8000, # example value: below this model's output limit
)
choice = resp.choices[0]
parts.append(choice.message.content)
if choice.finish_reason != "length":
break
messages.append({"role": "assistant", "content": choice.message.content})
messages.append({"role": "user", "content": "Continue exactly where you stopped. Don't repeat anything."})
text = "".join(parts)同样的提醒:这是该模式的示例,并非真实记录的运行。注意各部分之间的衔接处。模型有时会在连接处重复一句话或重新开始一个列表。
每一轮都会将到目前为止的所有内容作为输入重新发送,并且每个输出 token 都会计费。长答案比短答案花费更多。下面是一个 8,000 token 的答案,输入为 2,000 token,这适用于表中的每个模型:
| 模型 | 输入 $/1M | 输出 $/1M | 费用 | OpenRouter |
|---|---|---|---|---|
| GLM-5.3-Flash | $0.02 | $0.04 | $0.00036 | $0.00069 |
| DeepSeek-V4-Flash | $0.015 | $0.10 | $0.00083 | $0.0013 |
| MiniMax-M2.7 | $0.05 | $0.15 | $0.0013 | $0.0102 |
总计 2,000 个输入 token 和 8,000 个输出 token。每 100 万 token 的价格为当前价格,会随我们的资费一同变动;OpenRouter 列显示相同工作负载的参考价格。
当 finish_reason 为 stop 时#
stop 表示模型结束了答案。如果它比你期望的更早结束,那不是限制问题,更大的 max_tokens 也不会有任何改变。说明你想要什么:长度、章节、详细程度。还要检查请求是否设置了 stop 参数;出现在答案中的停止序列会立即结束它。
按答案长度选择模型#
从你需要的答案出发。如果它适合 8,192 tokens,MiniMax-M2.7(MiniMaxAI/)可以在 CheapTokens 上处理。它的输出比 OpenRouter 参考价格更便宜,计费为 $0.15(每 1M 输出 tokens)。价格在任何时段都相同,没有高峰时段,并且 API 兼容 OpenAI 和 Anthropic。
以下是每个模型的当前价格列表:
| 模型 | 上下文 | 输入 $/1M | 输出 $/1M | OpenRouter 输入 | OpenRouter 输出 |
|---|---|---|---|---|---|
| GLM-5.3-Flash reasoning | 390K | $0.02 | $0.04 | $0.0413 | $0.0758 |
| DeepSeek-V4-Flash | 380K | $0.015 | $0.10 | $0.0475 | $0.1568 |
| MiniMax-M2.7 | 180K | $0.05 | $0.15 | $0.30 | $1.20 |
价格以每 100 万 token 的美元金额计算。OpenRouter 数据仅供参考,可能会有变动。
如果你还没有发送过请求,Your first API request with CheapTokens 会带你走一遍。关于什么是 token 以及为什么输入和输出分开计数,请参阅 What is a token in AI?。
每个模型的端点、模型 ID 和限制都在 CheapTokens docs 中。



