【共创稿事节】HarmonyOS 7 Agent A2A 实战:让日程智能体和打车智能体自己谈成一单
2026/9/16 8:25:03 网站建设 项目流程

本文基于 HarmonyOS 7(API 26)官方《通过 AgentAbilityExtension 实现智能体间 A2A 协议通信》开发指导与 Agent Framework Kit 相关接口参考整理。文中代码示例为说明问题自写,接口名均出自官方文档并标注出处,方法签名与配置细节以官方 SDK 为准;未核实到底层调用细节的部分以示意性伪代码呈现并标注;文中不含实测数据,场景为按官方能力描述做的推演,运行表现以真机实测为准;7.0 相关能力需升级至 HarmonyOS 7 并以实际支持机型为准。


引子:一句"赶飞机",两个 App 自己谈成了

兄弟们好,我是V哥。

先描述一个按官方能力推演的场景:用户对小艺说"明早七点半赶飞机,帮我安排"。系统拆解意图,找到行程应用登记的日程智能体,日程智能体算出"七点十分出门",然后把"需要一辆车"这个子意图交回系统;系统撮合到打车应用登记的打车智能体,两边按 A2A 协议把时间、地点、车型谈拢,用户确认后订单落地,行程卡片自动更新(运行表现以真机实测为准)。

全程用户没打开任何一个 App。上一期V哥写过 Skill 化——应用把功能递进系统的意图分发池;这一期往上走一层:智能体和智能体之间,自己谈。这就是 HarmonyOS 7(API 26)新增的 Agent A2A 能力(官方发布说明)。

官方在发布说明里举的例子是健身 Agent:训练前中后的记录、指导、回顾、问答,全链路健身管理。V哥把"日程 + 打车"这个组合拆成三件事讲清楚:A2A 到底协作了什么、智能体怎么把自己挂进系统、一单是怎么按状态机谈成的。


一、A2A 不是接口互调,是意图协商

先纠正一个最常见的误解。很多同学一听"智能体之间通信",脑子里浮现的是 A 应用 import B 应用的 SDK,然后调 B 的方法。那叫接口互调,不叫 A2A。

接口互调的前提是调用方认识对方:知道对方是谁、方法签名是什么、出错返回什么。而 A2A 的前提恰恰相反——双方互不相识。官方对这套机制的表述是(通过 AgentAbilityExtension 实现智能体间 A2A 协议通信):

A2A(Agent to Agent)协议用于智能体之间的通信。A2A 服务端负责接收客户端请求、触发智能体执行任务、更新任务状态和返回执行结果。

V哥从官方的基本概念里读出的关键,是几个名词撑起的协商结构:

概念官方定义在"一单生意"里的角色
Agent CardJSON 元数据文档,描述智能体的身份、能力、端点地址、技能和认证要求生意场上的名片:先递名片,再谈事
Task有唯一标识和明确定义生命周期的有状态工作单元这单生意本身,全程可跟踪
Message客户端与智能体之间一次通信的单元,带 user / agent 角色谈判桌上说的每一句话
Artifact任务过程中生成的有形交付物,有唯一的产物 ID 和名称成单后的交付:订单、票据、结果
TaskState已提交、工作中、需要用户输入、已完成、已取消、已失败、已拒绝、需要认证谈判进度条

注意"认证要求"这三个字。接口互调的世界里,权限是编译期定死的;A2A 的世界里,智能体在名片上写清楚"找它办事需要什么资质",客户端解析 Agent Card 才知道如何安全有效地交互。发现、认证、协商、交付,四个环节都长在协议里,而不是长在某一次硬编码里——这是V哥判断"A2A 不是接口互调"的依据。

还有一条官方边界划在前头:实现 A2A 协议通信从 API 26.0.0 开始支持,AgentExtensionAbility 首批接口从 API 24 起就有,仅支持 Stage 模型,且不支持在 har 包中使用(接口参考)。7.0 相关能力需升级至 HarmonyOS 7 并以实际支持机型为准。


二、把智能体"挂"进系统:Agent Card 与 A2A 服务端

