学习笔记 · Obsidian

汇总、配对、测试框架与 Judge 校准

LangChainLangSmith

三类评估输出

Row-level

每个 example 产生独立 feedback,适合 correctness、格式、单步工具选择等。它能定位个案,但不能直接给出 F1、总体召回率或跨样本一致性。

Summary

Summary evaluator 一次接收整组 inputs、outputs、reference outputs,或完整 runs/examples,适合 F1、precision、recall、通过率和分布指标。它只能在完整离线 experiment 后计算。

Python 和 TypeScript 都可返回带 metric name/score 的字典;直接返回数值目前只有 Python 支持。文档示例存在函数名不一致等教学瑕疵,实践中应对 summary evaluator 做独立单测,并显式处理空分母、缺失 reference、类别不平衡和部分失败。

Pairwise

Pairwise evaluator 比较两个既有 experiment 的同一 example 输出。Python LangSmith 0.2.0 以上、TypeScript 0.2.9 以上;evaluate_comparative 可扩展到两组以上。

关键参数:

  • randomize order 默认关闭,用于缓解位置偏差;
  • max concurrency 默认 5;
  • load nested 默认关闭,只有需要 child runs 时开启;
  • evaluator 返回 run ID 到 score 的映射最稳妥,feedback key 建议加 pairwise_ 或 ranked_ 前缀。

Judge 仍可能偏好更长、特定风格或熟悉名字。应在 prompt 中明确忽略顺序和长度,并用双向顺序、人工偏好集和 tie 率审计。Pairwise 能说明相对偏好,不能证明胜者达到绝对安全或正确标准。

OpenEvals 与 AgentEvals

OpenEvals 提供预置 judge 工厂和 prompt,AgentEvals 提供 agent/trajectory 工具,可用于快速建立基线。它们既能在 pytest/Vitest/Jest 中自动记录 feedback,也可直接传给 evaluate;Python 直接传 evaluate 要求 LangSmith 0.3.11 以上。

预置 prompt 只是起点:

  • 检查 prompt、model、feedback key 和输入字段版本;
  • 用领域人工标注集验证;
  • 对安全、合规和财务判断保留确定性检查;
  • 升级 package 时重跑校准集,避免默认 prompt 变化造成指标漂移。

Pytest 集成

Python 插件要求 LangSmith 0.3.4 以上。每个带 pytest.mark.langsmith 的 test 会同步为 dataset example;每次 test suite 运行创建 experiment,并自动记录 pass feedback。

适合场景:

  • 不同 example 需要不同测试逻辑;
  • 既要记录连续质量指标,又要让 CI 通过 assert 失败;
  • 已有 pytest fixture、parametrize、async、xdist 或 watch 工作流。

数据记录规则:

  • log inputs、outputs、reference outputs 重复调用会覆盖前值;
  • test function 参数默认当 inputs,可通过 output_keys 标为 reference;
  • trace_feedback 内必须包含对应 log_feedback,才能关联 judge trace;
  • 默认按测试文件分 dataset,推荐 LANGSMITH_TEST_SUITE 汇总整个执行;
  • experiment metadata 的 session fixture 优先于环境变量;系统 revision/Git metadata 又优先于用户字段。该能力要求 LangSmith 0.7.13 以上。

缓存可通过 LANGSMITH_TEST_CACHE 保存 HTTP 请求;0.4.10 以上可按 URL/host 选择性缓存。Cassette 可能包含 prompt、输入、输出、header 或敏感业务数据,不能因为“用于测试”就直接提交仓库。必须先审查、脱敏、限制文件权限,并确保 cache key 覆盖影响模型响应的参数。

其他边界:

  • rich output 不兼容 pytest-xdist,且会隐藏标准 pytest 输出;排错时回到普通输出。
  • 0.3.3 及以前的参数名是 output=langsmith,新版本用 langsmith-output。
  • LANGSMITH_TEST_TRACKING=false 是 dry run,只阻止同步,不会阻止 target 自身访问外部模型或产生副作用。
  • parametrize 很大时改用 evaluate,以获得并发和 experiment 控制。

Vitest/Jest 集成

JS/TS 集成要求 LangSmith 0.3.1 以上。测试必须:

  • 从 langsmith/vitest 或 langsmith/jest 导入 describe/test;
  • 所有 test 放在 describe 内;
  • 使用额外参数声明 inputs 与 expected outputs;
  • 通过 logOutputs 或返回值记录实际输出。

建议把 eval 文件限定为 .eval.ts,并使用独立 config/reporter,避免改变普通单测行为。JSDOM 当前不支持,只能使用 Node 环境。Vitest 默认 watch 会重复触发昂贵 LLM 调用,因此 eval script 应显式关闭 watch。

差异:

  • wrapEvaluator 会把 judge trace 与主应用 trace 分开,并可把 key/score 自动写为 feedback。
  • Vitest 支持从现有 LangSmith dataset 拉 examples 后传给 test.each;该入口不适用于 Jest。
  • test function 直接 return 输出时,如果 assert/error 先失败,输出不会记录;需要故障证据时先 logOutputs。
  • process.env 中 ENVIRONMENT、NODE_ENV、LANGSMITH_ENVIRONMENT 会自动写入 experiment metadata,注意不要把敏感环境名或内部拓扑无意暴露给共享 workspace。

Harbor:容器化 agent benchmark

Harbor 把每个 trial 放进隔离容器,并与 LangSmith 在三处集成:

  1. plugin langsmith:把 job 同步成 dataset、experiment、trial runs、verifier feedback、token 和成本;
  2. agent langgraph:把 LangGraph/Deep Agent 作为 Harbor agent;
  3. env langsmith:每个 trial 使用独立 LangSmith sandbox。

前置要求是 Python 3.12 以上和 harbor[langsmith]。凭据可通过 LANGSMITH_API_KEY 或 SDK profile 注入,禁止写入 task 或镜像。

Plugin 即使 agent 不做 LangSmith tracing,也会生成 dataset/experiment 和结果,只是没有完整 agent trace。默认遇到 LangSmith API 失败会继续 Harbor job;生产 CI 应按重要性选择 fail-fast,并监控“benchmark 完成但结果未同步”的分裂状态。

Task 与执行模型

Task 包含 task.toml、instruction、Dockerfile/environment、tests/verifier,可选 solution;dataset 是多个 task。远程 task 按固定 commit 缓存在本地,local path 原地读取。trial 数量是 attempts × tasks × agents,并在并发上限内运行,支持 retry。

LangGraph agent 要求:

  • model 使用 provider:model 且已安装对应 langchain provider;
  • project path 中有 langgraph.json,指定 graph entry 与依赖;
  • dependency overrides 会替换声明依赖,不是追加;
  • configurable/model kwargs 进入运行配置,应做 schema 校验,不能允许 benchmark 输入任意改变安全策略。

每个 trial 会构建/启动环境、上传 project、安装依赖、运行 agent 和 verifier,再删除容器。容器隔离不自动保证安全:仍要 pin image digest/package、最小化网络与密钥、限制 CPU/内存/超时、审查 task 和 verifier、避免把不可信 solution 暴露给被测 agent。

LangSmith sandbox 可从预构建镜像、已有 snapshot 或 Dockerfile 创建。idle TTL=0 会关闭空闲停止;delete-after-stop 控制停止后的删除延迟,都会影响成本和敏感数据驻留。

用人工反馈校准 Judge

Align Evaluator 流程:

  1. 从 offline experiments 或 online runs 选择代表样本;
  2. 送入 annotation queue,由领域专家标注;
  3. 在 Evaluator Playground 对比 judge 与人工标签;
  4. 分析不一致、更新 rubric/prompt、保存并重复。

推荐至少从 20 个多样样本开始,并平衡正负标签。Alignment score 只是与当前标注集一致的百分比,不代表泛化质量;必须保留未参与 prompt 调优的 holdout 集,按场景和风险切片看表现,审查 annotator 一致性。

Evaluator Playground 的 prompt 更新默认不会自动保存。每次提升后应明确保存版本,否则比较基线可能仍是旧 prompt。

Corrections 与 few-shot

人工可在 comparison view、run table 或 SDK update feedback 的 correction.score 修正 judge 评分,并附解释。解释可自动进入 few-shot example 的 few_shot_explanation。

Few-shot 限制:

  • 只支持 Mustache prompt,不支持 Prompt Hub judge;
  • 只支持 run-level evaluator,不支持 thread-level;
  • prompt 变量必须包含主 prompt 变量、few_shot_explanation 和与 feedback key 同名的 score;
  • 默认插入 5 个,数据更多时随机选择;长 example 应减少数量控制 token;
  • correction 写入 dataset 可能延迟 1–2 分钟。

随机抽 few-shot 会引入运行间差异;若要发布门可复现,应固定校准 dataset 版本、样本策略、model/prompt,并定期审计 token 成本。Correction dataset 本身可能含生产输入输出和人工解释,权限与保留策略应等同敏感测试数据。

可落地的分层流水线

  1. 本地/PR:Code assertions + 小型 pytest/Vitest/Jest 套件,默认 dry-run 或受控 cache。
  2. CI:固定 dataset/version,执行 row evaluators、summary metrics 与关键 pairwise 回归。
  3. 大型 agent benchmark:Harbor 隔离环境,多 attempts,记录 reward、error、token、成本和依赖版本。
  4. 人工层:抽样审计 judge 分数、维护 correction/holdout 集。
  5. 发布后:线上 evaluator 发现新失败,回流 dataset,再做 backtest。

每层都要能回答“哪条证据失败、是否可重现、是否有副作用、费用多少”,而不仅是给出一个总分。