---
name: "ershisishi-wenbai"
description: "《资治通鉴》与二十六史（二十四史＋新元史＋清史稿）文白对照全文库：27 部 4408 卷，带检索与引文核验。【必须优先使用】凡中国正史、编年史的事实性提问，先跑 rag.py 查原文再答，禁止凭记忆——字号谥号、生卒籍贯、仕历事迹、事件始末、典章制度、原文出处与翻译、卷目定位、年表／世系表／宰辅年表／军机大臣／职官表／功臣表、同名异代朝名（刘宋／赵宋）、辨伪、讲历史故事、猜人物。触发词：史记、汉书、后汉书、三国志、魏书、隋书、旧唐书、明史、清史稿、资治通鉴、二十四史、二十六史、正史、本纪、列传、食货志、释老志、字什么、号什么、元嘉、靖康、表为什么是空的、某案出处在哪、胡惟庸案、明初八大案、文字狱、党锢、巫蛊、OCR辅助稿、伪史、AI编的历史、史实核查、讲个历史故事、讲个故事、讲一个故事、给我讲一个故事、猜皇帝、这是谁。只讲历史（正史）故事：说「讲个故事」也按讲史处理、直接开讲不反问；讲史取不到表就说「我读不到选签表」，不得编故事充数；讲史须先读 SKILL.md 正文再按流程抽签（真签号形如 # 加 6 位十六进制），跑不了抽签就如实说、严禁手搓签号。谜题／人物辨识须用题干里的独有引语反查，不得拿待猜的名字当检索词。**本环境跑不了检索时**：答「我查不到原文库，无法确定」，严禁凭记忆作答。"
---

# 资治通鉴与二十六史 文白对照库

