# BE05 — 知识入库体系总设计(Knowledge Ingest) > **版本:V1.1 | 定稿** > **定位**:把「素材入库」与「结构化知识入库」统一为一套可复用的知识入库体系,覆盖上传 → 生成 → 审批 → 入库全链路。 > **配套**:BE03(素材转换管线)、BE04(AI 检索)、`docs/knowledge_source/README.md`(知识源格式契约)。 --- ## 1. 模块职责 知识入库体系负责把两类知识源,统一经过「审批前置」流入三张消费表,最终支撑「可浏览 / 可考试 / 可 AI 检索」。 | 知识源类型 | 载体 | 审批单元 | 流入表 | |-----------|------|---------|--------| | **非结构化素材** | PPT/PDF/Word/视频/图片 | 逐文件 | knowledge_chunk(+ 预览) | | **结构化知识** | 知识源 md(docs/knowledge_source/) | 逐文档 | product / question / knowledge_chunk | **核心原则(与 P02/P04 对齐)**:所有知识只有 `approved` 才生效;`pending` / `rejected` 一律不解析、不进库、前台不可见。 --- ## 2. 完整目录结构(定稿) ``` eai_agentplatform_app/ ├── docs/ │ └── knowledge_source/ # 知识源文档(权威源,纳入 git 版本管理) │ ├── README.md # 格式契约 + 答案契约 + 审批状态机 │ ├── 01_通用规则.md │ ├── 02_资本咨询类.md │ ├── 03_资质认定辅导类.md │ ├── 04_AI咨询与实施类.md │ └── 05_企业级AI工具与平台.md │ ├── backend/ │ ├── app/ │ │ ├── api/ │ │ │ ├── media.py # 【已有】素材上传/审批/预览 │ │ │ └── knowledge.py # 【新增】知识源扫描/审批/摄入 │ │ ├── models/ │ │ │ ├── media_file.py # 【已有】素材表 │ │ │ ├── knowledge_chunk.py # 【改造】来源扩展(见 §4) │ │ │ └── knowledge_source.py # 【新增】知识源文档表 │ │ ├── services/ │ │ │ ├── media_service.py # 【已有】LibreOffice/PyMuPDF 转换管线 │ │ │ └── knowledge_service.py # 【新增】md 解析 + 摄入 │ │ └── scripts/ │ │ ├── init_db.py # 【已有】建表 + 种子 │ │ └── ingest_knowledge.py # 【新增】知识源扫描/摄入脚本 │ └── data/ │ ├── media/ # 【已有】素材物理文件(git 忽略) │ │ ├── upload/ │ │ └── _preview_cache/ │ └── logs/ # 【已有】special_trace 按天日志 │ └── docker-compose.yml # 【待创建】 ``` **约定**: - `docs/knowledge_source/` 是知识源 md 的唯一入库口(权威源,git 管理,可 diff 可回滚)。 - 运行时摄入**直接读取**该目录,不复制到 backend/data(单一事实源,避免双份漂移)。 - 素材物理文件仍在 `backend/data/media/`(git 忽略)。 --- ## 3. 两条流程的状态机(定稿) ### 流程 A:非结构化素材(BE03 已实现) ``` 员工上传 ──▶ media_file(pending) ──审批──▶ approved ──▶ 异步转换 管理员上传 ──▶ media_file(approved) ──▶ 立即异步转换 │ ▼ ┌──────────────────────────┐ │ 文档: LibreOffice→PDF→ │ │ PyMuPDF 提取→切片 │ │ 视频/图片: 仅预览 │ └──────────┬───────────────┘ ▼ knowledge_chunk ``` ### 流程 B:结构化知识源(本次新增) ``` 知识源 md(docs/knowledge_source/) │ ▼ 【扫描】ingest_knowledge.py / POST /api/knowledge/scan │ 解析 front-matter → 为每个 md 建 knowledge_source 记录 ▼ knowledge_source(pending) ──审批──▶ approved ──▶ 解析摄入 │ │ │ ├─→ product(status=active) │ ├─→ question(status=active) │ └─→ knowledge_chunk(source=knowledge_source) │ └─驳回──▶ rejected(理由必填,不生效) ``` **对称性**:素材「审批通过→转换提取」,知识源「审批通过→解析摄入」。两条通道最终都汇入 `knowledge_chunk` 供 AI 检索。 --- ## 4. 数据模型变更 ### 4.1 新增 `knowledge_source` 表 ```sql CREATE TABLE knowledge_source ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, title VARCHAR(256) NOT NULL COMMENT '文档标题', file_path VARCHAR(512) NOT NULL UNIQUE COMMENT 'md 相对路径(docs/knowledge_source/ 下)', category VARCHAR(64) NOT NULL COMMENT '分类:general/capital_consulting/qualification_counseling/ai_consulting/ai_tools_platform', domain ENUM('company','product','sales') NOT NULL DEFAULT 'product', source_version VARCHAR(32) NOT NULL COMMENT '源版本,如 V1.0', audit_status ENUM('pending','approved','rejected') NOT NULL DEFAULT 'pending', audit_by BIGINT UNSIGNED DEFAULT NULL COMMENT '审批人ID', audit_at DATETIME(6) DEFAULT NULL COMMENT '审批时间', reject_reason VARCHAR(512) DEFAULT NULL COMMENT '驳回理由', ingested TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否已摄入', created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), INDEX idx_ks_status (audit_status), INDEX idx_ks_category (category), CONSTRAINT fk_ks_auditor FOREIGN KEY (audit_by) REFERENCES user(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ``` ### 4.2 改造 `knowledge_chunk` 表(来源扩展) 现状 `media_file_id BIGINT UNSIGNED NOT NULL` 强绑定素材。改造后: ```sql media_file_id BIGINT UNSIGNED DEFAULT NULL, -- 由 NOT NULL 改为可空 knowledge_source_id BIGINT UNSIGNED DEFAULT NULL, -- 新增 -- 约束:media_file_id 与 knowledge_source_id 二者必居其一(应用层校验,Fail Fast) ``` 对应 ORM `models/knowledge_chunk.py`:`media_file_id` 改为可空,新增 `knowledge_source_id` 外键与 relationship。 --- ## 5. 模块清单(8 模块) | # | 模块 | 状态 | 职责 | 落点 | |---|------|------|------|------| | 1 | 上传模块 | ✅ 已有 | 直传 + 分片(>100MB) | `api/media.py` | | 2 | 转换模块 | ✅ 已有 | LibreOffice → PDF | `services/media_service.py` | | 3 | 提取切片模块 | ✅ 已有 | PyMuPDF 提取 + 段落切片 | `services/media_service.py` | | 4 | **摄入模块** | 🆕 新增 | 解析知识源 md → product/question/chunk | `services/knowledge_service.py` | | 5 | 审批模块 | 🔧 扩展 | 素材审批(已有)+ 知识源审批(新增) | `api/media.py` + `api/knowledge.py` | | 6 | 入库模块 | 🔧 扩展 | 写 product/question/knowledge_chunk | `services/knowledge_service.py` | | 7 | 预览模块 | ✅ 已有 | approved 素材预览 | `api/media.py` | | 8 | 检索模块 | ✅ 已有 | MySQL FULLTEXT 召回 | `services/ai_service.py` | --- ## 6. 新增 API(knowledge.py) ```python router = APIRouter(prefix="/api/knowledge", tags=["knowledge"]) # ── 扫描(管理员)── POST /api/knowledge/scan # 扫描 docs/knowledge_source/*.md # 为新增/变更的 md 建 knowledge_source 记录(status=pending) # 已存在且未摄入的记录跳过;返回扫描结果列表 # ── 审批(管理员)── GET /api/knowledge/audit-list?status=pending POST /api/knowledge/audit/{source_id} # { "action": "approve" | "reject", "reject_reason": "..." } # approve → 触发摄入(同步解析写入 product/question/chunk,标记 ingested=1) # reject → 必填 reject_reason,不摄入 # ── 状态查询 ── GET /api/knowledge/status/{source_id} # { "audit_status", "ingested", "reject_reason" } ``` --- ## 7. 摄入脚本(ingest_knowledge.py) ```python """知识源摄入脚本:扫描 md → 建记录 → (审批通过后)解析入库 用法: cd backend && source venv/bin/activate python -m app.scripts.ingest_knowledge --scan # 仅扫描建 pending 记录 python -m app.scripts.ingest_knowledge --ingest # 摄入单个已审批源 """ # 解析规则(严格对齐 knowledge_source/README.md 格式契约): # 1. 读 YAML front-matter:category / domain / source_version # 2. 按 "## " 二级标题切块: # ## 结构化产品数据 → 解析 "### code name" + "key: value" 列表 → product # ## AI 检索知识 → 每个 "### 标题" 段落 → knowledge_chunk # ## 考试题目 → 每个 "### Qn" 的字段列表 → question # 3. 摄入后 product/question 置 status=active # 4. knowledge_chunk 写入 knowledge_source_id,media_file_id 留空 ``` **Fail Fast 约束(G02)**:解析失败(front-matter 缺失、section 缺块、字段缺失)立即抛错并中断该源摄入,不静默跳过、不写半截数据。 --- ## 8. 格式契约(已定,见 knowledge_source/README.md) - 每个 md:YAML front-matter(`category` / `domain` / `source_version`)+ 三个固定 `## ` section。 - 题目答案契约:`judge=[bool]`、`single=[索引]`、`multiple=[索引列表]`。 - 已生成 5 个知识源:`01_通用规则` + `02/03/04/05` 四大分类,共 28 产品 + 20 题。 --- ## 9. 实现清单(代码侧,已完成) - [x] `models/knowledge_source.py` 新建 - [x] `models/knowledge_chunk.py` 来源扩展(media_file_id 可空 + knowledge_source_id) - [x] `services/knowledge_service.py`(md 解析 + 摄入) - [x] `api/knowledge.py`(scan / audit / status) - [x] `scripts/ingest_knowledge.py` - [x] `scripts/init_db.py` 追加 knowledge_source 建表 + knowledge_chunk 字段迁移 - [x] `docs/db_schema.md`、`docs/api.md` 同步更新