Tworzenie systemu wieloagentowego

1. Wprowadzenie

Przegląd

W tym module wyjdziesz poza proste chatboty i skonfigurujesz rozproszony system wieloagentowy.

Pojedynczy LLM może odpowiadać na pytania, ale złożoność rzeczywistego świata często wymaga specjalistycznych ról. Nie prosisz inżyniera backendu o zaprojektowanie interfejsu ani projektanta o optymalizację zapytań do bazy danych. Podobnie możemy tworzyć wyspecjalizowane agenty AI, które skupiają się na jednym zadaniu i współpracują ze sobą, aby rozwiązywać złożone problemy.

Utworzysz system tworzenia kursów, który będzie się składać z:

  1. Agent badawczy: korzysta z google_search, aby znajdować aktualne informacje.
  2. Judge Agent: ocenia jakość i kompletność wyników wyszukiwania.
  3. Agent do tworzenia treści: przekształca wyniki badań w uporządkowany kurs.
  4. Agent koordynujący: zarządza przepływem pracy i komunikacją między tymi specjalistami.

Wymagania wstępne

  • podstawowa znajomość Pythona,
  • znajomość konsoli Google Cloud;

Jakie zadania wykonasz

  • Zdefiniuj agenta korzystającego z narzędzi (researcher), który może przeszukiwać internet.
  • Zastosuj uporządkowane dane wyjściowe za pomocą Pydantic w przypadku judge.
  • Nawiązywanie połączenia z agentami zdalnymi za pomocą protokołu Agent-to-Agent (A2A).
  • Utwórz LoopAgent, aby utworzyć pętlę informacji zwrotnych między badaczem a oceniającym.
  • Uruchom rozproszony system lokalnie za pomocą ADK.
  • Wdróż system wielu agentów w Google Cloud Run.

Zasady architektury i orkiestracji

Zanim napiszemy kod, zobaczmy, jak te agenty ze sobą współpracują. Tworzymy potok tworzenia kursów.

Projekt systemu

Schemat architektury

Administrowanie za pomocą agentów

Standardowi agenci (np. badacz) wykonują pracę. Agenci Orchestratora (np. LoopAgent lub SequentialAgent) zarządzają innymi agentami. Nie mają własnych narzędzi. Ich „narzędziem” jest delegowanie zadań.

  1. LoopAgent: działa to jak pętla while w kodzie. Uruchamia sekwencję agentów wielokrotnie, dopóki nie zostanie spełniony warunek (lub nie zostanie osiągnięta maksymalna liczba iteracji). Używamy go w pętli badawczej:
    • Badacz znajduje informacje.
    • Sędzia ocenia je.
    • Jeśli Judge zwróci wartość „Fail”, EscalationChecker zezwoli na kontynuowanie pętli.
    • Jeśli Judge powie „Pass”, EscalationChecker przerywa pętlę.
  2. SequentialAgent: działa to jak standardowe wykonanie skryptu. Uruchamia agentów jeden po drugim. Używamy go w przypadku potoku wysokiego poziomu:
    • Najpierw uruchom pętlę wyszukiwania (aż do momentu, gdy uzyskasz odpowiednie dane).
    • Następnie uruchom kreator treści (aby napisać kurs).

Łącząc te elementy, tworzymy solidny system, który może samodzielnie korygować błędy przed wygenerowaniem ostatecznego wyniku.

2. Konfiguracja

Konfiguracja środowiska

Otwórz Cloud Shell: otwórz nową kartę i wpisz shell.cloud.google.com.

Pobieranie kodu startowego

  1. Sklonuj repozytorium początkowe do katalogu głównego:
    cd ~
    git clone https://github.com/amitkmaraj/prai-roadshow-lab-1-starter.git
    cd prai-roadshow-lab-1-starter
    
  2. Uruchom skrypt inicjujący, aby powiązać środki na platformie z rozliczeniami.
    chmod +x ./init.sh
    ./init.sh
    
  3. Otwórz ten folder w edytorze.

Włącz interfejsy API

Teraz, gdy masz już nowy projekt, uruchom to polecenie, aby włączyć niezbędne usługi Google Cloud:

