Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Protokol Agent-to-Agent (A2A) memungkinkan komunikasi standar antar agen, memungkinkan agen yang dibangun dengan kerangka kerja dan teknologi yang berbeda untuk berkomunikasi dengan mulus.
Apa itu A2A?
A2A adalah protokol standar yang mendukung:
- Identifikasi agen dengan kartu agen
- Komunikasi berbasis pesan antar agen
- Proses agenik yang berjalan lama melalui tugas
- Interoperabilitas lintas platform antara kerangka kerja agen yang berbeda
Untuk informasi selengkapnya, lihat spesifikasi protokol A2A.
Library Microsoft.Agents.AI.Hosting.A2A.AspNetCore menyediakan integrasi ASP.NET Core untuk memperlihatkan agen Anda melalui protokol A2A.
Paket NuGet:
Contoh
Contoh minimal ini menunjukkan cara mengekspos agen melalui A2A. Sampel termasuk dependensi OpenAPI dan Swagger untuk menyederhanakan pengujian.
1. Buat proyek ASP.NET Core Web API
Buat proyek ASP.NET Core Web API baru atau gunakan yang sudah ada.
2. Pasang dependensi yang diperlukan
Instal paket berikut:
Jalankan perintah berikut di direktori proyek Anda untuk menginstal paket NuGet yang diperlukan:
# 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. Mengatur koneksi Microsoft Foundry
Aplikasi ini memerlukan koneksi proyek Microsoft Foundry. Konfigurasikan titik akhir dan nama penyebaran menggunakan dotnet user-secrets atau variabel lingkungan.
Anda juga dapat mengedit appsettings.json, tetapi hal ini tidak disarankan untuk aplikasi yang disebarkan dalam lingkungan produksi karena beberapa data dapat dianggap rahasia.
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. Tambahkan kode ke Program.cs
Ganti konten Program.cs dengan kode berikut dan jalankan aplikasi:
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();
Peringatan
DefaultAzureCredential nyaman untuk pengembangan tetapi membutuhkan pertimbangan yang cermat dalam produksi. Dalam produksi, pertimbangkan untuk menggunakan kredensial tertentu (misalnya, ManagedIdentityCredential) untuk menghindari masalah latensi, pemeriksaan kredensial yang tidak diinginkan, dan potensi risiko keamanan dari mekanisme fallback.
Menguji Agen
Setelah aplikasi berjalan, Anda dapat menguji agen A2A menggunakan file berikut .http atau melalui antarmuka pengguna Swagger.
Format input mematuhi spesifikasi A2A. Anda dapat memberikan nilai untuk:
-
messageId- Pengidentifikasi unik untuk pesan spesifik ini. Anda dapat membuat ID Anda sendiri (misalnya GUID) atau mengaturnya kenulluntuk membiarkan agen membuatnya secara otomatis. -
contextId- Pengidentifikasi percakapan. Berikan ID Anda sendiri untuk memulai percakapan baru atau melanjutkan percakapan yang sudah ada dengan menggunakan kembalicontextIdsebelumnya. Agen akan mempertahankan riwayat percakapan untuk hal yang samacontextId. Agen juga akan menghasilkan satu untuk Anda, jika tidak ada yang disediakan.
# 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"
}
}
Catatan: Ganti {{baseAddress}} dengan titik akhir server Anda.
Permintaan ini mengembalikan respons JSON berikut:
{
"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"
}
Respons mencakup contextId (pengidentifikasi percakapan), messageId (pengidentifikasi pesan), dan konten aktual dari agen bajak laut.
Konfigurasi AgentCard
AgentCard menyediakan metadata tentang agen Anda untuk penemuan dan integrasi:
app.MapA2A(agent, "/a2a/my-agent", agentCard: new()
{
Name = "My Agent",
Description = "A helpful agent that assists with tasks.",
Version = "1.0",
});
Anda dapat mengakses kartu agen dengan mengirim permintaan ini:
# Send A2A request to the pirate agent
GET {{baseAddress}}/a2a/pirate/v1/card
Catatan: Ganti {{baseAddress}} dengan titik akhir server Anda.
Properti AgentCard
- Nama: Nama yang ditampilkan dari agen
- Deskripsi: Deskripsi singkat agen
- Versi: String versi untuk agen
- Url: URL Titik Akhir (ditetapkan secara otomatis jika tidak ditentukan)
- Kemampuan: Metadata opsional tentang streaming, pemberitahuan push, dan fitur lainnya
Mengekspos Beberapa Agen
Anda dapat mengekspos beberapa agen dalam satu aplikasi, selama titik akhir mereka tidak bertabrakan. Berikut adalah sebuah contoh:
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");
Paket ini agent-framework-a2a memungkinkan Anda terhubung ke agen eksternal yang mematuhi A2A dan mengekspos agen Kerangka Kerja Agen melalui protokol A2A.
pip install agent-framework-a2a --pre
Menyambungkan ke Agen A2A
Gunakan A2AAgent untuk membungkus titik akhir A2A jarak jauh apa pun. Agen menyelesaikan kemampuan agen jarak jauh melalui AgentCard-nya dan menangani semua detail protokol.
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())
Respons yang Mengalir
A2A secara alami mendukung streaming melalui Server-Sent Events — pembaruan tiba secara real time saat agen jarak jauh bekerja:
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))")
Tugas Berjalan Lama
Secara default, A2AAgent menunggu agen jarak jauh selesai sebelum kembali. Untuk tugas yang berjalan lama, atur background=True untuk mendapatkan token kelanjutan yang dapat Anda gunakan untuk melakukan polling atau berlangganan ulang nanti:
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)
Identitas Pembicaraan (context_id)
Ketika Anda memanggil A2AAgent.run() dengan AgentSession, agen secara otomatis mendapatkan A2A context_id dari session.service_session_id jika pesan keluar belum membawanya. Ini memungkinkan Anda mempertahankan kelangsungan percakapan di beberapa panggilan A2A tanpa mengatur context_id setiap pesan secara manual:
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)
Jika suatu pesan memiliki elemen context_id eksplisit dalam additional_properties, nilai tersebut akan diutamakan dibandingkan dengan fallback yang diturunkan dari sesi.
Authentication
Gunakan sebuah AuthInterceptor untuk titik akhir A2A yang aman.
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!")
Mengekspos Agen Kerangka Kerja Agen melalui A2A
A2AExecutor mengadaptasi Kerangka Kerja Agen apa pun ke protokol sisi server A2A. Anda dapat menghostingnya dengan server Starlette/ASGI resmi a2a-sdk sehingga klien A2A lainnya dapat menemukan dan memanggil agen Anda.
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 mengalirkan pembaruan agen sebagai artefak A2A ketika agen yang mendasar mendukung streaming, menyebarluaskan A2A context_id sebagai agen thread_id, dan mengekspos save_thread/get_thread kait yang dapat Anda ambil alih untuk penyimpanan utas persisten.
Tip
agent_framework_to_a2a.py Lihat sampel untuk contoh lengkap yang dapat dijalankan.