本迁移指南概述了 LangChain v1 的主要变更。要了解 v1 的新特性,请参阅 介绍文章 升级方式:
npm install langchain@latest @langchain/core@latest

createAgent

在 v1 中,react agent 预制件现在位于 langchain 包中。下表概述了功能上的变化:
部分变化内容
导入路径包从 @langchain/langgraph/prebuilts 移至 langchain
提示词参数重命名为 systemPrompt,动态提示词使用中间件
模型前钩子替换为具有 beforeModel 方法的中间件
模型后钩子替换为具有 afterModel 方法的中间件
自定义状态在中间件中定义,仅支持 zod 对象
模型通过中间件动态选择,不支持预绑定工具模型
工具工具错误处理移至带有 wrapToolCall 的中间件
结构化输出移除了 prompted output,使用 toolStrategy/providerStrategy
流式节点名称节点名称从 "agent" 改为 "model"
运行时上下文使用 context 属性替代 config.configurable
命名空间精简为专注于 agent 构建块,旧代码移至 @langchain/classic

导入路径

react agent 预制件的导入路径已从 @langchain/langgraph/prebuilts 改为 langchain。函数名从 createReactAgent 改为 createAgent
import { createReactAgent } from "@langchain/langgraph/prebuilts";
import { createAgent } from "langchain";

提示词

静态提示词重命名

prompt 参数已重命名为 systemPrompt
import { createAgent } from "langchain";

agent = createAgent({
  model,
  tools,
  systemPrompt: "You are a helpful assistant.",
});

SystemMessage

如果在系统提示词中使用 SystemMessage 对象,现在将直接使用字符串内容:
import { SystemMessage, createAgent } from "langchain";

const agent = createAgent({
  model,
  tools,
  systemPrompt: "You are a helpful assistant.",
});

动态提示词

动态提示词是一种核心的上下文工程模式——它根据当前对话状态来调整发送给模型的内容。为此,请使用 dynamicSystemPromptMiddleware
import { createAgent, dynamicSystemPromptMiddleware } from "langchain";
import * as z from "zod";

const contextSchema = z.object({
  userRole: z.enum(["expert", "beginner"]).default("beginner"),
});

const userRolePrompt = dynamicSystemPromptMiddleware<z.infer<typeof contextSchema>>( 
    (_state, runtime) => {
        const userRole = runtime.context.userRole;
        const basePrompt = "You are a helpful assistant.";

        if (userRole === "expert") {
            return `${basePrompt} Provide detailed technical responses.`;
        } else if (userRole === "beginner") {
            return `${basePrompt} Explain concepts simply and avoid jargon.`;
        }
        return basePrompt;
    }
);

const agent = createAgent({
  model,
  tools,
  middleware: [userRolePrompt],
  contextSchema,
});

await agent.invoke(
  {
    messages: [new HumanMessage("Explain async programming")],
  },
  {
    context: {
      userRole: "expert",
    },
  }
);

模型前钩子

模型前钩子现在作为带有 beforeModel 方法的中间件实现。这种模式更具可扩展性——你可以定义多个中间件在模型调用前运行,并在多个 agent 间复用它们。 常见用例包括:
  • 摘要对话历史
  • 修剪消息
  • 输入护栏,如 PII 脱敏
v1 包含内置的摘要中间件:
import { createAgent, summarizationMiddleware } from "langchain";

const agent = createAgent({
  model: "claude-sonnet-4-6",
  tools,
  middleware: [
    summarizationMiddleware({
      model: "claude-sonnet-4-6",
      trigger: { tokens: 1000 },
    }),
  ],
});

模型后钩子

模型后钩子现在作为带有 afterModel 方法的中间件实现。这使你可以在模型响应后组合多个处理程序。 常见用例包括:
  • 人机协作审批
  • 输出护栏
v1 包含内置的人机协作中间件:
import { createAgent, humanInTheLoopMiddleware } from "langchain";

const agent = createAgent({
  model: "claude-sonnet-4-6",
  tools: [readEmail, sendEmail],
  middleware: [
    humanInTheLoopMiddleware({
      interruptOn: {
        sendEmail: { allowedDecisions: ["approve", "edit", "reject"] },
      },
    }),
  ],
});

自定义状态

自定义状态现在通过中间件的 stateSchema 属性定义。使用 Zod 声明在 agent 运行期间携带的额外状态字段。
import * as z from "zod";
import { createAgent, createMiddleware, tool } from "langchain";

const UserState = z.object({
  userName: z.string(),
});

const userState = createMiddleware({
  name: "UserState",
  stateSchema: UserState,
  beforeModel: (state) => {
    // 访问自定义状态属性
    const name = state.userName;
    // 可选择根据状态修改消息/系统提示词
    return;
  },
});

const greet = tool(
  async () => {
    return "Hello!";
  },
  {
    name: "greet",
    description: "Greet the user",
    schema: z.object({}),
  }
);

