AI SDK 概念全景总结(v7) 二

1.11 Terminal UI --- @ai-sdk/tui

定位 :在终端里交互式跑 agent,用于本地开发、demo 与内部工具 ------ 提供 prompt 输入、流式响应、tool cards、reasoning 区块、滚动、工具审批提示,而不需要自己写界面。

入口 :runAgentTUI({ title, agent, transport, sandbox, tools, reasoning, responseStatistics, contextSize });安装 pnpm add @ai-sdk/tui ai @ai-sdk/openai。

本地 vs 远程 :传 agent 直接本地跑 ToolLoopAgent;传 transport(new DefaultChatTransport({ api: 'https://example.com/api/chat' }))即走远程 AI SDK UI-message endpoint,endpoint、鉴权、请求体行为由 transport 控制,TUI 的内部 chat id 与消息历史对 transport 契约保持私有。

沙箱 :来自 @ai-sdk/sandbox-just-bash 的 createJustBashNetworkSandboxSession({ cwd: '/home/user' }) → sandboxSession.restricted() 传给 TUI、sandboxSession.destroy() 放在 finally 释放。传 sandbox 时,TUI 把该 sandbox 以 experimental_sandbox 转发到每一次 agent 调用 ,工具的 description 函数与 execute 可从 options 读取并委派命令/文件操作。

审批交互 :toolApproval 支持策略函数,例如 weather: ({ location }) => cond ? 'approved' : 'user-approval';命中 user-approval 时暂停并等待用户按键。

选项取值:

选项 取值 默认
tools 'full'(显示输入+输出)/ 'collapsed'(只显示卡片)/ 'auto-collapsed'(最新一条展开,直到出现其他可见区块)/ 'hidden' 'auto-collapsed'
reasoning 同上四值 'auto-collapsed'
responseStatistics 'outputTokensPerSecond'(吞吐)/ 'outputTokenCount'(输出 token 数) 'outputTokensPerSecond'
contextSize 数值(如 200_000),提供后按模型上下文窗口百分比显示总 token 占用 无

快捷键 :Enter 提交、y/n 批准或拒绝工具调用、Up/Down 滚动、PageUp/PageDown 整页滚动、Ctrl+L 重绘、Esc / Ctrl+C 退出。

注意事项 :用 agent 选项时,agent 必须能被终端自由文本直接驱动 ------ 不得依赖 per-call options(即不能用 callOptionsSchema) ,不得使用 structured output ,因为 TUI 无法从自由 prompt 推断这些值;需要它们请改走 transport,或本地直接调 agent.generate() / agent.stream()。sandbox 的 description(工作目录、公网 hostname、暴露端口)不会自动进入 prompt ,需手动写进 agent instructions。restricted() 与 destroy() 必须成对使用,否则沙箱泄漏。


2. AI SDK Core 板块

定位 :Core 是对 LLM 的标准化集成层 ------ 统一的 prompt 结构、settings、结果形状,让上层(Agents/UI/RSC)不依赖具体厂商 API。

Core 函数清单(Overview 明确列出):

  • generateText --- 生成文本与工具调用,适合非交互自动化(起草邮件、网页摘要)以及使用工具的 agent。
  • streamText --- 流式生成文本与工具调用,适合聊天机器人、内容流式输出等交互场景。
  • 两者都通过 output 属性支持结构化输出(Output.object()、Output.array()),用于信息抽取、合成数据生成、分类任务与流式生成 UI。

其余 Core 能力按工具(Tool Calling、MCP、Code Mode、Tool Search)、上下文(runtime/tool context)、设置(Settings、Prompt Engineering)、推理(Reasoning、Decisions)、模态(Embeddings、Reranking、图像/视频/语音/转写/翻译、File/Skill Uploads、Realtime)、工程化(Middleware、Batch、Provider & Model Management、Error Handling、Testing、Telemetry、DevTools、Lifecycle Callbacks)分组展开。

2.1 Generating Text --- generateText 与 streamText

generateText 结果字段 (result.*):content(所有步骤生成的内容)、text(最终一步 的文本)、files(所有步骤生成的文件)、sources(所有步骤引用的来源,仅部分模型可用)、toolCalls、toolResults、finishReason、rawFinishReason(来自 provider 的原始原因)、usage(多步骤总量)、warnings(provider 警告,如不支持的设置)、steps(各步详情)、finalStep、output(按 output 规格产出的结构化结果)。原始响应头/ body 通过 finalStep.response 访问。

每步 performance 指标 :effectiveOutputTokensPerSecond(outputTokens / requestSeconds)、outputTokensPerSecond(流式专用,首个输出 chunk 之后 outputTokens / outputStreamSeconds;generateText 中为 undefined)、inputTokensPerSecond(流式专用,首 chunk 之前 inputTokens / ttftSeconds;generateText 为 undefined)、effectiveTotalTokensPerSecond、stepTimeMs(含模型响应与工具执行总耗时)、responseTimeMs、toolExecutionMs(按 tool call ID 为键 )、timeToFirstOutputMs(流式专用)、timeBetweenOutputChunksMs(≥2 个 chunk 时的间隔统计,含 min/p10/median/avg/p90/max)。

streamText 要点 :result.textStream 同时是 ReadableStream 与 AsyncIterable 。streamText 立即开始流式并抑制错误 (避免服务端崩溃),错误日志用 onError。它使用背压(backpressure),只在被请求时生成 token ------ 必须消费流才能结束 。与 UI/RSC 集成的 helper:createUIMessageStreamResponse({ stream: toUIMessageStream({ stream: result.stream }) })、pipeUIMessageStreamToResponse({...})、createTextStreamResponse({ stream: toTextStream({ stream: result.stream }) })、pipeTextStreamToResponse({...})。流结束时才 resolve 的一组 promise 与 generateText 字段同构(content/text/finalStep/files/sources/toolCalls/toolResults/finishReason/rawFinishReason/usage/warnings/steps);result.totalUsage 已废弃,改用 result.usage。

onChunk 收到的全部 stream part 类型 (26 种,构成 AI SDK 流协议词汇表):start、start-step、text-start、text-delta、text-end、reasoning-start、reasoning-delta、reasoning-end、custom、source、file、reasoning-file、tool-call、tool-input-start、tool-input-delta、tool-input-end、tool-result、tool-error、tool-output-denied、tool-approval-request、tool-approval-response、finish-step、finish、abort、error、raw。

生命周期回调 :onEnd(稳定,最后一步结束后触发,含 text、usage、finishReason、messages、steps 等);另有标注 experimental 的一组(会随小版本破坏性变更):onStart、onStepStart、onLanguageModelCallStart、onLanguageModelCallEnd、onToolExecutionStart、onToolExecutionEnd、onStepEnd。其中 onLanguageModelCallEnd 在模型响应已归一化解析之后、任何客户端工具执行之前触发,收到模型调用的 content parts、usage、finishReason、provider metadata。

关键差异:core 的 lifecycle 回调比 ToolLoopAgent 多出 onLanguageModelCallStart / onLanguageModelCallEnd (agent 侧只有 6 个)。core 生命周期回调内抛出的错误会被静默捕获,不会打断生成/流式。

流转换 :experimental_transform 选项;转换在回调被调用、promise 被 resolve 之前应用 (例如把文本全转大写的转换,onEnd 收到的就是转换后文本)。内置 smoothStream 平滑 text 与 reasoning 流。自定义转换函数接收模型可用 tools 并返回转换函数。可用 stopStream 提前停止流(如模型护栏被违反);调用 stopStream 时必须手动模拟 finish-step 与 finish 事件 ,否则流不成形、回调不被调用。可提供多个转换,按提供顺序应用。

Sources 与 Citations :Perplexity、Google 等 provider 会返回来源;url 类型 source 含 id、url、title(可选)、providerMetadata。OpenAI Responses 与 Anthropic web search 的 sources 是检索到的引用全集 (可能多于模型实际引用的条数);OpenAI file-search 结果也作为 document sources 暴露;检索数据不可用时,退化为 citation 派生的引用以保持兼容。Citations 是挂在每个 text content part 上的可选数组(Citation 类型从 ai 导出):source(URL 或 document,含可用时的 title,其 ID 标识被引用资源,不一定 与 result.sources 的 ID 对应)、startIndex/endIndex(provider 提供的可选偏移,end 不含 ,各 provider 字符索引惯例不同且 SDK 原样保留 )、citedText(来自 source 的支撑段落,是 source 文本而非生成答案里的偏移)。

用 citations 渲染内联引用,用 result.sources 列检索全集。JS 的 slice() 按 UTF-16 code unit 计数,文本含 emoji 等非 BMP 字符时 provider offset 可能需要换算;offset 缺失或不可靠时把引用与整个文本块一起渲染,不要猜范围。Anthropic 给的是支撑段落与 document 位置而非输出文本偏移 ,细节留在 provider metadata;OpenAI file-search 的 citation index 保留在 provider metadata,不作为输出文本范围解释 。源 URL 的 query 与 fragment 要保留(可能标识特定版本/页/段落);同一 source 可在不同位置被多次引用。streamText 下 citations 出现在 text-end 事件(关联该文本块 id)与完成的 result.content 文本 parts 上,并能在 toUIMessageStream 后作为 TextUIPart.citations 存活(即使禁用 source 事件);citation fallback source 事件可能在 provider 流末尾到达。原始 OpenAI annotations 与 Anthropic citations 仍保留在 text 的 provider metadata;其他 provider 可能省略 citations,省略不代表其 sources 是完整检索集。

2.2 Generating Structured Data --- Output 家族

定位 :文本生成之外,实际业务更需要结构化数据 (信息抽取、分类、合成数据)。许多模型支持 "JSON modes" / "tools",但你要手工提供 schema 并校验结果,因为 LLM 会产生不正确或不完整 的结构化数据。AI SDK 通过 generateText / streamText 的 output 属性跨 provider 标准化了结构化输出;schema 可用 Zod (zod-schema)、Valibot (valibot-schema)或 JSON Schema (json-schema)。

与工具同请求可组合 :结构化输出属于 generateText/streamText 流程的一部分,可与 tool calling 同时使用。关键规则:生成结构化输出本身算作一步 (多轮执行模型中每次模型调用或工具执行是一步),因此与工具组合时要在 stopWhen 里为工具执行和输出生成都留够步数。

五种 Output 类型:

类型 用法 校验行为
Output.text() 生成纯文本 不施加任何 schema ,直接返回字符串;不指定 output 时的默认行为
Output.object({ schema }) 按 schema 生成对象 结果做类型校验,确保匹配 schema
Output.array({ element, minItems, maxItems }) 生成类型化对象数组 每个元素须符合 element;边界限制元素数量
Output.choice({ options }) 从给定字符串选项中选一个(分类、固定枚举答案) 校验结果必须是选项之一,非法则抛错
Output.json() 生成并解析无 schema 的自由 JSON 只检查是否为合法 JSON ,不校验结构与类型;需要 schema 校验请用 .object / .array

Output.array 的边界规则:minItems、maxItems 必须是非负整数 ,且 minItems 不得大于 maxItems;两者取相同值即要求精确长度 。边界在 provider 支持时会作为结构化输出 schema 的一部分发送,同时 AI SDK 独立校验最终输出。

