!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

*   [Get started](/v0.1/docs/get_started/)
    
    *   [Introduction](/v0.1/docs/get_started/introduction/)
    *   [Installation](/v0.1/docs/get_started/installation/)
    *   [Quickstart](/v0.1/docs/get_started/quickstart/)
*   [LangChain Expression Language](/v0.1/docs/expression_language/)
    
    *   [Get started](/v0.1/docs/expression_language/get_started/)
    *   [Why use LCEL?](/v0.1/docs/expression_language/why/)
    *   [Interface](/v0.1/docs/expression_language/interface/)
    *   [Streaming](/v0.1/docs/expression_language/streaming/)
    *   [How to](/v0.1/docs/expression_language/how_to/routing/)
        
    *   [Cookbook](/v0.1/docs/expression_language/cookbook/)
        
    *   [LangChain Expression Language (LCEL)](/v0.1/docs/expression_language/)
*   [Modules](/v0.1/docs/modules/)
    
    *   [Model I/O](/v0.1/docs/modules/model_io/)
        
    *   [Retrieval](/v0.1/docs/modules/data_connection/)
        
    *   [Chains](/v0.1/docs/modules/chains/)
    *   [Agents](/v0.1/docs/modules/agents/)
        
        *   [Quick start](/v0.1/docs/modules/agents/quick_start/)
        *   [Concepts](/v0.1/docs/modules/agents/concepts/)
        *   [Agent Types](/v0.1/docs/modules/agents/agent_types/)
            
        *   [How-to](/v0.1/docs/modules/agents/how_to/custom_agent/)
            
        *   [Agents](/v0.1/docs/modules/agents/)
        *   [Tools](/v0.1/docs/modules/agents/tools/)
            
            *   [Toolkits](/v0.1/docs/modules/agents/tools/toolkits/)
            *   [Defining custom tools](/v0.1/docs/modules/agents/tools/dynamic/)
            *   [How-to](/v0.1/docs/modules/agents/tools/how_to/agents_with_vectorstores/)
                
    *   [More](/v0.1/docs/modules/memory/)
        
*   [Security](/v0.1/docs/security/)
*   [Guides](/v0.1/docs/guides/)
    
*   [Ecosystem](/v0.1/docs/ecosystem/)
    
*   [LangGraph](/v0.1/docs/langgraph/)
*   * * *
    

*   [](/v0.1/)
*   [Modules](/v0.1/docs/modules/)
*   [Agents](/v0.1/docs/modules/agents/)
*   [Tools](/v0.1/docs/modules/agents/tools/)
*   Defining custom tools

Defining custom tools
=====================

One option for creating a tool that runs custom code is to use a `DynamicTool`.

The `DynamicTool` and `DynamicStructuredTool` classes takes as input a name, a description, and a function. Importantly, the name and the description will be used by the language model to determine when to call this function and with what parameters, so make sure to set these to some values the language model can reason about!

The provided function is what will the agent will actually call. When an error occurs, the function should, when possible, return a string representing an error, rather than throwing an error. This allows the error to be passed to the LLM and the LLM can decide how to handle it. If an error is thrown, then execution of the agent will stop.

