Day 17 / 共 20 天 · 第 4 周 AI 网关/部署
AI 增强插件
昨天(Day 16)的 ai-proxy 解决了"怎么把请求发到各家 LLM";但光会转发不够——AI 网关还要治理:按 Token 数限流、统计可观测、语义缓存、内容安全、Prompt 管理。今天看这些 AI 增强插件,重点是"Token 治理闭环"。它们和 ai-proxy 一样都是 Wasm 插件,组合成完整前台。
📍 你在第 4 周(AI 网关 / 部署)的位置
D16 ai-proxy→
D17 AI 增强插件→
D18 hgctl CLI→
D19 部署→
D20 收官
🤔 痛点:只把请求转发给大模型,会出什么事故?
假设你的 AI 网关只会转发(Day 16 的 ai-proxy):某个用户写个脚本狂刷,一夜之间烧掉几万块 token 费用;有人往里灌违规内容;相似问题被反复问、重复付费给大模型;出了问题你还不知道是哪个用户、哪个模型花的钱。光"能调通"远远不够,得有一整套治理。
💡 先兜住今天(延续"大模型统一收费前台"世界观)
如果 Day 16 的 ai-proxy 是前台的"翻译窗口",今天这批插件就是前台的"计量收费 + 安检 + 客服"部门:Token 限流=按用电量收费的电表(用多少 token 扣多少额度);tokenusage=全楼唯一那块权威电表(大家都读它,不各算各的);ai-cache=常见问题的"标准答案墙"(问过的相似问题直接回,不再麻烦大模型);ai-security-guard=进出口安检(挡违规内容)。它们排成一条流水线,围着每一次 LLM 调用做治理。
L01
22 个 AI 插件
| 类别 | 插件 |
|---|---|
| 代理路由 | ai-proxy / model-router / model-mapper |
| 治理 | ai-token-ratelimit / ai-quota / ai-context-limit |
| 可观测 | ai-statistics / ai-history |
| Prompt | ai-prompt-template / ai-prompt-decorator |
| 性能 | ai-cache(语义缓存) |
| 安全 | ai-security-guard / ai-json-resp |
| 增强 | ai-rag / ai-search / ai-intent / ai-agent / mcp-router |
读法:22 个 AI 插件覆盖了 AI 网关的方方面面——不只是"转发到 LLM",而是围绕 LLM 调用的全套治理(限流/统计/缓存/安全/Prompt/RAG)。它们都是 Wasm 插件(Day 12-14 的套路),组合起来构成完整的 AI 网关。
L02
tokenusage 单一真相
// wasm-go/pkg/tokenusage/tokenusage.go GetTokenUsage(ctx, body)
// 从多协议 SSE(OpenAI/Gemini/Anthropic 各自字段路径)抽 input/output token
为什么需要"单一真相来源"?
AI 场景很多治理都基于"这次请求消耗了多少 token"——限流按 token、计费按 token、统计按 token。但不同 LLM 厂商的响应里 token 数字段路径不同(OpenAI 在
usage.total_tokens、Gemini 在别处)。如果每个插件各自解析,重复且易错。所以抽成一个共享函数 GetTokenUsage——所有 AI 插件都用它取 token 数。这就是"Single Source of Truth(单一真相来源)"——一处实现,处处复用,改一处生效所有。限流、统计、计费插件都依赖它,保证 token 计数一致。L03
Token 限流
// ai-token-ratelimit/main.go
// 请求阶段(main.go:52 Lua):只读判断是否超限(还没消耗,先拦)
// 响应阶段(main.go:71 Lua):incrby 实际消耗的 token(事后扣减)
// GetTokenUsage 从流式响应解析真实 token 数 → 超限返回 429
图注:像餐厅先看你有没有钱(预检),点的菜做出来了才按实际分量结账(响应阶段按真实 token 扣)。
📝 举个例子:一次调用怎么走两段
用户本分钟配额剩 500 token。① 请求到达:预检"500 > 0,够,放行"(此刻还不知道会用多少);② LLM 返回,
GetTokenUsage 解析出这次实际用了 input 120 + output 260 = 380;③ 响应阶段 incrby 380,剩余配额变成 120。下一次若来个预估要花很多的请求,预检发现不够就直接 429,连 LLM 都不调。为什么 Token 限流要"事后扣减"?
普通 QPS 限流在请求时判断即可。但 Token 限流的难点:请求时还不知道这次会消耗多少 token(取决于 LLM 生成多长)!所以两段式:①请求阶段——先看"剩余配额够不够",明显超了就拦(429);②响应阶段——等 LLM 返回,用
GetTokenUsage 解析出实际消耗的 token,incrby 扣减配额。用 Redis + Lua 固定窗口(Day 14)。这是"按真实用量计费/限流"的 AI 特有模式——传统限流按次数,AI 限流按 token。L04
AI 统计
// ai-statistics/main.go
// 5 阶段回调,产出:
// Prometheus metric(route.x.upstream.y.model.z.consumer.w.metric.name)
// 结构化 ai_log 日志
// ARMS trace span(gen_ai.usage.*)
// Attribute 从 request/response/streaming body 用规则抽取字段
读法:ai-statistics 采集 AI 特有的可观测数据:按"路由/上游/模型/调用方"多维度打点(Prometheus)、结构化 AI 日志、分布式追踪 span。让你能监控"哪个模型/哪个用户消耗了多少 token、延迟多少"——AI 成本和性能治理的基础。指标命名带 model/consumer 维度,能精确到"某用户用某模型"。
L05
Prompt 管理
- ai-prompt-template(
main.go:48):{{key}}占位符按 properties 展开成完整 messages。 - ai-prompt-decorator:Prepend/Append/Replace +
${geo-country}等变量注入。
在网关层管理 Prompt
Prompt 模板:让你在网关配置 Prompt 模板(如"你是{{role}},请回答:{{question}}"),客户端只传变量,网关展开成完整 prompt 发给 LLM。ai-prompt-decorator:给 prompt 自动加前缀/后缀(如统一的系统提示、安全约束)、注入变量(用户地区等)。好处:Prompt 逻辑集中在网关,不散落在各应用;改 Prompt 不用改应用代码。这是"AI 治理下沉到网关"的又一体现——就像传统网关管路由/限流,AI 网关还管 Prompt。
L06
语义缓存 / 安全
- ai-cache(语义缓存):相似问题命中缓存,不用重复调 LLM(省钱省延迟)。
- ai-security-guard:内容安全(敏感词/合规检测)。ai-json-resp:强制 JSON 格式输出。
- ai-rag / ai-search:检索增强(调向量库/搜索补充上下文)。
语义缓存 = "答过的相似问题不再问 LLM"
LLM 调用贵又慢。ai-cache:把问题和答案缓存,下次语义相似的问题(不用完全一样,用向量相似度判断)直接返回缓存答案,不调 LLM。比如"北京天气"和"北京今天几度"语义相似,第二个可命中第一个的缓存。大幅省 token 成本 + 降延迟。ai-security-guard 做内容安全(防有害输入输出)。这些都是"生产级 AI 网关"必备的治理能力——Higress 用插件把它们模块化。
L07
插件链编排
一次 AI 请求的插件链(
model-router(按 model 选上游)→ ai-prompt-template/decorator(改写 prompt)→ ai-token-ratelimit 请求阶段(查配额)→ ai-cache(查缓存,命中直接返回)→ ai-security-guard(内容安全)→ ai-proxy(协议转换 + 转发 LLM)→(响应)ai-statistics(统计 token)→ ai-token-ratelimit 响应阶段(扣减真实 token)。
这些插件按
POST /v1/chat/completions):model-router(按 model 选上游)→ ai-prompt-template/decorator(改写 prompt)→ ai-token-ratelimit 请求阶段(查配额)→ ai-cache(查缓存,命中直接返回)→ ai-security-guard(内容安全)→ ai-proxy(协议转换 + 转发 LLM)→(响应)ai-statistics(统计 token)→ ai-token-ratelimit 响应阶段(扣减真实 token)。
这些插件按
Phase/Priority(Envoy 课 Day 17 的 WasmPhase)有序编排在 Envoy 过滤器链上——组合出完整的 AI 网关。你可以只启用需要的插件。👶 第一人称视角:现在"你"是一个 POST /v1/chat/completions 请求,走一趟前台看看被谁拦下
👨🏫 你先撞到 model-router(分流台,看你要哪个模型,指去对应后端)→ 经过 ai-prompt-template(帮你把模板变量展开成完整 prompt)→ 到 ai-token-ratelimit 预检窗口(查你配额够不够,不够当场 429 请你回去)→ 路过 ai-cache 答案墙(要是有人问过和你几乎一样的问题,直接把存好的答案给你,你连大模型都不用见)→ 过 ai-security-guard 安检(内容违规就拦)→ 终于到 ai-proxy 翻译窗口转发给真正的 LLM。回程时 ai-statistics 记下你花了多少 token,ai-token-ratelimit 结算窗口按真实用量扣你额度。你(请求)从头到尾没操心过这些——前台的流水线替你办妥了。
L08
今日小结 + 动手
🧠 今天你应该能回答
- AI 插件覆盖哪些方面(不只代理)?
- tokenusage 为什么是"单一真相来源"?
- Token 限流为什么要两段式(请求判断+响应扣减)?
- ai-statistics 采集什么维度?Prompt 插件在网关层管什么?
- 语义缓存怎么省钱?一次 AI 请求的插件链?
✋ 动手
cd /Users/bitmart/work/codes/github/higress-group/higress/plugins/wasm-go/extensions
ls | grep ^ai- # 看所有 AI 插件
grep -n 'RequestPhase\|ResponsePhase\|GetTokenUsage' ai-token-ratelimit/main.go | head
明天预告 · Day 18:hgctl CLI——Higress 的命令行工具:install(K8s/Docker 两条路径)、plugin build(容器编译 Wasm)、gateway-config(看 Envoy 配置)、agent/mcp(AI Agent 部署)。