Codex 里的 Skill,我会更在意权限、规则和验证

Codex 里的 Skill,我会更在意权限、规则和验证

有一次我只是让 Codex 改 UserSettingsPanel.tsx 里的 loading 状态,Skill 里写的是"定位文件、改代码、跑测试"。组件确实改好了,测试也过了,但 diff 里多出了 settingsStore.tsSettingsProvider.tsx 的改动。问题不在那几行代码能不能跑,而是我根本没让它重写状态入口。测试只覆盖了 UI 渲染,没有覆盖 store 结构变化,所以测试全绿,事故照样发生。

Claude Code 那篇我更在意触发和上下文。到了 Codex 这里,我的关注点会往后挪一步:它进入 Skill 之后,会读哪些文件,会不会改过界,会跑什么命令,验证失败时会不会继续硬做。

这不是说 Codex 的 Skill 更危险,而是它更接近一个会动手的执行代理。Skill 写得越像操作手册,就越要把权限、修改范围和验证边界写清楚。

不是同一份 SKILL.md 就能跨工具直接用

Codex 和 Claude Code 都可以用 SKILL.md 承载工作流。文件形态看起来接近,但我不会把同一份 Skill 原封不动地跨工具复用。

在我这套使用里,Codex Skill 放在 .codex/skills/<skill-name>/SKILL.md 这类目录下。使用时可以明确点名某个 Skill,也可能让任务描述触发它。这个部分和 Claude 侧有相似之处。

差别出现在 Skill 进入之后。

Claude 侧我经常先担心它有没有进错场:一个普通组件任务,会不会被 description 带去做发布排障;一篇文章润色,会不会被误当成产品方案。Codex 侧我更早会看执行边界:它准备改哪些文件,哪些命令需要权限,验证失败之后有没有退回路径。

同样一句"完成后运行测试",放在 Claude 侧可能只是提醒;放在 Codex 侧,就可能变成下一步真实执行的命令。Skill 不是只影响表达,它会影响工具调用顺序。

Codex 侧的约束不是只有 Skill

我现在看 Codex 任务时,不会只看某个 Skill 本身。

至少有几层东西会一起影响它:

  • 当前会话权限:哪些命令能直接跑,哪些需要用户确认。
  • 项目规则:比如 .codex/rules 里的写作、审稿或工程约束。
  • 项目约定:如果代码项目里有 AGENTS.md,里面通常会写目录、测试、提交边界。
  • 当前任务描述:用户这次到底只让改哪里,还是允许顺手重构。
  • Skill 自己的工作流:文件定位、修改步骤、验证方式、交付标准。

这些东西有优先级冲突时,我更相信当前权限和项目规则。比如 Skill 里写了"检查构建结果",但当前环境不允许直接跑构建命令,这一步就不该绕过去执行。更稳的写法是把退回方案写进 Skill:

如果项目允许构建,运行项目指定的构建命令;如果构建命令受限,优先运行类型检查或相关单测;如果验证命令都不能执行,必须在最终回复里说明原因,并用 diff 确认修改范围。

这段话看起来啰嗦,但它解决的是很实际的问题:模型不会因为 Skill 里有"验证"两个字,就默认所有命令都能跑。

技术类 Skill 里,我会写具体定位命令

Codex 侧的技术 Skill,我会比 Claude 侧多写一类东西:常用定位命令。

不是写"先搜索相关文件"。这句话太宽,最后经常搜出一堆无关结果。更有用的是把这个项目里稳定的入口写出来:

bash 复制代码
rg "useFormState" --type ts
rg "PaymentCallback" src/
rg "settingsStore" src test

这些命令不是为了显得专业,而是减少模型猜目录的机会。一个前端项目里,"状态管理入口"可能在 src/stores,也可能在 features/settings/model,还可能藏在 provider 里。让模型自己猜,通常比给它一条窄搜索更不稳定。

但定位命令也不能写得太宽。

我见过一种 Skill 写法,上来就让模型跑:

bash 复制代码
rg "settings"

这和没写差不多。它会把页面、文案、测试、路由、埋点全搜出来,最后模型反而更容易把任务范围扩大。好的定位命令应该服务这次任务的第一步判断:我要找的是组件入口、状态入口、接口入口,还是测试入口。

所以我会在 Skill 里把命令按目的拆开:

目的 命令示例 用来判断什么
找组件入口 rg "UserSettingsPanel" src 这次任务主要改哪个 UI 文件
找状态入口 rg "settingsStore" src test 是否真的需要碰状态层
找测试覆盖 rg "UserSettingsPanel" test src --glob "*test*" 有没有相关断言能验证
找相邻实现 rg "loading" src/features/settings 当前模块已有模式是什么

这类命令不保证模型一定写对代码,但能把它拉回项目已有结构里。

修改范围要写成硬边界

我现在不太喜欢在 Skill 里写"修改相关文件"。这句话对人来说没问题,对执行代理来说太松。

"相关"可以被解释得很宽。改 loading 状态时,组件相关、store 相关、provider 相关、接口相关、测试相关,全都能算相关。最后 diff 变大,测试也可能过,但任务已经变形。

