{
"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": [
"#| eval:false\n",
"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": [
"#| eval: false\n",
"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": [
"#| eval: false\n",
"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": [
"#| eval: false\n",
"vegan_recipes = search.run(\"Vegan fried rice recipes\")\n",
"vegan_recipes[0:3]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#| eval: false\n",
"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": [
"#| eval: false\n",
"\n",
"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_serpapi_search(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": [
"#| eval: false\n",
"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": [
"#| eval: false\n",
"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
}