Xây dựng Ứng dụng Fitness AI Không Tay với Gemini Live API
Giới thiệu
Ứng dụng AI Personal Trainer là một sản phẩm thử nghiệm trong khuôn khổ Google AI Studio Multimodal Challenge. Ứng dụng này mang lại cách tiếp cận "giọng nói trước hết", biến chiếc smartphone của bạn thành một người bạn tập luyện tương tác. Điều đặc biệt là ứng dụng được điều khiển chủ yếu bằng các lệnh giọng nói, giúp người dùng tập trung vào bài tập thay vì màn hình.
Vấn đề cần giải quyết
- Sự phân tâm trong quá trình tập luyện: Người dùng thường phải tương tác với màn hình điện thoại liên tục.
- Thiếu tính cá nhân hóa: Hầu hết các ứng dụng hiện tại đều cung cấp giải pháp chung cho tất cả mọi người.
- Tương tác thụ động: Các ứng dụng chỉ hoạt động như công cụ theo dõi chứ không phải là trợ lý.
Các tính năng đã triển khai
- 🎤 Tạo chương trình tập luyện bằng giọng nói: Tương tác với AI để tạo ra các chương trình tập luyện cá nhân hóa.
- 🧠 Tương tác âm thanh thời gian thực: Giao tiếp hai chiều trong quá trình tập luyện.
- 📊 Hệ thống cơ sở dữ liệu toàn diện: Lưu trữ chương trình, phiên tập và tiến trình.
- 📈 Bảng điều khiển phân tích: Theo dõi tiến trình và phân tích hiệu suất.
- 📅 Tích hợp Google Calendar: Tự động thêm các buổi tập vào lịch.
- 🎯 Kiến trúc lai: Kết hợp tốc độ đối thoại với độ chính xác trong phân tích.
Trình diễn
⚡ Ứng dụng Trực tiếp
📱 Xem tại AI Studio
💻 Kho lưu trữ GitHub: ai-personal-trainer
Cách tôi sử dụng Google AI Studio
Quá trình phát triển bắt đầu trực tiếp trong Google AI Studio, nơi tôi thử nghiệm với nhiều phương pháp tương tác đa phương thức.
Quy trình phát triển
- Lập mẫu trong Google AI Studio: Tạo giao diện người dùng và thiết lập hệ thống ban đầu.
- Xuất và phát triển: Tải xuống dự án để phát triển tại chỗ.
- Phát triển mở rộng: Sử dụng Gemini CLI để tích hợp các chức năng phức tạp.
- Triển khai cuối cùng: Tải lên dự án hoàn chỉnh và sử dụng Deploy App.
Kiến trúc hai mô hình
Mô hình chính: Đối thoại thời gian thực
javascript
// Kết nối với đối thoại âm thanh trực tiếp
sessionRef.current = await clientRef.current.live.connect({
model: 'gemini-2.5-flash-preview-native-audio-dialog',
callbacks: {
onopen: () => setConnectionStatus('connected'),
onmessage: async (message) => {
// Xử lý lời nói của người dùng
if (message.serverContent?.inputTranscription) {
const userText = message.serverContent.inputTranscription.text;
onTranscript(userText);
}
// Phát âm thanh phản hồi của AI
const audio = message.serverContent?.modelTurn?.parts[0]?.inlineData;
if (audio && outputAudioContextRef.current) {
await playAudioResponse(audio);
}
}
},
config: {
systemInstruction: createDynamicPrompt(),
responseModalities: [Modality.AUDIO],
outputAudioTranscription: {}, // <--- Kích hoạt chức năng phiên dịch LLM
inputAudioTranscription: {}, // <--- Kích hoạt phiên dịch người dùng
speechConfig: {
voiceConfig: { prebuiltVoiceConfig: { voiceName: 'Orus' } }
}
}
});
Mô hình phân tích: Trích xuất dữ liệu
javascript
// Diễn giải chính xác các lệnh của người dùng
export const interpretWorkoutCommand = async (transcript: string): Promise<{ command: 'log_set' | 'get_form_tip' | 'chat_message', data: { reps?: number, weight?: number, text?: string } | null }> => {
const prompt = `Bạn là một trợ lý AI diễn giải các lệnh giọng nói từ người dùng trong quá trình tập luyện. Bản ghi âm giọng nói của người dùng là: "${transcript}".
Nhiệm vụ của bạn là phân tích bản ghi và phân loại nó thành một trong những lệnh sau, trích xuất dữ liệu liên quan.
CÁC LỆNH CÓ THỂ:
1. 'log_set': Người dùng thông báo hoàn thành một set. Họ có thể đề cập đến số lần (reps) và/hoặc trọng lượng.
- Từ khóa: "done", "finished", "log it", "reps", "weight", "kilos", số.
- Ví dụ bản ghi: "Okay, 12 reps tại 50 kilos", "Tôi đã xong", "8 reps", "log 90 pounds".
2. 'get_form_tip': Người dùng yêu cầu lời khuyên về kỹ thuật tập luyện.
- Từ khóa: "form", "technique", "how do I do this", "am I doing it right".
- Ví dụ bản ghi: "kiểm tra kỹ thuật của tôi", "kỹ thuật cho cái này là gì".
3. 'chat_message': Người dùng đang nói một điều gì khác, có thể là câu hỏi hoặc bình luận cho huấn luyện viên AI. Đây là mặc định nếu không có lệnh nào khác phù hợp.
- Ví dụ bản ghi: "còn bao nhiêu set", "Tôi cảm thấy mệt", "bài tập tiếp theo là gì".
Đáp lại theo định dạng JSON với "command" và "data" tùy chọn.
- Đối với 'log_set', 'data' phải là một đối tượng với các số 'reps' và 'weight' tùy chọn.
- Đối với 'get_form_tip', 'data' phải là null.
- Đối với 'chat_message', 'data' phải là một đối tượng với bản ghi gốc là 'text'.
Chỉ trả về đối tượng JSON.
`;
try {
const result = await ai.models.generateContent({
model: "gemini-2.5-flash",
contents: prompt,
...
Khả năng đa phương thức
1. Tương tác âm thanh liền mạch
Đã triển khai: sử dụng client.live.connect từ Gemini Live API SDK với truyền tải hai chiều liên tục
Điểm độc đáo: Hoạt động như một cuộc hội thoại điện thoại — bạn có thể ngắt lời và nhận phản hồi ngay lập tức
2. Xử lý lệnh lai
Kiến trúc:
- Mô hình Đối thoại: Duy trì cuộc trò chuyện tự nhiên.
- Mô hình Phân tích: Trích xuất dữ liệu chính xác từ lời nói.
Ví dụ xử lý:
javascript
Người dùng: "Đã làm tám reps với sáu mươi kilos, cảm thấy khá dễ"
Mô hình Đối thoại → "Tuyệt vời! Đã ghi 8 reps với 60 kg. Chúng ta có nên tăng trọng lượng không?"
Mô hình Phân tích →
{
"command": "log_set",
"data": {
"reps": 8,
"weight": 60
}
}
3. Hệ thống dữ liệu đầy đủ tính năng
Kiến trúc đã triển khai:
Chương trình tập luyện (/programs/{programId}):
json
{
"name": "Chương trình Tăng cường, 12 tuần",
"createdBy": "userId",
"workouts": {
"day1": {
"dayName": "Ngực và tay sau",
"exercises": [
{
"exerciseId": "bench_press",
"name": "Đẩy ngực với tạ",
"sets": [{"reps": 8, "weight": 60}],
"rest": 120
}
]
}
}
}
Phiên tập chi tiết (/sessions/{sessionId}):
json
{
"userId": "user123",
"date": "2024-01-15T10:00:00Z",
"programId": "strength_program_001",
"workoutId": "day1_chest",
"duration": 5400, // giây
"voiceTranscript": "Hoàn thành ghi chép cuộc hội thoại với AI...",
"performedSets": {
"set001": {
"exerciseId": "bench_press",
"setNumber": 1,
"reps": 8,
"weight": 62.5,
"timestamp": "2024-01-15T10:15:30Z"
}
}
}
4. Tích hợp tự động vào lịch
Đã triển khai: Tích hợp trực tiếp với Google Calendar API
javascript
export const scheduleWorkouts = async (workouts: Workout[], accessToken: string): Promise<void> => {
if (!workouts || workouts.length === 0) {
throw new Error("Không có buổi tập nào để lên lịch.");
}
const schedulePromises = workouts.map(workout => {
const startTime = getNextWorkoutDate(workout.dayOfWeek);
const endTime = new Date(startTime.getTime() + 60 * 60 * 1000); // Giả định thời gian 1 giờ
const event = {
'summary': `Buổi tập: ${workout.dayName}`,
'description': `Phiên tập được lên lịch của bạn.\n\nBài tập:\n- ${workout.exercises.map(e => e.name).join('\n- ')}`,
'start': {
'dateTime': startTime.toISOString(),
'timeZone': Intl.DateTimeFormat().resolvedOptions().timeZone,
},
'end': {
'dateTime': endTime.toISOString(),
'timeZone': Intl.DateTimeFormat().resolvedOptions().timeZone,
},
};
return fetch('https://www.googleapis.com/calendar/v3/calendars/primary/events', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(event),
});
});
await Promise.all(schedulePromises);
};
5. Hiểu biết ngữ cảnh về thuật ngữ thể hình
AI hiểu các từ vựng cụ thể:
- Nhận diện dữ liệu cho việc ghi nhận set (
log_set): AI tìm kiếm trong lời nói của người dùng các số và từ khóa (như "reps", "times", "weight", "pounds") để tự động điền dữ liệu về các set đã hoàn thành. - Xử lý yêu cầu và bình luận (
get_form_tip,chat_message): Các cụm từ không chứa dữ liệu trực tiếp để ghi nhận sẽ được xử lý như các yêu cầu từ huấn luyện viên hoặc bình luận đơn giản.
6. Bảng điều khiển Phân tích Toàn diện
Đã triển khai: Một phần phân tích chuyên dụng cung cấp cái nhìn chi tiết về hiệu suất tập luyện và theo dõi tiến trình.
Các tính năng bao gồm:
- Biểu đồ và đồ thị tiến trình hình ảnh
- Trực quan hóa dữ liệu tập luyện lịch sử
- Phân tích các chỉ số hiệu suất và xu hướng
Giới hạn hiện tại của MVP
Những thách thức chính:
- Độ chính xác của nhận diện giọng nói: AI không luôn luôn diễn giải chính xác các lệnh trong đối thoại trực tiếp, đặc biệt là khi có tiếng ồn nền.
- Thực hiện lệnh: Mô hình đôi khi "quên" thực hiện các hành động cụ thể trong ứng dụng sau khi phản hồi.
Tại sao tính đa phương thức quan trọng cho thể hình
Các ứng dụng thể hình truyền thống buộc bạn phải lựa chọn: HOẶC theo dõi dữ liệu HOẶC tập trung vào bài tập. Cách tiếp cận đa phương thức giải quyết vấn đề này:
- Giao diện giọng nói giúp bạn tập trung vào các bài tập.
- Phân tích giọng nói thông minh tự động cấu trúc dữ liệu.
- Phản hồi thời gian thực tạo cảm giác như có một huấn luyện viên cá nhân.
- Lịch tập tự động tích hợp thể hình vào cuộc sống hàng ngày.
Kết quả là một người bạn tập thể hình hiểu ngôn ngữ tự nhiên và thích ứng với phong cách riêng của từng người dùng.
Lưu ý: Mặc dù huấn luyện viên AI của tôi khá thông minh và khích lệ, chúng tôi vẫn khuyến nghị duy trì sự tỉnh táo, đặc biệt là khi liên quan đến sức khỏe. 💪
Lời cảm ơn
Tôi xin gửi lời biết ơn sâu sắc đến các tổ chức của Google AI Studio Multimodal Challenge vì cơ hội độc đáo để thử nghiệm với các công nghệ trí tuệ nhân tạo tiên tiến.
Cảm ơn đặc biệt đến:
- Đội ngũ Google AI Studio vì nền tảng trực quan giúp công nghệ phức tạp trở nên dễ tiếp cận.
- Các nhà phát triển Gemini Live Audio API vì công nghệ tương tác giọng nói thời gian thực cách mạng.
- Cộng đồng Dev.to vì đã cung cấp một nền tảng truyền cảm hứng cho các dự án sáng tạo.
Dự án này được thực hiện nhờ hệ sinh thái công cụ tiên tiến và cộng đồng phát triển hỗ trợ mà Google AI tạo ra.
MVP được phát triển với React, TypeScript, Firebase, Google Calendar API và khả năng đa phương thức Google Gemini