ai-agents-for-beginners

Planning Design Pattern

(Klicken Sie auf das obige Bild, um das Video dieser Lektion anzusehen)

Planungsdesign

Einleitung

Diese Lektion behandelt

Lernziele

Nach Abschluss dieser Lektion werden Sie ein Verständnis dafür haben, wie

Definieren des übergeordneten Ziels und Aufteilen einer Aufgabe

Defining Goals and Tasks

Die meisten realen Aufgaben sind zu komplex, um sie in einem einzigen Schritt zu bewältigen. Ein KI-Agent benötigt ein prägnantes Ziel, um seine Planung und Aktionen zu leiten. Betrachten Sie zum Beispiel das Ziel

"Generate a 3-day travel itinerary."

Obwohl es einfach auszusprechen ist, muss es noch verfeinert werden. Je klarer das Ziel ist, desto besser können sich der Agent (und alle menschlichen Kollaborateure) auf die Erzielung des richtigen Ergebnisses konzentrieren, z. B. die Erstellung eines umfassenden Reiseplans mit Flugoptionen, Hotel-Empfehlungen und Aktivitätsvorschlägen.

Aufgabenzerlegung

Große oder komplizierte Aufgaben werden überschaubarer, wenn sie in kleinere, zielorientierte Teilaufgaben aufgeteilt werden. Für das Beispiel des Reiseplans könnten Sie das Ziel wie folgt aufteilen:

Jede Teilaufgabe kann dann von dedizierten Agenten oder Prozessen bearbeitet werden. Ein Agent könnte sich auf die Suche nach den besten Flugangeboten spezialisieren, ein anderer auf Hotelbuchungen und so weiter. Ein koordinierender oder "nachgelagerter" Agent kann diese Ergebnisse dann zu einem kohärenten Reiseplan für den Endbenutzer zusammenstellen.

Dieser modulare Ansatz ermöglicht auch inkrementelle Verbesserungen. Sie könnten zum Beispiel spezialisierte Agenten für Essensvorschläge oder lokale Aktivitätsvorschläge hinzufügen und den Reiseplan im Laufe der Zeit verfeinern.

Strukturierte Ausgabe

Large Language Models (LLMs) können strukturierte Ausgaben (z. B. JSON) generieren, die für nachgelagerte Agenten oder Dienste einfacher zu parsen und zu verarbeiten sind. Dies ist besonders nützlich in einem Multi-Agenten-Kontext, wo wir diese Aufgaben nach Erhalt der Planungs Ausgabe ausführen können. Ein schneller Überblick dazu findet sich in diesem Blogbeitrag.

Der folgende Python-Snippet zeigt einen einfachen Planungsagenten, der ein Ziel in Teilaufgaben zerlegt und einen strukturierten Plan generiert

from pydantic import BaseModel
from enum import Enum
from typing import List, Optional, Union
import json
import os
from typing import Optional
from pprint import pprint
from autogen_core.models import UserMessage, SystemMessage, AssistantMessage
from autogen_ext.models.azure import AzureAIChatCompletionClient
from azure.core.credentials import AzureKeyCredential

class AgentEnum(str, Enum):
    FlightBooking = "flight_booking"
    HotelBooking = "hotel_booking"
    CarRental = "car_rental"
    ActivitiesBooking = "activities_booking"
    DestinationInfo = "destination_info"
    DefaultAgent = "default_agent"
    GroupChatManager = "group_chat_manager"

# Travel SubTask Model
class TravelSubTask(BaseModel):
    task_details: str
    assigned_agent: AgentEnum  # we want to assign the task to the agent

class TravelPlan(BaseModel):
    main_task: str
    subtasks: List[TravelSubTask]
    is_greeting: bool

client = AzureAIChatCompletionClient(
    model="gpt-4o-mini",
    endpoint="https://models.inference.ai.azure.com",
    # To authenticate with the model you will need to generate a personal access token (PAT) in your GitHub settings.
    # Create your PAT token by following instructions here: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
    credential=AzureKeyCredential(os.environ["GITHUB_TOKEN"]),
    model_info={
        "json_output": False,
        "function_calling": True,
        "vision": True,
        "family": "unknown",
    },
)

