Lab 09: Connected Agents - Orkiestracja multi-agent

Opis

W tym laboratorium poznasz architekturę multi-agent z głównym agentem jako orchestratorem delegującym zadania do wyspecjalizowanych sub-agentów. Zbudujesz system, gdzie jeden agent koordynuje pracę innych agentów, z których każdy ma swoją specjalizację.

Co zbudujesz:

  • Orchestrator Agent - główny koordynator (bez własnych tools)
  • KRS Agent - specjalista od Krajowego Rejestru Sądowego (reużycie z Lab 04)
  • Company API Agent - specjalista od lokalnej bazy firm (NOWY)

Use case: Użytkownik podaje numer KRS firmy → Orchestrator pobiera dane z rejestru (KRS Agent) → zapisuje firmę do lokalnej bazy (Company API Agent) → potwierdza operację.


Wprowadzenie: Dlaczego multi-agent?

Problem pojedynczego agenta

Kiedy agent ma zbyt wiele odpowiedzialności:

  • ❌ Trudny w utrzymaniu (długie instructions)
  • ❌ Ciężko testować (wiele tools w jednym miejscu)
  • ❌ Brak reusability (nie można użyć części logiki w innym kontekście)
  • ❌ Context overload (za dużo informacji w jednym prompcie)

Rozwiązanie: Connected Agents

Connected Agents to pattern gdzie:

  • Main Agent (Orchestrator): Koordynuje pracę, nie ma własnych tools
  • Sub-Agents: Wyspecjalizowani agenci, każdy odpowiada za jedną domenę
  • Separation of Concerns: Jasny podział odpowiedzialności
  • Reusability: Sub-agentów można użyć w różnych orchestratorach

Korzyści:

  • Modularność (każdy sub-agent = osobny komponent)
  • Łatwiejsze testowanie (test każdego sub-agenta osobno)
  • Reużywalność (ten sam KRS Agent w różnych scenariuszach)
  • Przejrzystość (clara responsibility boundaries)

Architektura systemu

graph TD
    User[👤 User] --> Orch[🎯 Orchestrator Agent<br/>GPT-4.1-mini<br/>Coordinator - no tools]

    Orch -->|"Delegates:<br/>Get company from KRS"| KRS[🏢 KRS Agent<br/>GPT-4.1-mini<br/>Registry specialist]
    Orch -->|"Delegates:<br/>Save/retrieve companies"| API[💾 Company API Agent<br/>GPT-4.1-mini<br/>Database specialist]

    KRS -->|Uses| KRSAPI[🔌 KRS API<br/>API Management<br/>External registry]
    API -->|Uses| CompanyAPI[🔌 Company API<br/>API Management<br/>Internal database]

    KRS -->|Returns data| Orch
    API -->|Returns data| Orch
    Orch -->|Final response| User

    style Orch fill:#4A90E2,stroke:#2E5C8A,color:#fff
    style KRS fill:#50C878,stroke:#2E7D4E,color:#fff
    style API fill:#9B59B6,stroke:#6C3483,color:#fff
    style User fill:#E8E8E8,stroke:#666,color:#333
    style KRSAPI fill:#F39C12,stroke:#C87F0A,color:#fff
    style CompanyAPI fill:#F39C12,stroke:#C87F0A,color:#fff

Komponenty systemu

1. Orchestrator Agent (Main Agent)

  • Model: GPT-4.1-mini
  • Rola: Koordynacja i routing zapytań użytkownika
  • Tools: TYLKO ConnectedAgentTool (nie ma własnych API tools!)
  • Odpowiedzialność: Zrozumienie intencji użytkownika i delegacja do odpowiedniego sub-agenta

2. KRS Agent (Sub-Agent)

  • Model: GPT-4.1-mini
  • Rola: Specjalista od Krajowego Rejestru Sądowego
  • Tools: OpenAPI Tool → KRS API (getKrsOdpisAktualny)
  • Odpowiedzialność: Pobieranie danych firm z rejestru KRS

3. Company API Agent (Sub-Agent)

  • Model: GPT-4.1-mini
  • Rola: Specjalista od lokalnej bazy firm
  • Tools: OpenAPI Tool → Company API (GET/POST/PATCH/DELETE /companies)
  • Odpowiedzialność: Zarządzanie firmami w lokalnej bazie danych

Company API - Nasza lokalna baza firm

Company API to REST API na Azure API Management które zarządza lokalną bazą danych firm.

Endpoints

Method Endpoint Operacja Opis
GET /companies get-companies Lista wszystkich firm w bazie
POST /companies post-companies Dodaj nową firmę (ID auto-generated)
GET /companies/{id} get-companies-id Pobierz firmę po ID
PUT /companies/{id} put-companies-id Upsert - utwórz lub zastąp firmę
PATCH /companies/{id} patch-companies-id Aktualizuj wybrane pola firmy
DELETE /companies/{id} delete-companies-id Usuń firmę po ID

Schema firmy

{
  "id": "string",
  "nazwa": "string",
  "nip": "string",
  "krs": "string",
  "regon": "string",
  "adres": "string"
}

Authentication

Company API używa API Management subscription key:

  • Header: Ocp-Apim-Subscription-Key: <your-key>
  • Query param: subscription-key=<your-key>

Teoria: Jak działają Connected Agents?

Delegation Flow

