コンテンツにスキップ

ADR-0045: AI のエージェントからの操作は、ツールごとに 7 日のあいだ保存するスイッチで許可し、消す操作と全体を置き換える操作はページが確認を出す

Status

承認

Context

AI のエージェントが、プレイグラウンドのツールを操作できるようにする。
誰に操作を許すか、利用者がどう許可するか、どの操作の前に利用者の確認を挟むかを決める必要がある。

Decision

1. 対象の利用者

訪問者の AI のエージェントと、運営者の AI のエージェントを区別しない。
アカウントが無く、区別する手段が無いためである。

2. 許可のスイッチ

ツールのページに、「AI からの操作」のスイッチを置く。

  • デフォルトはオフにする。
  • 利用者がオンにした状態は、ツールごとに、localStorage に 7 日の期限を付けて保存する。期限が過ぎたら、オフに戻す。
    • 保存する理由は、再訪のたびにオンにする手間を無くすためである。
    • 期限を付ける理由は、利用者が許可したことを忘れたまま、操作が公開され続けないようにするためである。
  • スイッチのほかに、状態を示す文言を、ヘッダーなどの画面に足さない。画面をシンプルに保つためである。
  • オフの間は、操作を登録しない。polyfill と、relay につなぐスクリプトも読み込まない。
  • オンにすると、操作を登録する。オフに戻すと、登録を解除する。
  • スイッチは、AI のエージェントを区別しない。オンの間は、その端末の拡張機能と、relay につないだ MCP のクライアントの全てが、操作を呼べる。

3. 操作を公開するページ

操作を公開するのは、play.fukuemon.dev をトップレベルで開いたページだけにする。
記事に埋め込む iframe には、allow="tools" を付けない。

4. ページが確認を出す操作

次の 5 つの操作は、ページが利用者に確認を出し、利用者が通してから実行する。
利用者が作ったものが、確認なしに消えないようにするためである。

  • 実行環境のファイルを消す操作
  • Go のファイルを消す操作
  • Excalidraw の全ての要素を消す操作
  • draw.io の図の全体を置き換える操作
  • スライドの Markdown の全文を置き換える操作

確認の画面に、「このページでは今後尋ねない」の選択を置く。
利用者が選ぶまで、ページは、5 つの操作のたびに確認を出す。
利用者が選ぶと、ページは、その後の操作を、確認を出さずに実行する。
AI のエージェントがスライドを書き換えるたびに、確認が出ないようにするためである。

「このページでは今後尋ねない」を選んだ状態も、ツールごとに、localStorage に 7 日の期限を付けて保存する。
期限が過ぎたら、確認を出す状態に戻す。

コマンドを実行する操作は、確認なしで実行する。
コマンドは WebContainers の中で動き、プレイグラウンドに保存した図とスライドに届かないためである。

次の操作も、確認なしで実行する。

  • SQL を実行する操作。DROP と DELETE を含む SQL も、確認なしで実行する。DB の中身は保存されず、Web Worker を作り直すと初期の状態に戻るためである。
  • Go のファイルを書く操作。Node の実行環境のファイルを書く操作も、確認を出さない。
  • Go を実行する操作と、テストを実行する操作。Yaegi で動かすコードが、ページの localStorage と IndexedDB を読み書きできないようにしたうえで、確認を出さない。

consequentialHint は、消す操作、draw.io の図の全体を置き換える操作、コマンドを実行する操作、SQL を実行する操作、Go を実行する操作、テストを実行する操作に付ける。
ヒントだけでは確認が出ないので、ページの確認と併せて使う。

5. 操作の記録

AI のエージェントが呼んだ操作の名前、引数、結果を、ツールの画面の操作の記録の欄に出す。

6. ADR-0031 の Decision 4 との関係

ADR-0031 の Decision 4 の条件(他人が用意したコードを、訪問者の操作なしに動かさない)は、変えない。
AI のエージェントが書いたコードは、利用者がスイッチをオンにし、自分のエージェントをつないだ後にだけ動く。スイッチのオンを保存してある 7 日のあいだも、利用者がオンにした状態として扱う。
利用者が自分の操作で動かしたコードとして扱う。

Verification

端末、ブラウザ、バージョンは、ADR-0044 の Verification と同じである。

確認したこと 結果
スイッチがオフのとき ページの中の API、拡張機能、relay のどれからも、操作は一覧に出なかった
スイッチをオンにしたとき 操作が一覧に出て、呼べた
スイッチをオフに戻したとき 操作が一覧から消えた。relay を通すと、呼んだときに「Tool slides_read not found」が返った
consequentialHint を付けた操作 全ての要素を消す操作、ファイルを消す操作、コマンドを実行する操作は、ページの中の API から、確認なしで実行された
別の origin の記事に埋め込んだ iframe allow="tools" が無いと、登録は「NotAllowedError」で拒否された。allow="tools" を付けると、登録できた
  • consequentialHint の行は、headless の Chrome 156 で確認した。ブラウザに組み込まれたエージェントと、headless でない Chrome が確認を出すかは未確認である。
  • どのページでも、呼んだ操作の名前、引数、結果が、操作の記録の欄に 1 行ずつ出た。
  • 試作のページは、relay につなぐスクリプトをページの読み込みのときに読み込んだので、スイッチがオフでも 127.0.0.1 への接続を試みた。スイッチをオンにしたときにだけ読み込む形は、試作していない。
  • ページが確認を出す作りと、スイッチと確認の状態を localStorage に保存する作りは、試作していない。試作のスイッチは、ページを開くたびにオフで始まった。
  • Excalidraw と draw.io の undo が、AI のエージェントの操作を戻せるかは未確認である。
  • COPY と pg_read_file のような、ファイルを読み書きする SQL が、Web Worker の外のファイルを読み書きできるかは、未確認である。

