mirror of
https://github.com/hwchase17/langchain.git
synced 2026-01-21 21:56:38 +00:00
Compare commits
9 Commits
replace_ap
...
cc/toolkit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8298c2b86f | ||
|
|
e4b9ac2f2f | ||
|
|
2b70a29854 | ||
|
|
e5048853ed | ||
|
|
1b9d58ba4a | ||
|
|
ae7175d9d4 | ||
|
|
e8f028db84 | ||
|
|
78c6fc8f13 | ||
|
|
ee06992c98 |
787
docs/docs/how_to/agent_toolkits.ipynb
Normal file
787
docs/docs/how_to/agent_toolkits.ipynb
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user