Demo

food-delivery-demo ── 原則の両立が難しい点を動くコードで検証する

5 つの設計原則が矛盾せず、Fowler/Lewis の特性とも整合するか。food-delivery-demo はその問いを動くコードで確かめる実証環境です。

単一巨大エージェント vs マルチエージェント(Arachne 実装)── 設計の違い

単一の巨大エージェントに全責務を集約した場合と、マイクロサービス原則に従ってマルチエージェントに分割した場合で、何が異なるか。 以下の対比表は、実装選択による具体的な差分を示しています。

観点 単一巨大エージェント Arachne マルチエージェント
System Prompt 管理 全ビジネスドメインのルールが一箇所に集約 各サービスが独立した system prompt を管理。変更は該当サービスのテーム限定。
Tool 権限の境界 全サービスの全 API にアクセス権。権限の明確な分界がない。 各エージェントは担当機能の tool のみ。サービス責務に沿った権限分離。
チーム Ownership エージェント全体を「誰が」保守するかが曖昧。変更による他ドメインへの波及に責任が分散。 エージェントはそのマイクロサービスを所有するチームが保守。責任は明確。
変更の影響範囲 一つの system prompt 変更が全エージェント行動に波及。小さな調整も全体の再デプロイが必要。 変更は該当サービスのみ。他サービスへの波及は HTTP 契約経由だけ。局所化できる。
業務知識の管理 ビジネスルールが prompt に混入。業務側が直接編集することが難しく、変更サイクルが遅い。 Skill ドキュメントとして業務知識を分離。activationHint は業務担当者が直接更新可能。
Discoveryの信頼性 固定的な API 呼び出し。サービス名や endpoint が変わるたびに prompt を編集。 Capability ベースの動的 discovery。サービス置き換え時に呼び出し元の変更が不要。
Context 汚染 複数ドメインの会話履歴が一つのコンテキストに混在。前の会話が後の判断に不意に影響する可能性。 会話は該当サービスのエージェント内に閉じている。ドメイン間の状態漏洩がない。

各項目の詳細は下の「原則ごとの両立検証」セクションで確認できます。

このデモの読み方

このデモの主眼は、サービス数やエージェント数ではありません。各原則で何がぶつかりやすく、どう対応したかを確認することです。 以下に、原則ごとの「両立が難しいポイント」と、その確認場所を対応させています。

既存システムへの段階的導入を想定している場合: 以下の検証・統合優先度を参考にしてください。この順序は既存の設計原則から導出されており、各ステップで原則を損なわずに統合できます。

ステップ1:外付け会話窓口から始める(support-service 相当) 既存 API に一切の変更を加えず、独立した会話インターフェースを追加します。リスクが最小で、チームがエージェント運用に慣れるフェーズです。
ステップ2:自然言語フロントドアを入口に追加する(order-intake-agent 相当) 既存 API 契約を変えず、API の手前に自然言語解釈層を追加します。入出力の型が既存システムと一致することで、変更の局所性が保証されます。
ステップ3:service-local agent に展開する(menu-service / delivery-service 相当) 各サービスが独自の system prompt・skill・tool で判断を担うようにします。この段階で DeterministicModel パターンによるテスト整備の重要性が明らかになります。

サービス構成図

全サービスの依存関係。実線は通常の HTTP 呼び出し、点線はオプショナルまたは非同期の呼び出しを示します。

flowchart LR
    UI[customer-ui]
    CS[customer-service]
    OS[order-service]
    MS[menu-service]
    KS[kitchen-service]
    DS[delivery-service]
    PS[payment-service]
    SS[support-service]
    RS[registry-service]
    HA[hermes-adapter]
    IA[idaten-adapter]
    IC([icarus-adapter])
    DB[(PostgreSQL)]
    RD[(Redis)]

    UI --> CS
    UI --> OS
    OS --> MS
    OS --> DS
    OS --> PS
    OS -.->|post-order| SS
    MS --> KS
    OS -->|discover by capability| RS
    DS -->|discover by capability| RS
    RS --> HA
    RS --> IA
    RS -. not available .-> IC
    OS --> DB
    OS --> RD
    

注文フロー(4 ステップ)

カスタマーが注文を確定するまでの 4 ステップと、各ステップでのサービス間通信を示します。

sequenceDiagram
    actor B as Browser
    participant OS as order-service
    participant OA as order-intake-agent
    participant MS as menu-service
    participant KS as kitchen-service
    participant DS as delivery-service
    participant RS as registry-service
    participant PS as payment-service

    Note over B,PS: Step 1 — suggest
    B->>OS: POST /api/order/suggest
    OS->>OA: normalize intent
    OA-->>OS: NormalizedOrderIntent
    Note right of OA: 自然言語意図を capability 境界へ接続
    OS->>MS: grounding handoff
    MS->>KS: inventory check
    KS-->>MS: stock + ETA
    MS-->>OS: MenuSelectionDecision
    OS-->>B: suggested items

    Note over B,PS: Step 2 — confirm-items
    B->>OS: POST /api/order/confirm-items
    OS-->>B: items confirmed

    Note over B,PS: Step 3 — confirm-delivery
    B->>OS: POST /api/order/confirm-delivery
    OS->>DS: delivery options
    DS->>RS: discover ETA services
    RS-->>DS: hermes + idaten
    DS-->>OS: DeliveryPlan
    OS-->>B: delivery options

    Note over B,PS: Step 4 — confirm-payment
    B->>OS: POST /api/order/confirm-payment
    OS->>PS: charge
    PS-->>OS: charged
    OS-->>B: order confirmed
    

原則ごとの両立が難しいポイントと証拠

Organized around Business Capabilities

両立が難しい点:AI を追加すると「エージェントが全部やる」方向になりやすく、サービスの責務境界が曖昧になるリスクがある。

解消:order / menu / kitchen / delivery / support はそれぞれ異なる業務責務を持つ。エージェントを持つサービス同士でも役割は重ならず、6 サービスが同じ「AI 担当」として束ねられていない。

確認場所:サービス一覧の役割列、/agents のサービスカード

Products not Projects

両立が難しい点:system prompt や skill ドキュメントは管理責任が曖昧になりやすい。エンジニア以外が更新できない形になると内容が古くなる。

解消:system prompt と skill は各サービスのソースコードとして管理される。skill には activationHint が YAML フロントマターで書かれ、業務担当者がコードを触らずに適用条件を変更できる。DeterministicModel パターンにより振る舞いは再現可能な形でテストされている。これによりワンチーム運用での業務側の関与深度が上がる。

確認場所:/agents のスキルタブ、testing-agents Essay

Smart Endpoints and Dumb Pipes

両立が難しい点:複数サービスで同じ LLM を使うとき、LLM が共有パイプになってサービス間の境界が崩れるリスクがある。また「正解が必要な処理」をエージェントに任せると結果が非決定的になる。

解消:payment-service はエージェントを持たない。課金確定は決定論的コードで実行する。各サービスの LLM 呼び出しは独自の system prompt と tool 定義で行われ、推論コンテキストはサービス境界に閉じている。サービス間通信は HTTP のみ。

確認場所:サービス一覧の payment-service 行、/agents の API 仕様タブ(x-ai-prompt-contract)

Decentralized Governance / Decentralized Data Management

両立が難しい点:サービスが互いを直接参照すると、デプロイの独立性が失われる。registry を使っても、使い方次第で中央集権的な構造になりうる。

解消:サービス間の collaborator 解決は POST /registry/discover(capability クエリ駆動)で行う。GET /registry/services は viewer 用途に分離し、サービス間の直接依存には使わない。各サービスは起動時に自己登録し、registry が落ちても既存の接続は維持される。呼び出し元が相手のサービス名を持たないことで、独立進化の障壁を下げられる。

確認場所:registry-service 行、capability-discovery Essay、/agents のサービスカード

設計原則と実装の対応

設計原則 food-delivery-demo での実装 どこで確認できるか
AI エージェントは自然言語フロントドアとして追加する order-service に order-intake-agent を置いてユーザー入力の一次解釈を担わせ、menu-service・delivery-service・support-service は service-local agent として catalog grounding、ETA 判断、サポート対話を担わせます order-service の suggest API が direct item request / recommendation request を正規化し、その handoff を受けた menu-service が明示指定優先で grounded な候補を返す流れで確認できます。自然言語の意図が capability 境界に接続される最初の段です → 観測ログ
従来の API は機械間連携の正本契約として残す 全サービスが REST API と OpenAPI 仕様を公開し、エージェントはその API をツールとして呼び出す形を維持します /agents の API 仕様タブから各サービスの OpenAPI を確認できます。エージェントのツール定義も同じ API 上に乗っています → 観測ログ
金額計算・課金・認可は決定論的コードで処理する payment-service はエージェントを持たず、支払い準備と課金確定をコードで完結させます payment-service の /v3/api-docs で、エージェント経由ではなく決定論的に処理されることを確認できます → 観測ログ
system prompt はエンジニアが管理するシステム制約として書く 各エージェントの system prompt はソースコード中に置き、役割・制約・ツール利用方針・言語設定を明示します /agents のサービスカードを開くと、登録済みの system prompt をそのまま読めます → 観測ログ
skill は業務知識の公開面として分離する menu-service と kitchen-service は商品説明・推薦ロジック・仕込みスケジュール方針を SKILL.md に分離します。スキルの発動条件も SKILL.md のフロントマターに記述し、サービスが起動時に動的に注入します /agents のスキルタブで system prompt とは別に管理されているスキルドキュメントを確認できます。activationHint は業務担当者が直接関与できる運用面です
# family-order-guide/SKILL.md(フロントマター抜粋)
---
name: family-order-guide
activationHint: 家族・複数人・子ども向けの相談のとき
---
→ 観測ログ
サービス間の collaborator 解決は capability ベースで動的に行う order / kitchen / menu / support / delivery が起動時に registry-service へ自己登録し、ダウンストリーム解決は POST /registry/discover で行います delivery-service が外部 ETA アダプターを discover 経由で発見し、ETA を比較して推奨を返すフローで確認できます。呼び出し元は相手サービス名を固定せず、能力記述で解決します → 観測ログ
会話責務・workflow 責務・仕様閲覧責務は UI レベルでも分離する カスタマー UI を /order(workflow)・/support(会話)・/agents(viewer)の 3 ページに分け、責務を混在させません /support は注文フローと独立しており、/order での workflow 処理中でも別タブでサポートに問い合わせできます

サービス構成

サービス ポート 役割 エージェント 設計ポイント
order-service 8080 注文ワークフロー coordinator / intent front door ✓ あり 4 ステップの workflow API(suggest → confirm-items → confirm-delivery → confirm-payment)を持ちます。order-intake-agent が suggest の自然言語 front door となり、direct item request / recommendation request を正規化したうえで menu / delivery / payment / support を registry 経由で動的に解決します。
menu-service 8081 catalog grounding・代替候補提示 ✓ あり order-service から受け取った正規化済み意図を live catalog に grounded な提案へ落とし込みます。direct item request では alias-based explicit match を優先し、exact match がない場合は menu-side alternatives だと明示します。欠品時は kitchen-service と連携して代替候補を提示します。skill の activationHint は業務担当者が直接更新できる面です。
kitchen-service 8082 キッチン状況管理 ✓ あり 厨房のキャパシティと仕込み状況を管理します。注文確定時に準備スケジュールを調整し、混雑時は代替提案をエージェントが生成します。業務知識は SKILL.md 側で管理でき、コード変更と分離されています。
delivery-service 8083 配送 ETA 評価・推奨 ✓ あり registry-service を通じて外部 ETA サービスを動的に発見し、自社急配と比較して推奨配送プランを返します。capability-based discovery の主な実証箇所です。
payment-service 8084 支払い処理 ─ なし エージェントを持ちません。支払い準備と課金確定は決定論的コードで実行します。「正解が必要な処理はコードで守る」という設計方針の体現です。
customer-service 8085 認証・顧客情報管理 ─ なし デモアカウント認証(demo/demo-pass など)と顧客プロフィールを提供します。JWT 発行と JWKS 公開を担い、他サービスがトークンを検証します。
support-service 8086 会話型サポート窓口 ✓ あり 注文フローとは分離した会話インターフェースです。FAQ・キャンペーン・サービス稼働状況・注文後フォローを扱います。[HANDOFF: order] で注文ページへの誘導も行います。
registry-service 8087 サービス登録・capability 検索 ✓ あり 各サービスが起動時に自己登録します。capability-registry-agent が POST /registry/discover で collaborator resolution を行い、GET /registry/services は viewer/inventory 用として意図的に分離されています。
hermes-adapter 8088 外部 ETA アダプター(常に遅延) ─ なし 外部配送会社のモックです。15 秒サイクルで周期的に停止します。delivery-service が外部候補の可用性変動を正しく処理するかを検証できます。
idaten-adapter 8089 外部 ETA アダプター(常に最速) ─ なし 外部配送会社のモックです。常に最短 ETA で AVAILABLE を返します。hermes-adapter と対にすることで、delivery-service の比較ロジックが機能することを確認できます。

カスタマー UI の 3 つの公開面

/order

4 ステップ注文 UI

ユーザーの注文意図を段階的に確定させる workflow-first UI です。各ステップで AI が提案と理由を返し、ユーザーが選択・調整します。会話的な自由入力と structured workflow の組み合わせが特徴です。

意図入力商品選択配送選択支払い確認

/support

会話型サポート

注文フローとは分離したサポート専用の会話窓口です。support-service のエージェントが対話を担います。注文関連の問い合わせには [HANDOFF: order] リンクで /order に誘導できます。

FAQキャンペーン稼働状況確認注文後フォロー

/agents

サービスビューワー

registry-service の GET /registry/services を使い、登録済みサービスのカード一覧を表示します。各カードからシステムプロンプト・スキル・OpenAPI 仕様(x-ai-prompt-contract 含む)を確認できます。

サービス一覧プロンプト確認スキル一覧OpenAPI 仕様

UI スクリーンショット

実際に起動中の food-delivery-demo から取得したスクリーンショットです。

起動方法

リポジトリの food-delivery-demo/ ディレクトリで make up を実行すると、 Docker Compose で全サービスが起動します。Bedrock を使う場合は make up-bedrock。 AWS 認証情報は aws configure export-credentials 経由で渡されます。

GitHub でコードを読む →

実行履歴(Execution History)について

注文ワークフローの各ステップを進めると、5 サービスの実行イベントが時系列で記録されます。 /order の UI から「実行履歴」パネルを開くと、サービス・カテゴリ・結果・ツール使用・トークン消費を確認できます。 エージェントの判断過程を追うための証拠面として設計しています。