Skip to main content

webnovel-write-batch

连续写作多章。当用户要求多章写作时必须使用此 skill。 ## 触发条件 - "连续写N章"、"写第X-Y章"、"批量写X-Y章"、"一次写N章" - "重写第X-Y章"、"修改第X-Y章" - "多章"、"多章节" ## 区分规则 - 单章 → webnovel-write - 多章 → 必须使用本 skill

Source facts

Repository
lujih/webnovel-writer-opencode
Last source activity
October 18, 2026 at 08:58
Detected SKILL.md language
Chinese
Stars
226
Forks
38

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
2 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
webnovel-write-batch
description
连续写作多章。当用户要求多章写作时必须使用此 skill。 ## 触发条件 - "连续写N章"、"写第X-Y章"、"批量写X-Y章"、"一次写N章" - "重写第X-Y章"、"修改第X-Y章" - "多章"、"多章节" ## 区分规则 - 单章 → webnovel-write - 多章 → 必须使用本 skill
compatibility
opencode
# 批量写作 ## ⛔ 硬规则(Anti-Laziness) 以下规则针对 AI 在长循环中的已知偷懒模式。**逐章执行前必须重现此清单。** | # | 禁止 | 正确做法 | |---|------|---------| | 1 | 口头描述代替 `Agent()` 调用 | 必须使用 Agent 工具调用 context-agent / chapter-writer-agent / reviewer / data-agent | | 2 | 跳过审查 | 每章必须运行 reviewer Agent + review-pipeline。blocking=false 也不能跳过 | | 3 | 用 Read 工具代替验证命令 | 每步后必须运行 bash 验证命令(test -s / ls / python -c) | | 4 | "稍后更新" batch_state | 每章完成后立即用 python -c 写 JSON,写完后重新读取验证 | | 5 | 章数多了开始跳步/简化流程 | 每章必须完整执行本 skill 的 9 步,不得缩减。3 章后强制暂停 | | 6 | 子代理失败后假装成功 | 每个 Agent() 调用后检查输出文件是否存在且非空。失败重试 1 次→仍失败则停止 | | 7 | 审查和润色合并执行 | chapter-writer-agent 先写正文 → reviewer 审查 → 有 blocking 则回传修复。禁止在审查前自行修改 | | 8 | 用简化版代替完整单章流程 | 每章 = 完整闭环。chapter-writer-agent 在干净上下文中执行创作,质量等同于单章 | ## 环境设置 ```bash export SCRIPTS_DIR="${PWD}/.opencode/scripts" export SKILL_ROOT="${PWD}/.opencode/skills/webnovel-write" test -d "${SCRIPTS_DIR}" || { echo "错误: 未找到 ${SCRIPTS_DIR},请确保当前目录是 webnovel-writer 仓库根目录"; exit 1; } export PYTHONUTF8=1 export PROJECT_ROOT="$(python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PWD}" where)" # 归一化为正斜杠,避免路径中的 \b \n 等在 python -c 中被转义 export PROJECT_ROOT="${PROJECT_ROOT//\\//}" test -n "$PROJECT_ROOT" && test -f "${PROJECT_ROOT}/.webnovel/state.json" || { echo "错误: PROJECT_ROOT 解析失败,请用 --project-root 显式指定"; exit 1; } ``` ## Step 0: 解析章节范围 - "写第9-15章" → S=9, E=15 - "连续写3章" → **扫描文件系统获取最新章节号**(同单章 Step 0),S=最新章+1, E=S+2 - "批量写5章" → 同上,E=S+4 **禁止依赖 state.json 的 current_chapter 或对话记忆来确定起始章号。** 章节文件是唯一真源。 ```bash LATEST=$(python -c " import re from pathlib import Path text_dir = Path('${PROJECT_ROOT}') / '正文' nums = [] for f in text_dir.rglob('第*章*.md'): m = re.match(r'第0*(\d+)章', f.name) if m: nums.append(int(m.group(1))) print(max(nums) if nums else 0) ") echo "最新章节: 第${LATEST}章" ``` 若无法解析,询问用户明确范围。上限 3 章(可通过 `--force` 参数绕过,上限 5 章)。 ## Step 0.5: 断点恢复 ```bash BATCH_STATE="${PROJECT_ROOT}/.webnovel/batch_state.json" if [ -f "$BATCH_STATE" ]; then STATUS=$(python -c "import json; print(json.load(open('$BATCH_STATE',encoding='utf-8-sig')).get('status',''))") if [ "$STATUS" = "running" ]; then echo "检测到未完成的批量任务" python -c " import json s = json.load(open('$BATCH_STATE', encoding='utf-8-sig')) print(f' 已完成: 第{s[\"completed_chapters\"]}章') print(f' 待恢复: 第{s[\"current_chapter\"]}章') " # 询问用户:继续 / 重新开始 / 放弃 elif [ "$STATUS" = "completed" ]; then echo "上一次批量任务已完成。" # 询问是否开始新批次 fi fi ``` ## Step 0.6: 初始化 batch_state(新任务) ```bash if [ ! -f "$BATCH_STATE" ] || [ "$STATUS" != "running" ]; then python -c " import json, datetime s = { 'task_id': f'batch_{datetime.datetime.now(datetime.timezone.utc).strftime(\"%Y%m%d_%H%M%S\")}', 'range': {'start': $S, 'end': $E}, 'status': 'paused', 'current_chapter': $S, 'completed_chapters': [], 'failed_chapters': [], 'chapter_results': {}, 'created_at': datetime.datetime.now(datetime.timezone.utc).isoformat() } open('$BATCH_STATE', 'w', encoding='utf-8').write(json.dumps(s, ensure_ascii=False, indent=2)) " fi ``` --- ## 批前一次性验证 在进入逐章循环前执行一次 preflight,后续各章不再重复。 ```bash python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" preflight ``` --- ## 逐章循环 > **每章 = 9 步完整闭环。创作在独立 subagent 干净上下文中执行。** ### 逐章检查清单(每章开始前重现) **步骤映射:** 0=环境变量验证, A=上章完整性, 1=刷新合同, 1b=结构自检, 2=context-agent, 3=写作, 4=审查, 5=review-pipeline, 6=修复轮, 7=data-agent, 8=commit+验证, 9=更新状态 ``` □ 0. 环境变量验证 □ A. 上章完整性检查(N > S 时) □ 1. 刷新合同树 □ 1b. 结构自检 □ 2. Agent(context-agent) → 写作任务书 □ 3. Agent(chapter-writer-agent) → 起草+润色 □ 4. Agent(reviewer) → 审查结果 □ 5. review-pipeline → 判定 blocking □ 6. blocking? → 提取反馈 → 回到 3(最多 2 轮) □ 7. Agent(data-agent) → 事实提取 □ 8. chapter-commit + 验证投影 + Git 备份 □ 9. 更新 batch_state + 进度反馈 ``` 每步执行前打印进度标识: ```bash echo "[Ch{N} Step {M}/9] {step_name}..." ``` --- ### Step 0: 环境变量验证(每章开始前强制) ```bash test -n "$PROJECT_ROOT" || { echo "❌ PROJECT_ROOT 未设置"; exit 1; } test -n "$SCRIPTS_DIR" || { echo "❌ SCRIPTS_DIR 未设置"; exit 1; } test -d "$PROJECT_ROOT" || { echo "❌ PROJECT_ROOT 目录不存在: $PROJECT_ROOT"; exit 1; } test -d "${PROJECT_ROOT}/.webnovel" || { echo "❌ ${PROJECT_ROOT}/.webnovel 不存在,PROJECT_ROOT 可能不正确"; exit 1; } echo "✅ PROJECT_ROOT=${PROJECT_ROOT}" ``` **状态门**: 若 batch_state.status 为 "paused",输出进度摘要并等待用户输入 "继续" 才将 status 改为 "running"。 --- ### Step A: 上章完整性检查(N > S 时强制) ```bash if [ "$N" -gt "$S" ]; then PREV=$((N - 1)) CHAPTER_FILE=$(python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" chapter-path --chapter $PREV) if [ ! -s "${PROJECT_ROOT}/${CHAPTER_FILE}" ]; then echo "❌ 第${PREV}章文件缺失。立即停止。" exit 1 fi IN_BATCH=$(python -c "import json; s=json.load(open('$BATCH_STATE',encoding='utf-8-sig')); print($PREV in s.get('completed_chapters',[]))") if [ "$IN_BATCH" != "True" ]; then echo "❌ 第${PREV}章未在 batch_state 中标记完成。立即停止。" exit 1 fi echo "✅ 第${PREV}章完整性检查通过" fi ``` --- ### Step 1: 刷新合同树 ```bash python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" placeholder-scan --format text ``` genre 从 `.webnovel/state.json` 的初始化配置快照读取。调用 story-system 前必须先从详细大纲解析真实本章目标,禁止传 `{章纲目标}`、`第N章章纲目标` 等占位 query。 ```bash # 用 skill_runner 传递 CJK,genre 自动从 state.json 读取,goal 从 stdin 传入 echo "${CHAPTER_GOAL}" | python -X utf8 "${SCRIPTS_DIR}/skill_runner.py" story-system \ --project-root "${PROJECT_ROOT}" --chapter {N} if [ $? -ne 0 ]; then echo "❌ story-system 合同刷新失败,阻断流程" exit 1 fi ``` 必备文件:`MASTER_SETTING.json`、`volume_{NNN}.json`、`chapter_{NNN}.review.json`。缺失则阻断。 `chapter_{NNN}.json` 必须优先检查顶层 `chapter_directive`。`chapter_focus` 只能来自 `chapter_directive.goal` 或真实 query,不得从 `dynamic_context` 的参考摘要继承。 --- ### 准备:结构自检 ```bash # 从章纲提取 intended_strand(统一小写,避免大小写不匹配) INTENDED_STRAND=$(python -c " import json contract_file = '${PROJECT_ROOT}/.story-system/chapters/chapter_$(printf '%03d' {N}).json' try: d = json.load(open(contract_file)) s = d.get('chapter_directive', {}).get('strand', '') print(s.strip().lower()) except: pass ") python -X utf8 "${SCRIPTS_DIR}/skill_runner.py" check-structural \ --project-root "${PROJECT_ROOT}" --chapter {N} --intended-strand "${INTENDED_STRAND}" --format json \ --output "${PROJECT_ROOT}/.webnovel/tmp/structural_check.json" ``` ```bash python -c " import json, sys d = json.load(open('${PROJECT_ROOT}/.webnovel/tmp/structural_check.json')) if not d.get('passed'): print('❌ 结构自检未通过,停止流程') for c in d['checks']: if c['severity'] == 'blocking' and not c['passed']: print(f' BLOCKING: {c[\"name\"]}: {c[\"detail\"]}') print(f' FIX: {c[\"fix\"]}') sys.exit(1) " || exit 1 # (use $? check for PowerShell compatibility) ``` --- ### Step 2: Agent(context-agent) → 写作任务书 **必须使用 Agent 工具调用 context-agent,不得由主流程自行整理。** ```text Agent( subagent_type: "context-agent", prompt: "chapter={N}; project_root=${PROJECT_ROOT}; scripts_dir=${SCRIPTS_DIR}; storage_path=${PROJECT_ROOT}/.webnovel; state_file=${PROJECT_ROOT}/.webnovel/state.json(projection/read-model,仅兼容读取)。先 research,再按 本章硬性约束→CBN/CPNs/CEN→本章禁区→风格指引→dynamic_context补充参考 的顺序输出五段写作任务书。" ) ``` 验证:任务书非空且包含"硬性约束"或"CBN"字样。失败或返回空→重试 1 次→仍失败则停止。 --- ### Step 3: Agent(chapter-writer-agent) → 起草+润色 **核心变更:原来主线程的起草(Step 3)和润色(Step 5)合并为一次 Agent 调用,在干净上下文中完成完整创作闭环。** 传入 prompt 结构: ```text Agent( subagent_type: "chapter-writer-agent", prompt: """ 【章节】第{N}章 【字数】2000-2500 字 【写作任务书】 {context-agent 产出的完整任务书} 【章纲约束】 {从 chapter_{NNN}.json 提取的 chapter_directive.goal / time_anchor / countdown / chapter_end_open_question / must_cover_nodes / forbidden_zones} 【润色指南】 - 风格适配:与 MASTER_SETTING 保持一致的人称/视角/叙事距离 - 排版:标题格式 `## 第{NNNN}章 标题`,段落间空行,对话分行 - Anti-AI 终检:消除"不是...而是..."句式、段落首尾总结句、冗余"突然/忽然"、机械动作罗列、直接情感告知 【审查反馈】 (首轮为空。修复轮时填入:) - [{category}] {description} (位置: {location}) """ ) ``` **验证:** ```bash CHAPTER_PATH=$(python -X utf8 "${SCRIPTS_DIR}/webnovel.py" --project-root "${PROJECT_ROOT}" chapter-path --chapter {N}) CHAPTER_FILE="${PROJECT_ROOT}/${CHAPTER_PATH}" test -s "$CHAPTER_FILE" || { echo "❌ 章节文件为空"; exit 1; } WORDS=$(python -c " import re t = open('$CHAPTER_FILE', encoding='utf-8').read() print(len(re.findall(r'[一-鿿]', t))) ") echo "字数: $WORDS" if [ "$WORDS" -lt 1500 ]; then echo "⚠️ 字数不足 1500" fi ``` 字数不足→重试 chapter-writer-agent(提示字数不足)。仍不足→标记 warning 继续。 --- ### Step 4: Agent(reviewer) → 审查 **必须使用 Agent 工具调用 reviewer,不得由主流程伪造审查 JSON。** ```text Agent( subagent_type: "reviewer",
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub