深度分析Agent反复执行循环配合工具调用的有效性,通过实验验证在复杂任务中的性能。高讨论热度,具有架构指导价值。
我和我的同事们在过去几个月里一直在开发一个名叫 Sketch 的 AI 编程助手。最让我惊讶的是,使用带有工具的 LLM 的主循环竟然简单到令人震惊的地步:
def loop(llm):
msg = user_input()
while True:
output, tool_calls = llm(msg)
print("Agent: ", output)
if tool_calls:
msg = [ handle_tool_call(tc) for tc in tool_calls ]
else:
msg = user_input()
要让上面的代码运行需要一些额外的设置(这是完整脚本),但核心思想就是上面这 9 行。这里 llm() 是一个函数,它将系统提示、到目前为止的对话和下一条消息发送到 LLM API。
工具使用是"LLM 返回与某个模式相对应的输出"的专业说法,在完整脚本中,我们在系统提示和工具描述提示中告诉 LLM 它可以访问 bash。
仅凭这一个用处广泛的工具,当前的模型(我们广泛使用 Claude 3.7 Sonnet)就能解决许多问题,其中有些甚至可以"一步到位"地解决。过去我需要查阅晦涩的 git 操作然后复制粘贴,现在我只需要请 Sketch 来做。过去我需要手动处理 git 合并,现在我让 Sketch 先尝试一下。过去我改一个类型后需要逐个处理类型检查器的报错(或者说实话吧,用 perl -pie 的疯狂方式),现在我用 Sketch 来试试。在适当的提示下,agent 循环可以是持久的。如果你没有安装某个工具,它会安装它。如果你的 grep 有不同的命令行选项,它会适应。(它也可能很令人恼火!"哦,这个测试没有通过……我们就跳过它吧,"它有时会令人疯狂地说。)
对于许多工作流,agent 工具是专门化的。Sketch 的工具库不只是 bash,因为我们发现少数几个额外的工具可以提高质量、加快迭代速度并促进更好的开发者工作流。让 LLM 能够正确编辑文本的工具出人意料地棘手。看到 LLM 在 sed 单行命令上的苦恼再次证实了可视化编辑器(相对于行编辑器)是了不起的。
我毫不怀疑 agent 循环将被融入更多日常自动化琐事中,这些琐事在历史上对通用工具来说过于具体,对传统自动化来说太晦涩和不稳定。我一直在想我花了多少时间将堆栈跟踪与 git 提交进行关联,以及 LLM 在进行初步处理时有多擅长。我们将在我们的 bin/ 目录中看到更多自定义的、临时的、一次性的 LLM agent 循环。拿上你最喜欢的 bearer token,试试看吧。
也发布在 philz.dev/blog/agent-loop/。