27 分•作者: mdhb•6 个月前
返回首页
最新
2 分•作者: woodruffw•6 个月前
1 分•作者: robmay•6 个月前
1 分•作者: sirodoht•6 个月前
1 分•作者: toomuchtodo•6 个月前
1 分•作者: chrisjj•6 个月前
1 分•作者: speckx•6 个月前
1 分•作者: aracena•6 个月前
1 分•作者: thunderbong•6 个月前
1 分•作者: gmays•6 个月前
1 分•作者: goless•6 个月前
1 分•作者: pranay01•6 个月前
11 分•作者: EvgeniyZh•6 个月前
12 分•作者: anerli•6 个月前
大家好,我是 Anders 和 Tom。两个月前,我们发布了一篇关于 AI 测试自动化框架的文章,获得了相当大的关注(<a href="https://news.ycombinator.com/item?id=43796003">https://news.ycombinator.com/item?id=43796003</a>)。
我们收到了社区的一些很棒的反馈,其中最积极的反馈是关于我们在浏览器代理中使用的“视觉优先”方法。然而,许多人希望在测试领域之外使用底层的代理。因此,今天,我们发布了功能齐全的 AI 浏览器自动化框架。
您可以使用它来自动化 Web 上的任务,在没有 API 的情况下集成应用程序,提取数据,测试您的 Web 应用程序,或者将其作为您自己的浏览器代理的构建块。
传统上,浏览器自动化只能通过 DOM 完成,尽管这并不是人类使用浏览器的方式。大多数浏览器代理仍然停留在这种范式中。通过“视觉优先”方法,我们避免依赖不稳定的 DOM 导航,并在各种网站中发现的复杂交互上表现更好,例如:
* 拖放交互
* 数据可视化、图表和表格
* 具有嵌套 iframe 的旧版应用程序
* Canvas 和 WebGL 密集型网站(如设计工具或照片编辑)
* 流式传输到浏览器的远程桌面
为了与浏览器进行精确的交互,我们使用视觉上基于的模型,根据像素坐标执行精确的操作。Magnitude 使用的模型必须足够智能,能够规划操作,并且能够执行它们。很少有模型既智能又具有视觉基础。我们强烈推荐 Claude Sonnet 4 以获得最佳性能,但如果您更喜欢开源,我们也支持 Qwen-2.5-VL 72B。
大多数浏览器代理从未投入生产。这是因为 (1) 上面提到的不稳定的 DOM 导航,以及 (2) 大多数浏览器代理缺乏控制。主导范式是您给代理一个高级任务 + 工具,并希望获得最好的结果。对于需要可靠和具体的生产自动化,这很快就会崩溃。使用 Magnitude,您可以通过我们的 `act()` 和 `extract()` 语法对代理进行细粒度的控制,并可以根据需要将其与您自己的代码混合使用。您还可以完全控制操作和代理级别的提示。
```ts
// Magnitude 可以处理高级任务
await agent.act('创建问题', {
// 可选地传递代理将酌情使用的数据
data: {
title: '使用 Magnitude',
description: '运行 "npx create-magnitude-app" 并按照说明操作',
},
});
// 它还可以处理低级操作
await agent.act('将 "使用 Magnitude" 拖到进行中列的顶部');
// 根据与提供的 zod 模式匹配的 DOM 内容智能地提取数据
const tasks = await agent.extract(
'列出进行中的问题',
z.array(
z.object({
title: z.string(),
description: z.string(),
// 代理可以提取现有数据或新见解
difficulty: z.number().describe('评估难度,范围 1-5'),
}),
),
);
```
我们有一个设置脚本,可以轻松地从示例开始,只需运行 "npx create-magnitude-app"。我们很乐意听取您的意见!
代码库:<a href="https://github.com/magnitudedev/magnitude">https://github.com/magnitudedev/magnitude</a>
3 分•作者: ww520•6 个月前
在严格的静态类型语言中进行动态分发是困难的。 像下面这样简单的例子:
```
map.put("add", add);
map.put("hello", hello);
fn add(a: i32, b: i32) i32 { return a + b; }
fn hello() []const u8 { return "Hello World"; }
```
是不可能实现的,因为map的键/值类型需要相同,但所有函数类型都不同。 动态地调用具有不同参数数量、不同参数类型和不同返回类型的函数是困难的。
其他语言要么使用动态类型、运行时反射、宏,或者传入一个大的泛型参数,让函数自己去处理。
在ZigJR中,我使用Zig的编译时特性来做编译时反射,以确定函数的参数类型、返回类型和返回错误。 我将它们打包成一个特定的调用对象,并使用接口模式来生成一个类型统一的对象,放入map中。 这并不容易,但可以做到。[1]
[1] <a href="https://github.com/williamw520/zigjr/blob/master/src/rpc/json_call.zig">https://github.com/williamw520/zigjr/blob/master/src/rpc/jso...</a>
1 分•作者: amichail•6 个月前
1 分•作者: eionelk8s•6 个月前
1 分•作者: chabad360•6 个月前
1 分•作者: throwaway913242•6 个月前
2 分•作者: rbanffy•6 个月前