Volver a proyectos
2026 · ML & IA · Activo

Virtual Assistant — Asistente IA local en iGPU, diseñado con V-Model y playbook de agentes

Asistente de IA local-first con tres interfaces (CLI, Telegram, Voz), Home Assistant, búsqueda web y memoria persistente. Inferencia sobre AMD Radeon 680M iGPU con llama-router, 5 capas aisladas, metodología V-Model NASA + Loop Engineering y playbook de agentes documentado en wiki-brain. ~2s en intents simples, p50 0.5s en el tier standard.

Python 3.12 V-Model NASA Loop Engineering llama-router llama.cpp Vulkan Qwen3.5-2B LFM2.5-8B-A1B (MoE) Home Assistant Telegram Wyoming Parakeet STT Piper TTS wiki-brain LLM Wiki Pattern

Problema

Soluciones de agentes existentes (OpenClaw, Hermes y similares) están dimensionadas para GPUs dedicadas o cloud. En una iGPU AMD Radeon 680M con 24 GB de RAM compartida, esos agentes no caben, van lentos, o se quedan en bucles de tool-calling por usar modelos sin fine-tuning. Faltaba un asistente personalizado, fluido, que corriese 24/7 en ese hardware modesto.

Solución

Construir un asistente propio en Python con 5 capas aisladas (Interfaces → Core → Tooling → Memory → LLM Gateway), router de modelos con 2 tiers activos (standard / capable) servido por llama.cpp + Vulkan en la iGPU, y un playbook de agentes en el wiki-brain que recoge las decisiones arquitectónicas y los conceptos aprendidos. La construcción se gobierna por V-Model NASA (ConOps → Requirements → HLD → LLD → V&V) y la iteración por Loop Engineering (Generator-Verifier con turn budget). Cada feature va en su propia rama y se mergea a main solo cuando los tests pasan y la aceptación humana está documentada.

Logros clave

  • Tres interfaces operativas: CLI, Telegram (raw httpx) y Voz (Wyoming + Parakeet STT + Piper TTS es_ES-davefx-medium)
  • 5 dominios de herramientas: domótica, web, sistema, información, grounding
  • llama-router con 2 tiers activos en routing real: standard (Qwen3.5-2B) y capable (LFM2.5-8B-A1B MoE)
  • Inferencia local en iGPU AMD Radeon 680M (Vulkan) con ~50 tok/s en el modelo standard, sin GPU dedicada
  • 800 tests pytest pasando, 30 escenarios de evaluación, runtime analyzer + métricas automáticas
  • Playbook de agentes en el wiki (LLM Wiki Pattern): glosario, fundamentos, contexto, guardrails, validación, multi-agente, debate
  • V-Model NASA aplicado: 11 iteraciones documentadas en `designs/` con ConOps, Requirements, HLD, LLD, V&V
  • Cascada determinista 3-stage en Perception: el ~80% del tráfico se resuelve sin llamar al LLM en <50ms

Motivación

OpenClaw recomienda “usar el modelo más potente disponible” y en la práctica los modelos sin fine-tuning de tool-calling “se quedan en bucles o fallan al formatear JSON”. Hermes Agent pide 64K+ tokens de contexto y modelos cloud. En una iGPU AMD Radeon 680M con 24 GB de RAM compartida y sin VRAM dedicada, esas soluciones no caben, van lentas, o son poco prácticas para uso 24/7.

Quería un asistente personalizado, fluido, que corriese en ese hardware. Y quería aprender a construir agentes de verdad, no consumir un framework.

Por eso, antes de tocar código:

  • Adopté el LLM Wiki Pattern de Karpathy: el conocimiento del proyecto se escribe en un wiki persistente, no en historiales de chat.
  • Creé el playbook de agentes en ese wiki — glosario, fundamentos, gestión de contexto, guardrails, validación, sistemas multi-agente y debate multi-agente — como marco conceptual propio antes de implementar.
  • Definí las reglas de git (rama por feature, atomic commits, validación automática antes de merge, clean code rule) en el fichero de reglas del proyecto (AGENTS.md).
  • Adopté el V-Model NASA como metodología de desarrollo para cada iteración.

El resultado: un asistente de IA local-first con tres interfaces, integración con Home Assistant, búsqueda web, memoria persistente y un sistema de reflexión que analiza su propio rendimiento. Un asistente fluido en hardware modesto es alcanzable — y las páginas siguientes muestran cómo se hizo y qué latencias se consiguen.


La aproximación: wiki primero, código después

La diferencia entre “usar un framework” y “construir un agente” está en el orden: primero las decisiones (wiki), luego la implementación (código).

