# 公文知识图谱优化与应用落地方案

## 1. 文档目标

本文档是公文文件检索系统知识图谱建设的**统一需求与设计文档**，涵盖治理图、事项图及条款图三个建设阶段，其中条款图进一步拆分为 **Phase 2A（条款基础图）** 和 **Phase 2B（条款细粒度语义）** 两个子阶段。

系统背景：

- 检索底座：OpenSearch 混合检索
- 问答模式：RAG
- 图谱底座：Neo4j GraphRAG
- 数据来源：公文全文、元数据、chunk
- 图谱更新方式：清除旧数据后全量重建
- 抽取约束：单轮 LLM 抽取
- Schema 管理方式：配置文件驱动（`graph_schema.yaml`）

---

## 2. 总体建设路线

### 2.1 三阶段规划

| 阶段 | 名称 | 目标 |
|------|------|------|
| Phase 0 | 治理图 | 文件依据、修订、废止、适用地域、主题归属、文档有效性 |
| Phase 1 | 事项图 | 事项、条件、材料、时限、适用对象、办理部门 |
| Phase 2A | 条款基础图 | 条款回链、条款定位事项与职责机构 |
| Phase 2B | 条款细粒度语义 | 条款级条件/材料/时限抽取 |

### 2.2 核心设计取舍

以下对象**不作为核心图节点**：

| 对象 | 处理方式 | 原因 |
|------|----------|------|
| DocCategory | `Document.doc_type` 属性 | 文种作为属性即可 |
| Subject | `Document.subject_summary` 属性 | 主旨摘要不需独立节点 |
| Keyword | `Document.keywords[]` 属性 | 关键词不需独立节点 |
| Person | 不纳入默认 schema | 签发人/经办人作为 Document 属性 |

### 2.3 核心建模原则

1. 图谱核心以 `Document / Organization / Region / PolicyTheme / Matter / Article` 为主
2. 价值重点不在"实体多"，而在"治理关系准、事项关系准、条款证据可回链"
3. 所有结构化结论原则上要能回链到原始 Document → Article → Chunk
4. `Article` 采用规则切分条款 + LLM 补充条款语义

### 2.4 重建策略

- 本方案不提供旧关系迁移逻辑，不支持在旧图基础上做增量兼容
- 必须先清空旧图数据（`MATCH (n) DETACH DELETE n`），再执行全量重建
- 旧节点（Person、DocCategory、Subject、Keyword）和旧关系（ISSUED、RECEIVED_BY、SIGNED、HANDLED、INVOLVES、COVERS_REGION、ABOUT、CATEGORIZED_AS、TAGGED、RELATED_TO）视为完全废弃

---

## 3. 设计原则

### 3.1 以业务价值驱动 schema
判断某类对象是否建模为节点，看是否支撑核心查询、支撑稳定关系、适合图遍历、值得维护归一化。

### 3.2 属性优先于弱节点
弱结构、低稳定性、低遍历价值的数据优先作为属性：文种、关键词、文件主旨摘要、发布/生效/失效日期。

### 3.3 强关系优先于弱标签
优先建设：BASED_ON, AMENDS, REPEALS, ISSUED_BY, APPLIES_TO_REGION, GOVERNS, REQUIRES_MATERIAL, HAS_CONDITION, HAS_TIME_LIMIT

### 3.4 图谱必须支持证据回链
每个结构化关系应尽量追踪到：来源文档、来源条款、来源 chunk、证据文本、抽取置信度。

### 3.5 Chunk 的当前定位

`Chunk` 是 RAG 检索与证据回链的底层载体，但当前阶段**不作为 Phase 0–2 的核心业务图节点显式建模**。

当前处理原则：

1. 图谱中的结构化关系通过以下信息保留 chunk 级溯源能力：`source_chunk_id`、`source_doc_id`、`source_article_id`、`evidence_text`、`confidence`
2. `Chunk` 仍可存在于检索系统或中间数据结构中，用于回链原始文本片段
3. 若后续需要实现条款-片段级可视化、证据链可视化，再考虑将 `Chunk` 显式节点化

当前图谱主干以 `Document / Matter / Article / Organization / Region / PolicyTheme` 为核心，而非以 chunk 为核心建模对象。