gcloud services enable \
    run.googleapis.com \
    artifactregistry.googleapis.com \
    cloudbuild.googleapis.com \
    aiplatform.googleapis.com \
    compute.googleapis.com

To może chwilę potrwać.

Instalowanie zależności

Do szybkiego zarządzania zależnościami używamy uv.

  1. Zainstaluj zależności projektu:
    # Ensure you have uv installed: pip install uv
    uv sync
    
  2. Ustaw identyfikator projektu Google Cloud.
    • Wskazówka: identyfikator projektu znajdziesz w panelu konsoli Google Cloud lub uruchamiając polecenie gcloud config get-value project.
    export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
    
  3. Ustaw pozostałe zmienne środowiskowe:
    export GOOGLE_CLOUD_LOCATION=us-central1
    export GOOGLE_GENAI_USE_VERTEXAI=true
    
    Ostrzeżenie: zmienne środowiskowe nie są zachowywane w nowych sesjach terminala. Jeśli otworzysz nową kartę terminala, musisz ponownie uruchomić te polecenia eksportu.

3. 🕵️ Agent do wyszukiwania informacji

Agent badawczy

Badacz to specjalista. Jego jedynym zadaniem jest wyszukiwanie informacji. Aby to zrobić, potrzebuje dostępu do narzędzia: wyszukiwarki Google.

Dlaczego warto rozdzielić rolę badacza?

Szczegółowe informacje: dlaczego nie wystarczy jeden agent do wszystkiego?

Małe, wyspecjalizowane agenty są łatwiejsze do ocenydebugowania. Jeśli wyniki są niezadowalające, zmień prompta badacza. Jeśli formatowanie kursu jest nieprawidłowe, możesz wprowadzić zmiany w narzędziu do tworzenia treści. W monolitycznym prompcie typu „zrób wszystko” poprawienie jednej rzeczy często powoduje, że przestaje działać inna.

  1. Jeśli pracujesz w Cloud Shell, uruchom to polecenie, aby otworzyć edytor Cloud Shell:
    cloudshell workspace .
    
    Jeśli pracujesz w środowisku lokalnym, otwórz ulubione środowisko IDE.
  2. Otwórz pokój agents/researcher/agent.py.
  3. Zobaczysz szkielet z informacją TODO.
  4. Dodaj ten kod, aby zdefiniować agenta researcher:
    # ... existing imports ...
    
    # Define the Researcher Agent
    researcher = Agent(
        name="researcher",
        model=MODEL,
        description="Gathers information on a topic using Google Search.",
        instruction="""
        You are an expert researcher. Your goal is to find comprehensive and accurate information on the user's topic.
        Use the `google_search` tool to find relevant information.
        Summarize your findings clearly.
        If you receive feedback that your research is insufficient, use the feedback to refine your next search.
        """,
        tools=[google_search],
    )
    
    root_agent = researcher
    

Kluczowe pojęcie: korzystanie z narzędzi

Zwróć uwagę, że przekazujemy wartość tools=[google_search]. ADK radzi sobie ze złożonością opisywania tego narzędzia modelowi LLM. Gdy model uzna, że potrzebuje informacji, generuje wywołanie narzędzia w formacie strukturalnym, ADK wykonuje funkcję Pythona google_search i przekazuje wynik z powrotem do modelu.

4. ⚖️ The Judge Agent

Agent oceniający

Badacz ciężko pracuje, ale LLM-y mogą być leniwe. Pracę musi sprawdzić sędzia. Sędzia akceptuje badania i zwraca uporządkowaną ocenę pozytywną lub negatywną.

Uporządkowane dane wyjściowe

Szczegółowe informacje: aby zautomatyzować przepływy pracy, potrzebujemy przewidywalnych wyników. Długie i niezrozumiałe opinie tekstowe są trudne do analizy automatycznej. Wymuszając schemat JSON (za pomocą Pydantic), zapewniamy, że Judge zwraca wartość logiczną pass lub fail, na podstawie której nasz kod może niezawodnie podejmować działania.

  1. Otwórz pokój agents/judge/agent.py.
  2. Zdefiniuj schemat JudgeFeedback i agenta judge.
    # 1. Define the Schema
    class JudgeFeedback(BaseModel):
        """Structured feedback from the Judge agent."""
        status: Literal["pass", "fail"] = Field(
            description="Whether the research is sufficient ('pass') or needs more work ('fail')."
        )
        feedback: str = Field(
            description="Detailed feedback on what is missing. If 'pass', a brief confirmation."
        )
    
    # 2. Define the Agent
    judge = Agent(
        name="judge",
        model=MODEL,
        description="Evaluates research findings for completeness and accuracy.",
        instruction="""
        You are a strict editor.
        Evaluate the 'research_findings' against the user's original request.
        If the findings are missing key info, return status='fail'.
        If they are comprehensive, return status='pass'.
        """,
        output_schema=JudgeFeedback,
        # Disallow delegation because it should only output the schema
        disallow_transfer_to_parent=True,
        disallow_transfer_to_peers=True,
    )
    
    root_agent = judge
    

Kluczowe pojęcie: ograniczanie zachowania agenta

Ustawiliśmy wartości disallow_transfer_to_parent=Truedisallow_transfer_to_peers=True. Wymusza to na modelu wyłącznie zwracanie ustrukturyzowanych JudgeFeedback. Nie może on „czatować” z użytkownikiem ani przekazywać sprawy innemu agentowi. Dzięki temu jest to deterministyczny element w naszym przepływie logicznym.

5. 🧪 Testowanie w izolacji

Zanim je połączymy, możemy sprawdzić, czy każdy agent działa. ADK umożliwia uruchamianie agentów pojedynczo.

Kluczowe pojęcie: interaktywne środowisko wykonawcze

adk run uruchamia lekkie środowisko, w którym jesteś „użytkownikiem”. Dzięki temu możesz przetestować instrukcje agenta i sposób korzystania z narzędzi w izolacji. Jeśli agentowi się to nie uda (np. nie może użyć wyszukiwarki Google), na pewno nie poradzi sobie z orkiestracją.

  1. Uruchom narzędzie Researcher w trybie interaktywnym. Zwróć uwagę, że odsyłamy do konkretnego katalogu agentów:
    # This runs the researcher agent in interactive mode
    uv run adk run agents/researcher
    
  2. W prompcie czatu wpisz:
    Find the population of Tokyo in 2020
    
    Powinien użyć narzędzia wyszukiwarki Google i zwrócić odpowiedź.Uwaga: jeśli zobaczysz błąd wskazujący, że projekt, lokalizacja i użycie wierzchołka nie są ustawione, sprawdź, czy identyfikator projektu jest ustawiony, i wykonaj to polecenie:
    export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
    export GOOGLE_CLOUD_LOCATION=us-central1
    export GOOGLE_GENAI_USE_VERTEXAI=true
    
  3. Zakończ czat (Ctrl+C).
  4. Uruchom narzędzie Judge interaktywnie:
    uv run adk run agents/judge
    
  5. W prompcie czatu zasymuluj dane wejściowe:
    Topic: Tokyo. Findings: Tokyo is a city.
    
    Powinien zwrócić status='fail', ponieważ wyniki są zbyt krótkie.

6. ✍️ Agent tworzenia treści

Kreator treści

Generator treści to kreatywny pisarz. Na podstawie zatwierdzonych badań tworzy kurs.

  1. Otwórz pokój agents/content_builder/agent.py.
  2. Zdefiniuj agenta content_builder.
    content_builder = Agent(
        name="content_builder",
        model=MODEL,
        description="Transforms research findings into a structured course.",
        instruction="""
        You are an expert course creator.
        Take the approved 'research_findings' and transform them into a well-structured, engaging course module.
    
        **Formatting Rules:**
        1. Start with a main title using a single `#` (H1).
        2. Use `##` (H2) for main section headings.
        3. Use bullet points and clear paragraphs.
        4. Maintain a professional but engaging tone.
    
        Ensure the content directly addresses the user's original request.
        """,
    )
    root_agent = content_builder
    

