本指南概述了 LangChain v1 与之前版本之间的主要变化。
简化的包
在 v1 中,langchain 包命名空间已显著缩减,以专注于代理的基本构建块。简化的包使核心功能更易于发现和使用。
命名空间
langchain-classic
如果您之前从 langchain 包中使用了以下任何内容,则需要安装 langchain-classic 并更新您的导入:
- 旧版链(
LLMChain、ConversationChain 等)
- 检索器(例如
MultiQueryRetriever 或之前 langchain.retrievers 模块中的任何内容)
- 索引 API
- Hub 模块(用于以编程方式管理提示)
- 嵌入模块(例如
CacheBackedEmbeddings 和社区嵌入)
langchain-community 重新导出
- 其他已弃用的功能
# 链
from langchain_classic.chains import LLMChain
# 检索器
from langchain_classic.retrievers import ...
# 索引
from langchain_classic.indexes import ...
# Hub
from langchain_classic import hub
安装方式:
pip install langchain-classic
迁移到 create_agent
在 v1.0 之前,我们建议使用 langgraph.prebuilt.create_react_agent 来构建代理。现在,我们建议您使用 langchain.agents.create_agent 来构建代理。
下表概述了从 create_react_agent 到 create_agent 的功能变化:
| 部分 | TL;DR - 变化内容 |
|---|
| 导入路径 | 包从 langgraph.prebuilt 移动到 langchain.agents |
| 提示 | 参数重命名为 system_prompt,动态提示使用中间件 |
| 模型前钩子 | 由具有 before_model 方法的中间件替换 |
| 模型后钩子 | 由具有 after_model 方法的中间件替换 |
| 自定义状态 | 仅支持 TypedDict,可通过 state_schema 或中间件定义 |
| 模型 | 通过中间件动态选择,不支持预绑定模型 |
| 工具 | 工具错误处理移至具有 wrap_tool_call 的中间件 |
| 结构化输出 | 移除提示输出,使用 ToolStrategy/ProviderStrategy |
| 流式节点名称 | 节点名称从 "agent" 更改为 "model" |
| 运行时上下文 | 通过 context 参数进行依赖注入,而不是 config["configurable"] |
| 命名空间 | 简化为专注于代理构建块,旧版代码移至 langchain-classic |
导入路径
代理预构建的导入路径已从 langgraph.prebuilt 更改为 langchain.agents。
函数名称已从 create_react_agent 更改为 create_agent:
from langgraph.prebuilt import create_react_agent
from langchain.agents import create_agent
更多信息,请参见 代理。
静态提示重命名
prompt 参数已重命名为 system_prompt:
from langchain.agents import create_agent
agent = create_agent(
model="claude-sonnet-4-6",
tools=[check_weather],
system_prompt="You are a helpful assistant"
)
SystemMessage 转字符串
如果在系统提示中使用 SystemMessage 对象,请提取字符串内容:
from langchain.agents import create_agent
agent = create_agent(
model="claude-sonnet-4-6",
tools=[check_weather],
system_prompt="You are a helpful assistant"
)
动态提示
动态提示是核心上下文工程模式——它们根据当前对话状态调整您告诉模型的内容。为此,请使用 @dynamic_prompt 装饰器:
from dataclasses import dataclass
from langchain.agents import create_agent
from langchain.agents.middleware import dynamic_prompt, ModelRequest
from langgraph.runtime import Runtime
@dataclass
class Context:
user_role: str = "user"
@dynamic_prompt
def dynamic_prompt(request: ModelRequest) -> str:
user_role = request.runtime.context.user_role
base_prompt = "You are a helpful assistant."
if user_role == "expert":
prompt = (
f"{base_prompt} Provide detailed technical responses."
)
elif user_role == "beginner":
prompt = (
f"{base_prompt} Explain concepts simply and avoid jargon."
)
else:
prompt = base_prompt
return prompt
agent = create_agent(
model="gpt-4.1",
tools=tools,
middleware=[dynamic_prompt],
context_schema=Context
)
# 使用上下文
agent.invoke(
{"messages": [{"role": "user", "content": "Explain async programming"}]},
context=Context(user_role="expert")
)
模型前钩子
模型前钩子现在作为具有 before_model 方法的中间件实现。
这种新模式更具可扩展性——您可以定义多个中间件在模型调用前运行,
在不同代理之间重用通用模式。
常见用例包括:
- 总结对话历史
- 裁剪消息
- 输入防护栏,例如 PII 脱敏
v1 现在内置了总结中间件作为选项:
from langchain.agents import create_agent
from langchain.agents.middleware import SummarizationMiddleware
agent = create_agent(
model="claude-sonnet-4-6",
tools=tools,
middleware=[
SummarizationMiddleware(
model="claude-sonnet-4-6",
trigger={"tokens": 1000}
)
]
)
自定义状态
自定义状态通过附加字段扩展默认代理状态。您可以通过两种方式定义自定义状态:
- 通过
create_agent 上的 state_schema - 最适合在工具中使用的状态
- 通过中间件 - 最适合由特定中间件钩子和附加到所述中间件的工具管理的状态
通过中间件定义自定义状态优于通过 create_agent 上的 state_schema 定义,因为它允许您将状态扩展在概念上限定在相关中间件和工具的范围内。state_schema 在 create_agent 上仍受支持以实现向后兼容。
通过 state_schema 定义状态
当您的自定义状态需要被工具访问时,使用 state_schema 参数:
from langchain.tools import tool, ToolRuntime
from langchain.agents import create_agent, AgentState
# 定义扩展 AgentState 的自定义状态
class CustomState(AgentState):
user_name: str
@tool
def greet(
runtime: ToolRuntime[None, CustomState]
) -> str:
"""使用此工具按名称问候用户。"""
user_name = runtime.state.get("user_name", "Unknown")
return f"Hello {user_name}!"
agent = create_agent(
model="claude-sonnet-4-6",
tools=[greet],
state_schema=CustomState
)
通过中间件定义状态
中间件也可以通过设置 state_schema 属性来定义自定义状态。
这有助于将状态扩展在概念上限定在相关中间件和工具的范围内。
from langchain.agents.middleware import AgentState, AgentMiddleware
from typing_extensions import NotRequired
from typing import Any
class CustomState(AgentState):
model_call_count: NotRequired[int]
class CallCounterMiddleware(AgentMiddleware[CustomState]):
state_schema = CustomState
def before_model(self, state: CustomState, runtime) -> dict[str, Any] | None:
count = state.get("model_call_count", 0)
if count > 10:
return {"jump_to": "end"}
return None
def after_model(self, state: CustomState, runtime) -> dict[str, Any] | None:
return {"model_call_count": state.get("model_call_count", 0) + 1}
agent = create_agent(
model="claude-sonnet-4-6",
tools=[...],
middleware=[CallCounterMiddleware()]
)
有关通过中间件定义自定义状态的更多详细信息,请参见 中间件文档。
状态类型限制
create_agent 仅支持 TypedDict 作为状态模式。不再支持 Pydantic 模型和数据类。
from langchain.agents import AgentState, create_agent
# AgentState 是一个 TypedDict
class CustomAgentState(AgentState):
user_id: str
agent = create_agent(
model="claude-sonnet-4-6",
tools=tools,
state_schema=CustomAgentState
)
只需从 langchain.agents.AgentState 继承,而不是从 BaseModel 继承或使用 dataclass 装饰。
如果需要执行验证,请在中间件钩子中处理。
动态模型选择允许您根据运行时上下文(例如,任务复杂性、成本约束或用户偏好)选择不同的模型。create_react_agent 在 langgraph-prebuilt 的 v0.6 中发布,支持通过传递给 model 参数的可调用对象进行动态模型和工具选择。
此功能已在 v1 中移植到中间件接口。
动态模型选择
from langchain.agents import create_agent
from langchain.agents.middleware import (
AgentMiddleware, ModelRequest
)
from langchain.agents.middleware.types import ModelResponse
from langchain_openai import ChatOpenAI
from typing import Callable
basic_model = ChatOpenAI(model="gpt-5-nano")
advanced_model = ChatOpenAI(model="gpt-5")
class DynamicModelMiddleware(AgentMiddleware):
def wrap_model_call(self, request: ModelRequest, handler: Callable[[ModelRequest], ModelResponse]) -> ModelResponse:
if len(request.state.messages) > self.messages_threshold:
model = advanced_model
else:
model = basic_model
return handler(request.override(model=model))
def __init__(self, messages_threshold: int) -> None:
self.messages_threshold = messages_threshold
agent = create_agent(
model=basic_model,
tools=tools,
middleware=[DynamicModelMiddleware(messages_threshold=10)]
)
预绑定模型
为了更好地支持结构化输出,create_agent 不再接受带有工具或配置的预绑定模型:
# 不再支持
model_with_tools = ChatOpenAI().bind_tools([some_tool])
agent = create_agent(model_with_tools, tools=[])
# 改为使用
agent = create_agent("gpt-4.1-mini", tools=[some_tool])
如果未使用结构化输出,动态模型函数可以返回预绑定模型。
create_agent 的 tools 参数接受以下列表:
- LangChain
BaseTool 实例(使用 @tool 装饰的函数)
- 具有适当类型提示和文档字符串的可调用对象(函数)
- 表示内置提供程序工具的
dict
该参数将不再接受 ToolNode 实例。
from langchain.agents import create_agent
agent = create_agent(
model="claude-sonnet-4-6",
tools=[check_weather, search_web]
)
处理工具错误
您现在可以通过实现 wrap_tool_call 方法的中间件来配置工具错误的处理。
from langchain.agents import create_agent
from langchain.agents.middleware import wrap_tool_call
from langchain.messages import ToolMessage
@wrap_tool_call
def handle_tool_errors(request, handler):
"""使用自定义消息处理工具执行错误。"""
try:
return handler(request)
except Exception as e:
# 仅处理由于无效输入导致的工具执行期间发生的错误
# 这些输入通过模式验证但在运行时失败(例如,无效的 SQL 语法)。
# 请勿处理:
# - 网络故障(改用工具重试中间件)
# - 不正确的工具实现错误(应向上冒泡)
# - 模式不匹配错误(框架已自动处理)
#
# 向模型返回自定义错误消息
return ToolMessage(
content=f"Tool error: Please check your input and try again. ({str(e)})",
tool_call_id=request.tool_call["id"]
)
agent = create_agent(
model="claude-sonnet-4-6",
tools=[check_weather, search_web],
middleware=[handle_tool_errors]
)
结构化输出
节点更改
结构化输出过去是在与主代理分离的节点中生成的。现在不再是这样。
我们在主循环中生成结构化输出,从而降低成本和延迟。
工具和提供程序策略
在 v1 中,有两种新的结构化输出策略:
ToolStrategy 使用人工工具调用来生成结构化输出
ProviderStrategy 使用提供程序原生的结构化输出生成
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy, ProviderStrategy
from pydantic import BaseModel
class OutputSchema(BaseModel):
summary: str
sentiment: str
# 使用 ToolStrategy
agent = create_agent(
model="gpt-4.1-mini",
tools=tools,
# 显式使用工具策略
response_format=ToolStrategy(OutputSchema)
)
移除提示输出
提示输出不再通过 response_format 参数支持。与人工工具调用和提供程序原生结构化输出等策略相比,提示输出尚未被证明特别可靠。
流式节点名称重命名
当从代理流式传输事件时,节点名称已从 "agent" 更改为 "model",以更好地反映节点的用途。
运行时上下文
当您调用代理时,通常需要传递两种类型的数据:
- 在整个对话过程中变化的动态状态(例如,消息历史)
- 在对话期间不变的静态上下文(例如,用户元数据)
在 v1 中,通过将 context 参数设置为 invoke 和 stream 来支持静态上下文。
from dataclasses import dataclass
from langchain.agents import create_agent
@dataclass
class Context:
user_id: str
session_id: str
agent = create_agent(
model=model,
tools=tools,
context_schema=Context
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "Hello"}]},
context=Context(user_id="123", session_id="abc")
)
旧的 config["configurable"] 模式仍适用于向后兼容,但对于新应用程序或迁移到 v1 的应用程序,建议使用新的 context 参数。
标准内容
在 v1 中,消息获得了与提供程序无关的标准内容块。通过 message.content_blocks 访问它们,以获得跨提供程序的一致、类型化视图。现有的 message.content 字段对于字符串或提供程序原生结构保持不变。
变化内容
- 消息上新增
content_blocks 属性,用于规范化内容
- 标准化的块形状,记录在 消息 中
- 可通过
LC_OUTPUT_VERSION=v1 或 output_version="v1" 将标准块序列化到 content 中
读取标准化内容
from langchain.chat_models import init_chat_model
model = init_chat_model("gpt-5-nano")
response = model.invoke("Explain AI")
for block in response.content_blocks:
if block["type"] == "reasoning":
print(block.get("reasoning"))
elif block["type"] == "text":
print(block.get("text"))
创建多模态消息
from langchain.messages import HumanMessage
message = HumanMessage(content_blocks=[
{"type": "text", "text": "Describe this image."},
{"type": "image", "url": "https://example.com/image.jpg"},
])
res = model.invoke([message])
示例块形状
# 文本块
text_block = {
"type": "text",
"text": "Hello world",
}
# 图像块
image_block = {
"type": "image",
"url": "https://example.com/image.png",
"mime_type": "image/png",
}
有关更多详细信息,请参见内容块 参考。
序列化标准内容
默认情况下,标准内容块不会序列化到 content 属性中。如果您需要在 content 属性中访问标准内容块(例如,当向客户端发送消息时),您可以选择将其序列化到 content 中。
export LC_OUTPUT_VERSION=v1
安装:
uv pip install langchain-classic
破坏性更改
放弃 Python 3.9 支持
所有 LangChain 包现在都需要 Python 3.10 或更高版本。Python 3.9 将于 2025 年 10 月达到 生命周期结束。
更新聊天模型的返回类型
聊天模型调用的返回类型签名已从 BaseMessage 修复为 AIMessage。实现 bind_tools 的自定义聊天模型应更新其返回签名:
def bind_tools(
...
) -> Runnable[LanguageModelInput, AIMessage]:
OpenAI 响应 API 的默认消息格式
当与响应 API 交互时,langchain-openai 现在默认将响应项存储在消息 content 中。要恢复以前的行为,请将 LC_OUTPUT_VERSION 环境变量设置为 v0,或在实例化 ChatOpenAI 时指定 output_version="v0"。
# 使用 output_version 标志强制执行先前行为
model = ChatOpenAI(model="gpt-4.1-mini", output_version="v0")
langchain-anthropic 中的默认 max_tokens
langchain-anthropic 中的 max_tokens 参数现在根据所选模型默认为更高的值,而不是之前的默认值 1024。如果您依赖旧的默认值,请显式设置 max_tokens=1024。
旧版代码移至 langchain-classic
标准接口和代理焦点之外的现有功能已移至 langchain-classic 包。有关核心 langchain 包中可用内容以及移至 langchain-classic 的内容的详细信息,请参见 简化的命名空间 部分。
移除已弃用的 API
已在 1.0 中弃用并计划删除的方法、函数和其他对象已被删除。请查看之前版本的 弃用通知 以获取替换 API。
文本属性
消息对象上的 .text() 方法的使用应去掉括号,因为它现在是一个属性:
# 属性访问
text = response.text
# 已弃用的方法调用
text = response.text()
现有的使用模式(即 .text())将继续有效,但现在会发出警告。方法形式将在 v2 中删除。
从 AIMessage 中移除 example 参数
example 参数已从 AIMessage 对象中移除。我们建议迁移到使用 additional_kwargs 来传递额外的元数据(如果需要)。
次要更改
AIMessageChunk 对象现在包含一个 chunk_position 属性,其位置为 'last',以指示流中的最后一个块。这允许更清晰地处理流式消息。如果块不是最后一个,chunk_position 将为 None。
LanguageModelOutputVar 现在键入为 AIMessage,而不是 BaseMessage。
- 合并消息块的逻辑(
AIMessageChunk.add)已更新,具有更复杂的选择处理,用于合并块的最终 ID。它优先考虑提供程序分配的 ID,而不是 LangChain 生成的 ID。
- 我们现在默认使用
utf-8 编码打开文件。
- 标准测试现在使用多模态内容块。
存档文档
旧文档已存档以供参考: