Open7

【Ruby】AWS S3から音声ファイルをダウンロードし、Whisper API → ChatGPT APIへ渡す

だーら(Flamers / Memotia)だーら(Flamers / Memotia)

やりたいこと

  • 会議の議事録の音声ファイルなどをS3にあげておき、自動で分析・要約作成などをしたい
  • これをRubyのプログラムで作ってみる

流れ

  • Ruby(on Rails)のプロジェクトから、S3へアクセスし、.wavファイルをダウンロード
  • Whisper APIに送り書き起こし
  • さらにChatGPT APIに送り分析
だーら(Flamers / Memotia)だーら(Flamers / Memotia)

S3から.wavファイルを落としてくる

  • tempfileに保存することで、Whisper APIに渡せる(渡しやすく?)ようになる。
class S3Service
  REGION = "ap-northeast-1"
  BUCKET_NAME = "bucked-name"
  FILE_NAME = "MyRecording.wav"

  def self.fetch_wav_from_s3
    file = s3_client.get_object(bucket: BUCKET_NAME, key: FILE_NAME).body.read

    tempfile = Tempfile.new(%w('temp', '.wav'))
    tempfile.binmode
    tempfile.write(file)
    tempfile.rewind

    tempfile
  end

  private

  def self.s3_client
    Aws::S3::Client.new(
      region: REGION,
      access_key_id: ENV['AWS_ACCESS_KEY_ID'],
      secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
    )
  end
end
  • tempfile回りの処理の中身はこうらしい
だーら(Flamers / Memotia)だーら(Flamers / Memotia)

Whisper APIにわたす

class WhisperApiService
  MODEL_NAME = "whisper-1"
  API_URL = "https://api.openai.com/v1/audio/transcriptions"
  OPENAI_API_KEY = ENV['OPENAI_API_KEY']

  def self.send_to_whisper(audio_file)
    uri = URI.parse(API_URL)

    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER

    request = Net::HTTP::Post.new(uri.request_uri, {
      'Content-Type' => 'multipart/form-data',
      'Authorization' => "Bearer #{OPENAI_API_KEY}"
    })

    request.set_form([
                       ["file", audio_file],
                       ["model", MODEL_NAME]
                     ], "multipart/form-data")

    http.request(request)
  end
end
だーら(Flamers / Memotia)だーら(Flamers / Memotia)

ChatGPT APIにわたす

class ChatGptApiService
  API_URL = "https://api.openai.com/v1/chat/completions"
  OPENAI_API_KEY = ENV['OPENAI_API_KEY']

  def self.send_to_chat_gpt(prompt)
    uri = URI.parse(API_URL)

    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER

    request = Net::HTTP::Post.new(uri.request_uri, {
      'Content-Type' => 'application/json',
      'Authorization' => "Bearer #{OPENAI_API_KEY}"
    })

    request.body = JSON.dump({
     "model" => "gpt-3.5-turbo",
     "messages" => [{"role" => "user", "content" => prompt}]
    })

    http.request(request)
  end

end
だーら(Flamers / Memotia)だーら(Flamers / Memotia)

つなぎこむ

  • 最後にこれらすべてをつなぎ込んで出力
class AiTalkAnalyzeService

  def self.analyze_from_talk
    wav_file = S3Service.fetch_wav_from_s3

    whisper_response = WhisperApiService.send_to_whisper(wav_file)
    talk_script = JSON.parse(whisper_response.body)["text"]

    chat_gpt_response = ChatGptApiService.send_to_chat_gpt(build_gpt_prompt(talk_script))
    analysis_text = JSON.parse(chat_gpt_response.body)["choices"][0]["message"]["content"]

    analysis_text
  end

  private

  def self.build_gpt_prompt(talk_script)
    # てきとうにWhisperの文字列に枕詞をつけて整形
  end
end