AI SDK ACP Harnesses 实战:为 Claude Code、Codex 与 Grok Build 配置认证与 AI Gateway 路由
【免费下载链接】aiThe AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents项目地址: https://gitcode.com/GitHub_Trending/ai/ai
本指南围绕 GitHub推荐项目精选 / ai / ai 仓库中examples/harness-e2e-next示例的 ACP(Agent Client Protocol)harness 配置展开,讲解如何通过createACP为 Claude Code、Codex、Grok Build 三个运行时声明直接凭据与 AI Gateway 配置,并深入剖析认证自动选择机制、权限模式限制与 Gateway 端点映射原理。读完本文,你将掌握在 AI SDK harness 抽象下编排外部编码 Agent 的完整配置方案,并能依据仓库源码定位每个配置项的底层行为。
ACP harnesses:将运行时配置与应用代码放在一起
在 AI SDK 的 harness 抽象中,ACP(Agent Client Protocol)是让外部编码 Agent(如 Claude Code、Codex、Grok Build)通过标准协议与 AI SDK 应用对接的桥梁。examples/harness-e2e-next示例项目遵循一个核心组织原则:将每个运行时特有的 ACP 配置,紧挨着消费它的应用代码存放,而不是散落在全局配置或环境变量里。
具体做法是:每个运行时提供一个独立的createACPprofile,集中声明两件事——该运行时的直接凭据环境变量,以及它的AI Gateway 配置。这些 profile 文件位于 examples/harness-e2e-next/agent/harness/ 目录下,其中acp-claude-code/harness.ts与acp-codex/harness.ts是两个典型实现,Grok Build 的对应 profile 则由@ai-sdk/harness-grok-build包中的grokBuild工厂提供(见 packages/harness-grok-build/src/grok-build-harness.ts)。
这种“profile 与应用同目录”的组织方式带来两个直接收益:其一,每个应用的 ACP 配置可独立演进、互不干扰;其二,配置语义一目了然——凭据从哪来、走哪条认证路径,都被显式写死在 profile 里,评审与排查都更有据可循。
认证选择:AI Gateway 自动识别与显式覆盖
ACP profile 的认证行为遵循一套明确的自动选择规则,这也是使用这些 harness 前必须理解的核心逻辑:
- 只要环境变量中存在
AI_GATEWAY_API_KEY或VERCEL_OIDC_TOKEN中的任意一个,profile 就会自动选择 AI Gateway作为认证与请求转发路径;此时可用AI_GATEWAY_BASE_URL覆盖 Gateway 的默认端点。 - 如果两种 Gateway 凭据都不存在,profile 则只转发该运行时自身配置的直接凭据(如
ANTHROPIC_API_KEY、CODEX_API_KEY、XAI_API_KEY)。 - 当调用方需要强制覆盖自动选择结果时,可把
createACP的auth参数显式设为'direct'或'ai-gateway'。
这套自动选择逻辑在源码中有完整印证。在 packages/harness-acp/src/acp-auth.ts 的resolveACPProviderAuthentication中可以看到:当 profile 声明了providerAuthentication时,函数会先解析认证模式,若模式为direct则直接返回直接认证环境;否则尝试解析 Gateway 凭据——若未显式指定模式(auto)且 Gateway 凭据缺失,则回退到直接认证;而一旦显式选择了ai-gateway却拿不到任何 Gateway 凭据,就会抛出明确错误:AI Gateway authentication was selected, but neither AI_GATEWAY_API_KEY nor VERCEL_OIDC_TOKEN is set.这保证了“自动回退”与“显式强制”两种语义都不会静默出错。
从源码结构可以推断,AI_GATEWAY_API_KEY与VERCEL_OIDC_TOKEN的优先级判定集中在@ai-sdk/harness的getAiGatewayAuthFromEnv工具中(见 packages/harness/src/utils/ai-gateway-auth.ts),acp-auth.ts通过resolveGatewayCredential统一消费该结果,并记录凭据来源(gatewayCredentialSource)用于认证 profile 的身份摘要。
三个运行时 profile 一览
示例项目为本次端到端矩阵固定了精确的实现版本,每个 profile 对应一个 npm 包与一个可执行入口:
| Profile | 固定版本包 | 可执行入口 |
|---|---|---|
acp-claude-code | @agentclientprotocol/claude-agent-acp@0.61.0 | claude-agent-acp |
acp-codex | @agentclientprotocol/codex-acp@1.1.4 | codex-acp |
acp-grok-build | @xai-official/grok@0.2.111 | grok agent stdio |
注意:上表中的包版本被 profile 精确固定(pin),确保端到端测试矩阵每次跑出的行为一致。以acp-claude-code为例,其 profile 通过source: { type: 'npm-simple', packageName: '@agentclientprotocol/claude-agent-acp', packageVersion: '0.61.0' }声明安装来源,见 examples/harness-e2e-next/agent/harness/acp-claude-code/harness.ts。
Claude Code ACP:Anthropic 启动环境与 Gateway 根端点
Claude Code 的 ACP profile(acp-claude-code)使用被固定实现的Anthropic 启动环境,并直连AI Gateway 的根端点(即 Gateway base URL 本身,不做/v1之类的后缀拼接)。
从 acp-claude-code/harness.ts 可以看到它的凭据与网关声明:
credentialEnv: ['ANTHROPIC_API_KEY', 'ANTHROPIC_AUTH_TOKEN'],直接认证接受ANTHROPIC_API_KEY与ANTHROPIC_AUTH_TOKEN两类凭据;当两者同时存在时,profile 会为它们各生成一条凭据代理(credential brokering)转换,把沙箱内的x-api-key/Authorization: Bearer请求头替换为宿主侧的真实凭据,匹配目标 URL 为ANTHROPIC_BASE_URL或默认的https://api.anthropic.com。
Gateway 路径下,profile 将三个环境变量映射到 Gateway 动态注入的来源:
providerAuthentication: { gateway: { env: { ANTHROPIC_API_KEY: { $source: 'gateway-api-key' }, ANTHROPIC_AUTH_TOKEN: { $source: 'gateway-api-key' }, ANTHROPIC_BASE_URL: { $source: 'gateway-base-url' }, CLAUDE_AGENT_SDK_CLIENT_APP: { $source: 'client-app' }, }, }, },这里$source: 'gateway-api-key'表示用 AI Gateway 的密钥填充 Anthropic 两类凭据,$source: 'gateway-base-url'表示把 Gateway 根端点作为 Anthropic 的 base URL,$source: 'client-app'则用于标记客户端应用身份。整个 profile 还通过modelMapping(session-config-option的model路径)把模型选择落到 ACP 会话配置上,并把allow-reads/allow-edits/allow-all三种 Harness 权限模式分别映射到 Claude Code 的default/acceptEdits/bypassPermissions会话模式。
Codex ACP:API Key 启动环境与 OpenAI 兼容 Gateway Provider
Codex 的 profile(acp-codex)走的是API Key 启动环境,并且要求 Gateway 侧配置一个以/v1结尾的 OpenAI 兼容 Provider。这一点与 Claude Code 的“根端点”形成鲜明对比——Codex 的model_providers配置中,ai_gatewayprovider 的base_url被显式要求追加/v1后缀(ensureSuffix: '/v1'),同时声明wire_api: 'responses'、preferred_auth_method: 'apikey',并透传User-Agent与x-client-app两个请求头用于客户端归属,见 acp-codex/harness.ts。
Codex profile 的凭据与环境转发也很有特点:
credentialEnv: ['CODEX_API_KEY', 'OPENAI_API_KEY'], forwardEnv: ['CODEX_CONFIG'],直接认证优先使用CODEX_API_KEY,未设置时回退到OPENAI_API_KEY;CODEX_CONFIG会被原样转发进沙箱,同时被用作指令注入的载体——instructionMapping以launch-env-json的方式把系统提示写入CODEX_CONFIG的developer_instructions字段。而resolveCodexACPBaseUrl(同文件 L97-L114)会先从CODEX_CONFIG的 JSON 中解析model_provider与对应base_url以定位凭据代理的匹配 URL,解析失败时回退到https://api.openai.com/v1。
Codex 权限模式:为什么只有 allow-all
Codex ACP 只支持permissionMode: 'allow-all',因为更严格的 Codex 权限模式会启用其内部沙箱,与 AI SDK harness 的沙箱编排冲突。这一点在 profile 中有直接体现:
permissionModeMapping: { 'allow-reads': null, 'allow-edits': null, 'allow-all': { type: 'session-mode', modeId: 'agent-full-access' }, } as const satisfies ACPPermissionModeMapping,null表示该 Harness 权限模式在 Codex ACP 下不可用。底层机制可见 packages/harness-acp/src/v1/bridge/permission-mode.ts:configureACPPermissionMode会先在映射表中查找目标,若对应项为null则抛出Permission mode "allow-reads" is not supported by this ACP harness.之类的错误,并提示改用allow-all。对应行为在 packages/harness-acp/src/acp-harness.test.ts 中有专门测试用例覆盖(transports explicit unsupported permission mode mappings)。
Grok Build ACP:二进制验证、隔离 GROK_HOME 与双端点映射
Grok Build 的 profile(acp-grok-build)在整个矩阵中比较特殊,因为安装的@xai-official/grok包的 npm trampoline 可能复用默认 Grok 主目录中已存在的旧二进制,导致验证时看到的并非包内声明的版本。为此,示例在验证阶段使用了隔离的GROK_HOME环境,并确认grok --version报告0.2.111 (94172f2aa4e5)——这正是被验证的真实二进制版本。
该精确版本二进制对外暴露以下环境变量:
| 环境变量 | 用途 |
|---|---|
XAI_API_KEY | 直接认证密钥 |
GROK_XAI_API_BASE_URL | OpenAI 兼容的推理端点 |
GROK_MODELS_BASE_URL | 模型列表端点 |
GROK_CLIENT_NAME/GROK_CLIENT_VERSION | 客户端归属(attribution)标识 |
在 Gateway 启动路由下,profile 会把两个端点(推理端点与模型端点)都映射到以/v1结尾的已配置 Gateway URL,同时供应客户端归属标识;而在直接模式下,这些值原样保留、不做任何改写。实现见 packages/harness-grok-build/src/grok-build-harness.ts:
providerAuthentication: { gateway: { env: { GROK_CLIENT_NAME: { $source: 'client-app-name' }, GROK_CLIENT_VERSION: { $source: 'client-app-version' }, XAI_API_KEY: { $source: 'gateway-api-key' }, GROK_XAI_API_BASE_URL: { $source: 'gateway-base-url', ensureSuffix: '/v1' }, GROK_MODELS_BASE_URL: { $source: 'gateway-base-url', ensureSuffix: '/v1' }, }, }, },此外 Grok Build 的可执行入口是grok agent stdio(executable: 'grok'+args: ['agent', 'stdio']),指令通过文件系统映射写入.grok/AGENTS.md,且其凭据代理在沙箱内将Authorization: Bearer <sandbox key>替换为宿主侧真实XAI_API_KEY。
凭据环境变量速查表
端到端示例所需的完整环境变量清单集中在 examples/harness-e2e-next/env.local.example 中,与上述 profile 一一对应:
# Vercel OIDC token,Vercel Sandbox 必需 VERCEL_OIDC_TOKEN=xxxxxxx # AI Gateway 凭据:任一 Harness 适配器使用,ACP profile 检测到即自动启用 Gateway AI_GATEWAY_API_KEY=xxxxxxx # Claude Code ACP 直接认证;ANTHROPIC_AUTH_TOKEN 存在时也会一并转发 ANTHROPIC_API_KEY=xxxxxxx ANTHROPIC_AUTH_TOKEN=xxxxxxx # Codex ACP 直接认证;CODEX_API_KEY 未设置时回退到 OPENAI_API_KEY CODEX_API_KEY=xxxxxxx OPENAI_API_KEY=xxxxxxx # Grok Build ACP 直接认证 XAI_API_KEY=xxxxxxx在应用中使用 ACP profile
这些 profile 最终通过HarnessAgent接入应用。以 acp-claude-code/basic-agent.ts 为例,profile 被直接作为harness传入,配合createVercelSandbox提供的沙箱:
export const claudeCodeACPHarnessAgent = new HarnessAgent({ harness: claudeCodeACPHarness, sandbox: createVercelSandbox({ runtime: 'node24', ports: [4000], }), tools: { getUserName: getUserNameTool }, debug: { enabled: true }, telemetry: { integrations: [ createTraceTreeReporter(), createFileReporter({ dir: '.harness-observability/acp-claude-code/basic', }), ], }, });创建会话后即可用agent.generate({ session, prompt })驱动外部编码 Agent 完成任务。acp-codex的 basic-agent.ts 结构完全一致,只是替换了 profile 与可观测性输出目录。示例中的两个 ACP profile 目录还各提供 8 个可复用 agent 变体(basic-agent、basic-stepped-agent、weather-agent、weather-approval-agent、weather-only-agent、builtin-tools、question-tool、ai-sdk-coding-agent),覆盖简单问答、分步执行、内置工具透传与编码仓库任务等场景。
小结
通过examples/harness-e2e-next的 ACP harnesses 示例可以看到,AI SDK 把外部编码 Agent 的接入抽象成三个层次:profile 声明(createACP定义凭据、可执行文件与 Gateway 映射)、自动/显式认证选择(AI_GATEWAY_API_KEY/VERCEL_OIDC_TOKEN触发 Gateway,auth参数强制覆盖)、运行时差异封装(Claude Code 的 Anthropic 环境、Codex 的/v1OpenAI 兼容 provider 与allow-all限制、Grok Build 的隔离GROK_HOME与双端点映射)。理解这三点,即可在自己的应用中安全、可复现地接入任意 ACP 兼容编码 Agent。
【免费下载链接】aiThe AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents项目地址: https://gitcode.com/GitHub_Trending/ai/ai
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考