流式结构化输出 :结构化数据复杂度带来不可接受的响应时延,streamText + output 可在生成过程中流式返回;客户端用 useObject hook 消费。

  • partial 无法校验 :流式过程中的部分输出不能对照 schema 校验,因为不完整数据未必符合期望结构。
  • elementStream :流式数组时逐个接收已完成并通过 element schema 校验 的元素。与 partialOutputStream 不同 ------ 后者流的是含未完成元素的整个部分数组 。若模型生成超过 maxItems,elementStream 会在发出第一个超额元素前报错 ;这不会自动中断 provider 生成 ,而最终的 output promise 会 reject。
  • 流中错误 :streamText 立即开始流式,错误成为流的一部分而非抛出异常(防崩溃),用 onError 处理。

Property Descriptions :给 schema 单个属性加 .describe("...") 可向模型提示该属性用途,提升结构化数据质量与准确率。特别适合:澄清含糊的属性名、指定期望格式或约定、为复杂嵌套结构提供上下文。

name 与 description :可为输出指定可选的 name 与 description,部分 provider 用它做额外引导(例如作为 tool 名或 schema 名)。支持于 Output.object({ name, description, schema })、Output.array({ name, description, element, minItems, maxItems })、Output.choice({ name, description, options })、Output.json({ name, description })。

Accessing Reasoning :结果的 reasoningText 属性提供模型生成该对象时的思考过程字符串(若可用)。

Error Handling(两种方式):

  1. 模型响应无法解析或校验失败 → generateText 以 AI_NoObjectGeneratedError reject。
  2. generateText 返回了结果但没有 output → 访问 result.output 抛 AI_NoOutputGeneratedError (例如最终一步不是以 stop 结束,而是以 tool-calls 结束)。因为 output 是 getter ,解构它同样触发该访问。

NoObjectGeneratedError 保留便于排障的信息:text(模型生成的文本,按对象生成模式可能是原始文本或 tool call 文本)、response(语言模型响应元数据:响应 id、时间戳、模型)、usage(本次请求 token 用量)、cause(错误成因,如 JSON 解析错误)。

原始响应访问 :response 属性(generateText 结果)可取 provider 完整响应头与 body。


2.3 Settings --- 模型调用与请求选项

定位 :跨 provider 统一的设置入口,分为语言模型调用选项 与请求选项两组。

Language Model Call Options :maxOutputTokens、temperature、topP、topK、presencePenalty、frequencyPenalty、stopSequences、seed、reasoning。另有 providerOptions 用于传递 provider 专属参数(配合其类型,如 OpenAILanguageModelResponsesOptions)。

Request Options :maxRetries(失败重试次数)、abortSignal(AbortSignal,可用 AbortSignal.timeout() 构造)、timeout、headers(附加到请求的 HTTP 头)。

不支持的设置通过 warnings 上报 :provider 返回的警告(如不支持某设置)在 result.warnings 中,跨步骤汇总(见 2.1、2.4)。

这些设置同时是 ToolLoopAgent 的顶层设置,并可被 prepareStep 逐步覆盖(覆盖只作用于当前步,显式假值如 temperature: 0 会被保留,见 1.4)。


2.4 Prompt Engineering --- 提示词开发与调试

定位 :Core 对提示词工程提供的不是 DSL 而是约定与可观测性 :prompt/messages 结构、工具描述、以及调试时查看真实请求内容的手段。

  • Tips 与 Prompts for Tools :为工具写清 description(模型据此决定是否调用),并用 schema 的字段描述约束输入(与 2.2 的 .describe() 呼应)。
  • Tool & Structured Data Schemas:把期望形状放进 schema,而不是塞进自然语言指令。
  • Debugging 三条路径:
    • Inspecting Warnings --- 检查 result.warnings,发现 provider 忽略了哪些设置。
    • Request Messages --- 通过 request.messages(结果中携带的实际发给模型的消息 )核对拼装结果;可在生成函数上启用 include: { requestMessages: true } 之类选项让 SDK 保留请求消息。
    • HTTP Request Bodies --- 通过 finalStep.request.body 查看发给 provider 的原始 HTTP 请求体。

这三层(模型输入消息 → 原始 HTTP body → provider warnings)正好覆盖「我的提示词到底以什么形式进了模型」的排障链路;ToolLoopAgent 的 steps 也暴露同样的每步信息。


2.5 Reasoning --- 顶层 reasoning 参数

定位 :用一个 provider 无关的顶层 reasoning 参数 统一控制推理模型的思考行为,取代散落在各家 providerOptions 里的写法。

  • Basic Usage / Streaming :generateText 与 streamText 都接受 reasoning;流式下推理内容以 reasoning-start / reasoning-delta / reasoning-end part 出现(见 2.1 的 part 列表),并可用 reasoningText(见 2.2)取文本。
  • Precedence Rules :顶层 reasoning 与各 provider 的 providerOptions 之间存在优先级规则,迁移时需注意覆盖关系。
  • Provider Support :并非所有 provider 都支持;文档为不支持 的情况定义了行为(对应 warnings)。
  • Migrating from providerOptions :文档给出三组 before/after 对照 ------ Anthropic 、Google(includeThoughts) 、OpenAI(reasoningSummary) :把原先写在 providerOptions.anthropic / providerOptions.google.includeThoughts / providerOptions.openai.reasoningSummary 的开关,改为使用统一的顶层 reasoning;对较老的 Anthropic 模型另有专门的迁移示例。

2.6 Runtime and Tool Context --- 两种上下文与遥测过滤

定位 :把服务端状态传出给 Agent/工具,同时不把它写进 prompt,并控制它在遥测中的可见性。

Context Types:

  • Runtime Context(runtimeContext) :整个调用的共享运行时状态 (示例中的 requestId、region 等)。贯穿 loop,可在 prepareCall、prepareStep、生命周期回调与最终结果中读取。
  • Tool Context(toolsContext) :按工具名为键 的映射;每个工具用 contextSchema 声明自己需要的形状,execute 只拿到自己那一份已校验的 context (示例:customerLookup 工具拿自己的凭据/区域配置)。

Telemetry Context Filtering :context 可能含敏感值,因此遥测默认受控;文档提供 telemetry.includeToolsContext 开关来决定工具上下文是否进入遥测数据。

Where Context Is Available :runtimeContext / toolsContext 在 ToolLoopAgent、generateText、streamText 以及 callOptionsSchema + prepareCall(每次调用注入)、prepareStep(逐步更新)、needsApproval(审批判断时也可读取)中可用 ------ 与 1.1/1.2/1.5 的描述一致。

Choosing the Right Context :跨工具共享、描述"这次运行" → runtimeContext;只属于某个工具的凭据/作用域 → toolsContext + contextSchema(最小可见面 + 独立校验)。


2.7 Tool Calling --- 工具调用与多步执行

定位 :工具是可被模型调用以执行特定任务的对象。Function tools 与 dynamic tools 共享四个核心要素:

  • description --- 可选的工具描述,会影响工具被选中的时机。可以是字符串,也可以是从工具 context 与 experimental sandbox 派生描述的函数。
  • inputSchema --- 定义输入参数的 Zod schema 或 JSON schema ;它既被 LLM 消费,也用于校验 LLM 产生的工具调用。
  • execute --- 可选的 async 函数,以工具调用的输入为参调用,产出泛型 RESULT 类型。之所以可选,是因为你可能想把工具调用转发给客户端或队列,而不在本进程执行。
  • strict --- 可选布尔,provider 支持时启用严格工具调用。

用 tool() helper 可推断 execute 参数类型。generateText / streamText 的 tools 参数是「工具名为键、工具为值」的对象(ToolSet)。模型使用工具称为 tool call ,工具的输出称为 tool result。工具调用不限于文本生成,也可用于渲染 UI(Generative UI)。

Dynamic Descriptions :描述可以是固定字符串或函数。当发给模型的描述应取决于当前工具 context 或 experimental sandbox(tenant、project、environment、workspace)时用函数。解析时机 :description 函数在每个生成步骤把工具定义发给模型之前 解析;它收到来自 toolsContext 的匹配 context 与当前 experimental_sandbox(若提供)。若 prepareStep 更新了 toolsContext 或 experimental_sandbox,下一步使用更新后的值。

Strict Mode :启用后,支持严格工具调用的 provider 只会产生符合 inputSchema 的工具调用 ,提升可靠性;但并非所有 schema 都被严格模式支持,且支持范围取决于具体 provider。默认关闭 ,可逐工具 设 strict: true。不支持严格模式的 provider/模型会忽略该选项。

Input Examples :为工具提供示例输入以引导模型理解数据结构;当 JSON schema 未能完全表达用法或存在可选值时尤其有用(配合 inputExamples)。只有 Anthropic provider 原生支持工具输入示例,其他 provider 忽略该设置。

Tool Execution Approval :默认带 execute 的工具在模型调用时自动执行;在 generateText、streamText 或 ToolLoopAgent 上用 toolApproval 配置审批。toolApproval 可以是:

  • 处理所有工具调用的 GenericToolApprovalFunction;
  • 逐工具 的状态映射和/或 SingleToolApprovalFunction 回调(两者都可返回 undefined,效果等同 'not-applicable')。

工具定义上较旧的 needsApproval 属性已废弃 ------ 存量代码仍可用,但新代码应把审批逻辑移到 toolApproval(注意:needsApproval 目前仍是 WorkflowAgent 的正式用法 ,见 1.10)。四种状态与 1.7 相同;对象形式可带 reason:自动批准/拒绝的 reason 发在 approval response 上,人工审批的 reason 发在 approval request 上 以便展示给审批人。Generic 函数收到 toolCall、tools、toolsContext、messages、runtimeContext(runtimeContext 的类型是 ToolApprovalConfiguration 的第二个类型参数,默认 Context);逐工具函数收到工具输入 + toolCallId、messages、toolContext(与工具执行的 context 同形,但不含 abortSignal )、runtimeContext。

错误类型 (工具相关):NoSuchToolError(模型调了不存在的工具)、InvalidToolInputError(输入不符合 schema)、ToolChoiceViolationError(违反 toolChoice 约束)、ToolCallRepairError。配合 repairToolCall 可修复不合法的工具调用(如工具名拼错、参数格式偏差)。

Multi-Step Calls(stopWhen) :generateText / streamText 也支持多步执行 ------ 每步是一次模型调用或工具执行;用 stopWhen 决定继续到第几步(与 1.4 同一套停止条件),步详情在 result.steps,含每步 performance,并有 onStepEnd 回调。

Tool call execution concurrency :用 toolCallConcurrency 限制一步内并发执行的工具调用数(1 = 按模型顺序串行),与 1.10 的 workflow 侧同名选项一致。

Response Messages :结果提供 responseMessages (本次生成产生的消息),便于把对话状态推进到下一轮;配合 initialMessages / options.messages 与 pruneMessages 做上下文管理。

Dynamic Tools / dynamicTool :运行时才提供的工具;可做类型安全处理 (Type-Safe Handling),并支持多模态结果(toModelOutput 控制模型看到的输出表示,见 1.9)。

Preliminary Tool Results :execute 可为 async generator,多次 yield 部分结果 ------ 子 agent 流式进度的底层机制(见 1.9)。相关工具输入回调:onInputStart、onInputDelta、onInputAvailable。

Tool Choice :'auto' | 'none' | 'required' | { type: 'tool', toolName },配合 activeTools 收窄工具面。

Experimental Sandbox :experimental_sandbox 提供命令/代码执行环境(类型 Experimental_SandboxSession),暴露 experimental_sandbox.description、run、workingDirectory、env 等;execute 中可通过 options 取用。文档强调传 sandbox 不等于工具被沙箱化 ,工具必须显式委派(见 1.2);telemetry.includeToolsContext 控制工具上下文是否进入遥测(见 2.6)。