Kluczowe pojęcie: propagacja kontekstu

Możesz się zastanawiać: „Skąd konstruktor treści wie, co znalazł badacz?”. W ADK agenty w potoku współdzielą session.state. Później w Orchestratorze skonfigurujemy Researcher i Judge tak, aby zapisywali wyniki w tym stanie współdzielonym. Prompt w Kreatorze treści ma dostęp do tej historii.

7. 🎻 Aranżer

Agent aranżera

Orchestrator to menedżer naszego zespołu wieloagentowego. W przeciwieństwie do specjalistycznych agentów (Badacz, Sędzia, Twórca treści), którzy wykonują określone zadania, zadaniem Koordynatora jest koordynowanie przepływu pracy i zapewnienie prawidłowego przepływu informacji między nimi.

🌐 Architektura: agent-agent (A2A)

Architektura A2A

W tym module utworzymy system rozproszony. Zamiast uruchamiać wszystkie agenty w jednym procesie Pythona, wdrażamy je jako niezależne mikroserwisy. Dzięki temu każdy agent może skalować się niezależnie i ulegać awarii bez powodowania awarii całego systemu.

Aby to umożliwić, używamy protokołu Agent-to-Agent (A2A).

Protokół A2A

Szczegółowe informacje: w systemie produkcyjnym agenci działają na różnych serwerach (a nawet w różnych chmurach). Protokół A2A tworzy standardowy sposób, w jaki mogą się one wykrywać i komunikować ze sobą za pomocą protokołu HTTP. RemoteA2aAgent to klient ADK dla tego protokołu.

  1. Otwórz pokój agents/orchestrator/agent.py.
  2. Znajdź komentarz # TODO: Define Remote Agents lub sekcję definicji agentów zdalnych.
  3. Aby zdefiniować połączenia, dodaj ten kod. Umieść ten kod po importach i przed innymi definicjami agentów.
    # ... existing code ...
    
    # Connect to the Researcher (Localhost port 8001)
    researcher_url = os.environ.get("RESEARCHER_AGENT_CARD_URL", "http://localhost:8001/a2a/agent/.well-known/agent-card.json")
    researcher = RemoteA2aAgent(
        name="researcher",
        agent_card=researcher_url,
        description="Gathers information using Google Search.",
        # IMPORTANT: Save the output to state for the Judge to see
        after_agent_callback=create_save_output_callback("research_findings"),
        # IMPORTANT: Use authenticated client for communication
        httpx_client=create_authenticated_client(researcher_url)
    )
    
    # Connect to the Judge (Localhost port 8002)
    judge_url = os.environ.get("JUDGE_AGENT_CARD_URL", "http://localhost:8002/a2a/agent/.well-known/agent-card.json")
    judge = RemoteA2aAgent(
        name="judge",
        agent_card=judge_url,
        description="Evaluates research.",
        after_agent_callback=create_save_output_callback("judge_feedback"),
        httpx_client=create_authenticated_client(judge_url)
    )
    
    # Content Builder (Localhost port 8003)
    content_builder_url = os.environ.get("CONTENT_BUILDER_AGENT_CARD_URL", "http://localhost:8003/a2a/agent/.well-known/agent-card.json")
    content_builder = RemoteA2aAgent(
        name="content_builder",
        agent_card=content_builder_url,
        description="Builds the course.",
        httpx_client=create_authenticated_client(content_builder_url)
    )
    

8. 🛑 Narzędzie do sprawdzania eskalacji

Pętla musi mieć możliwość zatrzymania. Jeśli sędzia powie „Pass”, chcemy natychmiast wyjść z pętli i przejść do narzędzia do tworzenia treści.

Logika niestandardowa z BaseAgent

