HarmonyOS 7.0 / API 26 小艺智能体高风险动作确认:为什么不能识别到意图就执行
这篇只讲一个问题:小艺智能体识别出用户意图以后,哪些动作可以直接执行,哪些动作必须再确认一次。
版本边界先写清楚:下面的思路面向 HarmonyOS 7.0 / API 26。这里不写泛泛的“智能化体验”,而是站在应用开发者的角度看一个更实际的问题:智能体可以帮用户省步骤,但不能替用户做高风险决定。尤其是删除、支付、提交、公开发布、修改账号资料这类动作,一旦做错,用户不会觉得应用智能,只会觉得应用不可靠。
为什么这个问题容易被忽略
很多页面一开始都是按钮触发的:用户点按钮,页面弹确认框,确认后再调用接口。接入智能体以后,入口变了,用户可能说一句“帮我清掉这些记录”,系统就识别成一个 action。如果代码里直接把这个 action 交给业务层执行,就会绕过原来的确认链路。
这类问题通常不是编译报错,而是流程设计错误。代码能跑,测试也可能只测到正常路径,但一到真实用户场景就容易出事。
我自己的判断方式比较简单:只要这个动作执行后很难撤回,或者会影响用户资产、隐私、数据完整性,就不能只靠意图识别结果直接执行,必须进入二次确认。
先把动作分级
不要把所有智能体动作都写成同一种处理方式。建议先做一层动作分级,让页面只处理结果,不直接猜风险。
| 动作类型 | 例子 | 是否需要确认 | 原因 |
|---|---|---|---|
| 查询类 | 查天气、查订单状态、查页面内容 | 一般不需要 | 不改数据,出错也容易纠正 |
| 页面跳转类 | 打开设置页、打开收藏列表 | 通常不需要 | 只是换页面,没有直接副作用 |
| 轻量修改类 | 切换主题、调整排序 | 视情况确认 | 可以撤回时风险较低 |
| 高风险修改类 | 删除记录、提交表单、公开发布 | 必须确认 | 执行后可能造成数据或隐私风险 |
| 资产相关类 | 支付、兑换、订阅、扣积分 | 必须确认 | 需要用户明确授权 |
这个表不要只写在文档里,最好落到代码里。否则后面每加一个动作,开发者都会按自己的理解写,风险边界会越来越乱。
例子一:删除历史记录不能只靠一句话
复现场景:
- 用户在应用里打开历史记录页。
- 用户对小艺说:“把最近浏览记录清掉”。
- 智能体识别出
clearHistory意图。 - 如果代码直接执行删除,用户可能来不及发现删的是全部记录还是筛选后的记录。
这个问题的核心不在智能体识别准不准,而在执行前有没有把影响范围说清楚。
建议做法是:先构造待确认动作,把动作名称、影响范围、数量、是否可撤回都列出来,再交给确认层处理。
typeRiskLevel='low'|'middle'|'high';interfaceAgentAction{actionId:string;name:string;riskLevel:RiskLevel;targetCount:number;reversible:boolean;reason:string;}interfaceConfirmResult{canRun:boolean;message:string;}classAgentActionGuard{check(action:AgentAction):ConfirmResult{if(action.riskLevel==='high'){return{canRun:false,message:`${action.name}会影响${action.targetCount}条数据,需要用户确认后再执行`};}if(!action.reversible&&action.targetCount>0){return{canRun:false,message:`${action.name}不支持撤回,先弹确认框`};}return{canRun:true,message:'低风险动作,可以直接执行'};}}页面里不要直接调用删除接口,而是先走 guard。
@Entry@Componentstruct AgentActionPage{privateguard:AgentActionGuard=newAgentActionGuard();@StateconfirmText:string='等待智能体动作';@StatependingActionId:string='';handleClearHistoryIntent(){constaction:AgentAction={actionId:'clear_history_recent',name:'清理最近浏览记录',riskLevel:'high',targetCount:28,reversible:false,reason:'用户通过智能体触发清理动作'};constresult=this.guard.check(action);if(!result.canRun){this.pendingActionId=action.actionId;this.confirmText=result.message;return;}this.runAction(action.actionId);}runAction(actionId:string){console.info(`[agent-action] run actionId=${actionId}`);}build(){Column({space:12}){Text('小艺智能体动作确认').fontSize(20).fontWeight(FontWeight.Bold)Text(this.confirmText).fontSize(14)Button('确认执行').enabled(this.pendingActionId.length>0).onClick(()=>{this.runAction(this.pendingActionId);this.pendingActionId='';this.confirmText='动作已确认执行';})}.padding(16)}}这样做的好处是,智能体只负责识别意图,真正执行前仍然由应用自己的安全链路兜住。后面如果要加“删除收藏”“清空缓存”“批量取消订阅”,也能复用同一套判断逻辑。
例子二:公开提交类动作要先让用户看结果
第二个常见场景是提交内容。比如用户说:“帮我把这段反馈发出去”。智能体可能已经帮用户整理好了文本,但公开发布、提交工单、反馈到社区这类动作,最好不要直接执行。
这里的风险不是技术接口复杂,而是内容可能不符合用户真实想法。用户说的是一句模糊指令,系统生成的是一段具体内容,中间必须给用户一次确认机会。
可以把提交动作拆成三个阶段:
prepare:生成待提交内容。preview:展示内容、目标位置和影响范围。submit:用户确认后再提交。
typeSubmitStep='prepare'|'preview'|'submit';interfaceAgentSubmitDraft{step:SubmitStep;title:string;content:string;target:string;confirmed:boolean;}classAgentSubmitFlow{next(draft:AgentSubmitDraft):AgentSubmitDraft{if(draft.step==='prepare'){return{...draft,step:'preview'};}if(draft.step==='preview'&&draft.confirmed){return{...draft,step:'submit'};}returndraft;}}页面层只根据阶段渲染,不要把提交按钮一直放开。
@Componentstruct SubmitPreviewPanel{@Statedraft:AgentSubmitDraft={step:'prepare',title:'应用反馈',content:'页面在弱网恢复后提示不够明确,希望增加重试说明。',target:'反馈中心',confirmed:false};privateflow:AgentSubmitFlow=newAgentSubmitFlow();build(){Column({space:10}){Text(this.draft.title).fontSize(18).fontWeight(FontWeight.Medium)Text(`提交位置:${this.draft.target}`).fontSize(13)Text(this.draft.content).fontSize(14)if(this.draft.step==='preview'){Checkbox().select(this.draft.confirmed).onChange((checked:boolean)=>{this.draft.confirmed=checked;})Text('我已确认提交内容和提交位置')}Button(this.draft.step==='prepare'?'生成预览':'提交').enabled(this.draft.step==='prepare'||this.draft.confirmed).onClick(()=>{this.draft=this.flow.next(this.draft);if(this.draft.step==='submit'){console.info('[agent-submit] user confirmed, submit now');}})}.padding(16)}}这个拆法看起来多了一步,但能避免两个问题:一是误提交,二是用户不知道系统到底替自己提交了什么。对智能体入口来说,这一步很关键。
我会怎么选方案
| 方案 | 适合场景 | 问题 |
|---|---|---|
| 识别到意图就执行 | 查询、跳转、无副作用动作 | 不适合删除、提交、支付等高风险动作 |
| 每个页面自己写确认 | 小项目、动作很少 | 后面动作多了容易漏 |
| 统一动作分级和确认流 | 多入口、多页面、多设备 | 前期要把动作模型设计好 |
我更建议第三种。不是因为它看起来复杂,而是因为智能体入口会越来越多:语音、卡片、桌面入口、跨设备入口都可能触发同一个动作。确认逻辑如果散在各个页面里,后面很难排查到底哪个入口绕过了安全判断。
怎么验证不是纸上谈兵
我会至少测这几条:
| 测试项 | 输入 | 预期 |
|---|---|---|
| 查询类动作 | 打开某个页面 | 直接执行 |
| 删除类动作 | 清理 28 条历史记录 | 进入确认态,不直接删除 |
| 提交类动作 | 生成反馈并提交 | 先预览,勾选确认后才能提交 |
| 异常动作 | actionId 为空 | 拦截并打印原因 |
| 恢复场景 | 应用切后台再回来 | pendingActionId 不丢,用户仍能看见待确认动作 |
日志也要留清楚,不然问题很难查:
[agent-action] intent=clearHistory risk=high targetCount=28 result=need_confirm [agent-submit] step=preview confirmed=false result=blocked [agent-submit] step=submit confirmed=true result=run总结
小艺智能体接入应用以后,真正要守住的不是“能不能识别出意图”,而是“识别出来以后能不能安全执行”。
查询和跳转可以快,高风险动作必须稳。我的建议是把动作分级、二次确认、影响范围、可撤回性这些规则抽成统一模块。页面只接收结果,不自己临时判断。这样后面接更多 HarmonyOS 7.0 / API 26 新能力时,应用不会因为入口变多而把安全边界写乱。