A2A协议开发指南

 

A2A协议开发指南

概述

A2A(Agent-to-Agent)协议是一种基于JSON-RPC的通信协议,专为代理之间的交互而设计。本指南为开发符合A2A协议规范的服务器和客户端组件提供了全面的指导。

目录

  1. 1. 协议基础
  2. 2. 服务器实现
  3. 3. 客户端实现
  4. 4. 运行Coder示例

协议基础

A2A协议建立在JSON-RPC 2.0之上,并定义了一组用于代理通信的方法。关键组件包括:

消息结构

所有A2A消息都遵循JSON-RPC 2.0格式,具有以下基本结构:

interface JSONRPCMessage {
  jsonrpc?: "2.0";
  id?: number | string | null;
  method?: string;
  params?: unknown;
  result?: unknown;
  error?: JSONRPCError;
}

协议流程

下面的序列图说明了A2A协议的主要交互流程:

A2A 主要流程

核心方法

该协议支持几个核心方法:

  • • tasks/send:向代理发送任务消息
  • • tasks/get:检索任务状态
  • • tasks/cancel:取消正在运行的任务
  • • tasks/pushNotification/set:为任务配置推送通知
  • • tasks/pushNotification/get:获取推送通知配置
  • • tasks/resubscribe:重新订阅任务更新
  • • tasks/sendSubscribe:发送任务消息并订阅更新

任务状态

任务可以处于以下状态之一:

  • • submitted:已提交
  • • working:正在处理
  • • input-required:需要输入
  • • completed:已完成
  • • canceled:已取消
  • • failed:失败
  • • unknown:未知

服务器实现

核心组件

服务器实现由几个关键组件组成:

  1. 1. 服务器(server.ts):处理HTTP请求的主服务器实现
  2. 2. 处理器(handler.ts):用于处理A2A协议消息的请求处理器
  3. 3. 存储(store.ts):任务存储和管理
  4. 4. 工具(utils.ts):实用函数
  5. 5. 错误处理(error.ts):错误定义和处理

基本用法(概念性)

