Udostępnij za pośrednictwem


Tworzenie systemów współpracy z wieloma agentami za pomocą połączonych agentów

Połączoni agenci w usłudze agenta usługi Azure AI Foundry umożliwiają podzielenie złożonych zadań na skoordynowane, wyspecjalizowane role — bez konieczności używania niestandardowego orkiestratora lub logiki routingu kodowanego ręcznie. Dzięki tej możliwości można projektować systemy, w których główny agent inteligentnie deleguje zadania dedykowanym podległym agentom, usprawniając przepływy pracy, takie jak obsługa klienta, badania rynkowe, podsumowania prawne i analiza finansowa.

Zamiast przeciążać jednego agenta zbyt wieloma umiejętnościami, można tworzyć skoncentrowanych, wielokrotnego użytku agentów, którzy bezproblemowo współpracują, poprawiając zarówno wydajność, jak i łatwość konserwacji.

Funkcje

  • Uproszczony projekt przepływu pracy: podział złożonych zadań między wyspecjalizowanymi agentami w celu zmniejszenia złożoności i zwiększenia przejrzystości.
  • Nie jest wymagana niestandardowa aranżacja: główny agent używa języka naturalnego do kierowania zadań, eliminując potrzebę zakodowanej logiki.
  • Łatwa rozszerzalność: Dodaj nowych połączonych agentów (na przykład tłumaczenie lub ocenianie ryzyka) bez modyfikowania głównego agenta.
  • Zwiększona niezawodność i możliwość śledzenia: przypisz do każdego agenta ukierunkowane obowiązki, aby ułatwić debugowanie i lepszą inspekcję.
  • Elastyczne opcje konfiguracji: Skonfiguruj agentów przy użyciu interfejsu bez kodu w portalu Foundry lub programowo za pomocą zestawu SDK języka Python.

Przykład: tworzenie modułowego agenta przeglądu kontraktu z połączonymi agentami

W miarę zwiększania złożoności przypadków użycia można skalować rozwiązanie sztucznej inteligencji, przypisując określone obowiązki wielu połączonych agentów. Dzięki temu każdy agent specjalizuje się w wąskim zadaniu, podczas gdy główny agent koordynuje ogólny przepływ pracy. Ta modularna konstrukcja zwiększa dokładność, łatwość konserwacji i możliwość śledzenia — szczególnie w przypadku domen o dużym rozmiarze dokumentów, takich jak legalność, zgodność i zaopatrzenie. Przyjrzyjmy się rzeczywistemu przykładowi tworzenia asystenta przeglądu kontraktu przy użyciu połączonych agentów.

Omówienie architektury

Agent główny — orkiestrator kontraktów

Działa jako centralny interfejs. Interpretuje polecenia użytkownika (takie jak "podsumuj klauzule", "porównaj wersje robocze" lub "sprawdź zgodność"), określa typ zadania i przekazuje je do odpowiedniego połączonego agenta.

  • Używane narzędzia: Brak bezpośredniego użycia

  • Obowiązki: klasyfikacja intencji i delegowanie

  • Przykładowy opis agenta:

    "Jesteś asystentem przeglądu kontraktu. W zależności od zapytania użytkownika określ, czy zadanie polega na podsumowaniu klauzul, porównaniu dokumentów, czy sprawdzaniu zgodności, a następnie pokieruj odpowiednio.

Połączony agent 1: podsumowywacz klauzul

Wyodrębnia kluczowe sekcje (takie jak Zakończenie, Odszkodowanie lub Poufność) z umowy i podsumowuje je w prostym języku.

  • Używane narzędzia:

    • Przeszukiwanie plików w celu odnalezienia przesłanego kontraktu
    • Interpreter kodu do skanowania dokumentu pod kątem nagłówków klauzul i podsumowania zawartości.
  • Obowiązki: wyodrębnianie i podsumowywanie informacji

  • Przykładowy opis agenta:

    "Wyodrębnij i podsumuj klauzule "Zakończenie", "Warunki płatności" i "Indemnity" z podanej umowy.

Połączony agent 2: moduł sprawdzania zgodności

Sprawdza umowę zgodnie ze standardami wewnętrznymi lub przekazanymi wytycznymi, aby zidentyfikować ryzykowny lub niezgodny język.

  • Używane narzędzia:

    • Wyszukiwanie plików w celu uzyskania dostępu do dokumentów zasad wewnętrznych lub szablonów kontraktów
    • Narzędzie OpenAPI do wywoływania wewnętrznego API zasad zgodności
    • Funkcja platformy Azure lub usługa Azure Logic Apps do uruchamiania prostych testów logiki (na przykład wymaganej obecności klauzuli lub walidacji progów)
  • Obowiązki: Dopasowywanie zasad i flagowanie ryzyka

  • Przykładowa instrukcja monitu:

    "Przejrzyj ten dokument pod kątem wytycznych dotyczących zgodności firmy i oznacz wszelkie odchylenia od zatwierdzonego szablonu".

Ograniczenia

  • Połączeni agenci nie mogą wywoływać funkcji lokalnych przy użyciu narzędzia wywołującego funkcję. Zalecamy zamiast tego użycie narzędzia OpenAPI lub usługi Azure Functions .
  • Obecnie nie można zagwarantować, że cytaty zostaną przekazane z połączonych agentów. Możesz spróbować użyć inżynierii poleceń w połączeniu z różnymi modelami, aby zwiększyć szansę, że cytaty zostaną wygenerowane przez główny model, ale wyniki podlegają zmienności.

Tworzenie konfiguracji obejmującej wiele agentów

  1. Przejdź do strony Agenci w portalu
  2. Wybierz istniejącego agenta z listy lub utwórz nowy.
  3. Przewiń w dół do sekcji Połączone agenci w panelu konfiguracji agenta i wybierz pozycję Dodaj +.

Zrzut ekranu przedstawiający stronę agentów w narzędziu Azure AI Foundry.

  1. W wyświetlonym oknie dialogowym wybierz agenta, któremu główny agent będzie mógł delegować zadania, i opisz:

    • Wybierz istniejącego agenta z listy rozwijanej. Jest to połączony agent, do którego główny agent będzie delegować zadania.
    • Wprowadź unikatową nazwę połączonego agenta (tylko litery i podkreślenia). Ta nazwa jest używana do wywoływania funkcji na poziomie interfejsu API. Zachowaj opisowość i czytelność dla maszyn, aby zmaksymalizować dokładność przypominania (na przykład summarize_text, lookup_product_info).
    • Dodaj jasny opis tego , kiedy i dlaczego należy wywołać połączonego agenta. Ułatwia to proces podejmowania decyzji głównego agenta, kiedy należy przekazać zadania połączonym agentom w czasie wykonywania.
  2. Wybierz Dodaj +

  3. Powtórz kroki od 3 do 5, aby dodać dodatkowych wyspecjalizowanych agentów do głównego agenta.

  4. Gdy połączeni agenci pojawią się na panelu konfiguracji, przewiń w górę i wybierz opcję Wypróbuj w Playground

  5. Użyj monitów testowych na placu zabaw agenta, aby sprawdzić, czy główny agent prawidłowo kieruje zadania do połączonych agentów, jeśli ma to zastosowanie. Jeśli na przykład utworzono głównego agenta o nazwie research_agent, który nie ma skonfigurowanych narzędzi i nawiązał połączenie agenta o nazwie stock_price_bot, spróbuj wykonać monit podobny do następującego:

    "Jaka jest bieżąca cena akcji firmy Microsoft?"

    Obiekt research_agent powinien przekazać to żądanie do stock_price_bot na podstawie zdefiniowanego opisu routingu.

Zrzut ekranu przedstawiający ekran połączonych agentów

Korzystanie z zestawu SDK dla platformy .NET

Uwaga / Notatka

To pokazuje synchroniczne użycie. Przykład asynchroniczny można znaleźć w witrynie GitHub

Aby umożliwić agentowi korzystanie z połączonego agenta, należy użyć ConnectedAgentToolDefinition wraz z identyfikatorem agenta, nazwą i opisem.

  1. Najpierw musimy utworzyć klienta agenta i odczytać zmienne środowiskowe, które będą używane w następnych krokach.

    var projectEndpoint = configuration["ProjectEndpoint"];
    var modelDeploymentName = configuration["ModelDeploymentName"];
    
    PersistentAgentsClient client = new(projectEndpoint, new DefaultAzureCredential());
    
  2. Następnie utworzymy głównego agenta mainAgenti połączonego stockAgent agenta przy użyciu klienta agenta. Ten połączony agent będzie używany do inicjowania obiektu ConnectedAgentToolDefinition.

    PersistentAgent stockAgent = client.Administration.CreateAgent(
            model: modelDeploymentName,
            name: "stock_price_bot",
            instructions: "Your job is to get the stock price of a company. If you don't know the realtime stock price, return the last known stock price."
            // tools: [...] tools that would be used to get stock prices
        );
    ConnectedAgentToolDefinition connectedAgentDefinition = new(new ConnectedAgentDetails(stockAgent.Id, stockAgent.Name, "Gets the stock price of a company"));
    
    PersistentAgent mainAgent = client.Administration.CreateAgent(
            model: modelDeploymentName,
            name: "stock_price_bot",
            instructions: "Your job is to get the stock price of a company, using the available tools.",
            tools: [connectedAgentDefinition]
        );
    
    
    
  3. Teraz utworzymy wątek, dodamy wiadomość zawierającą pytanie do agenta i rozpoczniemy proces.

    PersistentAgentThread thread = client.Threads.CreateThread();
    
    // Create message to thread
    PersistentThreadMessage message = client.Messages.CreateMessage(
        thread.Id,
        MessageRole.User,
        "What is the stock price of Microsoft?");
    
    // Run the agent
    ThreadRun run = client.Runs.CreateRun(thread, agent);
    do
    {
        Thread.Sleep(TimeSpan.FromMilliseconds(500));
        run = client.Runs.GetRun(thread.Id, run.Id);
    }
    while (run.Status == RunStatus.Queued
        || run.Status == RunStatus.InProgress);
    
    // Confirm that the run completed successfully
    if (run.Status != RunStatus.Completed)
    {
        throw new Exception("Run did not complete successfully, error: " + run.LastError?.Message);
    }
    
  4. Wydrukuj komunikaty agenta do konsoli w kolejności chronologicznej.

    Pageable<PersistentThreadMessage> messages = client.Messages.GetMessages(
        threadId: thread.Id,
        order: ListSortOrder.Ascending
    );
    
    foreach (PersistentThreadMessage threadMessage in messages)
    {
        Console.Write($"{threadMessage.CreatedAt:yyyy-MM-dd HH:mm:ss} - {threadMessage.Role,10}: ");
        foreach (MessageContent contentItem in threadMessage.ContentItems)
        {
            if (contentItem is MessageTextContent textItem)
            {
                string response = textItem.Text;
                if (textItem.Annotations != null)
                {
                    foreach (MessageTextAnnotation annotation in textItem.Annotations)
                    {
                        if (annotation is MessageTextUriCitationAnnotation urlAnnotation)
                        {
                            response = response.Replace(urlAnnotation.Text, $" [{urlAnnotation.UriCitation.Title}]({urlAnnotation.UriCitation.Uri})");
                        }
                    }
                }
                Console.Write($"Agent response: {response}");
            }
            else if (contentItem is MessageImageFileContent imageFileItem)
            {
                Console.Write($"<image from ID: {imageFileItem.FileId}");
            }
            Console.WriteLine();
        }
    }
    
  5. Czyszczenie zasobów przez usunięcie wątku i agenta.

    agentClient.DeleteThread(threadId: thread.Id);
    agentClient.DeleteAgent(agentId: agent.Id);
    agentClient.DeleteAgent(agentId: connectedAgent.Id);
    

