Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions python/llm/agents/agent-mastery-course/.env.example.labs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# API keys for the Agent Mastery Course labs
# Get these free accounts before starting:
# Arize: https://app.arize.com (observe traces)
# OpenAI: https://platform.openai.com/api-keys
# Tavily: https://auth.tavily.com (web search)

ARIZE_SPACE_ID=
ARIZE_API_KEY=
OPENAI_API_KEY=
TAVILY_API_KEY=
16 changes: 16 additions & 0 deletions python/llm/agents/agent-mastery-course/Dockerfile.labs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM python:3.11-slim

RUN pip install --no-cache-dir jupyterlab

COPY requirements-labs.txt /tmp/requirements-labs.txt
RUN pip install --no-cache-dir -r /tmp/requirements-labs.txt

WORKDIR /workspace

COPY labs/ /workspace/labs/
COPY lab-entrypoint.sh /lab-entrypoint.sh
RUN chmod +x /lab-entrypoint.sh

EXPOSE 8888

ENTRYPOINT ["/lab-entrypoint.sh"]
182 changes: 128 additions & 54 deletions python/llm/agents/agent-mastery-course/README.md
Original file line number Diff line number Diff line change
@@ -1,72 +1,146 @@
# AI Trip Planner
# AI Trip Planner — Agent Mastery Course

Fast, sequential trip planning with FastAPI (backend), React (frontend), and LangGraph for orchestration. Optional Arize tracing is supported.
This repo has two things:

1. **Agent Mastery Course labs** (start here) — Jupyter notebooks that build an AI travel agent step by step using the [Agno](https://github.com/agno-agi/agno) framework, with tracing on [Arize](https://app.arize.com).
2. **Trip Planner app** (optional) — A FastAPI + LangGraph backend with a minimal UI, RAG, and MCP demos.

---

## Quickstart

1) Requirements
- Python 3.10+ (Docker optional)
### 1. Prerequisites

- [Docker](https://docs.docker.com/get-docker/)

### 2. Get API keys (free)

You need 3 free accounts — the labs will prompt you for these keys:

2) Configure environment
- Copy `backend/env_example.txt` to `backend/.env`.
- Set one LLM key: `OPENAI_API_KEY=...` or `OPENROUTER_API_KEY=...`.
- Optional: `ARIZE_SPACE_ID` and `ARIZE_API_KEY` for tracing.
| Service | Sign up | What for |
|---------|---------|----------|
| **Arize** | https://app.arize.com | Observe agent traces |
| **OpenAI** | https://platform.openai.com/api-keys | LLM calls |
| **Tavily** | https://auth.tavily.com | Web search tool |

### 3. Set up

3) Install dependencies
```bash
cd backend
uv pip install -r requirements.txt # faster, deterministic installs
# If uv is not installed: curl -LsSf https://astral.sh/uv/install.sh | sh
# Fallback: pip install -r requirements.txt
git clone <repo-url>
cd agent-mastery-course

# Copy and fill in your API keys
cp .env.example.labs .env
```

Open `.env` with a text editor and add your keys.

### 4. Start

```bash
docker compose up --build
```

Docker builds the environment with all dependencies and starts Jupyter Lab.
The terminal will show logs — keep it running and open a new browser tab.

### 5. Open the lab

Open http://localhost:8888 in your browser. You'll see the lab notebooks:

```
labs/
├── lab1and2_base_agent.ipynb ← start here
├── lab3_agent_architectures.ipynb
├── lab4_tools.ipynb
├── lab5_RAG.ipynb
└── lab6_evals.ipynb
```

Double-click **lab1and2_base_agent.ipynb** and run the cells one by one.

### 6. What you'll see

- The agent plans a trip to Tokyo
- Each tool call and LLM request is traced to Arize
- Open https://app.arize.com to explore the traces

---

## Labs overview

| Lab | Topic | What you build |
|-----|-------|----------------|
| 1 & 2 | Base agent + tracing | A trip planner agent with tools |
| 3 | Agent architectures | Orchestrator-worker & parallel patterns |
| 4 | Tools | Enhance tools with real APIs |
| 5 | RAG | Add retrieval-augmented generation |
| 6 | Evals | Evaluate and log agent performance |

---

## Project structure

```
agent-mastery-course/
├── labs/ ← Jupyter notebooks (start here)
│ ├── lab1and2_base_agent.ipynb
│ ├── lab3_agent_architectures.ipynb
│ ├── lab4_tools.ipynb
│ ├── lab5_RAG.ipynb
│ └── lab6_evals.ipynb
├── backend/ ← FastAPI + LangGraph app (optional)
├── frontend/ ← Minimal UI (optional)
├── Dockerfile.labs ← Container for the labs
├── docker-compose.yml ← Runs Jupyter Lab
├── requirements-labs.txt ← Python deps for all labs
├── .env.example.labs ← API key template
└── README.md
```

4) Run
---

## Optional: Run the Trip Planner app

The `backend/` directory contains a FastAPI server with a LangGraph agent, optional RAG, MCP weather demo, and a minimal frontend.

### Backend setup

```bash
./start.sh # starts backend on 8000; serves minimal UI at '/'
# or
cd backend && uvicorn main:app --host 0.0.0.0 --port 8000 --reload
cd backend
cp .env.example .env
# Set OPENAI_API_KEY or OPENROUTER_API_KEY in backend/.env
uv pip install -r requirements.txt # or: pip install -r requirements.txt
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
```

5) Open
- Frontend: http://localhost:3000
- API: http://localhost:8000
- Docs: http://localhost:8000/docs
- Minimal UI: http://localhost:8000/
Open http://localhost:8000/docs to try the API.

### Backend with Docker

