Chrome拡張機能でTransformers.jsを使用する方法
開発者はTransformers.jsをChrome拡張機能に統合し、ブラウザ内で機械学習モデルを実行することでサーバー依存を排除し、プライバシー保護と低レイテンシを実現する。
キーポイント
ブラウザ内推論の実装手法
Transformers.jsとWebAssemblyを活用し、大規模モデルをクライアント側で動作させる具体的なコード例と設定手順を解説する。
サーバー依存の排除とプライバシー強化
データを外部サーバーに送信しないローカル実行により、機微情報の漏洩リスクを根本的に軽減し、コンプライアンス要件を満たす。
レイテンシ削減とユーザー体験の向上
ネットワーク通信を介さないため応答速度が劇的に向上し、リアルタイムな対話型アプリケーションやオフライン環境での利用が可能になる。
影響分析・編集コメントを表示
影響分析
ブラウザ内での大規模モデル実行は、エッジAIの実用化を加速させる。開発者はインフラコストを削減しつつ、ユーザーの機密データを安全に処理できるため、医療・金融などの敏感な分野でのAI導入が促進される。
編集コメント
技術的な詳細な実装手順が公開されたことは、Web開発者がAI機能を組み込む際の標準的なパターンを確立する。今後はセキュリティ監査とモデル最適化のベストプラクティスがさらに重要になるだろう。
バックグラウンドのサービスワーカー(background service worker)は、アクティブなタブのサイドパネル(side panel)を開くために chrome.action.onClicked も処理します。
関連する知っておくべきエントリーポイント:action.default_popup でポップアップ(popup)を定義でき、クイックアクションに適しています。本プロジェクトは永続的なチャットにサイドパネルを使用していますが、オーケストレーションパターン(orchestration pattern)は同じです。
1.2 What runs where
重要な設計上の判断は、重いオーケストレーションをバックグラウンドに保持し、UI/ページロジック(page logic)を軽量に保つことです。
- バックグラウンド(
src/background/background.ts)はコントロールプレーン(control plane)です:エージェントのライフサイクル(agent lifecycle)、モデル初期化(model initialization)、ツール実行(tool execution)、および特徴抽出(feature extraction)などの共有サービス。
- サイドパネル(
src/sidebar/*)はインタラクションレイヤー(interaction layer)です:チャットの入出力、ストリーミング更新(streaming updates)、および設定コントロール。
- コンテンツスクリプト(
src/content/content.ts)はページブリッジです:DOM抽出(DOM extraction)およびハイライト操作。
この分離の実践的な結果の一つとして、会話履歴もバックグラウンド(Agent.chatMessages)に保存されることです。UIは AGENT_GENERATE_TEXT などのイベントを送信し、バックグラウンドがメッセージを追加して推論(inference)を実行した後、MESSAGES_UPDATE をサイドパネルにemitします。
この分割はモデルの重複ロードを回避し、UIの応答性を維持するとともに、DOMアクセスに関するChromeのセキュリティ境界(security boundaries)を尊重します。
1.3 Messaging contract
ランタイム(runtimes)が分離されると、メッセージング(messaging)が中核となります。本プロジェクトでは、すべてのメッセージがsrc/shared/types.tsの列挙型(enums)を通じて型付けされています。
- サイドパネル -> バックグラウンド(
BackgroundTasks):
CHECK_MODELS, INITIALIZE_MODELS
- AGENT_INITIALIZE, AGENT_GENERATE_TEXT, AGENT_GET_MESSAGES, AGENT_CLEAR
- EXTRACT_FEATURES
- バックグラウンド -> サイドパネル(
BackgroundMessages):
DOWNLOAD_PROGRESS, MESSAGES_UPDATE
- バックグラウンド -> コンテンツ(
ContentTasks):
EXTRACT_PAGE_DATA, HIGHLIGHT_ELEMENTS, CLEAR_HIGHLIGHTS
オーケストレーションのルールはシンプルです。バックグラウンドが単一のコーディネーターであり、サイドパネルとコンテンツスクリプトはアクションを要求して結果を描画する専門的なワーカーです。
典型的なリクエストフロー:
- サイドパネルが
AGENT_GENERATE_TEXTを送信します。
- バックグラウンドが
Agent.chatMessagesに追加し、モデル/ツールのステップを実行します。
- バックグラウンドが
MESSAGES_UPDATEをemitします。
- サイドパネルが更新されたメッセージリストから再描画します。
2) Transformers.js integration details
2.1 Models and responsibilities
src/shared/constants.tsにおいて、この拡張機能は2つのモデルロール(model roles)を使用します:
- TextGeneration / LLM:onnx-community/gemma-4-E2B-it-ONNX(text-generation, q4f16)
- VectorEmbeddings:onnx-community/all-MiniLM-L6-v2-ONNX(feature-extraction, fp32)
この分割は意図的なものです。Gemma 4が推論/ツールの決定を処理し、MiniLMが ask_website および find_history の意味的類似性検索用のベクトル埋め込み(vector embeddings)を生成します。
2.2 Where inference runs
必ずJSON形式で返してください:
{"translation": "翻訳全文", "technical_terms": ["term1", "term2"]}
すべての推論処理はバックグラウンドで行われます(src/background/background.ts)。
pipeline("text-generation", ...)を介したテキスト生成。新しいDynamicCacheクラスによって有効化された一貫した KV キャッシング(Key-Value Caching)を備える
pipeline("feature-extraction", ...)を介した埋め込み(Embeddings)生成。ベクトル正規化(Vector Normalization)を適用
これにより、すべてのタブ/セッションに対して単一のモデルホストが提供され、重複するメモリ使用を回避し、サイドパネル UI の応答性を維持できます。モデルはバックグラウンドサービスワーカーから読み込まれるため、アーティファクト(生成物/キャッシュファイル)はウェブサイトごとのオリジンではなく拡張機能のオリジン(chrome-extension://<extension-id>)の下にキャッシュされ、拡張機能インストール全体で共有キャッシュが1つだけ使用されます。
MV3 のライフサイクルに関する注意:サービスワーカーは一時停止および再起動される可能性があるため、モデルのランタイム状態は回復可能として扱い、必要に応じて再初期化されるべきです。
2.3 モデルのダウンロードとキャッシュのライフサイクル
モデルのライフサイクルは明示的です。
CHECK_MODELS:既にキャッシュされている内容を確認し、残りのダウンロードサイズを見積もる
INITIALIZE_MODELS:モデルのダウンロード/初期化を行い、UI に対してDOWNLOAD_PROGRESSイベントを発行する
- セットアップ後は長寿命なインスタンスが再利用される:
生成パイプライン(src/background/agent/Agent.ts)
- 埋め込みパイプライン(
src/background/utils/FeatureExtractor.ts)
パーミッション(権限)とプライバシーはアーキテクチャの一部であり、後付けのチェックボックスではありません。本プロジェクトでは、public/manifest.json が sidePanel、storage、scripting、tabs を要求し、さらに http(s)://*/* に対して host_permissions も設定しています。
sidePanel:サイドパネル UI を開き制御するために必須
storage:セッションを跨いでツール/設定の状態を永続化するために必須
tabs+scripting:タブ認識型ツールやページレベルのアクションに必須
http(s)://*/*に対するhost_permissions:コンテンツ抽出/ハイライト機能は任意のウェブサイト上で動作するように設計されているため必須
なぜこれを狭く保つのか:パーミッションはユーザーの信頼と Chrome ウェブストアの審査リスクを定義します。機能が必要とするものだけを要求し、推論処理が拡張機能のランタイム内でローカルで行われることを明確に明記してください。これにより、ユーザーは自身のデータがどこで処理されるかを理解できます。
3) エージェントとツール実行ループ
3.1 ツール呼び出しの基礎(このレイヤーが存在する理由)
実行ループに入る前に、モデルのツール呼び出しがどのように動作するかを理解しておくと役立ちます(これはあらゆるエージェントワークフローの基礎となります)。メッセージとツールスキーマ(名前、説明、パラメータ)を渡すと、Transformers.js はモデルのチャットテンプレートを使用して、それらの入力から実際のプロンプトを生成します。チャットテンプレートはモデル固有であるため、正確なツール呼び出し形式は使用するモデルに依存します。Gemma-4 形式のテンプレートでは、モデルがツール呼び出しを行うと判断すると、特別なツール呼び出しトークンブロックを出力します。
import { pipeline } from "@huggingface/transformers";
const generator = await pipeline(
"text-generation",
"onnx-community/gemma-4-E2B-it-ONNX",
{
dtype: "q4f16",
device: "webgpu",
},
);const messages = [{ role: "user", content: "What's the weather in Bern?" }];
const output = await generator(messages, {
max_new_tokens: 128,
do_sample: false,
tools: [
{
type: "function",
function: {
name: "getWeather",
description: "Get the weather in a location",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "The location to get the weather for",
},
},
required: ["location"],
},
},
},
],
});
生成時、モデルは以下のような出力を返すことがあります:
<|tool_call>call:getWeather{location:<|"|>Bern<|"|>}<tool_call|>
これがまさに、本プロジェクトに正規化レイヤー(normalization layer)とパーサー(parser)が存在する理由です。モデルの出力は、決定論的なツール実行(deterministic tool executions)に変換される必要があります。
3.2 Tool interface in this project
[src/background/agent/webMcp.tsx](https://github.com/nico-martin/gemma4-browser-extension/blob/main/src/background/agent/webMcp.tsx) は拡張機能のツールをモデルが扱いやすい形式(model-friendly shape)に正規化します:
name,description,inputSchema,execute
例として挙げられるツールには、get_open_tabs、go_to_tab、open_url、close_tab、find_history、ask_website、highlight_website_element などがあります。
3.3 Loop design (Agent.runAgent)
ここでの核心的な設計上の選択は、内部モデル用のメッセージ(internal model messages)とUI表示用のチャットメッセージ(UI-facing chat messages)を分離することです:
- 内部モデル用トランスクリプト(Internal model transcript / messages):
generator(...)で使用される system/user/tool/assistant のターン。 - UI用トランスクリプト(UI transcript / chatMessages):ユーザーが視認する内容。ストリーミングされたアシスタントのテキスト、ツール実行メタデータ(tools)、パフォーマンス指標が含まれます。
実行フロー:
chatMessagesにユーザー入力を追加し、プレースホルダーのアシスタントメッセージを作成してトークンをストリーミングする。extractToolCalls.tsを用いてストリーミング中/最終のモデル出力を{ message, toolCalls }にパースする。- ユーザーに表示されるアシスタントメッセージはプレーンテキストのまま維持し、ツール呼び出し(tool calls)はバックグラウンドで実行する。
- ツール結果をアシスタントのツールメタデータに追加し、次のプロンプトターン(prompt turn)としてフィードバックする。
- ツール呼び出しが残らなくなるまで繰り返し、その後アシスタントのコンテンツと指標を確定する。
これにより、ユーザーとの通信をクリーンに保ちつつ、バックグラウンドで決定論的なツールループ(deterministic tool loop)を維持できます。
4) Data boundaries and persistence
状態の配置(State placement)は、MV3において非常に重要なもう一つのアーキテクチャ上の選択です。本実装では、状態はライフサイクル(lifecycle)とアクセスパターン(access pattern)に応じて分割されます:
- 会話状態(Conversation state):バックグラウンドメモリ(Agent.chatMessages)。ターンごとの高速なオーケストレーション用。
- ツール設定(Tool preferences):
chrome.storage.local。セッションを跨いで設定を永続化するため。 - セマンティック履歴ベクトル(Semantic history vectors):
IndexedDB(VectorHistoryDB)。より大規模なローカル検索データ用。 - 抽出されたページコンテンツ(Extracted page content):バックグラウンドキャッシュ(WebsiteContentManager)。アクティブなURLをキーとして使用。
1.2節で説明した通り、バックグラウンド (background) に会話履歴を保持することで、UIの更新を跨いで一貫した単一の正統状態(canonical state)が得られます。これにより、一時的状態(short-lived state)はメモリに、永続的な設定は拡張機能ストレージ (extension storage) に、重い検索データはローカルデータベース (local database) にそれぞれ保持されます。
5) ビルドとパッケージングに関する注意事項
複雑なビルド環境は必要ありませんが、MV3(Manifest Version 3)では各ランタイム (runtime) に対して予測可能な出力が必要です。
- vite.config.ts におけるマルチエントリービルド (Multi-entry build):
src/sidebar/index.html
- src/background/background.ts
- src/content/content.ts
- マニフェスト (manifest) に合わせた出力名/パスの確保(sidebar.html, background.js, content.js)。
- ランタイムのチャンク読み込み (chunk-loading) 問題を避けるため、コンテンツスクリプト (content script) は単一ファイルの出力として保持してください。
目標はシンプルです:Chromeのエントリポイント (entry point) ごとに1つのビルド成果物(artifact)を、public/manifest.json が期待する正確な場所に配置することです。
最終的なまとめ
このプロジェクト全体を可能にするアーキテクチャの選択は、関心の分離(separation of concerns)です:バックグラウンドがオーケストレーション (orchestration) とモデル実行 (model execution) を担い、UI表示面(UI surfaces)は軽量に保たれ、コンテンツスクリプトがページアクセスを処理します。
このプロジェクトはサイドパネル (side panel) を使用していますが、同じアプローチが他のセットアップでも機能します:
- ポップアップファーストアシスタント(Popup-first assistant):素早い対話には action.default_popup を使用し、会話状態とモデル実行はバックグラウンドが担当します。
- サイドパネルコパイロット(Side-panel copilot):長時間実行される会話は永続的なパネルに保持し、バックグラウンドがツールループ (tool loops) とキャッシュ処理(caching)を処理します。
- タブ別エージェント(Per-tab agents):各タブが独自のコンテキストを持つべき場合、バックグラウンドで tabId ごとに1つのエージェント状態を保持します。
- ハイブリッドUI(Hybrid UI)(ポップアップ+サイドパネル+オプションページ (options page)):すべてのUIエントリポイントは同じバックグラウンドコーディネーター (background coordinator) と通信し、同じメッセージインターフェース(message contracts)を再利用します。
実用的なルールはシンプルです:状態 (state) の所在(グローバル (global)、tabId、またはサイトスコープ(site-scoped))を決定し、その状態とモデル推論 (model inference) をバックグラウンドに保持(基本的にはバックグラウンドサービス (background services) として)、UI/コンテンツランタイム(UI/content runtimes)は専用クライアント(focused clients)として動作させます。
原文を表示
- Who this is for
- What we will build
- 1) Chrome extension architecture (MV3) 1.1 Runtime contexts and entry points
- 1.2 What runs where
- 1.3 Messaging contract
- 2) Transformers.js integration details 2.1 Models and responsibilities
- 2.2 Where inference runs
- 2.3 Download and cache lifecycle
- 3) Agent and tool execution loop 3.1 Tool-calling basics (why this layer exists)
- 3.2 Tool interface in this project
- Agent.runAgent)">3.3 Loop design (Agent.runAgent)
- 4) Data boundaries and persistence
- 5) Build and packaging notes
- Final takeaway
We recently released a Transformers.js demo browser extension powered by Gemma 4 E2B to help users navigate the web.
While building it, we ran into several practical observations about Manifest V3 runtimes, model loading, and messaging that are worth sharing.
Who this is for
This guide is for developers who want to run local AI features in a Chrome extension with Transformers.js under Manifest V3 constraints.
By the end, you will have the same architecture used in this project: a background service worker that hosts models, a side panel chat UI, and a content script for page-level actions.
What we will build
In this guide, we will recreate the core architecture of Transformers.js Gemma 4 Browser Assistant, using the published extension as a reference and the open-source codebase as the implementation map.
- Live extension: Chrome Web Store
- Source code: github.com/nico-martin/gemma4-browser-extension
- End result: a background-hosted Transformers.js engine, a side panel chat UI, and a content script for page extraction and highlighting.
1) Chrome extension architecture (MV3)
Before diving in, a quick scope note: I will not go deep on the React UI layer or Vite build configuration. The focus here is the high-level architecture decisions: what runs in each Chrome runtime and how those pieces are orchestrated.
If Manifest V3 is new to you, read this short overview first:
1.1 Runtime contexts and entry points
In MV3, your architecture starts in public/manifest.json. This project defines three entry points:
- background.service_worker = background.js, built from src/background/background.ts.
- side_panel.default_path = sidebar.html, built from src/sidebar/index.html.
- content_scripts[].js = content.js with matches: http(s)://*/* and run_at: document_idle, built from src/content/content.ts.
The background service worker also handles chrome.action.onClicked to open the side panel for the active tab.
Related entry point to know: a popup can be defined with action.default_popup and works well for quick actions. This project uses a side panel for persistent chat, but the orchestration pattern is the same.
1.2 What runs where
The key design decision is to keep heavy orchestration in the background and keep UI/page logic thin.
- Background (src/background/background.ts) is the control plane: agent lifecycle, model initialization, tool execution, and shared services like feature extraction.
- Side panel (src/sidebar/*) is the interaction layer: chat input/output, streaming updates, and setup controls.
- Content script (src/content/content.ts) is the page bridge: DOM extraction and highlight actions.
One practical consequence of this division is that the conversation history also lives in background (Agent.chatMessages): the UI sends events like AGENT_GENERATE_TEXT, background appends the message, runs inference, then emits MESSAGES_UPDATE back to the side panel.
This split avoids duplicate model loads, keeps the UI responsive, and respects Chrome's security boundaries around DOM access.
1.3 Messaging contract
Once runtimes are separated, messaging becomes the backbone. In this project, all messages are typed through enums in src/shared/types.ts.
- Side panel -> background (BackgroundTasks):
CHECK_MODELS, INITIALIZE_MODELS
- AGENT_INITIALIZE, AGENT_GENERATE_TEXT, AGENT_GET_MESSAGES, AGENT_CLEAR
- EXTRACT_FEATURES
- Background -> side panel (BackgroundMessages):
DOWNLOAD_PROGRESS, MESSAGES_UPDATE
- Background -> content (ContentTasks):
EXTRACT_PAGE_DATA, HIGHLIGHT_ELEMENTS, CLEAR_HIGHLIGHTS
The orchestration rule is simple: the background is the single coordinator; side panel and content script are specialized workers that request actions and render results.
Typical request flow:
- Side panel sends AGENT_GENERATE_TEXT.
- Background appends to Agent.chatMessages and runs model/tool steps.
- Background emits MESSAGES_UPDATE.
- Side panel re-renders from the updated message list.
2) Transformers.js integration details
2.1 Models and responsibilities
In src/shared/constants.ts, this extension uses two model roles:
- TextGeneration / LLM: onnx-community/gemma-4-E2B-it-ONNX (text-generation, q4f16)
- VectorEmbeddings: onnx-community/all-MiniLM-L6-v2-ONNX (feature-extraction, fp32)
The split is intentional: Gemma 4 handles reasoning/tool decisions, while MiniLM generates vector embeddings for the semantic similarity search in ask_website and find_history.
2.2 Where inference runs
All inference runs in background (src/background/background.ts):
- text generation via pipeline("text-generation", ...) with consistent KV Caching enabled by our new DynamicCache class
- embeddings via pipeline("feature-extraction", ...) plus vector normalization
This gives a single model host for all tabs/sessions, avoids duplicate memory usage, and keeps the side panel UI responsive. Because models are loaded from the background service worker, artifacts are cached under the extension origin (chrome-extension://<extension-id>) rather than per-website origins, which gives one shared cache for the whole extension install.
MV3 lifecycle note: service workers can be suspended and restarted, so model runtime state should be treated as recoverable and re-initialized when needed.
2.3 Download and cache lifecycle
The model lifecycle is explicit:
- CHECK_MODELS inspects what is already cached and estimates remaining download size.
- INITIALIZE_MODELS downloads/initializes models and emits DOWNLOAD_PROGRESS to the UI.
- Long-lived instances are reused after setup:
generation pipeline in src/background/agent/Agent.ts
- embedding pipeline in src/background/utils/FeatureExtractor.ts
Permissions and privacy are part of the architecture, not a checkbox at the end. In this project, public/manifest.json asks for sidePanel, storage, scripting, and tabs, plus host_permissions for http(s)://*/*:
- sidePanel: required to open and control the side panel UX.
- storage: required to persist tool/settings state across sessions.
- tabs + scripting: required for tab-aware tools and page-level actions.
- host_permissions on http(s)://*/*: required because content extraction/highlighting is designed to work on arbitrary websites.
Why keep this narrow: permissions define user trust and Chrome Web Store review risk. Request only what your features actually need, and state clearly that inference runs locally in the extension runtime so users understand where their data is processed.
3) Agent and tool execution loop
3.1 Tool-calling basics (why this layer exists)
Before the execution loop, it helps to understand how model tool calling works (the basis for any agentic workflow). You pass messages plus a tool schema (name, description, and parameters), and Transformers.js formats the actual prompt from those inputs using the model's chat template. Because chat templates are model-specific, the exact tool-call format depends on the model you use. With Gemma-4-style templates, the model emits a special tool-call token block when it decides to call one.
import { pipeline } from "@huggingface/transformers";
const generator = await pipeline(
"text-generation",
"onnx-community/gemma-4-E2B-it-ONNX",
{
dtype: "q4f16",
device: "webgpu",
},
);
const messages = [{ role: "user", content: "What's the weather in Bern?" }];
const output = await generator(messages, {
max_new_tokens: 128,
do_sample: false,
tools: [
{
type: "function",
function: {
name: "getWeather",
description: "Get the weather in a location",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "The location to get the weather for",
},
},
required: ["location"],
},
},
},
],
});
At generation time, the model can emit output like:
<|tool_call>call:getWeather{location:<|"|>Bern<|"|>}<tool_call|>
That is exactly why this project has a normalization layer (webMcp) and a parser (extractToolCalls): model output must be converted into deterministic tool executions.
3.2 Tool interface in this project
src/background/agent/webMcp.tsx normalizes extension tools into a model-friendly shape:
- name, description, inputSchema, execute
Example tools include get_open_tabs, go_to_tab, open_url, close_tab, find_history, ask_website, and highlight_website_element.
3.3 Loop design (Agent.runAgent)
The core design choice here is to separate internal model messages from UI-facing chat messages:
- Internal model transcript (messages): system/user/tool/assistant turns used for messages in generator(...).
- UI transcript (chatMessages): what the user sees, including streamed assistant text plus tool execution metadata (tools) and performance metrics.
Execution flow:
- Add user input to chatMessages, create a placeholder assistant message, and stream tokens.
- Parse streamed/final model output with extractToolCalls.ts into { message, toolCalls }.
- Keep the user-visible assistant message as plain text, while tool calls execute in background.
- Append tool results to the assistant tool metadata and feed results back as the next prompt turn.
- Repeat until no tool calls remain, then finalize assistant content + metrics.
This keeps user communication clean while preserving a deterministic tool loop in the background.
4) Data boundaries and persistence
State placement is another architectural decision that matters a lot in MV3. In this implementation, state is split by lifecycle and access pattern:
- Conversation state: background memory (Agent.chatMessages) for fast turn-by-turn orchestration.
- Tool preferences: chrome.storage.local so settings persist across sessions.
- Semantic history vectors: IndexedDB (VectorHistoryDB) for larger local retrieval data.
- Extracted page content: background cache (WebsiteContentManager) keyed by active URL.
As described in section 1.2, keeping conversation history in background gives one canonical state across UI updates. This keeps short-lived state in memory, durable settings in extension storage, and heavy retrieval data in a local database.
5) Build and packaging notes
You do not need a complex build setup, but MV3 does require predictable outputs for each runtime.
- Multi-entry build in vite.config.ts:
src/sidebar/index.html
- src/background/background.ts
- src/content/content.ts
- Ensure manifest-aligned output names/paths (sidebar.html, background.js, content.js).
- Keep the content script as a self-contained output to avoid runtime chunk-loading issues.
The goal is simple: one artifact per Chrome entry point, in the exact place public/manifest.json expects.
Final takeaway
The architecture choice that unlocks this whole project is clear separation of concerns: background owns orchestration and model execution, UI surfaces stay thin, and content scripts handle page access.
This project uses a side panel, but the same approach works for other setups:
- Popup-first assistant: use action.default_popup for quick interactions, with background owning conversation state and model execution.
- Side-panel copilot: keep long-running conversations in a persistent panel while background handles tool loops and caching.
- Per-tab agents: keep one agent state per tabId in background when each tab should have its own context.
- Hybrid UI (popup + side panel + options page): all UI entry points talk to the same background coordinator and reuse the same message contracts.
The practical rule is simple: decide where state lives (global, tabId, or site-scoped), keep that state and the model inference in background (basically as background services), and let UI/content runtimes act as focused clients.
関連記事
Google、Room 3.0を発表:Kotlinファーストの非同期マルチプラットフォーム永続化ライブラリ
GoogleはRoom 3.0を発表した。本バージョンは破壊的変更を導入し、Kotlin Multiplatform対応を強化するとともにJSとWasmへのサポートを追加した。
Google の Gemini 3.1 Flash TTS モデルによる自然な音声合成ツール
Google は、単一話者および複数話者の会話モードに対応し、発声指示タグの適用も可能な「Gemini 3.1 Flash TTS」モデルを公開した。このツールにより、テキストから自然な音声を生成してダウンロードできるようになった。
Google、Chromeを職場向けAIコワーカーに進化させる
Googleは企業向けChromeにGemini搭載の「自動閲覧」機能を追加し、従業員が調査やデータ入力などの業務を自動化できるようにした。