← Back
Applied AI 15 min read

This article isn’t translated yet — showing the Spanish original.

Agentes: cuándo un loop y cuándo un pipeline

Un agente es un while alrededor de la API donde el modelo elige la próxima acción. Un workflow tiene las aristas escritas por vos. De esa diferencia mecánica salen los cuatro criterios para decidir, los cuatro tiers de arquitectura, y por qué elegir bash o una herramienta dedicada es una decisión de control.

Data verified on 10 August 2026. Provider pricing, limits and flag names change.

Un agente es una forma de control de flujo. Todo lo demás —las herramientas, el sandbox, los guardrails— es consecuencia de esa decisión de flujo. Si entendés el mecanismo, podés predecir dónde falla, y eso alcanza para decidir arquitectura sin entrar en la discusión de si algo "es un agente de verdad".

El loop, literalmente

En "Building effective agents", Erik Schluntz y Barry Zhang definen workflows como "systems where LLMs and tools are orchestrated through predefined code paths" y agents como "systems where LLMs dynamically direct their own processes and tool usage, maintaining control over how they accomplish tasks". La diferencia mecánica es una sola línea de código: quién elige la próxima llamada.

Un agente es un while alrededor de la API:

messages = [{"role": "user", "content": tarea}]

while True:
    resp = client.messages.create(
        model="claude-opus-5",
        max_tokens=16000,
        tools=TOOLS,
        messages=messages,
    )
    messages.append({"role": "assistant", "content": resp.content})

    if resp.stop_reason != "tool_use":
        break

    resultados = [ejecutar(b) for b in resp.content if b.type == "tool_use"]
    messages.append({"role": "user", "content": resultados})

Tres detalles del bloque son load-bearing. max_tokens es obligatorio: sin él la request vuelve 400, así que el loop no arranca. El append del mensaje del asistente va antes del corte, de modo que el turno final también queda en el historial. Y el corte es stop_reason != "tool_use", no stop_reason == "end_turn": un max_tokens o un refusal traen cero bloques tool_use, y con el corte por end_turn caerían al camino de herramientas, armarían un resultados vacío y appendearían un mensaje de usuario sin contenido, que la API rechaza. Con herramientas server-side agregás una rama para pause_turn, que se reanuda reenviando el turno en vez de terminar.

Ahora mirá qué hace cada parte. El modelo emite un bloque tool_use con un nombre y un objeto de argumentos; ejecutar es tarea del harness. Tu código —la función ejecutar— decide si eso corre, con qué permisos, en qué sandbox, y qué texto vuelve como tool_result. El modelo ve ese texto en el context window y muestrea la próxima acción condicionado a todo lo anterior. Es el patrón que formaliza ReAct: la traza se construye en runtime y no existe antes de correr.

Un workflow es el mismo grafo con las aristas escritas a mano: clasificás, después extraés, después validás. Las llamadas al modelo están adentro de tu if. En el agente, tu if está adentro del loop del modelo.

De ahí sale la propiedad que ordena todo lo demás. En un workflow, el conjunto de secuencias posibles es finito y lo escribiste vos. En un agente, cada turno multiplica las ramas por la cantidad de herramientas disponibles: el espacio de trazas de N turnos es del orden de |herramientas|^N. No lo enumeraste nunca, y no lo vas a enumerar.

Dos paneles lado a lado. A la izquierda, un workflow: tres cajas encadenadas verticalmente —clasificar, extraer, validar— unidas por flechas fijas, con un recuadro al costado que anota que las tres aristas se escribieron antes de correr y que los caminos son enumerables; al pie, el conteo dice una sola secuencia posible. A la derecha, un agente: la caja del modelo emite tool_use hacia el harness, el harness despacha a una fila de cuatro herramientas —leer, escribir, bash, sql en producción— y una flecha larga vuelve por la izquierda llevando el tool_result de nuevo al modelo; al pie, el conteo dice herramientas elevado a turnos.
El workflow tiene las aristas escritas. El agente las muestrea en cada turno.

El costo del error cambia de lugar

Un workflow falla donde vos lo escribiste. El paso 3 tira excepción, mirás el paso 3. La cobertura de tests es tratable porque los caminos son enumerables, y cuando algo se rompe, el stack trace apunta a una línea que existe en tu repo.

Un agente falla donde no lo previste. Y su modo de falla característico es la acción plausible, ejecutada con éxito, sobre el objeto equivocado. El rm que corrió perfecto en el directorio que no era. El UPDATE sin WHERE que la base aceptó feliz.

