目录
我的博客里这批译文一共 25 篇原文对照:23 篇来自 Matthieu Riegler,另有 Minko Gechev 和 Jake Archibald 各一篇。它们不是一篇一篇手动翻出来的,是一个 agent 批量产出的。
其中 13 篇的发布时间戳落在 2026-05-30 的 14:20 到 14:35 之间——15 分钟挤进 13 篇,当天一共 19 篇。这个数字不是效率炫耀,它只是说明了一件事:当你把重复劳动固化成流程之后,产出速度就不再由你的耐心决定了。
这篇文章讲的不是「怎么让 AI 翻译得更好」,而是把一件重复的事变成工程问题的过程,包括它在哪里翻了车。
为什么值得做成 agent
手工翻译一篇技术博客,实际动作是这些:
- 打开原文,通读
- 新建 markdown 文件,写 frontmatter(标题、日期、slug、tags、描述、canonical URL)
- 逐段翻译,代码块保持原样
- 把原文里的图片一张张下载到本地,改写引用路径
- 单独存一份英文原文,供对照阅读
- 检查有没有漏段
其中只有第 3 步需要判断力,剩下 5 步全是机械操作。而且每篇都一模一样。
一篇的时候你会觉得「顺手就做了」。到第五篇,你开始烦。到第十篇,你会开始偷懒——比如图片先热链着吧,比如原文就不存了吧。质量下滑不是因为能力不够,是因为重复消耗掉了注意力。
这正是 agent 该接手的地方:把那 5 步机械操作写死,让每一篇的产出质量不依赖当时的耐心。
Agent 是怎么设计的
文件在 .github/agents/blog-translator.agent.md,4.8KB。核心不是提示词技巧,是把整个流程拆成不可跳过的步骤,并且写清楚每一步的产出物长什么样。
几个关键设计:
双文件产出
每篇翻译产出两个文件,不是一个:
src/content/blog/<category>/<slug>.md # 译文
src/content/originals/<slug>.md # 英文原文
这是为了博客的原文对照功能。译文里 isTranslation: true,站点就会在文章页启用对照阅读器,从 originals/ 里按同名 slug 取原文。
这个设计有个副作用我当时没想到:它让「有没有漏译」变成一个可机械检查的问题。 两个文件都在仓库里,行数比、代码块数量、标题数量都能直接比对。后来我写内容检查脚本时,这一条成了最有用的校验。
我抽查了这 25 对文件的行数比,全部落在 1.03 到 1.18 之间(中文比英文行数略多是正常的)。没有一篇出现腰斩式的漏译。
图片必须本地化
- Download each image to `public/blog-images/<slug>/` using terminal commands.
- Update the image references to point to `/blog-images/<slug>/<filename>`.
- If an image cannot be downloaded, keep the original URL and add a comment noting the failure.
热链源站的图片是技术博客的常见坑:源站改版、防盗链、域名过期,你的文章就变成一堆碎图。
这一条执行得很彻底。我检查了整个 src/content/blog/frontend/angular/ 目录,仍有热链的只有两篇——angular-change-detection 和 translate-angular-interceptors,都是这条流水线之前的老文章。流水线产出的图片都落在本地,public/blog-images/ 下现在有 16 个目录。
默认 draft: true
ALWAYS set `draft: true` in the frontmatter so the author can review before publishing.
这条是整个 agent 定义里最重要的一行。
它不提升任何效率,纯粹是踩刹车。意思是:agent 可以批量产出,但不能批量发布。25 篇全部先落进仓库的草稿状态,由我决定哪些放出去。
后来这条救过我一次,下面会讲。
术语和格式的约定
- 常见技术名词保留英文(React、Angular、API、Docker)
- 代码块逐字复制,只翻译注释,不动逻辑和变量名
- 保留原文的标题层级、列表、引用、表格
- 外链保留原 URL,但链接文字翻成中文
这些不是风格偏好,是减少每篇之间的随机差异。没有这些约定,25 篇会呈现 25 种翻译风格。
状态管理:25 篇不可能一次跑完
这是我觉得比 agent 定义本身更值得说的一点。
翻译 25 篇不是一次会话能完成的事。中间会断、会重启、会隔好几天。所以必须有个东西记住「哪些翻完了,哪些还没」,而且这个东西得在仓库里,不能在对话历史里。
我建了 docs/riegler-angular-translation-tracker.md:
| Date | Source URL | Local Slug | Status |
| ---------- | ------------------------------------------------------ | ------------------- | ------ |
| 2023-07-20 | https://riegler.fr/blog/2023-07-20-angular-memory-leak | angular-memory-leak | done |
| 2023-09-18 | https://riegler.fr/blog/2023-09-18-cldr-angular | cldr-angular | done |
...
一行一篇,翻完改状态。听起来很土,但它解决的是真实问题:
- 新开一个会话,AI 读这个文件就知道进度,不用我重新交代
- 我自己隔一周回来,也知道停在哪
- 不会重复翻译同一篇
从 git 记录看,这 25 篇实际是分四次提交完成的:5-27 三篇,5-30 二十篇,6-02 一篇,7-26 一篇。跨度两个月。没有这个 tracker,第二次续上就得从头理一遍。
结论:批量任务的状态必须落在仓库里,不能留在会话里。 会话会丢,仓库不会。
质量在哪里掉链子
前面都是顺利的部分。现在说砸的地方。
cldr 那篇的代码块
2026-07-11,也就是翻译完成一个多月后,我提了一个叫 fix: clean up cldr article formatting 的 commit,改了 539 行。
问题长这样。译文里的代码块变成了:
```
import '@angular/common/locales/global/fr'
;
bootstrapApplication
(App, {providers: [
{provide: LOCALE_ID
, useValue: 'fr'
}
]
}
)
;
```
应该是:
```ts
import "@angular/common/locales/global/fr";
bootstrapApplication(App, {
providers: [{ provide: LOCALE_ID, useValue: "fr" }],
});
```
代码被拆成了支离破碎的换行,而且代码块没标语言,导致语法高亮也没了。
原因是原文那篇的代码块在 HTML 里的结构比较特殊,抓取时按错误的边界切了行。agent 定义里写了「代码块逐字复制」,但它没有能力验证「逐字复制的结果是不是还能读」。
这就是这套流水线的能力边界:它能保证流程不漏步,不能保证每步的产出都对。
而且这个问题拖了一个多月才被发现——因为我没有逐篇细看,而 24 篇都是好的,抽查很容易抽不到那一篇。
那条 draft 规则救了什么
如果 agent 直接发布,这篇乱码代码会在线上挂一个多月。因为 draft: true,它至少经过了我按下发布键这一步。
当然我还是放过去了——说明人工 review 也会失效。但这条规则至少留了一道门,而门比没门强。
值不值得
省下的时间不好精确算,但可以估。手工翻一篇 3000 字左右的技术文章,含图片处理和格式整理,我大概需要 2-3 小时。25 篇就是 50-75 小时。
实际投入:写 agent 定义大概 2 小时,跑批和 review 大概 10 小时,事后修 bug 2 小时。
但我觉得更值得说的不是省时间,而是它让一件本来不会做的事变得可行。翻 25 篇这个念头,如果按 50 小时估算,我根本不会开始。能开始,是因为它变成了 5 小时能启动的事。
AI 真正改变的不是「同样的事做得更快」,是「原本不划算的事变得划算」。
这条流水线现在该停了
写这篇的时候我意识到一件事:源头枯竭了。
tracker 里最后一篇是 2025-04-05 的 input-output,之后 riegler.fr 就没有新的 Angular 文章了。整张表全是 done。
也就是说,这条流水线已经把能翻的都翻完了。继续维护它没有意义。
这反而是个好的时间点。翻译是理解别人的输出,做得再工整也是二手的。中文圈几乎没人做 PR / commit 级别的 Angular 机制解析,而我手上有一样别人没有的东西——一个真实的 Angular + Node BFF 生产项目。「这个新特性在我们的生产环境里能不能用、为什么不能用」,这种内容不可替代。
所以下一步是从「译」转到「写」。8 月我先把家庭服务器这一组写完了,Angular 的月度跟踪从本周开始记。这个 agent 完成了它的使命,可以退休了。
如果你也想做类似的事
几条我认为可迁移的:
- 先数一下有几步是机械的。 如果一件事里超过一半的步骤不需要判断力,且要重复五次以上,就值得固化。
- 写禁令,别写技巧。 「图片必须下载到本地」「默认 draft: true」这种约束,比任何提示词技巧都有效。约束是不变量,技巧是一次性的。
- 状态放仓库,不放会话。 一个 markdown 表格就够。
- 设计能被机械检查的产出。 我当初做双文件是为了对照阅读,意外收获是漏译变得可检测。如果产出结构本身支持校验,质量兜底就便宜很多。
- 接受它会翻车,但要有一道门。
draft: true不提升效率,它只是确保出错时你还有机会拦住。
最后一条最重要:这套东西的价值不在于 AI 翻得多好,而在于它让产出质量不再依赖你当时的耐心。第 25 篇和第 1 篇走的是同一条流水线。