const agent = createAgent({
  model: "claude-sonnet-4-6",
  tools: [greet],
  middleware: [userState],
});

await agent.invoke({
  messages: [{ role: "user", content: "Hi" }],
  userName: "Ada",
});

模型

动态模型选择现在通过中间件实现。使用 wrapModelCall 根据状态或运行时上下文切换模型(和工具)。在 createReactAgent 中,这是通过传递给 model 参数的函数实现的。 该功能在 v1 中已移植到中间件接口。

动态模型选择

import { createAgent, createMiddleware } from "langchain";

const dynamicModel = createMiddleware({
  name: "DynamicModel",
  wrapModelCall: (request, handler) => {
    const messageCount = request.state.messages.length;
    const model = messageCount > 10 ? "openai:gpt-5.4" : "openai:gpt-5-nano";
    return handler({ ...request, model });
  },
});

const agent = createAgent({
  model: "gpt-5-nano",
  tools,
  middleware: [dynamicModel],
});

预绑定工具模型

为了更好地支持结构化输出,createAgent 应该接收一个普通模型(字符串或实例)和一个单独的 tools 列表。在使用结构化输出时,避免传入已预绑定工具的模型。
// 不再支持
// const modelWithTools = new ChatOpenAI({ model: "gpt-5.4-mini" }).bindTools([someTool]);
// const agent = createAgent({ model: modelWithTools, tools: [] });

// 请使用
const agent = createAgent({ model: "gpt-5.4-mini", tools: [someTool] });

工具

createAgenttools 参数接受:
  • 使用 tool 函数创建的工具
  • LangChain 工具实例
  • 表示内置 provider 工具的对象

处理工具错误

现在你可以通过实现了 wrapToolCall 方法的中间件来配置工具错误处理。
import { createAgent, createMiddleware, ToolMessage } from "langchain";

const handleToolErrors = createMiddleware({
  name: "HandleToolErrors",
  wrapToolCall: async (request, handler) => {
    try {
      return await handler(request);
    } catch (error) {
      // 仅处理因无效输入导致运行时失败的工具执行错误
      // 这些输入通过了 schema 验证但在运行时出错(例如无效的 SQL 语法)。
      // 不要处理:
      // - 网络故障(应使用工具重试中间件)
      // - 不正确的工具实现错误(应向上抛出)
      // - schema 不匹配错误(框架已自动处理)
      //
      // 返回自定义错误消息给模型
      return new ToolMessage({
        content: `Tool error: Please check your input and try again. (${error})`,
        tool_call_id: request.toolCall.id!,
      });
    }
  },
});

const agent = createAgent({
  model: "claude-sonnet-4-6",
  tools: [checkWeather, searchWeb],
  middleware: [handleToolErrors],
});

结构化输出

节点变更

结构化输出过去是在独立于主 agent 的节点中生成的。现在不再如此。结构化输出在主循环中生成(无需额外的 LLM 调用),降低了成本和延迟。

工具和 provider 策略

在 v1 中,有两种策略:
  • toolStrategy 使用人造工具调用来生成结构化输出
  • providerStrategy 使用 provider 原生的结构化输出生成
import { createAgent, toolStrategy } from "langchain";
import * as z from "zod";

const OutputSchema = z.object({
  summary: z.string(),
  sentiment: z.string(),
});

const agent = createAgent({
  model: "gpt-5.4-mini",
  tools,
  // 显式使用工具策略
  responseFormat: toolStrategy(OutputSchema),
});

移除 prompted output

通过 responseFormat 中的自定义指令实现的 prompted output 已被移除,取而代之的是上述策略。

流式节点名称重命名

在从 agent 流式传输事件时,节点名称从 "agent" 改为 "model",以更好地反映节点的用途。

运行时上下文

调用 agent 时,通过 context 配置参数传递静态、只读的配置。这替代了使用 config.configurable 的模式。
import { createAgent, HumanMessage } from "langchain";
import * as z from "zod";

const agent = createAgent({
  model: "gpt-5.4",
  tools,
  contextSchema: z.object({ userId: z.string(), sessionId: z.string() }),
});

const result = await agent.invoke(
  { messages: [new HumanMessage("Hello")] },
  { context: { userId: "123", sessionId: "abc" } },
);
旧的 config.configurable 模式仍然有效以实现向后兼容,但对于新应用或迁移到 v1 的应用,推荐使用新的 context 参数。

标准内容

在 v1 中,消息获得了与 provider 无关的标准内容块。通过 message.contentBlocks 访问它们,即可获得跨 provider 的一致、带类型的视图。现有的 message.content 字段对于字符串或 provider 原生结构保持不变。

变化内容

  • 消息上新增 contentBlocks 属性,用于规范化内容。
  • 新增 ContentBlock 下的 TypeScript 类型,提供强类型支持。
  • 通过 LC_OUTPUT_VERSION=v1outputVersion: "v1" 可选择将标准块序列化到 content 中。

读取标准化内容

import { initChatModel } from "langchain";

