这道题表面问"优化",实际考的是你对 Agent 架构的理解深度。答好了,面试官会默认你具备工程落地能力。
先搞清楚:面试官到底在问什么
"Skill"是当前大模型 Agent 架构中的核心抽象------可复用的、模块化的能力单元。一个 Skill 通常包含:触发条件、输入参数、执行逻辑(可能调用 LLM)、输出结果。
"Token 消耗"是 Agent 系统最敏感的成本指标。一次多轮对话动辄上千 token,一个日活百万的 Agent 产品,Token 费用可以轻松吃掉利润。
所以这道题的本质是:
你能不能在不牺牲用户体验的前提下,通过 Skill 的架构设计,系统性地把 Token 用量打下来?
核心思路:Token 浪费在哪,Skill 就改哪
先建立一个分析框架。Agent 的 Token 消耗主要来自五个黑洞:
| 黑洞 | 典型场景 | Token 浪费量级 |
|---|---|---|
| ① 意图误判 | 用户问天气,Skill 触发了搜索流程,跑了三轮才纠正 | +200~500 |
| ② 重复调用 | 同样的查询被不同 Skill 各自调一次 LLM | ×2~×5 |
| ③ 冗余输出 | LLM 返回大段解释,实际只需要一个 JSON | +30%~200% |
| ④ 无效轮次 | Skill 链路设计不合理,多跳才能拿到结果 | +500~1000 |
| ⑤ 上下文膨胀 | 历史对话全部塞进 prompt,越聊越贵 | 持续增长 |
下面逐一给出 Skill 层面的解法。
解法一:精准路由 Skill------把"误触"消灭在入口
问题:用户一句话可能匹配多个 Skill,如果每个都试一遍,Token 直接翻倍。
设计 :在 Skill 之上加一层轻量级路由 Skill(Router Skill)。
`用户输入
→ Router Skill(只用 1~2 次 LLM 调用,甚至用分类模型)
→ 命中 Skill A → 执行
→ 命中 Skill B → 执行
→ 都不命中 → 走默认兜底
`
关键技巧:
- Router 本身用极短 prompt + Few-shot,控制在 50 token 以内
- 优先用embedding 相似度匹配替代 LLM 判断,零 Token 消耗
- 设置置信度阈值,低于阈值才 fallback 到 LLM,避免"宁可错杀不可放过"
效果:意图误判率从 15% 降到 3% 以内,平均每次请求节省 200~500 token。
解法二:Skill 结果缓存------相同问题不答第二遍
问题:同一个用户、类似的问题反复出现(比如"帮我查一下上次那个订单"),每次都重新跑完整 Skill 链。
设计 :给 Skill 加一层语义缓存(Semantic Cache)。
`Skill 执行前
→ 计算当前输入的 embedding
→ 查缓存:是否有语义相似度 > 0.95 的历史结果?
→ 有 → 直接返回缓存结果,0 Token
→ 无 → 正常执行 Skill,执行后写入缓存
`
进阶做法:
- 缓存 key 用 输入意图 + 关键参数的 hash,而不是原始文本
- 设置 TTL(如 24 小时),避免返回过期数据
- 缓存命中率通常能做到 30%~40%,高频场景甚至 60%+
效果:高频重复请求 Token 消耗直接归零。
解法三:结构化输出约束------逼 LLM 说人话,不说废话
问题:LLM 天生话多。你要一个 JSON,它给你一段话 + 解释 + JSON,Token 白白多出 30%~200%。
设计 :在 Skill 的执行 prompt 中强制输出格式约束。
json
`{
"skill": "query_weather",
"prompt_template": "你只需要返回一个 JSON 对象,不要任何其他文字。格式如下:\n{\"city\": \"string\", \"temp\": \"number\", \"desc\": \"string\"}\n用户输入:{input}",
"output_parser": "strict_json"
}
`
关键技巧:
- 明确写出 "不要输出任何其他内容",LLM 对否定指令的遵循度比你想象的高
- 用 JSON mode / structured output(GPT-4o、Claude 3.5 都支持),从模型层杜绝废话
- Skill 内部用 post-processor 二次校验,格式不对直接重试,避免脏数据进入下游
效果:单次 Skill 输出平均减少 40%~60% token。
解法四:Skill 链路扁平化------能一步到的,绝不走两步
问题:一个复杂任务被拆成 5 个 Skill 串行执行,每个 Skill 都调一次 LLM,Token 线性叠加。
设计 :推动 Skill 合并与并行。
| 原来(串行) | 优化后(合并/并行) |
|---|---|
| Skill A → Skill B → Skill C(3 次 LLM 调用) | Skill A+B 合并为一个 Skill(1 次调用) |
| Skill A 等待 Skill B 结果 | Skill A 和 Skill B 并行触发,结果在编排层合并 |
具体做法:
- 定期做 Skill 调用链路分析,找出高频串联组合,合并成复合 Skill
- 对于"先查再总结"这类固定模式,直接写成一个 prompt,一次搞定
- 引入 条件分支:如果 Skill A 的结果已经包含答案,直接跳过 Skill B
效果:平均 Skill 链路从 3.2 步降到 1.8 步,Token 节省 35%~45%。
解法五:上下文压缩 Skill------历史对话不要全塞
问题:Agent 为了"记住上下文",把前 20 轮对话全部塞进 prompt,到第 50 轮时 prompt 已经 8000+ token。
设计 :加一个上下文压缩 Skill(Context Compressor),在每 N 轮对话后自动触发。
`每 5 轮对话
→ 触发压缩 Skill
→ LLM 生成摘要:"前 5 轮的核心信息是:用户要查订单 12345,已确认发货,预计明天到"
→ 用摘要替换原始对话历史
→ 原历史归档到长期记忆,需要时再检索
`
关键技巧:
- 压缩比通常能做到 10:1 到 20:1(5000 token → 250~500 token)
- 摘要用 定长模板,进一步控制输出 token
- 长期记忆用 向量数据库,按需召回,不占 prompt 空间
效果:长对话场景下,prompt token 稳定在 1500 以内,不再持续膨胀。
面试回答框架(直接背)
如果面试官问这道题,建议按这个结构答,控制在 3~5 分钟:
第一句,定调 :
"Token 优化不是单个 prompt 的技巧问题,而是 Skill 架构层面的系统工程。我会从五个方向切入。"
然后逐条展开:
- 路由层------用 Router Skill + embedding 匹配,消灭误触
- 缓存层------语义缓存,重复请求零 Token
- 输出层------结构化约束,逼模型只输出必要内容
- 链路层------合并串行 Skill,减少调用次数
- 上下文层------定期压缩,控制 prompt 膨胀
最后一句,拉高 :"这五个方向不是孤立的,在实际系统中要配合监控------我会给每个 Skill 加 Token 消耗埋点,用数据驱动持续优化。"
一张图总结
`用户输入
│
▼
┌─────────────┐
│ Router Skill │ ← 精准路由,避免误触(省 200~500)
└──────┬──────┘
▼
┌─────────────┐
│ 语义缓存查重 │ ← 命中则 0 Token(省 30%~60% 高频请求)
└──────┬──────┘
▼
┌─────────────┐
│ Skill 执行 │ ← 结构化输出(省 40%~60%)
│ (合并/并行) │ ← 链路扁平化(省 35%~45%)
└──────┬──────┘
▼
┌─────────────┐
│ 上下文压缩 │ ← 每 N 轮自动摘要(10:1 压缩比)
└─────────────┘
`
这道题的深层考点,其实不是"你知不知道这些技巧",而是"你有没有在真实系统里干过这件事"。 答的时候多带数据、多提 trade-off,比堆术语有用十倍。