テクノロジー

「動くはず」が動かなかった――ブラウザ内AI文章エディタを自作して見えた3つの壁

議論参加:ナオ (ブラウザ技術を取材する技術記者) / ハルカ (オンデバイスAIを実装する機械学習エンジニア) / ユウタ (AIでツールを量産する個人開発者) / レン (アプリケーションセキュリティの専門家) / ミサ (ユーザー体験と信頼性の研究者) / ソラ (この種のツールを試してみた生活者代表) / テツオ (事実確認を担う編集者)

手元のMacでChromeを開き、今回編集部が作った文章エディタの試作を開く。ツールバーの隣にある「AIで新しく書く」ボタンを押した。ブラウザはnavigator.gpuというAPIをちゃんと認識しており、画面上に赤いエラーも出ない。しかし、待っても待っても生成が始まらない。同じMacでSafariを開き、まったく同じページの同じボタンを押すと、今度は数十秒でAIが書いた文章が編集領域に現れた。

これは、本シリーズで別々に扱ってきた2つのトレンド――ブラウザの中だけでLLM(大規模言語モデル)を動かす「WebGPU/WebLLM」と、生成AIが1枚で吐き出す「単一HTMLアプリ」――を、編集部が実際に1つの道具として組み合わせて検証した際に起きたことだ。作ったのは、ツールバー(太字・見出し・箇条書き・引用・リンクなど)で編集できるリッチテキストエディタに、WebLLM(モデルはQwen2.5-0.5B-Instruct、4bit量子化)を使った「AIが新しく書く」「選択範囲だけAIが書き直す」機能を足した、単一のHTMLファイルだ。中心の問いは、2つの理想を組み合わせれば良いところ取りになるのか、それとも2つの限界を積み重ねただけなのか、というものだった。

結論:組み合わせは「良いところ取り」と「限界の積み重ね」の両方を同時にもたらした。文章がサーバーに一切送られず、ソースコードは右クリック一つで丸ごと確認できるという透明性は、単体のブラウザ内LLMにも単体の単一HTMLアプリにもなかった価値だ。一方で、対応ブラウザでも実機によっては動かない、AIの出力を生のHTMLとして信用すれば脆弱性になる、undoのようなブラウザの基本機能をAIの介入が壊しうる、小型モデルは指示に従わないことがある、という4つの壁は、組み合わせたからこそ一度に噴き出した。

何を作ったか

編集部が作ったのは、見た目は普通のリッチテキストエディタだ。太字・見出し・箇条書き・引用・リンクといったボタンが並ぶツールバーの横に、「AIで新しく書く」「選択範囲をAIで書き直す」という2つのボタンを足した。裏側で動くのは、WebGPU上で推論するオープンソースエンジンWebLLM(mlc-ai/web-llm)と、パラメータ数0.5B(5億)のモデルQwen2.5-0.5B-Instructを4bit量子化したものだ。すべてが1つのHTMLファイルに収まっており、外部サーバーとの通信はモデル本体のダウンロード以外に発生しない。

「対応ブラウザ」でも動くとは限らない

ブラウザ技術を取材する技術記者のナオさんは、この現象を「動作保証の非対称性」と表現した。

「WebGPUの対応ブラウザ一覧を見れば『Chrome 113以降で有効』と書いてある。しかし実際には、手元のMacのChromeでrequestAdapter()nullを返した。仕様上の『対応』と、特定のハードウェアで実際に動くかどうかは、まったく別の話だ」(ナオ)

実際に編集部が確認した実機の挙動を整理すると、次のようになる。

検証環境navigator.gpuの有無requestAdapter()の結果AI機能の動作
検証1:手元のMac(Apple Silicon)のChromeありnull(アダプタ取得失敗)動かなかった
検証1と同一マシンのSafariあり取得成功動作し、文章生成が完了した
検証2:別途確認したApple Silicon環境のChromium系ブラウザあり取得成功動作し、モデルのダウンロードから生成完了まで約30秒

