SDK 的作用
SDK 只做证据采集。它给你一个小 HTTP 服务,把你的 Agent 调用套进target-invocation-v1 契约。你要写的只有一件事:
| SDK 做 | SDK 不做 |
|---|---|
提供 /healthz、/v1/agent/invocations、/v1/evidence/{run_id} | 创建 EvalRun、打分 |
校验 target-invocation-v1、拒绝运行时覆盖、防重放 | 跑 Judge、聚合结果 |
| 边界化并脱敏证据、按 run 存储 | 解析 Registry、挑选 Case |
| SDK 包 | 语言 | 你会用到的导出 |
|---|---|---|
agentbeat-sdk-py | Python | create_target_server、InvocationContext、EvidenceCollector、read_bearer_token |
agentbeat-sdk-js | Node | createTargetServer、bearerTokenFromFile |
SDK 的三条路由
SDK 提供下列三条路由,没有/run 别名或 EvalRun 端点。仅做 L1 的 Target 不要求 L2 证据读取。
| 路由 | 方法 | 鉴权 | 作用 |
|---|---|---|---|
/healthz | GET | 无 | 就绪检查。报告 evidence: "L1" 或 "L2"。 |
/v1/agent/invocations | POST | Bearer | 执行 Agent 调用。这是唯一的业务入口。 |
/v1/evidence/{run_id} | GET | Bearer | 获取有边界的 L2 证据文档。 |
| 防护 | 行为 | 错误码 |
|---|---|---|
| Schema | 未知顶层字段、错误的 schema_version、错误的 input | 400 |
| 关联绑定 | X-AIBeat-Run-ID / X-AIBeat-Case-ID 头必须与请求体一致 | 400 |
| 运行时覆盖 | metadata 不得配置模型、端点、token、工作区、工具、状态、sidecar | 400 |
| 重放 | 同一个 run_id 只接受一次 | 409 |
| 并发 | 在跑数量超过 max_concurrent_runs | 503 |
三个证据等级
调用接口保持一致,但更高层级需要真实观测,L3 还需要独立 State Controller,不能仅靠配置升级。| 等级 | Target 返回什么 | 怎么产生 |
|---|---|---|
| L1 | 只有 final_response | 关掉证据(evidence=False)。/healthz 报 evidence: "L1",没有 evidence_ref。 |
| L2 | final_response + evidence_ref | EvidenceCollector 记录有边界、已脱敏的 message/tool 事件。文档是 target-evidence-v1,assurance_level: "L2"。 |
| L3 | L2 + 已核验的前后状态 | 评测侧 State Controller 走 seed → reset → snapshot(before) → invoke → snapshot(after) → verify。Go Core 把 L2 文档与验证回执合并。 |
按框架接入
每个 adapter 把你框架的原生事件投影进target-evidence-v1。所有框架里 invoke 的形状都一样。
| 你的框架 | 用 | 注意 |
|---|---|---|
| LangGraph | LangGraphObserver | 读 stream_mode="updates",不改图 |
| OpenAI Agents | OpenAIAgentsTracingProcessor + observe_openai_agents_run | 进程级全局注册,per-run 隔离 |
| LangChain | LangChainCallbackHandler | 挂在调用根;与 LangSmith / Langfuse 并存 |
| Codex(Node) | createTargetServer + observeCodexNotification | 进程外 JSON-RPC |
| CrewAI / Langflow | 手工调 EvidenceCollector 方法 | 没有原生事件回调 |
| 其他 | OTelGenAISpanProcessor | 尽力兜底,限制见下 |
最小 Target(任意框架,L1 即可用)
evidence=False),同一个函数就能服务 L1 评测。使用默认值,则服务 L2 评测。
如果使用的框架没有对应的 Adapter,请使用 context.observe 这个手动收集器。直接调用它的强类型方法来构造证据。
LangChain
请将LangChainCallbackHandler 挂载到根 RunnableConfig 上。这样能正确收集模型、工具和完整链路的回调,并保持 run_id 层级树的完整。不要把它挂在子节点上,否则会丢失同级节点的回调,并导致工具结果找不到对应的调用记录。
LangChainTracer、Langfuse 的 CallbackHandler 共存在同一个 callbacks 列表中。如果是异步执行(ainvoke),请换用 AsyncLangChainCallbackHandler。
LangGraph
LangGraphObserver 读取 stream_mode="updates" 输出,不改图节点。它记录 assistant 消息和绑定的工具调用/结果。
OpenAI Agents
Agents SDK 默认通过全局注册表派发 Trace。在并发场景下必须做隔离。observe_openai_agents_run 函数将路由绑定到当前上下文(ContextVar),从而实现隔离。
openai-agents==0.22.0。保证并发调用不串轨是收集有效证据的基础。
OpenTelemetry(兜底方案)
OTelGenAISpanProcessor 是针对无专门集成框架的兜底方案。它只负责转换符合 GenAI 语义约定的 Span,且不接管全局 Trace 提供者。
- 内容采集是可选项(Opt-In)。 在 OTel 中,工具参数、输入输出等内容数据默认关闭。跑完一次后调用
processor.content_capture_report()(内部是ContentCaptureProbe)就能知道这些字段有没有真出现。如果缺失,AgentBeat 将记录降级的lifecycle事件,而不是编造数据。 - 语义约定仍在开发期。 OTel 的 GenAI 语义约定快照版本为
2026-09-03。后续属性名可能会变动,需要手动跟进升级。 - 不接管 Provider。 它绝不调用
trace.set_tracer_provider。
TracerProvider 上的所有导出器(Exporter)。AgentBeat 的脱敏机制只能保护生成的证据文档,无法控制发往其它监控系统的数据。
CrewAI / Langflow(手工埋点)
这两个框架在锁定的版本里没有原生事件回调,所以按上面 collector 的方法手工埋点。参考 Target 就是这么做。Codex(JavaScript)
Codex Target 是进程外模式:SDK 提供规范 HTTP 路由,observeCodexNotification 把 Codex app-server 的 JSON-RPC 通知投影成证据。
invoke 返回 finalResponse(驼峰),对应 Python 侧的 final_response。
注册 Target
Registry 条目只登记 target 名字和部署接线,不存模型、工具、fixture 或密钥的值——只有密钥 ref 和环境变量名,部署时才解析。Case 和浏览器请求只能选target_id 和 deployment_profile_id。
deploy/aibeat-eval/config/agent-target-registry.langgraph-reference.example.json。state_verifier: true 只是能力声明;L3 还要求实际注册的 State Controller、兼容 Deployment 和已验证的状态证据。
端到端验证
Target 起来后,按顺序走三条路由。/healthz 报 evidence: "L2" 和你配置的等级。第 2 步返回体里有 evidence_ref,说明 Target 在产出 L2 证据。/v1/evidence 返回 404,说明证据没开——检查 evidence 选项。
最终确认在 Workbench:注册 Target、绑定 deployment profile、跑一个 Case,确认同一个 run_id 下能看到 final_response 加 L2 trace(L3 还有已验证的状态回执)。
接入避坑指南
1. 模型在部署期固定。 模型端点、ID、Token 都由启动时的环境变量决定。在请求的metadata 里如果传入 model、base_url、token,会直接报 400 错误。如果需要换模型,请重新部署 Target。
2. L3 需要两套 Token。 状态控制器(State Controller)需要控制 Token 来捕获系统快照。Agent 自身也需要独立的工具 Token 来调用用例的工具。Agent 绝对不能接触控制 Token。
3. run_id 是一次性的。 重复传入同一个 run_id 会返回 409 run_id_reused。因为执行失败的轮次同样可能产生环境副作用,所以不管是重试还是新请求,都必须生成全新的 run_id。
安装依赖
SDK 核心无第三方依赖。每个 adapter 的框架版本由对应示例锁定:| Adapter | 包 | 锁定版本(参考示例) |
|---|---|---|
| 核心 | agentbeat-sdk | 1.0.0 |
| LangChain | langchain + langchain-core | 1.3.14 / 1.5.3 |
| LangGraph | langgraph + langchain-core | 1.2.10 / 1.5.3 |
| OpenAI Agents | openai-agents | 0.22.0 |
| OpenTelemetry | opentelemetry-sdk + opentelemetry-api | 1.34.0 |
| CrewAI | crewai + crewai-tools | 1.15.17 |
| Codex(Node) | 无(Node 运行时) | Node >=22.22.0 |
pyproject.toml 里抄对应块,别装未锁定的最新版。
下一步
Adapters
评测侧 Connector、Target SDK 与旧版兼容边界。
观察模型
你的证据投影进去的 Trace schema。
Evidence
Finding 里带什么:响应、Trace、环境差量。
Agent 快速开始
Target 种类和绑定它们的 Registry。