Tạo chatbot Alexa với Tambo và Deezer 🎶
Giới thiệu
Trong bài viết này, chúng ta sẽ cùng nhau khám phá cách tạo một chatbot AI cơ bản và thêm các công cụ cũng như thành phần giao diện người dùng tùy chỉnh. Chúng ta sẽ tích hợp một "công cụ tìm kiếm nhạc" và một "miniplayer nhạc" để mang lại khả năng nghe nhạc cho chatbot chỉ trong vòng mười phút.
Hãy bắt đầu với một bản demo nhanh:
1. Tạo ứng dụng Tambo mới
Đầu tiên, chúng ta sẽ tạo một ứng dụng Tambo mới (Tambo là một framework UI sinh ra mã nguồn mở):
bash
npx tambo create-app my-music-player
cd my-music-player
npx tambo init
Khi bạn đã thiết lập dự án Tambo của mình, bạn có thể xóa một vài tệp mẫu từ ví dụ:
bash
rm src/components/ui/card-data.tsx src/services/population-stats.ts
2. Định nghĩa các loại nhạc
Chúng ta sẽ sử dụng API Deezer để tìm kiếm nhạc, do đó hãy định nghĩa một số loại mà chúng ta sẽ sử dụng sau này.
Đặt những điều này vào src/lib/types.ts:
typescript
import { z } from "zod";
export const songSchema = z.object({
title: z.string().describe("Tiêu đề bài hát"),
artist: z.string().describe("Tên nghệ sĩ"),
album: z.string().describe("Tên album"),
duration: z.number().describe("Thời gian (giây)"),
preview: z.string().describe("URL preview (30 giây)"),
link: z.string().describe("Liên kết bài hát đầy đủ"),
albumCover: z.string().optional().describe("URL bìa album"),
});
export type Song = z.infer<typeof songSchema>;
export const searchMusicInputSchema = z.object({
query: z.string().describe("Truy vấn tìm kiếm nhạc (tiêu đề bài hát, tên nghệ sĩ, hoặc thể loại)"),
});
export type SearchMusicInput = z.infer<typeof searchMusicInputSchema>;
export const searchMusicSchema = z.function().args(searchMusicInputSchema).returns(z.array(songSchema));
3. Tạo dịch vụ tìm kiếm nhạc
Bây giờ, hãy định nghĩa một hàm server trong NextJS để truy vấn API Deezer. Chúng ta sẽ sử dụng điều này làm công cụ cho chatbot sau này.
Lưu mã này vào src/services/music-search.ts:
typescript
"use server";
import { SearchMusicInput, Song } from "@/lib/types";
export async function searchMusic({ query }: SearchMusicInput): Promise<Song[]> {
const response = await fetch(`https://api.deezer.com/search?q=${encodeURIComponent(query)}&limit=10`);
const data = await response.json();
if (data.error) throw new Error(data.error);
return (data.data || []).map((item: any) => ({
...item,
artist: item.artist?.name || "",
album: item.album?.title || "",
albumCover: item.album?.cover || undefined
}));
}
Lưu ý rằng chúng ta đang sử dụng các loại mà chúng ta đã định nghĩa ở bước 2.
4. Xây dựng thành phần Miniplayer nhạc
Ở bước tiếp theo, chúng ta sẽ thiết kế một thành phần React miniplayer nhạc trông giống như sau:
Đặt mã này vào src/components/ui/music-card.tsx:
typescript
import { z } from "zod";
import { useState, useEffect, useRef } from "react";
import { songSchema } from "@/lib/types";
export type MusicCardProps = z.infer<typeof songSchema>;
export function MusicCard({
title,
artist,
album,
preview,
link,
albumCover,
}: MusicCardProps) {
// ...
}
Bạn có thể tìm mã đầy đủ cho thành phần này tại đây. Lưu ý rằng chúng ta cũng đang sử dụng các loại từ bước 2.
5. Đăng ký công cụ và thành phần với Tambo
Bước cuối cùng là tích hợp cả công cụ tìm kiếm nhạc và thành phần miniplayer vào mẫu chatbot AI. Điều này có thể được thực hiện đơn giản bằng cách đăng ký các phần tử này (và các định nghĩa loại của chúng) với Tambo.
Để làm điều đó, hãy thay thế toàn bộ nội dung của src/lib/tambo.ts bằng mã sau:
typescript
"use client";
// Tệp cấu hình trung tâm cho các thành phần và công cụ Tambo
// Đọc thêm về Tambo tại https://tambo.co/docs
import { TamboComponent, TamboTool } from "@tambo-ai/react";
import { MusicCard } from "@/components/ui/music-card";
import { searchMusic } from "@/services/music-search";
import { songSchema, searchMusicSchema } from "@/lib/types";
// Các công cụ Tambo đã đăng ký cho AI sử dụng.
export const tools: TamboTool[] = [
{
name: "searchMusic",
description: "Tìm kiếm nhạc theo tiêu đề bài hát, tên nghệ sĩ hoặc bất kỳ truy vấn liên quan đến nhạc nào.",
tool: searchMusic,
toolSchema: searchMusicSchema,
},
];
// Các thành phần Tambo đã đăng ký cho AI sử dụng.
export const components: TamboComponent[] = [
{
name: "MusicCard",
description: "Một thành phần phát bài hát từ Deezer.",
component: MusicCard,
propsSchema: songSchema,
},
];
Kết luận
Đó là tất cả! Ứng dụng của bạn bây giờ nên hoạt động (hoặc hãy cho tôi biết 😉). Còn rất nhiều điều khác có thể thêm vào, như trạng thái tải cho thành phần miniplayer và bất kỳ công cụ hoặc thành phần bổ sung nào mà bạn có thể nghĩ đến.
Hãy tham gia Discord của Tambo để xem thêm các dự án bạn có thể xây dựng với Tambo!
Thực hành tốt nhất
- Luôn kiểm tra mã: Trước khi triển khai, hãy đảm bảo rằng mã của bạn đã được kiểm tra đầy đủ để tránh lỗi.
- Sử dụng quản lý trạng thái: Đối với các ứng dụng phức tạp hơn, hãy xem xét sử dụng một thư viện quản lý trạng thái như Redux hoặc Context API.
Cạm bẫy phổ biến
- Không xử lý lỗi API: Hãy chắc chắn rằng bạn có các phương thức xử lý lỗi khi truy vấn API để cải thiện trải nghiệm người dùng.
- Thiếu tài liệu cho mã: Viết tài liệu cho mã của bạn giúp người khác (và cả bạn trong tương lai) hiểu rõ hơn.
Lời khuyên về hiệu suất
- Tối ưu hóa tải trang: Sử dụng lazy loading cho các thành phần không cần thiết phải tải ngay lập tức.
- Giảm thiểu gọi API: Chỉ gọi API khi cần thiết và sử dụng cache để giảm tải.
Câu hỏi thường gặp
- Tambo là gì?
Tambo là một framework UI sinh ra mã nguồn mở cho phép xây dựng ứng dụng một cách nhanh chóng và dễ dàng. - API Deezer có miễn phí không?
Có, API Deezer có sẵn miễn phí cho người dùng, nhưng có một số giới hạn về số lượng yêu cầu.
Hy vọng bài viết này sẽ hữu ích cho bạn trong việc xây dựng một chatbot Alexa với Tambo và Deezer!