@voltagent/vercel-ai-exporter:为 Vercel AI SDK 接入 VoltAgent 可观测性的 OpenTelemetry 导出器实战指南
2026/9/24 15:20:08 网站建设 项目流程
  • 人工智能
  • AI Agent
  • Agent 框架
  • 后端
  • 多智能体
  • RAG
  • 工具调用
  • Agent 记忆

【免费下载链接】voltagent

AI Agent Engineering Platform built on an Open Source TypeScript AI Agent Framework

项目地址:https://gitcode.com/gh_mirrors/vo/voltagent
点击查看免费下载

本篇技术指南围绕 VoltAgent 官方 OpenTelemetry 导出器@voltagent/vercel-ai-exporter展开:它能把 Vercel AI SDK 自动生成的 OpenTelemetry Span 转换为 VoltAgent 时间线事件,让你在不改动业务代码的前提下获得 AI 调用、工具执行、Token 用量与多智能体(Multi-Agent)工作流的完整可观测能力。读完本文,你将掌握该包的安装配置、全部元数据选项、多智能体父子追踪的写法,以及它底层的 Span 解析、事件模型与错误处理机制,从而直接在自己的 Vercel AI 应用中落地生产级 LLM 观测。

一、这个包解决什么问题

Vercel AI SDK 自带基于 OpenTelemetry 的experimental_telemetry支持,会为generateTextstreamText等调用生成标准 Span,但 Span 只是原始遥测数据,需要导出到后端才能形成可阅读、可检索的执行历史。@voltagent/vercel-ai-exporter(仓库路径:packages/vercel-ai-exporter)正是连接二者的桥梁:它实现 OpenTelemetry 的SpanExporter接口,把 Vercel AI SDK 产生的 Span 转写为 VoltAgent 的 trace/事件结构,并上报到 VoltAgent 可观测性后端。

从源码看,其核心类VoltAgentExporter直接implements SpanExporter(见 src/exporter.ts),同时内部聚合了@voltagent/sdk提供的观测能力。整个包对外只导出两个符号:VoltAgentExporter类与VoltAgentExporterOptions配置类型(见 src/index.ts),API 面非常收敛。

相比裸的 OpenTelemetry 导出,该包的主要收益(也是 README 明确列出的 Features):

  • 自动追踪:AI 调用与工具使用无需手动打点,自动进入观测平台;
  • 多智能体支持:同一工作流中可同时追踪多个 Agent;
  • 父子层级:通过parentAgentId构建 Agent 层级树;
  • 完整类型安全:纯 TypeScript 实现,导出完整类型定义;
  • Vercel AI SDK 兼容:覆盖generateTextstreamTextgenerateObjectstreamObject等场景;
  • 灵活元数据metadata中的自定义字段可透传到观测平台。

二、安装与前置条件

使用 npm 安装包及其 OpenTelemetry 运行时依赖(与 README 一致):

npm install @voltagent/vercel-ai-exporter @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node
  • @voltagent/vercel-ai-exporter:本包;
  • @opentelemetry/sdk-node:OpenTelemetry Node SDK,用于创建NodeSDK实例;
  • @opentelemetry/auto-instrumentations-node:自动插桩集合,负责收集进程内各库的遥测数据。

Requirements(以仓库现状为准)