const model = await initChatModel("gpt-5-nano");
const response = await model.invoke("Explain AI");

for (const block of response.contentBlocks) {
  if (block.type === "reasoning") {
    console.log(block.reasoning);
  } else if (block.type === "text") {
    console.log(block.text);
  }
}

创建多模态消息

import { HumanMessage } from "langchain";

const message = new HumanMessage({
  contentBlocks: [
    { type: "text", text: "Describe this image." },
    { type: "image", url: "https://example.com/image.jpg" },
  ],
});
const res = await model.invoke([message]);

块类型示例

import { ContentBlock } from "langchain";

const textBlock: ContentBlock.Text = {
  type: "text",
  text: "Hello world",
};

const imageBlock: ContentBlock.Multimodal.Image = {
  type: "image",
  url: "https://example.com/image.png",
  mimeType: "image/png",
};
有关更多详细信息,请参阅内容块 参考文档

序列化标准内容

默认情况下,标准内容块不会序列化到 content 属性中。如果你需要在 content 属性中访问标准内容块(例如,向客户端发送消息时),可以选择将它们序列化到 content 中。
export LC_OUTPUT_VERSION=v1
了解更多:消息标准内容块。有关输入示例,请参阅 多模态

精简包

langchain 包的命名空间已精简,专注于 agent 构建块。旧功能已移至 @langchain/classic。新包仅暴露最有用和相关的功能。

导出内容

v1 包包含:
模块可用内容备注
AgentscreateAgentAgentState核心 agent 创建功能
Messages消息类型、内容块、trimMessages@langchain/core 重新导出
Toolstool、工具类@langchain/core 重新导出
Chat modelsinitChatModelBaseChatModel统一的模型初始化

@langchain/classic

如果你使用旧版链、索引 API 或以前从 @langchain/community 重新导出的功能,请安装 @langchain/classic 并更新导入:
npm install @langchain/classic
// v1 (新)
import { ... } from "@langchain/classic";
import { ... } from "@langchain/classic/chains";

// v0 (旧)
import { ... } from "langchain";
import { ... } from "langchain/chains";

破坏性变更

不再支持 Node 18

所有 LangChain 包现在要求 Node.js 20 或更高版本。Node.js 18 已于 2025 年 3 月 终止生命周期

新的构建产物

所有 langchain 包的构建现在使用打包器方式,而不是原始的 TypeScript 输出。如果你从 dist/ 目录导入文件(不推荐),则需要更新导入以使用新的模块系统。

旧代码移至 @langchain/classic

标准接口和 agent 之外的传统功能已移至 @langchain/classic 包。有关核心 langchain 包中可用的内容以及移至 @langchain/classic 的内容,请参阅 精简包 部分。

移除已弃用的 API

已在之前标记为弃用并计划在 1.0 中移除的方法、函数和其他对象已被删除。
以下已弃用的 API 在 v1 中已被移除:

核心功能

  • TraceGroup - 改用 LangSmith 追踪
  • BaseDocumentLoader.loadAndSplit - 改用 .load() 后跟文本分割器
  • RemoteRunnable - 不再支持

提示词

  • BasePromptTemplate.serialize.deserialize - 直接使用 JSON 序列化
  • ChatPromptTemplate.fromPromptMessages - 改用 ChatPromptTemplate.fromMessages

检索器

  • BaseRetrieverInterface.getRelevantDocuments - 改用 .invoke()

Runnables

  • Runnable.bind - 改用 .bindTools() 或其他特定绑定方法
  • Runnable.map - 改用 .batch()
  • RunnableBatchOptions.maxConcurrency - 在 config 对象中使用 maxConcurrency

聊天模型

  • BaseChatModel.predictMessages - 改用 .invoke()
  • BaseChatModel.predict - 改用 .invoke()
  • BaseChatModel.serialize - 直接使用 JSON 序列化
  • BaseChatModel.callPrompt - 改用 .invoke()
  • BaseChatModel.call - 改用 .invoke()

LLMs

  • BaseLLMParams.concurrency - 在 config 对象中使用 maxConcurrency
  • BaseLLM.call - 改用 .invoke()
  • BaseLLM.predict - 改用 .invoke()
  • BaseLLM.predictMessages - 改用 .invoke()
  • BaseLLM.serialize - 直接使用 JSON 序列化

流式处理

  • createChatMessageChunkEncoderStream - 直接使用 .stream() 方法

追踪

  • BaseTracer.runMap - 使用 LangSmith 追踪 API
  • getTracingCallbackHandler - 使用 LangSmith 追踪
  • getTracingV2CallbackHandler - 使用 LangSmith 追踪
  • LangChainTracerV1 - 使用 LangSmith 追踪

内存和存储

  • BaseListChatMessageHistory.addAIChatMessage - 使用 .addMessage() 并传入 AIMessage
  • BaseStoreInterface - 使用具体的存储实现

工具

  • getRuntimeEnvironmentSync - 使用异步的 getRuntimeEnvironment()