From Noisy Traces to Root Causes: Structural Trajectory Analysis and Causal Extraction for Agent Optimization
论文阅读:From Noisy Traces to Root Causes: Structural Trajectory Analysis and Causal Extraction for Agent Optimization
论文标题:From Noisy Traces to Root Causes: Structural Trajectory Analysis and Causal Extraction for Agent Optimization
作者:Ying Chang, Jiahang Xu, Xuan Feng, Chenyuan Yang, Peng Cheng, Yuqing Yang
作者机构:University of Chinese Academy of Sciences(中国科学院大学)、Microsoft Research(微软研究院)。其中,第一作者 Ying Chang 同时署名两家机构,其余作者来自 Microsoft Research。通讯作者为 Jiahang Xu。
发表位置:arXiv 预印本,尚未检索到正式会议或期刊录用记录(截至 2026 年 11 月)
arXiv 编号:2607.07702
发布时间:2026 年 7 月 8 日
原文链接:https://arxiv.org/abs/2607.07702
代码仓库:https://github.com/moomight/STRACE
主题:Agent Optimization、Reflexive Optimization、Trajectory Analysis、Causal Attribution、Prompt Optimization
核心问题:在长流程 Agent 的执行过程中,如何从大量冗余且充满噪声的执行轨迹中筛选出有价值的失败案例,定位真正导致失败的上游模块,并据此生成有针对性的 Prompt 优化策略?
1. 论文要解决什么问题?
随着 Agent 系统越来越复杂,一个任务可能需要经过 Planner、Router、Executor、Memory 等多个模块,甚至涉及多个子 Agent 的协作。
在这种情况下,一次任务执行会产生大量的执行轨迹(Trajectory),其中记录了 Agent 的决策、工具调用、模块输出以及最终执行结果。
这些轨迹实际上包含了优化 Agent 所需要的信息。
例如:
- Agent 在某一步选择了错误的工具。
- Planner 生成了不合理的执行计划。
- 某个子 Agent 多次执行失败。
- 不同模块之间的信息传递出现了问题。
- Agent 陷入循环,最终导致任务超时。
因此,一个很自然的思路是:将历史执行轨迹交给一个 Meta-Agent,让它分析失败原因,然后修改 Agent 的 Prompt。
这就是 Reflexive Optimization 的基本思路。
但是,作者指出,直接使用执行轨迹进行优化存在两个问题。
1.1 问题一:大量轨迹之间存在冗余
假设一个 Agent 执行了 1000 次任务,其中有 500 次失败。
这些失败并不意味着存在 500 种不同的问题。
实际上,可能只有以下几类:
- Planner 经常生成错误计划。
- Router 经常选择错误的子 Agent。
- 某个 Executor 容易陷入循环。
- 某种特定工具调用方式经常导致超时。
如果把 500 条失败轨迹全部交给优化器,会产生两个问题:
- 大量相似的失败案例会重复占用上下文。
- 优化器可能过度关注某些偶然出现的失败,而忽略真正重要的系统性问题。
因此,优化器需要的不是尽可能多的失败轨迹,而是能够代表不同失败模式的高价值样本。
1.2 问题二:单条轨迹内部也存在大量噪声
即使只保留一条失败轨迹,也不意味着这条轨迹中的所有步骤都值得交给优化器。
举个例子:
一个 Agent 执行了 50 个步骤,最终在第 50 步调用 Code Interpreter 时发生错误。
但是,真正的问题可能出现在第 5 步:
- Step 5:Planner 生成了一个错误参数。
- Step 10:Router 根据错误参数选择执行路径。
- Step 20:Executor 使用错误参数执行操作。
- Step 30:Agent 根据错误结果继续推理。
- Step 50:Code Interpreter 最终发生异常。
真正导致失败的是 Step 5 的 Planner,而不是 Step 50 的 Code Interpreter。
这就引出了一个关键问题:
错误发生的位置(Failure Manifestation)和错误产生的根源(Root Cause)可能并不是同一个地方。
如果优化器只关注最终报错的位置,就可能不断优化 Code Interpreter,而忽略真正需要修改的 Planner。
1.3 现有方法为什么不够好?
作者将现有方法面临的问题概括为 Context-Noise Trade-off,即上下文与噪声之间的权衡。
主要有两种极端:
方案一:使用完整轨迹。
把一整条执行轨迹全部交给优化器。
优点是保留了完整的历史信息,不容易丢失远距离的依赖关系。
缺点是包含大量无关步骤,增加 Token 消耗,也容易干扰优化器的判断。
方案二:截断轨迹。
只保留最后若干步,或者使用滑动窗口。
优点是上下文更短,成本更低。
缺点是可能直接丢掉真正的错误源头。
例如,只保留 Step 40~50,就完全看不到 Step 5 的 Planner 是如何产生错误参数的。

