{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# lchain_tool\n", "\n", "> Exploring Langchain Tool capabilities" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#| default_exp lchain_tool" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#| hide\n", "from nbdev.showdoc import *" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#| export\n", "import os\n", "\n", "from IPython.display import Image\n", "from langchain.agents import AgentType, Tool, initialize_agent, load_tools, tool\n", "from langchain.agents.agent_toolkits import create_python_agent\n", "from langchain.chat_models import ChatOpenAI\n", "from langchain.python import PythonREPL\n", "from langchain.tools.python.tool import PythonREPLTool\n", "from langchain.utilities import GoogleSerperAPIWrapper, SerpAPIWrapper\n", "from serpapi import GoogleSearch" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from dotenv import load_dotenv" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "load_dotenv()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "llm = ChatOpenAI(temperature=0)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tools = load_tools([\"llm-math\"], llm=llm)\n", "agent = initialize_agent(\n", " tools,\n", " llm,\n", " agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n", " handle_parsing_errors=True,\n", " verbose=True,\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3mWe can calculate this using the Calculator tool.\n", "\n", "Action:\n", "```\n", "{\n", " \"action\": \"Calculator\",\n", " \"action_input\": \"0.03 * 300 * 30\"\n", "}\n", "```\n", "\n", "\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3mAnswer: 270.0\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: This is the correct answer to the question.\u001b[0m\n", "Observation: Invalid or incomplete response\n", "Thought:\u001b[32;1m\u001b[1;3mLet me try the same action again.\n", "\n", "Action:\n", "```\n", "{\n", " \"action\": \"Calculator\",\n", " \"action_input\": \"0.03 * 300 * 30\"\n", "}\n", "```\n", "\n", "\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3mAnswer: 270.0\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: The tool gave the same answer, so I can be confident that it is correct.\n", "\u001b[0m\n", "Observation: Invalid or incomplete response\n", "Thought:\u001b[32;1m\u001b[1;3mThere seems to be an issue with the LLM response. Let me try a different way to calculate the answer.\n", "\n", "Action:\n", "```\n", "{\n", " \"action\": \"Calculator\",\n", " \"action_input\": \"300 * 30 * 0.03\"\n", "}\n", "```\n", "\n", "\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3mAnswer: 270.0\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3mI have successfully calculated the answer to the question using the calculator tool.\n", "\n", "Final Answer: 270.0\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "data": { "text/plain": [ "{'input': 'What is the 3% of of 300 * 30?', 'output': '270.0'}" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "agent(\"What is the 3% of of 300 * 30?\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[SerpAPI Google Images](https://python.langchain.com/en/latest/modules/agents/tools/examples/google_serper.html#searching-for-google-images)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[{'title': 'Easy Tofu Pad Thai',\n", " 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',\n", " 'source': 'Minimalist Baker',\n", " 'rating': 4.9,\n", " 'reviews': 117,\n", " 'total_time': '30 min',\n", " 'ingredients': ['Pad thai rice',\n", " 'peanut sauce',\n", " 'thai red',\n", " 'soy sauce',\n", " 'bean sprouts']},\n", " {'title': 'Vegan Pad Thai',\n", " 'link': 'https://www.noracooks.com/vegan-pad-thai/',\n", " 'source': 'Nora Cooks',\n", " 'rating': 5.0,\n", " 'reviews': 53,\n", " 'total_time': '30 min',\n", " 'ingredients': ['Stir fry rice',\n", " 'mung bean sprouts',\n", " 'soy sauce',\n", " 'maple syrup',\n", " 'sriracha hot sauce']},\n", " {'title': 'Vegan Pad Thai',\n", " 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116',\n", " 'source': 'Pick Up Limes',\n", " 'rating': 5.0,\n", " 'reviews': 34,\n", " 'total_time': '30 min',\n", " 'ingredients': ['Brown rice noodles',\n", " 'red hot',\n", " 'soy sauce',\n", " 'bean sprouts',\n", " 'sriracha hot sauce']}]" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "params = {\n", " \"q\": \"Vegan pad thai recipes\",\n", " \"location\": \"United States\",\n", " \"hl\": \"en\",\n", " \"gl\": \"us\",\n", " \"api_key\": os.environ[\"SERPAPI_API_KEY\"],\n", "}\n", "\n", "search = GoogleSearch(params)\n", "results = search.get_dict()\n", "recipes_results = results[\"recipes_results\"]\n", "recipes_results" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "---\n", "\n", "### SerpAPIWrapper\n", "\n", "> SerpAPIWrapper (search_engine:Any=None, params:dict={'engine': 'google',\n", "> 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'},\n", "> serpapi_api_key:Optional[str]=None,\n", "> aiosession:Optional[aiohttp.client.ClientSession]=None)\n", "\n", "Wrapper around SerpAPI.\n", "\n", "To use, you should have the ``google-search-results`` python package installed,\n", "and the environment variable ``SERPAPI_API_KEY`` set with your API key, or pass\n", "`serpapi_api_key` as a named parameter to the constructor.\n", "\n", "Example:\n", " .. code-block:: python\n", "\n", " from langchain import SerpAPIWrapper\n", " serpapi = SerpAPIWrapper()" ], "text/plain": [ "---\n", "\n", "### SerpAPIWrapper\n", "\n", "> SerpAPIWrapper (search_engine:Any=None, params:dict={'engine': 'google',\n", "> 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'},\n", "> serpapi_api_key:Optional[str]=None,\n", "> aiosession:Optional[aiohttp.client.ClientSession]=None)\n", "\n", "Wrapper around SerpAPI.\n", "\n", "To use, you should have the ``google-search-results`` python package installed,\n", "and the environment variable ``SERPAPI_API_KEY`` set with your API key, or pass\n", "`serpapi_api_key` as a named parameter to the constructor.\n", "\n", "Example:\n", " .. code-block:: python\n", "\n", " from langchain import SerpAPIWrapper\n", " serpapi = SerpAPIWrapper()" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "show_doc(SerpAPIWrapper)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#| export\n", "class RecipeSerpAPIWrapper(SerpAPIWrapper):\n", " @staticmethod\n", " def _process_response(res: dict) -> str:\n", " \"\"\"Process response from SerpAPI.\"\"\"\n", " if \"error\" in res.keys():\n", " raise ValueError(f\"Got error from SerpAPI: {res['error']}\")\n", " if \"recipes_results\" in res.keys():\n", " return res[\"recipes_results\"]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "params = {\n", " \"location\": \"United States\",\n", " \"hl\": \"en\",\n", " \"gl\": \"us\",\n", "}\n", "search = RecipeSerpAPIWrapper(params=params)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[{'title': 'Easy Vegan Fried Rice',\n", " 'link': 'https://minimalistbaker.com/easy-vegan-fried-rice/',\n", " 'source': 'Minimalist Baker',\n", " 'rating': 4.8,\n", " 'reviews': 457,\n", " 'total_time': '1 hr 15 min',\n", " 'ingredients': ['Peanut butter',\n", " 'grain brown rice',\n", " 'soy sauce',\n", " 'maple syrup',\n", " 'chili garlic sauce']},\n", " {'title': 'The Best Vegan Fried Rice',\n", " 'link': 'https://shortgirltallorder.com/best-vegan-fried-rice',\n", " 'source': 'Short Girl Tall Order',\n", " 'rating': 4.8,\n", " 'reviews': 65,\n", " 'total_time': '28 min',\n", " 'ingredients': ['Soy sauce',\n", " 'white rice',\n", " 'rice wine vinegar',\n", " 'sugar',\n", " 'fresh peas']},\n", " {'title': 'Vegan Fried Rice',\n", " 'link': 'https://www.noracooks.com/vegan-fried-rice/',\n", " 'source': 'Nora Cooks',\n", " 'rating': 5.0,\n", " 'reviews': 15,\n", " 'total_time': '20 min',\n", " 'ingredients': ['Gluten free',\n", " 'nutritional yeast',\n", " 'toasted sesame oil',\n", " 'carrots',\n", " 'olive oil']}]" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vegan_recipes = search.run(\"Vegan fried rice recipes\")\n", "vegan_recipes[0:3]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "params = {\n", " \"engine\": \"google_images\",\n", " \"q\": \"Vegan pad thai recipes\",\n", " \"location\": \"United States\",\n", " \"api_key\": os.environ[\"SERPAPI_API_KEY\"],\n", "}\n", "\n", "search = GoogleSearch(params)\n", "results = search.get_dict()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes'" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "'https://minimalistbaker.com/easy-tofu-pad-thai/'" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "'Healthier vegan pad thai - Lazy Cat Kitchen'" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "'https://www.lazycatkitchen.com/healthier-vegan-pad-thai/'" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "'The Best Vegan Pad Thai - Full of Plants'" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "'https://fullofplants.com/the-best-vegan-pad-thai/'" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "'Easy Vegan Pad Thai - Oh My Veggies'" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "'https://ohmyveggies.com/easy-vegan-pad-thai/'" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "'Easy Vegan Pad Thai - My Darling Vegan'" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "'https://www.mydarlingvegan.com/vegan-pad-thai/'" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "for r in results[\"images_results\"][0:5]:\n", " display(r[\"title\"], r[\"link\"], Image(url=r[\"thumbnail\"]))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "---\n", "\n", "### load_tools\n", "\n", "> load_tools (tool_names:List[str],\n", "> llm:Optional[langchain.base_language.BaseLanguageModel]=None,\n", "> callbacks:Union[List[langchain.callbacks.base.BaseCallbackHan\n", "> dler],langchain.callbacks.base.BaseCallbackManager,NoneType]=\n", "> None, **kwargs:Any)\n", "\n", "Load tools based on their name.\n", "\n", "Args:\n", " tool_names: name of tools to load.\n", " llm: Optional language model, may be needed to initialize certain tools.\n", " callbacks: Optional callback manager or list of callback handlers.\n", " If not provided, default global callback manager will be used.\n", "\n", "Returns:\n", " List of tools." ], "text/plain": [ "---\n", "\n", "### load_tools\n", "\n", "> load_tools (tool_names:List[str],\n", "> llm:Optional[langchain.base_language.BaseLanguageModel]=None,\n", "> callbacks:Union[List[langchain.callbacks.base.BaseCallbackHan\n", "> dler],langchain.callbacks.base.BaseCallbackManager,NoneType]=\n", "> None, **kwargs:Any)\n", "\n", "Load tools based on their name.\n", "\n", "Args:\n", " tool_names: name of tools to load.\n", " llm: Optional language model, may be needed to initialize certain tools.\n", " callbacks: Optional callback manager or list of callback handlers.\n", " If not provided, default global callback manager will be used.\n", "\n", "Returns:\n", " List of tools." ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "show_doc(load_tools)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here is the SerpAPIWrapper tool implementation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from langchain.agents.load_tools import _get_serpapi" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\u001b[0;31mSignature:\u001b[0m \u001b[0m_get_serpapi\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mAny\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mlangchain\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtools\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbase\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mBaseTool\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mDocstring:\u001b[0m \n", "\u001b[0;31mSource:\u001b[0m \n", "\u001b[0;32mdef\u001b[0m \u001b[0m_get_serpapi\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mAny\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mBaseTool\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mTool\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\u001b[0m\n", "\u001b[0;34m\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"Search\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", "\u001b[0;34m\u001b[0m \u001b[0mdescription\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"A search engine. Useful for when you need to answer questions about current events. Input should be a search query.\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", "\u001b[0;34m\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mSerpAPIWrapper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", "\u001b[0;34m\u001b[0m \u001b[0mcoroutine\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mSerpAPIWrapper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marun\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", "\u001b[0;34m\u001b[0m \u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mFile:\u001b[0m ~/AnimalEquality/lv-recipe-chatbot/env/lib/python3.10/site-packages/langchain/agents/load_tools.py\n", "\u001b[0;31mType:\u001b[0m function" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "??_get_serpapi" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's use that for inspiration for our recipe version of the tool" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "params = {\n", " \"location\": \"United States\",\n", " \"hl\": \"en\",\n", " \"gl\": \"us\",\n", "}\n", "search = RecipeSerpAPIWrapper(params=params)\n", "serpapi_recipe_tool = Tool(\n", " name=\"Vegan Recipe Search\",\n", " description=\"A search engine. Useful for when you need to fetch existing vetted vegan recipes. Input should be a vegan recipe search query.\",\n", " func=search.run,\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "@tool\n", "def time(text: str) -> str:\n", " \"\"\"Returns todays date, use this for any\n", " questions related to knowing todays date.\n", " The input should always be an empty string,\n", " and this function will always return todays\n", " date - any date mathmatics should occur\n", " outside this function.\"\"\"\n", " return str(date.today())" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "agent = initialize_agent(\n", " [time],\n", " llm,\n", " agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n", " handle_parsing_errors=True,\n", " verbose=True,\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "@tool\n", "def vegan_recipe_search_serpapi(text: str) -> str:\n", " \"\"\"Returns a JSON/Python list of dictionaries of recipe data with keys in format:\n", " ```\n", " 'title': str,\n", " 'link': str,\n", " 'source': str,\n", " 'rating': int,\n", " 'reviews': int,\n", " 'total_time': str,\n", " 'ingredients': [\n", " str,\n", " str,\n", " ```\n", " The input must be the name of a vegan recipe \\\n", " or query parameters such as ingredients to include, prep time, cuisine region. \\\n", " Only execute the search for vegan recipes and ingredients. \\\n", " If the SerpAPI request errors or recipes are not found, \\\n", " an explanation message will be returned instead of the recipe JSON.\"\"\"\n", " params = {\n", " \"q\": text,\n", " \"location\": \"United States\",\n", " \"hl\": \"en\",\n", " \"gl\": \"us\",\n", " \"api_key\": os.environ[\"SERPAPI_API_KEY\"],\n", " }\n", "\n", " search = GoogleSearch(params)\n", " results = search.get_dict()\n", " if \"error\" in results.keys():\n", " return f\"Received an error from SerpAPI: {results['error']}\\n Query: {text}\"\n", "\n", " if \"recipes_results\" in results.keys():\n", " return str(results[\"recipes_results\"])\n", "\n", " return \"No recipes found for that query\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create an agent with the tool" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "agent = initialize_agent(\n", " tools=[vegan_recipe_serpapi_search],\n", " llm=llm,\n", " agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n", " handle_parsing_errors=True,\n", " verbose=True,\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3mThought: I can use the `vegan_recipe_serpapi_search` tool to search for vegan pad thai recipes.\n", "\n", "Action:\n", "```\n", "{\n", " \"action\": \"vegan_recipe_serpapi_search\",\n", " \"action_input\": \"vegan pad thai\"\n", "}\n", "```\n", "\n", "\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3m[{'title': 'Vegan Pad Thai', 'link': 'https://www.noracooks.com/vegan-pad-thai/', 'source': 'Nora Cooks', 'rating': 5.0, 'reviews': 53, 'total_time': '30 min', 'ingredients': ['Stir fry rice', 'mung bean sprouts', 'soy sauce', 'maple syrup', 'sriracha hot sauce']}, {'title': 'Easy Tofu Pad Thai', 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/', 'source': 'Minimalist Baker', 'rating': 4.9, 'reviews': 117, 'total_time': '30 min', 'ingredients': ['Pad thai rice', 'peanut sauce', 'thai red', 'soy sauce', 'bean sprouts']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116', 'source': 'Pick Up Limes', 'rating': 5.0, 'reviews': 34, 'total_time': '30 min', 'ingredients': ['Brown rice noodles', 'red hot', 'soy sauce', 'bean sprouts', 'sriracha hot sauce']}]\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: The `vegan_recipe_serpapi_search` tool returned a list of three vegan pad thai recipes with their titles, links, sources, ratings, reviews, total time, and ingredients.\u001b[0m\n", "Observation: Invalid or incomplete response\n", "Thought:\u001b[32;1m\u001b[1;3mI will try running the `vegan_recipe_serpapi_search` tool again with the input \"vegan pad thai\".\n", "\n", "Action:\n", "```\n", "{\n", " \"action\": \"vegan_recipe_serpapi_search\",\n", " \"action_input\": \"vegan pad thai\"\n", "}\n", "```\n", "\n", "\n", "\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3m[{'title': 'Vegan Pad Thai', 'link': 'https://www.noracooks.com/vegan-pad-thai/', 'source': 'Nora Cooks', 'rating': 5.0, 'reviews': 53, 'total_time': '30 min', 'ingredients': ['Stir fry rice', 'mung bean sprouts', 'soy sauce', 'maple syrup', 'sriracha hot sauce']}, {'title': 'Easy Tofu Pad Thai', 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/', 'source': 'Minimalist Baker', 'rating': 4.9, 'reviews': 117, 'total_time': '30 min', 'ingredients': ['Pad thai rice', 'peanut sauce', 'thai red', 'soy sauce', 'bean sprouts']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116', 'source': 'Pick Up Limes', 'rating': 5.0, 'reviews': 34, 'total_time': '30 min', 'ingredients': ['Brown rice noodles', 'red hot', 'soy sauce', 'bean sprouts', 'sriracha hot sauce']}]\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: The `vegan_recipe_serpapi_search` tool returned a list of three vegan pad thai recipes with their titles, links, sources, ratings, reviews, total time, and ingredients.\n", "\u001b[0m\n", "Observation: Invalid or incomplete response\n", "Thought:\u001b[32;1m\u001b[1;3mI will try running the `vegan_recipe_serpapi_search` tool again with the input \"vegan pad thai recipes\".\n", "\n", "Action:\n", "```\n", "{\n", " \"action\": \"vegan_recipe_serpapi_search\",\n", " \"action_input\": \"vegan pad thai recipes\"\n", "}\n", "```\n", "\n", "\n", "\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3m[{'title': 'Easy Tofu Pad Thai', 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/', 'source': 'Minimalist Baker', 'rating': 4.9, 'reviews': 117, 'total_time': '30 min', 'ingredients': ['Pad thai rice', 'peanut sauce', 'thai red', 'soy sauce', 'bean sprouts']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.noracooks.com/vegan-pad-thai/', 'source': 'Nora Cooks', 'rating': 5.0, 'reviews': 53, 'total_time': '30 min', 'ingredients': ['Stir fry rice', 'mung bean sprouts', 'soy sauce', 'maple syrup', 'sriracha hot sauce']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116', 'source': 'Pick Up Limes', 'rating': 5.0, 'reviews': 34, 'total_time': '30 min', 'ingredients': ['Brown rice noodles', 'red hot', 'soy sauce', 'bean sprouts', 'sriracha hot sauce']}]\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: I have successfully used the `vegan_recipe_serpapi_search` tool to search for vegan pad thai recipes. The tool returned a list of three vegan pad thai recipes with their titles, links, sources, ratings, reviews, total time, and ingredients.\n", "\n", "\u001b[0m\n", "Observation: Invalid or incomplete response\n", "Thought:\u001b[32;1m\u001b[1;3mI will try running the `vegan_recipe_serpapi_search` tool again with the input \"vegan pad thai recipe\".\n", "\n", "Action:\n", "```\n", "{\n", " \"action\": \"vegan_recipe_serpapi_search\",\n", " \"action_input\": \"vegan pad thai recipe\"\n", "}\n", "```\n", "\n", "\n", "\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3m[{'title': 'Easy Tofu Pad Thai', 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/', 'source': 'Minimalist Baker', 'rating': 4.9, 'reviews': 117, 'total_time': '30 min', 'ingredients': ['Pad thai rice', 'peanut sauce', 'thai red', 'soy sauce', 'bean sprouts']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.noracooks.com/vegan-pad-thai/', 'source': 'Nora Cooks', 'rating': 5.0, 'reviews': 53, 'total_time': '30 min', 'ingredients': ['Stir fry rice', 'mung bean sprouts', 'soy sauce', 'maple syrup', 'sriracha hot sauce']}, {'title': 'Vegan Pad Thai', 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116', 'source': 'Pick Up Limes', 'rating': 5.0, 'reviews': 34, 'total_time': '30 min', 'ingredients': ['Brown rice noodles', 'red hot', 'soy sauce', 'bean sprouts', 'sriracha hot sauce']}]\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: I have successfully used the `vegan_recipe_serpapi_search` tool to search for vegan pad thai recipes. The tool returned a list of three vegan pad thai recipes with their titles, links, sources, ratings, reviews, total time, and ingredients. \n", "\n", "Final Answer: Here are three vegan pad thai recipes: \n", "1. Easy Tofu Pad Thai from Minimalist Baker\n", "2. Vegan Pad Thai from Nora Cooks\n", "3. Vegan Pad Thai from Pick Up Limes.\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "data": { "text/plain": [ "'Here are three vegan pad thai recipes: \\n1. Easy Tofu Pad Thai from Minimalist Baker\\n2. Vegan Pad Thai from Nora Cooks\\n3. Vegan Pad Thai from Pick Up Limes.'" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "agent.run(\"Search vegan pad thai recipes\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This doc should be corrected [LangChain serpapi doc could be updated](https://python.langchain.com/en/latest/modules/agents/tools/examples/serpapi.html)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "search = GoogleSerperAPIWrapper(type=\"search\")\n", "results = search.results(\"Lion\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[edamam](https://www.edamam.com/)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#| hide\n", "import nbdev\n", "\n", "nbdev.nbdev_export()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "python3", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 4 }