!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)

You are viewing the **preview** v0.2 docs. View the **stable** v0.1 docs [here](/v0.1/docs/get_started/introduction/). Leave feedback on the v0.2 docs [here](https://github.com/langchain-ai/langchainjs/discussions/5386).

[

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

](/v0.2/)[Integrations](/v0.2/docs/integrations/platforms/)[API Reference](https://v02.api.js.langchain.com)

[More](#)

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

[v0.2](#)

*   [v0.2](/v0.2/docs/introduction)
*   [v0.1](https://js.langchain.com/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

*   [Introduction](/v0.2/docs/introduction)
*   [Tutorials](/v0.2/docs/tutorials/)
    
    *   [Build a Question Answering application over a Graph Database](/v0.2/docs/tutorials/graph)
    *   [Tutorials](/v0.2/docs/tutorials/)
    *   [Build a Simple LLM Application](/v0.2/docs/tutorials/llm_chain)
    *   [Build a Query Analysis System](/v0.2/docs/tutorials/query_analysis)
    *   [Build a Chatbot](/v0.2/docs/tutorials/chatbot)
    *   [Build an Agent](/v0.2/docs/tutorials/agents)
    *   [Build an Extraction Chain](/v0.2/docs/tutorials/extraction)
    *   [Summarize Text](/v0.2/docs/tutorials/summarization)
    *   [Tagging](/v0.2/docs/tutorials/classification)
    *   [Build a Local RAG Application](/v0.2/docs/tutorials/local_rag)
    *   [Conversational RAG](/v0.2/docs/tutorials/qa_chat_history)
    *   [Build a Retrieval Augmented Generation (RAG) App](/v0.2/docs/tutorials/rag)
    *   [Build a Question/Answering system over SQL data](/v0.2/docs/tutorials/sql_qa)
*   [How-to guides](/v0.2/docs/how_to/)
    
    *   [How-to guides](/v0.2/docs/how_to/)
    *   [How to use example selectors](/v0.2/docs/how_to/example_selectors)
    *   [Installation](/v0.2/docs/how_to/installation)
    *   [How to stream responses from an LLM](/v0.2/docs/how_to/streaming_llm)
    *   [How to stream chat model responses](/v0.2/docs/how_to/chat_streaming)
    *   [How to embed text data](/v0.2/docs/how_to/embed_text)
    *   [How to use few shot examples in chat models](/v0.2/docs/how_to/few_shot_examples_chat)
    *   [How to cache model responses](/v0.2/docs/how_to/llm_caching)
    *   [How to cache chat model responses](/v0.2/docs/how_to/chat_model_caching)
    *   [How to create a custom LLM class](/v0.2/docs/how_to/custom_llm)
    *   [How to use few shot examples](/v0.2/docs/how_to/few_shot_examples)
    *   [How to use output parsers to parse an LLM response into structured format](/v0.2/docs/how_to/output_parser_structured)
    *   [How to return structured data from a model](/v0.2/docs/how_to/structured_output)
    *   [How to add ad-hoc tool calling capability to LLMs and Chat Models](/v0.2/docs/how_to/tools_prompting)
    *   [How to create a custom chat model class](/v0.2/docs/how_to/custom_chat)
    *   [How to do per-user retrieval](/v0.2/docs/how_to/qa_per_user)
    *   [How to track token usage](/v0.2/docs/how_to/chat_token_usage_tracking)
    *   [How to track token usage](/v0.2/docs/how_to/llm_token_usage_tracking)
    *   [How to pass through arguments from one step to the next](/v0.2/docs/how_to/passthrough)
    *   [How to compose prompts together](/v0.2/docs/how_to/prompts_composition)
    *   [How to use legacy LangChain Agents (AgentExecutor)](/v0.2/docs/how_to/agent_executor)
    *   [How to add values to a chain's state](/v0.2/docs/how_to/assign)
    *   [How to attach runtime arguments to a Runnable](/v0.2/docs/how_to/binding)
    *   [How to cache embedding results](/v0.2/docs/how_to/caching_embeddings)
    *   [How to split by character](/v0.2/docs/how_to/character_text_splitter)
    *   [How to manage memory](/v0.2/docs/how_to/chatbots_memory)
    *   [How to do retrieval](/v0.2/docs/how_to/chatbots_retrieval)
    *   [How to use tools](/v0.2/docs/how_to/chatbots_tools)
    *   [How to split code](/v0.2/docs/how_to/code_splitter)
    *   [How to do retrieval with contextual compression](/v0.2/docs/how_to/contextual_compression)
    *   [How to write a custom retriever class](/v0.2/docs/how_to/custom_retriever)
    *   [How to create custom Tools](/v0.2/docs/how_to/custom_tools)
    *   [How to debug your LLM apps](/v0.2/docs/how_to/debugging)
    *   [How to load CSV data](/v0.2/docs/how_to/document_loader_csv)
    *   [How to write a custom document loader](/v0.2/docs/how_to/document_loader_custom)
    *   [How to load data from a directory](/v0.2/docs/how_to/document_loader_directory)
    *   [How to load PDF files](/v0.2/docs/how_to/document_loader_pdf)
    *   [How to load JSON data](/v0.2/docs/how_to/document_loaders_json)
    *   [How to select examples by length](/v0.2/docs/how_to/example_selectors_length_based)
    *   [How to select examples by similarity](/v0.2/docs/how_to/example_selectors_similarity)
    *   [How to use reference examples](/v0.2/docs/how_to/extraction_examples)
    *   [How to handle long text](/v0.2/docs/how_to/extraction_long_text)
    *   [How to do extraction without using function calling](/v0.2/docs/how_to/extraction_parse)
    *   [Fallbacks](/v0.2/docs/how_to/fallbacks)
    *   [Few Shot Prompt Templates](/v0.2/docs/how_to/few_shot)
    *   [How to run custom functions](/v0.2/docs/how_to/functions)
    *   [How to construct knowledge graphs](/v0.2/docs/how_to/graph_constructing)
    *   [How to map values to a database](/v0.2/docs/how_to/graph_mapping)
    *   [How to improve results with prompting](/v0.2/docs/how_to/graph_prompting)
    *   [How to add a semantic layer over the database](/v0.2/docs/how_to/graph_semantic)
    *   [How to reindex data to keep your vectorstore in-sync with the underlying data source](/v0.2/docs/how_to/indexing)
    *   [How to get log probabilities](/v0.2/docs/how_to/logprobs)
    *   [How to add message history](/v0.2/docs/how_to/message_history)
    *   [How to generate multiple embeddings per document](/v0.2/docs/how_to/multi_vector)
    *   [How to generate multiple queries to retrieve data for](/v0.2/docs/how_to/multiple_queries)
    *   [How to parse JSON output](/v0.2/docs/how_to/output_parser_json)
    *   [How to retry when output parsing errors occur](/v0.2/docs/how_to/output_parser_retry)
    *   [How to parse XML output](/v0.2/docs/how_to/output_parser_xml)
    *   [How to invoke runnables in parallel](/v0.2/docs/how_to/parallel)
    *   [How to retrieve the whole document for a chunk](/v0.2/docs/how_to/parent_document_retriever)
    *   [How to partially format prompt templates](/v0.2/docs/how_to/prompts_partial)
    *   [How to add chat history to a question-answering chain](/v0.2/docs/how_to/qa_chat_history_how_to)
    *   [How to return citations](/v0.2/docs/how_to/qa_citations)
    *   [How to return sources](/v0.2/docs/how_to/qa_sources)
    *   [How to stream from a question-answering chain](/v0.2/docs/how_to/qa_streaming)
    *   [How to construct filters](/v0.2/docs/how_to/query_constructing_filters)
    *   [How to add examples to the prompt](/v0.2/docs/how_to/query_few_shot)
    *   [How to deal with high cardinality categorical variables](/v0.2/docs/how_to/query_high_cardinality)
    *   [How to handle multiple queries](/v0.2/docs/how_to/query_multiple_queries)
    *   [How to handle multiple retrievers](/v0.2/docs/how_to/query_multiple_retrievers)
    *   [How to handle cases where no queries are generated](/v0.2/docs/how_to/query_no_queries)
    *   [How to recursively split text by characters](/v0.2/docs/how_to/recursive_text_splitter)
    *   [How to reduce retrieval latency](/v0.2/docs/how_to/reduce_retrieval_latency)
    *   [How to route execution within a chain](/v0.2/docs/how_to/routing)
    *   [How to chain runnables](/v0.2/docs/how_to/sequence)
    *   [How to split text by tokens](/v0.2/docs/how_to/split_by_token)
    *   [How to deal with large databases](/v0.2/docs/how_to/sql_large_db)
    *   [How to use prompting to improve results](/v0.2/docs/how_to/sql_prompting)
    *   [How to do query validation](/v0.2/docs/how_to/sql_query_checking)
    *   [How to stream](/v0.2/docs/how_to/streaming)
    *   [How to create a time-weighted retriever](/v0.2/docs/how_to/time_weighted_vectorstore)
    *   [How to use a chat model to call tools](/v0.2/docs/how_to/tool_calling)
    *   [How to call tools with multi-modal data](/v0.2/docs/how_to/tool_calls_multi_modal)
    *   [How to use LangChain tools](/v0.2/docs/how_to/tools_builtin)
    *   [How use a vector store to retrieve data](/v0.2/docs/how_to/vectorstore_retriever)
    *   [How to create and query vector stores](/v0.2/docs/how_to/vectorstores)
*   [Conceptual guide](/v0.2/docs/concepts)
*   Ecosystem
    
    *   [🦜🛠️ LangSmith](/v0.2/docs/langsmith/)
        
    *   [🦜🕸️LangGraph.js](/v0.2/docs/langgraph)
*   Versions
    
    *   [Overview](/v0.2/docs/versions/overview)
    *   [v0.2](/v0.2/docs/versions/v0_2)
    *   [Release Policy](/v0.2/docs/versions/release_policy)
    *   [Packages](/v0.2/docs/versions/packages)
*   [Security](/v0.2/docs/security)

*   [](/v0.2/)
*   [How-to guides](/v0.2/docs/how_to/)
*   How to use legacy LangChain Agents (AgentExecutor)

On this page

How to use legacy LangChain Agents (AgentExecutor)
==================================================

Prerequisites

This guide assumes familiarity with the following concepts:

*   [Tools](/v0.2/docs/concepts#tools)

By themselves, language models can’t take actions - they just output text. Agents are systems that use an LLM as a reasoning engineer to determine which actions to take and what the inputs to those actions should be. The results of those actions can then be fed back into the agent and it determine whether more actions are needed, or whether it is okay to finish.

In this tutorial we will build an agent that can interact with multiple different tools: one being a local database, the other being a search engine. You will be able to ask this agent questions, watch it call tools, and have conversations with it.

info

This section will cover building with LangChain Agents. LangChain Agents are fine for getting started, but past a certain point you will likely want flexibility and control that they do not offer. For working with more advanced agents, we’d recommend checking out [LangGraph](/v0.2/docs/concepts/#langgraph).

Concepts[​](#concepts "Direct link to Concepts")
------------------------------------------------

Concepts we will cover are: - Using [language models](/v0.2/docs/concepts/#chat-models), in particular their tool calling ability - Creating a [Retriever](/v0.2/docs/concepts/#retrievers) to expose specific information to our agent - Using a Search [Tool](/v0.2/docs/concepts/#tools) to look up things online - [`Chat History`](/v0.2/docs/concepts/#chat-history), which allows a chatbot to “remember” past interactions and take them into account when responding to followup questions. - Debugging and tracing your application using [LangSmith](/v0.2/docs/concepts/#langsmith)

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

### Jupyter Notebook[​](#jupyter-notebook "Direct link to Jupyter Notebook")

This guide (and most of the other guides in the documentation) uses [Jupyter notebooks](https://jupyter.org/) and assumes the reader is as well. Jupyter notebooks are perfect for learning how to work with LLM systems because oftentimes things can go wrong (unexpected output, API down, etc) and going through guides in an interactive environment is a great way to better understand them.

This and other tutorials are perhaps most conveniently run in a Jupyter notebook. See [here](https://jupyter.org/install) for instructions on how to install.

### Installation[​](#installation "Direct link to Installation")

To install LangChain (and `cheerio` for the web loader) run:

*   npm
*   yarn
*   pnpm

    npm i langchain cheerio

    yarn add langchain cheerio

    pnpm add langchain cheerio

For more details, see our [Installation guide](/v0.2/docs/how_to/installation/).

### LangSmith[​](#langsmith "Direct link to LangSmith")

Many of the applications you build with LangChain will contain multiple steps with multiple invocations of LLM calls. As these applications get more and more complex, it becomes crucial to be able to inspect what exactly is going on inside your chain or agent. The best way to do this is with [LangSmith](https://smith.langchain.com).

After you sign up at the link above, make sure to set your environment variables to start logging traces:

    export LANGCHAIN_TRACING_V2="true"export LANGCHAIN_API_KEY="..."

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

We first need to create the tools we want to use. We will use two tools: [Tavily](/v0.2/docs/integrations/tools/tavily_search) (to search online) and then a retriever over a local index we will create

### [Tavily](/v0.2/docs/integrations/tools/tavily_search)[​](#tavily "Direct link to tavily")

We have a built-in tool in LangChain to easily use Tavily search engine as tool. Note that this requires an API key - they have a free tier, but if you don’t have one or don’t want to create one, you can always ignore this step.

Once you create your API key, you will need to export that as:

    export TAVILY_API_KEY="..."

    import { TavilySearchResults } from "@langchain/community/tools/tavily_search";const search = new TavilySearchResults({  maxResults: 2,});await search.invoke("what is the weather in SF");

    `[{"title":"Weather in San Francisco","url":"https://www.weatherapi.com/","content":"{'location': {'n`... 1111 more characters

### Retriever[​](#retriever "Direct link to Retriever")

We will also create a retriever over some data of our own. For a deeper explanation of each step here, see [this tutorial](/v0.2/docs/tutorials/rag).

    import "cheerio"; // This is required in notebooks to use the `CheerioWebBaseLoader`import { CheerioWebBaseLoader } from "langchain/document_loaders/web/cheerio";import { MemoryVectorStore } from "langchain/vectorstores/memory";import { OpenAIEmbeddings } from "@langchain/openai";import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";const loader = new CheerioWebBaseLoader(  "https://docs.smith.langchain.com/overview");const docs = await loader.load();const documents = await new RecursiveCharacterTextSplitter({  chunkSize: 1000,  chunkOverlap: 200,}).splitDocuments(docs);const vectorStore = await MemoryVectorStore.fromDocuments(  documents,  new OpenAIEmbeddings());const retriever = vectorStore.asRetriever();(await retriever.invoke("how to upload a dataset"))[0];

    Document {  pageContent: 'description="A sample dataset in LangSmith.")client.create_examples(    inputs=[        {"postfix": '... 891 more characters,  metadata: {    source: "https://docs.smith.langchain.com/overview",    loc: { lines: { from: 4, to: 4 } }  }}

Now that we have populated our index that we will do doing retrieval over, we can easily turn it into a tool (the format needed for an agent to properly use it)

    import { createRetrieverTool } from "langchain/tools/retriever";const retrieverTool = await createRetrieverTool(retriever, {  name: "langsmith_search",  description:    "Search for information about LangSmith. For any questions about LangSmith, you must use this tool!",});

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

Now that we have created both, we can create a list of tools that we will use downstream.

    const tools = [search, retrieverTool];

Using Language Models[​](#using-language-models "Direct link to Using Language Models")
---------------------------------------------------------------------------------------

Next, let’s learn how to use a language model by to call tools. LangChain supports many different language models that you can use interchangably - select the one you want to use below!

### Pick your chat model:

*   OpenAI
*   Anthropic
*   FireworksAI
*   MistralAI
*   Groq
*   VertexAI

#### Install dependencies

tip

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

*   npm
*   yarn
*   pnpm

    npm i @langchain/openai 

    yarn add @langchain/openai 

    pnpm add @langchain/openai 

#### Add environment variables

    OPENAI_API_KEY=your-api-key

#### Instantiate the model

    import { ChatOpenAI } from "@langchain/openai";const model = new ChatOpenAI(model: "gpt-4");

#### Install dependencies

tip

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

*   npm
*   yarn
*   pnpm

    npm i @langchain/anthropic 

    yarn add @langchain/anthropic 

    pnpm add @langchain/anthropic 

#### Add environment variables

    ANTHROPIC_API_KEY=your-api-key

#### Instantiate the model

    import { ChatAnthropic } from "@langchain/anthropic";const model = new ChatAnthropic({  model: "claude-3-sonnet-20240229",  temperature: 0});

#### Install dependencies

tip

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

*   npm
*   yarn
*   pnpm

    npm i @langchain/community 

    yarn add @langchain/community 

    pnpm add @langchain/community 

#### Add environment variables

    FIREWORKS_API_KEY=your-api-key

#### Instantiate the model

    import { ChatFireworks } from "@langchain/community/chat_models/fireworks";const model = new ChatFireworks({  model: "accounts/fireworks/models/firefunction-v1",  temperature: 0});

#### Install dependencies

tip

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

*   npm
*   yarn
*   pnpm

    npm i @langchain/mistralai 

    yarn add @langchain/mistralai 

    pnpm add @langchain/mistralai 

#### Add environment variables

    MISTRAL_API_KEY=your-api-key

#### Instantiate the model

    import { ChatMistralAI } from "@langchain/mistralai";const model = new ChatMistralAI({  model: "mistral-large-latest",  temperature: 0});

#### Install dependencies

tip

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

*   npm
*   yarn
*   pnpm

    npm i @langchain/groq 

    yarn add @langchain/groq 

    pnpm add @langchain/groq 

#### Add environment variables

    GROQ_API_KEY=your-api-key

#### Instantiate the model

    import { ChatGroq } from "@langchain/groq";const model = new ChatGroq({  model: "mixtral-8x7b-32768",  temperature: 0});

#### Install dependencies

tip

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

*   npm
*   yarn
*   pnpm

    npm i @langchain/google-vertexai 

    yarn add @langchain/google-vertexai 

    pnpm add @langchain/google-vertexai 

#### Add environment variables

    GOOGLE_APPLICATION_CREDENTIALS=credentials.json

#### Instantiate the model

    import { ChatVertexAI } from "@langchain/google-vertexai";const model = new ChatVertexAI({  model: "gemini-1.5-pro",  temperature: 0});

You can call the language model by passing in a list of messages. By default, the response is a `content` string.

    import { HumanMessage } from "@langchain/core/messages";const response = await model.invoke([new HumanMessage("hi!")]);response.content;

    "Hello! How can I assist you today?"

We can now see what it is like to enable this model to do tool calling. In order to enable that we use `.bind` to give the language model knowledge of these tools

    const modelWithTools = model.bindTools(tools);

We can now call the model. Let’s first call it with a normal message, and see how it responds. We can look at both the `content` field as well as the `tool_calls` field.

    const response = await modelWithTools.invoke([new HumanMessage("Hi!")]);console.log(`Content: ${response.content}`);console.log(`Tool calls: ${response.tool_calls}`);

    Content: Hello! How can I assist you today?Tool calls:

Now, let’s try calling it with some input that would expect a tool to be called.

    const response = await modelWithTools.invoke([  new HumanMessage("What's the weather in SF?"),]);console.log(`Content: ${response.content}`);console.log(`Tool calls: ${JSON.stringify(response.tool_calls, null, 2)}`);

    Content:Tool calls: [  {    "name": "tavily_search_results_json",    "args": {      "input": "weather in San Francisco"    },    "id": "call_y0nn6mbVCV5paX6RrqqFUqdC"  }]

We can see that there’s now no content, but there is a tool call! It wants us to call the Tavily Search tool.

This isn’t calling that tool yet - it’s just telling us to. In order to actually calll it, we’ll want to create our agent.

Create the agent[​](#create-the-agent "Direct link to Create the agent")
------------------------------------------------------------------------

Now that we have defined the tools and the LLM, we can create the agent. We will be using a tool calling agent - for more information on this type of agent, as well as other options, see [this guide](/v0.2/docs/concepts/#agent_types/).

We can first choose the prompt we want to use to guide the agent.

If you want to see the contents of this prompt in the hub, you can go to:

[https://smith.langchain.com/hub/hwchase17/openai-functions-agent](https://smith.langchain.com/hub/hwchase17/openai-functions-agent)

    import { ChatPromptTemplate } from "@langchain/core/prompts";import { pull } from "langchain/hub";// Get the prompt to use - you can modify this!const prompt = await pull<ChatPromptTemplate>(  "hwchase17/openai-functions-agent");console.log(prompt.promptMessages);

    [  SystemMessagePromptTemplate {    lc_serializable: true,    lc_kwargs: {      prompt: PromptTemplate {        lc_serializable: true,        lc_kwargs: {          template: "You are a helpful assistant",          inputVariables: [],          templateFormat: "f-string",          partialVariables: {}        },        lc_runnable: true,        name: undefined,        lc_namespace: [ "langchain_core", "prompts", "prompt" ],        inputVariables: [],        outputParser: undefined,        partialVariables: {},        template: "You are a helpful assistant",        templateFormat: "f-string",        validateTemplate: true      }    },    lc_runnable: true,    name: undefined,    lc_namespace: [ "langchain_core", "prompts", "chat" ],    inputVariables: [],    additionalOptions: {},    prompt: PromptTemplate {      lc_serializable: true,      lc_kwargs: {        template: "You are a helpful assistant",        inputVariables: [],        templateFormat: "f-string",        partialVariables: {}      },      lc_runnable: true,      name: undefined,      lc_namespace: [ "langchain_core", "prompts", "prompt" ],      inputVariables: [],      outputParser: undefined,      partialVariables: {},      template: "You are a helpful assistant",      templateFormat: "f-string",      validateTemplate: true    },    messageClass: undefined,    chatMessageClass: undefined  },  MessagesPlaceholder {    lc_serializable: true,    lc_kwargs: { optional: true, variableName: "chat_history" },    lc_runnable: true,    name: undefined,    lc_namespace: [ "langchain_core", "prompts", "chat" ],    variableName: "chat_history",    optional: true  },  HumanMessagePromptTemplate {    lc_serializable: true,    lc_kwargs: {      prompt: PromptTemplate {        lc_serializable: true,        lc_kwargs: {          template: "{input}",          inputVariables: [Array],          templateFormat: "f-string",          partialVariables: {}        },        lc_runnable: true,        name: undefined,        lc_namespace: [ "langchain_core", "prompts", "prompt" ],        inputVariables: [ "input" ],        outputParser: undefined,        partialVariables: {},        template: "{input}",        templateFormat: "f-string",        validateTemplate: true      }    },    lc_runnable: true,    name: undefined,    lc_namespace: [ "langchain_core", "prompts", "chat" ],    inputVariables: [ "input" ],    additionalOptions: {},    prompt: PromptTemplate {      lc_serializable: true,      lc_kwargs: {        template: "{input}",        inputVariables: [ "input" ],        templateFormat: "f-string",        partialVariables: {}      },      lc_runnable: true,      name: undefined,      lc_namespace: [ "langchain_core", "prompts", "prompt" ],      inputVariables: [ "input" ],      outputParser: undefined,      partialVariables: {},      template: "{input}",      templateFormat: "f-string",      validateTemplate: true    },    messageClass: undefined,    chatMessageClass: undefined  },  MessagesPlaceholder {    lc_serializable: true,    lc_kwargs: { optional: false, variableName: "agent_scratchpad" },    lc_runnable: true,    name: undefined,    lc_namespace: [ "langchain_core", "prompts", "chat" ],    variableName: "agent_scratchpad",    optional: false  }]

Now, we can initalize the agent with the LLM, the prompt, and the tools. The agent is responsible for taking in input and deciding what actions to take. Crucially, the Agent does not execute those actions - that is done by the AgentExecutor (next step). For more information about how to think about these components, see our [conceptual guide](/v0.2/docs/concepts/#agents).

Note that we are passing in the `model`, not `modelWithTools`. That is because `createToolCallingAgent` will call `.bind` for us under the hood.

    import { createToolCallingAgent } from "langchain/agents";const agent = await createToolCallingAgent({ llm: model, tools, prompt });

Finally, we combine the agent (the brains) with the tools inside the AgentExecutor (which will repeatedly call the agent and execute tools).

    import { AgentExecutor } from "langchain/agents";const agentExecutor = new AgentExecutor({  agent,  tools,});

Run the agent[​](#run-the-agent "Direct link to Run the agent")
---------------------------------------------------------------

We can now run the agent on a few queries! Note that for now, these are all **stateless** queries (it won’t remember previous interactions).

First up, let’s how it responds when there’s no need to call a tool:

    await agentExecutor.invoke({ input: "hi!" });

    { input: "hi!", output: "Hello! How can I assist you today?" }

In order to see exactly what is happening under the hood (and to make sure it’s not calling a tool) we can take a look at the [LangSmith trace](https://smith.langchain.com/public/b8051e80-14fd-4931-be0f-6416280bc500/r)

Let’s now try it out on an example where it should be invoking the retriever

    await agentExecutor.invoke({ input: "how can langsmith help with testing?" });

    {  input: "how can langsmith help with testing?",  output: "LangSmith can help with testing by providing a platform for building production-grade LLM applicatio"... 880 more characters}

Let’s take a look at the [LangSmith trace](https://smith.langchain.com/public/35bd4f0f-aa2f-4ac2-b9a9-89ce0ca306ca/r) to make sure it’s actually calling that.

Now let’s try one where it needs to call the search tool:

    await agentExecutor.invoke({ input: "whats the weather in sf?" });

    {  input: "whats the weather in sf?",  output: "The current weather in San Francisco is partly cloudy with a temperature of 64.0°F (17.8°C). The win"... 112 more characters}

We can check out the [LangSmith trace](https://smith.langchain.com/public/dfde6f46-0e7b-4dfe-813c-87d7bfb2ade5/r) to make sure it’s calling the search tool effectively.

Adding in memory[​](#adding-in-memory "Direct link to Adding in memory")
------------------------------------------------------------------------

As mentioned earlier, this agent is stateless. This means it does not remember previous interactions. To give it memory we need to pass in previous `chat_history`.

**Note**: The input variable needs to be called `chat_history` because of the prompt we are using. If we use a different prompt, we could change the variable name.

    // Here we pass in an empty list of messages for chat_history because it is the first message in the chatawait agentExecutor.invoke({ input: "hi! my name is bob", chat_history: [] });

    {  input: "hi! my name is bob",  chat_history: [],  output: "Hello Bob! How can I assist you today?"}

    import { AIMessage, HumanMessage } from "@langchain/core/messages";await agentExecutor.invoke({  chat_history: [    new HumanMessage("hi! my name is bob"),    new AIMessage("Hello Bob! How can I assist you today?"),  ],  input: "what's my name?",});

    {  chat_history: [    HumanMessage {      lc_serializable: true,      lc_kwargs: {        content: "hi! my name is bob",        additional_kwargs: {},        response_metadata: {}      },      lc_namespace: [ "langchain_core", "messages" ],      content: "hi! my name is bob",      name: undefined,      additional_kwargs: {},      response_metadata: {}    },    AIMessage {      lc_serializable: true,      lc_kwargs: {        content: "Hello Bob! How can I assist you today?",        tool_calls: [],        invalid_tool_calls: [],        additional_kwargs: {},        response_metadata: {}      },      lc_namespace: [ "langchain_core", "messages" ],      content: "Hello Bob! How can I assist you today?",      name: undefined,      additional_kwargs: {},      response_metadata: {},      tool_calls: [],      invalid_tool_calls: []    }  ],  input: "what's my name?",  output: "Your name is Bob! How can I help you, Bob?"}

If we want to keep track of these messages automatically, we can wrap this in a RunnableWithMessageHistory.

Because we have multiple inputs, we need to specify two things:

*   `input_messages_key`: The input key to use to add to the conversation history.
*   `history_messages_key`: The key to add the loaded messages into.

For more information on how to use this, see [this guide](/v0.2/docs/how_to/message_history).

    import { ChatMessageHistory } from "@langchain/community/stores/message/in_memory";import { BaseChatMessageHistory } from "@langchain/core/chat_history";import { RunnableWithMessageHistory } from "@langchain/core/runnables";const store = {};function getMessageHistory(sessionId: string): BaseChatMessageHistory {  if (!(sessionId in store)) {    store[sessionId] = new ChatMessageHistory();  }  return store[sessionId];}const agentWithChatHistory = new RunnableWithMessageHistory({  runnable: agentExecutor,  getMessageHistory,  inputMessagesKey: "input",  historyMessagesKey: "chat_history",});await agentWithChatHistory.invoke(  { input: "hi! I'm bob" },  { configurable: { sessionId: "<foo>" } });

    {  input: "hi! I'm bob",  chat_history: [    HumanMessage {      lc_serializable: true,      lc_kwargs: {        content: "hi! I'm bob",        additional_kwargs: {},        response_metadata: {}      },      lc_namespace: [ "langchain_core", "messages" ],      content: "hi! I'm bob",      name: undefined,      additional_kwargs: {},      response_metadata: {}    },    AIMessage {      lc_serializable: true,      lc_kwargs: {        content: "Hello Bob! How can I assist you today?",        tool_calls: [],        invalid_tool_calls: [],        additional_kwargs: {},        response_metadata: {}      },      lc_namespace: [ "langchain_core", "messages" ],      content: "Hello Bob! How can I assist you today?",      name: undefined,      additional_kwargs: {},      response_metadata: {},      tool_calls: [],      invalid_tool_calls: []    }  ],  output: "Hello Bob! How can I assist you today?"}

    await agentWithChatHistory.invoke(  { input: "what's my name?" },  { configurable: { sessionId: "<foo>" } });

    {  input: "what's my name?",  chat_history: [    HumanMessage {      lc_serializable: true,      lc_kwargs: {        content: "hi! I'm bob",        additional_kwargs: {},        response_metadata: {}      },      lc_namespace: [ "langchain_core", "messages" ],      content: "hi! I'm bob",      name: undefined,      additional_kwargs: {},      response_metadata: {}    },    AIMessage {      lc_serializable: true,      lc_kwargs: {        content: "Hello Bob! How can I assist you today?",        tool_calls: [],        invalid_tool_calls: [],        additional_kwargs: {},        response_metadata: {}      },      lc_namespace: [ "langchain_core", "messages" ],      content: "Hello Bob! How can I assist you today?",      name: undefined,      additional_kwargs: {},      response_metadata: {},      tool_calls: [],      invalid_tool_calls: []    },    HumanMessage {      lc_serializable: true,      lc_kwargs: {        content: "what's my name?",        additional_kwargs: {},        response_metadata: {}      },      lc_namespace: [ "langchain_core", "messages" ],      content: "what's my name?",      name: undefined,      additional_kwargs: {},      response_metadata: {}    },    AIMessage {      lc_serializable: true,      lc_kwargs: {        content: "Your name is Bob! How can I help you, Bob?",        tool_calls: [],        invalid_tool_calls: [],        additional_kwargs: {},        response_metadata: {}      },      lc_namespace: [ "langchain_core", "messages" ],      content: "Your name is Bob! How can I help you, Bob?",      name: undefined,      additional_kwargs: {},      response_metadata: {},      tool_calls: [],      invalid_tool_calls: []    }  ],  output: "Your name is Bob! How can I help you, Bob?"}

Example LangSmith trace: [https://smith.langchain.com/public/98c8d162-60ae-4493-aa9f-992d87bd0429/r](https://smith.langchain.com/public/98c8d162-60ae-4493-aa9f-992d87bd0429/r)

Conclusion[​](#conclusion "Direct link to Conclusion")
------------------------------------------------------

That’s a wrap! In this quick start we covered how to create a simple agent. Agents are a complex topic, and there’s lot to learn!

info

This section covered building with LangChain Agents. LangChain Agents are fine for getting started, but past a certain point you will likely want flexibility and control that they do not offer. For working with more advanced agents, we’d recommend checking out [LangGraph](/v0.2/docs/concepts/#langgraph)

* * *

#### Was this page helpful?

  

#### You can leave detailed feedback [on GitHub](https://github.com/langchain-ai/langchainjs/issues/new?assignees=&labels=03+-+Documentation&projects=&template=documentation.yml&title=DOC%3A+%3CPlease+write+a+comprehensive+title+after+the+%27DOC%3A+%27+prefix%3E).

[

Previous

How to compose prompts together

](/v0.2/docs/how_to/prompts_composition)[

Next

How to add values to a chain's state

](/v0.2/docs/how_to/assign)

*   [Concepts](#concepts)
*   [Setup](#setup)
    *   [Jupyter Notebook](#jupyter-notebook)
    *   [Installation](#installation)
    *   [LangSmith](#langsmith)
*   [Define tools](#define-tools)
    *   [Tavily](#tavily)
    *   [Retriever](#retriever)
    *   [Tools](#tools)
*   [Using Language Models](#using-language-models)
*   [Create the agent](#create-the-agent)
*   [Run the agent](#run-the-agent)
*   [Adding in memory](#adding-in-memory)
*   [Conclusion](#conclusion)

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.