なんか今時はブラウザの中でAIが動くらしいぞ!!! ということで、触ってみたわけです。
まずアプリケーションを cursor-agent に作らせてみた。
こういうやつ。よくあるチャットUIである。よくあるものなので、AIが苦もなく作ってくれる。便利だ。

Chrome v140ではまだプロンプトAPIはデフォルトで有効になっていないため、chrome://flags/ から Prompt APIを Enabled にする必要がある。再起動してAI使おうとすると、裏側でモデルのダウンロードが始まる。10G近くあるのでは。しばらく待ちましょう。
AIのバイブス
今日はなるべくフルオートでバイブコーディングってやつをやらせてみたかったんです。
ただ、最近はいろいろサプライチェーン攻撃とかが猛威を振るっていて、新しいプロジェクト構成をセットアップするのが少し怖さがある。ということで新しいOSユーザを作成して権限絞った状態で開発環境を構築した。「こ、これがエンジニア初心者にとってハードルが高いという『開発環境構築』か...!」みたいな気持ちになってた。はい。
新しい環境セットアップすると考えたとき、cursorはGitHubでログインすれば使えるので最小限の権限でイケるのがよいですね。SSOさえしなければ、組織の情報へのアクセスも発生しないし。
やり方
依頼の概要は以下のような感じ。
- ChromeのAI機能で完結するAIチャットを作ります。
- チャットUIを作ってくれ。画面下部にチャット入力欄があるよくある感じで。
- システムメッセージはチャット入力欄の下に必要に応じて出てくる感じにして。
- 音声入力もできるようにしてくれ。音声入力はトグルスイッチがヘッダについてるとかでいいよ。
- AIの応答は、受信・AIへの送信・思考中、みたいな感じでチャット画面の中で表示するようにしよう。
- Chromeのモデルがダウンロード中は「ダウンロード中」って表示させて。
- AIにはユーザー属性の推測とか、ここまでの会話の満足度とかを推論させよう。
あとは出来上がりを眺めながら、「このメッセージはチャット入力欄の下に移動して」とか「ストリーミング表示してくれ!」とか依頼していく。Chrome の AI 関係のAPIについての知識は十分ではなく、途中から自分も一緒に調べながらやってた。あとプロンプトにちょこちょこ手を入れるのは直接やってました。
作業感想
- いわゆる指示だけ出して成果物を評価するバイブコーディングをしてみたが実用性は高くなっている
- いきなり複雑なものを作り切れるわけでも、作ったものを修正しながら十分よい品質のものにしあげるのもまだ難しい
- ざっくり作ったものを眺めて失敗の経験や、設計に関する知識を次回のAIへの入力にして、何度も回せば品質はあがっていくイメージは十分ある
- 人間側が「これで動かないのはこのAPIがこの指定をサポートしていないからだ」みたいな知識を溜めていく。
- このサイクルがあるので、一番最初はしかたがないけど、AIへの入力は文書化しておくのが100%正解。
- AIに対して指示を出すため、ボキャブラリは多いに越したことはない。今回は、UI上の指定をするときに「サイドバー」や「フッター領域」みたいな一般用語はぱっと出てきたけど、チャットUIの中での「バブル」という用語を知らなかったり、「システムメッセージ」や「レベルインジケータ」みたいな言い回しが出てこなかったりした。言葉があれば指示が間違いづらくなる。人間が「なんとなく崩れている」と言ってもわからない。
できたものに対する感想(内容)
Chrome Prompt API の動作に合わせて設計されてない、という感想。効率が悪い。
最初は session をチャットのやりとりごとに生成するような作りになっていた。
セッションが不要になった場合は、destroy() を呼び出してリソースを解放します。セッションが破棄されると、そのセッションは使用できなくなり、進行中の実行はすべて中止されます。セッションの作成には時間がかかるため、モデルを頻繁にプロンプトする場合は、セッションを維持することをおすすめします。
と上のブログ記事にはあるのだけど、この記述をきっと cursor くんが見落としたに違いない...。で、あとから prompt()
から promptStreaming()
に変更したんだけど、システムプロンプトみたいなやつの取り回しが最初わかってなくて、毎回、「過去の要約 + 直近の会話のやりとり + システムプロンプト」を渡して推論させるような作りになっている。けど、これはたぶん誤りで、session は InitialPrompt を与えて初期化したあと、会話のやり取りはappend()
とか prompt()
で行って、コンテキスト長がいっぱいになったらここまでの要約をさせて clone()
で後続のセッションを作り、古いやつはdestroy()
しておく、というような使い方が想定されていそうである。...というのを、cursor くんもそうだけど自分もわかってなくて、だいぶよくわかんない作りになってしまった。
また、Reactで作らせて見た目はそれっぽくはなっているんだけど、UIコンポーネントとステート管理が密結合されてしまっている...というか「チャットUI」に「AIとの対話機能」が埋め込まれてしまっている。そういう、内部の作りの分割はあらかじめ人間が指示しないといけなさそうだ。指示というか、設計パターンだろうか。「こういうものとこういうものは分ける」みたいなやつ...。
特に指定しなかったからだろうけど、TypescriptではなくJavascriptで実装されていた。
AIに対してメッセージ送信するところの進捗をユーザーに共有するあたりとかはめちゃくちゃダミー感がある処理が生成されていてよかった。「とりあえず1秒待ったら送信済みにする」みたいな感じの setTimeout()
とか。
チャットに応じるAIの作り込みは楽しそうだ
思ったよりも「はい、AIにメッセージ渡して、結果をストリームで受け取って終わり」という感じではなくて面白かった。もうちょっと手を入れていきたい。