# goaiapi — 插件化 AI API 中继 一个**一切皆插件**的 AI API 流量中继。内核只是加载器:负责启动插件、版本管理、依赖解析、插件互调与动态加载/更新。中继的全部业务能力(反向代理转发、用量解析、留存、管理界面)都由独立进程插件实现,经内核 InvocationBroker 用 gRPC 互相调用。 ## 设计要点 - **进程隔离插件**:每个插件是独立二进制,经 [hashicorp/go-plugin](https://github.com/hashicorp/go-plugin) 用 gRPC 与内核通信。插件崩溃不会拖垮内核。 - **内核中转互调**:插件之间从不直连。A 调 B 时,A → 内核 Broker → B,请求/响应是 proto-wire 字节,内核不感知任何插件的具体类型。 - **三层插件**(由内核依据依赖图复算校验,不信插件自报): - **base**:无插件依赖(如 `echo-base`、`recorder-base`、`usage-base`) - **mid**:仅依赖 base(如 `transform-mid`、`dashboard`) - **complex**:依赖至少一个非 base(如 `proxy`、`streaming-demo`) - **版本管理**:依赖用 semver 约束声明,内核加载时校验已注册版本是否满足,并支持热升级(原子换 + 旧进程延迟排空)。 - **流量路径**:外部 HTTP(默认 `:8080`)→ 内核 → Broker → `proxy` 插件 → 上游;`proxy` 再经 Broker 调 `usage-base` 解析、`recorder-base` 留存。 ## 目录结构 | 目录 | 说明 | |---|---| | `proto/` | **语言中立的 API 契约源**(`contract.proto`)。其它语言从此生成客户端 | | `src/` | 全部源码(见 `src/go/`) | | `scripts/` | 构建与代码生成脚本(`build.ps1`、`genproto.ps1`) | | `build/` | 编译产物(`relay.exe` + `plugins/`)与运行数据。**不入库** | | `tools/` | 预留的本地工具目录(当前为空) | 每个一级子目录另有自己的 README。跨语言接入本系统,先看 `proto/README.md`。 ## 快速开始 构建(生成 proto、编译内核与全部插件): ```powershell .\scripts\build.ps1 ``` 运行(内核默认监听 `:8080` 收流量、`:8082` 控制端口,自动加载 `build/plugins/` 下的插件): ```powershell .\build\relay.exe -u https://your-upstream.example.com ``` 内核入口的命令行参数(见 `src/go/cmd/relay/main.go`): | 参数 | 默认 | 说明 | |---|---|---| | `-l` | `127.0.0.1:8080` | 外部流量监听地址 | | `-pd` | `build/plugins` | 插件目录(扫描 `*.exe` 自动加载;空字符串则不自动加载) | | `-pa` | `127.0.0.1:0` | 内核 Broker gRPC 地址(`:0` = 随机端口) | | `-ca` | `127.0.0.1:8082` | 插件管理控制端口(空字符串关闭) | | `-proxy` | `proxy` | 处理外部流量的代理插件名 | | `-drain` | `5000` | 热升级时旧插件进程排空等待毫秒数 | > 上游地址(`-u`)等参数由 `proxy` 插件接收。 ## 控制端口 API(默认 `:8082`) | 方法 | 路径 | 说明 | |---|---|---| | GET | `/api/plugins` | 列出已加载插件 | | GET | `/api/plugins/{name}` | 单个插件详情 | | POST | `/api/plugins/load` | `{"binary_path"}` 加载注册 | | POST | `/api/plugins/unload` | `{"name"}` 卸载(被依赖则拒绝) | | POST | `/api/plugins/upgrade` | `{"name","binary_path"}` 热升级 | ## 工具链 构建依赖外部工具链(不在 PATH 上时脚本内已硬编码路径,按本机实际调整): - Go 1.26.3 - protoc + `protoc-gen-go` / `protoc-gen-go-grpc`(仅在改 `contract.proto` 时需要;生成代码已入库) ## 主要依赖 `github.com/hashicorp/go-plugin`(插件进程框架)、`google.golang.org/grpc`(互调传输)、`github.com/Masterminds/semver/v3`(版本约束)、`modernc.org/sqlite`(留存索引,纯 Go 无需 CGO)。