从 Trace 里评估 Agent:结果、轨迹、效率与安全的工程实践

在这里插入图片描述
👤 个人主页:zzz_2368
🧪 系列主题:Agent 评测|从结果、轨迹到持续迭代
🔥 热门专栏:Agent | 小z的碎碎念 | Java后端
📚 本系列内容:评测体系、Rubric、Good Case、Bad Case、Trace 与长程 Agent

系列第 7 篇|上一篇:Agent 评测不能只看 Pass@1

上一篇讨论了 Lucky Pass:最终任务通过,不代表过程可靠。要识别盲目重试、越权调用、错误恢复失败和无效循环,首先需要一份能够被机器分析的执行记录,也就是 Trace。

这里的 Trace 指 Agent 运行过程中可观察的输入输出、工具调用、工具返回、状态变化、错误和资源统计。它不等于模型的隐藏思维链,也不要求系统保存模型未主动输出的内部推理。



一、为什么普通应用日志不够用

传统接口日志通常长这样:

2026-08-12 10:00:01 request started
2026-08-12 10:00:09 request finished, status=200

它只能说明接口返回成功,无法回答:

  • Agent 选择了哪些工具;
  • 工具参数是否正确;
  • 是否重复调用同一工具;
  • 哪一步开始偏离任务;
  • 最终外部状态是否真的改变;
  • 失败来自模型、工具还是环境;
  • 任务通过是否只是 Lucky Pass。

一份适合评测的 Trace 必须把“运行发生了什么”转换成结构化事件。Anthropic 在 Agent 评测工程说明中强调,应结合结果、Transcript/Trace 和多个 Grader,并通过阅读轨迹校准评分器是否公平。

二、最小 Trace Schema

先不要追求一套覆盖所有框架的庞大协议。对于多数工具型 Agent,下面这些字段已经可以支持第一版评测:

{
  "run_id": "run-20260812-001",
  "task_id": "refund-017",
  "trial_id": 2,
  "timestamp": "2026-08-12T10:00:03+08:00",
  "event_type": "tool_result",
  "step": 4,
  "tool_name": "query_order",
  "tool_call_id": "call-004",
  "input": {"order_id": "masked-order-id"},
  "output": {"status": "paid"},
  "error": null,
  "latency_ms": 238,
  "token_usage": {"input": 0, "output": 0},
  "environment": {
    "image": "agent-eval@sha256:example",
    "benchmark_version": "2026-08-12"
  }
}

推荐至少统一以下事件类型:

事件 含义 主要用途
run_start 一次 Trial 开始 关联任务、模型和环境
model_output 模型输出可观察动作或回复 检查格式和决策结果
tool_call Agent 发起工具调用 参数、权限、顺序评测
tool_result 工具返回结果 错误恢复和延迟分析
state_change 外部状态发生变化 审计副作用
checkpoint 阶段性验证 长程任务恢复和进展评分
run_end Trial 结束 关联 Outcome 和总成本

run_id + trial_id + step 应能恢复事件顺序,tool_call_id 应能关联调用和返回。涉及用户数据时要先脱敏;Trace 不是把敏感信息复制到另一个系统的理由。

三、四类评分器怎样读取同一条 Trace

1. Outcome Grader:检查最终状态

最终回复“退款已完成”不是证据。Outcome Grader 应直接读取模拟数据库、文件系统或测试 API:

def grade_outcome(final_state):
    return (
        final_state["refund_status"] == "completed"
        and final_state["refund_amount"] == final_state["expected_amount"]
    )

Outcome 通常是最适合确定性检查的一层。

2. Trajectory Grader:检查执行路径

轨迹评分不应要求唯一标准路径,而应检查必要约束和明显错误模式:

def grade_trajectory(events):
    tool_calls = [e for e in events if e["event_type"] == "tool_call"]
    names = [e["tool_name"] for e in tool_calls]

    queried_before_refund = (
        "query_order" in names
        and "create_refund" in names
        and names.index("query_order") < names.index("create_refund")
    )
    no_duplicate_refund = names.count("create_refund") <= 1
    return queried_before_refund and no_duplicate_refund

这里允许 Agent 在查询订单前先读取政策,也允许它使用不同的检索工具;只限制必须先核对订单、不得重复退款。

3. Efficiency Grader:检查预算

效率层可以直接聚合:

def grade_efficiency(events, max_calls=8, max_latency_ms=15_000):
    calls = sum(e["event_type"] == "tool_call" for e in events)
    latency = sum(e.get("latency_ms", 0) for e in events)
    return calls <= max_calls and latency <= max_latency_ms

阈值必须按任务难度分层。让复杂任务与简单任务共享一个工具调用上限,通常会制造错误结论。

4. Safety Grader:检查禁止行为

def grade_safety(events):
    forbidden = {"delete_account", "export_customer_profile"}
    return not any(
        e["event_type"] == "tool_call" and e["tool_name"] in forbidden
        for e in events
    )

高风险动作不建议与其他分数取平均。只要越权、泄密、重复支付等阻断条件发生,整个 Trial 就应失败并进入审计。

四、Run、Trace 和 Thread 三个粒度

LangChain 的 Agent Evals 资料将评测粒度区分为 Run、Trace 和 Thread,这种拆分对实际系统很有帮助:

粒度 示例 适合检查
Run 一次模型调用或工具调用 参数、延迟、格式、错误
Trace 完成一个任务的完整运行 结果、路径、预算、风险
Thread 跨多轮会话或多个任务 记忆、一致性、用户状态

例如,“工具参数是否合法”属于 Run 级;“是否完成退款”属于 Trace 级;“是否记住用户此前拒绝自动续订”则属于 Thread 级。把所有评测都塞进单条模型调用,会丢失长期状态;把所有问题都提升到 Thread 级,又会增加分析成本。

五、如何从 Trace 定位第一个偏离点

只给失败任务打标签还不够。一个更可操作的方法是标记 first divergence point:轨迹第一次偏离可接受行为边界的位置。

Step 1 读取退款政策       正常
Step 2 查询订单状态       正常
Step 3 将“已取消”误读为“已支付”  <-- 第一个偏离点
Step 4 创建退款           后续错误
Step 5 重试退款           连锁错误

定位第一个偏离点后,修复对象会更清晰:

  • 模型误读工具结果:调整结果 Schema、提示或模型;
  • 工具返回字段含糊:修改 Tool Contract;
  • 权限检查缺失:在 Harness 增加阻断规则;
  • 任务本身描述不清:修订评测样本;
  • 评分器错误:修正 Grader,而不是“优化”Agent 去迎合错误答案。

AgentLens 的价值也在于不只看最终测试,而是分析轨迹质量、浪费行为和偏离点。论文与项目说明见 Microsoft Research

六、用 Inspect AI 组织可重放评测

英国 AI Security Institute 的 Inspect AI支持内置 Agent、自定义 Agent、外部 Agent Bridge、多 Agent 和软件工程 Agent 评测。它还提供:

这些能力说明,Trace 不只是观测页面里的瀑布图,还应服务于重放、恢复、评分和版本比较。不过具体功能可能随 Inspect 版本变化,使用前应以当前官方文档和发布说明为准。

七、生产 Trace 的五个常见坑

1. 只记录成功路径

失败轨迹更有诊断价值。超时、解析错误、权限拒绝和工具异常都应保存为结构化事件。

2. 把模型回复当 Outcome

模型的“已完成”只是 Response。最终状态必须由系统或测试夹具独立读取。

3. 无限制保存原始参数

工具参数可能包含邮箱、订单、文件内容和 Token。应设计字段级脱敏、访问控制和保留周期。

4. Trace Schema 经常变化却没有版本

字段变更会破坏历史回放和指标比较。建议为 Schema、Agent Harness、任务集和评分器分别记录版本。

5. 用 LLM Judge 替代所有规则

能用数据库约束、JSON Schema、文件哈希或单元测试判断的内容,应优先使用确定性 Grader。模型裁判更适合开放式表达、策略合理性等难以规则化的部分,并需要人工样本校准。

八、最小落地顺序

如果现有 Agent 完全没有 Trace,可以按以下顺序建设:

第一阶段:run_id + task_id + tool_call/tool_result + run_end
第二阶段:加入 Outcome 快照、错误类型和成本字段
第三阶段:加入 Trajectory、Safety、Efficiency Grader
第四阶段:多 Trial 聚合、失败聚类和回归门禁
第五阶段:Checkpoint、重放和 Thread 级长期评测

这个顺序优先保证证据可用,再增加复杂评分。不要一开始就建设庞大的观测平台,却没有明确 Task 和成功标准。

九、结论

Trace 的作用不是让日志看起来更丰富,而是把 Agent 评测从“相信最终回复”升级为“检查可观察证据”。

一条可评分的 Trace 至少应该回答:

  1. Agent 调用了什么;
  2. 工具真实返回了什么;
  3. 外部状态如何变化;
  4. 第一次偏离发生在哪里;
  5. 最终结果、成本和安全是否通过。

下一篇将讨论另一个容易被 Trace 揭露的问题:Agent 失败可能并不是模型能力差,而是 CPU、内存、超时、网络和沙箱配置改变了结果。

参考资料

  1. Anthropic:Demystifying evals for AI agents
  2. Microsoft Research:AgentLens
  3. Inspect AI:Agents
  4. Inspect AI:Checkpointing
  5. LangChain:Evaluating AI Agents at Run, Trace, and Thread Level
  6. LangChain Agent Evals 文档

感谢阅读,记得点赞、关注、收藏,欢迎各位评论区交流!!!

btw:祝我生日快乐
在这里插入图片描述

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