HarmonyOS 7.0 / API 26 小艺智能体高风险动作确认:为什么不能识别到意图就执行

这篇只讲一个问题:小艺智能体识别出用户意图以后,哪些动作可以直接执行,哪些动作必须再确认一次。
版本边界先写清楚:下面的思路面向 HarmonyOS 7.0 / API 26。这里不写泛泛的“智能化体验”,而是站在应用开发者的角度看一个更实际的问题:智能体可以帮用户省步骤,但不能替用户做高风险决定。尤其是删除、支付、提交、公开发布、修改账号资料这类动作,一旦做错,用户不会觉得应用智能,只会觉得应用不可靠。
很多页面一开始都是按钮触发的:用户点按钮,页面弹确认框,确认后再调用接口。接入智能体以后,入口变了,用户可能说一句“帮我清掉这些记录”,系统就识别成一个 action。如果代码里直接把这个 action 交给业务层执行,就会绕过原来的确认链路。
这类问题通常不是编译报错,而是流程设计错误。代码能跑,测试也可能只测到正常路径,但一到真实用户场景就容易出事。
我自己的判断方式比较简单:只要这个动作执行后很难撤回,或者会影响用户资产、隐私、数据完整性,就不能只靠意图识别结果直接执行,必须进入二次确认。
不要把所有智能体动作都写成同一种处理方式。建议先做一层动作分级,让页面只处理结果,不直接猜风险。
| 动作类型 | 例子 | 是否需要确认 | 原因 |
|---|---|---|---|
| 查询类 | 查天气、查订单状态、查页面内容 | 一般不需要 | 不改数据,出错也容易纠正 |
| 页面跳转类 | 打开设置页、打开收藏列表 | 通常不需要 | 只是换页面,没有直接副作用 |
| 轻量修改类 | 切换主题、调整排序 | 视情况确认 | 可以撤回时风险较低 |
| 高风险修改类 | 删除记录、提交表单、公开发布 | 必须确认 | 执行后可能造成数据或隐私风险 |
| 资产相关类 | 支付、兑换、订阅、扣积分 | 必须确认 | 需要用户明确授权 |
这个表不要只写在文档里,最好落到代码里。否则后面每加一个动作,开发者都会按自己的理解写,风险边界会越来越乱。
复现场景:
- 用户在应用里打开历史记录页。
- 用户对小艺说:“把最近浏览记录清掉”。
- 智能体识别出
clearHistory意图。 - 如果代码直接执行删除,用户可能来不及发现删的是全部记录还是筛选后的记录。
这个问题的核心不在智能体识别准不准,而在执行前有没有把影响范围说清楚。
建议做法是:先构造待确认动作,把动作名称、影响范围、数量、是否可撤回都列出来,再交给确认层处理。
type RiskLevel = 'low' | 'middle' | 'high';
interface AgentAction {
actionId: string;
name: string;
riskLevel: RiskLevel;
targetCount: number;
reversible: boolean;
reason: string;
}
interface ConfirmResult {
canRun: boolean;
message: string;
}
class AgentActionGuard {
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
@Component
struct AgentActionPage {
private guard: AgentActionGuard = new AgentActionGuard();
@State confirmText: string = '等待智能体动作';
@State pendingActionId: string = '';
handleClearHistoryIntent() {
const action: AgentAction = {
actionId: 'clear_history_recent',
name: '清理最近浏览记录',
riskLevel: 'high',
targetCount: 28,
reversible: false,
reason: '用户通过智能体触发清理动作'
};
const result = 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:用户确认后再提交。
type SubmitStep = 'prepare' | 'preview' | 'submit';
interface AgentSubmitDraft {
step: SubmitStep;
title: string;
content: string;
target: string;
confirmed: boolean;
}
class AgentSubmitFlow {
next(draft: AgentSubmitDraft): AgentSubmitDraft {
if (draft.step === 'prepare') {
return { ...draft, step: 'preview' };
}
if (draft.step === 'preview' && draft.confirmed) {
return { ...draft, step: 'submit' };
}
return draft;
}
}
页面层只根据阶段渲染,不要把提交按钮一直放开。
@Component
struct SubmitPreviewPanel {
@State draft: AgentSubmitDraft = {
step: 'prepare',
title: '应用反馈',
content: '页面在弱网恢复后提示不够明确,希望增加重试说明。',
target: '反馈中心',
confirmed: false
};
private flow: AgentSubmitFlow = new AgentSubmitFlow();
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 新能力时,应用不会因为入口变多而把安全边界写乱。
更多推荐

所有评论(0)