メインコンテンツまでスキップ

音声文字起こしと音声生成

AIモデルを使用して、音声ファイルをテキストに文字起こしし、テキストから音声を生成します。​

AI Audio を使用する理由​

アプリケーションで音声を扱う必要がある場合があります。要約したい会議の録音、検索したいボイスメモ、または読み上げたい文章などです。これをゼロから構築するには、音声プロバイダーとの直接統合、APIキーの管理、ファイルアップロードの処理、フォーマット変換コードの記述が必要になります。

Squid AI Audio では、文字起こしと text-to-speech の両方を単一のバックエンド呼び出しで利用できます。

Backend code
// Transcribe an audio file to text
const text = await this.squid.ai().audio().transcribe(audioFile, {
modelName: 'whisper-1',
});

// Generate speech from text
const speechFile = await this.squid.ai().audio().createSpeech('Welcome to Squid', {
modelName: 'tts-1',
voice: 'nova',
});

概要​

Squid AI Audio は、単一の API の背後で OpenAI の Whisper(speech-to-text)モデルと TTS(text-to-speech)モデルをラップします。バックエンドからメソッドを呼び出すと、Squid が認証、ファイルアップロード、フォーマット変換、レスポンスのデコードを処理します。

AI Audio を使用する場面​

ユースケース推奨事項
音声を検索可能なテキストに変換するtranscribe()
合成音声でテキストを読み上げるcreateSpeech()
AI agent のチャット体験に音声入力を組み込むAI chat widget の enable-transcription フラグを使用
AI agent 用のカスタム音声voice options を持つ agents を使用
agent を電話通話やブラウザでのライブ音声会話に組み込むvoice agents を使用

仕組み​

  1. バックエンドサービスから this.squid.ai().audio().transcribe() または .createSpeech() を呼び出します。
  2. Squid バックエンドがリクエストを認証し、アプリケーション設定から OpenAI APIキーを検索して、呼び出しを転送します。
  3. 文字起こしでは、音声ファイルがモデルにストリーミングされ、文字起こし結果がテキストとして返されます。
  4. 音声生成では、モデルがバイナリ音声を返し、Squid がそれを File オブジェクト(TypeScript)または bytes(Python)でラップします。

クイックスタート​

前提条件​

  • squid init で初期化された Squid バックエンドプロジェクト
  • @squidcloud/backend パッケージ(TypeScript)または squidcloud-backend パッケージ(Python)
  • Squid Console でアプリケーションの AI provider として設定された OpenAI

ステップ 1: 音声呼び出しをラップする executable を作成する​

音声操作には Squid リソースへの admin access が必要なため、バックエンドで実行する必要があります。クライアントが安全に呼び出せるよう、executable でラップします。

Backend code
import { executable, SquidFile, SquidService } from '@squidcloud/backend';

export class AudioService extends SquidService {
@executable()
async transcribeAudio(audio: SquidFile): Promise<string> {
this.assertIsAuthenticated();

// SquidFile carries the original filename and MIME type from the client.
// Convert it to a native File so the audio client can stream it to OpenAI.
const file = new File([audio.data], audio.originalName, { type: audio.mimetype });

return this.squid.ai().audio().transcribe(file, {
modelName: 'whisper-1',
});
}
}

ステップ 2: バックエンドをデプロイするか、ローカルで実行する​

squid start

クラウドへのデプロイについては、バックエンドのデプロイを参照してください。

ステップ 3: クライアントから executable を呼び出す​

Client code
const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
const audioFile = fileInput.files![0];

const transcript = await squid.executeFunction('transcribeAudio', audioFile);
console.log(transcript);

認証と設定​

音声メソッドには、admin access を持つ認証済み Squid クライアントが必要です。これは transcribe() と createSpeech() の両方に当てはまります。推奨されるパターンは 2 つあります。

  1. 呼び出しを executables でラップする。 標準的なパターンです。executable は admin context でバックエンド上で実行され、クライアントが基盤となる APIキーを見ることはありません。executablesを参照してください。
  2. 権限を持つバックエンドサービスから呼び出す。 triggers、schedulers、webhooks、その他のバックエンド専用エントリポイントはすでにバックエンド権限で実行されるため、これらから音声メソッドを直接呼び出せます。

認証されていないブラウザクライアントからの呼び出しは、UNAUTHORIZED エラーで拒否されます。

OpenAI は Squid app で external service として有効にする必要があります。APIキーは Squid Console に保存され、音声クライアントはリクエスト時にそれを検索します。

コアコンセプト​

文字起こしモデル​

Squid は 3 種類の OpenAI 文字起こしモデルをサポートしています。

モデル備考
whisper-1デフォルト。最も幅広い response format をサポートし、最も低コストです。
gpt-4o-transcribe高精度。JSON のみを返します。
gpt-4o-mini-transcribegpt-4o-transcribe より小型かつ低コスト。JSON のみを返します。

文字起こしオプション​

AiAudioTranscribeOptions は modelName による discriminated union です。すべてのバリアントで、以下の基本フィールドを共有します。

フィールド型必須説明
modelNamestringはいサポートされる文字起こしモデルのいずれか
temperaturenumberいいえサンプリング温度
promptstringいいえ文字起こしを誘導する任意のテキスト(例: 固有名詞)

whisper-1 は追加で以下をサポートします。

フィールド型説明
responseFormatstring'json'、'text'、'srt'、'verbose_json'、'vtt' のいずれか。デフォルトは 'json'。

gpt-4o-transcribe と gpt-4o-mini-transcribe は 'json' のみを返します。

モデルの基盤となる response format にかかわらず、メソッドは常にプレーンな文字列を返します。

音声生成モデル​

モデル備考
tts-1より高速、低レイテンシ、やや低い忠実度
tts-1-hdより高い忠実度、低速
gpt-4o-mini-tts新しい GPT-4o ファミリーの TTS モデル

音声生成オプション​

AiAudioCreateSpeechOptions のフィールド:

フィールド型必須説明
modelNamestringはいサポートされる TTS モデルのいずれか
voicestringいいえ'alloy'、'ash'、'ballad'、'coral'、'echo'、'fable'、'onyx'、'nova'、'sage'、'shimmer'、'verse' のいずれか。デフォルトは 'alloy'。
responseFormatstringいいえ音声コンテナフォーマット。'mp3'、'opus'、'aac'、'flac'、'wav'、'pcm' のいずれか。デフォルトは 'mp3'。
instructionsstringいいえ音声スタイルに関する自由形式のガイダンス(例: 「ゆっくり、明瞭に話す」)
speednumberいいえ再生速度の倍率。デフォルトは 1.0。

戻り値の形式​

メソッドTypeScript の戻り値Python の戻り値
transcribe()Promise<string>str
createSpeech()Promise<File>bytes

TypeScript では、ファイルの MIME type と拡張子は responseFormat から推論されます。たとえば、responseFormat: 'mp3' を指定したリクエストは、MIME type が audio/mpeg の audio.mp3 という名前のファイルを返します。

コード例​

クライアントがアップロードした音声を文字起こしする​

Backend code
import { executable, SquidFile, SquidService } from '@squidcloud/backend';

export class AudioService extends SquidService {
@executable()
async transcribeRecording(audio: SquidFile, languageHint?: string): Promise<string> {
this.assertIsAuthenticated();

const file = new File([audio.data], audio.originalName, { type: audio.mimetype });

return this.squid.ai().audio().transcribe(file, {
modelName: 'whisper-1',
// Use the prompt to bias the model toward correct spellings or terminology.
prompt: languageHint,
});
}
}

音声を生成してクライアントに返す​

この例では、テキストから MP3 ファイルを作成し、クライアントが再生できるよう base64 として返します。

Backend code
import { executable, SquidService } from '@squidcloud/backend';