### 3.6 分阶段建设
不追求一步到位的大而全 schema，按阶段控制复杂度。

---

## 4. Phase 0：治理图

### 4.1 目标

支持文件依据链、修订/废止历史、同主题推荐、地域适用性、文件有效性判断辅助。

### 4.2 核心节点

#### Document

属性：doc_id, title, normalized_title, doc_code, doc_type, status (有效/部分失效/已废止/失效/待确认), publish_date, effective_date, expiry_date, admin_level (国家级/省级/市级/区县级/乡镇街道级/其他/未知), subject_summary, keywords[], knowledge_category, knowledge_category_code, source, full_text_url, is_current, is_placeholder, created_at, updated_at

**normalized_title 归一化规则**：

1. NFKC Unicode 正规化
2. 去除首尾空白
3. 统一全角/半角括号
4. 统一中英文引号样式
5. 去除首尾冗余标点
6. 折叠连续空白为单空格
7. 统一书名号内外空白
8. 保留标题核心文本（不删除年份、序号、附件号等有法律含义的部分）

注意：占位文档与正式文档的合并逻辑，优先依赖 `doc_code`，其次才考虑 `normalized_title`。

**status 字段来源优先级**：

1. 人工维护或权威元数据
2. 明确的治理关系推断（如被 REPEALS 指向）
3. 正文显式表述抽取（如"本通知自发布之日起施行"）
4. 默认空值或未知（不强行推断）

使用原则：`status` 是主状态字段；`is_current` 是辅助标记，不应替代 `status`；`expiry_date` 为空不代表文件永久有效。

**Document.status 推荐枚举**：

为避免状态值混乱，`Document.status` 固定为以下枚举之一：`有效`、`部分失效`、`已废止`、`失效`、`待确认`。

约束要求：不在上述枚举中的状态值不允许直接入库；上游状态值需在入库前统一映射为标准枚举；分析、推荐、过滤接口统一使用标准枚举值判断。

**Document.admin_level 推荐枚举**：

为避免层级字段口径不一致，`Document.admin_level` 固定为以下枚举之一：`国家级`、`省级`、`市级`、`区县级`、`乡镇街道级`、`其他`、`未知`。

如上游数据存在不同写法（如"县级""区级""县区级"），应在入库前统一映射。

**knowledge_category 编码映射**：

| 分类名称 | 编码 |
|----------|------|
| 国家/省领导讲话 | leader_speech_national_provincial |
| 市领导讲话稿 | leader_speech_city |
| 政策与法规 | policy_regulation |
| 报道材料 | news_report |
| 全会报告与规划 | plenary_report_planning |
| 政府工作报告 | government_work_report |
| 各单位公文 | official_document |
| 清远本地知识 | local_knowledge_qingyuan |
| 经济数据 | economic_data |
| 档案资料 | archive_material |

**knowledge_category 与 doc_type / PolicyTheme 的边界**：

- `knowledge_category`：文档属于哪类资料（管理分类）
- `doc_type`：文档是什么文种（通知/决定/批复等）
- `PolicyTheme`：文档讲的是什么主题（营商环境/数字政府等）

三者不可互相替代。`knowledge_category` 不仅是图谱属性，也是检索层核心过滤字段，必须同步写入 ES/OpenSearch 索引（keyword 类型）。

**knowledge_category 的来源约束**：`knowledge_category` 与 `knowledge_category_code` 来源于**上传元数据或后台人工标注**，不由 LLM 从正文中抽取。其语义定位不同于 `PolicyTheme` 的内容主题抽取结果，不应混用。主要用于：文档管理分类、检索过滤与聚合、检索路由与召回加权、图谱分析中的分类维度约束。

**ES 中的检索应用**：根据问题意图对 knowledge_category 做召回加权：

- 政策依据类问题 → 优先 policy_regulation
- 领导讲话类问题 → 优先 leader_speech_*
- 数据类问题 → 优先 economic_data
- 地方知识类问题 → 优先 local_knowledge_qingyuan

#### Organization

属性：org_id, name, normalized_name, short_name, org_type, admin_level, aliases[], region_code

#### Region