sequenceDiagram
    participant U as 👤 User
    participant O as Orchestrator Agent
    participant K as KRS Agent
    participant A as Company API Agent
    participant KAPI as KRS API
    participant CAPI as Company API

    U->>O: "Dodaj firmę PKN ORLEN (KRS 0000028860) do bazy"

    Note over O: 1. Analyzes request<br/>2. Decides to delegate<br/>3. Plans workflow

    O->>K: "Retrieve company data for KRS 0000028860"
    activate K
    K->>KAPI: GET /odpis-aktualny?krs=0000028860&rejestr=P
    KAPI-->>K: Returns company data
    K-->>O: {"nazwa": "PKN ORLEN S.A.", "nip": "7740001454", ...}
    deactivate K

    Note over O: Receives data from KRS Agent<br/>Prepares delegation to Company API Agent

    O->>A: "Save company to database with data: {...}"
    activate A
    A->>CAPI: POST /companies<br/>Body: {"nazwa": "PKN ORLEN S.A.", ...}
    CAPI-->>A: {"id": "1", "nazwa": "PKN ORLEN S.A.", ...}
    A-->>O: "Company saved successfully with ID: 1"
    deactivate A

    Note over O: Synthesizes results<br/>from both sub-agents

    O-->>U: "✅ Firma PKN ORLEN S.A. została pobrana z KRS<br/>i zapisana do bazy z ID: 1"

Kluczowe koncepty

1. Delegation (Delegacja)

  • Main Agent NIE wykonuje zadań sam
  • Main Agent DELEGUJE zadania do sub-agentów
  • Sub-agenci zwracają wyniki do Main Agent
  • Main Agent kompiluje wyniki i prezentuje użytkownikowi

2. ConnectedAgentTool

  • Specjalny typ tool w Azure AI Foundry
  • Pozwala jednemu agentowi wywołać drugiego agenta
  • Składnia: {"type": "connected_agent", "connected_agent_id": "sub_agent_id"}

3. Separation of Concerns

  • Każdy sub-agent odpowiada za jedną domenę
  • Sub-agenci nie wiedzą o sobie nawzajem
  • Orchestrator nie ma własnych API tools (tylko ConnectedAgentTool)

Limitations (Ograniczenia)

Ograniczenie Opis Obejście
Max depth = 2 Sub-agent NIE może mieć własnych connected agents Spłaszcz architekturę - usuń poziomy
No citations passthrough Citations z sub-agentów nie są przekazywane do main agent Prompt engineering: poproś sub-agenta o załączenie źródeł w tekście
No function calling Local Python functions nie działają jako tools w sub-agentach Użyj OpenAPI Tool lub Azure Functions
Performance Każda delegacja = dodatkowy round-trip Trade-off: modularność vs latency
Debugging Odpowiedzi sub-agentów widoczne TYLKO dla main agent Thread logs są kluczowe - sprawdzaj je regularnie

Ważne: Sub-agent nie może mieć własnych connected agents. Maksymalny depth to 2 poziomy:

  • ✅ OK: Main Agent → Sub-Agent
  • ❌ BŁĄD: Main Agent → Sub-Agent → Sub-Sub-Agent

Przygotowanie środowiska

Krok 1: Export OpenAPI spec dla Company API

Musisz wyeksportować OpenAPI specification z API Management:

  1. Azure Portal → API Management → APIs
  2. Wybierz Company API
  3. Kliknij Export (górny pasek)
  4. Wybierz OpenAPI v3 (JSON) ⚠️ Ważne: JSON, nie YAML!
  5. Zapisz plik lokalnie jako company-api.json

Dlaczego JSON? Azure AI Foundry lepiej obsługuje OpenAPI w formacie JSON przy tworzeniu connections.

Krok 2: Utworzenie Connection dla Company API

Connection przechowuje credentials centralnie - możesz reużywać w wielu agentach.

  1. W Azure AI Foundry Portal, kliknij More (menu u góry)
  2. Management centerProject (Twój projekt)
  3. Connected resources+ New connection
  4. Wybierz Custom keys
  5. Configuration:
    • Connection name: company-api-connection
    • Przewiń w dół do sekcji Connection key
    • Credentials (dodaj DWA klucze):
      • Pierwszy klucz:
        • Key: Ocp-Apim-Subscription-Key
        • Value: Wklej subscription key otrzymany od prowadzącego (z Azure Portal → APIM → Subscriptions)
        • Is secret: Zaznacz (checkbox)
      • Kliknij + Add key i dodaj drugi:
        • Key: subscription-key
        • Value: Ten sam subscription key co powyżej
        • Is secret: Zaznacz (checkbox)
  6. Create

Tip: Ten sam subscription key co do KRS API - możesz reużyć krs-apim-connection-<INICJAŁ> z Lab 04 jeśli chcesz!


Lab Część 1: Utworzenie Sub-Agentów

Krok 1: KRS Agent (reużycie z Lab 04)

Option A: Reużyj istniejącego KRS Agent z Lab 04

  • Jeśli masz już działającego KRS Agent z Lab 04 - użyj go
  • Skopiuj jego Agent ID (będzie potrzebny później)
  • Przejdź do Kroku 2

Option B: Utwórz nowego KRS Agent

  1. AI Foundry Portal → Twój Project → Agents (lewy panel)
  2. + Create agent

Konfiguracja:

Pole Wartość
Name krs_agent
Description Retrieves company data from Polish National Court Register (KRS) based on KRS number
Model gpt-4.1-mini-<INICJAŁ>
Instructions Zobacz poniżej ⬇️

Instructions dla KRS Agent:

Jesteś wyspecjalizowanym agentem do pobierania danych z Krajowego Rejestru Sądowego (KRS).

TWOJE ZADANIE:
- Pobierz aktualny odpis firmy z KRS na podstawie numeru KRS
- Zwróć strukturalne dane firmy (nazwa, NIP, REGON, adres, KRS)

NARZĘDZIE:
- getKrsOdpisAktualny - pobiera dane z KRS API

PARAMETRY:
- krs: numer KRS (10 cyfr, format: 0000123456)
- rejestr: ZAWSZE używaj "P" (rejestr przedsiębiorców)

ZASADY:
1. Wywołaj getKrsOdpisAktualny z numerem KRS i rejestr="P"
2. Wyciągnij najważniejsze pola: nazwa, NIP, REGON, adres siedziby, numer KRS
3. Zwróć dane w formacie JSON lub ustrukturyzowanym tekście
4. Jeśli API zwróci 404 - powiedz że firma nie znaleziona
5. NIE WYMYŚLAJ danych - używaj TYLKO informacji z API

FORMAT ODPOWIEDZI:
Zwróć dane w czytelnym formacie:
- Nazwa: [nazwa firmy]
- NIP: [nip]
- KRS: [krs]
- REGON: [regon]
- Adres: [pełny adres]
  1. Tools+ Add toolOpenAPI
    • Connection: Wybierz KRS API connection (z Lab 04)
    • Import: Wybierz OpenAPI spec dla KRS API
    • Add
  2. Create agent

  3. Test KRS Agent:
    • Nowy thread → Pytanie: "Pobierz dane firmy KRS 0000028860"
    • Oczekiwana odpowiedź: Dane PKN ORLEN S.A. (nazwa, NIP, adres, etc.)
    • ✅ Jeśli działa - KRS Agent gotowy!

Zapisz Agent ID:

  • Kliknij na agenta w liście → Skopiuj Agent ID (np. asst_abc123xyz)
  • Będzie potrzebny w Kroku 4

Krok 2: Company API Agent (NOWY)

Teraz utworzymy nowego sub-agenta do zarządzania lokalną bazą firm.

  1. AI Foundry PortalAgents+ Create agent

Konfiguracja:

Pole Wartość
Name company_api_agent
Description Manages local company database - saves, retrieves, updates, and deletes company records
Model gpt-4.1-mini-<INICJAŁ>
Instructions Zobacz poniżej ⬇️

Instructions dla Company API Agent:

Jesteś wyspecjalizowanym agentem do zarządzania lokalną bazą danych firm.

TWOJE ZADANIE:
- Zapisywanie firm do bazy danych
- Odczytywanie firm z bazy danych
- Aktualizacja i usuwanie firm

NARZĘDZIA (Company API):
- get-companies: Lista wszystkich firm w bazie
- post-companies: Dodaj nową firmę (ID generowane automatycznie)
- get-companies-id: Pobierz firmę po ID
- patch-companies-id: Aktualizuj wybrane pola firmy
- delete-companies-id: Usuń firmę po ID

ZASADY:
1. Gdy dostajesz prośbę "zapisz firmę" - użyj post-companies
2. Dane firmy MUSZĄ zawierać: nazwa, nip, krs, regon, adres
3. Gdy dostajesz prośbę "jakie firmy w bazie" - użyj get-companies
4. Przy aktualizacji użyj patch-companies-id (potrzebujesz ID firmy)
5. Zwracaj przyjazne komunikaty o sukcesie/błędzie

FORMAT DANYCH dla POST/PATCH:
{
  "nazwa": "nazwa firmy",
  "nip": "1234567890",
  "krs": "0000123456",
  "regon": "123456789",
  "adres": "ul. Przykładowa 1, 00-001 Warszawa"
}

KOMUNIKATY:
- Po zapisie: "Firma [nazwa] została zapisana do bazy z ID: [id]"
- Po liście: "W bazie znajduje się [N] firm: [lista nazw]"
- Po aktualizacji: "Firma [nazwa] została zaktualizowana"
- Po usunięciu: "Firma z ID [id] została usunięta"
  1. ActionsAdd actionOpenAPI 3.0 specification tool
  2. Tool details:
    • Name: company_api (bez spacji)
    • Description: Manages local company database - saves, retrieves, updates, and deletes company records
  3. OpenAPI spec:
    • Otwórz plik company-api.json (wyeksportowany w Kroku 1 przygotowania) w edytorze tekstowym
    • Skopiuj całą jego zawartość
    • Wklej zawartość JSON do pola tekstowego w portalu
  4. Authentication:
    • Type: Connection
    • Connection: Wybierz company-api-connection (utworzony w Kroku 2 przygotowania)
  5. Add

  6. Create agent

  7. Test Company API Agent:

Test 1: Lista firm (pusta baza)

  • Pytanie: "Jakie firmy są w bazie?"
  • Oczekiwana odpowiedź: "W bazie znajduje się 0 firm" lub podobna

Test 2: Dodanie firmy ręcznie

  • Pytanie: ``` Dodaj firmę do bazy:
    • Nazwa: Test Sp. z o.o.
    • NIP: 1234567890
    • KRS: 0000111111
    • REGON: 123456789
    • Adres: ul. Testowa 1, 00-001 Warszawa ```
  • Oczekiwana odpowiedź: "Firma Test Sp. z o.o. została zapisana do bazy z ID: 1"

Test 3: Lista firm (po dodaniu)

  • Pytanie: "Jakie firmy są w bazie?"
  • Oczekiwana odpowiedź: "W bazie znajduje się 1 firma: Test Sp. z o.o."

✅ Jeśli wszystkie testy przeszły - Company API Agent gotowy!

Zapisz Agent ID:

  • Skopiuj Agent ID dla company_api_agent
  • Będzie potrzebny w następnej części

Lab Część 2: Utworzenie Orchestrator Agent

Teraz utworzymy głównego agenta, który będzie koordynował pracę KRS Agent i Company API Agent.

