Open7
【Ruby】AWS S3から音声ファイルをダウンロードし、Whisper API → ChatGPT APIへ渡す
やりたいこと
- 会議の議事録の音声ファイルなどをS3にあげておき、自動で分析・要約作成などをしたい
- これをRubyのプログラムで作ってみる
流れ
- Ruby(on Rails)のプロジェクトから、S3へアクセスし、.wavファイルをダウンロード
- Whisper APIに送り書き起こし
- さらにChatGPT APIに送り分析
RubyプロジェクトからS3にアクセスする
- AWS SDK for Rubyを用いる
- RailsのActiveStorageでもAWSへのアクセスは可能だが、modelと紐づかない場合には推奨されない模様
- 参考までに
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回りの処理の中身はこうらしい
Whisper APIにわたす
- 公式の仕様書
- WhisperAPIにアクセスする専用のクラスを作る
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
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
つなぎこむ
- 最後にこれらすべてをつなぎ込んで出力
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
S3へアップロードするための署名付きURLを発行する
- AWS公式GitHubのサンプルコード
- AWS公式doc
- なぜ署名付きURLを発行したいか?という理由はこれ(自分自身のスクラップ)