# 绍派伤寒 · 越医知识图谱 — QC Audit

**Built by** 医哲未来人工智能研究院 (IMPFAI) · https://impfai.github.io/

> 本文件对应 **V7** 的公开发布版（18,149 节点 / 22,698 关系）。第一部分照录上游交付的口径；
> 第二部分「本仓库复核」记录导入时的实测结果与差异。机器可读版见 `qc_audit.json`。

## 一、上游交付口径

**Corpora（九种）**
- 《浙派中医丛书》专题系列·绍派伤寒, 沈钦荣主编 (2021)
- 《越医文化》十章 + 目录 + 后记
- 《何廉臣医案》660 则
- 《越中名医传》下篇 + 越中名医传补
- 《越醫雜詠》
- 《赵晴初医论》
- 《俞根初临证经验集要》沈钦荣编著（学派奠基人专著，十章）
- 《绍派伤寒史料图片研究》陶建华总审／沈钦荣、林怡冰编著（图片史料图录，204 幅）
- 沈钦荣 2022—2026 年当代骨伤科门诊病案 131 则

| | 上游交付 | 本站发布 |
|---|---:|---:|
| Nodes | 19,383 | **18,149** |
| Edges | 28,380 | **22,698** |
| Ontology classes defined / populated | 20 / 19 | 20 / 15 |
| Object properties defined / used | 46 / 40 | 46 / 32 |
| Layers | 7 | 6（当代病案层暂缓） |

差额全部来自当代病案层：5,682 条关系、1,234 个只由它引出的节点，见下「当代病案」。

### Extraction coverage

| Layer | Extracted / routed | Coverage |
|---|---|---|
| lineage | 544 / 544 | 100.0% |
| diagnostic | 330 / 333 | 99.1% |
| pattern | 776 / 793 | 97.9% |
| materia | 1,215 / 1,464 | 83.0% |
| case | 657 / 660 | 99.5% |
| culture | 1,802 / 2,407 | 74.9% |
| modern_case | 131 / 131 | 100.0% |

Coverage is *passages extracted* over *passages routed to that layer*. **Every shortfall is a
per-frame LLM token-ceiling stop, not an exhausted corpus.** Counts drawn from a partial layer —
above all 越医文化 at 74.9% and 本草方剂 at 83.0% — are lower bounds and must never be read as
"absent from the text".

### Identity merge

上游以 opencc 把繁简异写归并 89 组、医家别名 5 对，共 93 个节点合并；属性冲突按原文条数裁定
（何廉臣生年取 1860，3 段原文支持，而非 1861 的 1 段）。

### Cross validation

MiniMax-M3 作为第二引擎从未调用：其 API 密钥只以聊天文本提供，未写入执行环境。
所有关系均为单引擎抽取。

## 二、本仓库复核

### 1. 出处：段落编号与引擎

上游本次随图谱交付了 `nodes.csv` / `edges.csv`，与浏览器载荷逐条一致
（节点 ID 集合相同，关系多重集相同，无重复三元组）。CSV 为**每条关系**补上：

| 项 | 覆盖 |
|---|---|
| 段落编号 `passage_id` | 22,698 / 22,698 |
| 实际抽取引擎 `engine` | 22,698 / 22,698 |

| 引擎 | 关系 | `agreement` |
|---|---:|---|
| builtin-haiku | 20,698 | single_engine |
| builtin-sonnet | 1,674 | single_engine |
| builtin-haiku+vocab | 326 | vocabulary_bridge |

V5、V6 没有段落编号，引擎只能按层推定；这一限制在 V7 解除。

### 2. 原文独立核验

导入脚本逐条检查：原文句是否出现在所引段落正文中（规范化空白与全半角；以「 / 」分隔的多段引文各段分别命中亦算）。
结果写入每条关系的 `evidence_in_passage`，与上游的 `evidence_verbatim` 并列保留。

| 上游标记 | 本站核验 | 条数 |
|---|---|---:|
| 逐字 | 见于所引段落 | 17,779 |
| 逐字 | **未见于所引段落** | **312** |
| 非逐字 | 见于所引段落（仅空白 / 全半角差异） | 9 |
| 非逐字 | 未见于所引段落 | 268 |
| — | 段落无法解析 | 4,330 |

- 可解析的 18,368 条中，**17,788 条（96.8%）原文确在段内**。
- 上游标为逐字却找不到的 312 条，多是把医案**标题**当作证据（标题不在正文段落里）。
- 无法解析的 4,330 条全部来自《绍派伤寒》专著：它们沿用上游旧的 `p#####` 段落编号，
  而本仓库的 `corpus_shaopai.json` 是另一套 `b#####` 重切分，两者不能对应。
  上游若补交 `p#####` 语料，即可纳入核验。

### 3. 本体与基数

本体 1.2.0 原样取自上游 `ontology_spec.json`。

| 检查项 | 结果 |
|---|---|
| 定义域 / 值域违例 | **0** / 22,698 |
| 悬空端点 | 0 |
| 自环 | 0 |
| 重复三元组 | 0 |
| 声明为 0..1 却有多条出边的主语 | **55** |

基数例外按属性：籍贯 `physicianOfPlace` 20 · 源自 `derivesFrom` 14 · 载于 `statedIn` 11 ·
属于六经 `belongsToChannel` 3 · 属于世家 `physicianInFamily` 3 · 子证候 `subPatternOf` 2 ·
机构所在 `institutionAtPlace` 2。典型情形有三类：

