跳转到主要内容
内置的三个 sandbox agent(claude-codecodexbub)做到的能力不完全相同。adapter 的能力是正交的组合,每个能力对应一组断言。这篇按能力盘点三个内置 agent 各自做到哪,以及两个接 AI SDK 应用的内置件:进程内 agent 工厂 aiSdkAgent(含 HITL)和底层转换器 fromAiSdk

能力速览

能力对应的断言 / API
收发消息(基础契约)t.send()(可多次调用)、t.replyturn.outputEquals / outputMatches、按状态判断的 t.succeeded()
toolObservability · 事件流calledTool / toolOrder / usedNoTools / maxToolCalls / messageIncludes / noFailedActions / event / eventOrder 等整套作用域断言;负断言(notCalledTool 等)有完整事件流才可信
conversation · 会话续接跨轮记忆断言、t.newSession() 会话隔离
HITL(人工介入)t.parked()t.requireInputRequest()t.respond() / t.respondAll()
tracingEvalResult.traceniceeval view 的调用瀑布图

三个内置 agent 分别做到哪

Agent收发事件流会话续接HITLtracing备注
claude-code✅(claude --resume <id>额外声明 compactionObservabilityt.event("compaction") 可用
codex✅(codex exec resume <id>✅(http/json → OTLP)额外声明 compactionObservability
bub✅(--session-id + tape 续接)✅(http/protobuf → OTLP)额外声明 compactionObservability
三者都声明了 workspacesandboxdefineSandboxAgent 默认开启),所以 t.sandbox.fileChanged() / diff 断言、文件 IO、命令执行在三个 agent 上都能用,不受这张表限制。
三个内置 sandbox agent 目前都不支持 HITLsend 只返回 "completed" / "failed",从不返回 "waiting",也不吐 input.requested 事件。需要 t.respond() / t.requireInputRequest() 时,可以用下文的内建 aiSdkAgent(AI SDK v7 tool approval 原生映射成 HITL),或自己写 adapter:实现 waiting 状态 + input.requested 事件 + resume 交回。

逐 agent 细节

claude-code

  • 连接方式:沙箱里 spawn claude --print --dangerously-skip-permissions,读回 ~/.claude/projects/**/*.jsonl 最新一份 transcript。
  • 会话续接:ctx.session.isNewfalse 且有 id 时追加 --resume <id>
  • 鉴权:ANTHROPIC_API_KEY(可用配置项 apiKey 覆盖),可选 ANTHROPIC_BASE_URL
  • 支持 mcpServersskills(GitHub org/repo)配置项。
  • 没有声明 tracing:不会起 OTLP 接收器,EvalResult.trace 为空。

codex

  • 连接方式:沙箱里跑 codex exec --json(续接时是 codex exec resume <id> --json),stdout JSONL 当 transcript。
  • 鉴权:CODEX_API_KEY(不是 OPENAI_API_KEY),可选 CODEX_BASE_URL 接 OpenAI 兼容代理。
  • tracing 通过 ~/.codex/config.toml[otel.trace_exporter.otlp-http] 段配置,协议 http/json
  • 支持 mcpServersskills 配置项。

bub

  • 连接方式:沙箱里跑 bub run + --session-id,从 ~/.bub/tapes/<hash>.jsonl 读 tape 当 transcript。
  • 鉴权:BUB_API_KEY + BUB_API_BASE(OpenAI 兼容代理)。
  • tracing 通过环境变量注入(OTEL_EXPORTER_OTLP_TRACES_ENDPOINT 等),协议 http/protobuf
  • 支持 pythonPlugins 配置项。
  • 安装走 uv tool install(非 npm 包),首次安装带 checkpoint 缓存以加速后续沙箱。

aiSdkAgent:接 AI SDK 应用的内建 agent 工厂(含 HITL)

aiSdkAgentniceeval/adapter 导出)把「一个 generateText 调用」变成完整的进程内 agent。应用只写 generate(怎么召模型:model / tools / system prompt 都在这里配),协议侧的活 aiSdkAgent 都替你做了:
import { aiSdkAgent } from "niceeval/adapter";
import { generateText, isStepCount, type ModelMessage } from "ai";

export default defineExperiment({
  agent: aiSdkAgent<ModelMessage>({
    name: "my-assistant",
    generate: ({ messages, model, signal }) =>
      generateText({ model: resolveModel(model), system: SYSTEM_PROMPT,
                     tools, stopWhen: isStepCount(5), messages, abortSignal: signal }),
    data: (result) => ({ reply: result.text }),
  }),
  model: "deepseek-v4-pro",
});
它替你做好的能力:
  • 收发 + 事件流:结果经 fromAiSdk 直构——toolCallId 精确配对、时序保真、tool-error 映射成失败的 action.result、usage 聚合(v4 / v5 / v7 字段漂移都兜住)。
  • 会话续接messages 历史由 aiSdkAgent 管理,isNew 开新会话线、同 id 续接。
  • HITL:AI SDK v7 的 tool approval(工具带 needsApproval: true)原生映射——模型决定调用被拦工具时,本轮返回 status: "waiting" + input.requested 事件(action = 工具名、options = approve / deny);t.respond("approve" / "deny")aiSdkAgent 翻译成 tool-approval-response 交回 SDK,拒绝的调用以 rejected(而非 failed)落进事件流,calledTool(..., { status: "rejected" }) 可精确断言。这是目前唯一原生支持 HITL 的内置件。
  • tracing:声明 capabilities: { tracing: true } 后,OTel 管线全由工厂承担——每轮把绑定 NiceEval 接收端点的 @ai-sdk/otel 集成经 telemetry 交给 generate(原样透传给 generateTexttelemetry 选项即可),轮末自动 flush;并行 attempt 各用各的出口,不串流。设 otlpBackendUrl 可把同一批 span 双发到你自己的观测后端。需要在项目里安装 @ai-sdk/otel@opentelemetry/sdk-trace-node@opentelemetry/exporter-trace-otlp-http(NiceEval 的可选 peer 依赖,只有 tracing 用到)。
workspace / sandbox 不适用(它评的是 AI SDK 应用,不是改文件的 coding agent)——这正是 Agent × Sandbox 正交的含义。完整可跑示例见仓库 examples/zh/ai-sdk-v7/(六条 eval 逐项演示:结构化输出、事件流断言、多轮隔离、HITL 批准 / 拒绝、多模态、trace)。

fromAiSdkaiSdkAgent 底下的事件流转换器

fromAiSdkniceeval/adapter 导出)是 aiSdkAgent 内部用的转换函数,也可以在自己写的 adapter 里单独用(比如 HTTP web agent 的服务端直构,见 examples/zh/ai-sdk/)。它把 AI SDK 的 generateText / streamText 结果映射成 { events, usage, status },直接铺进 Turn
import { defineAgent, fromAiSdk } from "niceeval/adapter";

export default defineAgent({
  name: "my-ai-sdk-agent",
  async send(input) {
    const result = await generateText({ model, tools, prompt: input.text });
    return { ...fromAiSdk(result), data: result.text };
  },
});
status 由转换器给:有待人批准的 tool approval 时是 "waiting"(并附 input.requested 事件),否则 "completed"。会话续接(多轮 resume)、HITL 的裁决交回、tracing 取决于你自己的 send 怎么写——这三样正是 aiSdkAgent 替你写好的部分。

怎么选

  • 被测对象是 AI SDK agent 应用(工具循环):直接用 aiSdkAgent,所有能力都已做好(含 HITL,tracing 可选)。
  • 需要调用瀑布图(niceeval view 的 trace):codex / bub / aiSdkAgent(自发 OTLP),claude-code 目前拿不到 trace。
  • 需要人工审批 / 多步确认(HITL):目前只有 aiSdkAgent(AI SDK v7 tool approval);沙箱型三个都不支持,其它被测对象要自己写 adapter。
  • 想跑一个 coding agent 改代码、看 diff、判断工具调用:claude-code / codex / bub(收发 + 事件流 + 会话续接 + workspace + sandbox)。

相关阅读