自主性:非技术用户的编码代理 AI Engineer 2025-12-22

自主性:非技术用户的编码代理

在Replit,我们正在为非技术用户构建一个编码代理。这是一个非常特殊的挑战,我认为与这个房间里的许多人面临的挑战非常不同。

今天,我想谈谈为什么自主性已经成为我们追求的目标。大家都知道,自从去年9月我们发布了Rapid Agent的第一个版本以来,我们一直致力于此。

让我们从这张非常有趣的图开始。我的点击器可能有效,现在有效。 我相信你们都见过它。Zixs几周前发布了半自动值,某种程度上为我们澄清了代理建设者的格局。

一方面,你有低延迟的交互,这真的允许你留在循环中,你知道,这样你就可以深入工作,专注于手头的编码任务,但你需要成为专家。

你需要确切地知道模型需要什么,你需要快速理解如果你想接受或拒绝变化。然后,几个月来,我们中的许多人,包括Replit,都在某种程度上生活在这种价值中。

在这种情况下,代理不够自主,无法真正委托任务并返回查看结果,但同时它的运行时间不长,无法保持在区域内,不需要保持在循环中。幸运的是,我们成功地做到了这一点。

现在,我今天要讨论的内容是,今天的希望不会停止邀请我参加这个活动,即除了这个图之外,还有一个额外的维度,像第三个维度一样,大家都知道它还没有被涵盖。

也就是说,我们如何为非技术用户构建自主代理。所以,我今天要讨论的内容是,有两种类型的自主性。

一种是更受监督的。想象一下特斯拉FSD的例子。当你坐在特斯拉车里时,你仍然需要拥有驾驶执照。

你将坐在方向盘前。也许99%的时间你不会使用它,但是你在那里,以便处理意外情况。

同样,我们今天拥有的许多编码代理需要你具备技术能力才能正确使用它们。

我们在Replit和其他公司都专注于为自主编码代理提供顺畅的体验。所以,你被期望坐在后排。

你甚至无法接触到方向盘。我希望你根本不需要驾驶执照。为什么这很重要?

因为我们希望赋予每个知识工作者创造软件的能力。

我无法期望知识工作者了解代理应该做出的技术决策。我们应该将复杂性完全从他们身上转移。

当然,我们才刚刚开始。大家都知道,从不到一分钟的反馈循环、持续监督和讨论补全及协助开始,然后我们慢慢提升自主性水平。

我们有了基于React的第一个版本的代理。所以,我们通过在LMS上添加非常简单的范式,构思了自主性。然后,人工智能提供商明白工具调用非常重要,并投入大量精力来解决这个问题。

所以,我们构建了具有原生工具调用的下一个版本的代理。然后,我认为有第三代代理,我称之为自主代理,那是当我们开始突破一小时自主的壁垒时。

基本上,代理能够运行长期任务并保持连贯性。碰巧那些是我们去年发布的Rapid Agent版本。

所以,B3是几个月前我们发布的版本,它确实展示了这些特性。那么,今天的问题是,我们能否真正构建完全自主的代理,我们如何实现?

所以,我今天将尝试重新定义自主性的定义。我认为我们经常将自主性与在长时间内不间断工作的概念混淆,通常作为用户,你会失去控制。

实际上,我希望代理具备的自主性可以被非常具体地限定,什么是我的意思呢?尤其是通过Rapid Agent 3,我们实现的是,我们确保我们的代理做出神圣的技术决策。

当然,这可能会导致用户交互之间的间隔非常长。在某些情况下,代理再次运行数小时。

但这种情况只在任务范围非常广泛时才会发生。结果表明,在现实中,如果任务范围足够窄,你可以拥有一个非常自主的代理,并且仍然很快。

所以,我们可以通过这种方式实现用户在关心的问题上仍然保持控制,而用户关心的是他们正在构建的东西。

尤其是,我们的用户,知识工作者,他们不关心构建过程。他们只想看到目标实现。

所以,自主性不应该与长时间运行混淆。同样,它不应该成为一种虚荣指标。

大家都知道,我们中的很多人都把它当作荣誉徽章来讨论。但我认为,在如何构建更强大、更稳定的未来代理方面,我们需要改变我们在脑海中衡量的指标。

所以,从这个角度来看,任务具有自然的复杂性。基本上,我们关心的是它们具有最小的不可减少的工作量。

代理所做的是,它们总是经历计划、实施和测试的循环。当然,要使这发生并使其正确工作。

你希望这项工作在很长的查询轨迹上进行。所以,我们的目标是最大化代理的可减少运行时。

