Inicio / Artículos / El costo de procesamiento de los bucles de agentes frente a los chatbots

El costo de procesamiento de los bucles de agentes frente a los chatbots

Por qué la planificación al estilo ReAct y las cadenas de herramientas pueden multiplicar el costo de inferencia por 10 veces, y qué medidas de control evitan que las facturas se disparen.

2169 palabras

Por qué los agentes consumen ~10 veces más recursos que los chatbots

Pasar de los chatbots a los agentes autónomos no es solo un cambio superficial: se trata de un cambio en la arquitectura. Los bucles de razonamiento iterativo multiplican las inferencias y las operaciones de entrada/salida con herramientas, por lo que una sola tarea puede costar una orden de magnitud más que una respuesta limitada.

Chatbots: una llamada limitada

Un asistente clásico realiza aproximadamente lo siguiente: solicitud → una (o pocas) llamadas al modelo → respuesta. El costo aumenta según la cantidad de tokens de entrada y salida. La latencia corresponde a un único camino de procesamiento más la fase de muestreo.

from langchain_community.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI, OpenAIEmbeddings

# Initialize the components (Vector store and LLM)
vectorstore = FAISS.from_texts(
    ["AI Agents require iterative loops."],
    embedding=OpenAIEmbeddings()
)
retriever = vectorstore.as_retriever()
model = ChatOpenAI(model="gpt-4o-mini")

# Build the linear RAG chain
rag_chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | model
    | StrOutputParser()
)

# Execute the single, bounded inference call
# This represents exactly one unit of compute.
response = rag_chain.invoke("Why do agents need more compute?")

Agentes: planificar, actuar, corregir

Los agentes envuelven esa llamada en un bucle: pensar → elegir herramienta → observar → pensar de nuevo. Cada paso vuelve a enviar un contexto cada vez más extenso. La autocorrección tras los fallos añade más pasos.

import json

class AgenticResearchLoop:
    def __init__(self):
        self.conversation_history = []
        # We mock the LLM responses to illustrate the sequential, stateful calls
        self.mock_llm_steps = [
            # Call 1: Initial planning step
            {
                "thought": "I need to identify the top 3 Salesforce competitors. I will start with a web search.",
                "action": "web_search",
                "action_input": "top CRM competitors to Salesforce 2024"
            },
            # Call 2: Analyzing results and planning the next action
            {
                "thought": "The search returned HubSpot, Microsoft Dynamics, and Veeva. Now I need to query HubSpot's latest quarterly earnings.",
                "action": "web_search",
                "action_input": "HubSpot latest quarterly earnings revenue"
            },
            # Call 3: Processing data and executing the next planned step
            {
                "thought": "HubSpot reported $557M in revenue. Now I will search for Microsoft Dynamics earnings.",
                "action": "web_search",
                "action_input": "Microsoft Dynamics 365 quarterly revenue growth"
            },
            # Call 4: Final synthesis of all collected information
            {
                "thought": "I have successfully retrieved data for the key competitors. I can now compile the final summary.",
                "action": "finalize_answer",
                "action_input": "Salesforce competitors summary: HubSpot ($557M revenue), Microsoft Dynamics (growing), and Veeva."
            }
        ]
        self.api_call_counter = 0

    def query_llm(self, accumulated_prompt: str) -> dict:
        """Simulates an expensive inference call to the LLM provider."""
        self.api_call_counter += 1
        print(f"[LLM CALL #{self.api_call_counter}] Consuming tokens (Context size: {len(accumulated_prompt)} chars)...")
        # In production, this would be a real chat completion API call
        return self.mock_llm_steps[self.api_call_counter - 1]

    def run(self, user_goal: str):
        print(f"User Goal: {user_goal}\n")
        context = f"Goal: {user_goal}\n"

        while self.api_call_counter < len(self.mock_llm_steps):
            llm_response = self.query_llm(context)
            print(f"  Reasoning thought: {llm_response['thought']}")
            print(f"  Executing Tool: {llm_response['action']}({llm_response['action_input']})")

            observation = f"Successful result from {llm_response['action']}"
            print(f"  Observation: {observation}\n")

            context += (
                f"Thought: {llm_response['thought']}\n"
                f"Action: {llm_response['action']}\n"
                f"Observation: {observation}\n"
            )

# Execute the agent
agent = AgenticResearchLoop()
agent.run("Research the top 3 competitors to Salesforce and summarize their latest quarterly earnings")

Bucles de tipo ReAct

Un esquema mínimo de ReAct muestra por qué los costos aumentan drásticamente:

+-------------+      Tool Call Parameter      +----------------+
|             | ----------------------------> |                |
|  LLM Agent  |                               | External Tool  |
|             | <---------------------------- | (API/Database) |
+-------------+      Raw JSON Observation     +----------------+
       |
       v
[Append to Context Window] ---> [Trigger Next LLM Inference Turn]

Cada resultado de una herramienta se convierte en nuevos tokens a los que debe prestar atención la siguiente inferencia.

Anatomía de la explosión

  1. Múltiples inferencias por tarea en lugar de una sola.
  2. Crecimiento del contexto — historial, rastros de herramientas, pizarras de bocetos.
  3. Caminos sin salida especulativos — planes que se abandonan después de usar tokens pagados.
  4. Latencia de las herramientas acumulándose con el tiempo de la GPU.

Combinaciones de uso de herramientas

Las APIs externas añaden tiempo real y, a veces, más llamadas al modelo para analizar los resultados:

import json

