見出し画像

ChatGPT-APIを使用した英会話学習システムの構築とその応用方法

英会話を学びたいが、オンライン英会話は頻度が高いと高額なので、chatGPTを先生として会話できたらいいのではないかと思い、英会話システムを構築することにした。

実際の挙動

  1. プログラムをターミナル等で実行する。

  2. まずはユーザがマイクに向かって話しかける。

  3. その発言に対しアシスタントが音声付きで応答。

  4. 2と3を繰り返す

主な要件

- 実行環境:macのターミナル
- 言語:Python(3系)
- API:OpenAIのGPT-3.5, Google Cloudのtext-to-speechとspeech-to-text

実際のコード

import io
import os
import json
import time
import audioop
import wave
import openai
import pyaudio
import pygame
from google.cloud import texttospeech, speech_v1p1beta1 as speech
from google.oauth2 import service_account

# Google APIの認証情報を設定
GOOGLE_APPLICATION_CREDENTIALS = "path/to/your/google-credentials.json"

# OpenAI APIキーの設定
openai.api_key = "your_openai_api_key"

# Google APIクライアントの初期化
credentials = service_account.Credentials.from_service_account_file(GOOGLE_APPLICATION_CREDENTIALS)
text_to_speech_client = texttospeech.TextToSpeechClient(credentials=credentials)
speech_to_text_client = speech.SpeechClient(credentials=credentials)

# 音声をテキストに変換
def speech_to_text(audio_data):
    config = speech.RecognitionConfig(
        encoding=speech.RecognitionConfig.AudioEncoding.LINEAR16,
        sample_rate_hertz=44100,
        language_code="en-US",
    )

    response = speech_to_text_client.recognize(config=config, audio=audio_data)
    return response.results[0].alternatives[0].transcript

# テキストを音声に変換
def text_to_speech(text, output_path):
    input_text = texttospeech.SynthesisInput(text=text)
    voice = texttospeech.VoiceSelectionParams(language_code="en-US", ssml_gender=texttospeech.SsmlVoiceGender.FEMALE)
    audio_config = texttospeech.AudioConfig(audio_encoding=texttospeech.AudioEncoding.MP3)

    response = text_to_speech_client.synthesize_speech(input=input_text, voice=voice, audio_config=audio_config)

    with open(output_path, "wb") as out:
        out.write(response.audio_content)

# ユーザの発話を録音
def record_audio(output_file):
    CHUNK = 1024
    FORMAT = pyaudio.paInt16
    CHANNELS = 1
    RATE = 44100
    SILENCE_THRESHOLD = 300  # 無音判定のしきい値
    SILENCE_DURATION = 1.5  # 無音が続く秒数

    p = pyaudio.PyAudio()

    stream = p.open(format=FORMAT,
                    channels=CHANNELS,
                    rate=RATE,
                    input=True,
                    frames_per_buffer=CHUNK)

    print("話してください...")

    frames = []
    silence_start_time = None

    while True:
        data = stream.read(CHUNK)
        frames.append(data)
        current_volume = max(audioop.rms(data, 2) for _ in range(0, len(data), CHUNK))

        if current_volume < SILENCE_THRESHOLD:
            if silence_start_time is None:
                silence_start_time = time.time()
            elif time.time() - silence_start_time > SILENCE_DURATION:
                break
        else:
            silence_start_time = None

    print("録音終了")

    stream.stop_stream()
    stream.close()
    p.terminate()

    wf = wave.open(output_file, 'wb')
    wf.setnchannels(CHANNELS)
    wf.setsampwidth(p.get_sample_size(FORMAT))
    wf.setframerate(RATE)
    wf.writeframes(b''.join(frames))
    wf.close()

def generate_response(messages):
    chat_messages = [{"role": "system", "content": "You are a helpful assistant. Your task is to help users practice English."}]
    chat_messages.extend(messages)

    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=chat_messages,
        max_tokens=50,
        n=1,
        temperature=0.5,
    )

    return response.choices[0].message['content'].strip()


# 追加: 音声ファイルを再生
def play_audio_file(filepath):
    pygame.mixer.init()
    pygame.mixer.music.load(filepath)
    pygame.mixer.music.play()
    while pygame.mixer.music.get_busy():
        pygame.time.Clock().tick(10)
    pygame.mixer.quit()

def main():
    print("英語学習サービスへようこそ! 終了するには 'quit' と言ってください。")

    messages = []

    while True:
        # ユーザの発話を録音
        user_audio_file = "user_audio.wav"
        record_audio(user_audio_file)

        # 録音した音声をテキストに変換
        with io.open(user_audio_file, "rb") as audio_file:
            content = audio_file.read()
        audio = speech.RecognitionAudio(content=content)
        user_text = speech_to_text(audio)
        print("ユーザーの入力:", user_text)

        # ユーザが終了を要求した場合、ループを抜ける
        if user_text.lower() == "quit":
            print("英語学習サービスを終了します。")
            break

        messages.append({"role": "user", "content": user_text})

        # ChatGPTで返答を生成
        gpt_response = generate_response(messages)
        print("ChatGPTの返答:", gpt_response)

        messages.append({"role": "assistant", "content": gpt_response})

        # 返答を音声に変換して再生
        output_audio_file = "gpt_response.mp3"
        text_to_speech(gpt_response, output_audio_file)
        play_audio_file(output_audio_file)

if __name__ == "__main__":
    main()

Q&A