属性：region_id, name, full_name, region_code, region_level, parent_region_code, aliases[]

#### PolicyTheme

属性：theme_id, name, description, keywords[], parent_theme_id

每个 Document 默认仅保留 1-3 个最核心的 PolicyTheme，防止主题地图结构混乱和推荐噪声。

**PolicyTheme Top 1-3 筛选优先级**：

1. 标题直接命中的主题
2. 主旨摘要或摘要段落中高频出现的主题
3. 全文或条款中高置信度命中的主题
4. 若多个主题得分接近，最多保留 3 个

如主题置信度不足，则允许少于 3 个，不强制补满。

### 4.3 核心关系

| 关系 | 方向 | 说明 |
|------|------|------|
| ISSUED_BY | Document → Organization | 文件由某机构发布 |
| APPLIES_TO_REGION | Document → Region | 文件适用于某地域 |
| BELONGS_TO_THEME | Document → PolicyTheme | 文件属于某政策主题 |
| BASED_ON | Document → Document | 依据上位文件制定 |
| AMENDS | Document → Document | 修订某文件 |
| REPEALS | Document → Document | 废止某文件 |
| REFERENCES | Document → Document | 普通引用（兜底） |

**文件间关系判断优先级**（LLM 和规则引擎必须按此顺序判断）：

1. 明确"根据/依据/依照/按照" → **BASED_ON**
2. 明确"修改/修订/调整某文件" → **AMENDS**
3. 明确"废止/同时废止/停止执行" → **REPEALS**
4. 仅普通提及其他文件，且无法判断治理语义 → **REFERENCES**（兜底）

REFERENCES 仅作为兜底关系，不应替代明确可判断的治理关系。

**ISSUED_BY 关系属性预留**（当前不实现，后续联合发文推荐时使用）：

- `issuer_role`: `primary` / `joint`
- `order`: 发文机构顺序

### 4.4 占位文档机制

- LLM 抽取的 `BASED_ON / AMENDS / REPEALS` 目标自动创建占位文档节点
- 占位文档使用统一命名：`doc_id = ref:{doc_code}`、`doc_code`、`is_placeholder = true`
- 若历史数据或上游字段中使用 `doc_number`，应在入库阶段统一映射为 `doc_code`，避免命名混用

**占位文档吸收流程**：正式文档入库时，若 `doc_code` 匹配已有占位文档，应执行以下流程：

1. 创建或合并正式文档节点
2. 将占位节点上的入边/出边重定向到正式文档节点
3. 完成关系迁移后，再删除占位节点

不建议直接先删除占位节点再重建关系，以避免关系丢失和并发窗口问题。

若同一 `doc_code` 已存在 `BASED_ON / AMENDS / REPEALS` 关系，不再额外创建冗余 `REFERENCES`。

### 4.5 不进入主图的对象

- DocCategory → `Document.doc_type`
- Subject → `Document.subject_summary`
- Keyword → `Document.keywords[]`
- Person → 暂不纳入默认 schema

---

## 5. Phase 1：事项图

### 5.1 目标

支持办事问答、事项知识卡、结构化事项检索。

### 5.2 新增核心节点

#### Matter

属性：matter_id, name, normalized_name, matter_type, description, aliases[], status

示例：政府采购供应商资格审查、建设用地审批、差旅报销、档案归档

**Matter 建模判定原则** — 满足以下至少一项才建模为 Matter：

- 可以回答"由谁办理"
- 可以回答"需要什么材料"
- 可以回答"有什么条件"
- 可以回答"多久办完"
- 可以被一个或多个文件/条款明确规范

不建议作为 Matter 的对象：过于宏观的概念（如"行政管理"）、过于细碎的动作（如"填写附件"）、无稳定办理语义的短语（如"统筹协调"）。

#### Condition

属性：condition_id, name, description, condition_type, structured_value, operator

#### Material

属性：material_id, name, normalized_name, material_type, description, is_required, format_requirement

#### TimeLimit

属性：time_limit_id, name, duration, unit, context, time_type

**结构化要求**：

- `duration`：尽量转为可比较值
- `unit`：统一为规范值（工作日/自然日/月/年）
- `context`：描述起算条件（如"自受理之日起"）
- `name`：仅作展示，不作为唯一有效语义来源