Capa de conocimientoDónde vivePara qué sirve
Playbook de agenteswiki/concepts/playbook-*Marco conceptual: agent loop, tool calling, context rot, guardrails, eval sets
V-Model NASAwiki/concepts/v-model-nasa-desarrolloMetodología: ConOps → Requirements → HLD → LLD → V&V por cada feature
Git workflowFichero de reglas de cada proyectoReglas operativas: una rama por feature, validación antes de merge, clean code
Diseños del proyectolas páginas de diseño del proyectoProducto de trabajo de cada iteración V-Model

Esta estructura se autorrefuerza: cuando una feature entra en bucle (un test falla dos veces seguidas, una decisión arquitectónica se tambalea), el wiki explica por qué y el V-Model obliga a volver a la fase de Requirements antes de seguir tocando código.

El git workflow se aplica con disciplina: 11 iteraciones mergeadas a main desde el 16 de junio (v0.7 → v1.5.1), cada una en su propia rama con un merge commit dedicado.


Arquitectura: 5 capas con contrato único

Diagrama de las 5 capas y 6 fases del Core

Las 5 capas son el mínimo que aísla I/O, lógica de agente, tools, memoria y LLM en boundaries testeables independientemente. El Core tiene un dispatcher determinista (cascada de 3 niveles: keywords → cross-encoder → embeddings) que resuelve el ~80% del tráfico en <50ms sin llamar al LLM; el ~20% restante atraviesa las 6 fases completas con round loop y tool-calling.

Estado real de cada capa

  • Interfaces — CLI en REPL, Telegram vía raw httpx (30 tests), Voz con adaptador propio que habla Wyoming con Parakeet STT y Piper TTS es_ES-davefx-medium.
  • Tooling — ~16 herramientas organizadas en 5 dominios de intents:
    • Domótica (Home Assistant): encender/apagar dispositivos, ajustar valores (luces, clima, persianas), consultar el estado de cualquier entidad, listar el catálogo de dispositivos, lanzar rutinas del aspirador.
    • Web: búsqueda general y lectura de páginas concretas, con grounding de los resultados para evitar alucinaciones.
    • Sistema: inspección de contenedores Podman y diagnóstico básico de la flota.
    • Información y contexto: meteorología, eventos cercanos, fecha y hora como anclaje temporal, y dos síntesis que combinan múltiples fuentes cuando el usuario hace una pregunta abierta tipo “qué hacer hoy”.
    • Grounding transversal: valida que cada afirmación del agente esté respaldada por un resultado real de una herramienta, en <1ms sin LLM adicional.
  • Memory — Working en memoria, Episodic persistido en JSONL, Semantic con detección de routines y procedures, y un /memory consolidate que batchea patrones. Todo accesible vía subcomandos /memory del CLI.
  • LLM Gatewayllama-router con dos tiers activos en routing: standard (Qwen3.5-2B) y capable (LFM2.5-8B-A1B MoE). El CLI admite --model capable para enrutar a propósito.

Metodología: V-Model NASA + Loop Engineering

V-Model aplicado al desarrollo del agente

El V-Model se ejecuta operativamente como una cadena de loops Generator-Verifier con presupuesto duro (Loop Engineering, Addy Osmani 2026). Cada fase del V tiene su budget: si el Verifier falla dos veces seguidas, se escala al humano. Si el budget se agota, también. El acceptance final lo hace el humano ejecutando el CLI en REPL — el LLM nunca valida acceptance.

En este proyecto el V se materializa como: 11 páginas de diseño que cubren las iteraciones v0.7 a v1.5.1, 800 tests pytest que cubren unit + integration + voice mocks, 30 escenarios de evaluación ejecutables desde el eval runner, y la acceptance matrix que se actualiza con cada merge. El reflection phase (RuntimeAnalyzer, métricas de tool_error_rate y memory_hits_rate) cierra el círculo: detecta cuándo una feature degrada el sistema y propone IMPs al humano.


Inferencia: llama-router en la iGPU

llama-router es el servidor HTTP de llama.cpp compilado con backend Vulkan (la única opción real para acelerar modelos pequeños en GPUs AMD) y extendido con la opción --models-preset. En vez de exponer un único modelo a la vez, lee un archivo models.ini con secciones y mapea cada sección a un GGUF distinto. El agente HTTP recibe un parámetro model= y el router sirve el GGUF correspondiente; el cambio de tier no requiere reiniciar nada.

# models.ini (extracto del perfil activo lfm25-8b-capable)
[standard]
m = /models/Qwen3.5-2B-Q4_K_M.gguf
ctx-size = 16384
n-gpu-layers = 99
temp = 0.3
top-p = 0.8

[capable]
m = /models/LFM2.5-8B-A1B-Q4_K_M.gguf     # MoE 8.3B / 1.5B activos
ctx-size = 16384
n-gpu-layers = 99
temp = 0.3
top-p = 0.9
reasoning-budget = 4096

Tiers activos en el routing real del agente:

TierModeloTamañoRol en el agente
standardQwen3.5-2B (Q4_K_M)2B paramsEjecutor: tool calls, respuestas cortas, ~80% del tráfico
capableLFM2.5-8B-A1B (Q4_K_M, MoE)8.3B / 1.5B activosPlanificador: razonamiento, multi-paso, búsqueda web, vague-query grounding

