Budowanie agentów AI gotowych na MCP: architektura, która skaluje się

Article

Budowanie agentów AI gotowych na MCP: architektura, która skaluje się

Jeśli śledzisz przestrzeń narzędzi AI w 2024-2025, termin MCP pojawia się wszędzie. Model Context Protocol — otwarty standard Anthropic do łączenia modeli AI z narzędziami, źródłami danych i zewnętrznymi systemami — stał się cichym fundamentem poważnych architektur agentowych. Nie przez hype, ale dlatego że rozwiązuje realny problem: jak dać agentowi AI niezawodny, kompozycyjny dostęp do świata zewnętrznego bez pisania osobnego kodu integracyjnego dla każdego narzędzia?

To jest przewodnik praktyczny. Budujemy takie systemy. Oto co naprawdę działa.

Czym jest MCP (i czym nie jest)

MCP to protokół, nie framework. Pomyśl o nim jak o HTTP dla komunikacji AI-narzędzie — definiuje, jak host (klient LLM, np. Claude Desktop albo Twoja własna aplikacja) łączy się z serwerami, które eksponują możliwości: narzędzia, zasoby i prompty.

Serwer MCP to lekki proces deklarujący swoje możliwości. Klient MCP (Twój agent) odkrywa te możliwości i je wywołuje. Protokół obsługuje serializację, transport i negocjację możliwości. Ty piszesz logikę biznesową.

Czym MCP nie jest: nie jest usługą chmurową, nie jest vendor lock-in, nie jest magią. Serwer MCP to kod, który Ty (lub społeczność) piszesz i uruchamiasz. Protokół jest otwarty. Implementacje są pod Twoją kontrolą.

Znaczenie tego leży w standaryzacji. Przed MCP każda integracja AI była ad-hoc: własne definicje funkcji, własne schematy JSON, własna obsługa błędów. Z MCP piszesz jeden serwer, a każdy kompatybilny klient może go użyć.

Wzorzec orkiestratora

Wzorzec architektoniczny, który odblokowuje prawdziwą skalę, to orkiestrator: główny agent koordynujący wyspecjalizowane sub-agenty, z których każdy odpowiada za ograniczoną domenę.

Żądanie użytkownika
        │
        ▼
┌─────────────────┐
│   Orkiestrator  │  ← Główny agent (Claude, GPT-4o itp.)
│     Agent       │    Decyduje, które sub-agenty wywołać
└────────┬────────┘    Zarządza stanem konwersacji
         │
    ┌────┴─────┐
    │          │
    ▼          ▼
┌───────┐  ┌───────┐
│Search │  │ Data  │  ← Sub-agenty (wyspecjalizowane serwery MCP)
│ Agent │  │ Agent │    Każdy odpowiada za konkretną domenę
└───────┘  └───────┘
    │          │
    ▼          ▼
 Web/API    Baza danych

Orkiestrator nie wykonuje pracy — deleguje. To jest kluczowe. Gdy wkładasz wszystko w jednego agenta, dostajesz przepełnienie kontekstu, niespójne zachowanie i koszmary debugowania. Gdy rozdzielasz odpowiedzialności między wyspecjalizowane sub-agenty połączone przez MCP, każdy komponent pozostaje skupiony i testowalny.

Wzorzec orkiestratora naturalnie przekłada się też na komunikację A2A (agent-to-agent), gdzie wyjście jednego agenta staje się wejściem drugiego.

Użycie narzędzi: właściwa abstrakcja

Narzędzia MCP to atomowa jednostka możliwości agenta. Każde narzędzie ma nazwę, opis (to czyta LLM decydując, kiedy go użyć) i schemat wejścia. Serwer implementuje handler; klient go wywołuje.

# Definicja narzędzia serwera MCP (uproszczona)
@server.tool()
async def search_documents(
    query: str,
    top_k: int = 5,
    filters: dict | None = None
) -> list[dict]:
    """
    Przeszukaj bazę wiedzy w poszukiwaniu dokumentów pasujących do zapytania.
    Używaj gdy potrzebujesz informacji z wewnętrznych źródeł.
    Zwraca posortowane wyniki z treścią i metadanymi.
    """
    results = await vector_store.search(
        query=query,
        limit=top_k,
        filters=filters
    )
    return [{"content": r.content, "score": r.score, "source": r.source}
            for r in results]

Kilka rzeczy, które łatwo zrobić źle.

Jakość opisu determinuje dokładność wyboru narzędzia. LLM wybiera narzędzie na podstawie opisu. Jeśli opis jest niejasny lub pokrywa się z opisem innego narzędzia, dostajesz nieprzewidywalne zachowanie. Pisz opisy jak dokumentację dla juniora, który nie zna Twojego systemu.

Schematy wejścia powinny być rygorystyczne. Używaj wymaganych pól, enumów gdzie to możliwe i czytelnych opisów pól. Im bardziej ograniczone wejście, tym niezawodniej agent wywoła narzędzie poprawnie.

Zwracaj tylko to, czego agent potrzebuje. Jeśli narzędzie zwraca 2MB JSON, a agent potrzebuje trzech pól, marnujesz kontekst i spowalniasz inferencję. Filtruj po stronie serwera.

Zasoby i prompty

Narzędzia to najbardziej widoczna część MCP, ale zasoby i prompty są równie ważne.

Zasoby to źródła danych, które agent może czytać: pliki, wiersze bazy danych, odpowiedzi API. Są identyfikowane przez URI i mogą być listowane, czytane i subskrybowane. W architekturze orkiestratora zasoby pozwalają sub-agentom eksponować swój stan do orkiestratora bez budowania własnych API odczytu.

Prompty to wielokrotnego użytku szablony promptów, które serwery MCP mogą eksponować. Pozwala to scentralizować logikę systemowych promptów w serwerze MCP, wersjonować ją i serwować spójnie we wszystkich agentach używających serwera.

Jak Jeeves to implementuje

Nasz wewnętrzny projekt Jeeves to agent do automatyzacji biznesowej zbudowany dla produkcji. Stosuje wzorzec orkiestratora z czterema wyspecjalizowanymi sub-agentami, z których każdy działa jako niezależny serwer MCP:

  • Research Agent: wyszukiwanie w sieci, ekstrakcja treści, streszczanie
  • Data Agent: zapytania do bazy danych, generowanie raportów, transformacja danych
  • Calendar Agent: planowanie, koordynacja spotkań, przypomnienia
  • Communication Agent: szkicowanie emaili, wiadomości Slack, routing powiadomień

Orkiestrator to główny agent oparty na Claude, który utrzymuje kontekst konwersacji i decyduje, które sub-agenty wywołać na podstawie intencji użytkownika.

# Przepływ decyzji orkiestratora (pseudokod)

wiadomosc = "Podsumuj sprzedaż z ostatniego tygodnia i zaplanuj spotkanie przeglądowe"

# Orkiestrator identyfikuje wymagane sub-agenty
zadania = orkiestrator.plan(wiadomosc)
# → [
#     Zadanie(agent="data", akcja="pobierz_sprzedaz", params={"okres": "ostatni_tydzien"}),
#     Zadanie(agent="calendar", akcja="znajdz_slot", params={"czas_trwania": 60}),
#     Zadanie(agent="calendar", akcja="stworz_spotkanie", params={"..."}),
# ]

# Wykonaj z rozwiązywaniem zależności
wyniki = await orkiestrator.wykonaj(zadania)

# Zsyntetyzuj i odpowiedz
odpowiedz = orkiestrator.synteza(wyniki)

Kluczowa decyzja architektoniczna: każdy sub-agent jest niezależnie wdrażalny. Gdy Calendar Agent potrzebuje aktualizacji, wdrażamy go ponownie bez dotykania orkiestratora ani innych agentów.

Kwestie produkcyjne

Zarządzanie stanem to Twój problem, nie MCP. Protokół jest bezstanowy per wywołanie. Jeśli Twój agent musi utrzymywać stan między wywołaniami narzędzi (a będzie musiał), potrzebujesz magazynu stanu. Używamy Redis do krótkotrwałego stanu sesji i PostgreSQL do trwałego kontekstu.

Obsługa błędów musi być jawna. Serwery MCP mogą zwracać błędy, ale LLM musi wiedzieć, co z nimi zrobić. Projektuj odpowiedzi błędów jako obiekty strukturalne z kodem, wiadomością i opcjonalnymi wskazówkami ponawiania prób.

Timeouty dla wszystkiego. Wywołania narzędzi w produkcji zawodzą. Sieci się partycjonują. Zewnętrzne API przestają działać. Każdy handler narzędzia powinien mieć jawny timeout i ścieżkę graceful degradation.

Obserwowalność ma większe znaczenie niż myślisz. Loguj każde wywołanie narzędzia z wejściem, wyjściem, czasem trwania i podanym rozumowaniem LLM. Gdy coś pójdzie nie tak — a pójdzie — to jest to, czym debugujesz.

Dlaczego MCP wygrywa długoterminowo

Szczera odpowiedź na pytanie "dlaczego MCP zamiast własnego function calling" to ekosystem. W miarę wzrostu adopcji MCP zyskujesz:

  • Serwery budowane przez społeczność, które możesz wdrożyć w swojej architekturze (są już setki na mcpservers.org)
  • Narzędzia działające we wszystkich hostach kompatybilnych z MCP — zbuduj raz, uruchamiaj w Claude Desktop, swojej aplikacji, pipeline CI
  • Ustandaryzowane bezpieczeństwo i negocjację możliwości, które w przeciwnym razie musiałbyś budować sam

Jesteśmy jeszcze na wczesnym etapie. Protokół będzie ewoluował. Ale zasady architektoniczne — separacja odpowiedzialności, deklaratywne odkrywanie możliwości, kompozycyjna integracja narzędzi — są solidne niezależnie od tego, jak wygląda specyfikacja w wersji 2.0.


Budujemy systemy agentowe oparte na MCP dla klientów B2B w całej Europie. Jeśli oceniasz tę architekturę dla swojego biznesu, skontaktuj się z nami.

Comments

No comments yet. Be the first to comment.

Leave a comment