#### TargetGroup

属性：target_group_id, name, normalized_name, group_type, description, aliases[]

示例：企业法人、中小企业、事业单位、供应商、申请人

**与 Organization 的边界**：TargetGroup 表示适用对象的"类型"，不是具体机构或个人。具体机关/单位归为 Organization。

### 5.3 核心关系

| 关系 | 方向 | 说明 |
|------|------|------|
| GOVERNS | Document/Article → Matter | 文件或条款规范某事项 |
| HAS_CONDITION | Matter → Condition | 事项具有适用条件 |
| REQUIRES_MATERIAL | Matter/Article → Material | 事项或条款要求材料 |
| HAS_TIME_LIMIT | Matter → TimeLimit | 事项具有时限要求 |
| APPLIES_TO_TARGET | Matter → TargetGroup | 事项适用于某对象类型 |
| HANDLED_BY | Matter → Organization | 事项由某机构办理 |
| APPLIES_TO_REGION | Matter → Region | 事项适用于某地域（按需写入，见下方说明） |

**Matter 层地域关系写入原则**：`APPLIES_TO_REGION (Matter → Region)` 仅在事项层存在**独立于 Document 的显式地域约束**时写入。若事项未单独声明地域范围，则默认继承上游 Document 的适用地域，不重复创建 `Matter → Region` 关系。原因：避免重复建边造成图谱冗余；避免将文档地域范围误解为事项自身定义的地域范围；保持事项图语义更清晰。

### 5.4 主键与去重策略

Phase 1 各节点以 `name` 为 key_property。存在全局去重过度风险（如不同事项下的"营业执照副本"被合并），当前阶段接受此限制，后续可演进为组合主键（如 `normalized_name + material_type`）。

写关系时保留来源证据，查询展示时通过关系上下文解释语义。

### 5.5 Phase 1 节点的 ID 字段说明

`Condition / Material / TimeLimit / TargetGroup` 保留以下内部标识属性：`condition_id`、`material_id`、`time_limit_id`、`target_group_id`。

这些字段的用途是：

1. 作为 API 返回中的稳定标识
2. 为后续演进到组合主键或专用主键预留空间
3. 便于前端或下游系统进行节点引用

当前阶段约束：Neo4j merge 仍以 `name` 作为 `key_property`；`*_id` 属于内部生成属性，不参与当前阶段的主键判定；若 `*_id` 与 `name` 表达冲突，以当前 schema 规定的 merge key 为准。

---

## 6. Phase 2：条款图

### 6.1 Phase 2A：条款基础图

#### 目标

条款可回链到文档、条款能定位事项与职责机构。

#### Article 节点

属性：article_id (`{doc_id}__art_{order}`), article_number, title, content, order, norm_type (定义/要求/禁止/许可/程序/处罚/附则), anchor

#### 核心关系

| 关系 | 方向 | 说明 |
|------|------|------|
| HAS_ARTICLE | Document → Article | 文件包含条款 |
| GOVERNS | Article → Matter | 条款规范某事项（Phase 1 已定义为多源关系） |
| ASSIGNS_TO | Article → Organization | 条款赋予机构职责 |

#### 生成策略

**Step 1：规则切分**（新建 `article_splitter.py`）

- 基于正则的条款边界识别，支持格式：`第一条`、`第十二条`、`第1条`、`第 1 条`
- 正则至少支持中文数字、阿拉伯数字、空格容忍
- 推荐匹配模式：`r'第\s*[一二三四五六七八九十百千零〇\d]+\s*条'`
- 无"第X条"格式的文档不生成 Article 节点

**Step 2：LLM 语义补充**

- 输入：文档标题 + 文种 + 摘要 + 条款列表（不传全文，减少 token 负担）
- 输出：norm_type、关联 Matter/Organization 识别
- 批量标注（全部条款一次传入）

#### 降级策略

若文档不符合条款切分规则：不生成 Article 节点、不阻断 Document 级与 Matter 级图谱构建、仍保留基于 chunk 的证据回链能力。条款图是增强能力，不是前置必需能力。

