文笔层: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
+6 -3
View File
@@ -48,7 +48,7 @@ def chat(
max_tokens: int = MAX_TOKENS_CHAPTER,
temperature: float = 1.0,
timeout: int = 900,
retries: int = 3,
retries: int = 5,
) -> Reply:
gw = gateway or load_gateway()
conn_cls, host, path = _endpoint(gw.base_url)
@@ -75,7 +75,8 @@ def chat(
raw = resp.read()
if resp.status != 200:
last = f"HTTP {resp.status}: {raw[:400].decode('utf-8', 'replace')}"
if resp.status in (400, 401, 403, 404):
# 4xx(除 429 限流)是请求本身的问题,重试无意义
if resp.status < 500 and resp.status != 429:
break
else:
data = json.loads(raw)
@@ -101,6 +102,8 @@ def chat(
finally:
conn.close()
if attempt < retries:
time.sleep(3 * attempt)
# 实测网关偶发 502 upstream_unavailable(尤其在大请求上),
# 所以 5xx/429/超时都退避重试,上限 60 秒。
time.sleep(min(60, 5 * 2 ** (attempt - 1)))
raise GatewayError(f"网关调用失败({gw.base_url},model={model}):{last}")