免费POC, 零成本试错
AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


我要投稿

Perplexity 是怎么设计、打磨和维护 Agent Skills 的

发布日期:2026-05-09 23:43:05 浏览次数: 1522
作者:ChallengeHub

微信搜一搜,关注“ChallengeHub”

推荐语

探索Perplexity如何将专业能力封装为可调用的Agent技能模块,并揭示其与传统软件开发截然不同的设计哲学。

核心内容:
1. 模块化Agent Skills的架构与关键应用场景
2. 从Python之禅到“Skill之禅”的思维范式转变
3. Perplexity内部Skill开发与评审的核心指南公开

杨芳贤
53AI创始人/腾讯云(TVP)最具价值专家

Perplexity 是怎么设计、打磨和维护 Agent Skills 的

原文链接:https://research.perplexity.ai/articles/designing-refining-and-maintaining-agent-skills-at-perplexity

Perplexity 这套前沿 Agent 产品,骨子里靠的是一堆模块化的 Agent Skills——把那些专业知识和实操经验打包成一个个可调用的能力单元。Perplexity 内部维护着一个精挑细选的 Skill 库,覆盖各种技术场景:Perplexity Computer 里那些通用工具大多都是 Skill 撑起来的;金融、法律、医疗这些垂直领域有专门的能力模块;还有一长串针对各种用户细分需求的小模块。这里头有些 Skill 平时根本用不上,但一旦触发就特别关键。所以 Perplexity 的 Agents 团队一直把 Skill 质量看得跟代码质量一样重。

但话说回来,写一个高质量 Skill 所需要的直觉和最佳实践,跟写传统软件完全是两码事。Agents 团队 review 过工程师们写的大量 PR——这些工程师本身水平都很高,但写出来的 Skill 几乎都得返工,评论意见和修改建议一长串。原因很简单:很多写代码时是好习惯的模式,到了写 Skill 这里就成了反模式。

举个直观的例子,拿 PEP20 - Python 之禅 来对照一下,就能很明显地看出来:写好 Python 代码的那套思维,跟写好 Skill 完全不是一回事。Python 之禅那 20 条里头,至少有一半放在写 Skill 的语境下要么是错的,要么是会把人带沟里去的。挑五条对照看看:

Python 之禅 Skill 之禅
简洁胜于复杂
Skill 是一个文件夹,不是一个文件。复杂本身就是它的特性。
显式胜于隐式
激活靠的是隐式的模式匹配。要做渐进式披露。
稀疏胜于密集
上下文很贵,每个 token 都要尽可能高密度。
特殊情况不足以打破规则
那些"坑"恰恰就是特殊情况——而且是最有价值的内容。
实现起来容易解释,可能就是好主意
容易解释的东西,模型本来就会。删掉。

笔者要分享的这份指南,是 Perplexity 内部工程师在开发和评审 Skill 时实际在用的文档。这次也把它公开出来,希望踩过的坑、悟出来的道理能让更多人受益。无论是日常要写生产级 Skill 的工程师,还是想在自己擅长的领域里给 Computer 做个专属 Skill 的普通用户,这份文档都用得上。

到底什么是 Skill?

写 Skill 的时候,做的不是传统意义上的软件开发——尽管 Skill 现在确实已经成了 Agent 系统主要的逻辑核心之一。更准确地说,写 Skill 是在为模型和它所处的环境构建上下文。 Skill 有它自己的一套约束和设计原则,按写代码的思路去写 Skill,铁定翻车。

具体来说,从 Perplexity 的实践看,Skill 至少包含四层含义。

Skill 是一个目录

Skill 不是一个孤零零的 SKILL.md 文件。很多情况下,一个 Skill 会包含好几个文件。在以 Skill 命名的目录下,通常会有 SKILL.md(frontmatter 元数据加上指令本体)、scripts/(Agent 直接调用的代码,省得它每次都重新发明轮子)、references/(体量较大的文档,按需加载)、assets/(模板、schema、各种数据),以及 config.json(首次使用时的用户配置)。

这种"中心-辐条"的结构能让 Skill 保持高度聚焦和精简,而且文件夹结构本身就可以玩出很多花样。对于特别复杂的 Skill 来说,多层嵌套的目录结构能帮模型更好地导航。打个比方,如果一个 Skill 涉及 300 个主题、可以归到 20 个大领域下面——让今天最强的前沿模型从 300 个里精确挑出一个,仍然是个没解决的难题;但让它先在 20 个领域里挑一个,再在某个领域下的 15 个主题里挑一个,难度立马降下来了。

