Tính năng AI
Trợ lý AI nằm ở góc dưới bên phải của mọi trang tổng quan. Ứng dụng gọi LLM qua API tương thích OpenAI: Ollama trên máy khi phát triển, OpenAI khi triển khai; chỉ cần đổi biến môi trường.
Trợ lý AI
Mỗi vai trò có system prompt riêng, nên trợ lý trả lời theo nhu cầu của người dùng.
Trợ lý học tập
Giải thích khái niệm, trả lời câu hỏi, gợi ý cách học. Không giải hộ bài tập mà hướng dẫn học viên tự tìm lời giải.
Trợ lý giảng dạy
Gợi ý câu hỏi trắc nghiệm, tiêu chí chấm, mẫu nhận xét và cách giải thích nội dung khó.
Gắn widget trò chuyện
// src/app/(dashboard)/layout.tsx: có trong mọi trang tổng quan
<ChatWidget />
// Tùy chọn: truyền ngữ cảnh khóa học và bài học
<ChatWidget context={{ courseId, courseName, lessonId, lessonTitle }} />Chèn ngữ cảnh
Mỗi lần bạn gửi tin nhắn, LLM nhận:
- System prompt theo vai trò của người dùng.
- Tên khóa học và bài học hiện tại, nếu widget được truyền ngữ cảnh.
- Tối đa 20 tin nhắn gần nhất của cuộc trò chuyện, không quá 16.000 ký tự, tính từ tin mới nhất.
- Tin nhắn mới.
Phần ngữ cảnh nối vào system prompt
// src/services/ai.service.ts, buildSystemPrompt()
Current Context:
- Course: ${context.courseName}
- Lesson: ${context.lessonTitle}Widget trong layout trang tổng quan hiện chưa truyền ngữ cảnh khóa học, nên trợ lý chỉ dựa vào system prompt và lịch sử trò chuyện.
Cấu hình
Ứng dụng chỉ đọc ba biến môi trường, lúc khởi động; đổi xong phải khởi động lại ứng dụng.
Dev: Ollama trên máy
OPENAI_BASE_URL="http://localhost:11434/v1"
OPENAI_API_KEY="ollama"
OPENAI_MODEL="qwen2.5:7b-instruct"Production: OpenAI
OPENAI_BASE_URL="https://api.openai.com/v1"
OPENAI_API_KEY="sk-proj-..."
OPENAI_MODEL="gpt-4o-mini"- Trong UAT Docker, Ollama trên máy chủ được gọi qua
http://host.docker.internal:11434/v1. - Dùng model chat thường như
gpt-4o-mini. Model suy luận (dòng o*, gpt-5*) trả lỗi 400 vì code gửitemperaturevàmax_tokens. - Nếu bỏ trống
OPENAI_MODEL, code dùnggpt-4o; hãy luôn đặt rõ để kiểm soát chi phí. - Trang API keys của Quản trị hệ thống hiện chưa có tác dụng; chỉ cấu hình LLM bằng biến môi trường.
- Widget gọi
POST /api/ai/chat/stream: câu trả lời hiện dần theo từng đoạn (NDJSON). Câu hỏi và câu trả lời chỉ được lưu khi trợ lý trả lời xong. - Lịch sử trò chuyện được giữ
CHAT_RETENTION_DAYSngày (mặc định 180). JobGET /api/cron/chat-retention(headerAuthorization: Bearer $CRON_SECRET) xóa phần cũ hơn, chạy hằng ngày.
Giới hạn lượt hỏi
Số câu hỏi mỗi ngày theo vai trò. Chỉ tính câu hỏi của người dùng, không tính câu trả lời của trợ lý. Lượt hỏi được tính lại lúc 00:00 giờ Việt Nam. Trợ lý không trả lời trong 60 giây thì câu hỏi bị hủy.