Skip to content

AI アシスタント

Doggy はグローバル AI アシスタントを提供し、フローティングボタン + スライドパネルの形ですべてのページに存在します。コンテキスト登録メカニズムによりページと深く統合され、ReAct 推論ループとツール呼び出しをサポートします。

概要

AI アシスタントは symfony/ai-agent + symfony/ai-platform の技術スタックで構築され、プラットフォーム独自の LlmRouter ゲートウェイ体系に接続します:

Client POST /api/admin/ai/chat  { context, message }
  → AiChatController
    → AiContextRegistry::get(context)
      → AiContextProviderInterface (e.g. ViewEditorAiContext)
        → AiAssistant::chat(roleCode, systemPrompt, toolProviders, message)
          → Agent::call(MessageBag, options)
            → AgentProcessor::processInput (注入 Tool)
            → LlmRouterPlatform::invoke → LlmRouter → LlmGatewayFactory
            → AgentProcessor::processOutput (ReAct 循环)
            ← string response

グローバルエントリ

AI アシスタントパネルは templates/base.html.twig で無条件にインクルードされます:

twig
<body>
    {% block body %}{% endblock %}
    {% include 'admin/ai_chat.html.twig' %}
</body>
  • 開閉: 右下のフローティングボタン toggle-ai-chat / ai-chat-close
  • 入力: Enter で送信、Shift+Enter で改行
  • ローディング状態: リクエスト中は入力を無効化し、「思考中...」と表示
  • スタイル: public/sunui/admin/ai_chat.css

ページコンテキスト登録

各ページは window.__AI_CONTEXT__ を通じてアシスタントにコンテキストを登録します:

js
window.__AI_CONTEXT__ = {
    name: 'view_editor',                  // 后端 AiContextProviderInterface::getName()
    buildPrompt: function(msg) {          // 可选,构造发送给后端的消息
        return '[当前视图ID: xxx]\n\n' + msg;
    },
};

ビューエディタの登録例:

twig
<script>
  window.__VIEW_ID__ = {{ id|json_encode|raw }};
  window.__AI_CONTEXT__ = {
      name: 'view_editor',
      buildPrompt: function(msg) {
          var vid = window.__VIEW_ID__;
          return vid ? '[当前视图ID: ' + vid + ']\n\n' + msg : msg;
      },
  };
</script>

コンテキストプロバイダシステム

AiContextProviderInterface はコンテキストプロバイダを定義します:

php
namespace App\Service\AI\Runtime;

interface AiContextProviderInterface
{
    public function getName(): string;                    // 上下文标识
    public function getRoleCode(): string;                // LlmRouter 角色代码
    public function getSystemPrompt(): string;            // Agent 系统提示词
    public function getToolProviders(): array;            // Tool 对象数组
}

app.ai_context タグを通じて登録します:

yaml
App\Service\AI\Context\ViewEditorAiContext:
    tags:
        - { name: 'app.ai_context' }

新しいページコンテキストを追加

  1. AiContextProviderInterface を実装するクラスを作成
  2. services.yamltags: [{ name: 'app.ai_context' }] を追加
  3. ページテンプレートに window.__AI_CONTEXT__ = { name: 'your_name' } を設定

Agent ランタイム

AiAssistant は汎用化された Agent ファクトリで、chat() のたびに独立した Agent インスタンスを作成し、状態の汚染を防ぎます:

php
$platform = new LlmRouterPlatform($this->router, $this->converter);
$toolbox = new Toolbox($toolProviders);

$agent = new Agent(
    platform: $platform,
    model: $roleCode,
    inputProcessors: [
        new SystemPromptInputProcessor($systemPrompt),
        new AgentProcessor($toolbox),
    ],
    outputProcessors: [
        new AgentProcessor($toolbox),
    ],
    name: 'ai-assistant',
);

ReAct ループ

AgentProcessor は入力/出力プロセッサを兼ね、ツール呼び出しループを実装します:

  • processInput: Toolbox の Tool メタデータを注入
  • processOutput: 結果が ToolCallResult の場合:
    1. ToolCall 配列を MessageBag に追加
    2. ToolCall を実行し、ToolResult を MessageBag に書き戻す
    3. TextResult が返るまで再帰的に呼び出す

ツール体系

symfony/ai-agent#[AsTool] 属性でツールメソッドをマークします:

php
use Symfony\AI\Agent\Toolbox\Attribute\AsTool;

class ViewEditorToolProvider
{
    #[AsTool(name: 'view.getInfo', description: '获取视图的完整信息')]
    public function getViewInfo(string $viewId): array { ... }

    #[AsTool(name: 'view.updateSectionConfig', description: '更新视图的布局配置')]
    public function updateSectionConfig(string $viewId, string $contentWidth, ...): array { ... }
}

現在のビューエディタツール

Tool機能
view.getInfoビュー情報を取得(エンティティ、フィールド、レイアウト)
view.updateSectionConfigレイアウト設定を更新
view.updateFieldConfigフィールド設定を更新
view.listEntityFieldsエンティティフィールドを列挙

設計原則

  • 各ツールは単一責任のメソッド
  • パラメータ名は #[AsTool] JSON Schema のパラメータ名と一致(自動マッピング)
  • array を返す(ツール結果テキストに変換)

API エンドポイント

POST /api/admin/ai/chat

json
{
    "context": "view_editor",
    "message": "帮我改成三列布局"
}

成功レスポンス:

json
{
    "code": 200,
    "message": "success",
    "data": { "reply": "已修改为三列布局。" }
}

関連ファイル

ファイル責務
AiChatController.php{context, message} を受信し、対応する Provider に委任
AiContextRegistry.phpapp.ai_context タグのサービスを収集し、name で索引付け
AiAssistant.php汎用化された Agent ファクトリ
LlmRouterPlatform.phpPlatformInterface ブリッジ(MessageBag ↔ 配列)
ChatResultConverter.phpレスポンスデータ → TextResult/ToolCallResult
ViewEditorToolProvider.phpビューエディタの Tool メソッド
ChromeDevToolsToolProvider.phpCDP ブラウザデバッグツール
ViewFileToolProvider.phpビューファイル読み書きツール

MIT ライセンスでオープンソース | Copyright © 2026 Doggy