### 6.2 Phase 2B：条款细粒度语义

在 2A 基础上新增关系：

| 关系 | 方向 | 说明 |
|------|------|------|
| SETS_CONDITION | Article → Condition | 条款规定条件 |
| REQUIRES_MATERIAL | Article → Material | 条款要求材料（Phase 1 已定义） |
| SETS_TIME_LIMIT | Article → TimeLimit | 条款规定时限 |

目标：支持更精细的条款问答、条款级要件抽取、精细化制度分析。

条款到条件/材料/时限的语义标注复杂度明显高于条款到事项/机构，因此拆分为独立子阶段。

---

## 7. 配置驱动 Schema 设计

### 7.1 设计目标

将类型定义、关系定义、归一化规则统一配置化，支持 schema 低成本增减、提示词自动生成、Neo4j 类型校验、前端显示配置统一。

### 7.2 配置文件

`backend/app/config/graph_schema.yaml`

```yaml
entity_types:
  - name: Organization
    description: "政府机关、主管部门、责任部门"
    icon: bank
    color: "#52c41a"
    phase: phase_0
    extraction_mode: llm
    key_property: name
  # ... 其他类型

relationship_types:
  - name: ISSUED_BY
    source_labels: [Document]
    target_labels: [Organization]
    description: "文件由某机构发布"
    phase: phase_0
  # ... 其他关系

normalization_rules:
  Organization:
    strip_punctuation: true
    trim_whitespace: true
  PolicyTheme:
    strip_punctuation: true
    max_length: 30
  # ... 其他规则

knowledge_category_mapping:
  国家/省领导讲话: leader_speech_national_provincial
  # ...

active_phases:
  - phase_0
  # - phase_1
  # - phase_2a
  # - phase_2b
```

### 7.3 Phase 控制机制

只有 `active_phases` 中列出的 phase 对应的实体/关系才会被加载到运行时。修改后重启服务即可生效。

```yaml
active_phases:
  - phase_0
  # - phase_1
  # - phase_2a
  # - phase_2b
```

| Phase | 实体 | 关系 |
|-------|------|------|
| phase_0 | Organization, Region, PolicyTheme | ISSUED_BY, APPLIES_TO_REGION, BELONGS_TO_THEME, BASED_ON, AMENDS, REPEALS, REFERENCES |
| phase_1 | Matter, Condition, Material, TimeLimit, TargetGroup | GOVERNS, HAS_CONDITION, REQUIRES_MATERIAL, HAS_TIME_LIMIT, APPLIES_TO_TARGET, HANDLED_BY, APPLIES_TO_REGION |
| phase_2a | Article | HAS_ARTICLE, GOVERNS, ASSIGNS_TO |
| phase_2b | _(无新增实体)_ | SETS_CONDITION, SETS_TIME_LIMIT, REQUIRES_MATERIAL |

> 说明：`REQUIRES_MATERIAL` 在 Phase 1 已作为关系名存在；Phase 2B 的含义是新增 Article 端对该关系的使用，而非新增一个新的关系类型。

### 7.4 Phase 2B 启用依赖

`phase_2b` 依赖 `phase_2a`，**不可单独启用**。

原因：

1. `phase_2b` 本身不引入新增实体，仅在 `Article` 已存在的前提下，为条款补充更细粒度的语义关系
2. 若未启用 `phase_2a`，则运行时不存在 `Article` 节点，`SETS_CONDITION / SETS_TIME_LIMIT / REQUIRES_MATERIAL (Article → Material)` 将失去作用对象
3. 配置层允许 `phase_2b` 仅新增关系类型而无新增实体类型，但运行时必须保证 `Article` 已由 `phase_2a` 启用

建议的启用顺序：

```yaml
active_phases:
  - phase_0
  - phase_1
  - phase_2a
  - phase_2b
```

不建议跳过 `phase_2a` 直接启用 `phase_2b`。

---

## 8. 抽取策略设计

各 Phase 的"单轮 LLM 抽取"是指在**当前激活 phase 范围内**进行单轮抽取，而非在任意时刻同时抽取全部阶段的所有实体与关系。例如仅启用 `phase_0` 时，只抽取治理图相关实体与关系；启用 `phase_1` 后，才在此基础上增加事项图抽取；启用 `phase_2a/2b` 后，才增加条款层能力。

