From cd6ba4272c5aec61162c22b3f17aa1e64313674d Mon Sep 17 00:00:00 2001 From: Karen Javadyan Date: Thu, 28 Mar 2024 23:22:27 +0400 Subject: [PATCH] add optional DuckDuckGo tool use --- langgraph_example.ipynb | 137 ++++++++-------------------------------- rag_example.ipynb | 35 ++-------- 2 files changed, 34 insertions(+), 138 deletions(-) diff --git a/langgraph_example.ipynb b/langgraph_example.ipynb index e70dbd4..3bb77a0 100644 --- a/langgraph_example.ipynb +++ b/langgraph_example.ipynb @@ -16,11 +16,12 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from langchain_community.tools.tavily_search import TavilySearchResults\n", + "# from langchain_community.tools.ddg_search import DuckDuckGoSearchRun\n", "from langchain.agents import tool\n", "\n", "\n", @@ -36,26 +37,31 @@ ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ - "Add visualization for possible tools" + "from langgraph.prebuilt import ToolExecutor\n", + "\n", + "tool_executor = ToolExecutor(tools)" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "from langgraph.prebuilt import ToolExecutor\n", + "from langchain_community.tools.tavily_search import TavilySearchResults\n", + "my_tool = TavilySearchResults()\n", "\n", - "tool_executor = ToolExecutor(tools)" + "my_tool.run(\"Current president of Argentina\")" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -66,7 +72,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -77,24 +83,16 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'name': 'tavily_search_results_json', 'description': 'A search engine optimized for comprehensive, accurate, and trusted results. Useful for when you need to answer questions about current events. Input should be a search query.', 'parameters': {'type': 'object', 'properties': {'query': {'description': 'search query to look up', 'type': 'string'}}, 'required': ['query']}}\n" - ] - } - ], + "outputs": [], "source": [ - "print(functions[0])" + "print(functions[1])" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -103,7 +101,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -158,7 +156,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -207,35 +205,19 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'messages': [HumanMessage(content='Who is the current president of the Argentina, at March 2024? Please reverse the name'),\n", - " AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"current president of Argentina March 2024\"}', 'name': 'tavily_search_results_json'}}, response_metadata={'token_usage': {'completion_tokens': 25, 'prompt_tokens': 131, 'total_tokens': 156}, 'model_name': 'gpt-4-1106-preview', 'system_fingerprint': 'fp_123d5a9f90', 'finish_reason': 'function_call', 'logprobs': None}),\n", - " FunctionMessage(content='[{\\'url\\': \\'https://english.elpais.com/international/2024-03-19/freedom-and-poverty-in-argentina-mileis-100-frenetic-days-in-power-and-an-unprecedented-economic-experiment.html\\', \\'content\\': \\'Javier Milei came to power last December, in an Argentina worn down by successive crises.With the promise of ending the slow decline of the South American country and turning it into a world power again, the president announced that he was going to deregulate all sectors of the economy, privatize public companies, lower taxes, replace the peso with the dollar and shutter the Central Bank.\\'}, {\\'url\\': \\'https://www.reuters.com/world/americas/argentinas-milei-send-new-reform-bills-congress-2024-03-02/\\', \\'content\\': \"Item 1 of 5 Argentina\\'s President Javier Milei gestures as he attends the opening session of the 142nd legislative term, at the National Congress, in Buenos Aires, Argentina, March 1, 2024.\"}]', name='tavily_search_results_json'),\n", - " AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"text\":\"Javier Milei\"}', 'name': 'reverse_text'}}, response_metadata={'token_usage': {'completion_tokens': 17, 'prompt_tokens': 385, 'total_tokens': 402}, 'model_name': 'gpt-4-1106-preview', 'system_fingerprint': 'fp_99a5a401bb', 'finish_reason': 'function_call', 'logprobs': None}),\n", - " FunctionMessage(content='ieliM reivaJ', name='reverse_text'),\n", - " AIMessage(content='The current president of Argentina as of March 2024 is Javier Milei, and his name reversed is ieliM reivaJ.', response_metadata={'token_usage': {'completion_tokens': 29, 'prompt_tokens': 416, 'total_tokens': 445}, 'model_name': 'gpt-4-1106-preview', 'system_fingerprint': 'fp_123d5a9f90', 'finish_reason': 'stop', 'logprobs': None})]}" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from langchain_core.messages import HumanMessage\n", "\n", - "inputs = {\"messages\": [HumanMessage(content=\"Who is the current president of the Argentina, at March 2024? Please reverse the name\")]}\n", + "inputs = {\"messages\": [HumanMessage(content=\"Who is the current president of Argentina, at March 2024? Please reverse the name\")]}\n", "app.invoke(inputs)" ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -246,20 +228,9 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'The current president of Argentina as of March 2024 is Javier Milei, and his name reversed is ieliM reivaJ.'" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from langchain_core.runnables import RunnableLambda\n", "\n", @@ -272,65 +243,13 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "ename": "FileNotFoundError", - "evalue": "No such file or directory: ' +-----------+ \n | __start__ | \n +-----------+ \n * \n * \n * \n +-------+ \n | agent | \n *+-------+* \n ** *** \n ** ** \n ** ** \n+-----------------------+ ** \n| agent_should_continue | * \n+-----------------------+ * \n * ***** * \n * **** * \n * *** * \n +---------+ +--------+ \n | __end__ | | action | \n +---------+ +--------+ '", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "File \u001b[0;32m~/projects/PyData-March-Langchain/venv/lib/python3.11/site-packages/IPython/core/display.py:1045\u001b[0m, in \u001b[0;36mImage._data_and_metadata\u001b[0;34m(self, always_both)\u001b[0m\n\u001b[1;32m 1044\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m-> 1045\u001b[0m b64_data \u001b[38;5;241m=\u001b[39m \u001b[43mb2a_base64\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnewline\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[38;5;241m.\u001b[39mdecode(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mascii\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 1046\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n", - "\u001b[0;31mTypeError\u001b[0m: a bytes-like object is required, not 'str'", - "\nThe above exception was the direct cause of the following exception:\n", - "\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)", - "File \u001b[0;32m~/projects/PyData-March-Langchain/venv/lib/python3.11/site-packages/IPython/core/formatters.py:977\u001b[0m, in \u001b[0;36mMimeBundleFormatter.__call__\u001b[0;34m(self, obj, include, exclude)\u001b[0m\n\u001b[1;32m 974\u001b[0m method \u001b[38;5;241m=\u001b[39m get_real_method(obj, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprint_method)\n\u001b[1;32m 976\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m method \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 977\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mmethod\u001b[49m\u001b[43m(\u001b[49m\u001b[43minclude\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minclude\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mexclude\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mexclude\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 978\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m 979\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n", - "File \u001b[0;32m~/projects/PyData-March-Langchain/venv/lib/python3.11/site-packages/IPython/core/display.py:1035\u001b[0m, in \u001b[0;36mImage._repr_mimebundle_\u001b[0;34m(self, include, exclude)\u001b[0m\n\u001b[1;32m 1033\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39membed:\n\u001b[1;32m 1034\u001b[0m mimetype \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_mimetype\n\u001b[0;32m-> 1035\u001b[0m data, metadata \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_data_and_metadata\u001b[49m\u001b[43m(\u001b[49m\u001b[43malways_both\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[1;32m 1036\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m metadata:\n\u001b[1;32m 1037\u001b[0m metadata \u001b[38;5;241m=\u001b[39m {mimetype: metadata}\n", - "File \u001b[0;32m~/projects/PyData-March-Langchain/venv/lib/python3.11/site-packages/IPython/core/display.py:1047\u001b[0m, in \u001b[0;36mImage._data_and_metadata\u001b[0;34m(self, always_both)\u001b[0m\n\u001b[1;32m 1045\u001b[0m b64_data \u001b[38;5;241m=\u001b[39m b2a_base64(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdata, newline\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m)\u001b[38;5;241m.\u001b[39mdecode(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mascii\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 1046\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m-> 1047\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mFileNotFoundError\u001b[39;00m(\n\u001b[1;32m 1048\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNo such file or directory: \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;241m%\u001b[39m (\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdata)) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01me\u001b[39;00m\n\u001b[1;32m 1049\u001b[0m md \u001b[38;5;241m=\u001b[39m {}\n\u001b[1;32m 1050\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmetadata:\n", - "\u001b[0;31mFileNotFoundError\u001b[0m: No such file or directory: ' +-----------+ \n | __start__ | \n +-----------+ \n * \n * \n * \n +-------+ \n | agent | \n *+-------+* \n ** *** \n ** ** \n ** ** \n+-----------------------+ ** \n| agent_should_continue | * \n+-----------------------+ * \n * ***** * \n * **** * \n * *** * \n +---------+ +--------+ \n | __end__ | | action | \n +---------+ +--------+ '" - ] - }, - { - "ename": "FileNotFoundError", - "evalue": "No such file or directory: ' +-----------+ \n | __start__ | \n +-----------+ \n * \n * \n * \n +-------+ \n | agent | \n *+-------+* \n ** *** \n ** ** \n ** ** \n+-----------------------+ ** \n| agent_should_continue | * \n+-----------------------+ * \n * ***** * \n * **** * \n * *** * \n +---------+ +--------+ \n | __end__ | | action | \n +---------+ +--------+ '", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "File \u001b[0;32m~/projects/PyData-March-Langchain/venv/lib/python3.11/site-packages/IPython/core/display.py:1045\u001b[0m, in \u001b[0;36mImage._data_and_metadata\u001b[0;34m(self, always_both)\u001b[0m\n\u001b[1;32m 1044\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m-> 1045\u001b[0m b64_data \u001b[38;5;241m=\u001b[39m \u001b[43mb2a_base64\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnewline\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[38;5;241m.\u001b[39mdecode(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mascii\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 1046\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n", - "\u001b[0;31mTypeError\u001b[0m: a bytes-like object is required, not 'str'", - "\nThe above exception was the direct cause of the following exception:\n", - "\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)", - "File \u001b[0;32m~/projects/PyData-March-Langchain/venv/lib/python3.11/site-packages/IPython/core/formatters.py:347\u001b[0m, in \u001b[0;36mBaseFormatter.__call__\u001b[0;34m(self, obj)\u001b[0m\n\u001b[1;32m 345\u001b[0m method \u001b[38;5;241m=\u001b[39m get_real_method(obj, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprint_method)\n\u001b[1;32m 346\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m method \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 347\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mmethod\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 348\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m 349\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n", - "File \u001b[0;32m~/projects/PyData-March-Langchain/venv/lib/python3.11/site-packages/IPython/core/display.py:1067\u001b[0m, in \u001b[0;36mImage._repr_png_\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1065\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_repr_png_\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[1;32m 1066\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39membed \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mformat \u001b[38;5;241m==\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_FMT_PNG:\n\u001b[0;32m-> 1067\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_data_and_metadata\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/projects/PyData-March-Langchain/venv/lib/python3.11/site-packages/IPython/core/display.py:1047\u001b[0m, in \u001b[0;36mImage._data_and_metadata\u001b[0;34m(self, always_both)\u001b[0m\n\u001b[1;32m 1045\u001b[0m b64_data \u001b[38;5;241m=\u001b[39m b2a_base64(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdata, newline\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m)\u001b[38;5;241m.\u001b[39mdecode(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mascii\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 1046\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m-> 1047\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mFileNotFoundError\u001b[39;00m(\n\u001b[1;32m 1048\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNo such file or directory: \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;241m%\u001b[39m (\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdata)) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01me\u001b[39;00m\n\u001b[1;32m 1049\u001b[0m md \u001b[38;5;241m=\u001b[39m {}\n\u001b[1;32m 1050\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmetadata:\n", - "\u001b[0;31mFileNotFoundError\u001b[0m: No such file or directory: ' +-----------+ \n | __start__ | \n +-----------+ \n * \n * \n * \n +-------+ \n | agent | \n *+-------+* \n ** *** \n ** ** \n ** ** \n+-----------------------+ ** \n| agent_should_continue | * \n+-----------------------+ * \n * ***** * \n * **** * \n * *** * \n +---------+ +--------+ \n | __end__ | | action | \n +---------+ +--------+ '" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "from IPython.display import Image\n", "Image(app.get_graph().draw_png())" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/rag_example.ipynb b/rag_example.ipynb index 0402a83..31e58ce 100644 --- a/rag_example.ipynb +++ b/rag_example.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -27,21 +27,9 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Document(page_content='Bears like to eat honey'),\n", - " Document(page_content='Habet works at AUA')]" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "retriever = vectorstore.as_retriever(search_kwargs={\"k\": 2})\n", "retriever.invoke(\"Who likes to eat honey?\")" @@ -49,7 +37,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -77,20 +65,9 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Habet works at AUA.'" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "chain.invoke(\"where Habet is working?\")" ]