Considered Options

選択肢 強み 弱み
採用: スイッチのオンと「このページでは今後尋ねない」を、ツールごとに localStorage に 7 日の期限を付けて保存し、消す操作と全体を置き換える操作はページが確認を出す 利用者が許可していない間は、操作を呼べない。再訪のたびにオンにする手間が無い。利用者が作ったものが、「このページでは今後尋ねない」を選ぶまで、確認なしに消えない オンにしてから 7 日のあいだは、ページを開くだけで操作が公開される。利用者が「このページでは今後尋ねない」を選んだ後は、消す操作も確認なしで実行される
スイッチを、ページを開くたびにオフに戻す 利用者が許可したことを忘れたまま、操作が公開されることが無い 再訪のたびに、スイッチをオンにする
スイッチのオンを、期限を付けずに localStorage に保存する 再訪のたびにオンにする手間が無い 利用者が許可したことを忘れたまま、操作が公開され続ける
スイッチの状態を示す文言を、ヘッダーなどに出す 利用者が、操作が公開されていることに気づきやすい 画面の要素が増える
?ai=1 のような URL で開くと、スイッチがオンで始まる 運営者が、自分のエージェントに URL を渡して使える 他人が、オンで始まる URL を開かせられる
読み取りのほかの全ての操作で、ページが確認を出す 利用者が、全ての変更を見てから通せる 図形を 1 つ足すたびに確認が出て、AI のエージェントに任せる利点が減る
ページは確認を出さず、スイッチと consequentialHint だけにする 作るものが少ない AI のエージェントが、利用者の図とファイルを、確認なしに消せる
操作を、運営者だけに公開する 訪問者の端末で、AI のエージェントが操作することが無い アカウントが無く、運営者を区別する手段が無い
記事に埋め込んだ iframe にも、操作を公開する 記事を読みながら、AI のエージェントに操作させられる 記事のページの操作は、範囲の外である。記事のページが、iframe の操作を見られるようになる

SQL だけを動かすツールと Go を動かすツールの操作に、確認を出すかの選択肢は次のとおり。

選択肢 強み 弱み
採用: Go のファイルを消す操作に確認を出し、SQL を実行する操作、Go を実行する操作、テストを実行する操作には出さない エージェントは、利用者の SQL を読み、直した SQL を実行できる。Go では、Node の実行環境と同じ使い方で、ファイルを書いて実行できる Yaegi に渡す symbol を増やすと、確認を出さない理由が成り立たなくなる
SQL を実行する操作で、SELECT のほかの文を含むときに確認を出す 利用者が、DB を変える SQL を見てから通せる 文の種類を見分ける処理が要る。CTE の中の DELETE と、関数の呼び出しでの書き込みは、見分けにくい
Go のファイルを消す操作に、確認を出さない 確認を出す操作が増えない 利用者が書き換えたファイルが、確認なしに消える。初期の状態に戻しても、書き換えた分は戻らない
Go を実行する操作とテストを実行する操作のたびに、確認を出す Yaegi に渡す symbol に依らずに、利用者が実行を見てから通せる 「このページでは今後尋ねない」を選ぶまで、エージェントが 1 回実行するたびに、利用者がボタンを押す

Consequences

Positive

  • 利用者がスイッチをオンにしていない間と、オンにしてから 7 日が過ぎた後は、AI のエージェントは、ツールを操作できない。
  • 利用者は、7 日のあいだ、再訪のたびにスイッチをオンにし直さずに済む。
  • 利用者は、AI のエージェントが行った操作を、画面で見られる。
  • 利用者が作った図、スライド、ファイルは、利用者が確認を通すか、「このページでは今後尋ねない」を選ばない限り、AI のエージェントの操作で消えない。
  • ファイルを消す操作が、利用者が書いて保存した Go のファイルを消すのは、利用者が確認の画面で確定のボタンを押したときと、「このページでは今後尋ねない」を選んだ後だけである。

Negative

  • スイッチは、AI のエージェントを区別しない。オンの間は、その端末でつながった全てのエージェントが、操作を呼べる。
  • 利用者がスイッチをオンにしてから 7 日のあいだは、そのツールのページを開くだけで、操作が公開される。利用者は、オンにしたことを、スイッチを見て確認する。
  • 「このページでは今後尋ねない」を選んでから 7 日のあいだは、AI のエージェントが、利用者が作った図、スライド、ファイルを、確認なしで消せる。
  • localStorage を消すと、スイッチと確認の状態は、デフォルトに戻る。
  • AI のエージェントは、確認なしで、コマンドを実行でき、ファイルを書き換えられ、図に要素を足せる。
  • AI のエージェントが実行環境で動かしたコードは、実行環境の中のファイルを消せる。確認が出るのは、ファイルを消す操作を呼んだときだけである。
  • 確認の画面と、操作の記録の欄を、ツールごとに置く。
  • AI のエージェントは、確認なしで SQL を実行できる。Go のファイルの書き換えと、Go のコードの実行も、確認なしでできる。