import {
  A2AServer,
  InMemoryTaskStore,
  TaskContext,
  TaskYieldUpdate,
from "./index"; // Assuming imports from the server package

// 1. Define your agent's logic as a TaskHandler
async function* myAgentLogic(
  context: TaskContext
): AsyncGenerator<TaskYieldUpdate> {
  console.log(`Handling task: ${context.task.id}`);
  yield {
    state: "working",
    message: { role: "agent", parts: [{ text: "Processing..." }] },
  };

  // Simulate work...
  await new Promise((resolve) => setTimeout(resolve, 1000));

  if (context.isCancelled()) {
    console.log("Task cancelled!");
    yield { state: "canceled" };
    return;
  }

  // Yield an artifact
  yield {
    name: "result.txt",
    mimeType: "text/plain",
    parts: [{ text: `Task ${context.task.id} completed.` }],
  };

  // Yield final status
  yield {
    state: "completed",
    message: { role: "agent", parts: [{ text: "Done!" }] },
  };
}

// 2. Create and start the server
const store = new InMemoryTaskStore(); // Or new FileStore()
const server = new A2AServer(myAgentLogic, { taskStore: store });

server.start(); // Starts listening on default port 41241

console.log("A2A Server started.");

服务器将在配置的端口上启动(默认:3000)。

客户端实现

关键特性:

  • • JSON-RPC通信: 根据JSON-RPC 2.0规范处理发送请求和接收响应(标准响应和通过服务器发送事件的流式响应)。
  • • A2A方法: 实现标准A2A方法,如sendTasksendTaskSubscribegetTaskcancelTasksetTaskPushNotificationgetTaskPushNotificationresubscribeTask
  • • 错误处理: 为网络问题和JSON-RPC错误提供基本错误处理。
  • • 流支持: 管理服务器发送事件(SSE)以获取实时任务更新(sendTaskSubscriberesubscribeTask)。
  • • 可扩展性: 允许为不同环境(例如Node.js)提供自定义fetch实现。

基本用法

import { A2AClient, Task, TaskQueryParams, TaskSendParams } from "./client"; // Import necessary types
import { v4 as uuidv4 } from "uuid"; // Example for generating task IDs

const client = new A2AClient("http://localhost:41241"); // Replace with your server URL

async function run() {
  try {
    // Send a simple task (pass only params)
    const taskId = uuidv4();
    const sendParams: TaskSendParams = {
      id: taskId,
      message: { role: "user", parts: [{ text: "Hello, agent!" }] },
    };
    // Method now returns Task | null directly
    const taskResult: Task | null = await client.sendTask(sendParams);
    console.log("Send Task Result:", taskResult);

    // Get task status (pass only params)
    const getParams: TaskQueryParams = { id: taskId };
    // Method now returns Task | null directly
    const getTaskResult: Task | null = await client.getTask(getParams);
    console.log("Get Task Result:", getTaskResult);
  } catch (error) {
    console.error("A2A Client Error:", error);
  }
}

run();

流式用法

import {
  A2AClient,
  TaskStatusUpdateEvent,
  TaskArtifactUpdateEvent,
  TaskSendParams, // Use params type directly
from "./client"; // Adjust path if necessary
import { v4 as uuidv4 } from "uuid";

const client = new A2AClient("http://localhost:41241");

async function streamTask() {
  const streamingTaskId = uuidv4();
  try {
    console.log(`\n--- Starting streaming task ${streamingTaskId} ---`);
    // Construct just the params
    const streamParams: TaskSendParams = {
      id: streamingTaskId,
      message: { role: "user", parts: [{ text: "Stream me some updates!" }] },
    };
    // Pass only params to the client method
    const stream = client.sendTaskSubscribe(streamParams);

    // Stream now yields the event payloads directly
    for await (const event of stream) {
      // Type guard to differentiate events based on structure
      if ("status" in event) {
        // It's a TaskStatusUpdateEvent
        const statusEvent = event as TaskStatusUpdateEvent; // Cast for clarity
        console.log(
          `[${streamingTaskId}] Status Update: ${statusEvent.status.state} - ${
            statusEvent.status.message?.parts[0]?.text ?? "No message"
          }`
        );
        if (statusEvent.final) {
          console.log(`[${streamingTaskId}] Stream marked as final.`);
          break; // Exit loop when server signals completion
        }
      } else if ("artifact" in event) {
        // It's a TaskArtifactUpdateEvent
        const artifactEvent = event as TaskArtifactUpdateEvent; // Cast for clarity
        console.log(
          `[${streamingTaskId}] Artifact Update: ${
            artifactEvent.artifact.name ??
            `Index ${artifactEvent.artifact.index}`
          } - Part Count: ${artifactEvent.artifact.parts.length}`
        );
        // Process artifact content (e.g., artifactEvent.artifact.parts[0].text)
      } else {
        console.warn("Received unknown event structure:", event);
      }
    }
    console.log(`--- Streaming task ${streamingTaskId} finished ---`);
  } catch (error) {
    console.error(`Error during streaming task ${streamingTaskId}:`, error);
  }
}

streamTask();

运行Coder示例

Coder示例是A2A代理的一个示例实现,可以处理与代码相关的任务。

设置

  1. 1. 安装依赖项:
git clone https://github.com/sing1ee/a2a-agent-coder.git
#or
git clone git@github.com:sing1ee/a2a-agent-coder.git

bun install
  1. 2. 确保您有所需的环境变量:
# set .env first
export $(cat .env | xargs)

运行示例

  1. 1. 启动a2a服务器(需要Node.js环境):
bun run agents:coder
  1. 2. 启动a2a客户端:
bun run a2a:cli

# result
$ bun x tsx src/cli.ts
A2A Terminal Client
Agent URL: http://localhost:41241
Attempting to fetch agent card from: http://localhost:41241/.well-known/agent.json
✓ Agent Card Found:
  Name:        Coder Agent
  Description: An agent that generates code based on natural language instructions and streams file outputs.
  Version:     0.0.1
Starting Task ID: a1a608b3-3015-4404-a83f-6ccc05083761
Enter messages, or use '/new' to start a new task.
Coder Agent > You: implement binary search
Sending...

Coder Agent [4:28:00 PM]: ⏳ Status: working
  Part 1: 📝 Text: Generating code...

Coder Agent [4:28:02 PM]: ⏳ Status: working
  Part 1: 📄 File: Name: src/algorithms/binary_search.py, Source: """
Implementation of the binary search algorithm in Python.
"""

def binary_search(arr, target):
    """
    Performs a binary search on a sorted array to find the index of a target value.

    Args:
        arr (list): A sorted list of elements.
        target: The value to search for in the array.

    Returns:
        int: The index of the target value if found, otherwise -1.
    """
    low = 0
    high = len(arr) - 1

    while low <= high:
        mid = (low + high) // 2  # Integer division to find the middle index

        if arr[mid] == target:
            return mid  # Target found at index mid
        elif arr[mid] < target:
            low = mid + 1  # Target is in the right half
        else:
            high = mid - 1  # Target is in the left half

    return -1  # Target not found in the array


Coder Agent [4:28:02 PM]: ✅ Status: completed
SSE stream finished for method tasks/sendSubscribe.
--- End of response for this input ---
Coder Agent > You:
Exiting terminal client. Goodbye!

错误处理

A2A协议定义了几个标准错误代码:

  • • -32700:解析错误
  • • -32600:无效请求
  • • -32601:方法未找到
  • • -32602:无效参数
  • • -32603:内部错误
  • • -32000:任务未找到
  • • -32001:任务不可取消
  • • -32002:不支持推送通知
  • • -32003:不支持的操作

最佳实践

  1. 1. 错误处理:始终为所有A2A协议方法实现适当的错误处理
  2. 2. 身份验证:实现适当的身份验证机制以确保安全通信
  3. 3. 任务管理:维护适当的任务状态管理和清理
  4. 4. 推送通知:在支持时实现推送通知以获取实时更新
  5. 5. 日志记录:实现全面的日志记录以便调试和监控

其他资源

A2A TypeScript Guide

 

posted on 2025-04-11 17:31  sing1ee  阅读(295)  评论(0)    收藏  举报