LightRAG 的 Java 工程化重生:香港大学图增强 RAG 骨架 × Elasticsearch 语义搜索血肉
这不是简单的 Java 移植,而是两个顶尖开源项目架构理念的深度化学反应。
本项目是 香港大学 LightRAG 与 Elasticsearch 语义搜索体系 的工程化融合产物。
- LightRAG 提供了「图增强文本索引 + 双层检索范式」的骨架,解决了传统 RAG "知识碎片化、缺乏全局关联" 的痛点
- Elasticsearch 语义搜索 提供了「HNSW 近似最近邻 + 混合检索 + RRF 排名融合 + 自动向量化」的工程血肉,解决了图检索在 "语义模糊匹配、高维向量召回、多路结果融合" 上的短板
两者的结合逻辑:
LightRAG 的图结构负责 "理解知识关联"(实体-关系-社区),ES 语义搜索负责 "高效模糊召回"(向量相似度-语义鸿沟-混合排名)。图给向量以结构,向量给图以语义广度。
┌─────────────────────────────────────────────────────────────────────────────┐
│ LightRAG4j 融合架构 │
├──────────────────────────────┬──────────────────────────────────────────────┤
│ LightRAG 骨架(港大) │ ES 语义血肉(Elastic) │
├──────────────────────────────┼──────────────────────────────────────────────┤
│ 图增强文本索引 │ dense_vector + HNSW 近似最近邻索引 │
│ 双层检索(低级/高级) │ hybrid search:kNN + BM25 混合召回 │
│ 实体-关系提取与去重 │ RRF(Reciprocal Rank Fusion)排名融合 │
│ 增量知识库更新 │ semantic_text 自动分块与增量索引思想 │
│ 检索增强答案生成 │ Query Vector Builder 查询端自动向量化 │
└──────────────────────────────┴──────────────────────────────────────────────┘
↓
Java 25 + Spring Boot 4.0.6
↓
Neo4j(图存储) + Qdrant(向量存储)
LightRAG 的核心创新是将文档切分后,通过 LLM 提取 实体(节点) 和 关系(边) 构建知识图谱:
文档 → 分块 → LLM提取实体/关系 → 图结构(Neo4j)
ES 语义的补强:传统 LightRAG 的图索引依赖精确实体匹配,对 "同义不同词" 的召回能力有限。本项目借鉴 ES semantic_text 的自动向量化思想,为每个实体、关系和文本块生成 Embedding,存入 Qdrant 的 HNSW 索引,使图节点具备 语义模糊匹配 能力。
| 层级 | LightRAG 贡献 | ES 语义搜索贡献 | 融合效果 |
|---|---|---|---|
| 低级检索 | 针对具体实体的精确图遍历 | knn query + HNSW 向量召回 |
实体既可通过图邻居扩展,又可通过向量语义相似度召回 |
| 高级检索 | 针对抽象主题的全局关系聚合 | semantic query + 语义匹配 |
主题聚合具备语义模糊匹配能力,不再依赖精确关键词 |
| 结果融合 | 简单合并实体与关系结果 | RRF 排名融合:按排名位置加权,消除向量分数与文本分数的量纲差异 | 多路召回结果科学融合,头部文档优势明显 |
融合后的检索流程:
- 查询关键词提取(LightRAG):LLM 提取
low_level_keywords+high_level_keywords - 多路向量召回(ES 语义):通过 Qdrant HNSW 索引进行近似最近邻搜索,召回 TopK 实体与关系
- 邻居扩展(LightRAG):收集检索节点的局部子图邻居,增强上下文
- RRF 融合(ES 语义):对多路召回结果按排名位置进行 Reciprocal Rank Fusion,生成统一排序
借鉴 ES Hybrid Search 的核心思想——"向量检索擅长语义匹配但不擅长精确匹配,BM25 擅长精确匹配但不理解同义词":
- 向量路(ES):通过 Qdrant 的 HNSW 索引,召回与查询语义相近的实体/关系(解决 "footwear ≈ 跑鞋" 的语义鸿沟)
- 图路(LightRAG):通过 Neo4j 的 Cypher 图遍历,召回与已知实体直接关联的邻居节点(解决 "多跳推理" 和 "结构化关联")
- 融合层(ES):RRF 公式
score = Σ 1/(k + rank_i)将两路结果融合,既保证语义相关性,又保证结构完整性
LightRAG 的增量更新机制:新文档提取的图与旧图取并集,无需重建。本项目进一步借鉴 ES semantic_text 的 自动分块(Chunking) 机制:
- 长文本按模型 token 限制自动切分,保证上下文连贯
- 每个 chunk 独立生成 Embedding,避免 "5000字论文中只有1段相关,但整体向量被稀释" 的问题
- 增量写入时,新 chunk 的向量直接追加到 Qdrant 集合, Neo4j 中的图节点通过
MERGE去重合并
| 层级 | 选型 | 来源/灵感 |
|---|---|---|
| 语言框架 | Java 25 + Spring Boot 4.0.6 + Maven | 工程化落地 |
| 图存储 | Neo4j 5.x(需 APOC 插件) | LightRAG 的图结构存储 |
| 向量存储 | Qdrant(REST API) | 替代 ES 的 dense_vector,保留 HNSW 语义检索能力 |
| 近似索引 | HNSW(Qdrant 内置) | ES 语义搜索的核心索引算法 |
| Embedding | OpenAI-compatible API(SiliconFlow) | ES text_embedding 任务类型的外部化实现 |
| 混合检索 | 自定义 RRF 融合层 | ES 8.8+ retriever: { rrf: ... } 的 Java 实现 |
| 序列化 | Jackson 3.x | 工程规范 |
| 依赖注入 | Lombok @RequiredArgsConstructor + final |
工程规范 |
# 启动 Neo4j(图存储) + Qdrant(向量存储)
docker-compose up -d- Neo4j:
bolt://localhost:7687(默认:neo4j/lightrag) - Qdrant:
http://localhost:6333
# 编译
mvn clean compile
# 运行单元测试(纯单元测试无需外部服务)
mvn clean test -Dtest=LightRAGServiceChunkTest
# 启动应用(:8080)
mvn spring-boot:run| 方法 | 路径 | 说明 |
|---|---|---|
POST |
/api/v1/rag/import |
文件导入(multipart,参数:chunkSize, overlapRatio) |
POST |
/api/v1/rag/query |
智能问答(Body: {"query": "..."}) |
POST |
/api/v1/rag/retrieve |
检索调试(返回实体/关系/文本块,用于观察双层检索过程) |
用户上传文件
↓
LightRAG: 文档分块(chunkDocument)
↓
LightRAG: LLM 并行提取实体 + 关系(GraphIndexer.index)
↓
┌─────────────────────────────────────────┐
│ 双写存储层: │
│ • Neo4j: MERGE 实体/关系节点(图骨架) │ ← LightRAG 图索引
│ • Qdrant: HNSW 索引 Embedding(语义血肉) │ ← ES 语义搜索原理
└─────────────────────────────────────────┘
↓
ES 式自动分块:长文本按 token 限制切分,重叠保证上下文
↓
增量更新完成(无需重建全量索引)
用户查询
↓
LightRAG: LLM 提取 low_level + high_level 关键词
↓
┌─────────────────────────────────────────────┐
│ 多路召回(ES 语义搜索思想): │
│ 路1: Qdrant kNN 向量检索(HNSW 近似最近邻) │ ← ES 语义召回
│ 路2: Neo4j 图遍历(邻居扩展) │ ← LightRAG 关联召回
└─────────────────────────────────────────────┘
↓
ES 式 RRF 融合:按排名位置加权,消除量纲差异
↓
LightRAG: 多源文本(实体描述 + 关系描述 + 原始文本)构建上下文
↓
LLM 生成答案(AnswerGenerator.generate)
↓
返回用户
com.github.lightrag
├── controller/LightRAGController REST API 入口(导入/查询/检索)
├── service/LightRAGService 编排层:LightRAG 数据流调度
├── service/FileParser 文件解析(.txt/.md/.doc)
├── core/GraphIndexer LightRAG 图索引:LLM 提取 → 双写存储
├── core/DualLevelRetriever 双层检索:低级(实体向量)+ 高级(关系向量)+ 邻居扩展
├── core/AnswerGenerator 检索增强生成:多源上下文 → LLM 答案
├── llm/LlmClient OpenAI-compatible 客户端(complete + embed)
├── storage/Neo4jGraphStorage LightRAG 图存储:Cypher MERGE 去重
├── storage/QdrantVectorStorage ES 语义向量存储:HNSW 索引 + kNN 检索
├── storage/VectorStorage 向量存储抽象接口
├── prompt/Prompts 提示模板(图构建/关键词提取/答案生成)
├── model/ 数据模型:Entity, Relation, Chunk, Keywords, RetrieveResult...
└── config/AppConfig Spring Bean 配置(Neo4j Driver + VectorStorage + LlmClient)
- 继承:图增强文本索引、双层检索范式、增量更新算法、实体-关系提取与去重逻辑
- 增强:将 LightRAG 的文本匹配升级为 语义向量召回,将简单结果合并升级为 RRF 科学融合
- 转化:将 Python 实验框架转化为 Java + Spring Boot 生产级服务
- 继承:
dense_vector+ HNSW 索引原理、Hybrid Search 多路召回思想、RRF 排名融合算法、semantic_text 自动分块理念 - 适配:由于 ES 为搜索引擎而非 RAG 框架,本项目将 ES 的语义搜索能力 嫁接 到 LightRAG 的图结构之上:
- 用 Qdrant 承担 ES 的
dense_vector+ HNSW 角色 - 用 Neo4j 承担 ES 无法提供的图关联遍历角色
- 用 自定义 RRF 层 实现 ES 8.8+ 的
retriever: { rrf: ... }
- 用 Qdrant 承担 ES 的
- 转化:将 ES 的索引/查询内部机制显式工程化为可独立部署的 Java 模块
本项目架构与实现深度参考了以下资料(详见 .references/ 目录):
- 论文原文:
.references/论文.html—— LightRAG: Simple and Fast Retrieval-Augmented Generation - 中文解析:
.references/LightRAG论文解析.md—— 图索引、双层检索、增量更新、评估实验完整解读 - 架构图示:
.references/Figure*.png—— 框架架构、提示模板、检索生成案例
- 原理详解:
.references/es/ES_SEMANTIC_PRINCIPLES.md—— 从文本向量化到 HNSW 索引到 kNN 检索的完整链路 - 内部实现:
.references/es/es的语义实现.md——semantic_text字段的自动分块、向量化、查询重写机制 - AI 特性:
.references/es/es的ai特性.md—— 推理 API、ELSER、混合检索、RRF、ES|QL AI 命令 - 语义处理示例:
.references/es/es语义处理例子.md - 增强计划:
.references/es/SEMANTIC_ENHANCEMENT_PLAN.md - 余弦语义鸿沟:
.references/es/COSINE_TO_SEMANTIC_GAP.md - 调用链分析:
.references/es/CALL_CHAIN.md
本项目基于研究性质的开源实现,架构设计源自香港大学 LightRAG 与 Elasticsearch 语义搜索体系。感谢 HKUDS 与 Elastic 的开源贡献。
一句话总结:LightRAG4j 是用 Java 重新讲述的一个故事——LightRAG 的图结构让知识有了关联,Elasticsearch 的语义搜索让关联具备了模糊理解的能力。