Home

LightRAG完全指南:最简单的本地化RAG系统构建教程 [2024年最新]

· 11 min read
img of LightRAG完全指南:最简单的本地化RAG系统构建教程 [2024年最新]

LightRAG: 轻量级检索增强生成系统

在当前大语言模型(LLM)蓬勃发展的时代,如何让LLM更好地利用外部知识成为一个关键问题。检索增强生成(RAG)技术通过在生成过程中引入相关知识来提升模型表现,但传统RAG系统往往较为复杂且资源需求高。

香港大学数据科学实验室开发的LightRAG系统提供了一个轻量级的解决方案。它巧妙地结合了知识图谱和向量检索,不仅能高效处理文本知识,还能捕捉知识之间的结构化关系。

为什么选择LightRAG?

在众多RAG系统中,LightRAG具有以下突出优势:

  1. 轻量级设计:

    • 最小化依赖,快速部署
    • 支持增量更新,无需重建索引
    • 内存占用低,适合个人开发者
  2. 双重检索机制:

    • 向量检索捕捉语义相似性
    • 图检索发现知识关联关系
    • 智能融合两种检索结果
  3. 灵活的模型支持:

    • 支持主流LLM(OpenAI、HuggingFace等)
    • 可使用开源嵌入模型
    • 支持自定义检索策略

快速上手

1. 安装配置

推荐使用pip直接安装:

    pip install lightrag-hku  

2. 基础使用示例

让我们通过一个实际例子来了解LightRAG的使用流程:

    import os
from lightrag import LightRAG, QueryParam
from lightrag.llm import gpt_4o_mini_complete

# 创建工作目录
WORKING_DIR = "./my_rag_project"
os.makedirs(WORKING_DIR, exist_ok=True)

# 初始化LightRAG
rag = LightRAG(
    working_dir=WORKING_DIR,
    llm_model_func=gpt_4o_mini_complete
)

# 准备示例文档
documents = [
    "人工智能(AI)是计算机科学的一个分支,致力于开发能模拟人类智能的系统。",
    "机器学习是AI的核心技术之一,它使计算机能够从数据中学习和改进。",
    "深度学习是机器学习的一个子领域,使用多层神经网络处理复杂问题。"
]

# 插入文档
rag.insert(documents)

# 进行查询测试
query = "请解释AI、机器学习和深度学习之间的关系"
result = rag.query(query, param=QueryParam(mode="hybrid"))
print(result)  

3. 进阶使用技巧

使用Ollama模型

如果您想使用开源的Ollama模型,可以按照以下方式配置:

    import os
import logging
from lightrag import LightRAG, QueryParam
from lightrag.llm import ollama_model_complete, ollama_embedding
from lightrag.utils import EmbeddingFunc

# 设置日志级别
logging.basicConfig(format="%(levelname)s:%(message)s", level=logging.INFO)

# 创建工作目录
WORKING_DIR = "./my_rag_project"
os.makedirs(WORKING_DIR, exist_ok=True)

# 初始化LightRAG,使用Ollama模型
rag = LightRAG(
    working_dir=WORKING_DIR,
    llm_model_func=ollama_model_complete,
    llm_model_name="gemma2:2b",  # 使用Gemma 2B模型
    llm_model_max_async=4,  # 最大并发请求数
    llm_model_max_token_size=32768,
    llm_model_kwargs={
        "host": "http://localhost:11434",  # Ollama服务地址
        "options": {"num_ctx": 32768}  # 上下文窗口大小
    },
    embedding_func=EmbeddingFunc(
        embedding_dim=768,
        max_token_size=8192,
        func=lambda texts: ollama_embedding(
            texts, 
            embed_model="nomic-embed-text",  # 使用nomic-embed-text作为嵌入模型
            host="http://localhost:11434"
        ),
    ),
)

# 插入文档并进行查询
documents = [
    "人工智能(AI)是计算机科学的一个分支,致力于开发能模拟人类智能的系统。",
    "机器学习是AI的核心技术之一,它使计算机能够从数中学习和改进。",
    "深度学习是机器学习的一个子领域,使用多层神经网络处理复杂问题。"
]

# 插入文档
rag.insert(documents)