我所说的可减少,是指用户无需做出任何技术决策,代理可以在完全自主的情况下完成任务。

这对于我们来说尤为重要,因为我不信任我们的用户能够做出技术决策。所以,他们在软件创建过程中需要一个适当的技术合作伙伴。

我希望在软件创建过程中抽象出尽可能多的复杂性。并且,最后但同样重要的是,我希望用户在创建过程中感到控制。

他们在创建过程中不会因为需要考虑代理做出的技术决策而感到压力。

那么,自主性的支柱是什么?我们如何实现这一目标?我认为有三个非常重要的支柱需要考虑。

第一个是当然是前沿模型的能力,比如我们在主代理循环中注入的基准智商。

我将把这留给读者和房间里的其他人去思考。我很高兴看到你们中的很多人正在构建令人惊叹的模型,我们在Rapid上一直在使用这些模型。

所以,这是第一个支柱。第二个支柱是验证。非常重要的是,我们在代理采取的每一步都测试本地的正确性。

原因是显而易见的。如果你在一个非常不稳定的基础上构建,最终,城堡将会倒塌。

所以,我们将验证纳入循环,以确保你在某种意义上拥有99.99%的可靠性,其中代理会做出无法避免的错误,如果你不对其施加控制。

最后一个,但同样重要的是,你在舞台上甚至更早听到了关于上下文管理的重要性。

一方面,你希望拥有一个能够全局一致的代理。所以,它与用户的意图、用户的期望相一致。

但同时,它也需要能够管理高层次的目标和代理正在执行的单一任务。我认为我们在过去几个月里在上下文管理方面取得了巨大的进步。

但我也很兴奋地看到,我们作为一个领域,将会取得怎样的进展。

让我们从我们在Rapid积极开展工作的第一个支柱开始,即验证。

那么,为什么我们关注这一点呢?在过去的一年里,我们意识到了一些事情,我想你们中的每个人都经历过这些。

没有测试,代理会构建很多画皮门。在我们的例子中,画皮门非常明显,因为我们创建了很多Web应用程序。

所以,当你最终尝试点击一个按钮时,处理程序没有被查找,或者我们显示的一些数据实际上是模拟数据,而不来自数据库。

但通常,这种现象遍及你构建的每种类型的组件,无论是前端还是后端。很多组件实际上并没有被代理完全实现。

所以,我们在内部运行了一些评估。我们发现超过30%的个别功能被破坏。

当然,这是代理第一次做饭的时候。 这也意味着,几乎每个应用程序,至少有一个破碎的功能或画皮门。它们很难被发现。

原因是用户不会花时间测试每一个按钮、每一个字段。

这可能也是为什么很多用户,尤其是非技术用户,仍然不能非常信任代码代理。他们在发现有画皮门时感到震惊。

那么,我们如何解决这个问题?

从根本上说,我们需要一个必须从环境中收集所有所需反馈的代理。

这说起来容易做起来难。再次,非技术用户不仅不能做出技术决策,也不能提供技术反馈。

他们充其量只能进行质量保证测试。他们可以遍历UI,交互式地与应用程序交互。

我相信你们在生活中都试过这样做。这非常枯燥,带来了非常糟糕的用户体验。

尽管我们在去年发布的第一个代理版本依赖于此,但用户很快就明白了,他们不想花时间进行测试。

所以,我们不得不找到一个完全正交的解决方案,即自主测试,它解决了几个不同的问题。

第一个是它打破了反馈瓶颈。即使我们要求用户提供反馈,我们也得不到足够的反馈。

现在,我们不必再等待人类反馈了。我们有一种方法可以自主地从应用程序中获取尽可能多的信息。

我们还希望防止小错误的积累。正如我之前所说,我们不希望代理在构建过程中积累复合错误。

最后但同样重要的是,我们必须克服前沿模型的惰性。所以,我们需要验证模型告诉我们任务已经完成时,实际上确实完成了, 结果不是被润色过的。

代码验证的范围很广,我想我们都从最左边开始了。大家都知道基本的代码分析,语言服务提供者。

我们一直在执行代码,自从我们拥有基本上能够进行调试的LMS以来。然后,我们慢慢开始转向右侧。

所以,生成单元测试并运行它们有局限性。仅限于功能正确性。单元测试不能很好地进行适当的集成测试。

我们也开始进行API测试,但仅限于API代码。所以,你可以测试应用程序的端点,但不能真正测试Web应用程序的功能和外观。

为此,在过去几个月里,H和其他公司正在投入大量精力,创建基于浏览器的自主测试。