Szczegółowe informacje: nie wszyscy agenci korzystają z dużych modeli językowych. Czasami potrzebujesz prostej logiki Pythona. BaseAgent umożliwia zdefiniowanie agenta, który po prostu uruchamia kod. W takim przypadku sprawdzamy stan sesji i używamy EventActions(escalate=True), aby zasygnalizować LoopAgent, że ma się zatrzymać.

  1. Nadal w agents/orchestrator/agent.py.
  2. Znajdź symbol zastępczy EscalationChecker TODO.
  3. Zastąp ją tą implementacją:
    class EscalationChecker(BaseAgent):
        """Checks the judge's feedback and escalates (breaks the loop) if it passed."""
    
        async def _run_async_impl(
            self, ctx: InvocationContext
        ) -> AsyncGenerator[Event, None]:
            # Retrieve the feedback saved by the Judge
            feedback = ctx.session.state.get("judge_feedback")
            print(f"[EscalationChecker] Feedback: {feedback}")
    
            # Check for 'pass' status
            is_pass = False
            if isinstance(feedback, dict) and feedback.get("status") == "pass":
                is_pass = True
            # Handle string fallback if JSON parsing failed
            elif isinstance(feedback, str) and '"status": "pass"' in feedback:
                is_pass = True
    
            if is_pass:
                # 'escalate=True' tells the parent LoopAgent to stop looping
                yield Event(author=self.name, actions=EventActions(escalate=True))
            else:
                # Continue the loop
                yield Event(author=self.name)
    
    escalation_checker = EscalationChecker(name="escalation_checker")
    

Kluczowa koncepcja: sterowanie przepływem za pomocą zdarzeń

Agenci komunikują się nie tylko za pomocą tekstu, ale też za pomocą zdarzeń. Przekazując zdarzenie za pomocą escalate=True, agent wysyła sygnał do elementu nadrzędnego (LoopAgent). Element LoopAgent jest zaprogramowany tak, aby przechwytywać ten sygnał i kończyć pętlę.

9. 🔁 Pętla badań

Pętla trenowania

Potrzebujemy pętli informacji zwrotnej: badania –> ocena –> (niepowodzenie) –> badania –> …

  1. Nadal w agents/orchestrator/agent.py.
  2. Dodaj definicję research_loop. Umieść ją po klasie EscalationChecker i instancji escalation_checker.
    research_loop = LoopAgent(
        name="research_loop",
        description="Iteratively researches and judges until quality standards are met.",
        sub_agents=[researcher, judge, escalation_checker],
        max_iterations=3,
    )
    

Kluczowe pojęcie: LoopAgent

LoopAgent przełącza się między sub_agents w określonej kolejności.

  1. researcher: wyszukuje dane.
  2. judge: ocenia dane.
  3. escalation_checker: określa, czy yield Event(escalate=True). Jeśli wystąpi escalate=True, pętla zostanie przerwana wcześniej. W przeciwnym razie rozpocznie się ponownie od etapu badacza (maksymalnie max_iterations).

10. 🔗 Ostateczny potok

Potok końcowy

Na koniec połącz wszystko w całość.

  1. Nadal w agents/orchestrator/agent.py.
  2. Zdefiniuj root_agent u dołu pliku. Upewnij się, że zastępuje on istniejący symbol zastępczy root_agent = None.
    root_agent = SequentialAgent(
        name="course_creation_pipeline",
        description="A pipeline that researches a topic and then builds a course from it.",
        sub_agents=[research_loop, content_builder],
    )
    

Kluczowe pojęcie: kompozycja hierarchiczna

Zwróć uwagę, że research_loop jest agentem (LoopAgent). Traktujemy go tak samo jak każdego innego subagenta w SequentialAgent. Ta możliwość łączenia pozwala tworzyć złożoną logikę przez zagnieżdżanie prostych wzorców (pętli w sekwencjach, sekwencji w routerach itp.).

11. 💻 Uruchom lokalnie

Zanim wszystko uruchomimy, zobaczmy, jak ADK symuluje lokalnie środowisko rozproszone.

Szczegółowe omówienie: jak działa lokalny proces programowania

W architekturze mikroserwisów każdy agent działa jako osobny serwer. Po wdrożeniu będziesz mieć 4 różne usługi Cloud Run. Symulowanie tego lokalnie może być uciążliwe, jeśli musisz otworzyć 4 karty terminala i uruchomić 4 polecenia.