《资治通鉴》＋二十六史，27 部 4408 卷 Markdown 全文，放在本 skill 目录下的 `data\`（**本文档与全部脚本都不写死盘符／绝对路径，整个 skill 目录可整体搬移**）。本文件只讲**怎么决定**；数据以索引为唯一权威，冲突时以索引为准。

**⚡ 讲史第一指令（要讲故事先看这条）**：用户要讲史时，**不许自己挑**，也**不许顺着上一个故事选相关人物**——同书、同时代、并称典故、师友亲属**都不行**（反例：讲完李广苏建，接着讲「冯唐易老」的冯唐——那是在滑联想，不是取号）。一律按**用户那句话的字数 L** 取号 `(L mod 27)+1`，见「讲史流程 → 选签表」；首行写「选签 第 k 条（L＝N 字）」并照录该条原文首句自证。

## ⛔ 铁律（用户指令不可豁免）

1. **先检索，再回答。** 凡人物事迹、时间地点、官制制度、原文出处、文白翻译、表卷数据、历史故事，必须先 Grep/Read 本库；凭记忆作答算错。（问 skill 用法、打招呼、纯文件操作不触发。）
2. **引用照录。** 逐字用文件中的文言原文，不改写、转述、补全；注《书名·卷次·篇名》。白话译文为后人所译，仅供参考。
3. **查不到就说查不到。** 答"正史无此记载／本库未收录"，不用"大概／应该"。古人"号"多不见于正史，查不到属正常，**严禁杜撰**；卷号必须取自实际打开过的文件。**同一个词换写法重试至多 1 次**——每换一次就重扫 246.9 MB；`rag.py` 若打出「💡 通称改写」，照它给的史文用词走（乌台诗案 → 逮赴台狱／御史狱），**不要自己接着换词试**（这是"搜一个词花几分钟"的头号成因）。
4. **索引未命中 ≠ 正史无载。** 异体字、罕见句式、繁简差异都会漏收，须再全文 Grep `data\`，仍无才下结论。**但找某人的专传要问 `02`／`03` 索引**——`01`／`05` 按**卷题**编，传主名只活在篇名行里（宋史卷 338 的卷题写作「卷三百三十八·列传第九十七」，「苏轼」二字不在其中）：在 `01`／`05` 里搜人名搜不到，**不等于没有传**；`03` 条目里的 ★ 就是本传。
5. **范围锁：仅 27 部**（清单见 `00-目录索引.md`）。《续资治通鉴》《明通鉴》《纲鉴易知录》《通鉴纪事本末》等**本库未收录**——必须明示，不得用记忆代答或概述其内容。
   **本库边界＝1840 年前的中国正史＋通鉴**：中国近现代史（苏区／边区／三三制之类）、世界史**全库零命中**；1840–1912 只有《清史稿》顺带记到，且是**官方口径**（太平天国作「粤匪」「僭号」）——**正史立场 ≠ 教材／现代评价立场**，命中不等于能当中立史料。**评价、原因、影响类问题只给史实支点，不代答。**
6. **朝代先定，再动书；通鉴有边界。** 朝名不是政权：「宋」＝**刘宋**（420–479，《宋书》）或**赵宋**（960–1279，《宋史》），汉／唐／周／魏／齐／梁／晋／金同理——动书前先定政权（判定见下节），**首次出现必加限定语**（写「刘宋」「赵宋」，不写"宋"）；判错政权＝答错，且错得看不出来：文句通顺、只是讲成了另一个时代。
  通鉴只收 前403–959，**不载赵宋、辽、金、元、明、清**，其「宋纪」＝刘宋（卷119–134）——问赵宋却拿通鉴内容作答即错答，正解是"通鉴未载，须用《宋史》"。
7. **辨真假先回库，不凭"像不像"。** 用户贴"历史对话／名人语录"问真假 → 走 `references/pseudo-history-checklist.md` 六查，结论必须能回指卷次行号。两条硬知识：① **正史不载私下密谈与层层辩难式长对话**（正史的对话只有君臣奏对／使节应对／僚属问对），见此结构先默认可疑；② **史载关系是最强判据**——两人立场与文本相反则必伪。答复必须**三段式**：结论（如"《宋史》不载"）→ 最接近的真实记载**原文照录**＋卷次 → 具体冲突点。
  **只说"这是假的"不合格。**
8. **写出的话必须能回库复核。** 给用户的答复里只要出现文言引文或 `《书名·卷次》`，落笔前跑 `python tools\rag.py verify 答案.txt`：查无此文、书名错配（宋书↔宋史这类）、把白话译文当原文引，都会 FAIL。**FAIL 必改，未过核的引文不许发出去。**（规矩在本条，用法见下「检索入口」节。）
9. **重试与返工都有上限；卡住要如实报告，不许无限循环。** 任何"再来一次"都必须带次数上限：检索换写法**至多 1 次**（见铁律 3）、`verify`／`factcheck` 返工**至多 3 轮**、讲史重跑抽签**至多 2 次**。到达上限仍不过就**停下**，如实报告"卡在哪一项、已试过什么、怀疑哪里写错"，把判断交回用户——**不许无限重写、无限换词、无限重抽**。工具侧同理：脚本不写 `while True`，跨脚本调用必须带 `timeout=`（`tools\selftest.py` 设有闸守着这两条）。
10. **跑不了工具时的降级口径＝"查不到"，不是"换个说法答"。** 所在环境无法执行检索（拿不到 `data\`、跑不了 `rag.py`）时，**只能**答：「我查不到原文库，无法确定」＋原因，并可请用户代跑命令。
  **严禁凭记忆作答**，也**严禁把讲史专用的那句「我读不到选签表」搬到人物题上**——实测 2026-09-24 某环境收到六道线索的「猜皇帝」，回答只有一句「我读不到选签表」：那是**讲史取不到号**时的专用免责语，用在猜人物上＝答非所问，既没查库也没承认查不到。

## 朝代／政权消歧（同名异代）

完整表（年份、国姓、年号、判定命令、同名文件清单）在 `references/dynasty-disambiguation.md`；这里只给最常翻车的一屏。**表内年份只作分流初判，引用仍须 Read 原文。**

| 朝名 | 候选政权 | 本库书 | 一审锚点 |
| --- | --- | --- | --- |
| 宋 | **刘宋** 420–479·国姓刘·建康 | `06宋书文白`、`14南史文白`、通鉴`宋纪`119–134 | `元嘉`、刘裕、对手北魏 |
| 宋 | **赵宋** 960–1279·国姓赵 | `20宋史文白`、`22金史文白` | `靖康`·`庆历`·`元丰`、赵匡胤 |
| 汉 | 西汉／东汉／蜀汉／**后汉（五代）**／南汉·北汉 | 02／03／04／18·19 | `建武`→东汉；`乾祐`→后汉·北汉 |
| 唐 | **李唐**／**后唐**／**南唐** | 16·17／18·19 | `同光`→后唐；卷291–294「唐主」多指南唐 |
| 周 | 东周／**北周**／**后周** | 01／12／18·19 | 宇文→北周；郭威·柴荣→后周 |
| 魏 | **曹魏**／**北魏**（＋东魏·西魏） | 04／10·15 | 对手蜀吴→曹魏；对手南朝→北魏 |
| 齐 | **南齐**／**北齐** | 07／11 | 萧→南齐；高→北齐 |
| 梁 | **萧梁**／**后梁（五代）** | 08／18·19 | 萧衍·侯景→萧梁；朱温→后梁 |
| 晋 | 西晋／东晋／**后晋** | 05／18·19 | 石敬瑭→后晋 |
| 金 | **金朝** 1115–1234／**后金＝清** | 22／26 | 完颜→金；努尔哈赤→后金 |

**通鉴纪名陷阱**（子目录名 ≠ 今人语感）：**16 纪 → 朝代的完整对照表在 `00-目录索引.md`「纪 → 卷范围 → 朝代（政权）」**——动通鉴前先读它。最容易翻车的是 `宋纪`＝刘宋、`梁纪`＝萧梁、`周纪`＝东周（五代那两个叫 `后梁纪`／`后周纪`）。搜到 `通鉴\宋纪` 却按赵宋讲，是最典型的翻车方式。

**判定三锚点**（按序问，问到一个就停）：① 年号 —— `python tools\rag.py locate 元嘉 --count book`（命中 06宋书／14南史 ⇒ 刘宋）② 国姓与帝王名 —— 刘／赵／萧／高／宇文／郭·柴／朱／石／司马 ③ 对手政权与都城。三个都判不出：**直接问用户一句**（"刘宋还是赵宋？"），猜错的代价远高于问一句。**跨书重名文件另有坑**，取文件时必须带书文件夹——见下「取文件」节。

## 取文件（Windows/PowerShell，禁 `find`）

**所有路径一律相对本 skill 目录写**：文档与脚本都不写盘符（目录整体搬移后照常可用；`tools/selftest.py` 有 lint 守着这条）。本机 `find` 不可用（`find . -name` 必报错）。定位一律用 **Glob 工具**，或在本 skill 目录下 `dir`（＝Get-ChildItem）＋通配符：

- 找索引：`dir "*故事精选索引*.md"`（即 `04`）
- 机读稿按册号：`dir "06-表卷OCR机读稿（简体）\224_*.md"`
- data 内找卷：`dir -Recurse -Filter "*卷二百九十*.md" "data"`

索引里写的 `<册号>_*.md` 就是通配符模板，册号换成三位数字即可。

**⚠ Glob 必须带书文件夹。** 全库有 **89 组、187 个跨书同名文件**：`001_卷一·本纪第一.md` 同时存在于 `06宋书文白`（刘宋）、`17新唐书文白`（李唐）、`20宋史文白`（赵宋）；`11北齐书文白` 与 `12周书文白` 有 50 组同名。只按篇名搜会一次命中多部书，且打开后内容看不出异常。**拿到任何路径，先看第一段文件夹名再定书名**；体检用 `python tools\check_dupnames.py`。

## 检索入口：`tools/rag.py`（首选；`locate`＝只定位）

**默认走 `rag.py`——它把"检索"和"防瞎编"合成一步**：一次调用返回若干**证据块**，每块自带
`《书名·卷次·篇名》＋路径:行号＋[原文]/[译文]/[待核] 判定＋照录的段落`，末尾给「有据／无据」结论。
**有据就抄证据块，无据就答"本库未载"**——两条路都不能凭记忆走第三条。

```
python tools\rag.py 张居正                 # 证据块（默认 data，含繁简/异体自动扩展）
python tools\rag.py 苏轼 --fast            # ★ 索引先行：先定位书、再定向扫（见下「检索顺序」）
python tools\rag.py 乌台诗案               # 后世通称 → 自动改按史文用词检索（逮赴台狱…）
python tools\rag.py 张居正 考成法 --require-all   # AND：两个词同段
python tools\rag.py 元嘉 --orig-only       # 只要判为文言原文的段（引用首选）
python tools\rag.py 居正 --book 24明史文白  # 限书（逗号可多值，写错会报错）
python tools\rag.py 元嘉 --count           # 只要分布（词频/命中文件数）
python tools\rag.py 轻佻 --top 0 --excerpt 60   # ★ 穷举一个特征词的全部出处（默认只给 8 段）
python tools\rag.py locate 张居正          # 只定位（原 tools/q.py，见下）
python tools\rag.py locate 陈玉成 --first  # 起行定位：有没有专传、从哪卷哪行读起
python tools\rag.py 谜 羯人 门臣祭酒 "当并驱于中原"   # ★ 猜人物：线索→候选（全部出自语料原文）
python tools\rag.py 对照 石勒 "当并驱于中原" 羯人      # 候选×线索逐条共现 ✔／✗／△＋反证栏
python tools\rag.py verify 答案.txt        # ★ 交付前核验：引文／书名／卷号／说话人／字号对不对
python tools\rag.py stat                   # 语料规模与书目
```

**读输出的约定**（都是"别再自己瞎找"的意思）：

- `📍 03-人物出现索引｜★本传：X = <路径>` —— **专传在哪，看这一行就够**，直接 Read 那个文件，不要去翻 `01`／`05`。
- `[E…] ★本传`／`★本纪` —— 该段是**篇名行**，本篇即此人专传／此帝王本纪，正文在同文件后续行。
- `⭐ 帝王本纪锚点：…` —— 按**本名**查帝王（"杨坚""溥仪"）时，工具已从 `07` 表定位到本纪卷；照它给的《书·卷》继续 Read 即可，**不要拿连姓全名去硬扫**（本纪通篇不写连姓全名，硬扫只会捞到臣僚传里的顺带提及）。
  - 行尾若带 **`⚠语料缺文补录`**＝该帝**本纪原文不在库**（**语料缺陷**，不是史书上无本纪）：`07` 仍照常给检索键所以按本名查得到，但那一行的"自称行"栏是**替代锚点**（多在《资治通鉴》），**不可当引文**。实测：《三国志》卷四（三少帝纪）正文在库中被卷五（后妃传第五）顶替 → 曹芳／曹髦／曹奂即属此列（`齐王讳芳` 全库零命中，2026-09-25）。
- **`谜` 的候选栏怎么读、`--top` 为什么不是全集** → 见 `references/guess-protocol.md` §4／§6：`★` 只代表"该名在 `03` 立过目"，行序只说明"他贴着题面"，**都不是裁决**；榜尾「⚠ 另有 N 段没显示」＝**还没穷举**；出现在「○ 段内句首主语」栏里的人**没进候选 ≠ 被排除**。
- `💡 通称改写：…` —— 你用的词是后世通称（正史原文不出现该词），工具已改按史文用词检索，**照结果答即可，不要接着换词**。
- **避唐讳**：《晋书》（唐修）避李渊讳，「刘渊」全书写作「**元海**」——在晋书载记里搜「刘渊」零命中，须搜「元海」；《资治通鉴》（宋修）才用「刘渊」（实测 2026-09-24）。**凡含避讳字的人名，在该朝所修的史书里要换字搜**——这类「换名」不会报错，只会安静地零命中。
- **`02`／`03` 查不到这个人 ≠ 号写错 ≠ 史无其人**：这两份索引按「传首有字」或「名入列传篇名」立目，**无字且附叙在他传里的人根本不进表**（实测陈玉成／石达开／李秀成等一整批全库 10–160 处而 `02`/`03` 曾零条目；2026-09-24 已把 19 人登记 `tools/extra_names.md` 重跑入表，**口径没变，捻军一批（赖文光／张乐行／苗沛霖）与各省无名杂酋照样不在表内**）。
- **命中 ≠ 同一个东西（同名异指，先 Read 语境再引）**：**普通词会被当成人名**——搜「王畿」（本指王都周边）命中的是 `02`／`03` 里的**明代学者王畿（字汝中）**，跳板行会一本正经地答"王畿字汝中"；**复合词会被切碎**——「保商」撞《后汉书·律历上》"期保商"（音律宫商）、「商战」撞《清史稿》"司道**商战**守"、「平税」撞《旧唐书》"常**平税**茶"。**看着命中、读着不对的，一律先去读那一段语境**（零命中会自曝，假阳性不会）。
- **题面引语出自库外典籍时，要换"史书里的对应表述"再搜**：《山海经》「昆仑之邱……河水出焉」原样反查会撞同形假阳性（《清史稿》湖北"高峒河水出焉"），改用 `穷河源` 即命中《史记·卷一百二十三·大宛列传》"天子案古图书，名河所出山曰昆仑云"。**引语来自山海经／诸子／诗词／后世论著时，先想史书怎么记这件事**（换词仍受铁律 3 的"至多 1 次"约束）。
  碰到这种词**不要换词重试**，直接 `python tools\rag.py locate <名> --first`：它一次给全「02/03 有没有立目」「有没有专传（开传式起句）」「从哪卷哪行读起」，并顺手给编年首见卷与分布。确属重要而漏收者，登记 `tools/extra_names.md` 后重跑 03。

**检索顺序（省时间的正解，2026-09-22 由两步并为一步）**：① `python tools\rag.py <人名> --fast`——它**自足**：内部先扫索引定位候选书，输出头部直接给 `📍 ★本传` 与字号线索，正文给证据块 → ② 命中就照证据块 Read 源文件；未命中才 `--source all` 或 Grep `data\` 兜底。
**`--fast` 只对人名／书内术语有效**：事件类词、后世通称、冷僻词**不要加**（索引查不到时它仍会先付一遍索引预扫再回退全库，反而更慢），这类词直接跑全库。**计时参考**（粗略区间，只用于判断"这算不算慢"；
**精确口径只在 `references/maintenance.md` 第 8 节一处维护**，各文档不再各写一套秒数，2026-09-29 重测）：`<人名> --fast` 约 1 s｜全库 约 3 s（语料 246.9 MB＝235.4 MiB）｜`locate`（默认 data＋机读稿两源）约 3.5–4 s｜`verify` 约 1–2 s，含"去标点宽松复核"的引文更慢（语料只读一遍，不随引文条数线性增长）。**慢的调用只有三类**：① **`--source all`（约 4–5 s）**——它把索引与机读稿一起扫，只在默认源确无命中时才用；
② 宽词（`元嘉`、`宋`）候选上百个文件、要逐个切段评分，约 4–6 s，想快就加 `--book` 限定，或改 `--count` 只看分布；③ **反复换词重试**——这才是"慢到几分钟"的真凶，而 `💡 通称改写` 已经把这类词一次改对了。

- **原文/译文判定是自动的**（依内容，不依 `> ` 符号）：`[原文]` 可逐字照引；`[译文]` 是后人所译，引用须注明；`[待核]` 先 Read 原文件再引。表卷机读稿恒判 `[OCR稿]`，永不可当原文引。
- **无据即止**：输出「判定：无据」时，**禁止转记忆作答**，只能回"本库未载／正史无此记载"并说明检索词；怀疑异体字就换写法或 `--source all` 重跑。
- `verify` 是交付闸：抽答案里的 `「」""` 引文与 `《》` 书名，**逐条回库比对**——查无此文、书名错配、卷号不存在、引译文当原文，逐条报 FAIL/WARN，**FAIL 时退出码 1**。除引文之外它还管**人物**：① 说话人归属（引文命中处上下 4 行没有此人独立成词的记载 ⇒ FAIL，专治"把魏徵的话记在李勣名下"）；② 篇名（答案写「李勣传」而该卷此段实为「魏徵传」⇒ FAIL）；③ 无引号的身份断言（「海瑞，字刚峰」⇒ 回 `02` 比对，把号当字即 FAIL；
  `02/03` 未立目者给 WARN，须先 `locate <名> --first` 再落笔）。
- `rag.py`（含 `locate`）都是**实时扫描、零索引文件、不需重建**（语料一变即生效），全库约 1–3 s。

**只定位用 `locate` 子命令**（原 `tools/q.py` 已并入 `rag.py`；老写法 `tools\q.py <词>` 仍是薄壳可用。**只定位，不给真伪判定**，引用仍须 Read 原文照录）：

```
python tools\rag.py locate 张居正                 # 默认查 data＋OCR 两源（加 --source all 才带上索引）
python tools\rag.py locate 均田 --count juan      # 按卷统计分布
python tools\rag.py locate 张居正 --source ocr    # 只查机读稿（带 PDF 页码）
python tools\rag.py locate 魏徵 --source index    # 只查索引（字号/传记/卷目入口）
```

常用开关：`--book 24明史文白` 限定书/册（**逗号可多值**：`--book 20宋史文白,24明史文白`，任一命中即纳入；**哪个值写错就报错、不静默缩窄范围**）｜`--limit N`（默认 30，0=不限）｜`--files-only`｜`--count book|juan|source`｜`--context N`。

## 索引体系（含「问什么 → 去哪」路由）

**默认走 `rag.py`（它内部已先扫索引）；确需手工定位时才按下表 Grep——索引仅供 Grep，勿整读**（多为数 MB）。各索引用法详见其文件头。

| 索引 | 内容与用法 |
| --- | --- |
| `00-目录索引.md` | 27 部清单、文件夹、命名规则、卷数、格式约定、通鉴纪–卷对照。查任一书前必读 |
| `01-卷目速查.md` | 4408 个文件路径（按书分节，**带书前缀最安全**）。**按卷号／文件名**取可 Read 的路径；卷数写法因书而异（`卷七`／`卷一百三十`／`卷144`），Glob 用模糊匹配。**传主名不在其中**（宋史卷 338 只写作「卷三百三十八·列传第九十七」）——查人物改用 `02`／`03` |
| `02-人物字号索引.md` | 4.06 万条「人名｜字｜路径」记字条目＋约 1400 条"号"附录；甲区高可信／乙区待核。**问字号第一站**。注意多书互证、同字不同人（字孔明＝诸葛亮／胡昭）；"号"附录按句式收录、未关联人名，引用前 Read 上下文 |
| `03-人物出现索引.md` | 1.32 万人 × 出现卷倒排；★ 本传，其余为提及卷；含 ⚠同名异人。查不到者：无"字"且无专传（审食其、樊於期）或单字名（迁、籍）→ 全文 Grep `data\`，常用者登记 `tools/extra_names.md` 重跑 |
| `04-故事精选索引.md` | 1.97 万情节窗「路径｜起行｜止行｜情节分｜首句」＋书节目录。**讲故事专用，由 `tools/pick_story.py` 读；不要自己挑书挑窗** |
| `05-卷名总表.md` | 「书名｜卷次｜类型｜篇名｜路径」＋主题速查。查主题（"食货""释老""经籍"）、破"志第X"占位篇名。**卷题级篇名后带「（含：A、B）」＝该卷传主/内容提示（自动提取，如「列传第十九（含：侯君集、张亮、薛万均）」），问"某事在哪卷"先看它**。「篇名」列不含传主名时查人走 `02`／`03`；明史「篇名未载·内容近X」是**推测**，须 Read 复核 |
| `06-表卷与原件索引.md` | 两段：①166 表卷可用性分级＋机读稿册号 ②38 册机读稿册表（末列＝点校本原件 PDF **册名**；原件本身不在本库内）。**问"表"必查** → 见下"表卷三级处理" |
| `07-帝王本纪索引.md` | **按本名／庙号／年号查帝王本纪的第一站**（本纪卷首只写「讳某」、通篇称「帝／上」，02/03 都不收帝王）。`rag.py` 已自动用它——输出头的 `⭐ 帝王本纪锚点` 即此表命中；手工 Grep 时以**检索键列**为准，自称行摘引用前仍须 Read 源文件。雷区：庙号跨朝重名（太祖／太宗历朝多名）、一篇本纪常分多卷（只首卷在表）、年号列机器抽取可能带前朝／邻国纪年、行尾「⚠」＝文件名错位或同书重复、自称行摘带「译」＝卷首无文言（**禁止照录**） |
| `08-案件索引.md` | **问「某案（胡惟庸案／巫蛊之祸／乌台诗案……）出处在哪」第一站**：二百五十余案「案件名｜时代·类型｜当事人｜检索词｜出处｜按语」，检索词经脚本实测在本库存在，出处栏已给《书名·卷次》＋`路径:行号`＋摘句（可逐条 Read 复核）。雷区：①「X案」这类今人通称本库多半零命中，**照该行检索词查、别照案名查**；② 行内 `⚠`＝本库未用此名或未载，须按按语换词或**如实答「本库未载」**，严禁凭记忆补卷次；③ 表头「本库未载的著名案件」清单（哭庙／苏报／杨月楼／宋教仁诸案）命中即答未载；④ 按语是编者提示、非史文 |
| `06-表卷OCR机读稿/`（繁）、`…（简体）/` | 38 册 OCR 机读稿，**非原文**，只作检索线索 |

**根目录下的 md 会进入 `--source index` 检索源**（只有 `SKILL.md` 与 `_` 开头的文件被排除）——临时/私人文件请加 `_` 前缀或放进子目录，否则会被当成索引参与检索。

**两类不走索引的问法**：

- 歧义朝名（宋／汉／唐／周／魏／齐／梁／晋／金）→ **先定政权**：见上「朝代／政权消歧」＋ `references/dynasty-disambiguation.md`，未定政权不得取书。
- 辨伪（"这段历史对话是真的吗"）→ 走 `references/pseudo-history-checklist.md` 六查＋三段式答复；有事实卡者另跑 `factcheck.py`。

**兜底**：以上都查不到 → Grep `data\`（先限定到某书文件夹）；制度条文亦走此路（先用主题入口定位志）。

主题锚点：经济——史记平准书·30、汉书食货志·24、魏书·110、隋书·24、宋史·173起、明史·77起、清史稿·120起；文化——汉书艺文志·30、隋书经籍志·32-35、明史艺文志·96起；北魏政治宗教——帝纪 1-12＋官氏志·113、刑罚志·111、食货志·110、释老志·114。更多见 `05`。

## 表卷三级处理（禁跳步）

166 个表卷中仅 **2 卷有表体**（清史稿·军机大臣年表，卷176–177，唯一可直接 Grep 的宰辅年表）；12 卷仅序文；**123 卷"（表略）"占位**；29 卷极短。占位/仅文字共 135 卷，其中 **128 卷已映射机读稿册号**，余 7 卷属《新元史》（点校本未收，无 PDF）。**严禁编造表内条目。**

1. **查机读稿**：按 `06` 行内册号打开 `06-表卷OCR机读稿（简体）\<册号>_*.md` Grep——**一律走简体版**（点校本是繁体，用简体词搜繁体目录会零命中，如"张居正"vs"張居正"）；关键词本身是繁体（"張居正""萬曆"）才搜 `06-表卷OCR机读稿/`。命中即得 PDF 页。
2. **查替代文本**：相应志（职官/百官/选举/地理志）或本纪、列传中的分散记载。
3. **查原件**：按册号在 `06` 册表末列取 PDF **册名**，到本机存放点校本电子版的目录里对号取件（该目录不在本库内，也不在任何文档里写死），交用户人工查阅。

> 册号速记：新唐书宰相表 122｜新唐书宗室世系表 123｜宋史宰辅表 161｜宋史宗室世系表 162–169｜元史宰相年表 207｜明史诸王世表 222–223｜明史宰辅年表 224｜清史稿大学士年表 262。世系读法与逐王/逐房定位见根目录 `唐代宗室世系讲解.md`、`宋代宗室世系讲解.md`、`明代宗室世系讲解.md`；宰相/首辅/军机大臣见 `宰相首辅军机查询指南.md`。

**引用纪律**：机读稿是**机器识别结果、非原文**（错率 5%–15%，生僻人名尤甚），只作检索线索与引用定位；表内数据须标"机器识别稿，字形待核"，**不得声称读过扫描件原文**。

## 讲史流程

**讲史的目标：让人愿意听完。** 有趣只靠三件事——**选有戏的窗**（情节分 ≥25）、**讲法有节奏**（冲突切入、不铺背景、照录 1–2 句原话）、**收尾有自己的看法**；**不是**靠加戏或编对话。史实没讲全，下一轮还能补；**讲得没意思，就没有下一轮了。**
**先裁决入口，再决定动不动抽签器。** 本技能只管**历史（正史）故事**——用户说「讲个故事／讲一个故事／给我讲一个故事」一律按**要正史故事**处理（本库只有正史），**直接抽签开讲，不反问**。三类情形分开处理，**一条回答只能落在一类里**——不许并行、不许把演义／虚构内容当正史讲：

- **未指明类型**（就一句"讲个故事／讲一个故事／给我讲一个故事"，未指明朝代或类型）→ **不反问、不澄清，直接走 `pick_story.py` 抽签，抽到哪个讲哪个**——本库只藏正史，默认按正史处理最安全；用户想听别的会自己说，没说他就是要你直接开讲。
- **演义／小说／民间／原创（虚构）故事**（三打白骨精、武松打虎、过五关斩六将之类）→ 本库**不提供这类史料**，但用户可能就是想听虚构故事；若讲，**必须在开头显式标注「⚠ 虚构／演义／小说情节，非真实历史」**，且不得与正史混叙、不得无标注当史讲。拿不准是不是史实，宁可标注。
- **明确历史／正史故事** → 才进入下面 1–5 步，走 `pick_story.py` 抽签；正文照窗口复述，**模型的语言能力只用来组织已 Read 到的史料，不用来生产故事**。

**选书抽签交给脚本，不许自己挑。** 手动挑书会稳定偏向《资治通鉴》（它在 `04` 里排第一、体量最大、最眼熟）——这是被反复观测到的失效模式。靠"提醒自己别总用通鉴"治不好，把抽签机械掉才能治好。

**环境能力分流（先判再动）**——**判据＝你手上有没有能跑命令的工具**，先看清再选路，**选错了路径就等于讲不出故事**：

- **有 shell／exec／代码执行类工具**（哪怕你还没用过、不确定它能不能跑）→ **必须**走下面**第 1 步**的脚本抽签（`pick_story.py`，**签号是唯一合规凭证**）。
  ⚠ **"试一次失败"不等于"不能执行"**：先按第 1 步**真跑一次**，只有**确实报错**（且按第 1 步的排错清单换过写法仍失败）才降级。**"我猜这里跑不了命令"不是降级理由**——实测 2026-10-01 群 bot 环境里 `execute_shell` 一直是通的，模型却因一条命令写法错误就以为没有执行能力，直接跳去用了降级表，结果**只报了签号、一个字的正文都没讲**。
- **确实没有执行工具**（工具清单里根本没有 shell／exec／代码执行）→ 走 **1-alt**：**手算选自 `04`**，仍然锚定 `04`。
- **连 `04-故事精选索引.md` 也读不到**（环境只喂了本文件这一篇正文）→ 才允许走 **1-alt-2**（27 条选签表）。**这是末位兜底**，正常情况下不许用——因为它**只给首句、不含正文**（详见该条）。

三种情况都**禁止**不看索引、凭记忆或想象直接讲一个故事——故事必须逐字来自所 Read 的窗口。

**怎么把脚本真的跑起来（本文件里所有命令都写成 `python tools\xxx.py`，那是以 skill 目录为工作目录的相对写法）**：

- ⚠ **在 AstrBot 这类 agent 环境里，你的工作目录不是 skill 目录**（实测是 `…/data/workspaces/<会话ID>/`）——
  **所以 `python tools\pick_story.py`、`04-故事精选索引.md` 这种相对写法一定失败**。
  **拿到脚本绝对路径的机械办法**：系统提示词的 Skills 一节会给出本 skill 的 `SKILL.md` **绝对路径**，
  **去掉末尾的 `SKILL.md` 就是 skill 根目录**，脚本就在它下面的 `tools\` 里。
  **每次执行都自己拼绝对路径，不要指望相对路径能用。**
- ⛔ **第一条命令就直接执行抽签器**（`pick_story.py`），**不要先"探路"**。实测 2026-10-01 群 bot 的失败全过程：
  第 1 步 `cat SKILL.md` → 第 2 步**凭想象去取一个并不存在的「选签表」文件**（本库压根没有这种东西）→
  第 3–4 步 `Get-ChildItem *故事*`（两轮空）→
  第 5 步用**相对路径**读 `04`（失败）→ 第 6 步绝对路径读 `04`（**超限**）→ 第 7 步只读到 `04` 头部 →
  第 8 步**去读 `pick_story.py` 的源码**。**八步全烧在"找路"上，一步也没执行**，最后框架报
  `Agent reached max steps (8), forcing a final response`，只好承认失败。
  **正确做法：第一刀就砍在 `python <skill根目录>\tools\pick_story.py`。**
- ⚠ **别去读脚本的源码**——读 `pick_story.py`、`rag.py` 的正文是"研究"不是"执行"，白烧一步。
  脚本的用法在本文件里已经写全了，直接跑。
- ⚠ **`04-故事精选索引.md` 有 3.1 MB**，而文件读取工具有上限（实测约 **256 KB**）——**整读一定被拒**。
  要读就只能开小窗口（如 `limit` 前 40 行取书节目录）；真要全书目请走 `pick_story.py`，别硬读 `04`。
- ⚠ **Windows 上别用 `&&` 连接命令**：本机 `execute_shell` 落在 **PowerShell 5.1**，它**不认 `&&`**（报 `标记"&&"不是此版本中的有效语句分隔符`）。要用 `;`，或**干脆分两次调用**（先 `cd`，再 `python …`）。
- ⚠ **脚本都在 `tools\` 下**：`rag.py`／`pick_story.py` 等**不在 skill 根目录**，写 `python rag.py` 会报 `No such file or directory`——正确写法是 `python tools\rag.py`。
- **一次命令通过不必怀疑环境**；**一条命令报错也先修写法**（换 `;`、补 `tools\`、改用绝对路径），**别因为一次写法错误就判定"这个环境跑不了命令"**（实测 2026-10-01 群 bot 就是这么从脚本流程滑到末位兜底表的）。

**⛔ 签号是算出来的，不是写出来的——严禁伪造。** 真签号形如 `#A1B2C3`（`#` + **6 位十六进制**），由 `pick_story.py` 按「书名｜路径｜起止行」哈希得出，**没跑脚本就编不出来**。凡出现下列任何一种，都是**伪造凭证**，比"讲不出故事"严重得多：