- **同一地点的不同写法**：何廉臣的籍贯同时连向「浙江绍兴」「绍兴」「越」，趙宗萬连向「會稽」「山陰」。
- **合方本就有多个来源**：柴平汤「源自」小柴胡汤与平胃散——它正是二方合用，0..1 的声明在此不成立。
  另注意 `derivesFrom` 的值域是著作，但不少宾语其实是方名（三拗汤、平胃散），上游把它们建成了 Work 节点。
- **抽取噪声**：个别学术观点「载于」多达 10 个宾语，其中有「六经总诀」「伤寒要义」这类篇章名而非书名。

V5、V6 的做法是把这些属性改为 0..*；自 V7 起**保留上游声明、如实报告例外**。
OWL 导出中这七条属性不声明为 `owl:FunctionalProperty`，以免推理机把同一主语的不同宾语
推断为 `owl:sameAs`。

数据中出现但规格未声明的属性：Doctrine `proposed_by` · Pattern `note` · Formula `base_formula` ·
Herb `dose` `unit` `processing` · CaseRecord `case_no` `note` `year`。

### 4. 当代病案

**状态：逐案记录暂缓发布。**

第九种语料是在世患者的门诊记录。逐案层在去标识化复核完成、并由数据方确认发布授权之前，
不进入本站图谱、页面与数据下载。本站发布的是：

- 上游聚合表 `modern_case_profiles.csv`（西医诊断 × 中医病名 × 证候 × 用药 × 外治，无个人字段）中
  至少 3 例的 9 行；
- 主页「当代门诊」一节的聚合计数，同样只列至少 3 例的条目。

聚合表虽无个人字段，但 61 行中有 52 行只有 1–2 例，其中 47 行各对应一名患者——一行就是一个人的
诊断、证候、用药与外治。这些行与逐案层一并暂缓。

暂缓的范围：

| 项 | 数 |
|---|---:|
| 当代病案语料的关系 | 5,682 |
| 只由它引出的节点 | 1,234 |
| ——其中医案 | 131 |
| ——其中西医诊断 / 外治操作 / 西药 / 辅助检查 | 72 / 38 / 24 / 37 |
| 受其影响、属性与出处恢复为上一版的节点 | 290 |
| `corpus_yueyi.json` 中删去的段落 | 131 |
| `modern_case_profiles.csv` 中少于 3 例的行 | 52 / 61 |

判定规则：一个节点只要在上一版中存在、或连有历史文献的关系、或带历史文献的出处，就予以保留；
保留节点中凡被当代病案触及的，其属性、别名、出处、提及数与坐标一律取上一版。
因此全图几何与线上版本一致，没有因删除而留下空洞。

**写盘前的隐私闸门**（两种模式都跑）：全部输出文本中，患者抬头（姓名 + 性别 + 年龄 + 住院号的行内格式）、
身份证号、手机号，以及运行时从原始文本推导出的患者姓名，计数必须为 0，否则导入中止、不写任何文件。
本版 24 个推导姓名、残留 0。

日后若确认可以发布，`--include-modern-cases` 会先经 `tools/deidentify.py` 处理：
行内患者抬头改写为「患者（性别，年龄）」、残留 7–8 位编号删除、日历日期只保留年份、
就诊跨度与逐次就诊日期（`visit_dates`）改写为天数、90 岁以上合并；再过更严格的闸门：
每条当代记录的**全部字符串字段**（不只正文）逐一核验，完整日期、月日、编号也必须为 0。

### 5. 与 V6 的差异

| 项 | 数 |
|---|---|
| V6 节点仍在 | 18,149 |
| V6 节点删去 | 2（上焦症、阳明症——上游并入上焦、阳明） |
| 新增节点（公开部分） | 0 |
| V6 关系删去 | 5（上述两节点的 2 条属于六经、3 条征象提示） |
| 新增关系（公开部分） | 3（征象提示，改指上焦 / 阳明） |
| 节点坐标变化 | 0 |
| 共有关系原文变化 | 0 / 22,695 |

### 6. 其他观察

1. 症状与诊法征象两类有 **439 个同名节点**并存，是两层抽取各自命名所致。
2. 繁简归并只作用于节点名称：机构 `kind` 属性仍有 學校 / 学校、醫社 / 医社 等两写。
3. 证候性质 `nature` 有「湿|热」与「湿热」两种写法，主页统计时合并显示，数据未改。
4. 中药节点上的 `dose` / `unit` / `processing` 是原文所见的抽取值，非药典常规剂量。
5. 方剂的逐味配伍未随交付提供：1,280 首方剂中 517 首有边，「药物组成」仅 41 条，
   `ingredientRole` 等四条方剂关系仍无实例。
6. 7,087 个节点没有任何已抽取关系（多为单次出现的症状 / 治法短语），浏览器中铺在最外一圈。
7. 22,368 条关系（98.5%）仅有单次原文支持。
8. 医案标题中只有 255/660 条含规范病名，其余命名的是证候——这是何廉臣的命题习惯，不是词表缺口。
9. 道地药材前缀（广 / 川 / 杭 / 建 / 云 / 西）与陈 / 真 / 原等品质标记刻意不做归并。

### 查询提示

Turtle 中所有中文字面量带 `@zh` 语言标记，SPARQL 需写 `"腹诊"@zh`，写成 `"腹诊"` 会静默返回空结果。
