Por qué lo local es primero importante para los sistemas de agentes
Ejecutar un sistema de agentes de IA en la nube funciona bien cuando necesitas atender a usuarios externos a escala. Funciona mal cuando los datos sobre los que necesita razonar son internos, confidenciales o sólo valiosos en conjunto en su propia infraestructura. El historial de tareas, los documentos internos, las credenciales de API y los registros operativos de una empresa no deben salir del edificio solo para ejecutar una consulta de IA sobre ellos.
Lavc Systems se diseñó en torno a esta restricción. El sistema debe ser capaz de razonar sobre datos propietarios, ejecutar tareas y mantener la memoria entre sesiones, sin que nada de ese material toque un servidor de terceros. Cada elección de tecnología en el stack se deriva de este principio.
La consecuencia es una arquitectura más estricta de la que requiere una plataforma en la nube. No se puede asumir una escala horizontal infinita. Debe ser deliberado sobre lo que permanece en la memoria, lo que va al disco y lo que se indexa en una base de datos vectorial. La infraestructura de IA local no es una versión simplificada de la IA en la nube, sino una disciplina de ingeniería diferente.
FastAPI como columna vertebral: ¿por qué no Node.js
El backend sigue funcionando FastAPI con Python 3.14 y Uvicorn. La elección de Python en lugar de Node.js aquí no tiene que ver principalmente con el rendimiento, sino con la proximidad del ecosistema. Las bibliotecas más importantes para los sistemas de agentes (LangGraph, ChromaDB, HuggingFace, APScheduler, SQLAlchemy) son todas nativas de Python. Crear un backend Node.js y llamar a los servicios Python agrega un límite de proceso que complica la administración del estado y la depuración sin agregar valor significativo.
El soporte asíncrono de FastAPI se asigna naturalmente al modelo de ejecución de un sistema agente donde muchas operaciones están vinculadas a E/S: esperando una respuesta del modelo, leyendo desde ChromaDB, consultando SQLite. La estructura del enrutador modular permite que cada dominio (tareas, agentes, documentos, programador, objetivos, observabilidad) sea propietario de sus propios endpoints sin necesidad de acoplarse a un archivo de controlador monolítico.
El patrón de enrutador de FastAPI es el equivalente backend de un límite de módulo bien delimitado: cada enrutador maneja un dominio, importa lo que necesita y no toca lo que no posee. A escala de una plataforma local, esta disciplina previene el inevitable modo de falla del "único manejador que hace todo".
Ollama: el tiempo de ejecución local LLM
Ollama maneja el servicio de modelos localmente, exponiendo un API compatible al que el backend llama exactamente como llamaría a un proveedor de nube. El modelo predeterminado es qwen2.5-coder:7b, elegido por su sólido razonamiento de código y su razonable huella de recursos en el hardware del desarrollador. La arquitectura no se vincula a este modelo: cambiar a un modelo diferente compatible con Ollama es un cambio de configuración, no un cambio de código.
La decisión de ingeniería importante aquí es lo que Ollama resuelve a nivel del sistema: elimina la dependencia de la red de la ruta de inferencia. Cuando un agente está a mitad de una tarea y necesita llamar al modelo, el viaje de ida y vuelta es local. Esto hace que la latencia sea predecible, elimina el riesgo de limitación de velocidad durante la ejecución intensiva y elimina el área superficial donde los datos internos podrían quedar expuestos a un proveedor externo.
El costo es hardware. Un modelo de parámetros 7B que se ejecuta en la CPU es más lento que una llamada a la nube API. En una máquina con una GPU capaz, la diferencia se reduce significativamente. El diseño del sistema tiene en cuenta esto agrupando llamadas LLM en la capa de orquestación en lugar de realizar llamadas redundantes en cada paso del agente.
LangGraph: orquestación como máquina de estados
LangGraph es la capa de orquestación. En lugar de escribir bucles de agentes imperativos en Python, LangGraph modela el flujo de trabajo de múltiples agentes como un gráfico dirigido donde los nodos son pasos del agente y los bordes son transiciones condicionales. Esto tiene varias consecuencias prácticas para un sistema como Lavc Systems.
Primero, las decisiones del agente coordinador se convierten en transiciones gráficas explícitas en lugar de controlar el flujo en un cuerpo funcional. Cuando el coordinador decide delegar al agente programador, esa delegación es un borde con nombre en el gráfico, no una llamada enterrada dentro de un bloque condicional. Esto hace que el seguimiento de ejecución sea legible y depurable: la pantalla Agent Graph en la interfaz de usuario lo muestra en vivo y muestra qué nodos están activos, cuáles se han completado y qué eventos se han emitido.
En segundo lugar, la gestión del estado de LangGraph es componible. Cada paso del agente recibe el estado actual del gráfico, modifica su segmento relevante y pasa el estado actualizado al siguiente nodo. Esto significa que el contexto disponible para cada agente es explícito y de tipo verificado, no un objeto ambiental enhebrado a través de una stack de llamadas. Para una pista de auditoría que aparece ante los usuarios como una pista operativa, las transiciones de estado explícitas son significativamente más fáciles de resumir que el estado compartido implícito.
El seguimiento operativo que ven los usuarios (intención detectada, contexto consultado, herramienta o acción utilizada, siguiente paso) no se genera pidiendo al modelo que resuma su propio razonamiento. Se deriva de las transiciones de estado del gráfico reales registradas durante la ejecución. Esto lo hace auditable y preciso en lugar de una aproximación generada por un modelo.
ChromaDB y la arquitectura RAG
ChromaDB es la base de datos vectorial que respalda la capa RAG. La elección de diseño de utilizar ChromaDB en lugar de alternativas como Qdrant o Weaviate se reduce a la simplicidad operativa: ChromaDB se ejecuta en proceso y almacena sus datos en el disco local sin ningún servicio separado que administrar. Para un sistema que prioriza lo local y donde los gastos operativos son una limitación principal, esto es importante.
RAG en Lavc Systems tiene dos propósitos que vale la pena distinguir. La primera es la recuperación de documentos: cuando un agente necesita razonar sobre documentos internos (PDF cargados, archivos de políticas, referencias técnicas), consulta ChromaDB con una incorporación del contexto de la tarea actual y recupera los k fragmentos semánticamente relevantes. El segundo propósito es la retroalimentación de artefactos: los resultados generados por los agentes durante la ejecución de la tarea se pueden cargar nuevamente en ChromaDB, haciendo que el resultado de una tarea esté disponible como contexto para tareas futuras.
Las incrustaciones se generan usando Transformadores de oraciones de HuggingFace biblioteca, nuevamente ejecutándose localmente. El modelo de incrustación se ejecuta una vez al inicio y permanece residente en la memoria durante la sesión. Esto elimina la necesidad de llamar a una incrustación API para cada consulta de fragmento de documento, lo que reintroduciría las preocupaciones de latencia y privacidad que justificaron la infraestructura local en primer lugar.
HybridMemory: dos tiendas con una interfaz
La memoria del agente en Lavc Systems utiliza un HybridMemory abstracción que unifica dos backends de almacenamiento diferentes: SQLite para registros estructurados y ChromaDB para recuperación semántica.
La división es deliberada. Los registros estructurados (historial de tareas, interacciones del usuario, hechos específicos sobre el estado del sistema) pertenecen al SQLite porque deben consultarse de manera determinista. "¿Qué tareas completó el agente programador esta semana?" es una consulta SQL, no una búsqueda semántica. Pero "qué contexto es más relevante para esta tarea" es una cuestión semántica, y pertenece a ChromaDB.
HybridMemory permite que la capa de agente use una única interfaz y enruta la consulta al almacén apropiado según el tipo de consulta. Esto evita el modo de falla común en el que los equipos eligen un paradigma de almacenamiento y luego contorsionan todas las consultas para que se ajusten a él: forzar búsquedas semánticas en SQL búsquedas LIKE o calzar filtros estructurados en puntuaciones de similitud de vectores.
APScheduler y la capa de objetivos autónomos
Programador APS maneja trabajos recurrentes: tareas que deben ejecutarse según una programación en lugar de según la demanda del usuario. Esto tiene más consecuencias de lo que parece para un sistema de agentes. Una fracción significativa del valor operativo no proviene de conversaciones interactivas de IA, sino de tareas que se ejecutan de manera confiable en segundo plano: generación de informes diarios, agregación de datos, reindexación de documentos, comprobaciones del estado del sistema.
Arriba de APScheduler se encuentra GoalEngine, que gestiona objetivos de orden superior. Los objetivos no son trabajos programados: son misiones multitarea con factores asociados de urgencia, importancia y fecha límite que generan una priority_score. Un objetivo como "preparar el informe ejecutivo semanal" podría descomponerse en varias tareas: extraer documentos recientes, resumir riesgos y oportunidades, generar un informe Markdown y crear tareas de seguimiento en Kanban.
La relación entre el planificador, el motor de objetivos y Kanban es la columna operativa del sistema. El Kanban rastrea el estado de ejecución. El planificador activa la recurrencia. El motor de objetivos proporciona la intención de nivel superior que determina qué tareas se crean y en qué secuencia.
React, Vite y Zustand en la interfaz
La interfaz es una React 18 aplicación construida con vite y diseñado con CSS de viento de cola. Usos de la gestión estatal Zustand. Estas son opciones convencionales para una aplicación TypeScript-primera React, y el interés está menos en por qué se eligió cada una y más en cómo se ajustan a los requisitos en tiempo real de una interfaz de monitoreo de agentes.
La pantalla Agent Graph es la parte técnicamente más exigente de la interfaz. Representa el flujo de trabajo de múltiples agentes en vivo (nodos, bordes, estados activos, recuentos de eventos y línea de tiempo) y se actualiza en tiempo real a medida que el backend impulsa los eventos de WebSocket. Esto requiere una tienda Zustand que pueda recibir actualizaciones parciales del controlador WebSocket y activar renderizaciones selectivas sin volver a renderizar el gráfico completo en cada evento.
La placa Kanban tiene un requisito diferente: actualizaciones optimistas. Cuando un usuario arrastra una tarjeta de tarea a una nueva columna, la interfaz de usuario debe reflejar ese cambio inmediatamente, antes de que se envíe la solicitud PATCH. /api/tasks/{id}/move ha completado. Si la solicitud falla, la tarjeta debe revertirse. Este patrón (mutación optimista con reversión de fallas) se administra en el almacén de tareas de Zustand en lugar de dentro del componente, lo que mantiene la capa del componente libre de lógica de coordinación.
WebSocket como bus de eventos en tiempo real
el /ws endpoint transporta todos los eventos en tiempo real desde el backend al frontend: cambios de estado de tareas, finalización de pasos del agente, entradas de registro, actualizaciones del estado del sistema y resultados del trabajo del programador. El uso de una única conexión WebSocket en lugar de sondear varios endpoints reduce la carga del servidor y proporciona a la interfaz de usuario un modelo de eventos consistente independientemente del módulo que generó el evento.
El backend gestiona la conexión WebSocket en ws.py, que mantiene la lógica de administración de conexiones separada de los módulos del enrutador. Cada enrutador emite eventos llamando a un emisor de eventos compartido; el controlador WebSocket se suscribe a ese emisor y reenvía eventos a los clientes conectados. Esto significa que agregar un nuevo tipo de evento (por ejemplo, una nueva acción de agente en un módulo futuro) solo requiere emitir el evento desde el nuevo enrutador, sin cambios en la capa de transporte WebSocket.
Seguridad: usuarios, auditoría y bóveda local
Una plataforma que almacena API credenciales, ejecuta tareas de forma autónoma y se conecta a herramientas externas necesita un modelo de seguridad coherente incluso cuando se ejecuta localmente. Lavc Systems incluye administración de usuarios y empresas con acceso específico, un registro de auditoría que registra quién hizo qué y cuándo, y una bóveda de credenciales local para almacenar API claves y secretos utilizados por herramientas y complementos.
La bóveda no es intencionalmente un administrador de secretos en la nube. El almacenamiento de credenciales localmente en una bóveda que la capa del agente puede leer en tiempo de ejecución mantiene los secretos fuera de cualquier servicio externo y al mismo tiempo permite la automatización que los requiere. La desventaja es que la seguridad de la bóveda local es tan sólida como la máquina en la que se ejecuta, lo cual es un límite aceptable para un sistema diseñado explícitamente para el funcionamiento local.
Skyler: el mismo asistente, un entorno de ejecución diferente
Skyler aparece en dos lugares del portafolio Lavc. La versión pública Skyler Assistant — se ejecuta en Cloudflare Workers con RAG manual, fallback de proveedor y un modelo de orquestación liviano diseñado para visitantes de portafolio público. Responde preguntas sobre el trabajo, el stack y la experiencia de Patrick. No tiene acceso a datos privados. No ejecuta tareas. Es una interfaz conversacional de sólo lectura sobre una base de conocimientos fija.
Skyler dentro de Lavc Systems es una implementación diferente en el mismo rol conceptual. Se ejecuta dentro del backend de FastAPI, tiene acceso a la base de datos SQLite, puede consultar ChromaDB, puede crear tareas, leer archivos cargados, escribir credenciales en la bóveda local y generar un seguimiento operativo de sus propias respuestas. El seguimiento no es una prosa generada por el modelo sobre lo que pensó el modelo; es un registro estructurado de las transiciones de estado reales ejecutadas durante la respuesta: intención detectada, fuente de contexto consultada, acción tomada, siguiente paso recomendado.
La lección arquitectónica de ambas versiones es que la calidad de un asistente de IA no está determinada principalmente por el modelo. Está determinado por los datos a los que puede acceder el asistente, qué acciones puede realizar y qué tan transparente es su razonamiento para las personas que confían en él. El Skyler público es útil porque tiene la base de conocimientos adecuada y reglas de respuesta claras. El sistema Skyler es más capaz porque tiene acceso al contexto operativo completo de la plataforma en la que vive.
Actualizar un asistente de IA no es un problema de actualización de modelo. Es un problema de acceso y contexto. El mismo diseño del asistente se vuelve más valioso a medida que amplía lo que puede observar y sobre lo que se le permite actuar, manteniendo al mismo tiempo el rastro de esa acción legible para los humanos.
La observabilidad como restricción de diseño.
Los sistemas de agentes fallan de maneras que son difíciles de depurar sin una observabilidad estructurada. Una tarea que produce un resultado incorrecto puede haber fallado en el paso de planificación del coordinador, en el paso de recuperación de documentos del analista, en el paso de generación del programador o en el paso de validación del revisor, y sin datos de seguimiento, la única señal es que el resultado fue incorrecto.
Lavc Systems trata la observabilidad como una preocupación de primera clase desde el principio. El módulo de observabilidad registra seguimientos, métricas y eventos de ejecución para cada acción del agente. La pantalla de Control los expone como un tablero. La página de detalles de la tarea muestra el registro de ejecución completo para una tarea específica, incluidos qué agentes ejecutaron, qué herramientas llamaron, qué contexto consultaron y cuánto tiempo tomó cada paso.
Esto no es principalmente para depurar, es para confiar. Es difícil confiar en un sistema de agente que se ejecuta de forma autónoma y produce resultados sin ninguna ventana de cómo llegó allí para realizar trabajos importantes. La observabilidad es el mecanismo mediante el cual el sistema gana la confianza para ejecutar sin supervisión tareas cada vez más importantes.