Googleが開発・提供している生成AIモデル。
文章の生成や要約、画像の編集、翻訳、ソースコードの生成など、さまざまなタスクに対応できる。
ChatGPTやClaudeに要らべていまいち存在感が薄い(気がする)
と思ったけど直前でバズってた。
テキストだけでなく、画像、動画、音声などをAIへの入力として扱える
AIへの入力をリアルタイムで行える。一般的なターン制のやりとりに比べてより自然な会話を行うことができる。 また、AIが返答中であっても割り込んで入力をおこなことができる
Gemini のモデルをテストできる実験環境。APIキーの発行などもこのサービスから行える。「Stream Realtime」のタブからMultimodal Live APIのテストが行える
自身のアプリケーションやサービスの中に、リアルタイムで応答するAIを組み込むことができる
とか作れそう
Multimodal Live APIを活用するにはWebSocketsを使う必要があります。ストリーミング処理になれていないと構築が難しいです。
multimodal-live-api-web-console
Googleが公式で公開しているMultimodal Live APIを使用するためのReactベースのスターターキット。ストリーミング処理やオーディオ、マイク、webカメラ、画面キャプチャなどのメディア処理などが最初からう用意されている
スターターキットのデモ
multimodal-live-api-web-console
別ブランチに別のスターターキットが入ってます。
src
├── App.scss
├── App.test.tsx
├── App.tsx
├── components
│ ├── altair
│ │ └── Altair.tsx
│ ├── audio-pulse
│ │ ├── AudioPulse.tsx
│ │ └── audio-pulse.scss
│ ├── control-tray
│ │ ├── ControlTray.tsx
│ │ └── control-tray.scss
│ ├── logger
│ │ ├── Logger.tsx
│ │ ├── logger.scss
│ │ └── mock-logs.ts
│ └── side-panel
│ ├── SidePanel.tsx
│ └── side-panel.scss
├── contexts
│ └── LiveAPIContext.tsx
├── hooks
│ ├── use-live-api.ts
│ ├── use-media-stream-mux.ts
│ ├── use-screen-capture.ts
│ └── use-webcam.ts
├── index.css
├── index.tsx
├── lib
│ ├── audio-recorder.ts
│ ├── audio-streamer.ts
│ ├── audioworklet-registry.ts
│ ├── multimodal-live-client.ts
│ ├── store-logger.ts
│ ├── utils.ts
│ └── worklets
│ ├── audio-processing.ts
│ └── vol-meter.ts
├── multimodal-live-types.ts
├── react-app-env.d.ts
├── reportWebVitals.ts
└── setupTests.ts
スターターキットとしてはコード量が多いが、殆どは通信周りの処理で複雑になっているだけ。とりあえず一番最初に理解すべきは以下のコード。
src
├── components
│ ├── altair
│ │ └── Altair.tsx *
Geminiに「render_altair」というファンクションコーリングを登録し、AIの判断で関数呼び出しを行わせVega-Altairとういうチャートライブラリを用いてチャートを出力している
自然言語のプロンプトを使って、AIモデルがユーザーの意図を理解し、外部関数の呼び出し(APIやアプリ内ロジックなど)を提案・実行する仕組み。
つまり、AIが自ら判断してイベントを発火しプログラム(関数)を実行する。
関数定義
モデル設定
関数が呼ばれたときのハンドリング
// Altairグラフを描画するための関数宣言オブジェクト
const declaration: FunctionDeclaration = {
// 関数の名前
name: "render_altair",
// 関数の説明
description: "Displays an altair graph in json format.", //altair グラフを json フォーマットで表示します。
// パラメータの定義
parameters: {
// パラメータはオブジェクト型で定義される
type: SchemaType.OBJECT,
// プロパティの定義
properties: {
json_graph: { //関数呼び出しの際に引数として渡される
type: SchemaType.STRING, // 文字列型のデータを受け取る
description:
"JSON STRING representation of the graph to render. Must be a string, not a json object", // プロンプト「レンダリングするグラフのJSON文字列表現。 json オブジェクトではなく、文字列でなければなりません。」
},
},
// 必須パラメータの指定
required: ["json_graph"],
},
};
useEffect(() => {
// Geminiのリクエスト設定を行うカスタムフック
setConfig({
// 使用するAIモデルのバージョン
model: "models/gemini-2.0-flash-exp",
// 音声出力の設定
generationConfig: {
responseModalities: "audio", // AIのレスポンスとして音声を使用
speechConfig: {
voiceConfig: { prebuiltVoiceConfig: { voiceName: "Aoede" } }, // 音声の種類を "Aoede" に設定
},
},
// システム命令の設定 (AIがどのように振る舞うか)
systemInstruction: {
parts: [
{
//プロンプト「あなたはアシスタントだ。 私がグラフの作成を依頼するときはいつでも、私が用意した「render_altair」関数を呼び出してください。 追加情報は求めず、最善の判断をしてください。」
text: 'You are my helpful assistant. Any time I ask you for a graph call the "render_altair" function I have provided you. Dont ask for additional information just make your best judgement.',
},
],
},
// 利用可能なツール (AIが実行できる追加機能)
tools: [
{ googleSearch: {} }, // 公式が用意しているファンクションコーリング(Google検索を利用できるようにする)
{ functionDeclarations: [declaration] }, // "render_altair" 関数をAIに登録
],
});
}, [setConfig]);
useEffect(() => {
// AI からのツール呼び出しを処理するハンドラ
const onToolCall = (toolCall: ToolCall) => {
// toolCall に含まれる関数呼び出しの中から "render_altair" に一致するものを探す
const fc = toolCall.functionCalls.find(
(fc) => fc.name === declaration.name,
);
// "render_altair" 関数が見つかった場合、引数として渡された JSON グラフを取得し、ステートを更新
if (fc) {
const str = (fc.args as any).json_graph; // 引数として渡された JSON グラフを取得
setJSONString(str); // チャートデータのステートを更新
}
// ツールの呼び出しに応答を返す処理
// この場合、ツールの処理が成功したことを AI に伝える
if (toolCall.functionCalls.length) {
setTimeout(
() =>
client.sendToolResponse({
functionResponses: toolCall.functionCalls.map((fc) => ({
response: { output: { success: true } }, // 成功したことを示すレスポンス
id: fc.id, // 各関数呼び出しの ID を返す
})),
}),
200, // 200ms の遅延を入れる
);
}
};
// "toolcall" イベントをリスニングしハンドラを登録する
client.on("toolcall", onToolCall);
// クリーンアップ処理: コンポーネントのアンマウント時にイベントリスナーを解除
return () => {
client.off("toolcall", onToolCall);
};
}, [client]); //LiveAPIContextで取得されたAPIクライアント
まずは、スターターキットにオリジナルのファクションコーリングを追加して機能を増やしていくのが良さそう。