La capa de gestión decide si el modelo sirve: Hermes Agent frente a deepagents
TL;DR
Intentamos usar deepagents (LangChain) para orquestar varios agentes con varias herramientas sobre modelos locales pequeños, y lo dejamos sin lograr un run completo — el detalle de los fallos está en límites de los modelos locales para coordinar subagentes. La pregunta que disparó esta comparación: si Hermes Agent consigue decisiones razonables con modelos igual de pequeños, ¿qué nos estábamos perdiendo?
Con el modelo fijo —pequeño, con tool-calling nativo débil— lo que determina el resultado no
es el prompt, es la capa de gestión que envuelve al modelo. deepagents es un harness
deliberadamente fino: asume que el modelo sigue instrucciones y emite tool_calls limpios.
Cuando el modelo no hace ninguna de las dos cosas, no hay red debajo. La conclusión no es
"deepagents es un mal framework", sino que el harness decide si la debilidad de un modelo
se traduce en fallo visible, en fallo silencioso, o en nada.
La idea que nos llevamos al próximo intento
Antes de cambiar de modelo, mirar qué del harness está sin montar: tool-calling forzado por la interfaz, estado escrito y verificado por código, presupuesto de iteraciones con timeout, y compresión de contexto automática. Son cuatro cosas que no dependen del tamaño del modelo, y en nuestras pruebas ninguna estaba puesta.
Qué tipo de evidencia es esta
Los fallos que describimos son nuestros y están medidos. Los mecanismos de Hermes salen de su documentación, no de haberlo ejecutado: no montamos Hermes ni corrimos un A/B contra deepagents. Esto es un argumento arquitectónico con una parte empírica y otra documental, no una comparativa medida. Tratarlo como hipótesis de trabajo bien fundada, no como veredicto.
Harness
La capa de gestión que envuelve al modelo en un agente: quién arma el prompt, quién formatea las llamadas a herramientas, quién guarda el estado, quién corta un bucle, quién decide qué parte del historial se envía. No es el modelo ni el prompt: es todo lo demás.
Los fallos que hay que explicar
Cuatro síntomas de nuestras pruebas, resumidos, porque son el punto de partida de la comparación:
| Síntoma | Modelo | Qué pasó |
|---|---|---|
No emite tool_calls |
gemma4:12b |
Responde con un saludo genérico; en prueba aislada con una tool sí llamaba |
| Malinterpreta la firma | qwen3:8b |
Asume que markdown_to_html lee un fichero y pide "el path del .md" |
| Fabrica y declara éxito | qwen3:8b |
Se salta las herramientas, escribe a mano un HTML vacío y anuncia "successfully generated 🎉" |
| Coste sin corte | qwen3.5:9b-mlx |
43 min de swap y 14 min de bucle de repetición, sin que nada los abortara |
El tercero es el peligroso: es un fallo que se presenta como éxito. Es el mismo patrón que ya nos apareció en retrieval —una etapa que devuelve algo plausible pero peor es más peligrosa que una que falla— documentado en búsqueda híbrida y en quién redacta la respuesta.
Los mecanismos del harness, uno por fallo
Lo que hace interesante a Hermes no es una idea genial, son seis mecanismos aburridos que atacan justo estos síntomas. Aquí van solo los que tocan nuestros fallos; la ficha completa del producto —modelo conceptual, backends de ejecución, gobernanza— está en Hermes Agent: qué es, cómo funciona por dentro y dónde encaja.
| Mecanismo de Hermes | Qué fallo nuestro ataca |
|---|---|
| API modes explícitos que estructuran el tool-call en el formato nativo del proveedor | Gemma sin tool_calls; qwen3:8b malinterpretando la firma |
| Refuerzo en prompt: "You MUST use your tools to take action — do not describe what you would do" | El modelo comportándose como un chat |
tool_search y toolsets acotables, para no exponer decenas de tools de golpe |
"Con system prompt largo y varias tools se comporta como un chat" |
Tools de estado (todo, memory, delegate_task) interceptadas antes del dispatcher: escribe y verifica el harness |
El HTML fabricado con "éxito" declarado |
IterationBudget (con tope independiente por subagente) y llamadas en hilo aparte, interrumpibles y con timeout |
Los 43 y los 14 minutos |
| Compresión de contexto automática al pasar del 50 % / 85 % de uso | La KV cache saturando la RAM por un contexto sin capar |
Vale la pena separar los dos que son cualitativamente distintos.
El tool-calling no se le pide al modelo, se le impone por la interfaz
Hermes resuelve tres API modes (chat_completions, anthropic_messages,
codex_responses) que estructuran la llamada en el formato nativo del proveedor, en vez de
depender de que el modelo genere JSON válido dentro de su texto libre.
Esto reencuadra nuestros dos primeros fallos. Ni Gemma ni qwen3:8b estaban fallando en
razonar qué hacer: fallaban en producir la estructura de salida esperada. Y esa
estructura, en el planteamiento por defecto, depende enteramente de que el modelo la
acierte sin ayuda. Es el mismo hallazgo que en local:
el tool-calling es una propiedad del serving,
solo que una capa más arriba.
El estado lo escribe el código, no la palabra del modelo
En Hermes, las tools de estado están interceptadas antes de llegar al dispatcher normal: es el harness quien escribe y verifica, no el modelo reportando lo que cree haber hecho.
Esa es la respuesta estructural al peor fallo que vimos. Y tiene un matiz que nos importa
para decidir arquitecturas: nosotros ya habíamos intentado arreglarlo por descomposición
—mover el paso frágil a un subagente publisher con un rol acotado y un toolset mínimo— y
no bastó: el modelo alucinó el resultado igualmente. Descomponer ayuda, pero un rol
acotado sigue siendo un modelo, y un modelo puede mentir sobre lo que hizo. El código
determinista no puede. Para los pasos que tienen que salir bien, el determinismo compra
una fiabilidad que ninguna cantidad de prompt compra.
Es la misma regla que ya aplicamos en RAG: si el agente sintetiza, las herramientas devuelven datos y no prosa. Un solo punto de responsabilidad, y que sea el que puedes verificar.
No es LangChain lo que falta: es deepagents sin el context engineering activado
Un matiz importante, para no sacar la conclusión equivocada. LangChain/LangGraph no
carece de mecanismos para curar el contexto: de hecho LangChain acuñó el término context
engineering y ofrece primitivos concretos — trim_messages para quedarse con los últimos
N mensajes, LangMem para resumen persistente y memoria semántica, y en LangGraph, al ser
orquestación de bajo nivel con estado explícito por nodo, el desarrollador decide
exactamente qué parte de ese estado ve el agente en cada paso.
El hueco está en deepagents como producto empaquetado: es un harness "batteries included" pero deliberadamente fino (planificación, filesystem virtual, subagentes) que no activa por defecto ninguno de esos primitivos. Los ladrillos existen en el ecosistema; el harness que se construyó encima no los usa solo. Hay que montarlos tú.
El hueco más profundo: no hay memoria tipada
Profundizando en el material de un curso de agent memory apareció una crítica más precisa que "falta context engineering". El valor no está en "recordar", sino en tratar la memoria como varios sistemas distintos, cada uno con su lógica de almacenamiento y recuperación — una distinción establecida en la literatura de arquitecturas de agentes (p. ej. el paper CoALA):
- Semántica — hechos y entidades: quién es quién, qué prefiere el usuario, relaciones entre conceptos.
- Episódica — eventos concretos de sesiones anteriores, con su contexto temporal.
- Procedimental — procedimientos y habilidades aprendidas y reutilizables.
- De trabajo — lo que está vivo ahora en la ventana de contexto de la llamada actual.
deepagents, tal cual viene, no distingue ninguna de las cuatro. Tiene un filesystem virtual y un historial de mensajes, que funcionan como memoria de trabajo y poco más: todo se mezcla en el mismo saco de estado, sin marcar qué es un hecho persistente, qué es un evento pasado y qué es un procedimiento ya validado. Parte de la confusión del modelo en nuestras pruebas viene de ahí — no hay estructura que le diga qué es relevante en cada paso.
Hermes separa parcialmente estos tipos: MEMORY.md/USER.md como snapshot semántico,
session_search (FTS5) como memoria episódica con recall cruzado entre sesiones, y su
sistema de skills como memoria procedimental explícita. Lo que no tiene documentado es
una capa de entidades tipo grafo. El detalle de cómo son esas skills y cómo se cargan por
niveles está en
el modelo conceptual de Hermes.
Aquí es donde esto toca RAG y no solo agentes
La memoria semántica y la episódica son retrieval: recuperación sobre hechos y sobre historial de sesiones, con sus mismos problemas de ranking, ruido y evaluación. Nada de lo que tenemos en RAG y retrieval cubre ese caso: ahí todo el retrieval es sobre corpus documental. Es un hueco identificado, no resuelto.
Una alternativa estructural: agentes que escriben código
Más allá de cambiar de framework, hay una opción que cambia el mecanismo en sí: en vez de
pedir JSON estructurado, usar agentes que razonan escribiendo código — el enfoque
CodeAgent de smolagents, o el
tool-calling programático de Hermes vía
execute_code, que encadena varias operaciones en una sola inferencia.
La intuición encaja con nuestros fallos: a un modelo pequeño le cuesta menos escribir una
llamada a función en código que producir un blob JSON ajustado a un schema exacto. Gemma no
emitía tool_calls; qwen3:8b malinterpretaba una firma. Ninguno de los dos es un fallo de
razonamiento, son fallos de formato — y el código es un formato que estos modelos han visto
mucho más que nuestros schemas.
Sin probar, así que queda como candidato para el próximo intento, no como recomendación.
Qué nos llevamos
- Con el modelo fijo, el harness decide el resultado. Un harness maduro puede hacer que un modelo débil parezca fiable; un harness ingenuo, con todo mezclado en un único saco de estado, produce exactamente los fallos que documentamos. La capa de gestión no es un detalle de implementación.
- El prompt es la pieza más barata, no la más importante. Una línea de refuerzo de acción ayuda y cuesta nada, pero no sustituye a que el estado lo escriba el código.
- Descomponer en subagentes ayuda pero no garantiza. Un rol acotado con prompt claro es más fiable; sigue siendo un modelo, y puede alucinar el resultado. Solo el código determinista es inmune a mentir sobre lo que hizo.
- Los fallos "de formato" no son fallos de capacidad. No emitir
tool_callso malinterpretar una firma son problemas de estructura de salida, y se atacan en la interfaz: formato nativo del proveedor, menos herramientas visibles, o cambiar a tool-calling por código. - Presupuestos y timeouts no mejoran nada, pero evitan perder tardes. Nuestros dos
bloqueos costaron 57 minutos entre ambos. Un
IterationBudgetno habría evitado el bucle: habría evitado que el bucle no se notara. - "Batteries included" no significa "todo activado". deepagents no monta los primitivos de curación de contexto que LangChain sí tiene. Antes de culpar al framework base, comprueba qué está apagado por defecto.
- Falta una arquitectura de memoria tipada, y es un hueco distinto del tool-calling. Son dos carencias ortogonales del mismo harness fino, y conviene no mezclarlas al diagnosticar.
Anexo: qué preguntarle a un harness antes de elegirlo (la receta)
Checklist para evaluar un framework de agentes, salida directa de esta comparación:
- ¿Quién formatea el tool-call? ¿El harness lo estructura en el formato nativo del proveedor, o confía en que el modelo genere JSON válido en texto libre?
- ¿Quién escribe el estado? ¿El código intercepta y verifica, o el estado es lo que el modelo dice que hizo? Pregunta de control: ¿puede el agente declarar éxito sin que haya artefacto?
- ¿Hay tope de iteraciones y timeout, y son por subagente? Si no, un bucle cuesta lo que tardes en darte cuenta tú.
- ¿Se comprime el contexto automáticamente, o hay que adivinar el
num_ctxcorrecto? - ¿Se puede acotar el toolset por rol? Exponer todas las herramientas a un modelo pequeño degrada su elección.
- ¿Distingue tipos de memoria, o todo va al mismo saco? Semántica, episódica, procedimental, de trabajo.
- ¿Fuerza un historial bien formado? Alternancia estricta de roles; historiales mal formados confunden a los modelos pequeños.
Referencias
Hermes Agent (Nous Research)
- Documentación general
- Architecture Overview
- Agent Loop Internals
- Prompt Assembly
- Tools & Toolsets
- Repositorio en GitHub
deepagents / LangChain / LangGraph
- deepagents — repositorio en GitHub
- Deep Agents: LangChain's SDK for Agents That Plan and Delegate (Talk Python)
- Context engineering in agents — Docs by LangChain
- Context Engineering — LangChain blog
Agentes de código (alternativa al tool-calling JSON)
- smolagents — repositorio en GitHub (Hugging Face)
- Building Agents That Use Code — Hugging Face Agents Course
Arquitectura de memoria