举个真实案例。这次美国报税季,Perplexity 在打造 Computer 美国所得税相关能力时,团队就用了三层嵌套的目录结构。这种层级在面对税法这种复杂场景时简直是必需品:早期测试的时候,他们试过把美国《国内税收法典》全部 1,945 个条款一股脑塞进一个文件夹里给模型,结果模型表现比根本不加载这个 Skill 还要糟糕。后来按逻辑重新切分成多层级,效果立竿见影。

不过这种层级结构也不是白来的。层级越深,对信息架构的精细打磨要求就越高,否则就要被多层间接寻址搞晕。团队为此专门做了快速参考索引、定制化的搜索工具等等,就是为了让模型尽可能少绕弯路就能定位到信息。这种笨功夫做扎实之后,最终的结果是值得的:模型在处理税务相关任务时,比单纯依赖通用工具强了不止一个档次。

Skill 是一种格式

Skill 同时是一种格式约定。根目录下的 SKILL.md 文件必须包含 name 和 description。而且这个 name 必须跟 Skill 所在的目录名严格一致,全部小写、不能有空格、可以用连字符。

这里头 description 这个字段是路由触发器,这是个常见的失误点:很多人把它当成"这个 Skill 是干啥的"内部文档来写,错。它实际上是给模型看的——告诉模型什么时候该加载这个 Skill。所以地道的写法是 "Load when..."(什么时候加载),而不是 "This Skill does..."(这个 Skill 做什么)。这事很重要,因为大部分实现都是把 description 直接注入到模型上下文里的。

frontmatter 里还有 depends:,可以用来构建 Skill 之间的层级依赖关系;以及 metadata:,主要用于评审和评估。不同的 Agent 系统还可以自定义 frontmatter 字段,按各自系统的需求灵活使用。当然也可以走另一条路:把 Skill 专属的元数据放进单独的 JSON 或 YAML 配置文件里。这种做法适合那种希望 Skill 能有不同运行时行为、又不想用细枝末节污染模型上下文的 Agent 系统。还有一种类似的玩法是在读取时把 frontmatter 给剥掉。Computer 用的就是后面这种方案——配置都保留在 SKILL.md 文件里,但在解析时小心处理;如果有些字段对模型上下文有用、有些没用,还可以做条件性剥离。

Skill 是可调用的

Skill 是可调用的,Agent 在运行时按需加载。重点:Skill 不会一股脑全部塞进上下文。 大多数 Agent 系统默认是按需逐步展开。

在 Computer 里,Skill 加载的过程大致是这样:Computer 先调用 load_skill(name="..."),把 Skill 目录复制到隔离的执行沙箱里,再递归加载 depends: 标签里声明的依赖,最后把 frontmatter 剥掉,所以 Agent 看到的只有正文内容和附属文件。

不同的 Agent 系统可以用不同方式暴露 Skill 内容。有些系统选择压根不暴露文件层级结构,让模型自己通过文件系统操作去发现;有些则把整个文件树(带截断或深度限制)给模型一份地图。Computer 选的是默认不在调用上下文里展开完整文件层级,但这个行为可以按 Skill 单独配置覆盖。

Skill 是渐进式的

Skill 是渐进式的。Computer 里有三层不同的上下文成本,每一层在不同阶段付出:

层级 加载内容 预算 何时付费
Index(索引层)
每个非隐藏 Skill 的 name: description
单 Skill 约 100 token
每个 session、每个用户、永远在付
Load(加载层)
完整的 SKILL.md 正文
约 5,000 token
Skill 被加载时一次性付清
Runtime(运行时层)
scripts/
references/assets/ 里的文件,子 Skill,FORMATTING.mdSPECIAL_CASES.md 等
不限
只有 Agent 真去读了才付

Computer 会先构建一个 Skill 索引,里面是每个可用 Skill 的 name 和 description。这个索引的预算特别紧——单 Skill 100 token 出头,越短越好。为啥这么抠门?因为这成本是每个 session、每个用户都要付的,它会被注入到对话最开头的系统提示词里。模型拿到这堆 Skill 名字和描述,才能决定要不要调用 load_skill()。所以能进这个索引的门槛极高:你的 Skill 必须确实有用,而且描述必须做到极度密集和精炼,因为所有人都在替它付费。