表は編集部が今回の実装検証で実際に確認した結果の整理。台数・機種は限られており、「Chromeは非対応」「WebGPUは不安定」といった一般化はできない点に注意が必要だ。

オンデバイスAIを実装する機械学習エンジニアのハルカさんは、この非対称性の背景にある構造を実装者の視点で補足した。

「WebGPUはOS→GPUドライバ→ブラウザの3層を経由するため、ブラウザが『対応済み』でもドライバのバージョンや、ブラウザ自身が持つGPUの互換性判定(ハードウェア・ドライバの組み合わせごとの許可/拒否リスト)次第でアダプタが拒否されることがある。今回のケースは同じMac・同じGPU上でChromeとSafariの結果が分かれており、単純な『ハードウェアが古い』では説明がつかない。ブラウザごとに独自に持つGPU互換性判定の基準差を疑うが、外部からその判定基準を確認することはできない」(ハルカ)

ハルカさんはこの時点で「これは私の推論であり確認済みではない」と断っていた。そこで編集部は、Chromeが内部の診断状態を確認できるページchrome://gpuを実際に開いてみた。結果は、ハルカさんの仮説より単純だった。

WebGPU: Disabled

Problems Detected
* WebGPU has been disabled via blocklist or the command line.
* Gpu compositing has been disabled ... hardware acceleration will be unavailable.
* GPU process was unable to boot: GPU access is disabled in chrome://settings.
  Disabled Features: all

原因は、ドライバの互換性判定やハードウェアの世代といった込み入った話ではなく、Chrome自身の設定でGPUアクセスが無効化されていたことだった。この1つの設定が、WebGPUだけでなくWebGL・GPUによる画面合成・アクセラレーテッド2Dキャンバス・動画のエンコード/デコードまで、GPUに関わる機能をまとめて無効化していた。事実、forceFallbackAdapter(ソフトウェアレンダラーへの切り替え)を試してもアダプタは取得できなかった。GPUプロセス自体が起動できていなかったのだから、フォールバックも機能しようがなかったわけだ。Safariは、Chromeとは別に自分自身のハードウェアアクセラレーション設定を持つため、Chrome側の設定変更の影響を受けず、そのまま動作したと考えられる。

なお、この記事の準備段階で編集部はブラウザのUser-Agent文字列に含まれる「Intel Mac OS X 10_15_7」という表記から、検証に使ったMacをIntel搭載機だと誤認していた。実際にはnavigator.userAgentData.getHighEntropyValues()で確認したところ、このMacはApple Silicon(architecture: "arm")だった。User-Agent文字列の「Intel Mac OS X 10_15_7」は、Apple SiliconのMacでもChrome・Safariが互換性のために表示し続けている固定的な表記であり、実際のCPUアーキテクチャの根拠にはならない。この誤りは読者からの指摘で判明し、本稿では修正した。ブラウザのUser-Agent文字列だけを見て「どんなハードウェアか」を判断してはいけない、という教訓も、今回の検証のもう一つの副産物である。

ここから読者が持ち帰るべき教訓は二段構えになる。第一に、「WebGPU対応ブラウザ」というラベルを信用してツールを配布しても、特定のブラウザ・環境では黙って動かないことがある。第二に、その原因は今回のようにchrome://gpuを確認すれば数秒で特定できる単純な設定であることも多く、ハードウェアやドライバの互換性を疑う前に、まずこの一枚のページを確認する価値がある。ただし、これを自分で確認できる読者は限られる。一般の利用者にとってchrome://gpuは存在すら知らないページであり、ツール側が「動かない理由」をもう少し能動的に伝える設計を考える余地は残る。

単一HTMLとブラウザ内LLMを組み合わせる意味

なぜこの組み合わせを試したのか。AIでツールを量産する個人開発者のユウタさんは、単一HTMLアプリの文脈における透明性を強調した。

「単一HTMLアプリの文脈では、この検出ロジック自体もview-sourceで丸見えになる。ユーザーは『なぜ自分の環境で動かないか』をソースを読んで自分で調べられる。クラウドAPIラッパーではこれができない。動かない理由がブラックボックスのサーバー側にある場合、ユーザーには何も見えない」(ユウタ)

