ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

AI SDK + evlog:每次AI调用一条完整事件,token、工具调用与成本尽收眼底

AI SDK + evlog:每次AI调用一条完整事件,token、工具调用与成本尽收眼底 【免费下载链接】evlogDigging through logs is not observability. Its hope — wide events, structured errors, TypeScript-first, every runtime.项目地址https://gitcode.com/gh_mirrors/ev/evlog点击查看免费下载evlog 是一个 TypeScript 优先的结构化日志库核心理念是每个请求一条宽事件wide event。配合官方 AI SDKevlog/ai会把每次 AI 调用的 token 用量、工具调用、流式速度与成本自动汇总进同一条宽事件——无需手写埋点也无需额外追踪。你是否遇到过这样的场景AI 接口跑了一分钟你却不知道它消耗了多少 token、调了哪些工具、花了多少钱本文带你用 3 步完成接入让 AI 调用可观测变得简单。一、为什么 AI 调用需要一条完整事件 AI 应用里的传统埋点方式痛点很明显token 是散的输入、输出、推理 token 藏在响应各处翻账单要逐个对成本是黑盒单次请求花了多少钱无法实时知道做预算告警和计费都很吃力工具调用难复盘一个多步 Agent 调了 5 次工具却看不出哪一步慢、哪一步失败日志是碎的一次聊天请求散落几十行日志凌晨三点只能靠 grep 找信号。evlog 的思路正好相反与其翻日志找线索不如每次只留一条完整事件。二、三步接入两行代码开始记录 AI 调用 ⚡2.1 安装依赖添加 AI SDK 即可evlog 通常在项目中已就绪npm install ai2.2 用中间件包裹模型加两行、改一个参数接入即完成import { useLogger } from evlog import { createAILogger } from evlog/ai const log useLogger(event) // evlog 的请求日志器 const ai createAILogger(log) // AI 可观测日志器 const result streamText({ model: ai.wrap(anthropic/claude-sonnet-4.6), messages, })ai.wrap()返回一个带中间件的模型之后generateText、streamText、ToolLoopAgent的每次调用都会自动累计数据。中间件不触碰你的onFinish回调、提示词和响应属于纯旁观式记录。2.3 拿回完整事件请求结束时宽事件自动携带ai字段发出{ method: POST, path: /api/chat, status: 200, durationMs: 4512, ai: { calls: 1, model: claude-sonnet-4.6, provider: anthropic, inputTokens: 3312, outputTokens: 814, totalTokens: 4126, reasoningTokens: 225, finishReason: stop, msToFirstChunk: 234, msToFinish: 4500, tokensPerSecond: 180 } }三、evlog/ai 会自动捕获哪些数据 不做任何额外配置ai.wrap()就已经记录了这些内容数据宽事件字段说明token 用量ai.inputTokens/ai.outputTokens/ai.totalTokens同一请求内多次调用自动累计缓存命中ai.cacheReadTokens/ai.cacheWriteTokens提示词缓存的读写 token推理 tokenai.reasoningTokens扩展思考产生的 token模型信息ai.model/ai.provider/ai.models最后使用的模型、提供方、多模型场景的全部模型工具调用ai.toolCalls默认记录工具名开启后可附带调用入参流式指标ai.msToFirstChunk/ai.tokensPerSecond首 token 时延、输出速度结束原因ai.finishReasonstop、tool-calls、error等错误ai.error模型调用失败信息先写入事件再重新抛出对流式响应evlog 在 Nuxt、Nitro、Next.js 等框架上会把宽事件的发出延迟到流结束后保证最终的 token 数据和请求上下文落在同一条事件上。四、估算 AI 调用成本加一张价格表 cost选项接受按每百万 token 美元计价的价格表宽事件会自动算出ai.estimatedCostconst ai createAILogger(log, { cost: { claude-sonnet-4.6: { input: 3, output: 15 }, gpt-4o: { input: 2.5, output: 10 }, }, }) // 在处理器里随时读取本次调用的成本 const cost ai.getEstimatedCost() console.log(本次调用花费 $${cost?.toFixed(4)})由此可以实现昂贵调用前先提醒用户、按用户汇总 AI 支出等场景。小建议把价格表和模型选择放在同一个文件里维护换模型时价格同步更新避免多条路由各自维护导致漂移。五、多步 Agent、RAG 与多模型场景 5.1 多步 Agent 全程留痕使用ToolLoopAgent时中间件对每一步自动记录宽事件里能看到逐步明细{ ai: { calls: 3, steps: 3, toolCalls: [searchWeb, queryDatabase, searchWeb], stepsUsage: [ { model: claude-sonnet-4.6, inputTokens: 1200, outputTokens: 300, toolCalls: [searchWeb] }, { model: claude-sonnet-4.6, inputTokens: 1500, outputTokens: 400, toolCalls: [queryDatabase, searchWeb] } ] } }想看到每个工具收到的入参调试 Agent 行为时非常有用开启toolInputsconst ai createAILogger(log, { toolInputs: { maxLength: 500 } })5.2 RAG 里的 embedding 调用embedding 模型不能通过中间件包裹用专门方法手动上报即可const { embedding, usage } await embed({ model: embeddingModel, value: query }) ai.captureEmbed({ usage, model: text-embedding-3-small, dimensions: 1536 })5.3 多模型路由每个模型各自wrap一次即可它们共享同一个累计器。事件里会同时出现ai.model最后一次使用的模型和ai.models出现过的全部模型路由行为一目了然。六、更深度的遥测工具执行耗时与总生成时长 ai.wrap()覆盖 token、模型与流式指标若还想拿到每个工具的执行耗时、成功/失败以及整次生成的总墙上时间再叠加一个集成即可const result await generateText({ model: ai.wrap(anthropic/claude-sonnet-4.6), tools: { getWeather, searchDB }, telemetry: { integrations: [createEvlogIntegration(ai)], }, })宽事件随之多出这些字段{ ai: { tools: [ { name: getWeather, durationMs: 150, success: true }, { name: searchDB, durationMs: 45, success: true } ], totalDurationMs: 2340 } }在 AI SDK v7 上该集成还会自动捕获 embedding、流式中止ai.finishReason: abort和不可恢复错误两者组合即完整的 AI 可观测。七、新手避坑4 条最佳实践 ✅敏感内容默认不开启prompt、output、toolInputs三个选项默认关闭模型收发过的内容不会流入日志目的地除非你点名要要捕获就先加maxLength和transform两者内置支持截断与脱敏。工具入参常含 SQL、密钥和用户数据生产环境建议先开截断再开捕获价格表单一来源cost表与模型配置放一起维护改模型和改价格发生在同一处错误也在同一条事件模型调用失败会先写入ai.error再重新抛出你的try/catch照常工作排查时一条事件同时看到错误、token 和工具调用。八、相关资源 官方文档 · AI SDK 集成总览apps/docs/content/5.use-cases/2.ai-sdk/01.overview.md用法模式流式、Agent、RAG、多模型apps/docs/content/5.use-cases/2.ai-sdk/02.usage.md全部选项工具入参、提示词/输出捕获、成本表apps/docs/content/5.use-cases/2.ai-sdk/03.options.md在处理器内读取元数据getMetadata/getEstimatedCost/onUpdateapps/docs/content/5.use-cases/2.ai-sdk/04.metadata.md深度遥测工具耗时、总生成时长apps/docs/content/5.use-cases/2.ai-sdk/05.telemetry.md核心实现createAILogger入口packages/evlog/src/ai/index.ts#L490-L531宽事件概念详解apps/docs/content/2.learn/2.wide-events.md从今天起让每次 AI 调用都留下一条完整、可检索、可分析的事件——token、工具调用与成本尽收眼底。赞分享【免费下载链接】evlogDigging through logs is not observability. Its hope — wide events, structured errors, TypeScript-first, every runtime.项目地址https://gitcode.com/gh_mirrors/ev/evlog点击查看免费下载相关推荐evlog × eve agent可观测性每轮对话一条宽事件token与工具调用全透明evlog × eve agent可观测性每轮对话一条宽事件token与工具调用全透明 evlog 是 TypeScript 优先的宽事件Wide EveDLSS Swapper 完整教程不等游戏更新一键切换 DLSS 版本DLSS Swapper 完整教程不等游戏更新一键切换 DLSS 版本 你想让老游戏用上新版 DLSS但游戏自带的 DLL 还停在旧版本甚至不知道文件藏桌面应用PostHog 前端中的 Tool 调用事件总线用 toolStreamEventsLogic 让页面实时响应 AI Agent 的每一次工具调用PostHog 前端中的 Tool 调用事件总线用 toolStreamEventsLogic 让页面实时响应 AI Agent 的每一次工具调用 导读 当用数据分析后端前端数据可视化大数据创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进