Skill 真正被加载之后,紧接着是完整的 SKILL.md 正文。理想状态下,正文不要超过 5,000 token。即便如此,也要做到字字珠玑——一旦加载,剩下的对话流程都得带着它的成本,直到触发上下文压缩。很多对话线程会同时加载三到五个 Skill,这个成本是叠加的。一个内容浮夸、废话连篇的 Skill 不光自己拖后腿,还会顺带把别的 Skill 和整体 Agent 能力一起拖下水。说白了:Skill 加载了却没干对事,那就是纯纯浪费上下文。

最后一层是脚本、子 Skill、特殊格式说明这些。这一层是放无限制、有条件分支的复杂逻辑的地方。Agent 只会在真用得上的时候才去读,所以这里的内容门槛要低很多。简单总结:索引层每个 token 都要斤斤计较;加载层稍微宽松一点;运行时最自由——可能塞两万 token,也可能完全不用。运行时这一层就是模型上下文真正能"渐进展开"的地方。

什么时候才需要 Skill?

Agents 团队经常被问:某某场景到底要不要做个 Skill?说实话,光靠第一性原理推导很难给出确定答案。唯一靠谱的方法是先不带 Skill 跑起来,找几个 hero query(高代表性的核心场景)跑一跑,看看 Agent 表现到底怎么样。

什么时候你需要一个 Skill

很多任务本来就在训练好的模型的能力分布之内。只有当你想以某种特定方式改变模型行为、而这种改变又不是在 prompt 里加一句话能搞定的时候,才需要写 Skill。换句话说,当 Agent 在缺少特定上下文时会做错,或者在表现上有不一致、非确定性、而你又需要它在多次运行中保持高度稳定时——这才是该出 Skill 的时候。

也可能是知识本身很稳定但不在训练数据里:训练截止之后才出现的新东西、企业内部专有的工作流。又或者纯粹是品味问题。比如 Computer 里好几个跟设计相关的 Skill,是 Perplexity 设计负责人 Henry Modisett 亲自写的。这些 Skill 里每一个 token 之所以存在,都是因为 Henry 在做网站和 PDF 设计上有自己很到位的审美——用什么字体、不能用什么字体、字体给人的感觉是怎样的,这些判断模型从训练数据里是学不出来的。

什么时候你不需要 Skill

笔者见过太多 Skill 里写着一串 git 命令、要求按顺序执行。这没必要——模型本来就会做这事。这种内容当文档不错,当 Skill 就是垃圾。

也见过 Skill 在重复系统提示词里已经讲过的话。完全没必要。对绝大多数请求都相关的知识,应该放在全局上下文里,而不是塞进按需加载的 Skill。

如果某个东西的变化速度比你能维护的速度还快,也别做成 Skill。比如调一个远端 MCP 端点,它的工具或者工具版本经常变——千万别把这些细节硬塞进 Skill,否则注定会出现版本漂移,模型也会跟着犯错。

每一个 Skill 都是一份"税"

这里有个非常实用的自检方法:对 Skill 里的每一句话问一下——"如果没这句话,Agent 会写错吗?"如果这句话不是非要不可,那它就没资格留在那里,因为每一次会话每一个用户都在为它付费。决定要不要新增一个 Skill 之前,记住这个税收逻辑。

下面这句法语原话听起来更带劲,大意是"我之所以把这封信写得这么长,是因为我没空把它写短"。

« Je n'ai fait celle-ci plus longue que parce que je n'ai pas eu le loisir de la faire plus courte. » —— 帕斯卡,《致外省人书》,1657 年

跟帕斯卡说的一样,每个 Skill 都得花时间打磨。写一个简短的 Skill 远比想象中要难。 如果你的 Skill 写得很轻松,那它八成是太长了,或者根本就不该存在。一个好 Skill 是被压到不能再压短的状态。

如果想着 one-shot 撸出一个 Skill,五分钟提个 PR——结果几乎注定是平庸的。事实上,已经有研究指出,让 LLM 自己写 Skill 给自己用,平均下来是没收益的:"模型自己生成的 Skill 平均没有任何效果,说明模型其实没法可靠地把那些它消费时受益的程序性知识自己写出来。"

怎么写一个 Skill

换种说法,必须把自己的判断和品味注入到每一个写出来的 Skill 里。具体步骤如下。

Step 0:先写 Eval

先把评估用例(eval)写出来。 评估用例可以从这几个地方挖:从生产环境或者团队内部 brain trust 里采样真实用户查询;之前因为没这个 Skill 导致 Agent 翻车的已知失败案例;还有那些贴近 Skill 边界但应该路由到别的 Skill 的"邻近域混淆"案例。

