HarmonyOS API 26 HMAF Skill 端侧 A2A 消息去重与上下文最小化
HarmonyOS API 26 HMAF 技能 端侧 A2A 消息去重与上下文最小化
适用版本:HarmonyOS API 26。本文讨论侧A2A协作的应用侧契约:消息如何带上理解、能力和权力等键,接收方如何做权限复核,超时或重复消息如何安全回退。示例是ArkTS端风格的纯逻辑模型,不表示完成HarmonyOS编译、系统解析、ArkUI联调或真机测试。
CSDN系列:HARMONYOS-BATCH-161



一、A2A的最小化问题域
端完成侧方协作不是把完整上下文给定广播所有技能,而是传递当前动作所需的最大字段,并让接收方重新做权限与最终校验。
二、消息契约
export interface A2AMessage { readonly messageId: string; readonly intentId: string; readonly capability: string; readonly expiresAt: number; readonly args: Readonly<Record<string, string>> }
messageId负责去重,intentId负责关联动作图,expiresAt限制重放窗口。
三、来源与能力验证
发送方声明来源不等于接收方授权。接收方应核对来源、能力白名单、参数模式和当前用户确认状态,再决定是否进入执行队列。
export interface VerifyResult { readonly ok: boolean; readonly reason?: 'expired' | 'unknown_capability' | 'invalid_args' | 'missing_consent' }
export function verifyMessage(message: A2AMessage, now: number, allowed: ReadonlySet<string>): VerifyResult { if (message.expiresAt <= now) return { ok: false, reason: 'expired' }; if (!allowed.has(message.capability)) return { ok: false, reason: 'unknown_capability' }; return { ok: true } }
四、权力等去重表
去重表只保存消息ID、状态和过渡时间,不保存完整的上下文。状态至少包含seen、running、done和rejected。
export type SeenState = 'seen' | 'running' | 'done' | 'rejected'
export interface SeenRecord { readonly messageId: string; readonly state: SeenState; readonly expiresAt: number }
export function shouldDrop(record: SeenRecord | undefined, now: number): boolean { return Boolean(record && record.expiresAt > now) }
五、上下文最小化
消息只说明必要参数。用户原始话术、动作、位置和设备指纹不默认透传给需要它们的技能;必要时使用短期引用并在执行后失效。
六、超时预算
export function remainingBudget(deadlineMs: number, nowMs: number): number { return Math.max(0, deadlineMs - nowMs) }
export function canForward(deadlineMs: number, nowMs: number, reserveMs: number): boolean { return remainingBudget(deadlineMs, nowMs) > reserveMs }
转发前先预备本地清理和回退时间,避免下部等待全部预算后无法向用户解释结果。
七、重放与乱序
接收方按messageId去重,按intentId和版本号处理乱序。旧版本消息只能被记录,不能覆盖已完成的新版本动作。
八、拒绝与回执
拒绝消息应注明稳定原因码,例如EXPIRED、NO_CONSENT、CAPABILITY_DENIED,不返回过度敏感信息。回执只说明状态变化,不回显完整参数。
九、部分成功
多个技能协作时,部分成功处于正常状态。结果应启动完成、跳过和待重试动作,而不是用户可以选择继续或取消,是收到笼系统的失败提示。
export interface A2AResult { readonly completed: readonly string[]; readonly skipped: readonly string[]; readonly retryable: readonly string[] }
十、本地服务器与清理
去重记录按 TTL 清理,应用退出或用户取消授权时清理对应意图。不要把去重表设置为长期业务数据库。
十一、API26版本声明
本文目标版本为HarmonyOS API 26(Version 26)。A2A、HMAF 和 Skill 按应用侧模型讨论,具体平台能力、权限和生命周期仍需以官方文档为准。
十二、UI状态映射
至少页面区分waiting、verifying、running、partial、rejected和done,每个非成功状态都提供原因与可恢复动作。
十三、安装场地
export interface A2AEvidence { readonly traceId: string; readonly messageId: string; readonly state: SeenState; readonly latencyMs: number; readonly reason?: string }
日志不保存原始话术和敏感参数,只保存诊断所需的带宽、状态和时间。
十四、回归矩阵
覆盖重复消息、过渡能力消息、乱序版本、未知、缺少确认、超时转发、部分成功、撤销授权和小窗口恢复。每条退出记录输入、判定和回。
十五、纯逻辑验证边界
此处未执行HarmonyOS编译、系统解析、ArkUI联调或真机测试;本地验证仅针对消息校验、去重、预算与状态映射。
十六、官方资料
十七、小结
端侧A2A的可靠性来自最小上下文、接收方复核、权力等去重和明确回执。围绕API 26固化这些应用侧契约,才能在接入器真实技能时保持可解释、可恢复能力和可回归。
十八、纵向队列的边界
发送队列只负责排序、中间检查和取消,不负责解释自然语言。解析器输出稳定的intentId后,队列才接续消息生命周期;这样可以把模型移动与执行可靠性隔离开。
export interface QueueItem { readonly message: A2AMessage; readonly enqueuedAt: number; readonly cancelled: boolean }
export function isExpired(item: QueueItem, now: number): boolean { return item.message.expiresAt <= now || item.cancelled }
十九、接收方的二次确认
即使上游已经确认,接收技能仍应在本地检查当前账号、设备状态和权限范围。拒绝时返回稳定错误码,调用方可以选择修改参数而不是盲目重试。
二十、版本迁移
消息契约升级时增加schemaVersion,接收方仅兼容明确声明的版本;不支持的版本进入CONTRACT_MISMATCH,并保留原消息摘要提供人工复盘。
export function supportsSchema(version: number, supported: ReadonlySet<number>): boolean { return supported.has(version) }
第二十一、端侧安全日志
日志以traceId、messageId、能力名和结果码为主,不记录完整话术、股票或文件内容。日志导出前需经过脱敏和权限检查,诊断能力避免变成隐私泄露入口。
二十二、交付前检查表
交付前确认:API 26版本是否写明;A2A消息有幂等键;接收方是否二次校验;隔壁与乱序是否可预测;用户是否能取消成功;部分是否可恢复;日志最小化是否可恢复;日志最小化;本地测试是否覆盖拒绝和重试。如果没有证据,均应保留为后续任务。
export function dedupeKey(message: A2AMessage): string { return `${message.intentId}:${message.messageId}` }
二十三、最小落地顺序
建议先在单进程内实现消息契约和去重表,再接入跨能力通道;先让拒绝、过渡和重复消息在本地回放,再增加真实执行器。这样即使平台能力或权限配置发生变化,动作图、回执和用户提示稳定的测试接入。接入API 26目标设备时,应把窗口变化、应用切后台并授权撤回作为回归独立场景,不要把一次成功运行当成长期兼容。证明
每轮恢复都保留输入消息摘要、去重表快照、最终状态和用户必要可见提示。对失败样本只保存的诊断字段,原始内容在测试结束后立即清理,为了避免追踪问题而扩大数据留存范围。
如果接收方拒绝了消息,发送方应收到强制回执,并能在动作中看到拒绝原因。对于可重试错误,重试必须耗费明确预算;对于权限和契约错误,只能引导用户修改输入或重新授权,不能用自动重试忽略边界问题。
套件边界也适用于多设备:设备切换时重新验证和授权,不直接恢复使用旧会话上下文。
因此,消息协议、机状态和用户提示应一起评审,不能只看传输是否成功。
最终验收以真实目标设备和官方能力说明一致,本文不虚构任何系统联调结论。这也是可审计协作的最后一个边界。请保留复盘记录。并标记负责人。
二十四、接入前检查清单
HarmonyOS AP正式接入前,工程侧要过一遍检查清单:SDK版本与目标API版本匹配、权限在清单中声明且其次申请、能力切换在专用配置层管理、包体积增量匹配预算。任何一项不过先停,带着不匹配的版本往上冲,排错会翻倍成本。
interface PrecheckItem { name: string; pass: boolean; note?: string }
const checklist: PrecheckItem[] = [
{ name: 'SDK/API版本匹配', pass: false },
{ name: '权限声明完整', pass: false },
{ name: '开关集中管理', pass: false },
{ name: '包体积增量<预算', pass: false },
]
const allPass = checklist.every(x => x.pass)
检查清单跑通的标志是:新建工程按清单接入一次成功,且不依赖任何辅助经验。做不到,说明文档还缺少关键步骤。
二十五、常见坑与版本装备记录
HarmonyOS AP最常践的坑集中在三处:样本代码用的旧接口在新版本被拆分、默认配置与生产预期不一致、调试环境与真机行为存在差异。每践一个坑就记进版本发票表,涉坑点、影响版本、修复方式与验证方式。
interface Pitfall { issue: string; sinceApi: string; fix: string; verifiedOn: string[] }
const pitfalls: Pitfall[] = []
function knownPit(api: string): Pitfall[] { return pitfalls.filter(p => p.sinceApi === api) }
车辆表的价值在升级时兑现:每次目标版本变更,先对照表过一遍已知坑,能省下一轮整轮盲目排查。
二十六、恢复口径与停止线
HarmonyOS AP的任何序列合入前都要回答相同问题:怎么证明没有把好的部分改坏。回归口径必须重复纸面:上一版通过的例子清单全量跑重、上一版记录的基线值全量对比、增加能力补一条典型例子。三件事缺一件,回归就是穿越场。
interface RegressionGate { lastPassedCases: number; rerun: number; baselineCompare: 'PASS' | 'FAIL'; newCaseAdded: boolean }
function gateOk(g: RegressionGate): boolean { return g.rerun === g.lastPassedCases && g.baselineCompare === 'PASS' && g.newCaseAdded }
停止线同样要提前写明:同一问题打回三次、恢复连挂两轮、或验证环境与目标环境共振,满足其一停止来复盘,流程是继续硬修。停止把线当成流程的一部分,才能避免在小问题上消耗掉整块的排期。
更多推荐




所有评论(0)