Token 预算设计是什么
上下文窗口是上限而不是目标,合理做法是把窗口拆成几块预算来管理:固定提示、检索资料、历史对话、输出预留、工具回包预留,各占一块并按预算裁剪,而不是「塞满再说」。以八千 token 窗口为例,系统提示与工具定义约一千、检索资料四千、历史一千、输出预留一千五、工具回包预留五百。超限时按优先级裁剪:先截检索资料,再压缩历史,最后才动输出额度,因为输出不足会直接导致任务失败。
预算分配示例
| 用途 | 预算 | 策略 |
|---|---|---|
| system 与工具定义 | 1.0K | 固定不变,对缓存友好 |
| 检索资料 | 4.0K | 按相关性截断,宁缺毋滥 |
| 历史对话 | 1.0K | 最近若干轮加摘要 |
| 输出预留 | 1.5K | 对应输出上限设置 |
| 工具回包预留 | 0.5K | 或折叠为大摘要 |
基本信息
| 拆块方式 | 固定提示、检索、历史、输出、工具回包 |
|---|---|
| 裁剪优先级 | 先截检索,再压历史,最后动输出 |
| 工具类任务 | 必须预留回包空间,否则第二轮直接爆窗 |
| 对应关系 | 输出预留即上限设置,两者保持一致 |
| 监控指标 | 实际输入 token 分布与预算的偏差 |
| 超限信号 | 请求被拒或报窗口超出错误 |
典型使用场景
- 多轮对话系统:给历史分配固定额度并配滚动摘要
- 工具调用型 Agent:为工具回包预留空间,避免第二个回合超限
- RAG 问答:为检索片段设定上限,控制成本与噪声
- 长文档处理:把整篇材料改为检索注入,压出预算空间
- 成本测算:按预算推算单次调用成本上限
预算校验逻辑
预算校验逻辑
budget = {"sys": 1000, "rag": 4000, "hist": 1000, "out": 1500, "tool": 500}
total = sum(budget.values()) # 8000,等于窗口上限
assert total <= model_ctx, "预算超窗"
# 实际拼装时逐块检查:超限按优先级裁剪
# 1) 截断检索资料(按相关度从后往前砍)
# 2) 压缩历史对话为摘要
# 3) 最后才下调输出预留,并同步调小上限设置
# 每次裁剪都记录日志,便于分析是不是检索给得太多工具调用型任务必须预留回包空间:工具返回的大段 JSON 会占输入额度,不预留时往往第二个回合就超出窗口。
预算要写成配置而不是散落在代码里:不同模型窗口不同,配置化之后换模型只需改数值,不必再改拼装逻辑。