以编程方式使用文档

本迁移指南概述了 LangChain v1 中的主要变更。要了解 v1 的新功能,请参阅 介绍性文章.

要升级,

npm install langchain@latest @langchain/core@latest
pnpm install langchain@latest @langchain/core@latest
yarn add langchain@latest @langchain/core@latest
bun add langchain@latest @langchain/core@latest

createAgent

在 v1 中,react 预构建代理现在位于 langchain 包中。下表概述了哪些功能发生了变化:

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

导入路径

react 预构建代理的导入路径已从 @langchain/langgraph/prebuilts to langchain变更。函数名称已从 createReactAgent to createAgent:

提示词

静态提示词重命名

参数 prompt 已重命名为 systemPrompt:

agent = createAgent({
  model,
  tools,
  systemPrompt: "You are a helpful assistant.", // [!code highlight]
});
const agent = createReactAgent({
  model,
  tools,
  prompt: "You are a helpful assistant.", // [!code highlight]
});

SystemMessage

如果使用 SystemMessage 对象在系统提示词中,字符串内容现在直接使用:

const agent = createAgent({
  model,
  tools,
  systemPrompt: "You are a helpful assistant.", // [!code highlight]
});
const agent = createReactAgent({
  model,
  tools,
  prompt: new SystemMessage(content: "You are a helpful assistant."), // [!code highlight]
});

动态提示词

动态提示词是一种核心的上下文工程模式——它们根据当前对话状态调整告诉模型的内容。要实现这一点,请使用 dynamicSystemPromptMiddleware:

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

const userRolePrompt = dynamicSystemPromptMiddleware<z.infer<typeof contextSchema>>( // [!code highlight]
    (_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; // [!code highlight]
    }
);

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

await agent.invoke(
  {
    messages: [new HumanMessage("Explain async programming")],
  },
  {
    context: {
      userRole: "expert",
    },
  }
);
const contextSchema = z.object({
  userRole: z.enum(["expert", "beginner"]),
});

const agent = createReactAgent({
  model,
  tools,
  prompt: (state) => {
    const userRole = state.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;
  },
  contextSchema,
});

// Use with context via config.configurable
await agent.invoke(
  {
    messages: [new HumanMessage("Explain async programming")],
  },
  {
    config: {
      configurable: { userRole: "expert" },
    },
  }
);

模型前置钩子

模型前置钩子现在作为中间件实现,使用 beforeModel 方法。这种模式更具可扩展性——你可以定义多个中间件在模型调用前运行,并可以在不同的代理之间复用。

常见用例包括: - 摘要对话历史 - 修剪消息 - 输入护栏,如 PII 删除

v1 包含内置的摘要中间件:

const agent = createAgent({
  model: "claude-sonnet-4-6",
  tools,
  middleware: [
    summarizationMiddleware({
      model: "claude-sonnet-4-6",
      trigger: { tokens: 1000 },
    }),
  ],
});
function customSummarization(state) {
  // Custom logic for message summarization
}

const agent = createReactAgent({
  model: "claude-sonnet-4-6",
  tools,
  preModelHook: customSummarization,
});

模型后置钩子

后模型钩子现已实现为中间件, afterModel 方法。这允许您在模型响应后组合多个处理器。

常见用例包括: - 人工介入审批 - 输出护栏

v1 包含一个内置的人工介入中间件:

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

const agent = createReactAgent({
  model: "claude-sonnet-4-6",
  tools: [readEmail, sendEmail],
  postModelHook: customHumanInTheLoopHook,
});

自定义状态

自定义状态现在在中间件中使用 stateSchema 属性定义。使用 Zod 声明在代理运行期间传递的附加状态字段。

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

