Dalam catatan blog hari ini, kami akan membina AI Assistant menggunakan tiga model AI berbeza: Whisper dan TTS daripada OpenAI dan Llama 3.1 daripada Meta.
Semasa meneroka AI, saya ingin mencuba pelbagai perkara dan mencipta pembantu AI yang berfungsi melalui suara. Rasa ingin tahu ini mendorong saya untuk menggabungkan model OpenAI's Whisper dan TTS dengan Meta's Llama 3.1 untuk membina pembantu yang diaktifkan suara.
Begini cara model ini akan berfungsi bersama:
Mari menyelami dan mula membina Pembantu AI yang sangat baik ini!
Kami akan menggunakan alat yang berbeza untuk membina pembantu kami. Untuk membina bahagian pelanggan kami, kami akan menggunakan Next.js. Walau bagaimanapun, anda boleh memilih mana-mana rangka kerja yang anda suka.
Untuk menggunakan model OpenAI kami, kami akan menggunakan TypeScript / JavaScript SDK mereka. Untuk menggunakan API ini, kami memerlukan pembolehubah persekitaran berikut: OPENAI_API_KEY—
Untuk mendapatkan kunci ini, kita perlu log masuk ke papan pemuka OpenAI dan cari bahagian kunci API. Di sini, kita boleh menjana kunci baharu.
Hebat. Kini, untuk menggunakan model Llama 3.1 kami, kami akan menggunakan Ollama dan Vercel AI SDK, menggunakan penyedia yang dipanggil ollama-ai-provider.
Ollama akan membenarkan kami memuat turun model pilihan kami (malah kami boleh menggunakan model lain, seperti Phi) dan menjalankannya secara tempatan. SDK Vercel akan memudahkan penggunaannya dalam projek Next.js kami.
Untuk menggunakan Ollama, kami hanya perlu memuat turunnya dan memilih model pilihan kami. Untuk catatan blog ini, kami akan memilih Llama 3.1. Selepas memasang Ollama, kami boleh mengesahkan sama ada ia berfungsi dengan membuka terminal kami dan menulis arahan berikut:
Perhatikan bahawa saya menulis "llama3.1" kerana itu model pilihan saya, tetapi anda harus menggunakan model yang anda muat turun.
Sudah tiba masanya untuk memulakan sesuatu dengan menyediakan apl Next.js kami. Mari mulakan dengan arahan ini:
npx create-next-app@latest
Selepas menjalankan arahan, anda akan melihat beberapa gesaan untuk menetapkan butiran apl. Jom ikut langkah demi langkah:
Langkah lain adalah pilihan dan terpulang kepada anda sepenuhnya. Dalam kes saya, saya juga memilih untuk menggunakan TypeScript dan Tailwind CSS.
Sekarang selesai, mari masuk ke projek kami dan pasang kebergantungan yang kami perlukan untuk menjalankan model kami:
npx create-next-app@latest
Kini, matlamat kami adalah untuk merakam suara kami, menghantarnya ke bahagian belakang, dan kemudian menerima respons suara daripadanya.
Untuk merakam audio kami, kami perlu menggunakan fungsi sisi klien, yang bermaksud kami perlu menggunakan komponen klien. Dalam kes kami, kami tidak mahu mengubah keseluruhan halaman kami untuk menggunakan keupayaan pelanggan dan mempunyai keseluruhan pokok dalam berkas pelanggan; sebaliknya, kami lebih suka menggunakan komponen Pelayan dan mengimport komponen pelanggan kami untuk meningkatkan aplikasi kami secara progresif.
Jadi, mari buat komponen berasingan yang akan mengendalikan logik pihak klien.
Di dalam folder apl kami, mari buat folder komponen, dan di sini, kami akan mencipta komponen kami:
npm i ai ollama-ai-provider openai
Mari teruskan dan mulakan komponen kami. Saya teruskan dan menambah butang dengan beberapa gaya di dalamnya:
app ↳components ↳audio-recorder.tsx
Dan kemudian importnya ke dalam komponen Pelayan Halaman kami:
// app/components/audio-recorder.tsx 'use client' export default function AudioRecorder() { function handleClick(){ console.log('click') } return ( <section> <button onClick={handleClick} className={`bg-blue-500 text-white px-4 py-2 rounded shadow-md hover:bg-blue-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-white transition duration-300 ease-in-out absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2`}> Record voice </button> </section> ) }
Sekarang, jika kami menjalankan apl kami, kami akan melihat perkara berikut:
Hebat! Sekarang, butang kami tidak melakukan apa-apa, tetapi matlamat kami adalah untuk merakam audio kami dan menghantarnya ke suatu tempat; untuk itu, mari kita buat cangkuk yang akan mengandungi logik kita:
// app/page.tsx import AudioRecorder from '@/app/components/audio-recorder'; export default function Home() { return ( <AudioRecorder /> ); }
Kami akan menggunakan dua API untuk merakam suara kami: navigator dan MediaRecorder. API navigator akan memberi kami maklumat tentang peranti media pengguna seperti audio media pengguna, dan MediaRecorder akan membantu kami merakam audio daripadanya. Beginilah mereka akan bermain bersama:
app ↳hooks ↳useRecordVoice.ts import { useEffect, useRef, useState } from 'react'; export function useRecordVoice() { return {} }
Mari terangkan kod ini langkah demi langkah. Pertama, kami mewujudkan dua negeri baharu. Yang pertama adalah untuk menjejaki masa kami merakam, dan yang kedua menyimpan tika MediaRecorder kami.
// apps/hooks/useRecordVoice.ts import { useEffect, useRef, useState } from 'react'; export function useRecordVoice() { const [isRecording, setIsRecording] = useState(false); const [mediaRecorder, setMediaRecorder] = useState<MediaRecorder | null>(null); const startRecording = async () => { if(!navigator?.mediaDevices){ console.error('Media devices not supported'); return; } const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); const mediaRecorder = new MediaRecorder(stream); setIsRecording(true) setMediaRecorder(mediaRecorder); mediaRecorder.start(0) } const stopRecording = () =>{ if(mediaRecorder) { setIsRecording(false) mediaRecorder.stop(); } } return { isRecording, startRecording, stopRecording, } }
Kemudian, kami akan mencipta kaedah pertama kami, startRecording. Di sini, kita akan mempunyai logik untuk mula merakam audio kita.
Kami mula-mula menyemak sama ada pengguna mempunyai peranti media yang tersedia terima kasih kepada API navigator yang memberi kami maklumat tentang persekitaran penyemak imbas pengguna kami:
Jika kami tidak mempunyai peranti media untuk merakam audio kami, kami hanya kembali. Jika mereka berbuat demikian, maka izinkan kami membuat strim menggunakan peranti media audio mereka.
const [isRecording, setIsRecording] = useState(false); const [mediaRecorder, setMediaRecorder] = useState<MediaRecorder | null>(null);
Akhir sekali, kami meneruskan dan mencipta contoh MediaRecorder untuk merakam audio ini:
npx create-next-app@latest
Kemudian kami memerlukan kaedah untuk menghentikan rakaman kami, yang akan menjadi stopRecording kami. Di sini, kami hanya akan menghentikan rakaman kami sekiranya perakam media wujud.
npm i ai ollama-ai-provider openai
Kami sedang merakam audio kami, tetapi kami tidak menyimpannya di mana-mana. Mari tambahkan useEffect dan rujukan baharu untuk mencapai ini.
Kami memerlukan rujukan baharu, dan di sinilah cebisan data audio kami akan disimpan.
app ↳components ↳audio-recorder.tsx
Dalam useEffect kami akan melakukan dua perkara utama: simpan bahagian tersebut dalam ref kami, dan apabila ia berhenti, kami akan mencipta Blob baharu jenis audio/mp3:
// app/components/audio-recorder.tsx 'use client' export default function AudioRecorder() { function handleClick(){ console.log('click') } return ( <section> <button onClick={handleClick} className={`bg-blue-500 text-white px-4 py-2 rounded shadow-md hover:bg-blue-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-white transition duration-300 ease-in-out absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2`}> Record voice </button> </section> ) }
Sudah tiba masanya untuk menyambungkan cangkuk ini dengan komponen AudioRecorder kami:
// app/page.tsx import AudioRecorder from '@/app/components/audio-recorder'; export default function Home() { return ( <AudioRecorder /> ); }
Jom pergi ke bahagian lain syiling, bahagian belakang!
Kami mahu menggunakan model kami pada pelayan untuk memastikan keadaan selamat dan berjalan dengan lebih pantas. Mari buat laluan baharu dan tambahkan pengendali untuknya menggunakan pengendali laluan daripada Next.js. Dalam folder Apl kami, mari buat folder "Api" dengan laluan berikut di dalamnya:
Kami mahu menggunakan model kami pada pelayan untuk memastikan keadaan selamat dan berjalan dengan lebih pantas. Mari buat laluan baharu dan tambahkan pengendali untuknya menggunakan pengendali laluan daripada Next.js. Dalam folder Apl kami, mari buat folder "Api" dengan laluan berikut di dalamnya:
app ↳hooks ↳useRecordVoice.ts import { useEffect, useRef, useState } from 'react'; export function useRecordVoice() { return {} }
Laluan kami dipanggil 'sembang'. Dalam fail route.ts, kami akan menyediakan pengendali kami. Mari mulakan dengan menyediakan SDK OpenAI kami.
// apps/hooks/useRecordVoice.ts import { useEffect, useRef, useState } from 'react'; export function useRecordVoice() { const [isRecording, setIsRecording] = useState(false); const [mediaRecorder, setMediaRecorder] = useState<MediaRecorder | null>(null); const startRecording = async () => { if(!navigator?.mediaDevices){ console.error('Media devices not supported'); return; } const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); const mediaRecorder = new MediaRecorder(stream); setIsRecording(true) setMediaRecorder(mediaRecorder); mediaRecorder.start(0) } const stopRecording = () =>{ if(mediaRecorder) { setIsRecording(false) mediaRecorder.stop(); } } return { isRecording, startRecording, stopRecording, } }
Dalam laluan ini, kami akan menghantar audio dari bahagian hadapan sebagai rentetan base64. Kemudian, kami akan menerimanya dan mengubahnya menjadi objek Penampan.
const [isRecording, setIsRecording] = useState(false); const [mediaRecorder, setMediaRecorder] = useState<MediaRecorder | null>(null);
Sudah tiba masanya untuk menggunakan model pertama kami. Kami mahu menukar audio ini kepada teks dan menggunakan model Whisper Speech-To-Text OpenAI. Whisper memerlukan fail audio untuk mencipta teks. Memandangkan kami mempunyai Penampan dan bukannya fail, kami akan menggunakan kaedah 'toFile' mereka untuk menukar Penimbal audio kami kepada fail audio seperti ini:
// check if they have media devices if(!navigator?.mediaDevices){ console.error('Media devices not supported'); return; } // create stream using the audio media device const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
Perhatikan bahawa kami menentukan "mp3". Ini adalah salah satu daripada banyak sambungan yang boleh digunakan oleh model Whisper. Anda boleh melihat senarai penuh sambungan yang disokong di sini: https://platform.openai.com/docs/api-reference/audio/createTranscription#audio-createtranscription-file
Setelah fail kami sedia, mari serahkan kepada Whisper! Menggunakan contoh OpenAI kami, ini adalah cara kami akan menggunakan model kami:
// create an instance passing in the stream as parameter const mediaRecorder = new MediaRecorder(stream); // Set this state to true to setIsRecording(true) // Store the instance in the state setMediaRecorder(mediaRecorder); // Start recording inmediately mediaRecorder.start(0)
Itu sahaja! Sekarang, kita boleh beralih ke langkah seterusnya: menggunakan Llama 3.1 untuk mentafsir teks ini dan memberi kita jawapan. Kami akan menggunakan dua kaedah untuk ini. Mula-mula, kami akan menggunakan 'ollama' daripada pakej 'ollama-ai-provider', yang membolehkan kami menggunakan model ini dengan Ollama kami yang dijalankan secara tempatan. Kemudian, kami akan menggunakan 'generateText' daripada Vercel AI SDK untuk menjana teks.
Nota sampingan: Untuk menjadikan Ollama kami dijalankan secara setempat, kami perlu menulis arahan berikut dalam terminal:
npx create-next-app@latest
npm i ai ollama-ai-provider openai
Akhir sekali, kami mempunyai model terakhir kami: TTS daripada OpenAI. Kami ingin membalas kepada pengguna kami dengan audio, jadi model ini akan sangat membantu. Ia akan menukar teks kita kepada ucapan:
app ↳components ↳audio-recorder.tsx
Model TTS akan menukar respons kami kepada fail audio. Kami mahu menstrim audio ini kembali kepada pengguna seperti ini:
// app/components/audio-recorder.tsx 'use client' export default function AudioRecorder() { function handleClick(){ console.log('click') } return ( <section> <button onClick={handleClick} className={`bg-blue-500 text-white px-4 py-2 rounded shadow-md hover:bg-blue-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus:ring-offset-white transition duration-300 ease-in-out absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2`}> Record voice </button> </section> ) }
Dan itu sahaja keseluruhan kod bahagian belakang! Sekarang, kembali ke bahagian hadapan untuk menyelesaikan pendawaian semuanya.
Dalam cangkuk useRecordVoice.tsx kami, mari buat kaedah baharu yang akan memanggil titik akhir API kami. Kaedah ini juga akan mengambil semula respons dan memainkan audio yang kami strimkan kepada pengguna dari bahagian belakang.
// app/page.tsx import AudioRecorder from '@/app/components/audio-recorder'; export default function Home() { return ( <AudioRecorder /> ); }
Hebat! Kini setelah kami mendapat respons yang distrim, kami perlu mengendalikannya dan memainkan semula audio kepada pengguna. Kami akan menggunakan API AudioContext untuk ini. API ini membolehkan kami menyimpan audio, menyahkodnya dan memainkannya kepada pengguna setelah ia sedia:
app ↳hooks ↳useRecordVoice.ts import { useEffect, useRef, useState } from 'react'; export function useRecordVoice() { return {} }
Dan itu sahaja! Kini pengguna harus mendengar respons audio pada peranti mereka. Untuk menyelesaikan masalah, mari jadikan apl kami lebih bagus dengan menambahkan sedikit penunjuk pemuatan:
// apps/hooks/useRecordVoice.ts import { useEffect, useRef, useState } from 'react'; export function useRecordVoice() { const [isRecording, setIsRecording] = useState(false); const [mediaRecorder, setMediaRecorder] = useState<MediaRecorder | null>(null); const startRecording = async () => { if(!navigator?.mediaDevices){ console.error('Media devices not supported'); return; } const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); const mediaRecorder = new MediaRecorder(stream); setIsRecording(true) setMediaRecorder(mediaRecorder); mediaRecorder.start(0) } const stopRecording = () =>{ if(mediaRecorder) { setIsRecording(false) mediaRecorder.stop(); } } return { isRecording, startRecording, stopRecording, } }
Dalam catatan blog ini, kami melihat cara menggabungkan berbilang model AI boleh membantu kami mencapai matlamat kami. Kami belajar menjalankan model AI seperti Llama 3.1 secara tempatan dan menggunakannya dalam apl Next.js kami. Kami juga menemui cara untuk menghantar audio kepada model ini dan menstrim kembali respons, memainkan semula audio kepada pengguna.
Ini hanyalah salah satu daripada banyak cara anda boleh menggunakan AI—kemungkinan tidak berkesudahan. Model AI ialah alat hebat yang membolehkan kami mencipta perkara yang dahulunya sukar dicapai dengan kualiti sedemikian. Terima kasih kerana membaca; kini, giliran anda untuk membina sesuatu yang menakjubkan dengan AI!
Anda boleh mendapatkan demo lengkap di GitHub: AI Assistant dengan Whisper TTS dan Ollama menggunakan Next.js
Atas ialah kandungan terperinci Cara membina pembantu AI dengan OpenAI, Vercel AI SDK dan Ollama dengan Next.js. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!