ershisishi-wenbai · git:20261008.2abdf11 · 2026-10-08 · sha256 51f4aa9690d3a24d

ershisishi-wenbai git:20261008.2abdf11A

Immutable. This exact content never changes and is served at /api/v1/blob/51f4aa9690d3a24d.

---
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 | 北史 | 卷三十·列传第十八·卢玄等18人 | 元叉之废灵太后也,相州刺史、中山王熙起兵于邺。败 |
| 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`)、照录原文、记清《书名·卷次·篇名》。此后若想把这个问题想得更深,可以再看看手边别的地方有没有能帮上忙的工具或材料——**有就接着用,没有就把话停在事实层面**,并标明「以下为推测」,不为其编造依据。