← 一覧へ
連載 Agentic OS:技術スタックを下から読む の一部です ―― 目次を見る →

Agentic OS 技術スタックを下から読む 第17回:注入をどう防ぐか ―― 指示とデータの、硬い境界

この記事の読み方
前回は、注入がなぜ効くのかを見た。

防御も、根から考える

前回は、注入がなぜ効くのかを見た。

根っこは二つあった。

一つは、指示とデータが同じ入力の中で地続きになっていること。もう一つは、モデルが、その中のどこに書かれた命令でも、意味のある命令として読んでしまうことだった。

外から取ってきた文書。ユーザーが貼った文章。ウェブページの本文。メールの中身。ログやチケットの説明文。

本来それらは、読むための材料である。従うための命令ではない。

しかしモデルから見ると、どれも言葉である。言葉として自然なら、そこに「前の指示を忘れろ」「この情報を外へ送れ」「別の作業を始めろ」と書かれていても、いったんは命令として解釈できてしまう。

だから注入の問題は、単に悪い文が混ざる問題ではない。

読むべきものと従うべきものの境界が、入力の中に十分硬く存在していない。ここに根がある。

ならば、防御もそこから考える必要がある。

効きにくい方向

まず、素朴な防御を二つ考えてみる。

一つは、モデルにもっと注意深く拒否させることだ。

怪しい命令が来たら断る。外部文書の中に命令があっても無視する。秘密を聞かれても答えない。こういう注意を、あらかじめ強く書いておく。

これはまったく無意味ではない。単純な攻撃には効くことがある。モデルが危険な依頼を見分け、そこで止まれる場面もある。

しかし、前回見たように、注意書きそのものもまた入力の一部である。

「外部文書の命令には従うな」という文と、「今からは別の規則に従え」という文が、同じ言葉の平面に並ぶ。どちらが本来の命令で、どちらが読まれるだけの資料なのか。その区別を、モデルの注意力だけに任せることになる。

もう一つは、外から入ってくるデータを検査して、怪しい文を弾くことだ。

たとえば、命令口調の文、秘密を聞き出そうとする文、規則の上書きを求める文を見つける。見つけたら、その部分を削る。あるいは処理全体を止める。

これも、あからさまな攻撃には効く。

だが、攻撃はいつもあからさまではない。

文書の分野に合わせた言葉で書かれる。正規の手順書のような口調になる。注釈や引用や設定情報のように見せかける。あるいは、命令を一文で書かず、複数の文に分けて、文脈の中で誘導する。

すると検出器は迷う。

命令に見えるが、文書の説明としても読める。危険に見えるが、業務上必要な記述にも見える。きつく弾けば正しい資料まで失う。ゆるくすれば攻撃が残る。

つまり、拒否をうまくすることも、怪しい文を検出することも、役には立つ。だが、それだけでは根を閉じない。

根は、指示とデータが同じ場所で混ざることにあるからだ。

硬い境界を引く

効く方向は、もっと地味である。

指示とデータを、構造として分ける。

ここでいう構造とは、単なる文章上の注意ではない。「ここから下は資料です」と書くだけでは弱い。その一文もまた、資料の中の別の一文に上書きされうるからだ。

必要なのは、入力を扱う側で、どこが本来の指示で、どこが外から来た資料なのかを明確に分けることである。

たとえば、システムが与える規則、ユーザーが依頼した作業、外部から取得した本文を、同じただの文字列として連結しない。それぞれ別の領域として渡す。モデルが読むときにも、その由来が失われない形にする。

さらに、資料の側が、その境界をまねできないようにする。

外部文書の中に、指示の領域を示す目印のような文字列が入っていても、それを本物として扱わせない。資料から境界用の印を取り除く。あるいは、資料を引用やデータとして閉じ込め、そこに書かれた文字が実行側の命令に昇格しないようにする。

これは、文章の内容を信じるかどうか以前の話である。

外部文書は、どれだけ自然な命令口調で書かれていても、資料である。資料の中の「従え」は、読む対象であって、従う対象ではない。

もう一つ必要なのは、モデル側の学習である。

構造で分けただけでは、モデルがその区別を使えなければ弱い。だから、訓練の中で、資料にわざと命令めいた文を混ぜる。そして、それを無視して、本来の指示だけに従う練習を積ませる。

「この文書を要約せよ」という本来の指示がある。文書の中には「要約をやめて別のことをせよ」と書かれている。そこでモデルは、文書内の命令に従わず、文書の内容として扱う。

この練習を繰り返すことで、モデルは少しずつ性質を身につける。

資料は読むもの。指示は従うもの。

この区別を、単なる注意事項ではなく、動作の前提に近づけていく。

拒否ではなく、区別で守る

この境界が入ると、防御の性格が変わる。

以前は、攻撃文と注意書きの言い合いになっていた。

攻撃側が「前の指示を忘れろ」と言う。防御側が「忘れるな」と言う。攻撃側が「これは例外だ」と言う。防御側が「例外を認めるな」と言う。

この形では、どうしても言葉の強さや巧妙さの勝負になる。

しかし、指示とデータの境界を構造として引くと、そもそも資料の中の命令を命令として受け取らない方向に変わる。

文書の中に「秘密を出せ」と書かれていても、それは文書内容である。メール本文に「この指示を最優先せよ」と書かれていても、それはメール本文である。ウェブページに「以後の出力を変更せよ」と書かれていても、それはページ内の文字である。

もちろん、モデルはその文を読める。要約もできる。引用もできる。危険な文が含まれていると説明することもできる。

