代码执行作为动作空间,比结构化 JSON 调用更灵活,也更容易自我修正

问题:JSON 工具调用的限制

主流的 Agent 框架(LangChain、AutoGPT 等)通常采用这样的动作模式:

{
  "action": "search_web",
  "parameters": {
    "query": "Python asyncio 教程",
    "num_results": 5
  }
}

这种结构化 JSON 调用有几个限制:

  1. 动作空间固定:只能调用预先定义好的工具,遇到新需求无法处理
  2. 无法在单次 turn 内组合多步逻辑:每次调用是独立的
  3. 出错后难以定向修复:调用失败只能重试,无法根据错误信息调整策略

CodeAct(Wang et al., 2024)的核心主张是:把 Python 解释器变成 Agent 的动作执行器


CodeAct 的核心设计

统一动作空间

CodeAct 让 Agent 输出可直接执行的 Python 代码:

# Agent 的一次输出
import requests
from bs4 import BeautifulSoup

response = requests.get("https://docs.python.org/asyncio")
soup = BeautifulSoup(response.text, 'html.parser')

sections = soup.find_all('section', limit=3)
for s in sections:
    print(s.get_text()[:200])

这段代码可以调用外部库、做中间计算、根据执行结果决定下一步,也可以在出错时通过 traceback 进行调试。这些是 JSON 调用难以做到的。

多轮交互中的状态保持

CodeAct 运行在一个持久的 Python 解释器会话中,变量、函数、导入的库跨轮次保持:

Turn 1:
  Agent 代码:df = pd.read_csv('data.csv')
  执行结果:DataFrame 加载成功,1000 行 x 12 列

Turn 2:
  Agent 代码:df[df['score'] > 0.8].groupby('category').size()
  执行结果:各类别高分条目统计

Turn 3:
  Agent 代码:# df 仍然在内存中,直接继续处理
  top_cats = df.groupby('category')['score'].mean().nlargest(3)
  print(top_cats.to_markdown())

这相当于给 Agent 一个持久化的工作空间,而不是每次从零开始。


与 JSON 工具调用的对比

论文对 CodeAct 和标准工具调用进行了对比:

任务类型JSON 工具调用CodeAct
单步工具调用相当相当
多步推理链较差较好
需要中间计算无法完成可处理
工具调用出错后修复困难可读 traceback 修复
需要临时组合工具无法完成可临时写函数

在需要"数学计算 + 网络请求 + 数据处理"混合的任务中,CodeAct 的成功率比 JSON 调用高出约 20 个百分点。


代码作为动作空间的几个优势

表达力:Python 是图灵完备的,可以表达任何可计算任务。JSON 工具调用只能表达预先定义的操作集合。

可组合性:代码支持函数调用、循环、条件分支,可以在内部调用多个工具并按需组合,不必等待 LLM 多轮交互。

自修正性:代码执行失败时,Python 给出精确的错误类型和行号。看到 TypeError: unsupported operand type(s) for +: 'int' and 'str' 之后,修复成功率高于看到模糊的"工具调用失败"。

可读性:人类可以直接审查 Agent 生成的代码,理解它在做什么,这对需要人工审核的场景有实际价值。


安全性:代码执行的风险

代码作为动作空间有一个需要处理的风险:Agent 生成的代码可能删除文件、发起网络请求、访问系统环境变量或启动子进程。

CodeAct 的应对方案是沙箱隔离:在容器环境中运行代码,限制文件系统访问范围,禁用危险的系统调用。后来的 OpenDevin、SWE-agent 在这方面做得更完整,用 Docker 容器提供软件工程环境,同时通过权限控制防止越界操作。


实践中的 CodeAct:OpenHands

CodeAct 论文之后,原团队推出了 OpenHands(前身 OpenDevin)项目:

  • 每个 Agent 有独立的 Docker 环境
  • 支持浏览器、终端、文件系统的交互
  • 代码执行结果实时流式返回给 LLM
  • 内置权限沙箱和人工审批机制

小结

CodeAct 的主要贡献是系统地对比和论证了一个设计选择:代码执行比结构化工具调用更适合作为通用 Agent 的动作空间。

这个结论目前已被多家平台采纳——OpenAI 的 Assistants API 提供 Code Interpreter,Google 的 Gemini 内置代码执行环境,Anthropic 的 Claude 也支持在工具调用中执行代码。代码执行作为 Agent 动作空间,已经成为比较普遍的做法,CodeAct 是较早系统性论证这一点的工作。

版权声明: 如无特别声明,本文版权归 sshipanoo 所有,转载请注明本文链接。

(采用 CC BY-NC-SA 4.0 许可协议进行授权)

本文标题:05. CodeAct:把代码执行变成通用 Agent 的动作空间

本文链接:https://www.sshipanoo.com/blog/ai/code-agent-harness/05-CodeAct/

本文最后一次更新为 天前,文章中的某些内容可能已过时!