- 手写一个 `选签 000001` / `选签 12` 之类**六位纯数字或自编编号**（真签号含 A–F，且必带 `#`）；
- 自己拼一行 `选签 000001（史记文白 | 401–420 | 首句：…）` 冒充抽签输出（**实测 2026-10-01 群 bot 在 `max steps` 用尽后就这么干了**）；
- 拿"工具到上限了／跑不了脚本"当理由，换个格式把选号硬凑出来继续讲。

**跑不了抽签就如实说**：「我这边没能跑成抽签（原因：…），请你代为执行，或换一句再问」——**宁可交白卷，不许交假凭证**。
同理，`--check` 会按"签号个数／凭证形态"机械判；伪造的号对不上两本账，照样判不合格。

1-alt. **降级路径（确实没有执行工具时）：手算选自 `04`，可核验**：Read `04-故事精选索引.md` 第 9–37 行的**书节目录**（27 行，格式 `书名｜起行–结束行｜N 窗`，**只为定位行号**）→ 以**用户这句话的字数 L** 为种子机械选区：第 `(L mod 27)+1` 部书，在该书区间 `[s, e]` 内取 `04` 第 `s + (L mod (e-s+1))` 行（若该行是 `## 书名` 标题或空行，向下顺延到最近的一条窗口行）→ 该行给出 `路径｜起行｜止行`，按它 Read 源文件照录复述。
   - **凭证**：回答**首行**写「引用 `04` 第 N 行（L＝用户消息字数）」；任何人打开 `04` 第 N 行都应看到**同一路径与起止行**——对不上＝没走索引。
   - 这条只解决"能不能从 `04` 拿到故事"，**不改变**「只讲一个」「不反问」「照录原文」三条硬规则；**第 2 步的「读窗并补全」同样适用**——按窗口行号 Read 后，仍要往前找人物出场、往后找结局再开讲。

