写作现场:2024 年 12 月 31 日。 smolagents v1.0.0 允许模型生成 Python,而不是为每次工具调用单独构造 JSON。循环、分支、中间变量和多次工具调用可以压缩在一个解释器 action 内。相应的代价是:Agent 状态不再只存在于 transcript,执行器 namespace 也成为可跨 step 延续的第二份记忆。
执行粒度与双重状态
MultiStepAgent 管理 system prompt、任务、planning step 与 action loop;CodeAgent 将每轮模型生成的代码交给 Python executor:
模型生成代码
→ python_interpreter tool call
→ executor 执行整段程序
→ logs / value 写入 observation
→ 未调用 final_answer 时继续下一轮
一段代码内部可以完成循环、筛选并调用多个工具,但外层 transcript 可能只记录一条 python_interpreter action。这减少模型往返和中间 token,却改变审计粒度。若系统需要按工具授权、计费或记录调用链,trace 必须进入 tool wrapper 或 executor 内部;只检查顶层消息会漏掉实际副作用。
状态也分为两层:
logs / transcript 下一轮模型可读的文字历史
self.state 下一段代码直接访问的 Python 对象
第一步把大表格存为 df 后,下一步可以直接继续计算,不必把数据序列化回 prompt。首发实现中的 run(reset=True) 会清理 logs 与监控信息,但不会自动创建全新的 executor state。复用同一个 Agent 实例时,旧变量可能继续存在。
这不是偶然泄漏,而是跨 step 计算得以成立的机制。接入方必须明确 session boundary:何时创建新 executor、哪些对象可以跨 turn、任务结束时如何销毁,以及多用户场景下实例是否复用。否则 transcript 已重置并不意味着执行状态已经隔离。
代码护栏、隔离与回滚边界
local executor 通过 AST evaluator 限制 import、内建函数、属性访问、操作次数和输出长度,工具与额外变量显式注入 namespace。这些约束能够缩小可执行语言,但不能超过被注入工具的权限上限。允许写文件或调用业务 API 的工具,会把相同能力交给生成代码。
E2B 等远程 sandbox 改变代码运行位置,便于限制文件系统、网络和进程生命周期;它不能撤销已经提交到外部服务的副作用。Python mutation 本身也不是事务:
ledger = []
ledger.append("charged")
1 / 0
异常发生后,前面的状态修改仍可能保留。框架可以将异常作为 observation 交给模型修复,无法自动恢复内存对象、文件和外部系统到执行前状态。高风险路径仍需要幂等键、dry run、人工确认、结果收据与 compensating action。
CodeAgent 适合控制流需要动态生成的研究、数据分析和实验任务;动作逐项审批的流程更适合 ToolCallingAgent。当路径趋于稳定且副作用提高时,应将流程固化为普通函数或持久工作流,只把开放判断保留给模型。smolagents 的“轻量”体现在抽象数量,而不是状态与安全责任更少。
版本与源码
信息边界:本文写于 2024 年 12 月 31 日,只依据首发实现;后续 executor、timeout 与安全机制不在本文判断中。