diff --git a/README-zh.md b/README-zh.md index e69de29b..aad05ae7 100644 --- a/README-zh.md +++ b/README-zh.md @@ -0,0 +1,1380 @@ +# LightRAG: Simple and Fast Retrieval-Augmented Generation + + + +## 🎉 新闻 + +- [X] [2025.03.18]🎯📢LightRAG现已支持引文功能。 +- [X] [2025.02.05]🎯📢我们团队发布了[VideoRAG](https://github.com/HKUDS/VideoRAG),用于理解超长上下文视频。 +- [X] [2025.01.13]🎯📢我们团队发布了[MiniRAG](https://github.com/HKUDS/MiniRAG),使用小型模型简化RAG。 +- [X] [2025.01.06]🎯📢现在您可以[使用PostgreSQL进行存储](#using-postgresql-for-storage)。 +- [X] [2024.12.31]🎯📢LightRAG现在支持[通过文档ID删除](https://github.com/HKUDS/LightRAG?tab=readme-ov-file#delete)。 +- [X] [2024.11.25]🎯📢LightRAG现在支持无缝集成[自定义知识图谱](https://github.com/HKUDS/LightRAG?tab=readme-ov-file#insert-custom-kg),使用户能够用自己的领域专业知识增强系统。 +- [X] [2024.11.19]🎯📢LightRAG的综合指南现已在[LearnOpenCV](https://learnopencv.com/lightrag)上发布。非常感谢博客作者。 +- [X] [2024.11.12]🎯📢LightRAG现在支持[Oracle Database 23ai的所有存储类型(KV、向量和图)](https://github.com/HKUDS/LightRAG/blob/main/examples/lightrag_oracle_demo.py)。 +- [X] [2024.11.11]🎯📢LightRAG现在支持[通过实体名称删除实体](https://github.com/HKUDS/LightRAG?tab=readme-ov-file#delete)。 +- [X] [2024.11.09]🎯📢推出[LightRAG Gui](https://lightrag-gui.streamlit.app),允许您插入、查询、可视化和下载LightRAG知识。 +- [X] [2024.11.04]🎯📢现在您可以[使用Neo4J进行存储](https://github.com/HKUDS/LightRAG?tab=readme-ov-file#using-neo4j-for-storage)。 +- [X] [2024.10.29]🎯📢LightRAG现在通过`textract`支持多种文件类型,包括PDF、DOC、PPT和CSV。 +- [X] [2024.10.20]🎯📢我们为LightRAG添加了一个新功能:图形可视化。 +- [X] [2024.10.18]🎯📢我们添加了[LightRAG介绍视频](https://youtu.be/oageL-1I0GE)的链接。感谢作者! +- [X] [2024.10.17]🎯📢我们创建了一个[Discord频道](https://discord.gg/yF2MmDJyGJ)!欢迎加入分享和讨论!🎉🎉 +- [X] [2024.10.16]🎯📢LightRAG现在支持[Ollama模型](https://github.com/HKUDS/LightRAG?tab=readme-ov-file#quick-start)! +- [X] [2024.10.15]🎯📢LightRAG现在支持[Hugging Face模型](https://github.com/HKUDS/LightRAG?tab=readme-ov-file#quick-start)! + + + + 算法流程图 + + + +*图1:LightRAG索引流程图 - 图片来源:[Source](https://learnopencv.com/lightrag/)* + +*图2:LightRAG检索和查询流程图 - 图片来源:[Source](https://learnopencv.com/lightrag/)* + + + +## 安装 + +### 安装LightRAG核心 + +* 从源代码安装(推荐) + +```bash +cd LightRAG +pip install -e . +``` + +* 从PyPI安装 + +```bash +pip install lightrag-hku +``` + +### 安装LightRAG服务器 + +LightRAG服务器旨在提供Web UI和API支持。Web UI便于文档索引、知识图谱探索和简单的RAG查询界面。LightRAG服务器还提供兼容Ollama的接口,旨在将LightRAG模拟为Ollama聊天模型。这使得AI聊天机器人(如Open WebUI)可以轻松访问LightRAG。 + +* 从PyPI安装 + +```bash +pip install "lightrag-hku[api]" +``` + +* 从源代码安装 + +```bash +# 如有必要,创建Python虚拟环境 +# 以可编辑模式安装并支持API +pip install -e ".[api]" +``` + +**有关LightRAG服务器的更多信息,请参阅[LightRAG服务器](./lightrag/api/README.md)。** + +## 快速开始 + +* [视频演示](https://www.youtube.com/watch?v=g21royNJ4fw)展示如何在本地运行LightRAG。 +* 所有代码都可以在`examples`中找到。 +* 如果使用OpenAI模型,请在环境中设置OpenAI API密钥:`export OPENAI_API_KEY="sk-..."`。 +* 下载演示文本"狄更斯的圣诞颂歌": + +```bash +curl https://raw.githubusercontent.com/gusye1234/nano-graphrag/main/tests/mock_data.txt > ./book.txt +``` + +## 查询 + +使用以下Python代码片段(在脚本中)初始化LightRAG并执行查询: + +```python +import os +import asyncio +from lightrag import LightRAG, QueryParam +from lightrag.llm.openai import gpt_4o_mini_complete, gpt_4o_complete, openai_embed +from lightrag.kg.shared_storage import initialize_pipeline_status +from lightrag.utils import setup_logger + +setup_logger("lightrag", level="INFO") + +async def initialize_rag(): + rag = LightRAG( + working_dir="your/path", + embedding_func=openai_embed, + llm_model_func=gpt_4o_mini_complete + ) + + await rag.initialize_storages() + await initialize_pipeline_status() + + return rag + +def main(): + # 初始化RAG实例 + rag = asyncio.run(initialize_rag()) + # 插入文本 + rag.insert("Your text") + + # 执行朴素搜索 + mode="naive" + # 执行本地搜索 + mode="local" + # 执行全局搜索 + mode="global" + # 执行混合搜索 + mode="hybrid" + # 混合模式集成知识图谱和向量检索 + mode="mix" + + rag.query( + "这个故事的主要主题是什么?", + param=QueryParam(mode=mode) + ) + +if __name__ == "__main__": + main() +``` + +### 查询参数 + +```python +class QueryParam: + mode: Literal["local", "global", "hybrid", "naive", "mix"] = "global" + """指定检索模式: + - "local":专注于上下文相关信息。 + - "global":利用全局知识。 + - "hybrid":结合本地和全局检索方法。 + - "naive":执行基本搜索,不使用高级技术。 + - "mix":集成知识图谱和向量检索。混合模式结合知识图谱和向量搜索: + - 同时使用结构化(KG)和非结构化(向量)信息 + - 通过分析关系和上下文提供全面的答案 + - 通过HTML img标签支持图像内容 + - 允许通过top_k参数控制检索深度 + """ + only_need_context: bool = False + """如果为True,仅返回检索到的上下文而不生成响应。""" + response_type: str = "Multiple Paragraphs" + """定义响应格式。示例:'Multiple Paragraphs'(多段落), 'Single Paragraph'(单段落), 'Bullet Points'(要点列表)。""" + top_k: int = 60 + """要检索的顶部项目数量。在'local'模式下代表实体,在'global'模式下代表关系。""" + max_token_for_text_unit: int = 4000 + """每个检索文本块允许的最大令牌数。""" + max_token_for_global_context: int = 4000 + """全局检索中关系描述的最大令牌分配。""" + max_token_for_local_context: int = 4000 + """本地检索中实体描述的最大令牌分配。""" + ids: list[str] | None = None # 仅支持PG向量数据库 + """用于过滤RAG的ID列表。""" + ... +``` + +> top_k的默认值可以通过环境变量TOP_K更改。 + + + 使用类OpenAI的API + +* LightRAG还支持类OpenAI的聊天/嵌入API: + +```python +async def llm_model_func( + prompt, system_prompt=None, history_messages=[], keyword_extraction=False, **kwargs +) -> str: + return await openai_complete_if_cache( + "solar-mini", + prompt, + system_prompt=system_prompt, + history_messages=history_messages, + api_key=os.getenv("UPSTAGE_API_KEY"), + base_url="https://api.upstage.ai/v1/solar", + **kwargs + ) + +async def embedding_func(texts: list[str]) -> np.ndarray: + return await openai_embed( + texts, + model="solar-embedding-1-large-query", + api_key=os.getenv("UPSTAGE_API_KEY"), + base_url="https://api.upstage.ai/v1/solar" + ) + +async def initialize_rag(): + rag = LightRAG( + working_dir=WORKING_DIR, + llm_model_func=llm_model_func, + embedding_func=EmbeddingFunc( + embedding_dim=4096, + max_token_size=8192, + func=embedding_func + ) + ) + + await rag.initialize_storages() + await initialize_pipeline_status() + + return rag +``` + + + + + 使用Hugging Face模型 + +* 如果您想使用Hugging Face模型,只需要按如下方式设置LightRAG: + +参见`lightrag_hf_demo.py` + +```python +# 使用Hugging Face模型初始化LightRAG +rag = LightRAG( + working_dir=WORKING_DIR, + llm_model_func=hf_model_complete, # 使用Hugging Face模型进行文本生成 + llm_model_name='meta-llama/Llama-3.1-8B-Instruct', # Hugging Face的模型名称 + # 使用Hugging Face嵌入函数 + embedding_func=EmbeddingFunc( + embedding_dim=384, + max_token_size=5000, + func=lambda texts: hf_embed( + texts, + tokenizer=AutoTokenizer.from_pretrained("sentence-transformers/all-MiniLM-L6-v2"), + embed_model=AutoModel.from_pretrained("sentence-transformers/all-MiniLM-L6-v2") + ) + ), +) +``` + + + + + 使用Ollama模型 + +### 概述 + +如果您想使用Ollama模型,您需要拉取计划使用的模型和嵌入模型,例如`nomic-embed-text`。 + +然后您只需要按如下方式设置LightRAG: + +```python +# 使用Ollama模型初始化LightRAG +rag = LightRAG( + working_dir=WORKING_DIR, + llm_model_func=ollama_model_complete, # 使用Ollama模型进行文本生成 + llm_model_name='your_model_name', # 您的模型名称 + # 使用Ollama嵌入函数 + embedding_func=EmbeddingFunc( + embedding_dim=768, + max_token_size=8192, + func=lambda texts: ollama_embed( + texts, + embed_model="nomic-embed-text" + ) + ), +) +``` + +### 增加上下文大小 + +为了使LightRAG正常工作,上下文应至少为32k令牌。默认情况下,Ollama模型的上下文大小为8k。您可以通过以下两种方式之一实现这一点: + +#### 在Modelfile中增加`num_ctx`参数。 + +1. 拉取模型: + +```bash +ollama pull qwen2 +``` + +2. 显示模型文件: + +```bash +ollama show --modelfile qwen2 > Modelfile +``` + +3. 编辑Modelfile,添加以下行: + +```bash +PARAMETER num_ctx 32768 +``` + +4. 创建修改后的模型: + +```bash +ollama create -f Modelfile qwen2m +``` + +#### 通过Ollama API设置`num_ctx`。 + +您可以使用`llm_model_kwargs`参数配置ollama: + +```python +rag = LightRAG( + working_dir=WORKING_DIR, + llm_model_func=ollama_model_complete, # 使用Ollama模型进行文本生成 + llm_model_name='your_model_name', # 您的模型名称 + llm_model_kwargs={"options": {"num_ctx": 32768}}, + # 使用Ollama嵌入函数 + embedding_func=EmbeddingFunc( + embedding_dim=768, + max_token_size=8192, + func=lambda texts: ollama_embedding( + texts, + embed_model="nomic-embed-text" + ) + ), +) +``` + +#### 低RAM GPU + +为了在低RAM GPU上运行此实验,您应该选择小型模型并调整上下文窗口(增加上下文会增加内存消耗)。例如,在6Gb RAM的改装挖矿GPU上运行这个ollama示例需要将上下文大小设置为26k,同时使用`gemma2:2b`。它能够在`book.txt`中找到197个实体和19个关系。 + + + + LlamaIndex + +LightRAG支持与LlamaIndex集成。 + +1. **LlamaIndex** (`llm/llama_index_impl.py`): + - 通过LlamaIndex与OpenAI和其他提供商集成 + - 详细设置和示例请参见[LlamaIndex文档](lightrag/llm/Readme.md) + +### 使用示例 + +```python +# 使用LlamaIndex直接访问OpenAI +import asyncio +from lightrag import LightRAG +from lightrag.llm.llama_index_impl import llama_index_complete_if_cache, llama_index_embed +from llama_index.embeddings.openai import OpenAIEmbedding +from llama_index.llms.openai import OpenAI +from lightrag.kg.shared_storage import initialize_pipeline_status +from lightrag.utils import setup_logger + +# 为LightRAG设置日志处理程序 +setup_logger("lightrag", level="INFO") + +async def initialize_rag(): + rag = LightRAG( + working_dir="your/path", + llm_model_func=llama_index_complete_if_cache, # LlamaIndex兼容的完成函数 + embedding_func=EmbeddingFunc( # LlamaIndex兼容的嵌入函数 + embedding_dim=1536, + max_token_size=8192, + func=lambda texts: llama_index_embed(texts, embed_model=embed_model) + ), + ) + + await rag.initialize_storages() + await initialize_pipeline_status() + + return rag + +def main(): + # 初始化RAG实例 + rag = asyncio.run(initialize_rag()) + + with open("./book.txt", "r", encoding="utf-8") as f: + rag.insert(f.read()) + + # 执行朴素搜索 + print( + rag.query("这个故事的主要主题是什么?", param=QueryParam(mode="naive")) + ) + + # 执行本地搜索 + print( + rag.query("这个故事的主要主题是什么?", param=QueryParam(mode="local")) + ) + + # 执行全局搜索 + print( + rag.query("这个故事的主要主题是什么?", param=QueryParam(mode="global")) + ) + + # 执行混合搜索 + print( + rag.query("这个故事的主要主题是什么?", param=QueryParam(mode="hybrid")) + ) + +if __name__ == "__main__": + main() +``` + +#### 详细文档和示例,请参见: + +- [LlamaIndex文档](lightrag/llm/Readme.md) +- [直接OpenAI示例](examples/lightrag_llamaindex_direct_demo.py) +- [LiteLLM代理示例](examples/lightrag_llamaindex_litellm_demo.py) + + + + 对话历史支持 + +LightRAG现在通过对话历史功能支持多轮对话。以下是使用方法: + +```python +# 创建对话历史 +conversation_history = [ + {"role": "user", "content": "主角对圣诞节的态度是什么?"}, + {"role": "assistant", "content": "在故事开始时,埃比尼泽·斯克鲁奇对圣诞节持非常消极的态度..."}, + {"role": "user", "content": "他的态度是如何改变的?"} +] + +# 创建带有对话历史的查询参数 +query_param = QueryParam( + mode="mix", # 或其他模式:"local"、"global"、"hybrid" + conversation_history=conversation_history, # 添加对话历史 + history_turns=3 # 考虑最近的对话轮数 +) + +# 进行考虑对话历史的查询 +response = rag.query( + "是什么导致了他性格的这种变化?", + param=query_param +) +``` + + + + + 自定义提示支持 + +LightRAG现在支持自定义提示,以便对系统行为进行精细控制。以下是使用方法: + +```python +# 创建查询参数 +query_param = QueryParam( + mode="hybrid", # 或其他模式:"local"、"global"、"hybrid"、"mix"和"naive" +) + +# 示例1:使用默认系统提示 +response_default = rag.query( + "可再生能源的主要好处是什么?", + param=query_param +) +print(response_default) + +# 示例2:使用自定义提示 +custom_prompt = """ +您是环境科学领域的专家助手。请提供详细且结构化的答案,并附带示例。 +---对话历史--- +{history} + +---知识库--- +{context_data} + +---响应规则--- + +- 目标格式和长度:{response_type} +""" +response_custom = rag.query( + "可再生能源的主要好处是什么?", + param=query_param, + system_prompt=custom_prompt # 传递自定义提示 +) +print(response_custom) +``` + + + + + 独立关键词提取 + +我们引入了新函数`query_with_separate_keyword_extraction`来增强关键词提取功能。该函数将关键词提取过程与用户提示分开,专注于查询以提高提取关键词的相关性。 + +##### 工作原理 + +该函数将输入分为两部分: + +- `用户查询` +- `提示` + +然后仅对`用户查询`执行关键词提取。这种分离确保提取过程是集中和相关的,不受`提示`中任何额外语言的影响。它还允许`提示`纯粹用于响应格式化,保持用户原始问题的意图和清晰度。 + +##### 使用示例 + +这个`示例`展示了如何为教育内容定制函数,专注于为高年级学生提供详细解释。 + +```python +rag.query_with_separate_keyword_extraction( + query="解释重力定律", + prompt="提供适合学习物理的高中生的详细解释。", + param=QueryParam(mode="hybrid") +) +``` + + + + + 插入自定义KG + +```python +custom_kg = { + "chunks": [ + { + "content": "Alice和Bob正在合作进行量子计算研究。", + "source_id": "doc-1" + } + ], + "entities": [ + { + "entity_name": "Alice", + "entity_type": "person", + "description": "Alice是一位专门研究量子物理的研究员。", + "source_id": "doc-1" + }, + { + "entity_name": "Bob", + "entity_type": "person", + "description": "Bob是一位数学家。", + "source_id": "doc-1" + }, + { + "entity_name": "量子计算", + "entity_type": "technology", + "description": "量子计算利用量子力学现象进行计算。", + "source_id": "doc-1" + } + ], + "relationships": [ + { + "src_id": "Alice", + "tgt_id": "Bob", + "description": "Alice和Bob是研究伙伴。", + "keywords": "合作 研究", + "weight": 1.0, + "source_id": "doc-1" + }, + { + "src_id": "Alice", + "tgt_id": "量子计算", + "description": "Alice进行量子计算研究。", + "keywords": "研究 专业", + "weight": 1.0, + "source_id": "doc-1" + }, + { + "src_id": "Bob", + "tgt_id": "量子计算", + "description": "Bob研究量子计算。", + "keywords": "研究 应用", + "weight": 1.0, + "source_id": "doc-1" + } + ] +} + +rag.insert_custom_kg(custom_kg) +``` + + + +## 插入 + +#### 基本插入 + +```python +# 基本插入 +rag.insert("文本") +``` + + + 批量插入 + +```python +# 基本批量插入:一次插入多个文本 +rag.insert(["文本1", "文本2",...]) + +# 带有自定义批量大小配置的批量插入 +rag = LightRAG( + working_dir=WORKING_DIR, + addon_params={ + "insert_batch_size": 4 # 每批处理4个文档 + } +) + +rag.insert(["文本1", "文本2", "文本3", ...]) # 文档将以4个为一批进行处理 +``` + +`addon_params`中的`insert_batch_size`参数控制插入过程中每批处理的文档数量。这对于以下情况很有用: + +- 管理大型文档集合的内存使用 +- 优化处理速度 +- 提供更好的进度跟踪 +- 如果未指定,默认值为10 + + + + + 带ID插入 + +如果您想为文档提供自己的ID,文档数量和ID数量必须相同。 + +```python +# 插入单个文本,并为其提供ID +rag.insert("文本1", ids=["文本1的ID"]) + +# 插入多个文本,并为它们提供ID +rag.insert(["文本1", "文本2",...], ids=["文本1的ID", "文本2的ID"]) +``` + + + + + 使用管道插入 + +`apipeline_enqueue_documents`和`apipeline_process_enqueue_documents`函数允许您对文档进行增量插入到图中。 + +这对于需要在后台处理文档的场景很有用,同时仍允许主线程继续执行。 + +并使用例程处理新文档。 + +```python +rag = LightRAG(..) + +await rag.apipeline_enqueue_documents(input) +# 您的循环例程 +await rag.apipeline_process_enqueue_documents(input) +``` + + + + + 插入多文件类型支持 + +`textract`支持读取TXT、DOCX、PPTX、CSV和PDF等文件类型。 + +```python +import textract + +file_path = 'TEXT.pdf' +text_content = textract.process(file_path) + +rag.insert(text_content.decode('utf-8')) +``` + + + + + 引文功能 + +通过提供文件路径,系统确保可以将来源追溯到其原始文档。 + +```python +# 定义文档及其文件路径 +documents = ["文档内容1", "文档内容2"] +file_paths = ["path/to/doc1.txt", "path/to/doc2.txt"] + +# 插入带有文件路径的文档 +rag.insert(documents, file_paths=file_paths) +``` + + + +## 存储 + + + 使用Neo4J进行存储 + +* 对于生产级场景,您很可能想要利用企业级解决方案 +* 进行KG存储。推荐在Docker中运行Neo4J以进行无缝本地测试。 +* 参见:https://hub.docker.com/_/neo4j + +```python +export NEO4J_URI="neo4j://localhost:7687" +export NEO4J_USERNAME="neo4j" +export NEO4J_PASSWORD="password" + +# 为LightRAG设置日志记录器 +setup_logger("lightrag", level="INFO") + +# 当您启动项目时,请确保通过指定kg="Neo4JStorage"来覆盖默认的KG:NetworkX。 + +# 注意:默认设置使用NetworkX +# 使用Neo4J实现初始化LightRAG。 +async def initialize_rag(): + rag = LightRAG( + working_dir=WORKING_DIR, + llm_model_func=gpt_4o_mini_complete, # 使用gpt_4o_mini_complete LLM模型 + graph_storage="Neo4JStorage", #<-----------覆盖KG默认值 + ) + + # 初始化数据库连接 + await rag.initialize_storages() + # 初始化文档处理的管道状态 + await initialize_pipeline_status() + + return rag +``` + +参见test_neo4j.py获取工作示例。 + + + + + 使用Faiss进行存储 + +- 安装所需依赖: + +``` +pip install faiss-cpu +``` + +如果您有GPU支持,也可以安装`faiss-gpu`。 + +- 这里我们使用`sentence-transformers`,但您也可以使用维度为`3072`的`OpenAIEmbedding`模型。 + +```python +async def embedding_func(texts: list[str]) -> np.ndarray: + model = SentenceTransformer('all-MiniLM-L6-v2') + embeddings = model.encode(texts, convert_to_numpy=True) + return embeddings + +# 使用LLM模型函数和嵌入函数初始化LightRAG +rag = LightRAG( + working_dir=WORKING_DIR, + llm_model_func=llm_model_func, + embedding_func=EmbeddingFunc( + embedding_dim=384, + max_token_size=8192, + func=embedding_func, + ), + vector_storage="FaissVectorDBStorage", + vector_db_storage_cls_kwargs={ + "cosine_better_than_threshold": 0.3 # 您期望的阈值 + } +) +``` + + + + + 使用PostgreSQL进行存储 + +对于生产级场景,您很可能想要利用企业级解决方案。PostgreSQL可以为您提供一站式解决方案,作为KV存储、向量数据库(pgvector)和图数据库(apache AGE)。 + +* PostgreSQL很轻量,整个二进制发行版包括所有必要的插件可以压缩到40MB:参考[Windows发布版](https://github.com/ShanGor/apache-age-windows/releases/tag/PG17%2Fv1.5.0-rc0),它在Linux/Mac上也很容易安装。 +* 如果您是初学者并想避免麻烦,推荐使用docker,请从这个镜像开始(请务必阅读概述):https://hub.docker.com/r/shangor/postgres-for-rag +* 如何开始?参考:[examples/lightrag_zhipu_postgres_demo.py](https://github.com/HKUDS/LightRAG/blob/main/examples/lightrag_zhipu_postgres_demo.py) +* 为AGE创建索引示例:(如有必要,将下面的`dickens`改为您的图名) + ```sql + load 'age'; + SET search_path = ag_catalog, "$user", public; + CREATE INDEX CONCURRENTLY entity_p_idx ON dickens."Entity" (id); + CREATE INDEX CONCURRENTLY vertex_p_idx ON dickens."_ag_label_vertex" (id); + CREATE INDEX CONCURRENTLY directed_p_idx ON dickens."DIRECTED" (id); + CREATE INDEX CONCURRENTLY directed_eid_idx ON dickens."DIRECTED" (end_id); + CREATE INDEX CONCURRENTLY directed_sid_idx ON dickens."DIRECTED" (start_id); + CREATE INDEX CONCURRENTLY directed_seid_idx ON dickens."DIRECTED" (start_id,end_id); + CREATE INDEX CONCURRENTLY edge_p_idx ON dickens."_ag_label_edge" (id); + CREATE INDEX CONCURRENTLY edge_sid_idx ON dickens."_ag_label_edge" (start_id); + CREATE INDEX CONCURRENTLY edge_eid_idx ON dickens."_ag_label_edge" (end_id); + CREATE INDEX CONCURRENTLY edge_seid_idx ON dickens."_ag_label_edge" (start_id,end_id); + create INDEX CONCURRENTLY vertex_idx_node_id ON dickens."_ag_label_vertex" (ag_catalog.agtype_access_operator(properties, '"node_id"'::agtype)); + create INDEX CONCURRENTLY entity_idx_node_id ON dickens."Entity" (ag_catalog.agtype_access_operator(properties, '"node_id"'::agtype)); + CREATE INDEX CONCURRENTLY entity_node_id_gin_idx ON dickens."Entity" using gin(properties); + ALTER TABLE dickens."DIRECTED" CLUSTER ON directed_sid_idx; + + -- 如有必要可以删除 + drop INDEX entity_p_idx; + drop INDEX vertex_p_idx; + drop INDEX directed_p_idx; + drop INDEX directed_eid_idx; + drop INDEX directed_sid_idx; + drop INDEX directed_seid_idx; + drop INDEX edge_p_idx; + drop INDEX edge_sid_idx; + drop INDEX edge_eid_idx; + drop INDEX edge_seid_idx; + drop INDEX vertex_idx_node_id; + drop INDEX entity_idx_node_id; + drop INDEX entity_node_id_gin_idx; + ``` +* Apache AGE的已知问题:发布版本存在以下问题: + > 您可能会发现节点/边的属性是空的。 + > 这是发布版本的已知问题:https://github.com/apache/age/pull/1721 + > + > 您可以从源代码编译AGE来修复它。 + > + +## 删除 + +```python +# 删除实体:通过实体名称删除实体 +rag.delete_by_entity("Project Gutenberg") + +# 删除文档:通过文档ID删除与文档相关的实体和关系 +rag.delete_by_doc_id("doc_id") +``` + +## 编辑实体和关系 + +LightRAG现在支持全面的知识图谱管理功能,允许您在知识图谱中创建、编辑和删除实体和关系。 + + + 创建实体和关系 + +```python +# 创建新实体 +entity = rag.create_entity("Google", { + "description": "Google是一家专注于互联网相关服务和产品的跨国科技公司。", + "entity_type": "company" +}) + +# 创建另一个实体 +product = rag.create_entity("Gmail", { + "description": "Gmail是由Google开发的电子邮件服务。", + "entity_type": "product" +}) + +# 创建实体之间的关系 +relation = rag.create_relation("Google", "Gmail", { + "description": "Google开发和运营Gmail。", + "keywords": "开发 运营 服务", + "weight": 2.0 +}) +``` + + + + + 编辑实体和关系 + +```python +# 编辑现有实体 +updated_entity = rag.edit_entity("Google", { + "description": "Google是Alphabet Inc.的子公司,成立于1998年。", + "entity_type": "tech_company" +}) + +# 重命名实体(所有关系都会正确迁移) +renamed_entity = rag.edit_entity("Gmail", { + "entity_name": "Google Mail", + "description": "Google Mail(前身为Gmail)是一项电子邮件服务。" +}) + +# 编辑实体之间的关系 +updated_relation = rag.edit_relation("Google", "Google Mail", { + "description": "Google创建并维护Google Mail服务。", + "keywords": "创建 维护 电子邮件服务", + "weight": 3.0 +}) +``` + + + +所有操作都有同步和异步版本。异步版本带有前缀"a"(例如,`acreate_entity`,`aedit_relation`)。 + +#### 实体操作 + +- **create_entity**:创建具有指定属性的新实体 +- **edit_entity**:更新现有实体的属性或重命名它 + +#### 关系操作 + +- **create_relation**:在现有实体之间创建新关系 +- **edit_relation**:更新现有关系的属性 + +这些操作在图数据库和向量数据库组件之间保持数据一致性,确保您的知识图谱保持连贯。 + +## 数据导出功能 + +## 概述 + +LightRAG允许您以各种格式导出知识图谱数据,用于分析、共享和备份目的。系统支持导出实体、关系和关系数据。 + +## 导出功能 + +### 基本用法 + +```python +# 基本CSV导出(默认格式) +rag.export_data("knowledge_graph.csv") + +# 指定任意格式 +rag.export_data("output.xlsx", file_format="excel") +``` + +### 支持的不同文件格式 + +```python +# 以CSV格式导出数据 +rag.export_data("graph_data.csv", file_format="csv") + +# 导出数据到Excel表格 +rag.export_data("graph_data.xlsx", file_format="excel") + +# 以markdown格式导出数据 +rag.export_data("graph_data.md", file_format="md") + +# 导出数据为文本 +rag.export_data("graph_data.txt", file_format="txt") +``` + +## 附加选项 + +在导出中包含向量嵌入(可选): + +```python +rag.export_data("complete_data.csv", include_vector_data=True) +``` + +## 导出数据包括 + +所有导出包括: + +* 实体信息(名称、ID、元数据) +* 关系数据(实体之间的连接) +* 来自向量数据库的关系信息 + +## 实体合并 + + + 合并实体及其关系 + +LightRAG现在支持将多个实体合并为单个实体,自动处理所有关系: + +```python +# 基本实体合并 +rag.merge_entities( + source_entities=["人工智能", "AI", "机器智能"], + target_entity="AI技术" +) +``` + +使用自定义合并策略: + +```python +# 为不同字段定义自定义合并策略 +rag.merge_entities( + source_entities=["约翰·史密斯", "史密斯博士", "J·史密斯"], + target_entity="约翰·史密斯", + merge_strategy={ + "description": "concatenate", # 组合所有描述 + "entity_type": "keep_first", # 保留第一个实体的类型 + "source_id": "join_unique" # 组合所有唯一的源ID + } +) +``` + +使用自定义目标实体数据: + +```python +# 为合并后的实体指定确切值 +rag.merge_entities( + source_entities=["纽约", "NYC", "大苹果"], + target_entity="纽约市", + target_entity_data={ + "entity_type": "LOCATION", + "description": "纽约市是美国人口最多的城市。", + } +) +``` + +结合两种方法的高级用法: + +```python +# 使用策略和自定义数据合并公司实体 +rag.merge_entities( + source_entities=["微软公司", "Microsoft Corporation", "MSFT"], + target_entity="微软", + merge_strategy={ + "description": "concatenate", # 组合所有描述 + "source_id": "join_unique" # 组合源ID + }, + target_entity_data={ + "entity_type": "ORGANIZATION", + } +) +``` + +合并实体时: + +* 所有来自源实体的关系都会重定向到目标实体 +* 重复的关系会被智能合并 +* 防止自我关系(循环) +* 合并后删除源实体 +* 保留关系权重和属性 + + + +## 缓存 + + + 清除缓存 + +您可以使用不同模式清除LLM响应缓存: + +```python +# 清除所有缓存 +await rag.aclear_cache() + +# 清除本地模式缓存 +await rag.aclear_cache(modes=["local"]) + +# 清除提取缓存 +await rag.aclear_cache(modes=["default"]) + +# 清除多个模式 +await rag.aclear_cache(modes=["local", "global", "hybrid"]) + +# 同步版本 +rag.clear_cache(modes=["local"]) +``` + +有效的模式包括: + +- `"default"`:提取缓存 +- `"naive"`:朴素搜索缓存 +- `"local"`:本地搜索缓存 +- `"global"`:全局搜索缓存 +- `"hybrid"`:混合搜索缓存 +- `"mix"`:混合搜索缓存 + + + +## LightRAG初始化参数 + + + 参数 + +| **参数** | **类型** | **说明** | **默认值** | +|--------------|----------|-----------------|-------------| +| **working_dir** | `str` | 存储缓存的目录 | `lightrag_cache+timestamp` | +| **kv_storage** | `str` | 文档和文本块的存储类型。支持的类型:`JsonKVStorage`、`OracleKVStorage` | `JsonKVStorage` | +| **vector_storage** | `str` | 嵌入向量的存储类型。支持的类型:`NanoVectorDBStorage`、`OracleVectorDBStorage` | `NanoVectorDBStorage` | +| **graph_storage** | `str` | 图边和节点的存储类型。支持的类型:`NetworkXStorage`、`Neo4JStorage`、`OracleGraphStorage` | `NetworkXStorage` | +| **chunk_token_size** | `int` | 拆分文档时每个块的最大令牌大小 | `1200` | +| **chunk_overlap_token_size** | `int` | 拆分文档时两个块之间的重叠令牌大小 | `100` | +| **tiktoken_model_name** | `str` | 用于计算令牌数的Tiktoken编码器的模型名称 | `gpt-4o-mini` | +| **entity_extract_max_gleaning** | `int` | 实体提取过程中的循环次数,附加历史消息 | `1` | +| **entity_summary_to_max_tokens** | `int` | 每个实体摘要的最大令牌大小 | `500` | +| **node_embedding_algorithm** | `str` | 节点嵌入算法(当前未使用) | `node2vec` | +| **node2vec_params** | `dict` | 节点嵌入的参数 | `{"dimensions": 1536,"num_walks": 10,"walk_length": 40,"window_size": 2,"iterations": 3,"random_seed": 3,}` | +| **embedding_func** | `EmbeddingFunc` | 从文本生成嵌入向量的函数 | `openai_embed` | +| **embedding_batch_num** | `int` | 嵌入过程的最大批量大小(每批发送多个文本) | `32` | +| **embedding_func_max_async** | `int` | 最大并发异步嵌入进程数 | `16` | +| **llm_model_func** | `callable` | LLM生成的函数 | `gpt_4o_mini_complete` | +| **llm_model_name** | `str` | 用于生成的LLM模型名称 | `meta-llama/Llama-3.2-1B-Instruct` | +| **llm_model_max_token_size** | `int` | LLM生成的最大令牌大小(影响实体关系摘要) | `32768`(默认值由环境变量MAX_TOKENS更改) | +| **llm_model_max_async** | `int` | 最大并发异步LLM进程数 | `4`(默认值由环境变量MAX_ASYNC更改) | +| **llm_model_kwargs** | `dict` | LLM生成的附加参数 | | +| **vector_db_storage_cls_kwargs** | `dict` | 向量数据库的附加参数,如设置节点和关系检索的阈值 | cosine_better_than_threshold: 0.2(默认值由环境变量COSINE_THRESHOLD更改) | +| **enable_llm_cache** | `bool` | 如果为`TRUE`,将LLM结果存储在缓存中;重复的提示返回缓存的响应 | `TRUE` | +| **enable_llm_cache_for_entity_extract** | `bool` | 如果为`TRUE`,将实体提取的LLM结果存储在缓存中;适合初学者调试应用程序 | `TRUE` | +| **addon_params** | `dict` | 附加参数,例如`{"example_number": 1, "language": "Simplified Chinese", "entity_types": ["organization", "person", "geo", "event"], "insert_batch_size": 10}`:设置示例限制、输出语言和文档处理的批量大小 | `example_number: 所有示例, language: English, insert_batch_size: 10` | +| **convert_response_to_json_func** | `callable` | 未使用 | `convert_response_to_json` | +| **embedding_cache_config** | `dict` | 问答缓存的配置。包含三个参数:`enabled`:布尔值,启用/禁用缓存查找功能。启用时,系统将在生成新答案之前检查缓存的响应。`similarity_threshold`:浮点值(0-1),相似度阈值。当新问题与缓存问题的相似度超过此阈值时,将直接返回缓存的答案而不调用LLM。`use_llm_check`:布尔值,启用/禁用LLM相似度验证。启用时,在返回缓存答案之前,将使用LLM作为二次检查来验证问题之间的相似度。 | 默认:`{"enabled": False, "similarity_threshold": 0.95, "use_llm_check": False}` | + + + +## 错误处理 + + +点击查看错误处理详情 + +API包括全面的错误处理: + +- 文件未找到错误(404) +- 处理错误(500) +- 支持多种文件编码(UTF-8和GBK) + + + +## API + +LightRag可以安装API支持,以提供Fast api接口来执行数据上传和索引/Rag操作/重新扫描输入文件夹等。 + +[LightRag API](lightrag/api/README.md) + +## 图形可视化 + +LightRAG服务器提供全面的知识图谱可视化功能。它支持各种重力布局、节点查询、子图过滤等。**有关LightRAG服务器的更多信息,请参阅[LightRAG服务器](./lightrag/api/README.md)。** + + + +## 评估 + +### 数据集 + +LightRAG使用的数据集可以从[TommyChien/UltraDomain](https://huggingface.co/datasets/TommyChien/UltraDomain)下载。 + +### 生成查询 + +LightRAG使用以下提示生成高级查询,相应的代码在`example/generate_query.py`中。 + + + 提示 + +```python +给定以下数据集描述: + +{description} + +请识别5个可能会使用此数据集的潜在用户。对于每个用户,列出他们会使用此数据集执行的5个任务。然后,对于每个(用户,任务)组合,生成5个需要对整个数据集有高级理解的问题。 + +按以下结构输出结果: +- 用户1:[用户描述] + - 任务1:[任务描述] + - 问题1: + - 问题2: + - 问题3: + - 问题4: + - 问题5: + - 任务2:[任务描述] + ... + - 任务5:[任务描述] +- 用户2:[用户描述] + ... +- 用户5:[用户描述] + ... +``` + + + +### 批量评估 + +为了评估两个RAG系统在高级查询上的性能,LightRAG使用以下提示,具体代码可在`example/batch_eval.py`中找到。 + + + 提示 + +```python +---角色--- +您是一位专家,负责根据三个标准评估同一问题的两个答案:**全面性**、**多样性**和**赋能性**。 +---目标--- +您将根据三个标准评估同一问题的两个答案:**全面性**、**多样性**和**赋能性**。 + +- **全面性**:答案提供了多少细节来涵盖问题的所有方面和细节? +- **多样性**:答案在提供关于问题的不同视角和见解方面有多丰富多样? +- **赋能性**:答案在多大程度上帮助读者理解并对主题做出明智判断? + +对于每个标准,选择更好的答案(答案1或答案2)并解释原因。然后,根据这三个类别选择总体赢家。 + +这是问题: +{query} + +这是两个答案: + +**答案1:** +{answer1} + +**答案2:** +{answer2} + +使用上述三个标准评估两个答案,并为每个标准提供详细解释。 + +以下列JSON格式输出您的评估: + +{{ + "全面性": {{ + "获胜者": "[答案1或答案2]", + "解释": "[在此提供解释]" + }}, + "赋能性": {{ + "获胜者": "[答案1或答案2]", + "解释": "[在此提供解释]" + }}, + "总体获胜者": {{ + "获胜者": "[答案1或答案2]", + "解释": "[根据三个标准总结为什么这个答案是总体获胜者]" + }} +}} +``` + + + +### 总体性能表 + +| |**农业**| |**计算机科学**| |**法律**| |**混合**| | +|----------------------|---------------|------------|------|------------|---------|------------|-------|------------| +| |NaiveRAG|**LightRAG**|NaiveRAG|**LightRAG**|NaiveRAG|**LightRAG**|NaiveRAG|**LightRAG**| +|**全面性**|32.4%|**67.6%**|38.4%|**61.6%**|16.4%|**83.6%**|38.8%|**61.2%**| +|**多样性**|23.6%|**76.4%**|38.0%|**62.0%**|13.6%|**86.4%**|32.4%|**67.6%**| +|**赋能性**|32.4%|**67.6%**|38.8%|**61.2%**|16.4%|**83.6%**|42.8%|**57.2%**| +|**总体**|32.4%|**67.6%**|38.8%|**61.2%**|15.2%|**84.8%**|40.0%|**60.0%**| +| |RQ-RAG|**LightRAG**|RQ-RAG|**LightRAG**|RQ-RAG|**LightRAG**|RQ-RAG|**LightRAG**| +|**全面性**|31.6%|**68.4%**|38.8%|**61.2%**|15.2%|**84.8%**|39.2%|**60.8%**| +|**多样性**|29.2%|**70.8%**|39.2%|**60.8%**|11.6%|**88.4%**|30.8%|**69.2%**| +|**赋能性**|31.6%|**68.4%**|36.4%|**63.6%**|15.2%|**84.8%**|42.4%|**57.6%**| +|**总体**|32.4%|**67.6%**|38.0%|**62.0%**|14.4%|**85.6%**|40.0%|**60.0%**| +| |HyDE|**LightRAG**|HyDE|**LightRAG**|HyDE|**LightRAG**|HyDE|**LightRAG**| +|**全面性**|26.0%|**74.0%**|41.6%|**58.4%**|26.8%|**73.2%**|40.4%|**59.6%**| +|**多样性**|24.0%|**76.0%**|38.8%|**61.2%**|20.0%|**80.0%**|32.4%|**67.6%**| +|**赋能性**|25.2%|**74.8%**|40.8%|**59.2%**|26.0%|**74.0%**|46.0%|**54.0%**| +|**总体**|24.8%|**75.2%**|41.6%|**58.4%**|26.4%|**73.6%**|42.4%|**57.6%**| +| |GraphRAG|**LightRAG**|GraphRAG|**LightRAG**|GraphRAG|**LightRAG**|GraphRAG|**LightRAG**| +|**全面性**|45.6%|**54.4%**|48.4%|**51.6%**|48.4%|**51.6%**|**50.4%**|49.6%| +|**多样性**|22.8%|**77.2%**|40.8%|**59.2%**|26.4%|**73.6%**|36.0%|**64.0%**| +|**赋能性**|41.2%|**58.8%**|45.2%|**54.8%**|43.6%|**56.4%**|**50.8%**|49.2%| +|**总体**|45.2%|**54.8%**|48.0%|**52.0%**|47.2%|**52.8%**|**50.4%**|49.6%| + +## 复现 + +所有代码都可以在`./reproduce`目录中找到。 + +### 步骤0 提取唯一上下文 + +首先,我们需要提取数据集中的唯一上下文。 + + + 代码 + +```python +def extract_unique_contexts(input_directory, output_directory): + + os.makedirs(output_directory, exist_ok=True) + + jsonl_files = glob.glob(os.path.join(input_directory, '*.jsonl')) + print(f"找到{len(jsonl_files)}个JSONL文件。") + + for file_path in jsonl_files: + filename = os.path.basename(file_path) + name, ext = os.path.splitext(filename) + output_filename = f"{name}_unique_contexts.json" + output_path = os.path.join(output_directory, output_filename) + + unique_contexts_dict = {} + + print(f"处理文件:{filename}") + + try: + with open(file_path, 'r', encoding='utf-8') as infile: + for line_number, line in enumerate(infile, start=1): + line = line.strip() + if not line: + continue + try: + json_obj = json.loads(line) + context = json_obj.get('context') + if context and context not in unique_contexts_dict: + unique_contexts_dict[context] = None + except json.JSONDecodeError as e: + print(f"文件{filename}第{line_number}行JSON解码错误:{e}") + except FileNotFoundError: + print(f"未找到文件:{filename}") + continue + except Exception as e: + print(f"处理文件{filename}时发生错误:{e}") + continue + + unique_contexts_list = list(unique_contexts_dict.keys()) + print(f"文件{filename}中有{len(unique_contexts_list)}个唯一的`context`条目。") + + try: + with open(output_path, 'w', encoding='utf-8') as outfile: + json.dump(unique_contexts_list, outfile, ensure_ascii=False, indent=4) + print(f"唯一的`context`条目已保存到:{output_filename}") + except Exception as e: + print(f"保存到文件{output_filename}时发生错误:{e}") + + print("所有文件已处理完成。") + +``` + + + +### 步骤1 插入上下文 + +对于提取的上下文,我们将它们插入到LightRAG系统中。 + + + 代码 + +```python +def insert_text(rag, file_path): + with open(file_path, mode='r') as f: + unique_contexts = json.load(f) + + retries = 0 + max_retries = 3 + while retries < max_retries: + try: + rag.insert(unique_contexts) + break + except Exception as e: + retries += 1 + print(f"插入失败,重试({retries}/{max_retries}),错误:{e}") + time.sleep(10) + if retries == max_retries: + print("超过最大重试次数后插入失败") +``` + + + +### 步骤2 生成查询 + +我们从数据集中每个上下文的前半部分和后半部分提取令牌,然后将它们组合为数据集描述以生成查询。 + + + 代码 + +```python +tokenizer = GPT2Tokenizer.from_pretrained('gpt2') + +def get_summary(context, tot_tokens=2000): + tokens = tokenizer.tokenize(context) + half_tokens = tot_tokens // 2 + + start_tokens = tokens[1000:1000 + half_tokens] + end_tokens = tokens[-(1000 + half_tokens):1000] + + summary_tokens = start_tokens + end_tokens + summary = tokenizer.convert_tokens_to_string(summary_tokens) + + return summary +``` + + + +### 步骤3 查询 + +对于步骤2中生成的查询,我们将提取它们并查询LightRAG。 + + + 代码 + +```python +def extract_queries(file_path): + with open(file_path, 'r') as f: + data = f.read() + + data = data.replace('**', '') + + queries = re.findall(r'- Question \d+: (.+)', data) + + return queries +``` + + + +## Star历史 + + + + + + + + + +## 贡献 + +感谢所有贡献者! + + + + + +## 🌟引用 + +```python +@article{guo2024lightrag, +title={LightRAG: Simple and Fast Retrieval-Augmented Generation}, +author={Zirui Guo and Lianghao Xia and Yanhua Yu and Tu Ao and Chao Huang}, +year={2024}, +eprint={2410.05779}, +archivePrefix={arXiv}, +primaryClass={cs.IR} +} +``` + +**感谢您对我们工作的关注!** diff --git a/README.assets/b2aaf634151b4706892693ffb43d9093.png b/README.assets/b2aaf634151b4706892693ffb43d9093.png new file mode 100644 index 00000000..ac387811 Binary files /dev/null and b/README.assets/b2aaf634151b4706892693ffb43d9093.png differ diff --git a/README.assets/iShot_2025-03-23_12.40.08.png b/README.assets/iShot_2025-03-23_12.40.08.png new file mode 100644 index 00000000..c4250b12 Binary files /dev/null and b/README.assets/iShot_2025-03-23_12.40.08.png differ diff --git a/README.md b/README.md index f07c4530..0fadf32c 100644 --- a/README.md +++ b/README.md @@ -28,22 +28,10 @@ - -This repository hosts the code of LightRAG. The structure of this code is based on nano-graphrag. - - - - + - - - - - - - 🎉 News - +## 🎉 News - [X] [2025.03.18]🎯📢LightRAG now supports citation functionality. - [X] [2025.02.05]🎯📢Our team has released [VideoRAG](https://github.com/HKUDS/VideoRAG) understanding extremely long-context videos. @@ -63,8 +51,6 @@ This repository hosts the code of LightRAG. The structure of this code is based - [X] [2024.10.16]🎯📢LightRAG now supports [Ollama models](https://github.com/HKUDS/LightRAG?tab=readme-ov-file#quick-start)! - [X] [2024.10.15]🎯📢LightRAG now supports [Hugging Face models](https://github.com/HKUDS/LightRAG?tab=readme-ov-file#quick-start)! - - Algorithm Flowchart @@ -779,7 +765,7 @@ For production level scenarios you will most likely want to leverage an enterpri create INDEX CONCURRENTLY entity_idx_node_id ON dickens."Entity" (ag_catalog.agtype_access_operator(properties, '"node_id"'::agtype)); CREATE INDEX CONCURRENTLY entity_node_id_gin_idx ON dickens."Entity" using gin(properties); ALTER TABLE dickens."DIRECTED" CLUSTER ON directed_sid_idx; - + -- drop if necessary drop INDEX entity_p_idx; drop INDEX vertex_p_idx; @@ -1081,33 +1067,33 @@ Valid modes are: Parameters -| **Parameter** | **Type** | **Explanation** | **Default** | -| -------------------------------------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | -| **working\_dir** | `str` | Directory where the cache will be stored | `lightrag_cache+timestamp` | -| **kv\_storage** | `str` | Storage type for documents and text chunks. Supported types:`JsonKVStorage`, `OracleKVStorage` | `JsonKVStorage` | -| **vector\_storage** | `str` | Storage type for embedding vectors. Supported types:`NanoVectorDBStorage`, `OracleVectorDBStorage` | `NanoVectorDBStorage` | -| **graph\_storage** | `str` | Storage type for graph edges and nodes. Supported types:`NetworkXStorage`, `Neo4JStorage`, `OracleGraphStorage` | `NetworkXStorage` | -| **chunk\_token\_size** | `int` | Maximum token size per chunk when splitting documents | `1200` | -| **chunk\_overlap\_token\_size** | `int` | Overlap token size between two chunks when splitting documents | `100` | -| **tiktoken\_model\_name** | `str` | Model name for the Tiktoken encoder used to calculate token numbers | `gpt-4o-mini` | -| **entity\_extract\_max\_gleaning** | `int` | Number of loops in the entity extraction process, appending history messages | `1` | -| **entity\_summary\_to\_max\_tokens** | `int` | Maximum token size for each entity summary | `500` | -| **node\_embedding\_algorithm** | `str` | Algorithm for node embedding (currently not used) | `node2vec` | -| **node2vec\_params** | `dict` | Parameters for node embedding | `{"dimensions": 1536,"num_walks": 10,"walk_length": 40,"window_size": 2,"iterations": 3,"random_seed": 3,}` | -| **embedding\_func** | `EmbeddingFunc` | Function to generate embedding vectors from text | `openai_embed` | -| **embedding\_batch\_num** | `int` | Maximum batch size for embedding processes (multiple texts sent per batch) | `32` | -| **embedding\_func\_max\_async** | `int` | Maximum number of concurrent asynchronous embedding processes | `16` | -| **llm\_model\_func** | `callable` | Function for LLM generation | `gpt_4o_mini_complete` | -| **llm\_model\_name** | `str` | LLM model name for generation | `meta-llama/Llama-3.2-1B-Instruct` | -| **llm\_model\_max\_token\_size** | `int` | Maximum token size for LLM generation (affects entity relation summaries) | `32768`(default value changed by env var MAX_TOKENS) | -| **llm\_model\_max\_async** | `int` | Maximum number of concurrent asynchronous LLM processes | `4`(default value changed by env var MAX_ASYNC) | -| **llm\_model\_kwargs** | `dict` | Additional parameters for LLM generation | | -| **vector\_db\_storage\_cls\_kwargs** | `dict` | Additional parameters for vector database, like setting the threshold for nodes and relations retrieval. | cosine_better_than_threshold: 0.2(default value changed by env var COSINE_THRESHOLD) | -| **enable\_llm\_cache** | `bool` | If `TRUE`, stores LLM results in cache; repeated prompts return cached responses | `TRUE` | -| **enable\_llm\_cache\_for\_entity\_extract** | `bool` | If `TRUE`, stores LLM results in cache for entity extraction; Good for beginners to debug your application | `TRUE` | -| **addon\_params** | `dict` | Additional parameters, e.g.,`{"example_number": 1, "language": "Simplified Chinese", "entity_types": ["organization", "person", "geo", "event"], "insert_batch_size": 10}`: sets example limit, output language, and batch size for document processing | `example_number: all examples, language: English, insert_batch_size: 10` | -| **convert\_response\_to\_json\_func** | `callable` | Not used | `convert_response_to_json` | -| **embedding\_cache\_config** | `dict` | Configuration for question-answer caching. Contains three parameters:``- `enabled`: Boolean value to enable/disable cache lookup functionality. When enabled, the system will check cached responses before generating new answers.``- `similarity_threshold`: Float value (0-1), similarity threshold. When a new question's similarity with a cached question exceeds this threshold, the cached answer will be returned directly without calling the LLM.``- `use_llm_check`: Boolean value to enable/disable LLM similarity verification. When enabled, LLM will be used as a secondary check to verify the similarity between questions before returning cached answers. | Default:`{"enabled": False, "similarity_threshold": 0.95, "use_llm_check": False}` | +| **Parameter** | **Type** | **Explanation** | **Default** | +|--------------|----------|-----------------|-------------| +| **working_dir** | `str` | Directory where the cache will be stored | `lightrag_cache+timestamp` | +| **kv_storage** | `str` | Storage type for documents and text chunks. Supported types: `JsonKVStorage`, `OracleKVStorage` | `JsonKVStorage` | +| **vector_storage** | `str` | Storage type for embedding vectors. Supported types: `NanoVectorDBStorage`, `OracleVectorDBStorage` | `NanoVectorDBStorage` | +| **graph_storage** | `str` | Storage type for graph edges and nodes. Supported types: `NetworkXStorage`, `Neo4JStorage`, `OracleGraphStorage` | `NetworkXStorage` | +| **chunk_token_size** | `int` | Maximum token size per chunk when splitting documents | `1200` | +| **chunk_overlap_token_size** | `int` | Overlap token size between two chunks when splitting documents | `100` | +| **tiktoken_model_name** | `str` | Model name for the Tiktoken encoder used to calculate token numbers | `gpt-4o-mini` | +| **entity_extract_max_gleaning** | `int` | Number of loops in the entity extraction process, appending history messages | `1` | +| **entity_summary_to_max_tokens** | `int` | Maximum token size for each entity summary | `500` | +| **node_embedding_algorithm** | `str` | Algorithm for node embedding (currently not used) | `node2vec` | +| **node2vec_params** | `dict` | Parameters for node embedding | `{"dimensions": 1536,"num_walks": 10,"walk_length": 40,"window_size": 2,"iterations": 3,"random_seed": 3,}` | +| **embedding_func** | `EmbeddingFunc` | Function to generate embedding vectors from text | `openai_embed` | +| **embedding_batch_num** | `int` | Maximum batch size for embedding processes (multiple texts sent per batch) | `32` | +| **embedding_func_max_async** | `int` | Maximum number of concurrent asynchronous embedding processes | `16` | +| **llm_model_func** | `callable` | Function for LLM generation | `gpt_4o_mini_complete` | +| **llm_model_name** | `str` | LLM model name for generation | `meta-llama/Llama-3.2-1B-Instruct` | +| **llm_model_max_token_size** | `int` | Maximum token size for LLM generation (affects entity relation summaries) | `32768`(default value changed by env var MAX_TOKENS) | +| **llm_model_max_async** | `int` | Maximum number of concurrent asynchronous LLM processes | `4`(default value changed by env var MAX_ASYNC) | +| **llm_model_kwargs** | `dict` | Additional parameters for LLM generation | | +| **vector_db_storage_cls_kwargs** | `dict` | Additional parameters for vector database, like setting the threshold for nodes and relations retrieval | cosine_better_than_threshold: 0.2(default value changed by env var COSINE_THRESHOLD) | +| **enable_llm_cache** | `bool` | If `TRUE`, stores LLM results in cache; repeated prompts return cached responses | `TRUE` | +| **enable_llm_cache_for_entity_extract** | `bool` | If `TRUE`, stores LLM results in cache for entity extraction; Good for beginners to debug your application | `TRUE` | +| **addon_params** | `dict` | Additional parameters, e.g., `{"example_number": 1, "language": "Simplified Chinese", "entity_types": ["organization", "person", "geo", "event"], "insert_batch_size": 10}`: sets example limit, output language, and batch size for document processing | `example_number: all examples, language: English, insert_batch_size: 10` | +| **convert_response_to_json_func** | `callable` | Not used | `convert_response_to_json` | +| **embedding_cache_config** | `dict` | Configuration for question-answer caching. Contains three parameters: `enabled`: Boolean value to enable/disable cache lookup functionality. When enabled, the system will check cached responses before generating new answers. `similarity_threshold`: Float value (0-1), similarity threshold. When a new question's similarity with a cached question exceeds this threshold, the cached answer will be returned directly without calling the LLM. `use_llm_check`: Boolean value to enable/disable LLM similarity verification. When enabled, LLM will be used as a secondary check to verify the similarity between questions before returning cached answers. | Default: `{"enabled": False, "similarity_threshold": 0.95, "use_llm_check": False}` | @@ -1132,166 +1118,9 @@ LightRag can be installed with API support to serve a Fast api interface to perf ## Graph Visualization - - Graph visualization with html +The LightRAG Server offers a comprehensive knowledge graph visualization feature. It supports various gravity layouts, node queries, subgraph filtering, and more. **For more information about LightRAG Server, please refer to [LightRAG Server](./lightrag/api/README.md).** -* The following code can be found in `examples/graph_visual_with_html.py` - -```python -import networkx as nx -from pyvis.network import Network - -# Load the GraphML file -G = nx.read_graphml('./dickens/graph_chunk_entity_relation.graphml') - -# Create a Pyvis network -net = Network(notebook=True) - -# Convert NetworkX graph to Pyvis network -net.from_nx(G) - -# Save and display the network -net.show('knowledge_graph.html') -``` - - - - - Graph visualization with Neo4 - -* The following code can be found in `examples/graph_visual_with_neo4j.py` - -```python -import os -import json -from lightrag.utils import xml_to_json -from neo4j import GraphDatabase - -# Constants -WORKING_DIR = "./dickens" -BATCH_SIZE_NODES = 500 -BATCH_SIZE_EDGES = 100 - -# Neo4j connection credentials -NEO4J_URI = "bolt://localhost:7687" -NEO4J_USERNAME = "neo4j" -NEO4J_PASSWORD = "your_password" - -def convert_xml_to_json(xml_path, output_path): - """Converts XML file to JSON and saves the output.""" - if not os.path.exists(xml_path): - print(f"Error: File not found - {xml_path}") - return None - - json_data = xml_to_json(xml_path) - if json_data: - with open(output_path, 'w', encoding='utf-8') as f: - json.dump(json_data, f, ensure_ascii=False, indent=2) - print(f"JSON file created: {output_path}") - return json_data - else: - print("Failed to create JSON data") - return None - -def process_in_batches(tx, query, data, batch_size): - """Process data in batches and execute the given query.""" - for i in range(0, len(data), batch_size): - batch = data[i:i + batch_size] - tx.run(query, {"nodes": batch} if "nodes" in query else {"edges": batch}) - -def main(): - # Paths - xml_file = os.path.join(WORKING_DIR, 'graph_chunk_entity_relation.graphml') - json_file = os.path.join(WORKING_DIR, 'graph_data.json') - - # Convert XML to JSON - json_data = convert_xml_to_json(xml_file, json_file) - if json_data is None: - return - - # Load nodes and edges - nodes = json_data.get('nodes', []) - edges = json_data.get('edges', []) - - # Neo4j queries - create_nodes_query = """ - 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 - REMOVE e:Entity - WITH e, node - CALL apoc.create.addLabels(e, [node.entity_type]) YIELD node AS labeledNode - RETURN count(*) - """ - - create_edges_query = """ - 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' - WHEN edge.keywords CONTAINS 'located' THEN 'located' - WHEN edge.keywords CONTAINS 'occurs' THEN 'occurs' - ELSE REPLACE(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(*) - """ - - set_displayname_and_labels_query = """ - MATCH (n) - SET n.displayName = n.id - WITH n - CALL apoc.create.setLabels(n, [n.entity_type]) YIELD node - RETURN count(*) - """ - - # Create a Neo4j driver - driver = GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USERNAME, NEO4J_PASSWORD)) - - try: - # Execute queries in batches - with driver.session() as session: - # Insert nodes in batches - session.execute_write(process_in_batches, create_nodes_query, nodes, BATCH_SIZE_NODES) - - # Insert edges in batches - session.execute_write(process_in_batches, create_edges_query, edges, BATCH_SIZE_EDGES) - - # Set displayName and labels - session.run(set_displayname_and_labels_query) - - except Exception as e: - print(f"Error occurred: {e}") - - finally: - driver.close() - -if __name__ == "__main__": - main() -``` - - - - - Graphml 3d visualizer - -LightRag can be installed with Tools support to add extra tools like the graphml 3d visualizer. - -[LightRag Visualizer](lightrag/tools/lightrag_visualizer/README.md) - - + ## Evaluation @@ -1386,28 +1215,28 @@ Output your evaluation in the following JSON format: ### Overall Performance Table -| | **Agriculture** | | **CS** | | **Legal** | | **Mix** | | -| --------------------------- | --------------------- | ------------------ | ------------ | ------------------ | --------------- | ------------------ | --------------- | ------------------ | -| | NaiveRAG | **LightRAG** | NaiveRAG | **LightRAG** | NaiveRAG | **LightRAG** | NaiveRAG | **LightRAG** | -| **Comprehensiveness** | 32.4% | **67.6%** | 38.4% | **61.6%** | 16.4% | **83.6%** | 38.8% | **61.2%** | -| **Diversity** | 23.6% | **76.4%** | 38.0% | **62.0%** | 13.6% | **86.4%** | 32.4% | **67.6%** | -| **Empowerment** | 32.4% | **67.6%** | 38.8% | **61.2%** | 16.4% | **83.6%** | 42.8% | **57.2%** | -| **Overall** | 32.4% | **67.6%** | 38.8% | **61.2%** | 15.2% | **84.8%** | 40.0% | **60.0%** | -| | RQ-RAG | **LightRAG** | RQ-RAG | **LightRAG** | RQ-RAG | **LightRAG** | RQ-RAG | **LightRAG** | -| **Comprehensiveness** | 31.6% | **68.4%** | 38.8% | **61.2%** | 15.2% | **84.8%** | 39.2% | **60.8%** | -| **Diversity** | 29.2% | **70.8%** | 39.2% | **60.8%** | 11.6% | **88.4%** | 30.8% | **69.2%** | -| **Empowerment** | 31.6% | **68.4%** | 36.4% | **63.6%** | 15.2% | **84.8%** | 42.4% | **57.6%** | -| **Overall** | 32.4% | **67.6%** | 38.0% | **62.0%** | 14.4% | **85.6%** | 40.0% | **60.0%** | -| | HyDE | **LightRAG** | HyDE | **LightRAG** | HyDE | **LightRAG** | HyDE | **LightRAG** | -| **Comprehensiveness** | 26.0% | **74.0%** | 41.6% | **58.4%** | 26.8% | **73.2%** | 40.4% | **59.6%** | -| **Diversity** | 24.0% | **76.0%** | 38.8% | **61.2%** | 20.0% | **80.0%** | 32.4% | **67.6%** | -| **Empowerment** | 25.2% | **74.8%** | 40.8% | **59.2%** | 26.0% | **74.0%** | 46.0% | **54.0%** | -| **Overall** | 24.8% | **75.2%** | 41.6% | **58.4%** | 26.4% | **73.6%** | 42.4% | **57.6%** | -| | GraphRAG | **LightRAG** | GraphRAG | **LightRAG** | GraphRAG | **LightRAG** | GraphRAG | **LightRAG** | -| **Comprehensiveness** | 45.6% | **54.4%** | 48.4% | **51.6%** | 48.4% | **51.6%** | **50.4%** | 49.6% | -| **Diversity** | 22.8% | **77.2%** | 40.8% | **59.2%** | 26.4% | **73.6%** | 36.0% | **64.0%** | -| **Empowerment** | 41.2% | **58.8%** | 45.2% | **54.8%** | 43.6% | **56.4%** | **50.8%** | 49.2% | -| **Overall** | 45.2% | **54.8%** | 48.0% | **52.0%** | 47.2% | **52.8%** | **50.4%** | 49.6% | +| |**Agriculture**| |**CS**| |**Legal**| |**Mix**| | +|----------------------|---------------|------------|------|------------|---------|------------|-------|------------| +| |NaiveRAG|**LightRAG**|NaiveRAG|**LightRAG**|NaiveRAG|**LightRAG**|NaiveRAG|**LightRAG**| +|**Comprehensiveness**|32.4%|**67.6%**|38.4%|**61.6%**|16.4%|**83.6%**|38.8%|**61.2%**| +|**Diversity**|23.6%|**76.4%**|38.0%|**62.0%**|13.6%|**86.4%**|32.4%|**67.6%**| +|**Empowerment**|32.4%|**67.6%**|38.8%|**61.2%**|16.4%|**83.6%**|42.8%|**57.2%**| +|**Overall**|32.4%|**67.6%**|38.8%|**61.2%**|15.2%|**84.8%**|40.0%|**60.0%**| +| |RQ-RAG|**LightRAG**|RQ-RAG|**LightRAG**|RQ-RAG|**LightRAG**|RQ-RAG|**LightRAG**| +|**Comprehensiveness**|31.6%|**68.4%**|38.8%|**61.2%**|15.2%|**84.8%**|39.2%|**60.8%**| +|**Diversity**|29.2%|**70.8%**|39.2%|**60.8%**|11.6%|**88.4%**|30.8%|**69.2%**| +|**Empowerment**|31.6%|**68.4%**|36.4%|**63.6%**|15.2%|**84.8%**|42.4%|**57.6%**| +|**Overall**|32.4%|**67.6%**|38.0%|**62.0%**|14.4%|**85.6%**|40.0%|**60.0%**| +| |HyDE|**LightRAG**|HyDE|**LightRAG**|HyDE|**LightRAG**|HyDE|**LightRAG**| +|**Comprehensiveness**|26.0%|**74.0%**|41.6%|**58.4%**|26.8%|**73.2%**|40.4%|**59.6%**| +|**Diversity**|24.0%|**76.0%**|38.8%|**61.2%**|20.0%|**80.0%**|32.4%|**67.6%**| +|**Empowerment**|25.2%|**74.8%**|40.8%|**59.2%**|26.0%|**74.0%**|46.0%|**54.0%**| +|**Overall**|24.8%|**75.2%**|41.6%|**58.4%**|26.4%|**73.6%**|42.4%|**57.6%**| +| |GraphRAG|**LightRAG**|GraphRAG|**LightRAG**|GraphRAG|**LightRAG**|GraphRAG|**LightRAG**| +|**Comprehensiveness**|45.6%|**54.4%**|48.4%|**51.6%**|48.4%|**51.6%**|**50.4%**|49.6%| +|**Diversity**|22.8%|**77.2%**|40.8%|**59.2%**|26.4%|**73.6%**|36.0%|**64.0%**| +|**Empowerment**|41.2%|**58.8%**|45.2%|**54.8%**|43.6%|**56.4%**|**50.8%**|49.2%| +|**Overall**|45.2%|**54.8%**|48.0%|**52.0%**|47.2%|**52.8%**|**50.4%**|49.6%| ## Reproduce diff --git a/lightrag/api/README-zh.md b/lightrag/api/README-zh.md new file mode 100644 index 00000000..839aa2ef --- /dev/null +++ b/lightrag/api/README-zh.md @@ -0,0 +1,559 @@ +# LightRAG 服务器和 Web 界面 + +LightRAG 服务器旨在提供 Web 界面和 API 支持。Web 界面便于文档索引、知识图谱探索和简单的 RAG 查询界面。LightRAG 服务器还提供了与 Ollama 兼容的接口,旨在将 LightRAG 模拟为 Ollama 聊天模型。这使得 AI 聊天机器人(如 Open WebUI)可以轻松访问 LightRAG。 + + + + + + + +## 入门指南 + +### 安装 + +* 从 PyPI 安装 + +```bash +pip install "lightrag-hku[api]" +``` + +* 从源代码安装 + +```bash +# 克隆仓库 +git clone https://github.com/HKUDS/lightrag.git + +# 切换到仓库目录 +cd lightrag + +# 如有必要,创建 Python 虚拟环境 +# 以可编辑模式安装并支持 API +pip install -e ".[api]" +``` + +### 启动 LightRAG 服务器前的准备 + +LightRAG 需要同时集成 LLM(大型语言模型)和嵌入模型以有效执行文档索引和查询操作。在首次部署 LightRAG 服务器之前,必须配置 LLM 和嵌入模型的设置。LightRAG 支持绑定到各种 LLM/嵌入后端: + +* ollama +* lollms +* openai 或 openai 兼容 +* azure_openai + +建议使用环境变量来配置 LightRAG 服务器。项目根目录中有一个名为 `env.example` 的示例环境变量文件。请将此文件复制到启动目录并重命名为 `.env`。之后,您可以在 `.env` 文件中修改与 LLM 和嵌入模型相关的参数。需要注意的是,LightRAG 服务器每次启动时都会将 `.env` 中的环境变量加载到系统环境变量中。由于 LightRAG 服务器会优先使用系统环境变量中的设置,如果您在通过命令行启动 LightRAG 服务器后修改了 `.env` 文件,则需要执行 `source .env` 使新设置生效。 + +以下是 LLM 和嵌入模型的一些常见设置示例: + +* OpenAI LLM + Ollama 嵌入 + +``` +LLM_BINDING=openai +LLM_MODEL=gpt-4o +LLM_BINDING_HOST=https://api.openai.com/v1 +LLM_BINDING_API_KEY=your_api_key +MAX_TOKENS=32768 # 发送给 LLM 的最大 token 数(小于模型上下文大小) + +EMBEDDING_BINDING=ollama +EMBEDDING_BINDING_HOST=http://localhost:11434 +EMBEDDING_MODEL=bge-m3:latest +EMBEDDING_DIM=1024 +# EMBEDDING_BINDING_API_KEY=your_api_key +``` + +* Ollama LLM + Ollama 嵌入 + +``` +LLM_BINDING=ollama +LLM_MODEL=mistral-nemo:latest +LLM_BINDING_HOST=http://localhost:11434 +# LLM_BINDING_API_KEY=your_api_key +MAX_TOKENS=8192 # 发送给 LLM 的最大 token 数(基于您的 Ollama 服务器容量) + +EMBEDDING_BINDING=ollama +EMBEDDING_BINDING_HOST=http://localhost:11434 +EMBEDDING_MODEL=bge-m3:latest +EMBEDDING_DIM=1024 +# EMBEDDING_BINDING_API_KEY=your_api_key +``` + +### 启动 LightRAG 服务器 + +LightRAG 服务器支持两种运行模式: +* 简单高效的 Uvicorn 模式 + +``` +lightrag-server +``` +* 多进程 Gunicorn + Uvicorn 模式(生产模式,不支持 Windows 环境) + +``` +lightrag-gunicorn --workers 4 +``` +`.env` 文件必须放在启动目录中。启动时,LightRAG 服务器将创建一个文档目录(默认为 `./inputs`)和一个数据目录(默认为 `./rag_storage`)。这允许您从不同目录启动多个 LightRAG 服务器实例,每个实例配置为监听不同的网络端口。 + +以下是一些常用的启动参数: + +- `--host`:服务器监听地址(默认:0.0.0.0) +- `--port`:服务器监听端口(默认:9621) +- `--timeout`:LLM 请求超时时间(默认:150 秒) +- `--log-level`:日志级别(默认:INFO) +- --input-dir:指定要扫描文档的目录(默认:./input) + +### 启动时自动扫描 + +当使用 `--auto-scan-at-startup` 参数启动任何服务器时,系统将自动: + +1. 扫描输入目录中的新文件 +2. 为尚未在数据库中的新文档建立索引 +3. 使所有内容立即可用于 RAG 查询 + +> `--input-dir` 参数指定要扫描的输入目录。您可以从 webui 触发输入目录扫描。 + +### Gunicorn + Uvicorn 的多工作进程 + +LightRAG 服务器可以在 `Gunicorn + Uvicorn` 预加载模式下运行。Gunicorn 的多工作进程(多进程)功能可以防止文档索引任务阻塞 RAG 查询。使用 CPU 密集型文档提取工具(如 docling)在纯 Uvicorn 模式下可能会导致整个系统被阻塞。 + +虽然 LightRAG 服务器使用一个工作进程来处理文档索引流程,但通过 Uvicorn 的异步任务支持,可以并行处理多个文件。文档索引速度的瓶颈主要在于 LLM。如果您的 LLM 支持高并发,您可以通过增加 LLM 的并发级别来加速文档索引。以下是几个与并发处理相关的环境变量及其默认值: + +``` +WORKERS=2 # 工作进程数,不大于 (2 x 核心数) + 1 +MAX_PARALLEL_INSERT=2 # 一批中并行处理的文件数 +MAX_ASYNC=4 # LLM 的最大并发请求数 +``` + +### 将 Lightrag 安装为 Linux 服务 + +从示例文件 `lightrag.sevice.example` 创建您的服务文件 `lightrag.sevice`。修改服务文件中的 WorkingDirectory 和 ExecStart: + +```text +Description=LightRAG Ollama Service +WorkingDirectory= +ExecStart=/lightrag/api/lightrag-api +``` + +修改您的服务启动脚本:`lightrag-api`。根据需要更改 python 虚拟环境激活命令: + +```shell +#!/bin/bash + +# 您的 python 虚拟环境激活命令 +source /home/netman/lightrag-xyj/venv/bin/activate +# 启动 lightrag api 服务器 +lightrag-server +``` + +安装 LightRAG 服务。如果您的系统是 Ubuntu,以下命令将生效: + +```shell +sudo cp lightrag.service /etc/systemd/system/ +sudo systemctl daemon-reload +sudo systemctl start lightrag.service +sudo systemctl status lightrag.service +sudo systemctl enable lightrag.service +``` + +## Ollama 模拟 + +我们为 LightRAG 提供了 Ollama 兼容接口,旨在将 LightRAG 模拟为 Ollama 聊天模型。这使得支持 Ollama 的 AI 聊天前端(如 Open WebUI)可以轻松访问 LightRAG。 + +### 将 Open WebUI 连接到 LightRAG + +启动 lightrag-server 后,您可以在 Open WebUI 管理面板中添加 Ollama 类型的连接。然后,一个名为 lightrag:latest 的模型将出现在 Open WebUI 的模型管理界面中。用户随后可以通过聊天界面向 LightRAG 发送查询。对于这种用例,最好将 LightRAG 安装为服务。 + +Open WebUI 使用 LLM 来执行会话标题和会话关键词生成任务。因此,Ollama 聊天补全 API 会检测并将 OpenWebUI 会话相关请求直接转发给底层 LLM。Open WebUI 的截图: + + + +### 在聊天中选择查询模式 + +查询字符串中的查询前缀可以决定使用哪种 LightRAG 查询模式来生成响应。支持的前缀包括: + +``` +/local +/global +/hybrid +/naive +/mix +/bypass +``` + +例如,聊天消息 "/mix 唐僧有几个徒弟" 将触发 LightRAG 的混合模式查询。没有查询前缀的聊天消息默认会触发混合模式查询。 + +"/bypass" 不是 LightRAG 查询模式,它会告诉 API 服务器将查询连同聊天历史直接传递给底层 LLM。因此用户可以使用 LLM 基于聊天历史回答问题。如果您使用 Open WebUI 作为前端,您可以直接切换到普通 LLM 模型,而不是使用 /bypass 前缀。 + +## API 密钥和认证 + +默认情况下,LightRAG 服务器可以在没有任何认证的情况下访问。我们可以使用 API 密钥或账户凭证配置服务器以确保其安全。 + +* API 密钥 + +``` +LIGHTRAG_API_KEY=your-secure-api-key-here +WHITELIST_PATHS=/health,/api/* +``` + +> 健康检查和 Ollama 模拟端点默认不进行 API 密钥检查。 + +* 账户凭证(Web 界面需要登录后才能访问) + +LightRAG API 服务器使用基于 HS256 算法的 JWT 认证。要启用安全访问控制,需要以下环境变量: + +```bash +# JWT 认证 +AUTH_USERNAME=admin # 登录名 +AUTH_PASSWORD=admin123 # 密码 +TOKEN_SECRET=your-key # JWT 密钥 +TOKEN_EXPIRE_HOURS=4 # 过期时间 +``` + +> 目前仅支持配置一个管理员账户和密码。尚未开发和实现完整的账户系统。 + +如果未配置账户凭证,Web 界面将以访客身份访问系统。因此,即使仅配置了 API 密钥,所有 API 仍然可以通过访客账户访问,这仍然不安全。因此,要保护 API,需要同时配置这两种认证方法。 + +## Azure OpenAI 后端配置 + +可以使用以下 Azure CLI 命令创建 Azure OpenAI API(您需要先从 [https://docs.microsoft.com/en-us/cli/azure/install-azure-cli](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) 安装 Azure CLI): + +```bash +# 根据需要更改资源组名称、位置和 OpenAI 资源名称 +RESOURCE_GROUP_NAME=LightRAG +LOCATION=swedencentral +RESOURCE_NAME=LightRAG-OpenAI + +az login +az group create --name $RESOURCE_GROUP_NAME --location $LOCATION +az cognitiveservices account create --name $RESOURCE_NAME --resource-group $RESOURCE_GROUP_NAME --kind OpenAI --sku S0 --location swedencentral +az cognitiveservices account deployment create --resource-group $RESOURCE_GROUP_NAME --model-format OpenAI --name $RESOURCE_NAME --deployment-name gpt-4o --model-name gpt-4o --model-version "2024-08-06" --sku-capacity 100 --sku-name "Standard" +az cognitiveservices account deployment create --resource-group $RESOURCE_GROUP_NAME --model-format OpenAI --name $RESOURCE_NAME --deployment-name text-embedding-3-large --model-name text-embedding-3-large --model-version "1" --sku-capacity 80 --sku-name "Standard" +az cognitiveservices account show --name $RESOURCE_NAME --resource-group $RESOURCE_GROUP_NAME --query "properties.endpoint" +az cognitiveservices account keys list --name $RESOURCE_NAME -g $RESOURCE_GROUP_NAME +``` + +最后一个命令的输出将提供 OpenAI API 的端点和密钥。您可以使用这些值在 `.env` 文件中设置环境变量。 + +``` +# .env 中的 Azure OpenAI 配置 +LLM_BINDING=azure_openai +LLM_BINDING_HOST=your-azure-endpoint +LLM_MODEL=your-model-deployment-name +LLM_BINDING_API_KEY=your-azure-api-key +AZURE_OPENAI_API_VERSION=2024-08-01-preview # 可选,默认为最新版本 +EMBEDDING_BINDING=azure_openai # 如果使用 Azure OpenAI 进行嵌入 +EMBEDDING_MODEL=your-embedding-deployment-name +``` + +## LightRAG 服务器详细配置 + +API 服务器可以通过三种方式配置(优先级从高到低): + +* 命令行参数 +* 环境变量或 .env 文件 +* Config.ini(仅用于存储配置) + +大多数配置都有默认设置,详细信息请查看示例文件:`.env.example`。数据存储配置也可以通过 config.ini 设置。为方便起见,提供了示例文件 `config.ini.example`。 + +### 支持的 LLM 和嵌入后端 + +LightRAG 支持绑定到各种 LLM/嵌入后端: + +* ollama +* lollms +* openai 和 openai 兼容 +* azure_openai + +使用环境变量 `LLM_BINDING` 或 CLI 参数 `--llm-binding` 选择 LLM 后端类型。使用环境变量 `EMBEDDING_BINDING` 或 CLI 参数 `--embedding-binding` 选择嵌入后端类型。 + +### 实体提取配置 +* ENABLE_LLM_CACHE_FOR_EXTRACT:为实体提取启用 LLM 缓存(默认:true) + +在测试环境中将 `ENABLE_LLM_CACHE_FOR_EXTRACT` 设置为 true 以减少 LLM 调用成本是很常见的做法。 + +### 支持的存储类型 + +LightRAG 使用 4 种类型的存储用于不同目的: + +* KV_STORAGE:llm 响应缓存、文本块、文档信息 +* VECTOR_STORAGE:实体向量、关系向量、块向量 +* GRAPH_STORAGE:实体关系图 +* DOC_STATUS_STORAGE:文档索引状态 + +每种存储类型都有几种实现: + +* KV_STORAGE 支持的实现名称 + +``` +JsonKVStorage JsonFile(默认) +MongoKVStorage MogonDB +RedisKVStorage Redis +TiDBKVStorage TiDB +PGKVStorage Postgres +OracleKVStorage Oracle +``` + +* GRAPH_STORAGE 支持的实现名称 + +``` +NetworkXStorage NetworkX(默认) +Neo4JStorage Neo4J +MongoGraphStorage MongoDB +TiDBGraphStorage TiDB +AGEStorage AGE +GremlinStorage Gremlin +PGGraphStorage Postgres +OracleGraphStorage Postgres +``` + +* VECTOR_STORAGE 支持的实现名称 + +``` +NanoVectorDBStorage NanoVector(默认) +MilvusVectorDBStorge Milvus +ChromaVectorDBStorage Chroma +TiDBVectorDBStorage TiDB +PGVectorStorage Postgres +FaissVectorDBStorage Faiss +QdrantVectorDBStorage Qdrant +OracleVectorDBStorage Oracle +MongoVectorDBStorage MongoDB +``` + +* DOC_STATUS_STORAGE 支持的实现名称 + +``` +JsonDocStatusStorage JsonFile(默认) +PGDocStatusStorage Postgres +MongoDocStatusStorage MongoDB +``` + +### 如何选择存储实现 + +您可以通过环境变量选择存储实现。在首次启动 API 服务器之前,您可以将以下环境变量设置为特定的存储实现名称: + +``` +LIGHTRAG_KV_STORAGE=PGKVStorage +LIGHTRAG_VECTOR_STORAGE=PGVectorStorage +LIGHTRAG_GRAPH_STORAGE=PGGraphStorage +LIGHTRAG_DOC_STATUS_STORAGE=PGDocStatusStorage +``` + +在向 LightRAG 添加文档后,您不能更改存储实现选择。目前尚不支持从一个存储实现迁移到另一个存储实现。更多信息请阅读示例 env 文件或 config.ini 文件。 + +### LightRag API 服务器命令行选项 + +| 参数 | 默认值 | 描述 | +|-----------|---------|-------------| +| --host | 0.0.0.0 | 服务器主机 | +| --port | 9621 | 服务器端口 | +| --working-dir | ./rag_storage | RAG 存储的工作目录 | +| --input-dir | ./inputs | 包含输入文档的目录 | +| --max-async | 4 | 最大异步操作数 | +| --max-tokens | 32768 | 最大 token 大小 | +| --timeout | 150 | 超时时间(秒)。None 表示无限超时(不推荐) | +| --log-level | INFO | 日志级别(DEBUG、INFO、WARNING、ERROR、CRITICAL) | +| --verbose | - | 详细调试输出(True、False) | +| --key | None | 用于认证的 API 密钥。保护 lightrag 服务器免受未授权访问 | +| --ssl | False | 启用 HTTPS | +| --ssl-certfile | None | SSL 证书文件路径(如果启用 --ssl 则必需) | +| --ssl-keyfile | None | SSL 私钥文件路径(如果启用 --ssl 则必需) | +| --top-k | 50 | 要检索的 top-k 项目数;在"local"模式下对应实体,在"global"模式下对应关系。 | +| --cosine-threshold | 0.4 | 节点和关系检索的余弦阈值,与 top-k 一起控制节点和关系的检索。 | +| --llm-binding | ollama | LLM 绑定类型(lollms、ollama、openai、openai-ollama、azure_openai) | +| --embedding-binding | ollama | 嵌入绑定类型(lollms、ollama、openai、azure_openai) | +| auto-scan-at-startup | - | 扫描输入目录中的新文件并开始索引 | + +### 使用示例 + +#### 使用 ollama 默认本地服务器作为 llm 和嵌入后端运行 Lightrag 服务器 + +Ollama 是 llm 和嵌入的默认后端,因此默认情况下您可以不带参数运行 lightrag-server,将使用默认值。确保已安装 ollama 并且正在运行,且默认模型已安装在 ollama 上。 + +```bash +# 使用 ollama 运行 lightrag,llm 使用 mistral-nemo:latest,嵌入使用 bge-m3:latest +lightrag-server + +# 使用认证密钥 +lightrag-server --key my-key +``` + +#### 使用 lollms 默认本地服务器作为 llm 和嵌入后端运行 Lightrag 服务器 + +```bash +# 使用 lollms 运行 lightrag,llm 使用 mistral-nemo:latest,嵌入使用 bge-m3:latest +# 在 .env 或 config.ini 中配置 LLM_BINDING=lollms 和 EMBEDDING_BINDING=lollms +lightrag-server + +# 使用认证密钥 +lightrag-server --key my-key +``` + +#### 使用 openai 服务器作为 llm 和嵌入后端运行 Lightrag 服务器 + +```bash +# 使用 openai 运行 lightrag,llm 使用 GPT-4o-mini,嵌入使用 text-embedding-3-small +# 在 .env 或 config.ini 中配置: +# LLM_BINDING=openai +# LLM_MODEL=GPT-4o-mini +# EMBEDDING_BINDING=openai +# EMBEDDING_MODEL=text-embedding-3-small +lightrag-server + +# 使用认证密钥 +lightrag-server --key my-key +``` + +#### 使用 azure openai 服务器作为 llm 和嵌入后端运行 Lightrag 服务器 + +```bash +# 使用 azure_openai 运行 lightrag +# 在 .env 或 config.ini 中配置: +# LLM_BINDING=azure_openai +# LLM_MODEL=your-model +# EMBEDDING_BINDING=azure_openai +# EMBEDDING_MODEL=your-embedding-model +lightrag-server + +# 使用认证密钥 +lightrag-server --key my-key +``` + +**重要说明:** +- 对于 LoLLMs:确保指定的模型已安装在您的 LoLLMs 实例中 +- 对于 Ollama:确保指定的模型已安装在您的 Ollama 实例中 +- 对于 OpenAI:确保您已设置 OPENAI_API_KEY 环境变量 +- 对于 Azure OpenAI:按照先决条件部分所述构建和配置您的服务器 + +要获取任何服务器的帮助,使用 --help 标志: +```bash +lightrag-server --help +``` + +注意:如果您不需要 API 功能,可以使用以下命令安装不带 API 支持的基本包: +```bash +pip install lightrag-hku +``` + +## API 端点 + +所有服务器(LoLLMs、Ollama、OpenAI 和 Azure OpenAI)都为 RAG 功能提供相同的 REST API 端点。当 API 服务器运行时,访问: + +- Swagger UI:http://localhost:9621/docs +- ReDoc:http://localhost:9621/redoc + +您可以使用提供的 curl 命令或通过 Swagger UI 界面测试 API 端点。确保: + +1. 启动适当的后端服务(LoLLMs、Ollama 或 OpenAI) +2. 启动 RAG 服务器 +3. 使用文档管理端点上传一些文档 +4. 使用查询端点查询系统 +5. 如果在输入目录中放入新文件,触发文档扫描 + +### 查询端点 + +#### POST /query +使用不同搜索模式查询 RAG 系统。 + +```bash +curl -X POST "http://localhost:9621/query" \ + -H "Content-Type: application/json" \ + -d '{"query": "您的问题", "mode": "hybrid", ""}' +``` + +#### POST /query/stream +从 RAG 系统流式获取响应。 + +```bash +curl -X POST "http://localhost:9621/query/stream" \ + -H "Content-Type: application/json" \ + -d '{"query": "您的问题", "mode": "hybrid"}' +``` + +### 文档管理端点 + +#### POST /documents/text +直接将文本插入 RAG 系统。 + +```bash +curl -X POST "http://localhost:9621/documents/text" \ + -H "Content-Type: application/json" \ + -d '{"text": "您的文本内容", "description": "可选描述"}' +``` + +#### POST /documents/file +向 RAG 系统上传单个文件。 + +```bash +curl -X POST "http://localhost:9621/documents/file" \ + -F "file=@/path/to/your/document.txt" \ + -F "description=可选描述" +``` + +#### POST /documents/batch +一次上传多个文件。 + +```bash +curl -X POST "http://localhost:9621/documents/batch" \ + -F "files=@/path/to/doc1.txt" \ + -F "files=@/path/to/doc2.txt" +``` + +#### POST /documents/scan + +触发输入目录中新文件的文档扫描。 + +```bash +curl -X POST "http://localhost:9621/documents/scan" --max-time 1800 +``` + +> 根据所有新文件的预计索引时间调整 max-time。 + +#### DELETE /documents + +从 RAG 系统中清除所有文档。 + +```bash +curl -X DELETE "http://localhost:9621/documents" +``` + +### Ollama 模拟端点 + +#### GET /api/version + +获取 Ollama 版本信息。 + +```bash +curl http://localhost:9621/api/version +``` + +#### GET /api/tags + +获取 Ollama 可用模型。 + +```bash +curl http://localhost:9621/api/tags +``` + +#### POST /api/chat + +处理聊天补全请求。通过根据查询前缀选择查询模式将用户查询路由到 LightRAG。检测并将 OpenWebUI 会话相关请求(用于元数据生成任务)直接转发给底层 LLM。 + +```shell +curl -N -X POST http://localhost:9621/api/chat -H "Content-Type: application/json" -d \ + '{"model":"lightrag:latest","messages":[{"role":"user","content":"猪八戒是谁"}],"stream":true}' +``` + +> 有关 Ollama API 的更多信息,请访问:[Ollama API 文档](https://github.com/ollama/ollama/blob/main/docs/api.md) + +#### POST /api/generate + +处理生成补全请求。为了兼容性目的,该请求不由 LightRAG 处理,而是由底层 LLM 模型处理。 + +### 实用工具端点 + +#### GET /health +检查服务器健康状况和配置。 + +```bash +curl "http://localhost:9621/health" + +```