A2A aracı hizmeti

, A2AAgent uygulamanızın Aracıdan Aracıya (A2A) protokolü aracılığıyla kullanıma sunulan uzak aracılara bağlanmasını sağlar. A2A uyumlu uç noktaları standart AIAgentolarak sarmalar, böylece ve gibi tanıdık yöntemleri kullanarak hangi çerçeve veya teknolojiyle oluşturulduklarından bağımsız olarak RunAsyncRunStreamingAsync uzak aracılarla etkileşim kurabilirsiniz.

Bir Agent Framework aracısını A2A sunucusu olarak kullanıma açmak için bkz. A2A ile konak aracıları.

Getting Started

Projenize gerekli NuGet paketini ekleyin:

dotnet add package Microsoft.Agents.AI.A2A --prerelease

Aracı Bulma

Uzak bir A2A aracısı ile iletişim kurmadan önce, aracıyı bulmanız ve bir AIAgent örnek oluşturmanız gerekir. A2A protokolü, her birinin Aracı Çerçevesi tarafından desteklenen üç bulma stratejisini tanımlar.

Well-Known URI

A2A aracıları Aracı Kartı'nın standartlaştırılmış bir yolda bulunabilir olmasını sağlayabilir: https://{domain}/.well-known/agent-card.json. Kartı getirmek ve tek bir çağrıda aracı oluşturmak için kullanın A2ACardResolver :

using A2A;
using Microsoft.Agents.AI;

// Initialize a resolver pointing at the remote agent's host.
A2ACardResolver resolver = new(new Uri("https://a2a-agent.example.com"));

// Resolve the agent card and create an AIAgent in one step.
AIAgent agent = await resolver.GetAIAgentAsync();

// Use the agent.
Console.WriteLine(await agent.RunAsync("Hello!"));

İpucu

GetAIAgentAsyncayrıca A2AClientOptions için isteğe bağlı bir parametre kabul eder.

Catalog-Based Bulma

Kurumsal ortamlarda veya genel marketlerde Aracı Kartları genellikle merkezi bir kayıt defteri tarafından yönetilir. Böyle bir AgentCard kayıt defterinden zaten edindiğiniz bir kayıt defteri varsa, bunu doğrudan öğesine AIAgentdönüştürün:

using A2A;
using Microsoft.Agents.AI;

// Assume agentCard was retrieved from a registry or catalog.
AgentCard agentCard = await GetAgentCardFromRegistryAsync("travel-planner");

AIAgent agent = agentCard.AsAIAgent();

Console.WriteLine(await agent.RunAsync("Plan a trip to Paris."));

Doğrudan Yapılandırma

Aracı uç noktasının önceden bilindiği sıkı bir şekilde bağlanmış sistemler veya geliştirme senaryoları için doğrudan bir A2AClient oluşturun ve bunu öğesine AIAgentdönüştürün:

using A2A;
using Microsoft.Agents.AI;

// Create a client pointing at the known agent endpoint.
A2AClient a2aClient = new(new Uri("https://a2a-agent.example.com"));

AIAgent agent = a2aClient.AsAIAgent(name: "my-agent", description: "A helpful assistant.");

Console.WriteLine(await agent.RunAsync("What can you help me with?"));

Protokol Seçimi

A2A aracıları HTTP+JSON ve JSON-RPC gibi birden çok protokol bağlaması kullanıma açabilir. Varsayılan olarak, JSON-RPC yerine HTTP+JSON tercih edilir. Hangi protokol bağlamanın kullanıldığını açıkça denetlemek için kullanın A2AClientOptions.PreferredBindings :

Uyarı

Uzak A2A aracısı, seçili protokol bağlamasını destekleyen bir uç noktada kullanılabilir olmalıdır.

using A2A;
using Microsoft.Agents.AI;

A2ACardResolver agentCardResolver = new(new Uri("https://a2a-agent.example.com"));

AgentCard agentCard = await agentCardResolver.GetAgentCardAsync();

// Prefer HTTP+JSON protocol binding. For JSON-RPC, set PreferredBindings = [ProtocolBindingNames.JsonRpc]
A2AClientOptions options = new()
{
    PreferredBindings = [ProtocolBindingNames.HttpJson]
};

AIAgent agent = agentCard.AsAIAgent(options: options);

Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));

Streaming

A2A, Server-Sent Olayları aracılığıyla akış yanıtlarını destekler. Uzak aracı isteği işlerken güncelleştirmeleri gerçek zamanlı olarak almak için kullanın RunStreamingAsync :

using A2A;
using Microsoft.Agents.AI;

A2ACardResolver resolver = new(new Uri("https://a2a-agent.example.com"));
AIAgent agent = await resolver.GetAIAgentAsync();

