Strona główna / Artykuły

Deep Agents w LangChain: planowanie, podagenty i bramka bankowa

W jaki sposób DeepAgents wykorzystują planowanie, system plików oraz podagenty w pętli narzędziowej, w czym różnią się od ReAct oraz jak rozdzielać narzędzia pomiędzy agentami dziedzinowymi za bramką.

Wydawca: REACTAPP.TOP9 min czytania2002 słów

Źródła: Beyond Simple Agents: Engineering DeepAgents for Enterprise with LangChain

Wiele zespołów może zatrudnić agenta pracującego na laptopie. Znacznie mniej z nich potrafi utrzymać takiego agenta w użyciu w rzeczywistych zastosowaniach, i to właśnie w tym rozdźwięku powstają zaawansowane agenci. To nie jest tylko modny termin – to odpowiedź na konkretną ograniczoność: prosty cykl wywoływania narzędzi zawodzi, gdy praca staje się długa, składająca się z wielu elementów lub skomplikowana.

Ograniczenia prostego cyklu

Najprostszym agentem jest LLM działający w cyklu i wywołujący różne narzędzia. Taki agent jest zazwyczaj powierzchowny, co oznacza, że nie potrafi planować długotrwałych zadań ani sprostać skomplikowanym, wieloetapowym procesom. Dobrze radzi sobie z pojedynczym pytaniem, ale napotyka trudności przy zadaniach większej skali.

Produkty takie jak Deep Research, Manus i Claude Code poradziły sobie z tym dzięki czterem elementom: narzędziu do planowania, podagentom, systemowi plików oraz szczegółowemu poleceniu. Projekt deepagents powstał w wyniku próby zrozumienia, co sprawia, że Claude Code jest tak uniwersalny, oraz dalszego rozwijania tej koncepcji. LangChain nazywa takie agenty „deep agents”, ponieważ potrafią one planować złożone zadania i wykonywać je przez dłuższy czas. W praktyce jest to sposób LangChain na stworzenie autonomicznych agentów w stylu Claude Code, które potrafią radzić sobie z rzeczywistymi, wieloetapowymi zadaniami, a nie tylko jednorazowymi pytaniami.

deepagents to samodzielna biblioteka stworzona na bazie podstawowych elementów budujących agenty w LangChain i działająca w środowisku LangGraph, które zapewnia trwałe wykonywanie zadań, transmisję danych w czasie rzeczywistym oraz możliwość udziału człowieka w procesie. Dobrym opisem jest „uprząż dla agenta”: ten sam cykl wywoływania narzędzi co w innych frameworkach, ale wzbogacony o dodatkowe wbudowane narzędzia i funkcje.

Cztery składniki

Planowanie. Wbudowane narzędzie write_todos umożliwia agentowi podzielenie dużego zadania na pojedyncze kroki, śledzenie postępów oraz modyfikację planu w miarę pojawiania się nowych informacji.

System plików do przechowywania kontekstu. Narzędzia takie jak ls, read_file, write_file i edit_file umożliwiają agentowi przechowywanie obszernego kontekstu w pamięci lub na dysku, dzięki czemu okno kontekstu nie przepełnia się i można obsłużyć wyniki narzędzi dowolnej wielkości. Starsze wiadomości są automatycznie podsumowywane, gdy rozmowa staje się zbyt długa.

Podagenty. Wbudowane narzędzie do zadań tworzy specjalistycznych podagentów z izolowanym kontekstem. Główny agent pozostaje uporządkowany, podczas gdy pomocnik skupia się na konkretnym zadaniu.

Długie instrukcje systemowe. Instrukcje odbudowane z Claude Code są długie i zawierają szczegółowe wskazówki dotyczące używania narzędzi oraz przykłady z kilkoma scenariuszami pokazującymi, jak postępować w konkretnych sytuacjach. Bez nich te agenty byłyby znacznie mniej skuteczne. Instrukcje nadal odgrywają kluczową rolę.

Jego miejsce w stacku LangChain

Istnieją trzy warstwy, z których każda opiera się na tej poniżej. LangGraph to środowisko działania agentów, odpowiednie do łączenia różnych procesów roboczych i agentów. LangChain to framework dla agentów, przydatny do korzystania z podstawowego cyklu działania oraz tworzenia promptów i narzędzi od zera. Deep Agents to zestaw narzędzi służący do tworzenia autonomicznych agentów działających przez długi czas, które korzystają z wbudowanego planowania, systemu plików oraz innych dodatkowych funkcji. Ten zestaw jest zbudowany na abstrakcji agentów z LangChain, która z kolei opiera się na LangGraph.

Przykład z bankowości

Załóżmy, że bank udostępnia pięć narzędzi specjalistycznych: wyszukiwanie bankomatów według kodu pocztowego, wyświetlanie listy specjalistów od inwestycji w danym mieście, pobieranie informacji o firmach z portfela inwestycyjnego banku, dostarczanie szczegółów na temat planów emerytalnych oraz wyszukiwanie oddziałów w różnych regionach. Każde z tych narzędzi dobrze radzi sobie z jednym, określonym zadaniem. Problemy pojawiają się, gdy użytkownik prosi o coś, co wymaga jednoczesnego wykorzystania kilku z tych narzędzi:

Czy może Pan podać listę punktów obsługi bankomatami XYZ Bank wraz z firmami znajdującymi się w jego portfelu inwestycyjnym, a także informacje o lokalizacjach pracowników ds. inwestycji w Chicago?

Odpowiedź na to pytanie wymaga wykrycia kilku intencji w jednej prośbie, wyboru i skoordynowania odpowiednich narzędzi, utrzymania kontekstu w różnych domenach danych oraz połączenia wszystkich wyników w jedną spójną odpowiedź. Architektury zaprojektowane do procesów jednoetapowych lub liniowych często zawodzą w takich sytuacjach. Właśnie do tego stworzono zaawansowane agenty.

Sekwencja działa w następujący sposób.

  1. Planowanie. Główny koordynator analizuje złożone pytanie i używa funkcji write_todos, aby podzielić je na trzy zadania: uzyskanie listy punktów obsługi bankomatami, pozyskanie informacji o firmach z portfela inwestycyjnego oraz znalezienie lokalizacji pracowników w Chicago.
  • Tworzenie agentów. Zamiast przetwarzać wszystkie trzy zadania sekwencyjnie w jednym rozbudowanym kontekście, uruchamia trzy podagenty – po jednym na zadanie – z których każdy ma własne okno kontekstowe, dzięki czemu nie wpływają na siebie.
  • Wywoływanie narzędzi. Każdy podagent używa dokładnie odpowiedniego z pięciu narzędzi: get_atm_centers(zipcode=...), get_trusted_portfolio_companies() oraz get_investment_officers(city="Chicago").
  • Synteza. Wyniki są przekazywane z powrotem do orkiestratora, który łączy je w jedną dobrze sformatowaną odpowiedź i odznacza zadania jako zakończone.
  • Prosty agent do wywoływania narzędzi obsługiwałby wszystkie trzy zadania kolejno w ramach jednego kontekstu. Mógłby zapomnieć o wcześniejszych wynikach, stracić poczucie, na jakie pytanie odpowiada, lub osiągnąć limit kontekstu. Zaawansowany agent trzyma poszczególne zadania oddzielnie i śledzi postępy w liście zadań do wykonania, dzięki czemu nawet jeśli jedno wywołanie się nie powiedzie lub zwróci tylko część danych, koordynator wie, w jakim jest stanie.

    Struktura jest prosta:

    from deepagents import create_deep_agent
    
    agent = create_deep_agent(
        tools=[
            get_atm_centers,         # your ATM tool
            get_investment_officers, # your officers tool
            get_portfolio_companies, # your portfolio tool
            get_retirement_plans,    # your retirement tool
            get_bank_locations,      # your locations tool
        ],
        system_prompt="You are XYZ Bank's AI assistant. Always answer completely and cite sources."
    )
    
    result = agent.invoke({"messages": [{"role": "user", "content": "Can you give me a list of ATM centers for XYZ bank and also list the name of companies XYZ has in its investment portfolio? Also can you give me the location of XYZ investment agents in Chicago?"}]})
    

    Agent decyduje, jakie narzędzia wywołać, w jakiej kolejności oraz jak połączyć uzyskane wyniki. Nie musisz sam piszeć logiki routingu, a to jest prawdziwa wartość tego rozwiązania.

    ReAct wobec zaawansowanych agentów, gdy brakuje narzędzia

    Weźmy tę samą prośbę i dodajmy czwarte pytanie, na które nie istnieje żadne narzędzie: lista opcji kart kredytowych dla studentów. Oto jak każdy z tych podejść radzi sobie z tym zadaniem.

    Agent głęboki sprawdza swój rejestr narzędzi i tworzy listę zadań do wykonania przed podjęciem działań, dzięki czemu od razu widzi, że nie ma żadnego narzędzia do obsługi kart kredytowych. Uruchamia podagenty do trzech zadań, które wykonywane są równolegle i kończą się pomyślnie, oznacza pozycję dotyczącą karty kredytowej jako „brak dostępnych narzędzi” i zwraca jedną syntetyczną odpowiedź. Ta odpowiedź w pełni odpowiada na wszystkie trzy pytania i jasno informuje użytkownika, że nie skonfigurowano żadnego narzędzia do obsługi kart kredytowych i że może być konieczne jego dodanie. Nic się nie psuje, a częściowy sukces jest dokładnie zgłaszany.

    ReAct, skrót od Reasoning plus Acting, postępuje zgodnie z ścisłym cyklem Myśl, Działanie, Obserwacja, krok po kroku, bez wcześniejszego planu. To powoduje trzy problemy:

    • Działa sekwencyjnie – najpierw bankomaty, potem portfel, a następnie pracownicy. Problem z kartami kredytowymi pojawia się dopiero na końcu, po zakończeniu wszystkich pozostałych działań.
  • Nigdy nie skanuje dostępnych narzędzi. Znajduje to, którego brakuje, w trakcie wykonywania zadania, gdy próbuje je użyć, a w zależności od modelu LLM i implementacji może się zatrzymać, spróbować ponownie z wymyślonym nazwą narzędzia lub, co najgorsze, stworzyć wiarygodną listę kart kredytowych, ponieważ oczekuje istnienia odpowiedzi.
  • Ponieważ błąd występuje w środku pętli, nic nie gwarantuje, że trzy wcześniejsze wyniki dotrą do użytkownika w nienaruszonej formie. Agent może po prostu napotkać błąd i nic nie zwrócić.
  • ReAct nadaje się do krótkich, dobrze zdefiniowanych zadań, w których wiadomo, że wszystkie narzędzia istnieją. Agenci typu Deep są przeznaczone dla bardziej skomplikowanego świata rzeczywistego, gdzie pytania są złożone, narzędzia mogą być nieobecne, a mimo to chce się osiągnąć jak największą wartość z tego, co się ma.

    Pytanie projektowe: jeden agent ze wszystkimi narzędziami?

    Czy to oznacza, że powinniśmy stworzyć wiele narzędzi i udostępnić je wszystkie za pośrednictwem jednego agenta? Nie. Jeden agent zawierający 50 lub więcej narzędzi stanowi antypatern. Lepszym rozwiązaniem jest hierarchia agentów. Wyobraź sobie agenta, którego konfiguracja wymienia setki narzędzi – od wyszukiwania w internecie i e-maili po rezerwację lotów i starty rakiet – z poleceniem „sam to rozwiąż”. Może to czasami zadziałać, a od czasu do czasu odpowiada na skargi dotyczące opóźnionych dostaw, rezerwując lot, składając podatki i zamawiając pizzę. Nikt tego nie chce.

    Własność domeny

    Główną zasadą jest to, że każdy agent domeny zarządza małą, spójną grupą narzędzi – idealnie od trzech do pięciu – pochodzących z jednej dziedziny biznesowej. Agent bramkowy nigdy nie dotyka narzędzi; jedynie odczytuje intencję, kieruje ją do odpowiedniego agenta domeny i łączy uzyskane odpowiedzi. To ta sama separacja zadań, którą stosuje się w mikrosługach.

    W przypadku bankowości naturalny podział jest następujący:

    • Agent oddziału i bankomatu z metodami get_atm_centers oraz get_bank_locations, odpowiadający za lokalizację fizyczną: kody pocztowe, miasta, godziny otwarcia.
    • Agent ds. inwestycji z metodami get_portfolio, get_officers oraz get_retirement_plans, zajmujący się zarządzaniem finansami, w tym przepisami prawnymi, certyfikatami pracowników i typami planów emerytalnych.
    • Agent produktów z metodą get_credit_cards, gdy taka istnieje, a także produktami kredytowymi i kontami oszczędnościowymi, odpowiadający za katalog produktów. Gdy brakuje jakiegoś narzędzia, tylko ten agent zgłasza tę lukę, a pozostali kontynuują pracę bez zmian.

    Kod odzwierciedla tę strukturę:

    from deepagents import create_deep_agent
    # Each domain agent is self-contained
    branch_agent = create_deep_agent(
        tools=[get_atm_centers, get_bank_locations],
        system_prompt="You are the Branch & ATM specialist for XYZ Bank..."
    )
    investments_agent = create_deep_agent(
        tools=[get_portfolio, get_officers, get_retirement_plans],
        system_prompt="You are the Investments specialist for XYZ Bank..."
    )
    products_agent = create_deep_agent(
        tools=[get_credit_cards],  # sparse now, grows over time
        system_prompt="You are the Products specialist for XYZ Bank..."
    )
    # Gateway knows nothing about tools — only about agents
    gateway = create_deep_agent(
        tools=[
            branch_agent.as_tool(name="branch_atm_agent"),
            investments_agent.as_tool(name="investments_agent"),
            products_agent.as_tool(name="products_agent"),
        ],
        system_prompt="""You are the XYZ Bank assistant gateway.
        Parse the user's intent, delegate to the right domain agent(s),
        and synthesize a unified response. Never answer directly — always route."""
    )
    

    Dlaczego to działa skutecznie

    Gdy bank dodaje nowe funkcje, brama i inne agenty domenowe pozostają niezmienione. Można dodać narzędzie do odpowiedniego agenta domenowego lub stworzyć nowy, np. do obsługi pożyczek lub zwalczania oszustw, i zarejestrować go w bramie. Każda zmiana dotyczy tylko jednej domeny.

    Porównaj to z „lasem narzędzi”. Agent posiadający 30 takich narzędzi nie ma świadomości swojej domeny i może wywołać funkcję get_retirement_plans podczas odpowiadania na pytanie o godziny pracy bankomatu, po prostu dlatego, że obie te czynności należą do jego zakresu działania. Agenci domenowi unikają tego, nadając każdemu z nich precyzyjną tożsamość poprzez specjalne instrukcje systemowe oraz zestaw narzędzi. Agent, który wie, kim jest, podejmuje bardziej trafne decyzje w swojej specyficznej dziedzinie.

    Potrzebny test: jeśli spierasz się o to, czy dany narzędzie należy do agenta A, czy do agenta B, oznacza to albo, że narzędzie robi zbyt wiele i powinno zostać podzielone, albo że potrzebny jest trzeci domen. Granica ta powinna być tak oczywista, jak wiedza o tym, czy pytanie skierować do kierownika oddziału, czy do doradcy inwestycyjnego.

    Otwarte pytania

    Pozostają dwie kwestie: czy zaawansowani agenci w dużej mierze zależą od wyboru podstawowego modelu oraz czy można z ich pomocą stworzyć kompletną rozwiązanie end-to-end. Odpowiedź na drugie pytanie brzmi „tak”, a naturalnym następnym krokiem jest praktyczne zbudowanie tego scenariusza bankowego.

    Powiązane materiały

  • Notatki praktyczne: Graph RAG w działaniu – Dlaczego standardowy RAG zawodzi przy złożonych zapytaniach — Szczegółowy przewodnik po Notatkach praktycznych: Graph RAG w działaniu – Dlaczego standardowy RAG zawodzi przy złożonych zapytaniach: kontrakty, sprawdzenia oraz gotowe elementy kodu dla zespołów wdrażających ten model.
  • Dziewięć nawyków inżynierskich przy tworzeniu pierwszego agenta AI — Dziewięć nawyków, które zapobiegają awariom agentów w środowisku produkcyjnym: ocena najpierw, ograniczenia kontekstu, limity autonomii, śledzenie działań, wersjonowanie promptów, szacowanie kosztów oraz triaż błędów.
  • Czy Deep Agents potrzebują specyficznych modeli? Demo bankowe z LangSmith — Deep Agents jest w swojej architekturze niezależny od modeli, ale w praktyce jest wrażliwy na nie. Stwórz agenta bankowego wyposażonego w pięć narzędzi i dodaj śledzenie działania LangSmith, aby zobaczyć każdy krok.
  • Pobieranie informacji z rodzin dowodów: zapewnienie, by kontekst RAG obejmował każdą część pytania — Metoda pobierania typu Top-k może zwrócić pięć istotnych fragmentów, a mimo to pominąć połowę odpowiedzi. Planowanie rodzin dowodów, wyszukiwanie awaryjne oraz ponowna sortowanie pomagają wypełnić tę lukę.