AI 网关实战(2):7 个模块详解 + 请求完整流转路径

这是「AI 网关实战」系列第 2 篇。
上篇我们聊了为什么要搭 AI 网关,这篇深入每个模块,看看网关内部到底是什么样。


目录


先回忆一下 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 地址:https://github.com/ynzz-j/bank-ai-gateway

完整源码计划在完成最新 MVP 版本后,统一上传到 Gitee,届时会在公众号和系列文章里同步通知。


🔔 关注有价值

关注「亦暖筑序」,不错过系列更新:

已发布章节

  • 第 1 章:参考 OpenAI 架构,设计企业级 AI 网关

下篇预告

  • 第 3 章:技术选型——为什么是 Spring Boot 3 WebFlux + PostgreSQL + Redis

源码进度

🐙 开发进度在 GitHub 持续更新:https://github.com/ynzz-j/bank-ai-gateway

📦 完成最新 MVP 后,完整源码统一上传 Gitee

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