Saltar al contenido
← Todos los posts

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.

Ilustración de un agent harness como un chasis: el loop del modelo en el centro y cuatro instrumentos conectados a él (archivos y terminal, contexto que se compacta, subagentes, interruptor con candado y compuerta); la tarea entra por la izquierda, el informe sale por la derecha y una persona aprueba desde fuera

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:

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.

NivelQué escribes túQué te daCuándo encaja
LangGraphLos nodos, las aristas y el estadoRuntime durable, checkpoints, streaming, interruptsEl orden de los pasos lo decides tú
create_agentModelo, tools, system prompt, middlewareEl loop de tools ya resuelto y extensibleTarea abierta, contexto que cabe en una conversación
deepagentsModelo, tools, system promptEl loop más filesystem, subagentes, resumen, permisos, HITL, skillsTarea 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.

CapaMecanismo en deepagentsLo que el modelo vePost de la serie
Entorno de ejecuciónFilesystemMiddleware, backends, sandboxls, read_file, write_file, edit_file, glob, grep, execute3, 5, 6, 7
Gestión de contextoSummarizationMiddleware, prompt caching, offload a archivosNada nuevo: el contexto simplemente no se desborda8
DelegaciónSubAgentMiddleware, subagentes propiostask10
Steeringsystem prompt, interrupt_on, permissions, skills, memoryInstrucciones, pausas de aprobación, rechazos de escritura4, 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 problemaCon deepagentsMejor bajar a
Los pasos son fijos y conocidos (extraer, clasificar, publicar)El modelo tiene que “descubrir” un orden que ya sabíasLangGraph, o un workflow sin agente
Necesitas garantizar el orden: aprobación humana antes de A, A antes de B, nunca B sin ADependes de que el prompt convenza al modeloLangGraph: la arista lo garantiza
El estado es un objeto tipado con muchos campos, no una conversaciónTodo pasa por mensajes y archivosLangGraph 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 llamadacreate_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 promptcreate_agent con tus tools
Necesitas ver cada transición en las trazas y poder reproducirlaEl loop del harness es un solo nodo que se repiteLangGraph: un nodo por paso
Varios agentes con un protocolo de handoff definidoEl modelo elige a quién delegar y cuándoLangGraph con subgrafos y aristas explícitas
Hay que cumplir un SLA de latencia por respuestaEl número de vueltas del loop no es predecibleLangGraph 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.

Seguir leyendo