文笔层:AI 味机检、标点规范化、分块大量扩写(第 1 集成稿 10805 字)

- 修复上次提交把 dfannals/cli.py 写成 0 字节的问题(它是唯一入口,导致管道不可运行)
- 性别:解析 <caste>,人物表与写作素材带性别(Ral Fastenhatchets 实为女性)
- 新增 dfannals/deslop.py:AI 味机械诊断(硬伤词/句式/标点,按千字密度报告)
- 新增 dfannals/normalize.py:标点与结构清理(引号配对、重复段落与句子、模型自加的小节标记)
- 新增 dfannals/expand.py 与 prompts/literary-expander.md:按年份场景分块大量扩写
- 专名防幻觉:每块附史料专名白名单,事后按段自动修复可疑专名
- episode 命令并进文笔层(骨架稿另存 .skeleton.md),新增 expand 命令做 A/B 对照
- 新增 notes/switched-threads.md 与 test_deslop / test_normalize 回归测试
- 提交前拦截「已跟踪文件为空」,防止上述事故复发
This commit is contained in:
Chen Yi
2026-10-05 22:27:02 +08:00
parent 08a032120a
commit 8630dcad55
23 changed files with 1971 additions and 56 deletions
+9 -6
View File
@@ -54,14 +54,15 @@ class CastRow:
fid: int
name: str
race: str
gender: str # 男/女/空(史料未载)
span: str
role: str # 主角 / 对手 / 配角
appearances: int
identity: str
def as_row(self) -> str:
return (f"| {self.name} | {self.race or '—'} | {self.span} | {self.identity or '—'} | "
f"{self.appearances} | {self.role} |")
return (f"| {self.name} | {self.race or '—'} | {self.gender or '—'} | {self.span} | "
f"{self.identity or '—'} | {self.appearances} | {self.role} |")
def _identity_of(world: World, fid: int, events: list[Event]) -> str:
@@ -107,6 +108,7 @@ def collect_rows(world: World, thread: Thread, episodes: list[Episode], max_othe
fid=fid,
name=world.figure_name(fid),
race=fig.race if fig else "",
gender=fig.gender if fig else "",
span=fig.alive_span if fig else "生卒不详",
role=role,
appearances=appearances.get(fid, 0),
@@ -136,8 +138,9 @@ def _bio_prompt(world: World, rows: list[CastRow], events: list[Event]) -> str:
for row in rows[:BIO_LIMIT]:
facts = [
(
f"{row.name}({row.race or '种族不详'},{row.span},本卷出场 {row.appearances} 次,"
f"身份:{row.identity or '不详'},在故事里是{row.role})"
f"{row.name}({row.race or '种族不详'},{row.gender or '性别史料未载'},{row.span},"
f"本卷出场 {row.appearances} 次,身份:{row.identity or '不详'},"
f"在故事里是{row.role})"
)
]
for e in events:
@@ -197,8 +200,8 @@ def build_cast(
f"本卷主角线索:{'、'.join(world.figure_name(m) for m in thread.members)}",
f"线索跨度:{_span_of(thread, episodes)}",
"",
"| 人物 | 种族 | 生卒 | 身份 | 本卷出场 | 角色 |",
"|---|---|---|---|---|---|",
"| 人物 | 种族 | 性别 | 生卒 | 身份 | 本卷出场 | 角色 |",
"|---|---|---|---|---|---|---|",
]
lines.extend(row.as_row() for row in rows)