### 8.1 Phase 0 单轮 LLM 抽取

Organization, Region, PolicyTheme + BASED_ON/AMENDS/REPEALS/REFERENCES。文档属性从元数据直接获取。

### 8.2 Phase 1 单轮 LLM 抽取

在 Phase 0 基础上增加：

- `Matter`、`Condition`、`Material`、`TimeLimit`、`TargetGroup`

以及以下关系：

- `GOVERNS`、`HAS_CONDITION`、`REQUIRES_MATERIAL`、`HAS_TIME_LIMIT`、`APPLIES_TO_TARGET`、`HANDLED_BY`
- `APPLIES_TO_REGION`（仅在事项层存在显式地域约束时抽取）

**Phase 1 抽取规则要点**：

- `Matter`：抽取"可独立办理或规范的具体行政事项"，粒度控制严格
- `Condition`：明确的适用/资格/前置条件，必须具体可判断
- `Material`：明确提到的材料名称，保留 `is_required` 属性
- `TimeLimit`：必须包含数字和单位的明确时间限制
- `TargetGroup`：适用对象的类型名称，不是具体人名或单位名
- `APPLIES_TO_REGION`：仅当事项本身明确具有独立地域限制时抽取；否则默认继承上游 `Document` 的适用地域

### 8.3 Phase 2 条款抽取

规则切分条款边界，LLM 仅做语义补标（norm_type、关联实体）。

### 8.4 组织层级关系

SUBORDINATE_TO / LOCATED_IN 保留为增强关系，不作为当前阶段主建设目标。来源优先级：组织主数据 > 行政区划字典 > 文档抽取补充。

---

## 9. 应用场景

### 9.1 场景 A：文档详情推荐与治理链（Phase 0，已实现）

**API**：

| 端点 | 方法 | 功能 |
|------|------|------|
| `GET /api/v1/graph/document/{doc_id}/recommendations` | GET | 同机构/同主题/同地域推荐 |
| `GET /api/v1/graph/document/{doc_id}/policy-chain` | GET | 政策依据链（仅 BASED_ON） |
| `GET /api/v1/graph/document/{doc_id}/revision-history` | GET | 修订/废止历史（仅 AMENDS/REPEALS） |
| `GET /api/v1/graph/document/{doc_id}/same-theme` | GET | 同主题文档 |

**推荐默认过滤规则**：排除 is_placeholder=true、status=已废止、当前文档自身。

**policy-chain 当前语义**：仅表示制定依据链（BASED_ON 向上追溯），不包含转发落实链、实施细则链、一般引用网络。后续引入 IMPLEMENTS/FORWARDS/REPLACES 时再扩展。

**revision-history 语义**：仅围绕 AMENDS 与 REPEALS 做双向遍历和时间线组织，不纳入 REFERENCES。若需普通关联文件，应单独提供 related-documents 接口。

### 9.2 场景 B：对话增强问答（Step 4）

轻量固定模板的图谱查询规划，不做通用 Cypher 自动生成。

**流程**：用户提问 → 规则匹配高频问题模板 → 未命中时 LLM 分类 → 匹配预定义查询模板 → 执行 Cypher → 合并 ES 结果 → LLM 生成答案

**Query Planner 采用"规则优先 + LLM 补充"**：

- 高频问题（依据什么文件、是否废止、哪个部门发布等）先用规则匹配
- 未命中或歧义较高时，再调用 LLM 分类
- 图谱查询失败时，自动回退普通 RAG

**核心原则**：图谱查询作为增强分支，不阻塞主 RAG 流程。planner 判断失败 → 回退普通检索问答；Cypher 查询失败 → 记录日志并回退；图谱结果为空 → 不中断回答。

**查询类型**：policy_basis, revision_status, issuing_org, theme_related, matter_info(Phase 1), material_list(Phase 1), article_detail(Phase 2)

**新建文件**：`graph_query_planner.py`, `prompts/query_planning.py`

### 9.3 场景 C：事项知识卡与办事问答（Phase 1 后）