const userState = createMiddleware({
  name: "UserState",
  stateSchema: UserState,
  beforeModel: (state) => {
    // Access custom state properties
    const name = state.userName;
    // Optionally modify messages/system prompt based on state
    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",
});
const UserState = z.object({
  userName: z.string(),
});

const greet = tool(
  async () => {
    const state = await getCurrentTaskInput();
    const userName = state.userName;
    return `Hello ${userName}!`;
  },
);

// Custom state was provided via agent-level state schema or accessed ad hoc in hooks
const agent = createReactAgent({
  model: "claude-sonnet-4-6",
  tools: [greet],
  stateSchema: UserState,
});

模型

动态模型选择现在通过中间件进行。使用 wrapModelCall 根据状态或运行时上下文交换模型(和工具)。在 createReactAgent中,这是通过传递给 model parameter.

此功能已在 v1 中移植到中间件接口。

动态模型选择

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

const agent = createAgent({
  model: "gpt-5-nano",
  tools,
  middleware: [dynamicModel],
});
function selectModel(state) {
  return state.messages.length > 10 ? "openai:gpt-5.5" : "openai:gpt-5-nano";
}

const agent = createReactAgent({
  model: selectModel,
  tools,
});

预绑定模型

为了更好地支持结构化输出, createAgent 应接收一个普通模型(字符串或实例)和一个单独的 tools 列表。使用结构化输出时,避免传递预绑定工具的模型。

// No longer supported
// const modelWithTools = new ChatOpenAI({ model: "gpt-5.4-mini" }).bindTools([someTool]);
// const agent = createAgent({ model: modelWithTools, tools: [] });

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

工具

tools 参数到 createAgent accepts:

  • - 使用创建的工具 tool
  • - LangChain 工具实例
  • - 表示内置提供商工具的对象

处理工具错误

您现在可以使用实现中间件来配置工具错误处理 wrapToolCall method.

const handleToolErrors = createMiddleware({
  name: "HandleToolErrors",
  wrapToolCall: async (request, handler) => {
    try {
      return await handler(request);
    } catch (error) {
      // Only handle errors that occur during tool execution due to invalid inputs
      // that pass schema validation but fail at runtime (e.g., invalid SQL syntax).
      // Do NOT handle:
      // - Network failures (use tool retry middleware instead)
      // - Incorrect tool implementation errors (should bubble up)
      // - Schema mismatch errors (already auto-handled by the framework)
      //
      // Return a custom error message to the model
      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],
});
const agent = createReactAgent({
  model: "claude-sonnet-4-6",
  tools: new ToolNode(
    [checkWeather, searchWeb],
    { handleToolErrors: true } // [!code highlight]
  ),
});

结构化输出

节点变更

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

工具和提供商策略

在 v1 中,有两种策略:

  • - toolStrategy 使用人工工具调用来生成结构化输出
  • - providerStrategy 使用提供商原生的结构化输出生成
const OutputSchema = z.object({
  summary: z.string(),
  sentiment: z.string(),
});

const agent = createAgent({
  model: "gpt-5.4-mini",
  tools,
  // explicitly using tool strategy
  responseFormat: toolStrategy(OutputSchema), // [!code highlight]
});
const OutputSchema = z.object({
  summary: z.string(),
  sentiment: z.string(),
});

const agent = createReactAgent({
  model: "gpt-5.4-mini",
  tools,
  // Structured output was driven primarily via tool-calling with fewer options
  responseFormat: OutputSchema,
});

已移除提示输出

通过中的自定义指令进行的提示输出 responseFormat 已被上述策略取代。

流式节点名称重命名

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

运行时上下文

调用代理时,通过 context 参数传递静态只读配置。这取代了使用 config.configurable.

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

const result = await agent.invoke(
  { messages: [new HumanMessage("Hello")] },
  { context: { userId: "123", sessionId: "abc" } }, // [!code highlight]
);
const agent = createReactAgent({ model, tools });

// Pass context via config.configurable
const result = await agent.invoke(
  { messages: [new HumanMessage("Hello")] },
  {
    config: { // [!code highlight]
      configurable: { userId: "123", sessionId: "abc" }, // [!code highlight]
    }, // [!code highlight]
  }
);

标准内容

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

发生了什么变化

  • - 新增 contentBlocks 消息上用于规范化内容的属性。
  • - 下方的全新 TypeScript 类型 ContentBlock 用于强类型支持。
  • - 可选地将标准块序列化为 content 通过 LC_OUTPUT_VERSION=v1 or outputVersion: "v1".

读取标准化内容

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);
  }
}
// Provider-native formats vary; you needed per-provider handling.
const response = await model.invoke("Explain AI");
for (const item of response.content as any[]) {
  if (item.type === "reasoning") {
    // OpenAI-style reasoning
  } else if (item.type === "thinking") {
    // Anthropic-style thinking
  } else if (item.type === "text") {
    // Text
  }
}

