Football Booking Chatbot Service
AI Chatbot service cho hệ thống đặt sân bóng đá — sử dụng FastAPI + Groq SDK (Llama 3.1/3.3) + RAG (Pinecone).
Tổng quan kiến trúc
Frontend (Next.js)
│ POST /chat/message (JSON)
│ POST /chat/message/stream (SSE)
▼
FastAPI Chatbot Service (port 3006)
│
├── RAG Pipeline ──► Pinecone (vector search)
│ fastembed (local ONNX embeddings)
│
├── LLM ─────────► Groq API
│ llama-3.1-8b-instant (fast)
│ llama-3.3-70b-versatile (complex)
│
├── Session Store ► Redis (DB 1, 30-min TTL)
│
└── Backend APIs ─► field-service :3002
booking-service :3003
Smart Routing (Model Selection)
| Loại yêu cầu | Model | Ví dụ |
|---|---|---|
| Tìm kiếm đơn giản | llama-3.1-8b-instant |
"Tìm sân ở Q1" |
| Tư vấn phức tạp | llama-3.3-70b-versatile |
"So sánh sân A vs B, ưu nhược điểm" |
Routing dựa trên keyword detection + message length > 80 chars.
RAG Pipeline
- User query → fastembed (local ONNX, ~46 MB, 384-dim, hỗ trợ tiếng Việt)
- Pinecone semantic search (top-k=3, min score=0.25)
- Context injection vào system prompt
- Groq LLM sinh phản hồi
Công nghệ
- Framework: FastAPI 0.115 + Uvicorn
- LLM: Groq SDK → Llama-3.1-8b-instant / Llama-3.3-70b-versatile
- Embeddings: fastembed (paraphrase-multilingual-MiniLM-L12-v2, ONNX, không cần API)
- Vector DB: Pinecone (cloud)
- Session: Redis (TTL 30 phút)
- Language: Python 3.10+
Cài đặt nhanh
# 1. Clone và cài UV (nếu chưa có)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 2. Sync dependencies
uv sync
# 3. Cấu hình env
cp .env.dev.example .env.dev
# Chỉnh sửa .env.dev và điền API keys
# 4. Chạy service
uv run uvicorn app.main:app --reload --port 3006
uv run --env-file .env.dev uvicorn app.main:app --reload --port 3006
Service sẽ chạy tại http://localhost:3006
Cấu hình môi trường (.env.dev)
| Biến | Bắt buộc | Mô tả |
|---|---|---|
GROQ_API_KEY |
✅ | Groq API key từ console.groq.com |
PINECONE_API_KEY |
✅ | Pinecone API key |
PINECONE_INDEX_NAME |
✅ | Tên Pinecone index (vd: football-fields-vn) |
REDIS_URL |
✅ | Redis URL (vd: redis://redis:6379/1) |
GROQ_FAST_MODEL |
❌ | Default: llama-3.1-8b-instant |
GROQ_POWER_MODEL |
❌ | Default: llama-3.3-70b-versatile |
GROQ_SMART_ROUTING |
❌ | true để bật smart routing (default: true) |
Index dữ liệu sân bóng vào Pinecone
Trước khi dùng chatbot, cần index dữ liệu sân vào Pinecone:
# Từ PostgreSQL trực tiếp (field-service không cần chạy)
uv run python scripts/index_fields_to_pinecone.py --source db
# Từ field-service API (field-service phải đang chạy)
uv run python scripts/index_fields_to_pinecone.py --source api
# Dry-run (test không upsert vào Pinecone)
uv run python scripts/index_fields_to_pinecone.py --source db --dry-run
API Endpoints
POST /chat/message
Chat thông thường — trả về JSON response.
// Request
{
"message": "Tìm sân cỏ nhân tạo 5 người ở Quận 7, giá dưới 300k",
"session_id": "optional-existing-session-id"
}
// Headers: X-User-Id: <user-uuid>
// Response
{
"reply": "Tôi tìm được 3 sân phù hợp với yêu cầu của bạn...",
"session_id": "uuid-session-id"
}
POST /chat/message/stream
Chat với SSE streaming — trả về token-by-token.
data: {"type": "model", "model": "llama-3.1-8b-instant"}
data: {"type": "thinking"}
data: {"type": "tool_calling", "tool": "search_fields"}
data: {"type": "token", "content": "Tôi "}
data: {"type": "token", "content": "tìm "}
...
data: {"type": "done", "session_id": "uuid"}
data: [DONE]
GET /chat/session/{session_id}
Lấy lịch sử hội thoại của session.
GET /health
Health check (kiểm tra Redis và Pinecone).
POST /internal/run-eval
Protected internal endpoint để OpenClaw trigger đánh giá từ xa.
- Header bắt buộc:
X-Internal-Service: <INTERNAL_SERVICE_SECRET> - Chạy
tests/eval_runner.pydưới dạng subprocess và trả về pass rate + output tail.
POST /internal/run-feedback-loop
Protected internal endpoint để OpenClaw trigger full feedback loop:
- (Optional) pre-eval baseline
- chạy
scripts/auto_prompt_optimizer.py - (Optional) post-eval
- ghi report vào
logs/feedback_loop/
CLI tương đương:
uv run python scripts/run_feedback_loop.py \
--api-url http://localhost:3006 \
--run-pre-eval \
--run-post-eval \
--max-iter 2 \
--target-pass-rate 0.80
Cấu trúc dự án
app/
├── main.py # FastAPI entry point
├── api/
│ ├── routes/chat.py # /chat endpoints
│ ├── routes/health.py # /health endpoint
│ └── deps.py # Dependency injection
├── application/
│ ├── chat_service.py # Orchestrator chính (RAG + LLM + Tools)
│ ├── session_service.py # Session lifecycle
│ ├── tool_executor.py # Tool dispatcher
│ └── prompts/ # Intent-based prompts (6 intent types)
├── infrastructure/
│ ├── llm/groq_client.py # Groq SDK wrapper
│ ├── llm/smart_router.py # Model selection logic
│ ├── rag/rag_service.py # RAG orchestration
│ ├── rag/pinecone_client.py # Pinecone client
│ ├── rag/embedding_client.py # fastembed wrapper
│ ├── redis/session_repo.py # Redis session repository
│ └── booking_api/ # HTTP clients cho backend services
└── domain/
├── models/ # ChatSession, Message, ToolResult
└── tools/ # 4 LLM tools (search, availability, bookings, create)
scripts/
└── index_fields_to_pinecone.py # Script index dữ liệu sân vào Pinecone
tests/
└── test_prompt_system.py # Intent classification tests
LLM Tools
| Tool | Mô tả |
|---|---|
search_fields |
Tìm sân bóng theo quận, giá, loại sân, rating |
check_availability |
Kiểm tra lịch trống của sân theo ngày |
get_my_bookings |
Lấy lịch sử đặt sân của user |
create_booking |
Đặt sân (sau khi confirm với user) |
Docker
Service được tích hợp trong docker-compose.yml của football-booking-backend-boilerplate:
chatbot-service:
build: ../football-booking-chatbot-service
ports:
- "3006:3006"
environment:
- REDIS_URL=redis://redis:6379/1
- FIELD_SERVICE_URL=http://field-service:3002
Chạy tests
uv run pytest tests/ -v
Local Mirror For Phase 2
Để local development gần giống production feedback loop (OpenClaw + internal endpoints + OmniRoute):
# 1) Đồng bộ env backend <-> chatbot (secret + chatbot URL + OmniRoute defaults)
bash scripts/setup_local_feedback_loop_env.sh
# 2) Khởi động chatbot-service (terminal A)
uv run --env-file .env.dev uvicorn app.main:app --host 0.0.0.0 --port 3006
# 3) Smoke test internal feedback-loop endpoints (terminal B)
bash scripts/test_feedback_loop_local.sh
Chạy feedback loop thủ công (local)
uv run python scripts/run_feedback_loop.py \
--api-url http://localhost:3006 \
--run-pre-eval \
--run-post-eval \
--max-iter 2 \
--target-pass-rate 0.80 \
--eval-delay 2.0
Report sẽ được tạo tại logs/feedback_loop/.