!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}return t}()||function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"light")}(),document.documentElement.setAttribute("data-announcement-bar-initially-dismissed",function(){try{return"true"===localStorage.getItem("docusaurus.announcement.dismiss")}catch(t){}return!1}())

[Skip to main content](#__docusaurus_skipToContent_fallback)

LangChain v0.2 is coming soon! Preview the new docs [here](/v0.2/docs/introduction/).

[

![🦜️🔗 Langchain](/v0.1/img/brand/wordmark.png)![🦜️🔗 Langchain](/v0.1/img/brand/wordmark-dark.png)

](/v0.1/)[Docs](/v0.1/docs/get_started/introduction/)[Use cases](/v0.1/docs/use_cases/)[Integrations](/v0.1/docs/integrations/platforms/)[API Reference](https://api.js.langchain.com)

[More](#)

*   [People](/v0.1/docs/people/)
*   [Community](/v0.1/docs/community/)
*   [Tutorials](/v0.1/docs/additional_resources/tutorials/)
*   [Contributing](/v0.1/docs/contributing/)

[v0.1](#)

*   [v0.2](https://js.langchain.com/v0.2/docs/introduction)
*   [v0.1](/v0.1/docs/get_started/introduction/)

[🦜🔗](#)

*   [LangSmith](https://smith.langchain.com)
*   [LangSmith Docs](https://docs.smith.langchain.com)
*   [LangChain Hub](https://smith.langchain.com/hub)
*   [LangServe](https://github.com/langchain-ai/langserve)
*   [Python Docs](https://python.langchain.com/)

[Chat](https://chatjs.langchain.com)[](https://github.com/langchain-ai/langchainjs)

Search

*   [Use cases](/v0.1/docs/use_cases/)
    
    *   [SQL](/v0.1/docs/use_cases/sql/)
        
    *   [Chatbots](/v0.1/docs/use_cases/chatbots/)
        
    *   [Extraction](/v0.1/docs/use_cases/extraction/)
        
    *   [Query Analysis](/v0.1/docs/use_cases/query_analysis/)
        
    *   [Q&A with RAG](/v0.1/docs/use_cases/question_answering/)
        
    *   [Tool use](/v0.1/docs/use_cases/tool_use/)
        
        *   [Quickstart](/v0.1/docs/use_cases/tool_use/quickstart/)
        *   [Agents](/v0.1/docs/use_cases/tool_use/agents/)
        *   [Choosing between multiple tools](/v0.1/docs/use_cases/tool_use/multiple_tools/)
        *   [Parallel tool use](/v0.1/docs/use_cases/tool_use/parallel/)
        *   [Tool error handling](/v0.1/docs/use_cases/tool_use/tool_error_handling/)
        *   [Human-in-the-loop](/v0.1/docs/use_cases/tool_use/human_in_the_loop/)
    *   [Interacting with APIs](/v0.1/docs/use_cases/api/)
    *   [Tabular Question Answering](/v0.1/docs/use_cases/tabular/)
    *   [Graphs](/v0.1/docs/use_cases/graph/)
        
    *   [Summarization](/v0.1/docs/use_cases/summarization/)
    *   [Agent Simulations](/v0.1/docs/use_cases/agent_simulations/)
        
    *   [Autonomous Agents](/v0.1/docs/use_cases/autonomous_agents/)
        
    *   [Code Understanding](/v0.1/docs/use_cases/code_understanding/)
    *   [Audio/Video Structured Extraction](/v0.1/docs/use_cases/media/)

*   [](/v0.1/)
*   [Use cases](/v0.1/docs/use_cases/)
*   [Tool use](/v0.1/docs/use_cases/tool_use/)
*   Choosing between multiple tools

On this page

Choosing between multiple tools
===============================

In the tools [Quickstart](/v0.1/docs/use_cases/tool_use/quickstart/) we went over how to build a Chain that calls a single `multiply` tool. Now let’s take a look at how we might augment this chain so that it can pick from a number of tools to call. We’ll focus on Chains since [Agents](/v0.1/docs/use_cases/tool_use/agents/) can route between multiple tools by default.

Setup[​](#setup "Direct link to Setup")
---------------------------------------

We’ll use OpenAI for this guide, and will need to install its partner package:

tip

See [this section for general instructions on installing integration packages](/v0.1/docs/get_started/installation/#installing-integration-packages).

*   npm
*   Yarn
*   pnpm

    npm install @langchain/openai

    yarn add @langchain/openai

    pnpm add @langchain/openai

You'll need to sign up for an OpenAI key and set it as an environment variable named `OPENAI_API_KEY`.

We'll also use the popular validation library [Zod](https://zod.dev) to define our tool schemas. It's already a dependency of `langchain`, but you can install it explicitly like this too:

*   npm
*   Yarn
*   pnpm

    npm install zod

    yarn add zod

    pnpm add zod

Tools[​](#tools "Direct link to Tools")
---------------------------------------

Recall the `multiply` tool from the quickstart:

    import { z } from "zod";import { DynamicStructuredTool } from "@langchain/core/tools";const addTool = new DynamicStructuredTool({  name: "add",  description: "Add two integers together.",  schema: z.object({    firstInt: z.number(),    secondInt: z.number(),  }),  func: async ({ firstInt, secondInt }) => {    return (firstInt + secondInt).toString();  },});

And now let's create `exponentiate` and `add` tools:

    const multiplyTool = new DynamicStructuredTool({  name: "multiply",  description: "Multiply two integers together.",  schema: z.object({    firstInt: z.number(),    secondInt: z.number(),  }),  func: async ({ firstInt, secondInt }) => {    return (firstInt * secondInt).toString();  },});const exponentiateTool = new DynamicStructuredTool({  name: "exponentiate",  description: "Exponentiate the base to the exponent power.",  schema: z.object({    base: z.number(),    exponent: z.number(),  }),  func: async ({ base, exponent }) => {    return (base ** exponent).toString();  },});

The main difference between using one Tool and many is that in the case of many we can’t be sure which Tool the model will invoke. So we cannot hardcode, like we did in the Quickstart, a specific tool into our chain. Instead we’ll create a function called `callSelectedTool` that takes the `JsonOutputToolsParser` output and returns the end of the chain based on the chosen tool.

This means that the `callSelectedTool` function appends the Tools that were invoked to the end of the chain at runtime. We can do this because LCEL allows runnables to return runnables themselves, which are then invoked as part of the chain.

    import { ChatOpenAI } from "@langchain/openai";import { convertToOpenAITool } from "@langchain/core/utils/function_calling";import { JsonOutputToolsParser } from "langchain/output_parsers";import {  RunnableLambda,  RunnablePassthrough,  RunnableSequence,} from "@langchain/core/runnables";const model = new ChatOpenAI({  model: "gpt-3.5-turbo-1106",});const tools = [multiplyTool, exponentiateTool, addTool];const toolMap: Record<string, any> = {  multiply: multiplyTool,  exponentiate: exponentiateTool,  add: addTool,};const modelWithTools = model.bind({  tools: tools.map(convertToOpenAITool),});// Function for dynamically constructing the end of the chain based on the model-selected tool.const callSelectedTool = RunnableLambda.from(  (toolInvocation: Record<string, any>) => {    const selectedTool = toolMap[toolInvocation.type];    if (!selectedTool) {      throw new Error(        `No matching tool available for requested type "${toolInvocation.type}".`      );    }    const toolCallChain = RunnableSequence.from([      (toolInvocation) => toolInvocation.args,      selectedTool,    ]);    // We use `RunnablePassthrough.assign` here to return the intermediate `toolInvocation` params    // as well, but you can omit if you only care about the answer.    return RunnablePassthrough.assign({      output: toolCallChain,    });  });const chain = RunnableSequence.from([  modelWithTools,  new JsonOutputToolsParser(),  // .map() allows us to apply a function for each item in a list of inputs.  // Required because the model can call multiple tools at once.  callSelectedTool.map(),]);

Note the use of `.map()` above - this is required because the model can choose to call multiple tools in parallel. See [this section](/v0.1/docs/use_cases/tool_use/parallel/) for more details.

info

You can see a LangSmith trace of this example [here](https://smith.langchain.com/public/b6a20569-d798-4e99-8a88-7ffaea58e25f/r)

    await chain.invoke("What's 23 times 7");

    [  {    type: 'multiply',    args: { firstInt: 23, secondInt: 7 },    output: '161'  }]

    await chain.invoke("add a million plus a billion");

    [  {    type: 'add',    args: { firstInt: 1000000, secondInt: 1000000000 },    output: '1001000000'  }]

    await chain.invoke("cube thirty-seven");

    [  {    type: 'exponentiate',    args: { base: 37, exponent: 3 },    output: '50653'  }]

* * *

#### Help us out by providing feedback on this documentation page:

[

Previous

Agents

](/v0.1/docs/use_cases/tool_use/agents/)[

Next

Parallel tool use

](/v0.1/docs/use_cases/tool_use/parallel/)

*   [Setup](#setup)
*   [Tools](#tools)

Community

*   [Discord](https://discord.gg/cU2adEyC7w)
*   [Twitter](https://twitter.com/LangChainAI)

GitHub

*   [Python](https://github.com/langchain-ai/langchain)
*   [JS/TS](https://github.com/langchain-ai/langchainjs)

More

*   [Homepage](https://langchain.com)
*   [Blog](https://blog.langchain.dev)

Copyright © 2024 LangChain, Inc.