AI 网关实战(二):拆解网关内部模块
这是「AI 网关实战」系列第 2 篇。 上篇我们聊了为什么要搭 AI 网关,这篇深入每个模块,看看网关内部到底是什么样。
目录
- 先回忆一下 7 个模块
- 模块 1:API 网关层 ★★★★★
- 模块 2:认证授权 ★★★★★
- 模块 3:渠道管理 ★★★★★
- 模块 4:合规过滤 ★★★★
- 模块 5:审计日志 ★★★★★
- 模块 6:限流熔断 ★★★★
- 模块 7:流式处理 ★★★★★
- 一个请求的完整流转路径
- 下一步
- 关于源码和开发进度
先回忆一下 7 个模块
AI 网关架构设计参考 OpenAI 网关,结合银行场景的特殊要求,设计了 7 个核心模块:
| 模块 | 重要性 | 做什么 |
|---|---|---|
| API 网关 | ★★★★★ | 统一入口,兼容 OpenAI 格式 |
| 认证授权 | ★★★★★ | JWT 管理端 + API Key 应用端 |
| 渠道管理 | ★★★★★ | 多供应商接入 + 故障转移 |
| 合规过滤 | ★★★★ | 敏感词 + 脱敏 + 风险提示 |
| 审计日志 | ★★★★★ | 每一条请求可追溯 |
| 限流熔断 | ★★★★ | 多层限流 + 熔断降级 |
| 流式处理 | ★★★★★ | SSE 流式返回 |
星级表示在银行场景下的重要性,你可以根据自己的业务需求调整优先级。
下面逐个模块详细讲解设计目标、核心功能和实现要点。
模块 1:API 网关层 ★★★★★
设计目标
客户端只认一套接口(OpenAI 兼容格式),无论底层调用的是 OpenAI、通义千问还是智谱,对客户端来说都是一样的。这样可以屏蔽下游供应商的差异,客户端只需要统一调用网关的接口即可。
核心功能
AI 网关作为统一入口,需要提供以下核心功能:
| 功能 | 说明 | 接口 |
|---|---|---|
| 聊天补全 | 流式/非流式都支持 | POST /api/v1/chat/completions |
| 文本补全 | 简单文本生成 | POST /api/v1/completions |
| 模型列表 | 聚合所有渠道可用模型 | GET /api/v1/models |
| 多渠道路由 | 按优先级 + 权重选择 | 内部逻辑 |
| 失败重试 | 可重试状态码 + 熔断 + 备用渠道 | 内部逻辑 |
关键设计:流式响应处理
这是新手最容易踩坑的地方。
流式请求有个矛盾:入参要全量过滤(好办),出参是分段返回的,怎么合规?
我的方案是:
| 场景 | 策略 |
|---|---|
| 非流式请求 | 请求和响应都做完整敏感词检测 |
| 流式请求(入参) | 全量过滤(入参不是流式,没问题) |
| 流式请求(出参) | 逐 chunk 做快速检测,完整响应异步审计留存 |
为什么出参不全程拦截?
因为流式体验的核心是"即时性",如果你等 AI 把话说完再检测合规,用户会感觉像在看慢动作回放。
所以我的做法是:
- 逐 chunk 做快速检测(只检测高频敏感词)
- 一旦发现违规,立即中断流,返回错误
- 完整响应异步审计,留存证据
模块 2:认证授权 ★★★★★
设计目标
银行场景必须有两套认证体系:
| 端 | 认证方式 | 用途 |
|---|---|---|
| 管理端 | JWT Token | 管理员登录后台,配置渠道、管理 API Key |
| 调用端 | API Key | 业务系统调用 AI 接口 |
核心功能
认证授权模块提供以下核心功能:
| 功能 | 说明 |
|---|---|
| JWT 认证 | 管理端登录获取 Token,有效期 2h |
| API Key 认证 | 前缀定位 + Hash 校验 |
| API Key 管理 | 创建/禁用/删除/轮换 |
| 配额校验 | Key 级别配额检查(请求数 + Token 数) |
| 登录安全 | 密码策略 + 失败锁定 |
关键设计:API Key 只存哈希
创建 API Key 时的流程:
1. 管理员登录 → 获取 JWT Token
2. 用 JWT 调用创建 API Key 接口
3. 生成随机 Key: sk-{8位随机前缀}-{32位随机后缀}
4. 存储: key_prefix = "sk-xxxxxxxx", key_hash = SHA256(完整key)
5. 返回: 完整 Key 明文(仅此一次,不存储明文)
客户端调用时:
1. Header: Authorization: Bearer sk-xxxxxxxx-yyyyyyyyyyyyyyyyyyyyyyyy
2. 系统用 key_prefix("sk-xxxxxxxx") 快速定位数据库记录
3. 对完整 key 做 SHA256,与 key_hash 比对
4. 通过 → 校验配额 → 放行
为什么要用前缀?
如果直接用 SHA256 做索引,每次都要哈希一遍,效率太低。用前缀定位,再哈希校验,速度更快。
密码安全策略
| 项目 | 规范 |
|---|---|
| 哈希算法 | bcrypt,cost factor ≥ 12 |
| 密码长度 | ≥ 8 位 |
| 复杂度 | 必须包含大写 + 小写 + 数字 + 特殊字符 |
| 失败锁定 | 连续 5 次失败,锁定 30 分钟 |
模块 3:渠道管理 ★★★★★
设计目标
支持多家 AI 供应商接入,实现故障转移和负载均衡,避免单点故障。
支持的渠道
AI 网关支持以下 6 家主流 AI 供应商:
| 类型 | 配置项 | 说明 |
|---|---|---|
| OpenAI | base_url, api_key, models, organization | 官方/兼容 API |
| Claude | base_url, api_key, models, anthropic_version | Anthropic |
| 文心 | api_key, secret_key, model_ids | 百度 |
| 通义 | api_key, model_ids | 阿里 |
| 智谱 | api_key, model_ids | 清华 |
| Kimi | api_key, model_ids | 月之暗面 |
核心功能
渠道管理模块的核心功能:
| 功能 | 说明 |
|---|---|
| 渠道配置 | 支持上述 6 家供应商 |
| 渠道状态 | 启用/禁用/熔断状态 |
| 模型映射 | 统一名称 → 渠道模型映射(如 gpt-4 → 各家的不同模型名) |
| 健康检查 | 定时探测渠道可用性 |
| 渠道 API Key 加密 | AES-256-GCM 加密(下篇详细讲) |
关键设计:模型映射
不同供应商对同一能力的模型命名不一样:
OpenAI: gpt-4
文心: ERNIE-Bot-4
通义: qwen-max
业务系统只认统一的 gpt-4,网关内部通过模型映射表转换:
CREATE TABLE model_mappings (
unified_name VARCHAR(64) NOT NULL, -- 统一名称:gpt-4
channel_id BIGINT NOT NULL,
provider_model VARCHAR(64) NOT NULL, -- 渠道内模型名:ERNIE-Bot-4
status SMALLINT NOT NULL DEFAULT 1
);
模块 4:合规过滤 ★★★★
设计目标
银行场景必须防止违规内容通过网关,确保输出内容符合合规要求。
核心功能
合规过滤模块提供以下功能:
| 功能 | 说明 |
|---|---|
| 敏感词过滤 | 入参/出参检测,支持白名单和组合规则 |
| 违规拦截 | 命中 BLOCK 规则直接拒绝 |
| 风险提示 | 自动追加免责声明 |
| 内容脱敏 | 手机号/身份证/银行卡号掩码 |
| 过滤策略扩展点 | 策略模式,预留 LLM 辅助判断扩展 |
关键设计:过滤器链(策略模式)
采用策略模式实现过滤器链,方便扩展:
public interface ContentFilter {
String name();
FilterResult filter(String content, FilterContext context);
int order(); // 执行顺序
}
// MVP 实现
public class RegexFilter implements ContentFilter { ... } // 正则脱敏
public class KeywordFilter implements ContentFilter { ... } // 敏感词检测
public class DisclaimerFilter implements ContentFilter { ... } // 免责声明
过滤执行顺序:
1. RegexFilter (order=10) — 正则脱敏(手机号/身份证/银行卡号掩码)
2. KeywordFilter (order=20) — 敏感词检测(含组合规则)
3. DisclaimerFilter (order=30) — 追加风险提示(仅出参)
敏感词分类
| 分类 | 说明 | 默认动作 |
|---|---|---|
| FRAUD | 诈骗相关 | BLOCK |
| COMPLIANCE | 合规红线 | BLOCK |
| PRIVACY | 隐私信息 | MASK |
| RISK | 风险敏感 | WARN |
| POLITICAL | 政治敏感 | BLOCK |
组合规则示例
规则: "转账" AND "验证码" → BLOCK
含义: 同时出现"转账"和"验证码"时拦截,防止社会工程学攻击
模块 5:审计日志 ★★★★★
设计目标
每一条管理操作、每一条 AI 调用都要可追溯,且不可篡改,满足合规审计要求。
审计范围
审计日志需要记录以下操作:
| 操作类型 | 资源类型 | 说明 |
|---|---|---|
| CREATE / DELETE | API_KEY | Key 的创建和删除 |
| CREATE / UPDATE / DELETE | CHANNEL | 渠道的增删改 |
| UPDATE | CONFIG | 系统配置变更 |
| UPDATE | USER | 用户状态变更 |
| LOGIN / LOGIN_FAIL | SESSION | 登录成功/失败 |
核心功能
审计日志模块的核心功能:
| 功能 | 说明 |
|---|---|
| 操作审计 | 记录所有管理操作(增删改) |
| 变更快照 | 记录操作前后的数据变更 |
| 查询接口 | 支持按操作人/时间/类型查询 |
| 不可篡改 | 审计日志只增不改不删 |
模块 6:限流熔断 ★★★★
设计目标
控制成本,保护服务稳定性,防止恶意调用或意外超支。
核心功能
限流熔断模块的核心功能:
| 功能 | 说明 |
|---|---|
| API Key 级限流 | 令牌桶,每 Key RPM + TPM 双维度 |
| 模型级限流 | 滑动窗口,防止单模型耗尽渠道配额 |
| 全局限流 | 保护网关自身 |
| 渠道熔断 | Resilience4j 熔断器 |
| 重试策略 | 可重试状态码 + 指数退避 |
限流配置示例
rate-limit:
global:
max-rpm: 1000 # 全局每分钟最大请求数
api-key:
algorithm: token-bucket
default-rpm: 60 # 默认每分钟60次
default-tpm: 100000 # 默认每分钟10万token
model:
algorithm: sliding-window
overrides:
gpt-4: { rpm: 10, tpm: 10000 }
gpt-4o: { rpm: 30, tpm: 60000 }
gpt-3.5-turbo: { rpm: 120, tpm: 200000 }
熔断配置
circuit-breaker:
failure-rate-threshold: 50 # 失败率阈值50%
slow-call-rate-threshold: 80 # 慢调用率阈值80%
slow-call-duration-threshold: 10s # 慢调用判定阈值
sliding-window-type: COUNT_BASED # 基于计数的滑动窗口
sliding-window-size: 10 # 窗口大小10次
minimum-number-of-calls: 5 # 最少5次调用后开始计算
wait-duration-in-open-state: 60s # 熔断开启后等待时间
permitted-number-of-calls-in-half-open-state: 3 # 半开状态允许的探测调用数
模块 7:流式处理 ★★★★★
设计目标
AI 对话必须流式,否则体验太差。
核心功能
流式处理模块的核心功能:
| 功能 | 说明 |
|---|---|
| SSE 流式响应 | Spring WebFlux Flux |
| 流式合规处理 | 入参全量过滤 + 出参滑动窗口快速检测 |
| 流式中断 | 检测到违规内容时中断流式输出 |
| 超时控制 | 流式请求整体超时 + 单 chunk 超时 |
一个请求的完整流转路径
上面讲了 7 个模块,现在把它们串起来,看看一个请求从进入到响应,到底经过了什么。
非流式请求(标准场景)
客户端请求
│
▼
[AuthFilter] ── Token/API Key 校验
│
▼
[RateLimitFilter] ── 限流检查(Redis 令牌桶)
│
▼
[ComplianceFilter] ── 入参合规过滤(敏感词 + 脱敏)
│
▼
[RouteService] ── 模型映射 + 渠道路由(优先级 + 权重)
│
▼
[CircuitBreaker] ── 熔断检查(Resilience4j)
│
▼
[ModelAdapter] ── 渠道适配器(OpenAI/Claude/文心/通义/...)
│
▼
[ComplianceFilter] ── 出参合规过滤(敏感词 + 脱敏 + 风险提示)
│
▼
[AuditLogger] ── 记录调用日志 + 审计日志
│
▼
客户端响应
流式请求(SSE)
流式请求的流转路径略有不同,主要差异在于合规处理和审计日志的处理方式:
客户端请求(stream=true)
│
▼
[AuthFilter] ── Token/API Key 校验
│
▼
[RateLimitFilter] ── 限流检查
│
▼
[ComplianceFilter] ── 入参合规过滤(全量)
│
▼
[RouteService] ── 模型映射 + 渠道路由
│
▼
[CircuitBreaker] ── 熔断检查
│
▼
[ModelAdapter] ── 渠道适配器(返回 Flux<ServerSentEvent>)
│
▼
[StreamComplianceFilter] ── 逐 chunk 快速检测
│ ├─ 发现违规 → 立即中断流 → 返回错误
│ └─ 无违规 → 继续
│
▼
[DisclaimerFilter] ── 追加风险提示(最后一个 chunk)
│
▼
[AuditLogger] ── 异步审计(完整响应留存)
│
▼
客户端流式接收
故障转移流程
当某个渠道出现故障时,系统会自动切换到备用渠道:
请求 → 渠道A
│
├─ 成功 → 返回
│
└─ 失败(可重试) → 重试渠道A(最多2次)
│
├─ 成功 → 返回
│
└─ 仍失败 → 记录渠道A失败 → 选择渠道B(同优先级次选或低优先级)
│
├─ 成功 → 返回
│
└─ 仍失败 → 返回错误(无可用渠道)
下一步
这篇讲了 7 个模块的设计细节,以及请求在网关内部的完整流转路径。
但还有个问题没说:我们用什么技术栈来实现这些?
下一篇(第 3 章)会详细讲技术选型:为什么是 Spring Boot 3 WebFlux + PostgreSQL + Redis,而不是其他组合。
关于源码和开发进度
这个项目的开发进度会在 GitHub 上持续更新,每一章对应的代码推进都会提交记录,你可以随时看到项目从零到一的成长过程。
GitHub 地址:github.com/ynzz-j/bank…
完整源码计划在完成最新 MVP 版本后,统一上传到 Gitee,届时会在公众号和系列文章里同步通知。
🔔 关注有价值
关注「亦暖筑序」,不错过系列更新:
已发布章节
- 第 1 章:参考 OpenAI 架构,设计企业级 AI 网关
下篇预告
- 第 3 章:技术选型——为什么是 Spring Boot 3 WebFlux + PostgreSQL + Redis
源码进度
🐙 开发进度在 GitHub 持续更新:github.com/ynzz-j/bank…
📦 完成最新 MVP 后,完整源码统一上传 Gitee