视频完整展示从小说输入到 YAML 剧本、完整剧本文本和前端工作台的端到端流程。
本项目对应“题目三:AI 小说转剧本工具”。工具读取 3 章以上中文小说文本,自动生成可直接阅读的完整剧本文本和结构化 YAML 剧本初稿,并提供 YAML Schema、Schema 设计说明和校验入口,方便作者继续编辑、扩写和二次打磨。
当前实现聚焦可运行、可校验、可追溯的自动化初稿生成:作者可以先阅读完整剧本文本,也可以继续编辑 YAML 结构数据;完整剧本由 YAML 稳定渲染,避免两个产物互相漂移。输出语言跟随源文档和 language 参数,中文源文档输出中文,英文源文档会保留英文人物、英文对白和英文完整剧本标签。
python -m pip install -r requirements.txt
python scripts/verify.py成功时会看到:
passed
Validation PASS
UI contract PASS
UI smoke PASS
Verification PASS
scripts/verify.py 会依次执行 pytest,转换、校验 sample 与 harbor 两组示例,并启动一次无浏览器前端 smoke 和 UI 合约检查,是本项目的主验证入口。GitHub Actions CI 在 pull request 和 main 分支 push 时执行同一条命令。
推荐直接双击仓库根目录脚本:
| 系统 | 双击文件 | 行为 |
|---|---|---|
| Windows | start_windows.bat |
创建 .venv、安装 Python 依赖、启动 Streamlit 工作台 |
| macOS | start_mac.command |
创建 .venv、安装 Python 依赖、启动 Streamlit 工作台 |
默认打开 http://127.0.0.1:8501;如果 8501 已被占用,会自动使用 8502 之后的空闲端口。macOS 如果提示无执行权限,在终端执行一次 chmod +x start_mac.command 后再双击。
| 文件 | 作用 |
|---|---|
novel_to_screenplay.py |
小说转结构化剧本 YAML 的命令行工具 |
run.py |
本地启动 Streamlit 工作台的统一入口 |
start_windows.bat |
Windows 双击一键启动脚本 |
start_mac.command |
macOS 双击一键启动脚本 |
app.py |
Streamlit 前端工作台,支持粘贴/上传、生成、预览和下载 YAML |
screenplay_schema.yaml |
可机读 JSON Schema 2020-12 校验文件,使用 YAML 编写 |
screenplay_yaml_schema.md |
YAML Schema 设计说明文档,解释字段设计原因 |
examples/sample_novel.txt |
3 章中文悬疑小说示例输入 |
examples/sample_screenplay.yaml |
悬疑示例输出,可由命令重新生成 |
examples/sample_screenplay.txt |
悬疑示例完整剧本文本,可由 YAML 渲染生成 |
examples/harbor_novel.txt |
3 章中文舞台/海港小说示例输入 |
examples/harbor_screenplay.yaml |
海港示例输出,可由命令重新生成 |
examples/harbor_screenplay.txt |
海港示例完整剧本文本,可由 YAML 渲染生成 |
scripts/verify.py |
一条命令完成测试、转换、校验和前端 smoke |
scripts/verify_ui.py |
自动检查完整剧本、YAML、原生场景导航、默认中文/DeepSeek 配置,并启动 Streamlit 检查本地 HTTP 200 |
PLAN.md |
长期计划、Phase/Sprint 拆解和当前方向锁定 |
CLAUDE.md |
项目约束、迭代协议和 Git 工作流 |
输入文本必须至少包含 3 个章节。推荐用章节标题分隔正文:
第一章 雨夜来信
雨水敲打着旧城区公寓的窗户。林舟把台灯调暗。
沈眠说:“这封信不是今天才寄出的。”
第二章 旧档案室
第二天清晨,林舟和沈眠来到市局旧档案室。
老周说:“昨晚停电二十分钟。”
第三章 天台录音
夜晚,林舟独自登上医院天台。
林舟说:“真正的证据还没有被毁掉。”
章节标题可以是“第一章”“第1章”“Chapter 1”等常见形式。少于 3 章时,转换命令会返回错误并停止。
如果正文是从 AI 对话或 Markdown 文档中复制出来的,转换前会先清理外层包装噪音,包括“好的,以下是小说正文”、代码块围栏、Markdown 章节标题前的 #、独立或行内长分隔线、免责声明和结尾客套话。清洗只发生在输入预处理阶段,输出仍以原文正文内容为依据。前端会显示“源文本清洗预览”,生成后的 YAML 会在 source.cleaning 记录清洗状态、删除行数、分隔噪音数量和风险说明。
python -m pip install -r requirements.txtpython novel_to_screenplay.py convert examples/sample_novel.txt -o examples/sample_screenplay.yaml --script-output examples/sample_screenplay.txt --title "雨夜旧案"只生成 YAML 时可执行:
python novel_to_screenplay.py convert examples/sample_novel.txt -o examples/sample_screenplay.yaml --title "雨夜旧案"成功输出示例:
Wrote examples/sample_screenplay.yaml with 3 chapters and 3 scenes. Script text: examples/sample_screenplay.txt.
python novel_to_screenplay.py validate examples/sample_screenplay.yaml成功输出示例:
Validation PASS
启动 Streamlit 工作台:
python -m streamlit run app.py界面支持粘贴、上传 .txt 小说和一键载入内置示例,填写作品标题和语言标签,生成前可查看源文本清洗预览,生成后优先展示原生完整剧本阅读台:左侧场景导航、右侧逐场正文、下方纯文本完整剧本,同时保留可编辑 YAML。作者可以下载 screenplay.txt,也可以在页面内编辑、重新校验并下载 screenplay.yaml。AI 清洗小说源和 AI 修订建议默认关闭;开启任一 AI 功能后先选厂商、再选内置模型,默认厂商为 DeepSeek。AI 源清洗发生在章节切分之前,失败时自动回退本地强清洗;AI 修订建议复用 --ai-assist revision-notes 同一套后处理逻辑,缺少 API key 时仍保留本地生成结果。
开启 AI 后必须先点击“保存并测试连接”。侧边栏会显示连接指示灯:未测试、配置已变更、已连接或连接失败。连接测试只代表 key 与 endpoint 可通;如果后续生成调用失败,状态灯会改为“生成调用失败,已回退本地结果”,不会继续只显示“已连接”。临时 API key 只保存在当前 Streamlit 会话中,不写入文件;连接失败时页面会保留本地强清洗、本地规则引擎生成的完整剧本和 YAML。
发布验收时可用无浏览器脚本验证前端输出合约和 HTTP 入口:脚本会生成样例剧本,检查 YAML 非空、完整剧本文本非空且不泄漏 HTML/包装符号、原生场景导航存在、YAML 编辑器能从当前输出回填、默认厂商为 DeepSeek、界面语言为中文,并确认 Streamlit 返回 HTTP 200。
python scripts/verify_ui.py前端生成后会通过可换行的“输出视图”导航进入各工作区,避免多个工具项挤在同一行:
| 视图 | 内容 |
|---|---|
| 完整剧本 | 从 YAML 渲染出的原生阅读工作台,包含场景导航、逐场正文、原文片段和纯文本完整剧本;对白按 人物:台词 呈现,可下载 .txt |
| 场景大纲 | 场次、标题、时间、地点、出场人物和摘要 |
| YAML 编辑 | 可编辑结构化剧本,可重新校验并下载 |
| 角色关系 / 地点 / 时间线 | 分表查看人物关系、场景空间和事件顺序 |
| AI 创作辅助 | 本地规则和可选 AI 给出的切场建议、角色检索词、情节检索词、改编优先级和场景改写卡 |
| 输出规范 | 章节数量、YAML 规范、完整剧本文本、核心数据完整性、AI/创作辅助状态和质量面板 |
| 修订建议 | 自动生成的编辑建议和 AI 修订建议 |
作者可以先在“完整剧本”视图按场景导航阅读逐场正文,再到 YAML 视图修改角色、场景、对白或备注,点击“校验当前 YAML”后查看字段级错误;只有当前编辑内容通过校验后,下载按钮才会导出修订版 YAML,完整剧本文本也会随最新有效 YAML 重新渲染。
当前前端默认先生成本地 creative_assist 底稿;即使不填 API key,也会展示切场建议、角色检索词、情节检索词、改编优先级和场景改写卡。填入 key 后,DeepSeek、MiniMax、Kimi 和 OpenAI 使用 OpenAI-compatible Chat Completions 形态,Claude 使用 Anthropic Messages 形态;模型只追加 revision_notes 并增强 creative_assist,不会直接改写剧本正文结构:
AI 调用超时统一为 300 秒。OpenAI-compatible 生成和源文本清洗默认不传 max_tokens,不在本项目侧设置输出 token 上限;连接测试仍使用很小的测试输出。Claude/Anthropic Messages 协议要求请求体必须包含 max_tokens,因此仅该协议保留必填兜底值。
| 厂商 | 默认模型 | Key 环境变量 | Endpoint |
|---|---|---|---|
| DeepSeek | deepseek-v4-flash |
DEEPSEEK_API_KEY |
https://api.deepseek.com/chat/completions |
| MiniMax | MiniMax-M3 |
MINIMAX_API_KEY |
https://api.minimax.io/v1/chat/completions |
| Kimi | kimi-k2.6 |
MOONSHOT_API_KEY |
https://api.moonshot.ai/v1/chat/completions |
| OpenAI | gpt-5.4-mini |
OPENAI_API_KEY |
https://api.openai.com/v1/chat/completions |
| Claude | claude-sonnet-4-6 |
ANTHROPIC_API_KEY |
https://api.anthropic.com/v1/messages |
生成的 YAML 顶层结构包括:
schema_version: "1.0"
project: {}
source: {}
characters: []
locations: []
timeline: []
scenes: []
quality_checks: {}
revision_notes: []
creative_assist: {}其中最常编辑的是:
| 字段 | 用途 |
|---|---|
source.chapters |
原小说章节摘要和章节编号 |
characters |
角色表,供场景和对白引用 |
characters[].relationships |
互动、并行动作和同场共现关系,帮助作者快速检查人物关系网 |
locations |
地点表,供场景引用 |
timeline |
关键事件顺序 |
scenes |
剧本场景列表,每场包含动作、对白、旁白、转场等 beats |
scenes[].source_excerpt |
场景对应的短原文片段,便于作者追溯和打磨 |
quality_checks |
自动质量报告,提示缺章、坏引用、序号异常和对白稀疏等问题 |
creative_assist |
创作辅助包,本地默认生成,AI 可增强,包含 AI 角色规约、切场建议、角色检索词、情节检索词、改编优先级和场景改写卡 |
python novel_to_screenplay.py convert <input.txt> -o <output.yaml> --title "<项目标题>" --language auto| 参数 | 必填 | 说明 |
|---|---|---|
<input.txt> |
是 | UTF-8 小说文本,至少 3 章 |
-o, --output |
是 | 输出 YAML 路径 |
--script-output |
否 | 同时输出从 YAML 渲染得到的完整剧本文本 .txt |
--title |
否 | 剧本项目标题,默认“小说改编剧本” |
--language |
否 | 输出语言标签,默认 auto,跟随源文档;可显式填 zh-CN 或 en-US |
--ai-assist |
否 | AI 辅助模式,默认 off;可选 revision-notes |
--ai-api-key-env |
否 | 存放 API key 的环境变量名,默认 OPENAI_API_KEY |
--ai-model |
否 | revision-notes 模式使用的模型名 |
--ai-provider |
否 | 写入 project.ai_assist.provider 的厂商标识,默认 openai-compatible |
--ai-base-url |
否 | AI endpoint;默认是 OpenAI-compatible chat completions endpoint |
--ai-api-protocol |
否 | 请求协议,支持 openai-compatible 和 anthropic-messages |
--ai-anthropic-version |
否 | Anthropic Messages API 版本 header,默认 2023-06-01 |
--ai-timeout |
否 | AI 辅助请求超时时间,单位秒,默认 300 |
默认转换流程完全本地可复现,不需要 API key:
python novel_to_screenplay.py convert examples/sample_novel.txt -o examples/sample_screenplay.yaml --title "雨夜旧案"默认转换会生成本地 creative_assist 底稿,不需要 API key。需要 AI 增强时,可以显式开启 revision-notes。该模式会把结构化剧本初稿发送给模型,让模型按五个角色规约工作:分场结构编辑、人物动机编辑、情节连续性编辑、剧本改写教练、质量复核编辑。每个角色都定义身份、任务、操作步骤、允许动作、禁止动作、输出字段和质量标准,并写入 creative_assist.prompt_strategy 供作者审计。模型只生成 revision_notes、检索词、改编建议和 scene_rewrite_cards,并在本地创作辅助底稿上增强 creative_assist;程序不会让模型直接改写 scenes、角色表或 Schema 关键字段。CLI 保留通用 OpenAI-compatible 参数,并额外支持 Anthropic Messages 协议;前端则提供 DeepSeek、MiniMax、Kimi、OpenAI、Claude 的厂商和内置模型选择。
python novel_to_screenplay.py convert examples/sample_novel.txt -o examples/sample_screenplay.yaml --title "雨夜旧案" --ai-assist revision-notes --ai-api-key-env OPENAI_API_KEY --ai-model gpt-4o-mini如果未设置对应环境变量,命令不会失败,输出 YAML 会保留本地规则引擎结果,并写入:
project:
ai_assist:
mode: revision-notes
provider: openai-compatible
api_protocol: openai-compatible
status: skipped_missing_key
revision_notes:
- type: ai_assist
text: "AI 辅助未调用:环境变量 OPENAI_API_KEY 未设置,已使用本地规则引擎生成可验证初稿。"
creative_assist:
mode: local-draft
provider: local-rules
model: deterministic-creative-assist
status: local_draft
segmentation_hints:
- scene: scene_001
source_chapters: [ch_001]
hint: "复核第 1 场是否按开场事件独立成场。"
character_queries:
- character: char_001
query: "林舟 旧案 动机"
plot_queries:
- source_chapters: [ch_001]
query: "匿名信 旧案 线索"
adaptation_notes:
- priority: medium
scene: scene_001
text: "复核是否需要将心理描写转为动作、旁白或角色交流。"
scene_rewrite_cards:
- scene: scene_001
source_chapters: [ch_001]
objective: "明确该场的可表演目标。"
action_draft: "把场景摘要转成动作链,保留原文事实。"
dialogue_seed: "围绕原文线索补一轮短对白。"
editing_risk: "采纳前对照 source_excerpt,避免新增事实。"python novel_to_screenplay.py validate <output.yaml>python novel_to_screenplay.py export-script examples/sample_screenplay.yaml -o examples/sample_screenplay.txtexport-script 会先校验 YAML,再把结构化数据渲染为完整剧本文本。文本包含标题页、人物表、逐场正文、动作、对白、旁白、转场、修订建议、AI 角色规约摘要和场景改写卡;对白采用 人物:台词,带说话方式时采用 人物(低声):台词,不包含 HTML 标签、Markdown 分隔线或列表包装符号,适合作者直接阅读或继续用文本编辑器打磨。
需要在 CLI 中启用 AI 源文本清洗时,复用 AI 辅助的厂商、模型、Endpoint 和 key 环境变量参数:
python novel_to_screenplay.py convert input.txt -o output.yaml --ai-clean-source --ai-provider deepseek --ai-model deepseek-v4-flash --ai-api-key-env DEEPSEEK_API_KEYvalidate 会同时执行两类检查:
| 检查 | 说明 |
|---|---|
| 内置语义校验 | 检查章节覆盖、地点引用、角色引用、时间线引用、修订建议 scene、scene 序号、beats 文本、creative_assist 引用等跨字段关系 |
| JSON Schema 校验 | 使用 screenplay_schema.yaml 检查必填字段、类型、枚举和数组约束 |
错误会以字段路径输出,例如:
ERROR: scenes.0.source_chapters.0: references unknown chapter ch_999
ERROR: scenes.0.location: references unknown location loc_missing
ERROR: timeline.0.related_characters.0: references unknown character char_404
ERROR: revision_notes.0.scene: references unknown scene scene_missing
ERROR: creative_assist.segmentation_hints.0.scene: references unknown scene scene_999
ERROR: creative_assist.character_queries.0.character: references unknown character char_999
ERROR: source.chapter_count: '3' is not of type 'integer'
quality_checks 是给作者和评审者看的自动质量报告,不替代人工改稿,但能快速暴露结构问题。
quality_checks:
scene_count: 3
dialogue_count: 9
warnings: []
chapter_coverage:
required_minimum: 3
covered_chapters:
- ch_001
- ch_002
- ch_003
missing_chapters: []
passed: true
schema_validation:
passed: true
errors: []
character_reference_check:
passed: true
undefined_characters: []
scene_sequence_check:
passed: true
missing_sequences: []
duplicate_sequences: []常见 warning 含义:
| warning | 含义 |
|---|---|
| 章节覆盖不足 | 场景未覆盖至少 3 个源章节 |
| 存在未覆盖源章节 | missing_chapters 中列出了未进入剧本的章节 |
| 未检测到对白 beat | 输出可能仍偏小说叙述 |
| 对白数量少于场景数 | 部分场景可能缺少角色交流 |
| 场景序号不连续或重复 | 需要修正 scene.sequence |
| 存在未定义角色引用 | 场景或对白引用了不存在的 characters.id |
| 存在无角色场景 | scenes[].characters 为空,需要补充出场角色或旁白 |
| 存在纯旁白场景 | 场景只含旁白,建议复核是否应改写为动作或角色对白 |
题目要求额外定义剧本 YAML Schema,并说明设计原因。本项目提供两份文件:
screenplay_schema.yaml:机器可读 Schema,用于自动校验。screenplay_yaml_schema.md:面向评审者和作者的 Schema 设计说明,逐项解释顶层字段、角色、地点、时间线、场景、beats、质量检查、修订建议和创作辅助包的设计原因。
tests/test_novel_to_screenplay.py 会抽取 screenplay_yaml_schema.md 中标记的完整 YAML 示例,并验证这些示例与 quality_checks() 的计算结果一致。
发布前执行 python scripts/verify.py。该命令通过后,再按下表核对题目硬要求与仓库证据是否一致:
| 题目要求 | 仓库证据 | 验证方式 |
|---|---|---|
| 输入 3 章以上中文小说文本 | examples/sample_novel.txt、examples/harbor_novel.txt 均为中文 3 章示例 |
python scripts/verify.py 会转换两组示例 |
| 自动转换为结构化 YAML 剧本 | novel_to_screenplay.py convert 生成 examples/sample_screenplay.yaml 和 examples/harbor_screenplay.yaml,并可同步生成完整剧本文本 |
python novel_to_screenplay.py validate examples/sample_screenplay.yaml |
| 前端可视化生成 | app.py 复用核心转换模块,支持粘贴/上传/示例载入、原生完整剧本预览、角色/地点/时间线分视图、YAML 编辑和下载,并提供 DeepSeek 默认的多厂商 AI 选择 |
python scripts/verify_ui.py 检查前端 smoke、UI 合约与 HTTP 200,pytest 覆盖 UI 生成函数 |
| 输出可编辑剧本初稿 | YAML 顶层包含 project、source、characters、locations、timeline、scenes、quality_checks;每场含 source_excerpt 便于追溯;前端支持完整剧本阅读、页面内编辑和重新校验 |
在 UI 中编辑 YAML 后点击“校验当前 YAML”,或打开示例 YAML 编辑 scenes[].beats |
| 输出完整剧本文本 | render_screenplay_text() 和 export-script 将 YAML 渲染为 .txt,示例包含 examples/sample_screenplay.txt、examples/harbor_screenplay.txt |
python novel_to_screenplay.py export-script examples/sample_screenplay.yaml -o examples/sample_screenplay.txt |
| 输入废话与格式噪音清洗 | normalize_text() 和 prepare_source_text() 会先过滤 AI 前言、Markdown 代码围栏、独立/行内分隔线、提示/免责声明等包装噪音,并可选调用 AI 清洗源文本,避免客套话进入章节、场景和完整剧本文本 |
pytest 覆盖带 AI 包装话术、---------- 和 AI 源清洗的 3 章输入 |
| 提供 YAML Schema | screenplay_schema.yaml 使用 JSON Schema 2020-12 描述机器校验规则 |
validate 命令会加载该 Schema |
| 提供 Schema 设计说明文档 | screenplay_yaml_schema.md 逐项解释字段设计原因,并包含可验证 YAML 示例 |
pytest 会抽取文档示例并校验 |
| AI 辅助修订建议与创作辅助 | 默认本地生成 creative_assist;--ai-assist revision-notes 可调用 OpenAI-compatible endpoint 或 Anthropic Messages endpoint 生成 revision_notes 并增强 creative_assist;前端可选 DeepSeek、MiniMax、Kimi、OpenAI、Claude,并提供“保存并测试连接”状态灯;缺 key 时 skipped_missing_key 且主流程成功 |
pytest 覆盖本地创作辅助、无 key fallback、连接测试、厂商 preset、模型建议清洗和创作辅助表格 |
| 少于 3 章时拒绝生成 | convert 会返回 ERROR: 至少需要 3 个章节 |
pytest 覆盖短输入错误分支 |
| 发布分支可运行并可一条命令验收 | scripts/verify.py 串联 pytest、示例转换和示例校验 |
python scripts/verify.py |
题目原文参照 agent.md。当前审计结论如下:
| 题目要求 | 当前结论 | 证据文件 | 验证命令 |
|---|---|---|---|
| 输入 3 个章节以上的中文小说文本 | 已覆盖 | examples/sample_novel.txt、examples/harbor_novel.txt;novel_to_screenplay.py 的章节解析和短输入拒绝逻辑 |
python scripts/verify.py |
| 自动转换为结构化剧本 | 已覆盖 | novel_to_screenplay.py convert;examples/sample_screenplay.yaml、examples/harbor_screenplay.yaml;完整剧本文本由 export-script 从 YAML 渲染 |
python novel_to_screenplay.py validate examples/sample_screenplay.yaml |
| 输出 YAML 格式 | 已覆盖 | screenplay_schema.yaml、screenplay_yaml_schema.md、示例 YAML 输出 |
python novel_to_screenplay.py validate examples/harbor_screenplay.yaml |
| 让作者快速获得可编辑、可进一步打磨的剧本初稿 | 已覆盖 | UI 生成后先展示完整剧本,再提供 YAML 编辑校验;YAML 中的 characters[].relationships、characters、locations、timeline、scenes[].source_excerpt、scenes[].beats、revision_notes、creative_assist、quality_checks |
在 UI 中点击“校验当前 YAML”,或打开示例 YAML 后直接编辑字段 |
| 额外写一篇文档定义剧本 YAML Schema | 已覆盖 | screenplay_yaml_schema.md |
pytest 会校验文档中的完整 YAML 示例 |
| Schema 文档说明设计原因 | 已覆盖 | screenplay_yaml_schema.md 对顶层结构、角色、地点、时间线、场景、beats、质量检查、修订建议和创作辅助包说明设计原因 |
python -m pytest -q |
| AI 辅助剧本创作工具定位 | 已覆盖 | 默认路径是可验证的本地自动改编引擎,并生成本地创作辅助底稿;--ai-assist revision-notes 可选接入 LLM 生成修订建议、切场建议、角色检索词、情节检索词和改编优先级;前端默认 DeepSeek 且支持 MiniMax、Kimi、OpenAI、Claude;无 API key 时仍可运行并标记 skipped_missing_key |
python -m pytest -q |
当前发布候选以当前评审分支最新提交为准;合并后 main 必须继续满足同一组条件。冻结前必须满足以下条件:
| 冻结项 | 发布候选证据 | 验证方式 |
|---|---|---|
| 题目原文可追溯 | agent.md 保留题目三需求,README 最终审计逐条映射 |
检查“最终题目符合性审计” |
| 默认运行路径可复现 | 不设置 API key 时仍可转换 3 章中文小说并输出 YAML 与完整剧本文本 | python scripts/verify.py |
| 前端工作台可启动 | app.py 提供 Streamlit UI;README 写明 python -m streamlit run app.py;UI 合约覆盖完整剧本、YAML、原生场景导航、默认中文和默认 DeepSeek |
python scripts/verify_ui.py 自动检查 UI 合约并启动 HTTP 200 smoke |
| 页面内编辑校验闭环 | YAML 视图支持编辑、重新校验、错误表格和下载当前 YAML | pytest 覆盖 validate_editable_yaml 与 README 说明 |
| 示例输入输出完整 | examples/sample_* 与 examples/harbor_* 两组样例均包含输入、YAML 和完整剧本文本 |
python scripts/verify.py 会重生成、validate 并导出剧本文本 |
| Schema 与设计说明完整 | screenplay_schema.yaml 和 screenplay_yaml_schema.md 同时存在,且文档示例可校验 |
python -m pytest -q |
| AI 辅助边界清晰 | 默认 creative_assist 来自本地规则;prompt_strategy 记录分场结构编辑、人物动机编辑、情节连续性编辑、剧本改写教练、质量复核编辑的身份、做法、允许项和禁止项;--ai-assist revision-notes 只追加 revision_notes 并增强 creative_assist;缺 key 时写入 skipped_missing_key;前端按厂商 preset 选择内置模型,也允许填入自定义模型名,并按协议区分 OpenAI-compatible 与 Anthropic Messages |
pytest 覆盖无 key、成功返回和失败回退,并补充详细 prompt 规约、prompt_strategy Schema、厂商 preset 和自定义模型覆盖 |
| 不依赖写死样例数据 | 前端默认标题为通用“小说改编剧本”;示例只在用户点击载入时填充;完整剧本渲染测试覆盖非示例人物名和对白 | pytest 覆盖默认标题不使用 雨夜旧案,并验证自定义人物输出为 人物:台词 |
| 发布入口唯一 | scripts/verify.py 串联 pytest、示例转换、示例校验、完整剧本导出、前端 smoke 和 UI 合约 |
python scripts/verify.py |
| 无已知发布阻塞项 | README 不应残留未完成状态标记;发现补强项时应进入下一次有验证的增量提交 | pytest 覆盖发布候选冻结清单 |
当前发布候选必须能完成“生成-编辑-校验-追溯-下载”闭环。评审者可以按下表核对:
| 步骤 | 用户动作 | 仓库证据 | 验证方式 |
|---|---|---|---|
| 生成 | 输入或上传 3 章以上中文小说,点击生成剧本(生成 YAML 与完整剧本文本) | app.py 调用 generate_screenplay_yaml,CLI 调用 convert |
python scripts/verify.py 会重生成两组示例 |
| 阅读 | 在“完整剧本”视图查看可直接阅读的剧本文本 | render_screenplay_text() 从最新有效 YAML 渲染文本 |
python novel_to_screenplay.py export-script examples/sample_screenplay.yaml -o examples/sample_screenplay.txt |
| 编辑 | 在 YAML 视图修改角色、场景、对白或备注 | UI 使用可编辑 YAML 文本框,不是只读预览 | pytest 覆盖 validate_editable_yaml |
| 校验 | 点击“校验当前 YAML”查看错误表格 | validate_editable_yaml 复用 validate_data 做 Schema 与语义校验 |
pytest 覆盖合法 YAML、解析错误和语义错误 |
| 追溯 | 查看 scenes[].source_excerpt 对照短原文片段 |
生成器为每个 scene 写入 source_excerpt,示例 YAML 已包含 |
python novel_to_screenplay.py validate examples/sample_screenplay.yaml |
| 下载 | 校验通过后点击“下载当前 YAML”,或在完整剧本视图下载 screenplay.txt |
未校验或有错误时 YAML 下载按钮禁用,完整剧本始终来自最新有效 YAML | python scripts/verify_ui.py 确认 UI 合约和 HTTP 入口;pytest 覆盖说明文本 |
输入只有两章时,转换会失败:
ERROR: 至少需要 3 个章节,当前只识别到 2 个章节。
如果场景或对白引用了未定义角色,校验会失败:
ERROR: scenes.0.characters.0: references unknown character char_missing
ERROR: scenes.0.beats.0.character: references unknown character
如果场景地点、时间线章节/角色或修订建议 scene 指向不存在的 ID,校验也会失败:
ERROR: scenes.0.location: references unknown location loc_missing
ERROR: timeline.0.source_chapters.0: references unknown chapter ch_404
ERROR: timeline.0.related_characters.0: references unknown character char_404
ERROR: revision_notes.0.scene: references unknown scene scene_missing
如果 scene.sequence 不连续或重复,质量报告会给出:
scene_sequence_check:
passed: false
missing_sequences: [2]
duplicate_sequences: [1]- 人物:自动抽取说话人和叙述动作中的人物名,纯称谓角色如“老师、医生、保安”会保留为可编辑角色,“警官老周”这类职业前缀加姓名会清理为稳定角色名;角色说明会写入首次有效出场、参与场次、对白数量、关系焦点、人物目标、打磨重点和关键线索;关系会区分
direct_interaction、paired_action、co_appears,便于作者检查人物关系网。 - 场景:按章节生成剧本场景,长章节可按时间、地点和事件转折拆为多场;场景角色会结合对白说话人与叙述正文提及补全,并为每场保留短原文片段
source_excerpt。 - 对白:清理
说道等说话动词残留,保留低声、轻声、笑着等说话方式到parenthetical;支持陆沉推开门:“别动。”、她冷笑:“……”这类隐式对白归属;完整剧本文本统一渲染为人物:台词。 - 英文源文档:
Chapter 1等英文章节、Noah said, "..."、Maya whispered, "..."这类英文对白会抽取为英文角色和对白;默认language=auto会跟随英文源文档,完整剧本文本使用Project Info、Characters、Script、Name: line等英文标签,不混入中文旁白或中文占位文案。 - 动作:从叙事正文中提取多条可表演动作、环境和道具线索作为
actionbeats;纯对白场景使用简短动作占位,避免重复对白正文。 - 转场:非末场转场会指向下一场标题,末场使用淡出。
- 旁白:无任何人物线索的场景会使用独立
旁白角色承载voice_over;若叙述正文能识别角色,则优先把场景归属到真实人物。
python -m pytest -q
python scripts/verify_ui.py
python scripts/verify.py
python -m streamlit run app.py当前发布目标是:clone 后安装依赖,执行 python scripts/verify.py 即可看到可用功能、前端 smoke、UI 合约和通过的校验结果;合并到 main 后保持同一入口可用。