Tier 1:只接 send
应用代码一行不改,接入只有一个 Adapter 文件——send 对着用户前端本来就在用的那个接口收发。
全套断言都在这一档:文本断言与 judge、结构化输出校验、多轮与会话隔离、HITL 审批流、事件映射给到的工具断言,以及 send 返回 usage 带来的用量断言——判决依据全部来自 send 返回的 Turn,后面两档不会再多出任何断言。应用接口本身暴露模型选择的话,模型对比 experiment 也在这一档——experiment 的 model 经 ctx.model 传给 Adapter,随请求转发即可。
大多数团队从这里开始,很多也停在这里就够了。
Tier 2:send + OTel
还是同一个send、同一套事件映射,只是让应用把 OTel span 也发给 NiceEval 一份。应用已埋点(AI SDK telemetry、LangGraph、OpenLLMetry / OpenInference、自埋 gen_ai)就零改动;没埋点补的是一段通用 OTel 初始化——这属于可观测性建设,不是为 eval 定制的改造。
这一档买到的是观测:niceeval view 的调用瀑布图——应用内部每次模型调用、每次工具执行、各自的耗时与 token,按轮铺成时间线。断言不受影响:span 只进瀑布图,不进事件流、不喂断言。走法见OTel 接入。
Tier 3:侵入改造 + experiment flags
要评「改 prompt / 换工具集 / 开关某个 feature 谁更好」这类 feature A/B test 时,对照点在应用内部,前两档拿不到。这一档改应用内部代码,把变体暴露成外部可选的配置:experiment 的flags 经 ctx.flags 透传给 Adapter,Adapter 随请求交给应用(HTTP header、请求体字段、环境变量都行),应用按 flag 切换变体。
注意侵入的是应用(把变体暴露成配置),不是接入面——Adapter 本身不变,依然只经对外接口调用应用。
无侵入是前两档的底线
前两档都是无侵入的:应用由你按它自己的方式启动(pnpm start、部署在哪都行),eval 侧不 spawn 应用进程、不另开端口——Adapter 只对着用户前端本来就在用的那个接口(HTTP 端点、SSE 流)收发,连不上时报”先起应用”的明确错误。两档的区别只在观测数据:Tier 1 只有 send 返回的事件,Tier 2 多一份发给 NiceEval 的 span、瀑布图随之出现。
怎么升级
三档递进不互斥:先用 Tier 1 跑通基线和模型对比;要调用瀑布图,升 Tier 2;要对照应用内部变体,再升 Tier 3。每次升级都只是给 Adapter 或应用加东西,experiment 侧怎么组织对比见实验。相关阅读
- 接入你的 Agent — 接入全景:最小接入与参数通道。
- Adapter — 契约本身:
send传入什么返回什么,ctx.model/ctx.telemetry/ctx.flags按档位出现。 - OTel 接入 — Tier 2 的完整走法。
- 实验 — model / flags 对比在 experiment 侧怎么声明。