跳到内容

工具

工具是一种将函数及其输入模式封装起来的方式,以便可以将其传递给支持工具调用的聊天模型。这允许模型请求执行此函数并使用特定输入。

您可以定义自己的工具,也可以使用 LangChain 提供的预构建集成

定义工具

您可以使用 tool 函数创建工具

import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { initChatModel } from "langchain/chat_models/universal";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

const multiply = tool(
  async (input: { a: number; b: number }) => {
    return input.a * input.b;
  },
  {
    name: "multiply",
    schema: z.object({
      a: z.number().describe("First operand"),
      b: z.number().describe("Second operand"),
    }),
    description: "Multiply two numbers.",
  }
);

const llm = await initChatModel("anthropic:claude-3-7-sonnet-latest");
const agent = createReactAgent({
  llm,
  tools: [multiply],
});

如需更多自定义,请参阅自定义工具指南

向模型隐藏参数

某些工具需要仅在运行时可用的参数(例如,用户 ID 或会话上下文),这些参数不应由模型控制。

您可以将这些参数放在智能体的 stateconfig 中,并在工具内部访问这些信息

import { z } from "zod";
import { tool } from "@langchain/core/tools";
import {
  getCurrentTaskInput,
  LangGraphRunnableConfig,
} from "@langchain/langgraph";
import { MessagesAnnotation } from "@langchain/langgraph";

const myTool = tool(
  async (
    input: {
      // This will be populated by an LLM
      toolArg: string;
    },
    // access static data that is passed at agent invocation
    config: LangGraphRunnableConfig
  ) => {
    // Fetch the current agent state
    const state = getCurrentTaskInput() as typeof MessagesAnnotation.State;
    doSomethingWithState(state.messages);
    doSomethingWithConfig(config);
    // ...
  },
  {
    name: "myTool",
    schema: z.object({
      myToolArg: z.number().describe("Tool arg"),
    }),
    description: "My tool.",
  }
);

禁用并行工具调用

某些模型提供商支持并行执行多个工具,但允许用户禁用此功能。

对于受支持的提供商,您可以通过 model.bindTools() 方法将 parallel_tool_calls: false 设置为禁用并行工具调用

import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

const add = tool(
  async (input: { a: number; b: number }) => {
    return input.a + input.b;
  },
  {
    name: "add",
    schema: z.object({
      a: z.number().describe("First operand"),
      b: z.number().describe("Second operand"),
    }),
    description: "Add two numbers.",
  }
);

const multiply = tool(
  async (input: { a: number; b: number }) => {
    return input.a * input.b;
  },
  {
    name: "multiply",
    schema: z.object({
      a: z.number().describe("First operand"),
      b: z.number().describe("Second operand"),
    }),
    description: "Multiply two numbers.",
  }
);

const llm = new ChatOpenAI({ model: "gpt-4.1" });

const tools = [add, multiply];
const agent = createReactAgent({
  // disable parallel tool calls
  llm: llm.bindTools(tools, { parallel_tool_calls: false }),
  tools,
});

const response = await agent.invoke({
  messages: [{ role: "user", content: "what's 3 + 5 and 4 * 7?" }],
});

直接返回工具结果

使用 returnDirect: true 立即返回工具结果并停止智能体循环

import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { initChatModel } from "langchain/chat_models/universal";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

const add = tool(
  async (input: { a: number; b: number }) => {
    return input.a + input.b;
  },
  {
    name: "add",
    schema: z.object({
      a: z.number().describe("First operand"),
      b: z.number().describe("Second operand"),
    }),
    description: "Add two numbers.",
    returnDirect: true,
  }
);

const llm = await initChatModel("anthropic:claude-3-7-sonnet-latest");
const agent = createReactAgent({
  llm,
  tools: [add],
});

const response = await agent.invoke({
  messages: [{ role: "user", content: "what's 3 + 5?" }],
});

强制使用工具

要强制智能体使用特定工具,您可以在 model.bindTools() 中设置 tool_choice 选项

