BluePeriod Docs
開発

エージェント・ツール統合ガイド

GUI・内製エージェント・MCPエージェントの3者統合仕様

18. エージェント・ツール統合ガイド (Agent Tool Integration Guide)

1. 概要

BluePeriodは、ユーザー自身が操作する「GUI」、内蔵された「内製エージェント(Integrated Agent)」、そして外部の「MCPエージェント(External Agent: Claude Code等)」の3者がアプリの機能を利用できるハイブリッド構成を採用しています。

本ドキュメントでは、新しい機能を追加・開放する際の最重要原則である**「三層の整合性(Three-layer Consistency)」**と、その実装ワークフローを定義します。

1.1. 三層の整合性の原則

機能を実装する際、開発者は以下の「三層」すべてで同等・同質な操作が可能であることを保証しなければなりません。

  1. GUI (User): ユーザーインターフェース(ボタン、ダイアログ等)を通じて人間が実行できること。
  2. Internal Agent (Jotai/LangGraph): 内蔵AI(LangGraph)が、Feature層のツール(createProjectTools(), createEditorialTools() 等)を通じてJotaiステート(=メモリ上)で同等の操作を実行できること。
  3. External Agent (MCP Tool): 外部のMCP対応エージェントが、Honoサーバー経由のMCPツール(blueperiod_*)として同等の操作をリモート実行できること。

ギャップの解消

これら三層の間に機能の非対称性(「GUIでしかできない」「内製AIしかアクセスできない情報がある」)が存在する場合、それは設計負債となります。今後の実装では、常にこの三層間のギャップを埋めることを優先してください。

1.2. コア思想:浅いエージェントと深いエージェント

結論: BluePeriodのMCPツール群は、高度な機能の「リモコン」ではなく、データの「解剖権と再構築権」をAIに与えるためのものであるべきです。

理由 エージェント統合には、2つの異なるアプローチが存在すると考えられます。私たちは、外部エージェントに対しては後者の「深いエージェント」としての接し方を強く推奨し、そのための基盤を提供します。

浅いエージェント (Shallow Agent / Remote Control)

  • 定義: アプリケーションが提供する「高レイヤーな機能(生成ボタン、リライト機能など)」を外部からキックするだけのエージェント。
  • 特徴: 実装は容易ですが、AIはアプリの「既製品の機能」の枠組みに縛られます。
  • 欠点: アプリ開発者が想定したプロンプト以上のことはできず、外部エージェントの真の知能を活かせません。

深いエージェント (Deep Agent / Co-Architect)

  • 定義: アプリケーションの「生データ」にアクセスし、「原子的な操作(フィールドの書き換えなど)」を組み合わせて自ら思考・執筆するエージェント。
  • 特徴: AIは「脳」であり、BluePeriodはその脳が使う「道具箱(ツール)と作業机(データプロバイダー)」になり、人間と対等な「共創者」として振舞います。

Deep MCP vs Shallow MCP (設計指針)

項目❌ Shallow (リモコン型)✅ Deep (主体型)
設計思想アプリの「生成ボタン」を押させるアプリの「生データ」を渡して考えさせる
ツールの粒度「面白い設定を作って」 (High-level)「キャラAの属性をXに変更して」 (Atomic)
AIの役割アプリの機能の実行係プロジェクト全体の監督・執筆者
開発の優先度内蔵AI機能のMCP化生データの読み書き権限の完全開放

2. 三層統合ツールの実装 4ステップ・ワークフロー

機能を新設・拡張する場合、外部エージェントも利用できるよう、**低レイヤーかつ原子的(Atomic)**な操作として実装する必要があります。

ステップ 1: Service Layer の実装(データの原子操作)

ビジネスロジックをJotaiやUI、具体的な通信プロトコルから切り離し、純粋なデータ永続化層(Service)として実装します。

  • 場所: next-app/src/lib/features/<category>/service.ts (または local-<category>-service.ts)
  • 内容: 特定のデータ(キャラクター、設定、プロット項目、プロンプト)の CRUD。

ステップ 2: Feature Layer Tool の定義 (Jotai / LangChain)

内製エージェントとMCPの両方で使用される、Feature層のツールを定義します。必要に応じてHITL(Human-in-the-loop)の承認ダイアログを挟みます。

  • 場所: next-app/src/lib/features/<category>/tools.ts
  • 内容: get, set (Jotai) を介してServiceを呼び出すラッパー。blueperiod_ プレフィックスで標準化されます。
  • 統合: next-app/src/lib/features/editorial/tools/index.ts で各Featureツールを統合し、createEditorialTools() として提供されます。

ステップ 3: MCP Tool の定義 (Hono Server)

外部AIが通信できるよう、MCPのJSON-RPCスキーマを定義します。

  • 場所: next-app/src/server/api/mcp/index.ts
  • 内容: 構造化されたスキーマ(Zod)とツールの説明(Description)。常に projectId 等のスコープを明示します。
  • ポイント: 外部エージェントが「深いエージェント」として振る舞えるよう、以下の3点セット(Aditスイート)を各ドメインに提供することを原則とします。
    • blueperiod_apply_<domain>_adit: JSONパッチ形式の精密編集
    • blueperiod_apply_<domain>_delimiter: SEARCH/REPLACEブロック形式の編集
    • blueperiod_overwrite_<domain>: 全上書き(新規作成時など)

ステップ 4: WebView Bridge の実装 (MCP Client)

Hono BrokerからのMCPリクエストを受け取り、実際のServiceを呼び出してJotaiステートに反映させます。

  • 場所: next-app/src/hooks/useMcpBridge.ts
  • 内容: セキュリティポリシー(設定での有効/無効、ユーザーの承認(HITL)確認)の適用を含みます。
  • 重要: 内製エージェントのツール(Step 2)とロジックを共有するか、直接 Service Layer を呼び出します。

3. ツール実装チェックリスト (Verification Checklist)

新しいエージェントツールを導入する、あるいは既存ツールを変更する場合、以下の「6つのポイント」を全て更新したか確認してください。一つでも欠けると、エージェントの体験が損なわれます。

  1. [ ] Logic: src/lib/features/<category>/service.ts に原子的なデータ操作が実装されているか?
  2. [ ] Definition: src/lib/features/editorial/tools/toolDefinitions.ts にツールが登録され、requiresConfirmationDefault が適切に設定されているか?
  3. [ ] i18n: src/i18n/locales/ja.json および en.jsonagent.tools セクションに、名称と説明が追加されているか?
  4. [ ] HITL UI: src/components/agent/AgentToolReviewDialog.tsxfetchOriginal 等に、そのツールの Diff(差分)を表示するためのロジックが含まれているか?(ツール名が artifactmanuscript を含んでいれば半自動でターゲットになります)
  5. [ ] MCP Bridge:
    • src/server/api/mcp/index.ts に定義を追加したか?
    • src/hooks/useMcpBridge.ts にハンドラ(case文)を追加したか?
  6. [ ] Guidance: src/lib/chat/prompts.tsAGENT_AUTONOMY_GUIDELINE や各エージェントの System Prompt に、そのツールの使い所や注意点が記載されているか?

4. ツール設計のベストプラクティス (Best Practices)

エージェントが快適かつ効率的に動作できるよう、ツール設計時には以下のガイドラインを遵守してください。

4.1. レスポンスサイズの最適化 (Context Preservation)

エージェントのコンテキスト(LLMの入力枠)を浪費しないよう、情報の粒度を適切に管理します。

  • List-Get パターン:
    • list_* ツール(例: blueperiod_list_characters)は、ID、名前、タイトル、更新日時などの最小限のメタデータのみを返却します。
    • 詳細な情報(本文、設定プロンプト等)が必要な場合のみ、get_* ツール(例: blueperiod_get_character)を個別に呼び出すように設計します。
  • 巨大データの除外:
    • blueperiod_get_project のように広範囲のデータを返すツールでは、原稿本文(manuscripts)などの巨大なフィールドを明示的に除外して返却します。

4.2. エラーハンドリングの一貫性

ツール実行のエラーが「サーバーの故障」としてではなく、「操作の失敗」として正しく伝わるようにします。

  • 200 OK & isError:
    • ツール実行内のエラー(例: IDが見つからない、引数が不正)は、HTTPステータス500を避け、200 OKを返した上で、MCPレスポンスの isError: true フラグを立てて具体的なエラーメッセージを返却します。
  • 先行バリデーション:
    • projectId, sectionId などの必須引数は、実際の処理に入る前に存在チェックを行い、欠落している場合は即座に人間が理解可能なエラーメッセージを返却します。

4.3. 循環参照防止 (Circular Reference Prevention)

ツール実行の結果をログ保存する際、巨大なデータ構造(メッセージ履歴、Artifactの本文等)が含まれていると、JSON.stringify によるクラッシュや循環参照エラーが発生する可能性があります。

実装パターン: src/stores/chat/agent.ts

// エージェントの全出力をメインストリーム(content)に統合する新しいパターン

// 1. セマンティック・コードブロックとして content に埋め込む
if (tc.name === 'record_thought') {
  rebuiltContent += `\n\n\`\`\`thought\n${thought}\n\`\`\`\n`;
} else if (tc.name === 'plan_task') {
  rebuiltContent += `\n\n\`\`\`plan\n${JSON.stringify(planArgs)}\n\`\`\`\n`;
} else if (tc.name === 'response') {
  rebuiltContent += `\n\n${content}\n`;
} else {
  // 技術ツール(web_search等)は lightweight に記録
  const { history: _h, ...safeArgs } = tc.args;
  rebuiltContent += `\n\n\`\`\`call\n${JSON.stringify({ tool: tc.name, args: safeArgs })}\n\`\`\`\n`;
}

// 2. thoughtLog には技術的なツール実行記録のみ保存(UIのアコーディオン用)
currentThoughtLog.push({
  phase: lastPhase,
  content: `Tool: ${tc.name}`,
  toolName: tc.name,
  toolArgs: safeArgs,  // 安全な引数のみ保存
  timestamp: Date.now()
});

: 2026-03-28のGraph設計リファクタリングで、ツールログは thoughtLog(技術ログ)と content(メインストリーム)に分離されました。record_thoughtplan_taskreport_progressresponse の出力はメインストリームに統合され、コピー可能です。

除外すべきフィールドのガイドライン:

フィールド理由
historyメッセージ履歴全体(巨大かつ循環参照の可能性)
content長文テキスト(Artifactの本文等、別途保存されている)
artifactsArtifact配列全体(個別参照可能なため除外)

原則: 「ストリーミングで再取得可能なデータ」や「別途Artifactとして保存されているデータ」はツールログから除外し、ログは「何のアクションを行ったか」という軽量な記録にとどめます。

4.4. 生成メタデータの追跡 (Generation Metadata)

AIエージェントによる自動生成物の一貫性を保つため、メタデータを記録します。

  • model / generatedAt:
    • 原稿の書き込みなど、AIがコンテンツを生成するツールでは、オプション引数として使用した model と生成日時 generatedAt を受け取れるようにし、データの debugInfo 等に記録します。
  • isOriginal / sourceLang:
    • 翻訳やリライトの文脈を失わないよう、書き込み対象がオリジナル言語なのか、何語からの翻訳なのかを明示するフラグを設けます。

5. ギャップ分析の真の基準

今後の実装担当は、GUIのボタンを探すのではなく、以下の**「データの溝」**を埋めることに専念してください。

  1. Read Gap: GUIで見えているデータ(キャラクターの過去、プロットの裏設定等)が、MCPツールの戻り値に含まれているか?
  2. State Gap: GUIで手動で書き換えられる項目すべてに、それに対応する原子的更新ツールが存在するか?
  3. Context Gap: 現在の編集対象だけでなく、プロジェクト全体のメタ情報(著者名、トーン設定等)を把握できるか?

「内蔵AIができること」は無視してください。外部AIは自らそれ以上のことを行います。

5. 開発時の注意点

  • ポート番号: 開発サーバーは必ず 3703 ポートで立ち上げてください。
  • ロングポーリング: useMcpBridge はログ抑制のためにロングポーリングを行っています。サーバー側の maxAttempts とクライアント側の timeout の整合性に注意してください。
  • 副作用: ツール実行後は、ユーザーの混乱を防ぐために toast 等で通知を表示することを推奨します(useMcpBridge 内ですでに一部実装済み)。

関連ドキュメント:

On this page