Koszt obliczeniowy pętli agentów w porównaniu z chatbotami
Dlaczego pętla agenta z planowaniem w stylu ReAct i łańcuchami narzędzi może kosztować 10 razy więcej niż inferyencja chatbotów przy jednej wywołaniu ograniczonego modelu językowego, oraz jakie są zasady ograniczające ten koszt.
Źródła: Why AI Agents Consume 10x More Compute Than Your Chatbot
Dlaczego agenci zużywają około 10 razy więcej zasobów obliczeniowych niż chatboty
Przejście od chatbotów do autonomicznych agentów to nie tylko drobna modyfikacja – to zmiana architektury. Pętle rozumowania iteracyjnego mnożą liczbę operacji inferencji oraz zadań wejścia/wyjścia z narzędziami, przez co jeden zadań może kosztować o rzęd wielkości więcej niż jedna ograniczona odpowiedź.
Chatboty: jedna ograniczona rozmowa
Klasyczny asystent działa mniej więcej w ten sposób: prompt → jedna (lub kilka) prób wywołania modelu → odpowiedź. Koszt rośnie wraz z liczbą tokenów wejściowych i wyjściowych. Opóźnienie wynika z jednej ścieżki przetwarzania plus procesu próbkowania.
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?")
Agenci: planowanie, działanie, korekta
Agenci umieszczają to wywołanie w pętli: myślenie → wybór narzędzia → obserwacja → ponowne myślenie. Przy każdym kroku wysyłany jest coraz większy kontekst. Samokorekta po niepowodzeniach dodaje kolejne kroki.
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")
Pętle w stylu ReAct
Minimalny przykład implementacji ReAct wyjaśnia, dlaczego zużycie zasobów gwałtownie rośnie:
+-------------+ Tool Call Parameter +----------------+
| | ----------------------------> | |
| LLM Agent | | External Tool |
| | <---------------------------- | (API/Database) |
+-------------+ Raw JSON Observation +----------------+
|
v
[Append to Context Window] ---> [Trigger Next LLM Inference Turn]
Każdy wynik uzyskany z narzędzia staje się nowym tokenem, który musi zostać uwzględniony podczas następnej operacji inferencji.
Anatomia eksplozji
- Wielokrotne wnioskowanie na zadanie zamiast jednego.
- Rozwój kontekstu — historia, ślady narzędzi, notatniki.
- Spekulatywne ślepe zaułki — plany porzucone po wykorzystaniu tokenów.
- Opóźnienia narzędzi łączące się z czasem GPU.
Kompleksowe wykorzystanie narzędzi
Zewnętrzne API dodają czas pracy zegara oraz czasowo więcej wywołań modelu do przetwarzania wyników:
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}]}
)
Lançuch realizacji składający się z kilku kroków (poszukiwanie → koszyk → płatność → potwierdzenie) wymaga pracy równoważnej kilku odpowiedziom chatbota, nawet jeśli każdy krok jest „prosty”.
Porażka jest kosztowna
Ponawianie prób i analiza pomagają w zapewnieniu niezawodności, ale pogarszają sytuację pod względem rachunków. Bez budżetów zdezorientowany agent może popełniać błędy.
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}"
Rzeczywiste obciążenia
- Autonomiczne programowanie: edycja, testowanie, czytanie logów, ponowna edycja — dziesiątki wywołań modelu.
- Zarządzanie klientem za pomocą wielu API: identyfikacja, inwentaryzacja, wysyłka — narzędzia sekwencyjne.
- Nadzorcy infrastruktury: pomiary, diagnoza, proponowanie rozwiązań w ramach ścisłych SLO.
Gdy wystarcza czat
Należy preferować jednorazowe użycie narzędzi lub ich prostą aplikację, gdy zadanie polega na pytaniach i odpowiedziach, streszczaniu lub jednym wyświetleniu informacji. Zastosuj agenty, gdy środowisko jest częściowo obserwowalne, a rezultatem są działania wieloetapowe.
Zasady bezpieczeństwa
- Maksymalne limity liczby kroków, tokenów i kosztów za jedno uruchomienie
- Deterministyczne ścieżki dla działań o wysokim ryzyku
- Pesymetry do testowania narzędzi kodowych i wiersza poleceń
- Obserwowalność: śledzenie każdej myśli/narzędzia z tagami kosztów
- Caching stabilnych wyników; zmniejszanie długości zapytań pomiędzy etapami
Co wymaga architektura
Traktuj agenty jak systemy rozproszone: budżety, właściwości idempotencji, audyty oraz SLO — a nie jak interfejsy czatowe z flagą pętli. Wysoka wydajność 10× nie jest błędem; to cena kontroli iteracyjnej, chyba że zaprojektuje się ją inaczej.
Oznacz każdy okres czasowy tagami agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy okres czasowy tagami agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy okres czasowy tagami agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy okres czasowy tagami agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy okres czasowy tagami agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy okres czasowy tagami agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy okres czasowy tagami agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł przypisać współczynnik 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł zastosować współczynnik pomnożenia 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł zastosować współczynnik pomnożenia 10×.
Oznacz każdy fragment tagiem agent_id i step_index, aby dział finansowy mógł zastosować współczynnik pomnożenia 10×.