かつてAIにブランドサイトの構築を依頼したことがあります。一見すると説得力のあるものが返ってきましたが、実際に重要な部分が壊れていました。ヘッダーにはリンクがたった2つしかありませんでした。「About」ページはどこにもありませんでした。バックエンドには管理パネルが存在していましたが、フロントエンドにはそこに到達できるボタンもルートもありませんでした。サーバーサイドは機能していましたが、ユーザーサイドは機能していませんでした。

これに直面した多くの人は、AIが怠慢になったか、トークン制限に達したのだと思い込みます。しかし、そうではありません。問題は構造的なものです。AIのコーディングツールは、内部の一貫性を監視するように作られています。彼らは「自分が宣言したすべてが、互いに整合しているか?」と問いかけます。「この成果物には、含まれるべきものがすべて含まれているか?」とは問いません。もしブランドサイト用に2つのページを指定すれば、モデルは忠実に、その2つのページが互いにリンクしているかどうかを確認します。リンクが解決されると、タスクは完了したとみなされます。ブランドサイトには「About」ページ、信頼の証(trust signals)、あるいは問い合わせ経路が必要であるという固有の概念を、AIは持っていないのです。彼らの頭の中に標準(スタンダード)は存在しません。

私はこの解決策を Completeness Baseline(網羅性のベースライン) と呼んでいます。

網羅性のベースラインとは、単にある成果物が含まれていなければならない要素の標準的なチェックリストのことです。成果物を生成した後、ツールの内部的な「完了」という感覚を信じるのではなく、この外部標準に照らして実際の出力を検証するのです。

3つのレイヤーによる検証

欠けている要素がすべて同じように明白であるとは限りません。有用なベースラインは、3つの異なるレイヤーをチェックします。

存在性(Existence)。 その部分は実際に存在するか? 基本的なことのように聞こえますが、AIはダッシュボードページ自体を生成することなく、ダッシュボードページを参照するナビゲーション・ラッパーを平然と構築することがあります。参照は存在しますが、対象が存在しないのです。

到達可能性(Reachability)。 実際のユーザーがそこに到達できるか? 隠れた管理パネルは典型的な症状です。ルートとコンポーネントの両方がコードベースに存在していても、メニュー項目、ボタン、またはリダイレクトがインターフェースにそれらを露出させていなければなりません。通常の利用中にユーザーが偶然それを見つけることができないのであれば、それは実質的に存在しないのと同じです。

実体性(Substantiation)。 表面の下に実際のデータや構造があるか? 読み込みはできるものの、プレースホルダーのテキストしか含まれておらず、画像アップロードのスロットもないページは、衣装を着ただけの骸骨です。画像スロットや編集可能なテキストフィールドのない「About」ページは、たとえHTMLが綺麗にレンダリングされていても、不完全です。

これら3つのレイヤーは、異なる種類の欠落を捉えます。「存在性」は、見当たらない靴を見つけます。「到達可能性」は、クローゼットに閉じ込められた靴を見つけます。「実体性」は、底のない靴を見つけます。

タイプ別のベースライン

一つのベースラインですべてのプロジェクトをカバーすることはできません。構築しているものを分類し、そのカテゴリにおける譲れない条件を定義する必要があります。

ブランドサイトには、特定のセクションと到達可能なページが必要です。「About」、「Contact」、プライバシー関連のリンク、そしてすべての主要なビューを実際に表示できるナビゲーションなどを想定してください。

APIには、ドキュメント、網羅的なエラーコード、およびレート制限が必要です。成功時に200 OKを返し、それ以外すべてに汎用的な500を返す動作するエンドポイントは、完成したAPIではありません。それはリスクです。

**自動化(Automations)**には、ログと失敗アラートが必要です。ワークフローが午前2時に停止し、人間が実行履歴を確認するまで誰も気づかないのであれば、その自動化は不完全です。オブザーバビリティ(観測性)はボーナス機能ではありません。それは成果物の一部です。

