实战知识库迁移 02:清洗文档并补齐元数据

先理解:清洗是为了让知识可被信任

原始文档通常不适合直接给 AI 用:标题不统一、内容重复、版本混乱、负责人缺失。清洗不是美化排版,而是把文档变成机器能稳定处理、人能追溯责任的知识条目。

本篇把 Markdown 文档转换成 JSONL。每行代表一条可入库知识,并带上分类、负责人、权限、版本等元数据。

元数据不要贪多

第一版只保留真正会用到的字段:idtitlecategoryownervisibilityversionupdated_at。字段太多会增加维护成本,最后大家会乱填或不填。

清洗后的抽检

脚本跑完后一定要人工抽检。看标题是否完整、分类是否合理、权限是否正确、内容是否被截断。自动化脚本负责效率,人工抽检负责方向。

本篇把原始 Markdown 文档转换成结构化 JSONL。每条 JSONL 是一个知识块,带来源、权限、版本和负责人。

本篇成品

text
docs/after_sales_policy.md
processed/chunks.jsonl
tools/process_docs.py

样例文档

docs/after_sales_policy.md

md
# 售后政策

owner: 客服运营
version: 2026.04
permission: internal
domain: business
topic: after_sales

## 七天无理由退货
签收后 7 天内,商品未拆封、配件齐全,可申请无理由退货。

## 免费保修
保修期内的非人为性能故障可申请免费检测。进水、摔落、私拆不属于免费保修范围。

处理脚本

tools/process_docs.py

python
import hashlib
import json
import re
from pathlib import Path

DOC_DIR = Path("docs")
OUT = Path("processed/chunks.jsonl")

def clean(text: str) -> str:
    return re.sub(r"\n{3,}", "\n\n", text).strip()

def doc_id(path: Path, text: str) -> str:
    digest = hashlib.sha1(text.encode("utf-8")).hexdigest()[:10]
    return f"{path.stem}-{digest}"

def parse_metadata(lines: list[str]) -> tuple[dict, list[str]]:
    meta = {}
    body_start = 0
    for i, line in enumerate(lines):
        if ":" in line and not line.startswith("#"):
            key, value = line.split(":", 1)
            meta[key.strip()] = value.strip()
        elif line.startswith("## "):
            body_start = i
            break
    return meta, lines[body_start:]

def split_sections(body: str) -> list[str]:
    parts = re.split(r"\n(?=## )", body)
    return [clean(p) for p in parts if len(clean(p)) > 20]

def main():
    OUT.parent.mkdir(parents=True, exist_ok=True)
    rows = []
    for path in DOC_DIR.glob("*.md"):
        lines = path.read_text(encoding="utf-8").splitlines()
        meta, body_lines = parse_metadata(lines)
        for section in split_sections("\n".join(body_lines)):
            rows.append({
                "id": doc_id(path, section),
                "text": section,
                "source": str(path),
                "owner": meta.get("owner"),
                "version": meta.get("version"),
                "permission": meta.get("permission"),
                "domain": meta.get("domain"),
                "topic": meta.get("topic"),
                "quality_status": "draft",
            })
    OUT.write_text("\n".join(json.dumps(r, ensure_ascii=False) for r in rows), encoding="utf-8")
    print(f"wrote {len(rows)} chunks")

if __name__ == "__main__":
    main()

执行和验收

bash
mkdir -p tools processed
python tools/process_docs.py
head -n 1 processed/chunks.jsonl

每条记录必须包含:

  • id
  • text
  • source
  • owner
  • version
  • permission
  • domain
  • topic

缺少这些字段的文档不要进入正式索引。

实战知识库迁移 03:权限、版本和同步,不要让 AI 读错知识
实战知识库迁移 01:盘点知识源并设计分类体系