【免费下载链接】evlog
Digging through logs is not observability. It's hope — wide events, structured errors, TypeScript-first, every runtime.
evlog 是 TypeScript 优先的宽事件(Wide Events)日志库,而 evlog/eve 集成让基于 eve 构建的 AI Agent 获得真正的可观测性:每一轮对话结束时产出一条宽事件,token 用量、模型成本、每一次工具调用的耗时与成败,全部收敛进同一个 JSON 对象——告别"翻日志找上下文"。
为什么 AI Agent 可观测性要告别"翻日志"
一次 Agent 对话可能触发多次模型调用、若干工具执行、甚至人工审批。用传统方式打散日志,你会得到十几条彼此孤立的记录:step completed、tool call、approval pending……排查一次退款为何失败,得靠人脑把它们重新拼起来。
evlog 的思路相反:把**"一轮 Agent 对话"当作一个工作单元**,在整个回合内持续累积上下文,结束时一次性发出一条信息完整的宽事件。这个概念在官方教程里有完整讲解,见 wide-events 文档。
对 Agent 场景来说,宽事件还额外回答了三个高频问题:
- 💰这轮花了多少钱?——token 用量与成本按轮次自动汇总
- 🔧模型调了哪些工具、哪个慢了?——每次工具执行都有耗时和成功状态
- 🧾业务发生了什么?——工具内部用
useLogger()补上的客户、订单、审批字段
快速上手:evlog/eve 钩子只需一个文件
eve 会自动发现agent/hooks/下的钩子文件。接入 evlog 只需要新建一个文件,核心逻辑在 defineEvlogHook:
// agent/hooks/evlog.ts import { defineEvlogHook } from 'evlog/eve' import { createAxiomDrain } from 'evlog/axiom' export default defineEvlogHook({ init: { env: { service: 'my-agent' } }, drain: createAxiomDrain(), })就这么多。之后 eve 的每个流式事件(turn.started、step.completed、action.result等)都会被钩子自动收集,无需中间件——因为 Agent 的工作单元是对话轮次,不是 HTTP 请求。
想让工具把业务字段写进宽事件?在工具执行器里调用 useLogger() 即可,它通过 AsyncLocalStorage 自动解析出当前轮次的 logger:
// agent/tools/lookup_order.ts const log = useLogger() log.set({ order: { id: order.id, amount: order.amount } })宽事件长什么样:一轮对话一条 JSON
对话结束后,drain 收到的是一条自包含的事件。以一个正在等待审批的退款请求为例(摘自 eve 集成文档):
{ "method": "EVE", "path": "/sessions/sess_abc/turns/turn_0", "status": 200, "duration": "7.9s", "eve": { "sessionId": "sess_abc", "turnId": "turn_0", "phase": "awaiting-approval" }, "customer": { "slug": "acme-corp", "plan": "enterprise" }, "order": { "id": "4821", "amount": 890 }, "approval": { "status": "pending", "tool": "issue_refund" }, "ai": { "model": "deepseek/deepseek-v4-flash", "calls": 2, "inputTokens": 11724, "outputTokens": 282, "tools": [ { "name": "lookup_customer", "durationMs": 26, "success": true }, { "name": "lookup_order", "durationMs": 13, "success": true } ] } }注意eve.phase:只有异常结束(等待审批、被拒绝、取消、失败)才会出现,正常完成不产生噪音——宽事件依然"宽",但不啰嗦。
Token 用量与工具调用追踪:透明在哪
ai字段的汇总由 buildAiField 从 eve 的流式事件中逐步累积(见 TurnAccumulator 的累计器设计):
| 字段 | 你能看到什么 |
|---|---|
ai.inputTokens/ai.outputTokens | 本轮全部模型调用的 token 汇总 |
ai.costUsd/ai.estimatedCost | 优先取 eve 上报的真实成本;没有时按你配置的单价表估算 |
ai.tools[].durationMs | 每次工具调用的耗时,慢工具一眼定位 |
ai.tools[].success | 工具成败,失败还会带error原因 |
ai.tools[].inputTokens | 工具结果回灌给模型的 token 增量,把成本归因到具体工具 |
eve.authorizations/eve.subagents | 连接授权、子 Agent 委派的耗时与结果 |
eve.compaction | 上下文压缩次数,以及触发时上下文有多满 |
配合尾采样(keep回调),你可以只保留"值得看"的轮次——比如 token 超阈值或工具失败的对话,其余按采样率丢弃,成本可控。
实战示例:Clearbill 退款 Agent 的完整链路
仓库自带一个客服退款 Agent 演示,完整流程是:lookup_customer→lookup_order→issue_refund(金额超 $100 触发人工审批)。三个工具都用useLogger()往当前轮次里写业务字段:
- 客户查询工具:lookup_customer.ts
- 退款工具(含审批门与审计记录):issue_refund.ts
- 钩子配置(批量落盘 + 尾采样保留退款/审计轮次):agent/hooks/evlog.ts
最终财务团队在日志后台拿到的是每轮一个 JSON:客户、订单、退款、审计轨迹、token 用量、工具结果,一个都不缺。示例项目说明见 examples/eve/README.md。
本地跑起来:
git clone https://gitcode.com/gh_mirrors/ev/evlog cd evlog pnpm install pnpm example eve打开 http://localhost:3000,点击示例提示词,就能看到宽事件从"等待审批"到"退款完成"的全过程。
进阶:用 requestId 把 Trace 与宽事件双向打通
eve 自带 Agent Runs 和 OpenTelemetry 链路追踪,但 span 和宽事件默认互不相认。defineEvlogInstrumentation 会在每个模型调用 span 上打上evlog.request_id与evlog.session_id——和宽事件里的requestId是同一个值。于是你可以从 Braintrust、Datadog 或 Agent Runs 里的一条 trace直接跳到对应宽事件,再跳回来。
示例项目里就只有一行(见 agent/instrumentation.ts):
export default defineEvlogInstrumentation()另外,开启sessionEvent: true后,会话结束时还会额外发出一条会话级宽事件(emitSessionEvent),把整段对话的轮次数、总 token、总成本、用过的工具全部汇总成一行——"一次对话一行"的账单视角。
生产环境最佳实践清单
| 关注点 | 建议 |
|---|---|
| 隐私 | message默认'omit'不记录用户消息原文;需要排查时再开'preview'(默认截断 500 字符),'full'前先过一遍 PII 政策 |
| 终端输出 | 生产设init.pretty: false,美化输出只留给本地开发 |
| 上报延迟 | 用批量或异步 drain(如createDrainPipeline包装),绝不阻塞对话轮次 |
| 内存 | maxSessions(默认 256)自动淘汰最久未活跃的会话状态 |
| 版本 | eve 仍在 beta,生产环境请锁定eve与evlog版本 |
相关模块路径速查
- eve 集成实现:packages/evlog/src/eve/index.ts
- eve 集成教程:5.use-cases/5.eve.md
- 宽事件核心概念:2.learn/2.wide-events.md
- 完整退款 Agent 示例:examples/eve/
- 结构化审计日志:packages/evlog/src/audit.ts
一句话总结:让 eve agent 的每一轮对话都留下一条讲清所有事的宽事件,token 花了多少、工具跑了多久、审批卡在哪一步——打开日志就知道。🪵
【免费下载链接】evlog
Digging through logs is not observability. It's hope — wide events, structured errors, TypeScript-first, every runtime.
相关推荐
ottomator-agents 中的 Pydantic AI 入门实践:构建一个带工具调用与 Langfuse 可观测性的对话 Agent
ottomator agents 中的 Pydantic AI 入门实践:构建一个带工具调用与 Langfuse 可观测性的对话 Agent 本文以 ottom
示例工程evlog enrichers实战:自动为每条事件附加User-Agent、地理位置与trace上下文
evlog enrichers实战:自动为每条事件附加User Agent、地理位置与trace上下文 evlog 的 enrichers(日志增强器) 让每条
treg Agent Skill 完全指南:用一条 Token 把 3000+ 外部数据与生成式 API 变成 Agent 的可调用工具
treg Agent Skill 完全指南:用一条 Token 把 3000+ 外部数据与生成式 API 变成 Agent 的可调用工具 本文以 treg 官方
后端API网关MCP 服务dsh-plugin
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考