to expand usability. The blog also discusses various opportunities to further improve the LangChain platform.response = await agent_chain.arun(input="What's the latest xkcd comic about?")print(response)            > Entering new AgentExecutor chain...    Thought: I can navigate to the xkcd website and extract the latest comic title and alt text to answer the question.    Action:    ```    {      "action": "navigate_browser",      "action_input": {        "url": "https://xkcd.com/"      }    }    ```        Observation: Navigating to https://xkcd.com/ returned status code 200    Thought:I can extract the latest comic title and alt text using CSS selectors.    Action:    ```    {      "action": "get_elements",      "action_input": {        "selector": "#ctitle, #comic img",        "attributes": ["alt", "src"]      }    }    ```         Observation: [{"alt": "Tapetum Lucidum", "src": "//imgs.xkcd.com/comics/tapetum_lucidum.png"}]    Thought:    > Finished chain.    The latest xkcd comic is titled "Tapetum Lucidum" and the image can be found at https://xkcd.com/2565/.Adding in memoryâ€‹Here is how you add in memory to this agentfrom langchain.prompts import MessagesPlaceholderfrom langchain.memory import


you add in memory to this agentfrom langchain.prompts import MessagesPlaceholderfrom langchain.memory import ConversationBufferMemorychat_history = MessagesPlaceholder(variable_name="chat_history")memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)agent_chain = initialize_agent(    tools,     llm,     agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,     verbose=True,     memory=memory,     agent_kwargs = {        "memory_prompts": [chat_history],        "input_variables": ["input", "agent_scratchpad", "chat_history"]    })response = await agent_chain.arun(input="Hi I'm Erica.")print(response)            > Entering new AgentExecutor chain...    Action:    ```    {      "action": "Final Answer",      "action_input": "Hi Erica! How can I assist you today?"    }    ```            > Finished chain.    Hi Erica! How can I assist you today?response = await agent_chain.arun(input="whats my name?")print(response)            > Entering new AgentExecutor chain...    Your name is Erica.        > Finished chain.    Your name is Erica.PreviousSelf ask with searchNextAdd Memory to OpenAI Functions AgentCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Page Not Found | ğŸ¦œï¸�ğŸ”— Langchain

Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKPage Not FoundWe could not find what you were looking for.Please contact the owner of the site that linked you to the original URL and let them know their link is broken.CommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


ReAct document store | ğŸ¦œï¸�ğŸ”— Langchain


Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKGet startedIntroductionInstallationQuickstartModulesModel I/â€‹OData connectionChainsMemoryAgentsAgent typesConversationalOpenAI functionsOpenAI Multi Functions AgentPlan and executeReActReAct document storeSelf ask with searchStructured tool chatHow-toToolsToolkitsCallbacksModulesGuidesEcosystemAdditional resourcesModulesAgentsAgent typesReAct document storeReAct document storeThis walkthrough showcases using an agent to implement the ReAct logic for working with document store specifically.from langchain import OpenAI, Wikipediafrom langchain.agents import initialize_agent, Toolfrom langchain.agents import AgentTypefrom langchain.agents.react.base import DocstoreExplorerdocstore = DocstoreExplorer(Wikipedia())tools = [    Tool(        name="Search",        func=docstore.search,        description="useful for when you need to ask with search",    ),    Tool(        name="Lookup",        func=docstore.lookup,        description="useful for when you need to ask with lookup",    ),]llm = OpenAI(temperature=0, model_name="text-davinci-002")react = initialize_agent(tools, llm, agent=AgentType.REACT_DOCSTORE, verbose=True)question = "Author David Chanoff has collaborated with a U.S. Navy admiral who served as the ambassador to the United Kingdom under which President?"react.run(question)            > Entering new AgentExecutor chain...        Thought: I need to search David Chanoff and find the


Thought: I need to search David Chanoff and find the U.S. Navy admiral he collaborated with. Then I need to find which President the admiral served under.        Action: Search[David Chanoff]        Observation: David Chanoff is a noted author of non-fiction work. His work has typically involved collaborations with the principal protagonist of the work concerned. His collaborators have included; Augustus A. White, Joycelyn Elders, Ä�oÃ n VÄƒn Toáº¡i, William J. Crowe, Ariel Sharon, Kenneth Good and Felix Zandman. He has also written about a wide range of subjects including literary history, education and foreign for The Washington Post, The New Republic and The New York Times Magazine. He has published more than twelve books.    Thought: The U.S. Navy admiral David Chanoff collaborated with is William J. Crowe. I need to find which President he served under.        Action: Search[William J. Crowe]        Observation: William James Crowe Jr. (January 2, 1925 â€“ October 18, 2007) was a United States Navy admiral and diplomat who served as the 11th chairman of the Joint Chiefs of Staff under Presidents Ronald Reagan and George H. W. Bush, and as the ambassador to the United Kingdom and Chair of the Intelligence Oversight Board under President Bill Clinton.    Thought: William J. Crowe served as the ambassador to the United Kingdom under President Bill Clinton, so the answer is Bill Clinton.        Action: Finish[Bill Clinton]        > Finished chain.    'Bill Clinton'PreviousReActNextSelf ask with


> Finished chain.    'Bill Clinton'PreviousReActNextSelf ask with searchCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


ReAct | ğŸ¦œï¸�ğŸ”— Langchain


Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKGet startedIntroductionInstallationQuickstartModulesModel I/â€‹OData connectionChainsMemoryAgentsAgent typesConversationalOpenAI functionsOpenAI Multi Functions AgentPlan and executeReActReAct document storeSelf ask with searchStructured tool chatHow-toToolsToolkitsCallbacksModulesGuidesEcosystemAdditional resourcesModulesAgentsAgent typesReActOn this pageReActThis walkthrough showcases using an agent to implement the ReAct logic.from langchain.agents import load_toolsfrom langchain.agents import initialize_agentfrom langchain.agents import AgentTypefrom langchain.llms import OpenAIFirst, let's load the language model we're going to use to control the agent.llm = OpenAI(temperature=0)Next, let's load some tools to use. Note that the llm-math tool uses an LLM, so we need to pass that in.tools = load_tools(["serpapi", "llm-math"], llm=llm)Finally, let's initialize an agent with the tools, the language model, and the type of agent we want to use.agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)Now let's test it out!agent.run("Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?")    > Entering new AgentExecutor chain...     I need to find out who Leo DiCaprio's girlfriend is and then calculate her age raised to the 0.43 power.    Action: Search    Action Input: "Leo DiCaprio girlfriend"    Observation: Camila Morrone    Thought: I need to find out Camila Morrone's


Camila Morrone    Thought: I need to find out Camila Morrone's age    Action: Search    Action Input: "Camila Morrone age"    Observation: 25 years    Thought: I need to calculate 25 raised to the 0.43 power    Action: Calculator    Action Input: 25^0.43    Observation: Answer: 3.991298452658078        Thought: I now know the final answer    Final Answer: Camila Morrone is Leo DiCaprio's girlfriend and her current age raised to the 0.43 power is 3.991298452658078.        > Finished chain.    "Camila Morrone is Leo DiCaprio's girlfriend and her current age raised to the 0.43 power is 3.991298452658078."Using chat modelsâ€‹You can also create ReAct agents that use chat models instead of LLMs as the agent driver.from langchain.chat_models import ChatOpenAIchat_model = ChatOpenAI(temperature=0)agent = initialize_agent(tools, chat_model, agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION, verbose=True)agent.run("Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?")PreviousPlan and executeNextReAct document storeUsing chat modelsCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


OpenAI Multi Functions Agent | ğŸ¦œï¸�ğŸ”— Langchain


Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKGet startedIntroductionInstallationQuickstartModulesModel I/â€‹OData connectionChainsMemoryAgentsAgent typesConversationalOpenAI functionsOpenAI Multi Functions AgentPlan and executeReActReAct document storeSelf ask with searchStructured tool chatHow-toToolsToolkitsCallbacksModulesGuidesEcosystemAdditional resourcesModulesAgentsAgent typesOpenAI Multi Functions AgentOn this pageOpenAI Multi Functions AgentThis notebook showcases using an agent that uses the OpenAI functions ability to respond to the prompts of the user using a Large Language ModelInstall openai,google-search-results packages which are required as the langchain packages call them internallypip install openai google-search-resultsfrom langchain import SerpAPIWrapperfrom langchain.agents import initialize_agent, Toolfrom langchain.agents import AgentTypefrom langchain.chat_models import ChatOpenAIThe agent is given ability to perform search functionalities with the respective toolSerpAPIWrapper:This initializes the SerpAPIWrapper for search functionality (search).import getpassimport osos.environ["SERPAPI_API_KEY"] = getpass.getpass()    Â·Â·Â·Â·Â·Â·Â·Â·# Initialize the OpenAI language model# Replace <your_api_key> in openai_api_key="<your_api_key>" with your actual OpenAI key.llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-0613")# Initialize the SerpAPIWrapper for search functionality# Replace <your_api_key> in openai_api_key="<your_api_key>" with your actual SerpAPI key.search = SerpAPIWrapper()# Define a list of tools offered by the agenttools = [    Tool(        name="Search",


= [    Tool(        name="Search",        func=search.run,        description="Useful when you need to answer questions about current events. You should ask targeted questions.",    ),]mrkl = initialize_agent(    tools, llm, agent=AgentType.OPENAI_MULTI_FUNCTIONS, verbose=True)# Do this so we can see exactly what's going on under the hoodimport langchainlangchain.debug = Truemrkl.run("What is the weather in LA and SF?")    [chain/start] [1:chain:AgentExecutor] Entering Chain run with input:    {      "input": "What is the weather in LA and SF?"    }    [llm/start] [1:chain:AgentExecutor > 2:llm:ChatOpenAI] Entering LLM run with input:    {      "prompts": [        "System: You are a helpful AI assistant.\nHuman: What is the weather in LA and SF?"      ]    }    [llm/end] [1:chain:AgentExecutor > 2:llm:ChatOpenAI] [2.91s] Exiting LLM run with output:    {      "generations": [        [          {            "text": "",            "generation_info": null,            "message": {              "content": "",


