commit 31ff30496f2a0a23b65c3e164c2f5dd4b2b641f9 Author: Stephen Chu Date: Fri Jan 23 09:22:47 2026 -0800 Initial commit: SQL Support Bot Starter Simple starter code for building a customer support agent using LangGraph Studio. Co-Authored-By: Claude Opus 4.5 diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..e229a10 --- /dev/null +++ b/.env.example @@ -0,0 +1,10 @@ +# API Keys +OPENAI_API_KEY=your_openai_key_here + +# Optional: LangSmith tracing +LANGSMITH_API_KEY=your_langsmith_key_here +LANGCHAIN_TRACING_V2=true +LANGCHAIN_PROJECT=music-support-bot + +# Optional: Model override +MODEL=gpt-4o diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea7406c --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +.env +__pycache__/ +*.pyc +*.pyo +*.pyd +.Python +*.so +*.egg +*.egg-info/ +dist/ +build/ +.venv/ +venv/ +venv_*/ +.DS_Store +*.db-journal +.vscode/ +.idea/ +.langgraph_api/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..ec03d35 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +# Music Store Customer Support Bot - Starter Code + +Simple starter code for building a customer support agent for the Chinook music store database using `create_agent()`. + +## Setup + +```bash +# 1. Install dependencies +pip install -r requirements.txt +pip install langgraph-cli + +# 2. Add your API key to .env +# Edit OPENAI_API_KEY in the .env file + +# 3. Run Studio +langgraph dev +``` + +This opens LangGraph Studio in your browser where you can chat with the agent. +The Chinook database is loaded automatically from GitHub on startup. + +## Project Structure + +``` +take_home/ +├── README.md +├── langgraph.json # LangGraph Studio configuration +├── requirements.txt # Python dependencies +├── .env # Environment variables (add your API keys here) +├── .env.example # Template +└── src/ + ├── agent.py # Agent definition using create_agent() + ├── db.py # Database connection (loads from GitHub) + └── tools/ + ├── customer_tools.py # get_customer_orders tool + └── music_tools.py # list_tracks_by_artist tool +``` + +## Capabilities + +The agent can: +1. **Order history** - View recent orders for a customer +2. **Browse music** - List tracks by artist name + +## Database + +The Chinook database is a sample music store database loaded automatically from GitHub. Tables include: +- **Customer** - Customer information +- **Invoice** - Purchase orders +- **InvoiceLine** - Items in each order +- **Track** - Music tracks +- **Album** - Albums containing tracks +- **Artist** - Artists who created albums +- **Genre** - Music genres diff --git a/langgraph.json b/langgraph.json new file mode 100644 index 0000000..9c5ee0e --- /dev/null +++ b/langgraph.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://langchain-ai.github.io/langgraph/schemas/langgraph.json", + "graphs": { + "agent": "./src/agent.py:build_agent" + }, + "env": ".env", + "dependencies": ["./requirements.txt"] +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..79d81ee --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +langchain-core>=0.3.28 +langchain>=0.3.14 +langgraph>=1.0.0 +langsmith>=0.3.0 +langchain-openai>=0.3.0 +python-dotenv>=1.0.0 +requests>=2.31.0 diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/agent.py b/src/agent.py new file mode 100644 index 0000000..b8daa45 --- /dev/null +++ b/src/agent.py @@ -0,0 +1,45 @@ +""" +Music Store Customer Support Bot - Simple 2-Tool Agent + +Uses create_agent() with minimal tools for simplicity. +""" +import os +from langchain_openai import ChatOpenAI +from langchain.agents import create_agent +from src.tools.customer_tools import get_customer_orders +from src.tools.music_tools import list_tracks_by_artist + +# Model configuration +DEFAULT_MODEL = os.getenv("MODEL", "gpt-4o") + + +# System prompt for the agent +SYSTEM_PROMPT = """You are a helpful customer support agent for a music store. + +You can help customers with: +1. Viewing their order history +2. Browsing tracks by artist + +Important: +- Always ask for the customer ID when they want to view orders +- Use the provided tools to query the database +- Be friendly, helpful, and professional +- For questions outside these capabilities, politely explain what you can help with""" + + +def build_agent(): + """Build the customer support agent with 2 simple tools.""" + model = ChatOpenAI(model=DEFAULT_MODEL, temperature=0) + + tools = [ + get_customer_orders, # View order history + list_tracks_by_artist # Browse tracks by artist + ] + + agent = create_agent( + model=model, + tools=tools, + system_prompt=SYSTEM_PROMPT + ) + + return agent diff --git a/src/db.py b/src/db.py new file mode 100644 index 0000000..0948a0e --- /dev/null +++ b/src/db.py @@ -0,0 +1,12 @@ +"""Chinook database connection. Loads from GitHub into memory on import.""" + +import sqlite3 +import requests + +_conn = sqlite3.connect(":memory:", check_same_thread=False) +_conn.executescript(requests.get("https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sql").text) + + +def execute_query(query: str) -> list[tuple]: + """Execute a query and return results.""" + return _conn.execute(query).fetchall() diff --git a/src/tools/__init__.py b/src/tools/__init__.py new file mode 100644 index 0000000..a0c1ef2 --- /dev/null +++ b/src/tools/__init__.py @@ -0,0 +1 @@ +"""Tools for the music store support bot.""" diff --git a/src/tools/customer_tools.py b/src/tools/customer_tools.py new file mode 100644 index 0000000..b222605 --- /dev/null +++ b/src/tools/customer_tools.py @@ -0,0 +1,13 @@ +from langchain_core.tools import tool +from src.db import execute_query + + +@tool +def get_customer_orders(customer_id: str) -> list[dict]: + """Get recent orders for a customer by their ID.""" + rows = execute_query(f""" + SELECT InvoiceId, InvoiceDate, Total + FROM Invoice WHERE CustomerId = {customer_id} + ORDER BY InvoiceDate DESC LIMIT 10 + """) + return [{"invoice_id": r[0], "date": r[1], "total": r[2]} for r in rows] diff --git a/src/tools/music_tools.py b/src/tools/music_tools.py new file mode 100644 index 0000000..96d835a --- /dev/null +++ b/src/tools/music_tools.py @@ -0,0 +1,16 @@ +from langchain_core.tools import tool +from src.db import execute_query + + +@tool +def list_tracks_by_artist(artist_name: str) -> list[dict]: + """List tracks by an artist (partial name match supported).""" + rows = execute_query(f""" + SELECT t.Name, al.Title, ar.Name + FROM Track t + JOIN Album al ON t.AlbumId = al.AlbumId + JOIN Artist ar ON al.ArtistId = ar.ArtistId + WHERE ar.Name LIKE '%{artist_name}%' + ORDER BY al.Title, t.Name LIMIT 20 + """) + return [{"track": r[0], "album": r[1], "artist": r[2]} for r in rows]