character-refs
给任何故事里的角色真出参考图(小说改编、自己原创的故事、单独设计一个角色都行,不需要小说原文): 一段话描述角色,拆成分层字段、补全后确认,…
从小说或短故事里拆出角色表、人物画像、形象提示词、音色提示词, 其中形象提示词含一张角色设定图的完整版面指令(左半身像 + 右全身三视图 + 细节条), 产出 JSON + Markdown + 可交互的 report.html。 报告语言可指定(--lang),默认中文,任意语言都支持;零依赖、零 API key、不出图。 Use when asked to 拆小说角色、分析人物、生成角色卡、character sheets from a novel。
$ npx -y skills add eternityspring/shuohao-skills --skill novel-characters --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/novel-charactersContext preview
The summary Claude sees to decide when to auto-load this skill.
从小说或短故事里拆出角色表、人物画像、形象提示词、音色提示词, 其中形象提示词含一张角色设定图的完整版面指令(左半身像 + 右全身三视图 + 细节条), 产出 JSON + Markdown + 可交互的 report.html。 报告语言可指定(--lang),默认中文,任意语言都支持;零依赖、零 API key、不出图。 Use when asked to 拆小说角色、分析人物、生成角色卡、character sheets from a novel。
name: novel-characters
description: |
从小说或短故事里拆出角色表、人物画像、形象提示词、音色提示词,
其中形象提示词含一张角色设定图的完整版面指令(左半身像 + 右全身三视图 + 细节条),
产出 JSON + Markdown + 可交互的 report.html。
报告语言可指定(--lang),默认中文,任意语言都支持;零依赖、零 API key、不出图。
Use when asked to 拆小说角色、分析人物、生成角色卡、character sheets from a novel。
allowed-tools:
- Read
- Write
- Bash
- Task
- Glob
metadata:
version: 2.0.0
triggers:
- novel-characters
- 拆角色
- 拆书角色
- 小说角色
- 人物画像
- 角色卡
- 三视图
- character sheet from novel
license: Apache-2.0
requires:
bins:
- node # >= 18,只用标准库,无 npm 依赖
runtimes:
- claude-code
- codex输入一篇小说/短故事,输出每个角色的:人物画像、形象提示词、音色提示词、角色设定图的版面指令。
**本 skill 不出图,只产提示词。**出图是下游的事——它要选模型、选画风、选画幅,那三件事在这里一个都答不了。
`{baseDir}` = 本文件所在目录。脚本 `{baseDir}/scripts/novel-characters.mjs`,零依赖,`node` 直接跑。
**运行环境**:Claude Code 和 codex 都能跑,没有差别——这条管线全是 node 脚本加模型读写,不碰任何本机可执行文件。
---
用户可以指定语言,比如「用英文」「--lang en」「日本語で」。**没说就是中文(`zh`)。**
这个 `lang` 会一路传下去:第二趟生成角色卡时决定人类可读字段用什么语言,`validate` 和 `render` 也都要带上。
**界面文案分两种情况:**
node {baseDir}/scripts/novel-characters.mjs ui-template <lang>它打印一份英文骨架,把每个值翻译成目标语言,整块放进 `cast.json` 顶层的 `ui` 字段。渲染时会合并进内置表。
**不给 `ui` 的话 `validate` 会直接报错**——否则报告会是「角色内容是法语、界面标签是英文」的半吊子状态。
支持的语言不受内置表限制,法语韩语西班牙语都能出完整报告。
用户给文件路径就直接用。直接粘正文的,**先落到一个临时 .txt**——后面校验「引文是否逐字」要拿原文比对,没有原文文件这步就没法做。
确定输出目录:用户指定就用;没指定就用原书同级目录。
**有 `outline.json`(novel-outline 的产出)就一起要过来,走 seed**——大纲是角色设定的上游,它的 `characters` 块已经定死了角色清单:
node {baseDir}/scripts/novel-characters.mjs seed <outline.json> > <workdir>/seed.json搬过来的是大纲已经拍板的事实,留空的是这一层才该做的设计:
| outline 的字段 | seed 之后 | | --- | --- | | `id` | 原样保留成角色码——下游 script / storyboard 用它引用角色 | | `name` | 角色表就照这份,**不再自己判断谁该进** | | `tier` | 映射成 `importance`:`lead` → `protagonist`、`support` → `supporting`、`functional` → `minor` | | `arc` | 直接落进 `persona.arc` | | `role` / `from` | 进 `seedNote`——定位(女主 / 反派)与「由原著的谁合并而来」,扫原文时知道该收哪几条线的戏 |
留空待填:`aliases`(要读原文才知道)、`oneLiner`、`persona` 其余各项、`image`、`voice`。**seed 出来的是骨架不是成品**,直接跑 `validate` 会报一堆字段缺失,那是预期的——后面 Step 2–6 就是来填它的。
两处口径要守住:
**没有 `outline.json` 也照常跑**,本 skill 不依赖它——跳过 seed,从 Step 2 开始自己从原文拆角色表。
node {baseDir}/scripts/novel-characters.mjs chunk <book.txt> <workdir>打印 `{"chunks": N, ...}`。
**当前环境支持子代理就并发**(Claude Code 的 Task、codex 的 subagent):每块一个子代理,**所有调用放在同一条消息里**才是真并发。不支持就一块一块串行读,结果一样,只是慢。
每个子代理的任务: 1. 读 `{baseDir}/references/roster-pass.md`,照它执行 2. 读 `<workdir>/chunk-NN.txt` 3. 把 roster JSON 写到 `<workdir>/roster-NN.json` 4. 只回一句「done NN,抽到 X 个角色」
node {baseDir}/scripts/novel-characters.mjs merge <workdir> | tee <workdir>/merged.json落到 `merged.json` 不只是留档:Step 6 的 assemble 靠它拿同档角色的戏份顺序。
按名字+别名精确收敛(某块把「陆」列成「陆行远」的别名,两条就并成一个人),notes 累加、quotes 去重,按出现块数降序——出现的块越多戏份越重。
输出是 `{ "characters": [...], "mergeCandidates": [...] }`。**`mergeCandidates` 要逐条复核**:精确匹配只能收敛两块恰好写了相同称呼的情况,剩下的是语义判断,脚本做不了。候选来自名字包含关系(`「陆」⊂「陆行远」`)——是强信号不是判决,同姓的父子、兄弟就不能合。候选之外你自己看出来的同人(「陆先生」和「行远」没有包含关系,不会进候选)也要合。
要合并就写一份 merges.json 再落地:
{ "merges": [{ "keep": "陆行远", "absorb": ["陆", "陆先生"] }] }node {baseDir}/scripts/novel-characters.mjs merge <workdir> --apply merges.json | tee <workdir>/merged.json`keep`/`absorb` 用名字或任一别名定位都行,找不到会直接报错。输出仍带 `mergeCandidates`,剩下的都确认是不同的人(或清空)再进下一步。没有要合的就直接往下走——但 `merged.json` 必须留着。
取前 N 位。默认 30,用户说了就听用户的。剩下的角色在最后汇报里提一句「还识别出 X 位没做画像」。
每个角色一份,同样能并发就并发。
每份任务拿到:
按 `profile-pass.md` 完成身份—外观语义自检后再交卡:人物档案、形象提示词、本地译文与设定图主体不能各说一种身份。大纲决定名单和改编取舍,原文观察补足外形依据;不要只给大纲而跳过 Step 2–4 的原文扫描。
角色卡 JSON 写到 `<workdir>/card-<slug>.json`。**断点续跑**:`card-<slug>.json` 已存在的角色不必重跑。
**同时写一段故事摘要**:用 `lang` 指定的语言,3–5 句,交代时空背景、核心情境、这几个人聚在一起的由头。短篇直接从原文写;长篇从各块的 roster note 归纳。不剧透结局,不写成推荐语。写到 `<workdir>/summary.txt`。非内置语言的话,把 Step 0 翻好的 ui 整块存成 `<workdir>/ui.json`。
然后合成 cast.json——**用 assemble,不要手拼**(手拼会丢字段、写错顶层键):
node {baseDir}/scripts/novel-characters.mjs assemble <workdir> \
--source <书名> --lang <lang> \
--out <输出目录>/<书名>-cast.json坏卡会被逐个点名——哪份 `card-*.json` 坏了就只重跑那个角色,其他不用动。
同档角色的先后是戏份顺序,来自 Step 4 留下的 `<workdir>/merged.json`(assemble 自动读,也可用 `--order` 指别的文件)。报告左栏「按戏份排序」的序号就靠它——看到「同档角色将按文件名序」的警告说明 merged.json 丢了,回 Step 4 重新生成。
node {baseDir}/scripts/novel-characters.mjs validate <cast.json> <book.txt>记得带上 `--lang`(Step 0 定的)。检查:结构、`importance` 枚举、**引文逐字**、**出图提示词不含人名**、**语言分工**(人类字段跟随 `lang`、出图/TTS 提示词永远英文)、以及**非内置语言必须带 `ui`**。
**有违规就按报错逐条修,改完重跑,直到通过。** 这四类错模型真的会犯——这套检查就是被真实输出打出来的。
cd <输出目录>
node {baseDir}/scripts/novel-characters.mjs render <cast.json> --md > <书名>-cast.md
node {baseDir}/scripts/novel-characters.mjs render <cast.json> --html > report.html语言取 `cast.json` 里的 `lang`,要临时覆盖就加 `--lang <code>`。
`render` 默认去 cast.json 同级的 `images/<slug>-sheet.png` 找图;图在别处就用 `--images <目录>` 指过去(任意路径)。**本 skill 不产生这些文件**——下游出完图,重跑一次 render 就能把图嵌进报告。
report.html 的样式约定见 `{baseDir}/references/report-style.md`——要改样式先读它,别把它改回通用卡片墙。
最终落地:
<输出目录>/
├── <书名>-cast.json
├── <书名>-cast.md
├── report.html ← 双击就能开
└── images/ ← 本 skill 不写这个目录
└── <slug>-sheet.png ← 下游出完图放这儿,render 会捡起来一句话说清:角色数、报告路径。校验一次没过的话,说明修了什么。原文被截断要明确说清楚。
AI 短剧制作的 skill 集合:从一本小说到直接喂生成管线的制作素材——拆角色、排大纲、出场景与道具设定、写剧本、切分镜。给 AI 编码 agent 用,Claude Code 和 codex 都能跑。 整条管线长这样——改编大纲收敛结构,剧本、场景、角色三者同步迭代,分镜只做输出不做新决定: 五段管线 skill 的报告都支持中英双语界面:默认中文,render --lang en 出全英文报告(数据内容保持原文)。character-refs 的报告同样内置中英日界面,其他语言现场翻译。
Repo: eternityspring/shuohao-skills
给任何故事里的角色真出参考图(小说改编、自己原创的故事、单独设计一个角色都行,不需要小说原文): 一段话描述角色,拆成分层字段、补全后确认,…
给 AI 短剧出美术设定集(场景 + 叙事道具):场景的设计意图、一致性锚点、光照时段变体、 空景提示词;道具的戏剧功能、状态变体、尺度参照、白底无手提示词。 产出 art.json +…
把一本小说改编成短剧大纲五件套:改编说明、人物表、爽点表、分集梗概、资产清单, 产出 outline.json + Markdown + 单页评审报告(KPI…
给 AI 短剧写剧本:把 novel-outline 的分集梗概落成结构化的场次 + 节拍流(动作节拍与台词行交替), 台词逐句带说话人与语气,时长逐集按语速确定性折算。产出…
给 AI 短剧出分镜:三层结构——段(一次视频生成,≤15 秒)→ 分镜(段内 2–5 秒的剪切,认领剧本节拍) → 分镜图(每切一张关键帧:主分镜图钉 0.00…