Krok 3: Utworzenie Orchestrator Agent

  1. AI Foundry PortalAgents+ Create agent

Konfiguracja:

Pole Wartość
Name orchestrator_agent
Description Main coordinator that delegates tasks to specialized sub-agents (KRS and Company API)
Model gpt-4.1-mini
Instructions Zobacz poniżej ⬇️

Instructions dla Orchestrator Agent:

Jesteś głównym agentem koordynującym pracę wyspecjalizowanych sub-agentów.

TWOJE SUB-AGENCI:
1. **krs_agent** - pobiera dane firm z Krajowego Rejestru Sądowego (KRS)
2. **company_api_agent** - zarządza lokalną bazą danych firm (dodawanie, odczyt, aktualizacja, usuwanie)

TWOJA ROLA:
Analizujesz zapytania użytkownika i DELEGUJ zadania do odpowiednich sub-agentów.
NIE wykonuj zadań samodzielnie - ZAWSZE deleguj do sub-agentów.

SCENARIUSZE:

**Scenariusz 1: Dodanie firmy po numerze KRS**
Użytkownik: "Dodaj firmę KRS 0000028860 do bazy"
Flow:
1. Deleguj do krs_agent → pobierz dane z KRS (podaj numer KRS)
2. Poczekaj na odpowiedź z danymi firmy
3. Deleguj do company_api_agent → zapisz firmę do bazy używając danych z KRS
4. Podsumuj: "Firma [nazwa] została pobrana z KRS i zapisana do lokalnej bazy z ID: [id]"

**Scenariusz 2: Listowanie firm**
Użytkownik: "Jakie firmy mam w bazie?"
Flow:
1. Deleguj do company_api_agent → pobierz listę firm (get-companies)
2. Pokaż użytkownikowi listę w czytelnym formacie (tabela lub lista punktowana)

**Scenariusz 3: Sprawdzenie firmy bez zapisywania**
Użytkownik: "Sprawdź firmę KRS 0000028860"
Flow:
1. Deleguj do krs_agent → pobierz dane z KRS
2. Pokaż użytkownikowi dane BEZ wywoływania company_api_agent (nie zapisuj do bazy)

**Scenariusz 4: Aktualizacja firmy w bazie**
Użytkownik: "Zaktualizuj adres firmy ID 1 na 'ul. Nowa 10, 00-001 Warszawa'"
Flow:
1. Deleguj do company_api_agent → patch-companies-id z nowym adresem (podaj ID i nowe dane)
2. Podsumuj: "Adres firmy został zaktualizowany"

**Scenariusz 5: Usunięcie firmy**
Użytkownik: "Usuń firmę ID 1"
Flow:
1. Deleguj do company_api_agent → delete-companies-id (podaj ID)
2. Podsumuj: "Firma z ID 1 została usunięta z bazy"

**Scenariusz 6: Multi-step (kilka firm)**
Użytkownik: "Dodaj 3 firmy: KRS 0000028860, KRS 0000033427, KRS 0000011288"
Flow:
1. Dla każdego numeru KRS wykonaj Scenariusz 1:
   - krs_agent → pobierz dane
   - company_api_agent → zapisz do bazy
2. Podsumuj: "Dodałem 3 firmy do bazy: [lista nazw z ID]"

ZASADY DELEGACJI:
- Zapytania o KRS (numery KRS, odpisy, dane z rejestru) → krs_agent
- Operacje na bazie (zapis, lista, aktualizacja, usuwanie) → company_api_agent
- NIE wykonuj zadań samodzielnie - ZAWSZE deleguj do sub-agentów
- Czekaj na odpowiedź sub-agenta przed kolejnym krokiem
- Kompiluj odpowiedzi sub-agentów w finalną odpowiedź dla użytkownika

KOMUNIKACJA Z UŻYTKOWNIKIEM:
- Bądź przyjazny i opisuj co robisz: "Pobieram dane z KRS... Zapisuję do bazy..."
- Pokazuj podsumowania: "Znalazłem firmę X w KRS i zapisałem do bazy z ID Y"
- Formatuj odpowiedzi używając Markdown:
  - Nagłówki: ### Wyniki
  - Listy: - Firma 1, - Firma 2
  - Tabele dla wielu firm
- Jeśli sub-agent zwróci błąd (np. firma nie znaleziona w KRS) - poinformuj użytkownika wyraźnie

ERROR HANDLING:
- Jeśli krs_agent zwróci "firma nie znaleziona" → Powiedz użytkownikowi i NIE próbuj zapisywać do bazy
- Jeśli company_api_agent zwróci błąd (np. 404, 400) → Wyjaśnij problem użytkownikowi
- Jeśli brak numeru KRS w zapytaniu → Poproś użytkownika o podanie numeru KRS
  1. Tools → ⚠️ NIE dodawaj żadnych OpenAPI tools!
    • Orchestrator nie ma własnych API tools
    • Ma tylko Connected Agent tools (następny krok)
  2. Create agent

Krok 4: Dodanie Connected Agents do Orchestratora

Teraz podłączymy KRS Agent i Company API Agent jako tools Orchestratora.

  1. Otwórz Orchestrator Agent (agent orchestrator_agent)
  2. Tools+ Add toolConnected Agent

Dodanie KRS Agent:

Pole Wartość
Connected Agent Wybierz krs_agent z listy (lub wklej Agent ID)
Name krs_agent ⚠️ Ważne: dokładnie ta nazwa!
Description Retrieves company data from Polish National Court Register (KRS) based on KRS number. Use when user asks for company data from KRS registry.

Kliknij Add

  1. Tools+ Add toolConnected Agent (drugi sub-agent)