El blast radius de un agente es el conjunto de acciones irreversibles que sus herramientas hacen alcanzables.

Por eso la pregunta de diseño que rinde es qué tan reversible es cada cosa que el agente puede hacer, medida acción por acción. Y por eso el conteo de herramientas dice poco: un agente con veinte herramientas de solo lectura tiene blast radius vacío, porque ninguna de sus acciones alcanzables es irreversible. Uno con dos herramientas, donde una escribe en producción, no.

Los cuatro criterios

La documentación de Anthropic ordena la decisión en cuatro preguntas. Si alguna da que no, conviene quedarse un tier más abajo.

CriterioLa preguntaQué la responde
Complejidad¿Es multi-paso y difícil de especificar de antemano?Intentar escribir el pipeline. Si te sale, no hacía falta el agente.
Valor¿El resultado justifica más costo y más latencia?El loop hace N llamadas donde el workflow hacía una.
Viabilidad¿El modelo es capaz en este tipo de tarea?Una eval, no una intuición.
Costo del error¿Los errores se detectan y se revierten?Tests, code review, rollback.

Los tres primeros hablan de la tarea y del modelo. El cuarto habla de tu infraestructura, y es el único que podés cambiar vos esta semana. Un agente sobre un repo con tests y git es viable porque el error se detecta en CI y se revierte con un checkout. El mismo agente sobre un sistema sin rollback resuelve el mismo problema con un perfil de riesgo distinto. Ese criterio es también la razón de que el mismo agente sea buena idea en staging y mala en producción sin que cambie una línea de su prompt.

Los cuatro tiers

De más simple a más complejo:

  1. Una sola llamada a la API. Prompt, tal vez tools, una respuesta.
  2. Un workflow con lógica en tu código. Vos escribís el orden; el modelo llena los huecos.
  3. Un agente con tus propias herramientas. Vos corrés el loop y definís el harness.
  4. Un agente gestionado. El proveedor corre el loop y hospeda el sandbox.

La recomendación explícita es empezar por el más simple que resuelva el problema. La razón es la de siempre: cada tier que subís agrega estados que no enumeraste. El tier 2 te da determinismo de orden. El tier 3 te da control total del punto de ejecución, que es lo que vas a querer cuando las acciones sean caras de revertir. El tier 4 te saca la operación del sandbox de encima y te la saca también de las manos.

Cuatro bloques de altura creciente apoyados sobre una misma línea base, como una escalera que sube de izquierda a derecha: una llamada a la API, un workflow con la lógica en tu código, un agente con tus propias herramientas y un agente gestionado. Un eje vertical a la izquierda apunta hacia arriba y mide la capacidad que se gana; otro a la derecha apunta hacia abajo y mide el determinismo y el control que se ceden. Debajo, tres barras marcan dónde no hay loop, en qué escalón el harness es tuyo y en cuál lo corre el proveedor. Cada bloque anota cuántos caminos posibles quedan: uno, los que escribiste, los que se muestrean, y los que se muestrean fuera de tu proceso.
El tier 3 es el último escalón donde el punto de ejecución todavía es tuyo.

Bash contra herramientas dedicadas

Acá el eje se vuelve concreto. Una herramienta bash le da al modelo alcance máximo: cualquier binario del sistema, composición con pipes, todo el ecosistema de Unix sin que vos escribas un wrapper. CodeAct mide esa ganancia: expresar acciones como código ejecutable habilita composición, control de flujo y bucles dentro de una sola acción. El costo está del lado del harness. Lo que te llega es esto:

{ "name": "bash", "input": { "command": "find . -name '*.tmp' -delete" } }

Un string opaco. Para saber si eso borra tres archivos o el árbol entero tenés que parsear shell —sustitución de comandos, variables, redirecciones, alias— y el shell es Turing-completo. No hay un gate confiable sobre un string arbitrario.

Promover la acción a herramienta dedicada te cambia el objeto que interceptás:

{
  name: "delete_files",
  description: "Borra archivos del working tree. Usala cuando la tarea " +
    "pide eliminar archivos concretos que ya identificaste. Para descubrir " +
    "qué borrar, usá Glob primero: esta herramienta no acepta patrones.",
  input_schema: {
    type: "object",
    properties: {
      paths: { type: "array", items: { type: "string" },
               description: "Rutas absolutas. Sin globs." }
    },
    required: ["paths"]
  }
}

