基于 OpenResty + Lua 实现的 OpenAI 兼容 API 反向代理,通过大模型返回的usage信息记录每次请求的 Token 使用量。
- 透明代理:完全兼容 OpenAI API 格式,对客户端无感知
- 自动注入:为流式请求自动注入
stream_options.include_usage=true,确保能获取 Token 统计 - 双模式支持:同时支持流式(SSE)和非流式响应的 Token 解析
- 按 Key 记录:自动提取 API Key,按用户维度记录使用量
- CSV 日志:Token 使用数据以 CSV 格式存储,便于后续分析和统计
.
├── llm_token.conf # Nginx 配置文件
└── lua/
├── access.lua # 请求处理:提取 Key、注入 stream_options
├── body_filter.lua # 响应处理:解析 usage 信息
└── log.lua # 日志记录:写入 CSV 文件
┌──────────┐ ┌─────────────────────────────────────────┐ ┌──────────┐
│ Client │───▶│ OpenResty │───▶│ LLM API │
└──────────┘ │ ┌─────────┐ ┌────────────┐ ┌───────┐ │ └──────────┘
│ │ access │ │body_filter │ │ log │ │
│ │ 提取Key │ │ 解析Token │ │记录CSV│ │
│ │注入选项 │ │ │ │ │ │
│ └─────────┘ └────────────┘ └───────┘ │
└─────────────────────────────────────────┘
- access 阶段:提取请求中的 API Key,检测流式请求并注入
stream_options.include_usage=true - body_filter 阶段:累积完整响应,解析 JSON 或 SSE 格式中的
usage字段 - log 阶段:将时间戳、API Key、prompt_tokens、completion_tokens 写入 CSV 日志
- OpenResty 1.19.x 或更高版本
-
将
lua/目录复制到 OpenResty 安装目录下:cp -r lua/ /usr/local/openresty/nginx/lua/
-
修改
llm_token.conf中的代理目标地址:proxy_pass https://your-llm-api-endpoint/v1/;
-
将配置文件引入 Nginx 主配置:
# 在 nginx.conf 的 http 块中添加 include /path/to/llm_token.conf;
-
重载 Nginx 配置:
openresty -s reload
在 llm_token.conf 中修改日志输出位置:
set $token_log_file "/your/custom/path/token_usage.csv";默认监听 90 端口,可按需修改:
listen 90; # 改为你需要的端口CSV 格式,包含以下字段:
| 字段 | 说明 |
|---|---|
| timestamp | 请求时间 (YYYY-MM-DD HH:MM:SS) |
| api_key | 请求使用的 API Key |
| prompt_tokens | 输入 Token 数量 |
| completion_tokens | 输出 Token 数量 |
示例:
2024-01-15 10:30:45,sk-xxxx,150,89
2024-01-15 10:31:02,sk-yyyy,203,156配置完成后,将客户端的 API 地址指向代理即可:
curl http://localhost:90/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
"model": "deepseek-v3.1",
"messages": [{"role": "user", "content": "Hello!"}],
"stream": true
}'- 仅记录有效请求(prompt_tokens 或 completion_tokens 不为 0)
- 后端 API 需支持
stream_options.include_usage参数(OpenAI API 及 vLLM 等兼容实现均支持) - 确保日志文件路径有写入权限
MIT License