OpenViking 使用量审计(Usage Audit):如何记录 Agent 到底用了多少上下文
【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking
当你把 Agent 接入 OpenViking 之后,一个很现实的问题出现了:Agent 到底消耗了多少上下文?今天调了多少次检索?Token 花在哪了?OpenViking 使用量审计(Usage Audit)模块就是为了解答这些问题而生的——它是 OpenViking Server 内置的产品级统计与请求审计能力,默认开启,无需额外配置,就能把 Agent 的 Token 消耗、检索次数、上下文写入活动逐日记录下来,并在 Console 里以 Dashboard 形式呈现。
为什么需要"使用量审计" 📊
很多人做 Agent 可观测性时,只盯着 QPS、延迟这类运维指标(Prometheus 已经管好了)。但还有一层常被忽视的产品语义数据:
| 你关心的问题 | 对应的审计数据 |
|---|---|
| 今天 Agent 烧了多少 Token? | vlm.call/embedding.call事件聚合 |
| 检索功能用得频繁吗? | search.find/search.search请求统计 |
| 谁在往上下文里写数据? | 资源/技能/会话提交热力图 |
| 哪个请求失败了、为什么? | 请求审计日志(状态码、耗时、错误码) |
简单说:Prometheus 告诉你"系统健不健康",Usage Audit 告诉你"业务值不值钱"。
工作原理:一条事件总线,两个消费方 🔌
Usage Audit 最聪明的设计在于:它不在 API 请求链路上同步写库,而是复用 OpenViking 已有的 Observability 事件总线。
数据流大致如下:
业务请求 / 模型调用 | v Observability Event Bus(进程内事件总线) | +--> Metrics subscriber(运维指标) | +--> Usage/Audit subscriber(使用量审计) | v 后台 Worker 批量写 SQLite | v /api/v1/console/* 查询接口关键设计点:
- 非阻塞投递:请求路径只做"发事件",绝不等待写库,业务延迟零感知;
- 后台批量落库:Worker 用有界队列(默认 10000)+ 批量写入(默认 500 条/批),每秒 flush 一次;
- 优雅降级:队列满时丢弃统计事件并累计
dropped_count,宁可少记也不拖垮主链路; - 优雅关闭:服务停止时尽量 flush 剩余事件,避免尾部审计丢失或重复写入。
事件总线的实现位于 events.py,审计订阅者见 subscriber.py,后台批量写库逻辑在 worker.py。
四类审计数据,口径一目了然 🧾
1️⃣ Token 统计
来自模型调用事件,按小时粒度落库(跨时区的"今日"查询可以在读端灵活切分):
| 事件 | 展示口径 |
|---|---|
vlm.call | prompt_tokens→vlm_input,completion_tokens→vlm_output |
embedding.call | prompt_tokens→embedding_input |
rerank.call | 已可落库 |
2️⃣ 今日检索
统计POST /api/v1/search/find与POST /api/v1/search/search的成功请求数,Dashboard 首屏直接展示。
3️⃣ 上下文提交热力图
追踪四类成功写请求(添加资源、添加技能、会话消息、会话 commit),按"日期 × 小时"分桶,一眼看出 Agent 什么时候在"记忆"。
4️⃣ 请求审计日志
每次 API 调用记录:request_id、账号/用户、路由、状态码、耗时、错误码等信息。注意两点:
/metrics、/health、/api/v1/console/*等自身基础设施请求不会进入审计,避免污染数据;error_details经过凭据脱敏和大小限制,不额外保存原始请求体、header 或堆栈——审计而不"偷窥"。
五分钟上手:配置与查询 ✅
好消息是:什么都不用配,它就在工作。默认配置下 SQLite 文件位于 workspace 的_system/usage_audit/usage_audit.sqlite3。
如果想自定义(保留期、批量大小等),完整配置示例:
{ "server": { "observability": { "usage_audit": { "enabled": true, "backend": "sqlite", "queue_size": 10000, "batch_size": 500, "usage_retention_days": 14, "audit_retention_days": 7, "timezone": "local" } } } }几个值得知道的字段:
| 字段 | 默认值 | 说明 |
|---|---|---|
usage_retention_days | 14 | Token/检索/热力图聚合数据保留天数,0为不裁剪 |
audit_retention_days | 7 | 请求审计日志保留天数 |
audit_retention_per_account | 1000 | 每个账号保留的最新审计条数 |
timezone | local | 查询兜底时区;写入永远按 UTC,读端再按你的时区分桶 |
查询入口:Console 通过 4 个 BFF 接口读取审计数据,仅ROOT/ADMIN角色可访问:
GET /api/v1/console/dashboard/summary # 首屏:上下文数据量 + 今日 Token + 今日检索 GET /api/v1/console/tokens # Token 趋势(按日期范围) GET /api/v1/console/context-commits # 上下文提交热力图 GET /api/v1/console/audit # 请求审计分页查询(支持状态码/api_type 筛选)本地快速验证:先发起一次检索请求触发数据,再查 Dashboard 汇总——
curl -X POST "http://127.0.0.1:1933/api/v1/search/find" \ -H "Authorization: Bearer $OPENVIKING_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"hello","limit":3}' curl "http://127.0.0.1:1933/api/v1/console/dashboard/summary" \ -H "Authorization: Bearer $OPENVIKING_API_KEY"查询服务时区解析逻辑见 api_service.py,表结构定义见 schema.py。
常见问题速查 🛠️
Q:Console 返回enabled=false?检查server.observability.usage_audit.enabled是否为false,或启动日志中是否出现Usage/Audit store initialized with sqlite backend。
Q:Dashboard 今天没有 Token?Token 只有触发vlm.call/embedding.call事件才会计入。记住数据按 UTC 写入,若请求没传timezone参数,会回退到 server 配置的兜底时区。
Q:请求日志里为什么没有 Console 自己的请求?预期行为。/api/v1/console/*被排除在审计之外,防止 Console 页面刷新"刷爆"审计表。
Q:生产环境多实例怎么部署?当前仅 SQLite backend,适合单机。多实例场景应实现UsageAuditStore协议换成共享存储,而不是让各实例各写本地库。
写在最后 ✨
OpenViking 使用量审计用最小的架构成本(一条进程内事件总线 + 一个后台批量 Worker),把"Agent 用了多少上下文"这件大事变得开箱即用:
- 📈零侵入:复用现有 observability 事件,业务代码零改动;
- ⚡零延迟代价:非阻塞投递 + 批量写库,统计永不拖慢 API;
- 🕐时区友好:UTC 写入、读端分桶,全球团队看同一份数据;
- 🔒有分寸的审计:脱敏 + 排除自身请求,记录行为但不泄露隐私。
完整设计说明见官方文档 Usage/Audit 使用说明,相关测试覆盖在 tests/observability/ 目录下,欢迎对照源码深入了解。
【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考