Skip to content

Repository files navigation

方寸写作 · AI 仿写工作室

把一本源书变成可发布的新书——借 toonflow 原生三阶段管线(骨架→改编→剧本→小说), 注入仿写约束与类型红线,批量产出剧情原创、风格一致的全新网文。

目标是「工作室级量产」:用数量对冲单本爆不爆的不确定性,在架 30-50 本的长尾累加实现稳定收入。


你能用这个项目做什么

场景 命令
仿写一本书(小说源,单本全自动) python tools/transcript/imitate.py --src source/xxx.txt --name 我的新书 --episodes 90
仿写一本书(剧本源,按集) python tools/transcript/imitate.py --src 剧本.txt --src-type screenplay --name 我的新书 --episodes 90
改编成剧本(小说→剧本,忠实保留剧情人物) python tools/transcript/imitate.py --src 源书.txt --name 我的改编 --episodes 90(建项目后把 用户需求.md 首行改成 # 意图:改编原著成剧本
改编成小说(小说→小说,忠实改编) 同上,意图行写 # 意图:改编原著成小说
批量仿写多本书(并行调度) python tools/transcript/batch_run.py --list config/batch_books.json --concurrency 2
多季/系列(一部部做 500 集长篇) 书单加 series/part 字段,第 2 部起自动接前情(见下)
扫什么题材火(本地读快照) python tools/transcript/topic_scan.py
断点续跑(骨架已有,只补剧本+小说) python tools/transcript/imitate.py --name 我的新书 --only-script
发布准备(S4 之后必做) python tools/transcript/publish_prep.py all 项目名 "新书名" --author 笔名
汇总发布目录(看全部成品) python tools/transcript/publish_prep.py collect → 生成 publish/ 及各书四件套

管线一句话

源书(小说 或 剧本) → [事件表] → [S1 骨架(独创新剧情)] → [S2 改编策略]
 → [S3 剧本(90集)] → [S4 小说化(番茄风, ~2500字/章)] → 新书出品
 → 【阶段五:发布准备】书名定稿同步(set-title) · 投稿信息(submission) · 封面提示词(cover, story-cover skill) · 汇总导出(collect → publish/)

源可以是「小说」(按第N章) 或 「剧本」(按第N集);脚本自动归一化为 toonflow 只读的
第N章.txt,对上层透明。剧本源只按『第N集』拆分,正文偶发的『原书第3章』不会误判分章。

核心设计原则:不改 toonflow 原生 prompt,只通过「仿写需求注入 + 列名 guard + 长度兜底 + 脱敏安全网」做非侵入式仿写。产出的剧情 100% 原创、专名零泄漏。


意图驱动:仿写还是改编,由你一句话决定(零开关)

之前有人反馈「这工具只能仿写」——其实不是。它既能仿写也能改编,区别完全由你写在 真仿写资产/用户需求.md 顶部的意图行决定,不需要任何命令行开关

每次运行 imitate.py 都会重读这个文件、重新识别意图,并写回 config.json,所以建完项目后 随时改需求也能切换模式(旧 --imitation 之类硬编码开关已废弃)。

三种意图(写第一行就行)

意图行(写 用户需求.md 第一行) 模式 产出 行为
# 意图:仿写新IP(默认) 仿写 小说 S1→S2→S3 剧本→S4 小说,剧情 100% 原创、专名零泄漏
# 意图:改编原著成剧本 改编 剧本 S1→S2→S3 剧本,停在剧本(不进 S4 小说化),忠实保留原书剧情与人物
# 意图:改编原著成小说 改编 小说 全管线,但 S1/S2/S4 按「忠实改编」约束工作,保留原书剧情与人物

判定规则(通用、无开关):

  • 意图行含「改编原著 / 我要改编原著 / 忠于原著 / 忠实改编」→ 改编模式;
  • 含「仿写新IP / 我要仿写」或没写 → 仿写模式(兼容旧 brief);
  • 意图里带「成剧本 / 转剧本 / 剧本 / 分镜」等词 → 产出剧本,S3 后直接收尾不进 S4。

怎么用

# 1) 正常建项目(默认生成 用户需求.md,首行即「# 意图:仿写新IP」)
python tools/transcript/imitate.py --src source/女配.txt --name 我的新书 --episodes 90

# 2) 想改成「忠实改编成剧本」:编辑 projects/我的新书/真仿写资产/用户需求.md
#    把首行改成  # 意图:改编原著成剧本
#    同时删掉下方「## 用户需求」段里的「仿写红线条款」(那段是仿写专用,改编用不上)
#    重跑同一条命令即可,无需任何额外参数:
python tools/transcript/imitate.py --src source/女配.txt --name 我的新书 --episodes 90
#    运行时会打印:🎯 意图识别:改编原著(imitation=False,产出=screenplay)

注:--no-decode 仍可强制只出剧本(等价于临时意图=成剧本),但推荐用意图行—— 意图行是持久、写回 config 的「控制面」,改一次全局生效;--no-decode 只是单次覆盖。


项目结构(新用户指南)

fangcun-write/
├── tools/transcript/         ← **管线脚本(你主要打交道的地方)**
│   ├── imitate.py             单书全自动仿写管线(支持 --src-type / --series / --part / --prev)
│   ├── batch_run.py           批量调度器(读书单 JSON、受限并发、多季串联)
│   ├── series_worldbook.py    多季模式:跨季复制 name_map + 生成前情提要 + 聚合世界书
│   ├── gen_name_map.py        每本书的专属脱敏映射生成器
│   ├── multi_season_smoke.py  非 LLM 冒烟测试(双源拆分 / 跨季前情 / 世界书聚合)
│   └── topic_scan.py          选题扫描器(读番茄离线榜单,零 API)
│
├── series/                   ← **多季世界书**(每系列一部 worldbook.md,人工审查用)
│   └── <系列名>/worldbook.md
│
│
├── source/                 ← **源书语料库**(受保护,别删;按 女频/男频 等分目录)
│   └── 女频/ 七零/ 八零/ ...(各频道源书,根目录不再散放)
│
├── 真仿写资产/                ← 共享资产
│   └── name_map.json           脱敏映射母本(自动复制到新项目)
│
├── projects/                 ← **每本书的产出**(.gitignore 排除)
│   └── 项目名/
│       ├── novel/               番茄风小说("第01章.md")
│       ├── script/              剧本中间态
│       ├── skeleton/            故事骨架
│       ├── adaptation/          改编策略
│       ├── qc/                  QC 审核报告
│       └── 真仿写资产/          该书专属:仿写需求、name_map
│
├── config/                 批量任务配置(batch_books.json / batch_summary.md)
├── .env                       环境变量(DEEPSEEK_API_KEY 放这里)
├── .gitignore
└── README.md                  ← 你正在看的文件

开始使用(新用户)

1. 配 API Key

在项目根创建 .env 文件(已 gitignore),写入:

DEEPSEEK_API_KEY=你的deepseek密钥

当前使用 deepseek-chat 模型(每本约 180 次调用,适合批量)。

2. 跑第一本书(试试效果)

# 事件表 → 骨架 → 改编 → 剧本 → 小说,全自动
python tools/transcript/imitate.py --src source/女频/女配一睁眼,失忆男主冷脸洗床单.txt --name 试试手 --episodes 10 --style "豪门甜宠"

3. 批量铺书

编辑 config/batch_books.json,添加你的书单,然后:

python tools/transcript/batch_run.py --list config/batch_books.json --concurrency 2

4. 选题

python tools/transcript/topic_scan.py
# 产出 topic_recommend.md,告诉你现下什么题材最火

看中某本后,下载原书全文(落盘 downloads/<书名>.txt,可直接喂仿写):

# 顶层显眼入口(自动拉起下载器服务,无需 cd 进 skill 目录)
python tools/fangcun_download.py search "书名关键词"     # 先看搜索结果
python tools/fangcun_download.py fetch  "书名" --pick 1 --channel 女频   # 下载第1本
# 下载完会打印下一步仿写命令,复制即用

下载器实现在 .agents/skills/fanqie-downloader/(exe + API 编排),fangcun_download.py 只是给「方寸仿写」用的薄壳入口。需要批量下载等进阶能力时可直接用该 skill 的 download_cli.py

5. 剧本源仿写(源是剧本,不是小说)

源书可以是已经写好的剧本(按 第N集 划分),同样能仿写。脚本会自动识别: 按 第N集 拆分单元,并归一化落盘为 toonflow 只读的 第N章.txt(对上层透明)。

# --src-type screenplay 显式声明剧本源;不写则按「集多→剧本 / 章多→小说」自动识别
python tools/transcript/imitate.py --src 我的剧本.txt --src-type screenplay --name 新剧仿写 --episodes 90

# 剧本目录源也支持(第N集.md 逐个文件)
python tools/transcript/imitate.py --src source/某剧/ --src-type screenplay --name 新剧仿写 --episodes 90

注意:剧本源只按『第N集』拆分,正文里偶发的「原书第3章」「回忆第5章」等穿书 写法不会被误判成章边界——这是有意为之的防护,保证分章干净。

6. 多季 / 系列模式(一部部做 500 集长篇)

toonflow 原生对单本 500 集不友好(S1 8192 截断 + S2 读整骨架易爆)。最稳的解法是把 长篇拆成多部,每部 = 一个独立 project(约 90 集),共享三样东西使剧情连贯、专名不漂移:

  1. name_map 跨季复制 —— 角色专名全程一致(陆砚舟永远是陆砚舟)。
  2. 前情提要.md —— 确定性抽取上一季结局 + 人物现状 + 未回收伏笔,注入下一季 S1~S4。
  3. worldbook.md —— 各季前情聚合,供人工一致性审查(series/<系列>/worldbook.md)。

第 ≥2 部会用 force_map=True 强制复制上一季的 name_map,避免误用仓库默认母本。 前情衔接完全确定性(不额外烧 LLM),下一季仍须 100% 原创(红线照常生效)。

书单写法(在 config/batch_books.json 给同系列各本加 series/part 字段):

[
  { "name": "锦绣_第1部", "src": "source/锦绣.txt", "style": "古言权谋甜宠",
    "platform": "横屏", "episodes": 90, "gen_map": true, "enabled": true,
    "series": "锦绣", "part": 1 },
  { "name": "锦绣_第2部", "src": "source/锦绣续.txt", "style": "古言权谋甜宠",
    "platform": "横屏", "episodes": 90, "gen_map": false, "enabled": true,
    "series": "锦绣", "part": 2 }
]
  • series 同名即同一系列;part 是第几部,第 2 部起自动 prev = f"{series}_第{part-1}部"
  • 第 2 部起 gen_mapfalse(name_map 由上一季复制,省一次抽取)。
  • 调度器会先等上一季跑完novel 章数达标或 stage=='S4完成'),再复制 events 省重复抽取、接前情、开跑。
  • 全部跑完后自动 aggregate_worldbook(series) 生成系列世界书。

