news 2026/5/16 18:08:40

[A2A协议与实现-02]Agent发现机制和两种响应方式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[A2A协议与实现-02]Agent发现机制和两种响应方式

要使用A2A协议进行协作,Agent首先需要相互发现并了解彼此的功能。在A2A协议中,当服务端接收到来自客户端针对Agent的调用请求时,它可以以两种基本方式进行响应,一是响应承载结果的消息,二是响应异步执行的任务。Agent的发现机制和响应方式是这篇文章关注的两个主题。

1. Agent发现机制

A2A通过AgentCard对Agent的自我描述进行标准化。。AgentCard定义了Agent提供的功能。客户端Agent可以通过多种策略发现这些AgentCard。客户Agent使用AgentCard来确定目标Agent的资质、构建请求结构并确保安全沟通,它可以采用如下的几种策略来发现AgentCard

1.1 知名URI(Well-Known URI)

在这种策略下,A2A服务器通过在其域内使用标准化的、众所周知的URI托管AgentCard,使其易于被发现。标准路径为https://{agent-server-domain}/.well-known/agent-card.json,遵循RFC 8615的原则。具体流程如下:

  • 客户端Agent知道或通过编程方式发现潜在的A2A服务器的域名(例如smart-thermostat.example.com);
  • 客户端向https://smart-thermostat.example.com/.well-known/agent-card.json发送HTTP GET请求;
  • 如果AgentCard存在且可访问,服务器将以JSON响应的形式返回该AgentCard
    `
    这种发现策略的优点是:易于实施,符合标准且有助于自动发现。

1.2 精选注册表/目录服务(Curated Registries/Catalog-Based Discovery)

这种方法常用于企业环境或公共市场,其中AgentCard通常由中央注册机构管理。该注册机构充当中央存储库,允许客户根据技能标签等标准查询和发现经纪人。在这种策略中,注册中心维护着一个AgentCard集合。客户通过查询该注册中心,根据各种标准(例如,提供的技能、标签、提供商名称、能力)查找Agent,具体流程如下:

  • A2A服务器将其AgentCard发布到注册表;
  • 客户端Agent通过注册表的API进行查询,并按特定技能等条件进行搜索;
  • 注册表返回匹配的AgentCard或推荐信息;

这种策略的优点是:

  • 集中式管理和治理;
  • 基于能力的发现(例如,按技能);
  • 支持访问控制和信任框架;
  • 适用于私有和公共市场;

如果采用这种Agent发现策略,需要部署和维护注册表服务,目前A2A规范尚未对这种策略提供标准化的API定义。

1.3 直接配置/私有发现( Direct Configuration/Private Discovery)

这种方法适用于紧密耦合的系统、私有Agent或开发用途,其中客户端直接配置AgentCard信息或 URL。客户端应用程序利用硬编码的详细信息、配置文件、环境变量或专有API进行发现。这种方法简单直接,适用于在已知的静态关系中建立联系,但需要考虑如下的因素:

  • 对于动态发现场景而言,这种方式不够灵活;
  • AgentCard信息的更改需要重新配置客户端;
  • 基于专有 API 的发现机制也缺乏标准化;

2. 两种响应方式

在A2A协议中,当服务端接收到来自客户端针对Agent的调用请求时,它可以以两种基本方式进行响应:

  • 响应承载结果的消息:这种类型的响应通常用于无需进一步状态管理即可立即完成的、独立的交互;
  • 响应异步执行的任务:如果响应是一个任务,Agent将按照定义的生命周期处理该任务,根据需要传递进度信息并要求输入,直到任务达到中断状态(例如,需要输入、需要身份验证)或终止状态(completed,canceled,rejectedfailed);

2.1 多个消息/任务的关联

context_id是一个关键标识符,它在逻辑上将多个Task和Message对象分组,从而确保交互的连续性:

  • 当客户端首次发送消息时,Agent会响应一个新的context_id。 如果发起了一个任务,该任务还会有一个task_id
  • 客户端可以发送后续消息,并包含相同的context_id,以表明它们正在同一上下文中继续之前的交互;
  • 客户端还可以选择将task_id附加到后续消息中,以表明该消息将继续执行该特定任务;

context_id支持跨多个可能并发的任务进行协作,以实现共同目标或共享上下文会话。在内部,A2A Agent使用context_id来管理其内部对话状态或其LLM上下文。可以将context_id视为一个会话ID, 相当于LangChain中的thread_id

2.2 返回Message还是Task?

选择以Message还是Task进行响应,取决于交互的性质和Agent的能力。Message适用于不需要长时间处理或复杂状态管理的事务性交互,而Task适用于需要持续跟踪、状态管理或用户输入的更复杂的交互。具体实现可以采用如下几种模式:

  • Message-Only:始终以消息对象进行响应。它们通常不管理复杂的状态或长时间运行的执行,并使用context_id将消息关联起来。这些Agent可以直接封装LLM调用和简单的工具;
  • Task-Only:始终以Task对象作为响应,即使是回复也一样,这些响应随后会被建模为已完成的任务。任务创建后,Agent只会返回Task对象来响应发送的消息。任务完成后,将无法再发送任何消息。这种方法避免了在Task和Message之间进行选择,即使是简单的交互也会创建已完成的任务对象;
  • Mixed: 生成消息对象和任务对象。这类Agent使用消息来协商Agent的功能和任务范围,然后发送一个任务对象来跟踪执行情况并管理诸如需要输入或错误处理等状态。任务创建后,Agent只会响应发送的消息而返回任务对象;任务完成后,将无法再发送任何消息。混合Agent使用消息来协商任务范围,然后生成一个任务来跟踪其执行情况;

2.3 Task的定义

我们已经介绍A2A规范针对Message的定义,接下来我们看看如下这个定义Task的Protobuf消息类型。 Task是A2A协议中的最核心逻辑单元。它不仅仅是一个简单的指令,而是一个具有生命周期的会话容器。在Multi-Agent协作中,一个任务可能涉及多次往返对话、状态切换以及最终产出。Task将这些信息全部整合在了一起:

message Task { string id = 1 [(google.api.field_behavior) = REQUIRED]; string context_id = 2; TaskStatus status = 3 [(google.api.field_behavior) = REQUIRED]; repeated Artifact artifacts = 4; repeated Message history = 5; google.protobuf.Struct metadata = 6; }

消息成员说明如下:

  • id:每个Task的唯一标识符,通常由创建它的Agent生成。它对于跟踪、引用和管理任务非常重要;
  • context_id:与Task相关联的上下文标识符。这允许多个任务共享相同的上下文信息,促进协作和状态管理;
  • status:Task的当前状态,定义了任务的生命周期阶段(pending,in_progress,completed,canceled,rejected,failed)。状态的变化可以触发不同的行为或通知;
  • artifacts:与Task相关的产出物列表。这些Artifact代表了任务执行过程中生成的结果或中间成果,可以是文本、图像、结构化数据等多种形式;
  • history:与Task相关的消息历史记录。这些消息记录了任务执行过程中所有的交互,包括客户端和Agent之间的通信。这对于调试、审计和理解任务执行过程非常有用;
  • metadata:一个结构化的键值对集合,用于携带与这个Task相关的上下文信息。这些信息可以用于分类、搜索、调试等目的;

中文将Status和State都翻译成状态了,所以对于如下两个分别命名为TaskStatusTaskState的消息类型,我们不能简单地称它们为任务状态。这两个消息类型定义了A2A协议中任务的生命周期管理机制。它不仅记录了任务进行到哪一步,还提供了处理异常和交互的标准化流程。

message TaskStatus { TaskState state = 1 [(google.api.field_behavior) = REQUIRED]; Message message = 2; google.protobuf.Timestamp timestamp = 3; } enum TaskState { TASK_STATE_UNSPECIFIED = 0; TASK_STATE_SUBMITTED = 1; TASK_STATE_WORKING = 2; TASK_STATE_COMPLETED = 3; TASK_STATE_FAILED = 4; TASK_STATE_CANCELED = 5; TASK_STATE_INPUT_REQUIRED = 6; TASK_STATE_REJECTED = 7; TASK_STATE_AUTH_REQUIRED = 8; }

TaskStatus(状态容器)这是对任务某一时刻情况的快照,除了具有一个TaskState类型的state字段外,还关联中一个Message。当TaskStateFAILED时,这里存放错误详情;当TaskStateINPUT_REQUIRED时,这里存放Agent向用户提出的问题。TaskState是一个枚举,表明任务当前所处的生命周期阶段。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/16 18:08:30

RA6M4驱动SSD1306 OLED:RT-Thread软件I2C配置与驱动移植详解

1. 项目概述与核心思路最近在折腾瑞萨的RA6M4开发板,手头正好有一块闲置的0.96寸OLED屏幕,驱动芯片是经典的SSD1306,通信接口是I2C。这类小屏幕在嵌入式项目里太常见了,做个状态显示、参数监控或者简单的UI交互都非常方便。RA6M4作…

作者头像 李华
网站建设 2026/5/16 18:06:12

从API密钥管理角度体验Taotoken平台的安全与便捷

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 从API密钥管理角度体验Taotoken平台的安全与便捷 对于需要集成多个大语言模型的团队而言,API密钥的管理往往是一项繁琐…

作者头像 李华
网站建设 2026/5/16 18:05:40

鸿蒙系统显示问题查找命令

1、查看服务列表,系统中所有正在运行的系统服务 hidumper -ls2、服务状态和配置信息 hidumper -s3、查看所有系统参数的统计信息 hidumper --ipc -a --stat4、屏幕信息 hidumper -s WindowManagerService -a -a5、观察渲染服务render_service 进程的CPU占用率是否在花屏时…

作者头像 李华
网站建设 2026/5/16 18:02:11

Pine Script V6实战:从社区代码库到专业交易策略开发

1. 项目概述与核心价值如果你在交易领域摸爬滚打了一段时间,尤其是在使用TradingView这个平台,那么你一定听说过Pine Script。它就像是TradingView的“官方编程语言”,让你能把自己的交易想法,从模糊的直觉变成清晰、可回测、可自…

作者头像 李华
网站建设 2026/5/16 18:01:09

clrun:容器化CLI工具的革命性实践,让容器即命令成为现实

1. 项目概述:一个被低估的容器化运行环境最近在整理一些遗留的自动化脚本时,我遇到了一个老生常谈的问题:如何让一个几年前写的、依赖特定Python版本和一堆老掉牙库的脚本,在一台全新的、系统环境“干净”的机器上稳定运行&#x…

作者头像 李华
网站建设 2026/5/16 18:00:02

2026智慧医院评审:物流自动化与医院物流机器人评级选型参考

开篇:2026年智慧医院管理分级评估推进在即。根据现行《医院智慧管理分级评估标准体系(试行)》,物流自动化已从“可选配置”转变为四级和五级评审的实质性支撑条件。与此同时,国家“人工智能医疗卫生”相关政策及《医院…

作者头像 李华