Dodanie Company API Agent:

Pole Wartość
Connected Agent Wybierz company_api_agent z listy (lub wklej Agent ID)
Name company_api_agent ⚠️ Ważne: dokładnie ta nazwa!
Description Manages local company database - saves, retrieves, updates, and deletes company records. Use when user wants to save companies to database, list companies, or modify database.

Kliknij Add

  1. Save agent (jeśli są niezapisane zmiany)

Dlaczego nazwa i opis są ważne?

  • Name: Model używa nazwy do wywołania tool (musi pasować do nazwy w instructions!)
  • Description: Model decyduje KIEDY użyć tool na podstawie description (musi być konkretny!)

Sprawdzenie:

  • Orchestrator Agent powinien mieć 2 tools typu Connected Agent:
    • krs_agent
    • company_api_agent
  • 0 tools typu OpenAPI (Orchestrator nie ma własnych API tools)

Krok 5: Test podstawowego flow

Teraz przetestujemy czy cała orkiestracja działa.

Test: Dodanie firmy z KRS do bazy

  1. Otwórz Orchestrator Agent
  2. Nowy thread
  3. Pytanie:
Dodaj firmę PKN ORLEN (KRS 0000028860) do mojej bazy danych

Oczekiwany flow:

flowchart LR
    U[User Query] --> O[Orchestrator<br/>analyzes]
    O -->|"Get data for<br/>KRS 0000028860"| K[KRS Agent]
    K -->|KRS API call| K2[Returns:<br/>PKN ORLEN data]
    K2 --> O
    O -->|"Save company<br/>with data"| C[Company API<br/>Agent]
    C -->|POST /companies| C2[Returns:<br/>ID: 1]
    C2 --> O
    O --> R[Final response<br/>to user]

    style O fill:#4A90E2,color:#fff
    style K fill:#50C878,color:#fff
    style C fill:#9B59B6,color:#fff

Oczekiwana odpowiedź (przykład):

Pobieram dane firmy z KRS...

✅ Znalazłem firmę w rejestrze KRS:
- Nazwa: PKN ORLEN S.A.
- NIP: 7740001454
- KRS: 0000028860
- REGON: 610188201
- Adres: ul. Chemików 7, 09-411 Płock

Zapisuję firmę do lokalnej bazy danych...

✅ Firma PKN ORLEN S.A. została zapisana do bazy z ID: 1

Co sprawdzić w Thread logs:

  1. Delegacja do krs_agent:
    • Log: Calling connected agent: krs_agent
    • Tool call: getKrsOdpisAktualny z parametrami {krs: "0000028860", rejestr: "P"}
  2. Odpowiedź krs_agent:
    • Widoczna TYLKO dla orchestratora (nie dla użytkownika bezpośrednio)
    • Zawiera dane PKN ORLEN
  3. Delegacja do company_api_agent:
    • Log: Calling connected agent: company_api_agent
    • Tool call: post-companies z body zawierającym dane PKN ORLEN
  4. Odpowiedź company_api_agent:
    • Zawiera ID zapisanej firmy (np. “1”)
  5. Final response:
    • Orchestrator kompiluje odpowiedzi sub-agentów
    • Zwraca podsumowanie użytkownikowi

Jeśli test przeszedł - Twój system multi-agent działa!


Lab Część 3: Testowanie scenariuszy

Teraz przetestujemy różne scenariusze użycia naszego systemu multi-agent.

Scenariusz 1: Dodanie firmy po numerze KRS ✅ (już przetestowany)

Input:

Dodaj firmę PKN ORLEN (KRS 0000028860) do bazy

Expected flow:

  1. Orchestrator → krs_agent (pobierz dane)
  2. Orchestrator → company_api_agent (zapisz do bazy)
  3. Orchestrator → user (potwierdzenie)

Success criteria:

  • ✅ Firma pobrana z KRS
  • ✅ Firma zapisana w Company API z ID
  • ✅ Użytkownik otrzymał potwierdzenie

Scenariusz 2: Listowanie firm w bazie

Input:

Jakie firmy mam w mojej bazie danych?

Expected flow:

  1. Orchestrator → company_api_agent (GET /companies)
  2. Orchestrator → user (sformatowana lista)

Expected response (przykład):

### Firmy w bazie danych

W bazie znajduje się 1 firma:

| ID | Nazwa | NIP | KRS | Adres |
|----|-------|-----|-----|-------|
| 1 | PKN ORLEN S.A. | 7740001454 | 0000028860 | ul. Chemików 7, 09-411 Płock |

Success criteria:

  • ✅ Lista wyświetlona w czytelnym formacie
  • ✅ Wszystkie firmy z bazy pokazane

Scenariusz 3: Sprawdzenie firmy bez zapisywania

Input:

Sprawdź dane firmy KRS 0000033427 ale NIE zapisuj do bazy

Expected flow:

  1. Orchestrator → krs_agent (pobierz dane)
  2. Orchestrator → user (dane firmy BEZ wywoływania company_api_agent)

Expected response (przykład):

Dane firmy z rejestru KRS:

- Nazwa: MICROSOFT SP. Z O.O.
- NIP: 5260250995
- KRS: 0000033427
- REGON: 012072970
- Adres: ul. Postępu 18, 02-676 Warszawa

Firma NIE została zapisana do bazy (zgodnie z Twoją prośbą).

Success criteria:

  • ✅ Dane z KRS pobrane
  • ✅ Company API Agent NIE został wywołany
  • ✅ Brak nowego rekordu w bazie

Scenariusz 4: Multi-step (dodanie wielu firm)

Input:

Dodaj do bazy 3 firmy:
1. KRS 0000028860 (PKN ORLEN)
2. KRS 0000033427 (Microsoft)
3. KRS 0000011288 (Samsung)

Expected flow:

  1. Loop 3x:
    • Orchestrator → krs_agent (firma 1)
    • Orchestrator → company_api_agent (zapis 1)
    • Orchestrator → krs_agent (firma 2)
    • Orchestrator → company_api_agent (zapis 2)
    • Orchestrator → krs_agent (firma 3)
    • Orchestrator → company_api_agent (zapis 3)
  2. Orchestrator → user (podsumowanie)

Expected response (przykład):

Dodałem 3 firmy do bazy danych:

1. ✅ PKN ORLEN S.A. (KRS: 0000028860) - ID: 1
2. ✅ MICROSOFT SP. Z O.O. (KRS: 0000033427) - ID: 2
3. ✅ SAMSUNG ELECTRONICS POLSKA SP. Z O.O. (KRS: 0000011288) - ID: 3

Wszystkie firmy zostały pomyślnie dodane do bazy.

Success criteria:

  • ✅ 3 firmy pobrane z KRS
  • ✅ 3 firmy zapisane w bazie (3 nowe ID)
  • ✅ Podsumowanie ze wszystkimi firmami

Scenariusz 5: Error handling (nieprawidłowy numer KRS)

Input:

Dodaj firmę KRS 9999999999 do bazy

Expected flow:

  1. Orchestrator → krs_agent (pobierz dane)
  2. krs_agent → KRS API zwraca 404
  3. krs_agent → orchestrator (“firma nie znaleziona”)
  4. Orchestrator → user (błąd, BEZ wywoływania company_api_agent)

Expected response (przykład):

❌ Nie mogę dodać firmy do bazy.

Sprawdziłem rejestr KRS i firma o numerze KRS 9999999999 nie została znaleziona.

Możliwe przyczyny:
- Nieprawidłowy numer KRS
- Firma nie istnieje w rejestrze
- Firma została wykreślona

Proszę sprawdź numer KRS i spróbuj ponownie.

Success criteria:

  • ✅ Błąd wykryty przez krs_agent
  • ✅ Company API Agent NIE został wywołany
  • ✅ Użytkownik otrzymał jasny komunikat o błędzie

Scenariusz 6: Aktualizacja danych firmy

Input:

Zaktualizuj adres firmy ID 1 na: ul. Nowa 100, 00-001 Warszawa

Expected flow:

  1. Orchestrator → company_api_agent (PATCH /companies/1)
  2. Orchestrator → user (potwierdzenie)

Expected response (przykład):

✅ Adres firmy z ID 1 został zaktualizowany.

Nowy adres: ul. Nowa 100, 00-001 Warszawa

Success criteria:

  • ✅ PATCH request wysłany z nowymi danymi
  • ✅ Firma zaktualizowana w bazie
  • ✅ Potwierdzenie dla użytkownika

Scenariusz 7: Usunięcie firmy

Input:

Usuń firmę ID 1 z bazy

Expected flow:

  1. Orchestrator → company_api_agent (DELETE /companies/1)
  2. Orchestrator → user (potwierdzenie)

Expected response (przykład):

✅ Firma z ID 1 została usunięta z bazy danych.

Success criteria:

  • ✅ DELETE request wysłany
  • ✅ Firma usunięta z bazy
  • ✅ Ponowne wywołanie GET /companies nie zwraca tej firmy

Lab Część 4: Observability i Debugging

Thread Logs - śledzenie delegacji

Thread logs to kluczowe narzędzie do debugowania Connected Agents.

Jak sprawdzić Thread logs:

Otwórz thread z interakcją z Orchestratorem

Co szukać w logach:

1. Main Agent Decision
   └─ "Analyzing user request..."
   └─ "Deciding to call connected agent: krs_agent"

2. Connected Agent Call
   └─ Tool: connected_agent
   └─ Arguments: {agent_id: "asst_abc...", query: "..."}

3. Sub-Agent Execution (może być widoczny lub nie)
   └─ Tool: getKrsOdpisAktualny
   └─ Arguments: {krs: "0000028860", rejestr: "P"}
   └─ Response: {data from KRS API}

4. Sub-Agent Response (widoczny TYLKO dla main agent)
   └─ "Firma PKN ORLEN S.A., NIP: 7740001454, ..."

5. Main Agent Compilation
   └─ "Received data from krs_agent"
   └─ "Now calling company_api_agent to save data"

6. Another Connected Agent Call
   └─ Tool: connected_agent
   └─ Arguments: {agent_id: "asst_xyz...", query: "..."}

7. Final Response to User
   └─ "Firma PKN ORLEN S.A. została zapisana z ID: 1"

Kluczowe punkty:

  • Connected agent calls: Szukaj “connected_agent” tool w logach
  • Sub-agent responses: Mogą być widoczne w “intermediate steps” (nie zawsze)
  • Final compilation: Main agent łączy wyniki sub-agentów

Jak debugować typowe problemy

Problem 1: Orchestrator wykonuje zadanie sam (nie deleguje)

Symptom:

  • Orchestrator próbuje sam odpowiedzieć bez wywoływania sub-agentów
  • Brak “connected agent call” w thread logs

Diagnoza:

  1. Sprawdź instructions Orchestratora - czy jasno mówią “ZAWSZE deleguj”?
  2. Sprawdź description Connected Agent tools - czy są konkretne?

Fix:

  • Popraw instructions - dodaj więcej scenariuszy z explicit delegation
  • Popraw descriptions - bądź konkretny kiedy użyć każdego sub-agenta

