{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d82e62ec",
   "metadata": {},
   "source": [
    "# ReAct\n",
    "\n",
    "This walkthrough showcases using an agent to implement the [ReAct](https://react-lm.github.io/) logic."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "102b0e52",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.agents import load_tools\n",
    "from langchain.agents import initialize_agent\n",
    "from langchain.agents import AgentType\n",
    "from langchain.llms import OpenAI"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0c9c056",
   "metadata": {},
   "source": [
    "First, let's load the language model we're going to use to control the agent."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "184f0682",
   "metadata": {},
   "outputs": [],
   "source": [
    "llm = OpenAI(temperature=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e67a000",
   "metadata": {},
   "source": [
    "Next, let's load some tools to use. Note that the `llm-math` tool uses an LLM, so we need to pass that in."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "256408d5",
   "metadata": {},
   "outputs": [],
   "source": [
    "tools = load_tools([\"serpapi\", \"llm-math\"], llm=llm)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b7d04f53",
   "metadata": {},
   "source": [
    "## Using LCEL\n",
    "\n",
    "We will first show how to create the agent using LCEL"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "bb0813a3",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.tools.render import render_text_description\n",
    "from langchain.agents.output_parsers import ReActSingleInputOutputParser\n",
    "from langchain.agents.format_scratchpad import format_log_to_str\n",
    "from langchain import hub"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "d3ae5fcd",
   "metadata": {},
   "outputs": [],
   "source": [
    "prompt = hub.pull(\"hwchase17/react\")\n",
    "prompt = prompt.partial(\n",
    "    tools=render_text_description(tools),\n",
    "    tool_names=\", \".join([t.name for t in tools]),\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "bf47a3c7",
   "metadata": {},
   "outputs": [],
   "source": [
    "llm_with_stop = llm.bind(stop=[\"\\nObservation\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "b3d3958b",
   "metadata": {},
   "outputs": [],
   "source": [
    "agent = {\n",
    "    \"input\": lambda x: x[\"input\"],\n",
    "    \"agent_scratchpad\": lambda x: format_log_to_str(x['intermediate_steps'])\n",
    "} | prompt | llm_with_stop | ReActSingleInputOutputParser()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a0a57769",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.agents import AgentExecutor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "026de6cd",
   "metadata": {},
   "outputs": [],
   "source": [
    "agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "57780ce1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m I need to find out who Leo DiCaprio's girlfriend is and then calculate her age raised to the 0.43 power.\n",
      "Action: Search\n",
      "Action Input: \"Leo DiCaprio girlfriend\"\u001b[0m\u001b[36;1m\u001b[1;3mmodel Vittoria Ceretti\u001b[0m\u001b[32;1m\u001b[1;3m I need to find out Vittoria Ceretti's age\n",
      "Action: Search\n",
      "Action Input: \"Vittoria Ceretti age\"\u001b[0m\u001b[36;1m\u001b[1;3m25 years\u001b[0m\u001b[32;1m\u001b[1;3m I need to calculate 25 raised to the 0.43 power\n",
      "Action: Calculator\n",
      "Action Input: 25^0.43\u001b[0m\u001b[33;1m\u001b[1;3mAnswer: 3.991298452658078\u001b[0m\u001b[32;1m\u001b[1;3m I now know the final answer\n",
      "Final Answer: Leo DiCaprio's girlfriend is Vittoria Ceretti and her current age raised to the 0.43 power is 3.991298452658078.\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'input': \"Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?\",\n",
       " 'output': \"Leo DiCaprio's girlfriend is Vittoria Ceretti and her current age raised to the 0.43 power is 3.991298452658078.\"}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent_executor.invoke({\"input\": \"Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b4a33ea8",
   "metadata": {},
   "source": [
    "## Using ZeroShotReactAgent\n",
    "\n",
    "We will now show how to use the agent with an off-the-shelf agent implementation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "9752e90e",
   "metadata": {},
   "outputs": [],
   "source": [
    "agent_executor = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "04c5bcf6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m I need to find out who Leo DiCaprio's girlfriend is and then calculate her age raised to the 0.43 power.\n",
      "Action: Search\n",
      "Action Input: \"Leo DiCaprio girlfriend\"\u001b[0m\n",
      "Observation: \u001b[36;1m\u001b[1;3mmodel Vittoria Ceretti\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3m I need to find out Vittoria Ceretti's age\n",
      "Action: Search\n",
      "Action Input: \"Vittoria Ceretti age\"\u001b[0m\n",
      "Observation: \u001b[36;1m\u001b[1;3m25 years\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3m I need to calculate 25 raised to the 0.43 power\n",
      "Action: Calculator\n",
      "Action Input: 25^0.43\u001b[0m\n",
      "Observation: \u001b[33;1m\u001b[1;3mAnswer: 3.991298452658078\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3m I now know the final answer\n",
      "Final Answer: Leo DiCaprio's girlfriend is Vittoria Ceretti and her current age raised to the 0.43 power is 3.991298452658078.\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'input': \"Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?\",\n",
       " 'output': \"Leo DiCaprio's girlfriend is Vittoria Ceretti and her current age raised to the 0.43 power is 3.991298452658078.\"}"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent_executor.invoke({\"input\": \"Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7f3e8fc8",
   "metadata": {},
   "source": [
    "## Using chat models\n",
    "\n",
    "You can also create ReAct agents that use chat models instead of LLMs as the agent driver.\n",
    "\n",
    "The main difference here is a different prompt. We will use JSON to encode the agent's actions (chat models are a bit tougher to steet, so using JSON helps to enforce the output format)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6eeb1693",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chat_models import ChatOpenAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "fe846c48",
   "metadata": {},
   "outputs": [],
   "source": [
    "chat_model = ChatOpenAI(temperature=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "0843590d",
   "metadata": {},
   "outputs": [],
   "source": [
    "prompt = hub.pull(\"hwchase17/react-json\")\n",
    "prompt = prompt.partial(\n",
    "    tools=render_text_description(tools),\n",
    "    tool_names=\", \".join([t.name for t in tools]),\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "a863b763",
   "metadata": {},
   "outputs": [],
   "source": [
    "chat_model_with_stop = chat_model.bind(stop=[\"\\nObservation\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "deaeb1f6",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.agents.output_parsers import ReActJsonSingleInputOutputParser"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "6336a378",
   "metadata": {},
   "outputs": [],
   "source": [
    "agent = {\n",
    "    \"input\": lambda x: x[\"input\"],\n",
    "    \"agent_scratchpad\": lambda x: format_log_to_str(x['intermediate_steps'])\n",
    "} | prompt | chat_model_with_stop | ReActJsonSingleInputOutputParser()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "13ad514e",
   "metadata": {},
   "outputs": [],
   "source": [
    "agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3a3394a4",
   "metadata": {},
   "outputs": [],
   "source": [
    "agent_executor.invoke({\"input\": \"Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ffc28e29",
   "metadata": {},
   "source": [
    "We can also use an off-the-shelf agent class"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6c41464c",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "agent = initialize_agent(tools, chat_model, agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION, verbose=True)\n",
    "agent.run(\"Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