await foreach (var update in agent.RunStreamingAsync("Write a short story about a robot."))
{
    if (!string.IsNullOrEmpty(update.Text))
    {
        Console.Write(update.Text);
    }
}

Arka Plan Yanıtları

A2A aracıları, uzun süre çalışan işlemleri işlemek için arka plan yanıtlarını destekler. Uzak bir A2A aracısı anlık ileti yerine bir görev döndürdüğünde, Aracı Çerçevesi sonuçları yoklama veya kesintiye uğrayan akışlara yeniden bağlanmak için kullanabileceğiniz bir devamlılık belirteci sağlar.

Görev Tamamlama yoklaması

Akış dışı senaryolarda, bir devamlılık belirteci almak ve görev tamamlanana kadar yoklama yapmak için kullanın AllowBackgroundResponses :

using A2A;
using Microsoft.Agents.AI;

A2ACardResolver resolver = new(new Uri("https://a2a-agent.example.com"));
AIAgent agent = await resolver.GetAIAgentAsync();

AgentSession session = await agent.CreateSessionAsync();

// AllowBackgroundResponses must be true so the server returns immediately with a continuation token
// instead of blocking until the task is complete.
AgentRunOptions options = new() { AllowBackgroundResponses = true };

// Start the initial run with a long-running task.
AgentResponse response = await agent.RunAsync(
    "Conduct a comprehensive analysis of quantum computing applications in cryptography.",
    session,
    options: options);

// Poll until the response is complete.
while (response.ContinuationToken is { } token)
{
    // Wait before polling again.
    await Task.Delay(TimeSpan.FromSeconds(2));

    // Continue with the token.
    response = await agent.RunAsync(session, options: new AgentRunOptions { ContinuationToken = token });
}

Console.WriteLine(response);

Akış Yeniden Bağlantısı

Akış senaryolarında her güncelleştirme bir devamlılık belirteci içerebilir. Akış kesilirse, yeniden bağlanmak ve yanıt akışını baştan almak için belirteci kullanın:

using A2A;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;

A2ACardResolver resolver = new(new Uri("https://a2a-agent.example.com"));
AIAgent agent = await resolver.GetAIAgentAsync();

AgentSession session = await agent.CreateSessionAsync();

ResponseContinuationToken? continuationToken = null;

await foreach (var update in agent.RunStreamingAsync(
    "Conduct a comprehensive analysis of quantum computing applications in cryptography.",
    session))
{
    // Save the continuation token to reconnect later if the stream is interrupted.
    // Continuation tokens are only returned for long-running tasks. If the A2A agent
    // returns a message instead of a task, the continuation token will not be initialized.
    if (update.ContinuationToken is { } token)
    {
        continuationToken = token;
    }
}

// If the stream was interrupted and a continuation token was captured,
// reconnect to the response stream using the saved continuation token.
if (continuationToken is not null)
{
    await foreach (var update in agent.RunStreamingAsync(
        session,
        options: new() { ContinuationToken = continuationToken }))
    {
        if (!string.IsNullOrEmpty(update.Text))
        {
            Console.WriteLine(update.Text);
        }
    }
}

Uyarı

A2A aracıları akışın belirli bir noktasından akışın yeniden başlatılmasını değil, akışın yeniden bağlanmasını (aynı yanıt akışını baştan elde etme) destekler.

Tools

A2AAgent uzak A2A aracısının etrafındaki aktarım düzeyi sarmalayıcıdır. Uzak aracı hangi araçları kullanırsa kullansın uzak tarafta bulunur ve kodunuz tarafından görünmez. Aracı Çerçevesi araç türleri (işlev araçları, kod yorumlayıcı, dosya arama, barındırılan/yerel MCP vb.) kendi içinde A2AAgent yapılandırılmaz; uzak aracının özelliklerini genişletmek için uzak aracının yapılandırmasını değiştirin.

Getting Started

A2A paketini yükleyin:

pip install agent-framework-a2a --pre

Başlatma Aşaması

A2AAgent , uzak aracı hakkında önceden ne kadar bilgi edindiğinize bağlı olarak üç yolla başlatılabilir.

Doğrudan URL

Uç noktanın bilindiği geliştirme veya sıkı bir şekilde bağlanmış sistemler için:

from agent_framework.a2a import A2AAgent

async with A2AAgent(name="remote", url="https://a2a-agent.example.com") as agent:
    response = await agent.run("Hello!")
    print(response.messages[0].text)

Yalnızca bir URL sağlandığında, A2AAgent dahili olarak en düşük aracı kartını oluşturur ve JSON-RPC kullanarak bağlanır.

Aracı Kartı

Kayıt defterinden veya katalogdan bir AgentCard dosyanız varsa doğrudan geçirin:

from agent_framework.a2a import A2AAgent