1-alt-2. **末位兜底：连 `04` 都读不到时的选签表（按用户消息字数机械取号，不必读任何文件）**：
  ⛔ **先确认你真的没有别的路**——本条的适用条件是"**手上没有执行工具，且连 `04-故事精选索引.md` 也读不到**"。只要你**能读 `04`**，就回到 **1-alt**；只要**有执行工具**，就回到**第 1 步**。**这条不是"省事的捷径"**。
  ⚠ **本条只给"篇目＋首句"，不含故事正文。** 取到号之后**必须去 Read 该篇原文并按第 2 步补全**——**只把首句照念一遍就当讲完了＝不合格**（读者看到的会是一句没头没尾的文言，等于没讲）。所以只要**环境能读到 `data\` 里的源文件**，本条的产出就只是"**选区**"，正文仍要 Read。
  下面的表共 27 条，对应 27 部书各一条；取**用户这句话的字数 L**，选第 `(L mod 27)+1` 条，讲该条——**选到哪个讲哪个，不得因「这条更有名／更精彩」而换**。
  回答首行写「选签 第 k 条（L＝N 字）」，并把该条的**原文首句照录一次**自证。
  **若连这张表也读不到**（所在环境拿不到本文件正文）：**必须如实说明「我读不到选签表，不能凭记忆编故事充当正史」**，改请用户给篇目、或让用户执行 `python tools\pick_story.py`——**绝不许随口编一个"听起来像史"的故事充数**（形如合法、实为瞎编，是本 skill 最重的失效模式）。

| # | 史书 | 篇目 | 该篇原文首句（照录；讲时须复述以自证） |
|---|---|---|---|
| 1 | 资治通鉴 | 资治通鉴·卷10 | 韩信使人间视，知其不用广武君策，则大喜，乃敢引兵 |
| 2 | 史记 | 卷八十三·鲁仲连邹阳列传第二十三 | 鲁仲连者，齐人也。好奇伟俶傥之画策，而不肯仕宦任 |
| 3 | 汉书 | 卷五十六·董仲舒传第二十六 | 臣谨案《春秋》之文，求王道之端，得之于正。正次王 |
| 4 | 后汉书 | 卷八十上·文苑列传第七十上 | 光和元年，举郡上计到京师。是时，司徒袁逢受计，计 |
| 5 | 三国志 | 卷六十四·吴书十九 | 恪意欲曜威淮南，驱略民人，而诸将或难之曰："今引 |
| 6 | 晋书 | 卷三十三·列传第三 | 武帝以崇功臣子，有干局，深器重之。元康初，杨骏辅 |
| 7 | 宋书 | 卷六十三·列传第二十三 | 勃好为文章，善弹琴，能围棋，而轻薄逐利。历尚书殿 |
| 8 | 南齐书 | 卷二十六·列传第七 | 显达素有威名，著于蛮虏，至是大损丧焉。御史中丞范 |
| 9 | 梁书 | 卷三十八·列传第三十二 | 迁员外散骑常侍。旧尚书南坐，无貂；貂自琛始也。顷 |
| 10 | 陈书 | 卷十八·列传第十二·沈众袁泌刘仲威等 | 袁泌，字文洋，左光禄大夫敬之弟也。清正有干局，容 |
| 11 | 魏书 | 卷十三·列传第一 | 景穆恭皇后郁久闾氏，河东王毗妹也。少以选入东宫， |
| 12 | 北齐书 | 卷四十六·列传第三十八 | 世轨，幼自严整，好法律，稍迁廷尉卿。洛州民聚结欲 |
| 13 | 周书 | 卷十五·列传第七 | 孝昌二年，又随广阳王征鲜于修礼。军次白牛逻，会章 |
| 14 | 隋书 | 卷六十四·列传第二十九 | 来护儿，字崇善，江都人也。幼而卓诡，好立奇节。初 |
| 15 | 南史 | 卷六十·列传第五十 | 伏惟陛下睿明启运，光天改物，拨乱惟武，经俗以文。 |
| 16 | 北史 | 卷三十·列传第十八·卢玄等１８人 | 元叉之废灵太后也，相州刺史、中山王熙起兵于邺。败 |
| 17 | 旧唐书 | 卷十五·宪宗下 | 十二年春正月辛酉朔，以用兵不受朝贺。癸未，贬义武 |
| 18 | 新唐书 | 卷二百二十二中·列传第一百四十七中 | 越析诏，或谓磨些诏，居故越析州，西距曩葱山一日行 |
| 19 | 旧五代史 | 卷三十九（唐书）·明宗纪五 | 十一月癸酉，日南至，帝御崇元殿受朝贺。甲戌，捧圣 |
| 20 | 新五代史 | 卷四·唐本纪第四 | 黄巢已陷京师，中和元年，代北起军使陈景思发沙陀先 |
| 21 | 宋史 | 卷三百四十二·列传第一百一 | 熙宁、元丰间，更制变令，士大夫多违己以求合，雍独 |
| 22 | 辽史 | 卷一百三·列传第三十三 | 今宜徙可敦城于近地，与西南副都部署乌古敌烈、隗乌 |
| 23 | 金史 | 卷一百十七·列传第五十五·徒单镒等 | 国用安，先前名叫安用，本名咬儿，淄州人。是红袄贼 |
| 24 | 元史 | 卷一百五十三·列传第四十·刘敏 | 王檝，字巨川，凤翔虢县人。父霆，金武节将军、麟游 |
| 25 | 明史 | 卷十·英宗本纪 | 五年春正月己未，大祀天地于南郊。二月乙亥，侍讲学 |
| 26 | 新元史 | 卷二百三十八·列传第一百三十五 | 萨都剌，字天锡，答失蛮氏，后徙居河间。萨都剌本朱 |
| 27 | 清史稿 | 卷二百九十一·列传七十八 | 傅鼐，字阁峰，富察氏，满洲镶白旗人。初授侍卫。雍 |

> 表由 `tools/make_story_pool.py` 读 `04` 按固定种子抽取（已剔除完璧归赵等超著名桥段、译注行、目录行与志表类）；需要换一批时改脚本里的 `SEED` 重跑。


1. **抽签**：`python tools\pick_story.py`
   - 默认**分层等概率**：27 部书先等概率选一部，再在该书内等概率选窗（若改为全库窗口等概率，通鉴占 6.9%，仍有偏重）；并自动排除最近 4 次**抽到或讲过**的书（读 `tools/_draw_log.md` 抽签记录 ＋ `tools/story_log.md` 讲完台账，两本账合并）。
   - 一次讲多个：`--count 3`（史书互不重复）。用户指定：`--dynasty 刘宋`、`--book 24明史文白`。歧义朝名如 `--dynasty 宋` 会被拒绝并要求二选一——这是设计如此，别绕过它。
   - 脚本直接给出路径、行号区间、首句、**签号**、可复制粘贴的 `Read` 调用。**禁止自己 Read `04` 挑书挑窗，也禁止"凭印象开一本书就讲"。**
2. **读窗并补全（窗口≠完整故事，这是"讲不全"的根因）**：窗口行号区间**中位数仅 8 行**（72.6% ≤10 行），常从人物生平**中段**起、到**中段**止，甚至**跨两个人物**——实测 08梁书卷46 抽到「承圣二年，**又**与王僧辩讨陆纳…」，那是杜龛传记的后半段，读者根本不知道他是谁。所以 Read 窗口后**必须前后补全**：
   - **往前**：首句含承接词（又／遂／于是／初／先是／既而…）、或人物未交代身份 → 继续往前读，直到**人物出场句**（"某某，字某某，某地人也"／"某，某之子也"）或本传起点；
   - **往后**：末句事件未结、人未卒、突然换人 → 继续往后读，直到**该人事迹收束**（卒／赠谥／"史臣曰"／下一位传主出场）。
   - **讲全的判据**：读者读完能答出**"这是谁、经历了什么、结局如何"**——**讲半截＝不合格**（宁可多读几十行，不可讲一段没头没尾的）。脚本的「讲全」行已给出建议扩读范围（窗口 ±30 行），按需再放宽。
   - 文白对照卷译文随行；纯原文补入卷自行翻译并说明。索引行号已抽检 54 窗零误差，可直接用。
3. **章法**：①**钩子**（人物＋冲突，用大白话，别拿书名开头）→ ②**白话讲主干**（用现代汉语把"谁、为什么、结果如何"讲清楚）＋关键处**照录原文金句**（对话／诏令／评语，**全篇 1–3 条足够，引文是点睛不是主体**）→ ③结尾注《书名·卷次·篇名》，**政权限定写全**（"刘宋"不写"宋"），能补余味更佳。
   - **趣味**：取 **`--min-score 25`** 以上的窗（有对话、有冲突）；开场用冲突切入、不铺背景；照录 1–2 句原话点睛；结尾留余味，**别写「这个故事告诉我们」**。
   - **评点（讲完要有自己的看法）**：结尾用 **1–2 句**说自己对这件事的解读——**妙在哪／错在哪／为什么改变了后来**，并点明依据（《书名·卷次》）。⚠ **「看法」与「照录」分开**：引文一律进「」，评点写在引文之外；看法只能建立在**库内史料**上，不得引入库外知识——否则就不是评点，是编史。
   - **照录必加引号。** 引原文一律用「」标明；自称「原文照录」却无引号引文＝不合格（`--check` 有此闸；`verify` 只认引号内引文）。
   - **表达纪律（2026-09-29 实测：讲全了却"读不懂"）**：讲史是**讲故事**，不是**史料摘抄**。三条硬性禁忌——① **不逐句引原文**：引文超过三五条、或读者要靠啃文言才跟得上的，就是写坏了（实测同一窗，引文 14 条版被评"不清楚"，改到 2 条版才通）；② **不按日期／月份罗列事件**（本纪天生是流水账），要**重排成因果链**（例：朝廷内部虚弱 → 外镇相继造反 → 只好倚重权臣）；
   - **篇幅（只管「写」，不管「读」）**：正文以 **400 字**为目标、情节复杂可到 **600 字**；**「讲全」优先于「讲短」**（判据＝读者能答出"这是谁、经历了什么、结局如何"）。⚠ **「读」不受此限**：读源文件要**往前回溯到人物出场、往后追到收束**（窗口 ±30 行，必要时读整卷或相邻卷），把前因后果弄明白再下笔——**读得多、讲得短**才是对的。把故事讲长的主因不是情节多，而是「逐句引原文」和「按年月罗列事件」。
     ③ **只留能推动故事的人**——本纪动辄十几个节度使任免与加官，无关人物一律不写，**别堆人名**。
4. **登记（可选，忘了不误事）**：讲完可补 `--commit-entry` 写入 `tools/story_log.md`（讲完台账，供回顾"讲过哪些"）。**轮换不依赖这一步**——抽签时 `tools/_draw_log.md` 已自动记（抽到即记），`--no-repeat` 并读两本账。别为"漏登记"纠结或补发一条，补跑一次 `--commit-entry` 即可。
5. **禁忌**：不编造情节、对话、动机；不改原文；人名官职以原文为准；不确定就说"原文未载"。
6. **交付校验**：把讲史回答存成文件，跑 `python tools\pick_story.py --check 答案.txt`（或 `--check -` 从 stdin）。它机械判三件事——**签号是否唯一**（>1 个＝讲了两遍）、**无签号时是否带了「虚构/非真实历史」标注**、签号能否对上两本账。**FAIL 必改**，退出码 1 就是不合格。

**硬规则（针对"仍偏爱通鉴／史记"这一被反复观测到的失效模式）**：

- **只讲人物的事，不讲制度条目。** 讲史的内容必须落在**列传／本纪里的人和事**上；志／表（职官、刑法、食货、地理、艺文、五行、祭祀…）是制度记述，**不是故事**——"某朝对刑狱制度进行改革"这种一句话概括不算讲史。`04` 与上面的选签表已在建库时剔除志／表卷（`build_story_index.py` 按 `05` 的类型列过滤），所以照抽的窗天然合规；**若你在零工具环境自选篇目，先确认卷题是"列传／本纪"再说**。
- **只讲一遍，可机械校验。** 一条回答**只含一个签号**、**只讲一个故事**；讲完即止。交付前跑 `pick_story.py --check` 把关——它按"签号个数"抓"讲两遍"，按"无签号又无标注"抓"没走脚本却当史讲"，不是靠自觉。
- **虚构必标注。** 凡脱离抽签窗口、或含演义／小说／创作内容（五关六将、桃园三结义、三打白骨精、武松打虎……），**必须在开头标「⚠ 非真实历史（演义／小说／虚构）」**，且不与正史混叙。正史故事有签号＋出处，**不需要**虚构标注——别两头都占。

- **首行必须带签号。** 抽签输出形如 `签号 #A1B2C3`，讲史回答的**首行原样带上它**。签号由「书名｜路径｜起止行」算出，**没跑脚本编不出来**——这是"到底走没走抽签"的唯一凭证。**没有签号的讲史＝自选书，不合格**，必须重跑抽签。
- **一次抽签只讲一个故事，不要讲两遍。** 三种翻车都见过：① 先自己按 `04` 的书节目录取一窗开讲，又跑脚本抽一窗讲第二次——**只认脚本抽的那一窗**（签号即凭证）；② 已经讲完又"再复述一遍／换个说法重讲"；③ **讲完自问自答续开场**——"你想听哪个朝代的故事呢？"→自己接"好啊"→"我给你讲个XX的故事"（XX 往往还是刚讲完的那个）。
  **讲完即止**："要不要再来一个"留给用户答，续讲必须等用户**下一轮**发起并重新抽签（轮换账会自动避开刚讲过的书）；一条回答里不许出现自问自答的对话桥段。**不要在正文之外另加摘要版**，也不要为了补签号把整段重发——签号写在**同一条回答的首行**就行。