与 UI 集成 :toUIMessageStream 把工具 parts 送到前端,客户端用 addToolApprovalResponse 回应审批、addToolOutput 提交客户端工具结果(配合 useChat)。


2.8 MCP 三件套(Tools / Apps / Events)

2.8.1 Model Context Protocol (MCP)

定位:连接 MCP server 并使用其工具/资源/补全/prompt。

  • 初始化 :createMCPClient() ;transport 四种:HTTP(推荐) 、SSE 、Stdio(本地 server) 、Custom Transport (MCPTransport、StreamableHTTPClientTransport)。初始化细节涉及 initialize、initialInitializeResult、initialSessionId、terminateSessionOnClose、onSessionExpired。
  • OAuth :auth / authProvider / authorization 凭据流;共享 OAuth 凭据存储 、Authorization Server 校验 (validateAuthorizationServerURL、iss)、Callback Issuer 校验 (callbackIssuer)、动态客户端凭据恢复 (clientMetadata、redirect_uris、application_type)。相关错误类:MCPClientError、MCPClientOAuthError、UnauthorizedError(OAuth 错误码 invalid_client、invalid_grant、unauthorized_client、statusCode)。
  • 瞬时工具失败重试 :maxRetries。
  • 使用 MCP 工具 :Schema Discovery (发现工具 schema)、onDiscovery / onDynamicallyRegistered、Tool Annotations 与审批 (metadata.annotations 含 readOnlyHint、destructiveHint、idempotentHint、openWorldHint,可与 toolApproval 联动)、Schema Definition 、Typed Tool Outputs (outputSchema、structuredContent、CallToolResult、isError、content)。工具漂移检测:detectToolDrift、fingerprintTools。Provider 侧集成示例:openai.tools.mcp。用户交互请求回调 onElicitationRequest(context.arguments、context.tokens)。
  • MCP Resources :Listing Resources、Reading Resource Contents、Listing Resource Templates(uri、title、schemas)。
  • MCP Completions :complete、capabilities.completions。
  • MCP Prompts:使用 server 侧 prompt 模板。

2.8.2 MCP Apps --- 交互式工具 UI

定位 :连接 MCP Apps 并渲染可交互的工具 UI。要点:

  • Host Flow:宿主(你的应用)承载 App 渲染。
  • Connect With MCP Apps Support :用 mcpAppClientCapabilities 声明支持(native 能力)。
  • Expose Only Model-Visible Tools :用 splitMCPAppTools 把工具面拆成模型可见 (modelVisible)与仅 App 可见两类,避免把 UI 专用工具暴露给模型。
  • Read App Resources :readMCPAppResource (resourceUri)。
  • Proxy App-Visible Tool Calls :App 发起的调用需代理,并用 client.callTool ;结果含 structuredContent、content。
  • Render With React :experimental_MCPAppRenderer + fallback 渲染。
  • 另有 Best Practices 与 Reference 小节。

2.8.3 MCP Events --- Webhook 事件契约

定位:理解 MCP webhook 事件契约以及订阅/验签/接收的 AI SDK API。

  • Choose who manages subscriptions:由应用或 MCP server 管理订阅。
  • 机制 :client.experimental_events 提供事件面;createAdapter 适配 webhook;Experimental_MCPEventStore 存储事件;接口包含 get、getById、set、update、delete、onEvent。
  • 可靠性字段 :cursor、gap.cursor(缺口检测 )、truncated、delivery.secret(验签)、termination.error、ttlMs、refreshBefore、messageId、eventStore。
  • 文档提供 Connect the webhook and client 步骤与 Runnable example、API Reference。

2.9 Code Mode --- 用沙箱 JS/TS 编排工具

定位 :让模型以沙箱内的 JavaScript/TypeScript 程序编排 AI SDK 工具 ,而不是逐个发起 tool call ------ 适合需要循环、条件、Promise.all、JSON.parse/JSON.stringify 等组合逻辑的场合。

  • 安装 后,在 generateText / streamText / ToolLoopAgent 上启用:experimental_runCodeMode (亦见 runCodeMode),并配 experimental_toolCallers。
  • Discovering Tools Through Conversation / Searching Deferred Tools :配合 toolDiscovery 与 deferLoading(见 2.10),模型可先发现再使用工具;getInventory、getDemand 提供工具清单与需求视图。
  • Writing Code Mode Programs / Direct Execution :程序以 code_mode 方式执行;对无法在代码内完成的调用,可回退为 DIRECT_TOOL_CALL。
  • Tool Approval :Code Mode 下的工具审批仍走 toolApproval 语义。
  • Execution Limits (executionPolicy,全部为可配置上限):timeoutMs、maxBridgeRequests、maxInFlightBridgeRequests、maxResultBytes、maxSourceBytes、maxStackSizeBytes、maxToolInputBytes、maxToolOutputBytes、maxConsoleOutputBytes、memoryLimitBytes,以及 experimental_setMaxWorkers(并发 worker 数)。
  • Isolation and Tool Access :沙箱内可访问的能力(fetch、process、module、require、console.log/debug/info/error、Promise.all、eval)与隔离边界由执行策略决定;工具通过 execute、inputExamples 暴露。

定位 :toolSearch() 让模型按需找到所需工具,而不必把每个工具定义都塞进初始上下文。

  • 用法:把工具注册为 deferLoading: true ;搜索匹配工具的 name 与 description ,并让它们在下一个模型步骤可用。
  • 适用于 generateText、streamText、ToolLoopAgent、以及 @ai-sdk/workflow 的 WorkflowAgent;模型提供搜索查询,工厂可选接受应用自定义的 search 回调与 maxResults 上限。
  • 两种模式 :Direct Tool Calling ------ 模型初始只看到 search,搜索后把匹配定义加入 provider 工具列表并由模型直接调用(这会改变工具定义,可能使已缓存的 prompt 前缀失效 );Code Mode ------ 支持保留缓存 的 code mode(见 2.9),WorkflowAgent 支持直接工具调用。
  • 与 activeTools 配合控制每步工具面。

2.11 Language Model Middleware

定位 :在不改变调用方代码 的前提下增强语言模型行为 ------ 包装模型后仍是一个标准 LanguageModelV4。

  • 入口 :wrapLanguageModel({ model, middleware }) ;单个 middleware 可实现 transformParams 、wrapGenerate 、wrapStream (分别拦截参数与 doGenerate / doStream 调用)。类型名 LanguageModelV4Middleware ;也可用 createToolMiddleware 构造工具侧 middleware。
  • 多个 middlewares:可组合成链。
  • 内置 middleware :
    • extractReasoningMiddleware({ ... }) --- 从文本中抽取推理(选项含 startWithReasoning、reasoning)。
    • extractJsonMiddleware() --- 从文本中抽取 JSON。
    • simulateStreamingMiddleware() --- 把非流式模型模拟成流式。
    • defaultSettingsMiddleware({ ... }) --- 补默认设置。
    • defaultInstructionsMiddleware({ ... }) --- 补默认指令。
    • addToolInputExamplesMiddleware({ ... }) --- 为工具补输入示例(与 2.7 的 inputExamples 呼应)。
    • Provider 专用工具格式 middleware:gemmaToolMiddleware 、hermesToolMiddleware (把工具调用文本按各家格式解析,配合 format、prefix、onVersion)。
  • Community Middleware :社区提供的 middleware;文档示例含自定义 tool call parser。
  • 实现要点 :SystemModelMessage 的处理与 allowSystemInMessages (某些模型不接受 system 消息,需要把 system 折叠进首条消息,配合 findSources、getLastUserMessageText 之类的辅助逻辑)。
  • 典型自建场景 :Logging、Caching、RAG(检索增强)、Guardrails 、以及按请求配置自定义 metadata (providerOptions)。

2.12 Batch --- 异步批处理

定位 :以 provider 的批量接口异步处理大批请求(成本与时延通常优于逐条调用)。

  • Supported providers :OpenAI、Anthropic、Google、xAI 等(不支持时抛 UnsupportedFunctionalityError)。
  • 核心 API :experimental_startBatch (提交批次,含 instructions、messages、providerOptions 等常规字段,以及 requests / requestCounts )、experimental_getBatchStatus / getBatchStatus、experimental_getBatchResults / getBatchResults、experimental_cancelBatch / cancelBatch、experimental_listBatches / listBatches。
  • 状态与分页 :状态取值 pending / completed / failed ;列表用 cursor / nextCursor;每条请求含 id、customId、completionWindow、createdAt、expiresAt;provider 原始状态在 rawStatus ,结果条目含 error、response、usage、finishReason / rawFinishReason、providerMetadata;webhook 通知字段 webhookUrl。
  • Image requests / Batch tools :批量不仅限于文本 ------ 图像请求(generateImage 相关,images、size、aspectRatio)与作为 batch 请求的工具调用 (工具在批处理结果中以 execute 执行,产出 GeneratedFile 等)。
  • Request controls :单条请求可带 abortSignal、maxRetries、headers、timeout 及生成设置(maxOutputTokens、temperature、topP、topK、presencePenalty、frequencyPenalty、stopSequences、seed、reasoning)。
  • Retrieving results :结果检索与逐条响应解析(content、text、files、providerMetadata)。

2.13 Provider & Model Management

定位:多 provider、多模型的统一入口与治理,避免每处调用都手写 provider 实例。

  • Custom Providers :customProvider({ ... }) ------ 自定义 provider 以适配非标准模型;文档示例四类:custom model settings (按模型名注入设置)、model name alias (别名映射)、limit available models (限制可用模型)、files and skills interfaces(暴露文件/技能能力,见 2.24、2.25)。
  • Provider Registry :createProviderRegistry({ ... }) ,把多个 provider 注册进一个注册表并用统一字符串选模型 。Setup 支持 Custom Separator (自定义 provider/model 分隔符)。可按能力取模型:languageModel 、embeddingModel (文中示例使用文本 embedding 模型)、imageModel 、videoModel 、files 、skills 、decisionModel / decisionModels(见 2.16)。
  • Combining Custom Providers, Provider Registry, and Middleware:三者可叠加 ------ 注册表出模型,middleware 包装行为。
  • Global Provider Configuration / Customizing the Global Provider :配置全局默认 provider(fallbackProvider),使模型字符串(如 "anthropic/claude-sonnet-5.5")可直接工作;文档含 Experimental decision models 的注册方式。
  • Anthropic 专属选项示例类型:AnthropicLanguageModelOptions。

2.14 Error Handling

定位 :区分常规错误 与流式错误两套处理方式。

  • Handling regular errors :generateText 等一次性调用以异常 reject;用 try/catch 并配合 maxRetries 控制 provider 错误重试。
  • Handling streaming errors (simple streams) :简单文本流不含 error part,错误需在 onError 中处理。
  • Handling streaming errors (streaming with error support) :完整流协议里 error 是流的一种 part (见 2.1 的 part 列表),错误成为流的一部分而非抛出,避免服务端崩溃;result.stream / fullStream 可观察到 error。
  • Retrying provider errors after streaming starts :流已开始后重试 provider 错误的能力有限,文档给出 StreamProviderError 、isRetryable 与 streamRetries 的语义(配合 onLanguageModelCallStart / onLanguageModelCallEnd / onStepStart / steps 观察每次尝试)。
  • Handling stream aborts :abortSignal(含 AbortSignal.timeout())触发时用 onAbort 处理;abort 也是流的一种 part。

2.15 Testing --- mock providers

定位 :用 AI SDK Core 的mock provider 做无网络的单元测试。

  • MockLanguageModelV4 --- 语言模型 mock;文档示例覆盖 generateText、streamText、generateText with Output、streamText with Output、ToolLoopAgent(agent 也可整体 mock)。
  • MockEmbeddingModelV4 --- embedding 模型 mock(配 embed / embedMany)。
  • 辅助:simulateReadableStream (把固定 chunk 列表变成流,驱动 streamText)、mockId (固定工具调用/块 id,避免快照抖动)、mockValues(固定随机/时间等值)。
  • Simulate UI Message Stream Responses --- 模拟整条 UI 消息流,用于测试前端消费侧。

2.16 Embeddings

定位:把文本/数据转成向量,用于检索、聚类、相似度匹配。

  • 核心 API :embed({ model, value }) (单值)、embedMany({ model, values }) (批量)、cosineSimilarity({ a, b })(相似度计算)。
  • Token Usage :embedMany 返回 usage(token 用量);单值同理。
  • Settings :provider 无关设置 dimensions (输出维度)、providerOptions(如 providerOptions.google.content 传 content 类型配置)。
  • 工程选项 :maxParallelCalls (并行请求数)、maxRetries (重试)、abortSignal 与 timeout (AbortSignal.timeout())、headers(自定义请求头)。
  • Response Information :rawResponse(body)保留 provider 原始响应;providerMetadata 保留各家元数据。
  • Embedding Middleware :用 wrapEmbeddingModel 包装 embedding 模型(类型 EmbeddingModelMiddleware),与 2.11 的 wrapLanguageModel 同构。
  • Embedding Providers & Models:各家 embedding 模型通过 provider 工厂获取(也可经 Provider Registry,见 2.13)。

2.17 Reranking

定位 :对候选文档按与查询的相关性重新排序,常用于检索管线第二段。

  • 核心 API :experimental_rerank({ model, query, documents }) (文中亦称 rerank);结果字段 ranking (每项含 index 、relevanceScore / score 、并可用 originalIndex 回指原数组下标)、query、documents、model、usage(totalTokens)。
  • Working with Object Documents :文档可以是字符串,也可以是对象(document)。
  • Understanding the Results :ranking 按相关性降序,index 指向传入 documents 的位置。
  • Settings :topN(只返回前 N 条)。
  • 工程选项 :maxRetries、abortSignal、timeout、headers;rawResponse(body)与 providerMetadata。
  • 与 Embeddings 组合即为典型 RAG 检索:embedMany → 相似度召回 → experimental_rerank 精排。

2.18 Decisions --- experimental_decide

定位 :让模型对结构化问题 (选择题、打分、布尔判断)基于共享状态 给出答案,并返回概率/置信度 ------ 比自由文本更适合做判定门、分类、评估。

  • 核心 API :experimental_decide({ model, questions, state, options }) ,返回 answers。
  • Question types :三类 ------ choice (从选项选一个)、score (打分)、boolean 。类型 Experimental_DecisionQuestion ;supportedQuestionTypes 描述模型支持哪些题型。
  • Multimodal state :判定可基于多模态状态,状态类型 Experimental_DecisionState / Experimental_DecisionStatePart ,复用内容 part(TextPart 、FilePart ;文档示例含 bottom/box/left/right/top 等图像定位语义)。
  • Probabilities and confidence :返回 probabilities / probability ;rounding 选项含 probabilityDecimals 、scoreDecimals 控制位数。
  • Provider models / Model aliases and registries / Default-provider strings :决策模型可直接实例、走 Provider Registry(createProviderRegistry、customProvider、decisionModel、decisionModels、自定义 separator),或用默认 provider 字符串;AI Gateway 场景(AI_GATEWAY_API_KEY、providerOptions.gateway.models)。
  • Errors and cancellation :InvalidArgumentError、InvalidResponseDataError、NoSuchModelError、NoSuchProviderError、UnsupportedModelVersionError、Experimental_DecisionRefusalError (模型拒绝作答);支持 abortSignal、headers。
  • Scope and examples :文档给出 typeSafeAi 用法与 Experimental_DecisionMockModelV4 (测试用 mock),以及回调 experimental_onDecisionModelCallStart / experimental_onDecisionModelCallEnd(见 2.20)。
  • 与 2.2 的 Output.choice() 区别:Output.choice 是文本生成流程 里的输出模式,experimental_decide 是独立 API,带状态、概率与拒绝语义。

2.19 Image Generation

定位:文生图与图像编辑的统一 API。

  • 核心 API :generateImage({ model, prompt }) ,结果含 image (首图)与 images (多图);文件形式为 GeneratedFile(uint8Array / base64、mediaType)。
  • Settings :size (如 provider 支持的具体尺寸)、aspectRatio 、seed (可复现)、n/count (多图)、maxImagesPerCall (每次调用上限)、provider 专属 providerOptions。
  • Generating Multiple Images / Image-to-Image Editing :文档含多图画与编辑支持检测 supportsFileInputs 、supportsMaskInputs(判断模型能否接受输入文件与蒙版)。
  • 工程选项 :maxRetries、abortSignal、timeout、headers、warnings(不支持的设置)、providerMetadata、usage。
  • Underlying calls :模型调用底层是 doGenerate / doStream(provider 侧接口)。
  • Error Handling :无法产出图像时抛 AI_NoImageGeneratedError (cause、images、usage、warnings)。
  • Image Middleware :wrapImageModel (类型 ImageModelV4Middleware)包装图像模型。
  • Generating Images with Language Models :也可通过语言模型的工具/多模态输出产生 images(见 2.1 的 files)。

2.20 Realtime --- 实时语音对话

定位 :构建实时(音频双向)对话。

  • Setup Endpoint --- 服务端建立 realtime 会话(示例 id 前缀 vcst_)。
  • AI Gateway --- 可经 AI Gateway 接入 realtime 模型。
  • Client Session --- 客户端会话管理;React 侧 hook experimental_useRealtime ,用 useMemo 建立 session,api.session 暴露会话 API。
  • Tool Calling / Server-Backed Tool Endpoint / Client Tool Handler --- realtime 会话内也支持工具调用:服务端提供 tool endpoint,客户端用 onToolCall 处理并回写 addToolOutput。
  • Supported Providers --- 文档列出支持的 realtime provider。

2.21 Transcription / Translation / Speech

Transcription(语音转文本)

  • 核心 API :transcribe({ model, audio }) ,结果含 text;音频输入可为 ArrayBuffer、Uint8Array、Buffer、文件、URL(URL)。
  • Streaming Transcription :experimental_streamTranscribe ,含 fullStream(流 part)与 text promise;相关事件回调 experimental_onStreamTranscriptionStart / experimental_onStreamTranscriptionEnd;实时模型示例 scribe_v2_realtime。
  • Settings :inputAudioFormat 、language 、providerOptions(各家参数)。
  • Download Size Limits :createDownload 与下载大小限制(超限抛 DownloadError)。
  • 工程选项 :maxRetries、abortSignal、timeout、headers、warnings;错误 AI_NoTranscriptGeneratedError(cause);onError、telemetry。
  • Transcription Models (文中出现):OpenAI whisper、Deepgram nova/telephony,AssemblyAI universal,Google chirp_2/chirp_3,ElevenLabs scribe_v1/scribe_v1_experimental/scribe_v2,以及 wizper、enhanced、full、machine、low_cost 等模型变体。

Translation(语音翻译)

  • 核心 API :experimental_transcribe 之外的 experimental_translate (文中亦简称 translation),结果含 translationText 与音频输出。
  • Stream parts :experimental_streamTranslate ,fullStream 支持文本与音频 chunk,可用 includeRawChunks 保留 provider 原始 chunk(raw)。
  • Settings :sourceLanguage 、targetLanguage 、inputAudioFormat 、outputAudioFormat 、providerOptions。
  • 工程选项 :abortSignal、headers、maxRetries;错误 AI_NoTranslationGeneratedError(cause、error);response。

Speech(文本转语音)

  • 核心 API :generateSpeech({ model, text }) ,结果含音频(Uint8Array/base64、mediaType)。
  • Telemetry 、providerOptions(各家音色/稳定性/输出格式)、warnings、headers、maxRetries、abortSignal、timeout。
  • Error Handling :AI_NoSpeechGeneratedError (cause)。
  • Speech Models (文中出现):ElevenLabs eleven_v3、eleven_turbo_v2/eleven_turbo_v2_5、eleven_flash_v2/eleven_flash_v2_5、eleven_multilingual_v2,以及 default 音色配置。

2.22 Video Generation

定位:文生视频与图生视频。

  • 核心 API :experimental_generateVideo({ model, prompt }) ,结果含 video / videos (GeneratedFile:uint8Array、base64、url)。
  • Settings :aspectRatio 、resolution 、durationSeconds (时长)、fps (帧率)、generateAudio (是否生成音频)、seed 、maxVideosPerCall 、providerOptions。
  • Image-to-Video Generation / First and Last Frame :用 image 、lastFrame 、frameImages 控制起止帧。
  • Reference Inputs :inputReferences(参考图/素材)。
  • Polling(关键机制) :视频生成通常是异步任务 ------ poll 选项含 poll.delay (intervalMilliseconds)与 poll.timeoutMs ;也支持 createWebhook 走 webhook 通知(webhook、received)。
  • 工程选项 :maxRetries、abortSignal、timeout、headers、warnings、providerMetadata、usage;错误 AI_NoVideoGeneratedError(cause);body、responses、mediaType。

2.23 File Uploads 与 Skill Uploads

File Uploads(文件上传与 provider 引用)

  • 核心 API :uploadFile({ data, mediaType, name, purpose }) ;结果字段 files、id、bytes、byteSize 、createdAt、expiresAt、api、providerMetadata。
  • Provider References :返回 ProviderReference ,可在后续推理调用中引用已上传文件而无需重复上传 ,跨 provider 使用(Multi-Provider Usage );purpose 决定文件用途(各家取值不同)。
  • Supported File Types / Provider-Specific Options / Streaming Uploads :支持类型、各家选项(providerOptions)、以及流式上传(避免整体载入内存)。
  • 不支持时抛 UnsupportedFunctionalityError ;abortSignal、headers 可用。

Skill Uploads(技能上传)

  • 定位 :把 Agent Skill (SKILL.md 目录包)上传到 provider,之后在推理调用中以引用方式使用。
  • 核心 API :uploadSkill({ skill }) ,结果类型 UploadSkillResult (字段 id、name、description、displayTitle 、latestVersion 、expiresAt、sha256Hash、size、source、path、api、warnings、providerMetadata)。
  • Skill Files :技能由文件集合构成(示例用 fs.readFileSync 读 SKILL.md,内容可为字符串或 Uint8Array)。
  • Using Skills in Inference Calls :Anthropic 走 providerOptions.anthropic.container.skills ;OpenAI 走 providerOptions.openai.skills ;content 中 type: 'skill' 引用。
  • 与 Harnesses 的 Skills(见 3.3)是不同层:这里是把技能上传到 provider 容器 ,那里是给 harness 运行时装配技能。

2.24 Telemetry --- OpenTelemetry 集成

定位:把生成/embedding/rerank/工具调用变成 OTel span,接入现有可观测性栈。

  • Enabling telemetry(两步) :Step 1 在 instrumentation 文件(如 instrumentation.ts)里 registerTelemetry(...) 注册 OpenTelemetry 集成;Step 2 在调用上开启 experimental_telemetry: { isEnabled: true } 。Opting out ------ 默认关闭,也可逐调用禁用。
  • Telemetry Metadata :functionId (区分同应用内不同调用,写入 ai.telemetry.functionId)、metadata (自定义属性)、captureContent(是否记录输入输出内容,默认不记录敏感内容)。
  • 上下文可见性 :telemetry.includeRuntimeContext 、telemetry.includeToolsContext (默认不把 context 放进 span,见 2.6)。
  • Custom Tracer :可传自定义 tracer (Tracer / TracerProvider)而非全局默认。
  • Telemetry Integrations :Registering integrations globally (registerTelemetry)、Per-call integrations (telemetry.integrations)、Tracing channel(多通道)。
  • Building a custom integration :实现集成的 Available lifecycle methods (onStart、onStepStart、onToolExecutionStart、onToolExecutionEnd、onStepEnd、onEnd、onError、onAbort 等),并可 enrichSpan ;span 类型 spanType 取值 CLIENT / INTERNAL ;recordInputs / recordOutputs 控制内容记录;工具种类区分 FunctionTool、DynamicTool、ProviderDefinedTool、ProviderExecutedTool。
  • GenAI Semantic Conventions(新语义约定) :gen_ai.operation.name、gen_ai.provider.name、gen_ai.request.model、gen_ai.response.model、gen_ai.response.id、gen_ai.response.finish_reasons、gen_ai.usage.input_tokens / gen_ai.usage.output_tokens / gen_ai.usage.characters / gen_ai.usage.seconds、gen_ai.input.messages / gen_ai.output.messages / gen_ai.output.type / gen_ai.system_instructions、gen_ai.tool.name / gen_ai.tool.type / gen_ai.tool.definitions / gen_ai.tool.call.id / gen_ai.tool.call.arguments / gen_ai.tool.call.result、gen_ai.client.operation.duration、gen_ai.execute_tool.duration、gen_ai.agent.name、gen_ai.evaluation.result、gen_ai.system。
  • Legacy AI SDK Spans(LegacyOpenTelemetry) :AI SDK 自有属性命名空间 ai.*:ai.operationId、ai.model.id、ai.model.provider、ai.prompt(ai.prompt.messages、ai.prompt.tools、ai.prompt.toolChoice)、ai.request.text、ai.response.id / ai.response.model / ai.response.text / ai.response.object / ai.response.toolCalls / ai.response.usage / ai.response.finishReason / ai.response.providerMetadata / ai.response.timestamp / ai.response.msToFirstChunk / ai.response.msToFinish、ai.stream.firstChunk / ai.stream.finish、ai.settings.maxOutputTokens / ai.settings.maxRetries / ai.settings.output、ai.usage.promptTokens / ai.usage.completionTokens / ai.usage.tokens、ai.value / ai.values、ai.toolCall.id / name / args / result、ai.telemetry.functionId,以及 span 名:ai.generateText、ai.generateText.doGenerate、ai.streamText、ai.streamText.doStream、ai.generateObject、ai.generateObject.doGenerate、ai.streamObject、ai.streamObject.doStream、ai.embed、ai.embed.doEmbed、ai.embedMany、ai.embedMany.doEmbed、ai.embedding、ai.embeddings、ai.generateSpeech、ai.transcribe、ai.streamTranscribe、ai.rerank、ai.reranking、ai.decide。

2.25 DevTools

定位:本地调试与检查 AI SDK 应用 ------ 捕获真实请求/响应/步骤/媒体并在专用 viewer 里回放。

  • Installation & Requirements:安装 DevTools 包并满足 Node 版本与 OTel 前提。
  • Register the integration :把 DevTools 作为一个 telemetry integration 注册(与 2.24 的 registerTelemetry 同一扩展点),因此任何走 telemetry 的调用都能被捕获 ------ 覆盖 generateText、streamText、generateObject、streamObject、ToolLoopAgent 等。
  • Launch the viewer :用 npx 启动 viewer(http/https 本地端口);Choose a viewer theme。
  • Monorepo usage:monorepo 下的注册与端口共享方式。
  • Captured data :一次 run 与其中每个 step (消息、工具调用与结果、usage、finishReason)、Media previews (图片/音频等媒体预览,用 include / media 选项控制),并支持 toModelOutput 的表示形式。
  • How it works:靠 telemetry span 上报 → 存储 → viewer 读取。
  • Security considerations :DevTools 捕获的是真实输入输出(可能含敏感数据) ,只应在本地/受控环境启用,不要把捕获数据当作生产遥测出口(内容记录由 2.24 的 captureContent、telemetry.includeRuntimeContext / includeToolsContext 控制)。

2.26 Lifecycle Callbacks

定位 :官方统一文档,覆盖 generateText、streamText、embed、embedMany、rerank、experimental_decide 六类调用的生命周期事件(ToolLoopAgent 复用同一批 generation 事件类型,见 1.2)。

  • Use Cases :Request Logging、Measuring Model Performance (用 performance,含 stepTimeMs、responseTimeMs、toolExecutionMs、timeToFirstOutputMs 等,见 2.1)、Debugging Multi-Step Tool Calls (steps、stepNumber)、Monitoring Tool Execution(toolCall、toolContext)、Observing Embeddings and Reranking。
  • Generation Lifecycle(事件顺序) :onStart → 每步 `onStepStart` → `onLanguageModelCallStart` → `onLanguageModelCallEnd` → (每个工具)`onToolExecutionStart` → `onToolExecutionEnd` → onStepEnd → onEnd;流式另有 onError、onAbort(streamText 的 onChunk 更细粒度,见 2.1);工具输入侧 onInputStart / onInputDelta / onInputAvailable。
  • generateText 与 streamText :上表全部回调;streamText 特有 onChunk、onError。
  • embed 与 embedMany :onStart / onEnd,事件含 value/values、embedding/embeddings、usage(EmbeddingModelUsage )、model、provider、response。
  • rerank :onStart / onEnd,事件含 query、documents、ranking、topN、usage。
  • experimental_decide :experimental_onDecideStart / experimental_onDecideEnd (事件类型 Experimental_DecideStartEvent / Experimental_DecideEndEvent),并有 onQuestion / onAnswer 、模型调用级 onModelCallStartEvent / onModelCallEndEvent(亦见 2.18 的 experimental_onDecisionModelCallStart / End);事件含 questions、answers、state、finishReason、usage、callId。
  • Event Data Reference :各事件的公共数据类型 ------ StepResult、StepResultPerformance、LanguageModelUsage、LanguageModelCallPerformance、LanguageModelRequestMetadata、LanguageModelResponseMetadata、TypedToolCall、FinishReason、ProviderOptions、activeTools、toolChoice、instructions、messages、modelId、providerOptions、maxRetries、headers、timeout、responseMessages、finalStep、warnings、operationId、runtimeContext(RUNTIME_CONTEXT / CONTEXT )、toolOutput 判别联合(type、output、error)、toolExecutionMs、stepNumber、steps、toolCalls/toolResults、content、text、finishReason。
  • Runtime and Tool Context :回调里可读 runtimeContext 与 toolContext;结合 telemetry.includeRuntimeContext / telemetry.includeToolsContext 决定是否进入 span(见 2.6、2.24)。

3. AI SDK Harnesses 板块

定位 :harness 抽象让你通过统一的 AI SDK 界面运行成熟的 agent harness 。Harness = 完整的 agent 运行时 (如 Claude Code、Codex、Pi),它拥有的能力大过一次模型调用 :workspace 访问、内置编码工具、原生 session 状态、compaction(压缩) 、权限流程、以及运行时专属配置。Harness adapter 可以让运行时在 sandbox 中执行,但各 adapter 的执行环境不同 ------ 使用前务必读该 adapter 的运行时位置与安全指引。

与 provider/model 的关系(关键区分) :harness 抽象独立于 provider/model 抽象 ------ provider 向 Core 函数(generateText、streamText)暴露模型;harness 向 HarnessAgent 暴露 agent 运行时 。两者解耦但尽量使用兼容原语 :harness 输出被投影进 AI SDK 的流与响应类型 ,因此消费模型流的地方也能消费 harness 流(例如把 HarnessAgent 的 stream 交给 toUIMessageStream 并用 useChat 渲染)。API 设计力求让 AI SDK 用户熟悉,但 harness 运行时的概念确实与底层语言模型不同:配置在契合处沿用 AI SDK 惯例,在 harness 行为不同处有意分叉。

Harness 包是实验性的 ,早期 API 在版本之间预期会有破坏性变更。

何时用 harness :需要现成 agent 运行时驱动任务时 ------ 能检查和修改沙箱 workspace 的编码 agent;自带内置工具与权限模型的运行时;由运行时自己掌握对话历史 的多轮会话;希望保留 harness 原生行为而不是用 tool loop 重造的工作流。反过来:需要直接控制模型调用、工具循环、模型设置、结构化输出或自定义 agent 架构时,用 provider + model。

四个核心部件:

  1. HarnessAgent ------ 应用代码里使用的 AI SDK agent 实现。
  2. Harness adapter ------ 连接具体运行时的包,例如 @ai-sdk/harness-claude-code。
  3. Sandbox provider ------ harness 运行所在的隔离文件系统与进程环境。
  4. Session ------ 一次 harness 运行的活动对话与 workspace 状态。

Compatible Streams :HarnessAgent.generate() 返回 AI SDK 的 GenerateTextResult ,HarnessAgent.stream() 返回 StreamTextResult ,因此可以消费熟悉字段:result.text、result.stream、result.steps、result.usage、result.responseMessages。harness 专属事件被翻译成兼容 stream part ------ text、reasoning、tool calls、tool results、usage、finish reasons 尽量用 AI SDK 同形结构;没有一等公民 part 的事件(如 workspace 文件变更、compaction)以 dynamic provider-executed tool parts 的形式呈现(见 3.2 与 3.8)。

Sessions Matter(最关键的差异) :与语言模型调用不同,harness session 拥有状态 ------ 它承载 harness 运行时、sandbox、工作目录、原生对话历史、待处理审批。跑每一轮之前要先创建 session:

ts 复制代码
const session = await agent.createSession();
try {
  const result = await agent.generate({ session, prompt: 'Inspect the repository and summarize the test setup.' });
  console.log(result.text);
} finally {
  await session.destroy();
}

服务端路由要用稳定的 sessionId ,并持久化 session.detach() 或 session.stop() 返回的 resume 状态。

3.1 HarnessAgent

定位 :Harnesses 板块的主 API ------ 由 harness adapter 支撑的 AI SDK Agent 实现 ,提供 generate() 与 stream(),返回 AI SDK 兼容的结果,而实际推理由预先配置好的 harness 完成。

Installation :core harness 包 + 一个 harness adapter + 一个 sandbox adapter。Bridge-backed harness(Claude Code、Codex 等)必须使用真实网络 sandbox ,如 @ai-sdk/sandbox-vercel;host-runtime harness(如 Pi)也可用 @ai-sdk/sandbox-just-bash,因为它不需要 sandbox-exposed port。并确保环境变量里备好 sandbox 与 harness 凭据。

Create an Agent :在 module scope 构造 agent ------ 它持有配置,不持有 live session ,live state 属于 HarnessAgentSession 。sandbox session 单独创建后传给 agent.createSession() 。model 指定 harness runtime 使用的模型,模型标识符是各 harness 专属的 ;省略则用 harness 默认模型;model 按轮应用 ,因此 prepareCall 可以在轮次之间替换它。