依赖版本要求说明
Node.js20+包内使用crypto.randomUUID()等较新 API;CHANGELOG 也记录了放弃 Node 18 的变更
Vercel AI SDK(aiREADME 声明 3.0+;当前包版本2.0.2peerDependencies要求ai@^6.0.0即与 AI SDK v6 对齐,见 package.json
OpenTelemetry SDK@opentelemetry/core@opentelemetry/sdk-trace-base均要求^2.0.0@opentelemetry/sdk-node引入

注意版本差异:README 中写的是 "Vercel AI SDK 3.0+",但当前package.json的 peer 依赖已是ai@^6.0.0(2.x 版本与 AI SDK v6 对齐,详见 CHANGELOG.md)。如果你的项目直接调用 AI SDK,请以 v6 的上游迁移指南为准。许可证为 MIT。

三、快速开始:最小可运行配置

在应用入口(通常是main文件)初始化导出器与 OpenTelemetry SDK,然后在 AI 调用上开启 telemetry 即可。

import { VoltAgentExporter } from "@voltagent/vercel-ai-exporter"; import { NodeSDK } from "@opentelemetry/sdk-node"; import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentsations-node"; import { openai } from "@ai-sdk/openai"; import { generateText } from "ai"; // 初始化 VoltAgent 导出器 const voltAgentExporter = new VoltAgentExporter({ publicKey: process.env.VOLTAGENT_PUBLIC_KEY, secretKey: process.env.VOLTAGENT_SECRET_KEY, debug: true, // 开发阶段建议开启,生产环境建议关闭 }); // 装配 OpenTelemetry SDK const sdk = new NodeSDK({ traceExporter: voltAgentExporter, instrumentations: [getNodeAutoInstrumentations()], }); sdk.start(); // 正常使用 Vercel AI SDK,只需开启 experimental_telemetry const result = await generateText({ model: openai("gpt-4o-mini"), prompt: "Hello, how are you?", experimental_telemetry: { isEnabled: true, metadata: { agentId: "my-assistant", userId: "user-123", }, }, }); console.log(result.text);

获取 API 密钥(以 VoltAgent 可观测性平台的常规流程为准):

  1. 注册并创建组织(organization);
  2. 在组织内创建项目(project);
  3. 在项目设置中获取两个环境变量:
    • VOLTAGENT_PUBLIC_KEY:用于客户端标识;
    • VOLTAGENT_SECRET_KEY:用于安全的服务端通信。

建议写入.env并通过process.env注入,而非硬编码在源码中。

你可能看到的一条提示:如果调用时未提供agentId,控制台会输出:

📋 VoltAgent: Using default agent for tracking. 💡 For better tracking, add agentId to your metadata: experimental_telemetry: { isEnabled: true, metadata: { agentId: 'my-agent' } }

这是正常行为——导出器会回退到默认 Agent 标识ai-assistant(源码中的DEFAULT_AGENT_ID常量,见 src/exporter.ts),所有活动都会归组到该默认 Agent 下。想要更细粒度的追踪,就按提示补上agentId

四、VoltAgentExporter 配置项详解

VoltAgentExporterOptions在 src/exporter.ts 中定义,字段与默认值如下:

配置项类型默认值作用
publicKeystring""VoltAgent 后端公钥,用于客户端标识
secretKeystring""VoltAgent 后端密钥,用于安全通信
baseUrlstring"https://api.voltagent.dev"可观测性后端地址,自托管时可改
autoFlushbooleantrue是否自动批量上报
flushIntervalnumber5000自动上报间隔(毫秒)
debugbooleanfalse开启详细调试日志

从构造器实现可见(src/exporter.ts):debug默认关闭;baseUrl未传时固定为https://api.voltagent.devautoFlush默认trueflushInterval默认5000毫秒。调试日志统一带[VoltAgentExporter]前缀并包含时间戳,方便排查。

开发与生产区分:生产环境应关闭debug,例如按环境切换:

const voltAgentExporter = new VoltAgentExporter({ publicKey: process.env.VOLTAGENT_PUBLIC_KEY, secretKey: process.env.VOLTAGENT_SECRET_KEY, debug: process.env.NODE_ENV === "development", });

五、元数据(Metadata)选项:完整字段与含义

experimental_telemetry.metadata是接入观测的关键入口,字段会以ai.telemetry.metadata.*前缀写入 Span 属性,再由导出器解析还原(见 src/exporter.ts 的extractTraceMetadataparseSpanMetadata)。README 给出的完整元数据示例:

experimental_telemetry: { isEnabled: true, metadata: { agentId: "my-agent", // Agent 标识(必填建议) parentAgentId: "parent-agent", // 父 Agent(可选,用于构建层级) userId: "user-123", // 用户 ID conversationId: "conv-456", // 会话 ID tags: ["marketing", "ai"], // 标签数组 instructions: "Agent instructions", // Agent 描述/系统指令 // ... 其他任意自定义元数据 }, }

各字段在源码中的用途:

  • agentId:决定该次调用的执行历史归属于哪个 Agent;缺省时回退到ai-assistant
  • parentAgentId:声明父子关系。导出器发现它后,会把子 Agent 的事件递归地向上传播到父 Agent 的历史中(见下文多智能体章节);
  • userId/conversationId:作为 trace 级元数据传递给后端,用于按用户、会话过滤;
  • tags:会被聚合成 trace 级标签(parseTagsTraceAttribute会对所有 Span 的 tags 去重合并);
  • instructions:作为 Agent 描述写入事件元数据,便于在控制台快速理解 Agent 职责;
  • 自定义字段:任何以ai.telemetry.metadata.为前缀的属性都会被剥离前缀后透传,因此你可以携带environmentversionsessionId等任意上下文。

补充上下文示例

const result = await generateText({ model: openai("gpt-4o-mini"), prompt: "Tell me a joke", experimental_telemetry: { isEnabled: true, metadata: { agentId: "comedy-assistant", instructions: "You are a fun comedian assistant", userId: "user123", sessionId: "session456", environment: "production", version: "1.2.0", }, }, });

六、工具(Tools)追踪

启用 telemetry 后,AI 调用中的工具定义与执行会被自动追踪——工具名、入参、出参、执行时间线都会进入观测平台。README 中的示例(含 Zod 参数校验):

import { generateText } from "ai"; import { z } from "zod"; const result = await generateText({ model: openai("gpt-4o-mini"), prompt: "What's the weather like in Tokyo?", tools: { weather: { description: "Get weather information", parameters: z.object({ location: z.string(), }), execute: async ({ location }) => { return { location, temperature: 22 }; }, }, }, experimental_telemetry: { isEnabled: true, metadata: { agentId: "weather-assistant", userId: "user-123", }, }, });

底层实现要点(结合 src/exporter.ts):

  • 导出器通过 Span 名称包含tool或属性ai.toolCall.name来识别工具 Span(getSpanType,见 L917-L934);
  • 每个工具 Span 会被转换为tool:starttool:success(或tool:error)两类事件,metadata中包含displayNameid(工具名)以及归属的agentId
  • 工具的执行输入来自ai.toolCall.args,输出来自ai.toolCall.result
  • 若工具 Span 自身没有agentId,导出器会尝试从父 Span 或同 trace 中最近的 generation Span 推断归属(见extractAgentIdFromSpan,L1378-L1443),实在推断不出才落到默认 Agent。

七、多智能体与父子层级追踪

这是该包最具价值的特性。README 的营销计划示例展示了"主 Agent 规划 + 子 Agent 执行"的模式:

// 主 Agent const { text: plan } = await generateText({ model: openai("gpt-4o-mini"), prompt: "Create a marketing plan", experimental_telemetry: { isEnabled: true, metadata: { agentId: "planning-agent", userId: "user-123", conversationId: "marketing-workflow", }, }, }); // 子 Agent(声明父级关系) const { text: execution } = await generateText({ model: openai("gpt-4o-mini"), prompt: `Execute this plan: ${plan}`, experimental_telemetry: { isEnabled: true, metadata: { agentId: "execution-agent", parentAgentId: "planning-agent", // 父级关系 userId: "user-123", conversationId: "marketing-workflow", }, }, });

源码级原理:多智能体支持远不止"打个标记",其实现包括:

  1. Agent 发现discoverAgentsInTrace遍历同 trace 内所有 Span,按agentId聚合成AgentInfo(含parentAgentIddisplayName、起止时间与所属 Span 列表),见 src/exporter.ts;
  2. 按依赖排序创建历史sortAgentsByDependency会先创建父 Agent 的执行历史,再创建子 Agent 的,并内置循环引用检测防止无限递归(L334-L400);
  3. 独立历史:每个 Agent 拥有独立的 history(以agentId_traceId为键),同时globalAgentHistories支持跨 trace 关联(L98-L100);
  4. 递归事件传播addEventToTrace在写入子 Agent 自身历史后,会通过propagateEventToAncestors沿parentChildMap/globalParentChildMap一路向上传播到所有祖先的历史(L506-L608)。传播时保留原始归属:metadata中追加fromChildAgent(直接子 Agent)、originalAgentId(事件最初来源)、propagationDepth(传播深度)与propagationPath(可读路径),并设置 10 层最大深度与环检测双重保险;
  5. Agent 生命周期事件:每个 Agent 的第一个 generation Span 触发agent:start,最后一个完成 Span 触发agent:success,出错时触发agent:error(L725-L820)。

因此,即便你的层级深达三层以上(如 master → division → specialist),子 Agent 的工具调用也会完整出现在每一级祖先的执行历史中,且事件始终标注原始发起者——这一点在 src/exporter.spec.ts 的 "Deep Nested Multi-Agent Hierarchies (3+ Levels)" 测试组中有系统验证(含 4 层归属保持、循环引用、深度上限、跨 trace 传播等用例)。

更丰富的多角色示例

三个 Agent 串联(研究 → 写作 → 审校)时,只需各自声明agentIdrole等元数据,即可在控制台分别查看每个角色的执行情况:

// research-agent:负责收集信息 // writing-agent:基于研究结果写作 // review-agent:审校改进 // 三者均可通过 agentId 独立分组,通过 conversationId 关联为同一工作流

八、Span 识别与数据解析的底层机制

为了更精准地排查问题,值得了解导出器如何把 Vercel AI SDK 的 Span 翻译成 VoltAgent 事件。

Span 类型判定getSpanType,src/exporter.ts):

  • generation:Span 名称包含generatestreamgenerateobjectstreamobject(大小写不敏感);
  • tool:名称包含tool或存在属性ai.toolCall.name
  • 其他:unknown,会被忽略。

只处理 Vercel AI 的 SpanisVercelAiSpan检查instrumentationScope.name === "ai",其他插桩产生的 Span 不会进入转换流程(L896-L901)。

输入/输出解析parseSpanInput/parseSpanOutput,L988-L1046):输入优先取ai.prompt.messages(JSON 解析)、ai.promptai.toolCall.args;输出则按ai.response.object(generateObject 场景)、ai.response.textai.result.textai.toolCall.resultai.response.toolCallsai.embedding(s)的顺序取值,并兼容 object 与 text 同时存在的组合。

Token 用量解析parseUsage,L1090-L1114):同时兼容新旧属性名——输入侧按gen_ai.usage.prompt_tokens/gen_ai.usage.input_tokens/ai.usage.promptTokens依次回退,输出侧对应gen_ai.usage.completion_tokens/gen_ai.usage.output_tokens/ai.usage.completionTokens,并自动计算totalTokens

模型参数与首字节耗时parseModelParameters/parseCompletionStartTime,L1116-L1183):会抽取modeltemperaturemaxTokensfinishReasontoolChoicesystemmaxRetriesmodeoutput等参数;completionStartTime则基于ai.response.msToFirstChunk(旧版为ai.stream.msToFirstChunk)加上 Span 开始时间推算,用于度量"首 token 延迟"。

错误处理:Span 状态码为 2(ERROR,常量ERROR_STATUS_CODE)时,generation 生成agent:error事件、工具生成tool:error事件,均携带error.message;导出过程本身出错时,回调会收到ExportResultCode.FAILED(L176-L182)。

九、内存与生命周期管理

导出器内部维护多张 Map(活跃历史、父子关系、trace 内 Agent、全局历史、工具 Span 缓存、延迟 Span 队列等),并提供两个清理入口(src/exporter.ts):

  • forceFlush():对所有仍活跃的 trace 调用trace.end()兜底收尾,随后清空全部缓存并触发一次sdk.flush()
  • shutdown():内部委托给forceFlush()

对应测试("Memory Management" 用例组,见 src/exporter.spec.ts)验证了 forceFlush 与 shutdown 后各类缓存均被清空。生产环境中,建议在进程退出前调用shutdown(),避免丢失未上报的数据。

十、最佳实践与故障排查

综合 README 与仓库实现,落地时建议:

  1. 使用有意义的agentIdcustomer-support-agentproduct-recommendation-agent优于agent1
  2. 尽量携带上下文instructionsuserIdsessionIdcategorypriority等字段会让历史记录更具可分析性;
  3. 密钥走环境变量
    # .env VOLTAGENT_PUBLIC_KEY=your_public_key VOLTAGENT_SECRET_KEY=your_secret_key VOLTAGENT_BASE_URL=https://api.voltagent.dev
  4. 按环境控制 debug:仅开发环境开启,避免生产日志刷屏;
  5. 自定义 Span 细化追踪:可用@opentelemetry/apitrace.getTracer()包裹业务步骤,与 AI 调用构成完整执行链:
    import { trace } from "@opentelemetry/api"; const tracer = trace.getTracer("my-app"); const result = await tracer.startActiveSpan("user-request-processing", async (span) => { span.setAttributes({ "user.id": "user123" }); // ... generateText 调用 ... span.end(); return response; });
  6. 错误自动记录:捕获异常后调用span.recordException(error)setStatus({ code: 2, message }),即可在观测平台看到agent:error事件。

常见问题排查

  • 控制台无数据:检查VOLTAGENT_PUBLIC_KEY/VOLTAGENT_SECRET_KEY与网络连通性;
  • Span 缺失:确认experimental_telemetry.isEnabled: truesdk.start()在 AI 调用前执行;
  • 性能:生产环境可使用批量上报(autoFlush默认开启,flushInterval可按需调整);
  • 归属不清晰:优先为每个 Agent 显式声明agentId,减少依赖默认 Agent 或推断逻辑。

十一、更深入的学习路径

  • 完整集成文档见仓库内 website/docs/integrations/vercel-ai.md,其中包含安装(npm/pnpm/yarn)、API 密钥获取、基本/工具/元数据/多智能体分步示例、高级特性(自定义 Span、错误追踪)与故障排查;
  • 导出器全部实现源码:packages/vercel-ai-exporter/src/exporter.ts;
  • 单测与多智能体深度用例:packages/vercel-ai-exporter/src/exporter.spec.ts;
  • 包配置与版本约束:packages/vercel-ai-exporter/package.json;
  • 版本演进记录:packages/vercel-ai-exporter/CHANGELOG.md。

整体来看,@voltagent/vercel-ai-exporter遵循"零侵入接入、元数据驱动追踪、层级化事件传播"的设计:你只需在调用时开启 telemetry 并声明agentId/parentAgentId,就能获得从单次生成到多层多智能体工作流的完整可观测数据,同时通过标准 OpenTelemetry 协议与既有可观测性栈无缝共存。

  • 人工智能
  • AI Agent
  • Agent 框架
  • 后端
  • 多智能体
  • RAG
  • 工具调用
  • Agent 记忆

【免费下载链接】voltagent

AI Agent Engineering Platform built on an Open Source TypeScript AI Agent Framework

项目地址:https://gitcode.com/gh_mirrors/vo/voltagent
点击查看免费下载

相关推荐

上一篇:NAS媒体库智能管理:5分钟自动化部署终极指南
下一篇:如何使用Chart.js浏览器扩展xhub:GitHub页面图表增强完整指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询