1. Projektübersicht
Das A2A (Agent2Agent) .NET SDK ist eine .NET-Bibliothek, die Googles A2A Protocol v0.2.1 implementiert und Agent-zu-Agent-Kommunikation in .NET-Anwendungen ermöglicht. Dieses SDK ist für die Arbeit mit ASP.NET Core-Anwendungen konzipiert und bietet eine einfache Möglichkeit, A2A-Unterstützung zu Ihren Agenten hinzuzufügen.
Hauptmerkmale
- Protokollkompatibilität: Implementiert die meisten Funktionen des A2A Protocol v0.2.1
- Multi-Framework-Unterstützung: Unterstützt .NET 9.0, .NET 8.0 und .NET Standard 2.0
- ASP.NET Core-Integration: Bietet einfache Integrationsmethoden
- Aufgabenverwaltung: Standardisierte Aufgabenverwaltung und Ausführungsunterstützung
- Streaming: Unterstützt Echtzeit-Streaming-Antworten
- OpenTelemetry: Integrierte Telemetrie- und Observability-Unterstützung
Projektstatus
Die Bibliothek hat die meisten Funktionen des Protokolls implementiert, aber einige Szenarien können noch unvollständig sein. Das größte fehlende Feature ist der Client-Callback mit Push-Benachrichtigungen.
2. A2A .NET Core-Architektur
2.1 Projektstruktur
src/
├── A2A/ # Haupt-A2A-Protokollimplementierung
│ ├── Client/ # Client-Komponenten
│ ├── JsonRpc/ # JSON-RPC-Implementierung
│ ├── Models/ # Datenmodelle
│ ├── Server/ # Serverseitige Komponenten
│ └── openapi.yaml # API-Spezifikation
└── A2A.AspNetCore/ # ASP.NET Core-Integration
2.2 Hauptkomponenten
- A2A Core Library: Enthält die Haupt-Protokollimplementierung
- A2A.AspNetCore: Bietet ASP.NET Core-Integration
- Beispielprojekte: Beispielcode, der verschiedene Nutzungsszenarien demonstriert
3. A2A .NET Client-Implementierung
3.1 A2AClient-Klasse
Die A2AClient
-Klasse ist die Haupt-Client-Schnittstelle für die Kommunikation mit Agenten und implementiert das IA2AClient
-Interface.
Hauptfunktionen:
public class A2AClient : IA2AClient
{
// Nachricht senden
public Task<A2AResponse> SendMessageAsync(MessageSendParams taskSendParams)
// Aufgabe abrufen
public Task<AgentTask> GetTaskAsync(string taskId)
// Aufgabe abbrechen
public Task<AgentTask> CancelTaskAsync(TaskIdParams taskIdParams)
// Stream-Nachricht senden
public async IAsyncEnumerable<SseItem<A2AEvent>> SendMessageStreamAsync(MessageSendParams taskSendParams)
// Aufgabe erneut abonnieren
public async IAsyncEnumerable<SseItem<A2AEvent>> ResubscribeToTaskAsync(string taskId)
}
Hauptmerkmale:
- JSON-RPC-Kommunikation: Alle Kommunikation erfolgt über das JSON-RPC-Protokoll
- Streaming-Antwort: Unterstützt Server-Sent Events (SSE) für Echtzeit-Streaming
- Serialisierungsoptimierung: Verwendet System.Text.Json Source Generator für Hochleistungs-Serialisierung
- Fehlerbehandlung: Vollständige Fehlerbehandlung und Zustandsverwaltung
3.2 JsonRpcContent-Klasse
Speziell für JSON-RPC-Anfragen entwickelte HTTP-Content-Klasse:
public class JsonRpcContent : HttpContent
{
public JsonRpcContent(JsonRpcRequest request)
{
_request = request;
Headers.ContentType = new MediaTypeHeaderValue("application/json");
}
}
3.3 A2ACardResolver-Klasse
Wird zum Parsen und Abrufen von Agent-Karteninformationen verwendet:
public class A2ACardResolver
{
public async Task<AgentCard> GetAgentCardAsync(Uri agentUri)
public async Task<AgentCard> GetAgentCardAsync(string agentUrl)
}
4. A2A .NET Server-Implementierung
4.1 TaskManager-Klasse
Der TaskManager
ist die Haupt-Serverkomponente, die für die Verwaltung des Aufgaben-Lebenszyklus verantwortlich ist.
Hauptverantwortlichkeiten:
- Aufgaben-Lebenszyklus-Verwaltung: Erstellen, Aktualisieren, Abbrechen von Aufgaben
- Nachrichtenverarbeitung: Behandlung eingehender Nachrichten und Aufgaben-Updates
- Event-Verteilung: Verwaltung von Aufgaben-Statusänderungs-Events
- Storage-Abstraktion: Aufgaben-Persistierung über das
ITaskStore
-Interface
Hauptmethoden:
public class TaskManager : ITaskManager
{
// Event-Handler
public Func<MessageSendParams, Task<Message>>? OnMessageReceived { get; set; }
public Func<AgentTask, Task> OnTaskCreated { get; set; }
public Func<AgentTask, Task> OnTaskCancelled { get; set; }
public Func<AgentTask, Task> OnTaskUpdated { get; set; }
public Func<string, AgentCard> OnAgentCardQuery { get; set; }
// Hauptoperationen
public async Task<AgentTask> CreateTaskAsync(string? contextId = null)
public async Task<AgentTask?> CancelTaskAsync(TaskIdParams? taskIdParams)
public async Task<A2AResponse?> SendMessageAsync(MessageSendParams messageSendParams)
public async Task<IAsyncEnumerable<A2AEvent>> SendMessageStreamAsync(MessageSendParams messageSendParams)
public async Task UpdateStatusAsync(string taskId, TaskState status, Message? message = null, bool final = false)
public async Task ReturnArtifactAsync(string taskId, Artifact artifact)
}
4.2 ITaskStore-Interface
Abstraktes Interface für Aufgaben-Speicherung:
public interface ITaskStore
{
Task<AgentTask?> GetTaskAsync(string taskId);
Task SetTaskAsync(AgentTask task);
Task UpdateStatusAsync(string taskId, TaskState status);
}
4.3 ASP.NET Core-Integration
Über die von der A2A.AspNetCore
-Bibliothek bereitgestellten Erweiterungsmethoden:
// JSON-RPC A2A-Unterstützung hinzufügen
app.MapA2A(taskManager, "/echo");
// HTTP A2A-Unterstützung hinzufügen
app.MapHttpA2A(taskManager, "/echo");
5. A2A .NET Datenmodelle
5.1 Haupt-Modellklassen
AgentCard - Agent-Karte
public class AgentCard
{
public string Name { get; set; } // Agent-Name
public string Description { get; set; } // Agent-Beschreibung
public string Url { get; set; } // Agent-URL
public AgentProvider? Provider { get; set; } // Anbieter-Informationen
public string Version { get; set; } // Versionsinformationen
public AgentCapabilities Capabilities { get; set; } // Agent-Fähigkeiten
public List<AgentSkill> Skills { get; set; } // Agent-Fertigkeiten
public List<string> DefaultInputModes { get; set; } // Standard-Eingabemodi
public List<string> DefaultOutputModes { get; set; }// Standard-Ausgabemodi
}
AgentTask - Agent-Aufgabe
public class AgentTask : A2AResponse
{
public string Id { get; set; } // Aufgaben-ID
public string? ContextId { get; set; } // Kontext-ID
public AgentTaskStatus Status { get; set; } // Aufgabenstatus
public List<Artifact>? Artifacts { get; set; } // Aufgaben-Artefakte
public List<Message>? History { get; set; } // Nachrichtenverlauf
public Dictionary<string, JsonElement>? Metadata { get; set; } // Metadaten
}
Message - Nachricht
public class Message : A2AResponse
{
public MessageRole Role { get; set; } // Nachrichtenrolle (User/Agent)
public List<Part> Parts { get; set; } // Nachrichtenteile
public string? MessageId { get; set; } // Nachrichten-ID
public string? TaskId { get; set; } // Zugehörige Aufgaben-ID
public string? ContextId { get; set; } // Kontext-ID
public Dictionary<string, JsonElement>? Metadata { get; set; } // Metadaten
}
5.2 Aufgabenstatus
public enum TaskState
{
Submitted, // Eingereicht
Working, // In Bearbeitung
InputRequired, // Eingabe erforderlich
Completed, // Abgeschlossen
Canceled, // Abgebrochen
Failed, // Fehlgeschlagen
Rejected // Abgelehnt
}
5.3 Nachrichtenteil-Typen
Unterstützt mehrere Nachrichtenteil-Typen:
TextPart
: TextinhaltFilePart
: DateiinhaltDataPart
: Dateninhalt
6. Detaillierte Analyse des A2A .NET AgentServer-Beispiels
6.1 Projektübersicht
Das AgentServer-Beispiel zeigt, wie verschiedene Arten von Agenten erstellt und bereitgestellt werden, einschließlich:
- EchoAgent: Einfacher Echo-Agent
- EchoAgentWithTasks: Echo-Agent mit Aufgabenunterstützung
- HostedClientAgent: Gehosteter Client-Agent
- ResearcherAgent: Forscher-Agent (State Machine-Implementierung)
6.2 EchoAgent-Implementierung
public class EchoAgent
{
private ITaskManager? _taskManager;
public void Attach(TaskManager taskManager)
{
_taskManager = taskManager;
taskManager.OnMessageReceived = ProcessMessage;
taskManager.OnAgentCardQuery = GetAgentCard;
}
public Task<Message> ProcessMessage(MessageSendParams messageSendParams)
{
var messageText = messageSendParams.Message.Parts.OfType<TextPart>().First().Text;
var message = new Message()
{
Role = MessageRole.Agent,
MessageId = Guid.NewGuid().ToString(),
ContextId = messageSendParams.Message.ContextId,
Parts = [new TextPart() { Text = $"Echo: {messageText}" }]
};
return Task.FromResult(message);
}
}
6.3 ResearcherAgent-Implementierung
ResearcherAgent zeigt eine komplexere State Machine-Implementierung:
public class ResearcherAgent
{
private enum AgentState
{
Planning, // Planungsphase
WaitingForFeedbackOnPlan, // Warten auf Feedback zum Plan
Researching // Forschungsphase
}
public async Task Invoke(string taskId, string message)
{
switch (_agentStates[taskId])
{
case AgentState.Planning:
await DoPlanning(taskId, message);
break;
case AgentState.WaitingForFeedbackOnPlan:
if (message == "go ahead")
await DoResearch(taskId, message);
else
await DoPlanning(taskId, message);
break;
case AgentState.Researching:
await DoResearch(taskId, message);
break;
}
}
}
7. Wie man das AgentServer-Beispiel ausführt
7.1 Umgebungsanforderungen
- .NET 9.0 SDK oder höher
- Optional: OpenTelemetry Collector (für Telemetriedaten)
7.2 Ausführungsschritte
-
Projekt klonen:
git clone https://github.com/a2aproject/a2a-dotnet cd a2a-dotnet
-
Zum Beispielverzeichnis navigieren:
cd samples/AgentServer
-
Projekt ausführen:
dotnet run
-
Überprüfen, ob der Service läuft: Der Service startet auf den folgenden Ports:
- HTTP: http://localhost:5048
- HTTPS: https://localhost:7014
7.3 Verfügbare Endpunkte
/echo
- Einfacher Echo-Agent/echotasks
- Echo-Agent mit Aufgabenunterstützung/hostedclient
- Gehosteter Client-Agent/researcher
- Forscher-Agent
7.4 API-Aufrufe testen
Agent-Karte abrufen
curl -X GET http://localhost:5048/echo/.well-known/agent.json
Nachricht an Echo-Agent senden
curl -X POST http://localhost:5048/echo \
-H "Content-Type: application/json" \
-d '{
"id": "1",
"jsonrpc": "2.0",
"method": "message/send",
"params": {
"message": {
"messageId": "12345",
"role": "user",
"parts": [
{
"kind": "text",
"text": "Hello, world!"
}
]
}
}
}'
Forscher-Agent-Aufgabe erstellen
curl -X POST http://localhost:5048/researcher \
-H "Content-Type: application/json" \
-d '{
"id": "1",
"jsonrpc": "2.0",
"method": "message/send",
"params": {
"message": {
"messageId": "research-1",
"role": "user",
"parts": [
{
"kind": "text",
"text": "Research the current price of butter"
}
]
}
}
}'
8. Sequenzdiagramme
8.1 Einfaches Nachrichtenverarbeitungs-Sequenzdiagramm
sequenceDiagram
participant Client as Client
participant Server as A2A Server
participant Agent as Agent Implementation
participant TaskMgr as TaskManager
Client->>Server: POST /echo (JSON-RPC message/send)
Server->>TaskMgr: SendMessageAsync()
TaskMgr->>Agent: OnMessageReceived()
Agent->>Agent: ProcessMessage()
Agent-->>TaskMgr: Return Message
TaskMgr-->>Server: Return A2AResponse
Server-->>Client: JSON-RPC Response
8.2 Aufgabenverarbeitungs-Sequenzdiagramm
sequenceDiagram
participant Client as Client
participant Server as A2A Server
participant TaskMgr as TaskManager
participant Agent as Agent Implementation
participant Store as TaskStore
Client->>Server: POST /researcher (message/send)
Server->>TaskMgr: SendMessageAsync()
TaskMgr->>TaskMgr: CreateTaskAsync()
TaskMgr->>Store: SetTaskAsync()
TaskMgr->>Agent: OnTaskCreated()
Agent->>Agent: State Change (Planning)
Agent->>TaskMgr: UpdateStatusAsync(Working)
TaskMgr->>Store: UpdateStatusAsync()
Agent->>TaskMgr: ReturnArtifactAsync()
Agent->>TaskMgr: UpdateStatusAsync(InputRequired)
TaskMgr-->>Server: Return AgentTask
Server-->>Client: JSON-RPC Response
Note over Client,Store: Client sends follow-up message
Client->>Server: POST /researcher (message/send, taskId)
Server->>TaskMgr: SendMessageAsync()
TaskMgr->>Store: GetTaskAsync()
TaskMgr->>Agent: OnTaskUpdated()
Agent->>Agent: State processing logic
Agent->>TaskMgr: UpdateStatusAsync(Completed)
TaskMgr-->>Server: Return AgentTask
Server-->>Client: JSON-RPC Response
8.3 Streaming-Verarbeitungs-Sequenzdiagramm
sequenceDiagram
participant Client as Client
participant Server as A2A Server
participant TaskMgr as TaskManager
participant Agent as Agent Implementation
Client->>Server: POST /echo (JSON-RPC message/stream)
Server->>TaskMgr: SendMessageStreamAsync()
TaskMgr->>Agent: OnMessageReceived()
loop Streaming Response
Agent->>TaskMgr: Generate Event
TaskMgr->>Server: A2AEvent
Server->>Client: Server-Sent Event
end
Agent->>TaskMgr: Complete Processing
TaskMgr->>Server: End Stream
Server->>Client: Close Connection
9. Wichtige A2A .NET Design-Patterns
9.1 Event-Driven Architecture
TaskManager verwendet das event-driven Pattern:
OnMessageReceived
: Behandlung eingehender NachrichtenOnTaskCreated
: Aufgaben-Erstellungs-EventOnTaskUpdated
: Aufgaben-Update-EventOnTaskCancelled
: Aufgaben-Abbruch-Event
9.2 Strategy Pattern
Verschiedene Agent-Implementierungen können verschiedene Verarbeitungsstrategien haben:
- Zustandslose Verarbeitung (EchoAgent)
- Zustandsbehaftete Verarbeitung (ResearcherAgent)
- Aufgaben-orientierte Verarbeitung (EchoAgentWithTasks)
9.3 Storage-Abstraktion
Aufgaben-Storage-Abstraktion über das ITaskStore
-Interface:
InMemoryTaskStore
: In-Memory-Storage-Implementierung- Erweiterbar für Datenbank-Storage-Implementierungen
10. A2A .NET Performance und Observability
10.1 Performance-Optimierung
- Source-Generated Serialization: Verwendet System.Text.Json Source Generator
- AOT-Kompatibilität: Unterstützt Native AOT-Kompilierung
- Asynchrone Verarbeitung: Umfassende Nutzung des async/await-Patterns
- Streaming-Verarbeitung: Unterstützt Streaming großer Datenvolumen
10.2 Observability
Integrierte OpenTelemetry-Unterstützung:
- Distributed Tracing: ActivitySource-Integration
- Metrics Collection: Aufgabenstatus- und Performance-Metriken
- Logging: Strukturierte Logging-Unterstützung
// OpenTelemetry-Konfigurationsbeispiel
builder.Services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddSource(TaskManager.ActivitySource.Name)
.AddSource(A2AJsonRpcProcessor.ActivitySource.Name)
.AddConsoleExporter()
.AddOtlpExporter());
11. A2A .NET Zusammenfassung
Das A2A .NET SDK bietet eine vollständige, produktionsreife Lösung für die Implementierung von Agent-zu-Agent-Kommunikation in .NET-Anwendungen.
11.1 Hauptvorteile
- Standardisiertes Protokoll: Basiert auf Googles A2A Protocol-Standard
- Einfache Integration: Einfache ASP.NET Core-Integration
- Flexible Architektur: Unterstützt mehrere Agent-Implementierungspatterns
- Hohe Performance: Optimierte Serialisierung und asynchrone Verarbeitung
- Observability: Integrierte Telemetrie- und Monitoring-Unterstützung
- Erweiterbarkeit: Abstrakte Interfaces unterstützen benutzerdefinierte Implementierungen
11.2 Anwendungsfälle
- KI-Agent-Systeme: Aufbau intelligenter Agent-Interaktionssysteme
- Microservice-Architektur: Intelligente Kommunikation zwischen Services
- Workflow-Engine: Agent-basierte Verarbeitung komplexer Geschäftsprozesse
- Chatbots: Multi-Agent-kollaboratives Dialogsystem
11.3 Zukünftige Entwicklung
- Push-Benachrichtigungen: Vollständige Client-Callback-Unterstützung
- Mehr Storage-Backends: Datenbank- und verteilte Storage-Unterstützung
- Sicherheitsverbesserungen: Umfassendere Authentifizierungs- und Autorisierungsmechanismen
- Protokoll-Updates: Auf dem neuesten Stand mit den neuesten A2A Protocol-Versionen bleiben
11.4 Entwicklungsempfehlungen
- Einfach beginnen: EchoAgent verwenden, um grundlegende Konzepte zu verstehen
- Zustandsverwaltung verstehen: ResearcherAgent's State Machine-Implementierung studieren
- Fokus auf Fehlerbehandlung: Umfassende Fehlerbehandlung und Recovery-Mechanismen implementieren
- Monitoring und Debugging: OpenTelemetry für System-Monitoring verwenden
- Test-Driven: Umfassende Unit- und Integrationstests schreiben
Dieses SDK bietet .NET-Entwicklern eine leistungsstarke und flexible Plattform zum Aufbau intelligenter Agent-Systeme der nächsten Generation. Durch seine klare Architektur und reichen Beispiele können Entwickler schnell beginnen und komplexe Agent-zu-Agent-Kommunikationsanwendungen erstellen.