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

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

这篇只讲一个问题:小艺智能体识别出用户意图以后,哪些动作可以直接执行,哪些动作必须再确认一次。

版本边界先写清楚:下面的思路面向 HarmonyOS 7.0 / API 26。这里不写泛泛的“智能化体验”,而是站在应用开发者的角度看一个更实际的问题:智能体可以帮用户省步骤,但不能替用户做高风险决定。尤其是删除、支付、提交、公开发布、修改账号资料这类动作,一旦做错,用户不会觉得应用智能,只会觉得应用不可靠。

为什么这个问题容易被忽略

很多页面一开始都是按钮触发的:用户点按钮,页面弹确认框,确认后再调用接口。接入智能体以后,入口变了,用户可能说一句“帮我清掉这些记录”,系统就识别成一个 action。如果代码里直接把这个 action 交给业务层执行,就会绕过原来的确认链路。

这类问题通常不是编译报错,而是流程设计错误。代码能跑,测试也可能只测到正常路径,但一到真实用户场景就容易出事。

我自己的判断方式比较简单:只要这个动作执行后很难撤回,或者会影响用户资产、隐私、数据完整性,就不能只靠意图识别结果直接执行,必须进入二次确认。

先把动作分级

不要把所有智能体动作都写成同一种处理方式。建议先做一层动作分级,让页面只处理结果,不直接猜风险。

动作类型 例子 是否需要确认 原因
查询类 查天气、查订单状态、查页面内容 一般不需要 不改数据,出错也容易纠正
页面跳转类 打开设置页、打开收藏列表 通常不需要 只是换页面,没有直接副作用
轻量修改类 切换主题、调整排序 视情况确认 可以撤回时风险较低
高风险修改类 删除记录、提交表单、公开发布 必须确认 执行后可能造成数据或隐私风险
资产相关类 支付、兑换、订阅、扣积分 必须确认 需要用户明确授权

这个表不要只写在文档里,最好落到代码里。否则后面每加一个动作,开发者都会按自己的理解写,风险边界会越来越乱。

例子一:删除历史记录不能只靠一句话

复现场景:

  1. 用户在应用里打开历史记录页。
  2. 用户对小艺说:“把最近浏览记录清掉”。
  3. 智能体识别出 clearHistory 意图。
  4. 如果代码直接执行删除,用户可能来不及发现删的是全部记录还是筛选后的记录。

这个问题的核心不在智能体识别准不准,而在执行前有没有把影响范围说清楚。

建议做法是:先构造待确认动作,把动作名称、影响范围、数量、是否可撤回都列出来,再交给确认层处理。

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

这样做的好处是,智能体只负责识别意图,真正执行前仍然由应用自己的安全链路兜住。后面如果要加“删除收藏”“清空缓存”“批量取消订阅”,也能复用同一套判断逻辑。

例子二:公开提交类动作要先让用户看结果

第二个常见场景是提交内容。比如用户说:“帮我把这段反馈发出去”。智能体可能已经帮用户整理好了文本,但公开发布、提交工单、反馈到社区这类动作,最好不要直接执行。

这里的风险不是技术接口复杂,而是内容可能不符合用户真实想法。用户说的是一句模糊指令,系统生成的是一段具体内容,中间必须给用户一次确认机会。

可以把提交动作拆成三个阶段:

  1. prepare:生成待提交内容。
  2. preview:展示内容、目标位置和影响范围。
  3. 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 新能力时,应用不会因为入口变多而把安全边界写乱。

Logo

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

更多推荐