mirror of
https://github.com/web-infra-dev/midscene.git
synced 2025-07-27 10:50:11 +00:00

* feat(web-integration): support disable cache for a single api call * feat(workflow): version mismatch * feat(web-integration): cache rename to cacheable * feat(web-integration): add cacheable option to multiple API methods and update caching documentation * docs(site): update cacheable option descriptions to reference caching feature documentation * docs(core): update caching doc --------- Co-authored-by: yutao <yutao.tao@bytedance.com>
586 lines
17 KiB
Plaintext
586 lines
17 KiB
Plaintext
# API 参考
|
||
|
||
> 在以下文档中,你可能会看到带有 `agent.` 前缀的函数调用。如果你在 Playwright 中,这些调用是不带 `agent.` 前缀的,如 `async ({ ai, aiQuery }) => { /* ... */}`。这只是解构语法的区别。
|
||
|
||
## 构造器
|
||
|
||
Midscene 中每个 Agent 都有自己的构造函数。
|
||
|
||
* 在 Puppeteer 中,使用 [PuppeteerAgent](./integrate-with-puppeteer)
|
||
* 在桥接模式(Bridge Mode)中,使用 [AgentOverChromeBridge](./bridge-mode-by-chrome-extension#constructor)
|
||
|
||
这些 Agent 有一些相同的构造参数:
|
||
|
||
* `generateReport: boolean`: 如果为 true,则生成报告文件。默认值为 true。
|
||
* `autoPrintReportMsg: boolean`: 如果为 true,则打印报告消息。默认值为 true。
|
||
* `cacheId: string | undefined`: 如果配置,则使用此 cacheId 保存或匹配缓存。默认值为 undefined,也就是不启用缓存。
|
||
* `actionContext: string`: 调用 `agent.aiAction()` 时,发送给 AI 模型的背景知识,比如 '有 cookie 对话框时先关闭它',默认值为空。
|
||
|
||
在 puppeteer 中,还有三个额外的参数:
|
||
|
||
* `forceSameTabNavigation: boolean`: 如果为 true,则限制页面在当前 tab 打开。默认值为 true。
|
||
* `waitForNetworkIdleTimeout: number`: 在执行每个操作后等待网络空闲的超时时间,默认值为 2000ms,设置为 0 则禁用超时。
|
||
* `waitForNavigationTimeout: number`: 在页面跳转后等待页面加载完成的超时时间,默认值为 5000ms,设置为 0 则禁用超时。
|
||
|
||
## 交互方法
|
||
|
||
这些是 Midscene 中各类 Agent 的主要 API。
|
||
|
||
:::info 自动规划 v.s. 即时操作
|
||
|
||
在 Midscene 中,你可以选择使用自动规划(Auto Planning)或即时操作(Instant Action)。
|
||
|
||
* `agent.ai()` 是自动规划(Auto Planning):Midscene 会自动规划操作步骤并执行。它更智能,更像流行的 AI Agent 风格,但可能较慢,且效果依赖于 AI 模型的质量。
|
||
* `agent.aiTap()`, `agent.aiHover()`, `agent.aiInput()`, `agent.aiKeyboardPress()`, `agent.aiScroll()` 是即时操作(Instant Action):Midscene 会直接执行指定的操作,而 AI 模型只负责底层任务,如定位元素等。这种接口形式更快、更可靠。当你完全确定自己想要执行的操作时,推荐使用这种接口形式。
|
||
|
||
:::
|
||
|
||
### `agent.aiAction()` 或 `.ai()`
|
||
|
||
这个方法允许你通过自然语言描述一系列 UI 操作步骤。Midscene 会自动规划这些步骤并执行。
|
||
|
||
* 类型
|
||
|
||
```typescript
|
||
function aiAction(prompt: string, opt?: {
|
||
cacheable?: boolean;
|
||
}): Promise<void>;
|
||
function ai(prompt: string): Promise<void>; // 简写形式
|
||
```
|
||
|
||
* 参数:
|
||
* `prompt: string` - 用自然语言描述的操作内容
|
||
* `opt?: Object` - 可选,一个配置对象,包含:
|
||
* `cacheable?: boolean` - 当启用 [缓存功能](./caching.mdx) 时,是否允许缓存当前 API 调用结果。默认值为 True
|
||
|
||
* 返回值:
|
||
* 返回一个 Promise。当所有步骤执行完成时解析为 void;若执行失败,则抛出错误。
|
||
|
||
* 示例:
|
||
|
||
```typescript
|
||
// 基本用法
|
||
await agent.aiAction('在搜索框中输入 "JavaScript",然后点击搜索按钮');
|
||
|
||
// 使用 .ai 简写形式
|
||
await agent.ai('点击页面顶部的登录按钮,然后在用户名输入框中输入 "test@example.com"');
|
||
|
||
// 使用 ui-tars 模型时,可以使用更高维度的提示词
|
||
await agent.aiAction('发布一条微博,内容为 "Hello World"');
|
||
```
|
||
|
||
:::tip
|
||
|
||
在实际运行时,Midscene 会将用户指令规划(Planning)成多个步骤,然后逐步执行。如果 Midscene 认为无法执行,将抛出一个错误。
|
||
|
||
为了获得最佳效果,请尽可能提供清晰、详细的步骤描述。具体可以参考这篇文档:[编写提示词的技巧](./prompting-tips)
|
||
|
||
关联文档:
|
||
* [选择 AI 模型](./choose-a-model)
|
||
|
||
:::
|
||
|
||
### `agent.aiTap()`
|
||
|
||
点击某个元素。
|
||
|
||
* 类型
|
||
|
||
```typescript
|
||
function aiTap(locate: string, options?: Object): Promise<void>;
|
||
```
|
||
|
||
* 参数:
|
||
* `locate: string` - 用自然语言描述的元素定位。
|
||
* `options?: Object` - 可选,一个配置对象,包含:
|
||
* `deepThink?: boolean` - 是否开启深度思考。如果为 true,Midscene 会调用 AI 模型两次以精确定位元素。
|
||
* `cacheable?: boolean` - 当启用 [缓存功能](./caching.mdx) 时,是否允许缓存当前 API 调用结果。默认值为 True
|
||
* 返回值:
|
||
* `Promise<void>`
|
||
|
||
* 示例:
|
||
|
||
```typescript
|
||
await agent.aiTap('页面顶部的登录按钮');
|
||
|
||
// 使用 deepThink 功能精确定位元素
|
||
await agent.aiTap('页面顶部的登录按钮', { deepThink: true });
|
||
```
|
||
|
||
### `agent.aiHover()`
|
||
|
||
鼠标悬停某个元素上。
|
||
|
||
* 类型
|
||
|
||
```typescript
|
||
function aiHover(locate: string, options?: Object): Promise<void>;
|
||
```
|
||
|
||
* 参数:
|
||
* `locate: string` - 用自然语言描述的元素定位。
|
||
* `options?: Object` - 可选,一个配置对象,包含:
|
||
* `deepThink?: boolean` - 是否开启深度思考。如果为 true,Midscene 会调用 AI 模型两次以精确定位元素。
|
||
* `cacheable?: boolean` - 当启用 [缓存功能](./caching.mdx) 时,是否允许缓存当前 API 调用结果。默认值为 True
|
||
* 返回值:
|
||
* `Promise<void>`
|
||
|
||
* 示例:
|
||
|
||
```typescript
|
||
await agent.aiHover('页面顶部的登录按钮');
|
||
```
|
||
|
||
### `agent.aiInput()`
|
||
|
||
在某个元素中输入文本。
|
||
|
||
* 类型
|
||
|
||
```typescript
|
||
function aiInput(text: string, locate: string, options?: Object): Promise<void>;
|
||
```
|
||
|
||
* 参数:
|
||
* `text: string` - 要输入的文本内容。使用空字符串可以清空输入框。
|
||
* `locate: string` - 用自然语言描述的元素定位。
|
||
* `options?: Object` - 可选,一个配置对象,包含:
|
||
* `deepThink?: boolean` - 是否开启深度思考。如果为 true,Midscene 会调用 AI 模型两次以精确定位元素。
|
||
* `cacheable?: boolean` - 当启用 [缓存功能](./caching.mdx) 时,是否允许缓存当前 API 调用结果。默认值为 True
|
||
|
||
* 返回值:
|
||
* `Promise<void>`
|
||
|
||
* 示例:
|
||
|
||
```typescript
|
||
await agent.aiInput('Hello World', '搜索框');
|
||
```
|
||
|
||
### `agent.aiKeyboardPress()`
|
||
|
||
按下键盘上的某个键。
|
||
|
||
* 类型
|
||
|
||
```typescript
|
||
function aiKeyboardPress(key: string, locate?: string, options?: Object): Promise<void>;
|
||
```
|
||
|
||
* 参数:
|
||
* `key: string` - 要按下的键,如 `Enter`、`Tab`、`Escape` 等。不支持组合键。
|
||
* `locate?: string` - 用自然语言描述的元素定位。
|
||
* `options?: Object` - 可选,一个配置对象,包含:
|
||
* `deepThink?: boolean` - 是否开启深度思考。如果为 true,Midscene 会调用 AI 模型两次以精确定位元素。
|
||
* `cacheable?: boolean` - 当启用 [缓存功能](./caching.mdx) 时,是否允许缓存当前 API 调用结果。默认值为 True
|
||
|
||
* 返回值:
|
||
* `Promise<void>`
|
||
|
||
* 示例:
|
||
|
||
```typescript
|
||
await agent.aiKeyboardPress('Enter', '搜索框');
|
||
```
|
||
|
||
### `agent.aiScroll()`
|
||
|
||
滚动页面或某个元素。
|
||
|
||
* 类型
|
||
|
||
```typescript
|
||
function aiScroll(scrollParam: PlanningActionParamScroll, locate?: string, options?: Object): Promise<void>;
|
||
```
|
||
|
||
* 参数:
|
||
* `scrollParam: PlanningActionParamScroll` - 滚动参数
|
||
* `direction: 'up' | 'down' | 'left' | 'right'` - 滚动方向
|
||
* `scrollType: 'once' | 'untilBottom' | 'untilTop' | 'untilRight' | 'untilLeft'` - 滚动类型
|
||
* `distance: number` - 滚动距离,单位为像素。
|
||
* `locate?: string` - 用自然语言描述的元素定位。如果未传入,Midscene 会在当前鼠标位置滚动。
|
||
* `options?: Object` - 可选,一个配置对象,包含:
|
||
* `deepThink?: boolean` - 是否开启深度思考。如果为 true,Midscene 会调用 AI 模型两次以精确定位元素。
|
||
* `cacheable?: boolean` - 当启用 [缓存功能](./caching.mdx) 时,是否允许缓存当前 API 调用结果。默认值为 True
|
||
|
||
* 返回值:
|
||
* `Promise<void>`
|
||
|
||
* 示例:
|
||
|
||
```typescript
|
||
await agent.aiScroll({ direction: 'up', distance: 100, scrollType: 'once' }, '表单区域');
|
||
```
|
||
|
||
:::tip 关于 `deepThink` (深度思考)特性
|
||
|
||
`deepThink` 是一个强大的特性,它允许 Midscene 调用 AI 模型两次以精确定位元素。这在目标元素面积较小、难以和周围元素区分时非常有用。
|
||
|
||
:::
|
||
|
||
## 数据提取
|
||
|
||
### `agent.aiQuery()`
|
||
|
||
使用此方法,你可以直接从 UI 提取数据,并借助多模态 AI 的推理能力,实现智能提取。只需在 `dataDemand` 中定义期望格式(如字符串、数字、JSON、数组等),Midscene 即返回相应结果。
|
||
|
||
* 类型
|
||
|
||
```typescript
|
||
function aiQuery<T>(dataShape: string | Object): Promise<T>;
|
||
```
|
||
|
||
* 参数:
|
||
* `dataShape: T`: 描述预期的返回值格式。
|
||
|
||
* 返回值:
|
||
* 返回值可以是任何合法的基本类型,比如字符串、数字、JSON、数组等。
|
||
* 你只需在 `dataDemand` 中描述它,Midscene 就会给你满足格式的返回。
|
||
|
||
* 示例:
|
||
|
||
```typescript
|
||
const dataA = await agent.aiQuery({
|
||
time: '左上角展示的日期和时间,string',
|
||
userInfo: '用户信息,{name: string}',
|
||
tableFields: '表格的字段名,string[]',
|
||
tableDataRecord: '表格中的数据记录,{id: string, [fieldName]: string}[]',
|
||
});
|
||
|
||
// 你也可以用纯字符串描述预期的返回值格式:
|
||
|
||
// dataB 将是一个字符串数组
|
||
const dataB = await agent.aiQuery('string[],列表中的任务名称');
|
||
|
||
// dataC 将是一个包含对象的数组
|
||
const dataC = await agent.aiQuery('{name: string, age: string}[], 表格中的数据记录');
|
||
```
|
||
|
||
此外,我们还提供了 `aiBoolean()`, `aiNumber()`, `aiString()` 三个便捷方法,用于直接提取布尔值、数字和字符串。
|
||
|
||
|
||
### `agent.aiBoolean()`
|
||
|
||
从 UI 中提取一个布尔值。
|
||
|
||
* 类型
|
||
|
||
```typescript
|
||
function aiBoolean(prompt: string): Promise<boolean>;
|
||
```
|
||
|
||
* 参数:
|
||
* `prompt: string` - 用自然语言描述的期望值。
|
||
|
||
* 返回值:
|
||
* 返回一个 Promise。当 AI 返回结果时解析为布尔值。
|
||
|
||
* 示例:
|
||
|
||
```typescript
|
||
const bool = await agent.aiBoolean('是否存在登录对话框');
|
||
```
|
||
|
||
### `agent.aiNumber()`
|
||
|
||
从 UI 中提取一个数字。
|
||
|
||
* 类型
|
||
|
||
```typescript
|
||
function aiNumber(prompt: string): Promise<number>;
|
||
```
|
||
|
||
* 参数:
|
||
* `prompt: string` - 用自然语言描述的期望值。
|
||
|
||
* 返回值:
|
||
* 返回一个 Promise。当 AI 返回结果时解析为数字。
|
||
|
||
* 示例:
|
||
|
||
```typescript
|
||
const number = await agent.aiNumber('账户剩余的积分');
|
||
```
|
||
|
||
### `agent.aiString()`
|
||
|
||
从 UI 中提取一个字符串。
|
||
|
||
* 类型
|
||
|
||
```typescript
|
||
function aiString(prompt: string): Promise<string>;
|
||
```
|
||
|
||
* 参数:
|
||
* `prompt: string` - 用自然语言描述的期望值。
|
||
|
||
* 返回值:
|
||
* 返回一个 Promise。当 AI 返回结果时解析为字符串。
|
||
|
||
* 示例:
|
||
|
||
```typescript
|
||
const string = await agent.aiString('当前列表的第一条记录的名称');
|
||
```
|
||
|
||
## 更多方法
|
||
|
||
### `agent.aiAssert()`
|
||
|
||
通过自然语言描述一个断言条件,让 AI 判断该条件是否为真。当条件不满足时,SDK 会抛出错误,并在错误信息中追加 AI 返回的详细原因。
|
||
|
||
* 类型
|
||
|
||
```typescript
|
||
function aiAssert(assertion: string, errorMsg?: string): Promise<void>;
|
||
```
|
||
|
||
* 参数:
|
||
* assertion: string - 用自然语言描述的断言条件。
|
||
* errorMsg?: string - 当断言失败时附加的可选错误提示信息。
|
||
|
||
* 返回值:
|
||
* 返回一个 Promise。当断言成功时解析为 void;若断言失败,则抛出一个错误,错误信息包含 `errorMsg` 以及 AI 生成的原因。
|
||
|
||
* 示例:
|
||
```typescript
|
||
await agent.aiAssert('"Sauce Labs Onesie" 的价格是 7.99');
|
||
```
|
||
|
||
:::tip
|
||
断言在测试脚本中非常重要。为了降低因 AI 幻觉导致错误断言的风险(例如遗漏错误),你也可以使用 `.aiQuery` 加上常规的 JavaScript 断言来替代 `.aiAssert`。
|
||
|
||
例如,你可以这样替代上面的断言代码:
|
||
|
||
```typescript
|
||
const items = await agent.aiQuery(
|
||
'"{name: string, price: number}[], 返回商品名称和价格列表'
|
||
);
|
||
const onesieItem = items.find(item => item.name === 'Sauce Labs Onesie');
|
||
expect(onesieItem).toBeTruthy();
|
||
expect(onesieItem.price).toBe(7.99);
|
||
```
|
||
:::
|
||
|
||
### `agent.aiLocate()`
|
||
|
||
通过自然语言描述一个元素的定位。
|
||
|
||
* 类型
|
||
|
||
```typescript
|
||
function aiLocate(locate: string, options?: {
|
||
cacheable?: boolean;
|
||
}): Promise<{
|
||
rect: {
|
||
left: number;
|
||
top: number;
|
||
width: number;
|
||
height: number;
|
||
};
|
||
center: [number, number];
|
||
}>;
|
||
```
|
||
|
||
* 参数:
|
||
* `locate: string` - 用自然语言描述的元素定位。
|
||
* `options?: Object` - 可选,一个配置对象,包含:
|
||
* `deepThink?: boolean` - 是否开启深度思考。如果为 true,Midscene 会调用 AI 模型两次以精确定位元素。
|
||
* `cacheable?: boolean` - 当启用 [缓存功能](./caching.mdx) 时,是否允许缓存当前 API 调用结果。默认值为 True
|
||
|
||
* 返回值:
|
||
* 返回一个 Promise。当元素定位成功时解析为元素定位信息。
|
||
|
||
* 示例:
|
||
|
||
```typescript
|
||
const locateInfo = await agent.aiLocate('页面顶部的登录按钮');
|
||
console.log(locateInfo);
|
||
```
|
||
|
||
|
||
### `agent.aiWaitFor()`
|
||
|
||
等待某个条件达成。考虑到 AI 服务的成本,检查间隔不会超过 `checkIntervalMs` 毫秒。
|
||
|
||
* 类型
|
||
|
||
```typescript
|
||
function aiWaitFor(
|
||
assertion: string,
|
||
options?: {
|
||
timeoutMs?: number;
|
||
checkIntervalMs?: number;
|
||
}
|
||
): Promise<void>;
|
||
```
|
||
|
||
* 参数:
|
||
* `assertion: string` - 用自然语言描述的断言条件
|
||
* `options?: object` - 可选的配置对象
|
||
* `timeoutMs?: number` - 超时时间(毫秒),默认为 15000
|
||
* `checkIntervalMs?: number` - 检查间隔(毫秒),默认为 3000
|
||
|
||
* 返回值:
|
||
* 返回一个 Promise。当断言成功时解析为 void;若超时,则抛出错误。
|
||
|
||
* 示例:
|
||
|
||
```typescript
|
||
// 基本用法
|
||
await agent.aiWaitFor("界面上至少有一个耳机的信息");
|
||
|
||
// 使用自定义配置
|
||
await agent.aiWaitFor("购物车图标显示数量为 2", {
|
||
timeoutMs: 30000, // 等待 30 秒
|
||
checkIntervalMs: 5000 // 每 5 秒检查一次
|
||
});
|
||
```
|
||
|
||
:::tip
|
||
考虑到 AI 服务的时间消耗,`.aiWaitFor` 并不是一个特别高效的方法。使用一个普通的 `sleep` 可能是替代 `waitFor` 的另一种方式。
|
||
:::
|
||
|
||
### `agent.runYaml()`
|
||
|
||
执行一个 YAML 格式的自动化脚本。脚本中的 `tasks` 部分会被执行,并返回所有 `.aiQuery` 调用的结果。
|
||
|
||
* 类型
|
||
|
||
```typescript
|
||
function runYaml(yamlScriptContent: string): Promise<{ result: any }>;
|
||
```
|
||
|
||
* 参数:
|
||
* `yamlScriptContent: string` - YAML 格式的脚本内容
|
||
|
||
* 返回值:
|
||
* 返回一个包含 `result` 属性的对象,其中包含所有 `aiQuery` 调用的结果
|
||
|
||
* 示例:
|
||
|
||
```typescript
|
||
const { result } = await agent.runYaml(`
|
||
tasks:
|
||
- name: search weather
|
||
flow:
|
||
- ai: input 'weather today' in input box, click search button
|
||
- sleep: 3000
|
||
|
||
- name: query weather
|
||
flow:
|
||
- aiQuery: "the result shows the weather info, {description: string}"
|
||
`);
|
||
console.log(result);
|
||
```
|
||
|
||
:::tip
|
||
更多关于 YAML 脚本的信息,请参考 [Automate with Scripts in YAML](./automate-with-scripts-in-yaml)。
|
||
:::
|
||
|
||
### `agent.setAIActionContext()`
|
||
|
||
设置在调用 `agent.aiAction()` 时,发送给 AI 模型的背景知识。
|
||
|
||
* 类型
|
||
|
||
```typescript
|
||
function setAIActionContext(actionContext: string): void;
|
||
```
|
||
|
||
* 参数:
|
||
* `actionContext: string` - 要发送给 AI 模型的背景知识。
|
||
|
||
* 示例:
|
||
|
||
```typescript
|
||
await agent.setAIActionContext('如果 “使用cookie” 对话框存在,先关闭它');
|
||
```
|
||
|
||
### `agent.evaluateJavaScript()`
|
||
|
||
这个方法允许你在 web 页面上下文中执行一段 JavaScript 代码,并返回执行结果。
|
||
|
||
* 类型
|
||
|
||
```typescript
|
||
function evaluateJavaScript(script: string): Promise<any>;
|
||
```
|
||
|
||
* 参数:
|
||
* `script: string` - 要执行的 JavaScript 代码。
|
||
|
||
* 返回值:
|
||
* 返回执行结果。
|
||
|
||
* 示例:
|
||
|
||
```typescript
|
||
const result = await agent.evaluateJavaScript('document.title');
|
||
console.log(result);
|
||
```
|
||
|
||
## 属性
|
||
|
||
### `.reportFile`
|
||
|
||
报告文件的路径。
|
||
|
||
## 更多配置
|
||
|
||
### 在运行时设置环境变量
|
||
|
||
你可以通过 `overrideAIConfig` 方法在运行时设置环境变量。
|
||
|
||
```typescript
|
||
import { overrideAIConfig } from '@midscene/web/puppeteer'; // 或其他的 Agent
|
||
|
||
overrideAIConfig({
|
||
OPENAI_BASE_URL: "...",
|
||
OPENAI_API_KEY: "...",
|
||
MIDSCENE_MODEL_NAME: "..."
|
||
});
|
||
```
|
||
|
||
### 打印 AI 性能信息
|
||
|
||
设置 `DEBUG=midscene:ai:profile:stats` 环境变量,你可以看到每次调用 AI 的时间和 token 数量。
|
||
|
||
```bash
|
||
export DEBUG=midscene:ai:profile:stats
|
||
```
|
||
|
||
### 自定义运行产物目录
|
||
|
||
设置 `MIDSCENE_RUN_DIR` 变量,你可以自定义运行产物目录。
|
||
|
||
```bash
|
||
export MIDSCENE_RUN_DIR=midscene_run # 默认值为当前运行目录下的 midscene_run 目录,支持设置为绝对路径或者相对于当前目录的相对路径
|
||
```
|
||
|
||
### 使用 LangSmith
|
||
|
||
LangSmith 是一个用于调试大语言模型的平台。想要集成 LangSmith,请按以下步骤操作:
|
||
|
||
```bash
|
||
# 设置环境变量
|
||
|
||
# 启用调试标志
|
||
export MIDSCENE_LANGSMITH_DEBUG=1
|
||
|
||
# LangSmith 配置
|
||
export LANGSMITH_TRACING_V2=true
|
||
export LANGSMITH_ENDPOINT="https://api.smith.langchain.com"
|
||
export LANGSMITH_API_KEY="your_key_here"
|
||
export LANGSMITH_PROJECT="your_project_name_here"
|
||
```
|
||
|
||
启动 Midscene 后,你应该会看到类似如下的日志:
|
||
|
||
```log
|
||
DEBUGGING MODE: langsmith wrapper enabled
|
||
```
|
||
|