OpenCode 解剖

本文以OpenCode为例,介绍构成一个AI编码代理的主要组件。

OpenCode 解剖

在过去的几个月里,我们看到很多编码代理被构建出来。它们大多数表现良好,不是因为底层工具很出色,而是因为底层模型非常优秀。随着每个模型迭代,构建一个编码代理变得越来越容易。我并不是说这很容易,但构建一个好产品的门槛比一年前要低。在这篇文章中,我解释了构成编码代理的主要组件。

Opencode 是一个开源的编码代理。它类似于 aider,另一个我将在另一篇文章中评论的编码代理。请注意,opencode有不同风格/分叉版本,我将使用 sst仓库 来解释代码。

1、什么是代理?

在AI和LLM的炒作中,每个人对代理的定义都不同。从技术角度来看,代理是一个程序,它不断调用一个工具增强型LLM,直到满足某个条件。这里的“工具增强型LLM”指的是与一些工具(编辑文件、读取文件、在线获取文档、发送文本等)配对的LLM调用,以增强其能力。

从编程的角度来看,代理是一个 while 循环,它不断调用LLM,直到满足最终条件(例如,传递一段文字,通过语音得到答案“是”,或者只是从模型中获得答案)。LLM通过工具来推进任务,无论是读取文件、编辑文件、获取语义信息还是进行网络搜索。举个具体的例子,当ChatGPT为你搜索互联网时,它会使用网络搜索工具来帮你查找互联网上的信息。编码代理使用读取文件、grep代码库或调用 LSP相关功能(查找符号定义、列出具有特定名称的函数等)的工具。

需要记住的心理模型如下所示。callLLM() 函数是添加工具到LLM调用的地方。

while (true) {
  result = callLLM(message)
  if (isFinalConditionMet(result)) {
    exit()
  }
  message = updateMessage()
}

2、编码代理简述

你的编码代理只是不断向LLM发送消息,直到你的条件得到满足。代理在其消息中发送可用的工具列表和工具的参数。LLM返回的可能是某些文本,或者要求代理调用某些工具。你可以看到一个非常简单的消息序列,说明对于一个非常简单的函数创建,这将如何工作。

OpenAI有一些很好的文档关于工具,重要的是所有工具都在本地执行。

3、模型互操作性

如今有许多模型提供商(OpenAI、Anthropic、xAI、Mistral 等),每个提供商都有自己的方式调用模型和处理工具,使得切换模型变得困难。Opencode 使用了 Vercel 的 AI SDK,该 SDK 抽象了模型提供商,使开发者能够编写与供应商无关的 AI 代理。

模型协调的核心是在 session/index.ts 中通过函数 streamText() 完成的。初始化模型和工具是在 provider/provider.ts 中完成的。

使用这种框架的好处很简单:你可以专注于构建应用程序的核心,而不必担心可以使用的平台或 AI 框架。任何开发 AI 应用的开发者都应该依赖这样的库(TypeScript 的 AI SDKPython 的 Langchain)以避免任何平台依赖。

4、提示质量非常重要

提示大小不再是主要限制,但提示的质量才是真正重要的。编辑或分析一个包含 1000 个文件的单体仓库,并试图只更新其中的 2 个文件,就像在 haystack 中寻找针一样。为了让你的 LLM 找到针,你最好给它非常详细的指令。

这就是为什么提示的质量如此重要。非常重要。

Opencode 的提示 非常长,并提供了大量应遵循的示例。有一些通用指南用于编写良好的提示:

  • 对你想要的内容要极其明确。如果某件事很重要,请用大写字母表示你对特定指示的重视。
  • 继续使用 Markdown 编写你的提示。使用 # 字符的标题来组织层次信息,使用 加粗 来突出显示非常重要的信息。
  • 使用特殊标记来指定示例,如 <example>

一旦你有了一个基本良好的提示,你需要能够用提供必要功能的工具来增强它,以便在 haystack 中找到针。

5、增强 LLM 工具

工具是真正的编码代理“魔法”。没有工具的 LLM 就像布鲁斯·韦恩。有了工具,它就变成了蝙蝠侠,可以拯救开发者免于数小时的调试。

常见的编码代理工具是:grep、读取文件或写入文件。所有 Opencode 的工具位于 packages/opencode/src/tool 中,并在 provider/provider.ts 中添加到 LLM。所有编码代理(包括 Cursor、Claude Code 等)仅依赖于两件事:

  • 提示的质量
  • 工具的质量和准确性

工具的重要部分是通过清晰的描述(如 这个)和参数(如 这些)正确地说明工具的功能。然后这些工具被调用到 LLM,并且程序循环使用工具结果,直到 LLM 完成。

我强调工具的质量对你的编码代理质量有显著贡献。这就是为什么所有流行的编码代理(Cursor)都会索引你的代码库:他们索引符号以轻松地向模型提供准确的数据。类似于获取一行代码的工具(许多 LLM 难以准确找到一行代码)或编辑文件:小的改动会对整体工具质量产生重大影响。这就是为什么拥有良好的评估可以帮助你快速迭代产品质量。

6、让代理进行计划

Opencode 有一个有趣的方法:它向代理提供了一个 TODO 列表工具。初始提示 解释了 TODO 列表的工作方式,以及可用于 读取写入 TODO 列表的工具。

代理不断使用这个 TODO 列表工具来跟踪要做什么以及按什么顺序做。

7、为什么编码代理的运营成本如此之高?

自 Claude Code 发布以来,用户抱怨了成本问题。

Claude Code 的团队甚至在 Latent Space 播客 中讨论过这个问题,解释了 Anthropic 的一些用户每天可能花费数千美元。虽然这可能是一个极端情况,但这表明这是一个合理的担忧。Cursor 可能还没有遇到这个问题,因为使用费用由风险投资资金大幅补贴。

编码代理之所以昂贵,是因为它们的实现方式:我们在提示和上下文中传递了大量的 token。当你的典型 ChatGPT 请求最多包含几百个 token 时,编码代理每条请求会消耗数万个 token。如果你像现在的潮流一样不断修改代码,这将很快变得非常昂贵。

我相信这不是一个真正的问题,我们以前见过这样的故事。风险投资资助 Uber 多年,直到用户上瘾于该平台并准备好支付真实乘车费用。亚马逊补贴了许多产品以建立主导地位,最终达到规模经济。毫无疑问,编码代理会继续存在;当前的经济模式可能必须演变。

8、接下来会发生什么?

在我看来,未来几个月主要有两个重大改进:

  1. 本地运行:像 ollama 这样的项目让在本地运行 LLM 变得非常容易。随着 LLM 越来越优化,CPU/GPU 越来越强大,可以肯定的是,编码代理将在几个月内本地运行。
  2. 更精确的工具:今天,大多数工具只是在代码库中进行 grep,就像你在开始处理新代码库时所做的那样。我可以预见,编码代理将拥有更多的工具来分析代码库,并向提示提供更好的信息。

原文链接:Anatomy of a Coding Agent: Opencode

汇智网翻译整理,转载请标明出处