# 使用不同的检索模式进行查询
modes = ["naive", "local", "global", "hybrid"]
query = "请解释AI、机器学习和深度学习之间的关系"

for mode in modes:
    print(f"\n使用{mode}模式的查询结果:")
    result = rag.query(query, param=QueryParam(mode=mode))
    print(result)  

使用Ollama模型的主要优势:

  • 完全开源,可本地部署
  • 支持多种开源模型
  • 可自定义模型参数
  • 无需API密钥

注意: 使用Ollama模型前需要先安装并启动Ollama服务。详细安装说明请参考Ollama官方文档

优化检索效果

LightRAG提供了多种检索模式,建议根据不同场景选择:

  • naive: 适合简单问答
  • local: 适合上下文相关的问题
  • global: 适合需要全局知识的问题
  • hybrid: 综合以上优点,是默认推荐模式
    # 示例:针对不同问题类型使用不同检索模式
# 简单事实查询
fact_query = "什么是机器学习?"
print(rag.query(fact_query, param=QueryParam(mode="naive")))

# 需要上下文的问题
context_query = "为什么说深度学习是机器学习的子领域?"
print(rag.query(context_query, param=QueryParam(mode="local")))

# 需要关联多个知识点的问题
complex_query = "AI技术的发展历程是怎样的?"
print(rag.query(complex_query, param=QueryParam(mode="hybrid")))  

自定义知识图谱

LightRAG允许您导入自定义知识图谱,这对于专业领域知识特别有用:

    # 构建领域知识图谱
domain_kg = {
    "entities": [
        {
            "entity_name": "机器学习",
            "entity_type": "技术",
            "description": "让计算机从数据中学习的方法",
            "source_id": "tech_doc_1"
        },
        {
            "entity_name": "神经网络",
            "entity_type": "模型",
            "description": "模拟人脑结构的数学模型",
            "source_id": "tech_doc_2"
        }
    ],
    "relationships": [
        {
            "src_id": "机器学习",
            "tgt_id": "神经网络",
            "description": "包含关系",
            "keywords": "核心技术,基础模型",
            "weight": 1.0,
            "source_id": "tech_doc_1"
        }
    ]
}

# 导入知识图谱
rag.insert_custom_kg(domain_kg)  

删除实体

LightRAG支持通过实体名称删除知识库中的实体:

    # 初始化LightRAG实例
rag = LightRAG(
    working_dir=WORKING_DIR,
    llm_model_func=gpt_4o_mini_complete
)

# 删除指定实体
rag.delete_by_entity("要删除的实体名称")  

这个功能在以下场景特别有用:

  • 删除过时的知识
  • 纠正错误信息
  • 维护知识库的准确性

多文件类型支持

LightRAG通过集成 textract 库支持多种文件格式的处理:

    import textract
from lightrag import LightRAG

# 初始化LightRAG
rag = LightRAG(
    working_dir=WORKING_DIR,
    llm_model_func=gpt_4o_mini_complete
)

# 支持的文件类型示例
file_types = {
    'PDF': 'document.pdf',
    'Word': 'document.docx',
    'PowerPoint': 'presentation.pptx',
    'CSV': 'data.csv'
}

# 处理不同类型的文件
for file_type, file_path in file_types.items():
    try:
        # 使用textract提取文本内容
        text_content = textract.process(file_path)
        
        # 将二进制内容转换为字符串并插入到LightRAG
        rag.insert(text_content.decode('utf-8'))
        print(f"成功处理{file_type}文件: {file_path}")
    except Exception as e:
        print(f"处理{file_type}文件时出错: {e}")  

textract支持的主要文件格式包括:

  • PDF文档 (.pdf)
  • Word文档 (.doc, .docx)
  • PowerPoint演示文稿 (.ppt, .pptx)
  • Excel表格 (.xls, .xlsx)
  • CSV文件 (.csv)
  • 纯文本文件 (.txt)
  • RTF文档 (.rtf)

注意: 使用textract前要安装相应的依赖。在某些系统上可能需要安装额外的系统库来支持特定的文件格式。