カテゴリを特定すれば、ベースラインは自然と決まります。難しいのは、コードが生成された後にそれを強制することです。

破綻しない設計ルール

私はこの考え方に基づいて自身のワークフローを再構築し、プロジェクトが徐々に崩壊していくのを防ぐための3つの実用的なルールにたどり着きました。

機能制限に基づいた設計(Capability-gated design)。 ツールや生成されたモジュールを採用する前に、それが実際に何ができるかを検知してください。コンポーネントライブラリにネイティブのモバイル用ドロワー(drawer)サポートがない場合、それが存在することを前提とした完全なナビゲーションスキームをAIに生成させてはいけません。機能が欠けている場合にシステムが壊れるのではなく、優雅に機能を縮小(degrade gracefully)させるべきです。まず境界を知り、その範囲内で設計してください。

パブリックなエンジン、プライベートな値(Public engine, private values)。 重い処理にはパブリックなエンジンを使用しますが、実行時に独自のデータ、設定、および規約を注入(inject)してください。これにより、個人の方法や会社のメソッドを、生成されたスケルトンから安全に分離して保持できます。AIはフレーム(枠組み)を構築します。あなたはそこにガラスをはめ込むのです。これにより、モデルが実際の標準に反する仮定をハードコードしたり、機密性の高いパターンをパブリックな学習コンテキストに漏洩させたりすることを防げます。

提案はさせるが、自動進行はさせない。 AIには次のステップを提案させ、最終的な選択は人間に強制する。実行のフローは自動化しても、判断を自動化してはならない。モデルがデータベースのマイグレーション、認証スキーム、決済フックを一度に自動生成してしまうと、監視を犠牲にして利便性を手に入れることになる。ツールには計画を提示させ、開発者にボタンを押させるべきだ。

適切なモデルの選び方

さまざまなモデルでテストした結果、価値の分かれ目が明確に見えてきた。安価なモデルは、機械的な大量作業を驚くほどうまくこなす。ボイラープレートや繰り返しの多いコンポーネント、構造的なスタブなどを、タイピングするよりも速く生成してくれる。一方で、高価なモデルがその価格に見合うのは、自制心を発揮したときだけだ。偽の修正案を捏造するのではなく、真の欠落を指摘してくれる場合にこそ、プレミアムな選択肢を選ぶ価値がある。存在しないAPIエンドポイントに対して回避策をハルシネーション(幻覚)で作り出すモデルは危険だ。一方で、「このワークフローには定義されていないwebhookターゲットが必要です」と立ち止まって言えるモデルには、コストを払う価値がある。量ではなく、洞察力に対して対価を払うのだ。

「魔法」を追うのではなく、ビルドシステムを構築せよ

より大きなモデルや高度なプロンプトのテクニックを投入することでAIの欠落を埋めようとしてはいけない。ベースラインによって解決すべきだ。欠落しているのは能力の問題ではなく、期待値の問題なのだ。

欠落を防ぐために、3つのことを行う。

コードが書かれる前に、システムに「完成度のベースライン」を与える。それをタスクのすぐ横に置く物理的なチェックリストにする。

規約を再利用可能なパーツとして組み込む。テンプレート、lintルール、または構築済みのスキャフォールド(scaffolds)を通じてベースラインを強制すれば、AIはあなたの基準を推測しようとするのではなく、正しい状態からスタートできるようになる。

判断のコントロールを人間に残したまま、フローを自動化する。反復作業はマシンに任せ、意思決定はコンテキストを理解している人間が行う。

私の働き方を変えた、最後にもう一つの習慣を紹介する。もし同じ設計判断を7回繰り返したなら、それを単発の選択として扱うのはやめよう。それは反復ではなく、「法則」だ。それに名前をつけ、ルールに変え、文書化する。パターンを明文化すれば、8回目にAIがそこから逸脱してしまう可能性を排除できる。

このフレームワークのソースと元の考察はこちらで見ることができます

同じ問題に取り組んでいる他の人々と意見交換をしたい場合は、GyaanSetu learning communityに参加してください。