Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Protokol A2A (Agent-to-Agent) umožňuje standardizovanou komunikaci mezi agenty, což umožňuje bezproblémovou komunikaci agentů vytvořených s různými architekturami a technologiemi.
Co je A2A?
A2A je standardizovaný protokol, který podporuje:
- Zjišťování agentů prostřednictvím karet agenta
- Komunikace založená na zprávách mezi agenty
- Dlouhotrvající agentické procesy prostřednictvím úkolů
- Interoperabilita mezi platformami mezi různými architekturami agentů
Další informace najdete ve specifikaci protokolu A2A.
Knihovna Microsoft.Agents.AI.Hosting.A2A.AspNetCore poskytuje integraci ASP.NET Core pro expozici vašich agentů prostřednictvím protokolu A2A.
Balíčky NuGet:
Example
Tento minimální příklad ukazuje, jak vystavit agenta prostřednictvím A2A. Ukázka zahrnuje závislosti OpenAPI a Swagger, které zjednodušují testování.
1. Vytvoření projektu webového rozhraní API ASP.NET Core
Vytvořte nový projekt webového rozhraní API ASP.NET Core nebo použijte existující projekt.
2. Instalace požadovaných závislostí
Nainstalujte následující balíčky:
- .NET CLI
Spuštěním následujících příkazů v adresáři projektu nainstalujte požadované balíčky NuGet:
# Hosting.A2A.AspNetCore for A2A protocol integration
dotnet add package Microsoft.Agents.AI.Hosting.A2A.AspNetCore --prerelease
# Libraries to connect to Microsoft Foundry
dotnet add package Azure.AI.Projects --prerelease
dotnet add package Azure.Identity
dotnet add package Microsoft.Agents.AI.Foundry --prerelease
# Swagger to test app
dotnet add package Microsoft.AspNetCore.OpenApi
dotnet add package Swashbuckle.AspNetCore
3. Konfigurace připojení Microsoft Foundry
Aplikace vyžaduje připojení projektu Microsoft Foundry. Nakonfigurujte koncový bod a název nasazení pomocí dotnet user-secrets nebo proměnných prostředí.
Můžete také jednoduše upravit appsettings.json, ale to se nedoporučuje pro aplikace nasazené v produkčním prostředí, protože některá data se dají považovat za tajná.
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. Přidejte kód do Program.cs
Nahraďte obsah Program.cs následujícím kódem a spusťte aplikaci:
using A2A.AspNetCore;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
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 AIProjectClient(
new Uri(endpoint),
new DefaultAzureCredential())
.GetProjectOpenAIClient()
.GetProjectResponsesClient()
.AsIChatClient(deploymentName);
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();
Výstraha
DefaultAzureCredential je vhodný pro vývoj, ale vyžaduje pečlivé zvážení v produkčním prostředí. V produkčním prostředí zvažte použití konkrétních přihlašovacích údajů (např ManagedIdentityCredential. ) k zabránění problémům s latencí, neúmyslnému testování přihlašovacích údajů a potenciálním bezpečnostním rizikům z náhradních mechanismů.
Testování agenta
Po spuštění aplikace můžete agenta A2A otestovat pomocí následujícího .http souboru nebo pomocí uživatelského rozhraní Swagger.
Vstupní formát odpovídá specifikaci A2A. Můžete zadat hodnoty pro:
-
messageId– Jedinečný identifikátor pro tuto konkrétní zprávu. Můžete vytvořit vlastní ID (např. GUID) nebo ho nastavit nanull, aby ho agent vygeneroval automaticky. -
contextId- Identifikátor konverzace. Zadejte vlastní ID, abyste mohli zahájit novou konverzaci nebo pokračovat v existující konverzaci opětovným použitím předchozíhocontextId. Agent bude spravovat historii konverzací pro tentýžcontextId. Agent pro vás vygeneruje také jeden, pokud není k dispozici.
# 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"
}
}
Poznámka: Nahraďte {{baseAddress}} koncovým bodem serveru.
Tento požadavek vrátí následující odpověď 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"
}
Odpověď obsahuje contextId (identifikátor konverzace), messageId (identifikátor zprávy) a skutečný obsah od pirátských agentů.
Konfigurace AgentCard
Tento AgentCard poskytuje metadata o vašem agentovi pro objevování a integraci.
app.MapA2A(agent, "/a2a/my-agent", agentCard: new()
{
Name = "My Agent",
Description = "A helpful agent that assists with tasks.",
Version = "1.0",
});
K kartě agenta se dostanete odesláním tohoto požadavku:
# Send A2A request to the pirate agent
GET {{baseAddress}}/a2a/pirate/v1/card
Poznámka: Nahraďte {{baseAddress}} koncovým bodem serveru.
Vlastnosti AgentCard
- Název: Zobrazovaný název agenta
- Popis: Stručný popis agenta
- Verze: Řetězec verze pro agenta
- Adresa URL: Adresa URL koncového bodu (automaticky přiřazená, pokud není zadána)
- Možnosti: Volitelná metadata o streamování, nabízených oznámeních a dalších funkcích
Zpřístupnění více agentů
V jedné aplikaci můžete vystavit více agentů, pokud jejich koncové body nekolidují. Tady je příklad:
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");
Balíček agent-framework-a2a umožňuje připojit se k externím agentům kompatibilním s A2A a vystavit agenta Agent Framework přes protokol A2A.
pip install agent-framework-a2a --pre
Připojení k agentovi A2A
Použijte A2AAgent k zabalení jakéhokoli vzdáleného koncového bodu A2A. Agent vyřeší možnosti vzdáleného agenta prostřednictvím jeho AgentCard a zpracuje všechny podrobnosti protokolu.
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())
Odpovědi na streamování
A2A přirozeně podporuje streamování prostřednictvím Server-Sent Events — aktualizace přicházejí v reálném čase, jak vzdálený agent pracuje.
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))")
Dlouhotrvající úkoly
Ve výchozím nastavení A2AAgent čeká, až vzdálený agent dokončí svou činnost, než se vrátí. U dlouhotrvajících úloh nastavte background=True , abyste získali token pro pokračování, který můžete použít k dotazování nebo opětovnému připisování později:
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)
Identita kontextu konverzace (context_id)
Při volání A2AAgent.run() s AgentSession agent automaticky odvozuje A2A context_id z session.service_session_id, pokud odchozí zpráva ještě žádný nenese. Díky tomu můžete udržovat kontinuitu konverzací ve více voláních A2A bez ručního nastavení context_id každé zprávy:
from agent_framework import AgentSession
from agent_framework.a2a import A2AAgent
async with A2AAgent(name="remote", url="https://a2a-agent.example.com") as agent:
session = AgentSession(service_session_id="my-conversation-1")
# context_id is automatically set to "my-conversation-1"
response = await agent.run("Hello!", session=session)
# Subsequent calls with the same session continue the conversation
response = await agent.run("Follow-up question", session=session)
Pokud má zpráva explicitní context_id ve svém additional_properties, má tato hodnota přednost před náhradní hodnotou odvozenou ze sezení.
Autentizace
Použijte AuthInterceptor pro zabezpečené A2A koncové body:
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!")
Zpřístupnění agenta rámce přes A2A
Adaptuje A2AExecutor libovolnou architekturu Agent agenta na protokol na straně serveru A2A. Můžete ho hostovat pomocí oficiálního a2a-sdk serveru Starlette/ASGI, aby ostatní klienti A2A mohli vyhledat a volat vašeho agenta.
import uvicorn
from a2a.server.apps import A2AStarletteApplication
from a2a.server.request_handlers import DefaultRequestHandler
from a2a.server.tasks import InMemoryTaskStore
from a2a.types import AgentCapabilities, AgentCard, AgentSkill
from agent_framework import Agent
from agent_framework.a2a import A2AExecutor
from agent_framework.openai import OpenAIChatClient
flight_skill = AgentSkill(
id="Flight_Booking",
name="Flight Booking",
description="Search and book flights across Europe.",
tags=["flights", "travel", "europe"],
examples=[],
)
public_agent_card = AgentCard(
name="Europe Travel Agent",
description="Helps users search and book flights and hotels across Europe.",
url="http://localhost:9999/",
version="1.0.0",
defaultInputModes=["text"],
defaultOutputModes=["text"],
capabilities=AgentCapabilities(streaming=True),
skills=[flight_skill],
)
agent = Agent(
client=OpenAIChatClient(),
name="Europe Travel Agent",
instructions="You are a helpful Europe Travel Agent.",
)
request_handler = DefaultRequestHandler(
agent_executor=A2AExecutor(agent),
task_store=InMemoryTaskStore(),
)
server = A2AStarletteApplication(
agent_card=public_agent_card,
http_handler=request_handler,
).build()
uvicorn.run(server, host="0.0.0.0", port=9999)
A2AExecutor Streamuje aktualizace agenta jako artefakty A2A, když podkladový agent podporuje streamování, propaguje A2A context_id jako agentův thread_id, a zveřejňuje save_thread/get_thread háky, které lze přepsat pro trvalé uchování vláken.
Tip
Podívejte se na ukázku kompletního spustitelného agent_framework_to_a2a.py příkladu.