Run a Turn :generate() 排空整轮 并返回 GenerateTextResult;stream() 用于增量输出。

Lifecycle Callbacks :在 HarnessAgent 上配置回调以观察 agent 调用、模型步骤与工具执行 。单次 generate() / stream() 上传入的回调会额外执行,且构造器级回调先跑 ;回调异常会被忽略,不会改变 agent 执行 。harness runtime 在内部执行其内置工具,对这些工具而言 onToolExecutionStart / onToolExecutionEnd 描述的是 runtime 上报结果之后的逻辑工具生命周期,回调仍在工具结果发布到结果流之前送达。

Runtime Context :runtimeContext 让应用上下文对每一轮 可用;用 prepareCall 为新 prompt 轮替换它。准备好的 context 在 generate() / stream() 中可用,并在内存内续跑(continueGenerate() / continueStream())期间保持不变 ;生命周期回调收到完整 context,结果里也有 finalStep.runtimeContext。runtime context 默认被排除在遥测之外 ,用 telemetry.includeRuntimeContext 逐个顶层属性加白(只有设为 true 的属性 才发给遥测集成);由于回调与结果仍拿到完整 context,不要存放这些消费方不该访问的密钥。

Generate Structured Output :构造时设 output,则每一轮都要求同一个类型化输出 ;agent 把输出规格转成 JSON Schema 交给 harness adapter、校验完成的响应、并通过 result.output 返回解析值。stream() 下读 partialOutputStream 拿增量解析值,await result.output 拿校验后的最终值。结构化数据同时仍以 JSON 存在于普通文本与流表面;adapter 不会把它加进 finish part 。Harness 结构化输出要求 schema ------ 无 schema 的 Output.json(),以及无法强制 schema 的 adapter 或运行时配置,都会抛 HarnessCapabilityUnsupportedError。

Messages and History :harness session 拥有自己的原生对话历史 。传 messages 或消息数组形式的 prompt 时,HarnessAgent 只取最新的 user message 作为本轮新输入,不会把既往对话重放进 harness 。但末尾的 tool message 另当别论 :tool approval response 与客户端提供的 tool result 会继续产生对应请求/调用的那个未完成 harness turn 。这与模型调用不同(模型调用通常由应用发送完整历史)------ 聊天路由应持久化并 resume harness session,而不是依赖消息重放。

Reading the Runtime's Own History :runtime 的对话可能在你进程之外增长(例如同一会话在 agent 自己的 CLI 里被交互续写),实时事件流看不到 那些交换。能访问 runtime 存储的 adapter 通过 session.readHistory() 暴露它。历史读取是 adapter 特定的:adapter 未实现 历史读取时抛 HarnessCapabilityUnsupportedError;实现了但当前环境无法触及 runtime 存储(例如存储位于远程 sandbox 内)时抛 HarnessHistoryUnavailableError ;尚无消息的对话不算错误 ,resolve 为空 messages 数组。

Session Lifecycle(每轮之后务必显式收尾):

  • session.destroy() 停止 runtime 并丢弃可续跑性。
  • session.detach() 停靠(park)runtime、返回 resume 状态,并让传入的 sandbox 继续运行以便之后 attach ;若轮次未完成,resume 状态包含 continuation 状态。
  • session.stop() 先保存 resume 状态再停止 runtime;轮次未完成时同样包含 continuation 状态。
  • session.suspendTurn() 面向跨进程边界继续活动轮次的高级场景。
  • session.hasUnfinishedTurn() 报告当前轮次是否必须先继续或挂起,session 才能接受新 prompt。

一次性脚本与测试用 destroy();需要多轮连续性的 HTTP 路由用 detach() 或 stop()。

Change Settings Between Turns :用 callOptionsSchema + prepareCall 派生每轮的 model、skills、instructions、tools、runtimeContext (与 ToolLoopAgent 同一套 call-options 模式)。prepareCall 在新 prompt 且其自定义 options 校验完成后运行,其设置随后整轮固定 ;若该轮因工具结果、审批、停止条件或进程交接而暂停,续跑复用同一套设置、不会再次调用 prepareCall (防止轮内设置漂移)。改 model 不会创建新 harness session :每个 adapter 在下一个 prompt 前切换/重配 runtime 并保留 session 的对话历史。但 Codex adapter 在 skills、instructions 或工具目录变化时会启动全新的原生 Codex thread (因为 codex exec resume 保留原始原生 thread bootstrap)------ harness session 仍可用,但既往原生上下文不会跨越这个设置变化边界;设置未变的轮次继续现有原生 thread。abortSignal 直接传给 generate() / stream() (它本就是 per-call 设置,不属于 prepareCall);output 也固定在 agent 上 (响应格式绑定 agent 的 output schema)。把 sandboxSession 传给 agent.createSession() 时调用方保有该 sandbox 的所有权 :session.stop() / session.destroy() 只结束 harness runtime,不会停止或销毁传入的 sandbox session ,此时 agent 构造器无需 sandbox provider。

Resuming :持久化不透明的 resume 状态。示例里 harness sessionId 就是 chatId,sandbox ID 从同一已知 ID 派生;若应用无法派生 sandbox ID,就改为持久化 sandboxSession.id 连同 harness sessionId 与 resume 状态。重新 attach sandbox 之后再让 agent resume 。创建时指定的 sandboxId 命名一个「新的」live sandbox,永不查找已有 ;用同一 ID 复用会在该 sandbox 已存在时失败 ------ 只有 resume 函数会执行查找 。HarnessAgent 在把 resume 状态交给 runtime 之前会校验它出自同一个 harness adapter 。若 resume 状态包含未完成轮次,先调用 continueStream() / continueGenerate() 再发新 prompt 。Vercel 的 resume 函数在 sandbox detach 后仍在运行、或被停止但留有可恢复快照时都能重新 attach;sandboxSession.destroy() 删除之后该 ID 无法再 resume。

Continue a Suspended Turn :需要跨进程边界交接活动轮次时,先挂起轮次并持久化 continuation 状态。只有来自 suspendTurn() 的原始 continuation 状态时,用 continueFrom resume,然后不发新 prompt 地继续该轮 :continueStream() 取增量输出,continueGenerate() 排空续跑的轮次并返回 GenerateTextResult。toolsContext 与 runtimeContext 有意不写进 continuation 状态 (它们可能含凭据或不可序列化的宿主对象);若被挂起的轮次使用了 prepareCall 派生的 context,把同样的值传给 createSession 以在续跑进程中重新绑定 ;未重新绑定的进程 resume 会回落到 agent 构造器级的 runtimeContext 与 toolsContext。

Stop After a Harness Step :用 stopWhen 进入语义步骤边界。谓词在真实的 harness 工具步骤之后 运行(这些步骤还能继续进入下一个模型步骤),并收到当前调用已完成的 steps 。谓词命中时,返回的 result 结束,而底层轮次仍未完成 ;相反,终结性的纯文本步骤 会消费该轮的 finish 事件并自然收尾。stopWhen 没有默认值 :省略时 HarnessAgent 持续运行到轮次自然结束或停下等待宿主输入,保留无步骤控制时的 agent 行为。传一个谓词或数组,任一命中即结束当前 result slice ;被停止的轮次用 createSession({ continueFrom }) + continueStream() / continueGenerate() 恢复。

Prepare the Sandbox(sandboxConfig):在 harness 启动之前准备 sandbox。

  • sandboxConfig.onBootstrap 在 sandbox 模板创建期间 运行,时机在 harness adapter 自身 bootstrap 之后、支持快照的 provider 发布快照之前;用于应被未来 session 复用的昂贵设置 。提供 onBootstrap 就必须同时提供 bootstrapHash,并在 bootstrap 产物应当使可复用快照失效时改变 hash。
  • sandboxConfig.onSession 在每个 sandbox session 被获取且其工作目录就绪之后运行(包括被 resume 的 session);用于 per-session 文件或轻量配置。
  • workDir 可选 :提供时必须相对于 sandbox 的默认工作目录 ,并用作 session 工作目录;设为 '.' 即直接使用 sandbox 默认工作目录本身。省略时普通 session 使用默认的 <harnessId>-<sessionId> 目录,而 onBootstrap 收到的是 sandbox 的默认工作目录。

Prepare Reusable Sandboxes :用 agent.getSandboxTemplate() 在创建 sandbox 之前解析某个 harness 的 bootstrap recipe(配合 sandboxConfig.onBootstrap);模板身份在 sandbox 创建前即已知,Vercel 会持久化准备好的快照并由它创建 live sandbox,相同的调用复用该快照 。多个 harness 共享同一个调用方 bootstrap 钩子时,可从所有 adapters 构建一个 模板:重复的 harnessId 以最后一个为准,且 recipe 身份在哈希前排序 ;onSession 不属于模板 ,仍会在每个获取的 session 上单独执行。派生模板的 cache key 含源快照 ID ,因此同 source + 同 template 的重复调用会复用准备好的快照 ------ 依赖缓存模板时要固定可变的 Git revision、镜像 tag 与源 URL 。sandboxId 命名的是 live sandbox,不是其可复用模板 ;原有的原生 name 选项同样命名 live sandbox,两者都提供时其值必须一致。

Settings(HarnessAgent 主要设置项) :harness(adapter 实例)、model(可选,harness 专属标识符)、id (可选的稳定 agent 标识符)、instructions(支持时追加到 runtime 的 system/developer prompt ,否则前置到 user prompt )、headers(构造期固定 ;不允许 authorization、x-api-key、user-agent、x-client-app )、callOptionsSchema + prepareCall、output、stopWhen、tools(harness 调用时由宿主执行的 AI SDK 工具)、runtimeContext、activeTools / inactiveTools、skills、permissionMode、toolApproval、sandboxConfig、以及 telemetry / debug / onLog(可观测性与诊断;用 telemetry.includeRuntimeContext 给 runtime context 属性加白)。遥测报告每轮解析出的 model、instructions 与 active 的宿主定义工具;skills 属于 adapter 上下文,没有对应的 AI SDK 遥测字段,因此不包含在标准遥测事件中 。adapter 专属设置放在 adapter 工厂上 ,例如 createCodex({ reasoningEffort: 'high' })。

Custom Sandbox Orchestration :应用自己创建与管理 sandbox 时,先准备网络 sandbox session,再把同一个 session 传给 agent.createSession();agent 既不创建 sandbox,也不会停止或销毁调用方拥有的 sandbox 。Basic Sandbox Sessions Without Network Control :只暴露文件系统与进程 API 的受限 basic session 只在项目无法暴露完整网络 session 时才用 (官方强烈建议传完整网络 session);agent 仍把 sandbox 生命周期留给调用者,且对 bridge-backed harness 必须在 adapter 上配置 bridge 端口及其外部可达 endpoint,因为 basic session 无法解析它们。

错误类型 :HarnessCapabilityUnsupportedError (adapter/运行时不支持该能力:结构化输出缺 schema、历史读取未实现、审批模式不受支持)、HarnessHistoryUnavailableError(实现了历史读取但当前环境无法访问 runtime 存储)。

3.2 Harness Tools

定位 :harness 有三类工具面 ------ ① 底层 harness runtime 暴露的 built-in tools(文件读写、shell、web search 等);② 你通过 tools 设置传给 HarnessAgent 的 AI SDK 工具;③ 通过 harness adapter 的 mcpServers 设置接入的外部 MCP 工具 。本页只讲 harness 特有行为,通用工具概念见 Core(2.7)。逐节细节 (内置工具的 providerExecuted: true 与跨 harness 通用名、宿主工具 toolsContext 的类型推导与校验、客户端工具的挂起/续跑、activeTools 与 inactiveTools 的运行时差异、受限 sandbox、permissionMode 与 toolApproval 两条通道、fileChange / compaction 投影)见 3.8。

  • Built-in Tools ------ harness 自带的运行时工具:文档列举 bash、read、edit、write、glob、grep、webSearch 等;permissionMode 控制范围:allow-all 、allow-edits 、allow-reads。
  • Host-Executed Tools ------ 由宿主(AI SDK)执行的工具,用 agent.tools / tools 传入 AI SDK tool() 定义,execute、contextSchema、toolsContext 沿用 Core 语义(见 2.7)。
  • Client-Side Tools ------ 省略 execute 即表示由浏览器/用户交互/外部进程提供结果,客户端用 addToolOutput 回写(配合 useChat,见 3.6);此时 result slice 在 tool-call 步骤处结束,session.hasUnfinishedTurn() 保持 true。
  • Tool Filtering ------ activeTools(允许列表)/ inactiveTools(禁止列表)按名筛选合并工具集;两者只能传其一。
  • MCP Tools ------ 外部 MCP 工具通过 adapter 的 mcpServers 设置接入(不是 Core 的 createMCPClient 路径)。
  • Sandbox in Tool Execution ------ 宿主工具通过 experimental_sandbox 收到 session 的 sandbox(受限 sandbox session) :能读写文件、执行命令,但无法停止网络沙箱或修改其网络策略。
  • Tool Approvals(两条互不相通的通道) ------ harness 区分 内置工具的权限 与宿主工具的审批 :内置用 permissionMode,宿主用 toolApproval (状态 not-applicable / approved / denied / user-approval,见 1.7),需要审批时流在 tool-approval-request 之后暂停 。宿主工具的审批由 HarnessAgent 负责因而跨 adapter 可用;内置审批则由 adapter 决定,不支持的 adapter 会在指定该模式时报错(详见 3.8)。
  • File Changes and Compaction ------ workspace 文件变更与 compaction 没有一等公民 part ,因此以 dynamic provider-executed tool parts (part.dynamic)投影到流中。

3.3 Harness Skills

定位 :Skills (agentskills.io/)是可复用的指令包 ,用于项目约定、工作流指引、领域特定流程等「应当被底层 harness 运行时发现」的指令。可以为 HarnessAgent 配置 skills,也可以在已完成的轮次之间替换它们。

  • Define Skills :通过 skills 设置传入。每个 skill 有四项:name (稳定标识符)、description (面向模型的简短摘要)、content (完整指令内容)、files (可选的、随 skill 打包的附加文本文件 )。附加文件使用相对 skill 根的 POSIX 路径 ,例如 reference.md、references/codes.md、templates/config.json;当希望 agent 去读它们时,在 content 里引用这些路径。
  • When to Use Skills(与 instructions 的分界) :skills 用于按需可用 的可复用指令,而不是像常规 instructions 那样始终加载进 agent 上下文 ;instructions 用于宽泛的 agent 行为与当前会话优先级。
  • 可在已完成的轮次之间 更换 skills,通过 callOptionsSchema + prepareCall 实现(见 3.1 的 Change Settings Between Turns)。
  • 与 Core 的 Skill Uploads(2.23)不同:这里面向 harness 运行时的技能装配,那里是把技能上传给 provider 容器。

3.4 Harness Adapters

定位 :harness adapter 把 HarnessAgent 连接到具体 agent 运行时 ------ 它们是 AI SDK model provider 在 harness 世界的对应物 :每个 adapter 包装一个运行时,并把它的 sessions、stream 事件、工具、usage、生命周期状态与配置归一化进 harness 契约。

已提供的 adapter(10 个) :Claude Code(@ai-sdk/harness-claude-code)、Cline(@ai-sdk/harness-cline)、Codex(@ai-sdk/harness-codex)、Cursor(@ai-sdk/harness-cursor)、Deep Agents(@ai-sdk/harness-deepagents)、fx(@ai-sdk/harness-fx)、GitHub Copilot(@ai-sdk/harness-github-copilot)、Grok Build(@ai-sdk/harness-grok-build)、OpenCode(@ai-sdk/harness-opencode)、Pi(@ai-sdk/harness-pi)。 Coming Soon :Amp(@ai-sdk/harness-amp)、Goose(@ai-sdk/harness-goose)、Mastra(@ai-sdk/harness-mastra)。

Adapter Capabilities(官方能力矩阵,选型时逐项核对):

Adapter Runtime location Custom tools Custom skills Structured output Built-in tool approval Built-in tool filtering History access
Claude Code Sandbox bridge ✓ ✓ ✓ ✓ ✓ ✗
Cline Host process ✓ ✓ ✓ ✓ ✓ ✗
Codex Sandbox bridge ✓ ✓ ✓ ✗ ✗ ✗
Cursor Sandbox via ACP ✓ ✓ ✗ ✗ ✗ ✗
Deep Agents Sandbox bridge ✓ ✓ ✓ ✓ ✓(via auto-rejection) ✗
fx Host process ✓ ✓ ✓ ✓ ✓ ✗
GitHub Copilot Sandbox via ACP ✓ ✓ ✗ ✗ ✗ ✗
Grok Build Sandbox via ACP ✓ ✓ ✓ ✗ ✗ ✗
OpenCode Sandbox bridge ✓ ✓ ✓ ✓ ✓ ✗
Pi Host process ✓ ✓ ✗ ✓ ✓ ✗

读表要点:所有已发布 adapter 都不支持 History access (session.readHistory() 目前无一可用);Structured output 在 Cursor、GitHub Copilot、Pi 上不可用 (要求 schema 的 output 会抛 HarnessCapabilityUnsupportedError);Built-in tool approval 与 filtering 只有 Claude Code / Cline / Deep Agents / fx / OpenCode 支持 (Deep Agents 的过滤通过 auto-rejection 实现)------ 因此 permissionMode 非默认值与内置工具过滤在不支持的 adapter 上会报错;Runtime location 分三类 :Sandbox bridge(Claude Code、Codex、Deep Agents、OpenCode)、Sandbox via ACP(Cursor、GitHub Copilot、Grok Build)、Host process(Cline、fx、Pi)------ 执行位置决定安全边界,用前必须读该 adapter 的运行时位置与安全指引(Overview 明确警告)。

3.5 Workflow Utilities --- 把 harness 轮次跑成持久 workflow

定位 :@ai-sdk/workflow-harness 提供在 workflow 内运行 HarnessAgent 轮次的 helper ------ 包内提供可序列化的状态机 ,以及 time-sliced 与 semantic agent step 两种轮次的 runner;你从自己的 'use workflow' / 'use step' 函数里调用相应 runner 。核心 harness 与 workflow 文件是框架无关的,示例中的 HTTP handler 只是以 Next.js 为例(用 Next.js 需先按 Workflow SDK 文档配置项目)。安装时除 workflow 专用包外,还需 core harness 包、一个 harness adapter 与一个 sandbox adapter。

Configuring the Harness Agent(两种模式的关键差异) :agent 大体可按常规配置;使用 semantic agent steps 时把 stopWhen 设为 isStepCount(1),使一次 stream() 恰好完成一个 agent step ;使用 time slices 时省略 stopWhen。

Using Semantic Agent Steps:在每个 agent step 之后持久化 harness 轮次。

  • Defining the Agent Step :把 Workflow step 放在自己的模块 里,并在 step body 内动态 import agent ------ 这样 agent、sandbox adapter 及其它 Node.js 依赖不会进入 workflow bundle。从 Workflow step 调用 runHarnessAgentStep()。
  • Defining the Semantic Agent Step Workflow :创建 workflow state,只要 agent 还有工作就持续调度 agentStep() 。每个 ready_for_next_step 结果都携带 continueFrom ,让下一个 Workflow step 继续同一个未完成轮次;轮次完成时 finalizeHarnessWorkflow() 返回其结果,workflow 失败时抛出。
  • Starting the Semantic Agent Step Workflow :从服务端代码启动。传转换后的消息,才能让 HarnessAgent 区分「新的 user turn」与 tool approval / tool result 续跑 。workflow state 的 sessionId 标识 harness session;step 在首次创建 sandbox 之前从中派生 sandboxId ,并在后续 steps 用同一 ID reattach ------ state 不序列化 live sandbox 。把 agent.ts、agent-step.ts、workflow.ts 与 route 保持在分离模块中。
  • 该示例只覆盖 workflow 执行基础;多轮对话必须在多次 workflow run 之间持久化 harness session 的 resumeFrom 状态。

Using Time Slices :按 wall-clock 边界持久化长时间运行的 harness 轮次(适合单步很长的编码任务)。

  • 省略 shared agent 上的 stopWhen,从 Workflow step 调用 runHarnessAgentTimeSlice() ;默认使用 750 秒预算 ,传 timeSliceSeconds 选择不同预算。
  • Defining the Time Slice Step:与 semantic agent step 相同 ------ step 独立成模块、body 内动态 import。
  • Defining the Time-Sliced Workflow :同样创建 workflow state 并持续调度 timeSliceStep();ready_for_next_step 携带 continueFrom,结束时由 finalizeHarnessWorkflow() 返回结果或抛错。
  • 销毁时机(重要) :destroyOnFinish 销毁 harness session,但永不销毁 supplied sandbox ;调用方可以在没有后续 step 需要 reattach 时显式 sandboxSession.destroy();绝不要在后续 step 必须 resume 的时间片边界销毁它 。若不从 sessionId 派生 sandboxId,就必须单独持久化 sandboxSession.id 才能跨 steps reattach。

Resume Persistence :workflow 会自动持久化每个 step 返回的 HarnessWorkflowState(含 continueFrom),作用域是当前这次 workflow run ;要跨多次 user-turn workflow run 继续原生 harness session,需按 sessionId 持久化不透明的 resumeFrom 状态 。存储实现对两种 workflow 方式完全相同 ;示例把文件读写放在 Workflow step 里,因为文件系统访问必须留在 workflow 函数之外 ;生产环境改用持久存储而非本地文件。接入点:在创建 workflow state 之前 load 上一次 resumeFrom,在执行循环之后 persist 更新后的值。

3.6 Harness UI(useChat 路由)

