TraceCompiler:将Agent轨迹编译为确定性工作流,API调用缩减68%
TraceCompiler: Skill-Guided Mining and Compilation of LLM Agent Traces into Mostly Deterministic Workflows
在大模型驱动的智能体(LLM Agent)落地实践中,一个长期困扰工程团队的问题在于:智能体每次面对相似任务时,都在重复“花钱探索已知路径”。无论是查询工单还是发起跨平台转账,即使同样的意图已经执行过成百上千次,Agent 依然会从头解析工具文档、尝试错误参数并触发重试、发起毫无必要的辅助读取,甚至在冗长的上下文中不断累加无用的推理历史。
ArXiv URL:https://arxiv.org/abs/2608.02680
现有的解决路径通常有两个极端:要么简单做“轨迹回放”(Trace Replay),把某一次成功的工具调用硬编码下来,但这样会机械地保留探索过程中的所有死胡同与冗余步骤;要么把历史轨迹总结成文本提示词(Prompt Guidance)塞给大模型,这又迫使模型在每次运行时重新解析一遍业务流程,推理延迟与 Token 成本居高不下。
针对这一困境,研究人员提出了 TraceCompiler。这项工作的核心构想是将 Agent 在多次探索中留下的嘈杂、混乱的执行轨迹(Traces),通过无监督聚类、行为去噪和严格的数据流依赖分析,“离线编译”为结构清晰、高确定性且可直接执行的工作流代码。在 AppWorld 基准的典型跨应用转账任务中,该方案将原本需要 34 次在线 API 调用的探索过程编译为仅需 11 次调用的精简工作流,且在未观测到安全分支时能主动阻断风险。其背后的理论框架与工程实现,为 Agent 从“黑盒试错”走向“工业级可靠执行”提供了全新解法。

为什么传统的流程挖掘无法应对 Agent 轨迹?
如果把 Agent 的工具调用记录视作日志,很多人的第一直觉是借鉴经典的业务流程挖掘(Process Mining)算法,通过统计事件先后出现的频率来生成状态机。但作者在论文一开始就指出了这一假设的失效:在 Agent 轨迹中,观察到的前后相邻(Adjacency)绝不等于存在依赖(Dependency)。
在大模型自主决策的场景下,两个工具调用连续发生,可能仅仅是因为模型习惯性地按某种风格顺序发出了两个完全独立的操作;也可能第一步是一次参数格式不合法的失败尝试,第二步才是修正后的真正调用;甚至第一步只是模型在无意识地读取某个根本不会被后续消费的元数据接口。如果仅按时间序列或统计频次将它们连成有向边,编译出的工作流不仅充满冗余,更会包含大量伪依赖。
此外,现实世界导出的 Agent 日志往往存在“部分可观测性”(Partial Observability):生产环境或评测基准为了脱敏或节约空间,往往只记录了传入工具的参数(Arguments),却没有完整记录工具返回的庞大结构体输出(Tool Outputs)。在无法直接比对“上游输出文本”与“下游输入文本”的情况下,如何确证上下游之间是否存在因果数据流?
TraceCompiler 将这一过程正式形式化为受限环境下的工作流编译问题,通过聚类、去噪、参数来源推断与符号化验证,最终输出由起始节点(START/END)、外部工具节点(TOOL)、确定性变换节点(TRANSFORM)、控制分支节点(DECISION)、兜底大模型节点(LLM)以及人工介入节点(HUMAN)构成的类型化有向无环图(DAG)。
核心机制:把“试错痕迹”剥离为可执行定义
TraceCompiler 的编译管线包含四个递进的核心阶段,旨在把“探索过程中的偶然历史”与“任务本身的必要结构”彻底剥离。
1. 意图聚类:保留调用拓扑的无监督汇聚
编译的前提是找到同一个任务的多条不同执行记录。论文采用了一种特殊的文档嵌入表征:不仅包含初始的用户 Prompt(赋予双倍权重以突出任务意图),还将每一轮推理的精简摘要与规范化后的工具调用交织在一起。这种交织方式保留了程序执行的拓扑顺序,避免了将工具简单视为“词袋”所造成的信息丢失。
随后系统采用平均联结的余弦距离层次聚类,并设定了一个保守的高相似度阈值(0.45)与最小支持频次下限(5 条)。作者明确指出,在工作流挖掘中,“欠聚类”(Under-merging)的危害远小于“过聚类”(Over-merging):如果同一个意图被错误地拆成了两个聚类,系统最多只是分别编译出两个各自可行的工作流;但如果把两种不同的业务逻辑强行混入同一个聚类,编译引擎就会在错误的拓扑中提取出相互矛盾的数据依赖,直接破坏工作流的正确性。
2. 行为去噪:参数比对破除重复调用迷思
在原始轨迹中,重复出现的工具调用是最昂贵也最易引起混淆的噪音。TraceCompiler 拒绝简单根据调用次数去判断,而是深入参数比对(Argument Comparison)来做细粒度分类:
-
重试噪音(Retries):如果连续多次调用同一接口,其参数在细微调整后最终成功,系统判定这是 Agent 的参数调试过程,自动塌缩(Collapse)为最后一次成功调用。
-
真实并发展开(Fan-out):如果调用同一接口多次,但每次传入的业务实体具有系统性差异(例如针对检索到的 5 首歌分别调用详情接口),系统识别其为遍历操作,编译为并行的映射执行。
-
分页循环(Pagination Loop):如果参数中只有形如
page_index的游标字段以 0、1、2 递增,其余查询参数完全静态,系统识别其为循环结构,而非独立调用或复杂数据依赖。 -
文档探测与死读(Schema Discovery & Dead Reads):Agent 在调用前频繁执行的只读查询,如果其返回内容从未在后续步骤的参数中被消费,直接在编译期剔除;若属于固定的环境元数据,则移至编译期静态处理。
3. 参数级依赖验证:基于“排除法”的硬边确立
这是整个系统最具形式化严谨性的环节。对于执行顺序上先于 $b$ 的工具调用 $a$(记为 $a \prec b$),TraceCompiler 规定:只有当 $b$ 的某个参数所绑定的值 $v$,能够证明唯一且排他地由 $a$ 产生时,才允许建立有向边 $a \rightarrow b$。
确立这一硬依赖需要同时满足两个条件:
-
消费端参数 $v$ 能够追溯到 $a$ 的产物;
-
彻底排除 $v$ 的其他一切潜在来源——包括用户的原始输入、预埋的静态上下文、工具 Schema 的默认缺省值,以及在 $b$ 之前调用的所有其他接口的输出。
只有成功完成这套“排除法证明”,该数据流依赖才会带上可审计的证据元组(Evidence Tuple)被固化为执行图中的硬边;如果存在歧义或候选者无法唯一排除,该依赖就会被降级标记为 suspected(疑似),并且不施加任何运行时执行顺序约束。
4. 参数来源分类与静态上下文注入
确定了依赖拓扑后,工作流中的每个参数绑定都会被划归为五种行为类型之一:
-
constant:跨轨迹完全稳定,且不能由请求文本解释的值(如组织固定的网关配置); -
user_input:直接提取自用户的运行时输入; -
copy_edge:严格经过上述验证的上游工具输出传递; -
transform_edge:经过可确定的字符串截取、列表提取等轻量转换后的数据流; -
llm_or_dynamic:真正包含开放语义决策、必须在运行时由大模型即时判断的动态槽位。
特别值得一提的是,对于 constant 类型,TraceCompiler 甚至可以在构建期直接执行一次只读探索,把解析出的静态值固化下来,在运行时彻底封禁那些文档探测接口。这种方式不仅大幅减少在线调用,更让编译出的流程高度接近传统软件系统的确定性管道。
实验检验:数据依赖的恢复精度与调用削减
为了验证这套机制的真实表现,论文在合成旅行基准 T1 与开放真实智能体评测集 AppWorld 上进行了双重检验。
1. 依赖识别精度:完胜基于邻接与频次的基线
在 T1 基准上,系统需要从包含 15,775 条真实定义-使用(def-use)依赖边的训练集中恢复因果拓扑。作者对比了三种方案:直接邻接基线(只要连续出现就建边)、设定频次阈值的直接跟随矩阵(Directly-Follows),以及 TraceCompiler 的机械化依赖验证规则。
结果显示,简单的邻接基线与频次基线在面临复杂 Agent 轨迹时,F1 分数仅在 0.711 到 0.712 左右徘徊,产生了海量的伪依赖。而 TraceCompiler 的参数依赖规则在不需要预知流程模板的前提下,取得了 0.928 的精确率 和 0.943 的召回率。更进一步,当由高水平大模型完全按照该规则技能进行“盲测”推理时,在抽样的 250 条依赖边上取得了 0.992 的精确率。这证明了通过参数来源排除法建立的因果依赖,具有极高的理论可信度。
2. 全局冗余调用到底有多少?
许多人直觉上认为 Agent 多调一两次工具无伤大雅,但作者对 AppWorld 覆盖的全部 56 个复现业务场景(共计 14,128 次工具调用)进行了全局量化统计:
在排除了正常的并发展开(Fan-out)后,仅统计“纯 Schema 文档探测”与“同一实例内传入完全相同参数的重复死读”两类无可争议的无用调用,每个场景下可直接消除的冗余调用比例中位数高达 51.4%(四分位间距 IQR 为 41.9%–74.1%)。在 56 个场景中有 33 个场景的无用调用超过了半数。这表明,当下主流的大模型在自主探索时,超过一半的开销消耗在了无效的重复尝试与环境摸索上。

3. 真实案例分析:Venmo 转账与安全拒绝编译
论文对 AppWorld 中最具代表性的两个多应用协同场景进行了端到端的实际编译与运行检验。
第一个场景是通过 Venmo 发起收款请求。三个历史实例在未编译前共产生了 34 次 API 调用,其中包含了大量的权限探测、失败凭证重试以及对好友列表的分页读取(page_index 从 0 递增到 2)。TraceCompiler 成功将重试折叠为单一逻辑鉴权,将多次分页规约为循环活动,并将跨应用提取的 access_token 固化为显式依赖边。
在热启动(Warm Session,即已持有会话 Token)的运行环境下,三个实例在编译后分别只需要 3 次、3 次和 5 次底层 API 调用(第 3 个实例的 5 次调用如实计算了分页循环发出的 3 次底层请求),总调用量从 34 次直降至 11 次,整个图谱中最终仅保留了 1 个负责解析转账对象的 LLM 决策节点。
更为关键的是留一交叉验证(Leave-One-Out)实验:如果把三个实例中的某一个扣留,仅用另外两个编译出的工作流去执行被扣留的实例,结果如何?
在 21 项状态测试中,工作流成功通过了 15 项。当扣留实例 1 或 3 时,剩余两个实例覆盖了收款人解析的全部路径,被扣留实例均获得满分通过(7/7)。而当扣留实例 2 时,因前两个实例均通过“好友列表”解析收款人,工作流从未学习过外部收款人分支;在面对实例 2 的未收录收款人时,工作流没有盲目猜测或胡乱调用,而是触发阻断安全升级(Escalate),拒绝执行转账,测试得分为 1/7。
第二个场景是抓取 Todoist 代办列表并同步至 Spotify 歌单。在这一任务中,编译引擎表现出了另一种关键能力——拒绝编译(Refusal to Compile)。由于 Agent 留下的探索轨迹未能完全确定歌曲添加操作的不可逆外部副作用(例如无法明确是覆盖播放列表还是追加),在存在歧义的数据绑定面前,TraceCompiler 宁可放弃生成可执行图,直接向人工报警。对于涉及外部资产、隐私与支付的高危场景,这种“无法证明安全就不编译”的防御性设计,正是工业落地最急需的底线约束。
工程反思与范式转移
读完整篇论文,最值得技术从业者关注的不仅是指标上的提升,更是其体现出的一种工程哲学转变。
过去一年中,业界对 Agent 的优化很大程度上停留在“动态适应”上:给大模型更长的上下文窗口、更密集的反馈强化学习(RL),让它在环境里越来越能“随机应变”。但这篇工作提出了一个完全相反的视角:大部分企业级重复任务根本不需要每次都去“随机应变”。既然 Agent 已经通过昂贵的探索踩平了业务系统的接口坑洼,那就应该把这些被证据支撑的路径收敛固化下来,让它回归为一个确定性、低成本、高并发且完全可审计的传统软件管道。
当然,TraceCompiler 目前依然有其明确的边界。作者在论文中非常诚实地指出了几项未决问题:
-
论文目前主要度量了运行时 API 调用的显著压缩,但并未将离线编译阶段消耗的大模型 Token 与算力计入 ROI 成本核算,因此并不能简单等同于“总体系统开销下降”,它更适用于长尾高频调用的业务流;
-
系统的顶层路由器(Router)依然依赖于用户 Prompt 的相似度匹配,如果路由器发生了假阳性分发(误把 A 任务派发给了 B 工作流),在涉及资金变更等危险操作时依然潜藏风险;
-
它的第一版实现依然封装为一个版本化的大模型“技能”(LLM Skill)而非纯符号化的解析器,虽然通过五轮对抗性审查进行了规则冻结,但在极端分布外输入下的稳定性依然依赖底层模型的指令遵循水准。
从无序的 Prompt Engineering,到脆弱的 Replay 脚本,再到如今具备参数验证与安全性证明的“轨迹编译器”,Agent 的开发形态正在向传统软件工程的经典范式靠拢。把探索留给离线的大模型,把确定性还给线上的代码——这或许是大模型真正融入现代企业软件基础设施的最务实路径。