00:00:00Cloudflow 正在开发一种名为 Artifacts 的东西,它是一个
00:00:05与 Git 兼容且专为代理(agents)设计的分布式文件系统,可以让你以编程方式创建、分支
00:00:10或删除成千上万个代码仓库,无论它们大小如何,可用于诸如并行
00:00:15PR 审查、大型代码库的自动重构以及按会话的代理工作区等场景。
00:00:20但由于它是构建在 Durable Objects 之上的,这意味着你必须使用 JavaScript
00:00:25而无法使用 shell 命令来运行 Git 吗?
00:00:28点击订阅,让我们一探究竟!
00:00:33GitHub 是为人类构建的,而不是为代理构建的,这意味着它们不需要任何社交
00:00:37功能,比如关注者或开始讨论,但代理非常擅长 Git,这已经在它们的
00:00:42训练数据中了。
00:00:43所以,Cloudflare 用 Zig 构建了一个基本的 Git 实现,将其编译为 Wasm 并放入
00:00:49Durable Object 中作为 Git 服务器。
00:00:52同时,客户端本身可以是任何你想要的,比如在 Worker 中使用 isomorphic Git
00:00:57或者使用 Git 协议,甚至使用 HTTP 客户端,这样你就可以为那些不使用 JavaScript 的工具连接到它。
00:01:03那些不使用 JavaScript 的东西。
00:01:05现在遗憾的是,在录制时,我无法访问 Artifacts,因为它处于
00:01:10私有内测阶段,但关于它的文档有很多,这意味着我可以根据这些文档创建一个演示,
00:01:15也许当它发布公共内测版时,你可以检查
00:01:19我的代码是否真的有效。
00:01:20所以我们要做的就是构建一个工具,获取特定代码仓库的一系列任务,
00:01:24并通过多次分支该仓库来并行运行所有这些任务,并在 Durable Object 的云仓库中
00:01:29为每个任务运行在它自己的 artifact 上。
00:01:34让我们看看它是如何工作的。
00:01:35我已经开始按照 Artifacts 的文档进行入门设置,以便在 Workers 中使用,
00:01:39所以我使用了这个命令,这个命令后面的这段文字只是项目的名称,
00:01:44可以是任何名称。
00:01:45所以我按照这些步骤操作,最终得到了这个基础的 Worker 代码。
00:01:49用于 Artifacts 的 Worker 比使用 REST API 性能略好,因为它们
00:01:53减少了往返次数。
00:01:55在此之后,你需要将 Artifacts 绑定添加到你的 wrangle.jsonc 或 toml 文件中,
00:02:00然后重新运行类型定义。
00:02:02这里的文档侧重于创建一个新的仓库,因此它使用了 Artifacts 绑定
00:02:07的 create 方法和一个仓库名称。
00:02:09它创建了名称,从而提供了令牌和远程地址。
00:02:13所以远程地址是 artifact 的位置,令牌或身份验证令牌也是必需的,
00:02:17用来给你提供访问权限。
00:02:18当然,你可以使用 Git 协议,利用远程地址和令牌与你的
00:02:22artifact 进行交互。
00:02:23但我们要做的有所不同。
00:02:25我们不是在 Artifacts Durable Object 中创建一个全新的仓库,而是首先
00:02:29检查是否存在名为 baseline 的仓库。
00:02:31如果不存在,我们要做的就是导入一个 Git 仓库,然后我
00:02:35将它命名为 baseline,然后返回该值。
00:02:39当然,如果你查看 Worker 绑定的 API 文档,你会看到更多
00:02:43可以添加到 import 方法的参数。
00:02:45但之后,当我们返回了现有的仓库,我们就可以对它做一些非常酷的事情了。
00:02:49做一些非常酷的事情。
00:02:50所以这些是我想要对仓库执行的任务,当然我已经硬编码了
00:02:53它们,但这些可以添加到输入或某种 UI 中。
00:02:56在这里,在 Worker 的默认导出中,我有 Anthropic SDK 以及我的
00:03:00baseline 仓库。
00:03:02我将循环遍历所有任务,在这里,我使用这个名称
00:03:06对仓库进行分支。
00:03:07然后我们有这个函数,我稍后会讲解,它在
00:03:10分支出的仓库中运行任务,并让代理进行更改,同时返回代理的摘要。
00:03:15也就是代理说的最后一句话,在每次 for 循环之后,我都会返回此
00:03:19信息。
00:03:20我将包含任务名称、分支名称、远程地址和令牌,
00:03:23以便我们随时可以访问它,看看更改是否良好,以及对已完成工作的
00:03:27摘要。
00:03:28所以目前 Worker 绑定还没有提供拉取、提交和推送的功能。
00:03:33因此在我的代码中,我必须用 isomorphic fetch 来实现,然后使用内存中存储系统
00:03:38来临时存储更改。
00:03:39所以回到代理代码中,我们在内存中创建文件系统,然后我们有一个
00:03:43系统提示词,告诉代理进行相关更改,然后提交他们的
00:03:47代码。
00:03:48因此,我们将使用提供的远程地址和令牌来克隆分支出的仓库。
00:03:51还有令牌。
00:03:52然后我们定义一些工具,比如读取、写入和提交。
00:03:55在这里我们选择模型并给我们的模型一个系统提示词,然后将任务作为用户消息传递。
00:03:59传递任务作为用户消息。
00:04:00其余代码就是你标准的代理循环。
00:04:02如果有工具调用,则停止推理并运行工具调用,在我们的例子中是读取、写入
00:04:07或提交,提交也顺便在提交后推送代码。
00:04:10拥有 artifact 的好处是,所有这些代码都将存在于 Durable Object 中,
00:04:14存储在对象的 SQLite 数据库中,如果 Durable Object 宕机,信息
00:04:20可以在它恢复运行后的任何时候从 SQLite 数据库中检索。
00:04:23然后在下面,我们在工具调用后继续模型的推理,然后返回
00:04:27模型的最新消息。
00:04:29我知道在无法运行代码的情况下,要想象这一切的发生是非常困难的,
00:04:32但希望你能看出 Artifacts 能做什么,以及它们的全部潜力。
00:04:37它们的全部潜力。
00:04:38想象一下,如果你能有一个 UI 来查看在这些 Artifacts 中发生的所有变化,
00:04:42并且你可以与单个代理或单个编排代理进行通信,以对不同的仓库进行更改。
00:04:46对不同的仓库进行更改。
00:04:48说到编排代理,我们可以有一个单一的 Worker,它可以编排
00:04:52所有这些正在发生的更改,并在审核代理检查过代码后将其合并到主仓库中。
00:04:56审核代理检查过代码。
00:04:57我们甚至可以将 Artifacts 与动态 Workers 结合起来,这样代理就可以运行它们更改后的代码,
00:05:02看看它是否能工作。
00:05:03如果不是 JavaScript 代码,那么我们可以使用 Cloudflare 沙箱来运行我们想要的任何语言
00:05:07甚至运行 shell 命令。
00:05:09更不用说还有 Cloudflare 浏览器选项,它运行一个 Puppeteer 浏览器供
00:05:13模型查看,看看它实现的如果是前端更改是否正确。
00:05:18说实话,我对 Artifacts 的可能性思考了很多,尽管
00:05:21我还不能运行它们。
00:05:22但有一件事我注意到了,那就是没有 git diff 命令。
00:05:25它没有在 Worker 绑定 API 或 isomorphic git 中暴露出来。
00:05:30所以也许做 git diff 的唯一方法是通过 Git 协议,或者他们可能会在
00:05:35未来添加它。
00:05:36无论如何,现在如果你想在不使用 Git 协议的情况下做到这一点,我想你可以使用
00:05:40isomorphic git,利用 git log 找到 Git 树,然后遍历树来
00:05:45比较差异。
00:05:46无论如何,我认为这是 Cloudflare 发布的一个非常酷的产品。
00:05:50尽管已经存在像 S3 文件、ZeroFS 和 JuiceFS 这样的其他文件系统工具,
00:05:55但我认为这些选项不兼容 Git,这是一个非常酷的功能
00:05:59而且对代理更友好。
00:06:01说到 S3,如果你曾经想在你的机器上本地运行它,那么看看
00:06:05Josh 的这段视频,他会告诉你究竟该怎么做。