class AgentExecutor:
    def __init__(self, prompt_template: str):
        self.context = prompt_template
        self.total_tokens_processed = 0
    def execute_step(self, reasoning: str, action_result: dict):
        step_input = f"\nThought: {reasoning}\nObservation: {json.dumps(action_result)}"
        self.context += step_input

        # Calculate mock token count (roughly 4 characters per token)
        context_tokens = len(self.context) // 4
        self.total_tokens_processed += context_tokens

        print(f"Context Size: {context_tokens} tokens | "
              f"Cumulative Tokens Billed: {self.total_tokens_processed}")
agent = AgentExecutor("System: You are an agent that books travel using tools.")
# Step 1: Flight Search Tool Output
agent.execute_step(
    reasoning="I need to find flights from JFK to LHR first.",
    action_result={"flights": [{"id": "AA100", "price": 450, "time": "08:00"}]}
)
# Step 2: Hotel Search Tool Output (Context has grown)
agent.execute_step(
    reasoning="Found flight AA100. Now I must find a hotel near Heathrow.",
    action_result={"hotels": [{"name": "Airport Inn", "price": 120, "rating": 4.2}]}
)

Una cadena de ejecución en varios pasos (búsqueda → carrito → pago → confirmación) requiere tanto trabajo como varias respuestas de un chatbot, incluso cuando cada paso es “simple”.

El fracaso cuesta caro

Los intentos repetidos y las reflexiones son útiles para la fiabilidad, pero perjudiciales para las facturas. Sin presupuestos, un agente confundido puede actuar de forma descontrolada.

import time
from typing import Callable, Any, Dict

class AgentRuntimeLimitError(Exception):
    """Raised when an agent violates runtime guardrails."""
    pass

def execute_agent_step(
    step_fn: Callable[[], Dict[str, Any]],
    max_iterations: int = 5,
    max_duration_seconds: float = 10.0
) -> Dict[str, Any]:
    """
    Executes an agent step loop with strict termination guardrails
    to prevent infinite ReAct loops and runaway API billing.
    """
    start_time = time.time()
    iterations = 0

    while iterations < max_iterations:
        elapsed_time = time.time() - start_time
        if elapsed_time > max_duration_seconds:
            raise AgentRuntimeLimitError(f"Execution timed out after {elapsed_time:.2f}s.")

        step_result = step_fn()
        iterations += 1

        if step_result.get("status") == "COMPLETED":
            return step_result

    raise AgentRuntimeLimitError(f"Exceeded maximum iterations limit: {max_iterations}"

Cargas de trabajo reales

  • Codificación autónoma: editar, probar, leer registros, editar de nuevo; decenas de llamadas al modelo.
  • Operaciones multi-API para clientes: identidad, inventario, envíos; herramientas secuenciales.
  • Monitores de infraestructura: realizar consultas, diagnosticar y proponer soluciones dentro de estrictos SLOs.

Cuando el chat es suficiente

Preferir el uso de herramientas de un solo uso o ligeras cuando la tarea sea preguntas y respuestas, resúmenes o una sola recuperación de información. Recurrir a agentes cuando el entorno esté parcialmente observado y se requiera una acción en múltiples pasos.

Límites y directrices

  • Límites estrictos en pasos, tokens y costos por ejecución
  • Rutas deterministas para acciones de alto riesgo
  • Sandboxes para herramientas de código y shell
  • Observabilidad: rastrear cada pensamiento/herramienta con etiquetas de costo
  • Cachear las recuperaciones estables; reducir los prompts entre pasos

Qué exige la arquitectura

Trate a los agentes como sistemas distribuidos: presupuestos, idempotencia, auditorías y SLOs, y no como interfaces de chat con una marca de bucle. El cálculo 10× no es un error; es el costo del control iterativo, a menos que se diseñe de forma diferente.

Etique cada segmento con agent_id y step_index para que finanzas pueda atribuir el multiplicador 10×.

Etique cada segmento con agent_id y step_index para que finanzas pueda atribuir el multiplicador 10×.

Etique cada segmento con agent_id y step_index para que finanzas pueda atribuir el multiplicador 10×.

Etique cada segmento con agent_id y step_index para que finanzas pueda atribuir el multiplicador 10×.

Etique cada segmento con agent_id y step_index para que finanzas pueda atribuir el multiplicador 10×.

Etique cada segmento con agent_id y step_index para que finanzas pueda atribuir el multiplicador 10×.

Etique cada segmento con agent_id y step_index para que finanzas pueda atribuir el multiplicador 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda asignar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda aplicar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda aplicar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda aplicar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda aplicar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda aplicar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda aplicar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda aplicar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda aplicar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda aplicar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda aplicar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda aplicar el multiplicador de 10×.

Etiqueta cada segmento con agent_id y step_index para que finanzas pueda aplicar el multiplicador de 10×.

Lecturas relacionadas

  • Mediciones de ingeniería de IA: costo del contexto, evidencia del agente e interoperabilidad — Un mapa de las mediciones de IA ejecutadas: sobrecarga de tokens MCP, fallos en el caché de prompts, brechas en la auditoría de agentes y fricción al cambiar modelos, con métodos y tamaños de muestra incluidos.
  • Dónde gastan tokens las herramientas de codificación agente en la práctica — Las ventanas de contexto, los bucles de herramientas y las reintentos multiplican el gasto; presupuestos y caché que mantienen las demostraciones asequibles.
  • Once maneras de interrumpir los bucles infinitos de agentes de IA — Detectar ciclos de herramientas atascados, agregar condiciones de parada y recuperarse con puntos de control en lugar de más tokens.