至少要保证你测试的是 Skill 在该加载的时候确实加载了。理想状态下,从生产环境采样一些案例。已知失败案例也很有价值:可能你写这个 Skill 的初衷就是为了解决某个具体的失败,又或者是在重构两个职责相邻、容易互相串味的 Skill。正面例子和反面例子都要有,而且要从相似的开始。反面例子的威力极大,有时候比正面例子还重要。

Step 1:写 description

这是整个 Skill 里最难写的一行。它是个路由触发器,不是文档说明。

要把 name 和 description 写对,你不需要关心 Skill 内部具体做什么。你只需要关心这个 Skill 是不是在该加载的时候加载、不会有偏离目标的副作用——这是头号失败模式。 每多加一个 Skill,都有可能让其他每一个 Skill 略微变差,所以必须把回归风险压到最低。

再强调一次:差的描述写"这个 Skill 是干嘛的"或者"这个 Skill 有什么用"。好的描述写"什么时候 Agent 应该加载它"。举个例子,假设有个 Skill 是用来盯 PR 进展的,别写"这个 Skill 监控 PR",要写工程师烦躁起来催进度时会蹦出来的话——比如 "babysit"(盯着)、"watch CI"(看 CI)、"make sure this lands"(确保它能合上)。

写 description 时有几个要点:用 "Load when..." 开头;控制在 50 词以内;描述用户的意图,最好直接来自真实查询;不要总结工作流程。真实查询能帮你做到 80-20 覆盖,一般两三个例子就够用了。要做到刚好够、又一点不多余,没那么容易。

Step 2:写正文

接下来才是写 Skill 的正文内容。注意,这一步既不是 Step 0 也不是 Step 1。

把工作流讲给 LLM 听,跟讲给同事听完全是两码事,跟讲给运行时系统听也是两码事。一个工程师学新软件工具,可能要看文档、找有经验的人带一下、自己上手用一段时间才上路。但对于已经存在至少一年的软件工具来说,提它的名字,LLM 该知道的都知道了。

写正文的时候,把那些显而易见的东西略掉。很多工程师写 readme.md 写惯了,习惯把每一个命令一个个列出来。写 Skill 时很容易就退回那个模式——感觉像在写文档,但要这么干,写出来的 Skill 就是垃圾。所以别把命令一条条列出来。

举个反例,别写:git log # 找到 commit; git checkout main; git checkout -b <clean-branch>; git cherry-pick <commit>;

而要写:**"把这个 commit cherry-pick 到一个干净分支上。处理冲突时保留原意。如果合不进去,说明原因。"**

后者比前者好太多了,尤其是在出问题的时候。别 railroad(生硬规定每一步)——那样做又脆又僵。要给模型留出灵活空间,让它在多种可行方案里选。再说一遍:对人来说是好文档的东西,对模型来说常常是烂文档。

接下来重点放在 gotchas(坑)和反面例子上。这部分内容信息密度极高,因为它在告诉模型什么不能做。Agent 每翻车一次就加一行,这个列表会自然而然地长起来。最后,如果有任何条件性的、内容特别厚重的部分,把它从作为枢纽的 SKILL.md 里挪出去,放进辐条文件——也就是可以渐进加载的附属文件。下一步会展开讲。

Step 3:用好层级结构

当需要用到脚本、参考文档或者特定工具的时候,就该把 Skill 的目录层级利用起来。scripts/ 里放那些 Agent 每次都会重复发明的确定性逻辑,预先给它写好让它直接用,而不是让它从头组装。references/ 里放体量大、只在特定条件下才需要的文档,比如"如果 API 返回非 200,去读 api-errors.md"。assets/ 里放 Agent 直接套用、按格式填充的输出模板,比如 report-template.md、各种输出 schema。config.json 用于首次使用时的用户配置,比如询问 Slack 频道是哪个,记下来下次直接用。

凡是从主 Skill 分支出去的条件性内容,都拆到子文件夹里。还要记住前面说过的多层嵌套——对特别复杂的 Skill,要认真考虑:到底是做成一个庞大单体,还是拆成多个 Skill 用 depends: 串起来更合适?

Step 4:迭代

接下来在分支上做大量迭代。从主分支开始,先不带 Skill 跑几轮,建好 hero query 集合,然后跑一大批 eval。

review 这个 Skill 的同事会感谢你提交的是一个完整 changeset 加上配套的 eval 集合。一个一个增量改动地 review 真的很痛苦(除了新加 gotcha 的情况),所以尽量把这种 review 负担压到最低。

很多次你会反复改一些小的措辞。description 里的小幅措辞调整,对路由的影响往往是巨大的(甚至会溢出影响到其他 Skill),所以这种工作要在 Step 5 之前全部搞定。

Step 5:发布

发就完事了。

怎么维护一个 Skill

写完一个 Skill 不是终点,还得维护。

让 Gotcha 飞轮转起来

从这一步开始,gotcha 列表往往会增长或者变化得很快。笔者经常看到工程师提没经过 eval 的 PR,里面甚至改了 description。Skill 合并之后还在改 description,那肯定是哪里出问题了。 你要改的是决定 Skill 是否被路由的那行字,那必须配套写新的 eval 来支撑这个改动。

Skill 是只增不删(append-mostly)的。 时间一长,最有价值积累的就是 gotcha 这一节。Agent 在某件事上翻车了——加一条 gotcha;Agent 在不该加载的时候加载了这个 Skill——收紧 description,再加几条反面 eval;Agent 在该加载的时候没加载——加关键词、加几条正面 eval;系统提示词变了——检查有没有冲突或重复。

发现一个失败案例就加一条 gotcha,这事很容易做。它是反面例子,并不算改了显式的指引,只是在告诉模型"嘿,这里有个已知的坑"。随着你从 80-20 往 99.9% 甚至 99.99% 的成功率推进,这个 gotcha 列表会越长越快。看到反面例子,主要往 gotcha 节里追加就行——别动指令、别动 description。

Eval 套件

Perplexity 内部跑着多套 eval 来检查不同维度。

第一类是 Skill 加载和 Skill 文件读取。检查 Skill 自身加载行为的 precision、recall 以及禁加载校验:Agent 在该路由的时候会路由到你的 Skill 吗?这类 eval 是用来确保新 Skill 不会破坏既有的边界划分。

第二类检查 渐进加载是否正确。Agent 加载了 Skill 没错,但它有没有去读那些附属文件?比如金融 Skill 在处理金融查询时,到底有没有去读 FORMATTING.md

第三类是 域内端到端任务完成度。跑完整个 Agent 循环,然后用 LLM judge 按一套定义清晰的 rubric 给结果打分。

最后非常重要的一点:这些 eval 必须在不同模型上跑。Computer 至少支持三种编排模型家族——GPT、Claude Opus、Claude Sonnet。Skill 加载和域内 Skill 都要跨这些不同的 Agent 编排器去验证,确保行为一致。Sonnet 和 GPT 在处理 Skill 时的行为差别其实挺大的。

最后的总结

写得越多,自然就越熟。如果日常做的、可重复的任务还没用 Skill 自动化起来,那马上开始。

写 Skill 这件事本身就是一种自我训练,越写越会写。而且 Skill 在自动化业务流程上特别管用。如果你能描述清楚自己每周站会前要做什么、每个 sprint 结束要做什么,或者作为工程师每天、每周乃至每个季度要重复做的事情——这些都应该写成 Skill,把时间买回来。复盘自动化、PR 审查……任何能做的任务,至少可以让 Skill 先做个初版,能省下来的时间真的不少。

话说回来,也别走极端——Skill 不是写起来轻松的东西,也不是任何场景都需要 Skill。少即是多。最后再敲三个钉子:

  1. 先写 eval 再写 Skill。 包含反面例子,以及那些贴近但不该路由过来的 Skill 的 forbidden load 校验。
  2. description 才是最难的部分。 用 "Load when..." 开头,每个词都在抢注意力。
  3. Gotcha 是高价值内容。 一开始就写薄一点,随着 Agent 翻车再慢慢长出来。

还有一点千万记住:新增一个 Skill 很容易把别的本来好好的 Skill 搞坏,哪怕你没动它一行——这就是所谓的"超距作用",要时刻警惕。

写 Skill 也好、维护 Skill 也好,把手边能用的工具都用起来。想再深入了解的话,Agent Skills 网站上有很多优秀案例,Perplexity 内部仓库和公开生态里也有大量值得参考的 Skill 设计。

图片
添加微信,备注”LLM“进入大模型技术交流群
图片

如果你觉得这篇文章对你有帮助,别忘了点个赞、送个喜欢

>/ 作者:ChallengeHub小编

  >/ 作者:欢迎转载,标注来源即可

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询