"content": "",              "additional_kwargs": {                "function_call": {                  "name": "tool_selection",                  "arguments": "{\n  \"actions\": [\n    {\n      \"action_name\": \"Search\",\n      \"action\": {\n        \"tool_input\": \"weather in Los Angeles\"\n      }\n    },\n    {\n      \"action_name\": \"Search\",\n      \"action\": {\n        \"tool_input\": \"weather in San Francisco\"\n      }\n    }\n  ]\n}"                }              },              "example": false            }          }        ]      ],      "llm_output": {        "token_usage": {          "prompt_tokens": 81,          "completion_tokens": 75,          "total_tokens": 156        },        "model_name":


},        "model_name": "gpt-3.5-turbo-0613"      },      "run": null    }    [tool/start] [1:chain:AgentExecutor > 3:tool:Search] Entering Tool run with input:    "{'tool_input': 'weather in Los Angeles'}"    [tool/end] [1:chain:AgentExecutor > 3:tool:Search] [608.693ms] Exiting Tool run with output:    "Mostly cloudy early, then sunshine for the afternoon. High 76F. Winds SW at 5 to 10 mph. Humidity59%."    [tool/start] [1:chain:AgentExecutor > 4:tool:Search] Entering Tool run with input:    "{'tool_input': 'weather in San Francisco'}"    [tool/end] [1:chain:AgentExecutor > 4:tool:Search] [517.475ms] Exiting Tool run with output:    "Partly cloudy this evening, then becoming cloudy after midnight. Low 53F. Winds WSW at 10 to 20 mph. Humidity83%."    [llm/start] [1:chain:AgentExecutor > 5:llm:ChatOpenAI] Entering LLM run with input:    {      "prompts": [        "System: You are a helpful AI assistant.\nHuman: What is the weather in LA and SF?\nAI: {'name': 'tool_selection', 'arguments': '{\\n  \"actions\": [\\n    {\\n      \"action_name\": \"Search\",\\n


{\\n      \"action_name\": \"Search\",\\n      \"action\": {\\n        \"tool_input\": \"weather in Los Angeles\"\\n      }\\n    },\\n    {\\n      \"action_name\": \"Search\",\\n      \"action\": {\\n        \"tool_input\": \"weather in San Francisco\"\\n      }\\n    }\\n  ]\\n}'}\nFunction: Mostly cloudy early, then sunshine for the afternoon. High 76F. Winds SW at 5 to 10 mph. Humidity59%.\nAI: {'name': 'tool_selection', 'arguments': '{\\n  \"actions\": [\\n    {\\n      \"action_name\": \"Search\",\\n      \"action\": {\\n        \"tool_input\": \"weather in Los Angeles\"\\n      }\\n    },\\n    {\\n      \"action_name\": \"Search\",\\n      \"action\": {\\n        \"tool_input\": \"weather in San Francisco\"\\n      }\\n    }\\n  ]\\n}'}\nFunction: Partly cloudy this evening, then becoming cloudy after midnight. Low 53F. Winds WSW at 10 to 20 mph. Humidity83%."      ]    }    [llm/end] [1:chain:AgentExecutor > 5:llm:ChatOpenAI]


[1:chain:AgentExecutor > 5:llm:ChatOpenAI] [2.33s] Exiting LLM run with output:    {      "generations": [        [          {            "text": "The weather in Los Angeles is mostly cloudy with a high of 76Â°F and a humidity of 59%. The weather in San Francisco is partly cloudy in the evening, becoming cloudy after midnight, with a low of 53Â°F and a humidity of 83%.",            "generation_info": null,            "message": {              "content": "The weather in Los Angeles is mostly cloudy with a high of 76Â°F and a humidity of 59%. The weather in San Francisco is partly cloudy in the evening, becoming cloudy after midnight, with a low of 53Â°F and a humidity of 83%.",              "additional_kwargs": {},              "example": false            }          }        ]      ],      "llm_output": {        "token_usage": {          "prompt_tokens": 307,          "completion_tokens": 54,          "total_tokens": 361        },        "model_name":


},        "model_name": "gpt-3.5-turbo-0613"      },      "run": null    }    [chain/end] [1:chain:AgentExecutor] [6.37s] Exiting Chain run with output:    {      "output": "The weather in Los Angeles is mostly cloudy with a high of 76Â°F and a humidity of 59%. The weather in San Francisco is partly cloudy in the evening, becoming cloudy after midnight, with a low of 53Â°F and a humidity of 83%."    }    'The weather in Los Angeles is mostly cloudy with a high of 76Â°F and a humidity of 59%. The weather in San Francisco is partly cloudy in the evening, becoming cloudy after midnight, with a low of 53Â°F and a humidity of 83%.'Configuring max iteration behaviorâ€‹To make sure that our agent doesn't get stuck in excessively long loops, we can set max_iterations. We can also set an early stopping method, which will determine our agent's behavior once the number of max iterations is hit. By default, the early stopping uses method force which just returns that constant string. Alternatively, you could specify method generate which then does one FINAL pass through the LLM to generate an output.mrkl = initialize_agent(    tools,    llm,    agent=AgentType.OPENAI_FUNCTIONS,    verbose=True,    max_iterations=2,    early_stopping_method="generate",)mrkl.run("What is the weather in NYC today, yesterday, and the day before?")    [chain/start] [1:chain:AgentExecutor] Entering Chain run with input:


[chain/start] [1:chain:AgentExecutor] Entering Chain run with input:    {      "input": "What is the weather in NYC today, yesterday, and the day before?"    }    [llm/start] [1:chain:AgentExecutor > 2:llm:ChatOpenAI] Entering LLM run with input:    {      "prompts": [        "System: You are a helpful AI assistant.\nHuman: What is the weather in NYC today, yesterday, and the day before?"      ]    }    [llm/end] [1:chain:AgentExecutor > 2:llm:ChatOpenAI] [1.27s] Exiting LLM run with output:    {      "generations": [        [          {            "text": "",            "generation_info": null,            "message": {              "lc": 1,              "type": "constructor",              "id": [                "langchain",                "schema",                "messages",                "AIMessage"


"AIMessage"              ],              "kwargs": {                "content": "",                "additional_kwargs": {                  "function_call": {                    "name": "Search",                    "arguments": "{\n  \"query\": \"weather in NYC today\"\n}"                  }                }              }            }          }        ]      ],      "llm_output": {        "token_usage": {          "prompt_tokens": 79,          "completion_tokens": 17,          "total_tokens": 96        },        "model_name": "gpt-3.5-turbo-0613"      },      "run": null    }    [tool/start] [1:chain:AgentExecutor > 3:tool:Search] Entering Tool run with


[1:chain:AgentExecutor > 3:tool:Search] Entering Tool run with input:    "{'query': 'weather in NYC today'}"    [tool/end] [1:chain:AgentExecutor > 3:tool:Search] [3.84s] Exiting Tool run with output:    "10:00 am Â· Feels Like85Â° Â· WindSE 4 mph Â· Humidity78% Â· UV Index3 of 11 Â· Cloud Cover81% Â· Rain Amount0 in ..."    [llm/start] [1:chain:AgentExecutor > 4:llm:ChatOpenAI] Entering LLM run with input:    {      "prompts": [        "System: You are a helpful AI assistant.\nHuman: What is the weather in NYC today, yesterday, and the day before?\nAI: {'name': 'Search', 'arguments': '{\\n  \"query\": \"weather in NYC today\"\\n}'}\nFunction: 10:00 am Â· Feels Like85Â° Â· WindSE 4 mph Â· Humidity78% Â· UV Index3 of 11 Â· Cloud Cover81% Â· Rain Amount0 in ..."      ]    }    [llm/end] [1:chain:AgentExecutor > 4:llm:ChatOpenAI] [1.24s] Exiting LLM run with output:    {      "generations": [        [          {            "text": "",            "generation_info": null,


"generation_info": null,            "message": {              "lc": 1,              "type": "constructor",              "id": [                "langchain",                "schema",                "messages",                "AIMessage"              ],              "kwargs": {                "content": "",                "additional_kwargs": {                  "function_call": {                    "name": "Search",                    "arguments": "{\n  \"query\": \"weather in NYC yesterday\"\n}"                  }                }              }            }          }        ]      ],


}        ]      ],      "llm_output": {        "token_usage": {          "prompt_tokens": 142,          "completion_tokens": 17,          "total_tokens": 159        },        "model_name": "gpt-3.5-turbo-0613"      },      "run": null    }    [tool/start] [1:chain:AgentExecutor > 5:tool:Search] Entering Tool run with input:    "{'query': 'weather in NYC yesterday'}"    [tool/end] [1:chain:AgentExecutor > 5:tool:Search] [1.15s] Exiting Tool run with output:    "New York Temperature Yesterday. Maximum temperature yesterday: 81 Â°F (at 1:51 pm) Minimum temperature yesterday: 72 Â°F (at 7:17 pm) Average temperature ..."    [llm/start] [1:llm:ChatOpenAI] Entering LLM run with input:    {      "prompts": [        "System: You are a helpful AI assistant.\nHuman: What is the weather in NYC today, yesterday, and the day before?\nAI: {'name': 'Search', 'arguments': '{\\n  \"query\": \"weather in NYC today\"\\n}'}\nFunction: 10:00 am Â· Feels Like85Â° Â· WindSE 4 mph Â· Humidity78% Â· UV Index3


Â· WindSE 4 mph Â· Humidity78% Â· UV Index3 of 11 Â· Cloud Cover81% Â· Rain Amount0 in ...\nAI: {'name': 'Search', 'arguments': '{\\n  \"query\": \"weather in NYC yesterday\"\\n}'}\nFunction: New York Temperature Yesterday. Maximum temperature yesterday: 81 Â°F (at 1:51 pm) Minimum temperature yesterday: 72 Â°F (at 7:17 pm) Average temperature ..."      ]    }    [llm/end] [1:llm:ChatOpenAI] [2.68s] Exiting LLM run with output:    {      "generations": [        [          {            "text": "Today in NYC, the weather is currently 85Â°F with a southeast wind of 4 mph. The humidity is at 78% and there is 81% cloud cover. There is no rain expected today.\n\nYesterday in NYC, the maximum temperature was 81Â°F at 1:51 pm, and the minimum temperature was 72Â°F at 7:17 pm.\n\nFor the day before yesterday, I do not have the specific weather information.",            "generation_info": null,            "message": {              "lc": 1,              "type": "constructor",              "id": [                "langchain",


"langchain",                "schema",                "messages",                "AIMessage"              ],              "kwargs": {                "content": "Today in NYC, the weather is currently 85Â°F with a southeast wind of 4 mph. The humidity is at 78% and there is 81% cloud cover. There is no rain expected today.\n\nYesterday in NYC, the maximum temperature was 81Â°F at 1:51 pm, and the minimum temperature was 72Â°F at 7:17 pm.\n\nFor the day before yesterday, I do not have the specific weather information.",                "additional_kwargs": {}              }            }          }        ]      ],      "llm_output": {        "token_usage": {          "prompt_tokens": 160,          "completion_tokens": 91,          "total_tokens": 251        },        "model_name": "gpt-3.5-turbo-0613"


"gpt-3.5-turbo-0613"      },      "run": null    }    [chain/end] [1:chain:AgentExecutor] [10.18s] Exiting Chain run with output:    {      "output": "Today in NYC, the weather is currently 85Â°F with a southeast wind of 4 mph. The humidity is at 78% and there is 81% cloud cover. There is no rain expected today.\n\nYesterday in NYC, the maximum temperature was 81Â°F at 1:51 pm, and the minimum temperature was 72Â°F at 7:17 pm.\n\nFor the day before yesterday, I do not have the specific weather information."    }    'Today in NYC, the weather is currently 85Â°F with a southeast wind of 4 mph. The humidity is at 78% and there is 81% cloud cover. There is no rain expected today.\n\nYesterday in NYC, the maximum temperature was 81Â°F at 1:51 pm, and the minimum temperature was 72Â°F at 7:17 pm.\n\nFor the day before yesterday, I do not have the specific weather information.'Notice that we never get around to looking up the weather the day before yesterday, due to hitting our max_iterations limit.PreviousOpenAI functionsNextPlan and executeConfiguring max iteration behaviorCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Page Not Found | ğŸ¦œï¸�ğŸ”— Langchain

Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKPage Not FoundWe could not find what you were looking for.Please contact the owner of the site that linked you to the original URL and let them know their link is broken.CommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Conversational | ğŸ¦œï¸�ğŸ”— Langchain


Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKGet startedIntroductionInstallationQuickstartModulesModel I/â€‹OData connectionChainsMemoryAgentsAgent typesConversationalOpenAI functionsOpenAI Multi Functions AgentPlan and executeReActReAct document storeSelf ask with searchStructured tool chatHow-toToolsToolkitsCallbacksModulesGuidesEcosystemAdditional resourcesModulesAgentsAgent typesConversationalOn this pageConversationalThis walkthrough demonstrates how to use an agent optimized for conversation. Other agents are often optimized for using tools to figure out the best response, which is not ideal in a conversational setting where you may want the agent to be able to chat with the user as well.This is accomplished with a specific type of agent (conversational-react-description) which expects to be used with a memory component.from langchain.agents import Toolfrom langchain.agents import AgentTypefrom langchain.memory import ConversationBufferMemoryfrom langchain import OpenAIfrom langchain.utilities import SerpAPIWrapperfrom langchain.agents import initialize_agentsearch = SerpAPIWrapper()tools = [    Tool(        name = "Current Search",        func=search.run,        description="useful for when you need to answer questions about current events or the current state of the world"    ),]memory = ConversationBufferMemory(memory_key="chat_history")llm=OpenAI(temperature=0)agent_chain = initialize_agent(tools, llm, agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION, verbose=True, memory=memory)agent_chain.run(input="hi, i am bob")    > Entering new AgentExecutor chain...        Thought: Do I need to use a tool? No


