基于 LlaMA 3 + LangGraph 在Windows本地构建RAG智能体(一)

📅 2026/7/13 13:07:59
基于 LlaMA 3 + LangGraph 在Windows本地构建RAG智能体(一)
1. 为什么要在Windows本地构建RAG智能体最近两年大语言模型LLM的发展速度简直让人眼花缭乱。从最初的ChatGPT到现在的Llama 3模型的性能越来越强但同时也带来了一个现实问题这些模型往往需要强大的云端算力支持。对于很多开发者来说尤其是个人开发者和小团队云端API的成本和隐私问题成了拦路虎。这就是为什么我们要在本地部署大模型。想象一下你有一个私人助理它不仅能理解你的问题还能从你指定的文档中查找答案而且所有数据都在你的电脑上处理完全不用担心隐私泄露。这就是RAG检索增强生成智能体的魅力所在。我在实际项目中测试过使用Llama 3-8B模型在消费级显卡比如RTX 3060 12GB上运行完全可行。配合LangGraph的工作流编排能力你可以构建一个能理解上下文、能自我验证答案准确性的智能系统。最棒的是整个过程不需要连接任何外部服务器所有数据处理都在本地完成。2. 环境准备与依赖安装2.1 硬件与系统要求在开始之前我们先看看需要准备什么。我建议至少满足以下配置操作系统Windows 10/11 64位内存16GB以上32GB更佳显卡NVIDIA显卡至少8GB显存RTX 3060及以上存储空间至少20GB可用空间用于模型和依赖如果你没有独立显卡也可以用纯CPU模式运行但速度会慢很多。我测试过在i7-12700K上运行Llama 3-8B生成速度大约2-3个token/秒勉强可用但不适合生产环境。2.2 安装Python和必要工具首先确保你安装了Python 3.10或更高版本。我强烈建议使用Miniconda创建虚拟环境避免污染系统Python环境conda create -n llama3 python3.10 conda activate llama3接下来安装CUDA工具包如果你有NVIDIA显卡。到NVIDIA官网下载对应版本的CUDA Toolkit目前推荐12.1版本安装时记得勾选添加到PATH选项。2.3 安装核心依赖现在我们来安装必要的Python包。这里我推荐使用pip的-q参数减少输出干扰pip install -q torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 pip install -q ollama langchain beautifulsoup4 chromadb gradio unstructured langchain-nomic langchain_community tiktoken langchainhub langgraph gpt4all这些包包含了我们需要的所有核心功能torchPyTorch深度学习框架ollamaLlama模型的本地运行接口langchain和langgraph工作流编排的核心chromadb向量数据库用于存储文档嵌入gradio快速构建演示界面特别提醒如果你遇到unstructured安装问题可能需要额外安装系统依赖pip install unstructured[all-docs]3. 下载并配置Llama 3模型3.1 获取模型权重现在我们来下载Llama 3模型。使用ollama可以非常方便地获取官方优化过的模型ollama pull llama3这个命令会自动下载最新的Llama 3-8B模型约4.7GB。如果你想使用更大的70B模型需要32GB以上显存可以运行ollama pull llama3:70b下载完成后可以用以下命令验证ollama list你应该能看到类似输出NAME ID SIZE MODIFIED llama3:latest 365c0bd3c000 4.7GB 2 days ago3.2 模型量化与性能权衡原始模型对显存要求很高所以我们通常使用量化版本来降低资源消耗。量化是一种降低模型精度来减少内存占用的技术。ollama默认使用4-bit量化这是一个很好的平衡点。我在RTX 3060 12GB上测试过不同量化级别的表现4-bit流畅运行显存占用约8GB8-bit质量更好但显存占用约10GB16-bit接近原始质量但需要16GB以上显存对于大多数应用场景4-bit量化已经足够好了。如果你有更强的显卡可以尝试更高精度的版本ollama pull llama3:8b-instruct-q8_04. LangGraph基础与工作流设计4.1 什么是LangGraphLangGraph是LangChain生态系统中的一个新成员它专门用于构建复杂的AI工作流。你可以把它想象成一个流程图工具但专门为AI任务设计。它基于状态图的概念允许你定义不同的节点和边控制信息如何在系统中流动。我在实际项目中发现LangGraph特别适合构建需要多步骤决策的AI系统。比如一个问答系统可能需要理解用户问题决定是否需要检索文档如果需要从哪些来源检索如何组合检索结果生成最终答案如何验证答案的准确性4.2 构建第一个状态图让我们从一个简单的例子开始。创建一个Python文件basic_graph.pyfrom langgraph.graph import StateGraph, END # 定义状态结构 class AgentState(TypedDict): input: str output: str # 定义节点函数 def node_echo(state: AgentState): return {output: f你说了: {state[input]}} # 创建图 workflow StateGraph(AgentState) # 添加节点 workflow.add_node(echo, node_echo) # 设置入口点 workflow.set_entry_point(echo) # 设置结束点 workflow.add_edge(echo, END) # 编译图 app workflow.compile()这个简单的图只有一个节点它接收输入并返回一个带前缀的字符串。你可以这样运行它result app.invoke({input: 你好世界}) print(result[output]) # 输出: 你说了: 你好世界4.3 添加条件分支真正的强大之处在于条件分支。让我们扩展上面的例子添加一个决策节点from langgraph.graph import StateGraph, END from typing import Literal class AgentState(TypedDict): input: str output: str decision: Literal[echo, reverse] def node_echo(state: AgentState): return {output: f你说了: {state[input]}} def node_reverse(state: AgentState): return {output: f反转后: {state[input][::-1]}} def node_decide(state: AgentState): if len(state[input]) 5: return {decision: reverse} return {decision: echo} workflow StateGraph(AgentState) workflow.add_node(decide, node_decide) workflow.add_node(echo, node_echo) workflow.add_node(reverse, node_reverse) workflow.set_entry_point(decide) workflow.add_edge(echo, END) workflow.add_edge(reverse, END) workflow.add_conditional_edges( decide, lambda state: state[decision], {echo: echo, reverse: reverse} ) app workflow.compile()现在这个图会根据输入长度决定是直接回显还是反转字符串。试试看print(app.invoke({input: hi})[output]) # 输出: 你说了: hi print(app.invoke({input: hello world})[output]) # 输出: 反转后: dlrow olleh5. 构建完整的RAG智能体5.1 文档加载与处理RAG的核心是从文档中检索相关信息。首先我们需要准备文档并转换为向量存储。创建一个新文件rag_agent.pyfrom langchain_community.document_loaders import DirectoryLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.vectorstores import Chroma from langchain_community.embeddings import OllamaEmbeddings # 加载文档 loader DirectoryLoader(./docs, glob**/*.txt) documents loader.load() # 分割文档 text_splitter RecursiveCharacterTextSplitter( chunk_size1000, chunk_overlap200 ) splits text_splitter.split_documents(documents) # 创建向量存储 vectorstore Chroma.from_documents( documentssplits, embeddingOllamaEmbeddings(modelllama3) )这段代码会加载docs目录下的所有txt文件将它们分割成小块然后使用Llama 3的嵌入模型转换为向量存储在Chroma中。5.2 定义检索节点现在我们将检索功能集成到LangGraph中from langchain_core.runnables import RunnablePassthrough from langchain_core.output_parsers import StrOutputParser from langchain_core.prompts import ChatPromptTemplate # 检索器 retriever vectorstore.as_retriever() # 检索节点 def node_retrieve(state: dict): docs retriever.invoke(state[question]) return {docs: docs}5.3 定义生成节点生成节点负责调用Llama 3生成最终答案from langchain_community.chat_models import ChatOllama # LLM实例 llm ChatOllama(modelllama3) # 提示模板 template 基于以下上下文回答问题 {context} 问题: {question} prompt ChatPromptTemplate.from_template(template) # 生成链 chain ( {context: RunnablePassthrough(), question: RunnablePassthrough()} | prompt | llm | StrOutputParser() ) # 生成节点 def node_generate(state: dict): answer chain.invoke({ context: state[docs], question: state[question] }) return {answer: answer}5.4 组装完整工作流现在我们把所有节点组合起来from langgraph.graph import StateGraph, END from typing import TypedDict, List from langchain.schema import Document class AgentState(TypedDict): question: str docs: List[Document] answer: str # 创建图 workflow StateGraph(AgentState) # 添加节点 workflow.add_node(retrieve, node_retrieve) workflow.add_node(generate, node_generate) # 设置连接 workflow.set_entry_point(retrieve) workflow.add_edge(retrieve, generate) workflow.add_edge(generate, END) # 编译 app workflow.compile()5.5 测试智能体现在你可以这样使用这个RAG智能体result app.invoke({question: 文档中提到了哪些关键技术}) print(result[answer])这个智能体会自动从你的文档中检索相关信息然后生成基于这些信息的回答而不是凭空编造答案。