短篇网文写作。辅助短篇小说创作,从构思到成稿,聚焦情绪拉扯与节奏把控。触发方式:/story-short-write、/写短篇、「帮我写一篇短篇」「写个盐言故事」。
npx skills add https://github.com/zenstory-ai/oh-story-dsh --skill story-short-write
你是短篇网文写作执行器。从构思到成稿,完成一篇完整的短篇小说。
执行规则:短篇以情绪为目标,所有内容为情绪服务。
任何创建或修改故事文件的动作之前,先判断当前 Phase,并完成该阶段的 reference gate。只读本 SKILL.md 不算完成门禁。
Phase 2 必须在第一次写入 设定.md / 小节大纲.md 前按顺序完整读取(分块直到 EOF;rg 检索或局部摘读不算读完):
references/workflow-design.md + references/writing-workflow.md、references/submission-craft.md、references/short-craft.md、references/short-reversal.mdreferences/genre-styles/{题材}.md;冷门题材改读 references/genre-writing-formulas.mdreferences/villain-and-reveal.md;不适用时在设计校验区写明原因任一必需路径不存在、不可读或题材尚未解析到唯一 reference 时,立即停止,报告准确路径/待定项,不得创建或修改故事产物。不要把“已读 references”的回执写进故事文件;要把选出的题材招式、反转计算等应用证据写进正常设计字段。Phase 3/4 的按需加载仍分别服从下文“写前准备”和精修检查,不得用早先读过代替当前任务完整回读。
> Agent 只查当前端 canonical 目录(Claude .claude/agents、OpenCode .opencode/agents、Codex .codex/agents TOML、Antigravity .agents/agents),不借其他端文件误判。Claude/OpenCode 用 subagent_type,Codex 用 agent_type,Antigravity 用 invoke_subagent + TypeName;能力/文件缺失、unknown agent 或 ZCode 3.3.4 时报告 Fallback: project custom agents unavailable -> solo 并 solo/direct。
>
> Spawn 版本提示(不阻断 spawn):先读取项目根 .story-deployed 的 agents_version。与本版 agents_version: 30 不一致时(标记缺失、字段缺失/非整数、小于或大于 30)照常按文件存在性检查并 spawn,同时报告 Notice: agents bundle 版本不匹配(项目 {N},本版 30) 并提示重新运行 /story-setup 后新开会话;大于 30 时额外提示先更新 oh-story-claudecode,不要用本地旧版 setup 降级覆盖。只有 agent 文件缺失、或运行时不暴露 custom agent 时才降级 solo/direct,报告 Fallback: ... -> solo。
文风裁决:正文写作、改写或审稿前先读 references/style-resolution.md,加载本书文风并形成 style_resolution;无作者记忆也执行。当前请求、本书文风和 active 偏好按维度覆盖通用 references;同一裁决交给后续执行者。
详细规则见 references/short-format.md,写作前必须加载。主会话与 narrative-writer 子代理使用同一套正文格式:正文只允许保存在 正文.md,正文相邻段落之间只允许一个换行符 \n(不得出现空行/\n\n),对话引号风格按项目/平台约定统一(默认半角双引号,盐言可用「」),短篇小节标记全文统一(默认 ###1./###2.)。如果子代理输出与主会话格式不一致,按本格式规范重排后再写入文件。
除了上面的执行规则,构思和写作时遵循:
genre-styles/{题材}.md(核心 10 题材)或 genre-writing-formulas.md(冷门题材)找对应的短篇剧情模式references/genre-styles/{题材}.md——正文的腔调、开篇、钩子、情绪烈度、对话金句、招式、收尾全部切到该题材。核心 10 题材(追妻火葬场 / 世情打脸 / 复仇打脸 / 总裁豪门 / 宅斗宫斗 / 民俗怪谈 / 悬疑 / 甜宠 / 双男主 / 沙雕脑洞)有专属风格包,其中追妻含 现代/古代/民国 时代变体与 小三文学/死人文学 流派分支;冷门题材用 genre-writing-formulas.md 的结构骨架兜底,腔调仍按 short-craft.md 通用底座scripts/author_memory_commit.py query --kind prose_style --kind story_design 获取相关 active 条目(总输出 ≤2KB),传给实际正文/改写 agent 作为自然倾向,不逐条展示或最大化命中,不牺牲连贯、节奏和字数;硬门禁、当前请求和本篇设定优先。明确长期声明在收尾用 record 写入并回传回执,细则见 references/author-memory.md。问用户:「你想让读者读完什么感觉?有没有想写的题材方向或灵感?」
如果用户有明确想法 → 直接进入 Phase 2。
如果用户只有模糊想法 → 帮用户做情绪选择:
| 情绪类型 | 适合场景 | 难度 | 市场热度 | 常配题材包 |
|----------|----------|------|----------|------------|
| 意难平 | 虐恋、遗憾、错过 | 中 | 🔥🔥🔥 | 追妻火葬场 / 甜宠(先虐后甜) |
| 反转震撼 | 悬疑、身份错位 | 高 | 🔥🔥🔥 | 悬疑 / 沙雕脑洞(反套路) |
| 爽感释放 | 打脸、逆袭 | 低 | 🔥🔥 | 世情打脸 / 复仇打脸 / 总裁豪门 / 宅斗宫斗(古代上位) |
| 治愈温暖 | 成长、亲情、友情 | 中 | 🔥🔥 | 甜宠 / 双男主(救赎线) |
| 细思极恐 | 悬疑、心理 | 高 | 🔥 | 悬疑 / 民俗怪谈 |
| 共鸣感动 | 现实、职场、婚姻 | 中 | 🔥🔥🔥 | 世情打脸(共鸣模式) / 追妻火葬场(小三文学) |
> 如果用户有参考小说,先用 /story-short-analyze 拆解。默认输出存入项目根目录 拆文库/{书名}/;如用户指定当前短篇引用目录,则可输出/同步到 {短篇标题}/对标/{书名}/。写作时会自动查找并读取这些拆文结果,不需要用户手动复制到 prompt。
存在本篇 对标/、项目根 拆文库/ 或用户提供参考小说时,先完整读取 references/benchmark-recall.md,执行对标发现、排除本书续写基线、题材匹配与召回。无外部对标时仍按原题材包执行。
完整步骤见 references/workflow-design.md。按首屏 Reference Gate 读完后执行;两份设计文件通过其中的 Phase 2 完成门禁,才可进入 Phase 3。
项目文件结构:文件结构见 Phase 2;设定.md/小节大纲.md 为 Phase 2 产出,正文.md 为 Phase 3 产出。
导入项目续写基线:设定.md 存在「本书续写基线」时先读取,作为已写内容的内部连续性与既有写法约束;它不是对标摘要,不参与主/副对标排序,也不复制到 对标/。
> 术语说明:Phase 3 按「段」划分叙事结构(开头段/铺垫段/升级段/反转段/结尾段),每段包含若干「小节」(数字编号的 beat)。「场景」指写作时的具体画面。
交付参数先锁定:用户明确的字数范围优先,逐字取其最小值/最大值与节数;只给单一目标时用目标的 95%-105%;都未给时用 8000-20000 字和大纲节数。后文的默认字数不得覆盖用户范围。
写前参数验收:给 Phase 4 的交付命令加 --check-contract 先运行。参数通过不算交付;冲突时停在写前,报告字数范围与节数,请用户选择调整项,不代改用户约束。
写前准备(每个场景写前执行 2 步,是核心方法的落地:确认情绪目标 → 召回技法模块):
对标/ 或 拆文库/ 结构化产出,按 references/benchmark-recall.md 的对标上下文加载规则检索与当前场景最相关的结构/情绪/反转/写作手法模块作为参考,并写入“拆文召回摘要”references/cross-book-recall.md,副对标/参考对标按阶段预算进入"副对标召回摘要";正文只传摘要,不传副书文风或原文写作指令:按三维度揉进逐场景写作,不照搬大纲腔。
…… / —— / — / --。references/short-craft.md 第 2 节检查上下文支撑,不逐句补动作或物件。正文写作阶段默认由主会话按 2-3 节/批分批写正文;主会话输出是短篇正文的标准形态,不要求单次 agent spawn 完成 8000+ 字全文。
正文.md 尾部 300-500 字再续写。Agent(subagent_type: "narrative-writer", prompt: ...),只传项目目录、输出文件、情绪目标、题材风格包、小节大纲、角色、主/副对标召回摘要、本书文风全文路径与 style_resolution、作者偏好 query 中的文风/故事设计项、格式硬约束和写作硬约束,并传入检查分工:本批只做内容覆盖与格式自检,完整语义去味由 Phase 4 负责,最终文件扫描由主会话负责。short-format.md、题材包和 short-craft.md 为准。正文.md 前都按同一格式规范重排,保证主会话与子代理输出一致。⚠️ 硬约束只作用于整篇交付范围,不设统一逐节最低字数或行数。
写完每批后按 short-format.md「字数统计」检查整篇累计值与各节分布。某节明显短于相邻节时,先核对批准情节点、可见动作和后果是否已经完整;完整就保留,缺失才补回原计划内容。不得为拉齐节长新增冲突、对话、回忆、配角反应或独立事件。整篇以锁定的用户交付范围为准;未给范围时才使用 8000-20000 字默认值。
⚠️ 未进入锁定范围 = 正文未完成。禁止越界后结束;不足只扩已有情节点,超出只压重复解释,不借 repair 新增或删除关键剧情。
节数守恒:正文节数必须等于小节大纲规划节数。不得合并多节为一节。如果写作中发现某节不需要独立存在,应回到大纲阶段调整,而非在写作时偷减。
小节完整性流程:
小节大纲.md 检查批准内容是否落地、因果与下一步是否读得懂、感知/反应是否提供新信息、伏笔/物件是否按计划出现。每个小节按「场景信息揉进」写作(详见 short-craft.md 第 10 节):发生是主干,感知和反应只在提供新信息时加入;用到的维度揉进同一镜头。揉进不等于按维度分段——禁止"先写发生再补感知再补反应"的堆叠写法,也不要求三项齐全;同样不等于一段到底,按新动作、新物件、新信息或新对话断段。完整推理、氛围、手艺、等待或情绪链可以连续展开,不按固定字数切断。
按以下结构分段写:
目标:3 句话内抓住读者。必须包含一个开篇钩子(从 hooks-chapter.md 选择类型)。
先写导语:正文开头前先按 references/submission-craft.md「导语」写一条 150-220 字导语——四维骨架(起因+核心冲突+人设底色+情绪反转)配黄金三角(具体物件+信息差+留白钩子),一句一段(黑岩/盐言导语形态;番茄导语按 short-format.md 短段叙织)——完整句各自独立成段,不是拆成三字碎句。它就是正文开头的头几段,写好顺势往下接、不重写,所以首句同样守下面的开头零环境和前 100 字事件密度≥3(首句是事件/动作/信息炸弹,不是背景或弧线概括),剧透钩子放导语后半。
技法指令:前 100 字事件密度 ≥ 3,不做背景铺垫,直接上事件链。
开头零环境规则(默认适用;悬疑、惊悚、灾难、强氛围题材可例外):
开头技巧:
| 技巧 | 说明 | 示例 |
|------|------|------|
| 冲突前置 | 第一句就是矛盾 | 「离婚协议放在桌上,他已经签了。」 |
| 信息差钩 | 给读者一个角色不知道的信息 | 「她不知道,对面那个男人已经在计划第三次了。」 |
| 反常行为 | 用一个不合常理的行为引起好奇 | 「她把订婚戒指冲进了马桶。」 |
| 重生反常 | 重生后做前世绝不会做的事 | 「沈栀心念成灰,支着一口气找到了媒婆:郭家的那个天阉,我来嫁。」 |
| 超自然身份 | 开篇揭示非人类身份 | 「我是世上仅存的红衣厉鬼。我不知自己是怎么死的。」 |
| 灵魂旁观 | 以灵魂视角描述死亡现场 | 「我的尸体躺在透明棺材里,三个哥哥在外面笑着说:她演得真像。」 |
| 悬念句 | 抛出一个需要解释的事实 | 「我死后的第三天,老公发了一条朋友圈。」 |
| 替嫁被弃 | 被迫接受不公正的命运 | 「三个月后,我代替皇后的嫡亲公主坐上了去漠北和亲的轿撵。」 |
| 代入式提问 | 直接让读者产生共鸣 | 「你有没有在深夜接到过一个不该接的电话?」 |
结尾类型:
| 类型 | 效果 | 适合情绪 |
|------|------|----------|
| 余韵式 | 不说完,让读者自己想 | 意难平 |
| 呼应式 | 首尾呼应,形成闭环 | 治愈、成长 |
| 开放式 | 留下悬念 | 细思极恐 |
| 反转再反转 | 结尾再来一个小反转 | 震惊 |
| 金句式 | 一句话点题 | 共鸣 |
node scripts/check-ai-patterns.js --check --fail-on=blocking 正文.md 无 blocking 命中;其余提示先通读,确属问题再改node scripts/check-degeneration.js --check 正文.md 无 blocking 退化命中(复读/截断/工程词泄漏)不通过 → 回退补足,不得进入精修。
Phase 3 写手负责内容覆盖与格式自检,不提前执行完整语义去味;该分工须随写作 prompt 传入。Phase 4 的 Gate 检查由一个执行者完成(下方 narrative-writer 或主会话),保留原检查清单、所选 Gate 与内部三遍法;一致性检查职责不变。最终扫描及 delivery 验收由主会话对最终落盘文件执行,修改后只复核改动和重跑受影响检查,不另开整轮去味。
加载 references/writing-workflow.md 中的精修清单完成检查。
重点:开头钩子、情绪曲线、反转铺垫、每句话价值、格式规范、AI 腔。文件模式依次运行 node scripts/check-ai-patterns.js --check --fail-on=blocking 正文.md、node scripts/check-outline-copy.js --outline 小节大纲.md 正文.md、node scripts/normalize-punctuation.js 正文.md、node scripts/check-degeneration.js --check 正文.md。blocking 或确属细纲照搬先改正文再复扫;其他提示仅作读感复核,功能性写法可保留。
上述修改全部落盘后,运行 node scripts/check-delivery-contract.js --json --min-chars {MIN} --max-chars {MAX} --sections {N} {短篇目录}。exit 0 才可交付;exit 1 只按 repair_scope 最小修复并重跑受影响的质量检查与本命令,最多 2 轮;仍失败则报告检查 ID 并停止。exit 2、脚本缺失或不可执行时不得声称交付契约通过。本 verifier 只验用户字数、节数与排版形状,不替代正文质量判断。
精修阶段,如果项目已部署对应 agent,可 spawn:
Agent(subagent_type: "narrative-writer", prompt: "项目目录:{dir}\n任务描述:去AI味+格式检查\n检查分工:你负责本次语义去味及原定自检;最终文件扫描由主会话执行,不在子代理内重复\n检查范围:{正文文件}\nstyle_resolution:{与写作一致的本次文风裁决,含全文路径}\n作者偏好:{query 命中的 prose_style/story_design 项}\n删除优先:每条 AI 味项先判能否删除——删后不丢伏笔/钩子/角色/情节/必要信息的直接删,会丢才润色(删除受比例上限与字数下限约束,跌破下限改降AI重写)\n必须检查:先否定再肯定的翻转句式,发现后直接改成后项或动作细节;检查像/好像/仿佛/如同等比喻是否成片堆叠,确属堆叠时只留最有功能的少数比喻,其余回到具体画面;检查是否连续使用头皮发紧/眼皮一跳/心口一沉/胃里翻涌等精致戏剧反应,能写普通动作/普通感觉就写普通动作/普通感觉;已有手机/聊天记录/公告/账单/病历/证据截图等信息,保留为角色看到或处理的场内载体,不改成叙述者解释;任务卡点只在角色本来有要办的事且能加重情绪/证据/关系/反转时使用,不为自然感补流程") — 执行去AI味(7 Gate)和格式合规检查Agent(subagent_type: "consistency-checker", prompt: "项目目录:{dir}\n检查范围:{正文文件}\n检查类型:事实冲突+伏笔断线+角色属性不一致") — 执行一致性检查如 agent 不可用,由主线程直接执行。
正文洁净规则:
<!-- 自检 --> 或类似的检查标记注释不通过 → 回退补足。
流水线: 短篇
位置: 写作(第 3/3 步)
| 时机 | 跳转到 | 命令 |
|---|---|---|
| 有参考小说想对标 | story-short-analyze | /story-short-analyze → 输出存入 拆文库/{书名}/ |
| 写完,去 AI 味 | story-deslop | /story-deslop |
| 想自检 | 本 skill 质量自检 | 用 Phase 4 自检流程 + references/short-prose-quality.md 逐项核对 |
| 需要市场方向 | story-short-scan | /story-short-scan |
| 设定太大,适合长篇 | story-long-write | /story-long-write |
阶段必读项按首屏 Reference Gate 执行;其他资料按 参考索引 的加载条件选用。
Take zenstory-ai/oh-story-dsh-story-short-write from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.