前回の続きから — 折衷案に残っていた2つの穴
前回のおさらいを一段落だけ。従来システムは 、同じ入力に同じ出力が返る決定論の世界で、その決定論が再現性・監査性・説明責任を支えていた。対してAIは の確率モデルで、同じ入力でも答えが揺れる。私はこの揺れを最終出力まで持ち込みたくなくて、間にJSON(=中間表現、IR)を挟み、TypeScriptの型定義で検証して後続を許可/不許可する仕組みに落とした。
前回、一番腹落ちしたのは中島氏の「LLMをコンパイラとして使う」という話だった。プロンプトを直接成果物にせず、間に台本(中間言語)を挟む。中間言語なら人間が監視できるし、コンパイラが安定していればAIの暴走を止められる、と。私がJSONでやっていたことに名前がついた感覚があって、「そういう会があったらもっと聞きたい」と書いて記事を閉じた。
で、半年運用した。動いてはいる。ただ、綻びが2つ見えてきた。
ひとつ。そもそも、この確率論は「毒」なのか。私は揺れを「意思決定に持ち込みたくないもの」として、ほぼ反射的にJSONで堰き止めていた。でも改めて考えると、AIの発散はメリットでもあるはずで、どこまでが福音で、どこからが毒なのか、その境界を自分でも定義できていなかった。ただ怖いから全部止めていた、というのが実態に近い。
ふたつ。決定論の置き場所は、本当にそこでよかったのか。よく見ると、私の折衷案では RAG が「たぶん関連する契約テキスト」をLLMに食わせていて、型検証はライブラリに後付け(bolt-on)でくっついていた。決定論を守りたいはずの箇所に、確率的な部品が混じっていた。関門の位置が、なんとなくで決まっていた。
ひとつ目が「毒と福音の境界をどう定義するか」、ふたつ目が「決定論の関門をどこに置くか」。順に降りていく。
(ちなみに前回、このジレンマのコンセプトアートをNanobananaに描かせたが、あれも同じプロンプトで同じ絵が出ない、非決定論のささやかな実例だった。揺れは、絵なら味になる。監査対象なら事故になる。この違いが、今回の背骨だ。)
確率論は毒か、福音か
最初は、単純にこう考えていた。入力には福音、出力には毒だ、と。
理由はこうだ。人が頭の中の曖昧なものを言葉にするとき、自然言語のゆらぎはむしろ助けになる。「今期の資本効率、事業部ごとに見たい」くらいの雑な入力から、モデルが不足を補い、意図を汲む。入力は、確率が働くべき場所に見えた。一方で、出力側で同じ問いに毎回違う図が返ってきたら、再現性・監査性・再利用性・比較可能性がまとめて落ちる。去年と今年で同じ定義のグラフが出ないなら、比較のしようがない。だから出力は毒。――入口は揺れていい、出口は揺れてはいけない。きれいに切れた気がした。
でも、これは反証できる。入力側にも、揺れてはいけない入力がある。
たとえば、確定した数値をそのまま打ち込む入力。あるいは、確率的に生成された図を、人が最後に手で直す訂正面。私が作っている描画エンジンにも、生成された図の引数をユーザーが編集パネルで直接いじれる場所を用意しているが、ここは自然言語に溶かしてはいけない。溶かした瞬間に「確定させる」という機能そのものが壊れる。むしろこの手の入力UIは、確率パイプにおける唯一のガードレールとして育つ。「入力=福音」で一括りにすると、この生き残る入力UIを見落とす。
だから、切れ目は入力/出力ではなかった。「人間の寄与が、ファジーな意図なのか、正確な値・確定した決定なのか」で切れる。 意図は、入力にあっても出力にあっても自然言語に溶けていい。確定した値は、入力にあっても出力にあっても、揺らされたら毒になる。だから守る。たまたま意図は入力側に、確定は出力側に多く現れる。最初に入力/出力で切れて見えたのは、そのためだった。
の発散そのものは、AIのケイパビリティだ。前回も書いたが、これを のようなガードレールで押さえ込むのは、確率的であることそのものを否定する方向に寄りやすい。決定論が欲しいなら最初から を書けばいい。殺すのではなく、封じ込める場所を選ぶ。
そう考えると、設計問題はこう言い換えられる。「出力を決定論にする」のではなく、「確率をどこに閉じ込め、どこに verdict(判定)の関門を置くか」だ。確率的な入力UI → 確率的な「意図→宣言」変換 → 【決定論ゲート=検証】 → 決定論的な出力UI
毒は、出力が決定論だから消えるのではない。出力の直前に verdict の関門を置いたから消える。順番が大事で、確率を流したあと、最後に関門で受け止める。
――ここで一段だけ、大きな旗を立てておく。「SaaS is dead」「UI is dead」という言い方が流行っている。私の見立てでは、これは全部が死ぬのではない。福音の面(意図を捕まえる入力)は自然言語に溶けて消え、毒の面(監査の要る出力)は残る。むしろ後者は、確率の時代にこそ価値が上がる。……この話は膨らませると一本の別記事になるので、ここでは旗だけ立てて、結でもう一度だけ戻る。
前回、私は「全てはツールに閉じた話ではなくケース別で、観点は決定論の是非だ」と書いた。今回はそれを、この「ファジーな意図=福音/確定した値=毒」という非対称にまで彫り込んだ、ということになる。
決定論をどこに置くか
ここからが本題だ。前節で「出力の直前に verdict の関門を置く」と言った。では、その関門を何で作るのか。
鋭い人はこう思うはずだ。
「決定論的な計算がしたいなら、Skill に検証コードを同梱すればいいのでは? RAG だってあるじゃないか。なぜわざわざ MCP なんだ?」
これはまっとうな問いで、私自身しばらく言語化できずにいた。順に潰していく。
なぜ RAG ではないのか
前回の私の折衷案では、RAG が契約(=守るべき定義や制約)をLLMに注入していた。これがまず綻びだった。
RAGは、確率的な検索が、確率的な消費者にテキストを食わせる構造をしている。取り出すのは「たぶん関連する契約テキスト」で、それをモデルが解釈する。この時点で、契約は拘束力を失って助言(advisory)に落ちる。言い換えられるし、部分的にしか適用されないこともある。そこには valid: true / false が存在しない。
つまりRAGは informing(知らせる)はできるが、verdict(判定)を出せない。決定論とは、判定を持つことだ。検索は類似度の柔らかいランキングであって、判定ではない。
もっと厄介なのは、RAGで決定論を守ろうとすると、確率がぶり返してくることだ。チャンクの切り方、埋め込み、top-k、クエリの言い回しひとつで、返ってくるものが揺れる。決定論の担保にRAGを使うのは、自己矛盾に近い。これが、前回の私が直感で「なんか違う」と感じていたことの正体だった。加えて、RAGのインデックスは元の契約のロッシーなコピー(影)で、必ず本体からドリフトする。
一行でまとめる。RAGは「契約はたぶん何と言っているか?」に答える。MCPは「これは適合か? yes/no」に答える。決定論は verdict を要求し、verdict を出せるのは呼び出せる(callable な)オラクルだけだ。
なぜ Skill ではないのか
では検証コードを Skill に同梱するのはどうか。RAGより筋がいい。ローカルに決定論的なコードを持てる。でも、これも据わりが悪い。理由は3つ。
① 権威の単一性。契約と検証は「唯一・バージョンひとつ」であるべき資産だ。Skillに同梱すると、複数のSkillにコピーが散る。散れば必ずドリフトする。既存の言説でも「複数のクライアントやアプリが同じ契約を必要とするならMCPを建てろ」と言われるが、これは接続性の軸ではなく、再利用(single source of truth)の軸の話だ。
② 実行境界=信頼境界。MCPのコードは author 側で走る。モデルのサンドボックスの外、ユーザーのシェルの外だ。だから改ざんできないし、中央で更新できるし、中身を配布せずに使わせられる。私の場合、可視化のカタログ(何をどう可視化するかの定義群)は社外秘の資産なので、これはほぼ決定打になる。Skillに同梱するコードは、モデルの実行環境に落ちてきて走る=可視で、可改変で、配布物だ。秘匿したいものを配ることになってしまう。
③ サーフェス依存性。Skillは特定のサーフェス(実行面)へのアダプタだ。私が実運用しているSkillの一つは、まさに「あるAIクライアントのブラウザ描画ペイン専用の振り付け」でしかない。描画用のハーネスを注入して、図形を右クリックでコピーできるようにして、アスペクト比を合わせて、valid: trueで完了する。同じMCPの上に、スライド出力用のSkillや別UI用のSkillが、それぞれ別に載る。Skillは、その場その場の振り付けだ。
大事なのは、①②③はSkillを貶めるための理屈ではない、ということだ。①②は「なぜRAGでもSkillでもないか」を同時に答えていて、③だけが「じゃあSkillには何を残すのか(=サーフェスへの適応)」を積極的に定義している。anti-skill ではなく、役割分担の定義だ。
| 何を提供するか | 信頼境界 | 決定論に向くか | |
|---|---|---|---|
| RAG | 確率的な知識注入(助言) | — | ✗ verdictがない |
| Skill | 手続き+ローカルな決定論コード | サンドボックス内・サーフェス束縛 | △ 単一・権威にできない |
| MCP | 権威あるverdict/契約 | サンドボックス外・単一・横断 | ◎ |
反論を先に潰しておく
たぶん全員が思う反論がある。「検証コード(validator)をSkillにTypeScriptで同梱すればよくないか?」 ――上の①②③がそのまま答えになる。コピーが散ってドリフトする(①)。サンドボックスの内側に置くと信頼境界を越えられない(②)。秘匿したいカタログを配ることになる(②)。中央更新もマルチサーフェス再利用も効かなくなる。
そして、生きた証拠がある。私が実運用しているSkillは、validator を同梱していない。MCP側の検証ツールを呼んでいるだけだ。契約こそがプロダクトで、Skillは捨てても構わない振り付けだから、そうなっている。設計を先に決めたわけではなく、運用しているうちにそうなった、というのが正直なところだ。
MCPが内包するのは「権威ある計算」だけでいい
ここで、自分の主張に一つ留保を入れておかないとフェアじゃない。「MCPは計算を内包すべきだ、WebAPIとは違う」という言い方をよく見るし、私も一時期そう言いたくなったが、これは軸として切れていない。コネクタ型のMCPだって計算はしている(リモートに委譲しているだけだ)。効く軸は「計算か通信か」ではなく、「アクセスを提供するのか、保証(verdict)を提供するのか」だ。
実際、私が作っている描画エンジンも、全部の計算をMCPに入れているわけではない。図を実際に描くレンダリング計算は、ブラウザ側にimportしたランタイムで走っている。MCPが持っているのは、契約と検証の計算だけだ。
だから正確には、こうなる。
MCPが内包するのは「権威ある・保証を与える計算(唯一であるべき計算)」であって、決定論的な計算のすべてではない。
存在証明 — 外部に一切到達しないMCP
ここまでを一枚の絵にすると、こうなる。
flowchart LR A["自然言語
(ファジーな意図)"] -->|確率| B["LLM"] B -->|確率| C["宣言 / IR
(JSON)"] C --> D{"MCP
verdict"} D -->|valid: true| E["ランタイム
(決定論的レンダリング)"] D -.->|valid: false| B E --> F["出力UI
(決定論)"] G["Skill
(サーフェス・アダプタ)"] -.-> F classDef prob fill:#ffe9e9,stroke:#e57373; classDef det fill:#e9f5ff,stroke:#64b5f6; classDef gate fill:#fff6d6,stroke:#e6b800,stroke-width:2px; class A,B,C prob; class E,F det; class D gate;
自然言語から、LLMが宣言(IR)を作る。その宣言が、MCPの関門で verdict を受ける。通れば、ランタイムが決定論的に図を描く。Skillは、その図を各サーフェスに載せるアダプタとして脇に付く。確率は入口に閉じ込められ、関門で堰き止められ、出口は決定論になる。
そして、この関門としてのMCPは、外部のどこにも到達しない。JSONの宣言を受け取り、契約に照らして
valid を返すだけ。ネットワークもDBも要らない。これが冒頭に書いた反例だ。「MCP=コネクティビティ」という通説では、外部到達ゼロのMCPは説明できない。だが、MCPにはコネクタ型とは別に、オラクル型(権威・verdictを返す型)がある。通説はコネクタ型しか語っていない、というだけの話だ。証明のために、中身(可視化のカタログや契約スキーマ)を晒す必要はない。むしろ晒さない方が、汎用の主張として強い。JSON宣言を検証して
valid を返すだけの、こんなトイMCPを一個でっち上げれば、旗は立つ:// 外部に一切アクセスしない、verdictだけを返すMCP(骨子)
server.tool("validate_declaration", { decl: z.unknown() }, async ({ decl }) => {
const result = CONTRACT.safeParse(decl); // ローカルの契約に照合するだけ
return result.success
? { valid: true }
: { valid: false, errors: result.error.issues }; // 通信ゼロ
});
繋ぐ先はない。それでも、これは正しいMCPだ。
前回、中島氏の「LLM=コンパイラ」論に「そういう会があったら聞きたい」と反応して記事を閉じた。あの中間表現(IR)が、私にとっての宣言JSONで、「コンパイラが安定していればAIの暴走を止められる」の“安定したコンパイラ”が、このMCPの検証だ。開いたループを、自分の手元で閉じたことになる。私はそれを、MCPとして実装した。
それでも「MCPは不要」なのか
結に入る。まず頭を納得させる、冷たい工学の話から。
前回、Xで見かける「Figma不要論」「MCP不要論」に触れた。vibe codingで画が一発で出るからFigmaは要らない、CLIとAPIがあればMCPは過剰な抽象で要らない――ある側面では、正しい。使い捨ての、監査も再利用もしない画面なら、その通りだと思う。
だが問題は、ツールの要不要ではなかった。確率を、どこで封じ込めるかの配置問題だった。巨大な基幹システムの大量のUI、ひとつのミスが巨額の損失に直結する動作。そこで、決定論を担保しきれないLLMに最後まで任せられるのか――前回の私はこれを「物差し」と呼んだ。その物差しで測れば、答えは出る。決定論の verdict を持つオラクルとして、MCPは要る。要らないのではなく、通説が語っていない型のMCPが要る。
これが、中島氏のコンパイラ論の、実装としての回収でもある。IR=宣言、安定したコンパイラ=MCPの検証。前回“聞きに行きたい”と思っていたものを、自分で建てた。
output UI は死なない
ここから、温度の話をする。
私たち人類は何十年もGUIを作ってきた。その蓄積を、確率的に揺れる一発書きのSVGと、会話に溶けたテキストの塊に、明け渡すのか。入力UIは溶けていい。意図の揺れは福音だからだ。だが出力UIは、揺れた瞬間に監査性・再利用性・比較可能性を失う。だから――output UI は死なない。死なせてはいけない。
彫り込みたいのは3点だ。
ひとつ、「出力はテキストで十分」への NO。すべてを会話に溶かすLLMネイティブUIの流れがある。でも、「今期のROICツリー、テキストで読みますか?」は成立しない。構造を持つ情報を線形の文章に潰すのは、認知負荷を上げる方向だ。
ふたつ、「揺れる一発書きSVG」への NO。出力の確率性を歓迎せよ、表面ではなく文脈を設計せよ、という設計言説がある。主張は分かる。でも――同じSVGを2回頼んで別物が出る図が、監査に耐えるか?
みっつ、「これだけ人類はGUIを作ってきたのに」という、当事者としての感情。前回、私は自分を船のたとえの「派手なレストランばかり作っている側」だと自嘲した。船体でもエンジンでもなく、取り替え可能な客室側だ、と。今回はそれを裏返したい。そのレストランこそ、死なない。 意図が溶けても、意思決定の現場で人が読み、比べ、責任を取る出力面は、揺れさせてはいけない場所として残り続ける。表現に人生を張ってきた側の、これは弁明ではなく確信だ。
そして私が作っている表現エンジンは、その確信を形にしたものだ。AIが意図を生成し、エンジンが表現を保証する。入力は確率、出力は決定論。同じ宣言からは、いつでも同じ図が出る。その保証の関門が、外部に到達しないMCPのverdictだ。工学(決定論をどこに置くか)が思想(output UI is alive)の証拠になり、思想が工学に意味を与えている。円環がひとつ閉じた。
最後に、旗を脆くしないために一つだけ。「output UI は死なない」を全称命題にするつもりはない。使い捨てで監査も要らないチャットの返答は、溶けていい。正確には、監査・再利用・比較を要する出力UIは死なない、だ。私の戦場である経営の意思決定は、その典型だというだけのことだ。前回「入力UIは死ぬ」を「意図を捕まえる入力は溶ける」に彫り直したのと同じように、出力側にも一度、同じ彫り込みを入れておく。
次回予告
――そういうことを、半年運用して考えた。
ここまで書いて、ひとつ気づいたことがある。SkillとMCPのこの関係は、Web開発のフロントエンドとバックエンドに、構造がよく似ている。フロントから送られてくるデータを、バックエンドは全面的には信用しない。フロント側の検証はUXのためのもので、データの本当の保証はバックエンドが持つ。この責務分離は、そのままSkill(書き換わる側)とMCP(verdictを持つ側)に読み替えられる。
ただ、対応はするが、一致はしない。そして、その「ずれ」のほうがおもしろい。
Webのフロントエンドも、書き換えられる道具ではあった。だがそれはハックだった。設計者の想定の外側で、上級者や悪意を持つ者が触る余地であって、だから「下から来るデータは疑え」が道具設計者の責務になった。ハックは、防ぐべき例外だった。
AI時代のSkillは、そこが違う。書き換えられることが、悪でも例外でもない。skillを利用してclaudeを使っていると、あたらしいskillを/skill-creatorが作り出し、更新ボタンを用意してくる。つまり、むしろ書き換えられる前提で設計されている。設計者はSkillを作るが、それはドラフトでしかなく、「あとは使いながら好きに変えてくれ」という含意が、最初から道具の側に組み込まれている。
ハックが例外ではなく仕様になった道具、と言ってもいい。
だとすれば、責務の分け方も変わるはずだ。書き換わることが仕様である道具を前提に、どこまでをSkillに委ね、どこからをMCPが権威として抱えるのか。今回はっきりさせた「verdictはMCP」の外側には、まだ言葉になっていない層がある。利用のルールやTips、作法のようなもの——あれは書き換えていいのか、それとも単一であるべきなのか。
今回も、答えより問いのほうが増えた。次は、そのあたりから始めたいと思う。
(続く)



