Strona główna / Artykuły

Czy zaawansowane agenty potrzebują specyficznych modeli? Dema bankowa z LangSmith

LangChain Deep Agents teoretycznie jest niezależny od modeli, ale w praktyce jest wrażliwy na nie. Agent bankowy wyposażony w pięć narzędzi, przeanalizowany za pomocą LangSmith, pokazuje, jakie modele są używane.

Wydawca: REACTAPP.TOP9 min czytania2109 słów

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

Kwestią, która naturalnie nasuwa się przy projektowaniu agentów za pomocą frameworka Deep Agents, jest to, czy do ich prawidłowego funkcjonowania potrzebny jest określony model. Szczera odpowiedź ma dwa aspekty. Pod względem architektonicznym Deep Agents nie ma znaczenia, jaki model używasz. W praktyce jednak wyniki w dużej mierze zależą od wybranego modelu.

Architektonicznie niezależny od modelu

W tym frameworku nic nie jest przypisane do konkretnego modelu, a kod to potwierdza. Można użyć dowolnego modelu do rozmów:

from langchain.chat_models import init_chat_model

# Swap any model in — the harness doesn't care
agent = create_deep_agent(
    model=init_chat_model("openai:gpt-4o"),
    tools=[...],
    system_prompt="..."
)

# Or Anthropic
agent = create_deep_agent(
    model=init_chat_model("anthropic:claude-opus-4-6"),
    tools=[...],
)

# Or Google
agent = create_deep_agent(
    model=init_chat_model("google_vertexai:gemini-2.0-flash"),
    tools=[...],
)

Narzędzie planowania, system plików, tworzenie podagentów oraz szczegółowe instrukcje – te cztery filary są w pełni zaimplementowane na poziomie frameworka. LangGraph dostarcza środowisko wykonawcze, a LLM jest po prostu silnikiem rozumowania podłączonym do tego układu.

Prawie w pełni zależne od modelu

Framework opiera się na zachowaniach, które nie są przez wszystkie modele realizowane w równym stopniu.

  • Niezawodne wywoływanie narzędzi. Cały proces zależy od tego, czy model wywołuje narzędzia we właściwym formacie i z poprawnymi argumentami. Słabsze modele wymyślają nazwy narzędzi, przekazują niewłaściwe typy parametrów lub pomijają wywołanie i odpowiadają prozą.
  • Przestrzeganie długich instrukcji systemowych. Wbudowane instrukcje są długie. Nakazują one modelowi najpierw zaplanować działania, użyć listy zadań, izolować kontekst w podagentach oraz sprawdzić własną pracę. Modele, które słabo przestrzegają instrukcji, odchodzą od nich w trakcie wykonywania zadania.
  • Koherencja na wielu etapach. Podczas długich procesów z licznymi wywołaniami narzędzi model musi pamiętać, co robi, co zostało zakończone i co następuje dalej. Mniejsze lub słabsze modele tracą wątek rozumowania.
  • Wiedza, kiedy przestać. Dobrze zaprogramowany agent zauważa, gdy ma już wystarczająco informacji, i kończy pracę. Źle skalibrowane modele zatrzymują się zbyt wcześnie lub wchodzą w nieskończony błąd.
  • Mniej więcej, gdzie plasują się modele

    Wyniki są niestabilne: częste błędy w formacie narzędzi, odchylenia w realizacji zadań i przedwczesne zakończenie pracy
    Poziom modelu Zachowanie z zaawansowanym agentem
    Modele najwyższej klasy Niezawodne używanie narzędzi, realizacja złożonych zadań, utrzymanie koherencji przy długich procesach
    Mocne modele średniego poziomu Dobre do większości zadań, z rzadkimi problemami przy bardzo długich sekwencjach
    Mniejsze lub modele otwarte

    Nazwy poziomów to przykłady z czasu pisania tekstu, a rankingi modeli szybko się zmieniają, dlatego sprawdź je na własnych zadaniach.

    Główne wnioski

    Pomyśl o karoserii samochodu wyścigowego z wymiennym silnikiem: cokolwiek zainstalujesz, maksymalna prędkość jest określana przez silnik. Układ wspomagający zapewnia strukturę: planowanie, pamięć, podagenty i ścieżki działania. Model dostarcza umiejętności prawidłowego wykorzystania wszystkich tych elementów. W celach produkcyjnych, szczególnie w banku, gdzie sfabrykowana lista bankomatów lub zmyślony pracownik ds. inwestycji może spowodować poważne szkody, należy używać modeli najwyższej jakości i nie oszczędzać na ich jakości.

    Czas zacząć coś budować

    Dosyć teorii. Dokumentacja bez uruchamiania kodu to dobrze znany żart: dwieście stron dokumentacji, piętnaście diagramów, dopracowany plik README, a nic, co faktycznie działa. Dlatego oto działająca demonstracja z pięcioma narzędziami bankowymi i danymi symulacyjnymi.

    Szybki start

    Stwórz klucz API w konsoli Anthropic, a następnie utwórz projekt:

    mkdir firstdeepagent && cd firstdeepagent
    uv add deepagent anthropic
    export ANTHROPIC_API_KEY='asdkjfbaepiufas;dkjcnaisdf'
    touch agent.py bank_tools.py mock_data.py
    

    Ty polecenia tworzą folder, instalują pakiety, eksportują klucz (użyj swojego rzeczywistego klucza, nigdy takiego, który został zapisany) oraz tworzą trzy pliki. Narzędzia do bank_tools.py to:

    from mock_data import (OFFICERS_DATA, PORTFOLIO_DATA, ATM_DATA,
                           RETIREMENT_DATA, LOCATIONS_DATA)
    
    def get_atm_centers(zipcode: str) -> dict:
        data = ATM_DATA.get(str(zipcode).strip())
        if not data:
            return {
                "error": f"No ATM data for zipcode '{zipcode}'.",
                "available_zipcodes": list(ATM_DATA.keys()),
            }
        return {"zipcode": zipcode, "atm_centers": data, "total": len(data)}
    
    
    def get_investment_officers(city: str) -> dict:
        key = city.strip().lower()
        data = OFFICERS_DATA.get(key)
        if not data:
            return {
                "error": f"No investment officers found in '{city}'.",
                "available_cities": [c.title() for c in OFFICERS_DATA],
            }
        return {"city": city, "officers": data, "total": len(data)}
    
    
    def get_portfolio_companies(sector: str = "all") -> dict:
        companies = PORTFOLIO_DATA
        if sector and sector.lower() != "all":
            companies = [c for c in companies if sector.lower() in c["sector"].lower()]
        return {"companies": companies, "total": len(companies), "total_aum": "$6.35B"}
    
    
    def get_retirement_plans(plan_type: str = "all") -> dict:
        plans = RETIREMENT_DATA
        if plan_type and plan_type.lower() != "all":
            plans = [
                p for p in plans
                if plan_type.lower() in p["name"].lower() or plan_type.lower() in p["type"].lower()
            ]
        return {"plans": plans, "total": len(plans)}
    
    
    def get_bank_locations(city: str = "all") -> dict:
        locations = LOCATIONS_DATA
        if city and city.lower() != "all":
            locations = [l for l in locations if city.lower() in l["city"].lower()]
        total_branches = sum(l["branches"] for l in locations)
        return {"locations": locations, "total_branches": total_branches}
    

    Moduł mock_data zawiera przykładowe rekordy, natomiast moduł tools-config przechowuje schematy narzędzi, mapowanie nazw na funkcje oraz komunikat systemowy. Trzymaj je w oddzielnych plikach, aby kod agenta pozostał niewielki. Główny pętla w agent.py wygląda następująco:

    import os
    import json
    import anthropic
    from tools_config import TOOL_SCHEMAS, TOOL_FN_MAP, SYSTEM_PROMPT
    
    
    def run_agent(client: anthropic.Anthropic, conversation: list[dict]) -> str:
        MAX_ITERATIONS = 10
        messages = list(conversation)
    
        for _ in range(MAX_ITERATIONS):
            response = client.messages.create(
                model="claude-sonnet-4-6",
                max_tokens=2048,
                system=SYSTEM_PROMPT,
                tools=TOOL_SCHEMAS,
                messages=messages,
            )
    
            tool_use_blocks = [b for b in response.content if b.type == "tool_use"]
    
            if not tool_use_blocks:
                text_parts = [b.text for b in response.content if b.type == "text"]
                return "\n".join(text_parts).strip()
    
            tool_results = []
            for block in tool_use_blocks:
                fn = TOOL_FN_MAP.get(block.name)
                result = fn(**block.input) if fn else {"error": f"Unknown tool: {block.name}"}
                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": json.dumps(result),
                })
    
            messages.append({"role": "assistant", "content": response.content})
            messages.append({"role": "user",      "content": tool_results})
    
        return "[Max iterations reached — partial answer may be incomplete.]"
    
    
    def main():
        api_key = os.environ.get("ANTHROPIC_API_KEY")
        if not api_key:
            print("Error: ANTHROPIC_API_KEY environment variable not set.")
            print("  export ANTHROPIC_API_KEY=your_key_here")
            raise SystemExit(1)
    
        client = anthropic.Anthropic(api_key=api_key)
        conversation: list[dict] = []
    
        print("XYZ Bank Agent — type 'quit' to exit.\n")
    
        while True:
            try:
                user_input = input("You > ").strip()
            except (EOFError, KeyboardInterrupt):
                print("\nGoodbye!")
                break
    
            if not user_input:
                continue
            if user_input.lower() in {"quit", "exit", "q"}:
                print("Goodbye!")
                break
    
            conversation.append({"role": "user", "content": user_input})
            answer = run_agent(client, conversation)
            conversation.append({"role": "assistant", "content": answer})
    
            print(f"\n{answer}\n")
    
    
    if __name__ == "__main__":
        main()
    

    Ruch w aplikacji

    Upewnij się, że klucz został wyeksportowany, a następnie uruchom agenta za pomocą uv run agent.py. Przykładowa sesja:

    XYZ Bank Agent — type 'quit' to exit.
    
    You > Who are the investment officers in Chicago? Also what retirement plans do you offer?
    
    Here's everything you need!
    
    ---
    
    ## 👔 Investment Officers in Chicago
    
    | Name | Title | Specialty | Phone | Email |
    |---|---|---|---|---|
    | **Margaret Chen** | Senior Investment Officer | Equities & ETFs | 312-555-0101 | m.chen@xyzbank.com |
    | **David Okafor** | Investment Officer | Fixed Income | 312-555-0182 | d.okafor@xyzbank.com |
    | **Sarah Kowalski** | Wealth Manager | Retirement Planning | 312-555-0147 | s.kowalski@xyzbank.com |
    
    ---
    
    ## 🏦 Retirement Plans Offered by XYZ Bank
    
    1. **XYZ Gold 401(k)**
       - Min. Contribution: $50/month | Employer match up to 6%
       - Features: Roth option, target date funds, low expense ratios
    
    2. **XYZ Silver IRA (Traditional)**
       - Min. Contribution: $25/month
       - Features: Tax-deferred growth, flexible contributions, 600+ fund choices
    
    3. **XYZ Roth IRA**
       - Min. Contribution: $25/month
       - Features: Tax-free withdrawals, no required minimum distributions, estate planning benefits
    
    4. **XYZ Executive SEP-IRA**
       - Contribute up to 25% of income
       - Features: High contribution limits, self-employed friendly, simple administration
    
    ---
    
    If you'd like to learn more about any of these plans or get in touch with one of our Chicago investment officers (especially **Sarah Kowalski**, who specializes in retirement planning!), feel free to ask! 😊
    
    You >
    

    Agent dzieli prośbę na konkretne kroki, wybiera odpowiednie narzędzia, je uruchamia i zbiera wyniki. Jeśli pomocne jest mapowanie mentalne, sekwencja wygląda tak: zadanie, planowanie, wywołania narzędzi, zebrane wyniki, ostateczna odpowiedź.

    Obserwowalność

    Taki system wymaga telemetryki, dlatego należy dodać LangSmith. Integracja jest prosta: dwa zmienne środowiskowe i około trzech linijek kodu. LangSmith otacza istniejące wywołania zamiast je zastępować.

    Ten skrypt bezpośrednio wywołuje Anthropic SDK, a nie LangChain, więc aby uzyskać bardziej szczegółowe ślady działania, można opcjonalnie ozdobić funkcję run_agent() adnotacją @traceable:

    from langsmith import traceable
    
    @traceable(name="xyz-bank-agent-run")
    def run_agent(client, conversation):
       ....................
       ....................
    

    Każde wezwanie narzędzia, decyzja modelu, liczba tokenów oraz opóźnienie pojawiają się w panelu sterowania LangSmith, bez konieczności modyfikacji pętli agenta. Uruchom to ponownie z bardziej złożonym pytaniem:

    uv run agent.py
    XYZ Bank Agent — type 'quit' to exit.
    
    You > Show ATMs in 10001, investment officers in New York, and all branch locations
    
    Here's a complete overview across all three categories:
    
    ---
    
    ## 🏧 ATMs in ZIP Code 10001
    
    | ATM Name | Address | Hours | Fee |
    |---|---|---|---|
    | Midtown Manhattan ATM | 350 5th Ave | 24/7 | No fee |
    | Penn Station ATM | 8 W 31st St | 24/7 | $2.50 (non-members) |
    
    ---
    
    ## 💼 Investment Officers — New York
    
    1. **James Thornton** — Chief Investment Officer
       - Specialty: Alternative Assets
       - 📞 212-555-0201 | ✉️ j.thornton@xyzbank.com
    
    2. **Priya Nair** — Investment Officer
       - Specialty: ESG Portfolios
       - 📞 212-555-0233 | ✉️ p.nair@xyzbank.com
    
    ---
    
    ## 🏦 All Branch Locations (61 Branches Nationwide)
    
    | City | Branches | Flagship Address | Hours |
    |---|---|---|---|
    | Chicago | 14 | 200 W Adams St, Chicago IL 60606 | Mon–Fri 9am–5pm, Sat 9am–1pm |
    | New York | 22 | 1 World Trade Center, NY 10007 | Mon–Fri 8am–6pm, Sat 9am–2pm |
    | Los Angeles | 11 | 333 S Grand Ave, LA 90071 | Mon–Fri 9am–5pm, Sat 9am–1pm |
    | Houston | 8 | 1000 Main St, Houston TX 77002 | Mon–Fri 9am–5pm |
    | Boston | 6 | 100 Federal St, Boston MA 02110 | Mon–Fri 9am–5pm, Sat 10am–1pm |
    
    ---
    
    Is there anything else you'd like to explore, such as retirement plans or our investment portfolio? 😊
    
    You > What companies are in XYZ Bank's portfolio? List only Technology sector companies
    
    Here are the **Technology sector companies** in XYZ Bank's investment portfolio:
    
    ---
    
    ## 💻 Technology Portfolio Companies
    
    | Company | Stake | Value | Rating |
    |---|---|---|---|
    | **Apex Technologies Inc.** | 4.2% | $840M | A+ |
    | **Sentinel Cybersecurity** | 7.3% | $1.5B | A+ |
    
    ---
    
    ### 📊 Summary
    - **Total Technology Holdings:** 2 companies
    - **Total Portfolio AUM:** $6.35B
    - Both companies carry an **A+ rating**, reflecting strong investment quality.
    
    ---
    
    Would you like to explore other sectors, view the full portfolio, or learn about our investment officers? Let me know! 😊
    
    You >
    

    Następnie otwórz stronę LangSmith i sprawdź nagrane wykonywania. Każde z nich przedstawia swoje kroki wraz z danymi wejściowymi, wyjściowymi, czasem trwania i błędami.

    Pakiet darmowy

    W momencie pisania ten plan jest bezpłatny – umożliwia 5 000 śledzeń miesięcznie i nie wymaga karty kredytowej. Obejmuje pełne śledzenie i debugowanie każdego kroku, w tym dane wejściowe, wyjściowe, opóźnienia, użycie tokenów i błędy, a także pole do szybkiego testowania. Jest ograniczony do jednego konta i jednego przestrzeni roboczej, z przechowywaniem śledzeń przez 14 dni – co nadaje się do tworzenia indywidualnych prototypów i dowodów koncepcyjnych. LangSmith informuje, że nie trenuje modeli na twoich śledzeniach, które pozostają prywatne dla twojej organizacji. Sprawdź aktualne plany przed poleganiem na tych ograniczeniach.

    Krótko mówiąc, zacznij od wersji darmowej. Nie kosztuje nic, jej konfiguracja trwa około 15 minut, a od razu pokazuje każde wezwanie narzędzia i podjętą decyzję. Przejdź na wyższą wersję dopiero wtedy, gdy ruch produkcyjny się zwiększy.

    Co robić dalej

    • Zastąp dane symulacyjne prawdziwymi źródłami, takimi jak system bankowości core, CRM czy wewnętrzne API.
    • Zbuduj hierarchię, w której orkiestrator gateway kieruje żądania do agentów domenowych.
    • Dodaj zasady bezpieczeństwa, które uprzejmie odrzucają pytania poza zakresem i przekazują je do ludzi.
    • Zachowuj historię rozmów pomiędzy kolejnymi krokami za pomocą Redis lub bazy danych.
    • Dodaj pamięć między sesjami, aby zapamiętywać wcześniejsze zapytania i preferencje powracających użytkowników.
    • Ustal limity szybkości i budżety tokenów dla każdego użytkownika i sesji.
    • Zbuduj zestaw oceny składający się z 30 do 50 reprezentatywnych zapytań wraz z oczekiwanymi wynikami.
  • Uruchamiaj ponownie ten zestaw eval za każdym razem, gdy zmienia się kod lub polecenia, aby wcześnie wykryć ukryte regresje.
  • Dodawaj każdą nową domenę jako oddzielnego agenta, zarejestrowanego przez bramkę.
  • Literatura pokrewna