export class SpeechService extends SquidService {
@executable()
async narrate(text: string): Promise<{ base64: string; mimeType: string }> {
this.assertIsAuthenticated();

const audioFile = await this.squid.ai().audio().createSpeech(text, {
modelName: 'tts-1-hd',
voice: 'nova',
responseFormat: 'mp3',
speed: 1.0,
});

// Convert the File to base64 so it can travel back to the client over JSON.
const buffer = Buffer.from(await audioFile.arrayBuffer());
return {
base64: buffer.toString('base64'),
mimeType: audioFile.type,
};
}
}

生成した音声を長期保存する場合は、インラインで返すのではなく、結果を storage connector にアップロードしてください。

往復処理: 音声を生成してから再度文字起こしする​

integration test または sanity check に役立つパターンです。

Backend code
const speechFile = await this.squid.ai().audio().createSpeech('The quick brown fox jumps over the lazy dog.', {
modelName: 'tts-1',
});

const transcript = await this.squid.ai().audio().transcribe(speechFile, {
modelName: 'whisper-1',
});

console.log(transcript); // "The quick brown fox jumps over the lazy dog."

エラー処理​

一般的なエラー​

エラー原因解決策
UNAUTHORIZED音声呼び出しが non-admin context から発生した(例: バックエンドなしのブラウザ)呼び出しを executable でラップするか、バックエンドコードから呼び出す
Unsupported audio modelmodelName がサポート対象リストにないリストに記載された文字起こしモデルまたは TTS モデルを使用する
OpenAI external services are disabledアプリケーションで OpenAI が有効になっていないSquid Console で OpenAI を有効にし、APIキーを設定する
File too largeアップロードされた音声が上流プロバイダーの制限を超えているWhisper のアップロード上限は 25 MB です。このサイズを超える音声は分割または圧縮してください。

呼び出し前に入力を検証する​

OpenAI Whisper API は 25 MB より大きいファイルを拒否します。上流のエラーを待つのではなく、executable 内で大きすぎるアップロードを拒否してください。

Backend code
@executable()
async transcribeAudio(audio: SquidFile): Promise<string> {
this.assertIsAuthenticated();

const MAX_BYTES = 25 * 1024 * 1024;
if (audio.size > MAX_BYTES) {
throw new Error('Audio file exceeds 25 MB. Split or compress before transcribing.');
}

if (!audio.mimetype.startsWith('audio/')) {
throw new Error('Only audio files are accepted');
}

const file = new File([audio.data], audio.originalName, { type: audio.mimetype });
return this.squid.ai().audio().transcribe(file, { modelName: 'whisper-1' });
}

ベストプラクティス​

  1. 音声呼び出しは常に executables でラップする。 音声メソッドには admin access が必要です。ブラウザから直接公開すると、APIキーが漏洩し、認証がバイパスされます。
  2. transcribe() を呼び出す前に、ファイルサイズと MIME type を検証する。 上流プロバイダーにも独自の制限があり、不正な入力を早期に拒否することで、ユーザーによりよいエラーメッセージを提供できます。
  3. 文字起こしでは prompt フィールドを使用する。 ドメイン固有の語彙、固有名詞、想定される言語を渡します。これは精度を向上させる最も低コストな方法です。
  4. **ストリーミングまたは低レイテンシ UX には tts-1 を選択し、**レイテンシより品質が重要なオフラインアセットには tts-1-hd を選択します。
  5. 音声 executables に rate limiting を適用する。 音声生成と文字起こしはどちらも有料 API quota を消費します。
  6. 生成された音声をキャッシュする。 同じ入力に対する text-to-speech は、特定の voice では常に同じ出力を生成するため、キャッシュにより quota を節約できます。

関連項目​

  • Executables - クライアントから呼び出せるよう音声呼び出しをラップする
  • AI agent - 音声入力と出力を備えた AI agent を構築する
  • AI chat widget - chat widget は enable-transcription を通じて音声入力を公開する
  • Rate and quota limiting - 音声 executables を不正利用から保護する