AgentSPEX: An Agent SPecification and EXecution Language
Paper: arXiv:2604.13346 Code: ScaleML/AgentSPEX Code reference:
main@2dc4d707(2026-04-27)
1. Motivation (研究动机)
现有 LLM agent 的一个核心矛盾是:越长程、越需要分支/循环/工具调用的任务,越不适合只靠一个 system prompt 让模型“自己反应式执行”。论文把当前做法分成两类:一类是 ReAct-style prompting,把任务说明放在一个 prompt 里,让模型随历史上下文增长而自行决定下一步;另一类是 LangGraph、DSPy、CrewAI 等 Python-centric orchestration,把控制流写进 Python 图、pipeline 或 role-based team 中。前者实现简单,但控制流、状态和中间产物都是隐式的;后者结构更强,但 workflow logic 与 Python 代码耦合,非程序员难维护,也不利于版本管理、审阅和快速修改。
AgentSPEX 要解决的具体问题不是“再发明一个 agent benchmark”,而是提供一种可执行的 workflow specification language:用户用 YAML 声明 agent 的步骤、分支、循环、并发、子模块调用和显式状态;harness 负责按规范执行、记录、恢复和验证。这个目标值得研究,是因为复杂 agent 的实际痛点往往不是单步推理,而是长程执行时的 context rot、不可复现、调试困难、失败后不能 resume,以及工作流作者必须同时理解 prompt、Python orchestration 与运行环境。
论文的背景判断是:当任务涉及长输入、多阶段推理、外部工具和大量中间状态时,把 workflow 结构直接塞进 prompt 但不强制执行,反而会增加模型负担。AgentSPEX 的假设是:让模型做语义推理,让解释器执行控制流,可以减少模型同时“理解流程 + 解决问题”的负担。
2. Idea (核心思想)
核心创新是把 agent workflow 变成一种声明式、可执行、可视化、可恢复的 YAML DSL。YAML 文件不是配置附属品,而是 AgentSPEX 的 executable specification:它同时描述任务目标、模型/工具配置、参数、步骤序列、状态变量、控制流和模块组合。执行时,Interpreter 解析 DSL,LLM Executor 只负责每个 task / step 内部的多轮工具循环,Checkpoint/Trace 系统负责可恢复性和可复现性。
与 LangGraph 的关键区别是抽象边界:LangGraph 把 graph、state transition 和 node function 主要放在 Python 中;AgentSPEX 把 workflow logic 提升到 YAML 层,让自然语言 instruction、变量注入和控制流处在同一份可读文件里。与纯 prompt/skill 方法的区别是执行语义:AgentSPEX 不让模型“猜”下一步,而是由 harness 强制执行 if、while、for_each、parallel、call 等结构。

