学习笔记 · Obsidian
Evaluator 构建、复用、成本与运行边界
先区分“何时评”与“如何评”
离线 evaluation 用有版本的 dataset 做 benchmark、unit test、regression、backtest 和 pairwise comparison;在线 evaluation 在无 reference 的生产流量上做实时质量监控、异常发现与失败样本回流。
Evaluator 是实现机制:
| 类型 | 适合 | 核心限制 |
|---|---|---|
| LLM-as-a-judge | 语义正确性、风格、安全、主观质量 | 非确定、有偏差、有 token 成本 |
| Code | schema、格式、精确值、正则、业务规则 | 只能覆盖可机械定义的条件 |
| Composite | 多指标加权为一个分数 | 权重会隐藏取舍,缺任一 constituent 就不计算 |
| Summary | F1、pass rate 等全实验统计 | 必须拿到完整 dataset,仅离线 |
| Pairwise | 两版本的相对偏好 | 有位置/长度/风格偏差,不能直接解释绝对质量 |
可靠策略通常是 Code 硬约束 + Judge 主观指标 + Summary/切片统计,而不是寻找一个“万能总分”。
Evaluator 是 workspace 共享资源
LLM judge 和 Code evaluator 在 workspace 级创建,可同时挂到多个 tracing project 与 dataset。修改共享 evaluator 会立即影响所有挂载资源的后续运行;Composite evaluator 则绑定具体 project/dataset,不出现在全局 evaluator 表中。
因此需要:
- 名称、feedback key、rubric、prompt/code、model 与版本纳入变更管理;
- 编辑前盘点 Projects & Datasets,变更后做受影响资源回归;
- 删除前必须先 detach;SDK 的 delete_run_rules=true 会连带删除引用规则,是高风险操作;
- 在线 evaluator 的 trace retention 设置会影响存储时长和费用。关闭 Extend trace retention 只影响保存后的新评分 trace,历史 trace 不回退。
管理 API 最低版本为 Python LangSmith 0.9.8、TypeScript 0.7.16。Client 默认从 LANGSMITH_API_KEY 与 LANGSMITH_ENDPOINT 读取凭据,不能硬编码。
SDK 生命周期与可复现性
SDK 支持 create、retrieve、partial update、list、spend 和 delete。
Code evaluator
服务端 evaluator 定义包含 perform_eval 函数源码和 language。通过 TypeScript SDK 创建 evaluator 时,示例仍上传 Python evaluator 代码;“调用 SDK 的语言”与“服务端执行代码的语言”不是同一概念。
LLM judge
服务端 judge 必须引用带 output schema 的 StructuredPrompt。prompt_repo_handle 是内部 repository handle,不是展示标题或 URL;必须同时固定 commit hash/tag、variable mapping 和 model 配置。
runtime 设置 use_corrections_dataset 与 num_few_shot_examples 只有 evaluator 已挂到资源且存在人工 correction 时才生效;update 调用本身不会立即执行一次评估,设置从下一次 run 生效。
列表与费用查询
- list 的 limit 是每页 1–100,不是结果总数;直接 async iteration 会自动翻页。
- spend 的 period_start 只能是日期字符串,传 datetime 会得到 400;它定义包含开始日、排除第 7 天的半开 7 日窗口。
- group_by、evaluator_id、session_id、dataset_id 四者必须恰好选一个。
- 没有记录时 groups 为空,不能把空列表解释为“费用为 0 且已完整计量”。
Dataset 绑定只处理未来实验
把 evaluator 绑定到 dataset 后,新 experiment 会自动执行它,并与 SDK 显式传入的 evaluators 叠加。绑定不会补评既有 experiment runs。
如果要评历史实验,应使用“evaluate existing experiment”等明确入口;不要通过反复 detach/attach 期待回填。绑定前还应确认 feedback key 不与 SDK evaluator 冲突,否则同名分数会失去可解释性。
LLM-as-a-judge 的契约
一个 judge 至少由四部分组成:
- 明确 rubric 与失败定义;
- 只映射判断所需的 input/output/reference 字段;
- 固定 prompt 与 model 版本;
- 用结构化输出定义 feedback key 和 Boolean、Categorical 或 Continuous 类型。
Mustache 变量使用双花括号,f-string 使用单花括号。reference-free 指标应移除 reference 变量,避免把空值误当证据。Prompt Hub 中的 prompt 不能在 evaluator editor 内直接修改,需要在 Playground 提交新版本后再引用。
UI 会把 output schema 的每个顶层 key 视为一项 feedback。feedback key 是长期统计契约,必须在 workspace 内保持含义稳定;改名、改方向或改量纲都应当作版本迁移。
SDK 自定义 judge 最低要求 LangSmith 0.2.0;target、dataset 与 judge function 仍需保持字段契约一致。对 judge 本身的模型调用也要 tracing,才能审计错误理由、token 和成本。
Code evaluator:UI 与本地 SDK 是两个执行面
UI 服务端 code evaluator:
- 函数名必须为 perform_eval,接收 run 与 example;
- 可读取 run inputs/outputs 与 example reference outputs;
- 可返回一个字典中的多项 metric;
- 不能访问互联网;
- 只允许标准库及固定版本的 numpy 2.2.2、pandas 1.5.2、jsonschema 4.21.1、scipy 1.14.1、scikit-learn 1.26.4。
这些限制使它适合确定性检查,但不适合依赖内部 API、动态 package 或外部模型的逻辑。
传给 evaluate/aevaluate 的本地 SDK evaluator 则运行在调用方环境。函数参数名是协议的一部分,可从 run、example、inputs、outputs、reference_outputs 中选子集。Python 可直接返回数值、布尔、字符串或多结果列表;跨 Python/TypeScript 最稳妥的形式是显式返回 key + score/value 字典。
本地 evaluator 可联网,但生产上仍应隔离副作用、设置超时/重试和最小出站权限。不要因 UI evaluator 禁网而误以为 SDK evaluator 也被沙箱化。
Composite:聚合不等于质量真相
UI Composite 支持:
- Average = 权重分数之和 / 权重之和;
- Sum = 权重分数之和。
任何 constituent evaluator 没有在某个 run 上产生反馈时,该 run 不会生成 composite score。修改权重会更新所有已配置 runs 的结果,属于历史指标语义变更,必须记录生效时间和版本。
SDK 示例要求 LangSmith 0.4.29 以上:先等待 experiment feedback 完整,再读取每行反馈并写入自定义 weighted score。若所需 metric 缺失或还未处理完成,应跳过而不是把它当零。重跑聚合时还应明确覆盖/去重策略,避免同一 run 出现多个不可区分的 composite feedback。
Composite 会把多维权衡压成一个数字。发布判断仍要保留原始 correctness、安全、延迟、成本等列,特别是任何“不可被其他优点抵消”的硬门。
费用控制
Evaluator spend cap 按 evaluator 在每个 attached project/dataset 上计算;组织管理员可设置组织默认值,再对具体 attachment 覆盖。周期从周一 00:00 UTC 重置,不按本地时区。
执行语义:
- 每次 evaluator 完成后才记账,因此并发在途调用可能让最终金额略超 cap;
- 到达限额只暂停 evaluator,不影响 agent 或原 trace;
- 被跳过的 runs 不会补评;重置或提高限额后只恢复新 runs;
- code evaluator、未挂载 evaluator 和没有 LLM 调用的 evaluator 不显示 spend。
限额当前只支持 OpenAI、Anthropic、Gemini,并依赖 LangSmith 中的 model pricing。设了 cap 后,不支持或未配置价格的模型不能用于 evaluator。LangSmith 按本地价格表估算,可能与 provider 折扣或合同账单不同。
因此成本治理要组合:
- 正确的模型价格与单位;
- sampling/filter、并发和每周 cap;
- evaluator trace count 与实际 provider 账单对账;
- cap 命中告警和“未评估样本”指标;
- 对关键安全 evaluator 设计降级或人工补审,不能静默缺失分数。
生产检查表
- ○ 先确认 evaluator 类型与 offline/online 运行面。
- ○ 固定 prompt/code/model/feedback schema 版本。
- ○ 共享编辑前列出所有 attached resources。
- ○ Dataset 绑定后只把新 runs 视为有完整评分。
- ○ UI code evaluator 不依赖网络或非白名单包。
- ○ Composite 保留 constituent 指标并处理 missing。
- ○ 预算按 UTC 周解释,监控被跳过且不会回填的 runs。
- ○ 删除、detach、run-rule 清理按可回滚变更执行。