LLMIndex的使用
本文介绍如何使用LangChain框架构建本地RAG(检索增强生成)系统,实现基于私有知识的LLM问答。通过Python代码示例,详细展示了从加载文档、文本分块、向量化存储到配置本地Qwen模型和构建RAG链的完整流程。该系统利用FAISS向量数据库进行高效检索,结合本地部署的LLM保障数据隐私。相比LlamaIndex,LangChain更适合简单RAG场景,提供模块化的链式编程体验。文章还解释
在大语言模型(LLM)快速发展的今天,如何让模型基于我们自己的私有知识进行准确回答,成为了一个关键问题。检索增强生成(Retrieval-Augmented Generation, RAG)正是解决这一问题的有效范式。本文将通过一段完整的 Python 代码,带你使用 LangChain 框架构建一个本地 RAG 系统,并借此介绍 LLM 应用开发中的核心组件——虽然标题提到“LLMIndex”,但实际在 LangChain 生态中,我们更常使用 FAISS、Chroma 等向量数据库来实现类似功能(注:LLMIndex 是 LlamaIndex 项目的核心概念,而本文使用的是 LangChain)。
📌 说明:本文示例基于 LangChain + 本地运行的 Qwen 模型(通过
http://127.0.0.1:1234/v1提供 OpenAI 兼容 API),适合希望在本地部署私有知识问答系统的开发者。
一、准备工作
pip install langchain langchain-community langchain-openai python-dotenv faiss-cpu
同时,你需要:
- 一个本地运行的大模型服务(如 LM Studio、Ollama 或 vLLM),并开启 OpenAI 兼容 API(端口 1234)。
- 一份名为
knowledge.txt的文本知识库文件(UTF-8 编码)。 - 在
.env文件中配置OPENAI_API_KEY(即使使用本地模型,LangChain 仍要求提供 API Key,可设为任意字符串,如sk-local)。
二、代码解析:构建 RAG 流程
1. 加载环境变量与文档
load_dotenv()
api_key = os.getenv("OPENAI_API_KEY")
loader = TextLoader("knowledge.txt", encoding="utf-8")
documents = loader.load()
这里我们使用 TextLoader 读取本地知识文件。LangChain 支持多种格式(PDF、Word、网页等),可根据需求替换加载器。
2. 文本分块(Chunking)
text_splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=50)
texts = text_splitter.split_documents(documents)
由于 LLM 有上下文长度限制,需将长文档切分为小段。RecursiveCharacterTextSplitter 按字符递归分割,保留语义连贯性,chunk_overlap 避免信息割裂。
3. 向量化与向量存储
embeddings = OpenAIEmbeddings(
model="text-embedding-qwen3-embedding-0.6b",
api_key=api_key,
base_url="http://127.0.0.1:1234/v1"
)
vectorstore = FAISS.from_documents(texts, embeddings)
关键点来了!我们使用 本地嵌入模型(如 Qwen Embedding)将文本转换为向量,并存入 FAISS(Facebook 开源的高效相似性搜索库)。这一步相当于构建了“知识索引”——类似于 LlamaIndex 中的 VectorStoreIndex。
4. 配置本地大语言模型
llm = ChatOpenAI(
model='qwen2.5-7b-instruct-1m',
api_key=api_key,
base_url="http://127.0.0.1:1234/v1"
)
通过 OpenAI 兼容接口调用本地 Qwen 模型,无需联网,保障数据隐私。
5. 构建 RAG 链
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
template = """使用以下上下文片段来回答问题。
如果你不知道答案,就说你不知道,不要编造答案。
{context}
问题: {question}
有用的回答:"""
prompt = ChatPromptTemplate.from_template(template)
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
qa_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
这是 LangChain 的精髓:声明式链式编程。
retriever从向量库中找出最相关的 3 个文本块;format_docs将检索结果拼接成字符串;prompt注入上下文和问题;llm生成答案;StrOutputParser提取纯文本。
整个流程清晰、模块化,易于调试和扩展。
6. 提问与输出
query = "LangChain 支持哪些功能?"
result = qa_chain.invoke(query)
print("问题:", query)
print("回答:", result)
系统会自动检索 knowledge.txt 中相关内容,并基于上下文生成精准回答。
三、为什么不用 LlamaIndex?
你可能会问:既然提到了 “LLMIndex”,为什么不直接用 LlamaIndex?
- LlamaIndex 更专注于 数据索引与查询优化,适合复杂知识图谱、多模态索引等场景;
- LangChain 则是一个 通用 LLM 应用框架,强调链式组合、工具集成(如 Agent、Memory)。
两者并非互斥,甚至可以结合使用。但在简单 RAG 场景下,LangChain + FAISS 已足够高效。
更多推荐

所有评论(0)