ai-agents-for-beginners

Erkundung des Microsoft Agent Frameworks

Agent Framework

Einleitung

Diese Lektion behandelt

Lernziele

Nach Abschluss dieser Lektion wissen Sie, wie Sie

Codebeispiele

Codebeispiele für das Microsoft Agent Framework (MAF) finden Sie in diesem Repository unter den Dateien xx-python-agent-framework und xx-dotnet-agent-framework.

Verständnis des Microsoft Agent Frameworks

Framework Intro

Microsoft Agent Framework (MAF) baut auf den Erfahrungen und Erkenntnissen aus Semantic Kernel und AutoGen auf. Es bietet die Flexibilität, die breite Palette agentenbasierter Anwendungsfälle zu adressieren, die sowohl in Produktions- als auch in Forschungsumgebungen auftreten, einschließlich

Um KI-Agenten in der Produktion bereitzustellen, enthält MAF auch Funktionen für

Das Microsoft Agent Framework konzentriert sich auch auf Interoperabilität durch

Schauen wir uns an, wie diese Funktionen auf einige der Kernkonzepte des Microsoft Agent Frameworks angewendet werden.

Schlüsselkonzepte des Microsoft Agent Frameworks

Agenten

Agent Framework

Agenten erstellen

Die Agentenerstellung erfolgt durch die Definition des Inferenzdienstes (LLM-Anbieter), einer Reihe von Anweisungen, denen der KI-Agent folgen soll, und eines zugewiesenen namens

agent = AzureOpenAIChatClient(credential=AzureCliCredential()).create_agent( instructions="You are good at recommending trips to customers based on their preferences.", name="TripRecommender" )

Das obige Beispiel verwendet Azure OpenAI, aber Agenten können mit einer Vielzahl von Diensten erstellt werden, einschließlich Azure AI Foundry Agent Service.

AzureAIAgentClient(async_credential=credential).create_agent( name="HelperAgent", instructions="You are a helpful assistant." ) as agent

OpenAI Responses, ChatCompletion APIs

agent = OpenAIResponsesClient().create_agent( name="WeatherBot", instructions="You are a helpful weather assistant.", )
agent = OpenAIChatClient().create_agent( name="HelpfulAssistant", instructions="You are a helpful assistant.", )

oder Remote-Agenten über das A2A-Protokoll.

agent = A2AAgent( name=agent_card.name, description=agent_card.description, agent_card=agent_card, url="https://your-a2a-agent-host" )

Agenten ausführen

Agenten werden mit den Methoden .run oder .run_stream für nicht-streaming- oder Streaming-Antworten ausgeführt.

result = await agent.run("What are good places to visit in Amsterdam?")
print(result.text)
async for update in agent.run_stream("What are the good places to visit in Amsterdam?"):
    if update.text:
        print(update.text, end="", flush=True)

Jede Agentenausführung kann auch Optionen zur Anpassung von Parametern wie max_tokens, die vom Agenten verwendet werden, tools, die der Agent aufrufen kann, und sogar das model selbst, das für den Agenten verwendet wird, beinhalten.

Dies ist nützlich in Fällen, in denen bestimmte Modelle oder Tools zur Erledigung einer Benutzeraufgabe erforderlich sind.

Tools

Tools können sowohl bei der Agentendefinition

def get_attractions( location: Annotated[str, Field(description="The location to get the top tourist attractions for")], ) -> str: """Get the top tourist attractions for a given location.""" return f"The top attractions for {location} are." 


# When creating a ChatAgent directly 

