✨ Świeża dostawa•nowe kody na kinetyka.pl: Gemini Pro 18 mies. 170 zł•Cursor, ElevenLabs, Lovable i więcej, roczne plany AI w ułamku ceny Zobacz →
Przejdź do treści
Artykuły

Frameworki agentów AI: LangGraph, CrewAI, OpenAI i Claude Agent SDK

Zmierzyłem pięć sposobów budowy tego samego agenta: linie kodu, czas, liczba zapytań, koszt i zależności. Tabela i rekomendacje, kiedy który framework.

11 min czytania
Logo LangChain, CrewAI, OpenAI i Claude - porównanie frameworków agentów AI

👁 117 przeczytań

// w skrócie
  • Do nauki i prostych agentów najlepsza jest własna pętla (16 linii) lub OpenAI Agents SDK (10 linii), LangGraph sprawdza się przy złożonych przepływach, a CrewAI przy zespołach z rolami.
  • Claude Agent SDK był najdroższy - kosztował 0,0149 USD za zadanie, czyli ponad dwukrotnie więcej niż ten sam model Haiku 4.5 we własnej pętli (0,0071 USD).
  • CrewAI wymaga instalacji aż 137 pakietów (ok. 790 MB środowiska) i ma najwolniejszy import spośród testowanych frameworków.

Napisałem tego samego agenta AI pięć razy: bez frameworka, w OpenAI Agents SDK, LangGraph, CrewAI i Claude Agent SDK. Każda wersja dostała te same trzy narzędzia i to samo zadanie, a ja zmierzyłem linie kodu, czas, liczbę zapytań do modelu i koszt. Krótka odpowiedź: do nauki i prostych agentów najlepsza jest własna pętla albo OpenAI Agents SDK, LangGraph wygrywa przy złożonych przepływach, CrewAI przy zespołach agentów z rolami, a Claude Agent SDK, gdy agent ma pracować na plikach jak Claude Code. Tekst jest częścią ścieżki Agenci AI od zera.

Stan na 4 października 2026

  • Wersje: openai 3.24.0, openai-agents 0.23.1, langgraph 1.2.12 z langchain-openai 1.6.7, crewai 1.15.23, claude-agent-sdk 0.2.163 (z Claude Code 2.1.287).
  • Model w czterech pierwszych wersjach: openai/gpt-5.6-luna. Claude Agent SDK działa tylko z modelami Claude, więc tam był Claude Haiku 4.5. Wszystko przez OpenRouter.
  • Każdą wersję uruchomiłem 3 razy. Zapytania i koszt liczyłem lokalnym licznikiem, przez który przechodził cały ruch do OpenRouter.
  • Wszystkie 15 przebiegów pomiarowych dało poprawny wynik (nie liczę dwóch pierwszych prób Claude Agent SDK, które padły na konfiguracji, opisuję je niżej). Łączny koszt pomiaru: 0,060 USD.

Zadanie testowe

Agent ma policzyć, ile wydałem na faktury z folderu dane/ (dwie w złotych, jedna na 120 EUR), przeliczając euro po bieżącym kursie NBP. Poprawny wynik to 3919,74 zł. Narzędzia są wspólne dla wszystkich wersji i siedzą w osobnym pliku:

  • szukaj_plikow: treść plików .txt z folderu;
  • kalkulator: bezpieczne liczenie wyrażeń;
  • czytaj_strone: pobranie strony albo odpowiedzi API.
"""Wspólne narzędzia dla wszystkich wersji agenta (zwykłe funkcje Pythona, bez frameworka)."""
import ast, operator, pathlib
import requests
from bs4 import BeautifulSoup

KATALOG = (pathlib.Path(__file__).parent.parent / "dane").resolve()
ZADANIE = ("Policz, ile łącznie wydałem w złotych na faktury z folderu dane. "
           "Fakturę w euro przelicz po dzisiejszym kursie NBP.")
INSTRUKCJA = ("Rozwiąż zadanie narzędziami. Kursy walut: https://api.nbp.pl/api/exchangerates/rates/a/{kod}/?format=json. "
              "Liczenie zawsze kalkulatorem. Odpowiadaj po polsku, krótko.")

def szukaj_plikow(fraza: str = "") -> str:
    """Pokazuje pliki .txt z folderu dane/ i ich treść. Pusta fraza = wszystkie pliki."""
    out = [f"== {p.relative_to(KATALOG)} ==\n{p.read_text(encoding='utf-8')[:1500]}"
           for p in sorted(KATALOG.rglob("*.txt")) if fraza.lower() in p.read_text(encoding="utf-8").lower()]
    return "\n".join(out) or "brak plików"

