LangChain:深度解析与应用实践
引言:为什么需要 LangChain?
想象一下,你要建造一座智能房屋:
传统方式(直接使用 LLM API)
你:调用 OpenAI API
↓
API:返回结果
↓
你:处理结果
↓
你:再次调用 API
↓
API:返回结果
↓
... 重复这个过程
问题:
- 每次都要手动处理
- 无法记住对话历史
- 无法访问外部数据
- 代码复杂且难以维护
使用 LangChain(智能房屋系统)
你:告诉 LangChain 你的需求
↓
LangChain:自动协调各个组件
├── 记忆系统(记住对话历史)
├── 工具系统(访问外部数据)
├── 链式系统(组合多个步骤)
└── 代理系统(自主决策)
↓
返回:智能、完整的解决方案
优势:
- 自动化处理
- 记住上下文
- 访问外部数据
- 代码简洁易维护
LangChain 就是这样一个"智能房屋系统":它帮你构建由大语言模型驱动的应用程序,让复杂的 AI 应用开发变得简单高效。
第一部分:什么是 LangChain?
核心比喻:LangChain 就像"AI 应用的构建框架"
想象 LangChain 就像乐高积木系统:
-
基础积木(Components) = LangChain 的核心组件
- Prompts(提示模板)
- Models(语言模型)
- Chains(链)
- Agents(代理)
- Memory(记忆)
-
组合方式(Patterns) = LangChain 的设计模式
- 如何组合积木
- 如何构建复杂结构
-
完整建筑(Applications) = 最终的应用
- 聊天机器人
- 文档问答系统
- 代码分析工具
技术定义
LangChain 是一个用于开发由大型语言模型(LLM)驱动的应用程序的开源框架。它提供了一套模块化的组件和工具,简化了 LLM 应用的开发、部署和监控。
核心特点:
- 数据感知:连接语言模型与外部数据源
- 主动性:集成工具和服务,与环境交互
- 模块化:可组合的组件设计
- 易用性:简化复杂应用开发
主要组件:
- LangChain 库:核心组件和工具
- LangServe:部署为 REST API
- LangSmith:调试、测试、监控平台
- LangGraph:有状态代理部署平台
第二部分:LangChain 核心概念
概念 1:Chains(链)
比喻:链就像"工作流程"
现实世界的工作流程:
步骤1:接收订单
步骤2:检查库存
步骤3:处理支付
步骤4:安排发货
步骤5:发送确认
LangChain 链:
步骤1:接收用户输入
步骤2:处理提示
步骤3:调用 LLM
步骤4:处理输出
步骤5:返回结果
简单链示例
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
# 1. 创建语言模型
llm = OpenAI(temperature=0.7)
# 2. 创建提示模板
prompt = PromptTemplate(
input_variables=["product"],
template="写一个关于 {product} 的简短产品描述。"
)
# 3. 创建链
chain = LLMChain(llm=llm, prompt=prompt)
# 4. 运行链
result = chain.run("智能手机")
print(result)
顺序链示例
from langchain.chains import SimpleSequentialChain
# 链1:生成产品名称
name_chain = LLMChain(
llm=llm,
prompt=PromptTemplate(
input_variables=["product_type"],
template="为 {product_type} 产品想一个创意名称。"
)
)
# 链2:生成产品描述
description_chain = LLMChain(
llm=llm,
prompt=PromptTemplate(
input_variables=["product_name"],
template="为名为 {product_name} 的产品写一个详细描述。"
)
)
# 组合链
overall_chain = SimpleSequentialChain(
chains=[name_chain, description_chain],
verbose=True
)
# 运行
result = overall_chain.run("智能手表")
概念 2:Agents(代理)
比喻:代理就像"智能助手"
传统方式(固定流程):
你:问问题
LLM:回答(只能基于训练数据)
代理方式(自主决策):
你:问问题
代理:分析问题
├── 需要搜索?→ 使用搜索工具
├── 需要计算?→ 使用计算器
├── 需要查数据库?→ 查询数据库
└── 需要总结?→ 调用 LLM
代理:组合结果
你:得到完整答案
代理示例
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType
from langchain.llms import OpenAI
# 定义工具
def search_tool(query: str) -> str:
"""搜索工具"""
# 实际实现搜索逻辑
return f"搜索结果:{query}"
def calculator_tool(expression: str) -> str:
"""计算器工具"""
try:
result = eval(expression)
return str(result)
except:
return "计算错误"
# 创建工具列表
tools = [
Tool(
name="搜索",
func=search_tool,
description="用于搜索信息。输入应该是搜索查询。"
),
Tool(
name="计算器",
func=calculator_tool,
description="用于数学计算。输入应该是数学表达式。"
)
]
# 初始化代理
llm = OpenAI(temperature=0)
agent = initialize_agent(
tools,
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
# 使用代理
result = agent.run("北京到上海的距离是多少公里?然后计算如果开车需要多少小时?")
概念 3:Memory(记忆)
比喻:记忆就像"对话历史记录"
没有记忆:
用户:"我叫张三"
系统:"好的"
用户:"我叫什么?"
系统:"我不知道" ❌
有记忆:
用户:"我叫张三"
系统:"好的,记住了"
用户:"我叫什么?"
系统:"你叫张三" ✅
记忆类型
1. ConversationBufferMemory(对话缓冲记忆)
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationChain
memory = ConversationBufferMemory()
chain = ConversationChain(
llm=llm,
memory=memory,
verbose=True
)
# 对话
chain.run("我叫张三")
chain.run("我的名字是什么?") # 会记住名字
2. ConversationBufferWindowMemory(窗口记忆)
from langchain.memory import ConversationBufferWindowMemory
# 只记住最近 K 轮对话
memory = ConversationBufferWindowMemory(k=2)
3. ConversationSummaryMemory(摘要记忆)
from langchain.memory import ConversationSummaryMemory
# 将对话历史总结为摘要
memory = ConversationSummaryMemory(llm=llm)
概念 4:Prompts(提示)
比喻:提示就像"给 AI 的指令模板"
没有模板:
每次都要写完整的提示
容易出错
难以维护
有模板:
定义一次,多次使用
统一格式
易于修改
提示模板示例
from langchain.prompts import PromptTemplate, FewShotPromptTemplate
# 简单提示模板
template = """
你是一位专业的产品经理。
请为以下产品写一个产品描述:
产品名称:{product_name}
产品类型:{product_type}
目标用户:{target_audience}
产品描述:
"""
prompt = PromptTemplate(
input_variables=["product_name", "product_type", "target_audience"],
template=template
)
# 使用
result = prompt.format(
product_name="智能手表",
product_type="可穿戴设备",
target_audience="年轻专业人士"
)
# 少样本提示模板
examples = [
{"word": "happy", "antonym": "sad"},
{"word": "tall", "antonym": "short"},
]
example_template = """
单词: {word}
反义词: {antonym}
"""
few_shot_prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=PromptTemplate(
input_variables=["word", "antonym"],
template=example_template
),
prefix="给出每个单词的反义词",
suffix="单词: {input}\n反义词:",
input_variables=["input"],
)
概念 5:Document Loaders(文档加载器)
比喻:文档加载器就像"文件阅读器"
不同格式的文件:
- PDF 文件
- Word 文档
- 网页
- 文本文件
- CSV 文件
文档加载器:
统一接口
自动识别格式
转换为标准格式
文档加载示例
from langchain.document_loaders import PyPDFLoader, TextLoader, WebBaseLoader
# 加载 PDF
loader = PyPDFLoader("document.pdf")
documents = loader.load()
# 加载文本文件
loader = TextLoader("document.txt")
documents = loader.load()
# 加载网页
loader = WebBaseLoader("https://example.com")
documents = loader.load()
# 文档分割
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
chunks = text_splitter.split_documents(documents)
概念 6:Vector Stores(向量存储)
比喻:向量存储就像"图书馆的索引系统"
传统搜索:
关键词匹配
精确匹配
无法理解语义
向量搜索:
语义理解
相似度匹配
更智能的检索
向量存储示例
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
# 创建嵌入
embeddings = OpenAIEmbeddings()
# 创建向量存储
vectorstore = FAISS.from_documents(chunks, embeddings)
# 相似度搜索
query = "什么是机器学习?"
docs = vectorstore.similarity_search(query, k=3)
# 带分数的搜索
docs_with_scores = vectorstore.similarity_search_with_score(query, k=3)
概念 7:Retrievers(检索器)
比喻:检索器就像"图书管理员"
检索器:
接收问题
在向量存储中搜索
返回相关文档
供 LLM 使用
检索器示例
from langchain.chains import RetrievalQA
# 创建检索器
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
# 创建问答链
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
return_source_documents=True
)
# 提问
query = "文档中提到了哪些主要概念?"
result = qa_chain({"query": query})
print(result["result"])
第三部分:RAG(检索增强生成)
什么是 RAG?
比喻:RAG 就像"带参考资料的考试"
传统 LLM(闭卷考试):
只能基于训练数据回答
可能产生幻觉
无法访问最新信息
RAG(开卷考试):
可以查阅文档
基于真实信息回答
减少幻觉
RAG 工作流程
1. 文档加载
↓
2. 文档分割
↓
3. 向量化
↓
4. 存储到向量数据库
↓
5. 用户提问
↓
6. 检索相关文档
↓
7. 将文档作为上下文
↓
8. LLM 生成答案
RAG 完整示例
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
from langchain.chains import RetrievalQA
from langchain.llms import OpenAI
# 1. 加载文档
loader = PyPDFLoader("knowledge_base.pdf")
documents = loader.load()
# 2. 分割文档
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
chunks = text_splitter.split_documents(documents)
# 3. 创建向量存储
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(chunks, embeddings)
# 4. 创建检索器
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
# 5. 创建 RAG 链
llm = OpenAI(temperature=0)
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
return_source_documents=True
)
# 6. 使用
query = "文档中主要讲了什么?"
result = qa_chain({"query": query})
print(f"答案:{result['result']}")
print(f"\n参考文档:")
for doc in result['source_documents']:
print(f"- {doc.page_content[:100]}...")
第四部分:LangChain 实际应用
应用 1:智能客服机器人
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
from langchain.llms import OpenAI
# 创建带记忆的对话链
memory = ConversationBufferMemory()
llm = OpenAI(temperature=0.7)
chain = ConversationChain(
llm=llm,
memory=memory,
verbose=True
)
# 对话示例
chain.run("你好,我想了解产品信息")
chain.run("你们有哪些产品?")
chain.run("价格是多少?")
应用 2:文档问答系统
from langchain.document_loaders import DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
from langchain.chains import RetrievalQA
# 1. 加载所有文档
loader = DirectoryLoader("./documents", glob="**/*.pdf")
documents = loader.load()
# 2. 分割文档
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
chunks = text_splitter.split_documents(documents)
# 3. 创建向量存储
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(chunks, embeddings)
# 4. 创建问答系统
qa_chain = RetrievalQA.from_chain_type(
llm=OpenAI(),
chain_type="stuff",
retriever=vectorstore.as_retriever()
)
# 5. 提问
answer = qa_chain.run("文档中提到了哪些重要概念?")
print(answer)
应用 3:代码分析工具
from langchain.agents import initialize_agent, Tool
from langchain.tools import ShellTool
from langchain.llms import OpenAI
# 定义代码分析工具
def analyze_code(code: str) -> str:
"""分析代码"""
# 实际实现代码分析逻辑
return f"代码分析结果:{code}"
# 创建工具
tools = [
Tool(
name="代码分析",
func=analyze_code,
description="分析 Python 代码的质量和结构"
),
ShellTool()
]
# 创建代理
agent = initialize_agent(
tools,
OpenAI(temperature=0),
agent="zero-shot-react-description",
verbose=True
)
# 使用
result = agent.run("分析这段代码:def hello(): print('world')")
应用 4:多步骤任务处理
from langchain.chains import LLMChain, SimpleSequentialChain
from langchain.prompts import PromptTemplate
# 步骤1:提取关键信息
extract_chain = LLMChain(
llm=llm,
prompt=PromptTemplate(
input_variables=["text"],
template="从以下文本中提取关键信息:\n{text}\n\n关键信息:"
)
)
# 步骤2:生成摘要
summarize_chain = LLMChain(
llm=llm,
prompt=PromptTemplate(
input_variables=["key_info"],
template="基于以下关键信息生成摘要:\n{key_info}\n\n摘要:"
)
)
# 步骤3:生成建议
suggest_chain = LLMChain(
llm=llm,
prompt=PromptTemplate(
input_variables=["summary"],
template="基于以下摘要生成建议:\n{summary}\n\n建议:"
)
)
# 组合链
overall_chain = SimpleSequentialChain(
chains=[extract_chain, summarize_chain, suggest_chain],
verbose=True
)
# 运行
result = overall_chain.run("这是一段很长的文本...")
第五部分:LangChain Expression Language (LCEL)
什么是 LCEL?
比喻:LCEL 就像"声明式编程语言"
命令式(传统方式):
步骤1:做这个
步骤2:做那个
步骤3:检查结果
步骤4:根据结果做其他事
声明式(LCEL):
描述:我想要什么
系统:自动处理如何实现
LCEL 示例
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
from langchain.schema import StrOutputParser
# 使用 LCEL 创建链
prompt = ChatPromptTemplate.from_template("写一个关于 {topic} 的简短故事。")
model = ChatOpenAI()
output_parser = StrOutputParser()
# 组合链(使用管道操作符)
chain = prompt | model | output_parser
# 运行
result = chain.invoke({"topic": "人工智能"})
print(result)
复杂 LCEL 链
from langchain.schema.runnable import RunnablePassthrough, RunnableLambda
# 创建多个步骤
def extract_keywords(text: str) -> str:
"""提取关键词"""
return "关键词1, 关键词2, 关键词3"
def generate_content(keywords: str) -> str:
"""基于关键词生成内容"""
return f"基于 {keywords} 生成的内容"
# 组合链
chain = (
{"keywords": RunnableLambda(extract_keywords)}
| RunnableLambda(generate_content)
)
# 运行
result = chain.invoke("输入文本")
第六部分:LangChain 生态系统
LangServe:部署为 API
比喻:LangServe 就像"将应用打包成服务"
from fastapi import FastAPI
from langchain.chains import LLMChain
from langserve import add_routes
# 创建 FastAPI 应用
app = FastAPI()
# 创建链
chain = LLMChain(...)
# 添加路由
add_routes(app, chain, path="/chain")
# 运行
# uvicorn app:app
LangSmith:监控和调试
比喻:LangSmith 就像"应用的仪表盘"
功能:
- 跟踪所有 LLM 调用
- 调试提示和链
- 评估模型性能
- 监控生产环境
使用示例:
import os
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "your-api-key"
# 现在所有 LangChain 调用都会被跟踪
chain.run("输入")
LangGraph:有状态代理
比喻:LangGraph 就像"状态机"
传统代理:
无状态
每次都是新的
LangGraph 代理:
有状态
记住历史
长期运行
第七部分:最佳实践
实践 1:提示工程
# ✅ 好的提示
prompt = """
你是一位专业的数据分析师。
请分析以下数据并给出见解:
数据:{data}
要求:
1. 识别关键趋势
2. 指出异常值
3. 提供建议
分析:
"""
# ❌ 不好的提示
prompt = "分析数据:{data}"
实践 2:错误处理
from langchain.callbacks import get_openai_callback
def safe_chain_run(chain, input_data):
try:
with get_openai_callback() as cb:
result = chain.run(input_data)
print(f"Token 使用:{cb.total_tokens}")
return result
except Exception as e:
print(f"错误:{e}")
return None
实践 3:成本控制
# 使用回调跟踪成本
from langchain.callbacks import get_openai_callback
with get_openai_callback() as cb:
result = chain.run("输入")
print(f"总成本:${cb.total_cost:.4f}")
print(f"Token 数:{cb.total_tokens}")
实践 4:缓存
from langchain.cache import InMemoryCache
from langchain.globals import set_llm_cache
# 启用缓存
set_llm_cache(InMemoryCache())
# 相同输入会使用缓存
chain.run("输入1") # 调用 LLM
chain.run("输入1") # 使用缓存
第八部分:常见问题和解决方案
问题 1:Token 限制
解决方案:
# 使用 MapReduce 链处理长文档
from langchain.chains import MapReduceChain
map_chain = LLMChain(...)
reduce_chain = LLMChain(...)
map_reduce_chain = MapReduceChain(
map_chain=map_chain,
reduce_chain=reduce_chain
)
问题 2:响应速度慢
解决方案:
# 使用异步调用
async def async_chain_run(chain, input_data):
result = await chain.ainvoke(input_data)
return result
# 批量处理
results = chain.batch([input1, input2, input3])
问题 3:成本过高
解决方案:
# 1. 使用缓存
set_llm_cache(InMemoryCache())
# 2. 使用更便宜的模型
llm = OpenAI(model_name="gpt-3.5-turbo") # 而不是 gpt-4
# 3. 限制 Token 数
llm = OpenAI(max_tokens=100)
第九部分:学习路径
入门阶段(1-2 周)
-
安装和配置
pip install langchain openai -
学习基础概念
- Chains
- Prompts
- Memory
-
完成第一个项目
- 简单的问答系统
进阶阶段(2-4 周)
-
深入学习
- Agents
- RAG
- Vector Stores
-
完成复杂项目
- 文档问答系统
- 智能客服机器人
高级阶段(持续学习)
-
掌握高级特性
- LCEL
- LangGraph
- LangSmith
-
优化和部署
- 性能优化
- 生产部署
- 监控和调试
第十部分:总结
LangChain 的核心价值
- 简化开发:让复杂 AI 应用开发变得简单
- 模块化设计:可组合的组件
- 丰富的功能:覆盖 AI 应用的各个方面
- 生产就绪:提供部署和监控工具
适用场景
- 文档问答系统
- 智能客服机器人
- 代码分析工具
- 内容生成应用
- 数据分析助手
学习建议
- 从简单开始:先理解基础概念
- 多做项目:通过实践学习
- 阅读文档:官方文档很详细
- 参与社区:GitHub、Discord 等
结语
LangChain 是一个强大的框架,它让构建 LLM 应用变得简单高效。无论你是初学者还是经验丰富的开发者,LangChain 都能帮助你快速构建高质量的 AI 应用。
记住:最好的学习方式是实践。 从简单的项目开始,逐步构建更复杂的应用,你会在实践中深入理解 LangChain 的强大之处。
开始你的 LangChain 之旅吧!