从 AxonHub 到 thinrelay

举报
哦啦啦啦啦 发表于 2026/09/07 16:16:24 2026/09/07
【摘要】 起因用 codex CLI、OpenRouter 这些工具时,每个都要直连不同的上游 API,密钥散落在各台 VPS 上。之前用 AxonHub 做统一网关,但它太重了——用户管理、模型映射、请求追踪,一堆我用不到的东西。我只需要一个东西:把请求转发到正确的上游,别丢流式数据。于是决定自己写一个。叫 thinrelay,取 “thin proxy” 之意。 定位先想清楚不做什么,比想做什么...

起因

用 codex CLI、OpenRouter 这些工具时,每个都要直连不同的上游 API,密钥散落在各台 VPS 上。之前用 AxonHub 做统一网关,但它太重了——用户管理、模型映射、请求追踪,一堆我用不到的东西。我只需要一个东西:把请求转发到正确的上游,别丢流式数据

于是决定自己写一个。叫 thinrelay,取 “thin proxy” 之意。

定位

先想清楚不做什么,比想做什么更重要:

  • 不做用户管理 — 个人网关,不是 SaaS
  • 不做 model mapping — 请求里写什么 model 就转发什么
  • 不做请求日志/追踪 — 不存任何数据,不写数据库
  • 不做 Web UI — 配置文件改完 reload 就行

要做的事就一件:统一入口,转发 API 请求,保留 SSE streaming

技术选型

Go。原因很简单:

  1. 编译成单二进制,扔到 VPS 上就能跑,没有 runtime 依赖
  2. net/http/httputil 自带反向代理,原生支持 SSE flush
  3. 我熟悉

依赖尽量少:yaml.v3(配置)、x/time/rate(限速)、utls(TLS 指纹伪装,后面说)。

开发过程

1. 骨架:config + HTTP server

先搭框架。YAML 配置文件定义网关的 listen address、API key、各上游的配置。HTTP server 用标准库 net/http,加一层 API key 校验中间件,加一个 /healthz 健康检查。

这部分没什么特别的,标准的 Go web server 模式。

2. Codex passthrough

Codex CLI 把 OAuth token 存在 ~/.codex/auth.json 里,明文 JSON。转发逻辑很简单:读 token → 构造请求 → 转发到 api.openai.com → 逐 chunk flush 回客户端。

func codexHandler(w http.ResponseWriter, r *http.Request) {
    // 读 ~/.codex/auth.json 拿 token
    // 构造转发请求,把 Authorization header 设上
    // httputil.ReverseProxy 转发,FlushInterval 设成 -1 立即 flush
}

关键细节:ReverseProxy.FlushInterval = -1 让 SSE 数据逐 chunk 立即 flush,不缓冲。如果忘了这个,流式响应会卡住,客户端等半天一次性收到所有数据。

3. OpenRouter passthrough

更简单。OpenRouter 用 API key 认证,配置文件里填上就行。转发逻辑和 Codex 一样,只是 token 来源不同。

5. 限速中间件

golang.org/x/time/rate 做令牌桶限速。默认 20 RPM,模拟正常单用户的请求频率。防止请求太快被 Google 检测到异常。

6. 统一路由

最后把三个 provider 的 handler 接到一起:

/v1/chat/completions  →  model
/codex/v1/*           →  Codex 直通
/openrouter/v1/*      →  OpenRouter 直通
/healthz              →  健康检查

统一入口 /v1/chat/completions 按 model 字段自动分流:model 名以 gemini 开头的走 AGY,其他的走 Codex。这样 CLI 工具只需要配一个 base URL,不用关心后端是哪个 provider。

编译

go build -o thinrelay .,12MB 单二进制。没有 Docker,没有数据库,没有外部依赖。

最终代码结构

thinrelay/
├── main.go           # 入口,HTTP server + 路由
├── config.go         # YAML 配置加载
├── codex.go          # Codex passthrough
├── openrouter.go     # OpenRouter passthrough
├── format.go         # OpenAI ↔ Gemini 格式转换
├── middleware.go     # API key 校验 + 限速
├── stream.go         # SSE streaming 支持
├── go.mod
└── config.example.yaml

约 1100 行 Go 代码。

部署

  1. 网关 VPS 上装 agy 并登录 → token 存进 keyring
  2. 网关 VPS 上装 codex 并登录 → token 存进 ~/.codex/auth.json
  3. cp config.example.yaml config.yaml,改 api_key 和 openrouter key
  4. ./thinrelay -config config.yaml
  5. 业务 VPS 上配 OPENAI_BASE_URL 指向网关

总结

一天写完,1100 行代码,12MB 二进制。做的事情很简单:统一入口、转发请求、保留流式。不做的事情很明确:不存数据、不做多用户、不做 Web UI。

thinrelay 不会成为开源项目,但作为个人工具,它刚好够用。AxonHub 能做的事它做不了,但 AxonHub 做的 90% 我都不需要。剩下的 10%,thinrelay 做到了。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。