Figure 1 解读:左侧是 agent definition:YAML 中显式写出 name、goal、config、workflow,并包含 for_each、call、task 等 step type;中间是 visual flow editor,把同一份 YAML 同步成图;右侧是 agent harness,由 Interpreter、LLM Executor、Durability System 和 Sandbox Environment 组成。图中最重要的分工是:YAML/Editor 负责“定义”;Interpreter 负责“按结构调度”;LLM Executor 负责“单步内的工具循环”;Sandbox/MCP 负责“实际工具访问”;Durability 负责“恢复、重放、日志和 verification”。
3. Method (方法)
3.1 Workflow language:轻量但覆盖长程 agent 的核心控制模式
AgentSPEX workflow 的顶层结构包括 name、goal、可选 config、parameters 和 workflow。论文 Figure 2 给出的例子是 topic research:先用 task 生成 search queries 并 save_as: search_queries,再用 call 调用 modules/search_and_summarize.yaml,最后用另一个 task 写 report。这里的关键不是 YAML 语法本身,而是每一步都有明确的输入、输出和状态名,后续步骤通过 {{variable}} 模板读取上下文变量。
论文 Table 1 支持的 constructs 如下:
| Category | Constructs | 作用 |
|---|---|---|
| Invocation | task, step | task 开启新 conversation;step 继续 persistent conversation |
| Control flow | if / switch, while, for_each | 条件分支、带上限循环、遍历列表 |
| Composition | call | 调用另一个 workflow 作为 submodule |
| Concurrency | parallel / gather | 并发执行步骤或子模块调用 |
| State | set_variable, increment, input, return | 显式写变量、累加、用户输入、返回值 |
task 与 step 的差别是 AgentSPEX 的上下文控制核心:task 适合“只把特定中间产物传给下一步”的场景,因为它从新 conversation 开始;step 适合需要连续多轮上下文的场景,因为它保留 conversation history。这个设计把“哪些信息进入下一轮模型上下文”从模型隐式决定改成 workflow 作者显式决定。
3.2 State、composition 与 context visibility
每个 workflow 维护一组 named context variables。步骤可以用 Mustache-style template(如 {{search_queries}})引用变量,用 save_as 保存输出。call 把 workflow 统一成 composable module:一个 workflow 可以调用另一个 workflow,传入 parameters,接收 return value;workflow 也可以注册为 skills/tools,让 agent 在执行中动态调用。论文把这称为 unified submodule abstraction,因为 skills 和 agents 都是 workflow。
直觉上,这相当于把 agent 运行时的“黑箱聊天记录”拆成两层:语义推理由 LLM 完成,结构化状态由 harness 保存。这样做的收益是长程任务不必把所有历史都塞回 prompt;作者可以决定某一步只接收某个 summary、某组 query 或某个 file path。
3.3 Agent harness:Interpreter + Executor + Sandbox + Durability
Harness 的执行流程分四块:
- Interpreter:读取 workflow file,验证结构,解析 config/parameters,展开模板变量,然后按 step type dispatch 到对应 handler。嵌套结构(loop、conditional、submodule call)由 Interpreter 递归管理,并给每个 operation 分配层级 step id(例如
3.2.1),供 checkpoint 和 logging 使用。 - LLM Executor:对每个
task或step运行多轮 tool-calling loop。每一轮把当前 message history 发给模型,执行模型返回的 tool calls,经 MCP client 把结果追加到 history,直到模型不再调用工具或达到 token/tool-call limit。 - Sandbox Environment:workflow 在 Docker-based sandbox 中执行,具备 browser、file system,以及超过 50 类工具(file operations、web search、code execution、browser automation 等)。
- Durability System:每步完成后保存 checkpoint,包括已完成 step id、当前 context、step-level metrics 和 sandbox state;同时记录 execution trace,可用于 resume 和 selective trace replay。

Figure 3 解读:可视化编辑器左侧是 node palette,中间是 workflow graph,右侧是同步的 YAML editor。图里展示了 deep research agent 的 while、for_each、parallel、task、set_variable 等嵌套结构;这说明 AgentSPEX 的可视化不是单独的 no-code layer,而是和 YAML spec 双向同步。对 workflow author 来说,图形视图降低理解成本,YAML 视图保留 version-control 和 code review 能力。

Figure 4 解读:dashboard 展示 SWE-Bench Verified run 的 step、iteration、tool calls、token/cost、message timeline、变量表和每轮 tool/result。它的作用不是给论文加 UI 截图,而是支撑长程 agent 的调试:如果某一步失败,用户可以看到是哪次 tool call、哪段 prompt、哪个 context variable 或哪次输出导致的,而不是只拿到一个最终失败结果。
3.4 Formal verification 的角色
AgentSPEX 的 verification 不是说 LLM 输出天然正确,而是说 YAML spec 让 control flow、variable dependency 和 step boundary 显式化,因此可以把 plan/trajectory 翻译成 Lean/Isabelle 等形式系统里的 predicate。Appendix C 用 AI Scientist 中的 extract_single_citation_module 展示:先从 task plan 推断变量应满足的 property,再对执行 trajectory 做 verification。这个方向的价值在于,它把“agent 是否按计划执行”从事后人工读日志,推进到可静态/运行时检查的形式。
3.5 released code 观察与伪代码
Code reference:
main@2dc4d707(2026-04-27) — pseudocode and mapping based on this commit
| Paper Concept | Source File | Key Class/Function |
|---|---|---|
| YAML parsing / workflow validation | src/harness/parsing/yaml_parser.py | YAMLTaskParser.load_task, _validate_task, _parse_step, _parse_for_each_step, _parse_parallel_step |
| Step dispatch / interpreter | src/harness/execution/interpreter.py | Interpreter.execute_workflow_step, _dispatch_step |
step / task LLM invocation | src/harness/execution/step_handlers/basic.py | BasicStepsMixin.execute_basic_step, execute_task_step |
| Control flow | src/harness/execution/step_handlers/control.py | execute_for_each_step, execute_conditional_step, execute_while_step, execute_switch_step |
| Submodule and concurrency | src/harness/execution/step_handlers/calls.py | execute_call_step, execute_gather_step, execute_parallel_step |
| Multi-turn tool loop | src/harness/execution/llm_executor.py | LLMExecutor.multi_step_tool_call_loop |
| Checkpoint/resume | src/harness/checkpoints/checkpoint_manager.py | CheckpointManager.__init__(load_existing=True), is_completed, mark_completed, _write_to_disk |
| Trace/replay | src/harness/checkpoints/tracing.py | record_llm_iteration, _next_replay_event |
| Sandbox MCP tool server | src/sandbox_vm/mcp/server.py, src/sandbox_vm/tools/mcp_server_tool_config.yaml | register_public_functions_as_tools, tool registry config |
| Visual editor | yaml-flow-editor/src/App.tsx, yaml-flow-editor/src/components/nodes/* | graph/YAML synchronized editor and node renderers |
| Formal verification | verifier/AgentVerifier/WorkflowToLean.py, verifier/AgentVerifier/*.lean | YAML-to-Lean conversion and workflow predicates |
| Demo / benchmark workflows | demo/*/*.yaml, src/benchmarks/*/*_agent.yaml | deep research, AI scientist, AI advisor, AIME/ChemBench/ELAIP/SWE/WritingBench workflows |
Parser 与 dispatch 的实现逻辑可概括为:
def load_and_dispatch_workflow(path, context, args, checkpoint_manager):
task_data = YAMLTaskParser().load_task(path) # yaml.safe_load + schema validation
config = YAMLTaskParser().get_config_with_defaults(task_data)
context.update(task_data.get("parameters", {}))
for step_number, step_data in enumerate(task_data["workflow"], start=1):
if checkpoint_manager and checkpoint_manager.is_completed(str(step_number)):
continue
output, tokens = interpreter.execute_workflow_step(
step_data=step_data,
context=context,
step_number=step_number,
args=args.with_config(config),
checkpoint_manager=checkpoint_manager,
)
if checkpoint_manager:
checkpoint_manager.mark_completed(str(step_number), output=output, context=context)task / step 的实现差别在 conversation history:
def execute_llm_invocation(kind, step, context, args):
instruction = expand_template_variables(step["instruction"], context)
save_as = step.get("save_as")
if kind == "step":
messages = ensure_conversation_history(context, args) # persistent history
else: # kind == "task"
messages = [] # fresh conversation
output, token_count = llm_executor.multi_step_tool_call_loop(
step_id=step.get("name"),
instruction=instruction,
message_history=messages,
tool_config=EffectiveToolConfig.compute(tools, context, step),
)
if save_as:
context[expand_template_variables(save_as, context)] = try_parse_python_literal(output)
return output, token_countparallel / gather 的实现不是 prompt 里“请并行”,而是在 handler 中用 isolated context copy 和 ThreadPoolExecutor 并发执行:
def execute_parallel_step(parallel_spec, context, args):
futures = []
with ThreadPoolExecutor(max_workers=len(parallel_spec["steps"])) as pool:
for i, child_step in enumerate(parallel_spec["steps"]):
child_context = copy.deepcopy(context)
futures.append(pool.submit(execute_workflow_step, child_step, child_context, f"parallel.{i}", args))
outputs = [None] * len(futures)
for i, future in enumerate(as_completed(futures)):
output, tokens = future.result()
outputs[i] = output
if "save_as" in parallel_spec:
context[parallel_spec["save_as"]] = outputs
return outputsDurability 的实现重点是 step-level checkpoint 与 trace event 对齐:
def durable_step(step_id, step_data, context):
if checkpoint_manager.is_completed(step_id):
return checkpoint_manager.get_substep_output(step_id)
before = snapshot(context)
output, tokens = interpreter.execute_workflow_step(step_data, context, step_id)
trace.record_llm_iteration(step_id=step_id, input_context=before, output=output, tokens=tokens)
checkpoint_manager.mark_completed(step_id, output=output, context=context)
return output论文公式与 released code 实现差异:这篇论文主要是系统/DSL 论文,没有训练目标或数学 loss;我没有发现需要在公式与代码之间对齐的核心算法公式。需要注意的实现细节是,README 示例里提到 workflows/quickstart.yaml,而 main@2dc4d707 的实际 demo/benchmark YAML 主要位于 demo/* 和 src/benchmarks/*;笔记中的 workflow/code mapping 以实际仓库路径为准。
4. Experimental Setup (实验设置)
4.1 Demos
论文提供三个 ready-to-use agents:
- Deep Research:输入用户 query,生成 Markdown report,模仿 OpenAI Deep Research / Gemini Deep Research 这类闭源产品。workflow 通过
breadth控制每层搜索 query 数,通过depth控制 follow-up query 层数;每层生成 targeted queries,并行执行 search,抽取中间 findings。 - AI Scientist:基于 Yu et al. (2025) 的实现,分为 Stage 1 Thinker 和 Stage 2 Writer。Thinker 做 safety classification、query generation、OpenAlex related-work retrieval、idea generation/refinement;Writer 顺序写论文段落,同时并行 citation workers 搜索并插入 references。
- AI Advisor:输入 proposal/paper,先 parse 文档并切成 semantic chunks,再把每个 chunk 总结成 structured JSON,最后合成包含 summary、novelty、significance、soundness、strengths、weaknesses、recommendations 的 rubric-based review。
4.2 Benchmarks / datasets / metrics
论文在 7 个 benchmark 上报告 pass@1 accuracy,除特别说明外使用 full test set:
| Domain | Benchmark | # Problems | Evaluation |
|---|---|---|---|
| Software Engineering | SWE-Bench Verified | 500 | sb-cli / hidden unit tests |
| Mathematics | AIME 2025 | 30 | Math-Verify |
| Chemistry | ChemBench | 90 | Exact Match |
| Chemistry | SciBench chemistry subsets | 213 | Exact Match |
| Chemistry | MMLU-Pro StemEZ physical chemistry | 216 | Exact Match |
| Generative Writing | WritingBench | 120 | LLM-as-Judge, 5 criteria, 10-point scale |
| Paper Understanding | ELAIPBench | 403 | Exact Match |
Baselines:多数 benchmark 对比 CoT 与 ReAct。CoT baseline 把必要信息放在单个 prompt 中;ReAct baseline 把 AgentSPEX workflow 放进初始 prompt,但不强制逐步执行,让模型自行解释 workflow 并决定 tool calls。AgentSPEX workflows 由作者手写,并借助 coding assistants。
模型设置:science、math、ELAIPBench 主要使用 GPT-5;WritingBench 使用 Claude-Sonnet-4.5-Thinking;SWE-Bench Verified 使用 Claude-Opus-4.5 与 Claude-Opus-4.6,reasoning effort 为 high,temperature=1.0。训练配置不适用:AgentSPEX 是 execution framework 论文,不训练新模型;仓库中的可复现实验入口是 src/benchmarks/*/*_agent.yaml 和 scripts/run_agent.sh,而不是 training launch script。
5. Experimental Results (实验结果)
5.1 Main benchmark results
| Benchmark | CoT / prior baseline | ReAct / prior baseline | AgentSPEX |
|---|---|---|---|
| SciBench | 85.92% | 87.79% | 90.61% |
| StemEZ | 82.87% | 84.72% | 86.57% |
| ChemBench | 78.90% | 77.80% | 83.30% |
| AIME 2025 | 94.60% without tools / 99.60% with Python | — | 100.0% |
| ELAIPBench | 37.22% | 33.80% | 43.70% |
| WritingBench | 79.90% | 80.30% | 81.00% |
| SWE-Bench Verified | mini-SWE-agent 76.20% | Live-SWE-agent 74.60% | 77.10% |
最强证据来自需要长输入或多步协调的任务:ELAIPBench 从 CoT 37.22% 提到 43.70%,ChemBench 从 CoT 78.90% / ReAct 77.80% 提到 83.30%。论文正文解释为:ReAct 虽然看到同一份 workflow,但没有 harness 强制执行,模型必须同时解释 workflow 结构和解决任务;AgentSPEX 把控制流交给 interpreter,可以减少这种额外负担。表 2 与正文有一个小表述细节:ChemBench 的 83.30% 相对 ReAct 是 +5.50 pp,相对 CoT 是 +4.40 pp;正文写“+5.5%”时对应的是 ReAct 差值。
5.2 SWE-Bench model-version robustness
SWE-Bench Verified 的附录表显示,AgentSPEX 在 Claude-Opus-4.5 到 4.6 的变化中更稳定:
| Agent | Claude-Opus-4.5 | Claude-Opus-4.6 | Δ |
|---|---|---|---|
| mini-SWE-agent | 76.8% | 75.6% | -1.2 |
| Live-SWE-agent | 78.0% | 71.2% | -6.8 |
| AgentSPEX | 77.2% | 77.0% | -0.2 |
这支持论文关于“Python prompt/control-flow 强耦合会对模型行为漂移敏感”的论点:当模型版本变化时,如果 prompt、控制流和 orchestration logic 交织在代码中,可能需要同步改 prompt 与 Python;AgentSPEX 把 workflow 结构放在 YAML spec 中,模型升级时行为更可控。
5.3 User study and framework comparison
用户研究包含 23 名参与者;每人看到两个实现同一 agentic behavior 的 workflow,一个用 AgentSPEX,一个用 LangGraph,并评价 interpretability 与 adoption preference。定性结果:参与者更常把 AgentSPEX 描述为 “accessible to non-coders” 和 “easier to understand”;LangGraph 则被认为 “customizable” 和 “more rigorous”。关键限制也在这里:多数参与者更愿意用 LangGraph 构建 complex workflow / 复杂多步 workflow,说明 AgentSPEX 的可读性优势并不自动转化为复杂工程信心。
框架对比表中,AgentSPEX 是唯一同时标记 Natural Language、Explicit Context、Visual Editor 三项为 ✓ 的方法;AutoGen/DSPy 三项均为 ✗,CrewAI 只有 Natural Language 为 Partial,LangGraph w/ LangFlow 有 Visual Editor 但没有 Natural Language 和 Explicit Context,PDL 有 Natural Language 且 Explicit Context 为 Partial。
5.4 Limitations and future work
论文没有列出传统意义上的 failure-case ablation,但从 discussion 可以归纳出三类限制。第一,AgentSPEX workflows 仍需要人工设计,论文也说 workflows are written manually with coding assistants;自动写 workflow 是 future work。第二,用户研究显示复杂 workflow 的可定制性信心仍不如 LangGraph。第三,formal verification 目前更多是潜力展示;要真正覆盖 agent execution 的语义正确性,还需要更完整的 predicate system、runtime checks 和外部工具验证。
未来方向包括:formal verification of agent execution、训练模型自动写/使用 workflows、把 end-to-end agentic training pipelines 纳入框架、增强 multi-agent orchestration,以及通过 context-compression 和更强抽象支持 long-context / longer-horizon tasks。