async with A2AAgent(agent_card=agent_card) as agent:
    response = await agent.run("Plan a trip to Paris.")
    print(response.messages[0].text)

AgentCard sağlandığında, A2AAgent varsayılan olarak name ve description kartından alır. Kartın öğesini kullanarak aktarım anlaşmasında bulunur supported_interfaces.

Well-Known URI(A2ACardResolver)

A2ACardResolver a2a-sdk standart iyi bilinen yolda (/.well-known/agent.json):

import httpx
from a2a.client import A2ACardResolver
from agent_framework.a2a import A2AAgent

async with httpx.AsyncClient(timeout=60.0) as http_client:
    resolver = A2ACardResolver(httpx_client=http_client, base_url="https://a2a-agent.example.com")
    agent_card = await resolver.get_agent_card()

async with A2AAgent(agent_card=agent_card) as agent:
    response = await agent.run("What can you help me with?")
    print(response.messages[0].text)

Streaming

Uzak aracı isteği işlerken güncelleştirmeleri gerçek zamanlı olarak almak için kullanın stream=True :

from agent_framework.a2a import A2AAgent

async with A2AAgent(name="remote", url="https://a2a-agent.example.com") as agent:
    stream = agent.run("Write a short story about a robot.", stream=True)
    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))")

Uzun Süreli Görevler

Varsayılan olarak A2AAgent, geri dönmeden önce uzak aracı bitene kadar bekler. Uzun süre çalışan görevler için, daha sonra yoklama yapmak veya abone olmak için kullanabileceğiniz bir devamlılık belirtecini ortaya çıkaracak şekilde ayarlayın background=True :

from agent_framework.a2a import A2AAgent

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)

Ayrıca yoklama yerine SSE akışına yeniden abone olabilirsiniz:

# Resubscribe to the task's event stream
response = await agent.run(continuation_token=response.continuation_token)

Konuşma Kimliği (context_id)

A2AAgent dayanıklı protokol durumunu AgentSession.service_session_id içinde eşleme A2AServiceSessionId olarak depolar:

Alan Türü Purpose
context_id str A2A konuşmasını tanımlar.
task_id str \| None Yanıt oluşturulduğunda en son uzak görevi izler.
task_state TaskState \| None Sonraki isteğin giriş gerektiren bir göreve devam edebilmesi veya tamamlanmış bir göreve başvurabilmesi için en son görev durumunu kaydeder.

Uygulamanız A2A bağlamını zaten biliyorsa yapılandırılmış duruma sahip bir oturum oluşturun:

from agent_framework import AgentSession
from agent_framework.a2a import A2AAgent, A2AServiceSessionId

async with A2AAgent(name="remote", url="https://a2a-agent.example.com") as agent:
    session = AgentSession(
        service_session_id=A2AServiceSessionId(
            context_id="my-conversation-1",
            task_id=None,
            task_state=None,
        )
    )

    # The A2A message uses context_id="my-conversation-1".
    response = await agent.run("Hello!", session=session)

    # A2AAgent updates task_id and task_state from the response.
    response = await agent.run("Follow-up question", session=session)

ayrıca ile başlayıp AgentSession() ilk yanıttan yapılandırılmış eşlemeyi doldurmaya izin vekleyebilirsiniz A2AAgent . Normal oturumu ile session.to_dict() kalıcı hale getirin ve ile AgentSession.from_dict(...)geri yükleyin; A2A bağlamı, görev kimliği ve görev durumu birlikte kalır.

içindeki TASK_STATE_INPUT_REQUIREDbir görev için, sonraki ileti bunu task_id aynı göreve devam etmek üzere ayarlar. Diğer görev durumları için, önceki görev kimliği aracılığıyla reference_task_ids gönderilir, böylece uzak aracı önceki sonucu geliştirebilir veya devam edebilir.

Authentication

Güvenli A2A uç noktaları için bir AuthInterceptor kullanın:

from a2a.client.auth.interceptor import AuthInterceptor
from agent_framework.a2a import A2AAgent

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!")

Zaman Aşımı Yapılandırması

A2AAgent istek zaman aşımlarını denetlemek için bir timeout parametre kabul eder:

import httpx
from agent_framework.a2a import A2AAgent

# Simple timeout (applies to all components)
async with A2AAgent(name="remote", url="https://example.com", timeout=120.0) as agent:
    ...

# Fine-grained timeout
async with A2AAgent(
    name="remote",
    url="https://example.com",
    timeout=httpx.Timeout(connect=10.0, read=120.0, write=10.0, pool=5.0),
) as agent:
    ...

Zaman aşımı belirtilmediğinde varsayılan değerler şunlardır: 10s connect, 60s read, 10s write, 5s pool.

Tools

