A proxy-based tool for tracing, recording, and replaying LLM API requests.
6.2K
中文说明 | English
llm-tracelab 是一个本地优先的 LLM HTTP 录制与回放代理。它当前覆盖 OpenAI-compatible、Anthropic Messages、Google GenAI 和 Vertex-native 这几类主流协议面。核心目标很直接:
项目定位接近 http record/replay,但针对 LLM 场景补了流式响应、Token usage、可视化查看和故障注入能力。
这次重构后的版本重点有四个:
pkg/llm 升级为按 provider/endpoint 工作的 adapter 层,统一处理 request、response、stream transcript 和 usage pipelinetrace_id,不再在 URL 中暴露本地路径LLM_PROXY_V3 的 # event: 现在不仅有 request/response 基础事件,还会落 llm.* provider timeline.http cassettepkg/replay.Transport 在测试中直接回放cmd/server 服务入口
internal/proxy 代理转发、stream 注入、响应拦截
internal/recorder .http 录制与落盘
internal/store SQLite 元数据索引
internal/monitor Monitor UI 与详情解析
pkg/recordfile 录制文件格式 V2/V3 解析与 V3 写入
pkg/replay 单元测试回放 Transport
pkg/llm 多厂商请求/响应归一化
更适合 AI 阅读的项目约定见 AGENTS.md,架构摘要见 docs/ARCHITECTURE.md,上游兼容矩阵见 docs/UPSTREAM_PROVIDERS.md,项目路线图见 docs/ROADMAP.md,Vertex 协议族设计说明见 docs/VERTEX_NATIVE_PLAN.md。
当前写入格式是 LLM_PROXY_V3:
# event: 会记录统一 timeline,例如 llm.output_text.delta、llm.reasoning.delta、llm.tool_call、llm.usagetrace_index.sqlite3默认存储布局:
logs/
trace_index.sqlite3
<upstream-host>/<model>/<yyyy>/<mm>/<dd>/*.http
server:
port: "8080"
monitor:
port: "8081"
upstream:
base_url: "https://api.openai.com/v1"
api_key: "sk-xxx"
provider_preset: "openai" # 推荐优先填写 preset
protocol_family: "" # 可留空自动推断;与 provider_preset 冲突会在启动时报错
routing_profile: "" # 可留空自动推断;不支持的 preset/profile 组合会 fail fast
api_version: "" # Azure 用 query 参数;Anthropic 用 anthropic-version header
deployment: "" # Azure deployment routing 时使用
project: "" # Vertex project/location routing 时使用
location: "" # Vertex regional host / path routing 时使用
model_resource: "" # Vertex model 资源,例如 publishers/google/models/gemini-2.5-flash
headers: {} # 额外上游请求头,比如 anthropic-beta
debug:
output_dir: "./logs"
mask_key: false
如果你不想从零开始写配置,直接参考这些现成样例:
支持的环境变量覆盖:
LLM_TRACELAB_SERVER_PORTLLM_TRACELAB_MONITOR_PORTLLM_TRACELAB_UPSTREAM_BASE_URLLLM_TRACELAB_UPSTREAM_API_KEYLLM_TRACELAB_UPSTREAM_PROVIDER_PRESETLLM_TRACELAB_UPSTREAM_PROTOCOL_FAMILYLLM_TRACELAB_UPSTREAM_ROUTING_PROFILELLM_TRACELAB_UPSTREAM_API_VERSIONLLM_TRACELAB_UPSTREAM_DEPLOYMENTLLM_TRACELAB_UPSTREAM_PROJECTLLM_TRACELAB_UPSTREAM_LOCATIONLLM_TRACELAB_UPSTREAM_MODEL_RESOURCELLM_TRACELAB_OUTPUT_DIRLLM_TRACELAB_MASK_KEY推荐的兼容配置思路:
provider_preset 和 base_url,并确保 base_url 已包含上游 API 前缀,例如 /v1、/api/v1、/openai、/openai/v1/openai/v1/...:设置 provider_preset: azure,可选 api_versionprovider_preset: azure,并补 deploymentprovider_preset: vllmprovider_preset: anthropic,如需 beta 能力可在 headers 里补 anthropic-betaprovider_preset: google_genai,当前支持 generateContent 和 streamGenerateContent 基础闭环provider_preset: vertex;它会根据 base_url 推断 vertex_express 或 vertex_project_location支持级别说明:
verified:已有行为测试或 cassette 级回归覆盖compatible:按现有协议族抽象应当可工作,但直接验证较少planned:尚未接入 preset 或尚未实现配置校验规则:
provider_preset、protocol_family、routing_profile 不再是松散字段provider_preset: anthropic 搭配 protocol_family: google_genai 会直接失败provider_preset: openrouter 搭配 routing_profile: azure_openai_v1 也会直接失败当前推荐支持矩阵:
provider_preset: openai
support: verified
protocol_family: openai_compatible
routing_profile: openai_defaultprovider_preset: openrouter | fireworks | together | deepseek | groq | moonshot | cerebras | perplexity
support: openrouter/fireworks/together/groq=verified; deepseek/moonshot/cerebras/perplexity=compatible
protocol_family: openai_compatible
routing_profile: openai_defaultprovider_preset: azure
support: verified
protocol_family: openai_compatible
routing_profile: azure_openai_v1 或 azure_openai_deploymentprovider_preset: vllm
support: verified
protocol_family: openai_compatible
routing_profile: vllm_openaiprovider_preset: anthropic
support: verified
protocol_family: anthropic_messages
routing_profile: anthropic_defaultprovider_preset: google_genai | google | gemini
support: verified
protocol_family: google_genai
routing_profile: google_ai_studioprovider_preset: vertex
support: verified
protocol_family: vertex_native
routing_profile: vertex_express | vertex_project_location
notes: 受控 preset;已覆盖 adapter / proxy / cassette regressionAnthropic 示例:
upstream:
base_url: "https://api.anthropic.com"
api_key: "sk-ant-xxx"
provider_preset: "anthropic"
api_version: "2023-06-01"
headers:
anthropic-beta: "tools-2024-04-04"
Google GenAI 示例:
upstream:
base_url: "https://generativelanguage.googleapis.com"
api_key: "AIza..."
provider_preset: "google_genai"
Vertex express 示例:
upstream:
base_url: "https://aiplatform.googleapis.com"
api_key: "ya29..."
provider_preset: "vertex"
model_resource: "publishers/google/models/gemini-2.5-flash"
Vertex project/location 示例:
upstream:
base_url: "https://us-central1-aiplatform.googleapis.com"
api_key: "ya29..."
provider_preset: "vertex"
project: "demo-project"
location: "us-central1"
model_resource: "publishers/google/models/gemini-2.5-flash"
如果你想完全避免 preset,也仍然可以继续显式填写:
protocol_family: vertex_nativerouting_profile: vertex_express | vertex_project_locationAzure deployment 示例:
upstream:
base_url: "https://demo-resource.openai.azure.com"
api_key: "azure-key"
provider_preset: "azure"
deployment: "gpt-4o-mini"
api_version: "2025-03-01-preview"
推荐使用 go-task:
task build
task run
task migrate
如果只想直接运行:
go run ./cmd/server -c config/config.yaml
把你的 SDK base_url 指向 http://localhost:8080/v1 后,请求就会被代理并录制。
访问 http://localhost:8081。
详情页现在包含三个主视图:
Timeline:消费 cassette 中的统一 llm.* 事件Summary:按对话、工具、输出块聚合展示Raw Protocol:左右分栏查看原始 request/response显式迁移命令:
go run ./cmd/server migrate -c config/config.yaml
这个命令默认会做两件事:
LLM_PROXY_V2 .http 文件原地改写成 LLM_PROXY_V3trace_index.sqlite3如果只想做其中一部分:
go run ./cmd/server migrate -c config/config.yaml -rewrite-v2=false
go run ./cmd/server migrate -c config/config.yaml -rebuild-index=false
适合老日志目录批量升级,或者 SQLite 索引损坏/丢失后的全量恢复。
容器内约定的标准路径:
/app/bin/llm-tracelab/app/config/config.yaml/app/data/traces/app/data/traces/trace_index.sqlite3默认提供:
启动方式:
export LLM_TRACELAB_UPSTREAM_API_KEY=sk-xxx
docker compose up --build
如果只想直接使用已经发布到 Docker Hub 的镜像,可以不克隆仓库,直接运行:
docker run --rm \
-p 8080:8080 \
-p 8081:8081 \
-e LLM_TRACELAB_UPSTREAM_BASE_URL=https://api.openai.com/v1 \
-e LLM_TRACELAB_UPSTREAM_API_KEY=sk-xxx \
-e LLM_TRACELAB_OUTPUT_DIR=/app/data/traces \
-e LLM_TRACELAB_SERVER_PORT=8080 \
-e LLM_TRACELAB_MONITOR_PORT=8081 \
-v "$(pwd)/docker-data:/app/data" \
kingfs/llm-tracelab:latest serve -c /app/config/config.yaml
如果你更习惯 docker compose,也可以直接引用 Docker Hub 镜像:
services:
llm-tracelab:
image: kingfs/llm-tracelab:latest
ports:
- "8080:8080"
- "8081:8081"
environment:
LLM_TRACELAB_UPSTREAM_BASE_URL: https://api.openai.com/v1
LLM_TRACELAB_UPSTREAM_API_KEY: ${LLM_TRACELAB_UPSTREAM_API_KEY}
LLM_TRACELAB_OUTPUT_DIR: /app/data/traces
LLM_TRACELAB_SERVER_PORT: "8080"
LLM_TRACELAB_MONITOR_PORT: "8081"
volumes:
- ./config/config.docker.yaml:/app/config/config.yaml:ro
- ./docker-data:/app/data
command: ["serve", "-c", "/app/config/config.yaml"]
如果本机访问 Go 官方模块代理较慢,可以在构建时直接传入 GOPROXY:
GOPROXY=https://goproxy.cn,direct docker compose build
默认挂载:
./config/config.docker.yaml -> /app/config/config.yaml:ro./docker-data -> /app/data运行镜像默认使用 root 用户启动。这是为了兼容最常见的 bind mount 场景,避免宿主机目录属主与容器内固定 UID/GID 不一致时出现 permission denied,例如无法创建 /app/data/traces。
如果在容器外部配置,优先通过挂载配置文件和环境变量覆盖 upstream、端口、输出目录;debug.output_dir 建议始终指向容器内挂载卷中的固定路径。
task fmt
task lint
task test
task build
task run
task migrate
task check
task docker:build
task docker:up
func TestChat(t *testing.T) {
tr := replay.NewTransport("testdata/chat.http")
cfg := openai.DefaultConfig("fake-key")
cfg.BaseURL = "http://localhost/v1"
cfg.HTTPClient = &http.Client{Transport: tr}
client := openai.NewClientWithConfig(cfg)
resp, err := client.CreateChatCompletion(context.Background(), req)
_ = resp
_ = err
}
.http cassette 是回放的事实来源pkg/llm



Content type
Image
Digest
sha256:58af90df2…
Size
17.7 MB
Last updated
6 days ago
docker pull kingfs/llm-tracelab