Thought: Do I need to use a tool? No    AI: Hi Bob, nice to meet you! How can I help you today?        > Finished chain.    'Hi Bob, nice to meet you! How can I help you today?'agent_chain.run(input="what's my name?")    > Entering new AgentExecutor chain...        Thought: Do I need to use a tool? No    AI: Your name is Bob!        > Finished chain.    'Your name is Bob!'agent_chain.run("what are some good dinners to make this week, if i like thai food?")    > Entering new AgentExecutor chain...        Thought: Do I need to use a tool? Yes    Action: Current Search    Action Input: Thai food dinner recipes    Observation: 59 easy Thai recipes for any night of the week Â· Marion Grasby's Thai spicy chilli and basil fried rice Â· Thai curry noodle soup Â· Marion Grasby's Thai Spicy ...    Thought: Do I need to use a tool? No    AI: Here are some great Thai dinner recipes you can try this week: Marion Grasby's Thai Spicy Chilli and Basil Fried Rice, Thai Curry Noodle Soup, Thai Green Curry with Coconut Rice, Thai Red Curry with Vegetables, and Thai Coconut Soup. I hope you enjoy them!        > Finished chain.    "Here are some great Thai dinner recipes you can try this week: Marion Grasby's Thai Spicy Chilli and Basil Fried Rice, Thai Curry Noodle Soup, Thai Green Curry with Coconut Rice, Thai Red Curry with Vegetables, and Thai Coconut Soup.


Thai Green Curry with Coconut Rice, Thai Red Curry with Vegetables, and Thai Coconut Soup. I hope you enjoy them!"agent_chain.run(input="tell me the last letter in my name, and also tell me who won the world cup in 1978?")    > Entering new AgentExecutor chain...        Thought: Do I need to use a tool? Yes    Action: Current Search    Action Input: Who won the World Cup in 1978    Observation: Argentina national football team    Thought: Do I need to use a tool? No    AI: The last letter in your name is "b" and the winner of the 1978 World Cup was the Argentina national football team.        > Finished chain.    'The last letter in your name is "b" and the winner of the 1978 World Cup was the Argentina national football team.'agent_chain.run(input="whats the current temperature in pomfret?")    > Entering new AgentExecutor chain...        Thought: Do I need to use a tool? Yes    Action: Current Search    Action Input: Current temperature in Pomfret    Observation: Partly cloudy skies. High around 70F. Winds W at 5 to 10 mph. Humidity41%.    Thought: Do I need to use a tool? No    AI: The current temperature in Pomfret is around 70F with partly cloudy skies and winds W at 5 to 10 mph. The humidity is 41%.        > Finished chain.    'The current temperature in Pomfret is around 70F with partly cloudy skies and winds W at 5 to 10 mph. The humidity is 41%.'Using a chat


winds W at 5 to 10 mph. The humidity is 41%.'Using a chat modelâ€‹The chat-conversational-react-description agent type lets us create a conversational agent using a chat model instead of an LLM.from langchain.memory import ConversationBufferMemoryfrom langchain.chat_models import ChatOpenAImemory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)llm = ChatOpenAI(openai_api_key=OPENAI_API_KEY, temperature=0)agent_chain = initialize_agent(tools, llm, agent=AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION, verbose=True, memory=memory)agent_chain.run(input="hi, i am bob")    > Entering new AgentExecutor chain...    {        "action": "Final Answer",        "action_input": "Hello Bob! How can I assist you today?"    }        > Finished chain.    'Hello Bob! How can I assist you today?'agent_chain.run(input="what's my name?")    > Entering new AgentExecutor chain...    {        "action": "Final Answer",        "action_input": "Your name is Bob."    }        > Finished chain.    'Your name is Bob.'agent_chain.run("what are some good dinners to make this week, if i like thai food?")    > Entering new AgentExecutor chain...    {        "action": "Current Search",        "action_input": "Thai food dinner recipes"    }    Observation: 64 easy Thai recipes for any night of the week Â· Thai curry noodle soup


Observation: 64 easy Thai recipes for any night of the week Â· Thai curry noodle soup Â· Thai yellow cauliflower, snake bean and tofu curry Â· Thai-spiced chicken hand pies Â· Thai ...    Thought:{        "action": "Final Answer",        "action_input": "Here are some Thai food dinner recipes you can try this week: Thai curry noodle soup, Thai yellow cauliflower, snake bean and tofu curry, Thai-spiced chicken hand pies, and many more. You can find the full list of recipes at the source I found earlier."    }        > Finished chain.    'Here are some Thai food dinner recipes you can try this week: Thai curry noodle soup, Thai yellow cauliflower, snake bean and tofu curry, Thai-spiced chicken hand pies, and many more. You can find the full list of recipes at the source I found earlier.'agent_chain.run(input="tell me the last letter in my name, and also tell me who won the world cup in 1978?")    > Entering new AgentExecutor chain...    {        "action": "Final Answer",        "action_input": "The last letter in your name is 'b'. Argentina won the World Cup in 1978."    }        > Finished chain.    "The last letter in your name is 'b'. Argentina won the World Cup in 1978."agent_chain.run(input="whats the weather like in pomfret?")    > Entering new AgentExecutor chain...    {        "action": "Current Search",        "action_input": "weather in pomfret"    }


"action_input": "weather in pomfret"    }    Observation: Cloudy with showers. Low around 55F. Winds S at 5 to 10 mph. Chance of rain 60%. Humidity76%.    Thought:{        "action": "Final Answer",        "action_input": "Cloudy with showers. Low around 55F. Winds S at 5 to 10 mph. Chance of rain 60%. Humidity76%."    }        > Finished chain.    'Cloudy with showers. Low around 55F. Winds S at 5 to 10 mph. Chance of rain 60%. Humidity76%.'PreviousAgent typesNextOpenAI functionsUsing a chat modelCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


OpenAI functions | ğŸ¦œï¸�ğŸ”— Langchain


Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKGet startedIntroductionInstallationQuickstartModulesModel I/â€‹OData connectionChainsMemoryAgentsAgent typesConversationalOpenAI functionsOpenAI Multi Functions AgentPlan and executeReActReAct document storeSelf ask with searchStructured tool chatHow-toToolsToolkitsCallbacksModulesGuidesEcosystemAdditional resourcesModulesAgentsAgent typesOpenAI functionsOpenAI functionsCertain OpenAI models (like gpt-3.5-turbo-0613 and gpt-4-0613) have been fine-tuned to detect when a function should to be called and respond with the inputs that should be passed to the function.
In an API call, you can describe functions and have the model intelligently choose to output a JSON object containing arguments to call those functions.


The goal of the OpenAI Function APIs is to more reliably return valid and useful function calls than a generic text completion or chat API.The OpenAI Functions Agent is designed to work with these models.Install openai,google-search-results packages which are required as the langchain packages call them internallypip install openai google-search-resultsfrom langchain import LLMMathChain, OpenAI, SerpAPIWrapper, SQLDatabase, SQLDatabaseChainfrom langchain.agents import initialize_agent, Toolfrom langchain.agents import AgentTypefrom langchain.chat_models import ChatOpenAIllm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-0613")search = SerpAPIWrapper()llm_math_chain = LLMMathChain.from_llm(llm=llm, verbose=True)db = SQLDatabase.from_uri("sqlite:///../../../../../notebooks/Chinook.db")db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True)tools = [    Tool(        name = "Search",        func=search.run,        description="useful for when you need to answer questions about current events. You should ask targeted questions"    ),    Tool(        name="Calculator",        func=llm_math_chain.run,        description="useful for when you need to answer questions about math"    ),    Tool(        name="FooBar-DB",        func=db_chain.run,        description="useful for when you need to answer questions about FooBar. Input should be in the form of a question containing full context"    )]agent =


