172 lines
8.3 KiB
Markdown
172 lines
8.3 KiB
Markdown
# 深入浅出 LightRAG:下一代知识图谱增强检索技术详解
|
||
|
||
> 本文档旨在帮助开发者从零理解 RAG 技术演进,掌握 LightRAG 的核心原理与工程实践。
|
||
|
||
## 1. 基础概念篇:从 RAG 说起
|
||
|
||
### 1.1 什么是 RAG?
|
||
|
||
- **核心痛点**:LLM 的幻觉问题与知识滞后性。
|
||
- **解决方案**:检索增强生成 (Retrieval-Augmented Generation)。
|
||
- **类比**:考试时允许“翻书”,而不是纯靠“死记硬背”。
|
||
|
||
### 1.2 为什么需要 LightRAG?
|
||
|
||
- **传统 RAG 的局限**:
|
||
- **碎片化**:只见树木不见森林,难以回答宏观总结类问题(如“文章的主旨是什么?”)。
|
||
- **关联弱**:无法有效处理跨段落、跨文档的逻辑关联。
|
||
- **Graph RAG 的崛起**:引入知识图谱,让 AI 理解实体间的关系。
|
||
- **LightRAG 的定位**:
|
||
- **快而轻**:相比微软 GraphRAG 动辄几小时的索引时间,LightRAG 更加轻量高效。
|
||
- **双流机制**:同时保留“向量检索”(即时性)和“图谱检索”(结构性)。
|
||
|
||
### 1.3 横向对比:LightRAG vs 其他框架
|
||
|
||
| 特性 | Naive RAG (LangChain等) | Microsoft GraphRAG | LightRAG |
|
||
| :--- | :--- | :--- | :--- |
|
||
| **核心机制** | 纯向量相似度 | 社区聚类 + 图谱 | 双层检索 (图+向量) |
|
||
| **索引速度** | 极快 (秒级) | 极慢 (小时级) | 较快 (分钟级) |
|
||
| **查询成本** | 低 | 极高 (大量Token消耗) | 中等 |
|
||
| **适用场景** | 简单事实问答 | 复杂数据集的宏观分析 | 兼顾细节与宏观的通用场景 |
|
||
|
||
---
|
||
|
||
## 2. 核心原理篇:LightRAG 如何工作?
|
||
|
||
### 2.1 架构总览
|
||
|
||
LightRAG 的核心在于它构建了一个**双层索引结构**,既能看清“细节”,又能把握“大局”:
|
||
|
||
```mermaid
|
||
graph TD
|
||
UserQuery[用户查询] --> KW[关键词提取]
|
||
KW -->|High-Level Keywords| Global[全局检索: 关系与宏观主题]
|
||
KW -->|Low-Level Keywords| Local[局部检索: 实体与具体细节]
|
||
UserQuery -->|Vector Search| Naive[向量检索: 文本片段]
|
||
|
||
Global --> Context[上下文融合]
|
||
Local --> Context
|
||
Naive --> Context
|
||
|
||
Context --> LLM[LLM 生成回答]
|
||
```
|
||
|
||
- **Low-Level (低层)**:具体的实体 (Entity) 和 概念 (Concept)。例如:“IPhone 16”、“A18芯片”。
|
||
- **High-Level (高层)**:实体间的关系 (Relation) 和 宽泛的主题。例如:“苹果公司的产品线策略”、“高性能芯片对续航的影响”。
|
||
|
||
### 2.2 数据处理流水线 (Pipeline)
|
||
|
||
从一篇文档变成知识库,需要经历以下步骤:
|
||
|
||
1. **切片 (Chunking)**:
|
||
- 将长文档切分为固定大小的文本块。
|
||
- **默认策略**:LightRAG 默认以 **1200 tokens** 为窗口大小进行切分,重叠 **100 tokens** 以保持上下文连贯性。
|
||
|
||
2. **提取 (Extraction)**:
|
||
- 利用 LLM 并行分析每个 Chunk。
|
||
- **提取目标**:
|
||
- **实体 (Entities)**:人名、地名、专有名词。
|
||
- **关系 (Relations)**:实体A <-> 关系描述 <-> 实体B。
|
||
- *Prompt 优化点*:针对中文环境,我们去除了原版 Prompt 中的 `{language}` 变量依赖,强制 LLM 输出与 Query 同语言的关键词,避免了“中文问->英文搜”的错位。
|
||
|
||
3. **存储 (Storage)**:
|
||
- **向量库 (VectorDB)**:存储文本块 (Chunks) 的 Embedding 向量,用于相似度检索。
|
||
- **图数据库 (GraphDB)**:存储节点 (实体) 和边 (关系),构建知识网络。
|
||
- **键值库 (KV Store)**:存储原始文本内容,用于最后生成答案时的上下文回填。
|
||
|
||
### 2.3 检索模式 (Mode) 详解
|
||
|
||
LightRAG 支持以下 6 种检索模式(参考 `base.py` 定义):
|
||
|
||
1. **Local Mode (局部模式)**
|
||
- **原理**:基于 `Low-level Keywords` (实体) 在图谱中寻找一跳邻居 (1-hop neighbors)。
|
||
- **场景**:侧重实体细节。例如:“张三的职位是什么?”
|
||
2. **Global Mode (全局模式)**
|
||
- **原理**:基于 `High-level Keywords` (关系) 在图谱中寻找全局关系路径。
|
||
- **场景**:侧重宏观关系。例如:“这家公司的管理层结构是怎样的?”
|
||
3. **Hybrid Mode (混合模式)**
|
||
- **原理**:`Local` + `Global` 的结合。同时关注细节和宏观。
|
||
- **场景**:通用场景,效果最均衡。
|
||
4. **Naive Mode (朴素模式)**
|
||
- **原理**:纯向量检索 (Vector Only)。不提取关键词,直接拿 Query 向量去撞库。
|
||
- **场景**:简单事实匹配,或者图谱尚未构建完成时。
|
||
5. **Mix Mode (融合模式)** [默认]
|
||
- **原理**:**Hybrid (图谱)** + **Naive (向量)** 的大融合。
|
||
- **特点**:最全面的上下文覆盖,但也最消耗 Token。
|
||
6. **Bypass Mode (直通模式)**
|
||
- **原理**:完全跳过 RAG 检索,直接将 Query 发送给 LLM。
|
||
- **场景**:闲聊、打招呼,或者不需要知识库的通用问题。
|
||
|
||
---
|
||
|
||
## 3. 工程实现篇:代码与细节
|
||
|
||
### 3.1 核心类解析 (伪代码)
|
||
|
||
```python
|
||
class LightRAG:
|
||
def insert(self, text):
|
||
# 1. 切分文本 -> chunks (默认 1200 tokens)
|
||
chunks = split_text(text, chunk_size=1200)
|
||
|
||
# 2. 并行调用 LLM 提取 (Entity, Relation)
|
||
# 这里使用 LLM (如 DeepSeek) 进行实体抽取
|
||
entities, relations = llm_extract(chunks)
|
||
|
||
# 3. 更新 Graph 和 VectorDB
|
||
graph.add_nodes(entities)
|
||
graph.add_edges(relations)
|
||
vector_db.add(chunks)
|
||
pass
|
||
|
||
def query(self, question, mode="hybrid"):
|
||
# 1. 预处理
|
||
# - bypass: 直接 return llm(question)
|
||
# - naive: 直接 vector_search(question)
|
||
|
||
# 2. 关键词提取 (Local/Global/Hybrid/Mix)
|
||
# 调用 LLM 分析 Query,提取关键词
|
||
# extract_keywords(question) -> {high_level, low_level}
|
||
|
||
# 3. 根据 mode 选择检索策略
|
||
# - local: graph.get_neighbors(low_level_keywords)
|
||
# - global: graph.traverse(high_level_keywords)
|
||
# - hybrid: local + global
|
||
# - mix: knowledge_graph + vector_retrieval
|
||
|
||
# 4. 收集 Context 并生成答案
|
||
# 将检索到的所有 Context 拼接到 System Prompt 中
|
||
# 调用 LLM 生成最终回答
|
||
pass
|
||
```
|
||
|
||
### 3.2 存储文件详解 (index_data)
|
||
|
||
在 `index_data` 目录下,你会看到以下核心文件,它们共同构成了 LightRAG 的“大脑”:
|
||
|
||
| 文件名 | 类型 | 用途 |
|
||
| :--- | :--- | :--- |
|
||
| `kv_store_text_chunks.json` | KV Store | **原始切片**。存储被切分后的文本块原始内容。 |
|
||
| `kv_store_full_docs.json` | KV Store | **完整文档**。存储上传的原始文档内容。 |
|
||
| `graph_chunk_entity_relation.graphml` | Graph | **知识图谱**。使用 NetworkX 格式存储实体(点)和关系(边)的拓扑结构。 |
|
||
| `vdb_entities.json` | Vector | **实体向量**。用于通过向量相似度查找相关实体。 |
|
||
| `vdb_chunks.json` | Vector | **切片向量**。用于 Naive 模式下的文本相似度检索。 |
|
||
| `vdb_relationships.json` | Vector | **关系向量**。用于查找相关的关系描述。 |
|
||
| `lightrag_cache.json` | Cache | **LLM 缓存**。存储 LLM 的历史响应,避免对相同问题重复调用 API (省钱神器)。 |
|
||
|
||
### 3.3 性能优化策略
|
||
|
||
- **异步并发**:LightRAG 内部大量使用 `async/await`,特别是在实体提取阶段,会并发请求 LLM,极大缩短索引时间。
|
||
- **缓存机制**:`lightrag_cache.json` 实现了请求级缓存。如果你的 Prompt 和输入没变,它会直接返回历史结果,0 延迟,0 成本。
|
||
- **增量更新**:RAG 不支持直接“修改”文档。我们的策略是 `Delete-then-Insert`(先删后加),确保图谱结构的原子性更新。
|
||
|
||
---
|
||
|
||
## 4. 实战指南:注意事项
|
||
|
||
- **LLM 选择**:LightRAG 强依赖 LLM 的指令遵循能力(用于提取实体)。推荐使用 **DeepSeek-V3**、**Qwen-2.5** 等强力模型,小模型(<7B)可能会导致提取失败。
|
||
- **成本控制**:
|
||
- **索引成本**:较高。因为要对全文做精细的实体提取。
|
||
- **查询成本**:中等。Hybrid 模式下,Context 长度可能会较长,注意控制 `top_k` 参数。
|
||
- **部署建议**:推荐使用 Docker 部署,屏蔽环境差异。API 服务已封装了队列机制,但底层写操作(索引)是单线程锁定的,**请勿多实例挂载同一目录并发写入**。
|