# Define the user message
messages = [
    SystemMessage(content="""You are an planner agent.
    Your job is to decide which agents to run based on the user's request.
                      Provide your response in JSON format with the following structure:
{'main_task': 'Plan a family trip from Singapore to Melbourne.',
 'subtasks': [{'assigned_agent': 'flight_booking',
               'task_details': 'Book round-trip flights from Singapore to '
                               'Melbourne.'}
    Below are the available agents specialised in different tasks:
    - FlightBooking: For booking flights and providing flight information
    - HotelBooking: For booking hotels and providing hotel information
    - CarRental: For booking cars and providing car rental information
    - ActivitiesBooking: For booking activities and providing activity information
    - DestinationInfo: For providing information about destinations
    - DefaultAgent: For handling general requests""", source="system"),
    UserMessage(
        content="Create a travel plan for a family of 2 kids from Singapore to Melboune", source="user"),
]

response = await client.create(messages=messages, extra_create_args={"response_format": 'json_object'})

response_content: Optional[str] = response.content if isinstance(
    response.content, str) else None
if response_content is None:
    raise ValueError("Response content is not a valid JSON string" )

pprint(json.loads(response_content))

# # Ensure the response content is a valid JSON string before loading it
# response_content: Optional[str] = response.content if isinstance(
#     response.content, str) else None
# if response_content is None:
#     raise ValueError("Response content is not a valid JSON string")

# # Print the response content after loading it as JSON
# pprint(json.loads(response_content))

# Validate the response content with the MathReasoning model
# TravelPlan.model_validate(json.loads(response_content))

Planungsagent mit Multi-Agenten-Orchestrierung

In diesem Beispiel empfängt ein Semantic Router Agent eine Benutzeranfrage (z. B. „Ich benötige einen Hotelplan für meine Reise“).

Der Planer dann


from pydantic import BaseModel

from enum import Enum
from typing import List, Optional, Union

class AgentEnum(str, Enum):
    FlightBooking = "flight_booking"
    HotelBooking = "hotel_booking"
    CarRental = "car_rental"
    ActivitiesBooking = "activities_booking"
    DestinationInfo = "destination_info"
    DefaultAgent = "default_agent"
    GroupChatManager = "group_chat_manager"

# Travel SubTask Model

class TravelSubTask(BaseModel):
    task_details: str
    assigned_agent: AgentEnum # we want to assign the task to the agent

class TravelPlan(BaseModel):
    main_task: str
    subtasks: List[TravelSubTask]
    is_greeting: bool
import json
import os
from typing import Optional

from autogen_core.models import UserMessage, SystemMessage, AssistantMessage
from autogen_ext.models.openai import AzureOpenAIChatCompletionClient

# Create the client with type-checked environment variables

client = AzureOpenAIChatCompletionClient(
    azure_deployment=os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME"),
    model=os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME"),
    api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
    azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),
)

from pprint import pprint

# Define the user message

messages = [
    SystemMessage(content="""You are an planner agent.
    Your job is to decide which agents to run based on the user's request.
    Below are the available agents specialized in different tasks:
    - FlightBooking: For booking flights and providing flight information
    - HotelBooking: For booking hotels and providing hotel information
    - CarRental: For booking cars and providing car rental information
    - ActivitiesBooking: For booking activities and providing activity information
    - DestinationInfo: For providing information about destinations
    - DefaultAgent: For handling general requests""", source="system"),
    UserMessage(content="Create a travel plan for a family of 2 kids from Singapore to Melbourne", source="user"),
]

response = await client.create(messages=messages, extra_create_args={"response_format": TravelPlan})

# Ensure the response content is a valid JSON string before loading it

response_content: Optional[str] = response.content if isinstance(response.content, str) else None
if response_content is None:
    raise ValueError("Response content is not a valid JSON string")

# Print the response content after loading it as JSON

pprint(json.loads(response_content))

Was folgt, ist die Ausgabe des vorherigen Codes und Sie können diese strukturierte Ausgabe dann verwenden, um sie an den assigned_agent weiterzuleiten und den Reiseplan für den Endbenutzer zusammenzufassen.

