Compare commits

...

9 Commits

Author SHA1 Message Date
Chester Curme
8298c2b86f update 2024-07-26 11:58:21 -04:00
Chester Curme
e4b9ac2f2f add api agent 2024-07-26 11:47:14 -04:00
Chester Curme
2b70a29854 Merge branch 'master' into cc/toolkits 2024-07-26 11:36:01 -04:00
Chester Curme
e5048853ed Merge branch 'master' into cc/toolkits 2024-07-23 11:56:31 -04:00
Chester Curme
1b9d58ba4a add snippet for pandas agent 2024-07-08 10:54:35 -04:00
Chester Curme
ae7175d9d4 Merge branch 'master' into cc/toolkits 2024-07-08 10:02:27 -04:00
Chester Curme
e8f028db84 add to index 2024-06-26 13:05:04 -04:00
Chester Curme
78c6fc8f13 start on doc 2024-06-26 13:03:53 -04:00
Chester Curme
ee06992c98 start 2024-06-25 14:50:15 -04:00
2 changed files with 788 additions and 0 deletions

View File

@@ -0,0 +1,787 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "4d1ede5d-064f-49ee-b6af-98a80bba7b39",
"metadata": {},
"source": [
"# How to use toolkits with agents\n",
"\n",
"LangChain implements a suite of [Tools](/docs/concepts#tools), as well as collections of tools designed to be used together called [Toolkits](/docs/concepts#toolkits). Tools allow LLMs to interact with the world by taking actions and observing results. Common examples include interacting with structured data in a database, searching the web, and interacting with APIs. See [integrations](/docs/integrations/toolkits/) for more examples.\n",
"\n",
"To create an agent and equip it with tools, we generally need three things: (1) a LLM; (2) the tools; and (3) a prompt. These are easily accessible:\n",
"\n",
"1. LangChain implements integrations with most [LLMs](https://python.langchain.com/v0.2/docs/integrations/chat/).\n",
"2. [Tools](/docs/concepts#tools) and [Toolkits](/docs/concepts#toolkits) can be imported from a LangChain library-- typically `langchain-community`. See integrations [here](/docs/integrations/toolkits/).\n",
"3. Prompts can be downloaded from the [LangSmith Hub](https://smith.langchain.com/hub), edited, or entirely customized.\n",
"\n",
"Once we have these three, we can incorporate them into an agent architecture. There are two ways of doing this:\n",
"\n",
"1. (Recommended) [LangGraph](https://langchain-ai.github.io/langgraph/) offers simple pre-built agent architectures, and implements a framework for customizing these architectures;\n",
"2. (Legacy) The [AgentExecutor](/docs/how_to/agent_executor/) class in `langchain` implements a class of agent architectures that can be used as well.\n",
"\n",
"Below, we demonstrate how to equip agents with a selection of common toolkits. We go through one example in-depth (SQL agents), and provide concise snippets that can be easily copy and pasted for the others.\n",
"\n",
"**Note**: This guide requires these dependencies:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5663db50-34c1-4bbb-9021-1645923a0d9f",
"metadata": {},
"outputs": [],
"source": [
"%pip install --upgrade --quiet langchain langchain_community langchainhub langgraph"
]
},
{
"cell_type": "markdown",
"id": "22883252-4c7b-4744-a0e9-52b101a60da9",
"metadata": {},
"source": [
"## ⚠️ Security note ⚠️\n",
"\n",
"There are inherent risks in giving models discretion to execute real-world actions. Take precautions to mitigate these risks:\n",
"\n",
"- Make sure that permissions associated with the tools are narrowly-scoped (e.g., for database operations or API requests);\n",
"- When desired, make use of [human-in-the-loop](https://langchain-ai.github.io/langgraph/how-tos/human_in_the_loop/breakpoints/) workflows."
]
},
{
"cell_type": "markdown",
"id": "e06239ef-174b-423b-a952-106f580cf232",
"metadata": {},
"source": [
"## Example: SQL agent"
]
},
{
"cell_type": "markdown",
"id": "33eb56a9-d997-40c9-9af5-8c08c875a11f",
"metadata": {},
"source": [
"### 1. Select LLM\n",
"\n",
"First we select a LLM. Any LLM supporting [tool calling](/docs/how_to/tool_calling) will suffice."
]
},
{
"cell_type": "markdown",
"id": "6db387f0-a887-427a-83db-0c9a61afdeec",
"metadata": {},
"source": [
"```{=mdx}\n",
"import ChatModelTabs from \"@theme/ChatModelTabs\";\n",
"\n",
"<ChatModelTabs customVarName=\"llm\" />\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "64868c61-9ec8-4e73-a518-9f5cef139662",
"metadata": {},
"outputs": [],
"source": [
"# | output: false\n",
"# | echo: false\n",
"\n",
"from langchain_openai import ChatOpenAI\n",
"\n",
"llm = ChatOpenAI(model=\"gpt-3.5-turbo-0125\", temperature=0)"
]
},
{
"cell_type": "markdown",
"id": "58f8fd77-0fa3-4709-8864-3670ce054b6e",
"metadata": {},
"source": [
"### 2. Load tools\n",
"\n",
"Next we load the tools. What we ultimately need is a list of [BaseTool](https://api.python.langchain.com/en/latest/tools/langchain_core.tools.BaseTool.html) objects. These can be assembled from individual tools. Toolkits also provide conveniences for loading sets of tools. Below we use the [SQLDatabaseToolkit](https://api.python.langchain.com/en/latest/agent_toolkits/langchain_community.agent_toolkits.sql.toolkit.SQLDatabaseToolkit.html) from `langchain-community`.\n",
"\n",
"We will use a local SQLite database in this example. Setup instructions for this database are available in the SQL question-answering tutorial [here](https://python.langchain.com/v0.2/docs/tutorials/sql_qa/#setup)."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "42c406ec-cec4-4e84-aeb9-494acb0f5c52",
"metadata": {},
"outputs": [],
"source": [
"from langchain_community.agent_toolkits import SQLDatabaseToolkit\n",
"from langchain_community.utilities import SQLDatabase\n",
"\n",
"db = SQLDatabase.from_uri(\"sqlite:///Chinook.db\")\n",
"toolkit = SQLDatabaseToolkit(db=db, llm=llm)\n",
"tools = toolkit.get_tools()"
]
},
{
"cell_type": "markdown",
"id": "5707b062-82fa-49b1-89cf-8f34210946a7",
"metadata": {},
"source": [
"### 3. Create prompt\n",
"\n",
"Here we will pull an instructive system message from the [LangSmith Hub](https://smith.langchain.com/hub).\n",
"\n",
"Importantly, prompts may feature parameters that should be specified. We can inspect these parameters via the `.input_variables` attribute of the prompt template:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "266a1008-8927-414c-bed3-a02729c0877a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['dialect', 'top_k']\n",
"================================\u001b[1m System Message \u001b[0m================================\n",
"\n",
"You are an agent designed to interact with a SQL database.\n",
"Given an input question, create a syntactically correct \u001b[33;1m\u001b[1;3m{dialect}\u001b[0m query to run, then look at the results of the query and return the answer.\n",
"Unless the user specifies a specific number of examples they wish to obtain, always limit your query to at most \u001b[33;1m\u001b[1;3m{top_k}\u001b[0m results.\n",
"You can order the results by a relevant column to return the most interesting examples in the database.\n",
"Never query for all the columns from a specific table, only ask for the relevant columns given the question.\n",
"You have access to tools for interacting with the database.\n",
"Only use the below tools. Only use the information returned by the below tools to construct your final answer.\n",
"You MUST double check your query before executing it. If you get an error while executing a query, rewrite the query and try again.\n",
"\n",
"DO NOT make any DML statements (INSERT, UPDATE, DELETE, DROP etc.) to the database.\n",
"\n",
"To start you should ALWAYS look at the tables in the database to see what you can query.\n",
"Do NOT skip this step.\n",
"Then you should query the schema of the most relevant tables.\n"
]
}
],
"source": [
"from langchain import hub\n",
"\n",
"prompt_template = hub.pull(\"langchain-ai/sql-agent-system-prompt\")\n",
"\n",
"assert len(prompt_template.messages) == 1\n",
"print(prompt_template.input_variables)\n",
"prompt_template.messages[0].pretty_print()"
]
},
{
"cell_type": "markdown",
"id": "fbaeddcd-4fa6-4688-bacb-cec79d2b71b3",
"metadata": {},
"source": [
"Here, we should specify the relevant SQL dialect, as well as the row limit for queries. Formatting choices for these parameters creates a string system message for our agent.\n",
"\n",
"These parameters represent common variants for a SQL agent prompt, but you should feel free to edit the entirety of the prompt to tune it to your use-case."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "19bc2cac-6d75-4308-ba07-ba76d6ebb3ca",
"metadata": {},
"outputs": [],
"source": [
"system_message = prompt_template.format(dialect=\"SQLite\", top_k=5)"
]
},
{
"cell_type": "markdown",
"id": "a70400eb-fbc1-4d84-bc27-2a3130ef9021",
"metadata": {},
"source": [
"### Create agent\n",
"\n",
"Finally, we create and run our agent. We demonstrate this with LangGraph and AgentExecutor.\n",
"\n",
"#### Langgraph (recommended)\n",
"\n",
"[LangGraph](https://langchain-ai.github.io/langgraph/) implements a framework for building custom and controllable agents. It offers several advantages, such as built-in persistence, enabling advanced human-in-the-loop and memory features.\n",
"\n",
"LangGraph also includes several pre-built agent architectures. Here, we will create a simple ReAct-style agent:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "29d1cf76-467e-40e3-ac69-6fa17ee91a36",
"metadata": {},
"outputs": [],
"source": [
"from langgraph.prebuilt import create_react_agent\n",
"\n",
"agent_executor = create_react_agent(llm, tools, state_modifier=system_message)"
]
},
{
"cell_type": "markdown",
"id": "9319a61f-5fcb-48bd-8b12-3daf0eef6efa",
"metadata": {},
"source": [
"We can then issue a query to the agent and observe the steps it takes in generating an answer. Note that it calls multiple tools that present available tables and their schemas before finally writing a SQL query."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "789d9e0e-1596-464b-b80c-a9dc6d46bd87",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"================================\u001b[1m Human Message \u001b[0m=================================\n",
"\n",
"Which country's customers spent the most?\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"Tool Calls:\n",
" sql_db_list_tables (call_hqnAveKp3famGpBLqbGlJ8HG)\n",
" Call ID: call_hqnAveKp3famGpBLqbGlJ8HG\n",
" Args:\n",
"=================================\u001b[1m Tool Message \u001b[0m=================================\n",
"Name: sql_db_list_tables\n",
"\n",
"Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"Tool Calls:\n",
" sql_db_schema (call_s4oouN9gi0TYRQbqTIZoaEXA)\n",
" Call ID: call_s4oouN9gi0TYRQbqTIZoaEXA\n",
" Args:\n",
" table_names: Customer, Invoice\n",
"=================================\u001b[1m Tool Message \u001b[0m=================================\n",
"Name: sql_db_schema\n",
"\n",
"\n",
"CREATE TABLE \"Customer\" (\n",
"\t\"CustomerId\" INTEGER NOT NULL, \n",
"\t\"FirstName\" NVARCHAR(40) NOT NULL, \n",
"\t\"LastName\" NVARCHAR(20) NOT NULL, \n",
"\t\"Company\" NVARCHAR(80), \n",
"\t\"Address\" NVARCHAR(70), \n",
"\t\"City\" NVARCHAR(40), \n",
"\t\"State\" NVARCHAR(40), \n",
"\t\"Country\" NVARCHAR(40), \n",
"\t\"PostalCode\" NVARCHAR(10), \n",
"\t\"Phone\" NVARCHAR(24), \n",
"\t\"Fax\" NVARCHAR(24), \n",
"\t\"Email\" NVARCHAR(60) NOT NULL, \n",
"\t\"SupportRepId\" INTEGER, \n",
"\tPRIMARY KEY (\"CustomerId\"), \n",
"\tFOREIGN KEY(\"SupportRepId\") REFERENCES \"Employee\" (\"EmployeeId\")\n",
")\n",
"\n",
"/*\n",
"3 rows from Customer table:\n",
"CustomerId\tFirstName\tLastName\tCompany\tAddress\tCity\tState\tCountry\tPostalCode\tPhone\tFax\tEmail\tSupportRepId\n",
"1\tLuís\tGonçalves\tEmbraer - Empresa Brasileira de Aeronáutica S.A.\tAv. Brigadeiro Faria Lima, 2170\tSão José dos Campos\tSP\tBrazil\t12227-000\t+55 (12) 3923-5555\t+55 (12) 3923-5566\tluisg@embraer.com.br\t3\n",
"2\tLeonie\tKöhler\tNone\tTheodor-Heuss-Straße 34\tStuttgart\tNone\tGermany\t70174\t+49 0711 2842222\tNone\tleonekohler@surfeu.de\t5\n",
"3\tFrançois\tTremblay\tNone\t1498 rue Bélanger\tMontréal\tQC\tCanada\tH2G 1A7\t+1 (514) 721-4711\tNone\tftremblay@gmail.com\t3\n",
"*/\n",
"\n",
"\n",
"CREATE TABLE \"Invoice\" (\n",
"\t\"InvoiceId\" INTEGER NOT NULL, \n",
"\t\"CustomerId\" INTEGER NOT NULL, \n",
"\t\"InvoiceDate\" DATETIME NOT NULL, \n",
"\t\"BillingAddress\" NVARCHAR(70), \n",
"\t\"BillingCity\" NVARCHAR(40), \n",
"\t\"BillingState\" NVARCHAR(40), \n",
"\t\"BillingCountry\" NVARCHAR(40), \n",
"\t\"BillingPostalCode\" NVARCHAR(10), \n",
"\t\"Total\" NUMERIC(10, 2) NOT NULL, \n",
"\tPRIMARY KEY (\"InvoiceId\"), \n",
"\tFOREIGN KEY(\"CustomerId\") REFERENCES \"Customer\" (\"CustomerId\")\n",
")\n",
"\n",
"/*\n",
"3 rows from Invoice table:\n",
"InvoiceId\tCustomerId\tInvoiceDate\tBillingAddress\tBillingCity\tBillingState\tBillingCountry\tBillingPostalCode\tTotal\n",
"1\t2\t2021-01-01 00:00:00\tTheodor-Heuss-Straße 34\tStuttgart\tNone\tGermany\t70174\t1.98\n",
"2\t4\t2021-01-02 00:00:00\tUllevålsveien 14\tOslo\tNone\tNorway\t0171\t3.96\n",
"3\t8\t2021-01-03 00:00:00\tGrétrystraat 63\tBrussels\tNone\tBelgium\t1000\t5.94\n",
"*/\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"Tool Calls:\n",
" sql_db_query (call_Hl8P9DXpfBNUrGbPxnDF6aZ7)\n",
" Call ID: call_Hl8P9DXpfBNUrGbPxnDF6aZ7\n",
" Args:\n",
" query: SELECT c.Country, SUM(i.Total) AS TotalSpent FROM Customer c JOIN Invoice i ON c.CustomerId = i.CustomerId GROUP BY c.Country ORDER BY TotalSpent DESC LIMIT 1\n",
"=================================\u001b[1m Tool Message \u001b[0m=================================\n",
"Name: sql_db_query\n",
"\n",
"[('USA', 523.0600000000003)]\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"Customers from the USA spent the most, with a total amount spent of $523.06.\n"
]
}
],
"source": [
"events = agent_executor.stream(\n",
" {\"messages\": [(\"user\", \"Which country's customers spent the most?\")]},\n",
" stream_mode=\"values\",\n",
")\n",
"for event in events:\n",
" event[\"messages\"][-1].pretty_print()"
]
},
{
"cell_type": "markdown",
"id": "14130bc9-c2f5-4056-9e66-5e56db9424ad",
"metadata": {},
"source": [
"#### AgentExecutor (legacy)\n",
"\n",
"`langchain` includes an [AgentExecutor](/docs/how_to/agent_executor) class that will also enable LLMs to execute tools and observe their results. `AgentExecutor` implements a class of ReAct-style agent architectures in which observations are recorded in a designated section of the prompt called a \"scratchpad\". For this reason, it requires a special prompt template.\n",
"\n",
"We can load this template from the LangSmith Hub and format in our system message from before:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "72fb273e-c44d-4122-b9a5-d9a89deae2cd",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['agent_scratchpad', 'input', 'system_message']\n"
]
}
],
"source": [
"prompt_template = hub.pull(\"langchain-ai/tools-agent\")\n",
"\n",
"print(prompt_template.input_variables)\n",
"\n",
"prompt = prompt_template.partial(system_message=system_message)"
]
},
{
"cell_type": "markdown",
"id": "0307a583-c034-4cc4-b06f-02369bcb04c9",
"metadata": {},
"source": [
"Finally, we create and execute the agent:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "c10133c4-4544-4fed-91ad-a186941a3923",
"metadata": {},
"outputs": [],
"source": [
"from langchain.agents import AgentExecutor, create_tool_calling_agent\n",
"\n",
"agent_executor = AgentExecutor(\n",
" agent=create_tool_calling_agent(llm, tools, prompt),\n",
" tools=tools,\n",
" verbose=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "70927301-d862-4d1b-88ef-3ede6ae26465",
"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\n",
"Invoking: `sql_db_list_tables` with `{}`\n",
"\n",
"\n",
"\u001b[0m\u001b[38;5;200m\u001b[1;3mAlbum, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track\u001b[0m\u001b[32;1m\u001b[1;3m\n",
"Invoking: `sql_db_schema` with `{'table_names': 'Customer, Invoice'}`\n",
"\n",
"\n",
"\u001b[0m\u001b[33;1m\u001b[1;3m\n",
"CREATE TABLE \"Customer\" (\n",
"\t\"CustomerId\" INTEGER NOT NULL, \n",
"\t\"FirstName\" NVARCHAR(40) NOT NULL, \n",
"\t\"LastName\" NVARCHAR(20) NOT NULL, \n",
"\t\"Company\" NVARCHAR(80), \n",
"\t\"Address\" NVARCHAR(70), \n",
"\t\"City\" NVARCHAR(40), \n",
"\t\"State\" NVARCHAR(40), \n",
"\t\"Country\" NVARCHAR(40), \n",
"\t\"PostalCode\" NVARCHAR(10), \n",
"\t\"Phone\" NVARCHAR(24), \n",
"\t\"Fax\" NVARCHAR(24), \n",
"\t\"Email\" NVARCHAR(60) NOT NULL, \n",
"\t\"SupportRepId\" INTEGER, \n",
"\tPRIMARY KEY (\"CustomerId\"), \n",
"\tFOREIGN KEY(\"SupportRepId\") REFERENCES \"Employee\" (\"EmployeeId\")\n",
")\n",
"\n",
"/*\n",
"3 rows from Customer table:\n",
"CustomerId\tFirstName\tLastName\tCompany\tAddress\tCity\tState\tCountry\tPostalCode\tPhone\tFax\tEmail\tSupportRepId\n",
"1\tLuís\tGonçalves\tEmbraer - Empresa Brasileira de Aeronáutica S.A.\tAv. Brigadeiro Faria Lima, 2170\tSão José dos Campos\tSP\tBrazil\t12227-000\t+55 (12) 3923-5555\t+55 (12) 3923-5566\tluisg@embraer.com.br\t3\n",
"2\tLeonie\tKöhler\tNone\tTheodor-Heuss-Straße 34\tStuttgart\tNone\tGermany\t70174\t+49 0711 2842222\tNone\tleonekohler@surfeu.de\t5\n",
"3\tFrançois\tTremblay\tNone\t1498 rue Bélanger\tMontréal\tQC\tCanada\tH2G 1A7\t+1 (514) 721-4711\tNone\tftremblay@gmail.com\t3\n",
"*/\n",
"\n",
"\n",
"CREATE TABLE \"Invoice\" (\n",
"\t\"InvoiceId\" INTEGER NOT NULL, \n",
"\t\"CustomerId\" INTEGER NOT NULL, \n",
"\t\"InvoiceDate\" DATETIME NOT NULL, \n",
"\t\"BillingAddress\" NVARCHAR(70), \n",
"\t\"BillingCity\" NVARCHAR(40), \n",
"\t\"BillingState\" NVARCHAR(40), \n",
"\t\"BillingCountry\" NVARCHAR(40), \n",
"\t\"BillingPostalCode\" NVARCHAR(10), \n",
"\t\"Total\" NUMERIC(10, 2) NOT NULL, \n",
"\tPRIMARY KEY (\"InvoiceId\"), \n",
"\tFOREIGN KEY(\"CustomerId\") REFERENCES \"Customer\" (\"CustomerId\")\n",
")\n",
"\n",
"/*\n",
"3 rows from Invoice table:\n",
"InvoiceId\tCustomerId\tInvoiceDate\tBillingAddress\tBillingCity\tBillingState\tBillingCountry\tBillingPostalCode\tTotal\n",
"1\t2\t2021-01-01 00:00:00\tTheodor-Heuss-Straße 34\tStuttgart\tNone\tGermany\t70174\t1.98\n",
"2\t4\t2021-01-02 00:00:00\tUllevålsveien 14\tOslo\tNone\tNorway\t0171\t3.96\n",
"3\t8\t2021-01-03 00:00:00\tGrétrystraat 63\tBrussels\tNone\tBelgium\t1000\t5.94\n",
"*/\u001b[0m\u001b[32;1m\u001b[1;3m\n",
"Invoking: `sql_db_query` with `{'query': 'SELECT c.Country, SUM(i.Total) AS TotalSpent FROM Customer c JOIN Invoice i ON c.CustomerId = i.CustomerId GROUP BY c.Country ORDER BY TotalSpent DESC LIMIT 1'}`\n",
"\n",
"\n",
"\u001b[0m\u001b[36;1m\u001b[1;3m[('USA', 523.0600000000003)]\u001b[0m\u001b[32;1m\u001b[1;3mCustomers from the USA spent the most, with a total amount spent of $523.06.\u001b[0m\n",
"\n",
"\u001b[1m> Finished chain.\u001b[0m\n"
]
},
{
"data": {
"text/plain": [
"{'input': \"Which country's customers spent the most?\",\n",
" 'output': 'Customers from the USA spent the most, with a total amount spent of $523.06.'}"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"agent_executor.invoke({\"input\": \"Which country's customers spent the most?\"})"
]
},
{
"cell_type": "markdown",
"id": "3b4fe0ba-21c9-4074-aa5f-1731ab488a83",
"metadata": {},
"source": [
"## Example: Pandas agent\n",
"\n",
"\n",
"**⚠️ Security note ⚠️**\n",
"\n",
"This agent relies on access to a python repl tool which can execute\n",
"arbitrary code. This can be dangerous and requires a specially sandboxed\n",
"environment to be safely used. Failure to run this code in a properly\n",
"sandboxed environment can lead to arbitrary code execution vulnerabilities,\n",
"which can lead to data breaches, data loss, or other security incidents.\n",
"\n",
"Do not use this code with untrusted inputs, with elevated permissions,\n",
"or without consulting your security team about proper sandboxing!"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "a58e987e-c281-4fbe-9c42-cbc594624ffc",
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"\n",
"df = pd.DataFrame(\n",
" [\n",
" {\n",
" \"name\": \"The Da Vinci Code\",\n",
" \"type\": \"book\",\n",
" \"price\": 15,\n",
" \"quantity\": 300,\n",
" \"rating\": 4,\n",
" },\n",
" {\n",
" \"name\": \"Jurassic Park\",\n",
" \"type\": \"book\",\n",
" \"price\": 12,\n",
" \"quantity\": 400,\n",
" \"rating\": 4.5,\n",
" },\n",
" {\n",
" \"name\": \"Jurassic Park\",\n",
" \"type\": \"film\",\n",
" \"price\": 8,\n",
" \"quantity\": 6,\n",
" \"rating\": 5,\n",
" },\n",
" {\"name\": \"Matilda\", \"type\": \"book\", \"price\": 5, \"quantity\": 80, \"rating\": 4},\n",
" {\n",
" \"name\": \"Clockwork Orange\",\n",
" \"type\": None,\n",
" \"price\": None,\n",
" \"quantity\": 20,\n",
" \"rating\": 4,\n",
" },\n",
" {\"name\": \"Walden\", \"type\": None, \"price\": None, \"quantity\": 100, \"rating\": 4.5},\n",
" ],\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "77941324-8efb-49f7-a53c-015c68fff477",
"metadata": {},
"outputs": [],
"source": [
"from langchain import hub\n",
"from langchain_experimental.tools.python.tool import PythonAstREPLTool\n",
"from langgraph.prebuilt import create_react_agent\n",
"\n",
"# Prompt\n",
"prompt_template = hub.pull(\"langchain-ai/pandas-agent-system-prompt\")\n",
"system_message = prompt_template.format(df_head=df.head())\n",
"\n",
"# Tools\n",
"tools = [PythonAstREPLTool(locals={\"df\": df})]\n",
"\n",
"agent_executor = create_react_agent(llm, tools, state_modifier=system_message)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "40c8504f-816d-4bd6-9949-a80315fcedae",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"================================\u001b[1m Human Message \u001b[0m=================================\n",
"\n",
"What is the average quantity of books with rating 4?\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"Tool Calls:\n",
" python_repl_ast (call_4UdfdfbQAKU3NtISwPBJisdH)\n",
" Call ID: call_4UdfdfbQAKU3NtISwPBJisdH\n",
" Args:\n",
" query: df[(df['type']=='book') & (df['rating']==4)]['quantity'].mean()\n",
"=================================\u001b[1m Tool Message \u001b[0m=================================\n",
"Name: python_repl_ast\n",
"\n",
"190.0\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"The average quantity of books with a rating of 4 is 190.\n"
]
}
],
"source": [
"events = agent_executor.stream(\n",
" {\"messages\": [(\"user\", \"What is the average quantity of books with rating 4?\")]},\n",
" stream_mode=\"values\",\n",
")\n",
"for event in events:\n",
" event[\"messages\"][-1].pretty_print()"
]
},
{
"cell_type": "markdown",
"id": "c7fdb885-39db-438b-a2a8-e7e60c411169",
"metadata": {},
"source": [
"## Example: API agent"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "29be4caa-e792-40c7-8a3e-d070f50f3e73",
"metadata": {},
"outputs": [],
"source": [
"openapi_api_spec = \"\"\"openapi: 3.0.0\n",
"info:\n",
" title: JSONPlaceholder API\n",
" version: 1.0.0\n",
"servers:\n",
"- url: https://jsonplaceholder.typicode.com\n",
"paths:\n",
" /posts:\n",
" get:\n",
" summary: Get posts\n",
" parameters: &id001\n",
" - name: _limit\n",
" in: query\n",
" required: false\n",
" schema:\n",
" type: integer\n",
" example: 2\n",
" description: Limit the number of results\n",
" responses:\n",
" '200':\n",
" description: Successful response\n",
" content:\n",
" application/json:\n",
" schema:\n",
" type: object\n",
" properties:\n",
" userId: int\n",
" id: int\n",
" title: str\n",
" body: str\n",
" /comments:\n",
" get:\n",
" summary: Get comments\n",
" parameters: *id001\n",
" responses:\n",
" '200':\n",
" description: Successful response\n",
" content:\n",
" application/json:\n",
" schema:\n",
" type: object\n",
" properties:\n",
" postId: int\n",
" id: int\n",
" name: str\n",
" email: str\n",
" body: str\n",
"\"\"\""
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "cc55107c-4315-4d1b-ae5e-4bbcea7beec4",
"metadata": {},
"outputs": [],
"source": [
"from langchain import hub\n",
"from langchain_community.agent_toolkits.openapi.toolkit import RequestsToolkit\n",
"from langchain_community.utilities.requests import TextRequestsWrapper\n",
"from langgraph.prebuilt import create_react_agent\n",
"\n",
"# Prompt\n",
"prompt_template = hub.pull(\"langchain-ai/api-agent-system-prompt\")\n",
"system_message = prompt_template.format(api_spec=openapi_api_spec)\n",
"\n",
"\n",
"# Tools\n",
"toolkit = RequestsToolkit(\n",
" requests_wrapper=TextRequestsWrapper(headers={}),\n",
" allow_dangerous_requests=True,\n",
")\n",
"tools = toolkit.get_tools()\n",
"\n",
"agent_executor = create_react_agent(llm, tools, state_modifier=system_message)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "d8d8c86e-3b4f-4668-83d0-4343e2597ccd",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"================================\u001b[1m Human Message \u001b[0m=================================\n",
"\n",
"What are the titles of the top two posts?\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"Tool Calls:\n",
" requests_get (call_oxSvNxEMiyEgG82mAZd316Bn)\n",
" Call ID: call_oxSvNxEMiyEgG82mAZd316Bn\n",
" Args:\n",
" url: https://jsonplaceholder.typicode.com/posts?_limit=2\n",
"=================================\u001b[1m Tool Message \u001b[0m=================================\n",
"Name: requests_get\n",
"\n",
"[\n",
" {\n",
" \"userId\": 1,\n",
" \"id\": 1,\n",
" \"title\": \"sunt aut facere repellat provident occaecati excepturi optio reprehenderit\",\n",
" \"body\": \"quia et suscipit\\nsuscipit recusandae consequuntur expedita et cum\\nreprehenderit molestiae ut ut quas totam\\nnostrum rerum est autem sunt rem eveniet architecto\"\n",
" },\n",
" {\n",
" \"userId\": 1,\n",
" \"id\": 2,\n",
" \"title\": \"qui est esse\",\n",
" \"body\": \"est rerum tempore vitae\\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\\nqui aperiam non debitis possimus qui neque nisi nulla\"\n",
" }\n",
"]\n",
"==================================\u001b[1m Ai Message \u001b[0m==================================\n",
"\n",
"The titles of the top two posts are:\n",
"1. \"sunt aut facere repellat provident occaecati excepturi optio reprehenderit\"\n",
"2. \"qui est esse\"\n"
]
}
],
"source": [
"events = agent_executor.stream(\n",
" {\"messages\": [(\"user\", \"What are the titles of the top two posts?\")]},\n",
" stream_mode=\"values\",\n",
")\n",
"for event in events:\n",
" event[\"messages\"][-1].pretty_print()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a1e41357-0876-4178-8d38-194a35f65c1c",
"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.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -218,6 +218,7 @@ For in depth how-to guides for agents, please check out [LangGraph](https://lang
- [How to: use legacy LangChain Agents (AgentExecutor)](/docs/how_to/agent_executor)
- [How to: migrate from legacy LangChain agents to LangGraph](/docs/how_to/migrate_agent)
- [How to: use toolkits with agents](/docs/how_to/agent_toolkits)
### Callbacks