目录
- 第一部分:基础入门
- 第二部分:核心概念详解
- 第三部分:提示工程
- 第四部分:记忆管理
- 第五部分:Runnable与链
- 第六部分:工具与函数调用
- 第七部分:代理Agent
- 第八部分:RAG检索增强
- 第九部分:详细应用案例
- 第十部分:高级特性
第一部分:基础入门
1.1 什么是LangChain?
LangChain是由LangChain AI公司开发的开源框架,专门用于构建基于大语言模型(LLM)的AI应用。它提供了一套标准化、模块化的工具和框架,使开发者能够快速构建从简单的聊天应用到复杂的多代理系统。
LangChain的核心价值
| 功能 | 描述 |
|---|---|
| 统一API | 无论使用OpenAI、Claude、Gemini,API接口保持一致 |
| 模块化设计 | 灵活组装各功能模块(提示、链、记忆、工具、代理) |
| 生产就绪 | 包含日志、监控、持久化、错误处理等企业级特性 |
| 丰富集成 | 集成200+外部服务(数据库、搜索引擎、API等) |
| 流式处理 | 支持实时流式输出,提升用户体验 |
| 中间件系统 | 通过中间件实现PII保护、人工审核、请求限流等 |
1.2 环境安装与配置
# 基础安装
pip install -U langchain langchain-core
# 安装特定LLM集成(选择需要的)
pip install langchain-openai # OpenAI
pip install langchain-anthropic # Claude
pip install langchain-google-genai # Gemini
pip install langchain-ollama # 本地模型
# 安装社区集成(包含许多工具和集成)
pip install langchain-community
# 安装LangSmith用于监控(可选但推荐)
pip install langsmith
# 安装其他常用工具
pip install python-dotenv # 环境变量管理
1.3 配置API密钥
import os
from dotenv import load_dotenv
# 从.env文件加载环境变量
load_dotenv()
# 或直接设置
os.environ["OPENAI_API_KEY"] = "your-api-key"
os.environ["ANTHROPIC_API_KEY"] = "your-api-key"
# LangSmith配置(用于追踪和调试)
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_API_KEY"] = "your-langsmith-key"
os.environ["LANGSMITH_PROJECT"] = "my-project"
1.4 快速开始示例
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage, SystemMessage
# 初始化模型
model = init_chat_model("gpt-4o-mini")
# 方式1:简单调用
response = model.invoke("你好,请自我介绍")
print(response.content)
# 方式2:结构化消息
messages = [
SystemMessage(content="你是一个专业的技术顾问"),
HumanMessage(content="什么是LangChain?")
]
response = model.invoke(messages)
print(response.content)
# 方式3:流式处理
for chunk in model.stream("讲述AI发展历史"):
print(chunk.content, end="", flush=True)
第二部分:核心概念详解
2.1 消息系统
LangChain使用标准化的消息格式来处理对话,这是与LLM交互的基础。
2.1.1 消息类型
from langchain.messages import (
HumanMessage, # 用户消息
AIMessage, # AI回复消息
SystemMessage, # 系统指令
ToolMessage, # 工具执行结果
FunctionMessage # 函数执行结果
)
# 构建对话历史
messages = [
# 系统消息:定义AI角色和行为
SystemMessage(content="你是一个精通Python的编程导师,用简洁的方式解释复杂概念"),
# 用户消息:第一轮提问
HumanMessage(content="什么是装饰器?"),
# AI消息:AI的回复
AIMessage(content="装饰器是一个函数,它接受另一个函数作为参数,并返回一个修改后的函数..."),
# 用户消息:跟进提问
HumanMessage(content="能给个实际例子吗?"),
# 工具消息:来自工具的结果
ToolMessage(
content="示例代码已执行,输出为:[1, 2, 3]",
tool_call_id="tool_123"
)
]
# 传递给模型
response = model.invoke(messages)
2.1.2 消息内容块
LangChain 1.2引入的内容块统一了不同LLM提供商的功能:
from langchain_anthropic import ChatAnthropic
model = ChatAnthropic(model="claude-sonnet-4-5-20250929")
# Claude支持多种内容块类型
response = model.invoke("分析这个复杂问题并给出推理过程")
# 访问响应中的各种内容块
if hasattr(response, 'content'):
for block in response.content:
if isinstance(block, dict):
if block.get("type") == "thinking":
print(f"推理过程: {block.get('thinking')}")
elif block.get("type") == "text":
print(f"最终答案: {block.get('text')}")
2.2 LLM与Chat Model
两种基本的模型接口:
from langchain_openai import ChatOpenAI, OpenAI
# Chat Model:推荐使用
# 专为对话优化,基于消息的接口
chat_model = ChatOpenAI(
model="gpt-4o",
temperature=0.7, # 创意度(0-1,0最保守)
max_tokens=2000, # 最大输出长度
timeout=30, # 超时时间
max_retries=2 # 失败重试次数
)
# LLM Model:遗留模式
# 基于文本的接口,已逐步被ChatModel替代
llm = OpenAI(
model="gpt-3.5-turbo-instruct",
temperature=0.5
)
# 调用方式相同
response = chat_model.invoke("你的问题")
print(response.content)
2.3 输出解析器
将模型输出转换为结构化格式:
from langchain.output_parsers import (
StrOutputParser, # 提取字符串
JSONOutputParser, # JSON解析
PydanticOutputParser, # Pydantic模型
CommaSeparatedListOutputParser # 逗号分隔列表
)
from pydantic import BaseModel, Field
# 方法1:简单字符串解析
from langchain.chat_models import init_chat_model
parser = StrOutputParser()
model = init_chat_model("gpt-4o-mini")
chain = model | parser
result = chain.invoke("生成5个创意产品名称")
print(result) # 直接获得字符串
# 方法2:JSON解析
from langchain.output_parsers import JsonOutputParser
parser = JsonOutputParser()
model = init_chat_model("gpt-4o-mini")
prompt = """
生成3个产品的信息,返回JSON格式:
[
{
"name": "产品名称",
"price": 价格,
"features": ["特性1", "特性2"]
}
]
"""
chain = model | parser
result = chain.invoke(prompt)
print(result) # 自动解析为Python字典列表
# 方法3:Pydantic模型解析(最强大)
from pydantic import BaseModel
class Product(BaseModel):
"""产品信息模型"""
name: str = Field(description="产品名称")
price: float = Field(description="价格")
features: list = Field(description="产品特性")
parser = PydanticOutputParser(pydantic_object=Product)
# 自动生成格式指导
format_instructions = parser.get_format_instructions()
print(format_instructions) # 告诉模型如何输出
prompt_text = f"""
生成一个产品的信息。
{format_instructions}
"""
chain = model | parser
result = chain.invoke(prompt_text)
# result是Product对象,可以直接访问属性
print(result.name, result.price, result.features)
# 方法4:列表解析
list_parser = CommaSeparatedListOutputParser()
chain = model | list_parser
result = chain.invoke("列出5种水果")
print(result) # ['苹果', '香蕉', '橙子', '葡萄', '西瓜']
第三部分:提示工程
3.1 Prompt Template基础
from langchain.prompts import PromptTemplate
# 方法1:简单模板
template = PromptTemplate(
input_variables=["product", "tone"],
template="为{product}生成一个{tone}的广告文案"
)
prompt = template.format(product="咖啡", tone="激情洋溢的")
print(prompt)
# 输出:为咖啡生成一个激情洋溢的广告文案
# 方法2:使用from_template(更简洁)
template = PromptTemplate.from_template(
"为{product}生成一个{tone}的广告文案"
)
# 方法3:多行模板
template = PromptTemplate.from_template(
"""
你是一个专业的营销专家。
产品:{product}
目标市场:{market}
广告风格:{style}
请生成一个能够吸引目标市场的广告文案。
"""
)
3.2 Chat Prompt Template
用于对话模型的高级提示:
from langchain.prompts import ChatPromptTemplate
from langchain.prompts import SystemMessagePromptTemplate, HumanMessagePromptTemplate
# 方法1:使用from_messages
chat_template = ChatPromptTemplate.from_messages([
("system", "你是一个专业的{profession}"),
("human", "请回答这个问题:{question}"),
])
messages = chat_template.format_messages(
profession="数据科学家",
question="什么是特征工程?"
)
print(messages)
# 方法2:使用专门的Template类
system_template = SystemMessagePromptTemplate.from_template(
"你是一个专业的{profession}"
)
human_template = HumanMessagePromptTemplate.from_template(
"请回答这个问题:{question}"
)
chat_template = ChatPromptTemplate.from_messages([
system_template,
human_template
])
# 方法3:多轮对话模板
chat_template = ChatPromptTemplate.from_messages([
("system", "你是一个友好的AI助手"),
("human", "你好,你叫什么?"),
("ai", "你好,我是Claude,很高兴认识你"),
("human", "{user_input}"),
])
messages = chat_template.format_messages(
user_input="你能做什么?"
)
response = model.invoke(messages)
3.3 高级提示模式
Few-Shot Learning(少样本学习)
from langchain.prompts import FewShotChatMessagePromptTemplate, ChatPromptTemplate
# 定义示例
examples = [
{
"input": "我想创业",
"output": "创业需要:1. 有竞争力的想法 2. 足够的资金 3. 坚定的执行力"
},
{
"input": "怎样改进生产效率",
"output": "可以考虑:1. 自动化生产流程 2. 优化工作流程 3. 员工培训"
}
]
# 创建示例提示
example_prompt = ChatPromptTemplate.from_messages([
("human", "{input}"),
("ai", "{output}")
])
# 创建少样本提示
few_shot_prompt = FewShotChatMessagePromptTemplate(
examples=examples,
example_prompt=example_prompt,
suffix="现在请回答这个问题:{input}",
input_variables=["input"]
)
# 使用
final_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个商业咨询专家"),
few_shot_prompt
])
messages = final_prompt.format_messages(
input="如何建立供应链?"
)
response = model.invoke(messages)
Dynamic Prompt Selection
from langchain.prompts import PromptTemplate
from langchain.chat_models import init_chat_model
# 根据用户输入选择不同的提示
def get_prompt(topic):
prompts = {
"编程": PromptTemplate.from_template(
"作为Python专家,解释{topic}的最佳实践"
),
"商业": PromptTemplate.from_template(
"作为商业顾问,分析{topic}对企业的影响"
),
"科学": PromptTemplate.from_template(
"作为科学家,从科学角度解释{topic}"
)
}
return prompts.get(topic, prompts["编程"])
# 使用
topic = "人工智能"
category = "科学" # 用户选择的类别
prompt = get_prompt(category)
formatted_prompt = prompt.format(topic=topic)
response = model.invoke(formatted_prompt)
第四部分:记忆管理
4.1 Memory系统概述
记忆是使AI应用能够进行有意义对话的关键。LangChain提供了多种记忆类型:
| 类型 | 保存方式 | 适用场景 | Token消耗 |
|---|---|---|---|
| BufferMemory | 保存全部对话 | 短对话,需要完整上下文 | 随对话增长 |
| BufferWindowMemory | 仅保存最近N轮 | 长对话,只需近期信息 | 恒定 |
| TokenBufferMemory | 按Token数限制 | 需要精确控制成本 | 恒定 |
| SummaryMemory | 自动总结 | 很长的对话 | 中等 |
4.2 Buffer Memory(缓冲记忆)
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationChain
from langchain.chat_models import init_chat_model
# 初始化
llm = init_chat_model("gpt-4o-mini")
memory = ConversationBufferMemory()
# 创建对话链
conversation = ConversationChain(
llm=llm,
memory=memory,
verbose=True # 打印调试信息
)
# 多轮对话
conversation.invoke({"input": "我叫张三"})
conversation.invoke({"input": "我的职业是工程师"})
conversation.invoke({"input": "你记得我的名字吗?"}) # AI会回忆
# 查看内存中的历史
print("对话历史:")
print(memory.buffer)
# 手动管理内存
memory.save_context(
{"input": "什么是机器学习"},
{"output": "机器学习是..."}
)
# 提取内存变量
variables = memory.load_memory_variables({})
print("内存变量:", variables)
# 返回消息列表格式(用于ChatModel)
memory_with_messages = ConversationBufferMemory(
return_messages=True
)
variables = memory_with_messages.load_memory_variables({})
# variables['history']是消息对象列表,而非字符串
4.3 Window Memory(窗口记忆)
from langchain.memory import ConversationBufferWindowMemory
# 只保存最近k轮对话
memory = ConversationBufferWindowMemory(
k=3, # 保留最近3轮对话
return_messages=True
)
conversation = ConversationChain(
llm=llm,
memory=memory
)
# 进行多轮对话
for i in range(10):
response = conversation.invoke({"input": f"这是第{i+1}轮对话"})
print(f"轮次{i+1}: 内存中保存{len(memory.buffer)}条消息")
# 你会看到内存中最多保存3轮对话
4.4 Token Buffer Memory
from langchain.memory import ConversationTokenBufferMemory
# 根据Token数量而不是对话数量来保留历史
memory = ConversationTokenBufferMemory(
llm=llm,
max_token_limit=1000, # 最多保留1000个Token
return_messages=True
)
conversation = ConversationChain(
llm=llm,
memory=memory
)
# 对话会自动控制在Token数量内
conversation.invoke({"input": "讲述一个长故事..."})
4.5 Summary Memory(总结记忆)
from langchain.memory import ConversationSummaryMemory
# 自动总结对话内容
memory = ConversationSummaryMemory(
llm=llm,
return_messages=True
)
conversation = ConversationChain(
llm=llm,
memory=memory
)
# 进行多轮长对话
conversation.invoke({"input": "早上我去咖啡馆喝了咖啡"})
conversation.invoke({"input": "然后去公园散步"})
conversation.invoke({"input": "下午参加了会议"})
conversation.invoke({"input": "晚上看了电影"})
# 查看自动生成的总结
print("对话总结:")
print(memory.buffer)
# 内存会逐步总结,减少Token消耗
4.6 自定义Memory类
from langchain.memory.chat_memory import BaseChatMemory
from langchain.schema import get_buffer_string
class CustomMemory(BaseChatMemory):
"""自定义记忆类"""
def load_memory_variables(self, inputs: dict) -> dict:
"""加载内存变量"""
buffer_string = get_buffer_string(
self.chat_memory.messages,
human_prefix="用户",
ai_prefix="助手"
)
return {"history": buffer_string}
def save_context(self, inputs: dict, outputs: dict) -> None:
"""保存对话上下文"""
self.chat_memory.add_user_message(inputs["input"])
self.chat_memory.add_ai_message(outputs["output"])
# 使用自定义记忆
memory = CustomMemory()
memory.save_context(
{"input": "你好"},
{"output": "你好!很高兴认识你"}
)
print(memory.load_memory_variables({}))
第五部分:Runnable与链
5.1 Runnable概念
Runnable是LangChain 1.2的核心抽象,代表可以被链式调用的任何操作。
from langchain_core.runnables import Runnable, RunnableLambda
from langchain_core.output_parsers import StrOutputParser
# 所有这些都是Runnable:
# - LLM模型
# - 提示模板
# - 输出解析器
# - 自定义函数
# - 工具调用
model = init_chat_model("gpt-4o-mini")
parser = StrOutputParser()
# Runnable可以链式组合(使用|操作符)
chain = model | parser
result = chain.invoke("你好")
print(result) # 直接获得字符串,不需要.content
5.2 构建链(Chain)
方法1:使用|操作符(推荐)
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import init_chat_model
from langchain_core.output_parsers import StrOutputParser
# 定义组件
prompt = ChatPromptTemplate.from_template(
"为{topic}生成一个创意想法"
)
model = init_chat_model("gpt-4o-mini")
parser = StrOutputParser()
# 链式组合
chain = prompt | model | parser
# 调用
result = chain.invoke({"topic": "未来的智能城市"})
print(result)
# 支持流式处理
for chunk in chain.stream({"topic": "AI应用"}):
print(chunk, end="", flush=True)
# 批量处理
results = chain.batch([
{"topic": "机器学习"},
{"topic": "深度学习"},
{"topic": "强化学习"}
])
方法2:RunnableLambda
from langchain_core.runnables import RunnableLambda
# 将普通函数转换为Runnable
def uppercase(text):
return text.upper()
def count_words(text):
return len(text.split())
# 创建Runnable
upper_runnable = RunnableLambda(uppercase)
count_runnable = RunnableLambda(count_words)
# 组合使用
chain = upper_runnable | count_runnable
result = chain.invoke("hello world")
print(result) # 2
# 链式包含模型
model = init_chat_model("gpt-4o-mini")
chain = model | RunnableLambda(lambda x: x.content.upper())
result = chain.invoke("say hello")
方法3:RunnableParallel(并行执行)
from langchain_core.runnables import RunnableParallel
prompt = ChatPromptTemplate.from_template("讨论{topic}")
model = init_chat_model("gpt-4o-mini")
# 并行运行多个链
parallel_chain = RunnableParallel(
original=model | StrOutputParser(),
uppercase=model | RunnableLambda(lambda x: x.content.upper()),
word_count=model | RunnableLambda(lambda x: len(x.content.split()))
)
result = parallel_chain.invoke({"topic": "AI发展"})
print(result)
# 输出:{
# 'original': '...',
# 'uppercase': '...',
# 'word_count': 123
# }
# 简化写法(字典自动转换为RunnableParallel)
parallel_chain = {
"analysis": model | StrOutputParser(),
"length": model | RunnableLambda(lambda x: len(x.content))
}
方法4:RunnablePassthrough
from langchain_core.runnables import RunnablePassthrough
prompt = ChatPromptTemplate.from_template(
"根据上下文和问题生成答案\n"
"上下文: {context}\n"
"问题: {question}"
)
# 保留原始输入
chain = {
"context": RunnablePassthrough(),
"question": lambda x: x
} | prompt | model | StrOutputParser()
# 简化:直接使用RunnablePassthrough
chain = RunnablePassthrough() | prompt | model | StrOutputParser()
result = chain.invoke({"context": "背景信息", "question": "问题"})
5.3 条件路由
from langchain_core.runnables import RunnableBranch
# 定义不同的处理链
technical_chain = init_chat_model("gpt-4o-mini") | StrOutputParser()
business_chain = init_chat_model("gpt-4o-mini") | StrOutputParser()
default_chain = init_chat_model("gpt-4o-mini") | StrOutputParser()
# 创建条件路由
def route_by_topic(x):
if "技术" in x.lower():
return technical_chain
elif "商业" in x.lower():
return business_chain
return default_chain
# 使用
router = RunnableBranch(
(lambda x: "技术" in x, technical_chain),
(lambda x: "商业" in x, business_chain),
default_chain
)
result = router.invoke("解释什么是技术")
5.4 重试与异常处理
from langchain_core.runnables import Runnable
import time
class ResilientChain(Runnable):
def __init__(self, chain, max_retries=3, backoff_factor=2):
self.chain = chain
self.max_retries = max_retries
self.backoff_factor = backoff_factor
def invoke(self, input):
for attempt in range(self.max_retries):
try:
return self.chain.invoke(input)
except Exception as e:
if attempt == self.max_retries - 1:
raise
wait_time = self.backoff_factor ** attempt
print(f"尝试{attempt + 1}失败,等待{wait_time}秒后重试...")
time.sleep(wait_time)
# 使用
chain = prompt | model | parser
resilient_chain = ResilientChain(chain, max_retries=3)
result = resilient_chain.invoke({"topic": "AI"})
第六部分:工具与函数调用
6.1 定义工具
from langchain.tools import tool, Tool
from typing import Optional
import math
import requests
# 方法1:使用@tool装饰器(推荐)
@tool
def calculate_area(radius: float) -> float:
"""计算圆的面积
Args:
radius: 圆的半径
"""
return math.pi * radius ** 2
@tool
def search_wikipedia(query: str, max_results: int = 3) -> str:
"""在Wikipedia搜索信息
Args:
query: 搜索关键词
max_results: 最多返回结果数
"""
# 实现搜索逻辑
return f"搜索 '{query}' 的结果..."
@tool
def get_current_weather(location: str, unit: str = "celsius") -> str:
"""获取指定位置的天气
Args:
location: 城市名称
unit: 温度单位(celsius或fahrenheit)
"""
return f"{location}的天气:晴天,25°C"
# 方法2:使用Tool类直接定义
def multiply(x: float, y: float) -> float:
"""两数相乘"""
return x * y
multiply_tool = Tool(
name="Multiply",
func=multiply,
description="将两个数字相乘",
# 可选:为参数提供更详细的描述
)
# 工具列表
tools = [calculate_area, search_wikipedia, get_current_weather]
6.2 工具执行
from langchain_core.tools import ToolException
# 工具执行和错误处理
@tool
def division(x: float, y: float) -> float:
"""两数相除
Args:
x: 被除数
y: 除数
"""
if y == 0:
raise ToolException("除数不能为0")
return x / y
# 执行工具
result = division.invoke({"x": 10, "y": 2})
print(result) # 5.0
# 获取工具信息
print(division.name) # "division"
print(division.description) # "两数相除..."
print(division.get_input_schema()) # 输入schema
6.3 动态工具注册
from langchain.agents import tool
import inspect
class ToolRegistry:
def __init__(self):
self.tools = {}
def register(self, name: str, description: str):
"""动态注册工具的装饰器"""
def decorator(func):
self.tools[name] = tool(func)
return func
return decorator
def get_tools(self):
return list(self.tools.values())
registry = ToolRegistry()
@registry.register("compute_factorial", "计算阶乘")
def factorial(n: int) -> int:
"""计算n的阶乘"""
if n <= 1:
return 1
return n * factorial(n - 1)
@registry.register("reverse_string", "反转字符串")
def reverse(text: str) -> str:
"""将字符串反转"""
return text[::-1]
# 获取所有注册的工具
tools = registry.get_tools()
6.4 工具组合与管理
from langchain.tools import StructuredTool
from pydantic import BaseModel, Field
class SearchInput(BaseModel):
"""搜索工具的输入"""
query: str = Field(description="搜索关键词")
max_results: int = Field(default=5, description="返回结果数")
# 使用Pydantic定义结构化输入
def web_search(query: str, max_results: int = 5) -> str:
"""从网络搜索信息"""
return f"找到关于'{query}'的{max_results}个结果"
search_tool = StructuredTool.from_function(
func=web_search,
name="WebSearch",
description="搜索网络获取信息",
args_schema=SearchInput
)
# 工具集合类
class ToolKit:
"""工具集合管理"""
def __init__(self):
self.tools = []
def add_tool(self, tool):
self.tools.append(tool)
def get_tools(self):
return self.tools
def get_tool_by_name(self, name: str):
for tool in self.tools:
if tool.name == name:
return tool
return None
toolkit = ToolKit()
toolkit.add_tool(calculate_area)
toolkit.add_tool(search_wikipedia)
toolkit.add_tool(search_tool)
# 获取工具
tools = toolkit.get_tools()
第七部分:代理Agent
7.1 创建基础代理
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
# 初始化模型
model = init_chat_model("gpt-4o")
# 创建代理(最新方式)
agent = create_agent(
model=model,
tools=tools, # 使用之前定义的工具
system_prompt="你是一个有用的AI助手,能够使用提供的工具来完成任务"
)
# 调用代理
result = agent.invoke({
"messages": [
{"role": "user", "content": "请计算半径为5的圆的面积"}
]
})
print(result)
7.2 代理类型详解
类型1:ReAct Agent(推荐)
# ReAct = Reasoning + Acting
# 代理会交替进行推理和工具调用
agent = create_agent(
model=model,
tools=tools,
system_prompt="""
你是一个问题解决助手。
对于每个问题,你应该:
1. 思考问题的关键点
2. 列出可以使用的工具
3. 逐步调用工具获取信息
4. 基于结果进行进一步分析
5. 给出最终答案
"""
)
# 使用
result = agent.invoke({
"messages": [
{"role": "user", "content": "请计算三个数字的阶乘:3、5、7"}
]
})
类型2:Structured Agent(结构化输出)
from pydantic import BaseModel
class AgentResponse(BaseModel):
"""代理的结构化响应"""
thought: str # 思考过程
action: str # 采取的行动
result: str # 结果
final_answer: str # 最终答案
# 代理可以配置返回结构化输出
agent = create_agent(
model=model,
tools=tools,
system_prompt="使用提供的工具完成任务,并以结构化格式返回结果"
)
7.3 工具调用链
from langchain.agents import tool_calls_to_messages
# 当模型调用工具时的处理流程
def process_tool_call(tool_call):
"""处理工具调用"""
tool_name = tool_call["name"]
tool_args = tool_call["args"]
# 查找并执行工具
tool = next((t for t in tools if t.name == tool_name), None)
if tool:
result = tool.invoke(tool_args)
return result
else:
return f"工具 '{tool_name}' 未找到"
# 示例流程
messages = [
{"role": "user", "content": "今天杭州的天气怎么样?"}
]
# 1. 第一次调用:模型生成工具调用
response = model.invoke(messages)
# 2. 如果模型生成了工具调用
if response.tool_calls:
for tool_call in response.tool_calls:
tool_result = process_tool_call(tool_call)
# 3. 将工具结果加入消息
messages.extend([
{"role": "assistant", "content": response.content},
{"role": "tool", "content": tool_result}
])
# 4. 再次调用模型生成最终回答
final_response = model.invoke(messages)
print(final_response.content)
7.4 代理状态管理
from typing import Annotated, TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
class AgentState(TypedDict):
"""代理状态"""
messages: Annotated[list, add_messages]
tool_calls: list
current_tool: str
# 构建状态图
def should_continue(state):
"""判断是否继续执行"""
return "CONTINUE" if state["tool_calls"] else "STOP"
graph = StateGraph(AgentState)
# 定义节点
def process_messages(state):
"""处理消息节点"""
response = model.invoke(state["messages"])
return {
"messages": [response],
"tool_calls": getattr(response, 'tool_calls', [])
}
def execute_tools(state):
"""执行工具节点"""
results = []
for tool_call in state["tool_calls"]:
result = process_tool_call(tool_call)
results.append(result)
return {"tool_calls": results}
# 添加节点
graph.add_node("process", process_messages)
graph.add_node("tools", execute_tools)
# 添加边
graph.add_edge(START, "process")
graph.add_conditional_edges(
"process",
should_continue,
{"CONTINUE": "tools", "STOP": END}
)
graph.add_edge("tools", "process")
# 编译图
agent = graph.compile()
7.5 代理中间件
from langchain.agents.middleware import AgentMiddleware
class LoggingMiddleware(AgentMiddleware):
"""记录所有代理活动的中间件"""
def before_agent(self, state):
print(f"[开始] 消息数量: {len(state.get('messages', []))}")
def after_agent(self, state):
print(f"[结束] 生成了工具调用: {len(state.get('tool_calls', []))}")
class RateLimitMiddleware(AgentMiddleware):
"""限制工具调用频率"""
def __init__(self, max_calls: int = 10):
self.max_calls = max_calls
self.call_count = 0
def wrap_tool_call(self, tool_call, handler):
if self.call_count >= self.max_calls:
return {"error": f"已达到最大工具调用限制 ({self.max_calls})"}
self.call_count += 1
return handler(tool_call)
class SensitiveOperationMiddleware(AgentMiddleware):
"""需要人工批准的敏感操作"""
def wrap_tool_call(self, tool_call, handler):
sensitive_tools = ["delete_database", "send_email", "withdraw_funds"]
if tool_call["name"] in sensitive_tools:
# 在实际应用中这里应该发送批准请求
print(f"[需要批准] 敏感操作: {tool_call['name']}")
# 等待批准或返回错误
return {"status": "pending_approval"}
return handler(tool_call)
# 创建带中间件的代理
agent = create_agent(
model=model,
tools=tools,
middleware=[
LoggingMiddleware(),
RateLimitMiddleware(max_calls=20),
SensitiveOperationMiddleware()
]
)
第八部分:RAG检索增强
8.1 向量存储与嵌入
from langchain.embeddings import init_embeddings
from langchain.vectorstores import InMemoryVectorStore
# 初始化嵌入模型
embeddings = init_embeddings("openai")
# 创建向量存储
vector_store = InMemoryVectorStore(
embedding_function=embeddings.embed_query
)
# 添加文档
documents = [
"LangChain是一个用于构建LLM应用的框架",
"代理可以使用工具来完成复杂任务",
"RAG结合了检索和生成的能力",
"提示工程对LLM应用很重要"
]
# 添加文档到向量存储
from langchain_core.documents import Document
docs = [Document(page_content=doc) for doc in documents]
vector_store.add_documents(docs)
# 搜索相似文档
results = vector_store.similarity_search("什么是LangChain", k=2)
for doc in results:
print(doc.page_content)
8.2 检索链
from langchain.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
# 构建RAG链
template = """
基于以下上下文回答问题。
上下文:
{context}
问题:{question}
答案:
"""
prompt = ChatPromptTemplate.from_template(template)
model = init_chat_model("gpt-4o-mini")
# 创建检索链
retriever = vector_store.as_retriever(search_kwargs={"k": 2})
rag_chain = (
RunnableParallel(
context=retriever,
question=RunnablePassthrough()
)
| {
"context": lambda x: "\n".join([doc.page_content for doc in x["context"]]),
"question": lambda x: x["question"]
}
| prompt
| model
| StrOutputParser()
)
# 使用
result = rag_chain.invoke("请解释RAG是什么")
print(result)
8.3 文档加载与处理
from langchain_community.document_loaders import WebBaseLoader, PDFPlumberLoader
from langchain.text_splitters import RecursiveCharacterTextSplitter
# 从网页加载
loader = WebBaseLoader("https://example.com")
documents = loader.load()
# 从PDF加载
pdf_loader = PDFPlumberLoader("document.pdf")
documents = pdf_loader.load()
# 文本分割
splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 每个块的字符数
chunk_overlap=50, # 块之间的重叠
separators=["\n\n", "\n", " ", ""]
)
chunks = splitter.split_documents(documents)
# 添加到向量存储
for chunk in chunks:
vector_store.add_documents([chunk])
8.4 混合检索
from langchain.retrievers import BM25Retriever, EnsembleRetriever
# BM25检索器(关键词搜索)
bm25_retriever = BM25Retriever.from_documents(chunks)
# 向量检索器
vector_retriever = vector_store.as_retriever()
# 集合检索器(结合两种方法)
ensemble_retriever = EnsembleRetriever(
retrievers=[bm25_retriever, vector_retriever],
weights=[0.5, 0.5] # 权重
)
# 使用
results = ensemble_retriever.get_relevant_documents("LangChain的核心特性")
第九部分:详细应用案例
案例1:智能个人助手
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent
from langchain.prompts import ChatPromptTemplate
from langchain.memory import ConversationBufferMemory
from langchain.tools import tool
from datetime import datetime
# 定义工具
@tool
def get_current_time() -> str:
"""获取当前时间"""
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
@tool
def set_reminder(task: str, time: str) -> str:
"""设置提醒"""
return f"已设置提醒:{time}提醒我'{task}'"
@tool
def search_knowledge_base(query: str) -> str:
"""搜索知识库"""
kb = {
"Python": "Python是一种高级编程语言",
"AI": "人工智能是模拟人类智能的技术",
"机器学习": "机器学习是AI的一个分支"
}
return kb.get(query, f"未找到关于'{query}'的信息")
# 创建助手
model = init_chat_model("gpt-4o-mini")
memory = ConversationBufferMemory(return_messages=True)
assistant = create_agent(
model=model,
tools=[get_current_time, set_reminder, search_knowledge_base],
system_prompt="""
你是一个有用的个人助手。你能够:
1. 告诉用户当前时间
2. 帮助设置提醒
3. 回答关于各个主题的问题
始终友好和专业,记住之前的对话内容。
"""
)
# 交互示例
messages = [
{"role": "user", "content": "现在几点了?"}
]
response = assistant.invoke({"messages": messages})
print("助手:", response)
messages.append({"role": "assistant", "content": response})
messages.append({"role": "user", "content": "帮我设置一个明天10点的提醒,提醒我开会"})
response = assistant.invoke({"messages": messages})
print("助手:", response)
案例2:代码审查机器人
from langchain.chat_models import init_chat_model
from langchain.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from pydantic import BaseModel, Field
class CodeReview(BaseModel):
"""代码审查结果"""
issues: list = Field(description="发现的问题列表")
severity: str = Field(description="严重程度: critical, high, medium, low")
improvements: list = Field(description="改进建议")
score: int = Field(description="代码质量评分 0-100")
# 构建代码审查链
template = """
请审查以下代码,找出潜在问题并提供改进建议。
代码:
```python
{code}
语言:{language} 焦点:{focus}
请以JSON格式返回审查结果。 """
prompt = ChatPromptTemplate.from_template(template) model = init_chat_model("gpt-4o") parser = JsonOutputParser(pydantic_object=CodeReview)
code_reviewer = prompt | model | parser
使用
code = """ def calculate_total(items): total = 0 for item in items: total = total + item['price'] * item['quantity'] return total """
result = code_reviewer.invoke({ "code": code, "language": "Python", "focus": "性能和最佳实践" })
print("代码审查结果:") for issue in result["issues"]: print(f"- {issue}") print(f"评分: {result['score']}/100")
## 案例3:文档问答系统
```python
from langchain_community.document_loaders import DirectoryLoader
from langchain.text_splitters import RecursiveCharacterTextSplitter
from langchain.embeddings import init_embeddings
from langchain.vectorstores import InMemoryVectorStore
from langchain.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
# 加载文档
loader = DirectoryLoader(
"./docs",
glob="*.md",
loader_cls=TextLoader
)
documents = loader.load()
# 分割文档
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=100
)
chunks = splitter.split_documents(documents)
# 创建向量存储
embeddings = init_embeddings("openai")
vector_store = InMemoryVectorStore(
embedding_function=embeddings.embed_query
)
vector_store.add_documents(chunks)
# 构建问答系统
retriever = vector_store.as_retriever(search_kwargs={"k": 3})
template = """
使用以下文档片段回答问题。如果无法从文档中找到答案,请说"我不知道"。
文档:
{context}
问题:{question}
答案:"""
prompt = ChatPromptTemplate.from_template(template)
model = init_chat_model("gpt-4o")
qa_system = (
{
"context": retriever | (lambda docs: "\n\n".join([d.page_content for d in docs])),
"question": RunnablePassthrough()
}
| prompt
| model
| StrOutputParser()
)
# 使用
answer = qa_system.invoke("什么是LangChain?")
print(answer)
案例4:多步骤工作流自动化
from langchain.agents import create_agent
from langchain.tools import tool
from langchain.chat_models import init_chat_model
from langgraph.graph import StateGraph, START, END
from typing import Annotated, TypedDict
from langgraph.graph.message import add_messages
class WorkflowState(TypedDict):
"""工作流状态"""
messages: Annotated[list, add_messages]
workflow_step: int
data: dict
# 定义工作流步骤对应的工具
@tool
def validate_input(data: str) -> str:
"""验证用户输入"""
if len(data) < 10:
return "输入太短,请至少输入10个字符"
return "输入有效"
@tool
def process_data(data: str) -> str:
"""处理数据"""
return f"已处理: {data.upper()}"
@tool
def generate_report(processed_data: str) -> str:
"""生成报告"""
return f"报告:\n{processed_data}\n生成时间:{datetime.now()}"
@tool
def send_notification(report: str) -> str:
"""发送通知"""
return "报告已发送给相关人员"
# 构建工作流
def validation_step(state):
"""第1步:验证"""
response = model.invoke({
"messages": state["messages"] + [
{"role": "system", "content": "请验证提供的数据"}
]
})
return {"messages": [response], "workflow_step": 2, "data": {"raw": state["messages"][-1]["content"]}}
def processing_step(state):
"""第2步:处理"""
response = model.invoke({
"messages": state["messages"] + [
{"role": "system", "content": "请处理验证后的数据"}
]
})
return {"messages": [response], "workflow_step": 3}
def reporting_step(state):
"""第3步:生成报告"""
response = model.invoke({
"messages": state["messages"] + [
{"role": "system", "content": "请基于处理结果生成报告"}
]
})
return {"messages": [response], "workflow_step": 4}
def notification_step(state):
"""第4步:发送通知"""
return {"messages": state["messages"], "workflow_step": 5}
# 构建图
model = init_chat_model("gpt-4o-mini")
graph = StateGraph(WorkflowState)
graph.add_node("validation", validation_step)
graph.add_node("processing", processing_step)
graph.add_node("reporting", reporting_step)
graph.add_node("notification", notification_step)
graph.add_edge(START, "validation")
graph.add_edge("validation", "processing")
graph.add_edge("processing", "reporting")
graph.add_edge("reporting", "notification")
graph.add_edge("notification", END)
workflow = graph.compile()
# 执行工作流
initial_state = {
"messages": [{"role": "user", "content": "请处理这个数据:这是一个关于销售数据的重要文档"}],
"workflow_step": 1,
"data": {}
}
result = workflow.invoke(initial_state)
案例5:实时数据分析与报告
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent
from langchain.tools import tool
import json
from datetime import datetime, timedelta
import random
# 定义数据工具
@tool
def fetch_sales_data(date_range: str) -> str:
"""获取销售数据"""
data = {
"total_sales": random.randint(50000, 100000),
"orders": random.randint(100, 500),
"customers": random.randint(50, 200),
"average_order_value": random.randint(200, 800)
}
return json.dumps(data)
@tool
def fetch_market_trends(category: str) -> str:
"""获取市场趋势"""
trends = {
"growth_rate": f"{random.randint(5, 20)}%",
"market_share": f"{random.randint(10, 40)}%",
"competitor_count": random.randint(5, 20)
}
return json.dumps(trends)
@tool
def generate_insights(data: str) -> str:
"""生成洞察"""
return f"基于数据的分析洞察:\n- 销售趋势向上\n- 客户满意度较高\n- 竞争压力适中"
@tool
def create_chart_url(chart_type: str, data: str) -> str:
"""创建图表"""
return f"chart.png?type={chart_type}&data={data[:20]}..."
# 创建数据分析代理
model = init_chat_model("gpt-4o")
analyst = create_agent(
model=model,
tools=[fetch_sales_data, fetch_market_trends, generate_insights, create_chart_url],
system_prompt="""
你是一个数据分析专家。你的任务是:
1. 获取最新的销售和市场数据
2. 分析数据中的趋势
3. 生成可视化图表
4. 提供可行性建议
使用提供的工具完成分析,并生成详细的报告。
"""
)
# 执行分析
result = analyst.invoke({
"messages": [
{"role": "user", "content": "请生成一份本周销售分析报告,包括趋势分析和图表"}
]
})
print("分析报告:")
print(result)
第十部分:高级特性
10.1 流式处理与实时输出
from langchain.chat_models import init_chat_model
from langchain.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_template(
"以故事的形式讲述{topic}"
)
model = init_chat_model("gpt-4o")
chain = prompt | model
# 流式输出
print("开始讲述...")
for chunk in chain.stream({"topic": "AI的未来"}):
print(chunk.content, end="", flush=True)
print("\n讲述完毕")
# 异步流式处理
import asyncio
async def async_stream():
async for chunk in chain.astream({"topic": "区块链技术"}):
print(chunk.content, end="", flush=True)
asyncio.run(async_stream())
# 批量处理
topics = ["人工智能", "机器学习", "深度学习"]
results = chain.batch([{"topic": t} for t in topics])
# 并行处理
import concurrent.futures
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = [
executor.submit(chain.invoke, {"topic": t})
for t in topics
]
results = [f.result() for f in futures]
10.2 对话持久化
from langgraph.checkpoint.sqlite import SqliteSaver
# 使用SQLite保存对话历史
checkpointer = SqliteSaver.from_conn_string(":memory:")
# 创建支持持久化的代理
agent = create_agent(
model=model,
tools=tools,
checkpointer=checkpointer
)
# 同一个用户的对话可以跨会话保持
user_id = "user_123"
session_1 = agent.invoke(
{"messages": [{"role": "user", "content": "我叫张三"}]},
config={"configurable": {"thread_id": user_id}}
)
# 后续对话会记住之前的信息
session_2 = agent.invoke(
{"messages": [{"role": "user", "content": "你记得我是谁吗?"}]},
config={"configurable": {"thread_id": user_id}}
)
# agent会回答"你是张三"
10.3 自定义中间件
from langchain.agents.middleware import AgentMiddleware
from langchain.tools import ToolException
import time
class PerformanceMonitorMiddleware(AgentMiddleware):
"""监控代理性能"""
def __init__(self):
self.metrics = []
def before_agent(self, state):
state["start_time"] = time.time()
def after_agent(self, state):
elapsed = time.time() - state.get("start_time", time.time())
self.metrics.append({
"execution_time": elapsed,
"tool_calls": len(state.get("tool_calls", []))
})
print(f"执行时间: {elapsed:.2f}秒")
def get_metrics(self):
return self.metrics
class DataValidationMiddleware(AgentMiddleware):
"""验证工具输入和输出"""
def wrap_tool_call(self, tool_call, handler):
# 验证输入
args = tool_call.get("args", {})
if not args:
raise ToolException("工具调用缺少参数")
# 执行工具
result = handler(tool_call)
# 验证输出
if result is None:
raise ToolException("工具返回了None")
return result
class ContextEnrichmentMiddleware(AgentMiddleware):
"""丰富执行上下文"""
def before_agent(self, state):
# 添加元数据
state["execution_id"] = f"exec_{int(time.time() * 1000)}"
state["metadata"] = {
"timestamp": datetime.now().isoformat(),
"version": "1.0"
}
monitor = PerformanceMonitorMiddleware()
agent = create_agent(
model=model,
tools=tools,
middleware=[
monitor,
DataValidationMiddleware(),
ContextEnrichmentMiddleware()
]
)
10.4 成本优化
from langchain.chat_models import init_chat_model
from langchain.callbacks import get_openai_callback
# 方法1:使用回调追踪成本
def analyze_with_cost_tracking():
with get_openai_callback() as cb:
# 执行操作
chain = prompt | model
result = chain.invoke({"topic": "AI"})
print(f"总Token数: {cb.total_tokens}")
print(f"提示Token: {cb.prompt_tokens}")
print(f"完成Token: {cb.completion_tokens}")
print(f"成本: ${cb.total_cost}")
# 方法2:智能模型选择
def select_model_by_complexity(task_complexity: str):
"""根据任务复杂度选择不同的模型"""
if task_complexity == "simple":
return init_chat_model("gpt-4o-mini") # 更便宜
elif task_complexity == "medium":
return init_chat_model("gpt-4")
else:
return init_chat_model("gpt-4-turbo") # 最强大
# 方法3:批量处理以减少API调用
def batch_process(queries, batch_size=10):
"""批量处理减少往返次数"""
results = []
for i in range(0, len(queries), batch_size):
batch = queries[i:i+batch_size]
result = chain.batch([{"topic": q} for q in batch])
results.extend(result)
return results
# 方法4:缓存优化
from langchain.cache import InMemoryCache
from langchain.globals import set_llm_cache
# 启用缓存
set_llm_cache(InMemoryCache())
# 相同的请求会使用缓存结果
result1 = model.invoke("什么是AI?")
result2 = model.invoke("什么是AI?") # 使用缓存,不消耗Token
10.5 监控与调试
import logging
from langsmith import Client
# 设置日志
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
# 启用LangSmith追踪
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_PROJECT"] = "my-project"
# 自定义回调用于监控
from langchain_core.callbacks import BaseCallbackHandler
class DebugCallback(BaseCallbackHandler):
"""调试回调"""
def on_llm_start(self, serialized, prompts, **kwargs):
logger.debug(f"LLM开始,提示: {prompts[0][:50]}...")
def on_tool_start(self, serialized, input_str, **kwargs):
logger.debug(f"工具启动: {serialized['name']}")
def on_tool_end(self, output, **kwargs):
logger.debug(f"工具完成,输出长度: {len(str(output))}")
def on_chain_error(self, error, **kwargs):
logger.error(f"链错误: {error}")
# 使用回调
chain = prompt | model
result = chain.invoke(
{"topic": "AI"},
config={"callbacks": [DebugCallback()]}
)
总结
LangChain 1.2.0是构建AI应用的强大框架,核心优势包括:
- 统一API - 无论使用哪个LLM,接口保持一致
- 模块化设计 - 灵活组装各种功能模块
- 生产就绪 - 包含监控、日志、错误处理等企业级特性
- 丰富集成 - 集成200+外部服务
- 中间件系统 - 实现细粒度的流程控制
掌握本教程中的所有概念和案例,您就能构建从简单的聊天应用到复杂的多代理系统的各种AI应用。