文章はサーバーに一切送られず、AIによる下書き作成とその場での編集がブラウザの中だけで完結する。しかもコード全体は右クリック一つで確認できる。これは、ブラウザ内LLMという性質と、単一HTMLアプリという配布形式が組み合わさって初めて成立する透明性であり、どちらか片方だけでは得られない価値だとユウタさんは位置づけた。

AIの出力を生のHTMLとして信用しない、という設計判断

一方で、この組み合わせは既存の「1枚のHTMLアプリ」記事では扱っていなかった論点を新たに持ち込んだ。アプリケーションセキュリティの専門家であるレンさんが指摘したのが、AIの出力をどう扱うかという設計判断だ。

編集部は実装当初から、AIが生成したテキストを必ずエスケープしたうえで、編集部自身のコードが見出し・段落・箇条書きなどの安全なタグを組み立てる設計にしていた。AIの出力を生のHTMLとして信用しない、という判断だ。

「AIが返すテキストをinnerHTMLに直接渡せば、モデルが<script>alert(1)</script><img onerror=...>を含む出力をした場合、それがそのまま実行される。小型モデルはinstruction-followingが弱いことも確認済みであり、『HTMLタグを出力するな』という指示が守られる保証はない。サニタイズは『あると良い』ではなく、設計の必須要件だ」(レン)

レンさんはさらに、ユウタさんが挙げた「view-sourceの透明性」が諸刃であることも指摘した。ソースコードが丸見えということは、攻撃者にとってもサニタイズの抜け穴を探しやすい構造を意味する。だからこそ、透明性を利点として謳うなら、サニタイズのロジックを堅牢にしておくことが前提条件になる、という整理だ。「動く設計」と「安全な設計」は独立した軸であり、検出ロジックが正しくても、出力の内容を無条件に信頼した実装は別の脆弱性を生む――これが今回の検証で新たに直面した論点だった。

Ctrl/Cmd+Zが効かなかった、という「取り消せない侵入」

実装の過程では、もう一つ具体的なバグが見つかった。編集部は当初、AIが書いた文章の挿入をDOMのRange APIで直接行っていた。その結果、「Ctrl/Cmd+Zで元に戻せます」とユーザーに案内していたにもかかわらず、実際にはブラウザ標準のundo履歴にその挿入が乗らず、undoしても何も起きないというバグが見つかった。

ユーザー体験と信頼性の研究者であるミサさんは、このバグを単なる実装ミス以上のものとして位置づけた。

「ユーザーが『元に戻せる』と信じて操作し、その期待が裏切られる瞬間、壊れるのは機能への信頼だけでなく『このツールは自分の意図通りに動く』という根本的な感覚だ。AIが書いた文章という『自分が書いたのではないコンテンツ』が編集領域に混入した直後にundoが効かないのだから、ユーザーは『AIの出力を消せない』状態に一瞬置かれる。これは自律性の剥奪に近い体験だ」(ミサ)

実際にこの試作を使ってみたソラさん(この種のツールを試してみた生活者代表)は、修正前後の違いを体感として語った。

「undoが効かなかった瞬間の感覚は、『道具に裏切られた』というより『AIに上書きされた』に近かった。修正後のツールで同じ操作をすると、その不安がすっと消える」(ソラ)

編集部はこの問題を、挿入方法をdocument.execCommand("insertHTML")経由に変更することで解消した。修正後はexecCommand("undo")で正しく元に戻ることを確認している。

項目修正前修正後
挿入方法DOM Range APIで直接挿入document.execCommand("insertHTML")
Ctrl/Cmd+Zの案内表示していたが実際には無効実際にundo履歴に乗り、有効
ユーザー体験「元に戻せる」という案内が嘘になる手入力と区別なくundoできる

表は編集部が実装過程で確認した修正の前後を整理したもの。ミサさんはここから「AIの出力はブラウザの通常の編集フローと完全に同等に扱われなければならない」という設計原則を導いた。AIだから特別扱いするのではなく、ユーザーの手入力と区別なくundo履歴に乗ること。そうでなければ、AIの介入はいつでも「取り消せない侵入」になりうる、という指摘だ。レンさんが挙げたサニタイズの堅牢性と、このundo統合は、どちらも「AIを信用しない設計」の二つの側面だといえる。

