niceeval/adapter 导出的工厂函数),按被测对象要不要隔离工作区分两类:Sandbox 型(claude-code / codex / bub)在 Docker 或云端 Sandbox 里跑 coding-agent CLI,能装 MCP server、Skill、Python 插件;非 Sandbox 型无侵入连一个已经在跑的 HTTP 服务,或者帮你手写 adapter 时省掉事件流映射。这篇按类型和具体 Adapter 分节,重点是每个 Adapter 的配置项——怎么选、怎么跑通第一条评估用例,见接入你的 Agent。
Sandbox 适配器
三个内置 Sandbox agent 都用defineSandboxAgent 构造,鉴权走环境变量(可用工厂参数覆盖),并且都支持在 Sandbox setup 阶段装扩展。怎么运行内置 Sandbox agent、目录结构和自定义 Sandbox adapter,见 Sandbox Agent;这里只讲每个 Adapter 能装什么、配置项怎么写。
本页的 settingsFile / configFile 都相对 NiceEval 项目根解析。项目根是执行 niceeval 时的当前工作目录,也就是包含 niceeval.config.ts 的目录,不是评估用例或 Experiment 文件所在目录。例如 Experiment 在 experiments/web/no-search.ts、配置在 configs/codex/no-web.toml 时,仍写 configFile: "configs/codex/no-web.toml"。
claude-code
- 鉴权:
ANTHROPIC_API_KEY(工厂参数apiKey可覆盖),可选ANTHROPIC_BASE_URL(工厂参数baseUrl)。 - 装 MCP server:
mcpServers配置项,setup阶段写进 Sandbox 里用户级的~/.claude.json(顶层mcpServers字段)。两种形态按字段区分:本地 stdio 进程写command(可带args/env);远程 Streamable HTTP 端点写url(可带headers,逐字进请求头,常用于Authorization),写成{ "type": "http", "url": …, "headers": … }条目。url要 Sandbox 内可达:服务跑在你自己机器上时,先用 cloudflared / tailscale 这类隧道暴露成公网地址。 - 装 Skill:
skills: SkillSpec[]——本地 Skill({ kind: "local", path },从项目根读文件或目录)或 Repo Skill({ kind: "repo", source, ref, skills },可钉 commit/tag、可只启用多 Skill 仓库里的一部分)。装进 Sandbox 的 project 级.claude/skills/<name>/,claude CLI 原生发现(原生Skill工具调用被 adapter 归一为skill.loaded事件,不重复记成工具调用;用t.loadedSkill()断言,不是t.calledTool("Skill", ...))。 - 装原生 Plugin:
plugins: ClaudeCodePluginSpec[],每一项声明 Marketplace 连接(name/source/ 可选ref)和其中的 Plugin 名。这个类型只属于 claude-code,传不进 codex。 - 官方配置文件:
settingsFile是运行 NiceEval 的机器上的本地项目路径,不是 Sandbox 内路径;它指向一份完整的 Claude Codesettings.json。路径相对项目根,只允许普通相对路径或./前缀;..、绝对路径、~和解析后逃出项目根的符号链接都会报错。Adapter 从本地读取后上传文件,原样替换 Sandbox 中原本为空的用户级~/.claude/settings.json;不继承宿主机配置,也不 deep merge 或重新序列化。model和env归 Experiment 和 Adapter 管,出现在文件里会在setup阶段报错并点名冲突键。Secret 走环境变量,别写进配置文件。 - 安装后脚本:
postSetup: SandboxHook[],在写 settings、挂 MCP、装 Skill 与 Plugin 全部完成后,按数组顺序在 Sandbox 里跑你的 Hook 函数。典型用途是运行插件自带的 setup 脚本(比如它要往全局配置里登记 hook)——这类脚本必须等安装产物就位才能跑。与它成对的收尾是preTeardown: SandboxHook[]:按逆序、在 agent 自己的 teardown 步骤之前执行,当且仅当postSetup的时点已经走到才触发。Hook 抛错算基础设施错误(Attempt 记 errored),不算 agent 答题失败。 - tracing:claude CLI 的 beta 原生遥测(
CLAUDE_CODE_ENHANCED_TELEMETRY_BETA),span 只有结构和计时,细节见 OTel 接入。
configs/claude-code/no-web.json 关闭内置联网检索:
codex
-
鉴权:
CODEX_API_KEY(工厂参数apiKey可覆盖,不是OPENAI_API_KEY),可选CODEX_BASE_URL(工厂参数baseUrl)接 OpenAI 兼容代理。 -
装 MCP server:
mcpServers配置项,setup阶段追加进~/.codex/config.toml的[mcp_servers.<name>]段。两种形态按字段区分:本地 stdio 进程写command(可带args/env);远程 Streamable HTTP 端点写url(可带headers,写成[mcp_servers.<name>.http_headers]子表)。url要 Sandbox 内可达:服务跑在你自己机器上时,先用 cloudflared / tailscale 这类隧道暴露成公网地址。 -
装 Skill:
skills: SkillSpec[],与 claude-code 同一个类型。装进.agents/skills/<name>/,并把发现指引写进 AGENTS.md——codex 没有 claude-code 那种原生 Skill 工具,只把文件装进去它不会主动去读;断言”用没用到”看它是否真的执行过读那个文件的 shell 命令,没有工具调用可以直接认。 -
装原生 Plugin:
plugins: CodexPluginSpec[],声明 Marketplace 连接(name/source/ 可选ref/ 可选sparse)和其中的 Plugin 名。sparse是路径数组(如[".agents", "plugins/repo-map"]),每项让codex plugin marketplace add带一个--sparse <path>,大仓库只拉插件所需路径,装出来的内容不变。这个类型只属于 codex,传不进 claude-code。 -
官方配置文件:
configFile是运行 NiceEval 的机器上的本地项目路径,不是 Sandbox 内路径;它指向一份完整的 Codexconfig.toml。路径相对项目根,只允许普通相对路径或./前缀;..、绝对路径、~和解析后逃出项目根的符号链接都会报错。Adapter 从本地读取后上传文件,原样替换 Sandbox 中原本为空的用户级~/.codex/config.toml;不继承宿主机配置,也不拼接、deep merge 或解析后重写。model、model_provider、model_providers、model_reasoning_effort、mcp_servers、otel归 Experiment 和 Adapter 管,出现在文件里会在setup阶段报错并点名冲突键。Secret 走环境变量,别写进配置文件。 -
安装后脚本:
postSetup: SandboxHook[],语义与 claude-code 相同:全部安装步骤完成后按序在 Sandbox 里跑你的 Hook 函数,适合运行插件自带的 setup 脚本;成对的preTeardown: SandboxHook[]按逆序在 agent teardown 之前收尾,当且仅当postSetup的时点已经走到才触发。脚本往 codex 全局配置登记的 hook 不需要交互式信任确认——运行时codex exec已绕过 hook 信任门槛,hook 直接生效。 -
tracing:内置,通过
config.toml的[otel.trace_exporter.otlp-http]段配置,协议http/json。
configs/codex/no-web.toml 关闭内置联网检索:
bub
- 鉴权:
BUB_API_KEY+BUB_API_BASE(OpenAI 兼容代理),工厂参数apiKey/apiBase可覆盖。 - 装 Skill:
skills: SkillSpec[],与另外两个 Adapter 同一个类型。装进.agents/skills/<name>/,发现指引写进 AGENTS.md。 - 装插件:
pythonPlugins: PythonPluginSpec[]({ package }:PyPI 包、版本约束或 git URL),setup阶段进uv tool install … --with <package>。这个类型只属于 bub;package 集合进安装 checkpoint key,插件不同的两个变体不会复用同一份安装缓存。 - 预制 Bub:NiceEval 的 E2B 配方会把 Bub、OTel 插件和 Python 插件集合算成安装指纹。Adapter 只复用指纹完全一致的环境;仅在 PATH 里放一个
bub不足以证明兼容。构建入口见 Sandbox provider · 从官方基线继续构建以提速。 - bub 没有
mcpServers——MCP 只属于支持它的 Adapter,Config 上压根没有这个字段。 - 安装后脚本:
postSetup: SandboxHook[],语义与另外两个 Adapter 相同:全部安装步骤完成后按序在 Sandbox 里跑你的 Hook 函数;成对的preTeardown: SandboxHook[]按逆序在 agent teardown 之前收尾,当且仅当postSetup的时点已经走到才触发。 - 安装方式:走
uv tool install(PyPI 包,不是 npm 包),首次安装会建 checkpoint 缓存加速后续 Sandbox。 - tracing:内置,通过环境变量注入,协议
http/protobuf。
三个 Sandbox 适配器对比
装了什么有据可查:Adapter 在
setup 收尾把安装清单写进 Sandbox 的 __niceeval__/agent-setup.json,运行器把它存成 Attempt Artifact agent-setup.json(库里读 attempt.agentSetup())。清单只记来源、ref、Skill/Plugin 名、解析出的版本,以及官方配置文件的项目相对路径和 SHA-256;不保存配置正文、API Key 或环境变量值。MCP server 同理只记非敏感字段:stdio 形态记 name / command / args 不记 env,HTTP 形态记 name / url 不记 headers。
非 Sandbox 适配器
被测对象不需要隔离工作区——已经部署的 HTTP 服务、自研 agent loop——用非 Sandbox 适配器无侵入接入,不需要 Docker。-
uiMessageStreamAgent:内置,无侵入连 AI SDKuseChat后端的 HTTP 端点,零映射(含 HITL)。 -
SDK 事件流转换器(
fromClaudeSdkMessages/fromPiAgentEvents/fromCodexThreadEvents):手写 adapter 连一个跑着 Claude Agent SDK / pi-agent-core / Codex SDK 的服务时,原生帧到标准事件的映射官方已经做好,只需要补传输粘合,配合driveFrameStream逐帧驱动。 -
fromAiSdk:AI SDKgenerateText/streamText结果到标准事件流的转换器,写自己的 HTTP web agent adapter 时用。
怎么选
- 被测对象是必须在真实文件系统里改代码、跑命令的 coding agent:
claude-code/codex/bub,见上文 Sandbox 适配器分节选配置。 - 被测对象是 AI SDK(
useChat后端)应用:uiMessageStreamAgent,零映射且含 HITL。 - 被测对象是其它已部署的 agent 系统(HTTP / gRPC):非 Sandbox,手写 adapter,官方 SDK 转换器能覆盖大半映射工作。
相关阅读
- 接入你的 Agent — 全景:experiment 怎么配、评估用例怎么写。
- Sandbox Agent — 怎么运行内置 Sandbox agent,以及怎么写自己的。
- 内置 Agent 能力参考 — 每个适配器逐能力盘点、非 Sandbox 适配器的完整代码示例。
- OTel 接入 — 把 span 发给 NiceEval,换
niceeval view的调用瀑布图。 - defineAgent 参考 —
defineAgent/defineSandboxAgent完整参数。