上一期 Skill 化的活儿是"写契约",这一期的活儿是"写名片 + 写服务端"。官方给的开发路径很清晰:服务端继承 AgentExtensionAbility 获得跨 App 进程通信能力,再通过 Agent Framework Kit 创建支持 A2A 协议的 Server 实例。V哥的打车智能体骨架这么写(接口名出自官方开发指导,方法签名以官方 SDK 为准):

// RideAgentExtAbility.ets —— 打车智能体的 A2A 服务端骨架import{hilog}from'@kit.PerformanceAnalysisKit';import{common,Want,AgentExtensionAbility}from'@kit.AbilityKit';import{RequestContext,createA2AServer,Server,TaskState,Role}from'@kit.AgentFrameworkKit';constTAG='=====RideA2AServer===='exportdefaultclassRideAgentExtAbilityextendsAgentExtensionAbility{// 服务端实例:负责处理智能体通信和任务生命周期管理privateserver:Server|null=null;// 核心业务逻辑:A2A Server 收到客户端请求后触发privateagentOnData=(method:string,context:RequestContext)=>{// V哥先做防御:从结构化上下文里取 AgentID,取不到直接拒绝constagentId:string=context.getAgentId()??'';if(!agentId){hilog.error(0x0000,TAG,'Agent ID not found in request context');return;}consttaskId:string=context.getTaskId()??'';switch(method){case'Execute':// ① 先报"开工":把任务推进到工作中this.server?.updateStatus(taskId,{state:TaskState.WORKING,message:{messageId:'msg1',role:Role.AGENT,parts:[{mediaType:'text/plain',text:'正在为你锁定车辆...'}]}});// ② 业务跑完,把交付物(订单结果)作为产物挂到任务上this.server?.addArtifact(taskId,{artifactId:'ride-order',parts:[{mediaType:'application/json',text:'{"orderNo":"...","eta":"6min"}'}]});// ③ 最后通知任务完成,整单闭环this.server?.updateStatus(taskId,{state:TaskState.COMPLETED,message:{messageId:'msg3',role:Role.AGENT,parts:[{mediaType:'text/plain',text:'车辆已预订成功!'}]}});break;case'Cancel':// 用户取消:收尾逻辑写在这里,别让任务悬着hilog.info(0x0000,TAG,'Cancel called');break;default:break;}}// 实例创建完成:首次收到请求时创建 A2A ServerasynconCreate(want:Want){try{constcard=this.context.agentCard;// 智能体名片来自组件上下文this.server=createA2AServer(card,this.agentOnData);}catch(error){hilog.error(0x0000,TAG,`Failed to create server:${error}`);}}// 客户端建连:开门营业,启动服务端onConnect(want:Want,proxy:common.AgentHostProxy){this.server?.start();}// 收到请求体:转交 server.onMessage,回包走 proxy.sendDataasynconData(proxy:common.AgentHostProxy,data:string){this.server?.onMessage(data,(response:string)=>{proxy.sendData(response);});}// 断连与销毁:打烊,回收资源onDisconnect(want:Want,proxy:common.AgentHostProxy){this.server?.stop();}onDestroy(){this.server?.stop();}}

V哥把官方要求的生命周期方法全部列出来了,因为这套骨架的时序本身就是协议:create(建名片)→ start(开门营业)→ onMessage(接单)→ stop(打烊)onCreate里那句this.context.agentCard值得多看一眼——智能体的名片不是在代码里现场拼的,它来自组件上下文,是随应用声明与配置登记好的(Agent Card 的具体配置方式以官方 SDK 文档为准)。

对照上一期会发现一个同构关系:SKILL.md 是 Skill 在意图分发池里的简历,Agent Card 就是智能体在协作网络里的简历。区别在于,智能体的简历多了两项硬信息——端点地址和认证要求。功能被调可以匿名,智能体协作必须验明正身。


三、一单是怎么谈成的:状态机走完才算数

把引子里那个场景的协作链路画出来:

链路里V哥最想展开的是"意图协商"这一段,因为它和接口互调的差别全在这里。日程智能体发起打车需求后,双方不是一次调用定生死,而是在 Task 的状态机里推进:

(示意性伪代码,描述协商语义;TaskState 各枚举字段以官方 SDK 为准) Task 已提交 └─> 打车 Agent:工作中(WORKING,正在匹配车辆) └─> 打车 Agent:需要用户输入(跨 App 动作用户拍板:确认车型与价格) └─> 用户确认 └─> 打车 Agent:工作中(锁定车辆) └─> 已完成(COMPLETED)+ Artifact(订单交付)

两个值得停下来想的点。

第一,"需要用户输入"是写进协议的状态,不是你自定义的弹窗。官方列出的任务状态里有这么一项,说明鸿蒙的 A2A 在协议层面就承认:智能体协作走到有副作用的动作时,必须停下来让人拍板。V哥的判断是——查天气、算出发时间这类只读动作可以自动流转,而下单、扣款这种动作,就该老老实实停在"需要用户输入",把确认权还给用户。协议给了你踩刹车的位置,别把油门焊死。

第二,Artifact 和 Message 是两种东西。谈判过程中说的话是 Message——指令、上下文、状态更新;最终交付的是 Artifact——有唯一 ID 和名称的交付物。把订单结果当聊天消息发出去,下游就没法可靠地引用它,这在多轮、多智能体的协作里是致命的。

还有一类特殊请求单独提一下:官方定义了 PerceptionSuggest 类型的请求,用于小艺感知用户当前所在 App、向智能体请求推荐内容(AgentChips 场景),交互流程有单独文档。也就是说,你的智能体不只是"被别的智能体调",还能在小艺的推荐位上主动露脸。


四、V哥的三条判断

① 撮合靠系统,被撮合的资格靠自己。日程智能体不需要认识打车智能体——它把子意图交给系统,系统按 Agent Card 撮合。官方把这一范式概括为"意图即服务",小艺作为系统级智能体承担意图理解与服务分发(官方发布说明)。撮合质量取决于系统,而轮不轮得到你进场,取决于名片上的能力描述写得清不清——写得含糊,协商还没开场你就出局了。

② 端 A2A 与云 A2A 是双轨,不是二选一。官方口径里,端侧保障低时延本地响应、隐私数据不出端,云侧支撑复杂任务的深度推理。日程、行程这类敏感数据走端侧,跨城比价、长程规划这类重推理走云侧,按任务属性分轨,别一刀切。

③ 开发者的活儿从"写页面"变成了"写能力"。这期和上一期合起来看,脉络很清楚:Skill 化让功能被系统调用,A2A 让智能体彼此协商,界面退居"最后一步",能力登记成了第一等公民。V哥的原话:以前你的应用是一座楼,用户找门牌号;现在你的应用是一个谈判代表,系统按名片找它谈事。代表的水平体现在名片和谈判记录(Agent Card 与任务状态机)上,不体现在装修上。


五、收尾:协作网络的价值,随节点超线性增长

A2A 的红利有个特点:单看你自己的智能体,价值有限;网络里接入的智能体越多,每一次协商的可能组合就越多。日程智能体今天跟打车谈,明天可能跟机票、酒店、会议助手谈——而你的接入成本,就是一张名片加一个服务端骨架。

7.0 刚发布,协作网络里的节点还不多。上一期V哥说 Skill 化是新门票,这一期补一句:A2A 是你在智能体协作网络里的席位,席位放出来的时候,坐上去的人最少。


参考与出处

本文的协议概念、接口名与能力描述来自以下官方文档与发布说明:

  • 通过 AgentAbilityExtension 实现智能体间 A2A 协议通信(AI / Agent Framework Kit)
  • @ohos.app.agent.AgentExtensionAbility 接口参考(Ability Kit)
  • A2A Server 模块 API 文档
  • 小艺 AgentChips 交互流程
  • HarmonyOS 7(API 26)面向 App 与 Agent 开放 Skill、Agent 及 AI 开放能力(官方新闻)
  • HarmonyOS 新能力一览(7 / API 26)

最后一句:图标时代比的是谁的门面亮,A2A 时代比的是谁的名片硬——把 Agent Card 当名片写,把任务状态机当谈判记录记,下一个被系统拉去谈事的,就是你的智能体。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询