上一期我们聊了 Agent 的环境,承载文件、网页、进程和数据库等真实对象,工具则构成 Agent 的观察空间与行动空间。
现在 Agent 已经进入真实环境,也拿到了行动所需的工具。但新的问题又冒出来了:同一个模型,面对同一套工具,为什么完成任务的过程仍然可能相差很大?它们之间还差一套可以反复使用的工作方法,这就是本文要讲的 Skill。
懒人图解版
任务的缺口
假设用户给 Agent 一个任务:
调研一个陌生的开源项目,说明它解决的问题、核心架构、使用边界与当前维护状态,并为关键判断附上来源。
Agent 已经获得项目代码、官方文档和网络访问工具,也可以搜索文件、读取代码、执行命令、检索网页和写入报告。只看工具列表,它似乎已经准备好了。但真正执行时,问题很快就会出现。
Agent 应该先读 README,还是先看代码入口?项目的自我介绍、代码里的实际实现和社区讨论发生冲突时,应该相信哪一个?如何区分已经确认的事实、根据代码作出的推断和仍待验证的信息?报告写完后,又该检查哪些内容?
工具不会回答这些问题。
文件搜索工具可以返回包含某个关键词的文件,网页检索工具可以找到项目资料,Shell 可以运行测试。但这些接口不会主动规定信息收集顺序、来源优先级和报告完成标准。于是,使用相同工具的两个 Agent,可能走出两条不同的路径:
Plain
Agent A
读取 README
↓
搜索几个关键词
↓
浏览部分代码
↓
直接生成报告
Plain
Agent B
确认项目身份与官方来源
↓
建立代码结构地图
↓
区分事实、推断与待验证项
↓
检查版本和维护状态
↓
核验关键主张
↓
按照验收项生成报告
Agent B 并没有获得更多工具权限。它只是多了一套经过组织的任务方法。
本文所说的 Skill,是一种面向特定任务类型,可以被注册、加载、组合和复用的能力模块。在支持动态发现的系统中,运行时还可以根据当前任务选择并按需加载相关 Skill。
一个 Skill 可能包含任务目标、适用范围、操作流程、判断原则、输入输出、约束条件和失败处理。有些 Skill 还会附带示例、检查表、参考资料、模板或脚本,并声明所需的工具、环境和权限。
具体组成取决于平台和任务。有些 Skill 只有简短说明和工作流,有些还会附带多级参考资料与可执行资源。目前并不存在一套适用于所有 Agent 系统的统一 Skill 格式。
因此,Skill 不能简单等同于一段 Prompt、一项工具,或者一份知识库文件。它组织的是完成一类任务所需的方法、约束和相关资源。工具提供动作,Skill 组织动作。
不过,能力包存在于系统中,还不代表 Agent 知道当前任务应该使用它。
Skill 的发现
一个 Agent 系统可能同时拥有代码审查、故障诊断、项目调研、数据分析和技术写作等多种 Skill。
任务开始时,系统需要知道有哪些 Skill 可用。这一步是 Skill 的发现。系统可以维护一份能力目录,只提供每项 Skill 的少量描述信息:
Plain
名称:开源项目调研
适用任务:分析陌生开源项目并生成有来源的技术报告
触发条件:用户要求调研新仓库、评估开源框架选型或梳理陌生项目架构
反例(何时不用):仅对本地已知代码库做单点 bug 修复,或仅查询某个 API 的语法用法
主要依赖:文件读取、代码搜索、网页访问
输出:结构化调研报告
版本:v2.1(示意)
这只是通用示意,不代表某个平台规定的配置格式。在实际工程中,"何时不要用我"(反例)往往比"我能做什么"更关键。 描述过于宽泛会导致 Skill 在无关任务上频繁误触发;明确划定边界与排除场景,是路由模型准确识别意图的核心工程技巧。
能力目录让系统先看到每个 Skill 的简要信息与路由边界,不用一开始就把所有能力的完整内容放进模型上下文。
假设系统中存在开源项目调研、代码结构分析、安全审计、发布说明生成和事实核验等候选能力。当前任务提到了陌生开源项目、核心架构、维护状态和信息来源,系统便可以根据适用范围和依赖条件,筛选出开源项目调研 Skill。
这里需要区分两个动作:发现 解决的是系统知道有哪些候选 Skill;选择解决的是当前任务应该使用哪一个。
选择可以依赖显式规则、语义匹配、模型判断,也可以由专门的路由逻辑完成。不同系统的实现会有差异,但都要考虑 Skill 的误触发和漏触发。名称相似不代表能力适用,任务信息不足时,系统也可能需要补充信息或放弃自动选择。
有些系统会在 Agent 初始化时,通过配置静态加载固定的 Skill。本文接下来关注的是另一条链路:系统先动态发现和选择能力,再按当前任务的需要加载具体内容。
在这条链路中,发现和选择只确定应该使用哪项能力,完整方法会在后续步骤中按需进入当前任务。
Skill 的加载
Skill 被选中以后,系统需要把完成当前任务所需的内容提供给 Agent。
这不等于把整个能力包一次性塞进模型上下文。一个 Skill 可能包含大量参考资料、模板和脚本。如果把成百上千个工具 Schema 和操作手册一次性静态塞入,不仅会迅速挤占上下文窗口、稀释注意力,还会因频繁修改系统前缀而破坏推理引擎的 KV Cache,导致首 Token 延迟与开销大幅攀升。因此,生产系统普遍采用"静态前缀只留元数据、具体内容按需追加"的渐进式披露设计:
Plain
能力描述
用于发现和选择
↓
核心说明
选中 Skill 后进入当前上下文
↓
参考资料、模板和脚本
执行到相关步骤时按需读取或运行
回到开源项目调研任务。系统选中主 Skill 后,可以先把它的核心方法放入当前上下文:
Plain
1. 确认项目身份和官方来源
2. 建立代码结构地图
3. 分开记录事实、推断和待验证项
4. 检查版本、许可证和维护状态
5. 为关键主张保存来源
6. 按照验收清单生成报告
执行到代码分析阶段时,Agent 再通过文件读取工具获得代码结构检查表;需要判断项目活跃度时,再读取维护状态的检查规则;准备输出报告时,才加载报告模板和引用规范。
核心说明通常会进入当前上下文。参考资料和模板可以留在上下文之外,由读取或检索工具按需提供。脚本则需要交给相应的执行器,并经过权限检查后才能运行。因此,下面几种状态要分开理解:
Plain
Skill 已经注册或安装
Skill 的描述可以被系统发现
Skill 已经被当前任务选中
核心说明已经进入当前上下文
相关资料、工具和执行依赖已经可用
其中任何一步完成,都不能代表后续步骤已经自动完成,特别是脚本。Skill 中包含一个脚本,只说明能力包提供了这项资源。读取脚本不等于执行脚本,能否运行仍然取决于系统有没有对应的工具、执行环境和权限。
一个 Skill 的方法足以覆盖简单任务。面对更复杂的目标,主 Skill 还可能需要其他能力配合。
Skill 的组合
下面采用一种示意性的能力拆分。真实系统也可以把这些步骤保留在同一个 Skill 中。我们把开源项目调研作为主 Skill,再组合两个辅助 Skill:
Plain
开源项目调研 Skill
│
├── 代码结构分析 Skill
│
└── 事实核验 Skill
这种组合不能只靠列出几个 Skill 名称。每项能力都要明确自己接收什么、产生什么,以及结果怎样交给下一步使用。
Plain
代码结构分析 Skill
输入:代码库位置、调研问题
输出:项目入口、核心模块、关键依赖、代码位置、未确认项
事实核验 Skill
输入:关键主张、候选来源
输出:已有支持、证据不足、来源冲突、内容可能过期
主 Skill 再根据这些中间结果组织报告:
Plain
调研问题
↓
项目基础事实
↓
代码结构结论
↓
主张与来源清单
↓
事实核验结果
↓
技术报告
明确输入输出,可以减少多个能力之间的信息丢失。如果代码分析只返回一段笼统总结,事实核验就很难知道每个结论来自哪个文件;如果事实核验没有区分证据不足和来源冲突,主 Skill 也无法判断应该删除结论、降低表述强度,还是继续补充资料。
Skill 组合还要处理依赖、顺序和冲突。例如,主 Skill 规定关键事实优先使用官方资料,事实核验 Skill 却找到了社区讨论中的相反说法。系统不能简单选择更符合预期的一方,而要保留两类来源的身份,在报告中区分官方声明、实际代码行为和社区反馈。
多个 Skill 同时加载,也会增加上下文成本。如果每项能力都带有大量说明和案例,真正与当前步骤相关的信息反而更难被找到。因此,Skill 组合通常要配合前面提到的按需加载,避免一次展开全部内容。
这里还要和第六期讲过的 Agent 编排做个区分 编排管理任务级的控制流、状态转移和执行边界。Skill 可以包含一类任务内部的操作流程,但通常不负责整条任务的全局控制。两者关注的层级不同,也可以组合使用。
能力组合好了,真实行动仍然要由工具完成。
行动的边界
把 Skill 称为能力包,很容易产生一个误解:加载某个 Skill 后,Agent 似乎就自动获得了新的外部权限。实际系统中,Skill、工具、环境与 Harness 承担着不同职责:
| 组成 | 主要职责 |
| Skill | 组织完成一类任务的方法、约束和相关资源 |
| 工具 | 提供读取、查询、修改或执行等外部接口 |
| 环境 | 承载文件、网页、进程和数据库等真实对象及其状态 |
| Harness 或相应运行支撑层 | 在模型外部协调能力加载、工具执行、权限、状态和验证 |
这里的 Harness 是对 Agent 运行支撑层的概括。不同系统可能把能力目录、工具执行、权限控制和结果验证拆成多个组件。
在调研任务中,Skill 可以要求 Agent 搜索项目入口、读取依赖文件、检查最近发布版本,或者运行测试验证代码行为。但这些要求只是工作方法的一部分,真正执行时仍然要调用相应工具。
如果系统没有提供网络访问工具,或者当前权限不允许访问外部网络,Skill 就无法查询最新版本。如果命令执行权限没有开放,Skill 也不能直接运行测试。比较可靠的处理方式,是把相关结论标记为未验证,并说明缺少哪项能力,不能把计划中的动作写成已经完成。
有些系统会在激活 Skill 时,同时把它依赖的工具提供给 Agent。这个动作改变的是当前任务可以看到和选择的工具集合,不会改变底层工具的接口、权限和安全边界。
Skill 也可以附带一个用于分析依赖关系的脚本,但脚本只有交给 Shell、代码执行器或其他工具后才会运行。Harness 仍然要检查脚本来源、参数、权限、超时和执行范围。
Plain
Skill:建议运行项目测试
↓
Agent:提出 run_tests 调用
↓
Harness:检查工具、参数与权限
↓
工具:在项目环境中运行测试
↓
环境:产生测试结果和状态变化
↓
Harness:收集证据并返回结果
这也解释了为什么相同的工具可能产生不同质量的结果。
Skill 不会改写底层工具的能力,但会影响 Agent 何时调用、怎样组合、如何检查返回结果,以及失败后采取什么措施。没有方法约束时,Agent 可能看到命令成功退出就继续写报告;加载调研 Skill 后,它还会检查测试范围、退出码和输出内容能否真正支持当前结论。
上一期提到过,工具调用成功只说明动作已经完成,环境是否进入预期状态仍然需要观察和验证。Skill 可以规定验证方法,但验证证据仍然来自工具与环境,最终由 Harness 或上层流程检查。
外部 Skill 中的说明、脚本和其他资源也属于高信任度输入。系统接入前需要审核来源和内容,并限制实际执行权限。因此,Skill 能指导 Agent 怎样使用工具,却不能替工具行动,也不能绕过运行层的权限和验证。
Skill 的复用
如果开源项目调研只执行一次,把所有方法临时写进当前 Prompt,也能完成任务。Skill 的价值在重复任务中会更加明显。
团队可能需要持续调研不同的开源项目。第一次任务结束后,大家发现原来的方法存在几个缺口:它默认项目都有完整文档,没有规定官方介绍与代码实现冲突时怎样处理,也没有检查仓库是否归档、最近版本何时发布。这些经验可以被整理回能力包,形成新的版本:
Plain
经验整理
↓
能力封装
↓
登记与版本化
↓
任务发现与加载
↓
执行和评估
↓
修订发布
↓
再次复用
一个能够稳定复用的 Skill,通常需要交代:
-
适用范围、输入要求和输出结构;
-
所需工具、执行环境与权限;
-
依赖的其他能力及其版本;
-
核心流程和任务完成标准;
-
信息不足或执行失败时的处理方式;
-
示例任务、评估方法和维护信息。
复用并不要求每次得到完全相同的结果。
当调研对象从一个 Python 项目换成前端框架时,代码入口、构建方式和社区结构都会变化。能够复用的是来源确认、代码分析、事实核验和报告验收的方法。项目事实仍然需要在新的环境中重新观察。
版本和环境依赖也不能忽略。某个 Skill 可能依赖网页访问和代码执行能力,也可能只适用于特定语言或仓库结构。依赖发生变化后,系统需要拒绝加载、选择兼容版本,或者明确缩小执行范围。
从这个角度看,本文讨论的工程化 Skill 很像团队外置保存的一类程序性知识。它以文档、代码或资源的形式存在于模型外部,需要在任务中被发现、加载和使用。它不会自动写进模型参数,也不代表 Agent 已经记住上一次任务里发生过什么。
Skill 的复用解决的是工作方法如何重复使用。跨会话记忆解决的,则是过去的信息如何在未来被保存、检索、更新和遗忘。这是下一期要继续讨论的问题。
结语
上一期的环境工程回答了 Agent 在哪里行动、能够看到什么,又能改变什么。本期继续补上另一层:面对一类任务,Agent 应该按照什么方法行动。
Skill 把流程、判断原则、约束和相关资源组织成能力包。在支持动态发现的系统中,它可以根据任务被发现、选择和按需加载,也可以与其他 Skill 组合使用。真正的外部行动仍然由工具完成,并受到环境与 Harness 的权限和验证约束。
工具决定 Agent 可以执行哪些动作,Skill 帮助它把一类事情做得更稳定、更一致,也更容易复用。Skill 可以被下一个任务再次加载,却不等于 Agent 已经记住过去。下一期,我们继续聊 Agent 怎样记住跨会话的东西。