`DynamicStructuredTool`s allow you to specify more complex inputs as [Zod](https://zod.dev) schemas for the agent to populate. However, note that more complex schemas require better models and agents. See [this guide](/v0.1/docs/modules/agents/agent_types/) for a complete list of agent types.

See below for an example of defining and using `DynamicTool`s.

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

    import { ChatOpenAI } from "@langchain/openai";import type { ChatPromptTemplate } from "@langchain/core/prompts";import { createOpenAIFunctionsAgent, AgentExecutor } from "langchain/agents";import { pull } from "langchain/hub";import { z } from "zod";import { DynamicTool, DynamicStructuredTool } from "@langchain/core/tools";const llm = new ChatOpenAI({  model: "gpt-3.5-turbo",  temperature: 0,});const tools = [  new DynamicTool({    name: "FOO",    description:      "call this to get the value of foo. input should be an empty string.",    func: async () => "baz",  }),  new DynamicStructuredTool({    name: "random-number-generator",    description: "generates a random number between two input numbers",    schema: z.object({      low: z.number().describe("The lower bound of the generated number"),      high: z.number().describe("The upper bound of the generated number"),    }),    func: async ({ low, high }) =>      (Math.random() * (high - low) + low).toString(), // Outputs still must be strings  }),];// Get the prompt to use - you can modify this!\// If you want to see the prompt in full, you can at:// https://smith.langchain.com/hub/hwchase17/openai-functions-agentconst prompt = await pull<ChatPromptTemplate>(  "hwchase17/openai-functions-agent");const agent = await createOpenAIFunctionsAgent({  llm,  tools,  prompt,});const agentExecutor = new AgentExecutor({  agent,  tools,  verbose: true,});const result = await agentExecutor.invoke({  input: `What is the value of foo?`,});console.log(`Got output ${result.output}`);/*  [chain/start] [1:chain:AgentExecutor] Entering Chain run with input: {    "input": "What is the value of foo?"  }  [agent/action] [1:chain:AgentExecutor] Agent selected action: {    "tool": "FOO",    "toolInput": {},    "log": "Invoking \"FOO\" with {}\n",    "messageLog": [      {        "lc": 1,        "type": "constructor",        "id": [          "langchain_core",          "messages",          "AIMessage"        ],        "kwargs": {          "content": "",          "additional_kwargs": {            "function_call": {              "name": "FOO",              "arguments": "{}"            }          }        }      }    ]  }  [tool/start] [1:chain:AgentExecutor > 8:tool:FOO] Entering Tool run with input: "undefined"  [tool/end] [1:chain:AgentExecutor > 8:tool:FOO] [113ms] Exiting Tool run with output: "baz"  [chain/end] [1:chain:AgentExecutor] [3.36s] Exiting Chain run with output: {    "input": "What is the value of foo?",    "output": "The value of foo is \"baz\"."  }  Got output The value of foo is "baz".*/const result2 = await agentExecutor.invoke({  input: `Generate a random number between 1 and 10.`,});console.log(`Got output ${result2.output}`);/*  [chain/start] [1:chain:AgentExecutor] Entering Chain run with input: {    "input": "Generate a random number between 1 and 10."  }  [agent/action] [1:chain:AgentExecutor] Agent selected action: {    "tool": "random-number-generator",    "toolInput": {      "low": 1,      "high": 10    },    "log": "Invoking \"random-number-generator\" with {\n  \"low\": 1,\n  \"high\": 10\n}\n",    "messageLog": [      {        "lc": 1,        "type": "constructor",        "id": [          "langchain_core",          "messages",          "AIMessage"        ],        "kwargs": {          "content": "",          "additional_kwargs": {            "function_call": {              "name": "random-number-generator",              "arguments": "{\n  \"low\": 1,\n  \"high\": 10\n}"            }          }        }      }    ]  }  [tool/start] [1:chain:AgentExecutor > 8:tool:random-number-generator] Entering Tool run with input: "{"low":1,"high":10}"  [tool/end] [1:chain:AgentExecutor > 8:tool:random-number-generator] [58ms] Exiting Tool run with output: "2.4757639017769293"  [chain/end] [1:chain:AgentExecutor] [3.32s] Exiting Chain run with output: {    "input": "Generate a random number between 1 and 10.",    "output": "The random number generated between 1 and 10 is 2.476."  }  Got output The random number generated between 1 and 10 is 2.476.*/

#### API Reference:

*   [ChatOpenAI](https://api.js.langchain.com/classes/langchain_openai.ChatOpenAI.html) from `@langchain/openai`
*   [ChatPromptTemplate](https://api.js.langchain.com/classes/langchain_core_prompts.ChatPromptTemplate.html) from `@langchain/core/prompts`
*   [createOpenAIFunctionsAgent](https://api.js.langchain.com/functions/langchain_agents.createOpenAIFunctionsAgent.html) from `langchain/agents`
*   [AgentExecutor](https://api.js.langchain.com/classes/langchain_agents.AgentExecutor.html) from `langchain/agents`
*   [pull](https://api.js.langchain.com/functions/langchain_hub.pull.html) from `langchain/hub`
*   [DynamicTool](https://api.js.langchain.com/classes/langchain_core_tools.DynamicTool.html) from `@langchain/core/tools`
*   [DynamicStructuredTool](https://api.js.langchain.com/classes/langchain_core_tools.DynamicStructuredTool.html) from `@langchain/core/tools`

* * *

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

[

Previous

Toolkits

](/v0.1/docs/modules/agents/tools/toolkits/)[

Next

Vector stores as tools

](/v0.1/docs/modules/agents/tools/how_to/agents_with_vectorstores/)

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.