Skip to content

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/ 目录下:

markdown
# 这是一个 Skill 的描述标题

你负责 [任务目标]。执行以下步骤:

1. [第一步做什么]
2. [第二步做什么]
3. [检查条件]
4. [输出格式要求]

注意事项:
- [安全边界]
- [不要做什么]
- [处理异常的方式]

关键原则

  • 用第二人称"你"——Skill 的内容会被注入到 AI 的系统提示中
  • 步骤要具体——"遍历目录"比"处理文件"清晰 10 倍
  • 明确输出格式——最后要生成什么报告?

2.2 如何调用 Skill

bash
# 直接调用指定 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
你负责将一批 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)` 和图片 `![alt](url)`
- 对本地文件链接(相对路径、绝对路径),检查目标文件是否存在
- 对外部链接,记录但不修改——由人工后续确认
- 对内部的 Notion 链接(https://notion.so/xxx),标记为 `<!-- TODO: 需要更新链接 -->`
- 生成链接验证报告

### 5. 标签统一
- 所有标签统一为英文 lowercase
- 用逗号分隔:[tag1, tag2, tag3]
- 移除重复标签
- 基于文章内容推荐 2-3 个可能缺失的标签(但不自动添加)

## 输出
处理完成后输出统计报告:
- 处理文件总数:X
- 新增 frontmatter:Y 个
- 修正标题层级:Z 处
- 发现失效内部链接:W 个
- Markdown 文件列表:列出所有被修改的文件
- 建议添加标签:按文件列出

## 安全规则
- 不要删除任何文件
- 不要修改代码块(``` 内的内容)
- 不要修改 .git、node_modules 目录下的文件
- 每个文件修改前后做一次 diff 确认

执行

bash
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

markdown
你负责批量修复 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(语法不破坏)

执行

bash
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

markdown
你负责将英文技术文档批量翻译为中文。严格遵循以下规则:

## 翻译规则

### 保持不变的内容
- 所有代码块(``` 和 ` 包裹的内容)
- HTML 标签和属性
- Markdown 链接的 URL 部分:`[要保持翻译的文本](https://url 保持不变)`
- 图片路径:`![alt 可翻译](path 保持不变)`
- 专业术语保持英文原词: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 等)

执行

bash
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

markdown
你负责从 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": "[email protected]",
  "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 开头加入编码检查:

markdown
## 执行前检查
- 读取每个文件前,先用 `file` 命令检查编码
- 对于非 UTF-8 文件,用 `iconv` 转为 UTF-8 后再处理
- 原始编码的文件保留备份

4.3 大文件处理

如果一个 Markdown 超过 5000 行,AI 可能无法一次完整读取。解决方案:

  • 在 Skill 中规定:"超过 3000 行的文件跳过并记录到报告中"
  • 对于必须处理的大文件,用分片策略

4.4 限流问题

批量处理 200 个文件可能触发 API 限流。应对策略:

markdown
## 速率控制
- 每处理 10 个文件,等待 5 秒
- 如果遇到 rate limit 错误,等待 30 秒后重试
- 记录已处理的文件列表,支持断点续传

4.5 AI 可能犯的错误

以下是我亲身经历的 AI 批量处理失误:

  1. 路径错误:AI 用错了文件路径分隔符(Windows \ vs Unix /),导致一批文件被复制到奇怪的位置
  2. 范围扩大:Skill 说"处理 src/ 下的 TS 文件",但没有排除 src/generated/,导致自动生成的代码被手动修改
  3. 格式破坏:AI 在某些文件中引入了不规范的 Markdown 语法
  4. 内容丢失:一次批量操作中,AI 在修改一个文件时意外删除了一个代码块

防御措施:使用 --plan 模式先预览所有变更,确认后再执行。对于高风险操作,要求 AI 在处理每个文件前后进行 diff 确认。


五、思维转变:从"写脚本"到"描述变换"

这是使用 AI 批量处理最重要的认知跃迁。

传统编程思维:"我需要遍历文件列表 → 对每个文件读取内容 → 解析 frontmatter → 如果缺失就生成新的 → 写回文件 → 统计结果"

AI 批量处理思维:"去遍历这个目录的所有 md 文件,检查每个文件是否有标准的 frontmatter,没有就根据文件内容生成一个,最后告诉我处理了多少个"

你不再是写执行逻辑的人,而是定义验收标准的人。 这是质的飞跃——你的角色从"程序员"变成了"质量监督员"。

什么时候不该用 AI 做批量处理?

不是所有批量操作都适合用 AI:

任务类型用 AI用传统工具
确定性文本替换❌ 浪费sed/awk 秒完成
模式匹配的重命名❌ 浪费renamemmv
文件格式转换❌ 浪费pandoc 一行搞定
需要内容理解的操作✅ 最佳几乎不可能
创意性内容生成✅ 最佳无法自动化
从非结构化文本提取结构化数据✅ 最佳编程复杂度过高

判断标准:如果规则完全确定、不依赖语义理解 → 用传统工具。如果需要理解内容、需要判断、需要"看着像那么回事" → 用 AI。


六、高级模式

6.1 Skill 链式调用

bash
# 先格式化 Markdown → 再添加 frontmatter → 最后验证链接
opencode run "依次执行 format-markdown、add-frontmatter、validate-links 三个 skill,处理 ~/docs/"

链式调用的关键在于:前一个 Skill 的输出构成了后一个 Skill 的输入基础。例如,format-markdown 统一了标题层级后,add-frontmatter 才能从 H1 准确提取 title。

6.2 条件处理

markdown
## 条件判断
- 如果文件修改时间在 2026 年之前 → 归档处理(添加 archived: true)
- 如果文件包含 "TODO" 关键字 → 收集到待办清单
- 如果文件大小 < 100 字节 → 可能为空文件,标记但不处理

6.3 元数据提取与汇总

这可能是批量处理最有价值的副产品:

markdown
## 额外分析
- 提取所有 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"。

给你的行动建议

  1. 从现在开始,找一个你最近需要重复操作的任务
  2. 花 15 分钟写一个 Skill 文件,用本文的模板
  3. 先用 --plan 模式预览效果
  4. 小范围测试 5 个文件
  5. 确认无误后跑全量
  6. 人工抽查 20% 的结果
  7. 把经过验证的 Skill 保存到你的 Skill 库

第一次你可能觉得写 Skill 比直接手动做还慢。做到第五次的时候,你就再也回不去没有 Skill 的日子了。

基于 VitePress 构建 | 部署于 Cloudflare Pages