AI SDK 的 Deep Agents Harness 适配器演进:从 @ai-sdk/harness-deepagents 看桥接式编码代理的运行机制与能力全景
【免费下载链接】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-deepagents是 AI SDK(The AI Toolkit for TypeScript)中把 LangChain 的 Deep Agents(基于 LangGraph 的编码代理运行时)接入 AI SDK Harness 体系的适配器。本文以该包的 CHANGELOG.md(版本 1.0.0 至 1.0.107)为骨架,结合 源码实现 逐层剖析:它如何在沙箱内通过 Node 桥接进程驱动deepagents包、如何通过 WebSocket 与宿主适配器交互、认证与凭据代理如何工作,以及activeTools/inactiveTools工具过滤、output结构化输出、credentialForwarding、mintBridgeToken、per-harness MCP 服务器、会话恢复等关键能力是如何随版本演进而逐步落地的。读完本文,你将掌握该适配器的完整配置面、生命周期模型与升级断点,可直接用于评估和接入自己的 Agent 应用。
一、包定位:桥接式(Bridge-Backed)Harness 适配器
从 README.md 与 package.json 可以看到,该包是一个HarnessV1适配器,harnessId为deepagents(见 deepagents-harness.ts)。它的核心设计是:
- 运行时在沙箱内:Deep Agents 运行时并不运行在宿主进程,而是通过一个 Node 桥接脚本
bridge.mjs运行在 AI SDK 沙箱(Sandbox)中,桥接运行时基于共享的@ai-sdk/harness/bridge。 - 宿主通过 WebSocket 驱动轮次:宿主适配器(
doStart加会话的doPromptTurn/doStop/doDestroy)通过 WebSocket 通道与沙箱内的桥接进程通信,流式事件(文本增量、推理增量、工具调用、文件变更等)沿该通道回传。 - 依赖按需安装:桥接进程所依赖的
deepagents包与 LangChain 系依赖,会在启动时通过pnpm install --frozen-lockfile安装到引导(bootstrap)目录,而不是打进宿主包。
包版本与@ai-sdk/harness、@ai-sdk/provider-utils保持严格同步(每次 Patch 都会联动升级对应依赖版本),这是 CHANGELOG 中最频繁出现的条目类型。包要求 Node.js >= 22,并以zod(^3.25.76 或 ^4.1.8)为 peer 依赖——这正是 1.0.3 中fix(harness): fix harness Zod usage to be v3/v4 compatible的由来:适配器内部统一使用zod/v4解析桥接协议,同时兼容宿主侧的 zod v3 与 v4。
1.1 快速上手
pnpm add @ai-sdk/harness-deepagents @ai-sdk/harnessimport { HarnessAgent } from '@ai-sdk/harness/agent'; import { deepAgents } from '@ai-sdk/harness-deepagents'; const agent = new HarnessAgent({ harness: deepAgents, // 等价于 createDeepAgents() // ...sandbox provider configuration });deepAgents是默认实例(等价于createDeepAgents(),见 index.ts),createDeepAgents(settings)则用于传入自定义设置。
二、认证体系:Anthropic 直连与 AI Gateway 双模式
Deep Agents 始终通过 Anthropic 客户端驱动模型,但非 Anthropic 模型可以经由 AI Gateway 的 Anthropic 兼容端点转发(含工具调用转换)。deepagents-auth.ts 完整实现了这套逻辑:
- 认证模式
DeepAgentsAuthenticationMode目前只有'anthropic'一种字面量(继承HarnessV1Authentication<'anthropic'>),运行时解析出的实际模式(DeepAgentsResolvedAuthenticationMode)则可能是'anthropic'或'ai-gateway'。 - 凭据环境变量固定为三个:
AI_GATEWAY_API_KEY、ANTHROPIC_API_KEY、ANTHROPIC_AUTH_TOKEN。 - 解析优先级:未显式配置时,若环境存在 AI Gateway 凭据则优先走 gateway,否则回退到 ambient Anthropic 凭据;显式传
auth: 'anthropic'则强制直连 Anthropic(读取ANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN/ANTHROPIC_BASE_URL),gateway 模式则把AI_GATEWAY_API_KEY同时映射为ANTHROPIC_API_KEY并设置ANTHROPIC_BASE_URL(Anthropic SDK 会自行追加/v1/messages,因此 base URL 保留在根路径)。
这也是 CHANGELOG 中auth选项演进的完整脉络:
| 版本 | 变更 | 含义 |
|---|---|---|
| 1.0.71 | simplify the auth param to be a simple string to choose the auth method | auth简化为字符串选择认证方式 |
| 1.0.92 | allow harness sessions to optionally authenticate from an isolated environment supplied through the auth option, and remove support for the formerly deprecated legacy auth options types | auth可传入隔离的凭据环境(不必读process.env),同时删除旧的遗留 auth 选项类型 |
因此现在可以这样编程式传入认证环境:
const agent = new HarnessAgent({ harness: createDeepAgents({ auth: { ANTHROPIC_API_KEY: token }, // 隔离环境,不读 process.env }), model: 'anthropic/claude-sonnet-4.5', });三、凭据代理与请求转换:沙箱内不落盘真实密钥
沙箱内的桥接进程也需要调用模型 API,但真实密钥不应直接注入沙箱进程环境。适配器在 1.0.72 引入了网络沙箱抽象层的请求转换能力,并基于它实现凭据代理(credential brokering):沙箱内使用临时伪造的秘密,宿主侧通过请求转换把请求头中的临时秘密替换回真实凭据。
实现位于 deepagents-auth.ts:createDeepAgentsRequestTransformations根据认证模式匹配请求 URL(gateway 模式用ANTHROPIC_BASE_URL,anthropic 模式默认https://api.anthropic.com),当宿主环境与沙箱环境同时存在ANTHROPIC_API_KEY或ANTHROPIC_AUTH_TOKEN时,分别注册x-api-key与Authorization: Bearer ...的请求头改写规则。
围绕该机制的 CHANGELOG 条目:
- 1.0.87:新增
credentialForwarding设置,为桥接式适配器提供细粒度控制——它自定义每个凭据值在被转发进沙箱进程前的改写方式,但不限制宿主进程能发现、读取的凭据范围(见 deepagents-harness.ts 的类型注释)。 - 1.0.90:加固凭据代理,只在携带正确的临时秘密时才应用替换(
harden credential brokering to only apply with correct ephemeral secret)。 - 1.0.100:当
credentialForwarding回调把全部凭据替换为临时假秘密时,不再误报"缺乏凭据代理支持"的警告(avoid warning about lack of credential brokering support ...)。 - 1.0.72:支持网络沙箱抽象中的请求转换并用于凭据代理,同时引入
getPortEndpoint()作为getPortUrl()(已弃用)的更全面替代。
此外从源码看,若沙箱会话不支持addRequestTransformations,适配器会退化为直接把改写后的凭据环境注入桥接进程,并通过warnCredentialBrokeringUnavailable提示凭据代理不可用。这解释了 CHANGELOG 中多次出现的"凭据代理"相关修复的上下文。
四、DeepAgentsHarnessSettings 完整配置面
结合 deepagents-harness.ts 的DeepAgentsHarnessSettings类型与协议定义,适配器的全部设置如下:
| 设置项 | 类型 | 说明 |
|---|---|---|
auth | DeepAgentsAuthenticationMode | 认证方式或隔离认证环境,未设置时按环境自动解析 |
credentialForwarding | HarnessV1CredentialForwarding | 自定义每个凭据转发进沙箱前的改写 |
thinking | DeepAgentsThinkingConfig | 控制 Anthropic 扩展思考;未设置保留 Deep Agents 运行时默认值 |
effort | 'low' \| 'medium' \| 'high' \| 'xhigh' \| 'max' | 自适应思考下的努力程度;未设置使用 LangChain Anthropic 客户端默认值 |
port | number | 桥接端口覆盖;默认取沙箱第一个声明的端口 |
portEndpoint | HarnessV1PortEndpoint | 覆盖连接沙箱桥接的宿主端点;使用 basic sandbox 会话时必须与port一起提供 |
startupTimeoutMs | number | 等待桥接广播端口的最长时间,默认 120000 |
mintBridgeToken | HarnessV1MintBridgeTokenCallback | 生成沙箱桥接认证令牌;默认随机 32 字节十六进制令牌 |
recursionLimit | number | 每轮 LangGraph super-step 上限,超限报错;省略时用 Deep Agents 默认值 |
mcpServers | Record<string, unknown> | 按名称键控的 MCP 服务器定义,使用底层运行时的原生 MCP 配置格式 |
其中thinking支持三种形态(bridge 协议 中有对应的 discriminated union schema):
type DeepAgentsThinkingConfig = | { type: 'adaptive'; display?: 'summarized' | 'omitted' } | { type: 'enabled'; budget_tokens: number; display?: 'summarized' | 'omitted' } | { type: 'disabled' };4.1 设置相关的重要版本演进
- 1.0.93:
model参数上移到HarnessAgent,各 harness 适配器构造函数不再各自支持model;同时新增prepareCall()支持,允许在两个轮次之间更改 harness 设置。1.0.94 进一步允许通过调用选项(call options)在轮次之间更换model。 - 1.0.104:正式移除先前已弃用的 harness 适配器设置上的
model与modelId配置——从源码看模型现在统一由HarnessAgent持有,并在doPromptTurn时经start消息传入桥接。 - 1.0.102:新增
headers属性,允许在推理请求(inference requests)上附带任意请求头;源码中该值通过start消息的headers字段下发。 - 1.0.64:新增 per-harness MCP 服务器支持(
mcpServers);同一版本还引入可选的mintBridgeToken(sandboxId)回调,用于控制桥接令牌的具体取值。 - 1.0.95:新增可复用的
createBridgeToken()与withBridgeToken()助手(供桥接式 harness 适配器使用),并修复了桥接解析会去寻找替代路径、进而引发 Turbopack 报错的问题。 - 1.0.96:新增可复用的
createReadBridgeAsset()助手(bootstrap 引导资产读取即由它实现,见 deepagents-bootstrap.ts)。 - 1.0.52:bootstrap 文件不再写入
/tmp,改放在沙箱工作目录内,以便快照型沙箱提供方可以持久化其安装与配方标记。 - 1.0.19:适配器统一发送
User-Agent与x-client-app请求头(客户端标识为ai-sdk/harness-deepagents/<version>,见 deepagents-harness.ts)。
五、内置工具:通用名到 LangGraph 原生工具的映射
适配器声明了 Deep Agents 全部可被模型调用的内置工具,统一注册在DEEPAGENTS_BUILTIN_TOOLS(deepagents-harness.ts)。AI SDK 侧若未全部列出,会抛出AI_NoSuchToolError,因此这张表必须与桥接层实际发射的工具名完全一致:
| 通用名 | 原生(LangGraph)工具 | 工具用途类别 | 输入 Schema 要点 |
|---|---|---|---|
read | read_file | readonly | { file_path } |
write | write_file | edit | { file_path, content } |
edit | edit_file | edit | { file_path, old_string, new_string } |
bash | execute | bash | { command } |
grep | grep | readonly | { pattern } |
glob | glob | readonly | { pattern } |
ls | ls | — | { path? }(无通用名,按原生名键控) |
task | task | — | { description?, subagent_type? }(派生子代理处理委派任务) |
write_todos | write_todos | — | { todos? }(管理结构化待办列表) |
需要说明:包 README.md 中的内置工具表(bash → shell、grep → search)与当前源码实现不一致,应以源码中的read_file/write_file/edit_file/execute/grep/glob映射为准——这属于文档滞后于代码的情况。
工具过滤能力(activeTools/inactiveTools)在1.0.11加入,允许按名启用/禁用内置工具;过滤逻辑经start消息的builtinToolFiltering字段下发。1.0.11同时为 harness 中若干重复层提供了工具函数。
六、生命周期与会话恢复:从停止/挂起到跨进程续跑
适配器实现的会话方法(deepagents-harness.ts)包括:
doPromptTurn:发起新轮次。校验结构化输出必须携带 JSON Schema;把 skills 物化到沙箱$HOME/.agents/skills(writeSkills,名称需匹配^a-z0-9?$,1-64 位小写字母数字加连字符);随后发送start消息并挂起订阅stream-start、text-delta、reasoning-delta、tool-call、tool-approval-request、tool-result、file-change、finish-step、raw等流部件。doContinueTurn:续跑当前轮次。若continueFrom目标桥接进程仍存活,doStart会以{ resume: true }打开通道回放游标之后的事件,不再发送start(发送会清空回放日志)。doSuspendTurn/doDetach:在游标处冻结当前轮次(channel.suspend()取得lastSeenEventId),保留桥接进程存活,返回包含桥接坐标(port、token、lastSeenEventId、sandboxId)与凭据代理环境的状态载荷,供后续进程重新附着(attach)。doStop/doDestroy:向桥接发送stop/destroy命令并执行进程回收(等待 5 秒超时后 kill)。doCompact:手动压缩不支持,抛HarnessCapabilityUnsupportedError。
CHANGELOG 中与之相关的关键条目:
- 1.0.94:
Preserve Deep Agents conversation context when a stopped session is resumed——停止的会话恢复时保留对话上下文。 - 1.0.78:实验性支持转向中干预(steering agent conversations mid-turn);同版本还支持向
HarnessAgentSession传入文件系统与进程受限的沙箱会话,网络沙箱会话方法不可用时自动回退(fallback)。 - 1.0.54:桥接方法重命名——
detach改为stop、shutdown改为destroy,语义更清晰。 - 1.0.42:移除损坏的桥接
channel.interrupt()层及其调用。 - 1.0.22:改进 opaque sandbox bridge 的错误处理;按底层模型步骤正确发射
finish-step流部件。 - 1.0.40:重构桥接代码,把流事件发射从 launcher 中拆分出来使其可测试;修复 Deep Agents 遥测中缺失模型 ID 的问题;修复对 Deep Agents 递归限制默认值过度覆盖的问题。
从源码结构看,doStart优先尝试"附着已有桥接"路径:只要continueFrom/resumeFrom状态里带桥接坐标,就先尝试以该坐标连接 WebSocket 并回放,失败再回退到全新拉起桥接进程。
七、引导(Bootstrap)机制:ripgrep 校验安装与依赖锁定
沙箱内首次启动时,适配器会写入三份引导资产(deepagents-bootstrap.ts):
bridge.mjs(桥接入口,从包内src/bridge/index.mjs读取后写入沙箱$WORKDIR/.harness-bootstrap/deepagents/)package.json与pnpm-lock.yaml(锁定deepagents及 LangChain 系版本)
随后执行两条引导命令:
- ripgrep 校验安装:
command -v rg已存在则跳过;否则按架构下载固定版本(14.1.1)的压缩包,用硬编码 SHA-256 校验(x64 与 aarch64 各一份)后安装到/usr/local/bin/rg。之所以必须安装,是因为 Deep Agents 的 grep 会外部调用rg,缺失时回退逻辑会整个读取工作目录(含 node_modules)到内存,容易 OOM。 pnpm install --frozen-lockfile --store-dir .pnpm-store:按锁定文件安装桥接运行时依赖。
bootstrap 目录位于沙箱默认工作目录之下,正是 1.0.52 变更的结果:快照型沙箱提供方可以在不要求根文件系统访问的前提下,持久化这份安装产物与配方标记。
八、协议约束与当前能力边界
从 deepagents-bridge-protocol.ts 与源码中的unsupported分支可以梳理出明确的边界:
- 提示(prompt)仅支持纯文本:
extractUserText会拒绝非 text 类型的内容部件(如图片、文件部件),否则抛HarnessCapabilityUnsupportedError。 - 结构化输出必须有 JSON Schema:
responseFormat.type === 'json'但未提供 schema 时会直接拒绝。 - basic 沙箱会话(无
getPortEndpoint能力)必须显式提供port与portEndpoint,否则启动即报错。 mintBridgeToken需要沙箱暴露 id:无 id 的会话使用该选项会抛HarnessCapabilityUnsupportedError(deepagents-harness.ts)。- 手动压缩不支持;README 同时提示续跑轮次、挂起/脱离、跨进程恢复与内置工具审批等能力仍属后续迭代(部分能力如工具审批、续跑与恢复在后续版本中已逐步落地,如 1.0.78、1.0.94 的进展)。
内置工具审批(built-in tool approvals)由桥接侧通过 Deep Agents 的interruptOn(HITL)中间件门控(supportsBuiltinToolApprovals: true),宿主侧通过tool-approval-request/tool-approval-response流部件完成人工确认交互。
九、验证与测试资产
包内提供了覆盖各层逻辑的测试,可直接作为理解行为的参考入口:
- deepagents-harness.test.ts:宿主适配器端到端行为测试
- deepagents-auth.test.ts:认证模式与环境解析测试
- deepagents-bridge-protocol.test.ts:桥接协议 schema 测试
- deepagents-bootstrap.ts 旁的路由资产、bridge 目录下的
approvals.test.ts、create-emit-stream-event.test.ts、json-schema-to-zod.test.ts、tool-filtering.test.ts、persistent-memory-saver.test.ts等则验证桥接内部各模块
README 明确标注当前状态为"happy-path validated":文本生成、流式输出、多轮记忆与宿主执行工具均已在真实 Vercel Sandbox 中端到端验证。测试可通过pnpm test:node运行(vitest 配置见 vitest.node.config.js)。
十、升级要点速览
对使用方而言,CHANGELOG 中最值得注意的破坏性/行为变化集中在:
- model 迁移(1.0.93 → 1.0.104):模型统一由
HarnessAgent({ model })持有,适配器设置上的model/modelId已删除,升级时需把模型参数上移。 - auth 选项简化(1.0.71 → 1.0.92):旧的 legacy auth 选项类型已移除,现在只接受认证方式字符串或隔离凭据环境对象。
- 桥接方法重命名(1.0.54):
detach→stop,shutdown→destroy。 - zod v3/v4 兼容(1.0.3):peer 依赖放宽到
^3.25.76 || ^4.1.8,宿主可按自身生态选择。
其余版本主要是@ai-sdk/harness与@ai-sdk/provider-utils的依赖联动升级,配合本文第五节列出的功能落地时间点,即可完整回溯该适配器的能力成长路径。
【免费下载链接】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),仅供参考