• 简体中文
  • 基本概念

    本文概述 Midscene 的核心概念,包括 Agent 的用法、架构、抽象方式和能力边界。你将了解 Agent 如何连接 AI 模型与目标界面,以及如何实现交互、断言等操作。

    规划并交互

    aiAct

    aiAct 接收用自然语言描述的目标。它会观察界面,规划操作步骤,定位目标元素并执行操作,直至完成目标。提示词也可以包含断言条件,Midscene 会在执行过程中验证这些条件。

    aiAct 灵活且自主,适合处理多步骤、包含条件分支或执行路径不确定的任务。每轮规划都可能调用模型,因此它通常比即时交互消耗更多时间和 token。

    典型用法:

    await agent.aiAct(
      '搜索耳机,将第一件商品加入购物车,并确认购物车数量变为 1',
    );

    如需为后续所有 aiAct 调用补充业务上下文,可以使用 agent.setAIActContext()

    agent.setAIActContext(
      '如果出现 Cookie 授权弹窗,请先关闭。页面中的价格单位是美元。',
    );

    aiAct 提供以下单次调用配置:

    • deepThink:加强任务拆解,并通过不同的模型调用分别完成规划和元素定位。该选项可以提高复杂任务的稳定性,但会增加模型调用次数和延迟。
    • deepLocate:增加一次模型调用,提高元素定位的准确性。当目标元素较小或容易与周围元素混淆时,可以启用该选项。
    • context:仅为本次调用补充业务知识或其他背景信息。对于 aiAct,该选项会覆盖 Agent 级别的 aiActContext。显式传入空字符串也会覆盖原有内容。
    await agent.aiAct('完成结账表单,在下单前停止', {
      deepThink: true,
      deepLocate: true,
      context: '测试账号已保存收货地址。',
    });

    即时交互

    即时交互类 API 每次只执行一个指定操作:先定位 UI 元素,再对该元素执行固定动作。

    这类 API 不会规划多个步骤。对于“如果出现弹窗,先关闭弹窗,然后点击结账按钮”这类需求,请使用 aiAct。即时交互 API 会将提示词视为目标元素的描述,而非工作流。

    aiTap

    aiTap 用于定位并点击元素。

    典型用法:

    await agent.aiTap('购物车中的结账按钮');

    当目标较小或视觉特征不明显时,可以启用 deepLocate

    await agent.aiTap('右上角的购物车图标', {
      deepLocate: true,
    });

    aiInput

    aiInput 用于定位输入框并输入指定内容。它默认使用 replace 模式:先清空输入框中的现有内容,再输入新内容。

    典型用法:

    await agent.aiInput('邮箱地址输入框', {
      value: 'user@example.com',
    });

    其他输入模式包括 typeOnlycleartypeOnly 会保留现有内容,clear 仅清空输入框。

    即时交互 API 还包括 aiHoveraiClearInputaiKeyboardPressaiScrollaiPinchaiLongPressaiDoubleClickaiRightClick。各 API 支持的平台不同,详见 API 参考中的规划与交互

    界面理解(Insight)

    界面理解类 API 只观察界面并返回分析结果,不会操作界面。它们默认使用当前截图。在 Web 页面中,如果任务需要读取截图中不可见的 DOM 信息,可以传入 domIncluded

    aiAssert

    aiAssert 用于检查自然语言描述的条件。条件成立时,该方法正常结束;条件不成立时,该方法会抛出错误,并在错误信息中说明模型返回的原因。

    典型用法:

    await agent.aiAssert('购物车中有一件商品,并且页面显示了小计金额');

    aiQuery

    aiQuery 用于从界面中提取结构化数据。请在提示词中描述所需数据,以及数据的预期类型或结构。

    典型用法:

    const items = await agent.aiQuery<
      Array<{ name: string; price: number }>
    >('购物车中的商品,{name: string, price: number}[]');

    aiBoolean

    aiBoolean 用于询问与界面有关的问题,并返回布尔值。

    典型用法:

    const loginDialogVisible = await agent.aiBoolean('登录对话框是否可见');

    其他便捷方法包括:返回数字的 aiNumber,以及返回字符串的 aiStringaiAsk

    用 JavaScript 编排工作流

    aiAct 将执行路径交给 Agent 规划。JavaScript 编排则将条件、循环和步骤顺序写入代码。界面理解类 API 为控制流提供界面状态,即时交互 API 负责执行指定操作。

    JavaScript 编排具有很强的确定性。执行路径明确写在代码中,开发者可以使用熟悉的调试工具,并精确控制每个分支的行为。

    确定性也会降低灵活性。代码只能处理显式编写的情况。例如,分辨率变化可能使页面需要额外滚动,突然出现的弹窗也可能阻断后续操作。如果脚本没有处理这些情况,整个工作流就容易失败。相比之下,aiAct 可以在执行过程中观察当前界面并重新规划。

    以下工作流将循环和条件判断写在 JavaScript 中。Midscene 负责读取界面状态并执行每次点击:

    const recordNames = await agent.aiQuery<string[]>('列表中的所有记录名称');
    
    for (const recordName of recordNames) {
      const completed = await agent.aiBoolean(
        `名为“${recordName}”的记录是否标记为“已完成”`,
      );
    
      if (!completed) {
        await agent.aiTap(`名为“${recordName}”的记录`);
      }
    }

    没有一种方案适用于所有自动化脚本:

    方案执行路径的控制者对 UI 变化的适应能力适用场景
    aiActAgent可以观察界面并重新规划目标明确,但操作步骤或 UI 状态可能变化
    JavaScript 编排代码需要显式处理每种变化流程稳定,且需要精确的分支、循环或调试
    混合使用Agent 和代码在自主性与显式控制之间取得平衡整体流程固定,但局部任务的执行路径不确定

    请根据具体任务选择方案,无须在整个脚本中只使用一种方案。可以将稳定的业务规则和控制流写入 JavaScript,将需要适应意外 UI 状态的步骤交给 aiAct。选择时,应综合考虑稳定性、灵活性、模型成本、执行延迟和维护成本。