AI SDK 集成
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 | 每个工具的 name、durationMs、success,以及 error(如果失败) |
ai.totalDurationMs | onStart → onFinish | 从生成开始到完成的总墙钟时间 |
中间件会捕获 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。