围绕 Matter 构建结构化知识卡：事项名称、适用对象、办理部门、办理条件、所需材料、办理时限、适用地域、依据文件。

**API**：

| 端点 | 方法 | 功能 |
|------|------|------|
| `GET /api/v1/graph/matters` | GET | 事项列表/搜索 |
| `GET /api/v1/graph/matters/{name}` | GET | 事项知识卡 |
| `GET /api/v1/graph/matters/{name}/requirements` | GET | 事项办理条件与材料 |

### 9.4 场景 D：治理型分析接口（Phase 0 数据充足后）

优先建设：

1. **失效引用检测** — 引用了已废止/失效文件的现行有效文件（检查 BASED_ON 和 REFERENCES 关系；AMENDS/REPEALS 属于治理行为本身，不纳入"失效引用"概念）
2. **主题时间线** — 某主题下所有文件按时间排列
3. **部门发文统计** — 按年份、按文种、按主题分布
4. **依据链覆盖分析** — 有多少现行文件缺少 BASED_ON 依据关系
5. **孤立文件检测** — 缺少关键关系或属性的 Document，采用**多条件组合判定**（分级：严重孤立=多个核心关系同时缺失且关键属性缺失；中度孤立=存在部分治理关系但主题/地域/分类维度不完整；轻度孤立=仅缺少个别辅助属性或单一关系）。可纳入判定的条件：无 ISSUED_BY、无 BELONGS_TO_THEME、无 APPLIES_TO_REGION、无 BASED_ON、status 缺失、knowledge_category 缺失

**API**：

| 端点 | 方法 | 功能 |
|------|------|------|
| `GET /api/v1/analytics/invalid-references` | GET | 失效引用检测 |
| `GET /api/v1/analytics/theme-timeline/{name}` | GET | 主题时间线 |
| `GET /api/v1/analytics/org/{name}` | GET | 部门发文统计 |
| `GET /api/v1/analytics/basis-coverage` | GET | 依据链覆盖分析 |
| `GET /api/v1/analytics/orphan-documents` | GET | 孤立文件检测 |

后置能力（不作为首批交付）：全局 PageRank、overview 大屏、跨地域对比分析、跨层级政策传播评分。

### 9.5 场景 E：主题地图（事项图稳定后）

构建 PolicyTheme → Matter → Document 层级导航结构。

**API**：

| 端点 | 方法 | 功能 |
|------|------|------|
| `GET /api/v1/topics` | GET | 主题列表（含文档计数） |
| `GET /api/v1/topics/{theme_name}` | GET | 主题详情（含下属事项和文件） |

### 9.6 场景 F：Research 专题研究（最后建设）

依赖治理关系准确 + 事项结构完整 + 条款回链稳定。

**第一版交付范围**（范围收缩）：

- 专题概述
- 核心文件清单
- 时间演进轨迹
- 依据链梳理
- 相关事项概览

**暂不在第一版承诺**：冲突条款识别、政策空白点判断、待更新文件建议、自动合规性结论。原因：这些高级分析结论高度依赖图谱完整性、状态字段准确性、条款语义标注稳定性。

**第一版输入范围约束**：优先支持已存在的 `PolicyTheme` 和已存在的 `Matter` 作为输入对象。暂不在第一版直接开放"任意自由文本主题"作为主输入形式，原因：自由文本主题容易退化为普通 RAG 报告生成，图谱命中率和结构化组织稳定性不足，用户对"专题研究"结果的预期较高。后续在主题图谱和事项图谱稳定后，再逐步开放更自由的研究主题输入。

**API**：`POST /api/v1/research/topic`

---

## 10. 实施计划

```
已完成:
  Step 1: 配置文件外部化 (graph_schema.yaml + loader)
  Step 2: Phase 0 治理图适配 (提示词/归一化/查询服务)
  Step 3: 文档推荐 / 依据链 / 修订链 API (场景A)

后续:
  Step 4:  对话增强问答 — 规则优先 + LLM 补充 (场景B)
  Step 5:  启用 Phase 1 + 全量重建 + 验证
  Step 6:  事项知识卡 / 办事问答 API (场景C)
  Step 7:  治理分析接口 — 含孤立文件检测 (场景D)
  Step 8:  启用 Phase 2A — Article 基础图 + 全量重建 + 验证
  Step 9:  政策主题地图 (场景E)
  Step 10: 启用 Phase 2B — 条款细粒度语义
  Step 11: Research 专题研究 — 第一版收缩范围 (场景F)
```

