A Dockerized customer-support application built with FastAPI, LangGraph, Gemini or Ollama, and PostgreSQL.
- Browser-based support chat UI
- Local low-latency request routing
- Order-status specialist agent
- Support-ticket specialist agent
- PostgreSQL conversation checkpoints
- Gemini and Ollama provider options
- Docker Compose deployment
Browser or API client
|
FastAPI
|
Local router
/ \
Order agent Support agent
| |
Order tool Ticket tool
\ /
PostgreSQL
The router classifies requests locally. The selected specialist calls the LLM only when needed. Tool calls are executed by LangGraph and the result is returned to the user.
- Docker Desktop
- A Gemini API key, or a local Ollama installation
Create .env from .env.example:
Copy-Item .env.example .envFor Gemini, set:
LLM_PROVIDER=gemini
GOOGLE_API_KEY=your_api_key_here
For Ollama, set:
LLM_PROVIDER=ollama
OLLAMA_MODEL=llama3.1
OLLAMA_BASE_URL=http://host.docker.internal:11434
Do not commit .env. It is excluded by .gitignore.
Start the API and PostgreSQL:
docker compose up -d --buildCheck service status:
docker compose psOpen the web UI:
http://127.0.0.1:8080/
Check the health endpoint:
http://127.0.0.1:8080/health
Open the interactive API documentation:
http://127.0.0.1:8080/docs
View application logs:
docker compose logs -f appStop the services:
docker compose downPowerShell request:
$body = @{
thread_id = "test-001"
message = "What is the status of order ORD-1001?"
} | ConvertTo-Json
Invoke-RestMethod `
-Uri "http://127.0.0.1:8080/api/v1/chat" `
-Method Post `
-ContentType "application/json" `
-Body $bodyExample response:
{
"thread_id": "test-001",
"response": "The order was handed to the post office and the tracking code is 98765."
}.
├── app/
│ ├── agent/
│ │ ├── graph.py # LangGraph workflow and routing
│ │ ├── llm_factory.py # Gemini and Ollama providers
│ │ └── tools.py # Order and support tools
│ ├── static/index.html # Browser chat UI
│ └── main.py # FastAPI application
├── docker-compose.yml # API and PostgreSQL services
├── Dockerfile # API image definition
├── requirements.txt # Python dependencies
└── .env.example # Safe configuration template
Order data and ticket creation currently use mock functions. PostgreSQL is used for LangGraph conversation checkpoints. Production deployments should use a secret manager and real order and ticket persistence.