OPS = {ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul, ast.Div: operator.truediv, ast.USub: operator.neg}
def kalkulator(wyrazenie: str) -> str:
    """Liczy wyrażenie arytmetyczne, np. 2214+1180.8."""
    def licz(n):
        if isinstance(n, ast.Constant): return n.value
        if isinstance(n, ast.BinOp): return OPS[type(n.op)](licz(n.left), licz(n.right))
        if isinstance(n, ast.UnaryOp): return OPS[type(n.op)](licz(n.operand))
        raise ValueError("tylko liczby i + - * /")
    return str(round(licz(ast.parse(wyrazenie, mode="eval").body), 4))

def czytaj_strone(url: str) -> str:
    """Pobiera tekst strony WWW lub odpowiedź API spod adresu URL."""
    r = requests.get(url, timeout=20, headers={"User-Agent": "promptowy-agenci-starter/1.0"})
    return BeautifulSoup(r.text, "html.parser").get_text(" ", strip=True)[:4000]

Dzięki temu porównuję tylko to, co dokłada framework, a nie same narzędzia. Jak działa pętla agenta od środka, pokazuję krok po kroku w tekście Jak zbudować agenta AI w Pythonie.

Wyniki pomiaru

WersjaLinie koduŚr. czasZapytania do modeluŚr. koszt zadaniaPakiety do instalacjiImportPoprawne
Bez frameworka (openai)167,3 s30,00064 USD140,6 s3/3
OpenAI Agents SDK108,8 s3-40,00083 USD391,3 s3/3
LangGraph197,9 s30,00062 USD431,3 s3/3
CrewAI1010,5 s3-40,00073 USD1371,9-2,5 s3/3
Claude Agent SDK (Haiku 4.5)2416,1 s4-50,0149 USD31 + Claude Code0,7-1,0 s3/3
Bez frameworka, ten sam Haiku 4.5 (kontrola)167,1 s40,0071 USD140,6 s1/1

Jak liczyłem:

  • Linie kodu: niepuste linie bez komentarzy, bez wspólnego pliku z narzędziami;
  • Czas: od startu procesu Pythona do wyniku, czyli z importem bibliotek. Średnia z 3 przebiegów;
  • Pakiety: liczba paczek, które pip instaluje razem z frameworkiem (rozwiązanie zależności dla Pythona 3.13);
  • Koszt: suma pola cost, które OpenRouter zwraca przy każdym zapytaniu.

Co z tego wynika:

  • Przy prostym agencie framework prawie nie zmienia kosztu. Wersje na Lunie mieszczą się między 0,0006 a 0,0009 USD. OpenAI Agents SDK i CrewAI czasem robiły czwarte zapytanie (osobne kroki kalkulatora zamiast jednego), stąd odrobinę wyższa średnia.
  • Claude Agent SDK jest wyraźnie droższy i wolniejszy, ale głównie przez model. Kontrola pokazuje rozkład: ten sam Haiku we własnej pętli kosztował 0,0071 USD, w Claude Agent SDK 0,0149 USD. Około połowy różnicy dokłada sam silnik Claude Code (dłuższe instrukcje systemowe, myślenie przed każdym krokiem).
  • CrewAI ciągnie najwięcej zależności (137 pakietów, ok. 790 MB środowiska) i ma najwolniejszy import. Zainstalowałem go w osobnym środowisku, żeby nie mieszać wersji z resztą.

1. Bez frameworka: 16 linii

import json, os
from openai import OpenAI
from narzedzia import ZADANIE, INSTRUKCJA, szukaj_plikow, kalkulator, czytaj_strone

client = OpenAI(base_url="https://openrouter.ai/api/v1", api_key=os.environ["OPENROUTER_API_KEY"])
FUNKCJE = {f.__name__: f for f in (szukaj_plikow, kalkulator, czytaj_strone)}
TOOLS = [{"type": "function", "function": {"name": n, "description": f.__doc__, "parameters": {"type": "object",
          "properties": {p: {"type": "string"} for p in f.__annotations__ if p != "return"}}}} for n, f in FUNKCJE.items()]

messages = [{"role": "system", "content": INSTRUKCJA}, {"role": "user", "content": ZADANIE}]
for krok in range(8):
    msg = client.chat.completions.create(model=os.environ["MODEL"], messages=messages, tools=TOOLS).choices[0].message
    messages.append(msg.model_dump(exclude_none=True))
    if not msg.tool_calls:
        print(msg.content); break
    for c in msg.tool_calls:
        wynik = FUNKCJE[c.function.name](**json.loads(c.function.arguments or "{}"))
        messages.append({"role": "tool", "tool_call_id": c.id, "content": wynik})

Wszystko jest na wierzchu: lista wiadomości, pętla, wywołanie funkcji. Opisy narzędzi generuję z docstringów. Brakuje tu logowania, ponawiania po błędach sieci i obsługi złych argumentów. W prawdziwym projekcie dopiszesz je w kolejnych 30-50 liniach, co pokazuję w pełnej wersji agenta.

2. OpenAI Agents SDK: 10 linii

import os
from openai import AsyncOpenAI
from agents import Agent, OpenAIChatCompletionsModel, Runner, function_tool, set_tracing_disabled
from narzedzia import ZADANIE, INSTRUKCJA, szukaj_plikow, kalkulator, czytaj_strone

set_tracing_disabled(True)
model = OpenAIChatCompletionsModel(model=os.environ["MODEL"], openai_client=AsyncOpenAI(
    base_url="https://openrouter.ai/api/v1", api_key=os.environ["OPENROUTER_API_KEY"]))
agent = Agent(name="Faktury", instructions=INSTRUKCJA, model=model,
              tools=[function_tool(f) for f in (szukaj_plikow, kalkulator, czytaj_strone)])
print(Runner.run_sync(agent, ZADANIE, max_turns=8).final_output)

Najkrótszy sensowny zapis. function_tool robi schemat z sygnatury funkcji, Runner.run_sync kręci pętlę z limitem max_turns. W zamian dostajesz od razu handoffy (przekazanie rozmowy innemu agentowi), guardrails, sesje i śledzenie przebiegów. Na OpenRouterze trzeba wyłączyć tracing i owinąć klienta w OpenAIChatCompletionsModel, bo domyślnie SDK mówi do API Responses od OpenAI.

3. LangGraph: 19 linii

import os
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, MessagesState, START
from langgraph.prebuilt import ToolNode, tools_condition
from narzedzia import ZADANIE, INSTRUKCJA, szukaj_plikow, kalkulator, czytaj_strone

narzedzia = [szukaj_plikow, kalkulator, czytaj_strone]
llm = ChatOpenAI(model=os.environ["MODEL"], base_url="https://openrouter.ai/api/v1",
                 api_key=os.environ["OPENROUTER_API_KEY"]).bind_tools(narzedzia)

def model(stan: MessagesState):
    return {"messages": [llm.invoke(stan["messages"])]}

graf = StateGraph(MessagesState)
graf.add_node("model", model)
graf.add_node("tools", ToolNode(narzedzia))
graf.add_edge(START, "model")
graf.add_conditional_edges("model", tools_condition)  # są wywołania narzędzi? -> "tools", nie -> koniec
graf.add_edge("tools", "model")
agent = graf.compile()

wynik = agent.invoke({"messages": [("system", INSTRUKCJA), ("user", ZADANIE)]}, {"recursion_limit": 16})
print(wynik["messages"][-1].content)

Najwięcej kodu, ale celowo zbudowałem graf ręcznie, zamiast użyć gotowego agenta z jednej funkcji. Widać tu ideę LangGraph: stan (lista wiadomości), węzły (model, narzędzia) i krawędzie (warunek „czy model prosi o narzędzie”). Przy jednym agencie to przerost formy. Przy przepływie z rozgałęzieniami, zatwierdzaniem przez człowieka, zapisem stanu i wznawianiem po awarii to właśnie ta struktura oszczędza pracę. Limit kroków to recursion_limit.

4. CrewAI: 10 linii

Nie przepłacaj za te subskrypcje

Prowadzę sklep z rocznymi dostępami do narzędzi AI - te same konta, o których piszę wyżej, tylko taniej niż w cenniku producenta.

Zobacz, co jest dostępne

import os
from crewai import Agent, Task, Crew, LLM
from crewai.tools import tool
from narzedzia import ZADANIE, INSTRUKCJA, szukaj_plikow, kalkulator, czytaj_strone

llm = LLM(model="openrouter/" + os.environ["MODEL"], base_url="https://openrouter.ai/api/v1",
          api_key=os.environ["OPENROUTER_API_KEY"])
ksiegowy = Agent(role="Księgowy", goal="Policzyć wydatki z faktur", backstory=INSTRUKCJA, llm=llm,
                 tools=[tool(f) for f in (szukaj_plikow, kalkulator, czytaj_strone)], max_iter=8, verbose=False)
zadanie = Task(description=ZADANIE, expected_output="Suma w złotych z krótkim wyliczeniem", agent=ksiegowy)
print(Crew(agents=[ksiegowy], tasks=[zadanie]).kickoff().raw)

CrewAI myśli rolami: agent ma rolę, cel i „historię”, a zadanie ma opis i oczekiwany wynik. Dla jednego agenta to sporo ceremonii, ale przy zespole („badacz” zbiera dane, „redaktor” pisze, „recenzent” sprawdza) ten model jest czytelny dla osób spoza IT. Model podajesz z prefiksem dostawcy, tu openrouter/. CrewAI wymaga Pythona od 3.10 do 3.13.

5. Claude Agent SDK: 24 linie

import asyncio, os
from claude_agent_sdk import ClaudeAgentOptions, ResultMessage, create_sdk_mcp_server, query, tool
from narzedzia import ZADANIE, INSTRUKCJA, szukaj_plikow, kalkulator, czytaj_strone

def owin(f, param):  # funkcja Pythona -> narzędzie SDK (zwraca bloki treści)
    @tool(f.__name__, f.__doc__, {param: str})
    async def t(args):
        return {"content": [{"type": "text", "text": f(args.get(param, ""))}]}
    return t

serwer = create_sdk_mcp_server("faktury", tools=[owin(szukaj_plikow, "fraza"), owin(kalkulator, "wyrazenie"),
                                                 owin(czytaj_strone, "url")])
opcje = ClaudeAgentOptions(system_prompt=INSTRUKCJA, model=os.environ.get("CLAUDE_MODEL", "anthropic/claude-haiku-4.5"),
                           mcp_servers={"faktury": serwer}, strict_mcp_config=True,
                           tools=[],  # bez wbudowanych narzędzi Claude Code (Bash, Edit itd.)
                           allowed_tools=["mcp__faktury__szukaj_plikow", "mcp__faktury__kalkulator",
                                          "mcp__faktury__czytaj_strone"], max_turns=8,
                           cli_path=os.getenv("CLAUDE_CLI"),  # Windows: ścieżka do claude.exe (nie claude.cmd)
                           setting_sources=[],  # nie wczytuj ~/.claude/settings.json (tam bywa inny ANTHROPIC_BASE_URL)
                           env={"ANTHROPIC_BASE_URL": "https://openrouter.ai/api",  # Claude przez OpenRouter
                                "ANTHROPIC_AUTH_TOKEN": os.environ["OPENROUTER_API_KEY"], "ANTHROPIC_API_KEY": ""})

async def main():
    async for m in query(prompt=ZADANIE, options=opcje):
        if isinstance(m, ResultMessage):
            print(m.result)
asyncio.run(main())

Najwięcej konfiguracji, bo Claude Agent SDK to cały Claude Code w roli biblioteki. Własne narzędzia podłączasz jako serwer MCP w pamięci (create_sdk_mcp_server), a wbudowane narzędzia (Bash, edycja plików) wyłączyłem przez tools=[]. Trzy rzeczy, które kosztowały mnie czas:

  • na Windows SDK odmawia uruchomienia claude.cmd z npm. Trzeba podać ścieżkę do claude.exe w cli_path;
  • bez setting_sources=[] SDK wczytał moje ustawienia z ~/.claude/settings.json i wysłał zapytania pod zupełnie inny adres, niż wskazałem w kodzie (dostałem błąd 403);
  • przez OpenRouter Claude Code łączy się z endpointem zgodnym z API Anthropic (ANTHROPIC_BASE_URL=https://openrouter.ai/api), a klucz idzie w ANTHROPIC_AUTH_TOKEN.

Porównanie: kiedy który framework

FrameworkKrzywa naukiMocna stronaSłabsza stronaWybierz, gdy
Bez frameworkanajłagodniejsza, jeśli znasz Pythonapełna kontrola, zero zależnościwszystko dopisujesz samuczysz się albo agent ma 2-5 narzędzi
OpenAI Agents SDKłagodnamało kodu, handoffy, guardrails, tracingdomyślnie nastawiony na API OpenAIchcesz szybko przejść od skryptu do kilku agentów
LangGraphnajbardziej stromagraf stanu, wznawianie, człowiek w pętlidużo pojęć na startprzepływ ma rozgałęzienia i musi być odporny na awarie
CrewAIłagodnazespoły agentów z rolami, czytelne dla nieprogramistówciężka instalacja, mniej kontroli nad pętląsymulujesz zespół: research, pisanie, recenzja
Claude Agent SDKśredniagotowe narzędzia do plików i terminala, uprawnienia, podagencitylko modele Claude, wyższy kosztagent ma pracować na repozytorium albo dokumentach jak Claude Code

Na rynku jest więcej frameworków. Google ma ADK (Agent Development Kit, wersja 2.11.0 na PyPI), Hugging Face ma smolagents (1.26.0), Microsoft rozwija Agent Framework. Nie mierzyłem ich w tym teście. Jeśli wolisz budować bez kodu, odpowiednikiem tych bibliotek są n8n z węzłem AI Agent i Gumloop.

Moja rekomendacja

  1. Najpierw napisz agenta bez frameworka. Jedno popołudnie nauki oszczędza tygodnie zgadywania, co framework robi pod spodem.
  2. Do pierwszego prawdziwego projektu weź OpenAI Agents SDK. Działa z OpenRouterem i lokalnymi modelami, ma najmniej ceremonii.
  3. Po LangGraph sięgnij, kiedy zaczniesz rysować przepływ na kartce i wyjdzie Ci schemat blokowy z pętlami i warunkami.
  4. CrewAI i Claude Agent SDK traktuj jako narzędzia do konkretnych zadań: zespół ról albo praca na plikach.

Najczęstsze pytania

LangChain czy LangGraph?

LangChain to biblioteka klocków (modele, narzędzia, parsery), LangGraph to sposób na sterowanie przepływem agenta grafem. W wersjach 1.x LangChain do agentów używa LangGraph pod spodem. Do nauki agentów zacznij od LangGraph, a z LangChain bierz tylko integracje, np. langchain-openai.

Czy frameworki agentów są darmowe?

Wszystkie pięć bibliotek z testu jest otwartych i darmowych. Płacisz za tokeny modelu. Płatne bywają dodatki: LangSmith (śledzenie LangGraph), chmura CrewAI, tracing u dostawców.

Który framework działa z lokalnymi modelami?

Własna pętla, OpenAI Agents SDK, LangGraph i CrewAI działają z Ollamą przez API zgodne z OpenAI. Claude Agent SDK wymaga modeli Claude.

Czy framework poprawia jakość agenta?

W moim teście nie. Wszystkie wersje dały ten sam wynik. Jakość zależy od modelu, opisów narzędzi i danych. Framework daje strukturę, logi i gotowe mechanizmy wokół pętli.

Ile kosztowało uruchomienie wszystkich wersji?

16 przebiegów (15 pomiarowych i 1 kontrolny) kosztowało 0,060 USD, z czego 0,052 USD to przebiegi na Claude Haiku.

Gdzie się nauczyć konkretnego frameworka?

Darmowe kursy: LangChain Academy (Intro to LangGraph), DeepLearning.AI (AI Agents in LangGraph, Multi AI Agent Systems with crewAI), dokumentacja OpenAI Agents SDK i Claude Agent SDK. Pełna lista z opisem jest w hubie.

Google · Twoje źródłaPromptowy wyżej w Twoim Google - jednym kliknięciemDodaj do preferowanych źródeł →

Źródła i data sprawdzenia

// Newsletter

Cały tydzień w AI, w jednym mailu

Wybrane premiery, narzędzia i analizy. Raz w tygodniu, prosto do skrzynki.

Zapisz się za darmo →
Za darmo. Wypisujesz się jednym kliknięciem.
// czytaj też

Podobne tematy na Promptowym

Piotr Olszewski

Piotr Olszewski

AUTOR I WYDAWCA

Piotr Olszewski - twórca i autor Promptowego, polskiego serwisu o sztucznej inteligencji. Codziennie śledzi premiery modeli, narzędzia i regulacje AI, i tłumaczy je prostym, konkretnym językiem.

// mapa strony

🛒 Sklep Kinetyka Google AI Gemini Pro 170 zł CapCut Pro 460 zł/rok Lovable Pro 400 zł/rok Zobacz wszystko →
promptowy w liczbach 0tekstów w archiwum0newsów z ostatnich 7 dni0modeli wideo w obserwatorium0zagadek w grach
× ‹ powiększenie ›