AI SDK 集成

更深入的遥测

使用 createEvlogIntegration 添加工具执行耗时和总墙钟时间。可与 supermemory 或 guardrails 等其他中间件组合使用。

createAILogger 会覆盖 token、模型信息和流式指标。若要实现更深入的可观测性——包括按工具执行耗时、成功/失败跟踪以及生成过程的总墙钟时间——请在其基础上添加 createEvlogIntegration()。它实现了 AI SDK 的 TelemetryIntegration 接口,并捕获仅靠中间件无法看到的数据。

与中间件组合使用(推荐)

当传入 AILogger 时,该集成会共享其累加器。两条路径都会写入同一个 ai.* 字段:

server/api/agent.post.ts
import { generateText } from 'ai'
import { createAILogger, createEvlogIntegration } from 'evlog/ai'

export default defineEventHandler(async (event) => {
  const log = useLogger(event)
  const ai = createAILogger(log)

  const result = await generateText({
    model: ai.wrap('anthropic/claude-sonnet-4.6'),
    tools: { getWeather, searchDB },
    experimental_telemetry: {
      isEnabled: true,
      integrations: [createEvlogIntegration(ai)],
    },
  })

  return { text: result.text }
})

你的宽事件现在包含了按工具统计的耗时:

Wide Event
{
  "ai": {
    "calls": 2,
    "steps": 2,
    "model": "claude-sonnet-4.6",
    "provider": "anthropic",
    "inputTokens": 3500,
    "outputTokens": 800,
    "totalTokens": 4300,
    "toolCalls": ["getWeather", "searchDB"],
    "tools": [
      { "name": "getWeather", "durationMs": 150, "success": true },
      { "name": "searchDB", "durationMs": 45, "success": true }
    ],
    "totalDurationMs": 2340,
    "msToFirstChunk": 180,
    "msToFinish": 2100,
    "tokensPerSecond": 380
  }
}

独立使用(不带中间件)

如果你的模型已经被包装过了(例如被另一个中间件包装),请直接传入请求日志器:

server/api/chat.post.ts
import { createEvlogIntegration } from 'evlog/ai'

const integration = createEvlogIntegration(log)

const result = await generateText({
  model: somePreWrappedModel,
  experimental_telemetry: {
    isEnabled: true,
    integrations: [integration],
  },
})

该集成捕获什么

数据来源描述
ai.tools[]onToolCallFinish每个工具的 namedurationMssuccess,以及 error(如果失败)
ai.totalDurationMsonStartonFinish从生成开始到完成的总墙钟时间

中间件会捕获 token、模型信息和流式指标。该集成会捕获工具执行耗时。两者结合,能为你提供完整的 AI 可观测性。

可组合性

ai.wrap() 可与已被其他工具包装的模型配合使用。如果你使用 supermemory、guardrails 中间件或其他任何模型包装器,请将包装后的模型传入 ai.wrap()

server/api/chat.post.ts
import { createAILogger } from 'evlog/ai'
import { withSupermemory } from '@supermemory/tools/ai-sdk'
import { createGateway } from 'ai'

const gateway = createGateway({ ... })
const ai = createAILogger(log)
const base = gateway('anthropic/claude-sonnet-4.6')
const model = ai.wrap(withSupermemory(base, 'your-org-id', { mode: 'full' }))

对于显式的中间件组合,请使用 createAIMiddleware 获取原始中间件,然后通过 wrapLanguageModel 自行组合:

server/api/chat.post.ts
import { createAIMiddleware } from 'evlog/ai'
import { wrapLanguageModel } from 'ai'

const model = wrapLanguageModel({
  model: base,
  middleware: [createAIMiddleware(log, { toolInputs: true }), otherMiddleware],
})

createAIMiddleware 返回的中间件与 createAILogger 内部使用的是同一个。区别在于:createAIMiddleware 不包含 captureEmbed(嵌入模型不使用中间件)。当你需要完整 API 时使用 createAILogger;当你需要显式的中间件顺序时使用 createAIMiddleware