Ten skrypt uruchamia uvicorn procesy dla badacza (port 8001), oceniającego (8002) i twórcy treści (8003). Ustawia zmienne środowiskowe, takie jak RESEARCHER_AGENT_CARD_URL, i przekazuje je do aranżera (port 8004). W ten sam sposób skonfigurujemy go później w chmurze.

Działa aplikacja

  1. Uruchom skrypt orkiestracji:
    ./run_local.sh
    
    Spowoduje to rozpoczęcie 4 osobnych procesów.
  2. Sprawdź:
    • Jeśli używasz Cloud Shell: kliknij przycisk Podgląd w przeglądarce (w prawym górnym rogu terminala) –> Podejrzyj na porcie 8080 –> Zmień port na 8000.
    • Jeśli korzystasz z lokalnej wersji: otwórz http://localhost:8000 w przeglądarce.
    • Prompt: „Utwórz kurs o historii kawy”.
    • Obserwuj: koordynator zadzwoni do badacza. Wynik jest przekazywany do sędziego. Jeśli sędzia nie zaliczy testu, pętla będzie się powtarzać.
    Rozwiązywanie problemów:
    • „Błąd wewnętrzny serwera” / błędy autoryzacji: jeśli widzisz błędy autoryzacji (np. związane z google-auth), upewnij się, że w przypadku korzystania z komputera lokalnego uruchomiono gcloud auth application-default login. W Cloud Shell upewnij się, że zmienna środowiskowa GOOGLE_CLOUD_PROJECT jest prawidłowo ustawiona.
    • Błędy terminala: jeśli polecenie nie działa w nowym oknie terminala, pamiętaj, aby ponownie wyeksportować zmienne środowiskowe (GOOGLE_CLOUD_PROJECT itp.).
  3. Testowanie agentów w izolacji: nawet gdy cały system jest uruchomiony, możesz testować poszczególnych agentów, kierując reklamy bezpośrednio na ich porty. Jest to przydatne do debugowania konkretnego komponentu bez wywoływania całego łańcucha.
    • Tylko dla badaczy (port 8001): http://localhost:8001
    • Judge Only (Port 8002): http://localhost:8002
    • Tylko Content Builder (port 8003): http://localhost:8003
    • Aranżer (port 8004): http://localhost:8004 (bezpośredni dostęp do logiki aranżera)

12. 🚀 Wdróż w Cloud Run

Ostateczna weryfikacja jest przeprowadzana w chmurze. Każdy agent zostanie wdrożony jako osobna usługa.

Informacje o konfiguracji wdrożenia

