本指南概述了 LangChain v1 与之前版本之间的主要变化。
简化包
在 v1 中,`langchain` 包命名空间已显著缩小,以专注于代理的基本构建块。精简后的包使得核心功能的发现和使用更加容易。
命名空间
langchain-classic
如果您从 `langchain` 包中使用以下任何功能,则需要安装 `langchain-classic` 并更新导入
- 旧版链(`LLMChain`、`ConversationChain` 等)
- 检索器(例如 `MultiQueryRetriever` 或来自旧版 `langchain.retrievers` 模块的任何内容)
- 索引 API
- hub 模块(用于以编程方式管理提示)
- 嵌入模块(例如 `CacheBackedEmbeddings` 和社区嵌入)
- `langchain-community` 重新导出
- 其他已弃用的功能
# Chains
from langchain_classic.chains import LLMChain
# Retrievers
from langchain_classic.retrievers import ...
# Indexing
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-5-20250929",
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-5-20250929",
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-4o",
tools=tools,
middleware=[dynamic_prompt],
context_schema=Context
)
# Use with 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-5-20250929",
tools=tools,
middleware=[
SummarizationMiddleware(
model="claude-sonnet-4-5-20250929",
max_tokens_before_summary=1000
)
]
)
模型后置钩子
模型后置钩子现在通过 `after_model` 方法作为中间件实现。这种新模式更具可扩展性——您可以在模型调用之后定义多个中间件来运行,从而在不同代理之间重用常见模式。 常见的用例包括:
v1 具有用于工具调用人工审批的内置中间件
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware
agent = create_agent(
model="claude-sonnet-4-5-20250929",
tools=[read_email, send_email],
middleware=[HumanInTheLoopMiddleware(
interrupt_on={
"send_email": True,
"description": "Please review this email before sending"
},
)]
)
自定义状态
自定义状态通过附加字段扩展了默认代理状态。您可以通过两种方式定义自定义状态
- 通过 `state_schema` 在 `create_agent` 上 - 最适合工具中使用的状态
- 通过中间件 - 最适合由特定中间件钩子和连接到该中间件的工具管理的状态
通过 `state_schema` 定义状态
当您的自定义状态需要由工具访问时,请使用 `state_schema` 参数
from langchain.tools import tool, ToolRuntime
from langchain.agents import create_agent, AgentState
# Define custom state extending AgentState
class CustomState(AgentState):
user_name: str
@tool
def greet(
runtime: ToolRuntime[CustomState]
) -> str:
"""Use this to greet the user by name."""
user_name = runtime.state.get("user_name", "Unknown")
return f"Hello {user_name}!"
agent = create_agent(
model="claude-sonnet-4-5-20250929",
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-5-20250929",
tools=[...],
middleware=[CallCounterMiddleware()]
)
有关通过中间件定义自定义状态的更多详细信息,请参阅中间件文档。
状态类型限制
`create_agent` 仅支持 `TypedDict` 作为状态模式。不再支持 Pydantic 模型和数据类。
from langchain.agents import AgentState, create_agent
# AgentState is a TypedDict
class CustomAgentState(AgentState):
user_id: str
agent = create_agent(
model="claude-sonnet-4-5-20250929",
tools=tools,
state_schema=CustomAgentState
)
只需从 `langchain.agents.AgentState` 继承,而不是从 `BaseModel` 继承或使用 `dataclass` 装饰。如果需要执行验证,请在中间件钩子中处理。
动态模型选择允许您根据运行时上下文(例如,任务复杂性、成本限制或用户偏好)选择不同的模型。在 `langgraph-prebuilt` 的 v0.6 中发布的 `create_react_agent` 支持通过传递给 `model` 参数的可调用对象进行动态模型和工具选择。 此功能已在 v1 中移植到中间件接口。动态模型选择
from langchain.agents import create_agent
from langchain.agents.middleware import (
AgentMiddleware, ModelRequest, ModelRequestHandler
)
from langchain.messages import AIMessage
from langchain_openai import ChatOpenAI
basic_model = ChatOpenAI(model="gpt-5-nano")
advanced_model = ChatOpenAI(model="gpt-5")
class DynamicModelMiddleware(AgentMiddleware):
def wrap_model_call(self, request: ModelRequest, handler: ModelRequestHandler) -> AIMessage:
if len(request.state.messages) > self.messages_threshold:
model = advanced_model
else:
model = basic_model
return handler(request.replace(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` 不再接受带有工具或配置的预绑定模型
# No longer supported
model_with_tools = ChatOpenAI().bind_tools([some_tool])
agent = create_agent(model_with_tools, tools=[])
# Use instead
agent = create_agent("gpt-4o-mini", tools=[some_tool])
如果不使用结构化输出,动态模型函数可以返回预绑定模型。
`create_agent` 的 `tools` 参数接受一个列表,其中包含
该参数将不再接受 `ToolNode` 实例。
from langchain.agents import create_agent
agent = create_agent(
model="claude-sonnet-4-5-20250929",
tools=[check_weather, search_web]
)
现在,您可以通过实现 `wrap_tool_call` 方法的中间件来配置工具错误的处理。
结构化输出
节点变更
结构化输出以前是在主代理之外的一个单独节点中生成的。现在不再是这种情况。我们现在在主循环中生成结构化输出,从而降低了成本和延迟。
在 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
# Using ToolStrategy
agent = create_agent(
model="gpt-4o-mini",
tools=tools,
# explicitly using tool strategy
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`][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
text_block = {
"type": "text",
"text": "Hello world",
}
# Image block
image_block = {
"type": "image",
"url": "https://example.com/image.png",
"mime_type": "image/png",
}
有关更多详细信息,请参阅内容块参考。
序列化标准内容
默认情况下,标准内容块不会序列化为 `content` 属性。如果您需要访问 `content` 属性中的标准内容块(例如,向客户端发送消息时),您可以选择将其序列化为 `content`。
export LC_OUTPUT_VERSION=v1
简化包
在 v1 中,`langchain` 包命名空间已显著缩小,以专注于代理的基本构建块。精简后的包使得核心功能的发现和使用更加容易。
命名空间
langchain-classic
如果您从 `langchain` 包中使用以下任何功能,则需要安装 `langchain-classic` 并更新导入
- 旧版链(`LLMChain`、`ConversationChain` 等)
- 检索器(例如 `MultiQueryRetriever` 或来自旧版 `langchain.retrievers` 模块的任何内容)
- 索引 API
- hub 模块(用于以编程方式管理提示)
- 嵌入模块(例如 `CacheBackedEmbeddings` 和社区嵌入)
- `langchain-community` 重新导出
- 其他已弃用的功能
# Chains
from langchain_classic.chains import LLMChain
# Retrievers
from langchain_classic.retrievers import ...
# Indexing
from langchain_classic.indexes import ...
# Hub
from langchain_classic import hub
安装:
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]:
在与 Responses API 交互时,`langchain-openai` 现在默认将响应项存储在消息 `content` 中。要恢复以前的行为,请将 `LC_OUTPUT_VERSION` 环境变量设置为 `v0`,或在实例化 `ChatOpenAI` 时指定 `output_version="v0"`。
# Enforce previous behavior with output_version flag
model = ChatOpenAI(model="gpt-4o-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()` 方法时应去掉括号,因为它现在是一个属性
# Property access
text = response.text
# Deprecated method call
text = response.text()
现有用法模式(即 `.text()`)将继续起作用,但现在会发出警告。方法形式将在 v2 中移除。
AIMessage 中移除了 `example` 参数
已从 `AIMessage` 对象中移除了 `example` 参数。我们建议迁移到使用 `additional_kwargs` 来根据需要传递额外的元数据。
次要变更
- `AIMessageChunk` 对象现在包含一个 `chunk_position` 属性,其位置为 `'last'`,表示流中的最后一个块。这使得流式消息的处理更加清晰。如果块不是最后一个块,`chunk_position` 将为 `None`。
- `LanguageModelOutputVar` 现在类型为 `AIMessage`,而不是 `BaseMessage`。
- 合并消息块(`AIMessageChunk.add`)的逻辑已更新,对合并块的最终 ID 进行了更复杂的选择处理。它优先考虑提供者分配的 ID,而不是 LangChain 生成的 ID。
- 我们现在默认使用 `utf-8` 编码打开文件。
- 标准测试现在使用多模态内容块。