AI 批量文件处理大师课:用 Codex + Skill 把 100 次重复操作变成一句话
你有没有过这种经历——面对 200 个 Markdown 文件,每个都需要加 frontmatter;或者 50 个 TypeScript 文件,import 顺序全乱了;又或者一个新接手的项目,所有错误处理都需要统一格式?
这种时候你会怎么做?
- Shell 脚本:写得动,但处理结构性内容(如"根据文章内容自动生成标签")几乎不可能
- 写个 Node/Python 程序:能做,但为了一次性任务写 200 行代码,写完自己都不想维护
- 手动改:别开玩笑了
我在 2024 年底发现了第三种解法:用 AI 的 Skill 系统描述你要做什么,让它自己去执行。这不是"让 AI 帮你写脚本"——而是"让 AI 成为脚本本身"。这篇文章是我用这种范式处理了几十个批量任务后的完整方法论。
一、为什么是 Codex + Skill 而不是别的方案?
先交代清楚工具选择。Codex(OpenAI 开源的 CLI 编码助手)是一个支持 Skill 机制的 AI 编码助手。Skill 本质上是一份 Markdown 格式的"任务说明书",告诉 AI 要做什么、怎么做、边界在哪里。
和直接对着 ChatGPT/Claude 说"帮我批量改文件"相比,Skill 的核心优势:
| 维度 | 直接对话 | Codex Skill |
|---|---|---|
| 可重复性 | 每次都要重新描述 | 写一次,反复用 |
| 执行精度 | 容易遗漏步骤 | 严格按 Skill 指令执行 |
| 安全控制 | 无法限制 AI 行为 | 可在 Skill 中定义边界 |
| 文件操作 | 需要手动上传/复制 | 直接操作本地文件系统 |
| 团队共享 | 无法共享工作流 | Skill 文件可 commit 到仓库 |
换句话说,Skill 把"提示词工程"变成了"工作流工程"。你不再关心怎么措辞让 AI 理解你——你直接写操作步骤。
二、Skill 系统基础
2.1 Skill 文件的结构
一个 Skill 文件就是一个 Markdown,放在 ~/.opencode/skills/ 目录下:
# 这是一个 Skill 的描述标题
你负责 [任务目标]。执行以下步骤:
1. [第一步做什么]
2. [第二步做什么]
3. [检查条件]
4. [输出格式要求]
注意事项:
- [安全边界]
- [不要做什么]
- [处理异常的方式]关键原则:
- 用第二人称"你"——Skill 的内容会被注入到 AI 的系统提示中
- 步骤要具体——"遍历目录"比"处理文件"清晰 10 倍
- 明确输出格式——最后要生成什么报告?
2.2 如何调用 Skill
# 直接调用指定 skill
opencode run "使用 add-frontmatter skill 处理 ~/blog/posts/ 下所有文件"
# 组合多个 skill(按顺序执行)
opencode run "依次执行 format-markdown 和 validate-links 两个 skill,处理 ~/docs/"
# 带条件的执行
opencode run "使用 lint-fix skill,只处理 src/ 下最近 7 天修改过的文件"
# dry-run 预览模式
opencode run --plan "使用 rename-slug skill 处理 ~/content/"三、四个真实场景完整演示
以下四个场景都是我在实际项目中遇到并解决的。每个场景附完整的 Skill 配置,你可以直接复制使用。
场景 A:批量整理 100+ 个 Markdown 文件
背景:我从 Notion 导出了 120 篇博客文章到 Markdown,但导出的文件乱七八糟——有的有 frontmatter 有的没有,标题层级混乱(有的是 H1 有的是 H2 开头),内部链接指向 Notion URL 而不是本地文件路径,tag 格式不统一(有的用 [tag1, tag2] 有的用 tag1, tag2)。
Skill 文件 ~/.opencode/skills/normalize-markdown.md:
你负责将一批 Markdown 文件规范化。严格执行以下步骤:
## 步骤
### 1. 遍历文件
遍历目标目录下所有 .md 文件,排除 node_modules、.git、_site 等目录。
### 2. 检查 Frontmatter
- 如果文件没有以 `---` 开头,需要根据文件内容和文件名添加 frontmatter
- 必须包含的字段:title(从第一个 H1 提取或从文件名推断)、date(从文件修改时间获取格式 YYYY-MM-DD)、tags(根据内容自动提取 3-5 个英文标签)
- 可选字段:description(从第一段提取摘要)、draft(默认 false)
- 已有 frontmatter 的文件:只统一字段名格式(date vs created_at),不改动内容
### 3. 标题层级修正
- 确保第一个标题是 H1(`# title`)
- 如果文件以 H2 开头,将它提升为 H1
- 确保标题层级不越级(H1 后必须是 H2,不能直接跳到 H3)
- 统计修正了多少处标题
### 4. 链接有效性验证
- 查找所有 Markdown 链接 `[text](url)` 和图片 ``
- 对本地文件链接(相对路径、绝对路径),检查目标文件是否存在
- 对外部链接,记录但不修改——由人工后续确认
- 对内部的 Notion 链接(https://notion.so/xxx),标记为 `<!-- TODO: 需要更新链接 -->`
- 生成链接验证报告
### 5. 标签统一
- 所有标签统一为英文 lowercase
- 用逗号分隔:[tag1, tag2, tag3]
- 移除重复标签
- 基于文章内容推荐 2-3 个可能缺失的标签(但不自动添加)
## 输出
处理完成后输出统计报告:
- 处理文件总数:X
- 新增 frontmatter:Y 个
- 修正标题层级:Z 处
- 发现失效内部链接:W 个
- Markdown 文件列表:列出所有被修改的文件
- 建议添加标签:按文件列出
## 安全规则
- 不要删除任何文件
- 不要修改代码块(``` 内的内容)
- 不要修改 .git、node_modules 目录下的文件
- 每个文件修改前后做一次 diff 确认执行:
opencode run "使用 normalize-markdown skill 处理 ~/blog/posts/ 下所有文件"实际效果(来自我的一次真实运行):
- 处理 127 个文件
- 为 64 个缺失 frontmatter 的文件补充完整
- 修正 18 处标题越级问题
- 发现 43 个失效链接(其中 31 个是 Notion 内部链接需要人工更新)
- 整个处理过程约 8 分钟完成
这 127 个文件如果手动处理,保守估计 4-6 小时。用 Skill 方案,8 分钟 + 写 Skill 文件 15 分钟 = 23 分钟。
踩过的坑:第一次运行时 Skill 没有写明"已有 frontmatter 的文件只统一字段名,不改内容",结果 AI 把一些我精心写好的 description 也重写了。教训:边界条件一定要在 Skill 里说清楚,不要指望 AI 自己判断。
场景 B:代码规范批量修复
背景:一个接手的老项目,150+ 个 TypeScript 文件,ESLint 报 400+ 个错误。大部分是 @typescript-eslint/no-explicit-any、import 顺序、缺少返回类型注解之类的问题。
Skill 文件 ~/.opencode/skills/lint-batch-fix.md:
你负责批量修复 TypeScript 代码规范问题。严格按照以下流程执行:
## 执行步骤
### 1. 问题发现
- 对目标目录运行 ESLint:`npx eslint --format json src/ > eslint-report.json`
- 解析 JSON 报告,按文件分组统计问题类型和数量
- 生成初始统计表
### 2. 分类处理策略
#### 可自动修复(auto-fixable)
- 直接使用 Edit 工具逐个修复
- 包括:import 排序、trailing comma、semicolon、indentation、quotes
#### 半自动修复(需要理解代码)
- 需要在 Skill 中明确规则的:
- `@typescript-eslint/no-explicit-any`:根据上下文推断类型,优先使用 `unknown` 而非 `any`
- 缺少返回类型注解:分析函数体推断返回类型并添加
- `no-unused-vars`:删除未使用的导入和变量
- `prefer-const`:将未重新赋值的 let 改为 const
#### 需人工审查(标记但不修改)
- `@typescript-eslint/no-unsafe-assignment`
- `@typescript-eslint/no-unsafe-member-access`
- 涉及安全敏感的警告
- 标记为 manual_review,附上文件路径:行号和建议修改方案
### 3. 输出报告
生成 CSV 文件 `lint-fix-report.csv`:文件路径, 初始问题数, 已修复, 需人工审查, 状态 src/components/Header.tsx, 8, 6, 2, partial src/utils/api.ts, 15, 12, 3, partial src/pages/Home.tsx, 3, 3, 0, done
总计行:总计, X, Y, Z
## 安全规则
- **绝对不要修改** `.eslintrc.js`、`.eslintrc.json`、`eslint.config.js`、`tsconfig.json`
- **不要删除** 任何文件
- **不要修改** node_modules、dist、build 目录
- 每个文件修改不超过 20 处(超过则标记为需分批处理)
- 修改前后确保文件仍然是有效的 TypeScript(语法不破坏)执行:
opencode run "使用 lint-batch-fix skill 批量修复 ~/project/src/ 下所有 TS 文件的 ESLint 错误"实际效果:150 个文件 → 412 个问题 → 自动修复 298 个 → 标记需人工 114 个。完成时间约 25 分钟。人工修复剩余 114 个约 1.5 小时。总耗时不到 2 小时 vs 纯手动预计 6-8 小时。
踩过的坑:有一次 Skill 没有明确说"不要修改 eslintrc",AI 自作主张把规则调松了。这是最危险的 AI 行为——从根源上"解决"问题而不是修复代码。所以现在我的所有 lint Skill 第一条安全规则就是:绝对不要修改 ESLint/Prettier/tsconfig 配置。
场景 C:批量翻译与本地化
背景:一个开源项目的文档需要从英文翻译到中文,一共 45 个 Markdown 文件。代码块不能翻译,API 名称不能翻译,链接不能断。
Skill 文件 ~/.opencode/skills/i18n-translate.md:
你负责将英文技术文档批量翻译为中文。严格遵循以下规则:
## 翻译规则
### 保持不变的内容
- 所有代码块(``` 和 ` 包裹的内容)
- HTML 标签和属性
- Markdown 链接的 URL 部分:`[要保持翻译的文本](https://url 保持不变)`
- 图片路径:``
- 专业术语保持英文原词:API、SDK、CLI、JSON、YAML、HTTP、CSS、npm、Node.js、React、Vue、TypeScript、Promise、async/await、WebSocket
- Frontmatter 中的 slug、permalink、date 等字段值
### 翻译要求
- 技术准确 > 文学优美
- 句子结构可调整以符合中文习惯,但含义必须精确
- 代码注释也需要翻译(`// This is a comment` → `// 这是一个注释`)
- 如果遇到不确定的技术术语,使用「保留英文并加中文注释」的格式
### 输出规则
- 输出文件保存为 `原文件名.zh-CN.md`(如 `README.md` → `README.zh-CN.md`)
- 如果 `原文件名_zh.md` 已存在,则修改为 `原文件名.zh-CN.md` 格式
- 跳过以上述格式命名的文件(避免重复翻译)
## 执行步骤
1. 遍历目录下所有 .md 文件
2. 跳过以 `.zh-CN.md` 结尾或包含 `_zh.` 的文件
3. 对每个文件执行翻译
4. 翻译完成后生成 `translation-report.csv`:源文件, 目标文件, 词数, 状态, 备注 getting-started.md, getting-started.zh-CN.md, 1240, done, - api-reference.md, api-reference.zh-CN.md, 3500, done, 包含大量代码块
## 安全规则
- 保持文件编码为 UTF-8
- 不要修改源文件
- 不要翻译 frontmatter 中的技术字段值(slug、date、draft 等)执行:
opencode run "使用 i18n-translate skill 将 ~/project/docs/ 下所有英文 Markdown 翻译为中文"实际效果:45 个文件,总计约 35000 词。AI 翻译耗时约 18 分钟。人工校对修正约 20 处术语问题(主要是一些框架特有的名词),额外花费 40 分钟。质量相当于专业人工翻译的 85-90%,远好于 Google 翻译的 60%。
一句实话:AI 翻译技术文档的质量已经很高了,但它对术语的一致性问题仍需注意。同一个英文术语在不同文件中可能被译成不同的中文,这在人工校对时需要特别关注。建议在 Skill 中加入一个术语表。
场景 D:从代码注释生成 API 文档
背景:一个有 80+ 个 API 路由的 Express 后端项目,JSDoc 注释已经写好了,但一直没人维护单独的 API 文档。需要从注释中提取信息生成文档。
Skill 文件 ~/.opencode/skills/generate-api-docs.md:
你负责从 TypeScript 源码的 JSDoc 注释中提取信息,生成 API 文档。
## 执行步骤
### 1. 扫描源文件
遍历 `src/routes/` 和 `src/controllers/` 下所有 .ts 文件。
### 2. 提取 API 端点信息
对每个路由定义,提取:
- HTTP 方法 + 路径(从 router.get/post/put/delete 等)
- 功能描述(从 JSDoc @description 或注释第一行)
- 请求参数(从 @param、@query、@body 等 JSDoc 标签)
- 请求体示例(从 @example 标签)
- 响应格式(从 @returns 标签)
- 认证要求(从 @auth 或 @requiresAuth 等自定义标签)
- 错误码说明(从 @throws 标签)
### 3. 生成文档
生成一个 `API.md` 文件,结构如下:
```markdown
# API 文档
> 自动生成于 {当前日期} | 从 {文件数} 个源文件提取
## 目录
[自动生成目录]
## 端点列表
### POST /api/users
**描述**:创建新用户
**认证**:需要 Bearer Token(Admin 角色)
**请求体**:
\`\`\`json
{
"email": "string (必填)",
"name": "string (必填)",
"role": "user | admin (选填,默认 user)"
}
\`\`\`
**成功响应** (201):
\`\`\`json
{
"id": "uuid",
"email": "user@example.com",
"name": "张三",
"createdAt": "2026-05-31T10:00:00Z"
}
\`\`\`
**错误响应**:
- 400: 参数验证失败
- 409: 邮箱已存在
- 403: 权限不足4. 信息不完整处理
- 缺少描述的端点 → 标记
⚠️ 待补充并在报告中列出 - 缺少请求示例的 → 标记
📝 需要示例 - 缺少错误码说明的 → 标记
⚠️ 错误码待完善
输出
- API.md:完整文档
- api-doc-report.csv:文档完整性统计
安全规则
- 不要修改任何源代码文件
- 如果 JSDoc 中包含
@internal或@private标记,跳过该端点 - 不要将包含敏感信息的注释写入文档(如密码示例、内网地址)
**执行**:
```bash
opencode run "使用 generate-api-docs skill 从 ~/project/src/ 生成 API 文档"实际效果:从 80+ 个路由定义中生成了结构化的 API 文档,包含 67 个已记录的端点和 13 个标记为"待补充"的端点。整个过程约 12 分钟。
一个重要发现:这个过程不仅生成了文档,还暴露了代码中的知识缺口——13 个端点缺少足够的 JSDoc 注释。这成为了后续编码规范改进的起点。
四、常见陷阱与安全守则
经过几十次批量处理任务,我总结了一套必须遵守的原则:
4.1 黄金法则
1. 永远先 --dry-run / --plan
2. 永远先 git commit 当前状态
3. 永远先小范围测试(5-10 个文件)
4. 永远不要让 AI 修改配置文件4.2 文件编码问题
这是我在处理中文文件时反复踩的坑。某些 Markdown 文件是 GBK 编码(从 Windows 系统导出),AI 用 UTF-8 读会乱码,然后"修复"这些乱码——制造更大的问题。
解决方案:在 Skill 开头加入编码检查:
## 执行前检查
- 读取每个文件前,先用 `file` 命令检查编码
- 对于非 UTF-8 文件,用 `iconv` 转为 UTF-8 后再处理
- 原始编码的文件保留备份4.3 大文件处理
如果一个 Markdown 超过 5000 行,AI 可能无法一次完整读取。解决方案:
- 在 Skill 中规定:"超过 3000 行的文件跳过并记录到报告中"
- 对于必须处理的大文件,用分片策略
4.4 限流问题
批量处理 200 个文件可能触发 API 限流。应对策略:
## 速率控制
- 每处理 10 个文件,等待 5 秒
- 如果遇到 rate limit 错误,等待 30 秒后重试
- 记录已处理的文件列表,支持断点续传4.5 AI 可能犯的错误
以下是我亲身经历的 AI 批量处理失误:
- 路径错误:AI 用错了文件路径分隔符(Windows
\vs Unix/),导致一批文件被复制到奇怪的位置 - 范围扩大:Skill 说"处理 src/ 下的 TS 文件",但没有排除
src/generated/,导致自动生成的代码被手动修改 - 格式破坏:AI 在某些文件中引入了不规范的 Markdown 语法
- 内容丢失:一次批量操作中,AI 在修改一个文件时意外删除了一个代码块
防御措施:使用 --plan 模式先预览所有变更,确认后再执行。对于高风险操作,要求 AI 在处理每个文件前后进行 diff 确认。
五、思维转变:从"写脚本"到"描述变换"
这是使用 AI 批量处理最重要的认知跃迁。
传统编程思维:"我需要遍历文件列表 → 对每个文件读取内容 → 解析 frontmatter → 如果缺失就生成新的 → 写回文件 → 统计结果"
AI 批量处理思维:"去遍历这个目录的所有 md 文件,检查每个文件是否有标准的 frontmatter,没有就根据文件内容生成一个,最后告诉我处理了多少个"
你不再是写执行逻辑的人,而是定义验收标准的人。 这是质的飞跃——你的角色从"程序员"变成了"质量监督员"。
什么时候不该用 AI 做批量处理?
不是所有批量操作都适合用 AI:
| 任务类型 | 用 AI | 用传统工具 |
|---|---|---|
| 确定性文本替换 | ❌ 浪费 | sed/awk 秒完成 |
| 模式匹配的重命名 | ❌ 浪费 | rename 或 mmv |
| 文件格式转换 | ❌ 浪费 | pandoc 一行搞定 |
| 需要内容理解的操作 | ✅ 最佳 | 几乎不可能 |
| 创意性内容生成 | ✅ 最佳 | 无法自动化 |
| 从非结构化文本提取结构化数据 | ✅ 最佳 | 编程复杂度过高 |
判断标准:如果规则完全确定、不依赖语义理解 → 用传统工具。如果需要理解内容、需要判断、需要"看着像那么回事" → 用 AI。
六、高级模式
6.1 Skill 链式调用
# 先格式化 Markdown → 再添加 frontmatter → 最后验证链接
opencode run "依次执行 format-markdown、add-frontmatter、validate-links 三个 skill,处理 ~/docs/"链式调用的关键在于:前一个 Skill 的输出构成了后一个 Skill 的输入基础。例如,format-markdown 统一了标题层级后,add-frontmatter 才能从 H1 准确提取 title。
6.2 条件处理
## 条件判断
- 如果文件修改时间在 2026 年之前 → 归档处理(添加 archived: true)
- 如果文件包含 "TODO" 关键字 → 收集到待办清单
- 如果文件大小 < 100 字节 → 可能为空文件,标记但不处理6.3 元数据提取与汇总
这可能是批量处理最有价值的副产品:
## 额外分析
- 提取所有 frontmatter 中的 tags,生成标签云统计
- 统计所有文章的字数和阅读时间估算
- 找出所有相互引用但目标不存在的链接
- 生成按日期排序的文章索引我通过这种元数据分析发现了一个项目中有 23 篇文章相互引用但链接全部 404——这是在文件级别逐个检查几乎不可能发现的问题。
七、我的个人工作流
这套方法已经深深嵌入了我的日常工作:
日常编码 → 发现重复性劳动 → 问自己:这能 Skill 化吗?→ 能 →
花 10 分钟写 Skill → 用 --plan 预览 → 满意 → 执行 → 人工抽查 20% → Done我维护了一个 Skill 库 ~/.opencode/skills/,目前有 12 个 Skill:
~/.opencode/skills/
├── normalize-markdown.md # Markdown 标准化
├── lint-batch-fix.md # ESLint 批量修复
├── i18n-translate.md # 文档翻译
├── generate-api-docs.md # API 文档生成
├── add-frontmatter.md # Frontmatter 补充
├── validate-links.md # 链接验证
├── format-prettier.md # Prettier 格式化
├── upgrade-deps.md # 依赖批量更新
├── generate-changelog.md # 生成 CHANGELOG
├── refactor-to-async.md # 回调 → async/await
├── add-unit-tests.md # 批量添加单元测试
└── i18n-key-extract.md # 国际化 key 提取每个 Skill 平均经过 3-5 次迭代才稳定下来。迭代的过程就是不断在 Skill 中添加边界条件处理。
八、总结
批量处理的核心永远不会变——你还是需要有清晰的输入、输出和执行步骤。但 AI Skill 系统把这个过程从"编写执行逻辑"变成了"定义执行规范"。
最让我震惊的不是效率提升(虽然确实提升了 5-20 倍),而是它改变了我的思维方式。以前遇到重复性任务,我的本能反应是"又要加班了"。现在的反应是"这个场景可以写一个 Skill"。
给你的行动建议:
- 从现在开始,找一个你最近需要重复操作的任务
- 花 15 分钟写一个 Skill 文件,用本文的模板
- 先用
--plan模式预览效果 - 小范围测试 5 个文件
- 确认无误后跑全量
- 人工抽查 20% 的结果
- 把经过验证的 Skill 保存到你的 Skill 库
第一次你可能觉得写 Skill 比直接手动做还慢。做到第五次的时候,你就再也回不去没有 Skill 的日子了。