マルチモーダルコンテンツ処理
PRX はマルチモーダルコンテンツ -- 画像、音声、動画 -- をチャネルと LLM プロバイダー全体でサポートします。マルチモーダルサブシステムはコンテンツタイプ検出、フォーマットトランスコーディング、サイズ制限、チャネルとプロバイダー間の機能ネゴシエーションを処理します。
概要
ユーザーがチャネルを通じてメディア添付ファイル(写真、ボイスメッセージ、ドキュメント)を送信すると、マルチモーダルパイプラインは以下を実行します:
- マジックバイトとファイル拡張子を使用してコンテンツタイプを検出
- サイズとフォーマットの制約に対してコンテンツを検証
- ターゲットプロバイダーがソースフォーマットをサポートしていない場合、コンテンツをトランスコード
- 会話コンテキストの一部として LLM プロバイダーにコンテンツをディスパッチ
- プロバイダーが画像や音声を生成した場合、レスポンスのメディアを処理
Channel Input Provider Output
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Content Type │ │ Response │
│ Detection │ │ Media │
└──────┬───────┘ └──────┬───────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Validation │ │ Transcoding │
│ & Limits │ │ (if needed) │
└──────┬───────┘ └──────┬───────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Transcoding │ │ Channel │
│ (if needed) │ │ Delivery │
└──────┬───────┘ └──────────────┘
│
▼
┌──────────────┐
│ Provider │
│ Dispatch │
└──────────────┘サポートされるコンテンツタイプ
画像
| フォーマット | 検出方法 | プロバイダーへの送信 | プロバイダーからの受信 |
|---|---|---|---|
| JPEG | マジックバイト FF D8 FF | 可能 | 可能 |
| PNG | マジックバイト 89 50 4E 47 | 可能 | 可能 |
| GIF | マジックバイト 47 49 46 | 可能(最初のフレーム) | 不可 |
| WebP | RIFF ヘッダー + WEBP | 可能 | 可能 |
| BMP | マジックバイト 42 4D | PNG にトランスコード | 不可 |
| TIFF | マジックバイト 49 49 または 4D 4D | PNG にトランスコード | 不可 |
| SVG | XML 検出 | PNG にラスタライズ | 不可 |
音声
| フォーマット | 検出方法 | 文字起こし | プロバイダー入力 |
|---|---|---|---|
| OGG/Opus | OGG ヘッダー | 可能(STT 経由) | 文字起こしテキスト |
| MP3 | ID3/sync ヘッダー | 可能(STT 経由) | 文字起こしテキスト |
| WAV | RIFF + WAVE | 可能(STT 経由) | 文字起こしテキスト |
| M4A/AAC | ftyp ボックス | 可能(STT 経由) | 文字起こしテキスト |
| WebM | EBML ヘッダー | 可能(STT 経由) | 文字起こしテキスト |
動画
| フォーマット | 検出方法 | 処理 |
|---|---|---|
| MP4 | ftyp ボックス | キーフレーム + 音声トラック抽出 |
| WebM | EBML ヘッダー | キーフレーム + 音声トラック抽出 |
| MOV | ftyp ボックス | キーフレーム + 音声トラック抽出 |
動画ファイルはキーフレーム画像と音声トラックに分解されます。キーフレームは画像として送信され、音声は文字起こしされます。
コンテンツタイプ検出
検出は 2 パスアプローチを使用します:
- マジックバイト -- ファイルの最初の 16 バイトを既知のシグネチャと照合
- ファイル拡張子 -- マジックバイトが決定的でない場合、ファイル拡張子をフォールバックとして使用
- MIME タイプヘッダー -- HTTP 経由で受信したコンテンツの場合、
Content-Typeヘッダーを参照
検出結果によって、どの処理パイプラインがコンテンツを処理するかが決定されます。
設定
toml
[multimodal]
enabled = true
[multimodal.images]
max_size_bytes = 20_971_520 # 20 MB
max_resolution = "4096x4096" # maximum width x height
auto_resize = true # resize images exceeding max_resolution
resize_quality = 85 # JPEG quality for resized images (1-100)
strip_exif = true # remove EXIF metadata for privacy
[multimodal.audio]
max_size_bytes = 26_214_400 # 25 MB
max_duration_secs = 300 # 5 minutes
stt_provider = "whisper" # "whisper", "deepgram", or "provider" (use LLM provider's STT)
stt_model = "whisper-1"
stt_language = "auto" # "auto" for language detection, or ISO 639-1 code
[multimodal.video]
max_size_bytes = 104_857_600 # 100 MB
max_duration_secs = 120 # 2 minutes
keyframe_interval_secs = 5 # extract one keyframe every 5 seconds
max_keyframes = 20 # maximum keyframes to extract
extract_audio = true # transcribe audio track設定リファレンス
画像
| フィールド | 型 | デフォルト | 説明 |
|---|---|---|---|
max_size_bytes | u64 | 20971520 | 画像ファイルの最大サイズ(20 MB) |
max_resolution | String | "4096x4096" | 画像の最大解像度(幅x高さ) |
auto_resize | bool | true | 超過サイズの画像を自動リサイズ |
resize_quality | u8 | 85 | リサイズ画像の JPEG 品質(1--100) |
strip_exif | bool | true | 画像から EXIF メタデータを除去 |
音声
| フィールド | 型 | デフォルト | 説明 |
|---|---|---|---|
max_size_bytes | u64 | 26214400 | 音声ファイルの最大サイズ(25 MB) |
max_duration_secs | u64 | 300 | 音声の最大長(5 分) |
stt_provider | String | "whisper" | 音声認識プロバイダー |
stt_model | String | "whisper-1" | STT モデル名 |
stt_language | String | "auto" | 文字起こしの言語ヒント |
動画
| フィールド | 型 | デフォルト | 説明 |
|---|---|---|---|
max_size_bytes | u64 | 104857600 | 動画ファイルの最大サイズ(100 MB) |
max_duration_secs | u64 | 120 | 動画の最大長(2 分) |
keyframe_interval_secs | u64 | 5 | キーフレーム抽出間隔(秒) |
max_keyframes | usize | 20 | 抽出するキーフレームの最大数 |
extract_audio | bool | true | 動画の音声トラックを文字起こし |
プロバイダー機能
すべての LLM プロバイダーが同じメディアタイプをサポートしているわけではありません。PRX は機能を自動的にネゴシエートします:
| プロバイダー | 画像入力 | 画像出力 | 音声入力 | ネイティブマルチモーダル |
|---|---|---|---|---|
| Anthropic (Claude) | 対応 | 非対応 | 非対応(先に文字起こし) | 対応(ビジョン) |
| OpenAI (GPT-4o) | 対応 | 対応(DALL-E) | 対応(Whisper) | 対応 |
| Google (Gemini) | 対応 | 対応(Imagen) | 対応 | 対応 |
| Ollama (LLaVA) | 対応 | 非対応 | 非対応 | 対応(ビジョン) |
| AWS Bedrock | モデル依存 | モデル依存 | 非対応 | モデル依存 |
プロバイダーがメディアタイプをネイティブにサポートしていない場合、PRX はフォールバック処理を適用します:
- 画像非対応 -- ビジョン対応モデルを使用して画像を説明し、その説明をテキストとして送信
- 音声非対応 -- 設定された STT プロバイダーで音声を文字起こしし、トランスクリプトをテキストとして送信
- 動画非対応 -- キーフレームと音声トランスクリプトを複合メッセージとして送信
チャネルメディア制限
各チャネルには独自のファイルサイズとフォーマット制限があります:
| チャネル | 最大アップロード | 最大ダウンロード | サポートフォーマット |
|---|---|---|---|
| Telegram | 50 MB | 20 MB | 画像、音声、動画、ドキュメント |
| Discord | 25 MB(無料) | 25 MB | 画像、音声、動画、ドキュメント |
| 16 MB(メディア) | 16 MB | JPEG、PNG、MP3、MP4、PDF | |
| 20 MB | 20 MB | 画像、音声、ドキュメント | |
| DingTalk | 20 MB | 20 MB | 画像、音声、ドキュメント |
| Lark | 25 MB | 25 MB | 画像、音声、動画、ドキュメント |
| Matrix | ホームサーバー依存 | ホームサーバー依存 | 一般的なフォーマットすべて |
| 25 MB(一般的) | 25 MB | MIME 添付ファイルですべて対応 | |
| CLI | ファイルシステム制限 | ファイルシステム制限 | すべてのフォーマット |
PRX はレスポンスの送信を試みる前にチャネルの制限を強制します。生成された画像やファイルがチャネルの制限を超える場合、圧縮されるかダウンロードリンクが代わりに提供されます。
トランスコーディングパイプライン
フォーマット変換が必要な場合、PRX は以下のトランスコーディングパイプラインを使用します:
- 画像トランスコーディング --
imageクレートで処理(純粋な Rust、外部依存なし) - 音声トランスコーディング -- FFmpeg がインストールされている場合はそれを使用、そうでなければ一般的なフォーマット用のネイティブデコーダーにフォールバック
- 動画キーフレーム抽出 -- FFmpeg が必要
FFmpeg 検出
PRX は起動時に FFmpeg を自動検出します:
bash
prx doctor multimodal出力例:
Multimodal Support:
Images: OK (native)
Audio transcoding: OK (ffmpeg 6.1 detected)
Video processing: OK (ffmpeg 6.1 detected)
STT provider: OK (whisper-1 via OpenAI)FFmpeg がインストールされていない場合、音声トランスコーディングと動画処理はネイティブサポートされるフォーマットに制限されます。
制限事項
- 動画処理にはシステムに FFmpeg がインストールされている必要あり
- 大きなメディアファイルは LLM トークン使用量を大幅に増加させる可能性あり(特に複数のキーフレーム)
- 一部のプロバイダーはビジョン/マルチモーダル API コールに追加料金を課す場合あり
- リアルタイム音声ストリーミング(ライブ音声会話)はまだサポートされていない
- プロバイダーから生成された画像(DALL-E、Imagen)はプロバイダーのコンテンツポリシーに従う
- SVG ラスタライズは基本的なレンダラーを使用。複雑な SVG は正確にレンダリングされない場合あり
関連ページ
- エージェントランタイム -- メディアコンテンツがエージェントループを流れる仕組み
- チャネル概要 -- チャネル固有のメディア処理
- プロバイダー概要 -- プロバイダーのマルチモーダル機能
- エンベディングバックエンド -- メモリ用のエンベディングモデル