P1 AIP
LLM 网关与降级
AIP 与大模型交互的唯一入口:deepseek-v4-flash 是主力、通义 qwen 是备用、local_rule 是最后兜底。熔断、自动切换、用量落库与成本预算都在这条网关上透明可见。看完这 3 个故事,你就能看懂"模型挂了查数为什么还不挂、账单花在哪"。
IT 管理员
业务分析师
熔断
降级
用量统计
成本预算
共 3 个故事
能 / 不能速览
✅ 这个主题能做
- 统一调用 deepseek-v4-flash / 通义 qwen / local_rule 三个 Provider,按任务降级链自动路由
- 连续失败自动熔断(默认 3 次 → open,冷却 30 秒半开试探,成功即恢复)
- 每次调用(成功/失败)落库 llm_call_logs:tokens / 成本 / 耗时 / 是否降级,重启不丢
- 成本预算:任务级单次预算(cost_limit_cents)+ 用户/应用累计预算,超限返回 COST_LIMIT_EXCEEDED
- 查看 Provider 健康与熔断状态(GET /api/v1/llm/providers)、用量统计(GET /api/v1/llm/usage)
- 统一 REST 入口 POST /api/v1/llm/chat,SSE 流式 POST /api/v1/llm/stream
⛔ 这个主题做不了
- 网关不带 embedding(明确报错,向量走独立 embedding 链路)
- 累计成本预算默认关闭(需 config llm.budget.enabled=true 或管理端点开启)
- 无预算看板与超限预警通道,无语义缓存 / 请求排队 / 内容过滤
- 熔断是简单连续失败计数,不区分 4xx / 5xx
- local_rule 只能"回显"输入,生成不了真实 SQL,NLQ 会断在生成步骤
适用角色
本主题面向两个角色:
- IT 管理员(赵工):看 providers / usage / routes 端点评估稳定性与成本,配置 API key、熔断参数与成本预算——是核心使用者。
- 业务分析师(王姐):NLQ 的无感知消费者,模型切换、降级都不影响她继续查数。
数据工程师(张工)在部署与排障时也会用到:确认 key 配置、判断"为什么走了降级"。
能力速览(能做什么)
多 Provider 路由
deepseek-v4-flash 主力 → 通义 qwen 备用 → local_rule 兜底,按任务类型配置降级链(llm_routes 表,DB 优先),请求时同步完成选择。
熔断与健康检查
连续失败计数熔断(默认 3 次 / 冷却 30 秒),半开试探恢复;/api/v1/llm/providers 暴露各 Provider 状态。
用量落库
每次调用(成功/失败)写 llm_call_logs 表:tokens、成本、耗时、是否降级、用户、应用;/api/v1/llm/usage 提供聚合 summary 与最近记录。
成本预算
任务级单次预算(cost_limit_cents)+ 用户/应用累计预算(默认关闭);管理端点 GET/PUT /llm/routes、PUT /llm/providers/:id 热同步,无需重启。
统一入口 + SSE
POST /api/v1/llm/chat 屏蔽底层 Provider 差异,响应给 provider / model / latency / degraded / cost;POST /api/v1/llm/stream 流式输出。
调整指南(怎么调整)
- 换主力 / 备用模型:改 config.yaml 的 llm.api_keys 与 llm.models;无配置时设 DEEPSEEK_API_KEY / DASHSCOPE_API_KEY 环境变量。
- 调熔断灵敏度:改网关 maxFailures(默认 3 次)与 cooldown(默认 30 秒)。
- 改某任务的降级链与单次预算:管理员在管理后台或 PUT /api/v1/llm/routes/:id 改 cost_limit_cents / fallback_order,保存即热同步。
- 开启累计预算:config.yaml 设 llm.budget.enabled=true + user_limit_cents / app_limit_cents;默认关闭,避免误拒绝。
- 决定是否切模型:用 usage 的 cost / latency_ms / degraded_calls 数据说话,别凭感觉换。
- 让成本可见:给 Provider 配置 cost_per_1k(DB llm_providers 或代码),cost 字段才有意义。
做得好的场景
网关把"换模型、防故障、算成本"收进同一条链路,特别适合以下场景:
- 主力模型抽风:deepseek 超时或 5xx 时自动切 qwen 备用,业务无感知,链路不断。
- 全部远程不可用:还有 local_rule 兜底,至少错误可见、可诊断,不"假死"。
- 成本与稳定性评估:用量已落库、可按用户/应用核算,换模型有数据依据。
- 换模型不动代码:业务逻辑只依赖 LLMService 接口,改配置或管理端点即可切换。
限制与不足
以下是明确的边界,使用前先知道:
- 累计预算默认关闭:要生效需配置 llm.budget.enabled=true;单次预算默认 cost_limit_cents=0(不限)。
- local_rule 救不了查数:它只回显输入,不含 <SQL>,Text2SQL 提取失败会返回 SQL_GENERATION_ERROR。
- 熔断粗糙:连续失败计数,不区分 4xx / 5xx;无预算看板与超限预警通道。
- 无 embedding / 语义缓存 / 请求排队:这些能力不在网关(embedding 走独立服务)。
- 未配 key 时只有 local_rule:deepseek / qwen 因未配置 API key 根本不会注册进网关。
场景故事
故事 1
主力模型超时熔断,网关自动切 qwen 备用,王姐无感知继续查数
场景:故障切换
角色:业务分析师
耗时:约 5 分钟
- 背景
- 王姐是业务分析师,负责季度销售复盘。周四上午她在"智能查询"里连着核对 5 个订单问题都很顺利,问到第 6 个时页面多转了 1~2 秒才出结果。她不知道的是:deepseek-v4-flash 刚刚连续超时失败被网关熔断,这次查询实际是备用 Provider 通义 qwen 完成的。
- 传统做法对比
- 以前接 AI 是"业务代码直连单一模型",模型一挂整条链路全断,业务只能干等 2~4 小时等供应商恢复,或反复重试。现在网关沿降级链自动切换备用 Provider,单次查询只是多了 1~3 秒,全程无人介入,业务无感。
- 角色
- 业务分析师(王姐,无感知消费者);IT 管理员(赵工,事后在 usage / providers 端点复盘)。
- 操作步骤
-
- 王姐照常用自己的账号登录 AIP(端口 18080)
- 打开"智能查询",继续提问(如"每个客户的订单数量")
- 观察结果照常返回,无需任何操作
- 赵工事后用 GET /api/v1/llm/usage 查看降级记录(已落库)
- 再用 GET /api/v1/llm/providers 确认 deepseek 的熔断状态
- 系统响应
- NLQ 照常返回"查询成功"与表格、图表;同时 llm_call_logs 新增一条 provider=qwen、degraded=true 的记录(已落库,重启不丢),providers 端点里 deepseek-v4-flash 的 circuit_state=open:
{
"code": 0,
"providers": [
{ "name": "deepseek-v4-flash", "available": true, "circuit_state": "open", "health": "ok" },
{ "name": "qwen", "available": true, "circuit_state": "closed", "model": "qwen-plus" },
{ "name": "local_rule", "available": true, "circuit_state": "closed" }
]
}
- 结果洞察
- 5 条查询全部成功,王姐全程无感;usage 里 3 条记录命中 qwen 且 degraded=true;deepseek 熔断进入 30 秒冷却。业务连续性达成,这就是"模型商品化"的价值——换模型不改业务逻辑,且降级调用全部落库可追溯。
- 调整建议
- 熔断冷却结束后会半开放一个试探请求,成功即自动恢复 closed;若 deepseek 持续失败,赵工可检查 API key 余额与网络,或调大 maxFailures 阈值降低敏感度;也可在 llm_routes 里调整该任务的降级链优先级。
- 动手试一试
- 登录:admin / admin1。页面路径:智能查询;排查用 GET /api/v1/llm/providers 与 /api/v1/llm/usage(带 Bearer token)。输入内容:连续问几个 NLQ 问题。预期结果:查询照常成功;usage 里出现 provider=qwen、degraded=true 的记录即说明降级发生。
- 限制提示
- 熔断是连续失败计数(默认 3 次),不区分 4xx / 5xx;若只配了 deepseek 的 key、没配 qwen,则降级链会直接跳过 qwen 落到 local_rule,此时 NLQ 会断在生成 SQL 一步。
故事 2
运维看 LLM 用量落库与成本预算,量化成本并给主力任务设单次预算
场景:成本管控
角色:IT 管理员
耗时:约 15 分钟
- 背景
- 赵工是 IT 管理员,负责 AIP 的运维与成本。群里有人反馈"最近查数好像变慢了",他要用数据判断:是 deepseek 不稳定,还是正常的网络波动?成本到底花在哪?他打开网关的三个观测端点——usage(用量已落库)、providers(状态)、routes(路由与预算),几分钟拿到了全貌。
- 传统做法对比
- 以前各家模型各自出账单、各自记调用日志,还散在不同控制台,想算一次成本要手动导表、自己拼,动辄半天;且用量只存内存、重启即清零,无法做月度核算。现在 GET /api/v1/llm/usage 直接给聚合 summary 加最近记录(数据已落 llm_call_logs 表),GET /api/v1/llm/routes 还能给任务配单次预算,几分钟出结论。
- 角色
- IT 管理员(赵工)。
- 操作步骤
-
- 登录 admin(admin / admin1),拿到 Bearer token
- GET /api/v1/llm/providers 查看三个 Provider 的 available / circuit_state / health
- GET /api/v1/llm/usage 查看 summary 与最近记录(落库数据)
- GET /api/v1/llm/routes 查看各任务降级链与预算配置
- 对高频任务(如 nlq)PUT /api/v1/llm/routes/:id 设置 cost_limit_cents 单次预算,保存即热同步
- 系统响应
- usage 返回聚合 summary(数据来自 llm_call_logs,重启不丢);routes 返回路由表与预算配置:
{
"code": 0,
"summary": {
"total_calls": 120, "success_calls": 110, "failed_calls": 10,
"total_tokens": 84500, "total_cost": 0.42,
"total_latency_ms": 252000, "degraded_calls": 8
}
}
-- routes 响应(示意)--
{
"code": 0,
"routes": [
{ "id": 1, "task_type": "nlq", "model_alias": "nlq", "cost_limit_cents": 0, "enabled": true, "description": "自然语言查询(默认链)" }
],
"budget": { "enabled": false, "user_limit_cents": 0, "app_limit_cents": 0 }
}
- 结果洞察
- 今天 120 次调用、10 次失败、8 次降级到 qwen、总成本约 0.42 元、平均延迟约 2.1 秒。结论:成本极低,但 deepseek 偶发失败导致约 7% 的调用走了备用。赵工把 nlq 任务单次预算设为 50 分(cost_limit_cents=50),防止单次超长 prompt 烧钱;累计预算暂不开(避免误拒绝现有环境)。
- 调整建议
- 在 config.yaml 调整熔断 maxFailures / cooldown 让恢复更快;给 qwen 配置 cost_per_1k 让成本核算更准;若要做"按用户控费",把 llm.budget.enabled=true 并设 user_limit_cents(单用户累计预算,超限返回 COST_LIMIT_EXCEEDED)。
- 动手试一试
- 登录:admin / admin1。接口:GET /api/v1/llm/usage、GET /api/v1/llm/providers、GET /api/v1/llm/routes。操作:把 nlq 路由的 cost_limit_cents 设为 100 再请求 /llm/chat 观察。预期结果:usage 返回 total_calls / total_cost / degraded_calls;routes 返回预算字段;超预算任务被拒并返回 COST_LIMIT_EXCEEDED。
- 限制提示
- 累计预算默认关闭(enabled=false 不生效);cost 是估算值(cost_per_1k × tokens),非供应商账单精确值;当前无预算看板与超限预警通道,超限仅拒绝调用并落失败记录。
故事 3
无 API key / 离线环境降级 local_rule 模板,NLQ 准确率归零
场景:降级兜底
角色:数据工程师
耗时:约 10 分钟
- 背景
- 张工是数据工程师,把 AIP 部署到一台无外网的演示机上。登录、数据源、智能查询页面都正常,但一问"每个客户的订单数量",页面返回的不是数据而是"Text2SQL 生成失败"。他检查网关状态才发现:没配 API key,远程 Provider 一个都没注册进来。
- 传统做法对比
- 以前没配模型服务,系统直接报"LLM 不可用"干等着,用户啥也看不到。现在有 local_rule 兜底,链路不会"假死",错误原因也清楚,但代价是它生成不了真实 SQL,NLQ 基本不可用。
- 角色
- 数据工程师(张工,部署者);演示观众(体验者)。
- 操作步骤
-
- 检查 config.yaml 的 llm.api_keys 与 .env 的 DEEPSEEK_API_KEY / DASHSCOPE_API_KEY
- GET /api/v1/llm/providers 看注册的 Provider 列表
- 发一条 NLQ 观察返回
- GET /api/v1/llm/usage 看 provider=local_rule 的调用记录(已落库)
- 系统响应
- providers 列表里只有 local_rule——deepseek / qwen 因未配 key 根本未注册进网关;NLQ 请求最终返回 500,code=SQL_GENERATION_ERROR;local_rule 的实际回复是一段模板文本(不含 <SQL>):
[本地规则降级] 未能连接远程 LLM,已启用本地规则兜底。您的输入:"每个客户的订单数量"。请检查 LLM 服务配置后重试。
- 结果洞察
- local_rule 只能"回显"用户输入,Text2SQL 从中提取不到 <SQL>,于是返回 SQL_GENERATION_ERROR。演示断在"生成 SQL"这一步——网关保证了链路不断、错误可见,但离线 / 无 key 环境想真查数,必须先把 key 配好。
- 调整建议
- 补配 DEEPSEEK_API_KEY(或 DASHSCOPE_API_KEY)后重启服务即可恢复;信创离线场景可把本地 Ollama / 昇腾 vLLM 以 OpenAI 兼容接口注册进网关;纯演示场景可准备一份"预录结果"页面,不依赖实时 LLM。
- 动手试一试
- 环境:本地或测试环境。操作:临时清空 key 重启服务,GET /api/v1/llm/providers 确认只剩 local_rule,发一条 NLQ 看 SQL_GENERATION_ERROR;补回 key 再重启对比恢复。注意:改完记得还原,别动共享配置。
- 限制提示
- local_rule 无成本、永远可用,但永远生成不了真实 SQL;降级态下 NLQ 准确率约等于 0,只能保证"链路可诊断";服务不会替你生成 key,key 必须人工配置。
常见问题
网关里有哪些 Provider,降级顺序是什么?
deepseek-v4-flash(主力)→ 通义 qwen(备用,默认模型 qwen-plus)→ local_rule(本地规则兜底)。按任务降级链依次尝试,熔断中的 Provider 会被跳过;任务级路由可在 llm_routes 表/管理端点调整。
熔断是什么意思,多久能恢复?
连续失败次数达到阈值(默认 3 次)后熔断器打开,拒绝请求进入冷却期(默认 30 秒);冷却结束进入半开状态放行一个试探请求,成功即恢复关闭,失败则重新打开。
用量数据会一直保存吗?
会。每次调用(成功/失败)经 dbUsageRecorder 写 llm_call_logs 表(SQLite),重启不丢;/api/v1/llm/usage 的 summary 与最近记录来自内存快照 + 落库数据,管理员可在管理后台/直查表核算成本。
为什么说 local_rule 兜底"救不了查数"?
local_rule 只是规则模板回显,不含 <SQL> 标签,Text2SQL 提取不到 SQL 就会返回 SQL_GENERATION_ERROR。它保证链路可诊断、错误可见,但 NLQ 结果不可用。
没配 key 时网关会怎样?
未配置 API key 的 Provider 在网关创建时就不注册,/api/v1/llm/providers 列表只剩 local_rule;所有 LLM 调用都走本地规则,NLQ 生成 SQL 会失败。
成本预算默认开吗?怎么启用?
默认关闭。单次预算:把某任务 llm_routes 的 cost_limit_cents 设为大于 0;累计预算:config.yaml 设 llm.budget.enabled=true + user_limit_cents / app_limit_cents。超限返回错误码 COST_LIMIT_EXCEEDED。
主题小结
一句话:LLM 网关是"模型商品化"的开关——换模型改配置、故障自动切换、用量落库、成本可设预算。记住几个边界:累计预算默认关闭、local_rule 救不了查数、无预算看板与预警,部署前先把 key 配好。