本指南概述了 LangChain v1 与之前版本之间的主要变化。

简化包

在 v1 中,langchain 包的命名空间已大幅缩减,专注于代理的基本构建块。简化后的包让发现和使用核心功能变得更容易。

命名空间

模块可用内容备注
langchain.agentscreate_agent, AgentState核心代理创建功能
langchain.messages消息类型,内容块trim_messageslangchain-core 重新导出
langchain.tools@tool, BaseTool, 注入帮助器langchain-core 重新导出
langchain.chat_modelsinit_chat_model, BaseChatModel统一的模型初始化
langchain.embeddingsinit_embeddings, Embeddings嵌入模型

langchain-classic

如果你之前在 langchain 包中使用了以下任何功能,则需要安装 langchain-classic 并更新你的导入:
  • 旧的链(LLMChainConversationChain 等)
  • 检索器(例如 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 
更多信息,请参阅 Agents

提示词

静态提示词重命名

prompt 参数重命名为 system_prompt
from langchain.agents import create_agent

agent = create_agent(
    model="claude-sonnet-4-6",
    tools=[check_weather],
    system_prompt="你是一个有帮助的助手"
)

SystemMessage 转换为字符串

如果在系统提示词中使用了 SystemMessage 对象,提取字符串内容:
from langchain.agents import create_agent

agent = create_agent(
    model="claude-sonnet-4-6",
    tools=[check_weather],
    system_prompt="你是一个有帮助的助手"
)

动态提示词

动态提示词是一种核心的上下文工程模式——它根据当前对话状态调整告诉模型的内容。使用 @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-5.4",
    tools=tools,
    middleware=[dynamic_prompt],
    context_schema=Context
)

# 使用上下文
agent.invoke(
    {"messages": [{"role": "user", "content": "解释异步编程"}]},
    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}
        )
    ]
)

模型后钩子

模型后钩子现在通过中间件实现,使用 after_model 方法。 这种新模式更具扩展性——你可以定义多个中间件在调用模型之后运行, 在不同的代理之间重用常见的模式。 常见用例包括: v1 内置了一个用于工具调用审批的人在回路中间件:
from langchain.agents import create_agent
from langchain.agents.middleware import HumanInTheLoopMiddleware

agent = create_agent(
    model="claude-sonnet-4-6",
    tools=[read_email, send_email],
    middleware=[
        HumanInTheLoopMiddleware(
            interrupt_on={
                "send_email": {
                    "description": "请在发送前审核这封邮件",
                    "allowed_decisions": ["approve", "reject"]
                }
            }
        )
    ]
)

自定义状态

自定义状态通过附加字段扩展默认的代理状态。你可以通过两种方式定义自定义状态:
  1. 通过 state_schemacreate_agent - 最适合在工具中使用的状态
  2. 通过中间件 - 最适合由特定中间件钩子和关联到该中间件的工具管理的状态
通过中间件定义自定义状态优于通过 state_schemacreate_agent 上定义,因为它允许你将状态扩展在概念上限定到相关的中间件和工具中。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 装饰。 如果需要进行验证,请在中间件钩子中处理。

模型

动态模型选择允许你根据运行时上下文(例如任务复杂度、成本限制或用户偏好)选择不同的模型。在 v0.6 版本的 langgraph-prebuilt 中发布的 create_react_agent 支持通过传递给 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.4")

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-5.4-mini", tools=[some_tool])
如果使用结构化输出,动态模型函数可以返回预绑定模型。

工具

create_agenttools 参数接受以下列表:
  • 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"工具错误:请检查您的输入并重试。({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-5.4-mini",
    tools=tools,
    # 显式使用工具策略
    response_format=ToolStrategy(OutputSchema)
)

移除了提示性输出

提示性输出 不再通过 response_format 参数支持。与人工工具调用和提供者原生结构化输出等策略相比,提示性输出已被证明不够可靠。

流式传输节点名重命名

从代理流式传输事件时,节点名从 "agent" 改为 "model",以更好地反映节点的目的。

运行时上下文

当你调用一个代理时,通常需要传递两种类型的数据:
  • 在对话过程中变化的动态状态(例如,消息历史)
  • 在对话过程中不变的静态上下文(例如,用户元数据)
在 v1 中,通过设置 context 参数给 invokestream 来支持静态上下文。
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 属性,用于标准化内容
  • 标准化的块形状,在 Messages 中记录
  • 通过 LC_OUTPUT_VERSION=v1output_version="v1" 可选择将标准块序列化到 content

读取标准化内容

from langchain.chat_models import init_chat_model

model = init_chat_model("gpt-5-nano")
response = model.invoke("解释 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": "描述这张图片。"},
    {"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
了解更多:消息标准内容块多模态

简化包

langchain 包的命名空间在 v1 中已大幅缩减,专注于代理的基本构建块。简化后的包让发现和使用核心功能变得更容易。

命名空间

模块可用内容备注
langchain.agentscreate_agent, AgentState核心代理创建功能
langchain.messages消息类型,内容块trim_messageslangchain-core 重新导出
langchain.tools@tool, BaseTool, 注入帮助器langchain-core 重新导出
langchain.chat_modelsinit_chat_model, BaseChatModel统一的模型初始化
langchain.embeddingsinit_embeddings, Embeddings嵌入模型

langchain-classic

如果你之前在 langchain 包中使用了以下任何功能,则需要安装 langchain-classic 并更新你的导入:
  • 旧的链(LLMChainConversationChain 等)
  • 检索器(例如 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
安装
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-5.4-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() 方法应去掉括号,因为它现在是一个属性:
# 属性访问
text = response.text

# 已弃用的方法调用
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 编码打开文件。
  • 标准测试现在使用多模态内容块。

存档文档

旧版文档已存档以供参考: