博客

Agent 轨迹分析与归因的数据工程实践

avatarDatabendLabs6月 22, 2026
Agent 轨迹分析与归因的数据工程实践

AI Agent 落地,如何攻克稳定性、成本与评估难题?

本文根据张雁飞在 Databend 社区活动的演讲实录整理而成,围绕“Trace 即 Evals”展开,系统梳理了 AI Agent 从 Prompt Engineering、Context Engineering 到 Harness Engineering 的演进,以及为什么 Agent 的稳定性、成本归因和效果评估,必须建立在完整执行轨迹之上。文章用 Claude Code、Evot、Pi 等 Agent 对比案例,讲清楚了 Agent Trace 为什么不同于传统 Trace,以及 Databend 如何用对象存储、VARIANT、加速列、全文检索和 Stream/Task 构建极简 Trace 存储与分析底座。阅读时间约 12 分钟。

从“存得下、查得出”到“支撑智能决策”

随着大模型和 AI Agent 的跨越式发展,我们能够明显感受到技术范式正在发生变化。很多人在这种变化中会感到焦虑,也希望找到更多突破口。在这样的时代,底层数据基础设施的角色也在改变。过去,我们对数据基础设施的核心要求是:存得下、查得出。而现在,我们更希望它能够支撑智能系统的运行,参与到智能决策和持续优化的过程中。

Databend 是一个云原生数仓。随着大模型的发展,大家对数仓提出了新的需求。Databend 近期正在和国内一些头部大模型厂商合作相关项目,在合作过程中,我们围绕 Agent 轨迹分析与归因做了一些实践和总结。

今天我们换一个视角来看这个问题:一个 Agent 跑了 3 小时,花了 12 美元,最后失败了,却不知道是哪一步跑偏;即使成功了,也不知道是哪一步做对了。下一次换模型、改 Prompt、加 Tool,效果到底变好还是变坏,也很难说清楚。这已经不是 Prompt Tuning 的问题,而是 Harness Engineering 的问题。

本次分享要解决的三个问题

我们今天讨论的核心问题是:怎样才能把 AI 用得比别人更好?本次分享希望解决三个具体问题。

第一,降低 Token 浪费。我们需要看清楚 Agent 哪一步在烧钱、绕路、重复调用。因为 AI 会产生幻觉,幻觉会导致它在执行任务时迷路。对人来说,一个任务可能很简单,几步就能确定路径;但对 AI 来说,它没有人的意识,它看到的上下文,本质上是在一个 Token 接一个 Token 地预测。

第二,让 Agent 更加稳定。对于同一个 Agent 产品,我们需要找到失败、幻觉和质量波动是从哪一步开始的。只有找到原因,才有办法做得比别人更好。

第三,也是大家非常困惑的一点:如果我要做一个 Agent 产品,改了一个 Prompt、加了一个 Tool,或者换了一个模型,怎么量化这次修改的效果?结果到底是变好还是变坏?如果只能凭感觉判断,就无法稳定迭代。

Databend 在和头部模型厂商合作的实践中,总结出一个核心方法:记录 Agent 每一步的执行轨迹,用数据而不是感觉来优化 Agent。这也是模型厂商正在关注的重要趋势。

Agent 工程演进的三个阶段

在进入具体项目实践之前,我们先看一下 Agent 工程演进的三个阶段。

第一个阶段是 Prompt Engineering。ChatGPT 刚出现时,大家主要是在聊天对话框里输入指令,例如进行一次检索、翻译一段文字,或者做一个摘要。这个阶段的核心是调指令、加示例、写思维链,优化的是单次模型调用的输入文本。

第二个阶段是 Context Engineering。进入 2025 年后,大家发现大模型基于通用知识,无法直接结合公司内部文档和知识来回答问题,于是 RAG 技术开始发展起来。模型可以调用公司的文档和知识库,客服助手、知识库问答类 Agent 也随之出现。这个阶段的核心是管理模型每一步应该看到什么,包括 RAG 检索、记忆压缩和窗口调度,优化的是多轮交互中的信息流。

第三个阶段是 Harness Engineering。到了 2026 年,随着 OpenClaw 爆火,大家发现只要给 Agent 一个工具,它就可以主动操作本地电脑,自主执行任务。这个阶段,Claude Code、Codex、Coze 这类 Coding Agent 开始大行其道,Agent 的形态也从单轮问答进入自主任务执行和多 Agent 协作。

发展阶段Prompt EngineeringContext EngineeringHarness Engineering
时间2022-202420252026
特点调指令、加示例、写思维链 — 优化单次模型调用的输入文本管理模型每步该看到什么:RAG 检索、记忆压缩、窗口调度 — 优化多轮交互的信息流围绕模型的整套执行基础设施:状态维护、工具中介、反馈注入、约束执行、进度验证
代表形态Chatbot、单轮问答、翻译 / 摘要RAG 应用、多轮对话助手、知识库问答Coding Agent、自主任务执行、多 Agent 协作

所谓 Harness,就是脚手架工程:我们如何约束 Agent 和模型,让它们做得更好。从我们的观察来看,Harness 包含两大部分。对于做产品的人来说,Harness 是产品框架,目标是让 Agent 跑得更好;对于训练模型的人来说,Harness 是考场,目标是让模型在里面练得更好。

从应用侧看 Harness:让 Agent 可控、可观测、可归因

从应用侧来看,Harness 的目标是把模型变成可控产品。

早期我们直接对接 API,做单轮交互。例如让模型发一封邮件,发送完毕后返回结果。现在,Agent 已经进化到执行复杂的多轮任务。一个任务可能跑几个小时,还涉及权限和成本控制。如果要把 Agent 提供给公司内部使用,就必须观测到每一步任务执行过程,并评估每次改动的结果。

因此,应用侧 Harness 的目标是让 Agent 可控、可观测、可归因,并且能够持续改进。而“改进是否生效”,需要依靠 Eval 来判断。

从模型侧看 Harness:把工具和流程练进模型

从模型侧来看,Harness 的目标是把工具和流程“练”进模型。

以前,外部 Harness 会告诉模型怎么做:工具用法靠 Prompt 描述,上下文压缩靠外部逻辑,执行策略靠脚手架约束。现在,模型开始在真实 Harness 上 Rollout,用 Trace 和 Reward 学习工具调用,把上下文管理和执行策略逐步练进模型。

从我们和大模型厂商合作的实际场景看,仅改 Harness,就可以带来 10 倍性能提升。

举个例子,Cursor 是较早做 Coding Agent 的产品。最近 Cursor 发布了 Composer 2.5 模型,基于 Kimi 训练。它以接近 Opus 十分之一的价格实现了不错的效果,虽然和 Opus 相比可能还有差距,但效果已经相当可观。

为什么它能基于相对便宜的模型和 Cursor 软件做得这么好?原因在于,Cursor 让模型学习如何使用 Cursor。Cursor 本身保留了大量用户使用数据,模型可以学习用户每一步调用了什么工具、采取了什么操作,然后把这些行为模式学进模型里,类似于给模型植入了很强的泛化能力。

例如,Cursor 里有哪些工具,模型遇到某类任务时应该优先使用什么工具,这些偏好会被训练进模型,成为模型权重中更重要的一部分。所以,如果你用 Cursor 调用 Composer,效果会很好;但如果用 Claude Code 或开源的 OpenCode 去调用同一个模型,效果就可能不好。原因是 Composer 学的是 Cursor 里的行为,它已经针对 Cursor 的 Harness 训练好了。

因此,Harness 能力正在逐渐下沉到模型里。模型厂商也知道,这才是它们的壁垒。不是 Harness 消失了,而是模型开始在 Harness 里学习,逐步内化工具使用、上下文管理和长期任务执行。而 Rollout 质量如何判断,同样要看 Trace。

工具名称和大小写为什么会影响效果

只要按照模型偏好的工具行为来设计,上层 Agent 产品甚至不需要太长的 Harness,Prompt 也不需要写得很复杂。

比如 Claude Code 里大概有 20 多个工具。要想让模型表现得像在 Claude Code 中一样,工具名称必须准确,大小写也要一致,工具描述也需要尽可能保持一致。这样调用 Opus 时,效果才会接近 Claude Code 自身的表现。

工具名称的大小写会影响效果。原因在于,Opus 训练时是基于 Claude Code 的。如果某个 Tool 的名称在训练中就是固定大小写,你给它一个小写版本,模型预测下一个 Token 时可能就会出现偏差。这个偏差看起来很小,但在多步 Agent 执行中会被不断放大。

为什么必须展开 Trace

从做 Agent 产品的角度看,大家最终都会遇到同一个问题:我们的改动到底是变好还是变差?

这个问题很难回答,因为 Agent 是一个不确定性系统。大模型会有幻觉,同样一个任务、同样一个软件,不同时间执行,结果可能好也可能坏。

怎样才能说清楚?从我们的实践来看,需要可观测性。也就是说,要把 Agent 和大模型交互的每一步轨迹记录下来,用明确的数据支撑每一步的判断。我们需要知道 Agent 从哪一步开始变坏,或者为什么变好;还要能按步骤对比两次执行的差异,把“哪一步”定位到成本和质量上。

最终,无论是从 Agent 产品视角,还是从模型训练视角,都需要 Trace。Trace 既是 Agent 产品的评测证据,也是模型训练的数据燃料。只有展开完整轨迹,才能把“变好还是变差”说清楚。

一个对比案例:Claude Code、Evot 和 Pi

接下来我们看一个对比案例。三个 Agent 分别是 Claude Code、Evot 和 Pi,它们调用的模型都是 DeepSeek V4 Pro。在这个案例中,Claude Code 执行了 15 分钟,Evot 执行了 5 分钟,开源 Agent Pi 执行了 4 分钟。这里的 Claude Code 调用 DeepSeek V4 Pro,作为一个对比参照。

大家可能会想,Claude Code 本身做得很好,为什么执行时间这么长?是 DeepSeek V4 Pro 这个模型太弱吗?其实不是。我们再看 Claude Code 调用自己的模型 Opus 4.6,同样的任务 3 分钟就完成了。

Agent调用模型Tool Call / 执行时间核心结论
Claude Codeopus 4.6约 30 步 / 3 分 18 秒模型与工具完美匹配,效率高
Claude CodeDeepSeek V4 pro约 60 多步 / 15 分钟 02 秒工具引导对第三方模型不生效,效率低
Evotopus 4.62 分 02 秒通用 agent,没有针对特定模型进行深度适配
EvotDeepSeek V4 pro5 分 38 秒通用 agent,没有针对特定模型进行深度适配
Piopus 4.62 分 38 秒通用 agent,没有针对特定模型进行深度适配
PiDeepSeek V4 pro4 分 48 秒通用 agent,没有针对特定模型进行深度适配

这说明 Claude Code 的 Harness 能力和它自己的模型是高度匹配的。换成别的模型,Prompt、Tool 或其他系统设置就可能让模型在执行过程中迷路,不知道该怎么做。

所以,模型厂商为什么要做自己的 Coding Agent?原因就在这里。它们会把自己的 Agent 行为、工具使用方式和工具描述,与模型预训练结合起来,让 Harness 下沉到模型里。模型知道工具偏好是什么,也知道应该如何配合 Agent。相比之下,Claude Code 调用 DeepSeek V4 Pro 的效果就会差很多。

Image

大家还可以看到,Evot 和 Pi 在调用 DeepSeek V4 Pro 和 Opus 4.6 时,执行时间差距不大。因为这两个 Agent 更偏通用,没有特别针对 Claude Code 或某个模型做深度适配。而 Claude Code 针对 Opus 模型有效,对第三方模型不一定有效。

因此,当你用 Claude Code 调用第三方模型时,效果较差不一定是因为模型差,而可能是 Agent 和模型没有配合好。从模型厂商角度看,它们会把 Agent 和模型训练成一套高度匹配的系统。这也是为什么第三方 Agent 和应用想充分发挥模型能力,会变得更难。

如果 Claude Code 调用 DeepSeek V4 Pro,你会发现执行时间更长,Token 消耗更大,不确定性也更高。如果只看最终结果,不了解背后的机制,就很容易得出“这个模型太差”的结论。但实际上,只看最终结果远远不够,必须展开 Trace,才能知道 Token 烧在哪里、时间慢在哪里、哪一步开始绕路。

Agent 的路径依赖与分叉点

Agent 的差异性来自路径依赖。一次工具调用选择、一次上下文裁剪、一次错误恢复,都会改变后续所有步骤。

展开 Trace 后会发现,差异从 Tool Call 序列就开始了。在三个 Agent 的路径图中,每一个色块代表一次工具调用;有的步骤里有上下两个色块,说明大模型返回了两个并行调用。例如 Claude Code 的第二步,就是两个并行色块。

这说明模型和 Agent 的配合非常重要。如果 Agent 和模型配合得好,并行度就会更高。这个过程类似数据库里的并行执行:并行度上去之后,任务执行时间会缩短,同时质量不一定下降。

Image

Agent 会对模型进行引导,告诉模型下一步要做什么。模型如果经过强化训练,就知道如何和 Agent 配合,执行起来会非常顺畅。在这个过程中,系统会采集大量 Trace,例如用户如何使用、每一步如何拆分,然后让模型学习这些行为。

再看一个分叉点例子。上面一条路径配合得很好,第 4 步选择 Edit,精准修改目标文件,然后一步一步完成任务。下面一条路径第 4 步选择 Bash,输出过多,导致后面绕了 17 步,耗费了更多时间和资源,最后虽然也完成了任务,但过程明显更低效。

Agent 和大模型之间的交互是链式反应。每执行一步,下一步都依赖上一步的结果。执行结果再被交给大模型,大模型再给出下一步动作,如此不断循环,最终得到结果。

Image

大模型本身没有状态,它不会天然维护完整任务状态。所以,只要某一步走错了,你把错误结果作为下一轮输入交给它,后续路径就会不断分叉。

如果我们知道分叉发生在第 4 步,就需要停下来分析:为什么会在第 4 步分叉?是不是 Prompt 的引导让模型在这一步产生了错误选择?分叉点隐藏在完整执行轨迹中,每一步的 Tool、Context、Token 和耗时都必须被存储、查询和对比。

LLM 请求里的 JSON 到底包含什么

很多人看到的是一个 IDE:给 Agent 一句话、一个任务,它就开始来回执行。但底层和大模型是怎么交互的,其实并不直观。我们做量化时,会始终观测这个过程。

一次发给 LLM 的请求里,通常包含系统指令、Agent 具备的工具和描述、Agent 与大模型之间的来回交互,以及每次交互产生的结果。

以前面的 Demo 为例,我们可以看到 Claude Code 调用 DeepSeek 模型的每一步。Claude Code 使用时会先连续发送三个 System 指令,之后返回当前任务名称。因此,Claude Code 的第一步并不真正干活,而是拿到任务标题。

第二步,Claude Code 会把大约 26 个工具,加上我们发出的 Fix Bug 任务,一起交给大模型。大模型返回的是更新后的进度计划。第三步,大模型仍然没有真正干活,而是在继续更新计划,类似于先规划要做什么。

到第四步,大模型才真正开始干活,例如返回要先查看哪个文件。通过这个过程可以看到 Claude Code Harness 的行为:它会先规划任务、明确要做什么,然后引导后续步骤,避免模型跑偏。但这种行为在 DeepSeek V4 Pro 这类模型上不一定生效。模型不熟悉这个 Harness,就可能不知道该如何配合。

如果 Claude Code 调用自己的 Opus 模型,由于模型已经经过强化训练,就会更遵循这个 Harness。它知道应该怎么做,也更“听话”,因为双方训练过,配合更顺畅。这也是为什么调用 DeepSeek V4 Pro 效果较差,而调用 Opus 效果更好。

因此,如果不记录这些 Trace,不观测每一步,就很难发现执行过程到底为什么会跑偏。这个 Demo 里大约跑了 69 步,每一步都可以被观测。可视化之后,人可以看到路径差异;如果让 AI 去跟踪每一步,分析速度会更快。

如果 Pi 这个 Agent 用 32 步完成任务,把 Pi 的 Trace 和 Claude Code 的 Trace 一起交给大模型,大模型很快就能分析出差距和原因。前提是你已经把详细 Trace 数据按各个维度存下来了,包括系统指令、工具描述、调用结果等。

Pi 使用的工具比较少,底层 Agent 框架 OpenCode 里的 Pi 主要使用读、Bash、编辑和写四类工具。Pi 有自己的一套 Harness,系统指令非常简洁,面向通用模型,不特别针对 Opus 或 GPT。因此,Pi 调用 Opus 或 GPT 时,差距不会特别大。

相比之下,Claude Code 的系统组件非常庞大,分为几块,每一块都针对自己的模型做了大量定制。比如 System Reminder,就是给 Opus 这类模型的指令,因为模型已经经过训练,知道如何遵循这些指令。由此可见,Harness 是不同 Agent 产品针对不同模型需要长期打磨的部分。

为什么 Agent Trace 不同于传统 Trace

一次发给 LLM 的请求,本质上是一个很大的 JSON。Demo 中可以看到,Claude Code 的 JSON 非常大,而 Pi 给大模型的 JSON 很简短:System 指令告诉模型“你是一个编程专家”,再加上四个工具和当前任务,整体非常直接。

Image

但到了第二步,你会发现 JSON 变得很长。因为系统必须把第一步完整 JSON 也带上,还要加上第一步的执行结果。第三步,又要把第二步的结果继续塞进新的 JSON 里,拼成一个完整状态。

因此,每一次给大模型的输入,都是前面内容加上新内容,窗口会越来越大。到最后,就需要做上下文压缩。压缩之后再交给大模型继续执行。这就是 Agent 执行的基本机制。

所以,我们需要保存整个 Session 过程中的 JSON,因为它们反映了每一步执行的不同结果。

传统 Trace 记录的是服务调用链,一次请求通常是秒级到分钟级,字段来自 SDK 或 Instrumentation,Schema 相对稳定,分析重点是 Latency、Status 和 Error,很固定也很明确。

但 Agent Trace 更复杂。一个任务可能持续几十分钟到几小时,Span 会持续追加,状态会跨步骤演化。内容来自 Prompt、Messages、Tool Call 和 Tool Result。大模型返回的结果经常不是合法 JSON,字段类型会漂移。分析重点也不再只是延迟和错误,而是 Token、Cost、Tool Choice 以及关键分叉点。

因此,Agent Trace 和传统 Trace 不是一一对应的关系。并不是传统 Trace 做得好的厂商,就一定能做好 Agent Trace。Agent Trace 的挑战是长跨度、大 JSON 和脏数据。真正麻烦的不是“存一条链路”,而是要处理长生命周期任务里的增量事件,把脏的、嵌套的、不断变化的大 JSON 清理、拆解、索引、聚合,并用于归因。

一条真实 Agent Trace 的规模

一条真实轨迹的规模可能非常大:单条 Trace 可以从 500KB 到 500MB,嵌套 3 到 8 层。

例如,一个 Agent Swarm 是集群式的。它先进行分工,分工之后并行执行,执行完之后再由统一的 Agent 做调度和汇总。这样一次任务可能产生约 500MB 数据,执行十几个小时,包含 10 万多个 Span,也就是我们前面说的 10 万多个步骤。

这种量级的 Trace,如果靠人来处理,根本顾不过来。这就是痛点。像 500MB 这样复杂的 Trace,对存储架构提出了很高要求。当脏 JSON 进来时,系统需要回答:怎么清理?怎么拆解?怎么建索引?

最重要的是,先把 Trace 数据存下来。但 Trace 不是存下来就有价值。只有清理、拆解、索引、聚合之后,才能支撑归因、回放和评测。

Agent Trace 数据层需要哪些数据库能力

要做好 Agent Trace,数据库需要具备几类核心能力。

第一,数据库要天然支持 JSON 原生存取。

第二,数据库要具备 JSON 清洗与变换能力。因为真实 Trace 里会有脏 JSON,系统必须有强大的函数能力来处理这些数据。

第三,JSON 索引要足够快。对于几百兆的 JSON,即使能存下来,查询时也不能每次都完整读出来,效率太低。系统需要通过常用索引实现轨迹数据的快速检索。例如 trace_id、model 等字段可以被抽取出来,建立索引,形成单独的 JSON 加速列。

第四,要支持 JSON 内全文索引。全文索引非常重要。比如用户吐槽某个任务执行得差,系统需要根据关键词找到对应对话,把 Trace 拉出来分析,最后判断是否有改进空间。

第五,要满足合规要求,支持 JSON Path RBAC。例如 Trace 中可能包含用户密码等敏感信息,需要按路径进行授权或脱敏。比如 Message 里的某个字段,公司 DA 能看到,业务人员能看到,而其他人不能看到。

第六,Agent Trace 数据巨大,每天可能产生几百 TB 数据,需要长期存储。因此数据库必须支持低成本对象存储。

第七,海量用户和 Agent Swarm 会并发产生 Trace,数据库还需要支持高吞吐写入。

Databend 的极简 Trace 存储与分析路线

大量用户持续使用 Agent,每个人都在不断生产数据,不断写入大 JSON,这对系统是很大的挑战。

Databend 选择了一条极简的 Trace 存储与分析路线。传统路线可能需要源数据、事务型数据库和数仓分别独立建设。而 Databend 的路径是:Trace 生产数据持续写入对象存储 S3,Databend 内部的 Task 从 S3 上完成入库和清洗,清洗后写入 events 表。

整个 JSON 可以写在一张表的一个字段里。这张表可以做全文索引、JSON 加速、脏 JSON 清洗,这些都在同一个表里完成。清洗完之后,Stream 捕获新增 events,驱动后续增量计算。Aggregate Task 自动刷新 traces,全流程无需外部调度器。

Image

最核心的是这张表本身需要具备很多能力。例如 JSON 部分会有物化字段,需要建立物化表;脏数据清洗需要完善的函数能力,并且这些能力都可以通过 SQL 表达。Databend 面向这种场景做了很多增强。

第一,先把数据沉下来,不要只看最终 Pass / Fail,原始 Trace 需要长期保留。

第二,计算能力要跟上。数据存下来之后,还要查得动、算得快。Databend 提供加速列、全文检索和增量聚合能力。

第三,上层按需构建。Eval、Replay、RL 不再各存一套,而是基于同一份 Trace 数据提供多种上层能力。

Image

总结:Trace 是 Agent 可靠性的基础设施

总结来说,要做好 Agent 轨迹分析与归因,需要一个像 Databend 这样的 Trace 存储和计算底座。

它基于对象存储、VARIANT、加速列、Stream / Task 构建,帮助团队在同一份数据上构建上层评测、回放、归因和训练数据。

Agent 的可靠性不会只来自更大的模型,也不会只来自更复杂的 Prompt。真正要把 Agent 从 Demo 推向生产,必须先把每一步 Trace 存下来、查得动、算得快,并能用数据回答:哪一步开始跑偏,哪一步消耗了 Token,哪一次改动真的让系统变好了。

这就是“Trace 即 Evals”的核心。

分享本篇文章

订阅我们的新闻简报

及时了解功能发布、产品规划、支持服务和云服务的最新信息!