import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { initChatModel } from "langchain/chat_models/universal";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

const greet = tool(
  async (input: { userName: string }) => {
    return `Hello ${input.userName}!`;
  },
  {
    name: "greet",
    schema: z.object({
      userName: z.string().describe("Name of the user to greet"),
    }),
    description: "Greet user.",
    returnDirect: true,
  }
);

const llm = new ChatAnthropic({ model: "claude-3-7-sonnet-latest" });
const tools = [greet];

const agent = createReactAgent({
  llm: llm.bindTools(tools, { tool_choice: { type: "tool", name: "greet" } }),
  tools,
});

const response = await agent.invoke({
  messages: "Hi, I am Bob",
});

避免无限循环

在没有停止条件的情况下强制使用工具可能会创建无限循环。请使用以下任一安全措施:

处理工具错误

默认情况下,智能体将捕获工具调用期间引发的所有异常,并将其作为工具消息传递给 LLM。要控制错误处理方式,您可以使用预构建的 ToolNode — 在 createReactAgent 内部执行工具的节点 — 通过其 handleToolErrors 参数进行控制

import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { initChatModel } from "langchain/chat_models/universal";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

const multiply = tool(
  async (input: { a: number; b: number }) => {
    if (input.a === 42) {
      throw new Error("The ultimate error");
    }
    return input.a * input.b;
  },
  {
    name: "multiply",
    schema: z.object({
      a: z.number().describe("First operand"),
      b: z.number().describe("Second operand"),
    }),
    description: "Multiply two numbers.",
  }
);

// Run with error handling (default)
const llm = await initChatModel("anthropic:claude-3-7-sonnet-latest");
const agent = createReactAgent({
  llm,
  tools: [multiply],
});

const response = await agent.invoke(
  { messages: [ { role: "user", content: "what's 42 x 7?" } ] }
);
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { initChatModel } from "langchain/chat_models/universal";
import { tool } from "@langchain/core/tools";
import { z } from "zod";
import { ToolNode } from "@langchain/langgraph/prebuilt";

const multiply = tool(
  async (input: { a: number; b: number }) => {
    if (input.a === 42) {
      throw new Error("The ultimate error");
    }
    return input.a * input.b;
  },
  {
    name: "multiply",
    schema: z.object({
      a: z.number().describe("First operand"),
      b: z.number().describe("Second operand"),
    }),
    description: "Multiply two numbers.",
  }
);

const toolNode = new ToolNode({
  tools: [multiply],
  handleToolErrors: false, // (1)!
});

const llm = await initChatModel("anthropic:claude-3-7-sonnet-latest");
const agentNoErrorHandling = createReactAgent({
  llm,
  tools: toolNode,
});

const response = await agentNoErrorHandling.invoke(
  { messages: [ { role: "user", content: "what's 42 x 7?" } ] }
);
  1. 这将禁用错误处理(默认启用)。

预构建工具

您可以通过将包含工具规范的字典传递给 createReactAgenttools 参数来使用模型提供商的预构建工具。例如,要使用 OpenAI 的 web_search_preview 工具

import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { initChatModel } from "langchain/chat_models/universal";

const llm = await initChatModel("openai:gpt-4o-mini");

const agent = createReactAgent({
  llm,
  tools: [{ type: "web_search_preview" }],
});

const response = await agent.invoke({
  messages: ["What was a positive news story from today?"],
});

此外,LangChain 支持广泛的预构建工具集成,用于与 API、数据库、文件系统、Web 数据等进行交互。这些工具扩展了智能体的功能,并能实现快速开发。

您可以在LangChain 集成目录中浏览可用集成的完整列表。

一些常用的工具类别包括

  • 搜索:Exa、SerpAPI、Tavily
  • 代码解释器:Python REPL
  • 数据库:SQL、MongoDB、Redis
  • Web 数据:Web 抓取和浏览
  • API:Discord、Gmail 和其他

这些集成可以使用上面示例中所示的相同 tools 参数进行配置并添加到您的智能体中。