创建多模态消息

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]);
const message = new HumanMessage({
  // Provider-native structure
  content: [
    { type: "text", text: "Describe this image." },
    { type: "image_url", image_url: { url: "https://example.com/image.jpg" } },
  ],
});
const res = await model.invoke([message]);

示例块类型

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.

const model = await initChatModel("gpt-5-nano", {
  outputVersion: "v1",
});

简化的包

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

导出

v1 包包含:

模块可用内容备注
Agents(代理)createAgent, AgentState核心代理创建功能
Messages(消息)消息类型、内容块、 trimMessages从重新导出 @langchain/core
Tools(工具)tool、工具类从重新导出 @langchain/core
Chat models(聊天模型)initChatModel, BaseChatModel统一模型初始化

@langchain/classic

如果您使用旧版链、索引 API 或之前从 @langchain/community重新导出的功能,请安装 @langchain/classic 并更新导入:

npm install @langchain/classic
pnpm install @langchain/classic
yarn add @langchain/classic
bun add @langchain/classic
// v1 (new)



// v0 (old)

破坏性变更

取消支持 Node 18

所有 LangChain 包现在需要 **Node.js 22 或更高版本**。Node.js 18 已于 停止维护 2025 年 3 月。

新的构建输出

所有 langchain 包的构建现在采用基于打包器的方法,而不是使用原始 TypeScript 输出。如果您之前从 dist/ 目录(不推荐这样做),你需要更新导入语句以使用新的模块系统。

旧代码已移至 @langchain/classic

标准接口和代理范围之外的旧功能已移至 @langchain/classic 包。请参阅 简化包 部分,了解核心 langchain 包中的可用内容以及移至 @langchain/classic.

已弃用API的移除

已在1.0版本中弃用并计划删除的方法、函数和其他对象已被删除。

View removed deprecated APIs

以下已弃用的API已在v1中移除:

#### 核心功能 - TraceGroup - 请改用LangSmith追踪 - BaseDocumentLoader.loadAndSplit - 请使用 .load() 后接文本分割器 - RemoteRunnable - 不再支持

#### 提示词 - BasePromptTemplate.serialize.deserialize - 请直接使用JSON序列化 - ChatPromptTemplate.fromPromptMessages - 请使用 ChatPromptTemplate.fromMessages

#### 检索器 - BaseRetrieverInterface.getRelevantDocuments - 请使用 .invoke() 替代

#### 可运行对象 - Runnable.bind - 请使用 .bindTools() 或其他特定绑定方法 - Runnable.map - 请使用 .batch() 替代 - RunnableBatchOptions.maxConcurrency - 请使用 maxConcurrency 在配置对象中

#### 聊天模型 - BaseChatModel.predictMessages - 请使用 .invoke() 替代 - BaseChatModel.predict - 请使用 .invoke() 替代 - BaseChatModel.serialize - 请直接使用JSON序列化 - BaseChatModel.callPrompt - 请使用 .invoke() 替代 - BaseChatModel.call - 请使用 .invoke() 替代

#### 大语言模型 - BaseLLMParams.concurrency - 请使用 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()