你的 AI Skill 越多越蠢?Token 上下文爆炸的求生指南
前端 AI Skill 体系 · 架构篇
当 Skill 数量从 20 增长到 100+,你会发现 AI 变迟钝了------不是模型退化,而是上下文窗口被 Skill 索引悄悄吃掉了一半。
目录
- 一个反直觉的现象
- [Token 税的本质:Every Skill is a Tax](#Token 税的本质:Every Skill is a Tax "#token-%E7%A8%8E%E7%9A%84%E6%9C%AC%E8%B4%A8every-skill-is-a-tax")
- [量化你的 Token 预算](#量化你的 Token 预算 "#%E9%87%8F%E5%8C%96%E4%BD%A0%E7%9A%84-token-%E9%A2%84%E7%AE%97")
- [短期止血:压缩你的 Skill 描述](#短期止血:压缩你的 Skill 描述 "#%E7%9F%AD%E6%9C%9F%E6%AD%A2%E8%A1%80%E5%8E%8B%E7%BC%A9%E4%BD%A0%E7%9A%84-skill-%E6%8F%8F%E8%BF%B0")
- 中期方案:域级懒加载
- 长期方案:语义路由引擎
- [实战:我是怎么把 20 个 Skill 的 Token 消耗砍掉 40%](#实战:我是怎么把 20 个 Skill 的 Token 消耗砍掉 40% "#%E5%AE%9E%E6%88%98%E6%88%91%E6%98%AF%E6%80%8E%E4%B9%88%E6%8A%8A-20-%E4%B8%AA-skill-%E7%9A%84-token-%E6%B6%88%E8%80%97%E7%A0%8D%E6%8E%89-40")
- 总结:分阶段生存策略
一个反直觉的现象
先问你一个问题:
你给 AI 装了 50 个 Skill,理论上它应该更强才对。但为什么对话一深入,它就开始"忘事"、漏规范、响应变慢?
我在管理 20 个自研 Skill 时就遇到了这个问题。起初只是偶尔丢上下文,后来做了个测算------发现 Token 消耗远超预期。
核心矛盾:
arduino
Skill 越多 → 索引层越厚 → 留给实际任务的上下文越少 → AI 越"蠢"
这不是模型的问题,是上下文窗口的物理限制问题。
Token 税的本质:Every Skill is a Tax
Perplexity 在其 Skill 设计哲学中有一个核心观点:
"Every Skill is a Tax" ------ 每增加一个 Skill,就对整个系统的上下文窗口征了一笔税。
这笔税从哪来?当 AI Agent 启动时,它需要加载所有已注册 Skill 的索引信息(description、intents、触发关键词)。这些文本加在一起,就是 Index 层消耗。
举个具体的例子。一个典型的 Skill 描述大约 80-120 tokens:
markdown
- fe-engineer-pack: Load when user says "技术方案"、"生成组件"、
"review 代码"、"接口联调"、"排查 bug"...
Capability pack: 10 sub-Skills covering full frontend
engineering workflow (S1-S10).
这 100 个 token 看起来不多,但乘以 Skill 数量,就不是小数目了。
量化你的 Token 预算
我做了一个实际测算表:
| 规模 | Index 层消耗 | 占 200K 窗口 | 用户可用空间 | 体感 |
|---|---|---|---|---|
| 20 Skill | ~2,000 tokens | 1% | 充裕,无感知 | 正常 |
| 50 Skill | ~5,000 tokens | 2.5% | 充裕 | 偶尔丢上下文 |
| 100 Skill | ~10,000 tokens | 5% | 尚可 | 长对话开始吃力 |
| 300 Skill | ~30,000 tokens | 15% | 紧张 | 复杂任务明显退化 |
| 500 Skill | ~50,000 tokens | 25% | 告急 | 用户输入被截断 |
| 1000 Skill | ~100,000 tokens | 50% | 崩溃 | 不可用 |
关键认知 :200K 窗口听起来很大,但 Token 税是全局税 、隐性税 、无条件税------即使你这次对话根本不会用到某个 Skill,它的描述依然占着位置。
这就好比你的工位上摆了 100 本工具书。每本只占一点空间,但加起来,你连放笔记本电脑的地方都没了。
短期止血:压缩你的 Skill 描述
适用阶段:当前 ~ 100 Skill
最直接的优化:把 description 当成路由触发器来写,而不是写成说明文档。
原则:30 词路由器
一个好的 description 应该满足:
- 30 词以内(英文,中文 50 字)
- 只写触发词,不解释功能细节
- 有明确边界,知道什么时候不该触发
Before vs After
Before(冗长型,~150 tokens):
markdown
- fe-engineer-pack: This is a capability pack that contains 10
sub-Skills covering the full frontend engineering workflow
including technical solution design, component generation,
code review, API integration, bug troubleshooting, performance
optimization, documentation, 3D scenes, data dashboards, and
refactoring. Load when user says "技术方案"、"生成组件"、
"review 代码"、"接口联调"、"排查 bug"、"性能优化"、
"技术文档"、"3D 场景"、"数据大屏"、"重构"、"提炼公共组件"
or similar engineering tasks.
After(路由器型,~60 tokens):
markdown
- fe-engineer-pack: Load when: "技术方案"、"生成组件"、
"review 代码"、"接口联调"、"排查 bug"、"性能优化"、
"3D 场景"、"数据大屏"、"重构".
Frontend engineering pack (S1-S10).
优化效果:单个 Skill 节省 ~60% tokens,20 个 Skill 累计节省 ~1,200 tokens。
三条压缩规则
| 规则 | 说明 | 示例 |
|---|---|---|
| 删除功能描述 | AI 不需要知道 Skill 能做什么,只需要知道什么时候触发 | ❌ "contains 10 sub-Skills covering..." → ✅ 删除 |
| 合并同义触发词 | 语义相近的触发词只保留最常用的 | ❌ "生成组件"+"创建组件"+"写组件" → ✅ "生成组件" |
| 加排除词 | 避免误触发比增加触发更重要 | ✅ "NOT: design review, PRD review" |
排除词(exclude_intents)的威力
当 Skill 数量到 50+,最常见的问题不是"该触发的没触发",而是不该触发的误触发了。
markdown
# 碰撞示例:用户说"性能优化"
- fe-engineer-pack ← 想触发这个
- fe-base-skill ← 也匹配了
- meta-hub ← 也匹配了(因为有"性能"关键词)
解法:给每个 Skill 加 exclude_intents:
json
{
"name": "meta-hub",
"intents": ["知识管理", "体系管理", "Skill 统计"],
"exclude_intents": ["写代码", "性能优化", "生成组件"]
}
原理:排除词的优先级高于触发词。先排除,再匹配,碰撞率直降 67%。
中期方案:域级懒加载
适用阶段:100 ~ 500 Skill
当 description 优化已经到极限,需要从架构层面下手------不是优化每个 Skill 占多少 token,而是减少同时加载的 Skill 数量。
核心思路:分层索引(Tiered Index)
yaml
┌─────────────────────────────────────────────────┐
│ L0: 域索引(~5 条,~500 tokens) │ ← 永远加载
│ 前端域 / 后端域 / 产品域 / 设计域 / 元层 │
├─────────────────────────────────────────────────┤
│ L1: 域内 Skill 索引(~20 条/域,~2,000 tokens) │ ← 按需加载
│ fe-hub / fe-engineer-pack / fe-test-pack / ... │
├─────────────────────────────────────────────────┤
│ L2: Skill 完整内容(~5,000 tokens/个) │ ← 触发后加载
│ SKILL.md 全文 + modules/ │
└─────────────────────────────────────────────────┘
工作流程:
- Agent 启动 → 只加载 L0 域索引(~500 tokens)
- 用户输入 → 匹配域(如"写组件" → 前端域)
- 加载前端域 L1 索引 → 匹配具体 Skill
- 触发目标 Skill → 加载 L2 完整内容
效果对比:
| 策略 | 100 Skill 时 Token 消耗 | 节省 |
|---|---|---|
| 全量加载 | ~10,000 tokens | 基准 |
| 域级懒加载 | ~2,500 tokens(L0 + 一个域的 L1) | 75% |
实现方式
在注册表中按域组织,Agent 启动时只读域级摘要:
json
{
"domains": [
{
"key": "frontend",
"summary": "前端开发:写代码、组件生成、Review、测试",
"skillCount": 12,
"hub": "fe-hub"
},
{
"key": "product",
"summary": "产品管理:PRD、竞品分析、优先级、用户故事",
"skillCount": 3,
"hub": "pm-hub"
}
]
}
只有当路由命中某个域时,才展开加载该域下的完整 Skill 列表。
Anthropic 的渐进式披露机制
这个思路不是我凭空想的。Anthropic 在其 Agent 设计指南中明确提到:
"渐进式披露(Progressive Disclosure):先给 Agent 最少的上下文,只在需要时逐步展开。"
域级懒加载就是这个原则的工程化落地------把"全量索引"变成"按需索引"。
长期方案:语义路由引擎
适用阶段:500+ Skill
当 Skill 数量到 500+,关键词匹配会遇到物理极限:
- 碰撞概率指数增长:500 个 Skill 的 intents 关键词池 > 5,000 个词,碰撞不可避免
- 遍历效率崩溃:O(n) 关键词遍历不再可接受
- "远距离作用"(Action at a Distance):加一个 Skill 可能让另一个 Skill 的路由变差
解法:用语义搜索替代关键词遍历
css
用户输入: "这个按钮的 hover 状态颜色不对"
↓
语义向量化 → [0.23, -0.15, 0.87, ...]
↓
与 Skill 语义库做 ANN 搜索(top-3)
↓
结果: [fe-engineer-pack(0.92), designer-pack(0.78), fe-base-skill(0.65)]
↓
路由到 fe-engineer-pack(置信度最高)
不再依赖"精准关键词命中",而是理解语义意图。即使用户的描述和触发词一个字都不重叠,只要语义相近就能正确路由。
Skill 联邦(Federation)
500+ Skill 时的组织架构:
meta-hub(联邦协调者)
├── 只维护域级元数据(5-10 条)
├── 不持有任何 Skill 的完整索引
└── 路由请求到域 hub
各域 hub(联邦成员)
├── 独立维护本域 Skill 注册表
├── 独立执行域内路由
└── 独立发布和版本管理
每个域 hub 成为独立的"微服务",meta-hub 退化为纯路由网关。这也符合微服务架构中"去中心化治理"的原则。
实战:我是怎么把 20 个 Skill 的 Token 消耗砍掉 40%
分享我自己管理 17 个自研 Skill 时做的实际优化。
Step 1:测量现状
先搞清楚当前每个 Skill 的 description 占多少 tokens:
bash
# 粗略估算方法:
# 英文单词数 × 1.3 ≈ token 数
# 中文字数 × 2 ≈ token 数
# 我的 17 个 Skill description 累计约 2,400 tokens
Step 2:按触发频率分级
| 频率 | Skill | 策略 |
|---|---|---|
| 高频(日常触发) | fe-hub, fe-engineer-pack, meta-hub | 保留完整 intents,不压缩 |
| 中频(周触发) | fe-test-pack, content-publish | 精简 description,删除冗余说明 |
| 低频(月触发) | fe-developer-distill, skill-scout | 极简路由器,只留核心触发词 |
Step 3:重写低频 Skill 的 description
markdown
# Before(fe-developer-distill,~120 tokens)
Load when user says "蒸馏编码风格"、"分析编码习惯"、"生成开发者 Skill"、
"提取编码风格"、"开发者画像"、"团队风格基线"、"更新团队蒸馏"、
"团队风格变化"、"团队编码规范更新"、"对比团队风格"、"团队蒸馏持续跟踪".
Distills developer coding DNA from Git history into a personal
Skill profile. Supports team-level continuous evolution (Phase 3/4).
# After(~50 tokens)
Load when: "蒸馏编码风格"、"开发者画像"、"团队风格基线".
Git 编码 DNA 蒸馏 → 个人/团队 Skill 画像.
Step 4:加 exclude_intents 防碰撞
json
{
"name": "meta-hub",
"exclude_intents": ["写代码", "fix bug", "生成组件", "写测试"]
}
最终效果
| 指标 | 优化前 | 优化后 | 变化 |
|---|---|---|---|
| 总 Token 消耗 | ~2,400 | ~1,440 | -40% |
| 平均 Skill 消耗 | ~141 tokens | ~85 tokens | -40% |
| 路由误匹配率 | ~12% | ~4% | -67% |
总结:分阶段生存策略
| 阶段 | Skill 数量 | 核心动作 | Token 效果 |
|---|---|---|---|
| 现在 | 20 | 不需要优化,1% 开销无感知 | 基准 |
| P1 | 50 | 压缩 description + exclude_intents | 节省 40% |
| P2 | 100 | 分层索引 + 域级懒加载 | 节省 75% |
| P3 | 500+ | 语义路由 + Skill 联邦 + 向量搜索 | 节省 95% |
一句话总结
Token 是 AI 的工作记忆------你给它装的 Skill 越多,它能用来思考的空间就越少。优化的关键不是让 Skill 更小,而是让 AI 只在需要时才看到它们。
写在最后
Token 上下文管理是 AI Skill 体系规模化的第一道坎。跨过这道坎的核心原则只有一个:
按需加载,永远只付当前任务的税。
如果你也在搭建自己的 AI Skill 体系,欢迎评论区交流你的 Skill 数量和遇到的问题。下篇会写 Skill 间的"外溢影响"问题------为什么加一个新 Skill 会让另一个不相关的 Skill 变傻。
🛠️ 配套工具 :
skill-token-audit.sh(Token 审计脚本),一行命令输出你的 Skill 体系健康报告。完整版私信获取,或评论区回复"审计"。
系列文章回顾:
- 基于四层Skill体系的前端团队AI提效实践
- 一份 AGENTS.md,让 AI 代码规范率从 60% 飙升到 95%
- 一行命令,让 AI 从此懂你项目的规范
- 👉 本文:你的 AI Skill 越多越蠢?Token 上下文爆炸的求生指南