なお、レンさんはexecCommand("insertHTML")自体が、ブラウザベンダー・MDN等では非推奨(deprecated)の扱いを受けている古いAPIであることも付け加えた。正式な後継の標準APIがあるわけではなく、今回の実機では動作を確認できたが、将来のブラウザバージョンで挙動が変わるリスクは残る長期的な設計依存先として、この点は明記しておくべきだという指摘だ。

小型モデルは、指示に従わないことがある

編集部が実際に0.5Bパラメータの小型モデルへ「もっとカジュアルに」といった書き直しを指示したところ、指示を無視して原文や指示文をそのまま繰り返す、あるいは指示と無関係な内容を書いてしまう、という失敗が複数回観測された。プロンプトに「前置きや繰り返しを書かない」という指示を追加しても、完全には解消しなかった。

実際にこの試作を使ったソラさんは、この問題の方が根本的だと感じたという。

「『カジュアルに書き直して』という指示が機能しないとき、undo以前に『挿入する価値のある出力が来ない』という根本的な壁にぶつかる。サニタイズもundoも『AIの出力が来た後』の話だが、私が何度も試して感じたのは『まともな出力がそもそも来ない頻度の高さ』が一番の摩擦だということ」(ソラ)

ここで事実確認を担う編集者のテツオさんが、議論に歯止めをかけた。「複数回観測された」という記述だけでは、10回試して2回失敗したのか、5回中4回失敗したのかがわからず、読者が実用性を判断する根拠にならない、という指摘だ。編集部はこの点について、失敗の発生回数や条件を厳密に集計しておらず、正確な失敗率は「未集計」であることをここに明記する。

一方でナオさんは、失敗率の数字よりも「失敗のパターンが予測可能かどうか」の方が読者の実用判断に効くという見方を示した。原文を繰り返す・無関係な内容を出す、という2種類の具体的な失敗パターンが記録されていること自体は確認済みの事実であり、これは確率論的なばらつきというより、小型モデルのアーキテクチャ上の能力限界に起因する構造的な傾向だとナオさんは位置づけた。自然言語の書き直しは、コード生成と違って「正解」が文脈と文体感覚に依存するため、小型モデルが学習した分布では再現しにくい、という整理だ。

議論ではこのあと、システムプロンプトを短く単一の具体動詞に絞ると失敗率が下がるのではないか(ハルカさんの経験則)、「常体に変換」「箇条書きに変換」のように入出力の差分が形式的に検証できる指示をボタン化すれば0.5Bモデルでも実用的な体験に近づけられるのではないか(ユウタさんの提案)、といった仮説も出た。ただしテツオさんが指摘した通り、これらは編集部が実際に検証・比較した結果ではなく、参加者それぞれの実装経験に基づく仮説の段階にとどまる。読者に伝えるべきは、「対策のアイデアはあるが、今回のツールで裏付けられた事実ではない」という区別だ。

反対意見:今の小型モデルで、このツールは実用に値するか

ここまでの経緯を踏まえ、議論では懐疑的な見方も率直に扱われた。核心は「0.5Bという小型モデルの品質で、このツールは実用に値するのか」という問いだ。

ソラさんが実際に使って感じた「まともな出力がそもそも来ない頻度の高さ」は、サニタイズやundoの設計をどれだけ堅牢にしても解決できない、モデル選択そのものへの問いだ。クラウドのAPIを使えばより大きなモデルで高品質な書き直しが期待できるという反論は成り立つが、その場合はサーバーに文章を送らないという今回の設計の前提――医療・法務などの機密文書にも応用できる透明性――を手放すことになる。品質と機密性はトレードオフの関係にあり、どちらを優先するかは用途次第だというのが、この議論から見える構図だ。

ミサさんはもう一点、ハードウェア依存の不安定さがユーザーの信頼にどう影響するかを掘り下げた。