Q. 文脈は理解する?
A. 理解します。しかし文脈を理解させて稼働させるとAPIの負荷が多くなるため金額的に使いすぎ注意。文脈の回数を制限する方法は後述で。

Q. 音声認識はどこで区切れる?
A. 話しかけずに数秒(プログラムでは1.5秒)経つと、自動で音声認識がストップする

Q. どうやって作った?
A. GPT4に「pythonのプログラムで、ユーザが発話し、chatGPTが返答するような英語学習サービスを作成したいです。 ユーザの発話はテキストに変換され、chatGPTの返答は音声に変換されます。発話からテキストの変換と テキストから音声の変換は googleクラウドプラットフォームのAPIを使用してください。実際に動作するプログラムをステップバイステップで考えてください」と打ちました。あとはエラー文など出たらそのままコピペ。

最後に

率直に……貧乏学生なので投げ銭を下さるとありがたいです。この英会話システムに関するTipsやアップデート等あれば随時更新していく予定です。

  • 文脈を保存する回数を制限する方法

  • アシスタントを自分好みに変換

  • 日本語の話し相手アシスタントとして活躍してもらう
    などなど……

文脈を保存する回数を制限する方法

main関数に古いメッセージを削除する機能を追加します。この例では文脈を4回まで保存する例です。

def main():
    print("英語学習サービスへようこそ! 終了するには 'quit' と言ってください。")

    messages = []

    while True:
        # ユーザの発話を録音
        user_audio_file = "user_audio.wav"
        record_audio(user_audio_file)

        # 録音した音声をテキストに変換
        with io.open(user_audio_file, "rb") as audio_file:
            content = audio_file.read()
        audio = speech.RecognitionAudio(content=content)
        user_text = speech_to_text(audio)
        print("ユーザーの入力:", user_text)

        # ユーザが終了を要求した場合、ループを抜ける
        if user_text.lower() == "quit":
            print("英語学習サービスを終了します。")
            break

        messages.append({"role": "user", "content": user_text})

        # 会話の文脈が4回を超えた場合、古いメッセージを削除
        if len(messages) > 4:
            messages.pop(0)  # ユーザーの古いメッセージを削除
            messages.pop(0)  # アシスタントの古いメッセージを削除

        # ChatGPTで返答を生成
        gpt_response = generate_response(messages)
        print("ChatGPTの返答:", gpt_response)

        messages.append({"role": "assistant", "content": gpt_response})

        # 返答を音声に変換して再生
        output_audio_file = "gpt_response.mp3"
        text_to_speech(gpt_response, output_audio_file)
        play_audio_file(output_audio_file)

if __name__ == "__main__":
    main()

アシスタントを自分好みに変換

generate_response関数内の"content": ~~~~のところを修正します。

def generate_response(messages):
    chat_messages = [{"role": "system", "content": "#Instructions : You are an American professional English teacher. Please chat with me under the following constraints.  #Constraints:  I am a beginner in English. You can choose the topic for our conversation. We will take turns writing one sentence at a time. If you notice any grammatical errors in my sentences, please correct them and explain why you made the correction."}]
    chat_messages.extend(messages)

    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=chat_messages,
        max_tokens=50,
        n=1,
        temperature=0.5,
    )

    return response.choices[0].message['content'].strip()

#Instructions : You are an American professional English teacher. Please chat with me under the following constraints. #Constraints: I am a beginner in English. You can choose the topic for our conversation. We will take turns writing one sentence at a time. If you notice any grammatical errors in my sentences, please correct them and explain why you made the correction.

という文章に変換することで、より英会話の先生として優秀かつ親切になります。このプロンプトは、[コピペでOK!ChatGPT×英語学習に使える「深津式汎用プロンプト」まとめ] https://thepast.jp/blog/the-ultimate-guide-for-using-chatgpt-for-english-learning/ を参考にさせていただきました。他にも英会話学習にChatGPTを使うアイデアが沢山紹介されております。

日本語の話し相手アシスタントとして活躍してもらう

2点変更します。

ステップ1:speech_to_text関数とtext_to_speech関数の言語設定を日本語("ja-JP")に変更

def speech_to_text(audio):
    config = speech.RecognitionConfig(
        encoding=speech.RecognitionConfig.AudioEncoding.LINEAR16,
        sample_rate_hertz=16000,
        language_code="ja-JP",  # en-USとなっている部分を変更
    )
def text_to_speech(text, output_audio_file):
    synthesis_input = texttospeech.SynthesisInput(text=text)
    voice = texttospeech.VoiceSelectionParams(
        language_code="ja-JP",  # en-USとなっている部分を変更
        ssml_gender=texttospeech.SsmlVoiceGender.FEMALE,
    )

ステップ2:generate_response関数内の"content": ~~~~のところを修正

def generate_response(messages):
    chat_messages = [{"role": "system", "content": "あなたはユーザの良き話し相手です。SF映画に出てくるような賢いアシスタントのような応答をします。"}]
    chat_messages.extend(messages)

    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=chat_messages,
        max_tokens=50,
        n=1,
        temperature=0.5,
    )

    return response.choices[0].message['content'].strip()

あなたはユーザの良き話し相手です。SF映画に出てくるような賢いアシスタントのような応答をします。

という文章に変更しました。実行の様子はこちら

学生をやりながら将来のために頑張っておりまして、今後の励みになりますので投げ銭を頂けますと幸いです。

この記事が参加している募集

AIとやってみた

この記事が気に入ったらサポートをしてみませんか?