{
    "is_greeting": "False",
    "main_task": "Plan a family trip from Singapore to Melbourne.",
    "subtasks": [
        {
            "assigned_agent": "flight_booking",
            "task_details": "Book round-trip flights from Singapore to Melbourne."
        },
        {
            "assigned_agent": "hotel_booking",
            "task_details": "Find family-friendly hotels in Melbourne."
        },
        {
            "assigned_agent": "car_rental",
            "task_details": "Arrange a car rental suitable for a family of four in Melbourne."
        },
        {
            "assigned_agent": "activities_booking",
            "task_details": "List family-friendly activities in Melbourne."
        },
        {
            "assigned_agent": "destination_info",
            "task_details": "Provide information about Melbourne as a travel destination."
        }
    ]
}

Ein Beispiel-Notebook mit dem vorherigen Codebeispiel ist hier verfügbar.

Iterative Planung

Einige Aufgaben erfordern ein Hin- und Her- oder Umplanen, bei dem das Ergebnis einer Teilaufgabe die nächste beeinflusst. Wenn der Agent beispielsweise beim Buchen von Flügen ein unerwartetes Datenformat entdeckt, muss er möglicherweise seine Strategie anpassen, bevor er mit den Hotelbuchungen fortfährt.

Zusätzlich kann Benutzerfeedback (z. B. eine menschliche Entscheidung, einen früheren Flug zu bevorzugen) eine teilweise Neuplanung auslösen. Dieser dynamische, iterative Ansatz stellt sicher, dass die endgültige Lösung mit den realen Einschränkungen und sich entwickelnden Benutzerpräferenzen übereinstimmt.

z.B. Beispielcode

from autogen_core.models import UserMessage, SystemMessage, AssistantMessage
#.. same as previous code and pass on the user history, current plan
messages = [
    SystemMessage(content="""You are a planner agent to optimize the
    Your job is to decide which agents to run based on the user's request.
    Below are the available agents specialized in different tasks:
    - FlightBooking: For booking flights and providing flight information
    - HotelBooking: For booking hotels and providing hotel information
    - CarRental: For booking cars and providing car rental information
    - ActivitiesBooking: For booking activities and providing activity information
    - DestinationInfo: For providing information about destinations
    - DefaultAgent: For handling general requests""", source="system"),
    UserMessage(content="Create a travel plan for a family of 2 kids from Singapore to Melbourne", source="user"),
    AssistantMessage(content=f"Previous travel plan - {TravelPlan}", source="assistant")
]
# .. re-plan and send the tasks to respective agents

Für eine umfassendere Planung schauen Sie sich Magnetic One Blogbeitrag zur Lösung komplexer Aufgaben an.

Zusammenfassung

In diesem Artikel haben wir ein Beispiel dafür betrachtet, wie wir einen Planer erstellen können, der die verfügbaren definierten Agenten dynamisch auswählen kann. Die Ausgabe des Planers zerlegt die Aufgaben und weist die Agenten zu, damit sie ausgeführt werden können. Es wird davon ausgegangen, dass die Agenten Zugriff auf die Funktionen/Werkzeuge haben, die zur Ausführung der Aufgabe erforderlich sind. Zusätzlich zu den Agenten können Sie andere Muster wie Reflexion, Zusammenfassung und Round-Robin-Chat einbeziehen, um die Anpassung weiter zu verbessern.

Zusätzliche Ressourcen

AutoGen Magentic One - Ein Generalistisches Multi-Agenten-System zur Lösung komplexer Aufgaben und hat beeindruckende Ergebnisse auf mehreren anspruchsvollen Agenten-Benchmarks erzielt. Referenz: autogen-magentic-one. In dieser Implementierung erstellt der Orchestrator aufgabenspezifische Pläne und delegiert diese Aufgaben an die verfügbaren Agenten. Zusätzlich zur Planung setzt der Orchestrator auch einen Tracking-Mechanismus ein, um den Fortschritt der Aufgabe zu überwachen und bei Bedarf neu zu planen.

Weitere Fragen zum Planungsdesign-Muster?

Treten Sie dem Azure AI Foundry Discord bei, um andere Lernende zu treffen, Sprechstunden zu besuchen und Ihre Fragen zu KI-Agenten beantwortet zu bekommen.

Vorherige Lektion

Vertrauenswürdige KI-Agenten erstellen

Nächste Lektion

Multi-Agenten-Entwurfsmuster