Input should be in the form of a question containing full context"    )]agent = initialize_agent(tools, llm, agent=AgentType.OPENAI_FUNCTIONS, verbose=True)agent.run("Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?")    > Entering new  chain...        Invoking: `Search` with `{'query': 'Leo DiCaprio girlfriend'}`            Amidst his casual romance with Gigi, Leo allegedly entered a relationship with 19-year old model, Eden Polani, in February 2023.    Invoking: `Calculator` with `{'expression': '19^0.43'}`        > Entering new  chain...    19^0.43```text    19**0.43    ```    ...numexpr.evaluate("19**0.43")...        Answer: 3.547023357958959    > Finished chain.    Answer: 3.547023357958959Leo DiCaprio's girlfriend is reportedly Eden Polani. Her current age raised to the power of 0.43 is approximately 3.55.        > Finished chain.    "Leo DiCaprio's girlfriend is reportedly Eden Polani. Her current age raised to the power of 0.43 is approximately 3.55."PreviousConversationalNextOpenAI Multi Functions AgentCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Plan and execute | ğŸ¦œï¸�ğŸ”— Langchain


Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKGet startedIntroductionInstallationQuickstartModulesModel I/â€‹OData connectionChainsMemoryAgentsAgent typesConversationalOpenAI functionsOpenAI Multi Functions AgentPlan and executeReActReAct document storeSelf ask with searchStructured tool chatHow-toToolsToolkitsCallbacksModulesGuidesEcosystemAdditional resourcesModulesAgentsAgent typesPlan and executePlan and executePlan and execute agents accomplish an objective by first planning what to do, then executing the sub tasks. This idea is largely inspired by BabyAGI and then the "Plan-and-Solve" paper.The planning is almost always done by an LLM.The execution is usually done by a separate agent (equipped with tools).Importsâ€‹from langchain.chat_models import ChatOpenAIfrom langchain.experimental.plan_and_execute import PlanAndExecute, load_agent_executor, load_chat_plannerfrom langchain.llms import OpenAIfrom langchain import SerpAPIWrapperfrom langchain.agents.tools import Toolfrom langchain import LLMMathChainToolsâ€‹search = SerpAPIWrapper()llm = OpenAI(temperature=0)llm_math_chain = LLMMathChain.from_llm(llm=llm, verbose=True)tools = [    Tool(        name = "Search",        func=search.run,        description="useful for when you need to answer questions about current events"    ),    Tool(        name="Calculator",        func=llm_math_chain.run,        description="useful for when you need to answer questions about math"    ),]Planner,


for when you need to answer questions about math"    ),]Planner, Executor, and Agentâ€‹model = ChatOpenAI(temperature=0)planner = load_chat_planner(model)executor = load_agent_executor(model, tools, verbose=True)agent = PlanAndExecute(planner=planner, executor=executor, verbose=True)Run Exampleâ€‹agent.run("Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?")            > Entering new PlanAndExecute chain...    steps=[Step(value="Search for Leo DiCaprio's girlfriend on the internet."), Step(value='Find her current age.'), Step(value='Raise her current age to the 0.43 power using a calculator or programming language.'), Step(value='Output the result.'), Step(value="Given the above steps taken, respond to the user's original question.\n\n")]        > Entering new AgentExecutor chain...    Action:    ```    {      "action": "Search",      "action_input": "Who is Leo DiCaprio's girlfriend?"    }    ```             Observation: DiCaprio broke up with girlfriend Camila Morrone, 25, in the summer of 2022, after dating for four years. He's since been linked to another famous supermodel â€“ Gigi Hadid. The power couple were first supposedly an item in September after being spotted getting cozy during a party at New York Fashion Week.    Thought:Based on the previous observation, I can provide the answer to the current objective.     Action:    ```    {      "action":


Action:    ```    {      "action": "Final Answer",      "action_input": "Leo DiCaprio is currently linked to Gigi Hadid."    }    ```            > Finished chain.    *****        Step: Search for Leo DiCaprio's girlfriend on the internet.        Response: Leo DiCaprio is currently linked to Gigi Hadid.        > Entering new AgentExecutor chain...    Action:    ```    {      "action": "Search",      "action_input": "What is Gigi Hadid's current age?"    }    ```        Observation: 28 years    Thought:Previous steps: steps=[(Step(value="Search for Leo DiCaprio's girlfriend on the internet."), StepResponse(response='Leo DiCaprio is currently linked to Gigi Hadid.'))]        Current objective: value='Find her current age.'        Action:    ```    {      "action": "Search",      "action_input": "What is Gigi Hadid's current age?"    }    ```            Observation: 28 years    Thought:Previous steps: steps=[(Step(value="Search for Leo DiCaprio's girlfriend on the internet."), StepResponse(response='Leo DiCaprio is currently linked to Gigi Hadid.')), (Step(value='Find her current age.'), StepResponse(response='28 years'))]        Current


current age.'), StepResponse(response='28 years'))]        Current objective: None        Action:    ```    {      "action": "Final Answer",      "action_input": "Gigi Hadid's current age is 28 years."    }    ```                > Finished chain.    *****        Step: Find her current age.        Response: Gigi Hadid's current age is 28 years.        > Entering new AgentExecutor chain...    Action:    ```    {      "action": "Calculator",      "action_input": "28 ** 0.43"    }    ```            > Entering new LLMMathChain chain...    28 ** 0.43    ```text    28 ** 0.43    ```    ...numexpr.evaluate("28 ** 0.43")...        Answer: 4.1906168361987195    > Finished chain.        Observation: Answer: 4.1906168361987195    Thought:The next step is to provide the answer to the user's question.        Action:    ```    {      "action": "Final Answer",      "action_input": "Gigi Hadid's current age raised to the 0.43 power is approximately 4.19."    }


to the 0.43 power is approximately 4.19."    }    ```                > Finished chain.    *****        Step: Raise her current age to the 0.43 power using a calculator or programming language.        Response: Gigi Hadid's current age raised to the 0.43 power is approximately 4.19.        > Entering new AgentExecutor chain...    Action:    ```    {      "action": "Final Answer",      "action_input": "The result is approximately 4.19."    }    ```            > Finished chain.    *****        Step: Output the result.        Response: The result is approximately 4.19.        > Entering new AgentExecutor chain...    Action:    ```    {      "action": "Final Answer",      "action_input": "Gigi Hadid's current age raised to the 0.43 power is approximately 4.19."    }    ```            > Finished chain.    *****        Step: Given the above steps taken, respond to the user's original question.                Response: Gigi Hadid's current age raised to the 0.43 power is approximately 4.19.    > Finished chain.    "Gigi Hadid's current age raised


> Finished chain.    "Gigi Hadid's current age raised to the 0.43 power is approximately 4.19."PreviousOpenAI Multi Functions AgentNextReActCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Toolkits | ğŸ¦œï¸�ğŸ”— Langchain

Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKGet startedIntroductionInstallationQuickstartModulesModel I/â€‹OData connectionChainsMemoryAgentsAgent typesHow-toToolsToolkitsCallbacksModulesGuidesEcosystemAdditional resourcesModulesAgentsToolkitsToolkitsinfoHead to Integrations for documentation on built-in toolkit integrations.Toolkits are collections of tools that are designed to be used together for specific tasks and have convenience loading methods.PreviousTools as OpenAI FunctionsNextCallbacksCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Add Memory to OpenAI Functions Agent | ğŸ¦œï¸�ğŸ”— Langchain


Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKGet startedIntroductionInstallationQuickstartModulesModel I/â€‹OData connectionChainsMemoryAgentsAgent typesHow-toAdd Memory to OpenAI Functions AgentRunning Agent as an IteratorCombine agents and vector storesAsync APICreate ChatGPT cloneCustom functions with OpenAI Functions AgentCustom agentCustom agent with tool retrievalCustom LLM AgentCustom LLM Agent (with a ChatModel)Custom MRKL agentCustom multi-action agentHandle parsing errorsAccess intermediate stepsCap the max number of iterationsTimeouts for agentsReplicating MRKLShared memory across agents and toolsStreaming final agent outputUse ToolKits with OpenAI FunctionsToolsToolkitsCallbacksModulesGuidesEcosystemAdditional resourcesModulesAgentsHow-toAdd Memory to OpenAI Functions AgentAdd Memory to OpenAI Functions AgentThis notebook goes over how to add memory to OpenAI Functions agent.from langchain import (    LLMMathChain,    OpenAI,    SerpAPIWrapper,    SQLDatabase,    SQLDatabaseChain,)from langchain.agents import initialize_agent, Toolfrom langchain.agents import AgentTypefrom langchain.chat_models import ChatOpenAI    /Users/harrisonchase/.pyenv/versions/3.9.1/envs/langchain/lib/python3.9/site-packages/deeplake/util/check_latest_version.py:32: UserWarning: A newer version of deeplake (3.6.4) is available. It's recommended that you update to the latest version using `pip install -U deeplake`.      warnings.warn(llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-0613")search = SerpAPIWrapper()llm_math_chain =


= SerpAPIWrapper()llm_math_chain = LLMMathChain.from_llm(llm=llm, verbose=True)db = SQLDatabase.from_uri("sqlite:///../../../../../notebooks/Chinook.db")db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True)tools = [    Tool(        name="Search",        func=search.run,        description="useful for when you need to answer questions about current events. You should ask targeted questions",    ),    Tool(        name="Calculator",        func=llm_math_chain.run,        description="useful for when you need to answer questions about math",    ),    Tool(        name="FooBar-DB",        func=db_chain.run,        description="useful for when you need to answer questions about FooBar. Input should be in the form of a question containing full context",    ),]from langchain.prompts import MessagesPlaceholderfrom langchain.memory import ConversationBufferMemoryagent_kwargs = {    "extra_prompt_messages": [MessagesPlaceholder(variable_name="memory")],}memory = ConversationBufferMemory(memory_key="memory", return_messages=True)agent = initialize_agent(    tools,    llm,    agent=AgentType.OPENAI_FUNCTIONS,    verbose=True,    agent_kwargs=agent_kwargs,    memory=memory,)agent.run("hi")            > Entering new  chain...    Hello! How can I assist you today?        > Finished chain.


