ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

使用 @ai-sdk/harness-acp 将 ACP v1 Agent 接入 AI SDK:桥接架构、配置映射与实战

使用 @ai-sdk/harness-acp 将 ACP v1 Agent 接入 AI SDK:桥接架构、配置映射与实战 使用 ai-sdk/harness-acp 将 ACP v1 Agent 接入 AI SDK桥接架构、配置映射与实战【免费下载链接】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-sdk/harness-acp是 AI SDK 的 HarnessV1 适配器它让HarnessAgent能够直接驱动遵循 Agent Client Protocol 为主线结合该包源码完整讲解它的桥接运行架构、安装配置、createACP全部核心选项模型映射、指令映射、权限模式映射、凭据代理等并给出一个可复制的端到端示例。读完本文你将能基于任意 NPM 安装的 ACP v1 实现在自己的沙箱中快速搭建一个 AI Agent Harness。架构总览桥接进程、沙箱与 WebSocketai-sdk/harness-acp是一个HarnessV1适配器其底层是一个通过 NPM 安装的Agent Client Protocol v1 实现下称ACP 实现。整体运行模型可以用一句话概括适配器在沙箱内托管一个桥接进程桥接进程在沙箱代理的回环端口上通过 WebSocket 与宿主机通信而配置的 ACP 实现与桥接进程一同运行在沙箱内部。具体链路对应 acp-v1-harness.ts 中doStart的实现为宿主侧的HarnessAgent调用createACP生成的适配器在沙箱会话中启动桥接脚本bridge.mjs桥接进程监听沙箱暴露的 TCP 端口BRIDGE_WS_PORT并携带一枚BRIDGE_CHANNEL_TOKEN令牌进行鉴权见 acp-v1-harness.ts宿主通过SandboxChannel底层为ws库的 WebSocket 客户端连接到该端口按照outboundMessageSchema/inboundMessageSchema见 acp-v1-bridge-protocol.ts收发桥接协议消息桥接进程内部加载 ACP v1 实现将宿主的请求翻译为 ACP JSON-RPC 方法session/new、session/start、session/set_mode、session/set_config_option等并把实现的流式事件翻译回宿主。因此有两条硬性约束README 也明确指出桥接型 ACP harness 要求沙箱至少暴露一个端口ports: [4000]或显式配置port。源码中resolveBridgePort会优先使用portOverride否则取沙箱ports数组的第一个元素两者都没有时直接抛出unsupported错误见 acp-v1-harness.ts。使用不支持getPortEndpoint的 basic 沙箱会话时必须同时显式配置port与portEndpoint见 acp-v1-harness.ts。从源码结构看桥接层还承担了相当多的职责包括ACP 流事件捕获acp-stream-capture.ts、Agent stderr 监控agent-stderr-monitor.ts、宿主工具 MCP 中继host-tool-relay.ts、host-tool-mcp.ts、会话生命周期管理session-lifecycle.ts与流翻译stream-translator.ts等这些都位于 bridge 目录 下。安装与首次启动安装共需三个包适配器本身、harness 基座提供HarnessAgent以及沙箱实现npm i ai-sdk/harness-acp ai-sdk/harness ai-sdk/sandbox-vercel从 package.json 可以看到ai-sdk/harness-acp运行时依赖ai-sdk/harness、ai-sdk/provider-utils与ws并将zod作为 peer 依赖支持^3.25.76 || ^4.1.8同时要求 Node.js22。包内声明了两个workspace:*依赖说明在 monorepo 环境下与 harness 基座共同演进。首次会话启动时桥接进程会在沙箱内部安装配置的 ACP 实现。安装方式由source字段决定见 implementation.tsnpm-simple按包名可选精确版本安装内部生成package.json并执行pnpm install --prodnpm-locked直接使用你提供的packageJson与pnpmLockYaml可选pnpmWorkspaceYaml以--frozen-lockfile锁定安装保证可复现install-command在沙箱内执行自定义安装命令可执行文件路径固定为home/.local/bin/executable并拥有独立的私有$HOME。最小可用示例连接 Codex ACPREADME 给出了一个完整示例——把HarnessAgent连接到 Codex ACP并使用 OpenAI 直连鉴权import { HarnessAgent } from ai-sdk/harness/agent; import { createACP } from ai-sdk/harness-acp; import { createCredentialRequestTransformation } from ai-sdk/harness/utils; import { createVercelSandbox } from ai-sdk/sandbox-vercel; const codexACP createACP({ harnessId: acp-codex, source: { type: npm-simple, packageName: agentclientprotocol/codex-acp, packageVersion: 1.1.4, }, executable: codex-acp, modelMapping: { type: session-config-option, path: model, }, credentialEnv: [CODEX_API_KEY, OPENAI_API_KEY], credentialBrokering: ({ env, sandboxEnv }) { const environmentVariableName env.CODEX_API_KEY ? CODEX_API_KEY : OPENAI_API_KEY; const credential env[environmentVariableName]; const sandboxCredential sandboxEnv?.[environmentVariableName]; if (!credential || !sandboxCredential) return []; return [ createCredentialRequestTransformation({ matchUrl: https://api.openai.com/v1, matchHeaders: { Authorization: Bearer ${sandboxCredential}, }, transformHeaders: { Authorization: Bearer ${credential} }, }), ]; }, instructionMapping: { type: launch-env-json, variable: CODEX_CONFIG, path: [developer_instructions], }, permissionModeMapping: { allow-reads: null, allow-edits: null, allow-all: { type: session-mode, modeId: agent-full-access }, }, authentication: { methodId: api-key, }, }); const agent new HarnessAgent({ harness: codexACP, sandbox: createVercelSandbox({ runtime: node24, ports: [4000], }), }); const session await agent.createSession(); try { const result await agent.generate({ session, prompt: Inspect this project and summarize its purpose., }); console.log(result.text); } finally { await session.destroy(); }运行前需在宿主机环境中设置CODEX_API_KEY或OPENAI_API_KEY二者取其一即可credentialBrokering回调会按优先级选择。session.destroy()放在finally中确保任何情况下会话资源都能被释放。配置项深度解析createACP的入参类型为ACPHarnessSettings见 acp-harness.ts除上文示例外下面逐个拆解核心配置。harnessId 与版本harnessId必填稳定的 kebab-case 标识符正则^[a-z0-9](?:-[a-z0-9])*$用于区分不同 ACP 实现、会话目录与生命周期状态。源码在 acp-v1-harness.ts 定义并在启动前校验。version默认v1目前仅支持v1传入其他值会抛出 Unsupported ACP protocol version见 acp-harness.ts。clientApp可选默认{ name: ai-sdk/harness-acp, version: VERSION }会在 ACP 客户端身份client/register中上报。实现安装source 与 executablesource必填npm-simple/npm-locked/install-command三种安装源详见上文首次启动一节。注意npm-simple的packageVersion必须是精确语义化版本且省略版本号时安装latestdist-tag此时版本不参与实现身份哈希——即上游发布新版本不会使既有生命周期状态失效见 acp-v1-settings.ts 与 implementation.ts。executable必填裸命令名不含路径安装后从node_modules/.bin/npm 源或home/.local/bin/install-command 源解析。args可选启动 ACP 实现时追加的命令行参数。模型映射modelMapping必填ACP 实现的模型选择操作各不相同因此modelMapping是必填项。两种取值类型定义见 acp-v1-settings.ts发送逻辑见 bridge/model-mapping.ts类型用途底层 ACP 方法session-config-option通过 ACP 配置选项指定模型path为配置选项 IDsession/set_config_optionconfigId: path,value: modelsession-model使用传统session/set_model方法path为 JSON-RPC 请求属性名session/set_model例如 Codex 使用session-config-optionpath: model而 Grok Build 等实现沿用session/set_model应改用session-model。另外当HarnessAgent未配置模型时适配器不会发送任何模型操作见 model-mapping.ts 的if (model null) return;。指令映射instructionMapping当 ACP 实现支持原生 system / developer prompt 时用instructionMapping把HarnessAgent的 instructions 路由进去。三种映射方式见 acp-v1-settings.ts 与 bridge/instruction-mapping.tssession-meta把指令写入 ACP 会话请求_meta字段下的指定路径path为相对_meta的属性路径数组launch-env-json实现启动前把指令合并进某个 JSON 环境变量variable的指定路径如示例中的CODEX_CONFIG→developer_instructionsfilesystem把指令写成一个 markdown 文件存放在实现有效$HOME下的相对路径。重要兼容性说明不配置instructionMapping时适配器保留向后兼容行为——把指令前置拼接到第一条用户 prompt上。另外session-meta与launch-env-json的路径会做安全校验禁止空属性名以及__proto__、constructor、prototype等危险段见 instruction-mapping.ts。权限模式映射permissionModeMapping把 HarnessAgent 的三种权限模式allow-reads/allow-edits/allow-all映射为 ACP 目标见 acp-v1-settings.ts值为null表示该权限模式不受支持调用时直接报错{ type: session-mode, modeId }调用 ACPsession/set_mode{ type: session-config-option, configId, value }调用session/set_config_option布尔值会附带type: boolean。Codex 特例Codex ACP 只支持permissionMode: allow-all因为它更受限的模式会启用 Codex 内部的沙箱导致嵌套沙箱冲突。示例中把allow-reads、allow-edits都置为null仅allow-all映射到agent-full-access模式。若运行时请求了未映射的模式适配器会抛出带提示的错误见 bridge/permission-mode.ts。凭据与认证authenticationACP 认证方式声明示例使用{ methodId: api-key }类型定义见 acp-auth.tsACPClientApp、ACPAuthenticationMode。credentialEnv与credentialBrokering二者必须同时配置否则createACP直接抛错ACP credentialEnv and credentialBrokering must be configured together.见 acp-harness.ts。credentialEnv声明要进入沙箱凭据环境的宿主机环境变量credentialBrokering是一个接收{ env, sandboxEnv, headers }并返回HarnessV1RequestTransformation[]的回调用于把真实凭据代理给沙箱内发出的匹配请求。两种沙箱行为差异README 明确强调支持additive request transformations即实现addRequestTransformations的沙箱只收到凭据占位符真实值仅当发出的出站请求携带预期占位符时才被注入对应createSandboxCredentialEnvironmentaddRequestTransformations的流程见 acp-v1-harness.ts其他沙箱保留传统行为直接把凭据值转发给 ACP 进程。credentialForwarding在凭据进入沙箱进程前做自定义改写authenticationFiles在实现启动前于其私有 home 目录下落地认证文件写入后统一chmod 600保护见 acp-v1-harness.ts。其他可选能力mcpServers/isMcpToolCall向 ACP 实现提供 MCP 服务器定义ai-sdk-harness-tools这一名字被保留给 HarnessAgent 工具占用会报错见 acp-harness.ts。hostToolMcpTransportharness 自有的、把宿主工具暴露给 ACP 实现的 MCP 服务器传输方式默认stdio某些只接受 HTTP/SSE MCP 服务器的实现需设为http并要求实现声明agentCapabilities.mcpCapabilities.http。askUserQuestions把 ACP 实现的原生提问请求桥接为 HarnessAgent 的askUserQuestions内置工具配置了它工具集会自动注入该内置工具见 acp-harness.ts。outputSchemaMapping把结构化输出的 JSON Schema 映射到 ACP 会话 prompt_meta下的指定路径当前仅session-prompt-meta类型。session.meta附加到 ACP 会话请求_meta的静态元数据。startupTimeoutMs桥接启动超时默认120_000毫秒见 acp-v1-harness.ts。mintBridgeToken自定义沙箱桥接鉴权令牌默认随机生成 32 字节十六进制串。env/forwardEnv运行环境字面量 / 按名转发的环境变量三个来源forwardEnv、credentialEnv、env之间的键不允许重叠否则校验失败见 implementation.ts。Skills 与指令落盘机制Skills 默认写入 ACP 实现有效$HOME下的.agents/skills目录常量DEFAULT_ACP_SKILLS_DIRECTORY见 acp-v1-skills.ts由实现原生发现。需要换目录时通过skillsDirectory指定其他相对路径例如 Claude Code 系的实现可设为.claude/skills。源码同时做了严格的路径与命名校验skill 名称必须为 kebab-case 小写 slug^[a-z0-9](?:-[a-z0-9])*$不允许./../ 重复名称附带文件路径必须是相对 POSIX 路径禁止绝对路径、反斜杠与..穿越且SKILL.md保留给 skill 定义文件不能被附带文件占用见 acp-v1-skills.ts。此外每个会话的桥接状态目录位于~/.ai-sdk/harness-acp/harnessId/sessionId 的 sha256 哈希见resolveACPPrivateSessionDirectory事件日志event-log.ndjson落在此目录供崩溃恢复disk-replay/lossy-rerun/cold-restore三种重放策略见 acp-v1-harness.ts使用。生命周期与崩溃恢复ACP 适配器实现了较完整的会话生命周期管理源码在 acp-v1-lifecycle.ts 与 bridge/session-lifecycle.ts冷启动createSession()后首次generate()发起session/newsession/start恢复resume通过continueFrom/resumeFrom携带生命周期状态优先尝试直接重连既有 WebSocket 桥带lastSeenEventId进程丢失恢复桥接失败时根据event-log.ndjson是否完整可重放选择disk-replay基于磁盘事件日志回放或lossy-rerun带turnStartConfig与acpSessionId重新跑一轮冷会话则走cold-restore见 acp-v1-harness.ts。生命周期状态本身也经过 zod schema 校验acpResumeStateSchema见 acp-harness.ts其中包含实现身份implementationIdentity、认证画像authenticationProfile、桥接坐标bridge与恢复/还原标记等字段。恢复前还会校验生命周期兼容性validateACPLifecycleCompatibility确保实现身份与认证画像匹配后才允许续跑。常见问题与使用边界必须暴露端口createVercelSandbox({ runtime: node24, ports: [4000] })中ports不能省略basic 沙箱会话则必须同时给port和portEndpoint。凭据配置成对出现credentialEnv与credentialBrokering要么都不配要么一起配否则启动即抛错。Codex 仅支持allow-all不要向 Codex 请求allow-reads/allow-edits其受限模式会启用 Codex 内部沙箱。modelMapping必填且选型取决于具体实现session-config-optionvssession-model未配置模型时不会发送模型操作。环境变量键冲突同一键不能同时出现在forwardEnv、credentialEnv、env中的任意两处。指令映射缺省行为不配instructionMapping时指令会前置拼接到首个用户 prompt向后兼容。Node 版本包要求 Node.js22见 package.json。小结ai-sdk/harness-acp通过沙箱内桥接 回环 WebSocket 协议翻译的架构把任意 ACP v1 实现无缝接入 AI SDK 的HarnessAgent并借助modelMapping、instructionMapping、permissionModeMapping、credentialBrokering等声明式映射弥合了不同 Agent 实现之间的协议差异。本文涉及的实现细节均可在 packages/harness-acp/src 下对应源码中验证入口与配置类型见 acp-harness.tsv1 运行逻辑见 acp-v1-harness.ts桥接子模块见 bridge 目录测试用例见各*.test.ts文件如 acp-harness.test.ts、acp-v1-lifecycle.test.ts。如需接入新的 ACP 实现参照上文示例替换source、executable、modelMapping与permissionModeMapping即可。【免费下载链接】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),仅供参考
返回列表