AWS Step FunctionsとBedrockで作る!AIラジオ自動生成システム
こんにちは!今回は、AWSのサーバーレスサービスを組み合わせて、AIが台本を作成し、音声合成してラジオ番組を自動生成するシステムを作りました🎙️
作ったもの
「AWS情報ニュース」という架空のラジオ番組を自動生成するシステムです。
主な機能:
ユーザーがテーマを入力
Amazon BedrockのAIが台本を自動生成
メールで承認フローを実装
Amazon Pollyで音声合成
BGM・ジングルを自動で合成
最終的なMP3ファイルをS3に保存
AIPollyと対話形式のラジオ
セリフの長さに応じて無音の音声を挟んであとで声をあてる

システム構成
A[ユーザー入力] --> B[Step Functions開始]
B --> C[Bedrock台本生成]
C --> D[SESでメール送信]
D --> E[人間による承認]
E --> F[台本分割処理]
F --> G[Polly音声合成<br/>並列処理]
G --> H[音声ファイル結合<br/>BGM・ジングル追加]
H --> I[S3に完成音声保存]
使用技術
AWS CDK (TypeScript)
AWS Step Functions - ワークフロー管理
Amazon Bedrock - AI台本生成
Amazon Polly - 音声合成
Amazon SES - メール送信
AWS Lambda - 各種処理
Amazon S3 - ファイル保存
API Gateway - Web UI
FFmpeg - 音声編集
実装のポイント
1. Step Functionsでワークフロー管理
// lib/aws_radio-stack.ts
const chain = genTask
.next(mailTask)
.next(approvalTask)
.next(splitTask)
.next(synthesizeMap)
.next(mergeTask);
const sm = new sfn.StateMachine(this, "PodcastWorkflow", {
definition: chain,
timeout: cdk.Duration.hours(2),
});
各ステップを順次実行し、エラーハンドリングやリトライも自動で管理されます。
2. Bedrockで台本自動生成
// lambda/generate-script/index.ts
const prompt = `
あなたは「AWS情報ニュース」という8分のラジオ番組の台本作成者です。「${title}」というテーマで、「kazuha」 と 「りゅうが」 の2人が対話形式で進めてください。
# 制約条件
- kazuha は AWS の上級者、りゅうが は初級者という設定
- 後半には「最新のAWSアップデート・リリースノート情報」コーナーを追加
- 台本全体で約8分程度の長さになるように
`;
const response = await bedrock.send(new InvokeModelCommand({
modelId: "anthropic.claude-3-sonnet-20240229-v1:0",
body: JSON.stringify({
anthropic_version: "bedrock-2023-05-31",
max_tokens: 4000,
messages: [{ role: "user", content: prompt }]
})
}));
Bedrockを使って、指定したテーマで自然な対話形式の台本を生成します。
3. 人間承認フロー
// lambda/send-mail/index.ts
const approveUrl = `${REVISE_URL_BASE}?token=${encodeURIComponent(taskToken)}&key=${encodeURIComponent(scriptKey)}`;
const body = `
<p>台本が生成されました 🎙️</p>
<p><strong>タイトル:</strong> ${title}</p>
<a href="${approveUrl}" target="_blank">台本を確認・承認する</a>
`;
Step FunctionsのWait for Task Tokenパターンを使用。メールのリンクから台本を確認・修正して承認できます。
4. 並列音声合成
// lib/aws_radio-stack.ts
const synthesizeMap = new sfn.Map(this, "SynthesizeBlocks", {
itemsPath: "$.blocks",
maxConcurrency: 5,
parameters: {
"block.$": "$$.Map.Item",
"scriptKey.$": "$.scriptKey",
"title.$": "$.title",
},
});
台本を分割して、各セリフを並列で音声合成することで処理時間を短縮。
5. 高度な音声編集
// lambda/generate-audio/mergeLambda.ts
// BGMと本編を合成
await runFfmpeg([
"-i", merged,
"-i", bgmProcessed,
"-filter_complex",
"[0:a][1:a]amix=inputs=2:duration=longest:dropout_transition=2[a]",
"-map", "[a]",
"-c:a", "libmp3lame",
"-q:a", "2",
withBgm
]);
// ジングルを追加
const finalList = "/tmp/final_list.txt";
writeFileSync(
finalList,
[`file '${jingleFileVolume}'`, `file '${withBgm}'`].join("\n")
);
FFmpegを使って、BGM・ジングル・音声を高品質で合成します。
デモ動画
実際の動作の流れ:
入力: "Bedrockとは"
AI生成台本(例)
**Kazuha:** こんにちは、みなさん!今日はAWSの新しいサービス「Bedrock」についてお話していきます。
**りゅうが:** こんにちは!Bedrockって最近よく聞くんですが、具体的にはどんなサービスなんですか?
**Kazuha:** Bedrockは、AWSが提供するAIモデルの基盤となるサービスです...
Kazuhaの声で自然な読み上げ
BGM・ジングルが自動で合成
約8分のラジオ番組が完成
学んだこと・苦労したポイント
1. Step Functionsのデータフロー
Map ステートで $$.Map.Item が参照できないエラーに遭遇。outputPathの設定や、前段のLambdaの返り値の形式を正しく合わせる必要がありました。
2. 音声品質の調整
Pollyの音声とBGM・ジングルの音量バランス調整に時間をかけました。FFmpegのamixフィルターやvolumeフィルターを駆使して自然な仕上がりに。
3. 並列処理の最適化
台本の各ブロックを並列処理することで、8分の番組を約2-3分で生成できるように最適化しました。
まとめ
AWSのサーバーレスサービスを組み合わせることで、完全自動でラジオ番組を生成するシステムが作れました!
特にStep Functionsによるワークフロー管理と、BedrockのAI生成能力の組み合わせは非常に強力でした。
皆さんもぜひAWSの最新AI機能を使って、面白いアプリケーションを作ってみてください

