Skip to main content
NiceEval 随包带几个官方 Adapter(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 servermcpServers 配置项,setup 阶段写进 Sandbox 里用户级的 ~/.claude.json(顶层 mcpServers 字段)。两种形态按字段区分:本地 stdio 进程写 command(可带 args / env);远程 Streamable HTTP 端点写 url(可带 headers,逐字进请求头,常用于 Authorization),写成 { "type": "http", "url": …, "headers": … } 条目。url 要 Sandbox 内可达:服务跑在你自己机器上时,先用 cloudflared / tailscale 这类隧道暴露成公网地址。
  • 装 Skillskills: 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", ...))。
  • 装原生 Pluginplugins: ClaudeCodePluginSpec[],每一项声明 Marketplace 连接(name / source / 可选 ref)和其中的 Plugin 名。这个类型只属于 claude-code,传不进 codex。
  • 官方配置文件settingsFile 是运行 NiceEval 的机器上的本地项目路径,不是 Sandbox 内路径;它指向一份完整的 Claude Code settings.json。路径相对项目根,只允许普通相对路径或 ./ 前缀;..、绝对路径、~ 和解析后逃出项目根的符号链接都会报错。Adapter 从本地读取后上传文件,原样替换 Sandbox 中原本为空的用户级 ~/.claude/settings.json;不继承宿主机配置,也不 deep merge 或重新序列化。modelenv 归 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 servermcpServers 配置项,setup 阶段追加进 ~/.codex/config.toml[mcp_servers.<name>] 段。两种形态按字段区分:本地 stdio 进程写 command(可带 args / env);远程 Streamable HTTP 端点写 url(可带 headers,写成 [mcp_servers.<name>.http_headers] 子表)。url 要 Sandbox 内可达:服务跑在你自己机器上时,先用 cloudflared / tailscale 这类隧道暴露成公网地址。
    是复数 mcp_servers:单数 [mcp_server.x] 会被 codex CLI 静默忽略,MCP 压根挂不上,且不会报错——自查用 codex mcp list
  • 装 Skillskills: SkillSpec[],与 claude-code 同一个类型。装进 .agents/skills/<name>/,并把发现指引写进 AGENTS.md——codex 没有 claude-code 那种原生 Skill 工具,只把文件装进去它不会主动去读;断言”用没用到”看它是否真的执行过读那个文件的 shell 命令,没有工具调用可以直接认。
  • 装原生 Pluginplugins: CodexPluginSpec[],声明 Marketplace 连接(name / source / 可选 ref / 可选 sparse)和其中的 Plugin 名。sparse 是路径数组(如 [".agents", "plugins/repo-map"]),每项让 codex plugin marketplace add 带一个 --sparse <path>,大仓库只拉插件所需路径,装出来的内容不变。这个类型只属于 codex,传不进 claude-code。
  • 官方配置文件configFile 是运行 NiceEval 的机器上的本地项目路径,不是 Sandbox 内路径;它指向一份完整的 Codex config.toml。路径相对项目根,只允许普通相对路径或 ./ 前缀;..、绝对路径、~ 和解析后逃出项目根的符号链接都会报错。Adapter 从本地读取后上传文件,原样替换 Sandbox 中原本为空的用户级 ~/.codex/config.toml;不继承宿主机配置,也不拼接、deep merge 或解析后重写。modelmodel_providermodel_providersmodel_reasoning_effortmcp_serversotel 归 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 可覆盖。
  • 装 Skillskills: 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 SDK useChat 后端的 HTTP 端点,零映射(含 HITL)。
  • SDK 事件流转换器fromClaudeSdkMessages / fromPiAgentEvents / fromCodexThreadEvents):手写 adapter 连一个跑着 Claude Agent SDK / pi-agent-core / Codex SDK 的服务时,原生帧到标准事件的映射官方已经做好,只需要补传输粘合,配合 driveFrameStream 逐帧驱动。
  • fromAiSdk:AI SDK generateText / streamText 结果到标准事件流的转换器,写自己的 HTTP web agent adapter 时用。
这几个适配器的完整参数、能力表和示例代码,见内置 Agent 能力参考

怎么选

  • 被测对象是必须在真实文件系统里改代码、跑命令的 coding agent:claude-code / codex / bub,见上文 Sandbox 适配器分节选配置。
  • 被测对象是 AI SDK(useChat 后端)应用:uiMessageStreamAgent,零映射且含 HITL。
  • 被测对象是其它已部署的 agent 系统(HTTP / gRPC):非 Sandbox,手写 adapter,官方 SDK 转换器能覆盖大半映射工作。

相关阅读