Docker (optional)
```bash
docker-compose up --build
docker compose -f docker-compose.backend.yml up --build
```

## Project Structure
- `backend/`: FastAPI app (`main.py`), LangGraph agents, tracing hooks.
- `frontend/index.html`: Minimal static UI served by backend at `/`.
- `optional/airtable/`: Airtable integration (optional, not on critical path).
- `test scripts/`: `test_api.py`, `synthetic_data_gen.py` for quick checks/evals.
- Root: `start.sh`, `docker-compose.yml`, `README.md`.

## Development Commands
- Backend (dev): `uvicorn main:app --host 0.0.0.0 --port 8000 --reload`
- API smoke test: `python "test scripts"/test_api.py`
- Synthetic evals: `python "test scripts"/synthetic_data_gen.py --base-url http://localhost:8000 --count 12`

## API
- POST `/plan-trip` → returns a generated itinerary.
Example body:
```json
{"destination":"Tokyo, Japan","duration":"7 days","budget":"$2000","interests":"food, culture"}
```
- GET `/health` → simple status.

## Notes on Tracing (Optional)
- If `ARIZE_SPACE_ID` and `ARIZE_API_KEY` are set, OpenInference exports spans for agents/tools/LLM calls. View at https://app.arize.com.
(Not yet created — the backend docker-compose is coming soon.)

### Backend features

- POST `/plan-trip` — generates a travel itinerary
- GET `/health` — health check
- GET `/` — minimal frontend
- Optional Arize tracing via `ARIZE_SPACE_ID` / `ARIZE_API_KEY`
- Optional RAG via `ENABLE_RAG=1` (curated local guide content)
- Optional MCP weather demo via `ENABLE_MCP=1`

---

## Troubleshooting
- 401/empty results: verify `OPENAI_API_KEY` or `OPENROUTER_API_KEY` in `backend/.env`.
- No traces: ensure Arize credentials are set and reachable.
- Port conflicts: stop existing services on 3000/8000 or change ports.

## Deploy on Render
- This repo includes `render.yaml`. Connect your GitHub repo in Render and deploy as a Web Service.
- Render will run: `pip install -r backend/requirements.txt` and `uvicorn main:app --host 0.0.0.0 --port $PORT`.
- Set `OPENAI_API_KEY` (or `OPENROUTER_API_KEY`) and optional Arize vars in the Render dashboard.

| Symptom | Fix |
|---------|-----|
| "No module named ..." in notebook | `Kernel → Restart Kernel` after the `!pip install` cell |
| API returns 401 | Verify the key is correct in your `.env` |
| No traces in Arize | Check `ARIZE_SPACE_ID` and `ARIZE_API_KEY` are set |
| Port 8888 in use | Change the port in `docker-compose.yml`: `"8889:8888"` |
| Docker build slow | Only the first build downloads packages. Rebuilds are instant. |
11 changes: 11 additions & 0 deletions python/llm/agents/agent-mastery-course/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
services:
labs:
build:
context: .
dockerfile: Dockerfile.labs
ports:
- "8888:8888"
volumes:
- ./labs:/workspace/labs
env_file:
- .env
33 changes: 33 additions & 0 deletions python/llm/agents/agent-mastery-course/lab-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/bash
set -euo pipefail

cat <<'BANNER'

╔══════════════════════════════════════════════════════════════╗
║ AI Trip Planner — Agent Mastery Course ║
╚══════════════════════════════════════════════════════════════╝

✓ Jupyter Lab is ready!

Open http://localhost:8888 in your browser
Then open: labs/lab1and2_base_agent.ipynb

Labs in this course:
lab1and2_base_agent.ipynb ← Start here
lab3_agent_architectures.ipynb
lab4_tools.ipynb
lab5_RAG.ipynb
lab6_evals.ipynb

To stop: press Ctrl+C in this terminal

BANNER

exec jupyter lab \
--ip=0.0.0.0 \
--port=8888 \
--no-browser \
--allow-root \
--NotebookApp.token='' \
--NotebookApp.password='' \
--LabApp.default_url=/lab/tree/labs
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,13 @@
"import os\n",
"from getpass import getpass\n",
"\n",
"os.environ[\"ARIZE_SPACE_ID\"] = globals().get(\"ARIZE_SPACE_ID\") or getpass(\"🔑 Enter your Arize Space ID: \")\n",
"os.environ[\"ARIZE_SPACE_ID\"] = os.environ.get(\"ARIZE_SPACE_ID\") or getpass(\"🔑 Enter your Arize Space ID: \")\n",
"\n",
"os.environ[\"ARIZE_API_KEY\"] = globals().get(\"ARIZE_API_KEY\") or getpass(\"🔑 Enter your Arize API Key: \")\n",
"os.environ[\"ARIZE_API_KEY\"] = os.environ.get(\"ARIZE_API_KEY\") or getpass(\"🔑 Enter your Arize API Key: \")\n",
"\n",
"os.environ[\"OPENAI_API_KEY\"] = globals().get(\"OPENAI_API_KEY\") or getpass(\"🔑 Enter your OpenAI API Key: \")\n",
"os.environ[\"OPENAI_API_KEY\"] = os.environ.get(\"OPENAI_API_KEY\") or getpass(\"🔑 Enter your OpenAI API Key: \")\n",
"\n",
"os.environ[\"TAVILY_API_KEY\"] = globals().get(\"TAVILY_API_KEY\") or getpass(\"🔑 Enter your Tavily API Key: \")"
"os.environ[\"TAVILY_API_KEY\"] = os.environ.get(\"TAVILY_API_KEY\") or getpass(\"🔑 Enter your Tavily API Key: \")"
]
},
{
Expand Down
Loading