Problem 2: Sub-agent nie jest wywoływany

Symptom:

  • Thread logs pokazują że Orchestrator “zdecydował się delegować” ale brak wywołania
  • Błąd: “Tool not found” lub podobny

Diagnoza:

  1. Sprawdź czy nazwa tool w instructions pasuje do nazwy w Connected Agent tool
    • Instructions: krs_agent → Tool name: krs_agent
    • Instructions: KRS_Agent → Tool name: krs_agent ❌ (wielkość liter!)

Fix:

  • Upewnij się że nazwa w instructions == nazwa w tool definition
  • Użyj snake_case konsekwentnie

Problem 3: Sub-agent zwraca błąd 401/403

Symptom:

  • Sub-agent wywołuje API tool ale dostaje 401 Unauthorized lub 403 Forbidden

Diagnoza:

  1. Sprawdź Connection dla tego API - czy subscription key jest poprawny?
  2. Sprawdź w Azure Portal APIM → Subscriptions czy key jest aktywny

Fix:

  • Zaktualizuj Connection z poprawnym subscription key
  • Lub regeneruj key w APIM i zaktualizuj Connection

Problem 4: Orchestrator “zapomina” o wcześniejszych delegacjach

Symptom:

  • Orchestrator deleguje do krs_agent ✅
  • Dostaje odpowiedź ✅
  • Ale potem nie wywołuje company_api_agent (zapomina o danych)

Diagnoza:

  • Instructions mogą być zbyt ogólne
  • Model nie rozumie że ma wykonać multi-step workflow

Fix:

  • W instructions dodaj explicit multi-step scenarios: ``` Scenariusz 1: Dodaj firmę
    1. NAJPIERW deleguj do krs_agent
    2. POCZEKAJ na odpowiedź
    3. POTEM deleguj do company_api_agent z danymi z kroku 1 ```

Flowchart: Debugging Decision Tree

flowchart TD
    Start([Problem with<br/>Connected Agents]) --> Check{What is<br/>the issue?}

    Check -->|Sub-agent not called| Desc[Check tool<br/>description]
    Check -->|Wrong sub-agent called| Instr[Check orchestrator<br/>instructions]
    Check -->|API error 401/403| Auth[Check API<br/>connection]
    Check -->|Agent does task itself| Deleg[Check delegation<br/>instructions]

    Desc --> DescFix[Make description<br/>more specific]
    Instr --> InstrFix[Add scenario<br/>examples]
    Auth --> AuthFix[Update subscription<br/>key in connection]
    Deleg --> DelegFix[Add explicit<br/>'ALWAYS delegate']

    DescFix --> Test[Test again]
    InstrFix --> Test
    AuthFix --> Test
    DelegFix --> Test

    Test --> Works{Works?}
    Works -->|Yes| Success([✅ Fixed!])
    Works -->|No| Logs[Check thread logs<br/>for more details]

    Logs --> Start

    style Start fill:#E8E8E8,stroke:#666
    style Success fill:#50C878,stroke:#2E7D4E,color:#fff
    style Check fill:#4A90E2,stroke:#2E5C8A,color:#fff
    style Test fill:#F39C12,stroke:#C87F0A,color:#fff

Best Practices

Kiedy używać Connected Agents?

Używaj Connected Agents gdy:

Scenariusz Dlaczego multi-agent?
Wiele domen KRS + Company DB + Accounting = 3 oddzielne sub-agenty zamiast jednego “monolitu”
Reużywalność Ten sam KRS Agent w różnych orchestratorach (HR, Finance, Legal)
Testowanie Łatwiej testować każdy sub-agent osobno niż jeden duży agent
Separation of concerns Jasny podział odpowiedzialności - każdy agent robi jedną rzecz dobrze
Długie instructions Jeśli instructions przekraczają 2000 słów - czas na podział

NIE używaj Connected Agents gdy:

Scenariusz Lepsze rozwiązanie
Proste zadanie Single agent z 1-2 tools wystarczy
Depth > 2 Spłaszcz architekturę - connected agents mają max depth = 2
Latency critical Każda delegacja = round-trip, single agent jest szybszy
Need citations Sub-agenci nie przekazują citations - prompt engineering ma ograniczenia

Separation of Concerns

Zasada: Każdy sub-agent odpowiada za jedną domenę.

Dobre przykłady:

  • ✅ KRS Agent: TYLKO KRS API
  • ✅ Company API Agent: TYLKO Company database
  • ✅ Email Agent: TYLKO wysyłanie emaili
  • ✅ Search Agent: TYLKO wyszukiwanie w dokumentach

Złe przykłady:

  • ❌ “Universal Agent”: KRS + Company DB + Email + Search (za dużo)
  • ❌ “Data Agent”: KRS + Tax Office + Court Records (3 różne API w jednym)

Reguła:

Jeśli sub-agent potrzebuje więcej niż 3 tools typu OpenAPI - prawdopodobnie robi za dużo.

Naming Conventions

Agent names:

  • Format: {domain}_{role} w snake_case
  • Przykłady:
    • krs_agent
    • company_api_agent
    • email_sender_agent
    • Agent1 (nie mówi co robi)
    • KRS-Agent (kebab-case może powodować problemy)

Tool names (Connected Agent):

  • MUSZĄ pasować do nazwy użytej w instructions
  • Przykład:
    Instructions: "Deleguj do krs_agent..."
    Tool name: "krs_agent"  ✅
    

Descriptions:

  • Bądź konkretny - model decyduje na podstawie description
  • Dobre: "Retrieves company data from Polish KRS registry based on KRS number"
  • Złe: "Gets data" (zbyt ogólne)

Error Handling Patterns

