Llevo semanas probando modelos locales con Ollama. Armé wm-project-llm-routing para enrutar tareas mecánicas (file search, lint, find-replace, doc-gen) a un modelo local y dejar la API de Anthropic para diseño y razonamiento. Para validar qué tolera el modelo local, escribí mi propio smoke-test harness — 8 tareas, criterios falsifiables.
Esta semana lo llevé al límite. Prompt de ~2000 palabras para que qwen3-coder:30b-a3b-q4_K_M construyera un sitio Astro 6 completo, con 11 acceptance checks al final.
Resultado: el modelo escribió Svelte dentro de archivos .astro, ignoró un STOP explícito y se atascó 30 min en un solo turn. Postmortem completo abajo — datos duros, archivos exactos, 4 causas raíz verificadas contra GitHub issues + paper del vendor.
Pregunta real del experimento: ¿puedo confiar en LLMs locales para reemplazar la API de Anthropic en mi workflow diario? Respuesta corta: no todavía. Larga: depende del tipo de tarea.
El modelo local hizo lo difícil bien — armar el scaffold con las versiones reales de los paquetes — y falló en lo sencillo: escribir un componente Astro sin meter sintaxis de Svelte por error.
El setup: no fue por mi hardware
Specs primero. Si tu primera reacción al leer “falló el modelo local” es “te quedaste corto de Mac”, no:
MacBook Pro Mac16,5 con M4 Max. Top consumer-grade de Apple. 64 GB de memoria unificada → la GPU direcciona pesos enormes sin penalty PCIe. qwen3-coder:30b ocupa 45 GB en VRAM durante inferencia. Quedan 19 GB para el resto del sistema. Estrecho pero funciona.
ollama ps mostró PROCESSOR: 100% GPU toda la sesión. Sin swap. Sin throttling térmico. Nada del lado del hardware que excusara lo que vino después.
El bottleneck fue el modelo. No el Mac.
Por qué probar local
Tres razones:
- Privacidad. Trabajo con código de clientes. Las policies “no entrenamos con tus prompts” son creíbles pero no criptográficas. Local sí: si nada sale del Mac, nada salió.
- Costo. Para tareas mecánicas (file search, lint, find-replace, doc-gen) pagar Opus rates es derrochar.
wm-project-llm-routingenruta esas a Ollama local; la API queda para diseño, legal y razonamiento complejo. - Curiosidad. Quiero saber qué tan en serio se puede tomar a los modelos abiertos en 2026.
Nota relevante al punto 1: Ollama ya no es 100% local por default. Track cloud nuevo desde primavera 2026 — modelos con sufijo :cloud corren en infraestructura de Ollama, no en tu Mac. Detalle abajo, en la sección dedicada.
El smoke test que pasó (88%) — el spoiler engañoso
Antes del benchmark validé el modelo con wm-llm-smoke-test — suite propia, 5 categorías × ~2 tareas, prompts aislados sin tool-use, evaluación contra keywords.
Resultado: 7/8 (88%). El único fail: alucinación de path — respondió src/task_classifier.py cuando la respuesta correcta era lib/classification.py. Fail honesto y conocido: LLMs alucinan paths sin tool-use. Para refactors, doc-gen y formateo: bien.
El benchmark: construir rockshop.com.mx desde cero
rockshop.com.mx es un dominio mío con SEO equity histórica para queries comerciales en CDMX. Hoy es un placeholder. Le di al modelo un prompt detallado (~2000 palabras) con:
- Stack pinneado: Astro 6.x, Tailwind 4.x vía
@tailwindcss/vite, TypeScript strict, Node 22 LTS - Estructura Atomic Design obligatoria (
atoms/,molecules/,organisms/) - Design tokens en CSS custom properties, prohibido hardcodear colores
- 3 páginas: inicio, catálogo placeholder, contacto
- Reglas duras: nada de licencias open-source, nada de imágenes de stock, nada de claims inventables sobre el negocio, copy en español mexicano sin voseo
- Acceptance test al final con 11 checks falsifiables (
grepesto, verifica aquello, build debe pasar)
Reglas del prompt: nada de simplificar sin avisar, nada de scope degradation, nada de simulación. El modelo debe construir el sitio completo y auto-ejecutar el acceptance test al final, reportando PASS/FAIL honesto por check.
Lancé el experimento + monitoreo en paralelo:
ollama pscada par de min → confirmar uso de GPUfindsobre el output dir → contar archivos creados- Inspección de proceso → detectar si Claude Code estaba esperando approval de tool-calls o trabajando
No “ver qué pasa”. Medir comportamiento.
Lo que construyó en 22 archivos: empezó bien
Quince minutos en, el conteo de archivos llegó a 22 con estructura limpia:
Astro 6.3.7, Tailwind 4.3.0, @astrojs/netlify 7.0.10, @astrojs/sitemap 3.7.2. Versiones reales, no inventadas. Verificó cada paquete con npm view antes de instalar.
src/components/{atoms,molecules,organisms}/ separados. Sin componentes en raíz duplicados. Folders correctos.
defineConfig con netlify adapter + sitemap integration. Faltaba enchufar Tailwind 4 via vite plugin pero el scaffold era razonable.
Texto literal "Proprietary. All Rights Reserved · Arnold Wender · 2026", como pidió el prompt. Sin reflejos de MIT o GPL.
En este punto el experimento prometía. La parte mecánica del scaffold — la parte donde un modelo coding-specialised debería brillar — la hizo bien.
Después se rompió.
El momento exacto del fracaso
Detecté el degrade leyendo su output en tiempo real. Le pregunté qué estaba haciendo. Su respuesta verbatim:
Estoy teniendo problemas con la sintaxis de los componentes Astro.
Vamos a simplificar todo el enfoque y crear un proyecto básico sin
usar componentes complejos. Primero, voy a eliminar todos los
componentes moleculares y atómicos y crear una estructura mínima. Esa frase rompe tres reglas explícitas del prompt: “no simplifiques sin avisar”, “atomic design obligatorio”, “no degrades scope unilateralmente”. El modelo decidió por su cuenta que la solución a un error de sintaxis era eliminar la arquitectura entera.
Pasé a revisar archivo por archivo. Abrí atoms/Heading.astro, atoms/Button.astro y atoms/Text.astro con el editor y el problema se hizo evidente:
---
props: {
level: 1,
text: String,
className: String,
}
---
{#if props.level === 1}
<h1 class={props.className}>{props.text}</h1>
{:else if props.level === 2}
<h2 class={props.className}>{props.text}</h2>
{:else if props.level === 3}
<h3 class={props.className}>{props.text}</h3>
{/if} ---
interface Props {
level?: 1 | 2 | 3 | 4 | 5 | 6;
text: string;
class?: string;
}
const { level = 1, text, class: className } = Astro.props;
const Tag = `h${level}`;
---
<Tag class={className}>{text}</Tag> Lo que escribió no es Astro. Es Svelte: el bloque {#if condition}...{:else if}...{/if} es sintaxis pura de Svelte, y la declaración props: {...} en el frontmatter es algo entre Vue 3 Options API y Svelte, pero ciertamente no Astro. Astro usa interface Props {} en TypeScript y renderiza con JSX-like, sin bloques {#if}.
El modelo confundió un framework con otro. No sabía la sintaxis de Astro, así que rellenó con lo que sí conocía. Todos los archivos eran lexicalmente inválidos para el parser de Astro — ningún npm run build iba a pasar con ese código.
Le pegué un mensaje explícito: “STOP. No borres atoms/, no reescribas nada, pégame el error verbatim primero”. El modelo aceptó cordialmente y reescribió tres archivos más con la misma sintaxis rota antes de pegarme el error. Ignoró el STOP. Y siguió.
Después de ~30 minutos en un solo turno donde el indicador decía “Deciphering… 29m 36s”, el modelo seguía atascado. Lo maté con Ctrl+C y terminé la evaluación.
El diagnóstico: cuatro causas raíz
Esto no fue un fail de un solo factor. Para cada hipótesis abrí búsquedas paralelas contra issues de GitHub, papers oficiales del vendor del modelo y reportes de la comunidad. Lo que encontré:
- Cross-framework hallucination
Astro 6 stable salió a fines de 2025 / principios de 2026. qwen3-coder fue entrenado con cutoff alrededor de julio 2025. Astro no estaba bien representado en sus datos de entrenamiento. El modelo rellenó con sintaxis del framework más cercano que sí conocía — Svelte, que también usa archivos SFC tipo .svelte con frontmatter y bloques de control de flujo. Es exactamente el tipo de error que un dev junior confundido haría.
- Ollama stable tiene bugs conocidos con Claude Code
Issue #15390 en ollama/ollama documenta "Invalid tool parameters" y CPU spikes de 100% con streaming tool calls. El fix requiere Ollama pre-release 0.14.3-rc1 o más nuevo. Yo estaba en stable. El agentic loop de Claude Code se atora silenciosamente cuando llega un tool-call con JSON mal formado.
- Default num_ctx es 4096, no 262144
Aunque ollama ps muestra context length 262144 (el MAX del modelo), las llamadas reales se limitan a 4096 tokens a menos que se sobrescriba en un Modelfile. Para un sitio entero con múltiples archivos en contexto, 4K se queda corto a los pocos turnos. El modelo empieza a perder memoria de las reglas del prompt original.
- qwen3-coder confabulates en conversación larga
Issue #17031 en NousResearch/hermes-agent documenta que el modelo fabrica historial de conversación previa cuando se ejecuta en harness agentic. No es exclusivo de Claude Code — es comportamiento conocido del modelo bajo loops largos.
Hay fixes documentados para tres de las cuatro causas: actualizar Ollama, sobrescribir num_ctx, cambiar a un modelo distinto como GLM-4.7-Flash que Zhipu AI ha pulido específicamente para agentic patterns. La primera causa — cross-framework hallucination de Astro — solo se resuelve esperando a que entrenen un modelo con datos más nuevos. O usando una API que sí los tiene (Claude, GPT, Gemini).
No estoy solo en esto: casos parecidos documentados
Después del fail, busqué fuentes externas para verificar si lo que viví era anecdótico o sistemático. Es sistemático. Cinco hallazgos relevantes:
"Agent mode not work when using Qwen3 model" — usuarios del IDE Continue reportan exactamente el mismo problema del modelo en harness agentic, fuera de Claude Code. No es bug de Claude Code: es del modelo bajo presión agentic.
Qwen3-Coder-Next Technical Report (arxiv 2603.00729): "Qwen3-Coder-Next NVFP4 was not stable enough for production usage and periodically crashed." Fuente oficial del vendor.
Discusiones de agentic engineering en dev.to y dotnetting documentan "context rot": degradación de performance del modelo cuando la sesión se alarga, el window se llena con errors traces y la calidad de decisiones cae. Patrón formalizado, no anécdota.
eval.16x.engineer publicó benchmark formal: Qwen3 Coder scoró 1/10 en TypeScript narrowing, "haciendo errores conceptuales que impedían que el código pasara el compilador". Claude Opus 4.6 produce código más consistente en loops largos — corroboración exacta de mi conclusión.
Test similar al mío con framework moderno: "required some iteration and patience". Fuera del comfort zone (CRUD/React), el modelo lucha sistemáticamente.
Comunidad agentic-engineering documenta el patrón explícito de modelos borrando tests, components o features para satisfacer falsamente el build. Es exactamente lo que mi qwen3 propuso ("voy a eliminar todos los componentes moleculares"). Bug-clase, no bug-único.
Si te asusta que sea solo “tu modelo en tu Mac” funcionando mal, no — es comportamiento sistemático del estado actual de los modelos abiertos en harness agentic largos. El fix más limpio sigue siendo no usarlos para eso aún.
Nota de contexto: Ollama ya no es 100 % local por default (mayo 2026)
Aprovecho el postmortem para registrar algo importante del estado actual del ecosistema, porque si llegaste a este artículo buscando “LLM local” puede que no estés al tanto: desde la primavera de 2026, Ollama tiene dos tracks distintos, y el menú del nuevo comando ollama launch claude los mezcla en la misma lista:
| Track | Sufijo | Privacidad | Latencia "hello" | Costo |
|---|---|---|---|---|
| Local | sin sufijo | 100% local (verificable) | 13–150 s | gratis (electricidad) |
| Cloud Ollama | :cloud | Policy "no logging" (no criptográfica) | <3 s | Free tier + $20/mes Pro |
| Anthropic API | n/a | Policy "no entrenamos" | <3 s | pay-per-token |
La feature ollama launch claude se rolleó en primavera 2026. Wirea Claude Code a Ollama sin tocar env vars. Pero ojo: en el header del UI de Claude Code aparece “API Usage Billing” para cualquier backend de Ollama, incluyendo el local. Ese label engañoso me hizo dudar durante un rato si mi modelo realmente estaba corriendo en mi Mac. Lo confirmé con ollama ps (PROCESSOR: 100% GPU durante toda la sesión). El label es genérico; no significa que estés pagando a Anthropic.
Si tu prioridad es privacidad verificable, elige solo modelos sin sufijo :cloud. Si tu prioridad es velocidad y aceptas la policy de “no logging” de Ollama, el cloud track tiene SOTA models (kimi-k2.6, glm-5.1) a precios razonables. No son opciones equivalentes — son trade-offs distintos.
Veredicto: cuándo SÍ vale qwen3-coder local
Resumiendo el aprendizaje en tabla:
| Tarea | qwen3-coder local M4 Max | Veredicto |
|---|---|---|
| Responder "hello" | 13–150 s | Lento pero acepta |
| Refactorizar una función aislada | OK | Sí |
| Doc-gen sobre código pegado en el prompt | OK | Sí |
| Smoke test de 8 tareas aisladas | 88% pass | Sí |
| Buscar archivos sin tool-use | Alucina paths | No |
| Construir un sitio Astro 6 sin supervisión | Cross-framework hallucination + degrada scope | No (mayo 2026) |
| Mantener coherencia en loop agéntic de 30+ turnos | Pierde contexto, ignora instrucciones | No (mayo 2026) |
Funciona como pair-programmer aislado. Dale una función, devuélvela refactorizada. Dale un párrafo, devuélvelo documentado. Para eso 88% pass rate es genuino y suficiente.
NO funciona como agente autónomo many-turn. Al menos no en mi setup de mayo 2026. Si tu workflow real necesita builds o refactors de proyectos enteros sin supervisión, sigues necesitando la API. O achicas el scope drásticamente — un archivo a la vez, con verificación humana entre cada uno.
Conclusión: el M4 Max no es el bottleneck
64 GB de RAM unificada, 40 GPU cores, memoria de sobra para correr modelos enormes — y el experimento falló igual. No por el hardware. Por capacidad del modelo y madurez del harness.
Para el hardware que tengo, qwen3-coder local sirve para tareas micro. No reemplaza a Claude Opus en builds reales. Y eso está bien — son herramientas distintas para problemas distintos.
Si inviertes en un Mac con RAM suficiente para LLMs locales, hazlo sabiendo que el ceiling lo pone el ecosistema de modelos abiertos + el tooling. NO el hardware. El M4 Max te da margen para los próximos 2–3 años. Lo que falta es que los modelos abiertos alcancen a los propietarios en capacidad agentic. Hoy no están ahí. En 2027, probablemente.
Sources verificadas durante este postmortem:
github.com/ollama/ollama/issues/15390— Invalid tool parameters + CPU fallback con Claude Codegithub.com/NousResearch/hermes-agent/issues/17031— Qwen3.6 confabulating session historydocs.ollama.com/integrations/claude-code— integración oficialollama.com/library/qwen3-coder— model cardollama.com/blog/launch—ollama launchrollout primavera 2026ollama.com/cloud— pricing + policy del track cloudgithub.com/continuedev/continue/issues/5419— Agent mode no funciona con Qwen3 (caso análogo en otro IDE)arxiv.org/abs/2603.00729— Qwen3-Coder-Next Technical Report (admisión oficial de inestabilidad en producción)eval.16x.engineer/blog/qwen3-coder-evaluation-results— benchmark formal: Qwen3 Coder 1/10 en TypeScript narrowingblog.logrocket.com/qwen-3-coder-agentic-cli/— LogRocket Svelte 5 + Firebase test con Qwen3-Coder