- **不反问、不追问。** 「讲个故事／讲一个故事／给我讲一个故事」＝「直接抽签讲一个给我听」——**不要**先问"想听哪个朝代／哪本史书／正史还是演义"，也不要讲完追问"要不要再来一个"；续听由用户下一轮发起。
- **不得以"更短／更有趣／更精彩／更出名"为由自选书。** 抽签器没有这类参数（只有 `--dynasty／--book／--topic／--count／--min-score／--exclude`）；一旦出现这类措辞，就是模型在凭印象挑书。
- **"名气"不是选区依据。** 同样**不得**因为"廉颇蔺相如更有名""完璧归赵大家更熟""这个更经典更精彩"而挑选书或窗口——**抽到哪个就讲哪个**。凡回答里出现"这个比较出名／这个经典／大家更熟悉"之类措辞，即判定为模型凭印象自选，不合格。
- **「禁止惯性连带」与「用户要续讲」是两件事，处理方式相反——别把用户点名的延续也当成偏食拦掉。**
  - **用户主动要接着听同一个故事／同一个人的后续**（"后来呢""接着讲""继续""然后呢""他后来怎么样了"）→ **判为续讲**，顺着库里的原文往下讲。
    **取点别猜，用工具**：`python tools\pick_story.py --next "<上一签路径>" <已读止行>`——它给两个候选：**①同一文件的后续行**（本传／本卷还没讲完）、**②同书紧邻的下一卷**（本传／本卷已读完，例：《旧五代史》卷一百一·隐帝纪上 → 卷一百二·隐帝纪中 → 卷一百三·隐帝纪下，隐帝的结局与郭威起兵都在这两卷里）。①若仍在讲**同一个人／同一件事**就续讲①，①已换传主、或上次读到的就是本卷末 → 用②。
    **不必重新抽签**——这不是自选书，是用户点名的延续。
    - **极简追问同样算**：「继续」「接着说」「然后呢」这类**一两个词的追问**，只要**上一轮刚讲完一个故事**且**还有后续**（`--next` 能给出①或②），就是续讲——**不是**"再讲一个"。
    - **指代真不清楚时才问一句**：若"继续"的上文不是刚讲完的故事（中间隔了别的话题、或上一轮根本没在讲史），先确认「是接着刚才那个故事讲吗」再动手——**这是澄清歧义，不是讲完追着推销**（"要不要再来一个"照旧禁止，那条针对的是**主动追问**）。
    - **万一真的没有后续**（`--next` 报"已到文件末尾"且"已是本目录最后一份"）→ **先如实说明**"这个人／这件事到此为止"，**再**按新故事抽签；**不要**不声不响换一本书。
    - **续讲不按字数取号**（零工具环境也一样）——按字数取号是"再讲一个"的机制。
    - **凭证**：首行写 **`续 #原签号　→《书名·卷次》`**（沿用上一签的签号＋标明续到哪一卷），正文照旧（白话为主、引文点睛）。`pick_story.py --check` 认这种写法（原签号唯一且能对账）。
  - **模型自己想接着讲"相关的人"**（用户并**没有**要求）→ **禁止**：同书、同时代、并称典故（"冯唐易老、李广难封"）、师友亲属一概不许。这是"惯性连带"，是偏食的老毛病。
  - **用户要"再讲一个"（另一个故事）** → 按新故事重新抽签（零工具环境按**新的字数 L 重新取号**）；`--no-repeat` 会自动避开刚讲过的书。
