本文目录5 个章节
01. Code-as-Action 的核心机制与执行闭环
在传统 Agent 架构中,大语言模型通常依赖静态的 JSON 格式或文本标记来触发外部工具。随着交互链路与计算逻辑的复杂度提升,采用 代码即动作(Code-as-Action) 范式能够将 Agent 的决策、工具调用与数据处理统一表征为可执行的 Python 代码。编程语言天然具备图灵完备的表达力,原生支持循环迭代、条件分支、变量存储与函数复合,使模型能够自如应对多步骤数据处理任务。
在运行过程中,Agent 依托状态化解释器(Stateful REPL)形成严密的执行闭环。模型生成结构化的 Python 代码块并提交至沙箱环境,解释器实时执行并捕获标准输出、返回值或异常堆栈,再将运行反馈注入后续 Prompt 上下文中。这种闭环机制赋予了 Agent 动态感知执行结果与连续调优的能力。
Code-as-Action 状态化执行闭环链路
-
解析目标与代码生成
大模型解析用户任务意图,将多步骤工具调用与控制逻辑编译为标准 Python 代码块。
-
沙箱环境安全执行
隔离沙箱加载运行时环境,执行模型生成的代码并维护会话级变量命名空间。
-
输出捕获与异常反馈
解释器实时捕获标准输出、变量状态及异常堆栈信息,并结构化回传至 Agent 控制层。
-
状态沉淀与自愈推进
模型依据执行反馈确认任务达成状态,或针对报错信息重构代码发起自愈迭代。
02. JSON 工具调用与 Code-as-Action 架构对比
传统的 JSON Function Calling 要求模型每执行一步操作都必须完成一次完整的 LLM 推理往返。当面对需要批量抓取数据、多级过滤或聚合计算的场景时,单步调用会导致推理轮次显著膨胀,大幅推高延迟与 Token 成本。此外,静态 JSON Schema 难以灵活表达复杂的数据传递依赖与动态重试逻辑。
相比之下,Code-as-Action 允许模型将多步操作编写为单个脚本一次性提交执行。更关键的是,它能够实现 上下文屏蔽(Context Shielding) 机制:海量中间数据(如数千条 API 响应或大型表格)直接保留在沙箱进程内存中进行过滤处理,仅将最终统计摘要或关键字段打印输出到 Prompt 上下文中,彻底避免上下文窗口被冗余数据挤爆。
工具调用范式核心维度对比
-
传统 JSON Function Calling
单步调用单次往返,依赖大模型上下文传递中间数据,无原生流程控制语句,多步任务延迟与 Token 消耗高。
-
Code-as-Action 架构范式
单轮执行多工具复合脚本,中间数据保留在沙箱内存,原生支持循环与分支,Token 消耗降低且执行效率高。
03. 状态化 REPL 与自愈调试代码实现
状态化 REPL(Stateful REPL)是 Code-as-Action 架构的核心运行底座。通过在多轮交互中共享同一个全局命名空间(Namespace),前序步骤加载的数据集、初始化的客户端对象与中间变量能够在后续步骤中直接复用,避免了反复读取文件或重复调用外部 API 的性能开销。
当代码在执行过程中触发语法错误、键值缺失或类型异常时,解释器会将完整的 Traceback 报错堆栈回传给 Agent。这种精确的错误诊断信号能够直接触发 自愈调试(Self-Debugging) 闭环:模型依据具体的行号与异常类型快速定位逻辑缺陷,针对性地生成 Patch 代码完成修复,从而大幅提升复杂任务的自主交付率。
import sys
import io
import traceback
class StatefulCodeREPL:
"""Stateful Python REPL Sandbox for Code-as-Action Agents."""
def __init__(self, tools_dict: dict = None):
# Persistent global namespace across multi-turn interactions
self.globals_env = {"__builtins__": __builtins__}
if tools_dict:
self.globals_env.update(tools_dict)
def execute(self, code: str) -> dict:
stdout_capture = io.StringIO()
stderr_capture = io.StringIO()
old_stdout, old_stderr = sys.stdout, sys.stderr
sys.stdout, sys.stderr = stdout_capture, stderr_capture
try:
# Execute code within persistent namespace
exec(code, self.globals_env)
output = stdout_capture.getvalue()
return {"status": "success", "output": output, "error": None}
except Exception:
# Capture full traceback for agent self-debugging
error_trace = traceback.format_exc()
return {"status": "error", "output": stdout_capture.getvalue(), "error": error_trace}
finally:
sys.stdout, sys.stderr = old_stdout, old_stderr04. 多层代码沙箱安全防御体系
允许模型自主编写并执行代码虽然极大地解放了计算表达力,但也引入了远程代码执行(RCE)、提示词注入攻击与系统资源耗尽等重大安全隐患。在生产级系统架构中,直接在主机上执行未受控的代码是绝对不被允许的,必须强制实施 沙箱隔离(Sandbox Isolation) 防御策略。
构建稳固的代码沙箱需要采用纵深防御(Defense-in-Depth)思想,结合静态 AST 语法树白名单校验、轻量级容器隔离(如 Docker 与 gVisor)、严格的网络出口策略以及高危操作的人工确认机制,将潜在的安全攻击面压缩至最低范围。
代码沙箱多层安全防护体系
-
AST 语法白名单静态过滤
在代码执行前解析抽象语法树,严格拦截高危模块导入(如 os、subprocess、socket)及未授权的文件访问。
-
轻量容器与微虚拟机隔离
使用 Docker、gVisor 或 E2B 微虚拟机为每个会话分配独立只读文件系统,配置 CPU 与内存硬性配额。
-
网络出口白名单与超时控制
默认禁用公网外部网络访问,按需配置域名出口白名单,并对单次代码执行设置严格的毫秒级超时熔断。
-
破坏性写操作确定性拦截
涉及数据库删除、生产环境部署或敏感资产变更的操作,强制由确定性代码中断流程并等待人工审批。
05. 生产级 Code-as-Action 架构权衡与选型
在实际工程选型中,Code-as-Action 并非在所有场景下都优于传统工具调用。它在数据探索、统计计算、复杂 API 组合与代码重构等具有显著计算密度的场景中优势巨大;而在简单的单步信息查询、固定模式的 CRUD 操作或安全敏感型金融交易中,轻量且确定性更强的 JSON 工具调用仍是更稳健的选择。
此外,Code-as-Action 对底层基础模型的代码编写与逻辑推演能力提出了更高要求。在当前前沿工程实践中,通常需要搭配在 SWE-bench Verified 或 LiveCodeBench 等评测中表现优异的推理与代码特化模型(如 Claude Opus/Fable 系列、GPT-5.6 Sol、o3-mini、DeepSeek-V4-Flash 或 Qwen3-Coder 系列),才能确保生成的 Python 脚本语法准确且具备高鲁棒性。
REFERENCES