1. 批量写技术博文,为什么“写”和“审”必须拆开
如果你用 AI 批量生成过技术博文,大概率遇到过这种场景:一次性让模型写 10 篇,前 3 篇看着还行,到第 5 篇开始出现结构塌陷、代码缺版本号、段落之间开始互相“串味”,最后几篇干脆变成同义反复。问题不在于模型能力不够,而在于写和审混在同一个上下文里——写的人(同一个 agent)天然会为自己的产出辩护,审的时候看到“自己刚写的东西”,标准会不自觉放松。
tech-batch 就是为解决这个问题设计的一个 OpenCode skill。它把“批量写技术博文”拆成两个独立阶段:写 agent 只负责产出初稿,审 agent 只负责按固定清单核验,两者上下文完全隔离。审不过就打回重写,直到零阻塞项才进入下一篇。适合谁?适合需要稳定产出系列技术内容、又不想每篇都人工盯质量的开发者或内容团队。
我试过把 10 篇 AI Agent 系列文章全部丢进这个流程跑,平均每篇 1.8 轮写审循环,从启动到全部通过大约 3-5 分钟一篇。下面把可复制的 skill 配置骨架、审核清单和一次完整的批量触发操作拆开讲。
2. TaoToken 前置:给写审两个 agent 各配一把钥匙
写审分离的前提是:写 agent 和审 agent 是两次独立的模型调用,各自有独立的上下文。这意味着你需要一个稳定的 API 入口来分别驱动它们。TaoToken 在这里的角色是统一的模型接入层——写 agent 和审 agent 可以指向不同的模型,但都通过同一套 API Key 和 base_url 调用,省去为每个 agent 单独维护一套鉴权的麻烦。
先拿到访问凭证。打开官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 注册后进入控制台,在 API Keys 页面创建一个新 Key。建议给写审流程单独建一个 Key,方便后续按调用量排查问题。
创建完成后,把 base_url 和 Key 记下来:
# 写审两个 agent 共用同一个接入地址 export TAOTOKEN_BASE_URL="https://taotoken.net/api" export TAOTOKEN_API_KEY="sk-你的实际Key"这里有个容易踩的坑:base_url 末尾不要带/v1,OpenCode skill 内部会按 OpenAI 兼容格式拼接路径。如果你用的是 Claude Code 这类工具,接入地址和 Key 的填法略有不同,可以参考接入文档里的对应章节。
模型选择上,写 agent 建议用长上下文、擅长结构化输出的模型,审 agent 建议用更“较真”的模型——两者不必相同。审 agent 的 prompt 很短(只有五问),对模型的理解力要求反而更高,因为它要在没有背景信息的情况下判断文章是否达标。
3. 可复制配置:tech-batch skill 骨架与审核清单
tech-batch 的核心是一个串行调度器加两份 prompt。调度器负责“写→审→改→再审”的循环,两份 prompt 分别定义写 agent 和审 agent 的职责。先看目录结构:
tech-batch/ ├── SKILL.md # skill 入口说明 ├── pipeline.py # 串行调度器 ├── prompts/ │ ├── writer.md # 写 agent prompt │ └── reviewer.md # 审 agent prompt(只含五问) ├── series/ │ ├── plan.json # 系列文章计划 │ └── batch_progress.json # 进度状态机 └── output/ # 成稿输出目录调度器是整个流程的骨架,它保证严格串行、断点续跑:
import json from pathlib import Path class BatchPipeline: def __init__(self, series_dir: str): self.series_dir = Path(series_dir) self.progress = self._load_progress() def _load_progress(self) -> dict: path = self.series_dir / "batch_progress.json" if path.exists(): return json.loads(path.read_text(encoding="utf-8")) return {"articles": [], "completed": 0, "current": 0, "status": "idle"} def _save_progress(self): path = self.series_dir / "batch_progress.json" path.write_text( json.dumps(self.progress, ensure_ascii=False, indent=2), encoding="utf-8" ) def run(self): for i, article in enumerate(self.progress["articles"]): if article["status"] == "completed": continue self.progress["current"] = i passed = False while not passed: self._write(article) # 写 agent 产出初稿 passed = self._review(article) # 审 agent 盲审 if not passed: self._revise(article) # 写 agent 逐条修改 article["status"] = "completed" self.progress["completed"] += 1 self._save_progress() def _write(self, article): # 调用写 agent,传入系列计划与参考素材 ... def _review(self, article) -> bool: # 调用审 agent,只传文章正文 + 五问清单 ... def _revise(self, article): # 把审 agent 的 blocking 项回传给写 agent ...审 agent 的 prompt 只有五问,这是整个设计里最关键的部分——它必须足够短,短到审 agent 没有空间去“发挥”:
# reviewer.md 你是一名独立审查员。你没有看过这篇文章的写作过程,也不需要了解它的背景。 只根据以下五个问题逐条核验,任何一项为否即为 blocking。 1. 字数是否 ≥ 800 字? 2. 结构是否完整(概念速查 + 底层原理 + 设计原则三段齐全)? 3. Mermaid 图是否为独立代码块、且无嵌套 subgraph? 4. 代码是否可复制、版本号/API 是否明确? 5. 是否无面试八股、无博文关联、无下一篇引导? 输出格式: - 逐条列出 yes/no - 所有 no 项附上具体位置和修改建议 - 全部 yes 时输出 PASS写 agent 的 prompt 则相反,塞满上下文:系列计划、参考素材路径、格式规范、目标读者。这种不对称是故意的——审 agent 越“无知”,判断越独立。
进度文件batch_progress.json是唯一真理源,主对话不依赖内存变量,每次操作前后都读写它。中断后重新运行,读文件即可恢复:
{ "articles": [ {"id": 1, "title": "AI Agent 入门", "status": "completed"}, {"id": 2, "title": "工具调用原理", "status": "in_progress"}, {"id": 3, "title": "记忆机制设计", "status": "pending"} ], "completed": 1, "current": 1, "status": "running" }4. 验证请求:一次批量生成后触发审核的完整操作
配置就绪后,跑一次真实的批量流程。假设系列计划里有 3 篇文章,先初始化进度文件:
cd tech-batch python -c " from pipeline import BatchPipeline p = BatchPipeline('series') p.progress['articles'] = [ {'id': 1, 'title': 'AI Agent 入门', 'status': 'pending'}, {'id': 2, 'title': '工具调用原理', 'status': 'pending'}, {'id': 3, 'title': '记忆机制设计', 'status': 'pending'} ] p._save_progress() print('进度文件已初始化') "启动串行流程:
python -c " from pipeline import BatchPipeline p = BatchPipeline('series') p.run() "运行过程中,你会看到类似这样的输出(调度器里加日志即可):
[article 1] 写 agent 产出初稿... [article 1] 审 agent 第 1 次盲审... Q1 字数: yes (1024) Q2 结构: yes Q3 Mermaid: no - 第 3 节 subgraph 嵌套 Q4 代码: yes Q5 风格: yes => BLOCKING: Q3 [article 1] 写 agent 修改 Q3... [article 1] 审 agent 第 2 次盲审... => PASS [article 1] completed [article 2] 写 agent 产出初稿...注意第 2 次盲审是全新的子 agent 调用,它不继承第 1 次的对话历史,不记得“上次改了什么”。它只是重新读当前版本,逐条核对五问。这就是盲审的意义——切断“审查疲劳”,避免因为“之前看过”而降低标准。
验证成功的标志是进度文件里所有文章状态变为completed:
cat series/batch_progress.json | python -m json.tool{ "articles": [ {"id": 1, "title": "AI Agent 入门", "status": "completed"}, {"id": 2, "title": "工具调用原理", "status": "completed"}, {"id": 3, "title": "记忆机制设计", "status": "completed"} ], "completed": 3, "current": 2, "status": "idle" }如果你只想先验证审 agent 是否正常工作,可以单独调用一次审查,不跑完整流程:
python -c " from pipeline import BatchPipeline p = BatchPipeline('series') article = p.progress['articles'][0] result = p._review(article) print('审查结果:', 'PASS' if result else 'BLOCKING') "5. 本篇常见错排查
审 agent 总是 PASS,明显有问题的文章也放行。先检查 reviewer.md 是否被写 agent 的上下文污染了——审 agent 的 prompt 里不能出现系列计划、参考素材路径、写作规范这些内容。它只应该看到文章正文和五问。如果审 agent 的调用复用了写 agent 的对话历史,盲审就失效了。
循环卡在某篇文章,改了十几轮还是不过。大概率是五问里有主观项混进去了。五问必须是可客观核验的布尔问题,“文笔好不好”“解释够不够清楚”这类判断会让审 agent 输出不稳定。把这类标准从 reviewer.md 里删掉,或者改写成可核验的形式,比如“是否包含至少一个完整可运行的代码块”。
进度文件损坏,重新运行时报 JSON 解析错误。调度器每次_save_progress都是全量写入,如果写入过程中进程被强杀,文件可能只写了一半。加一个原子写入:先写临时文件再os.replace。另外,batch_progress.json建议纳入版本控制,出问题可以直接回滚。
写 agent 和审 agent 用了同一个模型,审查效果差。不是不能用同一个模型,但写审分离的价值在于“不同上下文、不同职责”。如果模型相同,至少保证两次调用的 system prompt 和上下文完全隔离。条件允许的话,审 agent 换一个更擅长逻辑核验的模型,交叉验证效果更明显。
Mermaid 图审查总是报错但看不出问题。五问里的 Mermaid 检查项要具体到“独立代码块、无嵌套 subgraph”。嵌套 subgraph 在很多渲染器里会报错,审 agent 需要能识别subgraph关键字出现在另一个subgraph内部的情况。如果审 agent 判断不准,可以在 reviewer.md 里附上一个正例和一个反例。
批量跑到一半想调整某篇的写法。不要直接改 output 目录里的成稿,改series/plan.json里对应文章的写作要求,然后把该篇状态改回pending,重新运行调度器。调度器会跳过已 completed 的文章,只重跑这一篇。
6. 把写审分离接到你的日常流程里
tech-batch 这套骨架跑通之后,最实用的扩展是把它接到你的内容生产流水线上。写 agent 的 prompt 可以按系列替换,审 agent 的五问可以按内容类型调整——比如教程类加一条“每步是否有可复制命令”,原理类加一条“是否有至少一个类比说明”。审 agent 的 prompt 越短、越客观,盲审的效果越稳定。
如果你需要长期跑批量编码或 Agent 任务,Coding Plan 提供了更适合高频调用的额度方案,可以在控制台里对比一下按量调用和套餐的差异。写审分离的本质不是让 AI 更聪明,而是让两个“不聪明但职责单一”的 agent 互相补位——写的人只管写,审的人只管挑刺,质量反而比一个全能 agent 更可控。