最近在帮团队落地大模型应用时,深刻体会到从零到一构建一个稳定、可用的企业级智能系统有多“酸爽”。网上资料要么是零散的API调用,要么是过于学术化的概念讲解,真正能把LangChain、RAG、Agent这几个核心模块串起来,讲清楚从环境搭建、数据处理到生产部署全流程的实战教程少之又少。很多开发者卡在工具调用、知识库构建和智能体逻辑编排这些关键环节,导致项目迟迟无法上线。
本文旨在解决这个痛点。我将结合多个真实项目经验,为你拆解一套完整的、可落地的企业级大模型应用开发方案。从LangChain基础环境配置开始,手把手带你构建一个功能完备的RAG知识库问答系统,并在此基础上进阶开发一个能自主调用工具、完成复杂任务的智能体(Agent)。全程附带可运行的代码、避坑指南和性能优化建议,确保你学完就能动手,掌握企业级项目开发的核心技能。
1. 背景与核心概念:为什么需要LangChain、RAG与Agent?
在深入代码之前,我们必须先理清这几个核心概念以及它们要解决的问题。这能帮助你在后续开发中做出正确的技术选型和架构设计。
1.1 大模型应用的挑战与LangChain的定位
大语言模型(LLM)能力强大,但直接将其集成到业务系统中会面临诸多挑战:
- 上下文长度限制:模型无法记住和处理超长的对话或文档。
- 知识滞后性:模型的训练数据有截止日期,无法获取最新、最专业的领域知识。
- “幻觉”问题:模型可能会生成看似合理但完全错误的信息。
- 缺乏行动能力:模型本身无法执行查询数据库、调用API等具体操作。
LangChain应运而生,它不是一个新模型,而是一个用于开发由大语言模型驱动的应用程序的框架。它的核心价值在于提供了模块化的组件和链(Chain),让你能像搭积木一样,将LLM与外部数据源、工具、记忆系统等连接起来,构建出功能复杂的应用。简单说,LangChain是大模型应用的“粘合剂”和“脚手架”。
1.2 RAG:为模型注入专业知识和最新信息
RAG(Retrieval-Augmented Generation,检索增强生成)是解决模型知识滞后和幻觉问题的关键技术。其核心思想不是让模型“记住”所有知识,而是让模型学会“查阅资料”。
RAG系统的工作流程通常分为三步:
- 索引(Index):将你的私有文档(如产品手册、公司制度、技术文档)进行切分、向量化,并存入向量数据库。
- 检索(Retrieve):当用户提问时,系统将问题也转化为向量,并在向量数据库中搜索与之最相关的文档片段。
- 生成(Generate):将检索到的相关片段(作为上下文)和用户问题一起提交给LLM,让LLM基于这些可靠的上下文生成答案。
这样,答案的准确性不再完全依赖于模型的原始知识,而是依赖于你提供的可靠文档,极大地提升了专业领域问答的可靠性。
1.3 Agent:让模型拥有思考和行动的能力
如果说RAG扩展了模型的“知识”,那么Agent(智能体)则扩展了模型的“能力”。
一个基础的LLM只能进行文本对话。而一个Agent是一个具备自主性的系统,它以大语言模型为“大脑”,可以根据目标、结合上下文记忆、自主地规划、调用工具、执行动作并观察结果,最终完成复杂任务。
例如,一个数据分析Agent的任务可能是“分析上周的销售情况并生成报告”。它会自主规划:先调用工具A查询数据库获取销售数据,再调用工具B进行数据可视化,最后用LLM总结成报告。LangChain提供了Agent、Tool、AgentExecutor等核心组件来构建这样的智能体。
三者关系总结:LangChain是构建应用的框架;RAG是基于LangChain的一种用于增强知识的具体模式;Agent是基于LangChain的一种用于赋予行动能力的具体模式。在实际项目中,RAG和Agent常常结合使用,例如一个客服Agent可以先通过RAG检索知识库,再调用工单系统创建任务。
2. 环境准备与版本说明
本教程将构建一个完整的项目,建议使用Python 3.9及以上版本。我们将使用LangChain的主流社区版本,并搭配Chroma作为向量数据库(轻量易用),以及OpenAI的GPT模型作为LLM核心(也可替换为本地模型如Ollama)。
2.1 创建项目与虚拟环境
首先,创建一个干净的项目目录并设置独立的Python环境,这是管理依赖的最佳实践。
# 创建项目目录 mkdir enterprise-llm-app && cd enterprise-llm-app # 创建并激活虚拟环境 (Linux/macOS) python -m venv venv source venv/bin/activate # 创建并激活虚拟环境 (Windows) python -m venv venv venv\Scripts\activate2.2 安装核心依赖
创建requirements.txt文件,并安装以下依赖。请注意,LangChain社区活跃,版本更新较快,以下版本为当前稳定版本,未来如有变化请以官方文档为准。
# requirements.txt langchain==0.1.0 langchain-community==0.0.10 # 包含社区维护的集成工具 langchain-openai==0.0.5 # OpenAI集成 langchain-chroma==0.1.0 # Chroma向量数据库集成 chromadb==0.4.22 # Chroma客户端 openai==1.6.1 # OpenAI官方SDK tiktoken==0.5.2 # 用于Token计数 python-dotenv==1.0.0 # 管理环境变量 pypdf==3.17.0 # 用于读取PDF文档 unstructured==0.12.2 # 用于解析多种格式文档使用pip安装:
pip install -r requirements.txt2.3 配置API密钥与环境变量
为了安全地管理像OpenAI API Key这样的敏感信息,我们使用.env文件。
- 在项目根目录创建
.env文件。 - 从OpenAI官网获取你的API密钥,填入该文件。
# .env OPENAI_API_KEY="你的-openai-api-key-here" # 后续如需使用其他服务,如SerpAPI(谷歌搜索),也可在此添加 # SERPAPI_API_KEY="your-serpapi-key"重要:务必在.gitignore文件中添加.env,避免将密钥提交到代码仓库。
3. 核心模块拆解:LangChain基础组件
在开始实战前,快速理解几个最核心的LangChain组件,它们是你构建应用的基石。
3.1 模型I/O (LLMs & Chat Models)
这是与LLM交互的入口。LLM组件用于文本补全式调用,而ChatModel用于更结构化的对话式调用(推荐)。
# 文件:demo_basic_llm.py from langchain_openai import ChatOpenAI from langchain.schema import HumanMessage, SystemMessage from dotenv import load_dotenv load_dotenv() # 加载.env文件中的环境变量 # 初始化Chat模型,指定模型名称和温度(创造性) llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0) # 简单调用 response = llm.invoke("什么是LangChain?") print(response.content) # 结构化消息调用(更接近真实对话场景) messages = [ SystemMessage(content="你是一个专业的Python工程师。"), HumanMessage(content="请用Python写一个快速排序函数。") ] response = llm.invoke(messages) print(response.content)3.2 提示模板 (Prompt Templates)
为了避免在代码中硬编码提示词,使用PromptTemplate来抽象和复用提示逻辑。
# 文件:demo_prompt_template.py from langchain.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI prompt_template = ChatPromptTemplate.from_messages([ ("system", "你是一位{style}风格的技术作家。"), ("user", "请为{technology}写一段简介。") ]) # 填充模板,生成最终的提示消息列表 formatted_messages = prompt_template.format_messages( style="幽默风趣", technology="RAG" ) print(formatted_messages) llm = ChatOpenAI(model="gpt-3.5-turbo") response = llm.invoke(formatted_messages) print(response.content)3.3 链 (Chains)
Chain是将多个组件(模型、提示、工具等)按顺序组合起来的工作流。LCEL(LangChain Expression Language) 是推荐的新语法,用管道符|连接组件,非常直观。
# 文件:demo_chain_lcel.py from langchain.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI from langchain.schema.output_parser import StrOutputParser # 定义提示模板 prompt = ChatPromptTemplate.from_template("用不超过一句话解释{concept}") # 定义模型 llm = ChatOpenAI(model="gpt-3.5-turbo") # 定义输出解析器(将模型输出解析为字符串) output_parser = StrOutputParser() # 使用 LCEL 创建链: prompt -> llm -> output_parser chain = prompt | llm | output_parser # 运行链 result = chain.invoke({"concept": "向量数据库"}) print(result) # 输出:向量数据库是一种专门用于高效存储和检索高维向量数据(如图像、文本嵌入)的数据库系统。3.4 检索器 (Retrievers) 与向量存储 (Vectorstores)
这是RAG的核心。Vectorstore负责存储和检索向量化的文档片段。
# 这是一个概念示例,具体创建过程在下一章实战中体现 from langchain_chroma import Chroma from langchain_openai import OpenAIEmbeddings from langchain.schema import Document # 1. 准备文档 docs = [ Document(page_content="LangChain是一个用于开发大语言模型应用的框架。"), Document(page_content="RAG通过检索外部知识来增强大模型生成答案的准确性。"), ] # 2. 创建嵌入模型(用于将文本转为向量) embeddings = OpenAIEmbeddings(model="text-embedding-3-small") # 3. 将文档存入向量数据库(Chroma),并自动创建检索器 vectorstore = Chroma.from_documents(documents=docs, embedding=embeddings, persist_directory="./chroma_db") # 4. 获取检索器 retriever = vectorstore.as_retriever(search_kwargs={"k": 1}) # 检索最相关的1个片段 # 5. 进行检索 relevant_docs = retriever.invoke("什么是LangChain?") print(relevant_docs[0].page_content)4. 完整实战一:构建企业级RAG知识库问答系统
现在,我们将综合运用上述组件,构建一个完整的RAG系统。假设我们有一些公司内部的产品PDF文档,需要构建一个能回答相关问题的智能助手。
4.1 项目结构准备
创建如下项目结构:
enterprise-llm-app/ ├── .env ├── requirements.txt ├── app.py # 主应用入口 ├── core/ │ ├── __init__.py │ ├── knowledge_base.py # 知识库构建与加载模块 │ └── qa_chain.py # 问答链构建模块 ├── data/ # 存放原始文档(如PDF) │ └── product_manual.pdf └── chroma_db/ # 向量数据库持久化目录(自动生成)4.2 知识库构建模块
core/knowledge_base.py负责文档加载、切分、向量化并持久化存储。
# 文件:core/knowledge_base.py import os from langchain_community.document_loaders import PyPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_openai import OpenAIEmbeddings from langchain_chroma import Chroma from dotenv import load_dotenv load_dotenv() class KnowledgeBase: def __init__(self, persist_directory: str = "./chroma_db"): """初始化知识库,设置向量数据库路径和嵌入模型。""" self.persist_directory = persist_directory self.embeddings = OpenAIEmbeddings(model="text-embedding-3-small") # 如果已有持久化数据,则直接加载;否则创建一个空的 if os.path.exists(self.persist_directory): self.vectorstore = Chroma( persist_directory=self.persist_directory, embedding_function=self.embeddings ) print(f"已加载现有知识库,来自 {self.persist_directory}") else: self.vectorstore = None print("未找到现有知识库,请先执行 `build` 方法构建。") def build(self, data_dir: str): """ 从指定目录构建知识库。 参数: data_dir: 存放文档(如PDF)的目录路径。 """ documents = [] # 1. 加载文档:遍历目录,加载所有PDF文件 for filename in os.listdir(data_dir): if filename.endswith('.pdf'): file_path = os.path.join(data_dir, filename) print(f"正在加载文档: {file_path}") loader = PyPDFLoader(file_path) docs = loader.load() # 加载出的是一组Document对象 documents.extend(docs) if not documents: print("未在指定目录中找到任何PDF文档。") return # 2. 分割文本:将长文档切分成适合检索的小片段 text_splitter = RecursiveCharacterTextSplitter( chunk_size=500, # 每个片段大约500字符 chunk_overlap=50, # 片段间重叠50字符,保持上下文连贯 separators=["\n\n", "\n", "。", "!", "?", ",", " ", ""] ) splits = text_splitter.split_documents(documents) print(f"文档已分割为 {len(splits)} 个文本片段。") # 3. 向量化并存储:将文本片段转换为向量,存入ChromaDB self.vectorstore = Chroma.from_documents( documents=splits, embedding=self.embeddings, persist_directory=self.persist_directory ) print(f"知识库构建完成,已保存至 {self.persist_directory}") def get_retriever(self, search_type="similarity", k=4): """ 获取检索器。 参数: search_type: 检索类型,如 "similarity"(相似度), "mmr"(最大边际相关性去重) k: 返回的最相关片段数量。 返回: 一个检索器对象。 """ if self.vectorstore is None: raise ValueError("知识库未初始化或未构建,请先调用 `build` 方法。") return self.vectorstore.as_retriever(search_type=search_type, search_kwargs={"k": k}) if __name__ == "__main__": # 本地测试:构建知识库 kb = KnowledgeBase() kb.build("./data") # 假设你的PDF文档放在 ./data 目录下4.3 问答链构建模块
core/qa_chain.py负责组合检索器和LLM,形成完整的“检索-生成”流水线。
# 文件:core/qa_chain.py from langchain.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI from langchain.schema.runnable import RunnablePassthrough from langchain.schema.output_parser import StrOutputParser from dotenv import load_dotenv load_dotenv() def create_rag_chain(retriever): """ 创建一个RAG问答链。 参数: retriever: 知识库检索器。 返回: 一个可调用的RAG链。 """ # 定义提示模板,其中 {context} 和 {question} 是占位符 template = """你是一个专业的客服助手,请严格根据以下上下文信息来回答问题。 如果上下文信息中没有相关答案,请直接说“根据现有资料,我无法回答这个问题”,不要编造信息。 上下文信息: {context} 问题: {question} 请根据上下文提供准确、有用的答案:""" prompt = ChatPromptTemplate.from_template(template) # 初始化LLM llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0) # 使用LCEL定义RAG链 # 1. 将用户问题传入检索器,获取上下文 # 2. 将上下文和原始问题格式化到提示词中 # 3. 发送给LLM # 4. 解析输出 rag_chain = ( {"context": retriever, "question": RunnablePassthrough()} | prompt | llm | StrOutputParser() ) return rag_chain if __name__ == "__main__": # 本地测试:需要先有构建好的知识库 from core.knowledge_base import KnowledgeBase kb = KnowledgeBase() retriever = kb.get_retriever(k=2) chain = create_rag_chain(retriever) # 提问测试 question = "你们产品的主要优势是什么?" answer = chain.invoke(question) print(f"问题:{question}") print(f"答案:{answer}")4.4 主应用入口
app.py提供一个简单的命令行交互界面。
# 文件:app.py import sys sys.path.append('.') # 确保可以导入core模块 from core.knowledge_base import KnowledgeBase from core.qa_chain import create_rag_chain def main(): print("=== 企业级RAG知识库问答系统 ===") print("1. 初始化/加载知识库...") kb = KnowledgeBase() # 如果知识库不存在,则构建(首次运行) if kb.vectorstore is None: print("首次运行,需要构建知识库。") data_path = input("请输入存放文档的目录路径(例如 ./data): ").strip() kb.build(data_path) else: print("知识库加载成功。") print("\n2. 准备问答链...") retriever = kb.get_retriever(k=4) # 检索4个最相关片段 qa_chain = create_rag_chain(retriever) print("\n3. 系统就绪!请输入您的问题(输入 'quit' 或 'exit' 退出)") print("-" * 50) while True: question = input("\n您的问题: ").strip() if question.lower() in ['quit', 'exit']: print("再见!") break if not question: continue try: answer = qa_chain.invoke(question) print(f"\n助手: {answer}") except Exception as e: print(f"\n出错: {e}") if __name__ == "__main__": main()4.5 运行与验证
- 将你的产品手册等PDF文档放入
./data目录。 - 在终端运行
python app.py。 - 首次运行会提示构建知识库,输入
./data。 - 构建完成后,即可开始提问。
预期效果:系统会从你提供的PDF中检索相关信息,并生成基于上下文的准确回答,对于文档未涉及的问题会明确表示无法回答,有效缓解“幻觉”问题。
5. 完整实战二:开发能调用工具的智能体(Agent)
在RAG的基础上,我们进一步提升系统的能力,创建一个能自主使用工具的智能体。例如,一个可以查询天气、计算数学、搜索网络的助手。
5.1 定义工具(Tools)
工具是Agent能力的延伸。我们先定义几个简单的工具。
# 文件:core/agent_tools.py from langchain.tools import tool import requests import json from datetime import datetime @tool def get_current_time(): """获取当前的日期和时间。""" now = datetime.now() return now.strftime("%Y-%m-%d %H:%M:%S") @tool def calculator(expression: str) -> str: """计算一个数学表达式的值。支持加减乘除(+-*/)和括号。 参数: expression: 数学表达式,例如 ‘(3+5)*2‘。 """ # 警告:在生产环境中,直接使用eval有安全风险,此处仅作演示。 # 实际应用应使用安全的数学表达式解析库,如 `asteval`。 try: result = eval(expression) return f"{expression} = {result}" except Exception as e: return f"计算错误: {e}" # 注意:以下是一个需要API密钥的示例工具,你需要先注册相关服务。 # @tool # def search_web(query: str) -> str: # """使用搜索引擎搜索网络信息。 # 参数: # query: 搜索关键词。 # """ # import os # from serpapi import GoogleSearch # params = { # "engine": "google", # "q": query, # "api_key": os.getenv("SERPAPI_API_KEY") # 需要在.env中配置 # } # search = GoogleSearch(params) # results = search.get_dict() # # 简化返回第一个结果 # if 'organic_results' in results and len(results['organic_results']) > 0: # first_result = results['organic_results'][0] # return f"{first_result.get('title')}: {first_result.get('link')}\n{first_result.get('snippet')}" # return "未找到相关结果。"5.2 创建智能体(Agent)
我们将使用LangChain的ReAct框架来创建Agent,它擅长推理和调用工具。
# 文件:core/agent.py from langchain_openai import ChatOpenAI from langchain.agents import create_react_agent, AgentExecutor from langchain.tools import Tool from langchain import hub # 用于拉取预定义的提示词 from core.agent_tools import get_current_time, calculator from core.qa_chain import create_rag_chain from core.knowledge_base import KnowledgeBase from dotenv import load_dotenv load_dotenv() def create_agent(): """创建并返回一个配置好的智能体执行器。""" # 1. 初始化LLM llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0) # 2. 准备工具列表 # 首先,加载我们之前构建的RAG系统作为一个“知识库查询工具” kb = KnowledgeBase() retriever = kb.get_retriever(k=2) rag_chain = create_rag_chain(retriever) # 将RAG链包装成一个Tool对象 rag_tool = Tool( name="Knowledge_Base", func=rag_chain.invoke, description="当需要回答关于公司产品、政策或内部知识的问题时,使用此工具。输入是一个具体的问题。" ) tools = [ rag_tool, get_current_time, calculator, # 可以在此处添加更多工具,如 search_web ] # 3. 拉取一个为ReAct Agent设计好的提示词模板 prompt = hub.pull("hwchase17/react-chat") # 4. 创建ReAct Agent agent = create_react_agent(llm, tools, prompt) # 5. 创建Agent执行器,它负责运行Agent并处理工具调用循环 agent_executor = AgentExecutor( agent=agent, tools=tools, verbose=True, # 设置为True可以看到Agent的思考过程,便于调试 handle_parsing_errors=True, # 优雅地处理解析错误 max_iterations=5, # 限制最大迭代次数,防止死循环 early_stopping_method="generate" # 当Agent认为任务完成时停止 ) return agent_executor if __name__ == "__main__": # 本地测试智能体 agent_executor = create_agent() result = agent_executor.invoke({ "input": "先查一下现在几点,然后计算一下(15-3)除以4等于多少?最后问问知识库,我们产品的主要优势是什么?" }) print("\n最终结果:", result["output"])5.3 运行智能体
运行python core/agent.py,你会看到类似以下的输出(verbose模式开启):
> Entering new AgentExecutor chain... 我需要按顺序完成三个任务:查时间、计算、询问知识库。 首先,我需要获取当前时间。有一个工具叫`get_current_time`。 Action: get_current_time Action Input: "" Observation: 2024-05-27 10:30:15 Thought: 时间获取到了。接下来计算 (15-3)除以4。使用`calculator`工具。 Action: calculator Action Input: (15-3)/4 Observation: (15-3)/4 = 3.0 Thought: 计算完成。最后询问产品优势。使用`Knowledge_Base`工具。 Action: Knowledge_Base Action Input: 我们产品的主要优势是什么? Observation: 根据上下文信息,我们产品的主要优势在于其高度的可集成性、卓越的性能和7x24小时的技术支持。 Thought: 我已经完成了所有三个任务。 Final Answer: 当前时间是2024-05-27 10:30:15。(15-3)除以4等于3.0。关于我们产品的主要优势,根据知识库信息,其优势在于高度的可集成性、卓越的性能和7x24小时的技术支持。 > Finished chain. 最终结果: 当前时间是2024-05-27 10:30:15。(15-3)除以4等于3.0。关于我们产品的主要优势,根据知识库信息,其优势在于高度的可集成性、卓越的性能和7x24小时的技术支持。可以看到,Agent成功规划了步骤,并依次调用了三个不同的工具,最终整合出了一个连贯的回答。
6. 常见问题与排查思路
在开发过程中,你可能会遇到以下典型问题。
| 问题现象 | 可能原因 | 排查思路与解决方案 |
|---|---|---|
ModuleNotFoundError: No module named ‘langchain_xxx‘ | 依赖未安装或版本不匹配。 | 1. 检查requirements.txt中的包名是否正确。2. 运行 pip list | grep langchain查看已安装版本。3. LangChain v0.1.x后很多集成移到了 langchain-community,确保已安装。 |
| OpenAI API调用报错(认证失败、额度不足) | API密钥错误、未设置环境变量、账户余额不足。 | 1. 检查.env文件中的OPENAI_API_KEY是否正确,且已通过load_dotenv()加载。2. 登录OpenAI平台检查API密钥状态和余额。 3. 尝试在代码中直接 print(os.getenv(‘OPENAI_API_KEY‘))确认密钥已加载。 |
| 向量数据库检索结果不相关 | 文本分割策略不当、嵌入模型不匹配、检索参数k不合适。 | 1. 调整RecursiveCharacterTextSplitter的chunk_size和chunk_overlap(通常500-1000,重叠50-100)。2. 确保构建和检索时使用相同的嵌入模型。 3. 尝试不同的检索类型,如 search_type=“mmr“可以在相关性和多样性间取得平衡。4. 检查原始文档质量。 |
| Agent陷入循环或调用错误工具 | 工具描述不清晰、LLM温度过高、提示词引导不足。 | 1. 为每个工具编写清晰、具体的description,说明其用途和输入格式。2. 将LLM的 temperature设为0,减少随机性。3. 在Agent的提示词中明确约束,例如“你必须根据工具描述选择最合适的一个”。 4. 设置 max_iterations(如5)防止无限循环。 |
| 处理长文档时程序内存占用高或速度慢 | 一次性加载所有文档、嵌入计算耗时。 | 1. 对于超大文档,考虑流式加载或分批处理。 2. 对于生产环境,考虑使用更高效的嵌入模型(如 text-embedding-3-small)或本地嵌入模型(如sentence-transformers)。3. 将向量数据库部署为独立服务(如Chroma Server)。 |
‘Document‘ object has no attribute ‘page_content‘ | LangChain版本升级,Document对象属性名变化。 | 较新版本中,Document的核心属性是page_content和metadata。如果出错,检查你使用的Document类来源(应来自from langchain.schema import Document)。 |
7. 最佳实践与工程建议
将原型推进到生产环境,需要关注以下方面:
7.1 性能优化
- 嵌入模型选择:OpenAI的嵌入模型效果好但需网络调用且有成本。对于内部应用,可评估本地模型如
all-MiniLM-L6-v2(通过sentence-transformers库),在精度和速度间取得平衡。 - 检索优化:
- 混合搜索:结合向量相似度搜索和关键词(如BM25)搜索,提升召回率。
- 重排序:先用向量检索出大量候选(如k=20),再用更精细的交叉编码器模型进行重排序,返回Top-k,显著提升精度。
- 元数据过滤:在存储文档时添加元数据(如文档类型、部门、日期),检索时进行过滤,缩小搜索范围。
- 缓存:对频繁相同的查询结果进行缓存(例如使用
langchain.cache配合SQLiteCache或RedisCache),大幅降低LLM调用成本和延迟。
7.2 可观测性与评估
- 记录日志:详细记录用户的提问、检索到的文档片段、LLM的回复、工具调用记录。这对调试和后续分析至关重要。
- 构建评估集:准备一组标准问题及其预期答案,定期运行测试,监控RAG系统答案质量的变化(如使用
RAGAS等评估框架)。 - 监控关键指标:检索延迟、LLM调用耗时与费用、用户反馈(如点赞/点踩)。
7.3 安全与合规
- 输入输出检查:对用户输入进行清洗,防止提示词注入攻击。对模型输出进行内容安全过滤。
- 权限控制:知识库文档应有访问权限控制。在检索前,根据用户身份过滤其可访问的文档元数据。
- 数据隐私:如果使用云端LLM API,确认你的业务数据(特别是通过提示词发送的)是否符合公司的数据出境和安全政策。必要时使用本地化模型。
7.4 架构演进
- 从单体到服务化:当系统变复杂,可将RAG检索服务、Agent推理服务、工具服务等拆分为独立的微服务。
- 引入编排引擎:对于非常复杂的Agent工作流(涉及多步骤、条件分支、循环),可以考虑使用LangGraph(LangChain的另一库)来以图的形式定义和控制工作流,这比基础的AgentExecutor更强大、更可控。
- 结合业务系统:将Agent的工具与内部业务系统(CRM、ERP、工单系统)的API对接,使其能真正驱动业务流程。
通过本教程,你不仅学会了如何使用LangChain搭建RAG和Agent,更重要的是掌握了构建企业级大模型应用的核心方法论和工程化思维。从环境搭建、核心概念理解、模块化开发到生产级优化,这套流程可以应用到大多数类似的智能系统开发中。
真正的掌握源于实践。建议你以本项目为蓝本,尝试接入真实的公司文档,定义几个有业务价值的工具(如查询数据库、发送邮件),构建一个能解决实际问题的智能助手。在这个过程中,你会更深入地理解各个组件的细节和调优方法。