1 分•作者: thunderbong•9 个月前
返回首页
最新
1 分•作者: gmays•9 个月前
1 分•作者: goless•9 个月前
1 分•作者: pranay01•9 个月前
11 分•作者: EvgeniyZh•9 个月前
12 分•作者: anerli•9 个月前
大家好,我是 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•9 个月前
在严格的静态类型语言中进行动态分发是困难的。 像下面这样简单的例子:
```
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•9 个月前
1 分•作者: eionelk8s•9 个月前
1 分•作者: chabad360•9 个月前
1 分•作者: throwaway913242•9 个月前
2 分•作者: rbanffy•9 个月前
1 分•作者: amberjcjj•9 个月前
2 分•作者: alvis•9 个月前
1 分•作者: delduca•9 个月前
1 分•作者: igh•9 个月前
1 分•作者: max_•9 个月前
2 分•作者: oksteven•9 个月前
同时与多个 AI 模型聊天,并比较结果以选择最佳答案。这可以帮助您进行研究,因为不同的 AI 模型可能会给出不同的答案,而其中一些答案可能更好。
10 分•作者: PaulHoule•9 个月前
3 分•作者: jbryu•9 个月前
我正在一台 Hetzner CCX23 x86 云服务器(4 个 vCPU,16GB 内存,80GB 磁盘)上托管一个回合制多人浏览器游戏。后端使用 Node.js 和 Socket.IO 构建,并通过 Docker Swarm 运行。我还使用 Traefik 进行负载均衡。
匹配机制采用轮询分片方法:每个房间始终由同一个后端实例处理,这让我可以将游戏状态保存在内存中,并进行水平扩展,而无需使用 Redis。
问题如下:
在大约 500 个并发玩家分布在约 60 个房间(每个房间最多 8 个玩家)时,我看到 CPU 使用率较低,但事件循环延迟较高。我的游戏中的一个功能是在玩家回合期间打字——每个受限的按键都会实时广播给其他玩家。如果我移除这个逻辑,我可以处理 1000+ 玩家而没有问题。
在我的单服务器上扩展后端实例并没有帮助。我期望每个后端实例的负载更少会有所帮助,但我仍然在 500 个玩家左右达到相同的限制。这向我表明,瓶颈不在 CPU 或应用程序逻辑,而是在堆栈中更深层的东西。但我不知道是什么。
500 个玩家时的一些服务器指标:
* CPU:每个核心 25%(根据 htop)
* PPS:大约 3000 入 / 大约 3000 出
* 带宽:大约 100KBps 入 / 大约 800KBps 出
对于我的单服务器设置来说,500 个并发玩家可能只是一个现实的上限,还是配置有问题?我知道使用新服务器进行扩展应该可以解决这个问题,但我想先在网上咨询一下,看看我是否遗漏了什么。我刚接触多人游戏架构,所以非常感谢任何见解。