ChatGPTとは?
ChatGPTとは何でしょうか?
本人に聞いてみました。
おお、模範解答(?)ですね。
このように、ChatGPTとは、
AIの一種で、人間が質問したものに対して、
応答してくれます。
その精度や、回答が人間味があることで
話題になりましたね。
実際に色々試してみると、
面白いと思います。
「夏目漱石風に好きな人に告白してみて」とか、
「東京23区で一番勝ち組なのはどこ?」みたいな
アホみたいな質問にも回答してくれます。
「エッセイを作成して」とか、
しりとりの相手もしてくれます。
すごいですね笑
Vue.jsからChatGPT APIを叩いて話しかけた回答内容をずんだもんに喋ってもらう
※下記のコードは、Vue.jsの概要で実装したコードをもとに実装しているので、
まずは、こちらの記事でVue.jsのセットアップを済ませてからだと、
同じようにハンズオンできます。
まずは、Vue.jsのルーティングに、
ChatGPTにアクセスするページを追加します。
{
path: '/chat',
name: 'chat',
component: () => import('../components/Chat.vue')
}
axiosをインストールします。
docker compose exec front yarn add axios
肝心のChat.vueのファイルの、
コードの全体像は下記のようになります。
<template>
<v-row>
<v-col cols="4">
<v-card
class="mx-auto"
max-width="344"
variant="outlined"
>
<v-card-item>
<div class="text-overline mb-1">
入力したものをずんだもんに話してもらう
<v-text-field v-model="val"></v-text-field>
</div>
</v-card-item>
<v-card-actions>
<v-btn variant="outlined" v-on:click="buttonClicked">
送信
</v-btn>
</v-card-actions>
</v-card>
<audio class="audio"></audio>
</v-col>
<v-col cols="4">
<v-card
class="mx-auto"
max-width="344"
variant="outlined"
>
<v-card-item>
<div class="text-overline mb-1">
入力したものをChatGPTに飛ばす
<v-text-field v-model="chatgpt"></v-text-field>
</div>
</v-card-item>
<v-card-actions>
<v-btn variant="outlined" v-on:click="chatGptClick">
ChatGPTへ送信
</v-btn>
</v-card-actions>
</v-card>
<audio class="audio"></audio>
</v-col>
<v-col cols="4">
<v-card
class="mx-auto"
max-width="344"
variant="outlined"
>
<v-card-item>
ずんだもんに話しかける
</v-card-item>
<v-card-actions>
<v-btn variant="outlined" v-on:click="start">
開始
</v-btn>
<v-btn variant="outlined" v-on:click="end">
終了
</v-btn>
</v-card-actions>
</v-card>
<audio class="audio"></audio>
</v-col>
</v-row>
<v-row>
<v-col cols="12">
<div class="output"></div>
</v-col>
</v-row>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import axios from 'axios'
const buttonClicked = async () => {
await createAudio(val.value);
}
const chatGptClick = async () => {
const responseText = await requestChatAPI(chatgpt.value);
await createAudio(responseText)
const output = document.querySelector(".output");
output.textContent = responseText;
}
const val = ref('initial')
const chatgpt = ref('chatGPT initial')
async function createAudio(text) {
const audio = document.querySelector(".audio");
audio.src = await getAudioURL(text);
audio.play();
}
async function getAudioURL(text) {
const query = await getQuery(text);
const response = await axios.post(
"http://localhost:50021/synthesis?speaker=1",
query,
{ responseType: "blob" }
);
return URL.createObjectURL(response.data);
}
async function getQuery(text) {
const response = await axios.post(
`http://localhost:50021/audio_query?speaker=1&text=${text}`
);
return response.data;
}
const api_key = "各自のキー";
async function requestChatAPI(text) {
const headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${api_key}`,
};
const messages = [
{
role: "user",
content: text,
},
];
const payload = {
model: "gpt-3.5-turbo",
max_tokens: 128,
messages: messages,
};
const response = await axios.post(
"https://api.openai.com/v1/chat/completions",
payload,
{
headers: headers,
}
);
console.log('ChatGPT送信')
return response.data.choices[0].message.content;
}
const recognition = new webkitSpeechRecognition();
const language = "ja";
recognition.lang = language;
recognition.interimResults = true;
recognition.continuous = true;
recognition.onresult = handleResult;
async function handleResult(event) {
let finalTranscript = '';
for (let i = event.resultIndex; i < event.results.length; i++) {
const transcript = event.results[i][0].transcript;
console.log(transcript);
if (event.results[i].isFinal) {
finalTranscript += transcript;
const responseText = await requestChatAPI(finalTranscript);
await createAudio(responseText);
const output = document.querySelector(".output");
output.textContent = responseText;
}
}
}
const start = () => {
recognition.start();
};
const stop = () => {
recognition.stop();
};
</script>
こんな感じになります。
上記のコードは、音声認識をして、
その内容をChatGPTに渡して、
回答結果をずんだもんに話してもらうという流れになっています。
一つずつ解説します。
音声認識をしている部分
まず、音声認識の部分ですが、
下記のコードです。
const recognition = new webkitSpeechRecognition();
const language = "ja";
recognition.lang = language;
recognition.interimResults = true;
recognition.continuous = true;
recognition.onresult = handleResult;
async function handleResult(event) {
let finalTranscript = '';
for (let i = event.resultIndex; i < event.results.length; i++) {
const transcript = event.results[i][0].transcript;
console.log(transcript);
if (event.results[i].isFinal) {
finalTranscript += transcript;
const responseText = await requestChatAPI(finalTranscript);
await createAudio(responseText);
const output = document.querySelector(".output");
output.textContent = responseText;
}
}
}
このコードは、Web Speech API を使用して音声認識を行い、認識されたテキストを使用してチャットボットとの対話を実現するためのものです。
最初に webkitSpeechRecognition() を使用して、新しい SpeechRecognition オブジェクトを作成します。
language 変数を定義し、認識される言語を指定します。この場合は、"ja" (日本語) が指定されています。
recognition.lang を使用して、認識される言語を設定します。
recognition.interimResults が true に設定されており、認識中に中間結果を取得することができます。
recognition.continuous が true に設定されており、ユーザーが話し続けている間に音声認識が継続します。
recognition.onresult には、認識結果が利用可能になったときに呼び出されるコールバック関数 handleResult が設定されています。
handleResult 関数は、event オブジェクトを引数に受け取り、認識されたテキストを使用してチャットボットとの対話を実現します。
音声認識の結果は event.results 配列に格納されており、for ループを使用してその中から認識されたテキストを取得しています。
event.results[i].isFinal が true の場合、認識が終了したことを示し、finalTranscript 変数に認識されたテキストが追加されます。
requestChatAPI() 関数を使用して、finalTranscript のテキストをチャットボット API に送信し、応答を受信します。
createAudio() 関数を使用して、チャットボットの応答を音声合成し、ユーザーに再生します。
最後に、output 変数を使用して、チャットボットの応答を表示します。
ChatGPTさん
せっかくなので、ChatGPTに処理の内容について説明してもらいました。
ずんだもんと連携している部分
ずんだもんは、VOICEVOXというアプリで使用できるキャラクターで、
可愛い声が特徴的です。
https://voicevox.hiroshiba.jp/
https://github.com/VOICEVOX/voicevox_engine
アプリをインストールして、
起動しておけば、localhost:50021にリッスンして、
リクエストを送れるようになります。
該当コードは、
async function createAudio(text) {
const audio = document.querySelector(".audio");
audio.src = await getAudioURL(text);
audio.play();
}
async function getAudioURL(text) {
const query = await getQuery(text);
const response = await axios.post(
"http://localhost:50021/synthesis?speaker=1",
query,
{ responseType: "blob" }
);
return URL.createObjectURL(response.data);
}
async function getQuery(text) {
const response = await axios.post(
`http://localhost:50021/audio_query?speaker=1&text=${text}`
);
return response.data;
}
このコードは、与えられたテキストを使用して音声合成して再生する関数 createAudio と、テキストを使用して音声データの URL を取得する関数 getAudioURL 、テキストを使用してチャットボット API に送信するためのクエリを作成する関数 getQuery から構成されています。
createAudio 関数は、与えられたテキストを使用して音声合成して再生する関数です。まず、 document.querySelector を使用して、 HTML 上の audio タグを取得します。次に、 getAudioURL 関数を使用して、与えられたテキストを使用して音声データの URL を取得します。最後に、 audio.play() を呼び出して音声を再生します。
getAudioURL 関数は、与えられたテキストを使用して音声データの URL を取得する関数です。まず、 getQuery 関数を使用して、与えられたテキストを使用してチャットボット API に送信するためのクエリを取得します。次に、axios.post を使用して、API に対してクエリを送信し、Blob データを取得します。最後に、URL.createObjectURL を使用して Blob データから URL を作成し、URL を返します。
getQuery 関数は、与えられたテキストを使用して、チャットボット API に送信するためのクエリを作成する関数です。axios.post を使用して、API に対してテキストを送信し、応答を受信します。そして、API から受け取った応答データを返します。
このコードは、非同期処理を使用して、API からの応答を待ってから次の処理を実行することができます。また、 URL.createObjectURL を使用して Blob データから URL を作成することで、オーディオ再生のための URL を直接取得することができます。
ChatGPTさん
基本正しいのですが、
getQuery関数は、VOICEBOXのAPIに送信するためのクエリーです
(ChatGPTさん、チャットボットAPIとは何者でしょうか?)
ChatGPT APIを叩いている部分
さて、いよいよChatGPT APIを叩いている部分ですが、
async function requestChatAPI(text) {
const headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${api_key}`,
};
const messages = [
{
role: "user",
content: text,
},
];
const payload = {
model: "gpt-3.5-turbo",
max_tokens: 128,
messages: messages,
};
const response = await axios.post(
"https://api.openai.com/v1/chat/completions",
payload,
{
headers: headers,
}
);
console.log('ChatGPT送信')
return response.data.choices[0].message.content;
}
このコードは、OpenAIのChat APIを使用して、テキストを受け取り、AIが生成したテキストを返すための関数です。
まず、Authorizationヘッダーを設定して、APIキーを含めます。次に、リクエストの本文として、ユーザーが入力したテキストを含むメッセージオブジェクトを作成します。そして、APIの使用モデル、最大トークン数、そしてメッセージオブジェクトを含むペイロードを定義します。
最後に、Axiosを使用して、OpenAIのAPIエンドポイントにPOSTリクエストを送信し、レスポンスを受け取ります。レスポンスには、AIによって生成されたテキストが含まれています。また、送信が成功したことを示すために、"ChatGPT送信"という文字列をコンソールに出力します。最後に、AIが生成したテキストを返します。
ChatGPTさん
ありがとうございます!ChatGPTさん!