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' }新しいページコンテキストを追加
AiContextProviderInterfaceを実装するクラスを作成services.yamlにtags: [{ name: 'app.ai_context' }]を追加- ページテンプレートに
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の場合:- ToolCall 配列を MessageBag に追加
- ToolCall を実行し、ToolResult を MessageBag に書き戻す
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.php | app.ai_context タグのサービスを収集し、name で索引付け |
AiAssistant.php | 汎用化された Agent ファクトリ |
LlmRouterPlatform.php | PlatformInterface ブリッジ(MessageBag ↔ 配列) |
ChatResultConverter.php | レスポンスデータ → TextResult/ToolCallResult |
ViewEditorToolProvider.php | ビューエディタの Tool メソッド |
ChromeDevToolsToolProvider.php | CDP ブラウザデバッグツール |
ViewFileToolProvider.php | ビューファイル読み書きツール |