Podczas wdrażania agentów w Cloud Run przekazujemy kilka zmiennych środowiskowych, aby skonfigurować ich działanie i łączność:

  • GOOGLE_CLOUD_PROJECT: zapewnia, że agent używa prawidłowego projektu Google Cloud do logowania i wywoływania Vertex AI.
  • GOOGLE_GENAI_USE_VERTEXAI: informuje platformę agentów (ADK), aby do wnioskowania o modelu używała Vertex AI zamiast bezpośrednio wywoływać interfejsy Gemini API.
  • [AGENT]_AGENT_CARD_URL: jest to kluczowe dla Orchestratora. Informuje aranżera, gdzie znajdują się zdalni agenci. Ustawiając tę wartość na wdrożony adres URL Cloud Run (a konkretnie ścieżkę karty agenta), umożliwiamy usłudze Orchestrator wykrywanie i komunikowanie się z usługami Researcher, Judge i Content Builder przez internet.
  1. Wdróż Researcher:
    gcloud run deploy researcher \
      --source agents/researcher/ \
      --region us-central1 \
      --allow-unauthenticated \
      --labels dev-tutorial=prod-ready-1 \
      --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \
      --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true"
    
    Zapisz adres URL:
    RESEARCHER_URL=$(gcloud run services describe researcher --region us-central1 --format='value(status.url)')
    echo $RESEARCHER_URL
    
  2. Wdróż narzędzie Judge:
    gcloud run deploy judge \
      --source agents/judge/ \
      --region us-central1 \
      --allow-unauthenticated \
      --labels dev-tutorial=prod-ready-1 \
      --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \
      --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true"
    
    Zapisz adres URL:
    JUDGE_URL=$(gcloud run services describe judge --region us-central1 --format='value(status.url)')
    echo $JUDGE_URL
    
  3. Wdróż narzędzie Content Builder:
    gcloud run deploy content-builder \
      --source agents/content_builder/ \
      --region us-central1 \
      --allow-unauthenticated \
      --labels dev-tutorial=prod-ready-1 \
      --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \
      --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true"
    
    Zapisz adres URL:
    CONTENT_BUILDER_URL=$(gcloud run services describe content-builder --region us-central1 --format='value(status.url)')
    echo $CONTENT_BUILDER_URL
    
  4. Wdróż narzędzie Orchestrator: użyj przechwyconych zmiennych środowiskowych, aby skonfigurować narzędzie Orchestrator.
    gcloud run deploy orchestrator \
      --source agents/orchestrator/ \
      --region us-central1 \
      --allow-unauthenticated \
      --labels dev-tutorial=prod-ready-1 \
      --set-env-vars RESEARCHER_AGENT_CARD_URL=$RESEARCHER_URL/a2a/agent/.well-known/agent-card.json \
      --set-env-vars JUDGE_AGENT_CARD_URL=$JUDGE_URL/a2a/agent/.well-known/agent-card.json \
      --set-env-vars CONTENT_BUILDER_AGENT_CARD_URL=$CONTENT_BUILDER_URL/a2a/agent/.well-known/agent-card.json \
      --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \
      --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true"
    
    Zapisz adres URL:
    ORCHESTRATOR_URL=$(gcloud run services describe orchestrator --region us-central1 --format='value(status.url)')
    echo $ORCHESTRATOR_URL
    
  5. Wdróż frontend:
    gcloud run deploy course-creator \
        --source app \
        --region us-central1 \
        --allow-unauthenticated \
        --labels dev-tutorial=prod-ready-1 \
        --set-env-vars AGENT_SERVER_URL=$ORCHESTRATOR_URL \
        --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT
    
  6. Testowanie wdrożenia zdalnego: otwórz adres URL wdrożonego Orchestratora. Działa teraz w całości w chmurze, korzystając z bezserwerowej infrastruktury Google, aby skalować agentów.Wskazówka: wszystkie mikrousługi i ich adresy URL znajdziesz w interfejsie Cloud Run.

13. Podsumowanie

Gratulacje! Udało Ci się utworzyć i wdrożyć gotowy do produkcji rozproszony system z wieloma agentami.

Co udało się osiągnąć

  • Podzieliliśmy złożone zadanie: zamiast jednego obszernego prompta podzieliliśmy pracę na wyspecjalizowane role (badacz, oceniający, twórca treści).
  • Wdrożona kontrola jakości: użyliśmy LoopAgent i ustrukturyzowanego Judge, aby mieć pewność, że tylko informacje wysokiej jakości docierają do ostatniego etapu.
  • Stworzone z myślą o produkcji: dzięki protokołowi Agent-to-Agent (A2A) i usłudze Cloud Run stworzyliśmy system, w którym każdy agent jest niezależną, skalowalną mikrousługą. Jest to znacznie bardziej niezawodne niż uruchamianie wszystkiego w jednym skrypcie Python.
  • Orchestration: użyliśmy elementów SequentialAgentLoopAgent, aby zdefiniować jasne wzorce przepływu sterowania.

Następne kroki

Teraz możesz rozbudować ten system:

  • Dodaj więcej narzędzi: przyznaj badaczowi dostęp do dokumentów wewnętrznych lub interfejsów API.
  • Ulepsz narzędzie Judge: dodaj bardziej szczegółowe kryteria lub nawet krok „Człowiek w procesie”.
  • Zamiana modeli: wypróbuj różne modele dla różnych agentów (np. szybszy model dla sędziego, a bardziej zaawansowany dla autora treści).

Możesz teraz tworzyć złożone i niezawodne przepływy pracy oparte na agentach w Google Cloud.