每日新闻 / 2026-06-29

控制 LLM 输出长度:5 种方法让模型少说废话,token 账单立竿见影

XycAi
控制 LLM 输出长度:5 种方法让模型少说废话,token 账单立竿见影

生产环境跑了几个月 API,账单拉出来一看,有时候 70% 的 token 花在模型的"自我解释"和"礼貌性总结"上。同一个问题,GPT-5.4 能给你 800 token 的回答,调整提示词之后压到 200 token,信息量基本没损失。控制 LLM 输出长度不是什么高深技巧,但绝大多数人从没系统做过这件事。

方法一:max_tokens 是最硬的边界,但得配合用

很多人以为设了 max_tokens 就万事大吉。实际上这个参数只是截断,不是"精炼"——模型不知道你在 300 token 处要截断它,所以它可能把最重要的结论写在第 350 个 token,被你硬切掉,输出残缺。

正确做法是 max_tokens 配合明确的格式指令,告诉模型答案的结构和体量预期:

response = client.chat.completions.create(
    model="gpt-5.4-mini",
    max_tokens=300,
    messages=[
        {
            "role": "system",
            "content": "你是简洁的技术助手。每次回答不超过3句话,直接给结论,不解释背景。"
        },
        {"role": "user", "content": user_input}
    ]
)

对于 Claude Opus 4.8,同样逻辑,在 Anthropic API 里对应 max_tokens 字段(必填项),建议按场景预设:摘要类 150、问答类 250、代码生成类 600,不要统一设一个大值放任模型跑。

实测对比:一个"解释 Redis 缓存穿透"的问题,不设任何限制时 Claude Sonnet 4.6 输出约 520 token;加上 max_tokens=250 加格式指令后,输出 210 token,核心信息完整保留。

方法二:角色指令里植入"字数人格"

System prompt 是控制输出长度最稳定的杠杆。与其每次在 user message 里说"请简短回答",不如把简洁性直接写进角色定义里,让它成为模型的默认行为模式。

有效的写法不是"请简洁",而是给具体行为约束

你是一个 API 技术文档助手。
规则:
- 回答只包含结论和必要代码,不写"这是因为……"式的解释段落
- 列表项不超过 5 条,每条不超过 15 字
- 不写开头的问题复述,不写结尾的总结句
- 如果问题可以用一句话回答,就只写一句话

"不写开头的问题复述"这一条价值很高。模型有个习惯性动作:在回答前先把你的问题转述一遍("您问的是关于……"),这纯属无效 token,一个高频接口一天下来能多烧几千 token。

Gemini 3 系列在这方面表现相对啰嗦,尤其是 Flash 轻量版;在 system instruction 里加一行 Never restate the user's question 效果立竿见影。

方法三:结构化输出砍掉散文包装

让模型返回 JSON 而不是自然语言,是一种强制压缩的手段。散文回答里大量 token 花在连接词、过渡句、礼貌用语上;JSON 只保留字段和值。

OpenAI API 支持 response_format: { type: "json_object" } 或更精确的 Structured Outputs(传 JSON Schema)。以情感分析场景为例:

自然语言输出(约 85 token):

这段文本整体表达了较为积极的情绪,用户对产品功能表示满意,但对价格有轻微的负面倾向。总体情感倾向为正向。

JSON 输出(约 28 token):

{"sentiment": "positive", "score": 0.72, "price_concern": true}

同等信息量,token 消耗降到原来的 33%。对于批处理场景,这个差距直接体现在账单上。

Claude Code 和 Codex 这类编码 CLI 工具也适用这个思路——让它们输出 diff 格式或纯代码块,而不是"我来帮你修改这段代码,首先……"式的解说文。

方法四:Few-shot 示例校准输出体量

光说"简短"是模糊指令,给样例是精准指令。Few-shot 示例的长度会锚定模型的输出预期——你给的示例答案是 50 字,模型大概率也回 50 字左右。

示例问题:Python 里怎么反转字符串?
示例回答:s[::-1]

示例问题:什么是幂等性?
示例回答:同一操作执行多次与执行一次结果相同,如 HTTP GET、PUT。

现在回答:{user_question}

两个示例总共消耗不到 60 token,但对输出体量的锚定效果非常稳定。这个技巧在 DeepSeek V3 和 Qwen 3 上特别有效——这两个模型对 few-shot 格式遵循度高,几乎不会在给了简短示例后突然输出长篇大论。

需要注意的是 few-shot 示例本身会增加 input token,所以这个方法适合高频、格式固定的场景,一次性问答不值得加。

方法五:后处理截断 + 流式输出提前终止

前四个方法都作用于输入侧,这个方法作用于输出侧。对于延迟敏感的应用,流式输出(streaming)配合提前终止是控制 token 消耗的另一个维度。

import re

stream = client.chat.completions.create(
    model="claude-opus-4-8",  # 通过兼容层调用
    stream=True,
    messages=[...]
)

collected = []
for chunk in stream:
    delta = chunk.choices[0].delta.content or ""
    collected.append(delta)
    full_text = "".join(collected)
    # 检测到结束信号就停止接收
    if re.search(r'[。!?\n]{2}', full_text) and len(full_text) > 100:
        stream.close()
        break

这个方法的核心逻辑:检测到语义完整的停止信号(双换行、句号后换行等)就主动切断流,不等模型把后续的"总结"和"补充说明"写完。对于问答类接口,实测能减少 15%~25% 的 output token。

方法 适用场景 典型降幅 实现复杂度
max_tokens + 格式指令 所有场景 20%~40%
角色指令植入字数人格 固定功能接口 25%~50%
结构化 JSON 输出 数据提取、分类 40%~70%
Few-shot 体量锚定 高频固定格式 20%~45%
流式提前终止 实时对话、问答 15%~25%

五种方法组合使用才是最大化效果的路子。一个实际生产案例:客服问答接口同时启用角色指令 + JSON 输出 + max_tokens=200,月度 output token 消耗从 1.2 亿降到 4800 万,账单直接砍掉 60%,回答质量没有投诉上升。


如果你在多个模型之间做对比测试或者想把这几个参数调优落地,可以试试 XycAi 词元平台。它用一套 OpenAI 兼容 API 接入了 200+ 模型,GPT-5 系列、Claude Opus 4.8、Gemini 3、DeepSeek V3 都在里面,官方模型价格低至官价 1.4 折起,还支持 Claude Code、Codex、Gemini CLI 一键接入——调 max_tokens 做 A/B 对比的时候不用到处倒 key,一个接口搞定,账单也统一看得见。

一个 API 接入 200+ 全球 AI 模型

GPT · Claude · Gemini 官方模型低至 1.4 折起,持大模型算法备案号,CN2 直连低至 5ms,可开全球合规发票。

立即体验 XycAi →