文章目录
- 前言
- 一、LangChain框架基础认知
-
- [1.1 什么是LangChain](#1.1 什么是LangChain)
- [1.2 LangChain的核心优势](#1.2 LangChain的核心优势)
- [1.3 LangChain的典型应用场景](#1.3 LangChain的典型应用场景)
- [1.4 开发环境准备](#1.4 开发环境准备)
-
- [1.4.1 核心依赖安装](#1.4.1 核心依赖安装)
- [1.4.2 基础配置(以OpenAI为例)](#1.4.2 基础配置(以OpenAI为例))
- 二、LangChain核心架构与核心组件
-
- [2.1 核心架构解析](#2.1 核心架构解析)
- [2.2 核心组件详解](#2.2 核心组件详解)
-
- [2.2.1 提示词模板(Prompt Templates)](#2.2.1 提示词模板(Prompt Templates))
- [2.2.2 记忆(Memory)组件](#2.2.2 记忆(Memory)组件)
- [2.2.3 文档加载器(Document Loaders)与文本分割器(Text Splitters)](#2.2.3 文档加载器(Document Loaders)与文本分割器(Text Splitters))
- [2.2.4 向量存储(Vector Stores)与检索器(Retrievers)](#2.2.4 向量存储(Vector Stores)与检索器(Retrievers))
- [2.2.5 工具(Tools)与代理(Agents)](#2.2.5 工具(Tools)与代理(Agents))
- [2.2.6 链(Chains):组件的流程编排](#2.2.6 链(Chains):组件的流程编排)
- 三、LangChain实战:构建企业知识库问答系统
-
- [3.1 项目需求与架构设计](#3.1 项目需求与架构设计)
-
- [3.1.1 项目需求](#3.1.1 项目需求)
- [3.1.2 架构设计](#3.1.2 架构设计)
- [3.2 项目实现步骤](#3.2 项目实现步骤)
-
- [3.2.1 步骤1:环境准备与依赖安装](#3.2.1 步骤1:环境准备与依赖安装)
- [3.2.2 步骤2:文档处理与向量存储构建](#3.2.2 步骤2:文档处理与向量存储构建)
- [3.2.3 步骤3:构建问答链与API服务](#3.2.3 步骤3:构建问答链与API服务)
- [3.2.4 步骤4:项目测试与运行](#3.2.4 步骤4:项目测试与运行)
- 四、LangChain高级特性与性能优化
-
- [4.1 自定义组件开发](#4.1 自定义组件开发)
-
- [4.1.1 自定义提示词模板](#4.1.1 自定义提示词模板)
- [4.1.2 自定义工具](#4.1.2 自定义工具)
- [4.2 多模态LLM支持](#4.2 多模态LLM支持)
- [4.3 性能优化策略](#4.3 性能优化策略)
-
- [4.3.1 向量存储优化](#4.3.1 向量存储优化)
- [4.3.2 模型与检索优化](#4.3.2 模型与检索优化)
- [4.3.3 服务部署优化](#4.3.3 服务部署优化)
- 五、LangChain生态集成与社区资源
-
- [5.1 与主流技术的集成](#5.1 与主流技术的集成)
-
- [5.1.1 与Web框架集成](#5.1.1 与Web框架集成)
- [5.1.2 与向量数据库集成](#5.1.2 与向量数据库集成)
- [5.1.3 与开源LLM集成](#5.1.3 与开源LLM集成)
- [5.2 社区资源与学习渠道](#5.2 社区资源与学习渠道)
- 六、总结与扩展
-
- [6.1 核心知识点总结](#6.1 核心知识点总结)
前言
在大语言模型(LLM)产业化落地的浪潮中,单纯依赖LLM原生API已难以支撑复杂应用场景的开发需求。LangChain作为一款专注于LLM应用开发的开源框架,通过"组件化封装+流程化编排"的核心思想,打通了LLM与外部数据、工具的连接通道,大幅降低了智能应用的开发门槛。本文采用总分总编写模式,从LangChain的基础认知出发,逐步深入核心架构、核心组件、实战开发、高级特性及生态集成,结合理论讲解与可运行代码示例,系统梳理关键知识点。最后将通过专章总结全文核心内容、进行知识点扩展,并推荐优质阅读资料,助力开发者快速上手并深化LangChain应用能力。
一、LangChain框架基础认知
1.1 什么是LangChain
LangChain是2022年由Harrison Chase推出的开源开发框架,核心定位是"连接大语言模型与真实世界"。它并非替代LLM,而是为LLM应用开发提供一套标准化的组件和流程编排能力,解决了LLM原生能力的三大痛点:一是上下文窗口有限,无法处理长文本;二是无法直接访问外部动态数据(如实时新闻、企业内部文档);三是缺乏与外部工具交互的能力(如搜索引擎、数据库、办公软件)。
LangChain支持Python和JavaScript/TypeScript双语言生态,其中Python版本功能更完善、社区更活跃,是当前主流的开发选择。其核心价值在于"模块化"与"可扩展性",开发者可像搭积木一样组合各类组件,快速构建从简单对话机器人到复杂智能代理的各类LLM应用。
1.2 LangChain的核心优势
-
外部数据无缝集成:提供丰富的文档加载器(Document Loaders),支持PDF、Word、网页、数据库等多种来源数据的加载与处理,轻松实现"检索增强生成(RAG)",让LLM基于专属数据生成回答。
-
强大的工具调用能力:内置数十种常用工具(搜索引擎、计算器、代码执行器等),支持自定义工具扩展,通过代理(Agents)组件让LLM自主决策工具调用逻辑,完成复杂任务。
-
灵活的记忆机制:提供多种记忆(Memory)组件,实现对话历史的存储、管理与复用,让应用具备多轮对话上下文理解能力。
-
跨LLM兼容性:支持对接OpenAI、Anthropic、Google Gemini、开源LLM(Llama 2、ChatGLM、Qwen)等主流模型,开发者可灵活切换底层模型,降低对单一供应商的依赖。
-
完善的生态体系:集成向量数据库、Web框架、工作流工具等各类生态组件,提供丰富的模板和示例,加速应用开发流程。
1.3 LangChain的典型应用场景
LangChain的应用场景覆盖LLM落地的核心领域,典型场景包括:
-
检索增强生成(RAG)系统:企业知识库问答、文档问答、产品手册咨询、法律文书检索等。
-
智能对话机器人:多轮客服机器人、个人助手、教育辅导机器人、行业专属咨询机器人。
-
智能代理(AI Agents):自动报告生成、数据分析与可视化、代码生成与调试、自动化办公(邮件撰写、日程规划)。
-
文档处理与分析:多文档摘要、文档对比分析、文档格式转换、合同审核。
-
教育与内容创作:个性化学习方案生成、论文辅助写作、营销文案创作、剧本生成。
1.4 开发环境准备
1.4.1 核心依赖安装
以Python环境为例,LangChain核心依赖安装命令如下:
bash
# 创建并激活虚拟环境(可选)
python -m venv langchain-env
# Windows激活
langchain-env\Scripts\activate
# Mac/Linux激活
source langchain-env/bin/activate
# 安装LangChain核心库
pip install langchain
# 安装常用依赖(根据开发需求选择)
# 1. 对接OpenAI模型
pip install openai
# 2. 文档处理(PDF、Word等)
pip install pypdf python-docx beautifulsoup4
# 3. 向量数据库(本地轻量版)
pip install chromadb
# 4. Web框架(用于构建API服务)
pip install fastapi uvicorn
# 5. 开源LLM支持(以Llama 2为例)
pip install transformers accelerate
1.4.2 基础配置(以OpenAI为例)
使用LangChain对接LLM前,需配置模型API密钥。推荐通过环境变量配置,避免密钥泄露:
python
import os
from langchain_openai import ChatOpenAI
# 方式1:通过环境变量配置(推荐)
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"
# 方式2:直接在代码中配置(仅用于测试)
llm = ChatOpenAI(
api_key="your-openai-api-key",
model_name="gpt-3.5-turbo", # 模型名称
temperature=0.7, # 随机性:0-1,值越小越严谨
max_tokens=2048 # 最大生成Token数
)
# 测试模型连接
response = llm.invoke("请简要介绍LangChain框架")
print(response.content)
二、LangChain核心架构与核心组件

2.1 核心架构解析
LangChain的核心架构围绕"组件(Components)"和"链(Chains)"展开,整体分为三层,呈现"底层支撑-中层编排-上层应用"的结构:
-
基础组件层:最底层的核心模块,包括提示词模板、LLM封装、文档加载器、记忆、工具等,是构建所有应用的基础,具备高度可复用性。
-
链层:将多个基础组件按业务逻辑编排成的工作流,解决单一组件无法完成复杂任务的问题。如"提示词模板+LLM"的基础链、"检索器+LLM"的RAG链等。
-
应用层:基于链和组件构建的具体应用模板,如对话机器人、智能代理、RAG系统等,开发者可直接复用或基于模板二次开发。
核心设计思想是"组合优于继承",通过组件的灵活组合实现功能扩展,而非通过复杂的类继承关系,大幅提升了开发效率和灵活性。
2.2 核心组件详解
2.2.1 提示词模板(Prompt Templates)
提示词是LLM生成符合预期结果的关键,提示词模板则是LangChain中用于动态生成提示词的组件。它允许开发者定义固定的提示词结构,通过传入参数动态填充内容,避免重复编写相似提示词。
核心功能:动态参数填充、提示词格式校验、多轮对话提示词管理、自定义模板逻辑。
代码示例1:基础提示词模板
python
from langchain.prompts import PromptTemplate
# 定义模板:包含2个参数(product-产品名,audience-目标人群)
prompt_template = PromptTemplate(
input_variables=["product", "audience"],
template="请为{product}撰写一句面向{audience}的宣传语,要求简洁有力、突出产品核心优势。"
)
# 动态填充参数生成提示词
prompt = prompt_template.format(
product="智能降噪耳机",
audience="职场通勤人群"
)
# 调用LLM生成结果
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.8)
response = llm.invoke(prompt)
print("生成的宣传语:", response.content)
代码示例2:多轮对话模板(ChatPromptTemplate)
python
from langchain.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate
# 1. 系统提示:设定LLM的角色和行为准则
system_prompt = SystemMessagePromptTemplate.from_template(
"你是一名专业的产品文案顾问,擅长结合产品特性和目标人群痛点撰写宣传语。"
)
# 2. 人类提示:接收用户输入的动态参数
human_prompt = HumanMessagePromptTemplate.from_template(
"产品:{product},核心优势:{advantage},目标人群:{audience},请撰写3句宣传语。"
)
# 3. 组合为对话模板
chat_prompt_template = ChatPromptTemplate.from_messages([system_prompt, human_prompt])
# 4. 填充参数并生成提示词
prompt = chat_prompt_template.format_prompt(
product="便携式充电宝",
advantage="20000mAh容量、双向快充、轻薄便携",
audience="大学生群体"
).to_messages()
# 5. 调用LLM生成结果
llm = ChatOpenAI(model_name="gpt-3.5-turbo")
response = llm.invoke(prompt)
print("生成的宣传语:\n", response.content)
2.2.2 记忆(Memory)组件
LLM本身不具备记忆能力,每次调用都是独立会话。Memory组件的核心作用是存储和管理对话历史,让LLM能够基于上下文生成回答,实现多轮对话功能。
常用Memory类型:
-
ConversationBufferMemory:存储完整对话历史,适用于短对话场景。
-
ConversationBufferWindowMemory:仅存储最近N轮对话,避免历史过长导致Token超限。
-
ConversationSummaryMemory:对对话历史进行总结,存储总结结果而非完整历史,适用于长对话。
-
VectorStoreRetrieverMemory:将对话历史转换为向量存储,通过检索相关历史生成回答,适用于复杂长对话。
代码示例:基于ConversationBufferWindowMemory的多轮对话
python
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferWindowMemory
# 1. 初始化LLM
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.5)
# 2. 初始化Memory:保留最近2轮对话
memory = ConversationBufferWindowMemory(k=2, return_messages=True)
# 3. 构建对话链(组合LLM和Memory)
conversation_chain = ConversationChain(
llm=llm,
memory=memory,
verbose=True # 打印详细日志,便于调试
)
# 4. 多轮对话交互
print("第一轮对话:")
response1 = conversation_chain.invoke("什么是LangChain的链(Chains)?")
print("LLM回答:", response1["response"], "\n")
print("第二轮对话:")
response2 = conversation_chain.invoke("链和单个组件相比有什么优势?")
print("LLM回答:", response2["response"], "\n")
print("第三轮对话(验证上下文记忆):")
response3 = conversation_chain.invoke("你刚才说的链的优势,能结合RAG场景举个例子吗?")
print("LLM回答:", response3["response"], "\n")
# 查看当前存储的对话历史
print("当前存储的对话历史:")
print(memory.load_memory_variables({}))
2.2.3 文档加载器(Document Loaders)与文本分割器(Text Splitters)
文档加载器是LangChain实现外部数据集成的核心组件,用于读取不同格式、来源的外部文档,转换为统一的"Document"对象(包含page_content和metadata属性)。文本分割器则用于将长文本分割为短片段(Chunks),适配LLM的上下文窗口限制,同时保留文本语义完整性。
常用文档加载器:
-
PyPDFLoader:加载PDF文件;
-
Docx2txtLoader:加载Word文件;
-
WebBaseLoader:加载网页内容;
-
SQLDatabaseLoader:加载数据库数据;
-
NotionLoader:加载Notion文档。
常用文本分割器:
-
RecursiveCharacterTextSplitter:递归字符分割器,按指定字符数分割,遇到换行、空格等分隔符时拆分,是最常用的分割器;
-
TokenTextSplitter:按LLM的Token数量分割,精准适配上下文窗口;
-
SentenceTransformersTokenTextSplitter:按句子边界分割,确保片段语义完整。
代码示例:加载PDF文档并分割文本
python
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 1. 加载PDF文档(替换为你的PDF路径)
loader = PyPDFLoader("LangChain官方文档.pdf")
documents = loader.load() # 返回Document对象列表,每个对象对应PDF一页
print(f"加载的PDF页数:{len(documents)}")
# 2. 初始化文本分割器
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000, # 每个片段最大字符数
chunk_overlap=200, # 片段重叠字符数(保证上下文连续性)
length_function=len # 长度计算函数(按字符数)
)
# 3. 分割文本
split_documents = text_splitter.split_documents(documents)
print(f"分割后的文本片段数量:{len(split_documents)}")
# 4. 查看分割结果
print("\n第一个片段内容(前500字符):")
print(split_documents[0].page_content[:500])
print(f"\n第一个片段元数据:{split_documents[0].metadata}")
2.2.4 向量存储(Vector Stores)与检索器(Retrievers)
分割后的文本片段需要转换为向量(Embeddings)才能进行相似性检索(RAG场景的核心步骤)。向量存储用于存储文本向量,检索器则根据用户查询的向量,从向量存储中检索出最相关的文本片段。
常用向量存储:
-
Chroma:轻量级本地向量库,无需部署,适合开发测试;
-
Pinecone:云端向量数据库,支持大规模数据和高并发,适合生产环境;
-
FAISS:Facebook开源向量检索库,适合本地大规模向量检索;
-
Weaviate:开源云端向量数据库,支持语义搜索和知识图谱。
代码示例:使用Chroma构建向量存储并实现相似性检索
python
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
# 1. 加载并分割文档(复用前文代码)
loader = PyPDFLoader("LangChain官方文档.pdf")
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
split_documents = text_splitter.split_documents(documents)
# 2. 初始化Embeddings模型(将文本转换为向量)
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")
# 3. 构建Chroma向量存储
vector_store = Chroma.from_documents(
documents=split_documents,
embedding=embeddings,
persist_directory="./langchain_chroma_db" # 本地存储目录(持久化)
)
vector_store.persist() # 持久化向量存储
print("向量存储构建完成")
# 4. 初始化检索器:每次检索返回最相关的3个片段
retriever = vector_store.as_retriever(search_kwargs={"k": 3})
# 5. 相似性检索(模拟用户查询)
query = "LangChain的Memory组件有哪些类型?各自的适用场景是什么?"
relevant_docs = retriever.get_relevant_documents(query)
# 6. 查看检索结果
print(f"\n检索到的相关片段数量:{len(relevant_docs)}")
for i, doc in enumerate(relevant_docs, 1):
print(f"\n第{i}个相关片段:")
print(f"来源:PDF第{doc.metadata['page']}页")
print(doc.page_content[:400], "...")
2.2.5 工具(Tools)与代理(Agents)
工具是LangChain中让LLM与外部系统交互的组件,如搜索引擎、计算器、代码执行器、API调用器等。代理则是具备"决策能力"的组件,能根据用户需求自主决策调用哪些工具、调用顺序,最终完成复杂任务。
常用工具:
-
SerpAPIQueryRun:调用SerpAPI进行搜索引擎查询(获取实时数据);
-
PythonREPLTool:执行Python代码(数据分析、计算等);
-
WikipediaQueryRun:查询维基百科信息;
-
APITool:调用自定义API服务。
代码示例:使用Agent调用搜索引擎和计算器完成复杂任务
python
import os
from langchain_openai import ChatOpenAI
from langchain.agents import create_openai_tools_agent, AgentExecutor
from langchain.tools import Tool
from langchain.utilities import SerpAPIWrapper, Calculator
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
# 1. 配置API密钥(SerpAPI需单独申请:https://serpapi.com/)
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"
os.environ["SERPAPI_API_KEY"] = "your-serpapi-api-key"
# 2. 初始化工具
# 工具1:搜索引擎
search = SerpAPIWrapper()
search_tool = Tool(
name="Search",
func=search.run,
description="用于获取实时信息,如当前天气、新闻、股票价格、最新政策等"
)
# 工具2:计算器
calculator = Calculator()
calculator_tool = Tool(
name="Calculator",
func=calculator.run,
description="用于进行数学计算,如加减乘除、平方、开方、百分比计算等"
)
tools = [search_tool, calculator_tool]
# 3. 初始化LLM(需使用支持工具调用的模型)
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
# 4. 初始化Agent提示词模板
prompt = ChatPromptTemplate.from_messages([
("system", "你是智能助手,能自主判断是否需要调用工具完成用户需求。不需要调用工具时直接回答。"),
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad") # 存储Agent思考过程和工具调用记录
])
# 5. 创建Agent和执行器
agent = create_openai_tools_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 6. 执行复杂任务
task = "当前上海的气温是多少摄氏度?将这个温度转换为华氏度(华氏度=摄氏度×9/5 +32),并说明转换结果。"
result = agent_executor.invoke({"input": task})
print("\n最终结果:", result["output"])
2.2.6 链(Chains):组件的流程编排
链是LangChain中组合多个组件的核心机制,定义了组件的执行顺序和数据流转逻辑。通过链可以将"提示词模板+LLM+记忆+检索器+工具"等组件串联成完整工作流,实现复杂任务。
常用链类型:
-
LLMChain:基础链,仅包含"提示词模板+LLM",适用于简单文本生成;
-
ConversationChain:"提示词模板+LLM+记忆",适用于多轮对话;
-
RetrievalQA:"检索器+LLM",适用于RAG问答场景;
-
SequentialChain:按顺序执行多个链,前一个链的输出作为后一个链的输入,适用于多步骤任务。
代码示例:使用RetrievalQA链构建基础RAG问答系统
python
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.chains import RetrievalQA
from langchain_openai import ChatOpenAI
# 1. 加载、分割文档并构建向量存储(复用前文代码)
loader = PyPDFLoader("LangChain官方文档.pdf")
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
split_documents = text_splitter.split_documents(documents)
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")
vector_store = Chroma.from_documents(
documents=split_documents,
embedding=embeddings,
persist_directory="./langchain_chroma_db"
)
retriever = vector_store.as_retriever(search_kwargs={"k": 3})
# 2. 初始化LLM
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
# 3. 构建RetrievalQA链
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff", # 链类型:将检索到的片段拼接后输入LLM
retriever=retriever,
return_source_documents=True # 返回回答的来源文档(便于验证)
)
# 4. 执行RAG问答
query = "如何基于LangChain构建一个企业知识库问答系统?关键步骤是什么?"
result = qa_chain.invoke({"query": query})
# 5. 查看结果
print("LLM回答:\n", result["result"])
print("\n回答来源:")
for i, doc in enumerate(result["source_documents"], 1):
print(f"第{i}个来源:PDF第{doc.metadata['page']}页")
print(doc.page_content[:300], "...")
链类型说明:
-
stuff:拼接所有检索片段输入LLM,简单高效,但受限于上下文窗口;
-
map_reduce:先单独处理每个片段,再汇总结果,适合长文档;
-
refine:逐步优化回答,先处理第一个片段生成初步答案,再用后续片段修正;
-
map_rerank:为每个片段打分,选择分数最高的片段生成回答,适合相关性要求高的场景。
三、LangChain实战:构建企业知识库问答系统
3.1 项目需求与架构设计
3.1.1 项目需求
构建基于企业内部PDF文档的问答系统,支持用户通过自然语言查询企业信息(如员工手册、产品手册、业务流程),系统需基于文档内容生成准确回答,并标注回答来源,方便用户验证信息可信度。
3.1.2 架构设计
基于LangChain的RAG架构,系统分为5个核心模块,采用"数据处理-向量存储-检索生成-API服务"的流程:
-
文档加载模块:使用PyPDFLoader加载企业内部PDF文档;
-
文本处理模块:使用RecursiveCharacterTextSplitter分割文本;
-
向量存储模块:使用Chroma构建本地向量存储(开发环境);
-
检索生成模块:使用RetrievalQA链实现"检索相关文本-LLM生成回答";
-
API服务模块:基于FastAPI构建接口,支持前端调用。
3.2 项目实现步骤
3.2.1 步骤1:环境准备与依赖安装
bash
# 安装项目所需依赖
pip install langchain openai pypdf chromadb fastapi uvicorn python-multipart
3.2.2 步骤2:文档处理与向量存储构建
创建data_process.py文件,实现文档加载、分割与向量存储构建:
python
import os
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
# 配置API密钥
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"
def load_and_split_documents(doc_dir):
"""加载指定目录下的所有PDF文档并分割"""
loaders = []
# 遍历目录下的所有PDF文件
for filename in os.listdir(doc_dir):
if filename.endswith(".pdf"):
file_path = os.path.join(doc_dir, filename)
loader = PyPDFLoader(file_path)
loaders.append(loader)
# 加载所有文档
documents = []
for loader in loaders:
documents.extend(loader.load())
print(f"成功加载{len(documents)}页PDF文档")
# 分割文本
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
length_function=len
)
split_documents = text_splitter.split_documents(documents)
print(f"文本分割完成,得到{len(split_documents)}个文本片段")
return split_documents
def build_vector_store(split_documents, persist_dir="./enterprise_kb_chroma_db"):
"""构建并持久化向量存储"""
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")
vector_store = Chroma.from_documents(
documents=split_documents,
embedding=embeddings,
persist_directory=persist_dir
)
vector_store.persist()
print(f"向量存储构建完成,已持久化到{persist_dir}")
return vector_store
if __name__ == "__main__":
# 企业文档目录(需提前创建并放入PDF文件)
doc_dir = "./enterprise_documents"
# 加载并分割文档
split_docs = load_and_split_documents(doc_dir)
# 构建向量存储
build_vector_store(split_docs)
3.2.3 步骤3:构建问答链与API服务
创建app.py文件,基于FastAPI构建API服务:
python
import os
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from langchain_openai import ChatOpenAI
from langchain.chains import RetrievalQA
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
# 配置API密钥
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"
# 初始化FastAPI应用
app = FastAPI(
title="企业知识库问答系统",
description="基于LangChain构建的RAG问答系统,支持企业内部PDF文档查询",
version="1.0.0"
)
# 定义请求体模型
class QueryRequest(BaseModel):
query: str # 用户查询语句
k: int = 3 # 检索相关片段数量(默认3个)
# 初始化问答链
def init_qa_chain(k=3):
"""加载向量存储并初始化RetrievalQA链"""
# 加载向量存储
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")
vector_store = Chroma(
persist_directory="./enterprise_kb_chroma_db",
embedding_function=embeddings
)
# 构建检索器
retriever = vector_store.as_retriever(search_kwargs={"k": k})
# 初始化LLM
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
# 构建问答链
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
return_source_documents=True
)
return qa_chain
# 定义问答API接口
@app.post("/query_knowledge_base", summary="企业知识库查询")
async def query_knowledge_base(request: QueryRequest):
try:
# 初始化问答链
qa_chain = init_qa_chain(k=request.k)
# 执行查询
result = qa_chain.invoke({"query": request.query})
# 整理来源信息
sources = []
for doc in result["source_documents"]:
source_info = {
"filename": os.path.basename(doc.metadata["source"]),
"page": doc.metadata["page"],
"content_preview": doc.page_content[:300] + "..." # 内容预览(前300字符)
}
sources.append(source_info)
# 返回结果
return {
"query": request.query,
"answer": result["result"],
"sources": sources,
"status": "success"
}
except Exception as e:
raise HTTPException(status_code=500, detail=f"查询失败:{str(e)}")
# 健康检查接口
@app.get("/health", summary="健康检查")
async def health_check():
return {"status": "healthy", "message": "企业知识库问答系统运行正常"}
# 运行服务(命令行:uvicorn app:app --reload)
if __name__ == "__main__":
import uvicorn
uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=True)
3.2.4 步骤4:项目测试与运行
-
创建
enterprise_documents目录,放入企业内部PDF文档(如"员工手册.pdf"、"产品说明书.pdf"); -
运行
data_process.py,构建向量存储:python data_process.py; -
启动API服务:
uvicorn app:app --reload; -
测试接口:访问
http://localhost:8000/docs,使用FastAPI自动生成的文档测试/query_knowledge_base接口,输入查询语句(如"员工带薪年假天数如何规定?"),查看返回结果。
测试示例响应:
json
{
"query": "员工带薪年假天数如何规定?",
"answer": "根据企业员工手册规定,员工带薪年假天数根据工龄确定:1. 工龄满1年不满3年的,每年享受5天带薪年假;2. 工龄满3年不满10年的,每年享受10天带薪年假;3. 工龄满10年及以上的,每年享受15天带薪年假。年假需提前3个工作日提交书面申请,经部门主管批准后生效。",
"sources": [
{
"filename": "员工手册.pdf",
"page": 12,
"content_preview": "第三章 考勤与休假制度\n3.1 带薪年假\n为保障员工休息权利,根据《职工带薪年休假条例》,结合公司实际情况,制定本规定:\n1. 工龄满1年不满3年的,每年享受5天带薪年假;\n2. 工龄满3年不满10年的,每年享受10天带薪年假;\n3. 工龄满10年及以上的,每年享受15天带薪年假。\n员工申请年假需提前3个工作日提交书面申请,经部门主管审核批准后,报人力资源部备案。未按规定申请或申请未批准擅自休假的,按旷工处理。..."
}
],
"status": "success"
}
四、LangChain高级特性与性能优化
4.1 自定义组件开发
LangChain的模块化设计支持自定义组件,满足个性化需求。常见自定义场景包括自定义提示词模板、自定义工具、自定义记忆存储等。
4.1.1 自定义提示词模板
继承PromptTemplate类,重写相关方法,实现个性化模板逻辑。示例:企业专属宣传语模板(强制包含企业价值观)
python
from langchain.prompts import PromptTemplate
class EnterprisePromotionPrompt(PromptTemplate):
# 自定义属性:企业价值观
enterprise_value: str = "诚信、创新、客户至上"
def format(self, **kwargs):
# 扩展模板,强制包含企业价值观
self.template = f"{self.template}\n要求:宣传语需融入企业价值观------{self.enterprise_value}。"
return super().format(** kwargs)
# 使用自定义模板
prompt_template = EnterprisePromotionPrompt(
input_variables=["product", "audience"],
template="为{product}撰写面向{audience}的宣传语",
enterprise_value="诚信、创新、客户至上"
)
prompt = prompt_template.format(product="智能办公系统", audience="中小企业主")
print(prompt)
4.1.2 自定义工具
通过Tool类封装自定义函数,实现企业内部系统交互。示例:自定义员工信息查询工具
python
import requests
from langchain.tools import Tool
# 自定义函数:调用企业内部员工信息API
def query_employee_info(employee_id):
"""查询企业员工基本信息(姓名、部门、职位等),需传入员工ID"""
api_url = "http://internal.enterprise.com/api/employee"
params = {"employee_id": employee_id}
try:
response = requests.get(api_url, params=params)
response.raise_for_status() # 抛出HTTP错误
return response.json()
except Exception as e:
return f"查询失败:{str(e)}"
# 封装为LangChain工具
employee_tool = Tool(
name="EmployeeInfoQuery",
func=query_employee_info,
description="用于查询企业内部员工的基本信息,必须传入员工ID作为参数"
)
# 测试工具
result = employee_tool.run("10001")
print(result)
4.2 多模态LLM支持
LangChain支持多模态LLM(如GPT-4V、Gemini Pro),可处理文本、图像、音频等多种输入。通过MultiModalLLM组件实现图文结合问答等功能。
代码示例:使用GPT-4V实现图像内容分析
python
from langchain_openai import ChatOpenAI
from langchain.schema import HumanMessage
import base64
# 图像转base64编码(GPT-4V要求的输入格式)
def image_to_base64(image_path):
with open(image_path, "rb") as f:
return base64.b64encode(f.read()).decode("utf-8")
# 初始化多模态LLM(GPT-4V)
llm = ChatOpenAI(
model_name="gpt-4-vision-preview",
max_tokens=1000
)
# 准备图像(企业产品截图)
image_path = "product_screenshot.png"
image_base64 = image_to_base64(image_path)
# 构建包含图像和文本的提示词
messages = [
HumanMessage(
content=[
{"type": "text", "text": "请分析这张产品截图,说明产品的功能模块和使用场景。"},
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{image_base64}"}}
]
)
]
# 调用LLM生成结果
response = llm.invoke(messages)
print("图像分析结果:\n", response.content)
4.3 性能优化策略
针对生产环境,需从以下方面优化LangChain应用性能:
4.3.1 向量存储优化
-
开发环境使用Chroma,生产环境切换到Pinecone、Weaviate等云端向量数据库,支持水平扩展;
-
优化文本分割策略,根据文档类型调整
chunk_size和chunk_overlap,避免片段过长或过短; -
使用批量处理API(如
Chroma.from_documents)批量生成向量,提升效率。
4.3.2 模型与检索优化
-
根据任务复杂度选择合适的LLM:简单任务用gpt-3.5-turbo,复杂任务用gpt-4,平衡性能与成本;
-
中文场景使用中文Embeddings模型(如通义千问Embeddings、文心一言Embeddings),提升检索精度;
-
添加缓存机制(如Redis),缓存频繁查询的结果和检索结果,减少重复计算。
4.3.3 服务部署优化
-
使用LangChain异步API(如
ainvoke)和FastAPI异步接口,提升并发处理能力; -
将API服务集群化部署,使用Nginx作为负载均衡器;
-
对大文件文档进行预处理,提前生成向量并持久化,避免运行时重复处理。
五、LangChain生态集成与社区资源
5.1 与主流技术的集成
5.1.1 与Web框架集成
LangChain可与FastAPI、Flask、Django等Web框架无缝集成,快速构建Web应用。本文实战项目已展示与FastAPI的集成,如需集成Django,可将问答链封装为Django视图函数:
python
# Django视图函数示例
from django.http import JsonResponse
from django.views import View
from .utils import init_qa_chain # 复用前文的问答链初始化函数
class KnowledgeBaseQueryView(View):
def post(self, request):
try:
data = request.json
query = data.get("query")
k = data.get("k", 3)
qa_chain = init_qa_chain(k=k)
result = qa_chain.invoke({"query": query})
return JsonResponse({
"query": query,
"answer": result["result"],
"status": "success"
})
except Exception as e:
return JsonResponse({"status": "error", "detail": str(e)}, status=500)
5.1.2 与向量数据库集成
LangChain支持与主流向量数据库集成,除前文介绍的Chroma外,以Pinecone(云端)为例:
python
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Pinecone
import pinecone
# 初始化Pinecone
pinecone.init(
api_key="your-pinecone-api-key",
environment="your-pinecone-environment"
)
# 构建Pinecone向量存储
index_name = "enterprise-kb"
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")
vector_store = Pinecone.from_documents(
documents=split_documents, # 前文分割后的文本片段
embedding=embeddings,
index_name=index_name
)
5.1.3 与开源LLM集成
LangChain支持对接开源LLM(如Llama 2、ChatGLM、Qwen),降低对商业API的依赖。以ChatGLM为例:
python
from langchain.llms import ChatGLM
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
# 初始化ChatGLM
llm = ChatGLM(
endpoint_url="http://localhost:8000", # 本地部署的ChatGLM API地址
max_token=2048,
temperature=0.7
)
# 构建简单链
prompt_template = PromptTemplate(
input_variables=["question"],
template="回答问题:{question}"
)
chain = LLMChain(llm=llm, prompt=prompt_template)
# 执行查询
result = chain.invoke({"question": "LangChain的核心优势是什么?"})
print(result["text"])
5.2 社区资源与学习渠道
LangChain社区活跃,提供丰富的学习资源:
-
官方文档:LangChain Official Docs,最权威的知识点参考;
-
GitHub仓库:langchain-ai/langchain,查看源码、示例和最新特性;
-
LangChain Hub:LangChain Hub,共享和复用提示词模板、链配置;
-
社区论坛:LangChain Discord,与全球开发者交流问题。
六、总结与扩展
6.1 核心知识点总结
本文围绕LangChain框架展开,从基础认知到实战应用,系统梳理了核心知识点:
-
基础认知:LangChain的定义、核心优势(外部数据集成、工具调用、记忆机制等)及典型应用场景;
-
核心架构:"组件-链-应用"三层架构,核心设计思想是"组合优于继承";
-
核心组件:提示词模板(动态生成提示词)、记忆(对话历史管理)、文档加载器与文本分割器(外部数据处理)、向量存储与检索器(相似性检索)、工具与代理(外部系统交互)、链(组件编排);
-
实战开发:基于RAG架构构建企业知识库问答系统,涵盖文档处理、向量存储、问答链构建、API服务开发;
-
高级特性:自定义组件开发、多模态LLM支持、性能优化策略;
-
生态集成:与Web框架、向量数据库、开源LLM的集成方式。
LangChain的核心价值在于降低LLM应用开发门槛,通过组件化封装和流程化编排,让开发者无需关注底层细节,专注于业务逻辑实现。