跳到主要内容

CodeAct:为什么可执行的 Python 代码能让 LLM 智能体准确率提升 20%

· 阅读需 6 分钟
Mike Thrift
Mike Thrift
Marketing Manager

在阅读了上周关于“无法自我纠偏”的论文后,一个自然而然的问题出现了:如果大语言模型(LLM)不能可靠地审计自己的输出,那么什么样的操作格式能让智能体最有机会自动发现并从错误中恢复?CodeAct 由 Xingyao Wang 等人发表并被 ICML 2024 接收,文章认为答案是 Python 代码 —— 并不是因为代码有什么魔力,而是因为 Python 解释器提供了确定性的外部反馈,而这正是自我纠偏文献中指出 LLM 迫切需要的。

论文解读

2026-04-29-codeact-executable-code-actions-llm-agents

Xingyao Wang, Yangyi Chen, Lifan Yuan, Yizhe Zhang, Yunzhu Li, Hao Peng 和 Heng Ji 的论文《Executable Code Actions Elicit Better LLM Agents》(arXiv:2402.01030)提出用可执行的 Python 代码替换工具调用智能体中常见的 JSON 和文本操作格式。核心思想是,相比自然语言指令或结构化的 JSON,代码是智能体操作更好的通用语言,因为代码已经编码了控制流、数据依赖和多步骤组合 —— 而且 LLM 已经经过了大量的代码预训练。

论文做出了三项贡献:(1) 关于代码作为统一操作空间的理论阐述;(2) M3ToolEval,一个包含 82 个由人类策划的任务的新基准测试,这些任务需要多工具组合;(3) CodeActAgent,一个在 CodeActInstruct 上微调的 7B 模型。CodeActInstruct 是一个包含 7,139 条基于代码的多轮交互轨迹的数据集,涵盖信息检索、软件包、外部存储器和机器人规划。

核心观点

  • 在 M3ToolEval 上,使用 CodeAct 的 GPT-4 成功率达到 74.4%,而使用文本操作的成功率为 53.7% —— 在要求最高的多工具设定下,绝对提升了约 20 个百分点。
  • 在相同任务上,CodeAct 所需的交互轮数比基于 JSON 的智能体减少了约 30%。更少的轮数至关重要:每一次额外的往返都是错误传播的又一次机会。
  • Python 解释器充当了自动、零成本的错误信号。错误的中间计算会立即引发异常;智能体能看到回溯信息(traceback),无需单独的评审步骤即可进行修正。
  • 开源模型比闭源模型受益更多。CodeActAgent (Mistral 7B) 在 M3ToolEval 上达到 12.2%,而此前最强的开源智能体 (使用文本操作的 Lemur-70B) 仅为 3.7%。这种杠杆作用更高,是因为 Python 在预训练数据中非常丰富,而专门的 JSON 工具调用格式则不然。
  • CodeActInstruct 在四个专门挑选的领域进行训练以进行压力测试:信息检索、软件包调用、外部存储器操作和机器人规划。这些都是多步骤、依赖状态的任务 —— 正是 JSON 智能体容易出错的失效模式。

哪些结论站得住脚 —— 哪些不能

M3ToolEval 上 20% 的提升是真实的,但 M3ToolEval 只有 82 个任务。这是一个很小的样本,且论文没有报告置信区间。该基准测试也是由提出该方法的同一团队策划的,这在领域内是标准做法,但值得留意。在将 74.4% 视为可靠数据之前,我希望看到这在完全独立的基准测试上得到复现。

关于效率的说法(轮数减少 30%)是合理的,但它混淆了两件事。更少的轮数可能意味着智能体在每一步都更准确,也可能意味着失败得更早。论文并没有清晰地分解这一点。

开源和闭源模型之间公认的差距很大,CodeAct 并没有消除这一差距。12.2% 的 CodeActAgent (Mistral 7B) 远好于 3.7% 的 Lemur-70B,但使用 CodeAct 的 GPT-4 达到了 74.4%。格式虽然有帮助,但无法弥补 60 个百分点的能力差距。任何计划部署开源 Beancount 智能体的人都应该仔细审视这个数字。

沙箱问题只用了一个段落。在金融背景下执行任意代码不是一个无关紧要的边缘情况 —— 它是核心安全问题。论文并没有讨论当智能体生成的代码删除文件、进行网络调用或导入意外的库时会发生什么。对于生产环境的会计智能体来说,沙箱设计至少与操作格式同样重要。

为什么这对金融 AI 很重要

Beancount 的回写问题本质上就是 CodeAct 为之设计的挑战:智能体需要以特定顺序组合多个操作(读取当前余额、验证交易、写入新的过账、验证平衡方程),且数据在步骤之间流动。JSON 工具调用在处理这个问题时表现不佳,因为每次调用都是孤立的。而 Python 处理起来则非常自然。

更具体地说:CodeAct 风格的 Beancount 智能体可以将整个对账工作流表达为一个 Python 脚本 —— 通过库查询账本、计算差异、提议新条目,并在提交任何内容之前对结果运行 bean-check。解释器能捕获明显的错误;LLM 只需要处理语义错误。这比让 LLM 验证自己的 JSON 更有利于分工。

安全考量则指向了另一个方向。一个能在金融账本上不受限制执行 Python 的智能体是一个巨大的攻击面。正确的设计几乎肯定是一个受到严格限制的沙箱 —— 在指定临时目录之外禁止写入文件系统、禁止网络访问、禁止 shell 命令 —— 并结合在触碰任何文件之前的强制性 bean-check 关卡。CodeAct 提供了操作格式,但你仍然需要构建那个“牢笼”。

延伸阅读

  • OpenHands (原 OpenDevin) —— 由同一研究小组基于 CodeAct 构建的生产级智能体系统;展示了沙箱和执行环境的具体实现方式 (arXiv:2407.16741)
  • ToolBench / ToolLLM —— 使用 REST API 而非 Python 的工具调用智能体的基准测试和训练数据;与 CodeAct 的代码优先方法形成有用对比 (arXiv:2307.16789)
  • SWE-bench —— 在真实的 GitHub issue 上评估智能体,这需要多步骤的代码执行和文件编辑;这是目前最接近 Beancount 回写智能体所需通过的基准测试 (arXiv:2310.06770)