llmproxy 系统开发目的和基本功能

llmproxy 系列文章第一篇。这篇聊聊我为什么做这个项目、需求从哪里来、系统大致做什么、用了哪些技术。系统设计细节与开发过程,留给后续文章展开。

项目已开源(Gitee):https://gitee.com/bingersoft/llmproxy

一、为什么做一个 LLM 代理

做实际企业 AI 应用的过程中,我反复撞上同一堵墙:我会调 LLM API,但不了解中间发生了什么。

比如一个请求发往模型服务:

  • 它实际走的是什么线格式?不同厂商的协议差异到底在哪?
  • 流式输出是怎么切块推送的?首 Token 延迟(TTFT)怎么算?
  • usage 统计是怎么上报的?缓存命中的 Token 和正常输入有什么区别?
  • 上游出错时错误码语义是什么?哪些可以重试、哪些不行?

靠厂商 SDK 和官方文档,你只能看到"输入"和"输出",中间的技术细节全被封装掉了。而企业 AI 应用做得越多越发现:对大模型基本知识和技术细节不了解,就很难真正做好企业 AI 应用------成本算不清、高可用设计不好、安全和合规也做不实。

所以我想了一个最直白的办法:自己动手做一个 LLM 代理系统,让所有 LLM 交互数据都经过它,借由这个系统观察每一次请求、响应和中间过程。边做边学,让这个系统本身成为我研究 LLM 交互的"教具"。

这就是 llmproxy 的由来。这个项目的初衷从"学习"出发:产品是载体,真正目的是搞懂 LLM 交互这件事。

二、需求来源

项目最早源于一个很实际的需求:内网有几套自部署模型服务(Ollama、vLLM),地址、模型名、鉴权方式各不相同,业务系统每接一个都要改代码,于是先写了一个简单的"模型聚合器"。

随着系统演进,需求来源逐渐清晰:

  1. 最早调研了 LiteLLM。 这是一个把上百个模型提供方统一成一套接口的成熟项目,我从它借鉴最多的是协议适配器设计:llmproxy 的适配器接口即借鉴 LiteLLM 的 BaseConfig 抽象------请求/响应双向翻译、usage 提取、流式处理、参数能力声明。
  2. 之后参考了 1Panel 的 AI 网关。 2026-10 1Panel 把 AI 网关向社区免费开放(≤10 人团队),我做了逐项功能对比调研(统一接入、身份权限、并发配额、智能路由、内容合规、调用日志、用量统计等),作为功能路线图的输入。
  3. 将来还会对标 OneAPI、NewAPI 等常见 LLM 网关,继续做竞品分析,挑选适合的功能来实现。

挑选原则始终一致:主打学习。功能优先选有技术含量、能加深对 LLM 调用链理解、且规模适合自己动手实现的,不追求功能大而全。

三、系统定位

llmproxy 的定位一句话就能说清:它是一个 LLM 网关(LLM Proxy)。

用四个词概括:收敛、统一、可见、可控------把 N 家模型厂商(含自部署后端)的异构 API 收敛为统一的 OpenAI 线协议,让平台方对这条链路拥有计量、管控与降级能力。

同样重要的是它不做什么:

  • 不做运维内容:不管服务器/容器/GPU 生命周期,不部署本地模型(Ollama、vLLM 对它只是"上游服务");
  • 不做 Agent:没有智能体编排平台;
  • 不做 MCP Server:不托管、不管理 MCP 服务。

它是网关,就立足网关的本质工作:协议翻译、路由调度、访问控制、指标度量、计费与审计。

四、系统功能简介

按"层"梳理一下系统大致做什么:

复制代码
客户端(OpenAI / Anthropic / Responses SDK,仅改 base_url)
        │  Bearer sk-proxy-...
        ▼
┌───────────────────── llmproxy(单进程 :3002)─────────────────────┐
│  统一接入 → 鉴权授权 → 路由调度(重试/降级)→ 上游调用 → 计费/指标/审计  │
│                                                                   │
│  Web 管理台(Vue3)    指标(Prometheus /metrics)    请求审计归档    │
└───────────────────────────────────────────────────────────────────┘
        │  协议翻译:OpenAI 兼容 / Anthropic / Gemini / openai_responses
        ▼
 各厂商(OpenAI / Anthropic / Gemini / 通义 / DeepSeek / ...)
 + 自部署后端(vLLM / Ollama / llama.cpp 等)

4.1 统一接入(客户端面)

客户端只面向 OpenAI 线协议。拿到网关签发的 API Key 后,把 OpenAI SDK 的 base_url 改一行,就能调用所有已注册模型:

端点 说明
POST /v1/chat/completions 文本对话:非流式 + SSE 真流式 + 伪流式,全链路 tool-call 与图片输入
GET /v1/models 模型发现:能力旗标、上下文窗口等元数据
POST /v1/messages Anthropic 客户端协议入口,Anthropic SDK 原样直调
POST /v1/responses OpenAI Responses 客户端协议入口
POST /v1/embeddings 向量(embedding)接口
POST /v1/images/generations 文生图接口(异步上游由网关内部转成同步语义)

"仅改 base_url 即可切换"是硬约束:三种客户端协议都满足这一点,网关本地错误(400/402/403/404/429)也按对应客户端协议的线格式返回。

4.2 多厂商协议适配(上游面)

网关内置 26 条厂商目录,覆盖 OpenAI、Anthropic、Gemini、通义、DeepSeek、豆包、Kimi、GLM、MiniMax、混元、百度等在线厂商,以及 vLLM、Ollama、llama.cpp 等自部署后端。协议适配器负责双向翻译:

  • OpenAICompatAdapter:参数化设计,覆盖 14+ 家 OpenAI 兼容厂商,鉴权样式 4 种(bearer / x-api-key / x-goog-key / none);
  • AnthropicAdapter:Messages API 双向翻译(text、tool_use、流式事件序列、usage);
  • GeminiAdapter:generateContent 双向翻译;
  • openai_responses:Responses 原生端点上游适配器。

网关内部以 OpenAI chat 表示为规范形态,客户端协议 × 上游协议相互正交;新增协议只需继承一个适配器基类并在目录登记。

4.3 注册表与热配置

  • SQLite 是唯一真源,进程内保持只读快照;
  • 管理端任何写操作后快照原子替换:改配置不重启,进行中的请求不受影响,新请求立即用新配置;
  • 首次启动可用 bootstrap.yaml 引导导入(API Key 用环境变量占位符展开,不落明文)。

4.4 高可用机制

  • 重试 :可重试错误(429/5xx/超时)指数退避,尊重上游 Retry-After;
  • 降级链:模型级有序 fallback 候选,首选故障自动切备用;
  • 健康探测:周期轮询各上游模型列表,健康状态写入管理台与 Prometheus。

4.5 多租户与授权

权限体系分三层:用户组(Group)→ 用户(User)→ API Key(Key),属性按 Key → User → Group → 网关默认的固定顺序继承:

  • 客户端 Key 形如 sk-proxy-*,数据库只存 SHA-256 哈希,明文仅创建时展示一次;
  • 管理端分 admin / user 两种角色;user 只能看到本组数据(服务端强制数据范围);
  • 模型组:成员模型集合 + 每个模型的有序上游服务候选,是授权与路由调度的单位;
  • 请求时授权:按继承链解析模型访问白名单,越权请求直接 403,不产生上游调用、不扣费。

4.6 指标与可观测

  • 逐请求明细:五种 token 数(输入/输出/总计/缓存命中/缓存写入)、TTFT、总延迟、吞吐、成本、归一化错误码、重试次数;
  • 三级存储:请求明细 → 小时/日 rollup 聚合(指针式补算,进程重启不丢桶)→ 内存实时窗口(QPS、活跃流、token 速率);
  • Prometheus :/metrics 暴露请求计数、延迟/TTFT 直方图、成本累计、服务可用性等;
  • 请求审计:脱敏摘要审计 + 可选的单一客户端全量请求/响应磁盘归档(含图片抽取、保留期清理)。

4.7 预算管控与 Token 计费售卖

  • 客户端预算:日成本/月 Token 上限,超限 429 拒绝;
  • 计费售卖闭环 (按百万 Token 计价):
    • 定价表:输入/输出/缓存读单价 + 图像每张单价,版本化生效,历史计量不受改价影响;
    • 余额台账:组级充值/冲正/对账,流水 append-only,任意时刻可对账恒等;
    • 计量扣减:请求完成即生成幂等计量事件并发行扣减(并发压测零重复扣减);
    • 授信:可开启透支额度,余额可负但不超额度;
    • 账单:按模型/客户端协议聚合,CSV 导出;user 角色在「我的」页可见本组余额与账单摘要。
  • 组织维度:组级成本/收入/毛利三列统计,支持导出。

4.8 Web 管理台

Vue3 SPA,由后端直接托管(单进程单端口)。主要页面:登录、仪表盘(总览/流量/token/成本/模型排行/延迟/错误分布)、服务管理(CRUD + 连接测试)、模型管理(含降级链)、客户端与用户管理、用户组、定价表、账单、流量统计(按用户-客户端日用量)、请求审计、全量审计、管理操作日志、设置(十余项运行期参数热更新)、「我的」页;支持黑夜模式与菜单收起。

4.9 规划中的能力(Roadmap)

  • 多层并发控制 + 等待队列 :全局/组/Key/上游服务四级并发上限,超限请求 FIFO 排队,超时 429 + Retry-After;
  • 会话亲和:同一 Key 的连续请求在 TTL 内钉住同一上游,提升 prefix cache 命中率;
  • 智能路由 :model=auto 入口,分类器把简单/复杂请求分流到不同模型组(简单请求走便宜模型降本),每次路由决策全量可审计;
  • 调用前内容合规:组级敏感词库 + 可选语义检查,命中即 400 不出网,拦截事件全量审计。

五、技术栈:刻意保持简单

技术选型非常"克制",就两条原则:零运维、看得懂。

后端(Python 3.10+):

组件 用途
FastAPI + uvicorn 单进程服务:网关 API + 管理 API + 前端静态托管
httpx 全局共享异步 HTTP 客户端(连接池)访问所有上游
SQLite(标准库 sqlite3) 唯一存储:WAL 模式、单连接 + 线程锁、无 ORM
PyJWT 管理端 JWT 鉴权
prometheus-client /metrics 指标暴露
pydantic / pydantic-settings / PyYAML 数据校验、启动配置与引导文件

前端 (web/,构建产物由 FastAPI 直接托管):

组件 用途
Vue 3 + TypeScript 管理台 SPA
Vite 构建工具
Element Plus UI 组件库
ECharts 仪表盘图表
Pinia + vue-router 状态管理与路由
axios 管理端 API 封装

测试:pytest + pytest-asyncio,含 OpenAI SDK 真实直连集成测试、协议双向翻译 fixture 测试、多协议端到端测试。

部署形态 :单进程单端口(默认 3002),uvicorn main:app 即起。这种简单是刻意的------系统的重点是观察 LLM 交互细节,网关自身的部署与维护成本应压到最低,不干扰学习。

六、开发工具与环境

开发环境全部在 Windows 上,工作方式以"AI CLI 为主力":

  • omp:主力编码工具,承担需求分析、系统设计与系统开发;
  • Claude Code:负责调研(竞品分析、资料检索)与博客文章撰写;
  • BMAD Method / OpenSpec:两套规格驱动开发技能------前者产出 PRD、架构与故事清单,后者管理需求变更(提案 → 规格 → 任务清单),保证"先收敛需求、再动手实现";
  • herdr:在 Windows 上管理 omp / Claude Code 等多个 AI CLI 会话的工具;
  • VS Code:阅读代码与文档。

这种"多 CLI 协作 + 规格驱动"的开发过程,后续文章会专门展开。

写在后面

这个项目主打学习,开发过程本身就是内容。后续文章会展开:

  • 开发过程:规格驱动开发(BMAD / OpenSpec 工作流)是怎么跑起来的;
  • 协议适配器深入:Anthropic / Gemini / Responses 线格式双向翻译的实现细节;
  • 计费体系:计量扣减的幂等性、余额对账恒等式如何保证;
  • 指标体系:三级存储的设计取舍。
相关推荐
武子康2 小时前
CUDA OOM 不只是“显存不够”
人工智能·后端·agent
陈嘿萌2 小时前
Fusion Anything Model:面向通用多模态融合的基座模型
图像处理·人工智能·深度学习·计算机视觉·学术研究与理论基础
卷无止境2 小时前
ARM与x86、x64的能效之争:指令集只是故事的开头
后端·python
康实训3 小时前
高职院校智慧体适能实训室建设
人工智能·实训室·实训室建设
2601_962885723 小时前
如何用 Python 计算溃疡指数(Ulcer Index)?
开发语言·python
老鱼说AI3 小时前
SNN脉冲神经网络:全连接、卷积与循环SNN
人工智能·深度学习·神经网络·机器学习·自然语言处理
benchmark_cc3 小时前
如何为 QuantDash Python SDK 编写一个最小化的连接验证脚本?
python·数据分析·pandas·量化交易·股票数据·quantdash
code2cat3 小时前
【随笔】RAG检索缓存:复用证据之前,先把权限和版本放进缓存键
java·人工智能·缓存·知识库·rag
武天旭3 小时前
AI安全--AI大模型的数据投毒攻击污染
人工智能·安全