Las secciones [coding] y [finance] están definidas en models.ini (con Qwen2.5-Coder-3B y Qwen3-4B-Instruct-Alpha respectivamente) pero no se usan en el routing actual: el agente solo enruta entre standard y capable. Coding se reserva para una iteración futura de auto-mejora del propio asistente (UX); finance no es una necesidad del proyecto.

El routing predictivo envía ~80% de las peticiones al tier standard y solo escala a capable cuando la fase de Perception detecta señales de complejidad (multi-step, multi-entity, composite, ambiguo) o cuando la cascada de 3 niveles no resuelve con confianza suficiente.


Latencias obtenidas (medidas en AMD Radeon 680M Vulkan)

Tierp50 (latencia)p95 (latencia)VelocidadUso típico
standard0.5s1.5s~50 tok/s”enciende la luz”, “¿qué temperatura hace?”, tool calls cortos
capable~15s~60s~25 tok/s (MoE)“búscame horarios de cine”, “qué hacer hoy en Madrid”

Datos medidos en AMD Ryzen 5 6600U + Radeon 680M iGPU (Vulkan), 24 GB de RAM compartida, contenedor Podman con --device /dev/dri. Perfil activo: lfm25-8b-capable.

Punto clave: el tier standard — el que se usa en 4 de cada 5 interacciones — responde en medio segundo en el caso típico y en poco más de un segundo en el peor caso (p95). Es la zona donde un asistente se siente “fluido” en conversación, indistinguible de un bot que llama a una API cloud.

Para poner el hardware en perspectiva: LFM2.5-8B-A1B en un DGX Spark (NVIDIA GB10, 128 GB unificada, 273 GB/s) hace ~53 tok/s; en esta iGPU (Radeon 680M, ~100 GB/s de RAM compartida) hace ~25 tok/s. La diferencia es ~2x, explicable por la combinación de mayor ancho de banda de memoria (~2.7x) más la ventaja computacional del DGX. No es 10x, como sugeriría la diferencia de precio.


Conclusión: un asistente fluido en hardware modesto es alcanzable

Con el hardware correcto (Vulkan sobre iGPU AMD, modelos MoE activos pequeños, cuantización Q4_K_M), una arquitectura de 5 capas, una metodología rigurosa (V-Model + Loop Engineering + playbook) y un router de tiers — sí se puede. El sistema corre 24/7 en un servidor casero que consume ~25W en reposo y ~35W bajo carga. La factura de luz del asistente es la de una bombilla.

Las claves que hicieron el proyecto viable:

  1. Wiki primero — el playbook de agentes en el wiki forzó claridad conceptual antes de tocar código.
  2. V-Model por feature — cada iteración tiene su página de diseño (una por cada fase del V-Model: ConOps, Requirements, HLD, LLD, V&V). Sin requisitos no se implementa.
  3. Router de tiers — el 80% de las interacciones usan el modelo small y rápido; el 20% que necesita razonamiento escala a MoE.
  4. Cascada determinista — Perception resuelve la mayoría de intents sin LLM en <50ms. Esto cambia la sensación de fluidez más que cualquier otra cosa.
  5. Grounding sin IA — la validación de respuestas (grounding) usa regex y reglas de dominio, <1ms; ningún LLM adicional compite por la GPU.
  6. Tool registry MCP-style — una tool se registra una vez y queda disponible para CLI, Telegram y Voz.
  7. Reflection que se autocorrige — RuntimeAnalyzer detecta degradación y propone IMPs; memory persistente permite aprender entre sesiones.

Estado actual y roadmap

El proyecto está activo y en producción casera. Lo que funciona hoy:

  • ✅ 3 interfaces operativas: CLI, Telegram, Voz

  • ✅ ~16 herramientas agrupadas en 5 dominios (domótica, web, sistema, información, grounding)

  • ✅ 2 tiers de LLM activos en routing (standard, capable)

  • ✅ Memory persistente (JSONL episodic + JSON semantic con routines/procedures)

  • ✅ Reflection completo (RuntimeLogger, RuntimeAnalyzer, métricas, /health, /sugerencias)

  • ✅ Eval runner con 30 escenarios YAML (--eval)

  • ✅ 800 tests pytest pasando

  • ⏳ Tier coding para auto-mejora del asistente — no implementado todavía, está en el roadmap como objetivo de UX

  • ⏳ Tier finance — no es una necesidad del proyecto, queda en models.ini como definición teórica

El roadmap de iteraciones (v0.7 → v1.5+) está documentado en la página de roadmap del proyecto. Las próximas áreas de trabajo incluyen explorar el tier coding para tareas internas del propio agente (revisar PRs, refactors) y seguir reduciendo latencias en Perception y Context.


Referencias