【Figure 1,展示完整轨迹、简单截断和 STRACE 三种上下文构造方式的区别】
因此,作者希望解决的问题是:
既不能把整条轨迹不加区分地交给优化器,也不能简单地截断轨迹,而是应该保留真正与失败存在依赖关系的步骤。
此外,还需要在大量失败轨迹之间进行筛选,避免重复分析相同的问题。
2. STRACE 方法概述
为了解决上述问题,作者提出了 STRACE:
Structural Trajectory Analysis and Causal Extraction
即结构化轨迹分析与因果提取。
其核心思想是:
不再把 Agent 的执行轨迹当成一段普通的文本,而是结合 Agent 系统自身的结构,分析各个模块之间的数据依赖和控制依赖,从而找到真正导致失败的模块。
STRACE 将整个优化过程划分为四个阶段:
- Structural Modeling:构建 Agent 系统的执行依赖图。
- Failure Pattern Mining and Trace Filtering:挖掘失败模式并筛选代表性轨迹。
- Causal Localization:通过反向切片定位真正的失败根因。
- Inductive Policy Optimization:将失败经验归纳为通用规则,更新对应模块的 Prompt。
整体流程如下:
Agent 源代码、配置、Prompt
|
v
Phase 1: Structural Modeling
|
v
Execution Dependency Graph
|
|
大量 Agent 执行轨迹(成功 + 失败)
|
v
Phase 2: Failure Pattern Mining
|
v
Failure Diagnosis Summary
|
v
Representative Traces
|
v
Phase 3: Causal Localization
|
v
Backward Slicing
|
v
Root Cause
|
v
Phase 4: Inductive Policy Optimization
|
v
Generalized Optimization Rules
|
v
修改对应模块的 Prompt
可以看到,STRACE 实际上做了两层信息压缩:
- 批次级压缩:从大量执行轨迹中筛选出具有代表性的失败案例。
- 轨迹级压缩:从每条失败轨迹中提取真正与失败有关的因果上下文。
最终再将这些信息交给优化器。
下面具体介绍四个阶段。
3. STRACE 的四个核心阶段
3.1 Phase 1:Structural Modeling
首先,STRACE 需要了解待优化 Agent 系统的内部结构。
为什么需要这一步?
因为仅仅观察执行日志,很难判断两个模块之间是否存在真正的依赖关系。
例如:
Planner -> Router -> Executor -> Tool
如果 Executor 执行失败,我们需要知道:
- Executor 使用了什么信息?
- 这些信息由哪个模块生成?
- Router 是否决定了 Executor 的调用?
- 上游模块的错误是否可能传递到下游?
因此,作者提出先构建一个 Execution Dependency Graph(EDG),即执行依赖图。
3.1.1 如何构建 EDG?
STRACE 使用 LLM 阅读 Agent 的代码库和相关文件,包括:
- Agent 定义。
- Prompt。
- Tool 接口。
- 配置文件。
- Skills。
- 相关源代码和文档。
LLM 通过分析这些信息,识别系统中的主要功能模块,以及模块之间的信息流和调用关系。
图中的节点集合记为 \(V\),边集合记为 \(E\):
其中:
- \(V\):Agent 系统中的功能模块。
- \(E\):模块之间的依赖关系。
作者主要定义了两种依赖关系。
第一种:Data Dependency(数据依赖)
模块 B 使用了模块 A 产生的信息。
例如:
Planner
|
| 生成执行计划
v
Executor
|
| 使用执行计划
v
Tool
如果 Planner 产生了错误计划,这个错误就可能沿着数据流传递到 Executor 和 Tool。
第二种:Control Dependency(控制依赖)
模块 A 决定是否调用模块 B,或者决定调用哪个模块。
例如:
Router
|
| 决定调用哪个子 Agent
|
+----+----+
| |
v v
Executor A Executor B
即使 Executor B 本身没有问题,如果 Router 总是错误地选择 Executor B,那么真正需要优化的也可能是 Router。
3.1.2 EDG 到底是什么形式?
这里有一个值得注意的细节。
作者虽然称其为 Graph,但它并不是通过 GNN 学习得到的图,也不是传统意义上通过静态程序分析构建的完整程序依赖图。
论文明确说明,实际实现采用的是一种文本形式的边列表(Text Edge List)。
每条边记录:
- 两个模块之间的关系。
- 依赖类型(Data Dependency 或 Control Dependency)。
- 从代码库中找到的相关依据。
因此,它本质上是 LLM 根据代码、配置和文档推断出来的一份结构化依赖描述。
后续的失败分析和因果定位都会使用这份依赖描述。
这一阶段的输出就是 EDG,它相当于整个 STRACE 系统的结构先验(Structural Prior)。

3.2 Phase 2:Failure Pattern Mining and Trace Filtering
完成系统结构建模之后,STRACE 开始分析大量执行轨迹。
这一阶段的目标是:
从大量失败轨迹中找出最重要、最具代表性的失败模式,避免优化器重复分析相似问题。
作者将这一阶段分成两个步骤。
3.2.1 Diagnosis Summarization:失败诊断汇总
STRACE 并不是简单地把所有轨迹直接交给 LLM。
相反,它会先生成一个 Python Parser,对执行轨迹进行结构化解析。
具体流程是:
- 首先读取一条示例轨迹。
- 推断当前轨迹的日志格式和数据结构。
- 识别其中的结构分隔符,例如 Action、Observation 等。
- 动态生成适配当前日志格式的 Python 解析脚本。
- 使用这个脚本处理整个轨迹数据集。
最终,每条轨迹都会被提取出两类信息:
- Global Outcome:整个任务最终是否成功。
- Local Node Status:各个模块的局部执行状态,例如是否发生运行时异常。
然后,STRACE 从两个维度分析整个数据集。
维度一:Statistical Severity(统计严重程度)
作者定义了一个条件概率:
其中:
- Task Fail:整个任务执行失败。
- \(v_i\) Fail:模块 \(v_i\) 出现局部错误。
这个指标衡量的是:
当某个模块发生错误时,整个任务最终失败的概率有多大。
例如:
| 模块 | 局部错误后任务失败概率 |
|---|---|
| Planner | 90% |
| Router | 85% |
| Executor A | 30% |
| Executor B | 20% |
那么 Planner 和 Router 就可能是更加值得关注的系统瓶颈。
注意,这里计算的是条件概率,并不意味着已经证明该模块错误必然导致任务失败。它主要用于衡量局部错误与全局失败之间的统计关联。
维度二:Structural Path Patterns(结构路径模式)
除了统计每个模块的错误,STRACE 还会分析不同模块在执行轨迹中的调用序列。
重点识别以下异常模式:
- Self-loop:某个模块反复调用相同工具,没有取得实际进展。
- Oscillation:Agent 在不同模块或执行路径之间反复切换。
- Dead-end:某些模块调用序列经常导致任务终止或超时。
为什么需要第二个维度?
因为有些 Agent 并不会明确报告某个模块发生了异常,但是它可能一直在重复执行相同的操作。
例如:
Router -> Executor A
^ |
| |
+----------+
不断重复相同调用,最终超时。
这种情况下,单纯统计模块异常次数就无法发现问题。
因此,作者同时分析局部错误统计和整体调用路径。
最终得到一份 Failure Diagnosis Summary,即失败诊断汇总。
3.2.2 Representative Trace Selection:代表性轨迹筛选
有了全局诊断信息之后,STRACE 开始筛选代表性失败轨迹。
作者认为,不同失败轨迹之间往往存在大量重复,因此不需要将所有失败轨迹都交给优化器。
具体做法是:
- 根据局部错误的统计严重程度和结构路径模式,对轨迹进行聚类。
- 将具有相似失败特征的轨迹划分到同一个 Cluster。
- 从每个不同的 Cluster 中选择一定数量的代表性轨迹。
- 将这些轨迹交给下一阶段进行因果定位。
这样既能够覆盖主要失败模式,又能够控制优化器需要处理的轨迹数量。
另外,作者还考虑了一种特殊情况:
如果某个 Agent 的执行日志没有明确的模块级错误信息,那么 STRACE 会跳过局部错误状态的分析,改为结合全局任务结果和模块调用路径进行聚类和筛选。
这保证了方法不完全依赖显式异常信息。
3.3 Phase 3:Causal Localization
这是 STRACE 最核心的阶段。
前面的 Phase 2 已经筛选出了具有代表性的失败轨迹,但是每条轨迹内部仍然可能存在大量无关步骤。
因此,Phase 3 需要进一步回答两个问题:
- 哪些历史步骤真正影响了这次失败?
- 在这些相关步骤中,究竟是哪个模块最先出现了逻辑错误?
作者将这一过程分成两个步骤。
3.3.1 Step 1:Backward Slicing
首先,需要区分两个概念。
Manifestation Node(错误表现节点)
记为 \(v_m\),指错误实际表现出来的位置。
例如:
- Code Interpreter 抛出了异常。
- 某个 Executor 执行失败。
- 如果没有明确的错误信息,则使用轨迹中的终止节点。
Root Cause Node(根因节点)
记为 \(v_r\),指真正产生逻辑错误的模块。
例如:
Planner 在早期生成了错误参数,最终导致 Code Interpreter 在很久之后发生异常。
此时:
- \(v_m\) 是 Code Interpreter。
- \(v_r\) 是 Planner。
这两个节点可能相距很多个执行步骤。
因此,STRACE 不会直接将 \(v_m\) 作为优化目标,而是从 \(v_m\) 出发,沿着 EDG 中的依赖关系向后追溯。
这就是 Backward Slicing(反向切片)。
具体来说:
- 找到当前轨迹中的错误表现节点 \(v_m\)。
- 根据 EDG,寻找对该节点存在数据依赖或控制依赖的历史模块。
- 继续向前追溯这些模块的上游依赖。
- 递归保留所有能够影响当前错误的历史步骤。
- 删除与当前错误没有结构依赖关系的其他步骤。
最终得到一个精简后的因果切片:
它只包含那些直接或间接影响当前失败的历史信息。
举个例子:
Step 1: Planner 生成执行计划
|
v
Step 2: Router 选择 Executor
|
v
Step 3: Executor A 执行
|
v
Step 4: Executor B 执行
|
v
Step 5: Code Interpreter 报错
假设 Step 3 和 Step 4 之间没有任何与最终错误有关的数据或控制依赖,那么它们就可以被删除。
最终保留:
Step 1: Planner 生成错误参数
|
v
Step 2: Router 根据错误参数选择执行路径
|
v
Step 5: Code Interpreter 报错
这样就能在保留关键依赖关系的同时,大幅减少需要交给优化器的上下文。
3.3.2 Step 2:Root Cause Isolation
得到精简后的因果切片,并不意味着已经找到了真正的根因。
因为反向切片只能告诉我们哪些模块与最终失败存在依赖关系,并不能直接判断究竟是哪个模块最先产生了错误。
因此,STRACE 还需要对 \(C_{\text{slice}}\) 进行语义分析。
具体来说,LLM 从最终错误表现开始,沿着信息传递路径向上追溯,判断错误信息最早在哪个模块出现。
例如:
Planner
|
| 生成错误参数
v
Router
|
| 根据错误参数选择执行路径
v
Executor
|
| 使用错误参数执行
v
Code Interpreter
|
| 最终发生异常
v
Task Failure
此时:
- Code Interpreter 是错误表现节点。
- Planner 才是真正的根因节点。
STRACE 将 Planner 识别为 \(v_r\)。
至此,系统不仅知道任务为什么失败,还知道应该修改哪个模块。
这里需要特别注意:
STRACE 所谓的 Causal Localization,并不是通过实验干预或严格的统计因果发现来证明因果关系。
它实际上结合了两种信息:
- 由 EDG 提供的结构依赖先验。
- LLM 对精简轨迹进行的语义推理。
因此,更准确地说,它是一种依赖结构引导的因果溯源机制。
3.4 Phase 4:Inductive Policy Optimization
前面三个阶段主要负责分析失败,直到这一阶段才真正开始优化 Agent。
作者希望避免一种情况:
优化器只是记住某个具体任务失败的案例,却没有总结出能够迁移到其他任务的经验。
因此,STRACE 使用 Inductive Abstraction(归纳抽象)机制,将具体失败案例转换为通用的优化规则。
具体流程如下:
第一步:按照根因模块进行分组。
前面已经为每条失败轨迹找到了对应的根因节点 \(v_r\)。
STRACE 将具有相同根因模块的因果切片放在一起。
例如:
Planner:
- 失败案例 A
- 失败案例 B
- 失败案例 C
Router:
- 失败案例 D
- 失败案例 E
Executor A:
- 失败案例 F
- 失败案例 G
第二步:归纳通用优化规则。
优化器分析同一个模块对应的多个失败案例,提取反复出现的问题,并总结成可复用的启发式规则。
例如:
如果 Router 多次因为相似的错误选择了不合适的 Executor,那么优化器就应该总结:
- 哪些情况下不应该选择该 Executor?
- 应该优先考虑哪些其他执行路径?
- 遇到连续失败时应该如何切换策略?
而不是简单地把某次失败记录写进 Prompt。
第三步:修改根因模块的 Prompt。
得到通用规则之后,STRACE 将这些规则注入对应根因模块的 Prompt Policy。
例如:
原始 Router Prompt:
根据当前错误信息选择最合适的 Executor。
优化后的 Router Prompt:
根据当前错误信息选择最合适的 Executor。
额外规则:
如果当前执行路径已经连续失败,
不要继续重复选择相同的执行策略。
应当分析此前失败的原因,
并考虑切换到其他适合的执行路径。
这里有一个重要细节:
STRACE 修改的是根因模块的文本指令,而不是直接修改 Agent 的可执行代码。
因此,这套方法本质上属于 Prompt-level Optimization,也可以应用于 Harness Engineering。
对于不同系统,优化对象可以是:
- Planner 的 Prompt。
- Router 的 Prompt。
- Executor 的 Prompt。
- Tool-use Policy。
- 其他可调节的 Harness 指令。
论文还说明了一个实现细节:Phase 1~3 使用共享上下文,因为它们需要连续使用相同的 Agent 背景信息和 EDG;Phase 4 则使用独立上下文,只接收根因模块附近的局部信息,从而避免再次引入前面阶段的大量分析上下文。
4. 实验设置
作者在三个不同类型的 Benchmark 上验证 STRACE:
| Benchmark | 任务类型 | Agent 架构 | Backbone Model |
|---|---|---|---|
| HotpotQA | 多跳问答 | 四阶段推理工作流 | GPT-4o |
| WebArena | Web Navigation | 单 Agent CoT | GPT-4o |
| VeruSAGE-Bench | Rust 形式化验证 | Router-Executor 多 Agent | o4-mini |
其中,VeruSAGE-Bench 是论文重点展示的长流程 Agent 场景。
4.1 HotpotQA
HotpotQA 是一个多跳问答数据集。
作者采用四阶段推理工作流:
- Summarize1:总结第一轮检索结果。
- Create Query Hop2:生成第二轮检索查询。
- Summarize2:整合第二轮检索结果。
- Final Answer:生成最终答案。
STRACE 对这四个模块的 System Prompt 进行优化。
4.2 WebArena
WebArena 是一个 Web 交互任务 Benchmark。
实验使用原始的 CoT Web Navigation Agent,而不是多 Agent 系统。
Agent 根据当前网页的 Accessibility Tree、用户任务和之前的操作,决定下一步浏览器动作。
STRACE 优化的是这个 Agent 的单一指令 Prompt。
测试包含四类任务:
- Shopping
- CMS
- GitLab
4.3 VeruSAGE-Bench
这是论文中最重要的实验场景。
VeruSAGE 是一个用于 Rust 代码形式化验证的多 Agent 系统。
它采用迭代式验证与修复流程:
提交当前代码
|
v
Verus 验证器检查
|
v
Error Analyzer 分析错误
|
v
Router 选择修复策略
|
v
对应的 Sub-agent 执行修复
|
v
应用代码补丁
|
v
重新进行验证
|
+------ 成功:结束
|
+------ 失败:继续修复
系统包含多个专业化子 Agent,例如:
- Invariant Manager:分析和修复循环不变量。
- Proof Strategy Applicator:执行归纳、分情况讨论等证明策略。
- Prover Mode Activator:启用特定证明器模式。
- Syntax Fixer:修复 Rust 语法问题。
- Standard Lemma Guider:提供标准库引理使用建议。
系统共有 16 个可优化模块,包括 Router 和各个 Executor。
每个任务最多允许 20 次修复尝试,或者执行 20 分钟。
STRACE 主要优化 Router 和调用频率最高的 Top-k Executors 的 System Prompt。
数据集包含五个 Rust 项目:
- IronKV
- Memory Allocator
- Node Replication
- NRKernel
- Storage
每个项目采用 80%/20% 的训练与测试划分。
4.4 Baselines
论文比较了以下方法:
| 方法 | 核心思路 |
|---|---|
| Base Agent | 不进行优化 |
| Naive Few-shot | 将失败案例作为 Few-shot 示例 |
| Failure-Aware RAG | 使用 BM25 检索历史失败轨迹,作为 Prompt 参考 |
| Summary-based Selection | 对完整轨迹进行总结,再进行优化 |
| Retrieval-based Selection | 检索相关步骤作为优化上下文 |
| TextGrad | 将完整执行轨迹交给优化器进行文本梯度式优化 |
| GEPA | 通过反思和演化优化 Prompt,采用上下文截断等方式控制历史信息 |
其中:
- TextGrad 代表使用完整轨迹进行优化的思路。
- GEPA 代表通过上下文管理控制历史信息的思路。
- Summary-based 和 Retrieval-based 则用于比较不同的轨迹压缩策略。
值得注意的是,由于 VeruSAGE 的执行轨迹非常长,TextGrad 在该任务上需要超过 100k Tokens 的上下文,因此作者没有在 VeruSAGE-Bench 上报告 TextGrad 的结果。
另外,所有方法使用 Claude Sonnet 4.5 作为 Meta-Controller,温度为 1.0,以保证优化器配置的一致性。
5. 主要实验结果
5.1 HotpotQA
评价指标为 Exact Match(EM)。
| 方法 | EM |
|---|---|
| Base Agent | 37.0% |
| Naive Few-shot | 60.0% |
| Failure-Aware RAG | 57.7% |
| Summary-based Selection | 64.3% |
| Retrieval-based Selection | 46.0% |
| TextGrad | 62.0% |
| GEPA | 64.4% |
| STRACE | 68.5% |
STRACE 达到了 68.5%,相比基础 Agent 提升了 31.5 个百分点。
5.2 WebArena
评价指标为 Success Rate(SR)。
| 方法 | Shopping | CMS | GitLab | ALL | |
|---|---|---|---|---|---|
| Base Agent | 17.9% | 10.8% | 4.5% | 7.3% | 10.8% |
| Naive Few-shot | 23.1% | 13.5% | 9.1% | 7.3% | 13.7% |
| Failure-Aware RAG | 23.1% | 16.2% | 9.1% | 7.3% | 14.4% |
| Summary-based Selection | 25.6% | 10.8% | 9.1% | 12.2% | 15.1% |
| Retrieval-based Selection | 17.9% | 13.5% | 14.3% | 12.2% | 14.4% |
| TextGrad | 30.8% | 16.2% | 9.1% | 9.8% | 17.3% |
| GEPA | 23.1% | 10.8% | 27.3% | 9.8% | 16.5% |
| STRACE | 30.8% | 16.2% | 36.4% | 17.1% | 23.7% |
STRACE 在 WebArena 上取得了 23.7% 的总体成功率,相比基础 Agent 提升 12.9 个百分点。
其中 Reddit 和 GitLab 两类任务的提升比较明显。
但在 Shopping 和 CMS 上,STRACE 并没有明显超过所有其他方法,而是与部分 Baseline 持平。
5.3 VeruSAGE-Bench
这是论文最重要的实验。
| 方法 | IronKV | Memory Allocator | Node Replication | NRKernel | Storage | ALL |
|---|---|---|---|---|---|---|
| Base Agent | 41.6% | 66.7% | 80.0% | 20.0% | 46.2% | 42.5% |
| Naive Few-shot | 37.5% | 61.1% | 80.0% | 24.4% | 30.8% | 39.6% |
| Failure-Aware RAG | 37.5% | 66.7% | 70.0% | 29.3% | 38.5% | 42.5% |
| Summary-based Selection | 58.3% | 61.1% | 70.0% | 29.3% | 30.8% | 45.3% |
| Retrieval-based Selection | 37.5% | 66.7% | 90.0% | 22.0% | 38.5% | 41.5% |
| GEPA | 54.2% | 61.1% | 80.0% | 29.3% | 46.2% | 47.2% |
| STRACE | 62.5% | 88.9% | 100.0% | 31.7% | 61.5% | 58.5% |
可以看到:
STRACE 的总体成功率达到了 58.5%,相比基础 Agent 的 42.5% 提升了 16.0 个百分点。
相比表现最好的 Baseline GEPA,也提升了 11.3 个百分点。
论文将其概括为约 \(1.4\times\) 的成功率提升。
尤其是在 Memory Allocator、Node Replication 和 Storage 上,提升比较明显。
6. 案例分析:从表面错误找到真正的根因
为了进一步证明 Causal Localization 的作用,作者在 VeruSAGE-Bench 上展示了两个案例。
6.1 错误表现节点与根因节点的重新映射
作者选取了 200-case 设置中的 25 条代表性失败轨迹。
具体是:
- 选择 5 个高影响力的错误表现模块。
- 每个模块选取 5 条代表性轨迹。
- 总计 25 条轨迹。
如果不进行 Causal Localization,那么优化器会直接将这 25 条轨迹归因于它们发生错误的模块。
但是经过 STRACE 的根因定位之后:
25 条轨迹中有 12 条被重新映射到了上游根因模块。
原本只根据错误表现位置进行优化,可能会将多个问题归结到下游 Executor。
但是经过根因定位,优化目标扩展到了 6 个不同的节点,其中还发现了一个此前容易被忽略的上游模块:
assertion_reasoning_pipeline
这说明,如果仅仅根据异常出现的位置选择优化对象,确实可能修改错误的模块。
6.2 Breaking the Loop:解决反复调用问题
另一个案例来自 IronKV。
在这个任务中,Agent 不断调用某个下游修复模块 compute_repair,但是每次都无法真正解决问题。
最终,Agent 因为反复执行相同操作而超时。
如果只观察最终失败位置,很容易得出一个结论:
compute_repair 的修复能力不够强,需要优化这个模块。
但是 STRACE 通过反向切片发现,真正的问题来自上游 Router 的路由决策。
Router 不断将任务分配到不合适的修复路径,导致下游模块反复执行相同操作。
因此,真正应该修改的是上游路由逻辑,而不是不断优化下游修复模块。
STRACE 最终通过向对应模块注入新的启发式规则,避免继续选择错误的递归修复路径,从而解决了这一问题。