更稳的写法是把边界写硬一点:

默认只改当前任务指定文件和直接验证所需文件。不改配置、不迁移目录、不重构状态体系、不改公共 provider。除非当前任务明确要求,或者先说明为什么必须扩大范围。

这句话的价值不是禁止模型做正确修复。它是在要求模型扩大范围之前先停一下,把理由暴露出来。

我尤其会盯三类文件:

  • 配置文件:package.json、构建配置、CI 配置。
  • 公共入口:全局 provider、路由、store 聚合入口。
  • 跨模块共享文件:公共 hook、通用组件、基础工具函数。

这些文件不是不能改,但不应该被 Skill 顺手带着改。因为一旦改动出现在这些位置,影响面就不再是当前任务本身。

验证边界比"跑测试"更重要

Codex 侧 Skill 里,我会把验证写得具体一点。

只写"完成后跑测试"不够。它没有回答三个问题:

  • 跑哪个测试。
  • 测试不能跑怎么办。
  • 测试通过后还要不要看 diff。

我现在更愿意写成这种格式:

text 复制代码
验证顺序:
1. 优先运行与本次修改直接相关的测试。
2. 如果项目有类型检查且当前环境允许,运行类型检查。
3. 如果测试或类型检查因为权限、依赖或环境失败,不要假装已验证;说明失败原因。
4. 最后检查 diff,确认没有改到任务外文件。

这里的 diff 检查很关键。它不是功能验证,不能证明代码一定正确。但它能拦住另一类问题:模型把任务做大了。

比如一条 UI loading 修复,理想 diff 应该很小。哪怕测试全绿,如果 diff 里出现了 provider 重写,我也会停下来复看。Skill 里把这一步写明,能让 Codex 在收尾时多做一次范围自检。

不要让 Skill 推着模型越权执行

Skill 写得越详细,越容易出现另一个问题:模型把里面每一步都当成应该完成的任务。

但有些步骤本来就依赖权限和上下文。比如:

  • 安装依赖。
  • 改数据库 migration。
  • 跑部署脚本。
  • 修改 CI。
  • 重写配置。
  • 批量格式化整个项目。

这些动作不应该被 Skill 默认推动执行。它们要么需要用户确认,要么需要当前任务明确要求。

我会在 Codex 侧 Skill 里直接写:

不要为了让验证通过而自动安装新依赖、改全局配置、跳过权限限制或扩大重构范围。遇到这类需要时,先说明原因和影响,再等待确认。

这不是保守,而是把执行风险还给人来判断。Skill 可以沉淀经验,但不能替用户授权。

我会用任务后的 diff 反过来修 Skill

Codex 执行完一次任务后,最值得看的不是它最后那段总结,而是 diff。

如果 diff 里反复出现不该改的文件,说明 Skill 的修改边界写得太软。如果任务经常"完成了但没跑验证",说明验证步骤写得太空。如果模型总是先搜一大堆无关文件,说明定位命令太宽。

我一般会按这个顺序回查:

  1. 这次任务的入口文件找对了吗。
  2. diff 是否只覆盖当前任务需要的文件。
  3. 验证命令有没有跑,没跑有没有说明原因。
  4. 是否触碰了配置、公共入口或跨模块共享文件。
  5. Skill 里哪一句话给了它扩大范围的空间。

然后只改 Skill 里最小的一段。可能是补一句"不要改 provider",可能是把 rg "settings" 改成更窄的搜索,也可能是把"跑测试"改成具体的验证顺序。

Codex 侧我最在意的不是 Skill 写得多完整,而是它能不能稳住三件事:先找到正确文件,只改该改的范围,最后把验证和没验证的部分说清楚。

表面上看,这是在写一份 SKILL.md。实际是在给一个会读文件、会改代码、会跑命令的执行代理加护栏。Claude 侧更多是在防止进错上下文;Codex 侧更像是在防止它进场之后跑过界。

相关推荐
前端冒菜师2 小时前
别急着做 Agent,AI 工程化的第一步是 Skill 化
架构·ai编程
用户484526255822 小时前
NLP 任务不需要机器学习,几行代码调用 API 就够了
ai编程
kongba0073 小时前
Agent 专项对话索引随时补充,便于查询
ai编程
程序员黑豆3 小时前
AI全栈开发之Java:第一个Java程序
前端·后端·ai编程
李广坤4 小时前
Java AI 框架三剑客:Spring AI、Spring AI Alibaba、AgentScope 深度对比
ai编程
咖啡星人k4 小时前
MonkeyCode 的 Git 集成:AI编程如何与版本控制无缝协作
git·ai编程·monkeycode
搬砖的码农5 小时前
造一个 Agent 运行时 #01:我决定开干,顺便把坑都写下来
前端·agent·ai编程
打呵欠的猫5 小时前
新人入职第一天,代码写得像干了三年的老员工:我只做了一件事
ai编程
迷途小羔羊6786 小时前
Qoder(通义灵码)使用实践2-创建并使用skill
ai编程