1. AI 产品里,前端怎么降低 Token 消耗?
核心回答
前端降低 Token 成本,核心就是少给模型传无效上下文。
面试时先说这一句就够了。
面试官继续追问:具体怎么做?
可以从几个方向展开:
第一,控制上下文长度
不要每次请求都把完整聊天历史原样发送:
text
用户 A
助手 B
用户 C
助手 D
...
用户 X
而是根据当前问题,只保留真正相关的信息。
常见做法:
- 裁剪过长历史消息
- 对较早的对话做摘要
- 只保留最近 N 轮
- 根据相关性检索历史内容
- 用户切换会话时按需加载历史
例如:
text
完整历史 → 20,000 tokens
↓
保留最近对话
+
历史摘要
+
当前相关上下文
↓
最终请求 → 5,000 tokens
第二,减少不必要的数据传输
尤其是 AI 产品经常涉及:
- 图片
- 文件
- 网页内容
- Markdown
- 代码
- 日志
不能什么东西都原样塞给模型。
例如用户上传一张大图片,可以在进入模型之前:
text
原图
↓
判断尺寸
↓
必要时缩放
↓
压缩
↓
生成缩略图 / 提取必要信息
↓
再发送
对于文件、日志、网页内容,也可以先做:
text
原始内容
↓
去掉无关内容
↓
提取必要部分
↓
截断 / 摘要
↓
发送给模型
这里要注意一个关键点:
Token 成本最终取决于发送给模型的内容,而不是单纯取决于前端网络请求有多大。
所以"压缩 HTTP 请求体"不等于一定能降低 Token 成本。
2. 前端做历史消息裁剪,具体怎么设计?
核心回答
不要简单地按字符数截断,而应该按照 Token 数量和消息重要性控制上下文。
例如模型上下文预算是:
text
总预算:8000 tokens
系统指令:1000
历史消息:4000
当前问题:1000
预留输出:2000
那么历史消息最多只能使用:
text
8000 - 1000 - 1000 - 2000
= 4000 tokens
前端或者 BFF 就可以根据预算裁剪历史。 一个比较常见的策略:
text
System Prompt
↓
历史摘要
↓
最近几轮对话
↓
当前问题
↓
预留输出空间
而不是:
text
把全部聊天记录全部发送
3. 为什么"历史摘要"比单纯裁剪更好?
核心回答
单纯裁剪可能会丢失关键信息,摘要是用更少的 Token 保留历史里的关键事实。
例如之前有 20 轮对话:
text
第 1~15 轮
用户提出需求
助手讨论方案
最终确定:
React + TypeScript
后端使用 Node.js
接口采用 SSE
如果直接裁掉:
text
第 1~15 轮 ❌
模型可能不知道之前已经确定了什么。
可以变成:
text
历史摘要:
- 技术栈:React + TypeScript
- 后端:Node.js
- AI 输出:SSE 流式返回
- 当前正在解决:Token 成本优化
这样就能用更少的 Token 保留关键上下文。
4. 流式渲染能降低 Token 成本吗?
核心回答
流式渲染主要解决的是响应速度和用户体验,本身不会减少模型生成的 Token 数量。
比如模型最终生成:
text
1000 tokens
采用:
text
普通请求 → 一次性返回 1000 tokens
还是:
text
SSE → 分几十次返回这 1000 tokens
模型生成的 Token 还是 1000。
所以:
text
流式渲染
↓
降低首字延迟
提升交互体验
而:
text
上下文裁剪 / 摘要 / RAG / 精简输入
↓
减少输入 Token
两者解决的是不同问题。
5. 前端怎么减少重复请求?
核心回答
核心是避免同一个用户意图被重复发送给模型。
例如用户连续点击两次:
text
点击发送
↓
请求 A
再次点击
↓
请求 B
如果 A、B 内容完全一样,就可能产生重复 Token 消耗。
可以在前端做:
javascript
const key = hash({
conversationId,
messages,
model,
options
});
if (pendingRequests.has(key)) {
return;
}
pendingRequests.add(key);
try {
await requestAI();
} finally {
pendingRequests.delete(key);
}
还可以结合:
- 防抖
- 节流
- 请求状态锁
- AbortController
- 请求去重
- 缓存
但这里要区分:
防抖主要解决用户操作问题,请求去重才直接解决重复 AI 请求问题。
6. "拦截大文本、分片发送"一定能降低 Token 吗?
核心回答
不一定。分片解决的是请求大小、上下文窗口和处理方式,不代表 Token 总量自动减少。
比如:
text
10000 tokens
拆成:
text
2000 + 2000 + 2000 + 2000 + 2000
如果 5 次请求最终把这些内容全部交给模型,Token 并没有凭空减少。
甚至如果每次都重复携带:
text
System Prompt
历史上下文
用户内容
总 Token 还可能增加。所以真正应该问的是:
分片之后,模型最终实际看到多少 Token?
而不是:
请求是不是变小了?
7. 图片和文件怎么优化 Token?
核心回答
先判断模型到底需要什么信息,不需要把原始数据完整交给模型。
例如用户上传一份 50MB 日志:
text
50MB 原始日志
↓
前端 / BFF
↓
过滤无关日志
↓
提取 ERROR / WARN
↓
截取相关时间范围
↓
必要时摘要
↓
发送模型
如果用户只是问:
"为什么昨天 10 点服务挂了?"
那就没必要把整个日志文件全部塞给模型。更合理的是:
text
用户问题
↓
确定相关时间
↓
检索相关日志
↓
只把相关内容给模型
这实际上已经开始涉及 RAG / 检索增强 了。
8. 真正高级的 Token 成本优化应该怎么做?
核心回答
真正的优化不是单纯"少发点文字",而是建立从用户输入到模型请求的完整成本控制链路。
可以把整个链路说成:
text
用户输入
↓
前端预处理
├─ 输入去重
├─ 内容裁剪
├─ 文件/图片处理
└─ 请求去重
↓
上下文管理
├─ 最近消息
├─ 历史摘要
├─ 相关历史检索
└─ Token 预算
↓
请求构造
↓
BFF / AI Gateway
├─ 模型选择
├─ Prompt 管理
├─ 缓存
├─ 限流
└─ 成本统计
↓
LLM
↓
流式返回
↓
前端增量渲染
这里就出现了一个重要的认知:Token 成本优化不是纯前端问题。 前端能做的是:
text
减少无效输入
控制上下文
减少重复请求
优化文件/图片输入
按需加载历史
而真正完整的成本优化通常还要结合:
text
BFF / AI Gateway
模型路由
Prompt 缓存
上下文缓存
RAG
模型降级
限流
Token 统计
成本监控
9. 面试官追问:如果让你负责一个 AI 聊天产品,你怎么系统降低成本?
高分回答
我会先从输入侧控制 Token,而不是先考虑模型本身。前端会做请求去重、历史消息裁剪、历史摘要、按需加载上下文,以及图片和文件的预处理;然后在 BFF 或 AI Gateway 层统一做 Token 预算、模型路由、缓存和成本统计。
另外我会把"减少 Token"和"提升体验"分开看,比如流式渲染主要降低首字延迟,并不会直接减少 Token;真正影响 Token 成本的是模型最终实际收到和生成了多少内容。
最后通过 Token 使用量、请求成功率、首字延迟、单次请求成本等指标做监控,再针对高成本场景继续优化。
这比单纯回答:
"精简 Prompt、减少上下文。"
技术深度会高很多。
10. 这道题最容易踩的坑
| 说法 | 问题 |
|---|---|
| 精简 Prompt 就行 | 太浅,只覆盖一个点 |
| 流式渲染降低 Token | ❌ 主要优化体验,不直接降低 Token |
| 压缩 HTTP 请求降低 Token | ❌ 网络体积和 Token 数不是一回事 |
| 分片发送降低 Token | ❌ 分片本身不会减少 Token |
| 前端负责所有 Token 优化 | ❌ AI 成本控制通常是端到端问题 |
| 图片压缩一定降低 Token | ❌ 要看模型如何处理图片输入 |
| 删除所有历史消息 | ❌ 可能损失上下文,需要摘要/检索 |
| 字符数越少 Token 越少 | ❌ Token 与字符数不是简单一一对应 |
最值得记住的一句话
AI 前端做 Token 优化,本质就是控制"模型最终实际看到什么",而不是单纯控制"浏览器发了多少数据"。