【Figure 4,展示 Manifestation Node 到 Root Cause Node 的重新映射,以及 IronKV 中 compute_repair 循环的根因定位】
7. 消融实验与分析
作者通过消融实验验证了三个主要组件的作用:
- Structural Modeling
- Trace Filtering
- Causal Localization
7.1 各组件的消融结果
| 方法 | Success Rate | Optimization Cost |
|---|---|---|
| STRACE | 56% | $2.96 |
| w/o Structural Modeling | 48% | $5.10 |
| w/o Trace Filtering | 46% | $8.45 |
| w/o Causal Localization(Current Node) | 54% | $2.88 |
| w/o Causal Localization(Full Trace) | 54% | $5.93 |
注:这里是论文消融实验单独报告的设置,不能与前面主实验表中的 58.5% 直接混为同一组实验结果。
可以观察到:
第一,Structural Modeling 非常重要。
去掉依赖图之后,成功率从 56% 降低到 48%,优化成本也从 2.96 美元增加到 5.10 美元。
这说明,如果没有提前构建系统结构,优化器就需要自己从执行轨迹中推断模块之间的关系。
不仅效率更低,而且更容易错误判断失败路径。
第二,Trace Filtering 对优化成本影响很大。
去掉 Trace Filtering 之后,成功率下降到 46%,优化成本增加到 8.45 美元。
原因是优化器需要处理更多重复、低价值的失败轨迹,导致后续优化阶段消耗大量上下文和计算资源。
第三,Causal Localization 能够在保持上下文完整性的同时降低优化成本。
作者比较了两种方式:
- Current Node:只使用当前错误节点的信息。
- Full Trace:直接使用完整轨迹。
两者的成功率都只有 54%,低于完整 STRACE 的 56%。
但是 Full Trace 的优化成本达到了 5.93 美元,而 STRACE 只有 2.96 美元。
这说明:
仅仅保留当前错误节点,会丢失上游根因信息;直接保留完整轨迹,又会引入大量无关信息。
STRACE 的反向切片则在两者之间取得了更好的平衡。
7.2 优化成本分析
作者进一步统计了四个阶段的成本:
| 方法 | Phase 1 | Phase 2 | Phase 3 | Phase 4 | 总成本 |
|---|---|---|---|---|---|
| STRACE | 0.1135 | 0.1861 | 0.8515 | 1.8052 | 2.9563 |
| w/o Structural Modeling | - | 1.0099 | 2.2212 | 1.8734 | 5.1045 |
| w/o Trace Filtering | 0.1667 | - | 0.6802 | 7.6020 | 8.4489 |
| w/o Causal Localization(Current) | 0.2956 | 0.5320 | - | 2.0486 | 2.8762 |
| w/o Causal Localization(Full) | 0.2500 | 0.3597 | - | 5.3179 | 5.9276 |
单位:美元。
可以看到,真正消耗最多成本的是 Phase 4,也就是最终的 Prompt 优化阶段。
STRACE 的 Phase 4 成本为 1.8052 美元,占总成本的 61.1%。
去掉 Trace Filtering 后,Phase 4 成本直接增加到 7.602 美元。
这说明 Phase 2 的作用不仅仅是减少输入轨迹的数量,更重要的是减少后续优化器需要反复分析的低价值信息。
7.3 依赖图的鲁棒性
作者还研究了不同模型生成的 EDG 是否可靠,以及依赖图中存在一定噪声时是否会影响 STRACE。
他们让不同的模型根据相同代码库构建依赖图,并进行人工评估。
实验涉及:
- Claude Sonnet 4.5
- Claude Haiku 4.5
- GPT-5.1 Codex Mini
- DeepSeek-V3.1
- MiniMax-M2.5
人工评估发现,这些模型基本都能识别出系统中的核心依赖关系,区别主要体现在图的粒度以及额外噪声边的数量。
此外,作者还对依赖图进行随机增删边实验:
| 依赖图设置 | Success Rate |
|---|---|
| Base Agent(不优化) | 48% |
| No dependency graph | 48% |
| Remove 25% edges | 54% |
| Add 25% edges | 56% |
| Remove 10% edges | 56% |
| Add 10% edges | 62% |
| STRACE | 56% |
结果说明,依赖图不需要完全准确,也能够在一定程度的噪声下发挥作用。
但是,完全移除依赖图之后,性能就会退化到基础 Agent 水平。
这进一步说明,结构先验是 STRACE 的重要组成部分。
8. 局限性
作者明确指出了一个主要局限:
STRACE 需要能够访问目标 Agent 系统的内部结构。
具体来说,它需要读取:
- Agent 定义。
- Tool 接口。
- 配置文件。
- Prompt。
- Skills。
- 执行日志。
只有获得足够的系统信息,才能构建 EDG,并进行后续的因果定位。
因此,STRACE 更适合能够访问代码库或 Harness 的 Agent 系统,而不是完全黑盒的 Agent。
作者强调,这并不意味着需要访问底层模型权重,但是需要具备足够的系统级可见性。
将 STRACE 扩展到只有执行轨迹、无法访问内部实现的黑盒 Agent,仍然是未来的研究方向。
此外,从方法本身来看,还有一个值得注意的边界:
STRACE 的因果定位依赖于 LLM 对依赖图和执行轨迹的分析。虽然它能够根据结构关系缩小搜索范围,但依赖关系本身并不等于严格的因果证明。
例如,两个模块存在数据依赖,并不能单独证明上游模块一定是下游失败的根本原因。
因此,STRACE 的 Root Cause 更准确地说是通过结构先验与语义推理得到的根因判断,而不是通过干预实验验证的严格因果关系。
9. 总结
STRACE 提出了一套面向长流程 Agent 的结构化轨迹分析与 Prompt 优化框架。
它的核心流程可以概括为:
- Structural Modeling:分析 Agent 源代码和配置,构建模块之间的数据依赖与控制依赖关系。
- Failure Pattern Mining:从大量执行轨迹中统计失败模式,筛选具有代表性的失败案例。
- Causal Localization:利用依赖图进行反向切片,删除无关步骤,再通过 LLM 语义分析定位真正的根因模块。
- Inductive Policy Optimization:将多个失败案例归纳成通用优化规则,并更新对应根因模块的 Prompt。
从优化对象来看,STRACE 并没有修改 Backbone Model 的权重,也没有提出新的 RL 算法。
它主要优化的是 Agent 系统中各个模块的 Prompt Policy。
因此,这篇论文的核心并不是让 Agent 产生更多经验,而是改善 Agent 优化器获取经验、分析经验和使用经验的方式。
与直接将完整轨迹交给 Meta-Agent 进行反思相比,STRACE 增加了两个关键机制:
- 在多条轨迹之间进行失败模式挖掘和代表性筛选。
- 在单条轨迹内部进行基于依赖关系的反向切片和根因定位。
最终希望让优化器不仅知道 Agent 在哪里失败,还能知道应该修改哪个模块,以及应该向这个模块注入什么样的通用策略。
参考
-
Chang, Ying, et al. From Noisy Traces to Root Causes: Structural Trajectory Analysis and Causal Extraction for Agent Optimization. arXiv:2607.07702, 2026.
https://arxiv.org/abs/2607.07702 -
STRACE 官方代码仓库:
https://github.com/moomight/STRACE -
VeruSAGE: A Study of Agent-Based Verification for Rust Systems.
https://arxiv.org/abs/2512.18436 -
GEPA: Reflective Prompt Evolution Can Outperform Reinforcement Learning.
https://arxiv.org/abs/2507.19457 -
TextGrad: Automatic "Differentiation" via Text.
https://arxiv.org/abs/2406.07496

浙公网安备 33010602011771号