
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_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册后进入控制台在 API Keys 页面创建一个新 Key。建议给写审流程单独建一个 Key方便后续按调用量排查问题。创建完成后把 base_url 和 Key 记下来# 写审两个 agent 共用同一个接入地址 export TAOTOKEN_BASE_URLhttps://taotoken.net/api export TAOTOKEN_API_KEYsk-你的实际Key这里有个容易踩的坑base_url 末尾不要带/v1OpenCode 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(encodingutf-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_asciiFalse, indent2), encodingutf-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 次的对话历史不记得“上次改了什么”。它只是重新读当前版本逐条核对五问。这就是盲审的意义——切断“审查疲劳”避免因为“之前看过”而降低标准。验证成功的标志是进度文件里所有文章状态变为completedcat 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 更可控。