- **被要求"换一个／不要这本"时**，重跑抽签并排除刚讲过的那本：`python tools\pick_story.py --exclude 资治通鉴,史记`。**不要**换到"另一本眼熟的"——从通鉴滑到史记正是这么发生的。`--exclude` 是**一次性的**（不落盘，下次抽签自动重新纳入），符合"我说了不要 → 换一本 → 以后还能讲"的直觉；要拦住某本书**长期**不进抽签，那得改 `04` 本身，别在抽签器里藏常设名单。
- **用户指定主题／人名／桥段时，三条路分清楚**：
  - **只想要"某个范围里的随机一个"**（"讲个关于漕运的故事"，没有唯一答案）→ 走 `python tools\pick_story.py --topic XX`，**不要**自己 Grep `04` 挑窗。试抽/调试加 `--no-log`。
  - **点名要某个人**（"讲苏辙的故事""讲讲辛弃疾"）→ 走 `python tools\pick_story.py --person 苏辙`：先 `rag.py locate` 定位本传，再在**该传的多个情节窗**里抽一个——**一个人的故事不止一个**（实测苏辙传在 `04` 里有 **6 个**情节窗：开传／王安石变法时期／奏议／论差役法／论盐铁／文风为人）。首行**仍带签号**（与其他讲史一致）。⚠ **别用 `--topic 人名`**：`04` 的窗口只记路径（"卷三百三十九·列传第九十八"，**不含人名**），`--topic` 只能命中"首句恰好写了人名"的那一窗（苏辙只有 1 个），其余全漏。
  - **点名要某一个故事／成语／事件**（"讲完璧归赵""破釜沉舟是怎么回事"）→ **不要用 `--topic`**：它只匹配窗口的「首句＋路径」，对这类词**实测直接 rc=1 报错**。正确走法是 **`rag.py <点名词>` 定位 → Read → 按第 2 步「讲全」补全**：
    - 工具会自动做**通称改写**（"破釜沉舟"→ 破釜／卿子冠军），**照改写结果走**，别接着自己换词；
    - ⚠ **看清命中材料的性质**：要的是**本事原文**（本纪／列传／通鉴对应卷），**不是**译文、后世评述或他书用典——"破釜沉舟"字面命中的恰是《汉书》译文评述与《明史·史可法》用典，**照它讲就是把二手材料当了本事**；
    - **本源缺文就换替代出处并说明**（如《史记·项羽本纪》文白**缺钜鹿之战整段**，改用《通鉴·卷8》或《汉书·陈胜项籍传》）；真的零命中 → 如实说"本库无此记载"。
    - **凭证**：首行写 **`应点讲：《书名·卷次·篇名》`**（点名故事没有签号，出处就是凭证）。`pick_story.py --check` 认这种写法。

