上下文与成本控制
控制长对话历史,避免输入 Token 持续增长并意外消耗大量积分。
Chat Completions 是无状态的。除非你的应用在下一次请求的 messages 中再次发送历史内容,否则 GLM 5 不会自动记住上一轮 API 调用。
因此,上下文管理由应用负责,也是长对话和智能体工作流里最重要的成本控制手段之一。
重复历史如何计费
假设每一轮都把之前的完整对话重新发送:
| 调用 | 本次发送的消息 | 计费输入 Token |
|---|---|---|
| 1 | 当前用户消息 | 1,000 |
| 2 | 第 1 轮历史 + 当前消息 | 3,000 |
| 3 | 第 1–2 轮历史 + 当前消息 | 7,000 |
| 20 | 完整累计历史 | 80,000 |
模型每次都会重新处理本次请求里包含的所有 Token,因此较早的消息可能被重复计费很多次。
不要无限追加历史消息
长时间运行的客户端很容易从几万输入 Token 增长到几十万。持续监控 usage.prompt_tokens,限制历史长度,在下一次请求前摘要或删除较老的对话。
推荐策略
设置输入 Token 预算
在请求发出前为应用设定最大输入预算。接近预算时:
- 保留 system 消息。
- 保留最新用户请求。
- 保留完整的 assistant tool call 与 tool result 配对。
- 优先保留最近且仍有用的对话。
- 摘要或删除更早的历史。
只限制“消息条数”并不可靠,因为不同消息长度可能相差很大。
摘要旧对话
可以把较早的上下文压缩成一条简洁摘要:
[
{
"role": "system",
"content": "你是一名技术助手。对话摘要:用户正在 Cloudflare 上部署 Next.js API,需要零停机发布,目前还未配置回滚告警。"
},
{
"role": "user",
"content": "现在生成最终部署检查清单。"
}
]
摘要会丢失部分细节,因此最近消息和重要标识符仍建议保留原文。
开启新会话
如果旧上下文已经不再相关,就只发送当前 system 和 user 消息。这通常更便宜,也能减少旧信息对模型的干扰。
控制输出预占
请求发往模型前,GLM 5 会根据输入估算和最大输出参数预占积分。如果没有提供 max_completion_tokens 或 max_tokens,计费预占会使用内部 8,192 Token 估算值。
这个内部估算值不会改变模型的默认输出上限。对于明显只需要短答案的任务,可以显式设置更小的输出上限:
{
"model": "glm-5.3",
"messages": [
{
"role": "user",
"content": "只返回五项检查清单。"
}
],
"max_completion_tokens": 600
}
请求完成后会按本次请求最终记录的实际用量结算,多预占的积分会返还。但预设的最大输出过大时,低余额请求仍可能在发送模型前因为无法覆盖预占而失败。
模型上下文限制
GLM 5 不为所有模型维护一套统一的 Token 上下文窗口。不同模型的上下文与输出限制可能不同。
如果收到 context_length_exceeded,请缩短或摘要历史、减少工具定义,或降低最大输出。
监控实际用量
非流式响应会返回:
{
"usage": {
"prompt_tokens": 42215,
"completion_tokens": 186,
"total_tokens": 42401
}
}
常见防护措施包括:
- 在应用上下文预算的 50%、75%、90% 设置提醒。
- 记录每次请求的输入和输出 Token。
- 为用户或工作流设置消费上限。
- 连续请求输入量持续增长时触发告警。
- 遇到额度或参数错误时停止自动重试循环。
Context Caching 不是上下文上限
部分模型或 API 系统能够复用与上一请求完全相同的 Prompt 前缀,这通常称为 Prompt Caching 或 Context Caching。
缓存可能改善延迟或成本效率,但它不会:
- 自动从请求中删除旧消息。
- 阻止上下文窗口继续增长。
- 保证每次请求都命中缓存。
- 让重复 Token 永久免费。
当前 GLM 5 行为
GLM 5 当前返回 prompt_tokens、completion_tokens 和 total_tokens,不会对外暴露 cached_tokens,也不会因为缓存命中自动改变 GLM 5 积分结算。应用仍应主动管理历史并设置 Token 预算。
请求体大小限制
JSON 请求体最大为 4 MB。这是传输和内存保护限制,不等同于模型 Token 上下文窗口。小于 4 MB 的请求如果超过所选模型的上下文限制,仍可能返回错误。