From 4fa237d86230c4fbbb477d838657a55ab36d9703 Mon Sep 17 00:00:00 2001 From: Matt Dancho Date: Tue, 31 Dec 2024 11:25:19 -0500 Subject: [PATCH] sql agent tutorial --- .../agents/data_cleaning_agent.py | 2 + .../agents/data_wrangling_agent.py | 2 + .../agents/feature_engineering_agent.py | 2 + .../agents/sql_database_agent.py | 3 +- examples/sql_database_agent.ipynb | 704 ++++++++++++++++++ 5 files changed, 712 insertions(+), 1 deletion(-) create mode 100644 examples/sql_database_agent.ipynb diff --git a/ai_data_science_team/agents/data_cleaning_agent.py b/ai_data_science_team/agents/data_cleaning_agent.py index fff5112..45908cd 100644 --- a/ai_data_science_team/agents/data_cleaning_agent.py +++ b/ai_data_science_team/agents/data_cleaning_agent.py @@ -201,6 +201,8 @@ def recommend_cleaning_steps(state: GraphState): } def create_data_cleaner_code(state: GraphState): + if bypass_recommended_steps: + print("---DATA CLEANING AGENT----") print(" * CREATE DATA CLEANER CODE") data_cleaning_prompt = PromptTemplate( diff --git a/ai_data_science_team/agents/data_wrangling_agent.py b/ai_data_science_team/agents/data_wrangling_agent.py index 7263906..6e17102 100644 --- a/ai_data_science_team/agents/data_wrangling_agent.py +++ b/ai_data_science_team/agents/data_wrangling_agent.py @@ -194,6 +194,8 @@ def recommend_wrangling_steps(state: GraphState): def create_data_wrangler_code(state: GraphState): + if bypass_recommended_steps: + print("---DATA WRANGLING AGENT----") print(" * CREATE DATA WRANGLER CODE") data_wrangling_prompt = PromptTemplate( diff --git a/ai_data_science_team/agents/feature_engineering_agent.py b/ai_data_science_team/agents/feature_engineering_agent.py index 570d86c..d0df800 100644 --- a/ai_data_science_team/agents/feature_engineering_agent.py +++ b/ai_data_science_team/agents/feature_engineering_agent.py @@ -216,6 +216,8 @@ def human_review(state: GraphState) -> Command[Literal["recommend_feature_engine ) def create_feature_engineering_code(state: GraphState): + if bypass_recommended_steps: + print("---FEATURE ENGINEERING AGENT----") print(" * CREATE FEATURE ENGINEERING CODE") feature_engineering_prompt = PromptTemplate( diff --git a/ai_data_science_team/agents/sql_database_agent.py b/ai_data_science_team/agents/sql_database_agent.py index b5c161f..9610dec 100644 --- a/ai_data_science_team/agents/sql_database_agent.py +++ b/ai_data_science_team/agents/sql_database_agent.py @@ -182,7 +182,8 @@ def recommend_sql_steps(state: GraphState): } def create_sql_query_code(state: GraphState): - + if bypass_recommended_steps: + print("---SQL DATABASE AGENT---") print(" * CREATE SQL QUERY CODE") # Prompt to get the SQL code from the LLM diff --git a/examples/sql_database_agent.ipynb b/examples/sql_database_agent.ipynb new file mode 100644 index 0000000..12773ac --- /dev/null +++ b/examples/sql_database_agent.ipynb @@ -0,0 +1,704 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# How to Automate SQL Database Queries with AI\n", + "\n", + "### Free Generative AI Data Science Workshop\n", + "\n", + "If you want to learn how to build AI Agents that perform Data Science, Business Intelligence, Churn Modeling, Time Series Forecasting, and more, [register for my next free AI for Data Scientists workshop here.](https://learn.business-science.io/ai-register)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "vscode": { + "languageId": "bat" + } + }, + "source": [ + "# Table of Contents\n", + "\n", + "1. [Introduction](#introduction)\n", + "2. [Load Libraries](#load-libraries)\n", + "3. [Setup AI and Logging](#setup-ai-and-logging)\n", + "4. [Connect to a SQL Database](#connect-to-a-sql-database)\n", + "5. [Create The Agent](#create-the-agent)\n", + "6. [Run the Agent](#run-the-agent)\n", + "7. [Response](#response)\n", + " 1. [SQL Query Code](#sql-query-code)\n", + " 2. [Pandas Data Frame From SQL Query](#pandas-data-frame-from-sql-query)\n", + " 3. [Python Pipeline Function](#python-pipeline-function)\n", + " 4. [Storage Location](#storage-location)\n", + "8. [Free Generative AI Data Science Workshop](#free-generative-ai-data-science-workshop)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Load Libraries" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# * Libraries\n", + "\n", + "from langchain_openai import ChatOpenAI\n", + "\n", + "import pandas as pd\n", + "import sqlalchemy as sql\n", + "\n", + "import os\n", + "import yaml\n", + "from pprint import pprint\n", + "\n", + "from ai_data_science_team.agents import make_sql_database_agent" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Setup AI and Logging\n", + "\n", + "This section of code sets up the LLM inputs and the logging information. Logging is used to store AI-generated code and files during the AI Data Science Teams processing of files. \n", + "\n", + "*Important Note:* This example uses OpenAI's API. But any LLM can be used such as Anthropic or local LLMs with Ollama." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ChatOpenAI(client=, async_client=, root_client=, root_async_client=, model_name='gpt-4o-mini', model_kwargs={}, openai_api_key=SecretStr('**********'))" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# * Setup\n", + "\n", + "MODEL = \"gpt-4o-mini\"\n", + "LOG = True\n", + "LOG_PATH = os.path.join(os.getcwd(), \"logs/\")\n", + "\n", + "os.environ[\"OPENAI_API_KEY\"] = yaml.safe_load(open('../credentials.yml'))['openai']\n", + "\n", + "llm = ChatOpenAI(model = MODEL)\n", + "\n", + "llm\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Connect to a SQL Database\n", + "\n", + "Next, let's connect to the leads data from a SQL database. We will need to use a `sqlalchemy` connection to use the SQL Database Agent." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sql_engine = sql.create_engine(\"sqlite:///data/leads_scored.db\")\n", + "\n", + "conn = sql_engine.connect()\n", + "\n", + "conn" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create The Agent\n", + "\n", + "Run this code to create the agent with `make_sql_database_agent()`.\n", + "\n", + "The only required parameters are `model` and `connection`. \n", + "\n", + "- `model` is the LLM model that you want to use.\n", + "- `connection` is the sqlalchemy connection to the SQL database.\n", + "\n", + "Other parameters that I've included in this demo are:\n", + "\n", + "- `log`: Set up logging the SQL DB agent's pipeline function\n", + "- `log_path`: The directory to save the SQL DB agent's pipeline function\n", + "- `bypass_explain_code`: Dynamically bypass the explain code step in the LangGraph DAG. This is useful to speed up response time when you don't need to see the explain code.\n", + "- `bypass_recommended_steps`: Dynamically bypass the recommended steps in the LangGraph DAG. This is useful to speed up response time when you don't need to see the recommended steps." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Create the agent\n", + "sql_agent = make_sql_database_agent(\n", + " model = llm, \n", + " connection=conn, \n", + " log=LOG, \n", + " log_path=LOG_PATH,\n", + " bypass_explain_code=True,\n", + " bypass_recommended_steps=True,\n", + ")\n", + "\n", + "sql_agent" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run the Agent" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The main inputs to the SQL DB Agent are:\n", + "\n", + "- **user_instructions**: What actions you'd like to take on the SQL database query. \n", + "- **max_retries**: Used to limit the number of attempts to fix the SQL and Python code generated by the agent. Set this to 3 to limit to 3 attempts. \n", + "- **retry_count**: Set this to 0. " + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "---SQL DATABASE AGENT---\n", + " * CREATE SQL QUERY CODE\n", + " * CREATE PYTHON FUNCTION TO RUN SQL CODE\n", + " File saved to: /Users/mdancho/Desktop/course_code/ai-data-science-team/logs/sql_database.py\n", + " * EXECUTING AGENT CODE ON SQL CONNECTION\n" + ] + } + ], + "source": [ + "\n", + "response = sql_agent.invoke({\n", + " \"user_instructions\": \"Aggregate the product transactions by Product Description. Use suggested price and a quantity of 1 to approximate sales.\",\n", + " \"max_retries\":3, \n", + " \"retry_count\":0\n", + "})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Response\n", + "\n", + "The response produced contains everything we need to understand the data cleaning decisions made and get the cleaned dataset. " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['messages',\n", + " 'user_instructions',\n", + " 'data_sql',\n", + " 'sql_query_code',\n", + " 'sql_database_function',\n", + " 'sql_database_function_path',\n", + " 'sql_database_function_name',\n", + " 'sql_database_error',\n", + " 'max_retries',\n", + " 'retry_count']" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(response.keys())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### SQL Query Code" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('SELECT p.description, \\n'\n", + " ' SUM(p.suggested_price) AS total_sales\\n'\n", + " 'FROM products p\\n'\n", + " 'JOIN transactions t ON p.product_id = t.product_id\\n'\n", + " 'GROUP BY p.description;')\n" + ] + } + ], + "source": [ + "pprint(response['sql_query_code'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Pandas Data Frame From SQL Query" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
descriptiontotal_sales
04-Course Bundle - Machine Learning + Expert We...95216.666667
14-Course Bundle - Machine Learning + Expert We...4858.333333
24-Course Bundle - Machine Learning + Expert We...222500.000000
35 Course Bundle - Machine Learning + Web Apps ...1650.000000
45 Course Bundle - Machine Learning + Web Apps ...5638.888889
55 Course Bundle - Machine Learning + Web Apps ...2625.000000
65 Course Bundle - Machine Learning + Web Apps ...114000.000000
7Bundle - DS For Business + Web Apps (Level 1):...25666.666667
8Bundle - DS For Business + Web Apps (Level 1):...1600.000000
9Bundle - DS For Business + Web Apps (Level 1):...11825.000000
10Bundle - DS For Business + Web Apps (Level 1):...57000.000000
11Bundle - Data Science Starter Kit: R-Track - C...2600.000000
12Bundle - Machine Learning For Business: R-Trac...6066.666667
13Bundle - Machine Learning For Business: R-Trac...50600.000000
14DS4B 101-R: Business Analysis With R - 3 Low M...9200.000000
15DS4B 101-R: Business Analysis With R - 6 Low M...4700.000000
16DS4B 101-R: Business Analysis With R - Monthly...2600.000000
17DS4B 101-R: Business Analysis With R - Paid Co...43200.000000
18DS4B 101-R: Business Analysis With R - Single ...73200.000000
19DS4B 102-R: Shiny Web Applications (Intermedia...6200.000000
20DS4B 102-R: Shiny Web Applications (Intermedia...60000.000000
21DS4B 201-R: Data Science For Business With R -...2400.000000
22DS4B 201-R: Data Science For Business With R -...1500.000000
23DS4B 201-R: Data Science For Business With R -...7000.000000
24DS4B 201-R: Data Science For Business With R -...12600.000000
25DS4B 201-R: Data Science For Business With R -...88900.000000
26DS4B 201-R: Data Science For Business With R -...35000.000000
27DS4B 202A-R: Shiny Developer with AWS - 6 Low ...4650.000000
28DS4B 202A-R: Shiny Developer with AWS - Paid C...89600.000000
29DS4B 203-R: High-Performance Time Series Forec...2000.000000
30DS4B 203-R: High-Performance Time Series Forec...6716.666667
31DS4B 203-R: High-Performance Time Series Forec...112000.000000
32Jumpstart with R - Get Jumpstarted!225.000000
33Learning Labs Pro - 6-month Payment Option1200.000000
34Learning Labs Pro - Low Monthly Payments10290.000000
35Learning Labs Pro - Paid Course105644.000000
36Learning Labs Pro - Subscribe to LL PRO 6-Mont...975.000000
37Learning Labs Pro - Subscribe to LL PRO Annual...9000.000000
38Learning Labs Pro - Subscribe to LL PRO Monthl...5341.000000
39Learning Labs Pro - Yearly Membership14400.000000
40Learning Labs Pro - Yearly Plan90000.000000
\n", + "
" + ], + "text/plain": [ + " description total_sales\n", + "0 4-Course Bundle - Machine Learning + Expert We... 95216.666667\n", + "1 4-Course Bundle - Machine Learning + Expert We... 4858.333333\n", + "2 4-Course Bundle - Machine Learning + Expert We... 222500.000000\n", + "3 5 Course Bundle - Machine Learning + Web Apps ... 1650.000000\n", + "4 5 Course Bundle - Machine Learning + Web Apps ... 5638.888889\n", + "5 5 Course Bundle - Machine Learning + Web Apps ... 2625.000000\n", + "6 5 Course Bundle - Machine Learning + Web Apps ... 114000.000000\n", + "7 Bundle - DS For Business + Web Apps (Level 1):... 25666.666667\n", + "8 Bundle - DS For Business + Web Apps (Level 1):... 1600.000000\n", + "9 Bundle - DS For Business + Web Apps (Level 1):... 11825.000000\n", + "10 Bundle - DS For Business + Web Apps (Level 1):... 57000.000000\n", + "11 Bundle - Data Science Starter Kit: R-Track - C... 2600.000000\n", + "12 Bundle - Machine Learning For Business: R-Trac... 6066.666667\n", + "13 Bundle - Machine Learning For Business: R-Trac... 50600.000000\n", + "14 DS4B 101-R: Business Analysis With R - 3 Low M... 9200.000000\n", + "15 DS4B 101-R: Business Analysis With R - 6 Low M... 4700.000000\n", + "16 DS4B 101-R: Business Analysis With R - Monthly... 2600.000000\n", + "17 DS4B 101-R: Business Analysis With R - Paid Co... 43200.000000\n", + "18 DS4B 101-R: Business Analysis With R - Single ... 73200.000000\n", + "19 DS4B 102-R: Shiny Web Applications (Intermedia... 6200.000000\n", + "20 DS4B 102-R: Shiny Web Applications (Intermedia... 60000.000000\n", + "21 DS4B 201-R: Data Science For Business With R -... 2400.000000\n", + "22 DS4B 201-R: Data Science For Business With R -... 1500.000000\n", + "23 DS4B 201-R: Data Science For Business With R -... 7000.000000\n", + "24 DS4B 201-R: Data Science For Business With R -... 12600.000000\n", + "25 DS4B 201-R: Data Science For Business With R -... 88900.000000\n", + "26 DS4B 201-R: Data Science For Business With R -... 35000.000000\n", + "27 DS4B 202A-R: Shiny Developer with AWS - 6 Low ... 4650.000000\n", + "28 DS4B 202A-R: Shiny Developer with AWS - Paid C... 89600.000000\n", + "29 DS4B 203-R: High-Performance Time Series Forec... 2000.000000\n", + "30 DS4B 203-R: High-Performance Time Series Forec... 6716.666667\n", + "31 DS4B 203-R: High-Performance Time Series Forec... 112000.000000\n", + "32 Jumpstart with R - Get Jumpstarted! 225.000000\n", + "33 Learning Labs Pro - 6-month Payment Option 1200.000000\n", + "34 Learning Labs Pro - Low Monthly Payments 10290.000000\n", + "35 Learning Labs Pro - Paid Course 105644.000000\n", + "36 Learning Labs Pro - Subscribe to LL PRO 6-Mont... 975.000000\n", + "37 Learning Labs Pro - Subscribe to LL PRO Annual... 9000.000000\n", + "38 Learning Labs Pro - Subscribe to LL PRO Monthl... 5341.000000\n", + "39 Learning Labs Pro - Yearly Membership 14400.000000\n", + "40 Learning Labs Pro - Yearly Plan 90000.000000" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.DataFrame(response['data_sql'])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Python Pipeline Function" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('# Disclaimer: This function was generated by AI. Please review before '\n", + " 'using.\\n'\n", + " '# Agent Name: sql_database_agent\\n'\n", + " '# Time Created: 2024-12-31 11:20:18\\n'\n", + " '\\n'\n", + " '\\n'\n", + " 'def sql_database_pipeline(connection):\\n'\n", + " ' import pandas as pd\\n'\n", + " ' import sqlalchemy as sql\\n'\n", + " ' \\n'\n", + " ' # Create a connection if needed\\n'\n", + " ' is_engine = isinstance(connection, sql.engine.base.Engine)\\n'\n", + " ' conn = connection.connect() if is_engine else connection\\n'\n", + " '\\n'\n", + " \" sql_query = '''\\n\"\n", + " ' SELECT p.description, \\n'\n", + " ' SUM(p.suggested_price) AS total_sales\\n'\n", + " 'FROM products p\\n'\n", + " 'JOIN transactions t ON p.product_id = t.product_id\\n'\n", + " 'GROUP BY p.description;\\n'\n", + " \" '''\\n\"\n", + " ' \\n'\n", + " ' return pd.read_sql(sql_query, connection)\\n'\n", + " ' ')\n" + ] + } + ], + "source": [ + "pprint(response['sql_database_function'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Storage location if you logged the pipeline function." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/Users/mdancho/Desktop/course_code/ai-data-science-team/logs/sql_database.py\n" + ] + } + ], + "source": [ + "print(response['sql_database_function_path'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Free Generative AI Data Science Workshop\n", + "\n", + "If you want to learn how to build AI Agents that perform Data Science, Business Intelligence, Churn Modeling, Time Series Forecasting, and more, [register for my next free AI for Data Scientists workshop here.](https://learn.business-science.io/ai-register)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "ds4b_301p_dev", + "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.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}