核心洞察:Skills 不是代码,是上下文
Perplexity 的 Agent 产品建立在模块化 Agent Skills 的基础上。这些 Skills 包括为 Perplexity Computer 提供动力的通用工具、金融/法律/健康等垂直领域能力,以及大量解决用户需求的模块。
关键认知转变:当你写 Skill 时,你不是在写普通软件——你是在为模型和它的环境构建上下文。Skill 有不同的约束和设计原则。如果你像写代码一样写 Skill,你会失败。
Python 之禅 vs Skill 之禅
Perplexity 团队发现,Python 之禅(PEP20)的 20 条智慧中至少有一半在写 Skill 时是完全错误或具有误导性的:
| Python 之禅 | Skill 之禅 |
|---|---|
| 简单优于复杂 | Skill 是一个文件夹,不是文件。复杂度就是功能。 |
| 显式优于隐式 | 激活是隐式模式匹配。渐进式披露。 |
| 稀疏优于密集 | 上下文昂贵。每 token 最大信号。 |
| 特殊情况不足以打破规则 | Gotchas 就是特殊情况(最高价值内容)。 |
| 如果实现容易解释,可能是个好主意 | 如果容易解释,模型已经知道了。删掉它。 |
Skill 的四个本质
1. Skill 是一个目录
Skill 不只是单个 SKILL.md 文件。Perplexity 使用 hub-and-spoke 模式:
skill-name/
├── SKILL.md # frontmatter 和指令
├── scripts/ # Agent 运行的代码,不是重新发明的
├── references/ # 重文档,条件加载
├── assets/ # 模板、schema 和数据
└── config.json # 首次用户设置
多级层次结构的价值:当 Skill 需要跨越 300 个主题时,让模型在 300 个中可靠选择是未解决的挑战。但如果分成 20 个主题领域,模型先选领域再在 15 个中选择就容易得多。
Perplexity 在美国所得税能力中使用了三级主题嵌套。早期测试显示:把全部 1,945 节美国国税法放在单个文件夹中,性能比不加载 Skill 还糟糕。组织成逻辑分区对确保高精度读取操作不可或缺。
2. Skill 是一种格式
核心 SKILL.md 必须有名称和描述。描述是路由触发器,不是内部文档。常见失败点:描述不是说明 Skill 做什么,而是告诉模型何时加载 Skill。
好的描述以 "Load when..." 开头,50 字以内,描述用户意图(来自真实查询),不总结工作流。
3. Skill 是可调用的
Agent 在运行时加载 Skill。重要的是,Skills 不总是捆绑到上下文中。大多数 Agent 系统在特定需要时渐进式展开 Skills。
4. Skill 是渐进的
Perplexity Computer 实现了三层上下文成本:
| 层级 | 加载内容 | 预算 | 何时付费 |
|---|---|---|---|
| Index | 每个非隐藏 Skill 的 name: description | ~100 tokens/Skill | 每个 session,每个用户,始终付费 |
| Load | 完整 SKILL.md body | ~5,000 tokens | 加载时 |
| Runtime | scripts/、references/、assets/、子技能等 | 无上限 | 仅当 Agent 读取时 |
Index 层级:每 token 都重要。因为每个 session、每个用户都在为此付费。进入这个 index 的门槛极高——Skill 必须非常有用,描述必须极度密集和简洁。
Load 层级:理想情况下 body 不超过 5,000 tokens。一旦加载 Skill,对话剩余部分都要为此付费。许多线程加载 3-5 个不同 Skills,成本相乘。有废话的 Skill 几乎肯定会降低其他 Skills 和整体 Agent 能力。
Runtime 层级:放置无界条件分支逻辑的地方。Agent 只在需要时使用,门槛最低。
何时需要 Skill?
需要 Skill 的情况
- Agent 没有特殊上下文就会出错
- 需要跨运行极度一致的行为
- 知识持久但不在训练数据中
- 企业特定工作流
- 品味问题:Perplexity 的设计 Skills 由设计负责人 Henry Modisett 编写,指定用哪些字体、不用哪些字体、字体的感觉——模型无法从训练数据单独学习这些判断
不需要 Skill 的情况
- 工程师写了一系列需要按顺序执行的 git 命令——模型已经知道怎么做,这是好文档但不是好 Skill
- Skills 重复系统 prompt 中的指令——大多数请求相关的知识应放在全局上下文,不是条件加载的 Skill
- 变化速度超过维护速度的东西——比如远程 MCP 端点,工具或版本频繁变化,注入 Skill 会导致漂移
每个 Skill 都是税
对 Skill 中每句话应用这个测试:"没有这条指令,Agent 会做错吗?" 如果不需要,就不能留在那里,因为每个人每次都在为此付费。
"我只把这封信写得更长,是因为我没有时间把它写得更短。" —— 布莱兹·帕斯卡,1657
写短 Skill 很难。如果 Skill 容易写,它可能太长或不应该存在。好的 Skill 是尽可能短的。
研究显示:LLM 自己写的 Skills 平均没有收益——"模型无法可靠地编写它们受益的程序性知识"。
如何构建 Skill(5 步)
Step 0:写 Evals(最先做)
从真实用户查询、已知失败、邻域混淆中采样。至少测试 Skill 是否在需要时加载。负面示例极其强大,可能比正面示例更重要。
Step 1:写描述(最难的一行)
描述是路由触发器,不是文档。不关心 Skill 内容,只关心 Skill 是否在正确点加载、是否没有脱靶副作用——这是第一失败模式。每次添加新 Skill,都有让其他 Skill 稍微变差的风险。
坏的描述:描述 Skill 做什么或为什么有用。 好的描述:说 Agent 何时应该加载 Skill。
例如 PR 监控 Skill:不要写 Skill 做什么,写工程师沮丧时说的话——"babysit"、"watch CI"、"make sure this lands"。
Step 2:写 Body(注意这不是 Step 0 或 1)
向 LLM 传达工作流与向同事传达完全不同。学习新软件工具时,工程师可能需要读文档、获得有经验者的指导。但对于存在至少一年的软件工具,只需提及名字 LLM 就有所有需要的信息。
跳过明显的东西。不要写出一系列命令。例如不需要写:
git log # find the commit; git checkout main; git checkout -b <clean-branch>; git cherry-pick <commit>;
而是写:
"Cherry-pick the commit onto a clean branch. Resolve conflicts preserving intent. If it can't land cleanly, explain why."
模型在后者上会比前者过度规定的一系列命令做得好得多,尤其当事情出错时。不要 railroad(过度规定),在多种方法都可行时保持灵活。
聚焦 gotchas 或负面示例。这些是高信号内容,因为经常指导模型不该做什么。每次 Agent 绊倒时加一行,gotchas 会有机增长。
条件或极重内容移到 spoke 文件。从 SKILL.md hub 取出,放入可渐进加载的 accessory 文件。
Step 3:使用层次结构
scripts/:确定性逻辑,Agent 每次都会重新发明的——给它代码去组合,不是重建references/:仅在条件满足时加载的重文档——"如果 API 返回非 200,读取api-errors.md"assets/:Agent 复制和填充的输出模板——report-template.md、输出 schemaconfig.json:首次用户设置——询问 Slack 频道,保存,下次复用
Step 4:迭代
在分支上做大量迭代。从 main 分支无 Skill 开始,做迭代,构建 hero query 集,运行大量 evals。提交包含评估集的单一 changeset——审查连续的增量变化(除了新 gotcha)非常难。
描述中的小词变化可能对路由有超大影响(包括对其他 Skills 的溢出效应),在 Step 5 前完成所有这些工作。
Step 5:发布
Ship it.
如何维护 Skill
Gotchas 飞轮
Skills 主要是追加的。Gotchas 部分随时间积累最多价值:
- Agent 在某事上失败 → 添加 gotcha
- Agent 脱靶加载 Skill → 收紧描述,添加负面 evals
- Agent 该加载时不加载 → 添加关键词和正面 evals
- 系统 prompt 变化 → 检查竞争或重复
从 80-20 到 99.9% 成功率时,很容易增长 gotcha 列表。看到这些负面示例时,主要追加到 gotcha 部分。不应该添加更长指令或改变描述。
Eval 套件
Perplexity 运行多种 eval 套件:
- Skill 加载 eval:检查精度、召回、禁止检查——确保新 Skills 不破坏现有边界
- 渐进加载 eval:Agent 可能加载了 Skill,但它读取了 accessory 文件吗?
- 端到端任务完成 eval:运行完整 Agent 循环,用 LLM judge 基于明确标准评分
- 跨模型 eval:Computer 支持 GPT、Claude Opus、Claude Sonnet 三种编排模型族——确保不同模型行为一致。Sonnet 和 GPT 在 Skills 方面表现相当不同
最终要点
- 写 evals 在 Skill 之前。包括负面示例和相邻但不同 Skills 的禁止加载
- 描述是最难的部分。"Load when..."(每字都消耗注意力)
- Gotchas 是极高价值内容。从薄开始,随 Agent 失败增长
- 警惕远距离作用:添加新 Skill 很容易破坏其他现有 Skills,即使你没碰它们
- Less is more:Skill 不容易也不总是必要的
构建 Skills 的行为让你更擅长构建更多 Skills,它们也非常擅长自动化业务流程。如果你能描述每周 standup 前、每个 sprint 结束、或作为工程师每天/每周/每季度做的事情,你应该写个 Skill 买回你的时间。