假设我们正在构建的应用程序是一个Web应用程序,有两大类:计算机使用,它与用户界面是一一对应的映射。

所以,模型直接与应用程序交互,需要截图,相对昂贵且速度慢。

我相信你们自己都测试过。中间有一个很好的方法,就是浏览器使用,我们模拟用户界面。

然后,您可以通过浏览器与Web应用程序交互,依赖于通过抽象访问DOM。

那么,我们如何实现这一点?

我们要做的就是生成易于测试的应用程序,并将之前展示的所有内容合并在一起。

所以,我们允许我们的测试代理与应用程序交互,并在必要时截取屏幕截图。

所以,我们拥有完全回到计算机使用的能力。但大多数时候,我们与应用程序进行程序化交互。

所以,我们与数据库交互,读取日志,进行API调用,实际上点击应用程序,获取所有需要的信息。

通过把所有这些放在一起,我们收集足够的反馈,允许我们的代理取得进展,并修复它遇到的所有画皮门。

这是一个简短的技术深入探讨,关于我们如何实现这一点。我相信你们都见过基于工具的浏览器使用。

那里有很棒的库,首先想到的是斯坦。

这个想法是你有一个具有几个非常通用工具的代理。所以,代理可以创建新选项卡,可以点击,可以填写表格等。

限制在于很难列出您可能与浏览器交互的所有不同类型。

测试的问题与我之前提到的特斯拉类比非常相似。

也许这组可用的工具足以满足99%的交互类型。但总是有一些特殊情况,用户与Web应用程序的交互很难映射到这些工具调用。

所以,我们在Rapid的做法是,我们直接编写Playwright代码,而Playwright代码首先对大型语言模型来说非常易于管理。

大型语言模型非常擅长编写Playwright代码。我们从开始这个项目以来积累的经验也是非常强大和富有表现力的。

所以,从某种意义上说,它比左边的工具测试更强大、更具表现力。

最后但同样重要的是,创建Playwright代码有其优点。因为您可以重用这些测试。

一旦您用脚本编写测试,您就可以无限次运行它。所以,从某种意义上说,您创建测试时,也会创建一套回归测试套件,您可以在未来继续运行。

所有这些技巧,帮助我们创建比计算机使用便宜一倍、速度快一倍的东西。

而延迟的重要性我们稍后会再谈。

第二个我要谈到的支柱是上下文管理。

我会很快地讲这个问题,因为我想今天会有人做很多相关的演讲。

高层次的信息是, 长上下文模型对于处理奇异和长轨迹的工作并不需要。

从经验来看,我们发现即使是最雄心勃勃的任务,也可以在200,000个代币内完成。

所以,我们仍然不处于需要使用拥有1,000万或1亿个上下文窗口的模型来实际运行自主代理的世界。

我们通过正确学习如何进行上下文管理来实现这一点。

有几种不同的方法可以维护状态,而不需要将所有状态塞入上下文窗口。

例如,您可以使用代码库本身来维护状态。

您可以边创建新代码,边写文档。您也可以包含计划描述和代理正在工作的不同任务列表。

您可以将它们保存在文件系统中。所以,即使在那里,也有许多方法可以卸载内存。

最后但同样重要的是,我认为Anthropic一直在积极倡导这一点,您可以直接将记忆转储到文件系统中。

然后,确保您的代理在它们对您的工作变得相关时决定何时将它们写回。

所以,在过去几个月里,我们已经看到了很多公告。随便挑一个,比如来自Entropic的Cloud Sonet 4.7。

我希望4.5能够运行专注任务超过30小时。我们已经从OpenAI那里看到了类似的数学问题结果。

所以,我认为我们基本上打破了长时间运行并能够处理连续任务的壁垒。

我想说,使这一切发生的关键因素是,作为代理构建者,模型在子代理编排方面变得非常擅长。

子代理基本上通过在核心循环中被调用来工作。

所以,这是一个全新的开始。从空白状态开始。

作为代理构建者,您决定在子代理启动时要注入什么上下文。

这是一个与大家编写软件类似的概念,即关注点分离。

所以,你决定你的子引擎将要处理什么。你给它尽可能少的上下文。

你让它运行到完成。你只获得输出、结果。

你将它们放回主循环中,然后继续运行。

当然,它显著提高了每压缩的内存数量。

我直接从Replit的生产代理中带来了这个图。

当我们启动新的子视觉编排器时,代理在y轴上,您可以看到每压缩的内存数量。

所以,我们从大约35增加到最近的45到50。

所以,在压缩上下文方面有了很大的改进。

