Skip to content

Asistente IA

Doggy ofrece un asistente IA global, presente en todas las páginas en forma de botón flotante + panel deslizante, con integración profunda con las páginas mediante un mecanismo de registro de contexto, y soporte para el bucle de razonamiento ReAct y la llamada a herramientas.

Descripción general

El Asistente IA está construido sobre la pila tecnológica symfony/ai-agent + symfony/ai-platform y se conecta con el sistema de puerta de enlace LlmRouter propio de la plataforma:

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 (bucle ReAct)
            ← string response

Entrada global

El panel del Asistente IA se incluye de forma incondicional en templates/base.html.twig:

twig
<body>
    {% block body %}{% endblock %}
    {% include 'admin/ai_chat.html.twig' %}
</body>
  • Abrir/Cerrar: botón flotante en la esquina inferior derecha toggle-ai-chat / ai-chat-close
  • Entrada: Enter envía, Shift+Enter salto de línea
  • Estado de carga: durante la petición se deshabilita la entrada y se muestra "Pensando..."
  • Estilos: public/sunui/admin/ai_chat.css

Registro de contexto de página

Cada página registra su contexto en el asistente a través de window.__AI_CONTEXT__:

js
window.__AI_CONTEXT__ = {
    name: 'view_editor',                  // AiContextProviderInterface::getName() del backend
    buildPrompt: function(msg) {          // opcional, construye el mensaje enviado al backend
        return '[ID de vista actual: xxx]\n\n' + msg;
    },
};

Ejemplo de registro del editor de vistas:

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 de vista actual: ' + vid + ']\n\n' + msg : msg;
      },
  };
</script>

Sistema de proveedores de contexto

AiContextProviderInterface define los proveedores de contexto:

php
namespace App\Service\AI\Runtime;

interface AiContextProviderInterface
{
    public function getName(): string;                    // Identificador de contexto
    public function getRoleCode(): string;                // Código de rol de LlmRouter
    public function getSystemPrompt(): string;            // Prompt del sistema del Agente
    public function getToolProviders(): array;            // Matriz de objetos Tool
}

Se registra mediante la etiqueta app.ai_context:

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

Añadir un contexto de página nuevo

  1. Crea una clase que implemente AiContextProviderInterface
  2. Añade tags: [{ name: 'app.ai_context' }] en services.yaml
  3. Define window.__AI_CONTEXT__ = { name: 'your_name' } en la plantilla de la página

Runtime de Agente

AiAssistant es una fábrica de Agentes genérica: cada llamada a chat() crea una instancia de Agente independiente para garantizar que no haya contaminación de estado:

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',
);

Bucle ReAct

AgentProcessor actúa a la vez como procesador de entrada y de salida, implementando el bucle de llamada a herramientas:

  • processInput: inyecta los metadatos de las Tool del Toolbox
  • processOutput: cuando el resultado es ToolCallResult:
    1. Añade la matriz de ToolCall al MessageBag
    2. Ejecuta ToolCall → escribe el ToolResult de vuelta en el MessageBag
    3. Llama de forma recursiva hasta devolver un TextResult

Sistema de herramientas

Las herramientas se marcan con el atributo #[AsTool] de symfony/ai-agent:

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

class ViewEditorToolProvider
{
    #[AsTool(name: 'view.getInfo', description: 'Obtiene la información completa de la vista')]
    public function getViewInfo(string $viewId): array { ... }

    #[AsTool(name: 'view.updateSectionConfig', description: 'Actualiza la configuración de diseño de la vista')]
    public function updateSectionConfig(string $viewId, string $contentWidth, ...): array { ... }
}

Herramientas actuales del editor de vistas

ToolFunción
view.getInfoObtener información de la vista (entidad, campos, diseño)
view.updateSectionConfigActualizar la configuración del diseño
view.updateFieldConfigActualizar la configuración de campos
view.listEntityFieldsListar los campos de la entidad

Principios de diseño

  • Cada herramienta es un método con una única responsabilidad
  • Los nombres de parámetros coinciden con los del JSON Schema de #[AsTool] (mapeo automático)
  • Devuelven array (convertido en texto de resultado de la herramienta)

Endpoints de API

POST /api/admin/ai/chat

json
{
    "context": "view_editor",
    "message": "Cámbialo a un diseño de tres columnas"
}

Respuesta de éxito:

json
{
    "code": 200,
    "message": "success",
    "data": { "reply": "Modificado a un diseño de tres columnas." }
}

Archivos relacionados

ArchivoResponsabilidad
AiChatController.phpRecibe {context, message} y delega en el Provider correspondiente
AiContextRegistry.phpRecopila los servicios etiquetados con app.ai_context, indexados por nombre
AiAssistant.phpFábrica de Agentes genérica
LlmRouterPlatform.phpPuente de PlatformInterface (MessageBag ↔ array)
ChatResultConverter.phpConvierte los datos de respuesta en TextResult/ToolCallResult
ViewEditorToolProvider.phpMétodos Tool del editor de vistas
ChromeDevToolsToolProvider.phpHerramientas de depuración del navegador CDP
ViewFileToolProvider.phpHerramientas de lectura/escritura de archivos de vista

Código abierto bajo MIT | Copyright © 2026 Doggy