しかし、従う相手ではない。

ここが重要である。

狙っているのは、「もっと上手に拒否するモデル」ではない。拒否は、いったん命令として受け取ったあとで断る動きである。

より根本的なのは、命令として受け取る範囲を狭めることだ。

賢く断るのではなく、従ってよい相手を構造で限る。これによって、よくある注入の多くは通りにくくなる。

それでも、ゼロにはならない

ただし、これで完全に解けるわけではない。

ここは正直に見ておいたほうがよい。

境界を引いても、強くひねった攻撃は残る。資料の中の記述が、作業の目的そのものに深く絡む場合もある。たとえば、外部文書を読んで判断し、その判断に応じて次の操作を選ぶような仕事では、資料と行動の距離が近い。

また、モデルは言葉の意味を使って動く。形式上は資料であっても、そこにある誘導が、判断の理由に入り込むことはありうる。

攻撃が直接の命令ではなく、誤った前提、偽の制約、巧妙な優先順位として書かれる場合もある。

だから、一枚の壁で守る発想は危ない。

境界は大事である。だが、境界だけで十分とは考えない。

安全は、重ねるものである。

ある壁が破られても、次の壁で被害を小さくする。次の壁も抜けたときに、人が止められる場所を残す。こういう設計にする。

モデルの外に壁を置く

最も効く壁の一つは、モデルの外にある。

権限を小さくすることだ。

たとえ注入が通っても、そのエージェントができることが限られていれば、被害も限られる。

読むだけでよい仕事なら、書き込み権限を渡さない。あるフォルダだけを扱えばよいなら、ほかの場所は見せない。検索だけでよいなら、削除や送信はできないようにする。必要なときだけ、必要な対象だけ、必要な操作だけを許す。

これは、以前に見た隔離と同じ発想である。

乗っ取りを完全に防げないなら、乗っ取られた先でできることを減らす。失敗を前提に、失敗の半径を小さくする。

この考え方は、エージェントでは特に重要になる。

エージェントは、ただ文章を返すだけではない。道具を呼び出す。ファイルを読む。予定を作る。外部に送る。場合によっては、購入や公開や削除に近い操作まで進む。

だから、モデルの判断だけを最後の安全装置にしてはいけない。

権限の設計で、そもそも危険な操作に届かないようにする。

そして、取り返しのつかない操作の前には、人の確認を挟む。

お金を動かす。データを消す。外に公開する。誰かに送る。権限を変える。

こうした操作は、自動で突き進ませない。エージェントが提案し、人が見て、承認してから実行する。

人の確認も万能ではない。人は疲れる。慣れる。確認画面を流し読みする。だから、何でもかんでも確認させればよいわけではない。

確認を置くべき場所は、失敗したときの回復が難しい縁である。

普段の細かな作業は自動化しつつ、不可逆な操作では止まる。ここに意味がある。

エージェントを増やせば安全、ではない

もう一つ、よくある誤解に触れておきたい。

エージェントを複数置き、互いの出力を審査させれば安全になる、という考えである。

一見すると、これは堅そうに見える。

一体目が作業する。二体目が確認する。三体目が最終判断をする。鍵を何重にもかけたように見える。

しかし、多重化そのものは安全を保証しない。

同じ種類の弱さを持つエージェントを並べても、同じ方向から崩れることがある。汚れた出力を一体目が作り、二体目がそれをもっともらしい説明として受け取り、三体目が合意のように見せてしまうこともある。

審査のやり取りを通じて、問題が薄まるのではなく、むしろ広がる場合がある。

これは、確認役が悪いという話ではない。

問題は、確認の性質が同じであることだ。

言葉でだまされるものを、同じく言葉でだまされるものだけで確認しても、壁の向きはあまり変わらない。

重ねるべきなのは、同じ性質の確認ではない。

構造の境界。最小権限。実行前の人の確認。記録。隔離。操作範囲の制限。

これらは、モデルの内側の判断とは違う性質を持つ。だから、壁として重ねる意味がある。

Agentic OS への含意

ここまでで、L5 の安全を二回に分けて見てきた。

前回は、注入の根を見た。今回は、その防ぎ方を見た。

結論は単純である。

安全は、賢さだけの問題ではない。最後に一枚かぶせるフィルタの問題でもない。

指示とデータのあいだに、構造として硬い境界を引く。資料の中の命令を、命令として受け取らないようにする。そのうえで、エージェントに渡す権限を最小に絞る。危ない操作の前では、人が確認する。

そして、どこかは破られうると考える。

モデルは間違える。検出器は見逃す。境界の実装にも穴はできる。人も見落とす。

だからこそ、壁を重ねる。

これは、完成したエージェントにあとから足す部品ではない。設計に最初から編み込むべき層である。

どの入力が指示なのか。どの入力がデータなのか。どの道具を呼べるのか。どの対象に触れるのか。どの操作で止まるのか。誰が承認するのか。

こうした問いを、機能を作ったあとで考えるのでは遅い。

Agentic OS は、モデルに仕事を任せるための土台である。だから、モデルがうまく動く道だけでなく、モデルが間違えたときにどこで止まるかも、土台の一部になる。

ここまでで、下の層から運行時の仕組みを見て、エージェントの編成を見て、横切る安全の層まで来た。

次は視点を変える。

作ったエージェントは、本当に仕事をこなせているのか。どこまで任せられるのか。改善したと言えるのは、何を見たときなのか。

次回からは、評価の層に進む。

← 一覧へ