Qué es un agent harness (y cuándo no usarlo): deepagents frente a LangGraph
Qué es un agent harness, qué añade deepagents sobre create_agent y LangGraph, sus cuatro capas (entorno, contexto, delegación, steering) y la tabla para saber cuándo bajar a LangGraph.
Un agent harness es todo lo que rodea al modelo para convertirlo en un agente: el loop que lo llama una y otra vez, las herramientas que ejecuta, el espacio donde trabaja, la gestión de su contexto y los controles que le ponen límites. El modelo aporta el juicio; el harness aporta todo lo demás. Esta serie construye un auditor de sitios web con deepagents, el harness de código abierto de LangChain, una capa por post. Este primero fija el vocabulario: qué es un harness, en qué se diferencian LangGraph, create_agent y deepagents, cuáles son las cuatro capas que deepagents añade y, si ya estás decidiendo, cuándo un harness sobra y conviene bajar a LangGraph.
Resumen para perezosos
- Agente = modelo + harness. El harness es todo el código que no es el modelo: loop, tools, filesystem, sandbox, resumen de contexto, subagentes y aprobaciones. deepagents es un harness ya montado; LangGraph es el runtime sobre el que corre.
- Son tres niveles de la misma pila: LangGraph (tú dibujas el grafo),
create_agent(un loop de tools con middleware) y deepagents (ese loop más cuatro capas: entorno de ejecución, gestión de contexto, delegación y steering). - Usa el harness cuando la tarea es abierta y el modelo tiene que decidir el siguiente paso. Baja a LangGraph cuando el orden de los pasos lo decides tú, necesitas estado tipado o cada transición tiene que ser explícita.
En este artículo:
- Fundamentos — Qué es un agent harness · Tres niveles de la misma pila
- La anatomía — Las cuatro capas de deepagents · deepagents nació imitando a Claude Code
- El proyecto — El auditor que construimos en la serie · Cuándo no usar un harness
Qué es un agent harness
Por sí solo, un modelo de lenguaje recibe una entrada y genera una salida. Ejecutar comandos, acceder a archivos, mantener estado entre pasos o decidir cuándo una tarea está terminada requiere infraestructura alrededor del modelo, y a esa infraestructura se le llama harness. LangChain lo define así: “a harness is every piece of code, configuration, and execution logic that isn’t the model itself”, y lo resume en una ecuación que conviene memorizar: agente = modelo + harness.
La pieza más pequeña del harness es el agent loop: el while que llama al modelo, ejecuta la acción que eligió y le devuelve el resultado. El harness es ese loop más lo que se le fue añadiendo para que aguante tareas largas: un lugar donde leer y escribir archivos, una forma de ejecutar código sin poner en riesgo el proceso principal, un mecanismo para que el contexto no se desborde, una manera de repartir trabajo entre varios agentes y controles para que un humano pueda intervenir.
┌──────────────── harness ────────────────┐
│ │
objetivo ──────────► │ loop ─► tools ─► filesystem ─► sandbox │
│ │ │
│ ▼ │
│ modelo (elige la siguiente acción) │
│ │ │
│ contexto ─► subagentes ─► aprobaciones │
│ │
└────────────────────┬────────────────────┘
▼
resultado
La calidad del agente depende del modelo, pero en producción muchos de los problemas más difíciles —contexto que se llena, una tool que escribe donde no debía, un subagente que no devuelve lo que se le pidió— no vienen del modelo sino del harness. Por eso conviene tratarlo como una pieza de ingeniería propia y no como “configuración del modelo”.
LangGraph, create_agent y deepagents: tres niveles de la misma pila
LangChain ofrece tres formas de construir un agente, y las tres están apiladas: cada una está implementada sobre la anterior. Elegir el nivel es la primera decisión de diseño.
┌───────────────────────────────────────────────────────────────┐
│ deepagents harness opinado: filesystem, subagentes, │
│ create_deep_agent summarization, permisos, HITL, skills │
├───────────────────────────────────────────────────────────────┤
│ create_agent loop de tools + middleware │
│ (before_model, after_model, wrap_tool_call)│
├───────────────────────────────────────────────────────────────┤
│ LangGraph runtime: grafo de estado, checkpoints, │
│ StateGraph streaming, interrupts │
└───────────────────────────────────────────────────────────────┘
LangGraph es el nivel más bajo. Tú defines un grafo de estado: nodos que son funciones, aristas que dicen a qué nodo se pasa después y un estado tipado que fluye entre ellos. LangGraph aporta el runtime: ejecución durable con checkpoints, streaming de eventos e interrupciones para que un humano intervenga. No opina sobre cómo debe ser un agente; puedes dibujar un loop, un pipeline lineal o una máquina de estados con veinte ramas.
create_agent es el nivel intermedio: el loop de un agente ya escrito sobre LangGraph. Le das un modelo, una lista de tools y un system prompt, y obtienes un grafo compilado que llama al modelo, ejecuta las tools que pide y repite hasta que el modelo responde sin pedir más. Lo extensible es el middleware: funciones que se enganchan antes de llamar al modelo, después de la respuesta o alrededor de cada tool. Reintentos, límites, aprobaciones o resúmenes de contexto se implementan ahí sin tocar el loop.
from langchain.agents import create_agent
agent = create_agent(
model="anthropic:claude-sonnet-4-6",
tools=[fetch_page],
system_prompt="Eres un auditor técnico de sitios web.",
)
deepagents es el nivel más alto: create_agent con un stack de middleware ya decidido y un system prompt largo que enseña al modelo a usarlo. La llamada mínima se parece mucho a la anterior; la diferencia está en lo que el agente trae de fábrica: tools de filesystem, una tool task para delegar en subagentes, resumen automático del contexto y cacheo de prompt para los proveedores que lo soportan.
from deepagents import create_deep_agent
agent = create_deep_agent(
model="anthropic:claude-sonnet-4-6",
tools=[fetch_page],
system_prompt="Eres un auditor técnico de sitios web.",
)
result = agent.invoke({"messages": [{"role": "user", "content": "Audita https://example.com"}]})
print(result["messages"][-1].content)
Los tres niveles devuelven el mismo tipo de objeto, un grafo compilado de LangGraph, así que un deep agent se invoca, se le hace streaming y se incrusta como nodo de un grafo mayor igual que cualquier otro.
| Nivel | Qué escribes tú | Qué te da | Cuándo encaja |
|---|---|---|---|
| LangGraph | Los nodos, las aristas y el estado | Runtime durable, checkpoints, streaming, interrupts | El orden de los pasos lo decides tú |
create_agent | Modelo, tools, system prompt, middleware | El loop de tools ya resuelto y extensible | Tarea abierta, contexto que cabe en una conversación |
| deepagents | Modelo, tools, system prompt | El loop más filesystem, subagentes, resumen, permisos, HITL, skills | Tarea larga y abierta, con archivos y muchos pasos |
Las cuatro capas que deepagents añade sobre el loop
La documentación de deepagents agrupa lo que añade sobre create_agent en tres áreas: gestión de contexto, delegación y steering. Yo separo una cuarta, el entorno de ejecución, porque concentra más decisiones de diseño que las otras tres y ocupa más posts de la serie.
1. Entorno de ejecución. Es donde el agente trabaja. deepagents le da un filesystem virtual con las tools ls, read_file, write_file, edit_file, glob y grep, servido por un backend que tú eliges: en memoria dentro del estado del grafo (el default), el disco local, el store persistente de LangGraph o una composición de varios por ruta. Si el backend es un sandbox, aparece además una tool execute para correr comandos aislados.
2. Gestión de contexto. Un agente que lee páginas web enteras llena el contexto en pocos turnos. deepagents incluye un middleware de resumen que compacta la conversación cuando supera un umbral y otro que marca los bloques estables del prompt para que el proveedor los cachee. Combinado con el filesystem, el patrón es siempre el mismo: lo voluminoso se escribe en un archivo, en el contexto queda una referencia y el agente relee solo lo que necesita.
3. Delegación. La tool task permite al agente principal lanzar un subagente con contexto limpio, darle una instrucción y recibir solo el resultado. El subagente puede leer cincuenta archivos sin que el principal los vea, y el trabajo independiente se puede paralelizar. Se pueden definir subagentes propios con su modelo, sus tools y su prompt.
4. Steering. Todo lo que dirige y limita al agente desde fuera: el system prompt, las aprobaciones humanas antes de ejecutar ciertas tools (interrupt_on), los permisos por ruta sobre el filesystem, las skills que se cargan bajo demanda y la memoria persistente en archivos AGENTS.md. Es la capa que permite darle más autonomía al agente sin renunciar al control.
| Capa | Mecanismo en deepagents | Lo que el modelo ve | Post de la serie |
|---|---|---|---|
| Entorno de ejecución | FilesystemMiddleware, backends, sandbox | ls, read_file, write_file, edit_file, glob, grep, execute | 3, 5, 6, 7 |
| Gestión de contexto | SummarizationMiddleware, prompt caching, offload a archivos | Nada nuevo: el contexto simplemente no se desborda | 8 |
| Delegación | SubAgentMiddleware, subagentes propios | task | 10 |
| Steering | system prompt, interrupt_on, permissions, skills, memory | Instrucciones, pausas de aprobación, rechazos de escritura | 4, 6, 9 |
Nada de la tabla es imposible de escribir a mano como middleware sobre create_agent o como nodos de LangGraph. Lo que deepagents aporta es que ya está hecho, que las piezas se conocen entre sí y que el system prompt por defecto le explica al modelo cómo usarlas.
deepagents nació imitando a Claude Code
El README de deepagents lo dice en la primera pantalla: el proyecto está “inspired by Claude Code: an attempt to identify what makes it general-purpose, and push that further”. Las primeras versiones identificaron cuatro cosas: una tool de planificación (la lista de todos), subagentes, un filesystem y un system prompt detallado que enseña a usar las otras tres. Las cuatro capas del apartado anterior son la versión madura de aquella lista.
Cuando paso un día entero trabajando con Claude Code, casi todo lo que hace pasa por un puñado de herramientas: leer, escribir, editar, buscar, ejecutar y delegar. El modelo cambia de versión cada pocos meses; esas herramientas se mantienen. Eso es lo que deepagents intenta capturar: el harness es la parte estable, el modelo es la pieza intercambiable.
Ese origen dice para qué forma de problema está pensado el harness: investigación larga, generación de documentos, auditorías, tareas sobre un repositorio.
El proyecto de la serie: un auditor de sitios web
Las diez partes de la serie construyen el mismo agente: un auditor técnico de sitios web que revisa SEO clásico y GEO (optimización para motores generativos: lo que un crawler de IA puede leer y citar de tu sitio). Es un ejemplo didáctico que voy construyendo a lo largo de la serie, no un producto; no hay repo público ni cliente detrás, y los dominios de los ejemplos son siempre example.com.
La definición, fijada aquí para no cambiarla después:
AUDITOR DE SITIOS WEB — alcance de la serie
Entrada una URL raíz y un tope de páginas a revisar
Salida un informe en markdown escrito en /reports/<dominio>.md
con hallazgos, severidad y una recomendación por hallazgo
Revisa SEO title, meta description, jerarquía de headings,
canonical, robots.txt, sitemap, datos estructurados
GEO llms.txt, versión en markdown de cada página,
claridad del contenido para un crawler de IA,
respuestas directas a las preguntas del tema
Puede leer páginas del dominio, guardar cada página como archivo,
ejecutar scripts de análisis en un sandbox, delegar una
página o una dimensión a un subagente
No puede escribir fuera de /reports, salir del dominio sin aprobación,
modificar el sitio auditado
Elegí este proyecto porque cada capa del harness aparece con una razón concreta. Las páginas HTML son grandes, así que el contexto se desborda si no se descargan a archivos. Hay páginas independientes, así que la delegación tiene sentido. El agente escribe, así que los permisos importan. Algunas comprobaciones necesitan ejecutar código, así que hace falta un sandbox. Y los criterios GEO cambian con el tiempo, así que conviene guardarlos como una skill y no fijarlos en el system prompt. El orden de los posts sigue el orden en que un agente así crece, de un modelo con tools a subagentes en paralelo con trazas; la lista completa está en la página de la serie.
Cuándo no usar un harness: la tabla para bajar a LangGraph
Un harness opinado ahorra mucho trabajo cuando el problema tiene la forma para la que fue diseñado, y lo multiplica cuando no. La pregunta que decide es la misma de la serie anterior: ¿quién decide el siguiente paso? Si lo decide el modelo en cada vuelta, un harness encaja. Si lo decides tú antes de ejecutar, lo que quieres es un grafo.
| Señal en tu problema | Con deepagents | Mejor bajar a |
|---|---|---|
| Los pasos son fijos y conocidos (extraer, clasificar, publicar) | El modelo tiene que “descubrir” un orden que ya sabías | LangGraph, o un workflow sin agente |
| Necesitas garantizar el orden: aprobación humana antes de A, A antes de B, nunca B sin A | Dependes de que el prompt convenza al modelo | LangGraph: la arista lo garantiza |
| El estado es un objeto tipado con muchos campos, no una conversación | Todo pasa por mensajes y archivos | LangGraph con un state_schema propio |
| Cada turno cuesta y la tarea es corta (una clasificación, una extracción) | Pagas el system prompt del harness y sus tools en cada llamada | create_agent o una llamada directa al modelo |
| Tus tools no tienen forma de archivo ni de comando (una API de pagos, una cola) | El filesystem virtual no aporta nada y ocupa espacio en el prompt | create_agent con tus tools |
| Necesitas ver cada transición en las trazas y poder reproducirla | El loop del harness es un solo nodo que se repite | LangGraph: un nodo por paso |
| Varios agentes con un protocolo de handoff definido | El modelo elige a quién delegar y cuándo | LangGraph con subgrafos y aristas explícitas |
| Hay que cumplir un SLA de latencia por respuesta | El número de vueltas del loop no es predecible | LangGraph con un tope de pasos, o un workflow |
Dos matices. “Bajar” casi nunca es reescribir: como un deep agent es un grafo compilado, lo habitual es que el flujo determinista sea un grafo de LangGraph y el deep agent viva dentro como el nodo que resuelve la parte abierta. El auditor tendrá esa forma en el último post: un grafo que fija el orden (descubrir páginas, auditar, consolidar) y deep agents en los nodos que exigen juicio. Y las filas sobre costo y latencia no descartan el harness en tareas largas, sino en tareas cortas: un system prompt de varios miles de tokens y media docena de tools se amortizan en una auditoría de treinta turnos y se desperdician en una clasificación de uno. Si dudas, cuenta los turnos de una ejecución típica; por debajo de tres o cuatro, el harness casi siempre sobra.
Preguntas frecuentes
¿Un agent harness es lo mismo que un framework de agentes?
No exactamente. Un framework te da piezas para construir un agente (LangGraph es un framework). Un harness es un agente ya montado con esas piezas y con opiniones sobre cómo debe trabajar: qué tools tiene, cómo gestiona el contexto, cómo delega. deepagents es un harness construido con LangGraph; Claude Code es un harness construido sobre los modelos de Anthropic.
¿Necesito saber LangGraph para usar deepagents?
Para empezar, no: create_deep_agent recibe un modelo, tools y un prompt, y devuelve algo que se invoca con una lista de mensajes. Para depurar, sí conviene: el objeto que devuelve es un grafo de LangGraph, los threads y checkpointers son conceptos de LangGraph y las interrupciones para aprobación humana usan su mecanismo.
¿deepagents funciona solo con modelos de Anthropic?
No. El modelo se pasa como una cadena proveedor:modelo o como una instancia inicializada, y funciona con cualquier proveedor soportado por LangChain, incluidos modelos open-weight servidos localmente. Lo único específico es el middleware de cacheo de prompt, que solo actúa con proveedores que lo soportan. El segundo post corre el mismo auditor con un modelo frontier y con uno open-weight para ver dónde cambia el comportamiento.
¿Un harness sustituye a los límites duros de un agente?
No. El harness da mecanismos (aprobaciones, permisos por ruta, sandbox), pero los topes de iteraciones, de tiempo y de costo siguen siendo responsabilidad tuya, y conviene ponerlos fuera del agente, en el proceso que lo invoca. La serie anterior lo cubre en los límites duros de un agente autónomo; todo lo que dice ahí aplica igual con deepagents.
Conclusión
Un agente es un modelo más un harness, y el harness es la parte que tú diseñas: el entorno donde trabaja, cómo se gestiona su contexto, en quién delega y cómo lo diriges. LangChain lo ofrece en tres niveles apilados. Si el modelo tiene que decidir el siguiente paso en una tarea larga con archivos, empieza por deepagents. Si el orden lo decides tú, el estado es tipado o cada transición tiene que ser explícita, baja a LangGraph y mete el deep agent como un nodo donde haga falta juicio.
Para arrancar: define el alcance de tu agente en una hoja como la del auditor (entrada, salida, qué revisa, qué puede y qué no puede), pasa tu problema por la tabla de señales y solo entonces elige el nivel. El siguiente post construye el primer deep agent del auditor con create_deep_agent, lo corre con un modelo frontier y con uno open-weight, y mira dónde se separan.