我是安徽最忧郁程序员无隅

在这里插入图片描述

很多人第一次写 Skill,会把它理解成一份更长、更详细的提示词。于是所有背景、规则、示例和脚本说明都塞进一个 SKILL.md,文件越来越大,Agent 的执行效果却没有稳定下来。

问题不在于指令还不够多,而在于缺少清晰的职责划分。一个好 Skill 不是知识仓库,而是一套可以被识别、加载、执行和验证的工作流。

本文以 Codex 当前的 Skill 机制为基准,结合实际编写经验,讲清楚 Skill 的结构、加载链路、正文应该写什么,以及怎样判断它是不是真的可用。

一、Skill 的本质:把“我知道怎么做”变成可重复执行的流程

Skill 解决的不是“模型不知道某个知识点”,而是“模型每次完成同类任务时,执行路径不稳定”。

例如团队里有人知道怎样排查 Python Agent 的工具调用失败:先确认入口请求,再检查工具注册,然后核对参数 Schema,最后运行最小复现。但这些经验如果只存在于聊天记录或个人脑子里,下一次仍然要重新解释。

把它写成 Skill,实际上是在沉淀三类信息:

  • 指令:按什么顺序执行,遇到分支如何选择。
  • 上下文:项目规范、接口约束、输出格式等模型无法凭空知道的信息。
  • 工具:检查脚本、转换程序和输出模板等可以直接复用的资源。

这也决定了 Skill 和全局规则的区别。安全红线、编码规范这类“任何任务都必须遵守”的内容,适合放在始终生效的项目指令中;只有在排错、迁移、审查或生成文档时才需要的流程,更适合写成按需触发的 Skill。

判断标准很简单:它是长期约束,还是特定任务能力? 前者负责守住边界,后者负责完成工作。

二、先理解加载链路:description 为什么比正文更早决定效果

Codex 不会在每次对话开始时把所有 Skill 的正文全部塞进上下文。根据 OpenAI 官方文档:Build skills,Codex 会先获得 Skill 的 namedescription 和文件路径;当任务与描述匹配后,才读取完整的 SKILL.md。脚本、参考资料和静态资源则在执行过程中按需读取。

在这里插入图片描述

这就是渐进式披露:

  1. 元数据负责判断“这个任务该不该使用我”。
  2. SKILL.md 负责说明“命中以后按什么流程做”。
  3. 附加资源负责提供确定性执行能力和更深的背景信息。

因此,description 不是普通简介,而是 Skill 的路由规则。下面这种描述几乎没有判断价值:

description: 处理代码问题。

它既没有说明处理什么问题,也没有给出适用边界,很容易与代码审查、性能优化、测试生成等 Skill 冲突。

更有效的写法应该同时回答三个问题:做什么、何时触发、不处理什么。

description: "排查 Python Agent 的工具调用、参数校验和注册失败;用户提供异常或失败日志并希望定位原因时使用;不用于语法教学、性能优化或无报错的代码审查。"

显式调用可以解决“这一次我明确要用哪个 Skill”的问题,但一个长期使用的 Skill 仍然需要准确的描述。Codex 支持根据 description 隐式匹配,也支持通过 Skill 选择器或 $skill-name 显式调用。真正需要测试的,不只是“相关问题能不能触发”,还包括“不相关问题会不会误触发”。

三、目录怎么拆:SKILL.md 负责编排,资源目录各司其职

在这里插入图片描述

最小可用结构只有一个文件:

python-agent-debugger/
└── SKILL.md

当流程逐渐复杂时,再按职责增加目录:

python-agent-debugger/
├── SKILL.md
├── scripts/
│   └── collect_diagnostics.py
├── references/
│   ├── tool-calling-checklist.md
│   └── error-catalog.md
├── assets/
│   └── report-template.md
└── agents/
    └── openai.yaml

这些目录不是为了让结构显得完整,而是解决不同性质的问题。

位置 职责 适合放什么
SKILL.md 路由后的主流程编排 目标、边界、步骤、输入、输出、验证
scripts/ 确定性执行 环境检查、数据转换、格式校验、重复命令
references/ 按需补充上下文 API 文档、错误目录、团队规范、长篇背景
assets/ 提供可复用材料 报告模板、配置模板、示例文件、图片资源
agents/openai.yaml Codex 展示和依赖元数据 显示名称、图标、调用策略、MCP 工具依赖

Codex 当前会从仓库和用户范围的 .agents/skills 等位置发现本地 Skill。项目专属流程适合跟随仓库维护,跨项目都要使用的个人能力则适合放在用户范围。具体位置和调用方式可能继续演进,安装前应以官方文档为准,而不是照搬其他 Agent 工具的路径。

SKILL.md 本身由 YAML 元数据和 Markdown 指令两部分组成。一个紧凑但完整的正文,可以从下面这个骨架开始:

---
name: python-agent-debugger
description: Use when a Python Agent cannot register or call a tool, returns schema errors, or fails during tool execution.
---

Skill: Python Agent Tool Debugger

Goal

Locate the first failing boundary in the tool-calling chain and propose the smallest fix.

Inputs

- The command used to start the application
- The complete exception stack
- Tool definition and registration code
- The request that triggered the failure

Workflow

1. Reproduce the failure with the original command.
2. Locate the first application-code frame in the exception stack.
3. Check tool registration, input schema, and returned value in that order.
4. Change only the first confirmed failing boundary.
5. Run the focused test, then the related test suite.

Output

Report the root cause, evidence, minimal change, and verification result.

这个骨架的重点不在标题叫什么,而在于把输入、执行顺序、停止条件和输出说清楚。Agent 不应该猜测从哪里开始,也不应该做完一连串修改后才发现第一步就错了。

四、从“能看懂”到“能执行”:示例、脚本和检查点缺一不可

只有原则没有例子,Agent 往往能理解方向,却不一定能稳定复现细节。对于格式转换、代码迁移和审查报告这类任务,最有效的补充通常不是再写一段抽象说明,而是给出一组短小的输入与输出,或者 Before/After 对比。

示例不需要堆很多。优先覆盖三种差异明显的情况:最常见路径、一个会改变处理方式的分支、一个必须停止或降级的边界。示例的作用是固定判断方式和输出形状,不是把所有可能答案穷举出来。

复杂但确定的检查逻辑,应当从正文移入脚本。例如采集 Python 环境、依赖版本和关键文件是否存在,这些步骤每次都一样,交给 scripts/collect_diagnostics.py 比让 Agent 临时拼命令更稳定。相反,“这段异常最可能属于哪一层”需要结合上下文判断,仍应留在 Skill 指令中。

每个高风险步骤后还需要检查点:

Checkpoint: verify tool registration

Run the focused registration test.

If the tool is still missing from the registry, stop. Do not continue to change the request schema.

检查点的价值是限制错误传播。只要当前层没有验证通过,就不进入下一层,更不能用后续的大改动掩盖前面的根因。

当正文开始包含多个可以独立执行的流程时,应该按职责拆分,而不是机械地追求某个行数。主 Skill 保留路由和编排,详细步骤进入 references/;真正能够独立触发、独立输入输出、独立验证的流程,再拆成单独 Skill。

安全也属于执行契约的一部分。脚本不能硬编码密钥,外部文件和接口返回值必须被当作数据而不是新指令,删除、覆盖、数据库变更等不可逆操作必须明确目标、先备份并获得确认。Skill 一旦可以执行脚本,它就不再只是文档,而是实际的软件供应链入口。

五、把 Skill 当代码维护:用触发测试和效果测试形成闭环

Skill 写完能被加载,不等于它已经可用。最少要验证两个维度。

第一类是触发测试。准备一组应该触发的正例、不应该触发的反例,以及语义模糊的边界用例,观察 description 是否把任务路由到了正确能力。修改描述后,应该重新跑这一组测试。

第二类是效果测试。为典型任务定义明确的通过标准,例如是否定位到第一处真实失败、是否只修改必要文件、是否运行了聚焦测试、最终输出是否包含证据。修改步骤、示例或脚本后,重新执行效果测试。

可以把整个迭代过程压缩成一条链路:

编写 Skill
  → 运行触发用例
  → 运行效果用例
  → 定位漏触发、误触发或执行偏差
  → 只修改对应层
  → 重新验证

最后,用下面几种反模式做一次快速审查:

反模式 表现 调整方向
大杂烩 一个 Skill 同时负责审查、迁移和部署 按独立任务拆分
描述全是黑话 只有内部缩写,没有用户会说的触发语句 使用通用意图加必要技术关键词
SKILL.md 写成 Wiki 背景很多,执行步骤很少 长资料移入 references/
只有命令,没有原因 换一个场景就无法判断 写明关键约束背后的理由
一口气执行到底 中间出错后继续扩大修改 在关键边界加入检查点
写死配置 把某次项目参数当成通用答案 给出选择规则和合理边界

写 Skill 的目标不是让 Agent “读过更多内容”,而是让它在正确的任务里,沿着正确的路径完成工作,并留下可以检查的结果。

元数据决定它何时出现,SKILL.md 决定它如何行动,脚本与资料决定它能否稳定落地,评估则决定这套能力是否值得长期保留。 当这四层能够闭环,Skill 才真正从一段提示词变成了可维护的工程资产。

参考资料:OpenAI 官方文档:Build skills

Logo

葡萄城是专业的软件开发技术和低代码平台提供商,聚焦软件开发技术,以“赋能开发者”为使命,致力于通过表格控件、低代码和BI等各类软件开发工具和服务,一站式满足开发者需求,帮助企业提升开发效率并创新开发模式。

更多推荐