Ahora el harness tiene argumentos tipados antes de ejecutar nada, y con eso puede hacer cuatro cosas que sobre un string no puede:

  • Gate. Pedir confirmación mostrando la lista exacta de rutas.
  • Precondición. Hacer cumplir invariantes del estado: que el archivo no cambió desde la última lectura del modelo, que la ruta cae adentro del workspace. Bash puede hashear un archivo, pero no puede hacer cumplir el invariante sobre la acción que viene.
  • Render. Dibujar UI propia —un diff, una tabla— en vez de volcar stdout.
  • Paralelismo. Saber cuáles llamadas son independientes y correrlas juntas, porque la firma te dice qué toca cada una. Sobre bash, un grep paralelizable y un git push que no lo es tienen la misma forma, así que hay que serializar todo.

La regla práctica: empezar con bash por alcance, y promover a herramienta dedicada lo que necesite gate, render, auditoría o paralelismo.

Dos caminos para la misma acción de borrado. Arriba, el modelo emite un string con rm -rf ./build y el harness solo puede reenviarlo a una caja gris rotulada shell: entre la emisión y el efecto no hay ningún lugar donde intervenir, y una banda roja lo señala. Abajo, el modelo emite dos campos tipados, path y recursive, y el harness encadena cuatro cajas antes de tocar el disco: un gate que decide si el path está permitido, una precondición que verifica el estado del repo, un render que le muestra al humano el efecto en lugar de la sintaxis, y una marca de paralelismo. Las dos ramas terminan en la misma caja: el directorio borrado.
El rm es el mismo en los dos caminos; lo que cambia es cuántas veces tu código puede decir que no.

El criterio de corte es la reversibilidad

Lo difícil de revertir se promueve, y se promueve con un gate específico. Esta tabla es el artefacto operativo del artículo: inventariás las acciones que el agente puede tomar, las ordenás por reversibilidad, y cada fila sale con su destino y su gate escritos.

AcciónReversibleDónde viveGate del harness
ls, grep, catSí, trivialmentebashNinguno
Leer un archivo grandeSí, pero pesa en contextodedicadaNinguno; paginado y truncado en el retorno
Editar un archivo versionadoSí, con gitdedicadaPrecondición verificada por el harness (el archivo no cambió desde la última lectura) más diff renderizado
git push --forceDifícildedicadaConfirmación humana con el rango de commits a la vista
DDL o escritura en producciónNodedicadaConfirmación humana, o directamente fuera del agente

La última columna es la que convierte la tabla en implementación. "Dedicada" sin gate escrito es solo un cambio de firma.

La descripción es el prompt de la herramienta

La descripción es el factor que más influye en que el modelo use bien una herramienta, y la falla más común es sub-describir. "Borra archivos" es cierto y no sirve: no dice cuándo llamarla, qué formato aceptan los argumentos, ni qué hacer cuando falla.

Conviene ser prescriptivo sobre cuándo llamarla, no solo sobre qué hace. "Writing effective tools for agents — with agents", del equipo de ingeniería de Anthropic, lo plantea como escribirle a alguien que entra al equipo: hacé explícito el contexto implícito, usá nombres de parámetro sin ambigüedad —user_id antes que user—, agrupá familias de herramientas con un prefijo común, y devolvé respuestas con paginación o truncado en vez de volcar todo. Ese mismo texto es el que le dice al modelo cuándo elegir la herramienta dedicada en vez de resolverlo por bash. Si la descripción no lo dice, el modelo va a hacer lo obvio y tu punto de intercepción queda sin usar.

Skills: revelación progresiva y su factura

Una skill es una carpeta con un SKILL.md que empaqueta instrucciones y archivos para una tarea. El mecanismo es la revelación progresiva, y la documentación de Agent Skills de Anthropic (platform.claude.com, secciones overview y best practices) publica sus umbrales, así que la factura se puede imprimir en vez de afirmarla:

CapaCuánto pesaCuándo se carga
Metadata: name + description~100 tokens por skillSiempre, en cada request
Cuerpo del SKILL.mdBajo 5k tokensCuando la tarea dispara la skill
Archivos referenciadosCeroSolo cuando el modelo los abre

Los topes duros van con eso: la description admite hasta 1024 caracteres, el cuerpo se mantiene bajo 500 líneas, y las referencias van a un solo nivel de profundidad desde el SKILL.md.

La primera fila es la que factura. Con veinte skills instaladas, la metadata suma unos 2.000 tokens que se pagan en todos los pedidos, use el modelo alguna o ninguna. Enumerar quince frases de disparo casi sinónimas engorda esa fila y además generaliza peor que nombrar dos o tres categorías de intención: el modelo hace matching semántico, no lookup de strings.