How can I assist you today?        > Finished chain.    'Hello! How can I assist you today?'agent.run("my name is bob")            > Entering new  chain...    Nice to meet you, Bob! How can I help you today?        > Finished chain.    'Nice to meet you, Bob! How can I help you today?'agent.run("whats my name")            > Entering new  chain...    Your name is Bob.        > Finished chain.    'Your name is Bob.'PreviousStructured tool chatNextRunning Agent as an IteratorCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Tools | ğŸ¦œï¸�ğŸ”— Langchain

Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKGet startedIntroductionInstallationQuickstartModulesModel I/â€‹OData connectionChainsMemoryAgentsAgent typesHow-toToolsDefining Custom ToolsHuman-in-the-loop Tool ValidationMulti-Input ToolsTool Input SchemaTools as OpenAI FunctionsToolkitsCallbacksModulesGuidesEcosystemAdditional resourcesModulesAgentsToolsOn this pageToolsinfoHead to Integrations for documentation on built-in tool integrations.Tools are interfaces that an agent can use to interact with the world.Get startedâ€‹Tools are functions that agents can use to interact with the world.
These tools can be generic utilities (e.g. search), other chains, or even other agents.Currently, tools can be loaded with the following snippet:from langchain.agents import load_toolstool_names = [...]tools = load_tools(tool_names)Some tools (e.g. chains, agents) may require a base LLM to use to initialize them.
In that case, you can pass in an LLM as well:from langchain.agents import load_toolstool_names = [...]llm = ...tools = load_tools(tool_names, llm=llm)PreviousUse ToolKits with OpenAI FunctionsNextDefining Custom ToolsGet startedCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Tool Input Schema | ğŸ¦œï¸�ğŸ”— Langchain


Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKGet startedIntroductionInstallationQuickstartModulesModel I/â€‹OData connectionChainsMemoryAgentsAgent typesHow-toToolsDefining Custom ToolsHuman-in-the-loop Tool ValidationMulti-Input ToolsTool Input SchemaTools as OpenAI FunctionsToolkitsCallbacksModulesGuidesEcosystemAdditional resourcesModulesAgentsToolsTool Input SchemaTool Input SchemaBy default, tools infer the argument schema by inspecting the function signature. For more strict requirements, custom input schema can be specified, along with custom validation logic.from typing import Any, Dictfrom langchain.agents import AgentType, initialize_agentfrom langchain.llms import OpenAIfrom langchain.tools.requests.tool import RequestsGetTool, TextRequestsWrapperfrom pydantic import BaseModel, Field, root_validatorllm = OpenAI(temperature=0)pip install tldextract > /dev/null        [notice] A new release of pip is available: 23.0.1 -> 23.1    [notice] To update, run: pip install --upgrade pipimport tldextract_APPROVED_DOMAINS = {    "langchain",    "wikipedia",}class ToolInputSchema(BaseModel):    url: str = Field(...)    @root_validator    def validate_query(cls, values: Dict[str, Any]) -> Dict:        url = values["url"]        domain = tldextract.extract(url).domain        if domain not in _APPROVED_DOMAINS:            raise ValueError(                f"Domain {domain} is not on the


f"Domain {domain} is not on the approved list:"                f" {sorted(_APPROVED_DOMAINS)}"            )        return valuestool = RequestsGetTool(    args_schema=ToolInputSchema, requests_wrapper=TextRequestsWrapper())agent = initialize_agent(    [tool], llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=False)# This will succeed, since there aren't any arguments that will be triggered during validationanswer = agent.run("What's the main title on langchain.com?")print(answer)    The main title of langchain.com is "LANG CHAIN ğŸ¦œï¸�ğŸ”— Official Home Page"agent.run("What's the main title on google.com?")    ---------------------------------------------------------------------------    ValidationError                           Traceback (most recent call last)    Cell In[7], line 1    ----> 1 agent.run("What's the main title on google.com?")    File ~/code/lc/lckg/langchain/chains/base.py:213, in Chain.run(self, *args, **kwargs)        211     if len(args) != 1:        212         raise ValueError("`run` supports only one positional argument.")    --> 213     return self(args[0])[self.output_keys[0]]        215 if kwargs and not args:


215 if kwargs and not args:        216     return self(kwargs)[self.output_keys[0]]    File ~/code/lc/lckg/langchain/chains/base.py:116, in Chain.__call__(self, inputs, return_only_outputs)        114 except (KeyboardInterrupt, Exception) as e:        115     self.callback_manager.on_chain_error(e, verbose=self.verbose)    --> 116     raise e        117 self.callback_manager.on_chain_end(outputs, verbose=self.verbose)        118 return self.prep_outputs(inputs, outputs, return_only_outputs)    File ~/code/lc/lckg/langchain/chains/base.py:113, in Chain.__call__(self, inputs, return_only_outputs)        107 self.callback_manager.on_chain_start(        108     {"name": self.__class__.__name__},        109     inputs,        110     verbose=self.verbose,        111 )        112 try:    --> 113     outputs = self._call(inputs)        114 except (KeyboardInterrupt, Exception) as e:        115     self.callback_manager.on_chain_error(e, verbose=self.verbose)    File ~/code/lc/lckg/langchain/agents/agent.py:792, in AgentExecutor._call(self, inputs)        790 # We now enter the


inputs)        790 # We now enter the agent loop (until it returns something).        791 while self._should_continue(iterations, time_elapsed):    --> 792     next_step_output = self._take_next_step(        793         name_to_tool_map, color_mapping, inputs, intermediate_steps        794     )        795     if isinstance(next_step_output, AgentFinish):        796         return self._return(next_step_output, intermediate_steps)    File ~/code/lc/lckg/langchain/agents/agent.py:695, in AgentExecutor._take_next_step(self, name_to_tool_map, color_mapping, inputs, intermediate_steps)        693         tool_run_kwargs["llm_prefix"] = ""        694     # We then call the tool on the tool input to get an observation    --> 695     observation = tool.run(        696         agent_action.tool_input,        697         verbose=self.verbose,        698         color=color,        699         **tool_run_kwargs,        700     )        701 else:        702     tool_run_kwargs =


else:        702     tool_run_kwargs = self.agent.tool_run_logging_kwargs()    File ~/code/lc/lckg/langchain/tools/base.py:110, in BaseTool.run(self, tool_input, verbose, start_color, color, **kwargs)        101 def run(        102     self,        103     tool_input: Union[str, Dict],       (...)        107     **kwargs: Any,        108 ) -> str:        109     """Run the tool."""    --> 110     run_input = self._parse_input(tool_input)        111     if not self.verbose and verbose is not None:        112         verbose_ = verbose    File ~/code/lc/lckg/langchain/tools/base.py:71, in BaseTool._parse_input(self, tool_input)         69 if issubclass(input_args, BaseModel):         70     key_ = next(iter(input_args.__fields__.keys()))    ---> 71     input_args.parse_obj({key_: tool_input})         72 # Passing as a positional argument is more straightforward for         73 # backwards compatability         74 return tool_input    File


