Головна / Статті / Витрати на обчислення для циклів агентів порівняно з чат-ботами

Витрати на обчислення для циклів агентів порівняно з чат-ботами

Чому планування у стилі ReAct та ланцюги інструментів можуть збільшити вартість інференції у 10 разів — та які заходи допомагають контролювати ці витрати.

2169 слів

Чому агенти споживають приблизно у 10 разів більше ресурсів, ніж чат-боти

Перехід від чат-ботів до автономних агентів — це не просто зовнішня зміна, а зміна архітектури. Ітеративні цикли міркувань подвоюють кількість операцій з інструментами та вхідних/вихідних даних, тож виконання однієї задачі може коштувати у кілька разів більше, ніж одна обмежена відповідь.

Чат-боти: один обмежений запит

Класичний асистент виконує приблизно такі кроки: запит → один (або кілька) викликів моделі → відповідь. Витрати зростають пропорційно кількості токенів у вхідних та вихідних даних. Затримка складається з одного шляху обробки даних плюс процес вибору результату.

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?")

Агенти: планування, дія, корекція

Агенти організовують цей процес у цикл: міркування → вибір інструменту → спостереження → знову міркування. Кожен крок передає все більший обсяг контексту. Самокорекція після невдач додає ще більше кроків.

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")

Цикли у форматі ReAct

Мінімальний приклад реалізації ReAct пояснює, чому споживання ресурсів різко зростає:

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

Кожен результат використання інструменту стає новими токенами, на які мусить звернути увага наступна операція обробки даних.

Анатомія вибуху

  1. Кілька висновків за завданням замість одного.
  2. Розширення контексту — історія, сліди використання інструментів, нотатки.
  3. Гіпотетичні глухі кути — плани, які відкидаються після витрачання токенів.
  4. Затримка інструментів, що накопичується разом із часом обробки GPU.

Комплексне використання інструментів

Зовнішні API додають час обробки та іноді більше викликів моделей для аналізу результатів:

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}]}
)

Багатоетапний процес виконання завдань (пошук → кошик → оплата → підтвердження) вимагає кількох відповідей чат-бота, навіть якщо кожен етап є „простим“.

Невдачі коштують дорого

Повторні спроби та аналіз є корисними для надійності, але шкідливими для рахунків. Без бюджету агент може безрезультатно намагатися вирішити проблему.

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}"

Реальні навантаження

  • Автономне програмування: редагування, тестування, читання журналів, повторне редагування — десятки викликів моделей.
  • Багато-API операції для клієнтів: ідентифікація, інвентаризація, доставка — послідовні інструменти.
  • Системи моніторингу інфраструктури: збір даних, діагностика, пропозиції виправлень у рамках суворих SLO.

Коли достатньо чату

Використовуйте однократні операції або прості інструменти, коли завдання полягає у запитаннях та відповідях, стисненні інформації чи одноразовому пошуку даних. Звертайтеся до агентів, коли середовище частково спостерігається та результатом є багатокрокові дії.

Ограничення

  • Жорсткі ліміти на кількість кроків, токенів та витрати за один запуск
  • Детерміністичні шляхи для дій з високим ризиком
  • Середовища тестування для коду та інструментів командного рядка
  • Можливість спостереження: відстежування кожної думки/інструменту з позначками витрат
  • Кешування стабільних результатів пошуку; скорочення запитів між кроками

Що вимагає архітектура

Ставіться до агентів як до розподілених систем: бюджети, ідемпотентність, аудит та SLO — а не як до інтерфейсів чату з прапорцем циклу. 10× обчислювальна потужність — це не баг; це ціна ітеративного керування, якщо тільки ви не спроєктуєте систему інакше.

Позначайте кожен етап значеннями agent_id та step_index, щоб відділ фінансів міг присвоїти коефіцієнт 10×.

Позначайте кожен етап значеннями agent_id та step_index, щоб відділ фінансів міг присвоїти коефіцієнт 10×.

Позначайте кожен етап значеннями agent_id та step_index, щоб відділ фінансів міг присвоїти коефіцієнт 10×.

Позначайте кожен етап значеннями agent_id та step_index, щоб відділ фінансів міг присвоїти коефіцієнт 10×.

Позначайте кожен етап значеннями agent_id та step_index, щоб відділ фінансів міг присвоїти коефіцієнт 10×.

Позначайте кожен етап значеннями agent_id та step_index, щоб відділ фінансів міг присвоїти коефіцієнт 10×.

Позначайте кожен етап значеннями agent_id та step_index, щоб відділ фінансів міг присвоїти коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт помноження 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт помноження 10×.

Позначте кожен фрагмент значеннями agent_id та step_index, щоб відділ фінансів міг застосувати коефіцієнт помноження 10×.