Multi-agent customer support system built with LangGraph, LangChain, and PostgreSQL + pgvector. Workshop demo for "Observability, Evals & Security Guardrails for LLM Agents".
User Query
│
▼
┌──────────┐
│ Router │ ← structured output intent detection (ProviderStrategy)
└──────────┘
│
├─ general ────────► ShopAssist (lookup_order, process_refund, send_email, search_knowledge_base)
├─ order_support ──► ShopAssist
├─ policy_inquiry ─► PolicyAdvisor (search_knowledge_base)
└─ escalation ─────► EscalationAgent (search_knowledge_base, send_email)
- Python 3.11+
- uv (Python package manager)
- Docker & Docker Compose
- Node.js 20+ and pnpm (for local UI development)
- An OpenAI API key (or Azure OpenAI credentials)
There are two ways to run the project: Docker Compose (recommended) or local development.
Run the entire stack (database, backend, and UI) with a single command.
cp .env.example .envEdit .env and set your API key:
OPENAI_API_KEY=sk-your-key-hereFor Azure OpenAI, set LLM_PROVIDER=azure_openai and fill in the Azure fields.
docker compose up --buildThis starts three services:
| Service | Port | Description |
|---|---|---|
| db | 5432 | PostgreSQL 16 + pgvector |
| langgraph | 2024 | LangGraph dev server (Python backend) |
| ui | 3000 | Agent Chat UI (Next.js frontend) |
In a separate terminal:
docker compose exec langgraph uv run python -m support_swarm.db.seedNavigate to http://localhost:3000 and start chatting.
# View logs
docker compose logs -f
# View logs for a specific service
docker compose logs -f langgraph
# Restart a single service
docker compose restart langgraph
# Stop everything and remove volumes
docker compose down -vgit clone https://github.com/droideronline/pyconf-hyd-2026-trustworthy-llm-agents.git
cd pyconf-hyd-2026-trustworthy-llm-agents
uv synccp .env.example .envEdit .env and set your API key:
OPENAI_API_KEY=sk-your-key-hereFor Azure OpenAI, set LLM_PROVIDER=azure_openai and fill in the Azure fields.
docker compose up -d dbCreate tables and insert sample data (customers, orders, knowledge articles):
uv run python -m support_swarm.db.seedThis step requires your OPENAI_API_KEY to be set:
uv run python -m support_swarm.db.seed --embeddingsuv run langgraph dev --no-browserThe server starts at http://localhost:2024. Verify with:
curl http://localhost:2024/ok
# {"ok": true}In a new terminal:
cd agent-chat-ui
pnpm install
pnpm devThe UI opens at http://localhost:3000.
├── support_swarm/
│ ├── config/ # Settings, YAML config loader
│ ├── db/
│ │ ├── models/ # SQLAlchemy ORM (Customer, Order, Refund, EmailLog, KnowledgeArticle)
│ │ ├── engine.py # DB engine + session management
│ │ └── seed.py # Seed data + embedding generation
│ ├── declarative/
│ │ ├── agents/ # YAML agent specs (router, shop_assist, policy_advisor, escalation_agent)
│ │ ├── models.py # AgentSpec Pydantic model
│ │ └── yaml_utils.py # YAML loader
│ ├── tools/
│ │ ├── registry.py # Tool registry with @register_tool decorator
│ │ ├── shop_assist_tools.py # lookup_order, process_refund, send_email
│ │ └── shared.py # search_knowledge_base (pgvector semantic search)
│ ├── enums.py # Agent name enums
│ ├── model_client.py # LLM + embedding client factory
│ └── workflow.py # LangGraph multi-agent workflow with structured routing
├── agent-chat-ui/ # LangChain Agent Chat UI (Next.js)
├── langgraph.json # LangGraph dev server config
├── settings.yaml # App config (env var driven)
├── docker/ # Dockerfiles for langgraph and UI services
├── docker-compose.yml # Full stack: PostgreSQL + LangGraph + Chat UI
└── pyproject.toml # Python dependencies (managed by uv)
| Table | Records | Notes |
|---|---|---|
| customers | 4 | Alice, Bob, Charlie, Eve |
| orders | 7 | ORD-1001 to ORD-1007 (various statuses and amounts) |
| knowledge_articles | 5 | Return, Refund, Shipping, Warranty, Escalation |
ORD-1006 contains a prompt injection payload in the
notesfield for the security guardrails demo.
Those who attended our Workshop at PyConf Hyderabad 2026 on 14th March and given steps didn't work for you? Please do reach out to either of us at LinkedIn: