HarmonyOS API 26 HMAF Skill 多 Skill 冲突仲裁与可恢复执行

适用版本:HarmonyOS API 26。 本文讨论应用侧 HMAF Skill 冲突仲裁:当多个 Skill 同时匹配一个意图时,如何按优先级、权限、资源占用和用户确认选择唯一执行路径,并为拒绝、超时和部分成功提供回退。示例是 ArkTS 风格的纯逻辑模型,不声称已完成 HarmonyOS 编译、系统解析、ArkUI 联调或真机测试。

CSDN-SERIES:HARMONYOS-BATCH-162

一、仲裁输入的规范化

仲裁器不能直接消费自然语言片段。入口先把意图、设备能力、用户确认状态和资源占用整理为不可变快照,再交给纯函数计算。这样同一份快照可以在日志、回放和离线测试中复用;策略升级时,也能定位是输入变化还是规则变化导致结果不同。

export interface ArbitrationSnapshot { readonly intentId: string; readonly candidates: readonly SkillCandidate[]; readonly grantedScopes: readonly string[]; readonly activeLocks: readonly string[]; readonly userConfirmed: boolean }

规范化阶段要去掉未声明字段、截断过长文本,并对候选 Skill 的版本号做格式校验。任何字段缺失都应产生结构化错误,而不是让排序函数自行猜测默认值。跨设备场景还要把设备能力表达为快照约束,避免仲裁器隐式读取当前设备状态。

二、冲突矩阵与决策解释

当两个候选拥有相同资源锁时,优先级并不能单独决定结果。可以把冲突关系记录为矩阵,并为每个被淘汰候选保存原因码,例如 RESOURCE_LOCKED、SCOPE_MISSING、CONFIRM_REQUIRED。原因码适合做指标聚合,也能保证用户界面展示稳定。

export interface ConflictDecision { readonly winnerId?: string; readonly loserId: string; readonly reasonCode: 'RESOURCE_LOCKED' | 'SCOPE_MISSING' | 'CONFIRM_REQUIRED' | 'LOWER_PRIORITY' }

展示层只消费 ConflictDecision,不参与仲裁。日志记录完整矩阵,页面只展示与当前用户操作相关的信息,减少隐私暴露,也避免调试字段误当业务文案。

三、取消、超时与锁释放顺序

取消是正常路径,不应被当作异常。收到取消请求后,先阻止新动作进入执行队列,再撤销待确认项,最后释放资源锁。释放顺序必须可重复,重复取消不能造成负引用或二次释放。超时要携带阶段信息,让上层知道是在等待确认、等待资源还是执行阶段超时。

export function releaseLocks(lockIds: readonly string[], held: Set<string>): void { for (const id of lockIds) { held.delete(id) } }

如果执行器已经产生外部副作用,回退只能表示停止后续动作,不能宣称自动撤销外部变化。本文只描述状态和责任边界,真实业务仍需依据对应 Kit 的官方撤销能力确认。

四、可观测性与最小化日志

建议为每次仲裁分配短生命周期 traceId,记录候选数量、决策耗时、结果码和锁集合摘要,不记录原始提示词、个人身份字段或完整上下文。日志采集失败不能阻塞主流程;本地缓冲设置容量上限,超过上限时丢弃最旧的低优先级诊断记录。

export function toEvidence(result: ArbitrationResult, traceId: string): ArbitrationEvidence { return { traceId, intentId: traceId, candidates: result.completed.length + result.failed.length, selectedId: result.selectedId, reason: result.fallback, latencyMs: 0 } }

五、迁移与回滚策略

策略版本应随仲裁结果一同落盘,但不应把用户隐私上下文写入版本记录。灰度升级时,新旧仲裁器可以并行计算但只允许一个结果进入执行器;若两者不一致,优先采用旧版本并上报差异,待人工复核后再调整规则。回滚时仅切换策略版本,不删除历史证据。

六、交付前复核补充项

交付前至少复核四类边界:无候选时是否给出可理解的下一步;候选同分时是否保持稳定;资源锁超时后是否确实释放;用户拒绝确认后是否不会自动重试敏感动作。还要检查 A2A 消息是否只携带必要字段、重试是否带幂等键,以及错误提示是否明确区分权限不足和暂时不可用。

Skill冲突仲裁封面

候选Skill排序流程

仲裁器与执行器结构

七、冲突来自哪里

同一意图可能命中多个 Skill,也可能同时争用摄像头、音频焦点或文件写入能力。仲裁器必须先把候选集合结构化,再决定是否需要用户选择。

八、候选契约

export interface SkillCandidate { readonly id: string; readonly capability: string; readonly priority: number; readonly requiresConfirm: boolean; readonly resource: string }

候选描述能力和资源,不直接携带执行副作用;执行器只接收仲裁后的计划。

九、稳定排序

排序需要稳定:优先级相同按版本和注册时间决胜,不能依赖对象遍历顺序。

export function rankCandidates(items: readonly SkillCandidate[]): SkillCandidate[] { return [...items].sort((a,b)=>b.priority-a.priority || a.id.localeCompare(b.id)) }

十、权限先于优先级

没有权限的候选直接进入 rejected,不能因为优先级高而绕过授权。涉及个人数据或跨应用动作必须停在确认节点。

十一、资源锁

export function resourceConflict(a: SkillCandidate, b: SkillCandidate): boolean { return a.resource !== '' && a.resource === b.resource }

资源锁只描述当前事务,不应成为全局永久状态;任务结束、取消或超时都必须释放。

十二、用户确认

当两个候选都合法且结果差异明显时,展示简短选项和影响说明,让用户选择,而不是静默替换。

十三、仲裁结果

export type Arbitration = { kind: 'selected'; candidate: SkillCandidate } | { kind: 'confirm'; candidates: readonly SkillCandidate[] } | { kind: 'none'; reason: string }

十四、超时与回退

仲裁本身也有截止时间。超过预算时返回 none,并让页面提供重试、修改输入或取消,不继续堆积候选。

十五、部分成功

多个 Skill 串联时,一个步骤成功并不代表全链路成功。结果需要区分已完成、被跳过和可补偿动作。

export interface ArbitrationResult { readonly selectedId?: string; readonly completed: readonly string[]; readonly failed: readonly string[]; readonly fallback?: string }

十六、端侧A2A边界

跨端转发只携带候选 ID、意图 ID、版本和最小参数。接收端重新执行权限、过期和资源校验,不信任上游的最终判定。

十七、API26版本声明

本文目标版本为 HarmonyOS API 26(Version 26)。HMAF、Skill 和仲裁器按应用侧模型讨论,具体平台能力、权限和生命周期仍需对照官方文档确认。

十八、状态映射

页面区分 collecting、arbitrating、waitingConfirm、running、partial、rejected 和 done,保证每个异常都有可见原因和动作。

十九、观测字段

export interface ArbitrationEvidence { readonly traceId: string; readonly intentId: string; readonly candidates: number; readonly selectedId?: string; readonly reason?: string; readonly latencyMs: number }

日志只记录数量、ID 和原因码,不记录原始隐私内容。

二十、去重与版本

同一意图的重复仲裁返回已有结果;候选版本变化时重新校验权限和资源,不能复用旧的授权快照。

二十一、纯逻辑验证边界

本文未执行 HarmonyOS 编译、系统解析、ArkUI 联调或真机测试;本地验证仅针对排序、冲突、权限、状态映射和回退决策。

二十二、回归矩阵

覆盖空候选、同优先级、资源冲突、权限拒绝、需要确认、超时、重复提交、部分成功、撤销授权和小窗口恢复。

二十三、官方资料

二十四、交付前清单

确认版本声明、稳定排序、权限前置、资源锁释放、用户确认、超时预算、回退入口和日志脱敏均有测试证据。

二十五、最小落地顺序

先实现纯函数排序和冲突判定,再接入权限策略与确认 UI,最后接入真实执行器。每一步保留上一阶段的回退,避免解析、仲裁和副作用耦合。

二十六、小结

多 Skill 场景的可靠性来自确定性排序、权限前置、资源锁和可见回退。围绕 API 26 固化应用侧契约,才能在真实平台能力接入后保持可解释、可审计和可回归。

二十七、复盘记录

每轮复盘按 traceId 检查候选是否完整、仲裁是否稳定、权限是否清晰、用户是否能取消。任何缺失证据都保留为后续工程任务,不用“执行成功”一笔带过。

二十八、接入前检查清单

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) }

适配表的价值在升级时兑现:每次目标版本变更,先对照表过一遍已知坑,能省下一整轮盲目排查。

最后补一条执行细则:这份清单里的每一项判定都要落在可复查的载体上——数值进基线表、结论进复盘文档、异常进问题台账。没有载体的判定等于没有判定,口头确认的“通过”在两周后就会失去可信度。清单的价值不在于列了多少项,而在于每一项都有人认领、有记录可查、有复盘可追溯,三者齐备,清单才从形式变成质量屏障。

Logo

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

更多推荐