4. 性能优化建议

  1. 文档预处理:

    • 将长文档适当分块
    • 保持每块文本的完整性
    • 去除无关的格式信息
  2. 检索参数调优:

    • 调整top_k参数控制检索数量
    • 根据实际需求平衡精确度和速度
    • 适当设置相似度阈值
  3. 系统配置:

    • 选择合适的嵌入模型
    • 根据数据规模调整缓存大小
    • 定期清理无用的索引数据

5. 知识图谱可视化

LightRAG支持将知识图谱导出为可交互的HTML页面或导入到Neo4j数据库中进行分析。

HTML可视化

使用pyvis库可以生成一个交互式的知识图谱可视化页面:

    import networkx as nx
from pyvis.network import Network
import random

# 从GraphML文件加载图谱
G = nx.read_graphml("./my_rag_project/graph_chunk_entity_relation.graphml")

# 创建Pyvis网络图
net = Network(height="100vh", notebook=True)

# 将NetworkX图转换为Pyvis网络
net.from_nx(G)

# 为节点添加随机颜色
for node in net.nodes:
    node["color"] = "#{:06x}".format(random.randint(0, 0xFFFFFF))

# 保存为HTML文件
net.show("knowledge_graph.html")  

导出到Neo4j

您还可以将知识图谱导出到Neo4j图数据库中进行更深入的分析:

    import os
from neo4j import GraphDatabase
from lightrag.utils import xml_to_json

# Neo4j连接配置
NEO4J_URI = "bolt://localhost:7687"
NEO4J_USERNAME = "neo4j"
NEO4J_PASSWORD = "your_password"

# 批量处理参数
BATCH_SIZE_NODES = 500
BATCH_SIZE_EDGES = 100

def export_to_neo4j():
    # 转换GraphML为JSON格式
    xml_file = "./my_rag_project/graph_chunk_entity_relation.graphml"
    json_data = xml_to_json(xml_file)
    
    if not json_data:
        return
    
    # 获取节点和边数据
    nodes = json_data.get("nodes", [])
    edges = json_data.get("edges", [])
    
    # 创建Neo4j驱动
    driver = GraphDatabase.driver(
        NEO4J_URI, 
        auth=(NEO4J_USERNAME, NEO4J_PASSWORD)
    )
    
    try:
        with driver.session() as session:
            # 批量创建节点
            session.execute_write(
                lambda tx: tx.run("""
                    UNWIND $nodes AS node
                    MERGE (e:Entity {id: node.id})
                    SET e.entity_type = node.entity_type,
                        e.description = node.description,
                        e.source_id = node.source_id,
                        e.displayName = node.id
                    WITH e, node
                    CALL apoc.create.addLabels(e, [node.entity_type]) 
                    YIELD node AS labeledNode
                    RETURN count(*)
                """, {"nodes": nodes[:BATCH_SIZE_NODES]})
            )
            
            # 批量创建关系
            session.execute_write(
                lambda tx: tx.run("""
                    UNWIND $edges AS edge
                    MATCH (source {id: edge.source})
                    MATCH (target {id: edge.target})
                    WITH source, target, edge,
                    CASE
                        WHEN edge.keywords CONTAINS 'lead' THEN 'lead'
                        WHEN edge.keywords CONTAINS 'participate' THEN 'participate'
                        WHEN edge.keywords CONTAINS 'uses' THEN 'uses'
                        ELSE SPLIT(edge.keywords, ',')[0]
                    END AS relType
                    CALL apoc.create.relationship(source, relType, {
                        weight: edge.weight,
                        description: edge.description,
                        keywords: edge.keywords,
                        source_id: edge.source_id
                    }, target) YIELD rel
                    RETURN count(*)
                """, {"edges": edges[:BATCH_SIZE_EDGES]})
            )
            
    finally:
        driver.close()

if __name__ == "__main__":
    export_to_neo4j()  

实际应用案例

LightRAG在多个领域都展现出了优秀的表现:

  1. 客服问答系统:

    • 快速响应用户询问
    • 准确提取产品知识
    • 支持多轮对话
  2. 文档检索系统:

    • 智能总结长文档
    • 跨文档知识关联
    • 精准定位关键信息
  3. 知识库管理:

    • 自动构建知识图谱
    • 发现知识关联
    • 支持知识更新

参考资源

相关文章

There are no related posts yet. 😢