HarmonyOS 7 Agent Framework Kit 入门:先把能力边界和最小接入链路理清

实际项目第一次接触 Agent Framework Kit,最容易出现的误区不是代码写错,而是把几种完全不同的能力混在一起:有人把“在应用内拉起智能体”理解成应用已经具备完整智能体服务;有人看到 A2A 就直接设计跨应用调用,却没有先确认账号、应用关联、签名和开放范围;还有人把模型回答展示出来便认为链路完成,却没有处理取消、超时、重复点击和失败恢复。

HarmonyOS 7 对应 API 26.0.0。华为开发者官方的新能力页面把 Agent 系统能力、模型能力开放以及端侧、云侧 A2A 接入列为智能化方向;版本说明又明确,API 26 的 Agent Framework Kit 新增了通过 AgentAbilityExtension 实现智能体间 A2A 协议通信的能力。本文不虚构一个“已经上线”的项目,而是先回答更基础也更重要的问题:一个普通 HarmonyOS 应用准备接入 Agent 能力时,应该如何确定边界、拆分模块、管理状态,并建立可以继续联调的最小工程链路。

HarmonyOS 7 Agent Framework Kit 封面

证据说明:本文对平台能力的描述来自华为开发者官方页面与 API 26 版本资料。示例中的业务接口、状态机和适配层属于建议实现,用于说明工程组织方式,不代表华为官方接口名称。本轮没有执行真机 A2A 联调、性能测试或上架审核,因此不会把这些结果写成已经完成。

一、先区分“拉起智能体”和“提供智能体服务”

官方文档中心对 Agent Framework Kit 的定位,是在应用内拉起智能体组合,使用户可以在适当场景通过 UI 控件主动进入智能体验。API 26 的新增能力则进一步覆盖 AgentAbilityExtension 与智能体间 A2A 通信。这两个方向相关,但工程责任并不相同。

场景应用承担的主要责任最先验证的内容
应用内拉起智能体提供明确入口、传递必要上下文、展示启动与失败状态当前账号与应用是否具备接入条件
应用提供端侧 Agent 服务声明服务、处理请求、返回结构化结果、管理生命周期Extension 配置与协议契约是否一致
接入已有云 Agent处理账号关联、网络失败、服务端结果与隐私提示云端服务、授权范围和数据处理边界
Agent 调用应用能力把现有业务能力封装为稳定契约参数白名单、幂等和错误码

如果只需要在某个页面给用户一个“咨询助手”入口,就不要一开始搭建复杂的多 Agent 编排。如果目标是让另一个 Agent 调用本应用中的查询、创建或计算能力,则需要先把业务能力做成稳定服务,再讨论 A2A。顺序反过来,页面、协议和业务逻辑会缠在一起,后续几乎无法独立测试。

二、接入前的五步评估比直接写页面更重要

Agent 能力接入评估流程

第一步是确认场景。入口必须对应一个用户能够理解的任务,例如“根据当前行程生成准备清单”,而不是笼统的“打开 AI”。第二步是核对权限和账号条件。官方开放平台资料显示,部分应用内 Agent 关联仅支持选择同一账号下已经上架的应用;真机调试还涉及签名。没有满足条件时,应把它记录成环境阻塞,不能用模拟成功页面代替。

第三步是定义契约。请求中哪些字段由页面提供,哪些由服务补齐,哪些绝不能离开设备,都要在编码前写清楚。第四步才是封装调用,把平台调用集中到适配层。第五步是验证结果,至少覆盖成功、取消、超时、无权限、服务不可用和重复点击。

可以先用一份不依赖平台 API 的业务契约约束页面:

export interface TravelPlanRequest {
  destination: string
  days: number
  season: 'spring' | 'summer' | 'autumn' | 'winter'
}

export interface TravelPlanResult {
  summary: string
  checklist: string[]
  requestId: string
}

这段类型不是平台接口,它只负责应用自己的业务边界。destinationdaysseason 都可以在调用前校验;requestId 用来关联一次请求、日志和页面结果。平台 SDK 如何发起会话可以变化,但页面依赖的业务输入输出不必跟着变化。

三、用四层结构隔离平台变化

Agent 接入工程分层

页面层只负责触发、展示和重试;编排层管理状态机、超时、取消与去重;能力层定义业务契约并完成参数归一化;平台层才接触 Agent Framework Kit。这样的拆分不是为了增加文件数量,而是为了让每层都有可验证的责任。

建议目录可以保持简单:

features/travel-agent/
  pages/TravelAssistantPage.ets
  models/TravelAgentModels.ets
  services/TravelAgentOrchestrator.ets
  adapters/HarmonyAgentAdapter.ets
  validators/TravelRequestValidator.ets

如果平台能力处于 Beta、接口需要特定权限,或者当前开发账号暂时不可用,仍然可以测试验证器和编排状态机。反过来,如果页面直接 import 平台模块,任何权限变化、接口变更或模拟测试都会迫使页面一起修改。

四、页面状态必须比“一个 loading 布尔值”更完整

Agent 调用可能经历准备、等待、成功、失败和取消。只使用 isLoading 会产生两个问题:一是无法区分首次空白与失败后的空白;二是用户返回页面或连续点击时,不知道旧请求是否仍有效。

export type AgentPagePhase =
  'idle' | 'validating' | 'requesting' |
  'success' | 'failed' | 'cancelled'

export interface AgentPageState {
  phase: AgentPagePhase
  requestId?: string
  result?: TravelPlanResult
  errorMessage?: string
}

页面按钮是否可用、进度提示显示什么、是否允许重试,都由 phase 推导。进入 requesting 后禁用重复提交;回调返回时先比较 requestId,旧请求结果不能覆盖新请求。取消操作不应该伪装成失败,也不应该弹出吓人的错误提示。

五、参数校验要在平台调用之前完成

自然语言入口并不意味着业务参数可以无限宽松。旅行天数如果是零、负数或异常大值,目的地如果只有空格,都应该在本地阻断。越早拒绝无效输入,越容易给用户明确反馈,也能减少没有意义的平台请求。

export interface ValidationResult {
  ok: boolean
  message?: string
}

export function validateTravelPlan(
  request: TravelPlanRequest
): ValidationResult {
  if (request.destination.trim().length < 2) {
    return { ok: false, message: '请填写有效目的地' }
  }
  if (!Number.isInteger(request.days) ||
      request.days < 1 || request.days > 30) {
    return { ok: false, message: '行程天数应为1至30天' }
  }
  return { ok: true }
}

验证器只处理可确定的业务规则,不猜测用户身份,也不自行补充敏感信息。若 Agent 确实需要位置、账号或文件内容,应在真实功能中说明用途、触发系统授权并允许用户拒绝,不能因为“智能化”就跳过最小化原则。

六、编排层负责超时、取消和结果去重

下面的适配接口仍然是应用侧封装,并非官方 API。它的意义是让编排层只依赖一个窄接口:

export interface AgentRequestOptions {
  requestId: string
  timeoutMs: number
}

export interface AgentAdapter {
  requestPlan(
    request: TravelPlanRequest,
    options: AgentRequestOptions
  ): Promise<TravelPlanResult>

  cancel(requestId: string): Promise<void>
}

适配器内部才根据当前 SDK 与官方指南实现真实调用。编排层可以设置一个合理超时,但超时不等于平台任务一定已经停止,因此还应调用适配器的取消能力或把请求标记为失效。结果返回后再次检查当前请求标识,保证晚到的响应不会污染页面。

export class TravelAgentOrchestrator {
  private activeRequestId: string = ''

  constructor(private adapter: AgentAdapter) {}

  async execute(
    request: TravelPlanRequest
  ): Promise<TravelPlanResult> {
    const check = validateTravelPlan(request)
    if (!check.ok) {
      throw new Error(check.message ?? '参数无效')
    }

    const requestId = `${Date.now()}-${request.days}`
    this.activeRequestId = requestId
    const result = await this.adapter.requestPlan(request, {
      requestId,
      timeoutMs: 15000
    })

    if (this.activeRequestId !== requestId) {
      throw new Error('请求已失效')
    }
    return result
  }

  async cancel(): Promise<void> {
    const requestId = this.activeRequestId
    this.activeRequestId = ''
    if (requestId.length > 0) {
      await this.adapter.cancel(requestId)
    }
  }
}

实际工程还应使用更可靠的 UUID 生成方式,并把异常映射为业务错误类型。这里保留较短代码,是为了突出三件事:调用前验证、调用中保存请求标识、回调后拒绝失效结果。

七、A2A 不是“把字符串发给另一个应用”

API 26 版本资料明确提到,通过 AgentAbilityExtension 支持智能体间 A2A 协议通信。协议化通信意味着双方要对能力描述、输入、输出、错误和生命周期形成共同约束,而不是任意拼接 JSON 后期待对方理解。

设计 A2A 能力时至少要回答以下问题:

  1. 这个能力是否允许被其他智能体发现和调用?
  2. 调用方需要哪些身份、授权或应用关联条件?
  3. 输入字段是否有长度、枚举和值域限制?
  4. 同一请求重复到达时是否会产生重复订单、重复写入或重复通知?
  5. 服务退出、连接断开或用户取消后如何释放资源?
  6. 返回结果是最终结果、处理中状态,还是可重试错误?

对于会修改数据的能力,幂等键尤其重要。例如“创建提醒”不能仅以自然语言文本判断重复,应该由调用方提供稳定请求标识,服务端保存执行状态。对于只读查询,也要限制结果范围,避免一次请求读取不必要的个人信息。

八、错误不能只展示“调用失败”

排查 Agent 链路时,应先区分环境、配置、契约和运行期问题。不同问题给出的用户提示和开发日志完全不同。

现象优先检查用户侧处理
找不到可关联应用是否属于同一账号、应用是否满足平台要求提示功能暂不可用,不引导反复点击
真机无法启动能力签名、设备系统版本、API版本和开放权限保留页面原内容,提供返回或重试
请求立即被拒绝必填字段、枚举和值域、协议版本在表单附近指出具体无效字段
长时间无结果网络、Agent服务状态、超时与取消是否生效显示超时,可重新发起
返回后页面无变化请求ID是否过期、页面是否已销毁不用过期结果覆盖当前状态
连续生成多份结果是否禁用重复点击、是否使用幂等键保留最新有效结果并提示状态

开发日志可以记录阶段、耗时、错误类别和脱敏后的请求标识,但不要记录完整自然语言输入、账号凭据、授权票据或个人文件内容。日志的目标是定位链路,不是复制用户数据。

九、最小可运行链路应该如何验收

“页面能打开”不等于能力已经接入。“模拟数据能显示”也不能证明 Agent Framework Kit 可以在真实设备上工作。建议把验收拆为四层。

第一层是纯业务测试:验证输入边界、错误映射、请求去重和取消后的状态。第二层是平台适配测试:在具备条件的账号和设备上确认平台调用能够发起、返回和取消。第三层是页面回归:覆盖首次进入、后台恢复、旋转或窗口变化、连续点击、返回再进入。第四层是隐私与发布核对:确认权限、隐私政策、功能描述与真实行为一致。

[ ] HarmonyOS 7 / API 26 环境与设备范围已确认
[ ] 应用、Agent和开发者账号的关联条件已满足
[ ] 请求参数有白名单、长度和枚举校验
[ ] requesting阶段禁止重复提交
[ ] 取消或离开页面后,旧结果不会覆盖新状态
[ ] 超时、无权限、服务不可用具有不同错误类型
[ ] 日志不记录凭据、票据和完整个人内容
[ ] 真机结果与模拟结果分别标注,不混写

没有完成真机验证时,可以把文章和代码描述为“接入设计”或“建议实现”,不能写成“已成功上线”或“性能提升多少”。这种证据边界会让技术文章更可信,也方便后续把真实联调结果补进来。

十、从最小链路逐步演进,而不是一次做完所有智能化

第一阶段只选择一个低风险、结果可人工确认的任务,例如生成准备清单。第二阶段增加会话恢复、取消和超时。第三阶段才考虑端侧 A2A 或云 A2A,把现有业务能力开放给其他 Agent。每进入一个阶段,都重新检查权限、数据最小化、失败恢复和发布材料。

如果业务操作具有财务、医疗、身份认证或不可逆写入风险,Agent 只应提供建议或准备数据,最终动作仍需清晰的用户确认。不能让模型输出直接绕过业务校验,也不能把“用户说了一句话”当作所有权限的默认授权。

总结

HarmonyOS 7 为 Agent 与 A2A 带来了新的系统级入口,但真正稳定的接入从来不是在页面上放一个按钮。更可靠的方法是先判断自己需要的是拉起智能体、提供 Agent 服务,还是开放应用业务能力;再用页面层、编排层、能力层和平台层隔离责任;最后通过参数校验、状态机、请求标识、取消、超时和分层验收把链路闭合。

本文完成的是能力边界和工程骨架,不冒充真机联调结果。下一步应根据开发者账号实际可见的 Agent Framework Kit 指南,把平台适配层替换为真实接口,并在 HarmonyOS 7 / API 26 设备上记录可复现的启动、返回、取消和异常数据。

参考资料

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