音声機能は、あらゆるAIエージェントプラットフォームが急いで実装しようとしている機能となっています。当然の選択は、それをスタンドアロンのチャネルとして構築することです。WebアプリやCLIツール、Telegramボットの隣に置くようなものです。それは直感的に思えます。「音声」があれば「音声インターフェース」を作る、という具合です。しかし、その直感は脆弱なアーキテクチャを生み出します。作業の重複を招き、ログを混乱させ、プロジェクトのコンテキストを徐々に歪めてしまいます。
APCとAPXでは、異なる道を選びました。音声はチャネルではありません。「モード」なのです。それはサーフェス(接点)を置き換えるのではなく、その上に重なるものです。この区別を正しく行うことこそが、システムの乖離を防ぐ鍵となります。
誤った抽象化
音声を独自のチャネルとして扱うとき、エージェントとの「会話」は、タイピングによるものとは根本的に異なるものだという前提を暗黙のうちに置いています。エンジニアリングチームは、コードベースを分割することでこれに対応しようとします。突然、CLIチャネルと、それとは別のvoice-CLIチャネルが現れます。Webチャネルと、並行するvoice-webチャネルも同様です。それぞれが独自のプロンプトのバリエーション、フォーマット規則、コンテキスト処理ロジックを必要とします。
ここから混乱が始まります。エージェントの振る舞いを微調整するたびに、複数のプロンプトツリー全体にその変更をコピーしなければならなくなります。もしチームがひとつのサーフェスへの適用を忘れれば、体験は断片化します。ユーザーはテキストではあるトーンで、音声では少し異なるパーソナリティを感じることになります。時間が経つにつれ、こうした小さな不一致が積み重なり、「システムの乖離(system drift)」へと発展します。ポータブルなコンテキスト層は、あるブランチでは音声によるデリバリーを考慮し、別のブランチでは静かなテキストを考慮しなければならなくなるため、もはやポータブルではなくなります。抽象化が漏れ出し(abstraction leaks)、かつて統一されていたプロジェクト定義は、チャネルごとのハックの寄せ集めへと崩れていきます。
コンテキストとランタイムの分離
これを防ぐために、私たちは責任を厳密に分離された2つのレイヤーに分割しました。
APCはプロジェクトのコンテキストを保持します。プロジェクトを構成するエージェント、ルール、スキルを定義します。システムの「安定した意味」と考えてください。それは構造的な問いに答えます。「このエージェントは何を知っているか?」「何をすることが許可されているか?」「どのツールを呼び出せるか?」といった問いです。APCは、返答が画面に描画されるのか、チャットAPI経由で送信されるのか、あるいはスピーカーから出力されるのかについて、完全にアグノスティック(非依存)であるべきです。
APXはランタイムレイヤーを扱います。CLI、Webアプリケーション、デスクトップインターフェース、Telegramボットなど、実際に触れるサーフェスを管理します。ユーザーがリクエストを送信すると、APXはレスポンスをどこに、どのように提示するかを決定します。回答を「読むため」にフォーマットするか、「話すため」に最適化するかを判断することは、ランタイムの関心事です。それはAPCではなく、APXに属すべきものです。
この分離により、APCで定義されたプロジェクトは、APXがどれほど多くのサーフェスを公開しても、整合性を保ったままとなります。契約(contract)は変わりません。変わるのはプレゼンテーションレイヤーだけです。
モードの実際の仕組み
私たちの実装では、Telegram、CLI、Webアプリといったサーフェスは「チャネル」です。チャネルは「どこで」インタラクションが行われたかを伝えます。音声は、チャネルのメタデータを通じて「モード」としてレイヤー化されます。モードは「どのように」返答が振る舞うべきかを伝えます。
プロンプトビルダーはこの境界を尊重します。まずAPCのプロジェクトコンテキストから情報を取得し、次にチャネルのメタデータを検査します。もしデスクトップサーフェスが音声モードで動作している場合、ビルダーはその瞬間にのみ、特定の指示を追加します。例えば、モデルに対して「短い文章にする」「音声合成のために句読点を明確にする」「数字の読み上げ規則に従う」といった指示を与えます。同じデスクトップサーフェスがテキストモードで動作している場合、それらの音声に関する指示がプロンプトに入ることはありません。
その結果、サーフェスごとに単一のプロンプトツリーが実現されます。「voice-desktop」という別ブランチも、「whisper-web」というバリアントも存在しません。修飾(modifier)は、ランタイムが要求したとき、かつ「最後の責任ある瞬間(last responsible moment)」にのみ適用されます。コアとなるプロンプトは一定のままです。
得られるメリット
このアーキテクチャは、具体的に3つの方法で恩恵をもたらします。
メンテナンスコストの低減。 もし音声が独自のチャネルであれば、すべてのサーフェスに「双子」が必要になります。CLIチャネルとvoice-CLIチャネル、Telegramチャネルとvoice-Telegramチャネル、といった具合に管理しなければなりません。システムプロンプトを調整したり、フォーマットのバグを修正したり、スキルの説明を洗練させたりするたびに、その変更を両方のツリーに伝播させる必要があります。一つでも忘れれば、ユーザーはその差に気づきます。モードを使用することで、サーフェスごとに単一のプロンプトツリーを維持できます。音声は「道の分岐点」ではなく「条件付きのオーバーレイ」となるため、新しいインタラクション方法を追加しても、作業量は線形(リニア)に保たれます。
正確なロギング。 チャネルはインタラクションが発生した場所を記録します。モードは返答がどのように提供されたかを記録します。ユーザーがそれを読んだか聞いたかに関わらず、デスクトップでのインタラクションはデスクトップのインタラクションのままです。チームがバグを追跡したり分析を確認したりする際、「desktop-voice」と「desktop-text」を、あたかも異なるプロダクトのサーフェスであるかのように突き合わせる必要はありません。チャネル識別子はクリーンなまま保たれ、モードフラグはメタデータ内でその隣に整然と配置されます。場所と振る舞いが混ざり合わないため、ログは正確であり、デバッグはシンプルに保たれます。
クリーンなプロジェクトコンテキスト。 APCはコントラクトを定義します。返答が話されるのか、ささやかれるのか、あるいは等幅フォントで表示されるのかを、APCが気にする必要はありません。それらはランタイムの関心事です。音声フォーマットをAPX内に保持することで、APCのポータビリティを維持します。APCのプロジェクト定義をそのまま取り出し、音声特有のフォーマットの前提や音声最適化のための不要なコードを引きずることもなく、全く新しいランタイム環境に投入することができます。境界は保たれ、プロジェクトの意味は安定したままです。
デスクトップにおける証明
私たちのデスクトップパスは、日常的な使用においてこれを実証しています。デスクトップはサーフェスです。ユーザーが音声を有効にすると、システムはその同じデスクトップサーフェスを音声モードで実行します。音声はモードレイヤーに存在するため、デスクトップチャネルはその完全なコンテキストと振る舞いを保持します。異なるルールを持つ別のプロダクトになることはありません。プロンプトビルダーは単にフラグを検知し、必要な場合にのみ音声指示を追加します。ユーザーがテキストに戻ると、それらの指示は完全に消えます。基盤となるプロジェクトコンテキストが変化することはありません。デスクトップは常にデスクトップなのです。
真の要点
核心となる考えはシンプルです。APCは安定したプロジェクトの意味を記述し、APXはランタイムの実行を記述します。音声はサーフェスに対する修飾子であり、サーフェスそのものの置き換えではありません。そのように扱えば、プロンプトは軽量に保たれ、ログは明快になります。あなたの