A2AAgent uzak A2A aracısının etrafındaki aktarım düzeyi sarmalayıcıdır. Uzak aracı hangi araçları kullanırsa kullansın uzak tarafta bulunur ve kodunuz tarafından görünmez. Aracı Çerçevesi araç türleri (işlev araçları, kod yorumlayıcı, dosya arama, barındırılan/yerel MCP vb.) kendi içinde A2AAgent yapılandırılmaz; uzak aracının özelliklerini genişletmek için uzak aracının yapılandırmasını değiştirin.

Bir Foundry aracısının A2A aracısını araç olarak çağırmasını istiyorsanız, üzerindeki get_a2a_toolfabrikayaFoundryChatClient bakın.

Go, paket aracılığıyla uzak A2A aracılarını provider/a2aprovider destekler.

Agent Framework ve A2A paketlerini yükleyin:

go get github.com/microsoft/agent-framework-go
go get github.com/a2aproject/a2a-go/v2

Uzak A2A aracısına bağlanma

Uzak aracı kartını çözün, bu karttan bir A2A istemcisi oluşturun ve istemciyi standart bir Agent Framework aracısı olarak sarmalayın:

import (
    "context"

    "github.com/a2aproject/a2a-go/v2/a2aclient"
    "github.com/a2aproject/a2a-go/v2/a2aclient/agentcard"
    "github.com/microsoft/agent-framework-go/agent"
    "github.com/microsoft/agent-framework-go/provider/a2aprovider"
)

ctx := context.Background()

card, err := agentcard.DefaultResolver.Resolve(ctx, "http://localhost:5000")
if err != nil {
    panic(err)
}

client, err := a2aclient.NewFromCard(ctx, card)
if err != nil {
    panic(err)
}

a := a2aprovider.NewAgent(
    client,
    a2aprovider.AgentConfig{
        Config: agent.Config{
            Name:        card.Name,
            Description: card.Description,
        },
    },
)

resp, err := a.RunText(ctx, "Hello!").Collect()

Sağlayıcı, izleme iletilerinin konuşma sürekliliğini koruyabilmesi için A2A context_id ve görev kimliklerini Agent Framework oturumunda depolar.

Protokol seçimi

Uzak bir aracı birden çok aktarım bağlaması tanıtıyorsa, A2A istemcisini oluştururken tercih edilen aktarımı yapılandırın:

client, err := a2aclient.NewFromCard(
    ctx,
    card,
    a2aclient.WithConfig(a2aclient.Config{
        PreferredTransports: []a2a.TransportProtocol{a2a.TransportProtocolHTTPJSON},
    }),
)

JSON-RPC'yi tercih etmek istediğinizde kullanın a2a.TransportProtocolJSONRPC .

Uzun süreli görevler

A2A görevleri, Agent Framework devamlılık belirteçleri aracılığıyla ortaya çıkar. Çalıştırmayı açık bir oturum ve agent.AllowBackgroundResponses(true) ile başlatın, ardından yeni ileti olmadan ve devam belirteciyle Run çağrısını yaparak yoklayın:

session, err := a.CreateSession(ctx)
if err != nil {
    panic(err)
}

resp, err := a.RunText(
    ctx,
    "Process this large dataset.",
    agent.WithSession(session),
    agent.AllowBackgroundResponses(true),
).Collect()
if err != nil {
    panic(err)
}

for resp.ContinuationToken != "" {
    resp, err = a.Run(
        ctx,
        nil,
        agent.WithSession(session),
        agent.WithContinuationToken(resp.ContinuationToken),
    ).Collect()
    if err != nil {
        panic(err)
    }
}

Kesintiye uğrayan akış çalıştırmaları için, son alınan güncelleştirmeden update.ContinuationToken öğesini alın ve bunu agent.WithContinuationToken(token) ve agent.Stream(true) ile daha sonraki bir akış çalıştırmasına aktarın.

Uzak A2A aracılarını araç olarak kullanma

Her uzak aracıyı çözün, ile a2aprovider.NewAgentsarmalayın ve ile agenttool.Newbir araclara dönüştürün.

tools := make([]tool.Tool, 0, len(agentURLs))

for _, agentURL := range agentURLs {
    card, err := agentcard.DefaultResolver.Resolve(ctx, agentURL)
    if err != nil {
        panic(err)
    }

    client, err := a2aclient.NewFromCard(ctx, card)
    if err != nil {
        panic(err)
    }

    remoteAgent := a2aprovider.NewAgent(client, a2aprovider.AgentConfig{
        Config: agent.Config{
            Name:        card.Name,
            Description: card.Description,
        },
    })

    tools = append(tools, agenttool.New(remoteAgent, agenttool.Config{}))
}

İpucu

Tam çalıştırılabilir örnekler için A2A sağlayıcı örneğine ve A2A aracıları araç örneği olarak bölümüne bakın.

Sonraki Adımlar

Daha derine gidin: