Skip to content

可观测性与测试

Deep Agents 的测试对象不只是最终文本,还包括规划、工具参数、文件变化、subagent 委派、审批和失败 恢复。先用确定性 fixture 验证边界,再用少量真实模型样本评估质量,才能把偶然的“看起来能跑”变成 可回归的工程证据。

测试分层

层级主要问题推荐证据是否需要真实模型
纯函数单测权限、schema、路径和解析是否正确输入/输出断言
工具单测工具是否鉴权、幂等、处理错误本地 fixture、fake client
Agent 集成测试是否选择正确工具并形成预期轨迹scripted/fake model、状态与 tool-call 断言
离线 Evaluation结果、轨迹和安全质量是否达标固定 dataset、规则或 rubric可选
线上监控真实分布中是否退化trace、采样 evaluator、告警

前端类比

这类似测试一个 Redux + effects 应用:组件快照只覆盖最终 UI,仍要验证 action、effect、缓存和错误 分支。Agent 的最终回答相当于 UI,tool calls、state 和 artifacts 才是中间行为。

Deep Agents 原生语义:Harness 编译为 LangGraph 图。一次 run 会经过模型、middleware、tools、 subagents 与 checkpoint;测试可以在这些边界断言轨迹,不应依赖模型逐字复现同一答案。

无模型费用的确定性单测

先把安全策略写成普通函数并覆盖边界值。下面只运行本地 Python,不创建 Agent,也不访问网络:

python
from pathlib import PurePosixPath


def may_write(path: str) -> bool:
    normalized = PurePosixPath("/" + path.lstrip("/"))
    if ".." in normalized.parts:
        return False
    return normalized == PurePosixPath("/workspace") or PurePosixPath(
        "/workspace"
    ) in normalized.parents


def test_workspace_policy() -> None:
    assert may_write("/workspace/report.md")
    assert not may_write("/memories/policy.md")
    assert not may_write("/workspace/../secrets.txt")

真实工具仍要在服务端重新校验 trusted identity、资源 owner、参数上限和幂等键;不要把这一函数当作 完整授权实现。

Scripted Model 与确定性工具

仓库测试可使用 scripted/fake chat model 依次返回预设 tool call 和最终消息,并让工具读取本地 fixture。这样可以稳定验证:

  • write_todos 是否出现在复杂任务轨迹中。
  • 某个业务工具是否收到经过 schema 校验的参数。
  • 文件结果是否写到预期虚拟路径。
  • subagent output 是否回到主 Agent,而详细消息没有污染主上下文。
  • tool error 是否走预期恢复分支。

fake model 的具体测试类属于 LangChain/Deep Agents 当前测试支持面,名称可能随版本变化。应锁定依赖 版本并参考仓库同版本测试,不把内部 helper 当成稳定公共 API。

轨迹断言不要过度拟合

优先断言不变量:

python
tool_names = [call["name"] for call in captured_tool_calls]

assert "fetch_fixture" in tool_names
assert tool_names.count("publish_report") == 1
assert all("api_key" not in call["args"] for call in captured_tool_calls)

除非顺序本身就是业务契约,否则不要断言每一步完全相同。模型升级可能选择等价顺序,但以下行为 通常必须失败测试:越权工具、缺少引用、重复副作用、跳过强制审批,以及把秘密写入 trace/artifact。

Evaluation:结果、轨迹与安全

维度示例指标适合的 evaluator
Outcome结论是否回答问题、结构是否完整规则、参考答案、人工或 LLM rubric
Trajectory工具选择、参数、委派和重试是否合理代码规则、轨迹 matcher
Grounding每项关键结论是否有可追溯来源引用覆盖率、来源核验
Safety是否触发禁用工具、泄漏秘密或越过审批确定性规则、对抗用例
Efficiency模型/工具调用、token、耗时是否超预算trace 聚合阈值

先用 5–10 个手工策划的关键样本定义“好”,再扩展 dataset。LLM-as-judge 适合主观质量,但必须固定 rubric、记录 judge 模型版本,并用人工校准;路径、schema、权限和引用存在性优先用代码规则。

Tracing 与隐私

启用 LangSmith tracing 时只从部署环境注入配置,不把真实值写进仓库:

bash
export LANGSMITH_TRACING=true
export LANGSMITH_PROJECT=deepagents-staging
# LANGSMITH_API_KEY 由 secret manager 注入

Trace 能串联模型、工具、subagent 和延迟,适合定位循环、重试与上下文膨胀。上线前仍要明确:

  • 哪些 message、tool args/result 和附件允许发送到观测系统。
  • 如何脱敏 PII、凭据、用户文件和 sandbox 输出。
  • trace 保留期、租户访问控制和删除流程。
  • 在线 evaluator 的采样率、费用预算和告警阈值。

不使用 LangSmith 也应输出结构化 run/thread/tool 指标;可观测平台是实现选择,不是 Agent 正确性的 前提。

Beta Runtime Rubric

Python deepagents>=0.6.5 提供 Beta RubricMiddleware:它使用单独的 grader model 检查调用时传入的 rubric,在 needs_revision 时把逐项反馈送回工作 Agent,直到满足、失败或达到 max_iterations

这与离线 evaluation 的职责不同:runtime rubric 影响当前 run 的迭代,离线 evaluation 比较固定 dataset 上的版本。它会产生额外模型调用,不能替代确定性权限检查;应设置迭代上限、记录 grader 模型版本,并把 path、schema、引用存在性等机械规则留给代码 evaluator。

回归门禁

  1. PR:纯函数、工具、scripted model 与恶意输入测试全部通过。
  2. 预发布:固定 dataset 运行离线 evaluation,与基线比较 outcome、safety 和 cost。
  3. 灰度:检查失败率、p95 延迟、循环上限、HITL reject 率与 sandbox 异常。
  4. 生产:把失败 trace 脱敏后沉淀为新的离线样本,验证修复再发布。

先修

下一步

官方参考

学习文档整合站点