跳转到主要内容
这一页是 Coding Agent 把 NiceEval 接入一个项目的执行步骤。前提:niceeval 依赖已经装进项目、niceeval init 已经运行,你是从随包 INDEX.md 进入本页的。用用户的语言与用户交流;所有 API、字段和 CLI 行为以随包文档为准,不要凭训练记忆现编。

第 1 步:探索项目,再和用户确认

这一步决定后面整条路径。先自己读代码探明,把探到的结论列给用户核对,探不到的再提问——不要一上来就抛一串问题,也不要没探就假设。要探明的信息:
  1. 这是个什么 Agent:读 README、package.json 依赖、路由和 agent loop 代码,判断它是用什么写的(AI SDK、LangGraph、OpenAI Agents SDK、Claude Agent SDK、自研 loop……),核心用例是什么(客服?SQL?编码任务?)。
  2. 前端和 Agent 怎么通信:HTTP 还是 gRPC / WebSocket?协议是标准的还是自己实现的——AI SDK UI Message Stream、OpenAI Responses / Chat Completions 这类标准协议,还是 SDK 原生事件流透传,还是用户自定义的 JSON/SSE 帧?这直接决定 Adapter 是用内置的(零映射)还是手写 send(要自己写事件映射)。
  3. 后端有没有接 OTel:搜有没有 OTel SDK 初始化、AI SDK telemetry、LangSmith / OpenLLMetry / OpenInference 这类埋点。已经有的话 Tier 2 几乎零成本。
  4. 用户自己有没有做 A/B Test / feature flag:应用里已有变体开关的话,Experiment 的 flags 可以直接透传给它(Tier 3 的现成入口)。
  5. Judge 用什么:语义评分(t.judge.autoevals.*)要一个与被测 Agent 分离的 Judge 模型,走 OpenAI 兼容的 /chat/completions 协议——OpenAI 官方、DeepSeek、任何兼容该协议的网关都行。问用户手上有哪个服务的 key、想用什么 Judge 模型(没有内置默认模型,必须显式指定)。用户暂时没有 key 也不阻塞:Judge 断言会静默跳过,先用精确断言跑通。
  6. 是不是 Agent 本体要进 Sandbox:被测对象是 coding agent CLI、或给 coding agent 写的 Skill/Plugin/Hook/MCP server(要在隔离 workspace 里改文件/跑命令)的话,必须走 Sandbox,不能像 HTTP 服务那样直接 send。默认建议 dockerSandbox(),但要先跟用户确认——本机/CI 有没有 Docker、要不要 Vercel Sandbox 或其它远程 Provider;用户没有异议就默认走 Docker。Provider 只能写在代码里(Experiment 或 niceeval.config.tssandbox 字段),没有 CLI flag,也不会自动探测——见选择 Sandbox Provider
探完之后,向用户介绍接入等级并给出推荐(详见接入等级):
  • Tier 1(只接 send):应用一行不改,全套断言(文本、Judge、多轮、工具、HITL)都在这一档。
  • Tier 2(send + OTel):应用把 OTel span 也发 NiceEval 一份,换 niceeval view 的调用瀑布图;已有埋点(第 3 点探到的)就零改动。
  • Tier 3(侵入改造 + flags):把应用内部变体暴露成 flags 做 feature A/B;已有 A/B 开关(第 4 点探到的)就是现成入口。
默认推荐先 Tier 1 跑通,再升 Tier 2——尤其当第 3 点探到应用已有 OTel 时,明确告诉用户「升 Tier 2 只是把 span 多发一份,成本接近零」。Tier 3 只在用户明确要做变体对比时提。 按探明的形态挑对应文档,不要在没读的情况下直接开始写 Adapter:

第 2 步:配置 Judge

把第 1 步问到的 Judge 服务配上。Judge 走 OpenAI 兼容的 /chat/completions 协议,在 niceeval.config.ts 里配:
两个要提醒用户的点:
  • key 解析不到时 Judge 断言会静默跳过(不报错、不记分)——评估用例全绿不代表 Judge 真的跑了。所以配完先跑一条带 t.judge 的评估用例,在 niceeval view 里确认有 Judge 分数。
  • Judge 模型要与被测 Agent 分离,避免同一个模型给自己打分。模型解析优先级(单次调用 → 评估用例级 → 全局配置)和三种评分形状见 Judgejudge 字段全集见 defineConfig 参考

第 3 步:写三件套

按第 1 步选中的方向读完对应文档后,依次写:
  1. Adapteragents/*.ts 或用户项目里约定的目录)——只填 defineAgentsend,配置走工厂参数,不写死、不读 process.env。契约见 Adapter,API 签名见 defineAgent 参考,事件映射见事件参考
  2. Experimentexperiments/*.ts)——引用上面的 Adapter,声明 modelflagsruns 等。模型对比写两个实验文件,各自钉一个 modelevals: (eval) => boolean 决定各自运行哪些评估用例。路径只负责 id 和批量运行,报告读取每份快照的 selectedEvalIds
  3. 评估用例evals/*.eval.ts)——先探明这个应用是干嘛的,再写一条贴着它真实功能的评估用例:读它的 README、路由、工具定义或系统提示,找出它的核心用例(客服机器人就问一条真实的客服问题、SQL agent 就给一个真实的查询任务),拿这个用例做第一条评估用例的输入和断言,不要写「你好」这种和应用无关的占位输入。形式上仍从最小写起:一句输入,t.succeeded() + 一个针对预期回答的内容断言,跑通再加断言密度。写法见编写评估用例,断言与评分见评分指南,签名见 defineEval 参考
参数怎么从 Experiment 流到 Adapter、静态配置和每轮动态值怎么分(工厂参数 vs ctx),见接入自己的 Agent 架构上有两条硬规则,写 Adapter 时不要违反:
  • 不做进程内直调。就算 agent runtime 和评估用例在同一个代码库里,Adapter 也要走 HTTP(或对应传输层),不要把 fetch 换成直接 import 被测函数——原因见接入自己的 Agent 里「为什么不直调」。
  • 评估用例侧不代管被测进程。不 spawn 应用、不另开端口;应用由用户自己按平时的方式启动(pnpm dev 之类),Adapter 连不上时报「先起应用」这类明确的错误,不要自己起服务。

第 4 步:跑通并验证

Coding Agent 反馈闭环niceeval show--transcript--trace--diff 完成运行、观察、修改和重跑;查看器用法见查看结果。没跑通分三类定位:fetch 直接抛错 → 应用没起来或 URL 不对;t.succeeded() 不过 → 应用回了非成功状态;只有内容断言不过 → 接入已经通了,调断言或调应用。

第 5 步:收尾,告诉用户做了什么

跑通之后先总结,再谈下一步。总结要说清:接了什么被测对象、生成了哪几个文件(Adapter / Experiment / 评估用例各在哪)、niceeval exp compare-modelsniceeval view 怎么跑、第一次运行的结果是什么样。不要在没被要求的情况下顺手重构用户已有代码,也不要在这几个文件之外新增抽象。

第 6 步:问用户要不要往深了接

总结完之后,把还能往深接的选项列给用户——每一项都说清能做什么、大概改多少代码、买到什么好处,让用户自己选,不要自作主张多做: 共同点也要讲给用户:这些全是给 Adapter 或应用加增量,已写的评估用例一行不用改。三档投入分别买到什么、什么时候值得升级,见接入等级。第 1 步探到应用已有 OTel 埋点的话,瀑布图那条要主动推荐——成本接近零。