{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e89f490d",
   "metadata": {},
   "source": [
    "# Agents\n",
    "\n",
    "You can pass a Runnable into an agent."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "af4381de",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.agents import XMLAgent, tool, AgentExecutor\n",
    "from langchain.chat_models import ChatAnthropic"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "24cc8134",
   "metadata": {},
   "outputs": [],
   "source": [
    "model = ChatAnthropic(model=\"claude-2\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "67c0b0e4",
   "metadata": {},
   "outputs": [],
   "source": [
    "@tool\n",
    "def search(query: str) -> str:\n",
    "    \"\"\"Search things about current events.\"\"\"\n",
    "    return \"32 degrees\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "7203b101",
   "metadata": {},
   "outputs": [],
   "source": [
    "tool_list = [search]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "b68e756d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get prompt to use\n",
    "prompt = XMLAgent.get_default_prompt()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "61ab3e9a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Logic for going from intermediate steps to a string to pass into model\n",
    "# This is pretty tied to the prompt\n",
    "def convert_intermediate_steps(intermediate_steps):\n",
    "    log = \"\"\n",
    "    for action, observation in intermediate_steps:\n",
    "        log += (\n",
    "            f\"<tool>{action.tool}</tool><tool_input>{action.tool_input}\"\n",
    "            f\"</tool_input><observation>{observation}</observation>\"\n",
    "        )\n",
    "    return log\n",
    "\n",
    "\n",
    "# Logic for converting tools to string to go in prompt\n",
    "def convert_tools(tools):\n",
    "    return \"\\n\".join([f\"{tool.name}: {tool.description}\" for tool in tools])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "260f5988",
   "metadata": {},
   "source": [
    "Building an agent from a runnable usually involves a few things:\n",
    "\n",
    "1. Data processing for the intermediate steps. These need to represented in a way that the language model can recognize them. This should be pretty tightly coupled to the instructions in the prompt\n",
    "\n",
    "2. The prompt itself\n",
    "\n",
    "3. The model, complete with stop tokens if needed\n",
    "\n",
    "4. The output parser - should be in sync with how the prompt specifies things to be formatted."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "e92f1d6f",
   "metadata": {},
   "outputs": [],
   "source": [
    "agent = (\n",
    "    {\n",
    "        \"question\": lambda x: x[\"question\"],\n",
    "        \"intermediate_steps\": lambda x: convert_intermediate_steps(x[\"intermediate_steps\"])\n",
    "    }\n",
    "    | prompt.partial(tools=convert_tools(tool_list))\n",
    "    | model.bind(stop=[\"</tool_input>\", \"</final_answer>\"])\n",
    "    | XMLAgent.get_default_output_parser()\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "6ce6ec7a",
   "metadata": {},
   "outputs": [],
   "source": [
    "agent_executor = AgentExecutor(agent=agent, tools=tool_list, verbose=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "fb5cb2e3",
   "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 <tool>search</tool>\n",
      "<tool_input>weather in new york\u001b[0m\u001b[36;1m\u001b[1;3m32 degrees\u001b[0m\u001b[32;1m\u001b[1;3m\n",
      "\n",
      "<final_answer>The weather in New York is 32 degrees\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'question': 'whats the weather in New york?',\n",
       " 'output': 'The weather in New York is 32 degrees'}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent_executor.invoke({\"question\": \"whats the weather in New york?\"})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bce86dd8",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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
}