每个 Step 完成后应执行验证：清除旧数据 → 全量重建 → Cypher 校验 → API 校验。

---

## 11. 验证方案

### Phase 0 验证

- Document 是否具有 status/effective_date/expiry_date/knowledge_category
- BASED_ON/AMENDS/REPEALS 关系是否存在且方向正确
- 依据链查询、同主题推荐是否正常
- 占位文档创建与吸收机制是否工作
- 推荐结果是否正确排除占位文档和已废止文档
- knowledge_category 是否同时写入 Neo4j 和 ES
- `Document.status` 是否全部落入标准枚举
- `Document.admin_level` 是否全部落入标准枚举
- `normalized_title` 是否按统一规则生成
- 占位文档吸收后是否不存在悬空关系

### Phase 1 验证

- Matter/Condition/Material/TimeLimit/TargetGroup 节点写入成功
- 事项知识卡结果是否结构完整
- 归一化规则生效（Matter ≤ 50 字符、Material ≤ 100 字符等）
- TargetGroup 不含具体机关/个人名
- `*_id` 字段是否正常生成但未误作为 merge key
- `Matter → Region` 是否仅在显式地域约束下写入

### Phase 2 验证

- Article 切分正确性（标准"第X条"格式，含中文数字与阿拉伯数字）
- 非标准格式公文不生成错误 Article 节点（正确降级为无 Article 模式）
- norm_type 标注准确率
- 条款可回链到 Document（HAS_ARTICLE）
- 条款语义补标未重复写入已有关系

### 端到端问答测试

- 治理类："这份文件依据什么？""是否已被废止？""当前有效版本？"
- 事项类："XX事项需要哪些材料？""办理时限？""哪个部门负责？"
- 条款类："依据哪一条？""哪条规定了这一要求？"

---

## 12. 风险与应对

| 风险 | 应对 |
|------|------|
| 单轮抽取质量 | 严格控制每阶段启用的实体与关系数量 |
| 归一化污染 | 配置规则 + 核心实体人工抽样校验 |
| 条款切分误差 | 先覆盖标准"第X条"格式；非标准允许不生成条款图 |
| 图谱复杂度膨胀 | 每阶段只引入明确服务于应用场景的节点与关系 |
| 分析结果可解释性 | 优先建设可解释的治理分析，不先上复杂评分模型 |
| Phase 1 全局去重过度 | 先用 name 作 key_property，后续演进为组合主键 |
| 条款语义标注复杂度 | 拆分为 2A/2B 分步落地 |
| 图谱增强阻塞主流程 | 图谱查询作为增强分支，失败时回退普通 RAG |

---

## 13. 数据重建策略

每阶段完成后：更新 graph_schema.yaml → 重启服务 → 清除旧图谱 → POST /admin/graph/rebuild-all → Cypher 验证 → API 验证

重建注意事项：

- 文档主键规则必须稳定
- 归一化规则重建前冻结
- 新属性与关系同步更新写库逻辑
- 重建期间建议禁用外部图查询接口
- 若未清空旧图数据，可能导致新旧 schema 混杂、推荐结果污染、API 返回异常

---

## 14. 术语与命名统一约定

为避免实现中出现命名歧义，统一约定如下：

- `doc_code` 为正式发文字号/文号字段的标准名称；若历史系统或上游元数据中存在 `doc_number`，统一在入库时映射为 `doc_code`
- `status`、`admin_level`、`knowledge_category_code` 使用标准枚举或标准映射值
- 当前阶段 `Condition / Material / TimeLimit / TargetGroup` 的 merge key 为 `name`
- `*_id` 为内部标识属性，不参与当前阶段主键判定
- `Chunk` 当前为证据回链载体，不是核心业务图节点
- `GraphQueryPlanner` 为增强分支，不阻塞主 RAG 问答链路

以上约定在后续实现、测试、运维与接口设计中应保持一致。
