AI Agent hỗ trợ giao tiếp tiếng Anh — Voice + Text, real-time conversation với error correction, adaptive learning, và long-term memory.
| Layer | Công nghệ |
|---|---|
| Backend | Python 3.11, FastAPI, LiveKit Agents, LangGraph, LangChain |
| Frontend | React 18, TypeScript, Vite, TailwindCSS, Framer Motion |
| LLM | Google Gemini 2.5 Flash (free) / Groq Llama 3.3 70B (free) |
| Voice | LiveKit (WebRTC), Silero VAD |
| Memory | mem0 + pgvector |
| Database | PostgreSQL 16 + pgvector |
| Infra | Docker Compose |
User (Browser)
├── Voice ──→ LiveKit Server ──→ Agent Worker ──→ LangGraph
└── Text ──→ LiveKit Text Stream ──→ ↗
↓
assess → route → respond / correct / topic
↓
save_memory (mem0 + pgvector)
↓
TTS ← Agent Response → Text Stream → Browser
english-agent/
├── backend/
│ ├── app/
│ │ ├── main.py # LiveKit agent worker entry
│ │ ├── helper_api.py # FastAPI server (token API)
│ │ ├── core/
│ │ │ ├── settings.py # Pydantic config (.env)
│ │ │ ├── llm.py # Multi-provider LLM factory
│ │ │ └── langgraph_adapter.py # LangGraph ↔ LiveKit bridge
│ │ ├── agents/english_tutor/
│ │ │ ├── entrypoint.py # Agent session setup
│ │ │ ├── graph.py # LangGraph state machine
│ │ │ ├── models.py # State + structured output models
│ │ │ ├── prompts.py # 6 English tutoring prompts
│ │ │ └── nodes/
│ │ │ ├── assess.py # Error analysis + routing
│ │ │ ├── respond.py # Natural conversation
│ │ │ ├── correct.py # Friendly error correction
│ │ │ └── topic.py # Topic management
│ │ ├── memory/client.py # mem0 + pgvector client
│ │ ├── database/
│ │ │ ├── connection.py # Async PostgreSQL pool
│ │ │ └── models.py # User, PracticeSession, ErrorLog
│ │ ├── router/token.py # LiveKit token endpoint
│ │ └── schema/models.py # Provider & model enums
│ ├── pyproject.toml
│ ├── Dockerfile
│ └── .env.example
├── frontend/
│ ├── src/
│ │ ├── pages/ # Home, Practice, Dashboard
│ │ ├── components/
│ │ │ ├── chat/ # ChatRoom, MessageList, InputBar
│ │ │ ├── voice/ # AudioVisualizer, VoiceControls
│ │ │ └── feedback/ # CorrectionCard, ScoreDisplay
│ │ ├── hooks/ # useLiveKit, useTranscript
│ │ ├── stores/ # Zustand (chatStore, userStore)
│ │ └── lib/api.ts # API client
│ ├── package.json
│ └── vite.config.ts
└── docker-compose.yaml # LiveKit + PostgreSQL + API + Agent
- Python 3.11+
- Node.js 18+
- Docker & Docker Compose
- Google API Key (free): https://aistudio.google.com/apikey
git clone https://github.com/VanhPoker/EnglishAItutor.git
cd EnglishAItutorcd backend
# Copy env và điền API key
cp .env.example .env
# Mở .env → điền GOOGLE_API_KEY=your-key-here
# Tạo virtual environment
python -m venv .venv
# Activate (Linux/Mac)
source .venv/bin/activate
# Activate (Windows)
.venv\Scripts\activate
# Install dependencies
pip install -e .# Từ thư mục root (EnglishAItutor/)
docker compose up -d livekit postgresVerify:
docker compose ps
# livekit → 0.0.0.0:7880
# postgres → 0.0.0.0:5432Mở 2 terminal:
# Terminal 1: FastAPI server
cd backend
uvicorn app.helper_api:app --host 0.0.0.0 --port 8080 --reload
# Terminal 2: LiveKit Agent worker
cd backend
python -m app.main devcd frontend
npm install
npm run devTruy cập http://localhost:5173
- Chọn CEFR level (A1-C2)
- Chọn conversation topic
- Click Start Practicing
- Nói hoặc gõ tiếng Anh!
# Clone repo
git clone https://github.com/VanhPoker/EnglishAItutor.git
cd EnglishAItutor
# Setup env
cp backend/.env.example backend/.env
nano backend/.env
# Điền: GOOGLE_API_KEY=your-key
# Build & run everything
docker compose up -d --build
# Check status
docker compose ps
docker compose logs -f agentServices:
| Service | Port | URL |
|---|---|---|
| Frontend | 5173 | http://your-vm-ip:5173 |
| API | 8080 | http://your-vm-ip:8080 |
| LiveKit | 7880 | ws://your-vm-ip:7880 |
| PostgreSQL | 5432 | Internal |
# 1. Install dependencies
sudo apt update
sudo apt install -y python3.11 python3.11-venv nodejs npm docker.io docker-compose-v2
# 2. Clone & setup
git clone https://github.com/VanhPoker/EnglishAItutor.git
cd EnglishAItutor
cp backend/.env.example backend/.env
# Edit .env with your API keys
# 3. Start infra
docker compose up -d livekit postgres
# 4. Backend
cd backend
python3.11 -m venv .venv
source .venv/bin/activate
pip install -e .
# Start in background with tmux
tmux new -s api
uvicorn app.helper_api:app --host 0.0.0.0 --port 8080
# Ctrl+B, D to detach
tmux new -s agent
python -m app.main dev
# Ctrl+B, D to detach
# 5. Frontend
cd ../frontend
npm install
npm run build # Production build → dist/
npx serve dist -l 5173 # Serve static filesThêm Nginx reverse proxy:
# /etc/nginx/sites-available/english-tutor
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:5173;
}
location /api/ {
proxy_pass http://localhost:8080;
}
location /ws {
proxy_pass http://localhost:7880;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}sudo ln -s /etc/nginx/sites-available/english-tutor /etc/nginx/sites-enabled/
sudo certbot --nginx -d your-domain.com
sudo systemctl restart nginx| Variable | Required | Default | Description |
|---|---|---|---|
GOOGLE_API_KEY |
Yes* | — | Google AI Studio API key (Gemini) |
GROQ_API_KEY |
Alt* | — | Groq API key (fallback LLM) |
LIVEKIT_API_KEY |
Yes | devkey |
LiveKit API key |
LIVEKIT_API_SECRET |
Yes | secret |
LiveKit API secret |
LIVEKIT_URL |
Yes | ws://localhost:7880 |
LiveKit server URL |
POSTGRES_SERVER |
Yes | localhost |
PostgreSQL host |
POSTGRES_PORT |
Yes | 5432 |
PostgreSQL port |
POSTGRES_DB |
Yes | english_agent |
Database name |
POSTGRES_USER |
Yes | postgres |
DB username |
POSTGRES_PASSWORD |
Yes | postgres |
DB password |
*At least one LLM API key required (GOOGLE_API_KEY or GROQ_API_KEY).
Free API keys:
- Google Gemini: https://aistudio.google.com/apikey (1500 req/day free)
- Groq: https://console.groq.com/keys (free tier)
- Create
backend/app/agents/english_tutor/nodes/your_node.py:
from langchain_core.messages import AIMessage
from langchain_core.runnables.config import RunnableConfig
from app.agents.english_tutor.models import EnglishTutorState
async def your_node(state: EnglishTutorState, config: RunnableConfig) -> dict:
# Process state, call LLM, return updates
return {"messages": [AIMessage(content="...")]}- Register in
graph.py:
builder.add_node("your_node", your_node)
builder.add_edge("your_node", "save_memory")- Update routing in
route_after_assess()if needed.
- Create
backend/app/router/your_router.py - Register in
helper_api.py:
from app.router.your_router import router as your_router
app.include_router(your_router, prefix="/api")- Create
frontend/src/pages/YourPage.tsx - Add route in
App.tsx:
<Route path="/your-page" element={<YourPage />} />- Add nav link in
components/ui/Layout.tsx
cd backend
alembic init alembic
# Edit alembic/env.py → import app.database.models.Base
alembic revision --autogenerate -m "description"
alembic upgrade headcd backend
# Test all imports
python -c "
import os; os.environ['GOOGLE_API_KEY']='test'
os.environ['LIVEKIT_API_KEY']='devkey'; os.environ['LIVEKIT_API_SECRET']='secret'
from app.core.langgraph_adapter import LangGraphAdapter
from app.agents.english_tutor.graph import create_english_tutor_graph
from app.router.token import router
from app.database.models import User, PracticeSession, ErrorLog
print('ALL IMPORTS OK')
"
# Test API endpoints
python -c "
import os; os.environ['GOOGLE_API_KEY']='test'
os.environ['LIVEKIT_API_KEY']='devkey'; os.environ['LIVEKIT_API_SECRET']='secret'
from fastapi.testclient import TestClient
from app.helper_api import app
c = TestClient(app)
assert c.get('/health').status_code == 200
assert c.post('/api/token', json={'userId':'u1','userName':'Test'}).status_code == 200
print('API TESTS PASS')
"
# Test graph compilation
python -c "
import asyncio, os; os.environ['GOOGLE_API_KEY']='test'
os.environ['LIVEKIT_API_KEY']='devkey'; os.environ['LIVEKIT_API_SECRET']='secret'
from app.agents.english_tutor.graph import create_english_tutor_graph
g = asyncio.run(create_english_tutor_graph(use_checkpointer=False))
print('Graph nodes:', list(g.nodes.keys()))
"cd frontend
npx tsc --noEmit # TypeScript check
npm run build # Production build- Start all services (docker + backend + frontend)
- Open http://localhost:5173
- Click Start Practicing
- Test voice: click mic, speak English
- Test text: type a message with grammar errors
- Verify: agent responds and corrects errors naturally
| Issue | Solution |
|---|---|
ModuleNotFoundError |
pip install -e . trong backend/ |
No pq wrapper available |
pip install "psycopg[binary]" |
| LiveKit connection refused | docker compose ps — check LiveKit port 7880 |
| Token endpoint 500 | Check LIVEKIT_API_KEY / LIVEKIT_API_SECRET trong .env |
| Gemini quota exceeded | Thêm GROQ_API_KEY vào .env làm backup |
| Frontend proxy error | Ensure backend chạy ở port 8080 |
| Component | Cost |
|---|---|
| Google Gemini 2.5 Flash | Free (1500 req/day) |
| Groq Llama 3.3 70B | Free tier |
| LiveKit (self-hosted) | Free |
| PostgreSQL + pgvector | Free (Docker) |
| Total | $0 |
MIT