## 写史与改稿（双闸）

用户要"写个历史人物的故事""帮我改这段历史小说"时——**创作同样算史实性输出**：史实锚点零错误，虚构只能落在细节与对话，且必须标注。

1. **写前闸**：`rag.py locate <人名> --source index`（或直接 `rag.py <人名> --fast`）取本传卷 → Read 本传 → 取/建事实卡 `tools/facts/<人名>.md`（生卒·字号籍贯·出身·官职节点年·大事年·身后，每条挂卷次·行号）。无卡先建卡。
   - **跨朝补年号**：`factcheck.py` 内置的是明清年号表；写宋、唐等朝人物时，卡里必须加 `era: 熙宁|1068` 这样的行，否则年号不被识别、纪年检查会**静默失效**。参考 `tools/facts/沈括.md`、`tools/facts/王安石.md`。
   - **公元前用负数、生年无据写 0**（西汉及更早人物，2026-09-25 补）：`died: -157` ＝卒于公元前 157 年；`era: 高祖|-206` ＝高祖元年为前 206 年（算式 a+n-1 对负数同样成立）。**正史不载生年时写 `born: 0`＝「无下界」，跳过"早于生年"判定**——此前 `isdigit()` 只认无符号数，负数卡一律被判"缺 born/died"退码 2，西汉人物整张卡直接失效。参考 `tools/facts/刘恒.md`。
2. **写后闸**：`python tools\factcheck.py 稿件.txt --person <人名>`——FAIL 必改，WARN 逐条确认。**定稿前再跑 `python tools\rag.py verify 稿件.txt`**（铁律 8）：逐条核对稿里的文言引文是否真在库中、书名卷次是否对得上。卡里的 `banned` 可写正则，用来拦"伪造关系"与"当代话术"（如 `(沈括|括).{0,12}(拜访|求见).{0,10}(王安石|安石)`）。
   - **返工有上限，别无限重写**：同一份稿在同一项上**改满 3 轮仍 FAIL 就停下**，如实报告"卡在哪一项、已试过什么、怀疑卡里哪条写错"，把判断交回用户。**事实卡与库冲突时以库为准**，并把"卡可能写错"写进报告——卡是人写的，库是原文。
3. **锚点五查**：① 这年他活着吗、在哪个职位？② 该职位管得着这件事吗？③ 官名／刑名／地名是否当世用词？④ 人物立场是否与史实一致（如海瑞站在贫弱一边，不会替富商追银）？⑤ 这个说法出自正史、律典，还是小说与后世俗称？
4. **必须标注**：公案／断案／私访类题材多出自晚明公案小说（《海公案》等），正史无载——文末标"虚构"，并附"史实支点：《书名·卷次·篇名》"。
5. **律条不在本库**（《大明律》等未收录），引用须另据律典并说明；本库只能提供《明史·刑法志》层面的概述。
6. **先辨伪再创作**：若用户拿一段"既有的历史对话"来（要你续写或改写），先按 `references/pseudo-history-checklist.md` 判定真伪并说明，再决定怎么写——**不要在伪史的基础上"顺手补全"**。

## 文本格式

**判断原文还是译文看内容，不看 `> ` 符号。**

- 多数书：文言原文在前，`> ` 引用块为白话译文。
- **晋书、宋书、旧五代史等相反**：原文在 `> ` 块内。白话高频字（的/了/这/那/是/在）密度高者为译文。
- 通鉴 45 个补入卷：繁体原文＋胡三省注〔〕＋`译：` 前缀译文，检索原文宜用繁体。
- 宋史/明史/清史稿部分补入卷：纯文言无译文。梁书同卷可能有 `_译.md`（更详，优先）与 `_en.md`。
- 只搜译文加行首锚点 `^> .*关键词`（通鉴补入卷用 `^\s*译：`）。占位卷正文仅"（表略）"，命中后换卷或如实说明。

## 回答规范