compatability         74 return tool_input    File ~/code/lc/lckg/.venv/lib/python3.11/site-packages/pydantic/main.py:526, in pydantic.main.BaseModel.parse_obj()    File ~/code/lc/lckg/.venv/lib/python3.11/site-packages/pydantic/main.py:341, in pydantic.main.BaseModel.__init__()    ValidationError: 1 validation error for ToolInputSchema    __root__      Domain google is not on the approved list: ['langchain', 'wikipedia'] (type=value_error)PreviousMulti-Input ToolsNextTools as OpenAI FunctionsCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Multi-Input Tools | ğŸ¦œï¸�ğŸ”— Langchain


Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKGet startedIntroductionInstallationQuickstartModulesModel I/â€‹OData connectionChainsMemoryAgentsAgent typesHow-toToolsDefining Custom ToolsHuman-in-the-loop Tool ValidationMulti-Input ToolsTool Input SchemaTools as OpenAI FunctionsToolkitsCallbacksModulesGuidesEcosystemAdditional resourcesModulesAgentsToolsMulti-Input ToolsOn this pageMulti-Input ToolsThis notebook shows how to use a tool that requires multiple inputs with an agent. The recommended way to do so is with the StructuredTool class.import osos.environ["LANGCHAIN_TRACING"] = "true"from langchain import OpenAIfrom langchain.agents import initialize_agent, AgentTypellm = OpenAI(temperature=0)from langchain.tools import StructuredTooldef multiplier(a: float, b: float) -> float:    """Multiply the provided floats."""    return a * btool = StructuredTool.from_function(multiplier)# Structured tools are compatible with the STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION agent type.agent_executor = initialize_agent(    [tool],    llm,    agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,    verbose=True,)agent_executor.run("What is 3 times 4")            > Entering new AgentExecutor chain...        Thought: I need to multiply 3 and 4    Action:    ```    {      "action": "multiplier",      "action_input": {"a": 3, "b": 4}    }    ```        Observation: 12


}    ```        Observation: 12    Thought: I know what to respond    Action:    ```    {      "action": "Final Answer",      "action_input": "3 times 4 is 12"    }    ```        > Finished chain.    '3 times 4 is 12'Multi-Input Tools with a string formatâ€‹An alternative to the structured tool would be to use the regular Tool class and accept a single string. The tool would then have to handle the parsing logic to extract the relavent values from the text, which tightly couples the tool representation to the agent prompt. This is still useful if the underlying language model can't reliabl generate structured schema. Let's take the multiplication function as an example. In order to use this, we will tell the agent to generate the "Action Input" as a comma-separated list of length two. We will then write a thin wrapper that takes a string, splits it into two around a comma, and passes both parsed sides as integers to the multiplication function.from langchain.llms import OpenAIfrom langchain.agents import initialize_agent, Toolfrom langchain.agents import AgentTypeHere is the multiplication function, as well as a wrapper to parse a string as input.def multiplier(a, b):    return a * bdef parsing_multiplier(string):    a, b = string.split(",")    return multiplier(int(a), int(b))llm = OpenAI(temperature=0)tools = [    Tool(        name="Multiplier",        func=parsing_multiplier,        description="useful for when you need to multiply two numbers together. The input to


description="useful for when you need to multiply two numbers together. The input to this tool should be a comma separated list of numbers of length two, representing the two numbers you want to multiply together. For example, `1,2` would be the input if you wanted to multiply 1 by 2.",    )]mrkl = initialize_agent(    tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)mrkl.run("What is 3 times 4")            > Entering new AgentExecutor chain...     I need to multiply two numbers    Action: Multiplier    Action Input: 3,4    Observation: 12    Thought: I now know the final answer    Final Answer: 3 times 4 is 12        > Finished chain.    '3 times 4 is 12'PreviousHuman-in-the-loop Tool ValidationNextTool Input SchemaMulti-Input Tools with a string formatCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Tools as OpenAI Functions | ğŸ¦œï¸�ğŸ”— Langchain

Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKGet startedIntroductionInstallationQuickstartModulesModel I/â€‹OData connectionChainsMemoryAgentsAgent typesHow-toToolsDefining Custom ToolsHuman-in-the-loop Tool ValidationMulti-Input ToolsTool Input SchemaTools as OpenAI FunctionsToolkitsCallbacksModulesGuidesEcosystemAdditional resourcesModulesAgentsToolsTools as OpenAI FunctionsTools as OpenAI FunctionsThis notebook goes over how to use LangChain tools as OpenAI functions.from langchain.chat_models import ChatOpenAIfrom langchain.schema import HumanMessagemodel = ChatOpenAI(model="gpt-3.5-turbo-0613")from langchain.tools import MoveFileTool, format_tool_to_openai_functiontools = [MoveFileTool()]functions = [format_tool_to_openai_function(t) for t in tools]message = model.predict_messages(    [HumanMessage(content="move file foo to bar")], functions=functions)message    AIMessage(content='', additional_kwargs={'function_call': {'name': 'move_file', 'arguments': '{\n  "source_path": "foo",\n  "destination_path": "bar"\n}'}}, example=False)message.additional_kwargs["function_call"]    {'name': 'move_file',     'arguments': '{\n  "source_path": "foo",\n  "destination_path": "bar"\n}'}PreviousTool Input SchemaNextToolkitsCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Defining Custom Tools | ğŸ¦œï¸�ğŸ”— Langchain


Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKGet startedIntroductionInstallationQuickstartModulesModel I/â€‹OData connectionChainsMemoryAgentsAgent typesHow-toToolsDefining Custom ToolsHuman-in-the-loop Tool ValidationMulti-Input ToolsTool Input SchemaTools as OpenAI FunctionsToolkitsCallbacksModulesGuidesEcosystemAdditional resourcesModulesAgentsToolsDefining Custom ToolsOn this pageDefining Custom ToolsWhen constructing your own agent, you will need to provide it with a list of Tools that it can use. Besides the actual function that is called, the Tool consists of several components:name (str), is required and must be unique within a set of tools provided to an agentdescription (str), is optional but recommended, as it is used by an agent to determine tool usereturn_direct (bool), defaults to Falseargs_schema (Pydantic BaseModel), is optional but recommended, can be used to provide more information (e.g., few-shot examples) or validation for expected parameters.There are two main ways to define a tool, we will cover both in the example below.# Import things that are needed genericallyfrom langchain import LLMMathChain, SerpAPIWrapperfrom langchain.agents import AgentType, initialize_agentfrom langchain.chat_models import ChatOpenAIfrom langchain.tools import BaseTool, StructuredTool, Tool, toolInitialize the LLM to use for the agent.llm = ChatOpenAI(temperature=0)Completely New Tools - String Input and Outputâ€‹The simplest tools accept a single query string and return a string output. If your tool function requires multiple arguments, you might want to skip down to the StructuredTool section below.There are two ways to do this: either by using the Tool dataclass, or by subclassing the BaseTool class.Tool dataclassâ€‹The


Tool dataclass, or by subclassing the BaseTool class.Tool dataclassâ€‹The 'Tool' dataclass wraps functions that accept a single string input and returns a string output.# Load the tool configs that are needed.search = SerpAPIWrapper()llm_math_chain = LLMMathChain(llm=llm, verbose=True)tools = [    Tool.from_function(        func=search.run,        name="Search",        description="useful for when you need to answer questions about current events"        # coroutine= ... <- you can specify an async method if desired as well    ),]    /Users/wfh/code/lc/lckg/langchain/chains/llm_math/base.py:50: UserWarning: Directly instantiating an LLMMathChain with an llm is deprecated. Please instantiate with llm_chain argument or using the from_llm class method.      warnings.warn(You can also define a custom `args_schema`` to provide more information about inputs.from pydantic import BaseModel, Fieldclass CalculatorInput(BaseModel):    question: str = Field()tools.append(    Tool.from_function(        func=llm_math_chain.run,        name="Calculator",        description="useful for when you need to answer questions about math",        args_schema=CalculatorInput        # coroutine= ... <- you can specify an async method if desired as well    ))# Construct the agent. We will use the default agent type here.# See documentation for a full list of options.agent = initialize_agent(    tools, llm,


documentation for a full list of options.agent = initialize_agent(    tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)agent.run(    "Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?")            > Entering new AgentExecutor chain...    I need to find out Leo DiCaprio's girlfriend's name and her age    Action: Search    Action Input: "Leo DiCaprio girlfriend"    Observation: After rumours of a romance with Gigi Hadid, the Oscar winner has seemingly moved on. First being linked to the television personality in September 2022, it appears as if his "age bracket" has moved up. This follows his rumoured relationship with mere 19-year-old Eden Polani.    Thought:I still need to find out his current girlfriend's name and age    Action: Search    Action Input: "Leo DiCaprio current girlfriend"    Observation: Just Jared on Instagram: â€œLeonardo DiCaprio & girlfriend Camila Morrone couple up for a lunch date!    Thought:Now that I know his girlfriend's name is Camila Morrone, I need to find her current age    Action: Search    Action Input: "Camila Morrone age"    Observation: 25 years    Thought:Now that I have her age, I need to calculate her age raised to the 0.43 power    Action: Calculator    Action Input: 25^(0.43)        > Entering new LLMMathChain chain...    25^(0.43)```text    25**(0.43)    ```


25**(0.43)    ```    ...numexpr.evaluate("25**(0.43)")...        Answer: 3.991298452658078    > Finished chain.        Observation: Answer: 3.991298452658078    Thought:I now know the final answer    Final Answer: Camila Morrone's current age raised to the 0.43 power is approximately 3.99.        > Finished chain.    "Camila Morrone's current age raised to the 0.43 power is approximately 3.99."Subclassing the BaseTool classâ€‹You can also directly subclass BaseTool. This is useful if you want more control over the instance variables or if you want to propagate callbacks to nested chains or other tools.from typing import Optional, Typefrom langchain.callbacks.manager import (    AsyncCallbackManagerForToolRun,    CallbackManagerForToolRun,)class CustomSearchTool(BaseTool):    name = "custom_search"    description = "useful for when you need to answer questions about current events"    def _run(        self, query: str, run_manager: Optional[CallbackManagerForToolRun] = None    ) -> str:        """Use the tool."""        return search.run(query)    async def _arun(        self, query: str, run_manager: Optional[AsyncCallbackManagerForToolRun] = None    ) -> str:        """Use the tool asynchronously."""        raise NotImplementedError("custom_search does not support async")class


asynchronously."""        raise NotImplementedError("custom_search does not support async")class CustomCalculatorTool(BaseTool):    name = "Calculator"    description = "useful for when you need to answer questions about math"    args_schema: Type[BaseModel] = CalculatorInput    def _run(        self, query: str, run_manager: Optional[CallbackManagerForToolRun] = None    ) -> str:        """Use the tool."""        return llm_math_chain.run(query)    async def _arun(        self, query: str, run_manager: Optional[AsyncCallbackManagerForToolRun] = None    ) -> str:        """Use the tool asynchronously."""        raise NotImplementedError("Calculator does not support async")tools = [CustomSearchTool(), CustomCalculatorTool()]agent = initialize_agent(    tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)agent.run(    "Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?")            > Entering new AgentExecutor chain...    I need to use custom_search to find out who Leo DiCaprio's girlfriend is, and then use the Calculator to raise her age to the 0.43 power.    Action: custom_search    Action Input: "Leo DiCaprio girlfriend"    Observation: After rumours of a romance with Gigi Hadid, the Oscar winner has seemingly moved on. First being linked to the television personality in September 2022, it appears as if his "age bracket" has moved


the television personality in September 2022, it appears as if his "age bracket" has moved up. This follows his rumoured relationship with mere 19-year-old Eden Polani.    Thought:I need to find out the current age of Eden Polani.    Action: custom_search    Action Input: "Eden Polani age"    Observation: 19 years old    Thought:Now I can use the Calculator to raise her age to the 0.43 power.    Action: Calculator    Action Input: 19 ^ 0.43        > Entering new LLMMathChain chain...    19 ^ 0.43```text    19 ** 0.43    ```    ...numexpr.evaluate("19 ** 0.43")...        Answer: 3.547023357958959    > Finished chain.        Observation: Answer: 3.547023357958959    Thought:I now know the final answer.    Final Answer: 3.547023357958959        > Finished chain.    '3.547023357958959'Using the tool decoratorâ€‹To make it easier to define custom tools, a @tool decorator is provided. This decorator can be used to quickly create a Tool from a simple function. The decorator uses the function name as the tool name by default, but this can be overridden by passing a string as the first argument. Additionally, the decorator will use the function's docstring as the tool's description.from langchain.tools import tool@tooldef search_api(query: str) -> str:    """Searches the API for the query."""    return f"Results for query


"""Searches the API for the query."""    return f"Results for query {query}"search_apiYou can also provide arguments like the tool name and whether to return directly.@tool("search", return_direct=True)def search_api(query: str) -> str:    """Searches the API for the query."""    return "Results"search_api    Tool(name='search', description='search(query: str) -> str - Searches the API for the query.', args_schema=<class 'pydantic.main.SearchApi'>, return_direct=True, verbose=False, callback_manager=<langchain.callbacks.shared.SharedCallbackManager object at 0x12748c4c0>, func=<function search_api at 0x16bd66310>, coroutine=None)You can also provide args_schema to provide more information about the argumentclass SearchInput(BaseModel):    query: str = Field(description="should be a search query")@tool("search", return_direct=True, args_schema=SearchInput)def search_api(query: str) -> str:    """Searches the API for the query."""    return "Results"search_api    Tool(name='search', description='search(query: str) -> str - Searches the API for the query.', args_schema=<class '__main__.SearchInput'>, return_direct=True, verbose=False, callback_manager=<langchain.callbacks.shared.SharedCallbackManager object at 0x12748c4c0>, func=<function search_api at 0x16bcf0ee0>, coroutine=None)Custom Structured Toolsâ€‹If your functions require more structured arguments, you can use the StructuredTool class directly, or still subclass the BaseTool class.StructuredTool dataclassâ€‹To dynamically generate a structured tool from a given function, the fastest way to get started is with StructuredTool.from_function().import requestsfrom


given function, the fastest way to get started is with StructuredTool.from_function().import requestsfrom langchain.tools import StructuredTooldef post_message(url: str, body: dict, parameters: Optional[dict] = None) -> str:    """Sends a POST request to the given url with the given body and parameters."""    result = requests.post(url, json=body, params=parameters)    return f"Status: {result.status_code} - {result.text}"tool = StructuredTool.from_function(post_message)Subclassing the BaseToolâ€‹The BaseTool automatically infers the schema from the _run method's signature.from typing import Optional, Typefrom langchain.callbacks.manager import (    AsyncCallbackManagerForToolRun,    CallbackManagerForToolRun,)class CustomSearchTool(BaseTool):    name = "custom_search"    description = "useful for when you need to answer questions about current events"    def _run(        self,        query: str,        engine: str = "google",        gl: str = "us",        hl: str = "en",        run_manager: Optional[CallbackManagerForToolRun] = None,    ) -> str:        """Use the tool."""        search_wrapper = SerpAPIWrapper(params={"engine": engine, "gl": gl, "hl": hl})        return search_wrapper.run(query)    async def _arun(        self,        query: str,        engine: str =


query: str,        engine: str = "google",        gl: str = "us",        hl: str = "en",        run_manager: Optional[AsyncCallbackManagerForToolRun] = None,    ) -> str:        """Use the tool asynchronously."""        raise NotImplementedError("custom_search does not support async")# You can provide a custom args schema to add descriptions or custom validationclass SearchSchema(BaseModel):    query: str = Field(description="should be a search query")    engine: str = Field(description="should be a search engine")    gl: str = Field(description="should be a country code")    hl: str = Field(description="should be a language code")class CustomSearchTool(BaseTool):    name = "custom_search"    description = "useful for when you need to answer questions about current events"    args_schema: Type[SearchSchema] = SearchSchema    def _run(        self,        query: str,        engine: str = "google",        gl: str = "us",        hl: str = "en",        run_manager: Optional[CallbackManagerForToolRun] = None,    ) -> str:        """Use the tool."""        search_wrapper = SerpAPIWrapper(params={"engine": engine, "gl": gl, "hl": hl})        return search_wrapper.run(query)    async def


hl})        return search_wrapper.run(query)    async def _arun(        self,        query: str,        engine: str = "google",        gl: str = "us",        hl: str = "en",        run_manager: Optional[AsyncCallbackManagerForToolRun] = None,    ) -> str:        """Use the tool asynchronously."""        raise NotImplementedError("custom_search does not support async")Using the decoratorâ€‹The tool decorator creates a structured tool automatically if the signature has multiple arguments.import requestsfrom langchain.tools import tool@tooldef post_message(url: str, body: dict, parameters: Optional[dict] = None) -> str:    """Sends a POST request to the given url with the given body and parameters."""    result = requests.post(url, json=body, params=parameters)    return f"Status: {result.status_code} - {result.text}"Modify existing toolsâ€‹Now, we show how to load existing tools and modify them directly. In the example below, we do something really simple and change the Search tool to have the name Google Search.from langchain.agents import load_toolstools = load_tools(["serpapi", "llm-math"], llm=llm)tools[0].name = "Google Search"agent = initialize_agent(    tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)agent.run(    "Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?")


is her current age raised to the 0.43 power?")            > Entering new AgentExecutor chain...    I need to find out Leo DiCaprio's girlfriend's name and her age.    Action: Google Search    Action Input: "Leo DiCaprio girlfriend"    Observation: After rumours of a romance with Gigi Hadid, the Oscar winner has seemingly moved on. First being linked to the television personality in September 2022, it appears as if his "age bracket" has moved up. This follows his rumoured relationship with mere 19-year-old Eden Polani.    Thought:I still need to find out his current girlfriend's name and her age.    Action: Google Search    Action Input: "Leo DiCaprio current girlfriend age"    Observation: Leonardo DiCaprio has been linked with 19-year-old model Eden Polani, continuing the rumour that he doesn't date any women over the age of ...    Thought:I need to find out the age of Eden Polani.    Action: Calculator    Action Input: 19^(0.43)    Observation: Answer: 3.547023357958959    Thought:I now know the final answer.    Final Answer: The age of Leo DiCaprio's girlfriend raised to the 0.43 power is approximately 3.55.        > Finished chain.    "The age of Leo DiCaprio's girlfriend raised to the 0.43 power is approximately 3.55."Defining the priorities among Toolsâ€‹When you made a Custom tool, you may want the Agent to use the custom tool more than normal tools.For example, you made a custom tool, which gets information on music from your database. When a user


example, you made a custom tool, which gets information on music from your database. When a user wants information on songs, You want the Agent to use  the custom tool more than the normal Search tool. But the Agent might prioritize a normal Search tool.This can be accomplished by adding a statement such as Use this more than the normal search if the question is about Music, like 'who is the singer of yesterday?' or 'what is the most popular song in 2022?' to the description.An example is below.# Import things that are needed genericallyfrom langchain.agents import initialize_agent, Toolfrom langchain.agents import AgentTypefrom langchain.llms import OpenAIfrom langchain import LLMMathChain, SerpAPIWrappersearch = SerpAPIWrapper()tools = [    Tool(        name="Search",        func=search.run,        description="useful for when you need to answer questions about current events",    ),    Tool(        name="Music Search",        func=lambda x: "'All I Want For Christmas Is You' by Mariah Carey.",  # Mock Function        description="A Music search engine. Use this more than the normal search if the question is about Music, like 'who is the singer of yesterday?' or 'what is the most popular song in 2022?'",    ),]agent = initialize_agent(    tools,    OpenAI(temperature=0),    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,    verbose=True,)agent.run("what is the most famous song of christmas")            > Entering new AgentExecutor chain...     I should use a music search engine to find


Entering new AgentExecutor chain...     I should use a music search engine to find the answer    Action: Music Search    Action Input: most famous song of christmas'All I Want For Christmas Is You' by Mariah Carey. I now know the final answer    Final Answer: 'All I Want For Christmas Is You' by Mariah Carey.        > Finished chain.    "'All I Want For Christmas Is You' by Mariah Carey."Using tools to return directlyâ€‹Often, it can be desirable to have a tool output returned directly to the user, if itâ€™s called. You can do this easily with LangChain by setting the return_direct flag for a tool to be True.llm_math_chain = LLMMathChain(llm=llm)tools = [    Tool(        name="Calculator",        func=llm_math_chain.run,        description="useful for when you need to answer questions about math",        return_direct=True,    )]llm = OpenAI(temperature=0)agent = initialize_agent(    tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)agent.run("whats 2**.12")            > Entering new AgentExecutor chain...     I need to calculate this    Action: Calculator    Action Input: 2**.12Answer: 1.086734862526058        > Finished chain.    'Answer: 1.086734862526058'Handling Tool Errorsâ€‹When a tool encounters an error and the exception is not caught, the agent will stop


a tool encounters an error and the exception is not caught, the agent will stop executing. If you want the agent to continue execution, you can raise a ToolException and set handle_tool_error accordingly. When ToolException is thrown, the agent will not stop working, but will handle the exception according to the handle_tool_error variable of the tool, and the processing result will be returned to the agent as observation, and printed in red.You can set handle_tool_error to True, set it a unified string value, or set it as a function. If it's set as a function, the function should take a ToolException as a parameter and return a str value.Please note that only raising a ToolException won't be effective. You need to first set the handle_tool_error of the tool because its default value is False.from langchain.tools.base import ToolExceptionfrom langchain import SerpAPIWrapperfrom langchain.agents import AgentType, initialize_agentfrom langchain.chat_models import ChatOpenAIfrom langchain.tools import Toolfrom langchain.chat_models import ChatOpenAIdef _handle_error(error: ToolException) -> str:    return (        "The following errors occurred during tool execution:"        + error.args[0]        + "Please try another tool."    )def search_tool1(s: str):    raise ToolException("The search tool1 is not available.")def search_tool2(s: str):    raise ToolException("The search tool2 is not available.")search_tool3 = SerpAPIWrapper()description = "useful for when you need to answer questions about current events.You should give priority to using it."tools = [    Tool.from_function(        func=search_tool1,        name="Search_tool1",


name="Search_tool1",        description=description,        handle_tool_error=True,    ),    Tool.from_function(        func=search_tool2,        name="Search_tool2",        description=description,        handle_tool_error=_handle_error,    ),    Tool.from_function(        func=search_tool3.run,        name="Search_tool3",        description="useful for when you need to answer questions about current events",    ),]agent = initialize_agent(    tools,    ChatOpenAI(temperature=0),    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,    verbose=True,)agent.run("Who is Leo DiCaprio's girlfriend?")            > Entering new AgentExecutor chain...    I should use Search_tool1 to find recent news articles about Leo DiCaprio's personal life.    Action: Search_tool1    Action Input: "Leo DiCaprio girlfriend"    Observation: The search tool1 is not available.    Thought:I should try using Search_tool2 instead.    Action: Search_tool2    Action Input: "Leo DiCaprio girlfriend"    Observation: The following errors occurred during tool execution:The search tool2 is not available.Please try another tool.    Thought:I should try using Search_tool3 as a last resort.    Action: Search_tool3    Action Input: "Leo DiCaprio girlfriend"    Observation: Leonardo DiCaprio and Gigi Hadid


DiCaprio girlfriend"    Observation: Leonardo DiCaprio and Gigi Hadid were recently spotted at a pre-Oscars party, sparking interest once again in their rumored romance. The Revenant actor and the model first made headlines when they were spotted together at a New York Fashion Week afterparty in September 2022.    Thought:Based on the information from Search_tool3, it seems that Gigi Hadid is currently rumored to be Leo DiCaprio's girlfriend.    Final Answer: Gigi Hadid is currently rumored to be Leo DiCaprio's girlfriend.        > Finished chain.    "Gigi Hadid is currently rumored to be Leo DiCaprio's girlfriend."PreviousToolsNextHuman-in-the-loop Tool ValidationCompletely New Tools - String Input and OutputTool dataclassSubclassing the BaseTool classUsing the tool decoratorCustom Structured ToolsStructuredTool dataclassSubclassing the BaseToolUsing the decoratorModify existing toolsDefining the priorities among ToolsUsing tools to return directlyHandling Tool ErrorsCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.


Human-in-the-loop Tool Validation | ğŸ¦œï¸�ğŸ”— Langchain


Skip to main contentğŸ¦œï¸�ğŸ”— LangChainDocsUse casesIntegrationsAPILangSmithJS/TS DocsCTRLKGet startedIntroductionInstallationQuickstartModulesModel I/â€‹OData connectionChainsMemoryAgentsAgent typesHow-toToolsDefining Custom ToolsHuman-in-the-loop Tool ValidationMulti-Input ToolsTool Input SchemaTools as OpenAI FunctionsToolkitsCallbacksModulesGuidesEcosystemAdditional resourcesModulesAgentsToolsHuman-in-the-loop Tool ValidationOn this pageHuman-in-the-loop Tool ValidationThis walkthrough demonstrates how to add Human validation to any Tool. We'll do this using the HumanApprovalCallbackhandler.Let's suppose we need to make use of the ShellTool. Adding this tool to an automated flow poses obvious risks. Let's see how we could enforce manual human approval of inputs going into this tool.Note: We generally recommend against using the ShellTool. There's a lot of ways to misuse it, and it's not required for most use cases. We employ it here only for demonstration purposes.from langchain.callbacks import HumanApprovalCallbackHandlerfrom langchain.tools import ShellTooltool = ShellTool()print(tool.run("echo Hello World!"))    Hello World!    Adding Human Approvalâ€‹Adding the default HumanApprovalCallbackHandler to the tool will make it so that a user has to manually approve every input to the tool before the command is actually executed.tool = ShellTool(callbacks=[HumanApprovalCallbackHandler()])print(tool.run("ls /usr"))    Do you approve of the following input? Anything except 'Y'/'Yes' (case-insensitive) will be treated as a no.        ls /usr    yes    X11    X11R6    bin    lib    libexec    local    sbin    share    standalone


libexec    local    sbin    share    standalone    print(tool.run("ls /private"))    Do you approve of the following input? Anything except 'Y'/'Yes' (case-insensitive) will be treated as a no.        ls /private    no    ---------------------------------------------------------------------------    HumanRejectedException                    Traceback (most recent call last)    Cell In[17], line 1    ----> 1 print(tool.run("ls /private"))    File ~/langchain/langchain/tools/base.py:257, in BaseTool.run(self, tool_input, verbose, start_color, color, callbacks, **kwargs)        255 # TODO: maybe also pass through run_manager is _run supports kwargs        256 new_arg_supported = signature(self._run).parameters.get("run_manager")    --> 257 run_manager = callback_manager.on_tool_start(        258     {"name": self.name, "description": self.description},        259     tool_input if isinstance(tool_input, str) else str(tool_input),        260     color=start_color,        261     **kwargs,        262 )        263 try:        264     tool_args, tool_kwargs = self._to_args_and_kwargs(parsed_input)    File ~/langchain/langchain/callbacks/manager.py:672, in CallbackManager.on_tool_start(self, serialized,


in CallbackManager.on_tool_start(self, serialized, input_str, run_id, parent_run_id, **kwargs)        669 if run_id is None:        670     run_id = uuid4()    --> 672 _handle_event(        673     self.handlers,        674     "on_tool_start",        675     "ignore_agent",        676     serialized,        677     input_str,        678     run_id=run_id,        679     parent_run_id=self.parent_run_id,        680     **kwargs,        681 )        683 return CallbackManagerForToolRun(        684     run_id, self.handlers, self.inheritable_handlers, self.parent_run_id        685 )    File ~/langchain/langchain/callbacks/manager.py:157, in _handle_event(handlers, event_name, ignore_condition_name, *args, **kwargs)        155 except Exception as e:        156     if handler.raise_error:    --> 157         raise e        158     logging.warning(f"Error in {event_name} callback: {e}")    File ~/langchain/langchain/callbacks/manager.py:139,


{e}")    File ~/langchain/langchain/callbacks/manager.py:139, in _handle_event(handlers, event_name, ignore_condition_name, *args, **kwargs)        135 try:        136     if ignore_condition_name is None or not getattr(        137         handler, ignore_condition_name        138     ):    --> 139         getattr(handler, event_name)(*args, **kwargs)        140 except NotImplementedError as e:        141     if event_name == "on_chat_model_start":    File ~/langchain/langchain/callbacks/human.py:48, in HumanApprovalCallbackHandler.on_tool_start(self, serialized, input_str, run_id, parent_run_id, **kwargs)         38 def on_tool_start(         39     self,         40     serialized: Dict[str, Any],       (...)         45     **kwargs: Any,         46 ) -> Any:         47     if self._should_check(serialized) and not self._approve(input_str):    ---> 48         raise HumanRejectedException(         49             f"Inputs {input_str} to tool {serialized} were rejected."


{input_str} to tool {serialized} were rejected."         50         )    HumanRejectedException: Inputs ls /private to tool {'name': 'terminal', 'description': 'Run shell commands on this MacOS machine.'} were rejected.Configuring Human Approvalâ€‹Let's suppose we have an agent that takes in multiple tools, and we want it to only trigger human approval requests on certain tools and certain inputs. We can configure out callback handler to do just this.from langchain.agents import load_toolsfrom langchain.agents import initialize_agentfrom langchain.agents import AgentTypefrom langchain.llms import OpenAIdef _should_check(serialized_obj: dict) -> bool:    # Only require approval on ShellTool.    return serialized_obj.get("name") == "terminal"def _approve(_input: str) -> bool:    if _input == "echo 'Hello World'":        return True    msg = (        "Do you approve of the following input? "        "Anything except 'Y'/'Yes' (case-insensitive) will be treated as a no."    )    msg += "\n\n" + _input + "\n"    resp = input(msg)    return resp.lower() in ("yes", "y")callbacks = [HumanApprovalCallbackHandler(should_check=_should_check, approve=_approve)]llm = OpenAI(temperature=0)tools = load_tools(["wikipedia", "llm-math", "terminal"], llm=llm)agent = initialize_agent(    tools,    llm,    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,)agent.run(    "It's


agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,)agent.run(    "It's 2023 now. How many years ago did Konrad Adenauer become Chancellor of Germany.",    callbacks=callbacks,)    'Konrad Adenauer became Chancellor of Germany in 1949, 74 years ago.'agent.run("print 'Hello World' in the terminal", callbacks=callbacks)    'Hello World'agent.run("list all directories in /private", callbacks=callbacks)    Do you approve of the following input? Anything except 'Y'/'Yes' (case-insensitive) will be treated as a no.        ls /private    no    ---------------------------------------------------------------------------    HumanRejectedException                    Traceback (most recent call last)    Cell In[39], line 1    ----> 1 agent.run("list all directories in /private", callbacks=callbacks)    File ~/langchain/langchain/chains/base.py:236, in Chain.run(self, callbacks, *args, **kwargs)        234     if len(args) != 1:        235         raise ValueError("`run` supports only one positional argument.")    --> 236     return self(args[0], callbacks=callbacks)[self.output_keys[0]]        238 if kwargs and not args:        239     return self(kwargs, callbacks=callbacks)[self.output_keys[0]]    File ~/langchain/langchain/chains/base.py:140, in Chain.__call__(self, inputs, return_only_outputs, callbacks)


in Chain.__call__(self, inputs, return_only_outputs, callbacks)        138 except (KeyboardInterrupt, Exception) as e:        139     run_manager.on_chain_error(e)    --> 140     raise e        141 run_manager.on_chain_end(outputs)        142 return self.prep_outputs(inputs, outputs, return_only_outputs)    File ~/langchain/langchain/chains/base.py:134, in Chain.__call__(self, inputs, return_only_outputs, callbacks)        128 run_manager = callback_manager.on_chain_start(        129     {"name": self.__class__.__name__},        130     inputs,        131 )        132 try:        133     outputs = (    --> 134         self._call(inputs, run_manager=run_manager)        135         if new_arg_supported        136         else self._call(inputs)        137     )        138 except (KeyboardInterrupt, Exception) as e:        139     run_manager.on_chain_error(e)    File ~/langchain/langchain/agents/agent.py:953, in AgentExecutor._call(self, inputs, run_manager)        951 # We now enter the agent loop (until it returns


951 # We now enter the agent loop (until it returns something).        952 while self._should_continue(iterations, time_elapsed):    --> 953     next_step_output = self._take_next_step(        954         name_to_tool_map,        955         color_mapping,        956         inputs,        957         intermediate_steps,        958         run_manager=run_manager,        959     )        960     if isinstance(next_step_output, AgentFinish):        961         return self._return(        962             next_step_output, intermediate_steps, run_manager=run_manager        963         )    File ~/langchain/langchain/agents/agent.py:820, in AgentExecutor._take_next_step(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)        818         tool_run_kwargs["llm_prefix"] = ""        819     # We then call the tool on the tool input to get an observation    --> 820     observation = tool.run(        821


observation = tool.run(        821         agent_action.tool_input,        822         verbose=self.verbose,        823         color=color,        824         callbacks=run_manager.get_child() if run_manager else None,        825         **tool_run_kwargs,        826     )        827 else:        828     tool_run_kwargs = self.agent.tool_run_logging_kwargs()    File ~/langchain/langchain/tools/base.py:257, in BaseTool.run(self, tool_input, verbose, start_color, color, callbacks, **kwargs)        255 # TODO: maybe also pass through run_manager is _run supports kwargs        256 new_arg_supported = signature(self._run).parameters.get("run_manager")    --> 257 run_manager = callback_manager.on_tool_start(        258     {"name": self.name, "description": self.description},        259     tool_input if isinstance(tool_input, str) else str(tool_input),        260     color=start_color,        261     **kwargs,        262 )        263 try:        264     tool_args, tool_kwargs =


264     tool_args, tool_kwargs = self._to_args_and_kwargs(parsed_input)    File ~/langchain/langchain/callbacks/manager.py:672, in CallbackManager.on_tool_start(self, serialized, input_str, run_id, parent_run_id, **kwargs)        669 if run_id is None:        670     run_id = uuid4()    --> 672 _handle_event(        673     self.handlers,        674     "on_tool_start",        675     "ignore_agent",        676     serialized,        677     input_str,        678     run_id=run_id,        679     parent_run_id=self.parent_run_id,        680     **kwargs,        681 )        683 return CallbackManagerForToolRun(        684     run_id, self.handlers, self.inheritable_handlers, self.parent_run_id        685 )    File ~/langchain/langchain/callbacks/manager.py:157, in _handle_event(handlers, event_name, ignore_condition_name, *args, **kwargs)        155 except Exception as e:        156     if handler.raise_error:    --> 157         raise e


handler.raise_error:    --> 157         raise e        158     logging.warning(f"Error in {event_name} callback: {e}")    File ~/langchain/langchain/callbacks/manager.py:139, in _handle_event(handlers, event_name, ignore_condition_name, *args, **kwargs)        135 try:        136     if ignore_condition_name is None or not getattr(        137         handler, ignore_condition_name        138     ):    --> 139         getattr(handler, event_name)(*args, **kwargs)        140 except NotImplementedError as e:        141     if event_name == "on_chat_model_start":    File ~/langchain/langchain/callbacks/human.py:48, in HumanApprovalCallbackHandler.on_tool_start(self, serialized, input_str, run_id, parent_run_id, **kwargs)         38 def on_tool_start(         39     self,         40     serialized: Dict[str, Any],       (...)         45     **kwargs: Any,         46 ) -> Any:         47     if self._should_check(serialized) and not self._approve(input_str):    ---> 48         raise HumanRejectedException(


---> 48         raise HumanRejectedException(         49             f"Inputs {input_str} to tool {serialized} were rejected."         50         )    HumanRejectedException: Inputs ls /private to tool {'name': 'terminal', 'description': 'Run shell commands on this MacOS machine.'} were rejected.PreviousDefining Custom ToolsNextMulti-Input ToolsAdding Human ApprovalConfiguring Human ApprovalCommunityDiscordTwitterGitHubPythonJS/TSMoreHomepageBlogCopyright Â© 2023 LangChain, Inc.