本文介绍一套可以直接运行的 KAG(Knowledge-Augmented Generation)工程闭环:用大模型从小说文本中抽取知识图谱 JSON 一键导入 Neo4j,用评测集做 Recall@5 召回评测(LLM 参与生成 Cypher + 判定命中),最后把同一套链路用于图谱问答(LLM 生成 Cypher → 查图 → 再让 LLM 组织答案)。可作为 KAG / GraphRAG / KGQA 的最小可落地 MVP。
1. 为什么要做 KAG?我遇到的痛点
做 RAG 时,遇到过典型坑:
- 向量召回对'典故/情节类问题'并不稳定:搜'温酒斩华雄',但原文可能写成'其酒尚温'、人物可能是'云长/关公',词面变化导致召回波动。
- 如果分块策略偏大(窗口 512/overlap 80),章节内细粒度信息容易被稀释;如果分块过小,语义又不完整。
而知识图谱擅长的恰好是:
- 实体/事件/关系的结构化表示(谁在什么事件中做了什么)
- '章回定位'类问题可以走更确定的路径:通过
Event/Character -> APPEARS_IN -> Chapter精准落到具体章回
最终选择:
- RAG 负责'文本证据'与'长上下文生成'
- KG 负责'结构化召回、强约束定位',二者组合形成 KAG。
2. 本文工程结构:5 个测试类 + 1 个评测集
这套闭环全部以 JUnit 测试类的形式提供,方便在工程里反复迭代。
2.1 评测集
doc/eval/sanguo-kg-eval.json数据结构:query:问题answers[]:标准答案集合chapterTitle:期望命中的章回标题accept[]:可接受关键词(用于判定命中)
2.2 抽取:LlmKgExtractTest
- 输入:
doc/aigc_chunk_store_to_graph.csv - 输出:
doc/kg_extract_result.json做的事: - 逐行读取 CSV(每行本质是一段'章回文本')
- 调用 LLM 抽取:
Character/Location/Event/Item- 关系
relations[{type, head, tail}](这里已要求 LLM 输出中文关系短语)
- 附带写入章回元信息:
documentName/chapterTitle/chapterIndex/text
2.3 入库:KgNeo4jImportTest
- 输入:
doc/kg_extract_result.json - 输出:Neo4j 图数据库 核心写入逻辑:
- 创建
(:Chapter {chapterKey})作为'章回锚点' - 创建实体节点:
:Character|:Event|:Location|:Item {name} - 把实体与章回相连:
(n)-[:APPEARS_IN]->(c:Chapter)
APPEARS_IN 的含义:实体/事件出现在某章回。这个关系非常关键,它把'结构化实体世界'挂回到'可以回答问题的章回证据'。
2.4 schema 获取:Neo4jSchemaIntrospectTest
LLM 要生成靠谱的 Cypher,必须知道图谱里有哪些 label、有哪些关系类型、每个 label 的关键属性是什么。所以用 CALL db.labels() / CALL db.relationshipTypes() 做了 schema 探测。

