Neuron AI 4 es un framework PHP para crear agentes de IA con herramientas propias, memoria y aprobación humana, dentro de tu proyecto.
Se instala con un composer require, vive en el mismo repositorio que tu Drupal o tu ERP y corre en el proceso de la aplicación: no hay que montar un servicio en Python ni un segundo stack que operar.
Qué es Neuron AI 4 y por qué importa en un equipo PHP
Neuron es un framework open source (licencia MIT) para construir y orquestar agentes de IA en PHP. Un agente es una clase que extiende Agent, con instrucciones, un proveedor de modelo, memoria, herramientas propias y RAG. El framework se encarga de la capa que todos repetimos a mano: las llamadas al modelo, el manejo del contexto, el uso de herramientas y el streaming.
La diferencia práctica frente a un asistente externo está en el control. El prompt, las herramientas y los datos viven en tu repositorio, se versionan, se prueban y se auditan: el modelo solo ve la información que tú le entregas de forma explícita.
El proyecto está en GitHub y la referencia completa, en docs.neuron-ai.dev.
Instalación real: un comando y una clase
Los requisitos publicados son PHP ^8.1 y la extensión ext-curl. En un proyecto con Drupal o Symfony ya cumples ambos, así que la instalación es una línea:
composer require neuron-core/neuron-ai
Ojo al esqueleto que genera el framework:
vendor/bin/neuron make:agent SoporteClienteAgent
Las dos piezas obligatorias del agente son las instrucciones y las herramientas:
use NeuronAI\Agent\Agent;
use NeuronAI\Chat\Messages\UserMessage;
class SoporteClienteAgent extends Agent
{
protected function instructions(): string
{
return 'Eres un agente de soporte de una empresa colombiana de software. '
. 'Respondes en español de Colombia, con tono corto y profesional. '
. 'Nunca inventas datos: si no tienes el dato, indicas que lo consultas.';
}
protected function tools(): array
{
return [ConsultarPedido::class];
}
}
$respuesta = SoporteClienteAgent::make()
->setThreadId('chat_cliente_88')
->chat(new UserMessage('¿Cuál es el estado del pedido 1042?'));
echo $respuesta->getMessage()->getContent();
El setThreadId() es lo que amarra la conversación con una sesión: sin eso, cada chat() arranca sin contexto.
Un agente con una herramienta propia
Una herramienta es una clase que describe qué hace y qué datos necesita. El agente decide cuándo invocarla y usa el resultado como contexto para redactar la respuesta. En la v4 la clase Tool es abstracta: el nombre y la descripción son propiedades y la ejecución va en __invoke():
use NeuronAI\Tool;
class ConsultarPedido extends Tool
{
protected string $name = 'consultar_pedido';
protected ?string $description = 'Consulta el estado y el total de un pedido por su número.';
public function __construct(protected string $numeroPedido) {}
public function __invoke(): string
{
$fila = $this->consultarEnBaseDeDatos($this->numeroPedido);
return json_encode([
'encontrado' => (bool) $fila,
'estado' => $fila['estado'] ?? null,
'total' => $fila['total'] ?? null,
'fecha' => $fila['fecha'] ?? null,
], JSON_UNESCAPED_UNICODE);
}
}
Devuelve siempre JSON: es la forma más estable de que el modelo lea el resultado. Y valida la entrada, porque el modelo puede inventar un número de pedido.
Aprobación humana antes de tocar datos
Este es el patrón que más importa cuando el agente escribe en la base de datos. La regla simple: lecturas directas, escrituras con confirmación. La v4 trae esto de fábrica: un método requiresApproval() en la herramienta y el middleware ToolApproval en el agente.
class GenerarNotaCredito extends Tool
{
protected string $name = 'generar_nota_credito';
protected ?string $description = 'Prepara una nota crédito para un pedido. Requiere aprobación humana.';
public function __construct(protected string $apiKey) {}
public function requiresApproval(array $inputs): bool
{
return (float) ($inputs['monto'] ?? 0) > 500000;
}
public function __invoke(): string
{
return json_encode([
'estado' => 'pendiente_aprobacion',
'operacion' => 'crear_nota_credito',
'ejecutado' => false,
], JSON_UNESCAPED_UNICODE);
}
}
Con el middleware activo, el framework se detiene antes de ejecutar la herramienta y deja el estado de la llamada en el historial, dentro del último ToolCallMessage. Tu interfaz solo tiene que leer ese historial y pintar los botones de aprobar o rechazar. Si prefieres control manual, la herramienta puede devolver un estado pendiente_aprobacion, tu endpoint guarda la solicitud y notifica a una persona, y la escritura se ejecuta después con tu capa de negocio normal, nunca desde la herramienta.
Qué cambió en la versión 4
La v4 no es un parche: reconstruyó el componente Workflow, que es la base de todo el framework, y ajustó la API pública. La guía de actualización oficial es la referencia para todo esto.
De ChatHistoryInterface a MessageStoreInterface
El historial como concepto desaparece y en su lugar llega MessageStoreInterface. La diferencia es de alcance: el historial era una lista de mensajes; el store es un contrato de persistencia que puede cumplir una base de datos, Redis, un archivo o un servicio externo. Además, los mensajes que se salen de la ventana de contexto se marcan como archivados en vez de borrarse, así que el modelo ve un hilo recortado y tu almacenamiento conserva la conversación completa. Para una empresa que necesita que el historial sobreviva a reinicios y quede registrado para soporte, eso importa.
PSR-14 en lugar del observador propio
El observador basado en \SplObserver queda deprecado a favor del despachador de eventos PSR-14, y Guzzle dejó de ser dependencia del framework: ahora el cliente HTTP por defecto usa ext-curl. El paquete inspector-php también sale de las dependencias por defecto. En la práctica, si ya usas Symfony o Drupal, enganchar la observabilidad de tus agentes deja de ser trabajo extra.
FrontendTool, Streaming Channels y memoria semántica
La v4 suma una abstracción para herramientas que se ejecutan en el navegador o en el dispositivo (FrontendTool), canales de streaming para entregar la respuesta fuera del ciclo de la petición HTTP, SemanticMemoryRetrieval para recordar cosas entre conversaciones por significado y no solo por coincidencia literal, y ClassifierInterface para enrutar o puntuar sin gastar tokens de un modelo grande en una decisión de una palabra.
También cambian cosas internas que tocan código existente: Tool ahora es abstracta, el agente devuelve AgentState, stream() entrega el generador directamente y se eliminó el WorkflowHandler.
Migrar de Neuron 3 a Neuron 4
El paquete trae un directorio vendor/neuron-core/neuron-ai/upgrade con instrucciones para agentes de código. Revísalo antes de correrlo; este es el orden que uso:
- Fija la versión exacta en
composer.json("neuron-core/neuron-ai": "^4.0") antes de la primera corrida, para poder volver concomposer require neuron-core/neuron-ai:^3.0. - Si usabas
inspector-phpsolo para el observador, instálalo a mano; si ya usabas Guzzle por otra razón, déjalo explícito en tucomposer.json. - Migra tu implementación de
ChatHistoryInterfaceaMessageStoreInterface. - Revisa el flujo de interrupción y aprobación: cambió el esquema de persistencia del workflow y ya no se lanza la excepción de interrupción, se consulta
$state->isInterrupted(). - Reinstala las skills del framework en tu agente de código y vuelve a leer la guía.
Hazlo en una rama aparte y con pruebas. Un cambio de nombre de interfaz se detecta rápido, pero un prompt que se degrada en silencio no.
Conectarlo a Drupal y a un ERP sin montar Python
En Drupal el encaje natural es un servicio (Drupal::service()) que envuelve al agente, invocado desde un controlador AJAX o desde un webhook. Para streaming, stream() entrega eventos y los imprimes en un StreamedResponse de Symfony, con flush() entre fragmento y fragmento:
foreach ($agente->stream(new UserMessage('Resume el pedido 1042')) as $evento) {
if ($evento instanceof TextChunk) {
echo $evento->content;
flush();
}
}
En un ERP a medida el patrón es el mismo, y ahí es donde se gana la propuesta: consultas tu base de datos con el SQL que ya existe y con tus validaciones, y le dejas al agente la parte no determinista (redactar, resumir, clasificar, explicar). Sin exponer credenciales a un tercero y sin depender de un servicio externo que te cambie precios o se caiga.
Preguntas frecuentes
¿Neuron AI reemplaza a OpenAI, Claude o Gemini?
No. Es la capa de orquestación: gestiona el contexto, las herramientas, la memoria y el flujo. El proveedor del modelo lo eliges tú en configuración y puedes cambiarlo sin reescribir el agente.
¿Necesito aprender Python o montar un servicio aparte?
No. Es una librería PHP con tipos, se instala por Composer y se ejecuta en el mismo proceso de tu aplicación. El agente es una clase que extiendes, no un servicio que tengas que operar.
¿Qué versión de PHP necesita?
La v4 declara PHP ^8.1 y la extensión ext-curl, que ya viene activa en casi toda instalación. Igual apunta tu plataforma a una versión LTS soportada.
¿Cómo sé si un agente está listo para producción?
Tres pruebas mínimas: el mismo prompt con respuestas variables (si no es determinista, aísla el sampling), herramientas con datos faltantes (debe decir que no sabe, no inventar) y el flujo de aprobación humana verificado de punta a punta, con una escritura real en un entorno de pruebas.
¿Vale la pena para una pyme o es sobreingeniería?
Si el proceso manual ya te toma horas al día y tienes datos estructurados, sí. Un POS con licencia vitalicia o un ERP a medida que consulte y prepare acciones —siempre con aprobación humana— recupera horas sin cambiar de stack. Si tu flujo todavía es corto, empieza más pequeño.
Siguiente paso: elige un proceso concreto de tu operación, como el estado de un pedido, y constrúyelo como un agente con una sola herramienta de solo lectura. Cuando esa funcione bien en pruebas, agrega la primera escritura con aprobación humana. Si quieres partir de un ejemplo ya integrado con Drupal y tu ERP, conversemos en saibher.com/contacto.