Tworzenie konfiguracji obejmującej wiele agentów

Aby utworzyć konfigurację z wieloma agentami, wykonaj następujące kroki:

  1. Zainicjuj obiekt klienta.

    import os
    from azure.ai.projects import AIProjectClient
    from azure.ai.projects.models import ConnectedAgentTool, MessageRole
    from azure.identity import DefaultAzureCredential
    
    
    project_client = AIProjectClient(
    endpoint=os.environ["PROJECT_ENDPOINT"],
    credential=DefaultAzureCredential(),
    )
    
  2. Utwórz agenta, który będzie połączony z agentem głównym.

    stock_price_agent = project_client.agents.create_agent(
        model=os.environ["MODEL_DEPLOYMENT_NAME"],
        name="stock_price_bot",
        instructions="Your job is to get the stock price of a company. If you don't know the realtime stock price, return the last known stock price.",
        #tools=... # tools to help the agent get stock prices
    )
    
  3. Inicjowanie połączonego narzędzia agenta przy użyciu identyfikatora agenta, nazwy i opisu

    connected_agent = ConnectedAgentTool(
        id=stock_price_agent.id, name=connected_agent_name, description="Gets the stock price of a company"
    )
    
  4. Utwórz agenta "głównego", który będzie używać połączonego agenta.

    agent = project_client.agents.create_agent(
        model=os.environ["MODEL_DEPLOYMENT_NAME"],
        name="my-agent",
        instructions="You are a helpful agent, and use the available tools to get stock prices.",
        tools=connected_agent.definitions,
    )
    
    print(f"Created agent, ID: {agent.id}")
    
  5. Utwórz wątek i dodaj do niego komunikat.

    thread = project_client.agents.create_thread()
    print(f"Created thread, ID: {thread.id}")
    
    # Create message to thread
    message = project_client.agents.create_message(
        thread_id=thread.id,
        role=MessageRole.USER,
        content="What is the stock price of Microsoft?",
    )
    print(f"Created message, ID: {message.id}")
    
    
  6. Utwórz przebieg i poczekaj na jego ukończenie.

    
    # Create and process Agent run in thread with tools
    run = project_client.agents.create_and_process_run(thread_id=thread.id, agent_id=agent.id)
    print(f"Run finished with status: {run.status}")
    
    if run.status == "failed":
        print(f"Run failed: {run.last_error}")
    
    # Delete the Agent when done
    project_client.agents.delete_agent(agent.id)
    print("Deleted agent")
    
    # Delete the connected Agent when done
    project_client.agents.delete_agent(stock_price_agent.id)
    print("Deleted connected agent")
    
  7. Wyświetl odpowiedź agenta. Główny agent skompiluje odpowiedzi od połączonych agentów i przekaże odpowiedź. odpowiedzi połączonego agenta są widoczne tylko dla głównego agenta, a nie dla użytkownika końcowego.

    # Print the Agent's response message with optional citation
    response_message = project_client.agents.list_messages(thread_id=thread.id).get_last_message_by_role(
        MessageRole.AGENT
    )
    if response_message:
        for text_message in response_message.text_messages:
            print(f"Agent response: {text_message.text.value}")
        for annotation in response_message.url_citation_annotations:
            print(f"URL Citation: [{annotation.url_citation.title}]({annotation.url_citation.url})")