定位 :harness 流与 AI SDK UI message streams 兼容 ------ 客户端用 useChat(),服务端路由流式输出 HarnessAgent 的结果。与基于模型的聊天路由最重要的差异是 session 管理 :harness 拥有自己的对话状态,因此路由应按 chat id 去 resume 或创建 HarnessAgentSession,而不是把整段 UI 消息历史重放进模型。

  • Client / Agent :客户端照常 useChat();HarnessAgent 定义在服务器上。
  • Session Store :持久化 session.detach() 返回的不透明 resume 状态 ;若该轮因审批暂停或被其它方式打断,这个 resume 状态内部就携带了 continuation 状态 。chat id 可以直接当 harness sessionId ;示例从已知的 chat id 派生稳定的 sandboxId ,若不派生则必须单独持久化返回的 sandboxSession.id 。生产环境用持久存储 而不是内存 map。creator 总是创建新 sandbox,并在 sandboxId 冲突时失败;只有 resume 函数会 reattach 已存在的那个(与 3.1 一致)。
  • Route :三步 ------ 把 UI messages 转成 model messages、运行 harness 轮次、再把结果流转回 UI message stream。在获取 session 之前先创建 UI message stream ,这样 sandbox、bootstrap 与 harness 启动失败会作为 UI error parts 发出,而不是变成通用 HTTP 错误 。getHarnessErrorMessage 保留已审阅的、客户端安全的 harness 消息,并掩盖未知服务端错误 。⚠️ 不要把 createAgentUIStreamResponse 直接用在 HarnessAgent 上 ,除非你包装 agent 以注入所需 session ------ HarnessAgent.stream() 每次调用都要求 session。
  • Detach or Stop :想把 harness runtime 停靠并让 sandbox 保持温暖 以供下个请求时用 detach() (bridge-backed adapters 通常能高效 reattach 或 replay;轮次未完成时 detach() 的 resume 状态含 turn continuation 状态)。stop() 保存 resume 状态并停止 harness runtime,但不会停止 supplied sandbox ------ 该 network session 归调用方所有,应在聊天结束时调用它的 destroy(),而不是在后续请求还需要 reattach 时 ;跨进程保留所选 sandboxId。
  • Rendering Harness Parts :harness 输出使用与 AI SDK model streams 相同的 UI message part 形状 ------ text 与 reasoning parts;类型化 tool parts(tool-bash、tool-read ,或宿主工具 tool-weather );dynamic-tool parts 承载 fileChange、compaction 等动态事件。类型化 harness 内置工具按渲染普通 AI SDK tool parts 的方式渲染 ,并检查 part.state 的 input-streaming / input-available / output-available。
  • Type-Safe Tool Parts :在 HarnessAgent 的 session options 进入基础 Agent 调用参数之前,从 agent.tools 推断 UI tools ,然后客户端用 useChat<HarnessMessage>()。

3.7 Harness Terminal UI

定位 :@ai-sdk/tui 可以在终端渲染 harness streams、tool calls、reasoning sections 与 approval prompts 。关键约束:因为 HarnessAgent 的 generate 与 stream 都要求 session,所以要用一个小的 AgentTUIAgent adapter 包装它,为终端 UI 的整个生命周期注入同一个 session。

  • 终端持续运行直到用户用 Esc 或 Ctrl+C 退出(与 1.11 一致)。
  • 每次终端运行使用一个 session ;若使用长生命周期的终端工具且之后需要 resume,持久化 session.detach() 或 session.stop() 返回的状态。
  • 相关:Agents 板块的 Terminal UI(1.11,面向 ToolLoopAgent)、runAgentTUI API Reference、HarnessAgent(3.1)。

3.8 Harness Tools 逐节细节(对 3.2 的展开,同一篇官方文档)

Built-in Tools :每个 adapter 声明自己的 runtime 可原生调用 的内置工具;HarnessAgent 把它们与你的宿主工具合并 ,合并后的工具集通过 agent.tools 暴露。内置调用由 harness runtime 执行,不在你的应用进程内 ,因此流 parts 在 runtime 已执行时带 providerExecuted: true 。adapter 尽量使用跨 harness 通用名 :read、write、edit、bash、grep、glob、webSearch;没有通用名的原生工具按原生名出现。

Host-Executed Tools :像给 ToolLoopAgent 传工具一样传给 HarnessAgent;harness 调用 weather 时,由 HarnessAgent 在宿主进程执行 ,再把结果提交回 harness runtime 。宿主工具可声明 contextSchema 并通过 toolsContext 接收轮次作用域(turn-scoped)的上下文;用 prepareCall 在依赖自定义 call options 时替换 toolsContext。 toolsContext 的类型由工具集推导 :没有任何工具声明 context schema 时拒绝传入 ;有工具要求 context 对象时必填 ;所有 context 对象都可选时可选 。执行前 HarnessAgent 会逐个按该工具的 contextSchema 校验 ,并把配置好的 map 暴露在 step 结果与生命周期回调里。工具 context 仅存在于宿主侧,不会被序列化进挂起轮次的状态 ------ 为未完成的轮次重建 session 时必须显式重新绑定 。缺失或非法 context 会在宿主工具执行之前 校验失败;返回给 harness runtime 的校验错误被刻意做成通用信息,以免把宿主侧 context 值与 schema 细节泄露给模型。

Client-Side Tools :省略 execute 表示由浏览器、用户交互或其他外部进程提供结果。harness 调用没有 execute 的工具时,返回的 result slice 在 tool-call 步骤处结束 ,而底层轮次等待结果;session.hasUnfinishedTurn() 保持 true ,session.suspendTurn() 会把 pending 工具调用包含进可序列化的续跑状态 。UI 流程中,把 addToolOutput 之后产生的模型消息传给下一次 stream() / generate(),HarnessAgent 会提取末尾的 tool result 并自动继续暂停的轮次 。直接调用 agent 时,把原始结果传给 continueStream() / continueGenerate() ;外部工具失败时设 isError: true 。要跨进程继续:suspendTurn() → 用 continueFrom 重建 session → 把结果交给 continueStream() / continueGenerate()。

Tool Filtering :activeTools 是允许列表,inactiveTools 是禁止列表,两者都接受合并工具集 里的名字(adapter 声明的内置 + tools 传入的 AI SDK 工具)。二者只能传其一 :TypeScript 设置类型禁止同时出现,运行时也会抛错。对宿主工具 ,inactive 的不会传给底层 harness runtime ;若 runtime 仍尝试调用,HarnessAgent 返回execution-denied 结果。对内置工具 ,是否支持取决于 adapter :有的可原生过滤;有的通过其内置工具审批机制在执行前拒绝 inactive 调用且不发审批 request/response parts ;两者都不支持的 adapter 在你对内置工具做过滤时抛错。

Sandbox in Tool Execution :宿主工具通过与其它 AI SDK 工具相同的 experimental_sandbox 执行选项收到 session 的 sandbox ;该值是受限的 sandbox session ------ 工具可读写文件、执行命令,但无法停掉网络沙箱或修改其网络策略。

Tool Approvals(两条独立通道) :harness 区分内置工具的权限 与宿主工具的审批。

  • 内置工具用 permissionMode :allow-all (允许读、编辑、shell 命令,默认 )、allow-edits (允许读与编辑,adapter 支持内置审批时对 shell 命令请求审批 )、allow-reads (只允许读,adapter 支持时对编辑与 shell 命令请求审批)。
  • 宿主工具用 toolApproval ,接受与 AI SDK 状态对象相同的取值:not-applicable、approved、user-approval、denied。
  • 需要审批时流在 tool-approval-request 之后暂停 ;继续同一 session 的方式是发送 tool approval response 消息 ------ UI 流程里 useChat 在你添加审批结果时自动代发 ;直接调用时把审批响应作为下一次 stream() / generate() 的 messages。

Built-in Approval Support :多数 adapter 可暂停内置工具调用等待审批;不支持的 adapter 在指定了不受支持的审批模式时会报错 。宿主工具的审批由 HarnessAgent 负责,因此跨 adapter 都可用。

File Changes and Compaction :部分 harness 事件不是普通工具调用 ;为兼容 UI,HarnessAgent 把它们投影为 dynamic、provider-executed 的 tool parts :fileChange (不透明的 workspace 文件变更)、compaction (runtime 压缩上下文)。先检查 part.dynamic 再假定某个 tool part 属于你的类型化工具集。


4. 选型速查

需求 选择
一次模型调用(文本/结构化/工具) Core:generateText / streamText + Output.* + tool()
自主循环、多次工具调用、可复用 agent ToolLoopAgent (默认 stopWhen: isStepCount(20))
循环需要跨进程持久化、失败重试、审批跨挂起存活 WorkflowAgent (@ai-sdk/workflow,needsApproval)
要跑成熟编码运行时(Claude Code/Codex/Pi),保留其原生行为 HarnessAgent + adapter + sandbox + session
需要确定性、可重复的多段流程 core 函数 + Workflow Patterns(链/路由/并行/编排-worker/评估-优化)
敏感动作需要人工放行 toolApproval(+ 策略化用 @ai-sdk/policy-opa;服务端信任用 experimental_toolApprovalSecret)
上下文会被大量探索污染 Subagents + toModelOutput
工具太多、prompt 缓存吃紧 toolSearch() + deferLoading,或 Code Mode
前端聊天 useChat + createAgentUIStreamResponse / toUIMessageStream + ChatTransport(HarnessAgent 例外 :stream() 每次调用都要求 session,直接套用 createAgentUIStreamResponse 需先包装 agent 注入 session,见 3.6)
本地快速验证 @ai-sdk/tui(runAgentTUI)

贯穿全篇的几条硬规则:

  1. 服务端状态走 runtimeContext(共享)/ toolsContext + contextSchema(按工具),不要塞进 prompt ;Workflow 场景下这些值必须可序列化。
  2. ToolLoopAgent 默认 stopWhen: isStepCount(20),被该默认限制截断时 SDK 会记录 warning ;WorkflowAgent 的 generate() 默认最多 20 步、stream() 无上限 (除非显式设置);HarnessAgent 的 stopWhen 没有默认值 ------ 省略时一直跑到轮次自然结束或停下等待宿主输入。
  3. 审批只在 AI SDK 执行 的工具上生效,provider-executed 工具例外;useChat 模式下消息历史是客户端可控输入,敏感工具必须签名字段。
  4. prepareStep 的改写只作用于当前步 (messages 覆盖除外,它会持久成为后续基础)。
  5. prepareCall 返回对象替换 调用设置 ------ 必须先展开 ...settings。
  6. 生成结构化输出也算一步 ,与工具同用时给 stopWhen 留够步数。
  7. 生命周期回调里的异常被吞;遥测默认不记录 context 与内容,需显式开关。
  8. experimental_* 前缀的接口(sandbox、MCP events、batch、rerank、code mode、decide、realtime、transcribe/translate、generateVideo、toolApprovalSecret、transform、MCPAppRenderer)随时可能破坏性变更;Harnesses 整块处于实验期。

来源 :AI SDK v7 官方文档 Agents(11 篇)、AI SDK Core(32 篇)、AI SDK Harnesses(8 篇)三个板块的全部 51 个子主题页面 ,抓取于 ai-sdk.dev/docs(任意页面 URL 加 .md 后缀可直接取纯 Markdown 版本;全站索引见 ai-sdk.dev/llms.txt)。

精度说明 :第 0、1 章(Agents 11 篇)与第 3 章(Harnesses 8 篇)已按原文逐篇精读并校订 ;Core 板块 2.9--2.26 以各页官方小节标题与 API 标识清单为依据整理 ------ 命名与取值均出自原文,但未逐条复核每个可选参数的默认值。若某个 API 细节对你的实现关键,请按「本文小节 → 对应文档页面」回原文确认(各节标题即官方页面标题)。

相关推荐
申君健24864182772021 小时前
AI SDK 概念全景总结(v7)
后端
imDwAaY1 小时前
SQL 查询突然变慢了?一篇讲清慢 SQL 排查思路
后端·mysql
小羊没烦恼!2 小时前
T-SQL查询高级—SQL Server索引中的碎片和填充因子
开发语言·前端·javascript·数据库·后端·python·web安全
the局外人2 小时前
学会 SQLAlchemy 搭建 Python 与 MySQL 之间的数据访问桥梁 🚀
后端·python·sql
金銀銅鐵2 小时前
[Java] 用 GUI 展示 ArrayList 扩容的过程
java·后端·ai编程
霸道流氓气质3 小时前
基于 Spring @Profile 的 MQ 消费者按需开关设计
java·后端·spring
逆风优雅3 小时前
nestjs middleware 接口请求日志
后端·js