12作者: anerli6 个月前
大家好,我是 Anders 和 Tom。两个月前,我们发布了一篇关于 AI 测试自动化框架的文章,获得了相当大的关注(<a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=43796003">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;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:&#x2F;&#x2F;github.com&#x2F;magnitudedev&#x2F;magnitude">https:&#x2F;&#x2F;github.com&#x2F;magnitudedev&#x2F;magnitude</a>
3作者: ww5206 个月前
在严格的静态类型语言中进行动态分发是困难的。 像下面这样简单的例子: ``` 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>