agent = ChatAgent( chat_client=OpenAIChatClient(), instructions="You are a helpful assistant", tools=[get_attractions]

als auch bei der Ausführung des Agenten definiert werden.


result1 = await agent.run( "What's the best place to visit in Seattle?", tools=[get_attractions] # Tool provided for this run only )

Agenten-Threads

Agenten-Threads werden zur Handhabung von Multi-Turn-Konversationen verwendet. Threads können entweder durch

Zum Erstellen eines Threads sieht der Code wie folgt aus:

# Create a new thread. 
thread = agent.get_new_thread() # Run the agent with the thread. 
response = await agent.run("Hello, I am here to help you book travel. Where would you like to go?", thread=thread)

Sie können den Thread dann serialisieren, um ihn für die spätere Verwendung zu speichern.

# Create a new thread. 
thread = agent.get_new_thread() 

# Run the agent with the thread. 

response = await agent.run("Hello, how are you?", thread=thread) 

# Serialize the thread for storage. 

serialized_thread = await thread.serialize() 

# Deserialize the thread state after loading from storage. 

resumed_thread = await agent.deserialize_thread(serialized_thread)

Agenten-Middleware

Agenten interagieren mit Tools und LLMs, um Benutzeraufgaben zu erledigen. In bestimmten Szenarien möchten wir Zwischenschritte zwischen diesen Interaktionen ausführen oder verfolgen. Agenten-Middleware ermöglicht uns dies durch

Funktions-Middleware

Diese Middleware ermöglicht es uns, eine Aktion zwischen dem Agenten und einer Funktion/einem Tool, das er aufrufen wird, auszuführen. Ein Beispiel dafür ist, wenn Sie bei Funktionsaufrufen ein Logging durchführen möchten.

Im folgenden Code bestimmt next, ob die nächste Middleware oder die eigentliche Funktion aufgerufen werden soll.

async def logging_function_middleware(
    context: FunctionInvocationContext,
    next: Callable[[FunctionInvocationContext], Awaitable[None]],
) -> None:
    """Function middleware that logs function execution."""
    # Pre-processing: Log before function execution
    print(f"[Function] Calling {context.function.name}")

    # Continue to next middleware or function execution
    await next(context)

    # Post-processing: Log after function execution
    print(f"[Function] {context.function.name} completed")

Chat-Middleware

Diese Middleware ermöglicht es uns, eine Aktion zwischen dem Agenten und den Anfragen an das LLM auszuführen oder zu protokollieren.

Dies enthält wichtige Informationen wie die messages, die an den KI-Dienst gesendet werden.

async def logging_chat_middleware(
    context: ChatContext,
    next: Callable[[ChatContext], Awaitable[None]],
) -> None:
    """Chat middleware that logs AI interactions."""
    # Pre-processing: Log before AI call
    print(f"[Chat] Sending {len(context.messages)} messages to AI")

    # Continue to next middleware or AI service
    await next(context)

    # Post-processing: Log after AI response
    print("[Chat] AI response received")

Agenten-Speicher

Wie im Lektion Agentenbasierten Speicher behandelt, ist der Speicher ein wichtiges Element, damit der Agent über verschiedene Kontexte hinweg agieren kann. MAF bietet verschiedene Speicherarten

In-Memory-Speicher

Dies ist der Speicher, der in Threads während der Laufzeit der Anwendung gespeichert wird.

# Create a new thread. 
thread = agent.get_new_thread() # Run the agent with the thread. 
response = await agent.run("Hello, I am here to help you book travel. Where would you like to go?", thread=thread)

Persistente Nachrichten

Dieser Speicher wird verwendet, um den Gesprächsverlauf über verschiedene Sitzungen hinweg zu speichern. Er wird mit dem chat_message_store_factory definiert.

from agent_framework import ChatMessageStore

# Create a custom message store
def create_message_store():
    return ChatMessageStore()

agent = ChatAgent(
    chat_client=OpenAIChatClient(),
    instructions="You are a Travel assistant.",
    chat_message_store_factory=create_message_store
)

Dynamischer Speicher

Dieser Speicher wird dem Kontext hinzugefügt, bevor Agenten ausgeführt werden. Diese Speicher können in externen Diensten wie mem0 gespeichert werden.

from agent_framework.mem0 import Mem0Provider

# Using Mem0 for advanced memory capabilities
memory_provider = Mem0Provider(
    api_key="your-mem0-api-key",
    user_id="user_123",
    application_id="my_app"
)

agent = ChatAgent(
    chat_client=OpenAIChatClient(),
    instructions="You are a helpful assistant with memory.",
    context_providers=memory_provider
)

Agenten-Observability

Observability ist wichtig für den Aufbau zuverlässiger und wartbarer agentenbasierter Systeme. MAF integriert sich mit OpenTelemetry, um Tracing und Metriken für eine bessere Observability bereitzustellen.

from agent_framework.observability import get_tracer, get_meter

tracer = get_tracer()
meter = get_meter()
with tracer.start_as_current_span("my_custom_span"):
    # do something
    pass
counter = meter.create_counter("my_custom_counter")
counter.add(1, {"key": "value"})

Workflows

MAF bietet vordefinierte Schritte zur Erledigung einer Aufgabe und integriert KI-Agenten als Komponenten in diesen Schritten.

Workflows bestehen aus verschiedenen Komponenten, die eine bessere Steuerung des Ablaufs ermöglichen. Workflows ermöglichen auch die Multi-Agenten-Orchestrierung und Checkpointing zum Speichern von Workflow-Zuständen.

Die Kernkomponenten eines Workflows sind

Executor

Executor erhalten Eingabenachrichten, führen ihre zugewiesenen Aufgaben aus und erzeugen dann eine Ausgabenachricht. Dies treibt den Workflow zur Erledigung der größeren Aufgabe voran. Executor können KI-Agenten oder benutzerdefinierte Logik sein.

Kanten (Edges)

Kanten werden verwendet, um den Fluss von Nachrichten in einem Workflow zu definieren. Diese können sein:

Direkte Kanten – Einfache Eins-zu-Eins-Verbindungen zwischen Executor.

from agent_framework import WorkflowBuilder

builder = WorkflowBuilder()
builder.add_edge(source_executor, target_executor)
builder.set_start_executor(source_executor)
workflow = builder.build()

Bedingte Kanten – Aktiviert, nachdem eine bestimmte Bedingung erfüllt ist. Zum Beispiel kann ein Executor bei Nichtverfügbarkeit von Hotelzimmern andere Optionen vorschlagen.

Switch-Case-Kanten – Leiten Nachrichten basierend auf definierten Bedingungen an verschiedene Executor weiter. Zum Beispiel: Wenn ein Reisender Prioritätszugang hat, werden seine Aufgaben über einen anderen Workflow bearbeitet.

Fan-out-Kanten – Senden eine Nachricht an mehrere Ziele.

Fan-in-Kanten – Sammeln mehrere Nachrichten von verschiedenen Executor und senden sie an ein Ziel.

Ereignisse

Um eine bessere Observability von Workflows zu gewährleisten, bietet MAF integrierte Ereignisse für die Ausführung, einschließlich

Migration von anderen Frameworks (Semantic Kernel und AutoGen)

Unterschiede zwischen MAF und Semantic Kernel

Vereinfachte Agentenerstellung

Semantic Kernel erfordert die Erstellung einer Kernel-Instanz für jeden Agenten. MAF verwendet einen vereinfachten Ansatz durch die Verwendung von Erweiterungen für die Hauptanbieter.

agent = AzureOpenAIChatClient(credential=AzureCliCredential()).create_agent( instructions="You are good at reccomending trips to customers based on their preferences.", name="TripRecommender" )

Agenten-Thread-Erstellung

Semantic Kernel erfordert die manuelle Erstellung von Threads. In MAF wird dem Agenten direkt ein Thread zugewiesen.

thread = agent.get_new_thread() # Run the agent with the thread. 

Tool-Registrierung

In Semantic Kernel werden Tools beim Kernel registriert, und der Kernel wird dann dem Agenten übergeben. In MAF werden Tools direkt während des Agentenerstellungsprozesses registriert.

agent = ChatAgent( chat_client=OpenAIChatClient(), instructions="You are a helpful assistant", tools=[get_attractions]

Unterschiede zwischen MAF und AutoGen

Teams vs. Workflows

Teams sind die Ereignisstruktur für ereignisgesteuerte Aktivitäten mit Agenten in AutoGen. MAF verwendet Workflows, die Daten über eine grafbasierte Architektur an Executor weiterleiten.

Tool-Erstellung

AutoGen verwendet FunctionTool, um Funktionen für Agentenaufrufe zu umschließen. MAF verwendet @ai_function, das ähnlich funktioniert, aber auch automatisch Schemata für jede Funktion ableitet.

Agentenverhalten

Agenten sind in AutoGen standardmäßig Single-Turn-Agenten, es sei denn, max_tool_iterations ist höher eingestellt. Innerhalb von MAF ist der ChatAgent standardmäßig ein Multi-Turn-Agent, was bedeutet, dass er weiterhin Tools aufruft, bis die Aufgabe des Benutzers abgeschlossen ist.

Codebeispiele

Codebeispiele für das Microsoft Agent Framework finden Sie in diesem Repository unter den Dateien xx-python-agent-framework und xx-dotnet-agent-framework.

Haben Sie weitere Fragen zum Microsoft Agent Framework?

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.