El límite de anidación tiene un mecanismo detrás que conviene conocer, porque falla en silencio. Cuando una referencia está a más de un nivel, el modelo previsualiza el archivo anidado en vez de leerlo completo. La skill dispara, el modelo trabaja, y lo hace con información parcial sin que nada lo avise.

Grados de libertad

La especificidad de una instrucción tiene que coincidir con la fragilidad de lo que describe.

Naturaleza de la tareaQué escribir
Decisión de juicio, campo abiertoHeurísticas en prosa, criterios, contraejemplos
Operación frágil, una sola secuencia seguraEl comando exacto, verbatim

Un guion paso a paso para una decisión de juicio sobre-restringe: el modelo sigue el guion cuando el caso no encaja. Prosa vaga para una operación frágil sub-restringe: el modelo improvisa una variante que rompe. La mayoría de las skills malas fallan por el lado equivocado en cada mitad.

Dos cosas envejecieron mal en esa línea. Los prompts y skills escritos para modelos anteriores suelen ser demasiado prescriptivos para los actuales y reducen la calidad; enunciar el objetivo y las restricciones rinde más que enumerar los pasos. Y pedir explícitamente que el modelo verifique su trabajo hoy produce sobre-verificación: el comportamiento ya viene de fábrica, así que la instrucción se volvió contraproducente. Si querés garantías de calidad, van en el harness y en las evals —eso lo tratamos en "Evals: si no puede bloquear un deploy, no es una eval"—, no en una frase del prompt.

Herramientas

Cada una de estas hace visible una parte distinta del eje. Todas son gratis.

  • Claude Agent SDK (Python) — El harness de Claude Code expuesto como librería: el loop ya construido, con ejecución de herramientas, permisos, subagentes y compactación de contexto. La referencia para ver que un harness serio tiene más piezas que un while con un try, y para leer el sistema de permisos como la capa que decide si bash entra o no.
  • OpenAI Agents SDK — El mismo loop con otro vocabulario: lo que acá llamamos harness aparece repartido entre runner y guardrails. El tracing incorporado es el argumento visual de por qué observar un loop es distinto de observar un pipeline.
  • LangGraph — El lado pipeline: el flujo como grafo de nodos y aristas, con estado explícito, checkpoints y human-in-the-loop. El mismo framework te deja escribir el orden a mano o dejar que un nodo decida el próximo salto, así que el código hace visible dónde exactamente cedés el control.
  • Pydantic AI — La herramienta dedicada como contrato: el esquema es documentación para el modelo y validación en runtime al mismo tiempo, así que una llamada mal formada falla en el borde y no adentro de tu sistema.
  • smolagents — La implementación práctica de CodeAct: el agente actúa escribiendo Python en vez de emitir llamadas JSON. Incluye ejecución en sandbox, que es justo la pieza que hay que agregar cuando elegís el camino de bash o intérprete.
  • Model Context Protocol — El protocolo que estandariza cómo se le exponen herramientas, recursos y prompts a un agente. Mueve la pregunta de qué herramienta le doy a cómo se descubren y se gobiernan, y deja ver que el harness solo controla lo que está declarado: una herramienta MCP se lista y se audita; un comando adentro de bash, no.

Cómo decidir

El orden que se sostiene es de abajo hacia arriba.

  1. Escribí el pipeline. Si te sale, terminaste: tenés determinismo de orden y caminos enumerables por el precio de un if.
  2. Si no te sale porque no sabés de antemano cuántos pasos son ni en qué orden, pasá los cuatro criterios. Prestá atención al cuarto, porque es el único que podés arreglar vos: tests, review y rollback cambian el perfil de riesgo sin tocar el prompt.
  3. Inventariá las acciones alcanzables. No las herramientas: las acciones. Una herramienta bash aporta el conjunto entero de binarios del sistema, y eso es lo que hay que listar.
  4. Ordenalas por reversibilidad, con la tabla de más arriba. La columna que importa es la última.
  5. Promové las de abajo. Cada una sale con dos cosas escritas: la descripción, para que el modelo la elija en vez de resolverlo por bash, y el gate, para que un humano la confirme.

Un agente bien construido se mide por el undo: cada acción que puede tomar tiene vuelta atrás, y las que no la tienen pasan por un humano antes de correr. Si podés llenar la última columna de esa tabla para todas las filas, tenés un agente. Si hay filas en blanco, todavía tenés un pipeline con ambiciones.

Keep going

Reading

Videos

Next · DevOps · 19 min Lo que se promueve es el artefacto, no el código Read next →