- **朝名必加限定**：凡涉同名异代，写「刘宋」「赵宋（北宋）」「南齐」「后梁（五代）」，**不写"宋""齐""梁"**。引通鉴须连纪名写全（`《资治通鉴·宋纪一》卷119，刘宋`），不写"《资治通鉴》记载宋朝"。书名与卷次成对且互相自证（《宋书·卷一》＝刘裕，《宋史·卷一》＝赵匡胤——两书卷次篇名完全相同，写错书名几乎看不出来）。
- **跨书互证**：同一人/事常并见多书（李白见旧唐书卷一九〇下、新唐书卷二〇二），记载有出入须**并录原文、注明差异**，不自行取舍。
- **异文并录**：行尾带「异文：X」者为底本并列异文（端木赐/端沐赐），须两种写法并录、注"一作X"，不删不改；对照表 `tools/aliases.md`。
- **同名异人分流**：`03` 标「⚠同名异人」者（717 个）须**全列、逐一区分**——纪年＋身份词＋事迹＋所在书卷，不得合并成一人。标注只凭"同名而字不同"：同名者都无字或字相同时**不会标注**，故若见该名横跨多朝、或提及卷身份矛盾（一为将、一为僧），必须逐一 Read 核对。
- **「字」与「号」分开**：字见列传首句（「X，字Y」）；号（别号）正史基本不载；谥号／庙号见卒年条（「卒，谥曰×」）。查字号先走 `02-人物字号索引.md`。
- **事件／制度／案件类＝名词解释，一样要求出处。** 问「XX案／XX之变／XX之狱／XX之治是怎么回事」时，**先查 `08-案件索引.md`**（二百五十余案，行内检索词与出处均经脚本实测，照该行查、别照案名猜），再 **检索**（后世通称会被 `tools/aliases_events.md` 自动改写成史文用词，如「空印案」→ 空印事／空印纸），答复里**每个说法都要能指到《书名·卷次》**；**带不出出处＝没查**，只能答「本库未载」并列出检索词。
  ⚠ 实测 2026-09-25：某环境问「空印案」，答成**宋代**转运使留空白印章、"宋代财政制度漏洞""制度性腐败"，**全篇零出处**——而空印案是**明·洪武十五年**的事：《明史·卷九十四·刑法志》「先是，**十五年空印事发**。每岁布政司、府州县吏诣户部核钱粮、军需诸事，以道远，**预持空印文书**，遇部驳即改，以为常」（另见卷一百三十九郑士利上书、卷一百四十一方克勤坐"空印"事诛、卷二百八十一「复以空印事连，逮死」）。
  **朝代错＋机构错（宋转运使）＋零出处＝同一个动作：没检索，照印象编一套制度解释。**
- **禁「特征匹配猜人」。** 问"这是谁／什么谥号庙号"时**必须检索**；由"罗列特征→凭记忆找相似者"反推**一律算未查**（曾把石勒认成拓跋珪、高欢认成曹操）。**人物身份判断须附《书名·卷次》**。
- **核对表须写「反证」。** 每条附出处（《书名·卷次》），且**至少列一条不符项**——全打勾＝没真核对。
- **检索路径按"手上有名字没有"分岔。** 有名字 → `python tools\rag.py <人名> --fast` 取 ★本传；**没名字（「这是谁」）→ 不得拿待猜的名字当检索词**，改走**独有引语反查**：拿题干里最不可能与人重名的措辞直接搜库（优先序＝独有引语／罕见专名 ＞ 庙号＋谥号 ＞ 独有官名·封号·地名）。实测 `python tools\rag.py "当并驱于中原"` → 全库候选 **1** 个文件，即《晋书·卷一百五·载记第五》石勒本传。
- **④⑤ 检索词必须来自"题面字面"。** 不许拿"已选答案或其亲属／事件词"当检索起点——那是对自己的循环论证（反例：正解孟昶，我却搜「薄姬 魏豹」，搜到的自然"证明"了我猜的汉文帝）。四锚自查用的检索词同样受此约束。
- **⑥ 零命中的名词＝「本库未载」**（如「戒石铭」及其原名「令箴」，全库零命中），禁止凭记忆写一段"听起来对"的解释（**名词解释是幻觉高发区**）；用户主动告知的库外信息可标注来源后接受，但不得转而当本库证据。
- **猜不出来就说「无法唯一确定」。** 无候选、或候选都过不了全部硬锚 ⇒ 正解就是答"无法确定"，**禁止赌一个"最像的"**——答「无法唯一确定」是合规作答，不是失败。
- **⑦ 猜谜交付闸（硬条件）：只有两种合法形态。** ① **给出人名** ⇒ 逐条全中并**显式声明「无不符」**；② **答「无法唯一确定」** ⇒ 列候选与各自出局条数。⚠ 出现「不符／未见／未载／相反／存疑」却仍给具体人名 ⇒ 不合格（「本库未载」也算不符）；出现"替题面打补丁"的措辞 ⇒ 不合格。交付前必跑 `python tools\check_guess.py <答案.txt>`（rc=1 即改答形态②）。
- **⚠ 人物辨识／猜谜的成套规程见 `references/guess-protocol.md`**：五类病根（话题惯性／循环论证／改写题面／把候选栏当结论／零命中凭记忆解释）、穷举三条硬约束（合格者全集只能来自硬特征词 `--top 0 --excerpt 60`；**穷举结果不得再用关键词二次过滤**；默认 `--top 8` 不是全集）、五类假锚、落笔前四锚自查、案例台账。**碰到「这是谁／猜皇帝」先读它。**

## 自检（输出前过一遍）

① 先查了索引/原文，而非凭记忆？② 引用照录自实际打开的文件？③ 引的是文言原文还是白话译文？④ 卷号来自文件名/篇首而非记忆？⑤ 同名已分流、异文已并录？⑥ 查不到时如实说明、绝未编造？⑦ **朝代政权定了吗——"宋"写清是刘宋还是赵宋了吗？书名与路径里的文件夹名对得上吗？**⑧ **讲史那一签是脚本抽的吗——不是我自己挑的书吧？**⑨ **若是辨伪：六查做了几条？答复有"最接近的真实记载原文"这一段吗，
还是只有一句"这是假的"？**⑩ **答案里的每条文言引文和 `《书名·卷次》` 都跑过 `rag.py verify` 且无 FAIL 吗？**⑪ **问人家专传时，是照 `02`／`03` 的 ★本传 拿到的路径，还是在 `01`／`05` 里搜人名、搜不到就答"没有传"？遇到后世通称（乌台诗案／靖康之变…）有没有照 `rag.py` 的「通称改写」走，而不是自己接着换词？**⑫ **人物身份类（"这是谁"）：检索词用的是题干里的独有引语，还是待猜的那个名字？庙号／谥号这类硬锚逐条对过了吗，
有没有一条不符却仍以"整体很像"结案？**⑬ **猜出来的人过"四锚"了吗——`locate <名> --first` 说有没有专传、`verify` 的说话人归属闸过了吗、字号有没有 `02`/`07` 条目可指？候选栏没顶出他，是当"排除依据"还是先想"03 可能漏收"？**⑭ **若是"XX案／XX之变／XX之狱"这类事件·制度名词：先查 `08-案件索引.md` 了吗（照该行检索词查，别照案名猜；
行内 `⚠`＝本库未载，须答未载）？检索跑了吗？答复里每个说法都指得出《书名·卷次》吗？朝代（明？宋？）是原文里读到的，还是从"这事听起来像哪个朝代"推的？**

## 维护

**改语料、改脚本、跑 OCR、加事实卡前，先读 `references/maintenance.md`**（索引重跑顺序、加数据入口、OCR 管线、体检、环境注意事项都在那里）。

两条无需读手册的常备知识：
- `tools/rag.py`（含 `locate`）、`tools/pick_story.py` 与 `tools/facts/` 事实卡**无需重建**，语料一变即生效（`rag.py` 每次实时扫描，`pick_story.py` 每次直读 `04`，`story_log.md` 台账由它自己追加）；新增人物只加一张 md 卡。异体字/人名别名往 `tools/rag.py` 的 `RAG_VARIANTS` 表加一行即可（人物异文仍写 `tools/aliases.md`）；
  **后世通称**（乌台诗案、靖康之变…）往 `tools/aliases_events.md` 加一行，实时读取——右端词上线前必须 `python tools\rag.py <词> --count` 实测存在，否则等于换了个词还是零命中。**查不到的真人物**登记 `tools/extra_names.md`；**误收的假人名**登记 `tools/name_blocklist.md`（两者都需重跑 02→03）。
- Python 用 3.13.12（本机解释器的绝对路径只记在 `references/maintenance.md`「环境注意」节——**本文档不写盘符**）；改完任何索引脚本，最后跑 `python tools\selftest.py` 验收（退出码 0 即全通过，其中含 `rag.py selftest --quick`），**或直接 `python tools\make_indexes.py` 一键重建＋验收**。单独调试检索用 `python tools\rag.py selftest`（全量，较慢）。改语料后另跑 `python tools\check_dupnames.py` 看同名文件有没有扩大。

## 事实之外：能不能再深一层

本库只答**「是什么」**——原文、卷次、生卒、制度细节，一律来自检索；**不答「为什么」**——动机、归因、「表面是 X、实际是 Y」这类推断。本库缺证据时按铁律 3 如实答「本库未载」，不用训练记忆顶上。

碰到「为什么」类问题，本库只提供**原料**：先把事实取到手（`rag.py`）、照录原文、记清《书名·卷次·篇名》。此后若想把这个问题想得更深，可以再看看手边别的地方有没有能帮上忙的工具或材料——**有就接着用，没有就把话停在事实层面**，并标明「以下为推测」，不为其编造依据。
