Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Protokół Agent-to-Agent (A2A) umożliwia ustandaryzowaną komunikację między agentami, umożliwiając agentom skompilowaną przy użyciu różnych struktur i technologii bezproblemowe komunikowanie się.
Co to jest A2A?
A2A to standardowy protokół obsługujący:
- Odnajdywanie agentów za pośrednictwem kart agentów
- Komunikacja oparta na komunikatach między agentami
- Długotrwałe procesy agentyczne poprzez zadania
- Współdziałanie międzyplatformowe między różnymi frameworkami agentów
Aby uzyskać więcej informacji, zobacz specyfikację protokołu A2A.
Biblioteka Microsoft.Agents.AI.Hosting.A2A.AspNetCore zapewnia integrację ASP.NET Core na potrzeby uwidaczniania agentów za pośrednictwem protokołu A2A.
Pakiety NuGet:
Example
W tym minimalnym przykładzie pokazano, jak uwidocznić agenta za pośrednictwem usługi A2A. Przykład obejmuje zależności OpenAPI i Swagger w celu uproszczenia testowania.
1. Tworzenie projektu internetowego interfejsu API platformy ASP.NET Core
Utwórz nowy projekt internetowego interfejsu API platformy ASP.NET Core lub użyj istniejącego.
2. Zainstaluj wymagane zależności
Zainstaluj następujące pakiety:
Uruchom następujące polecenia w katalogu projektu, aby zainstalować wymagane pakiety NuGet:
# Hosting.A2A.AspNetCore for A2A protocol integration
dotnet add package Microsoft.Agents.AI.Hosting.A2A.AspNetCore --prerelease
# Libraries to connect to Azure OpenAI
dotnet add package Azure.AI.OpenAI --prerelease
dotnet add package Azure.Identity
dotnet add package Microsoft.Extensions.AI
dotnet add package Microsoft.Extensions.AI.OpenAI --prerelease
# Swagger to test app
dotnet add package Microsoft.AspNetCore.OpenApi
dotnet add package Swashbuckle.AspNetCore
3. Konfigurowanie połączenia azure OpenAI
Aplikacja wymaga połączenia azure OpenAI. Skonfiguruj punkt końcowy i nazwę wdrożenia przy użyciu dotnet user-secrets lub zmiennych środowiskowych.
Można również po prostu edytować element appsettings.json, ale nie jest to zalecane dla aplikacji wdrożonych w środowisku produkcyjnym, ponieważ niektóre dane mogą być uważane za tajne.
dotnet user-secrets set "AZURE_OPENAI_ENDPOINT" "https://<your-openai-resource>.openai.azure.com/"
dotnet user-secrets set "AZURE_OPENAI_DEPLOYMENT_NAME" "gpt-4o-mini"
4. Dodaj kod do Program.cs
Zastąp zawartość Program.cs pliku następującym kodem i uruchom aplikację:
using A2A.AspNetCore;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI.Hosting;
using Microsoft.Extensions.AI;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenApi();
builder.Services.AddSwaggerGen();
string endpoint = builder.Configuration["AZURE_OPENAI_ENDPOINT"]
?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = builder.Configuration["AZURE_OPENAI_DEPLOYMENT_NAME"]
?? throw new InvalidOperationException("AZURE_OPENAI_DEPLOYMENT_NAME is not set.");
// Register the chat client
IChatClient chatClient = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
.GetChatClient(deploymentName)
.AsIChatClient();
builder.Services.AddSingleton(chatClient);
// Register an agent
var pirateAgent = builder.AddAIAgent("pirate", instructions: "You are a pirate. Speak like a pirate.");
var app = builder.Build();
app.MapOpenApi();
app.UseSwagger();
app.UseSwaggerUI();
// Expose the agent via A2A protocol. You can also customize the agentCard
app.MapA2A(pirateAgent, path: "/a2a/pirate", agentCard: new()
{
Name = "Pirate Agent",
Description = "An agent that speaks like a pirate.",
Version = "1.0"
});
app.Run();
Testowanie agenta
Po uruchomieniu aplikacji możesz przetestować agenta A2A przy użyciu następującego .http pliku lub za pośrednictwem interfejsu użytkownika programu Swagger.
Format danych wejściowych jest zgodny ze specyfikacją A2A. Możesz podać wartości dla:
-
messageId- Unikatowy identyfikator dla tej konkretnej wiadomości. Możesz utworzyć własny identyfikator (np. identyfikator GUID) lub ustawić go tak, abynullumożliwić agentowi automatyczne wygenerowanie identyfikatora. -
contextId- Identyfikator konwersacji. Podaj własny identyfikator, aby rozpocząć nową konwersację lub kontynuować istniejącą, ponownie używając poprzedniegocontextIdelementu . Agent zachowa historię konwersacji dla tego samegocontextIdelementu . Agent wygeneruje jeden dla ciebie również, jeśli żaden nie zostanie podany.
# Send A2A request to the pirate agent
POST {{baseAddress}}/a2a/pirate/v1/message:stream
Content-Type: application/json
{
"message": {
"kind": "message",
"role": "user",
"parts": [
{
"kind": "text",
"text": "Hey pirate! Tell me where have you been",
"metadata": {}
}
],
"messageId": null,
"contextId": "foo"
}
}
Uwaga: zastąp {{baseAddress}} punktem końcowym serwera.
To żądanie zwraca następującą odpowiedź JSON:
{
"kind": "message",
"role": "agent",
"parts": [
{
"kind": "text",
"text": "Arrr, ye scallywag! Ye’ll have to tell me what yer after, or be I walkin’ the plank? 🏴☠️"
}
],
"messageId": "chatcmpl-CXtJbisgIJCg36Z44U16etngjAKRk",
"contextId": "foo"
}
Odpowiedź zawiera contextId (identyfikator konwersacji), messageId (identyfikator wiadomości) i faktyczną zawartość od agenta pirackiego.
Konfiguracja AgentCard
Zawiera AgentCard metadane dotyczące agenta na potrzeby odnajdywania i integracji:
app.MapA2A(agent, "/a2a/my-agent", agentCard: new()
{
Name = "My Agent",
Description = "A helpful agent that assists with tasks.",
Version = "1.0",
});
Dostęp do karty agenta można uzyskać, wysyłając następujące żądanie:
# Send A2A request to the pirate agent
GET {{baseAddress}}/a2a/pirate/v1/card
Uwaga: zastąp {{baseAddress}} punktem końcowym serwera.
Właściwości karty agenta
- Nazwa: Nazwa wyświetlana agenta
- Opis: krótki opis agenta
- Wersja: ciąg wersji agenta
- Adres URL: adres URL punktu końcowego (automatycznie przypisany, jeśli nie zostanie określony)
- Możliwości: metadane opcjonalne dotyczące przesyłania strumieniowego, powiadomień typu push i innych funkcji
Uwidacznianie wielu agentów
Możesz uwidocznić wielu agentów w jednej aplikacji, o ile ich punkty końcowe nie zderzają się. Oto przykład:
var mathAgent = builder.AddAIAgent("math", instructions: "You are a math expert.");
var scienceAgent = builder.AddAIAgent("science", instructions: "You are a science expert.");
app.MapA2A(mathAgent, "/a2a/math");
app.MapA2A(scienceAgent, "/a2a/science");
Pakiet agent-framework-a2a umożliwia nawiązywanie połączenia z zewnętrznymi agentami zgodnymi z usługą A2A i komunikowanie się z nimi.
pip install agent-framework-a2a --pre
Nawiązywanie połączenia z agentem A2A
Użyj A2AAgent, aby opakować dowolny zdalny punkt końcowy A2A. Agent ustala zdolności agenta zdalnego za pomocą AgentCard i zarządza wszystkimi szczegółami protokołu.
import asyncio
import httpx
from a2a.client import A2ACardResolver
from agent_framework.a2a import A2AAgent
async def main():
a2a_host = "https://your-a2a-agent.example.com"
# 1. Discover the remote agent's capabilities
async with httpx.AsyncClient(timeout=60.0) as http_client:
resolver = A2ACardResolver(httpx_client=http_client, base_url=a2a_host)
agent_card = await resolver.get_agent_card()
print(f"Found agent: {agent_card.name}")
# 2. Create an A2AAgent and send a message
async with A2AAgent(
name=agent_card.name,
agent_card=agent_card,
url=a2a_host,
) as agent:
response = await agent.run("What are your capabilities?")
for message in response.messages:
print(message.text)
asyncio.run(main())
Odpowiedzi w strumieniowaniu
A2A w sposób naturalny obsługuje przesyłanie strumieniowe za pośrednictwem zdarzeń wysyłanych przez serwer — aktualizacje są dostarczane w czasie rzeczywistym, w miarę jak działa agent zdalny:
async with A2AAgent(name="remote", url="https://a2a-agent.example.com") as agent:
async with agent.run("Tell me about yourself", stream=True) as stream:
async for update in stream:
for content in update.contents:
if content.text:
print(content.text, end="", flush=True)
final = await stream.get_final_response()
print(f"\n({len(final.messages)} message(s))")
Zadania długotrwałe
Domyślnie A2AAgent czeka na zakończenie pracy agenta zdalnego przed powrotem. W przypadku długotrwałych zadań ustaw background=True opcję uzyskania tokenu kontynuacji, którego można użyć do sondowania lub ponownego przypisania później:
async with A2AAgent(name="worker", url="https://a2a-agent.example.com") as agent:
# Start a long-running task
response = await agent.run("Process this large dataset", background=True)
if response.continuation_token:
# Poll for completion later
result = await agent.poll_task(response.continuation_token)
print(result)
Authentication
Użyj elementu AuthInterceptor dla zabezpieczonych punktów końcowych A2A:
from a2a.client.auth.interceptor import AuthInterceptor
class BearerAuth(AuthInterceptor):
def __init__(self, token: str):
self.token = token
async def intercept(self, request):
request.headers["Authorization"] = f"Bearer {self.token}"
return request
async with A2AAgent(
name="secure-agent",
url="https://secure-a2a-agent.example.com",
auth_interceptor=BearerAuth("your-token"),
) as agent:
response = await agent.run("Hello!")