在做 AI 系统设计时,经常会遇到这样一个现实问题:
原本一个完整任务预计需要消耗 100k Token,但公司最终只批准了 60k 的预算,该怎么办?
很多人的第一反应可能是:
换一个便宜一点的模型。
但如果让我来处理,我不会先从模型下手。
因为在一个真正的 AI 应用系统中,Token 消耗往往并不等于“模型真正用于思考的 Token”。
大量 Token 实际消耗在了:
- 历史上下文重复传递
- RAG 检索结果过多
- Agent 之间重复复制信息
- 不必要的模型调用
- 过度规划
- 冗长的中间输出
所以真正应该做的第一件事,是把这 100k Token 拆开看看究竟花在了什么地方。
一、先搞清楚:100k Token 到底花在哪里
假设现在一个任务的 Token 消耗大致如下:
历史上下文 20k
RAG 内容 30k
多 Agent 中间结果 25k
核心推理 15k
最终输出 10k
------------------------
总计 100k
单看这个数据其实就能发现一个问题:
真正用于核心推理的只有 15k。
剩下的大部分 Token 都是在给模型“喂信息”。
所以,如果公司要求把 100k 压缩到 60k,我们真正应该砍掉的并不是模型的思考能力,而是其中大量的重复信息和低价值信息。
这也是 Token 优化最重要的原则:
减少信息浪费,而不是简单降低模型能力。
二、第一优先级:砍掉无效上下文
很多 AI 系统最浪费 Token 的地方,其实不是输出,而是输入。
尤其是做 RAG、Agent、多轮对话之后,一个模型调用可能携带:
System Prompt
+
历史对话
+
用户问题
+
RAG 检索内容
+
工具调用结果
+
其他 Agent 输出
+
任务规划信息
如果系统没有专门做上下文管理,很容易出现一种情况:
模型每执行一步,都拖着整个历史上下文一起跑。
这其实非常浪费。
1. 历史对话压缩
历史对话没有必要无限保留。
例如一个已经进行了 30 轮的会话,真正对当前问题有价值的,可能只有:
- 最近几轮对话
- 用户长期约束
- 前面任务产生的重要结论
因此可以采用:
早期历史
↓
生成摘要
↓
摘要 + 最近 N 轮完整对话
例如原本:
历史上下文:20k
经过压缩之后:
历史摘要:3k
最近对话:5k
--------------
总计:8k
直接减少一半以上。
2. 控制 RAG 上下文
另一个 Token 消耗大户就是 RAG。
很多系统为了“不漏信息”,喜欢一次返回:
Top 20
Top 30
甚至 Top 50
然后全部塞给模型。
但召回数量增加,并不意味着答案质量一定会提高。
相反,大量低相关内容可能产生:
- Token 浪费
- 上下文噪声
- 模型注意力分散
- 错误信息干扰
更加合理的做法通常是:
粗召回 Top20
↓
Rerank
↓
Top5 / Top8
↓
模型
即:
召回可以多,但真正进入模型上下文的信息应该少。
大文档也是一样。
不要:
整份文档 → 模型
而应该:
相关片段 + 文档引用
需要更多信息时再继续读取。
3. 压缩工具调用结果
Agent 系统还有一个经常被忽略的问题:
Tool Result 非常容易膨胀。
比如调用一个 API 返回:
{
"id": "...",
"name": "...",
"created_at": "...",
"updated_at": "...",
"status": "...",
"metadata": {...},
"history": [...],
"result": {...},
"debug": {...}
}
但模型真正需要的可能只有:
{
"status": "success",
"result": {...}
}
因此工具返回最好增加一层:
Tool
↓
Result Processor
↓
提取模型真正需要的信息
↓
LLM
而不是无脑把 API 原始 JSON 全部塞给模型。
三、第二优先级:减少重复模型调用
另一个常见问题,是 AI 系统很容易出现“LLM 万能化”。
一个请求进来之后:
意图识别
↓
Query Rewrite
↓
任务分类
↓
Planner
↓
检索判断
↓
工具调用
↓
Reviewer
↓
最终回答
每一步都是一次模型调用。
从架构图上看确实很漂亮。
但生产环境跑起来以后,很快就会发现:
Token 和延迟一起爆炸。
因为并不是每一个问题都需要完整链路。
例如用户问:
新疆银行客服电话是多少?
这种问题根本不需要:
Planner
Multi-Agent
Reviewer
直接:
FAQ / RAG
↓
回答
就够了。
所以更加合理的架构应该是:
用户请求
↓
复杂度判断
↓
┌───────────────┐
简单任务 复杂任务
↓ ↓
直接执行 Planner
也就是:
从“所有请求走完整流程”,变成“按照任务复杂度分流”。
四、能不用大模型的地方,就不要用大模型
还有一些模型调用其实可以直接合并。
例如:
Intent Classification
↓
Query Rewrite
完全可以让一个模型一次返回:
{
"intent": "policy_query",
"rewritten_query": "新疆银行个人贷款提前还款政策"
}
而不是调用两次模型。
另外,一些确定性非常强的逻辑甚至不需要模型。
例如:
金额 > 100 万 → 人工复核
评分 > 70 → 高风险
文件大小 > 20MB → 拒绝上传
这种东西直接写规则即可。
不要:
if amount > 1000000
五行代码能解决的事情,却专门调一次 72B 模型问:
请判断这个金额是否超过 100 万。
LLM 应该解决的是不确定性问题,而不是替代所有传统代码逻辑。
五、第三优先级:模型分层
即使确定需要模型,也没有必要每一步都使用最强模型。
比如整个 Agent 系统可以按照任务复杂度进行模型分层:
任务 模型
分类 / 路由 / 提取 小模型
摘要 / Query Rewrite 中小模型
复杂推理 大模型
高风险审核 大模型
例如一个完整流程可能变成:
用户问题
↓
小模型:Intent
↓
小模型:Query Rewrite
↓
RAG
↓
大模型:核心推理
↓
必要时 Reviewer
相比于所有步骤全部调用大模型:
大模型
↓
大模型
↓
大模型
↓
大模型
这种方式不仅节约模型调用成本,同时也会显著降低整体延迟。
所以模型分层解决的不仅是:
多少钱的问题。
同时也是:
吞吐量和响应速度的问题。
六、第四优先级:限制 Multi-Agent 扩散
Multi-Agent 是我认为最容易导致 Token 预算失控的地方之一。
原因很简单。
每增加一个 Agent,可能意味着增加:
一份 System Prompt
+
一份 Context
+
一次模型推理
+
一份中间结果
如果多个 Agent 再互相通信:
Agent A → Agent B
Agent B → Agent C
Agent C → Agent A
Token 消耗很容易呈爆炸式增长。
所以生产环境中的 Multi-Agent 必须存在非常明确的资源约束。
例如:
max_agents: 3
max_plan_depth: 2
max_llm_calls: 8
max_tokens: 60000
Planner 在进行任务拆解之前,就应该知道:
我只有 60k Token 可以使用。
而不是先规划:
调用 8 个 Agent
每个 Agent 做 4 个子任务
最后再让 3 个 Reviewer 交叉验证
等执行到一半以后系统才发现:
Token Budget Exceeded
真正合理的 Planner 应该是:
任务复杂度
+
资源预算
+
时间限制
+
模型能力
↓
生成执行计划
这其实已经不只是“任务规划”了。
而是:
Resource-Aware Planning,资源感知型任务规划。
七、Agent 之间不要传作文
Multi-Agent 还有一个很隐蔽的浪费来源:
中间结果全部使用自然语言。
比如 Agent A 输出:
根据目前收集的信息进行综合分析,可以发现该客户存在较明显的风险……
洋洋洒洒 2000 字。
然后 Agent B 再读这 2000 字。
Agent C 再读一次。
最后 Reviewer 又读一次。
相当于同一份 Token 被消费了很多遍。
Agent 内部通信其实更适合使用结构化结果。
例如:
{
"risk_level": "high",
"reason_codes": [
"R12",
"R27"
],
"evidence_refs": [
"doc_12",
"doc_19"
]
}
后面的 Agent 如果需要详细信息,可以根据:
evidence_refs
再去读取。
因此内部 Agent 最理想的信息传递方式应该是:
结构化数据
+
Artifact
+
Reference
而不是:
自然语言小作文
自然语言应该尽量留到整个任务的最后一步:
真正面向用户的时候再生成。
八、第五优先级:缓存
当上下文和模型调用基本优化完之后,还有一个非常值得做的能力:
缓存。
企业 AI 场景有一个明显特点:
大量问题其实是重复的。
例如:
公积金贷款需要什么材料?
和:
办理公积金贷款要准备哪些资料?
从字符串角度来看并不一样。
但从语义角度来看,其实几乎是同一个问题。
因此缓存可以分成三层。
精确缓存
完全相同的请求:
Hash(Query)
↓
Cache
命中后直接返回。
Semantic Cache
对于语义高度类似的问题:
Query
↓
Embedding
↓
Vector Search
↓
Similarity > Threshold
↓
复用历史结果
例如:
公积金贷款需要什么材料?
和:
办理公积金贷款需要准备哪些资料?
就可能直接复用答案。
中间结果缓存
这一层在 Agent 系统里尤其重要。
可以缓存:
RAG 检索结果
SQL 查询结果
政策摘要
文档解析结果
Embedding
OCR
工具调用结果
很多数据完全没有必要每一个任务都重新计算。
九、100k Token 是怎么被压到 54k 的
回到最开始的例子。
原始消耗:
历史上下文 20k
RAG 内容 30k
多 Agent 中间结果 25k
核心推理 15k
最终输出 10k
------------------------
总计 100k
经过优化以后:
摘要后历史 8k
Rerank 后 RAG 15k
结构化 Agent 结果 8k
核心推理 15k
最终输出 8k
------------------------
总计 54k
从:
100k
降低到了:
54k
减少了接近一半。
但有意思的是:
核心推理:15k → 15k
我们几乎没有压缩模型真正用于解决问题的资源。
真正被砍掉的是:
重复上下文
低相关检索
冗余 Agent 输出
无效信息
所以 Token 优化真正追求的目标应该是:
信息密度最大化,而不是单纯 Token 最小化。
十、把 Token 当成 CPU 和内存一样管理
如果继续往架构层面思考,我认为 Token 不应该只是:
LLM API Usage
它其实应该成为一种正式的系统资源。
和:
CPU
Memory
GPU
Connection Pool
Thread Pool
一样。
因此整个 AI Runtime 可以增加一个:
Budget Manager
例如:
用户任务
↓
Budget Manager
↓
分配 60k Token
↓
Planner
↓
┌───────────┼───────────┐
↓ ↓ ↓
Context Budget RAG Budget Agent Budget
↓
Reasoning Budget
↓
Output Budget
假设一个任务总预算只有:
60k
可以提前分配:
Context ≤ 15k
RAG ≤ 15k
Agent ≤ 15k
Reasoning ≤ 10k
Output ≤ 5k
------------------
Total ≤ 60k
这样每一个模块在运行的时候,都知道自己的预算。
十一、超预算以后怎么办?
预算管理真正困难的地方,其实不是:
设定 max_tokens
而是:
超预算以后系统应该如何降级?
例如 Context 超预算:
Context > 15k
可以:
删除低价值历史
↓
压缩 Tool Result
↓
历史摘要
↓
再次计算 Token
RAG 超预算:
Top10
↓
Top8
↓
Top5
Agent Budget 超预算:
减少 Agent 数量
↓
降低 Planner Depth
↓
取消非必要 Reviewer
整体预算即将耗尽:
Budget Remaining < Threshold
则可以:
停止继续规划
↓
使用已有信息生成答案
所以真正成熟的 Token Budget 系统应该包含两部分:
Budget Allocation
+
Budget Degradation
即:
预算分配 + 超预算降级策略。
十二、Token Budget 本质上也是 Agent Runtime 的一部分
如果继续沿着这个思路往下推,会发现 Token Budget 并不是一个孤立功能。
它应该属于 Agent Runtime 的资源治理能力。
一个完整的 Agent Runtime 可能需要统一管理:
Token Budget
Model Calls
Agent Count
Execution Time
Concurrency
Tool Calls
GPU Resources
External API Cost
于是 Planner 不再只是:
这个问题应该怎么解决?
而需要同时思考:
在当前资源限制下,这个问题应该怎么解决?
这两个问题之间其实有非常大的区别。
前者容易生成一个理论上最强的方案:
10 个 Agent
+
20 次模型调用
+
多轮交叉验证
后者则会根据现实条件做取舍:
当前只有 60k Token
→ 2 个 Agent
→ 6 次调用
→ 保留核心验证
→ 取消低价值步骤
这才是真正可以落地到生产环境里的 Agent 系统。
最后
如果让我按照工程优先级优化 Token 消耗,我大概会按照这个顺序:
1. 砍无效上下文
↓
2. 减少重复模型调用
↓
3. 模型分层
↓
4. 限制 Multi-Agent 扩散
↓
5. 缓存
↓
6. 更细粒度优化
原因也很简单:
前几项解决的都是架构级浪费。
如果一个系统现在一个请求需要 100k Token,却直接开始研究:
这个 Prompt 能不能少写 200 个 Token?
其实意义并不大。
真正值得优化的是:
为什么同样的信息传了三遍?
为什么 Top20 的 RAG 全塞进去了?
为什么一个简单问题需要跑 Planner?
为什么三个 Agent 每个人都写了一份 2000 字报告?
为什么规则可以解决的问题也要调用大模型?
把这些问题解决以后,再去优化 Prompt、输出长度、模型量化,才真正有价值。
归根到底:
Token 不应该是模型想吃多少就吃多少,而应该由系统提前分配。
未来真正成熟的 Agent Runtime,一定不会只管理 Agent 怎么执行任务。
它还需要管理:
这个任务,到底值得花多少资源。