因为我们可以卸载很多上下文污染,通过使用子代理。

我要举个例子,这对我们来说有什么不同。

您知道,我展示的内容更多的是某种成本优化。

你在压缩得更少。你也有关注点的分离,这肯定会让你的代理更智能。

在测试方面,与子引擎合作几乎对我们来说是必不可少的。

而且我们开始研究自动化测试,甚至在子代理编排方面取得很大进展之前。

而我们发现的,是当然又是,就像我之前说的那样。

它使事情变得更容易、更好、更便宜。

但当你允许主循环不仅创建代码,还可以执行浏览器操作,将浏览器操作的观察结果放回主循环时。

你往往会用主循环看到的东西混淆编织循环,因为此时有太多信息。

所以,为了实现这一点,我们不仅要构建我之前向你们展示的整个Playwright框架。

我们还必须将我们的整个架构转移到子代理中。

所以,在这一点上,你可以非常清楚地看到这里关注点分离的原因。

主代理循环正在运行。

我们在某个时候决定是时候验证代理的输出是否正确。

我们在子代理内完成所有这些。

然后我们清理子代理的上下文窗口。

我们只是将最后的观察结果返回给代理循环,然后继续运行。

所以,如果你今天在使用子代理时遇到问题,这是你想要查看的原因。

所以,我认为我们已经涵盖了如何随着时间的推移创建越来越强大的自主代理的高层次概述。

而且我只看到我们作为一个领域会变得更加精通。

除了有一个额外的因素将带来不同,那就是并行性。

我认为并行性很重要,不是因为它会使代理更强大,而是因为它会使用户体验更加激动人心。

当然,拥有一个可以自主运行很长时间的代理很棒。

但同时,它也带来了使用户体验不那么刺激的代价。

你不再处于区域内。你要做的是写一个非常长的提示。

它被翻译成任务列表,然后你去和同事吃午饭。

然后你回来,希望代理已经完成了。

那不是大多数高效人士希望在生活中拥有的体验。

你知道,你希望在最短的时间内看到尽可能多的工作完成。

所以,我们作为一个领域,目前所做的是创建并行代理。

这是一个非常常见的权衡,顺便说一下,不仅适用于代理,也适用于整个计算领域。

对于并行代理,你要做的是,你用多个上下文窗口收集相同的上下文。

所以,每个并行代理可能共享80%的上下文。

当然,你只需通过并行运行代理来增加计算工作量。

还有另一个成本,对你们中的很多人来说是无形的,因为你们都是优秀的软件开发人员。

但是,当您在结束时获得多个并行代理的输出时,通常需要解决合并冲突。

所以,作为提醒,我的用户甚至不知道什么是合并冲突。

这是我自己要解决的事情。

所以,我们思考并行代理的当前方式并不适用于Replit。

但与此同时,我仍然非常希望实现这一点。

有许多有趣的功能可以通过并行性实现,而不仅仅是可以完成更多工作。

有时,您希望测试在代理创建代码时并行运行。

测试无论优化得多好,仍然非常缓慢。

如果代理只花时间测试,用户就不会与您的应用程序互动了。

同时,也很棒的是,有一个同步过程在代理运行时运行。

因为您可以将有用信息注入主核心循环。

最后但同样重要的是,这是一种常见的技巧,通过采样多个轨迹来提高性能,如果您有足够的预算。

很多好处都来自并行代理。

但我们今天实施它们的方式,我基本上称之为用户拥有一个编排器。

关键的区别在于,任务是由用户确定并由用户调度在不同的线程中。

所以有一定的手动过程,甚至任务分解在某种意义上是在你的脑海中完成的。

当你获得所有结果时,你需要经历合并冲突的问题。

而很多时候,这并不简单。

所以,我们今天正在为我们的下一个代理版本做的事情,是让核心循环成为编排器。

所以,关键的区别在于,子任务不是由用户确定,而是由核心循环确定。

并且并行性基本上是在飞行中做出的决定。

代理代表用户进行任务分解。

这带来了几个优势。

首先,对于用户来说,没有认知负担去理解他们应该如何分解任务。

同时,也有方法可以创建任务,以某种方式缓解合并冲突的问题。

我并不是说我们能够将问题减少到 100%,肯定会有一些特殊情况。

但有很多不同的技术已知在软件工程中,可以尝试让多个子代理不要相互冲突。

所以,核心循环作为编排器,将是我们接下来的主要赌注。

如果你们对这些话题感兴趣,我总是欢迎人才。

谢谢。 [Music]

📌 文中提及的人物和组织