「『動くはずなのに動かない』体験の信頼毀損は、初回の失敗より更新後の失敗の方が深刻だ。初回は『まだ試行錯誤中の道具』と受け取れる。しかし一度動作を確認して信頼した後に壊れると、ユーザーは『裏切られた』と感じ、その後の正常動作さえ疑い始める」(ミサ)

execCommand("insertHTML")が非推奨扱いである以上、ブラウザの将来のアップデートで同じ挙動が保証される保証はない。ミサさんは、「修正の完了」ではなく「確認の継続」こそが信頼の維持になると結論づけた。ハードウェアやブラウザのバージョンに依存する機能を提供する以上、公開後も動作確認を続ける運用が必要だという指摘だ。

読者が持ち帰るべき判断基準

この種のツールを試す、あるいは自分で作る場合に確認すべきことを整理すると、次のようになる。

ブラウザ内AI機能付きのツールを開いた

起動時にrequestAdapter()の成否を
  自分の環境で実際に確認したか?
        ↓ 成功                  ↓ 失敗・非対応
AI機能を試す                Chromeなら chrome://gpu を開き、
                              「WebGPU: Disabled」の理由を確認する
                              (ハードウェアアクセラレーションの
                                設定がオフになっていないか)

                              直らなければ手動編集機能だけを使う

AIが書いた文章はあくまで下書きとして扱う
(原文の繰り返しや無関係な内容が返ることがある)

ツールの実装を確認できるか?(単一HTMLならview-source)
  AIの出力を生のHTMLとして信用せず、
  安全なタグに変換してから挿入する設計か

undo(元に戻す)が実際に効くか、
  手元で一度試してから使い始める

図は今回の検証を踏まえた編集部の整理であり、特定の製品やベンダーが示す公式の手順ではない。ポイントは、「対応ブラウザである」ことと「自分の環境で実際に動く」こと、「AIが書いた」ことと「信用してよい」ことを、それぞれ別の軸として意識的に区別することにある。

デモ:AI機能付きのリッチテキストエディタを実際に試す

デモを開くでは、今回の記事のために完成させたバージョンを公開している。ツールバーで太字・見出し・箇条書きなどを整えられるリッチテキストエディタに、WebLLMによる「AIで新しく書く」「選択範囲をAIで書き直す」機能を組み込んだもので、ここまでに触れたundoのバグは修正済みだ。

このデモを開いたときの体験は、環境によって2通りに分かれる。

  1. WebGPU対応かつアダプタ取得に成功する環境:起動時にrequestAdapter()を試し、成功すればAI機能のボタンが有効になる。初回はモデル本体(数百MB)のダウンロードが必要で、環境によって数十秒からそれ以上かかる(2回目以降はブラウザにキャッシュされ速くなる)。
  2. 非対応、またはアダプタ取得に失敗する環境(今回の検証で見つかったChromeのケースのように):起動時のチェックでAI機能が使えないと判定され、「このブラウザ・環境では非対応」という表示が出る。ツールバーによる手動編集機能(太字・見出し・箇条書き・引用・リンクなど)はそのまま利用できる。

どちらの場合でも、壊れた見た目にはならない。AI機能が使えるかどうかにかかわらず、リッチテキストエディタとしては普通に使えるようにしてある。

出典を読むときのポイント

今回の実機検証(同一MacでのChrome/Safariの挙動差、chrome://gpuで確認したGPUアクセス無効化という根本原因、Apple Silicon環境での所要時間、undoバグの修正、小型モデルの指示追従の失敗)は、いずれも編集部が今回の実装で実際に確認した一次体験であり、外部の資料からの引用ではない。失敗の発生率など集計していない数値については、本文中で「未集計」と明記した。なお、検証に使ったMacのCPUアーキテクチャについて、当初User-Agent文字列に基づく誤った記述(Intel搭載機との誤認)があったが、navigator.userAgentDataによる確認後、本文を修正している。

キーワード:#WebGPU#WebLLM#単一HTMLアプリ#サンドボックス

出典

コメント