固定 3 题材金标准输入(仙侠/都市/悬疑,各含最小 spec+world+outline 及开篇章), 经真实 assemble()+build_write_request() 组装 craft-on / craft-off 两版写章请求: - dry 模式(默认,零成本、免真实 LLM,可进 CI):断言 craft 教条块、genre 片段、 开篇黄金三章 marker 确实按 fixture 注入正确内容,且 craft-off 基线不含这三者; 并把两版将发送给模型的 prompt 并排 dump 供人眼看。这些断言即 tests/test_craft_eval.py, 是 craft/审查注入路径的回归门禁。 - --live 模式(真实付费 LLM,绝不进 CI):经 gateway 各生成一章 + analyst 五维裁判, 凭据读 DB、路由走 tier_routing,与生产写章同一网关路径。 入口 `uv run python -m tests.craft_eval [--live]`;用法/成本/门禁说明见 README.md。
159 lines
6.0 KiB
Python
159 lines
6.0 KiB
Python
"""金标准输入 fixtures(灵感 F2)——3 个不同题材的最小 spec+world+outline。
|
||
|
||
每个 fixture 是一份**自造、不依赖 DB** 的最小设定:书级蓝本(含 genre)+ 世界观硬规则 +
|
||
定型主角 + 本章大纲节拍。评估脚本据此组装 craft-on / craft-off 两版写章请求。
|
||
新增题材只需追加一个 `FixtureCase`(genre 必须命中 `ww_config.GENRE_CRAFT` 才有片段可注)。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from dataclasses import dataclass, field
|
||
from typing import Any
|
||
|
||
from ww_core.domain.repositories import CharacterView, ProjectSpecView, WorldEntityView
|
||
|
||
|
||
@dataclass(frozen=True)
|
||
class FixtureCase:
|
||
"""一份金标准写章输入(题材 / 章号 / 书级蓝本 / 世界观 / 主角 / 本章节拍)。"""
|
||
|
||
slug: str
|
||
genre: str
|
||
chapter_no: int
|
||
spec: ProjectSpecView
|
||
world: tuple[WorldEntityView, ...]
|
||
characters: tuple[CharacterView, ...]
|
||
beats: dict[str, Any] = field(default_factory=dict)
|
||
|
||
|
||
_XIANXIA = FixtureCase(
|
||
slug="xianxia",
|
||
genre="仙侠",
|
||
chapter_no=3, # 开篇章(≤3)——覆盖黄金三章 marker 注入
|
||
spec=ProjectSpecView(
|
||
title="逆脉证道",
|
||
genre="仙侠",
|
||
logline="废脉少年叶尘为救绝症妹妹寻回春灵药,滴血觉醒上古逆天功法,逆修九境搅动仙门风云。",
|
||
premise="天地灵气稀薄,修行看灵脉品阶;废脉者纳灵极慢,被视作修行绝路。",
|
||
theme="卑微者的不屈与救赎——修的是道,护的是人。",
|
||
tone="热血隐忍",
|
||
narrative_pov="第三人称限知",
|
||
ending_type="正剧",
|
||
),
|
||
world=(
|
||
WorldEntityView(
|
||
type="设定",
|
||
name="九境修为",
|
||
rules={
|
||
"境界": ["淬体", "开脉", "灵动", "纳灵", "凝魂", "化虚", "通玄", "渡劫", "证道"],
|
||
"每境": "分前中后三重",
|
||
},
|
||
),
|
||
WorldEntityView(
|
||
type="设定",
|
||
name="灵脉",
|
||
rules={"作用": "决定纳灵速度", "废脉": "纳灵极慢,被视作修行绝路"},
|
||
),
|
||
),
|
||
characters=(
|
||
CharacterView(
|
||
name="叶尘",
|
||
role="主角",
|
||
motive="为身患寒髓之症、命不久矣的妹妹叶暖寻回春灵药",
|
||
backstory="青云宗外门弟子,天生废脉、常年受人轻慢,性子沉静隐忍。",
|
||
speech_tics={"风格": "话少、点到为止,逼到绝境时语气反而更冷更稳"},
|
||
),
|
||
),
|
||
beats={
|
||
"summary": "叶尘被同门构陷逐出青云宗,独行荒山避雨于古洞,"
|
||
"滴血觉醒《逆脉真解》,一招震退追杀者。",
|
||
"entities": ["叶尘"],
|
||
"text": "叶尘 古洞 滴血 觉醒 逆脉真解 震退 追杀者",
|
||
},
|
||
)
|
||
|
||
_URBAN = FixtureCase(
|
||
slug="urban",
|
||
genre="都市",
|
||
chapter_no=1, # 开篇第一章
|
||
spec=ProjectSpecView(
|
||
title="重启我的黄金时代",
|
||
genre="都市",
|
||
logline="落魄程序员林川一夜重生回到二十年前,凭前世记忆在时代风口逆天改命。",
|
||
premise="重生回到世纪初互联网草莽年代,机会遍地、格局未定。",
|
||
theme="不甘平庸者抓住的第二次机会。",
|
||
tone="爽快励志",
|
||
narrative_pov="第一人称",
|
||
ending_type="HE",
|
||
),
|
||
world=(
|
||
WorldEntityView(
|
||
type="设定",
|
||
name="重生规则",
|
||
rules={
|
||
"回溯": "重生回到 2003 年的大学时代",
|
||
"记忆": "完整保留前世记忆与二十年行业趋势",
|
||
},
|
||
),
|
||
),
|
||
characters=(
|
||
CharacterView(
|
||
name="林川",
|
||
role="主角",
|
||
motive="改写前世潦倒猝死的结局,护住家人、抓住时代机遇翻身",
|
||
backstory="前世三十五岁猝死于出租屋的落魄外包程序员。",
|
||
speech_tics={"风格": "表面随和、心里门儿清,说话带点自嘲"},
|
||
),
|
||
),
|
||
beats={
|
||
"summary": "林川在出租屋猝死后睁眼回到 2003 年的大学宿舍,"
|
||
"认出这是重来一次的机会,立下第一个目标。",
|
||
"entities": ["林川"],
|
||
"text": "林川 重生 2003 大学宿舍 认清机会",
|
||
},
|
||
)
|
||
|
||
_SUSPENSE = FixtureCase(
|
||
slug="suspense",
|
||
genre="悬疑",
|
||
chapter_no=2, # 开篇第二章
|
||
spec=ProjectSpecView(
|
||
title="雾隐镇失踪案",
|
||
genre="悬疑",
|
||
logline="刑警周砚回到多雾的故乡小镇调查连环失踪案,线索却一步步指向自己尘封的童年。",
|
||
premise="常年浓雾笼罩的封闭小镇,二十年前也发生过同样的失踪,无人被起诉。",
|
||
theme="逼近真相与自我和解的代价。",
|
||
tone="冷峻压抑",
|
||
narrative_pov="第三人称限知",
|
||
ending_type="开放",
|
||
),
|
||
world=(
|
||
WorldEntityView(
|
||
type="设定",
|
||
name="雾隐镇",
|
||
rules={
|
||
"环境": "常年浓雾、信号时断时续",
|
||
"旧案": "二十年前发生过同类失踪,卷宗离奇缺页",
|
||
},
|
||
),
|
||
),
|
||
characters=(
|
||
CharacterView(
|
||
name="周砚",
|
||
role="主角",
|
||
motive="查清连环失踪真相,也为解开自己童年缺失的那段记忆",
|
||
backstory="市局刑警,幼年从雾隐镇被送走,对故乡的记忆断片。",
|
||
speech_tics={"风格": "话短、爱用反问,审讯时不动声色"},
|
||
),
|
||
),
|
||
beats={
|
||
"summary": "周砚勘查第二名失踪者的住所,"
|
||
"在墙缝里发现一张与二十年前旧案笔迹相同的纸条,心头一凛。",
|
||
"entities": ["周砚"],
|
||
"text": "周砚 现场勘查 墙缝 纸条 二十年前 旧案",
|
||
},
|
||
)
|
||
|
||
# 金标准题材集:仙侠 / 都市 / 悬疑(各含开篇章,覆盖黄金三章 marker)。
|
||
FIXTURES: tuple[FixtureCase, ...] = (_XIANXIA, _URBAN, _SUSPENSE)
|