Pattern 1: Sub-agent przekazuje błąd w tekście

Sub-agent instructions:

Jeśli API zwróci 404:
- Zwróć: "ERROR: Firma nie znaleziona w KRS"

Orchestrator instructions:

Jeśli sub-agent zwróci "ERROR:..." - poinformuj użytkownika i ZATRZYMAJ workflow

Pattern 2: Orchestrator waliduje przed delegacją

Jeśli użytkownik nie podał numeru KRS:
- NIE deleguj do krs_agent
- Poproś użytkownika o numer KRS

Pattern 3: Retry logic

Jeśli krs_agent zwróci timeout:
1. Spróbuj ponownie (max 2 razy)
2. Jeśli nadal błąd - poinformuj użytkownika

Limitations (Ograniczenia)

1. Maximum Depth = 2

Ograniczenie:

  • Sub-agent NIE może mieć własnych connected agents
  • Maksymalna głębokość to 2 poziomy

Diagram:

✅ DOZWOLONE (Depth = 2):
Main Agent
├─ Sub-Agent 1
└─ Sub-Agent 2

❌ NIEDOZWOLONE (Depth = 3):
Main Agent
└─ Sub-Agent 1
   └─ Sub-Sub-Agent  ← BŁĄD!

Błąd:

Assistant Tool Call Depth Error: Sub-agent cannot have connected agents

Obejście:

  • Spłaszcz architekturę - usuń poziomy
  • Sub-Sub-Agent zrób Sub-Agent (sibling zamiast child)

2. Citations nie są przekazywane

Ograniczenie:

  • Sub-agent używa Bing Search → zwraca citations
  • Main agent NIE otrzyma citations w odpowiedzi
  • User nie zobaczy źródeł

Przykład:

Sub-Agent (z Bing Search):
"Według Microsoft.com, Azure AI Foundry..." [citation: microsoft.com]

Main Agent otrzyma:
"Według Microsoft.com, Azure AI Foundry..." (BEZ citation object)

Obejście (partial):

  • Prompt engineering: poproś sub-agenta o załączenie źródeł w tekście
    Instructions dla sub-agenta:
    "Jeśli używasz Bing Search - ZAWSZE podaj źródła w formacie: [Źródło: URL]"
    
  • Ale: variability (czasami działa, czasami nie)

3. Function Calling Tool nie działa

Ograniczenie:

  • Local Python functions (Function Calling tool) NIE działają w connected agents
  • Tylko OpenAPI Tool i Azure Functions działają

Przykład problemu:

# NIE ZADZIAŁA w sub-agencie:
def my_custom_function(data):
    return process(data)

# Tool definition:
{"type": "function", "function": my_custom_function}  

Obejście:

  • Zamiast local function → użyj OpenAPI Tool (API endpoint)
  • Lub: Azure Functions (serverless HTTP endpoint)

4. Performance - Round-trip Latency

Ograniczenie:

  • Każda delegacja = dodatkowy round-trip do API
  • Multi-step workflow może być wolniejszy niż single agent

Przykład:

Single Agent (1 hop):
User → Agent (KRS + DB tools) → User
Czas: ~3-5 sekund

Multi-Agent (3 hops):
User → Orchestrator → KRS Agent → Orchestrator → Company API Agent → Orchestrator → User
Czas: ~8-12 sekund

Trade-off:

  • ✅ Modularność i reużywalność
  • ❌ Wyższa latency

Kiedy to problem:

  • Real-time applications (chatbots, live support)
  • High-volume scenarios (setki requestów/min)

Kiedy OK:

  • Batch processing
  • Back-office workflows
  • Quality > speed

5. Debugging - Limited Visibility

Ograniczenie:

  • Odpowiedzi sub-agentów są widoczne TYLKO dla main agent
  • User nie widzi bezpośrednio co zwrócił sub-agent
  • Thread logs są kluczowe (ale czasami incomplete)

Obejście:

  • Main agent powinien “opowiadać” co robi:
    Instructions:
    "Opisuj każdy krok: 'Deleguje do krs_agent...', 'Otrzymałem dane...', 'Teraz zapisuję do bazy...'"
    
  • Sprawdzaj Thread logs regularnie podczas developmentu

Podsumowanie

Co poznaliśmy w Lab 09:

Connected Agents architecture:

  • Main Agent (Orchestrator) + Sub-Agents (specjaliści)
  • Delegation flow: User → Orchestrator → Sub-Agent → Tools → Orchestrator → User

Praktyczna implementacja:

  • 3 agentów: Orchestrator + KRS Agent + Company API Agent
  • ConnectedAgentTool jako sposób na wywoływanie sub-agentów
  • 7 scenariuszy testowych (podstawowy flow, lista, multi-step, error handling)

Best Practices:

  • Separation of concerns: każdy sub-agent = jedna domena
  • Naming conventions: snake_case, konkretne descriptions
  • Error handling: sub-agenci przekazują błędy w strukturalny sposób

Limitations:

  • Max depth = 2 (no sub-sub-agents)
  • Citations nie są przekazywane
  • Function calling tool nie działa
  • Performance: każda delegacja = round-trip

Kiedy używać Connected Agents?

Używaj gdy:

  • Masz wiele wyraźnie oddzielonych domen (KRS, DB, Email, etc.)
  • Chcesz reużywać sub-agentów w różnych kontekstach
  • System jest złożony i single agent byłby “overloaded”

NIE używaj gdy:

  • Zadanie jest proste (1-2 tools wystarczą w single agent)
  • Potrzebujesz depth > 2 (sub-sub-agents)
  • Latency jest krytyczna

results matching ""

    No results matching ""