单本手动触发(等价 CLI):

# 第 2 部显式指上一季
python tools/transcript/imitate.py --src 锦绣续.txt --name 锦绣_第2部 \
  --series 锦绣 --part 2 --prev 锦绣_第1部 --episodes 90

阶段五:发布准备(新书出品后的必做三步)

S4 跑完只是「有了可发的小说」,发布前还要补齐三件事:定书名、填投稿信息、出封面提示词。 这三步确定性、零 LLM,已固化成 tools/transcript/publish_prep.py,替代人工手搓(此前靠手动改 四五个文件,极易漏同步)。

步骤 1 · 书名定稿 + 全项目同步(set-title)

AI 自拟的书名常需替换。定稿后务必用本命令全量同步——imitate.py--new-name 只改 config.json,会漏掉 novel/script/skeleton/封面,导致上传时还是旧名:

python tools/transcript/publish_prep.py set-title 太子爷醉酒夜_仿写 "分手三年,偏执投资总裁跪求我回头"

它会对 config.json + 所有 novel/*.txt·第N章.md + script/第N集.md + skeleton.md + 封面提示词 + 投稿信息里的旧书名做替换,并重命名含旧名的成品 txt。新旧相同时 自动跳过(幂等),可放心重跑。

步骤 2 · 投稿信息(submission)

自动统计字数(读 novel/*_纯章节.txt 去空白)、推断类目/标签、搬运简介,生成 真仿写资产/投稿信息.md,可直接照着填番茄投稿表单:

python tools/transcript/publish_prep.py submission 太子爷醉酒夜_仿写 --author 一盏清酒

类目/标签按题材标签启发式推断(如 现代言情 › 豪门总裁 › 破镜重圆),可人工二次微调。

步骤 3 · 封面提示词(cover,严格走 story-cover skill)

封面提示词必须按你安装的 story-cover skill 方法论生成:平台风格串 / 书名字体 / 作者名字体 / 题材标签 / 色彩 / 光效 全部逐字取自 skill 风格库,本脚本不自编模板;人物据各书 「主角人设卡」+ 正文代词做具体化处理(服饰/姿态/发型/表情/道具),所以同题材也不会撞脸:

python tools/transcript/publish_prep.py cover 太子爷醉酒夜_仿写 --author 一盏清酒

生成 真仿写资产/封面/封面_storyskill_prompt.txt拿这文件去别的 AI(即梦 / MJ / SD)出底图—— 因为 AI 直接渲染中文书名必翻车(漏字错字)、且内置出图带「AI 生成」合规水印;书名 + 笔名建议出图后 用 PS / 稿定 / Canva 精确叠上去,零翻车、位置可控。

✅ 封面提示词全管线唯一走 story-cover 机制(publish_prep.py cover,落到 真仿写资产/封面/封面_storyskill_prompt.txt)。 imitate.pymerge_novel 交付环节已改调该机制,不再有第二套离线生成器;旧版 真仿写资产/封面提示词.md 与批量脚本 gen_cover_prompts.py 均已删除。

一步到位(all)

python tools/transcript/publish_prep.py all 太子爷醉酒夜_仿写 "分手三年,偏执投资总裁跪求我回头" --author 一盏清酒

= set-title + submission + cover 依次执行,跑完即具备发布所需的书名/投稿信息/封面提示词。

步骤 4 · 汇总发布目录(collect → publish/)

跑完上面三步后,一键把所有**已就绪(有成品 txt)**的书汇总到项目根的 publish/ 目录, 每本书一个子文件夹,四件套齐备,不用再切进每个 project 就能看全部原文与投稿信息

python tools/transcript/publish_prep.py collect

生成结构(项目根下):

publish/
├─ 发布清单.md                      ← 总览:几本就绪/待完稿、各本字数章节
├─ 分手三年,偏执投资总裁跪求我回头/
│  ├─ 纯章节.txt                    ← 上传用,去扉页
│  ├─ 完整版.txt                    ← 含书头/扉页
│  ├─ 投稿信息.md
│  └─ 封面提示词.txt
├─ 拒婚千金,大佬他非要宠我/
│  └─ (同上四件套)
└─ 大佬老公不说话?我话疗全家/
   └─ (同上四件套)
  • 只汇总 novel/<书名>_纯章节.txt 存在的书;无成品 txt 的项目(如京婚/冷战)列入「待完稿」不进发布目录。
  • 书名变更或删稿后重跑 collect,旧子目录自动清理,保持同步。
  • 发布清单 发布清单.md 顶部一行即「N 本就绪 / M 个待完稿」,发书前扫一眼即可。

关键概念(新人必读)

  • 仿写 ≠ 洗稿:管线注入「借结构不借内容、≥15 字相同即违规、专名零复用」的硬约束。S1 列名从原生「章节范围」改为「结构位+原创策略」,根除 1:1 章节锚定。
  • 仿写与改编都用同一套管线,由意图行切换真仿写资产/用户需求.md 首行写 # 意图:仿写新IP → 原创新书(默认);写 # 意图:改编原著成剧本 / # 意图:改编原著成小说 → 忠实改编,保留原书剧情人物。零命令行开关,运行期自动重判并写回 config.json(详见上「意图驱动」节)。
  • 源可以是小说也可以是剧本:小说按 第N章、剧本按 第N集 拆分;剧本只按集拆(正文偶发「第X章」不误判)。两者都归一化为 toonflow 只读的 第N章.txt,上层无感。
  • 多季/系列做长书:500 集长篇拆成多部(每部 ~90 集)最稳。靠 series_worldbook.py 跨季复制 name_map + 注入前情提要,第 ≥2 部 force_map=True 强制沿用上季专名,前情确定性生成、不额外烧 LLM。
  • 剧本中间态不丢掉:管线保留剧本(S3)→ 小说(S4)的两步走,不是一步到位。剧本可读,小说可发,两道产物都有用。
  • 每本书专属脱敏映射:gen_name_map 自动提取源书高频专名并生成全新替换名,sanitize_names 在管线最后做确定性替换,保证全本零泄漏。
  • QC 门禁:S1/S2 后自动跑审核报告,评分 D 级直接终止,C 级自动修复一次。质量不合格的书不会浪费后续 LLM 调用。
  • 容错续跑:剧本/小说单集失败被跳过,不会卡死全本。--only-script 可随时断点续跑。

常见问题

Q: 跑一本书要多少次 LLM 调用?成本多少? 约 180 次(S1 + S2 + 90×S3 + 90×S4),deepseek-chat 约 ¥3-5/本。

Q: 缺章怎么办? 偶发的 LLM 失败会被容错跳过,跑完后用 --only-script 重新跑一遍即可自动补缺失集。

Q: 产出能直接发吗? S4 产出已是可发布的番茄风小说(~2500 字/章、强章末钩子)。发布前还需走「阶段五:发布准备」: 用 publish_prep.py all <项目> "<新书名>" --author <笔名> 一键完成书名全量同步、投稿信息生成、 封面提示词生成(story-cover skill 方法论)。人工只需复核书名/类目、拿封面提示词去别的 AI 出图并叠字。

Q: 怎么增加源书? 把源书 txt 放入 source/,确保第 N 章(小说)或第 N 集(剧本)标记清晰,即可在 config/batch_books.json 引用。--src-type 可显式声明 novel / screenplay,不写则自动识别(集多→剧本 / 章多→小说)。系列书记得加 series/part 字段。


技术栈

  • Python 3.11+(标准库为主)
  • deepseek-chat(LLM 引擎)
  • toonflow-native orchestrator(prompt 模板+agent 框架,只读不改)

Releases

Packages

Contributors

Languages