摘要
一个 AI 后端从能调用模型到真正稳定运行,中间还有很长的距离。前面的文章已经完成了需求分析、架构设计、数据建模、模型抽象、流式接口、知识库、Agent、权限、监控和部署,本篇对整套项目进行复盘,检查还缺少哪些容易被忽略的能力。
本文不再新增一个孤立功能,而是从可靠性、安全性、数据治理、模型质量、成本、运维和团队协作七个方面建立上线检查清单,帮助把一个 Demo 逐步收敛为可维护的生产系统。
一、背景与问题
AI 项目的早期目标通常是:
text
用户输入问题
→ 调用模型
→ 返回答案
生产环境的真实链路则更复杂:
text
身份认证
→ 会话与权限
→ Prompt 和上下文组装
→ 检索与工具调用
→ 模型路由与重试
→ 流式响应
→ 用量、质量、审计与费用记录
只验证"接口能返回答案",无法发现以下问题:
- 用户是否能访问不属于自己的知识库内容。
- 客户端重试是否造成重复任务和重复计费。
- 模型输出是否触发了危险工具调用。
- 上游模型变慢时,系统是否会堆积请求。
- 费用能否按租户和应用准确统计。
- 版本升级后,答案质量是否下降。
项目复盘的重点是验证边界,而不是罗列更多技术名词。
二、核心概念
1. AI 应用的完成度分层
| 阶段 | 特征 |
|---|---|
| Demo | 能调用模型并返回文本 |
| 可用版本 | 有会话、错误处理和基础权限 |
| 稳定版本 | 有限流、超时、重试、监控和持久化 |
| 生产版本 | 有安全审计、质量评估、成本治理和恢复方案 |
| 平台版本 | 支持多应用、多模型、多租户和统一运营 |
不同阶段的目标不同。不要在 Demo 阶段一次性建设完整平台,也不要把生产系统停留在 Demo 的安全边界。
2. 功能正确性与系统正确性
功能正确性关注"答案是否符合预期",系统正确性还要关注:
- 失败时是否释放资源。
- 并发时是否保持隔离。
- 重试时是否幂等。
- 发布时是否可回滚。
- 数据删除后是否真正不可访问。
- 费用和审计是否可追溯。
AI 输出具有不确定性,系统边界必须比普通 CRUD 更明确。
3. 生产基线
一个最小生产基线包括:
text
身份与权限
数据安全
资源控制
可观测性
错误恢复
质量评估
成本管理
发布回滚
缺少其中任何一项,都可能在真实流量下暴露问题。
三、工作原理
1. 从请求到交付的完整链路
text
客户端请求
│
├─ 认证、租户识别、幂等键
├─ 配额与并发检查
├─ 会话读取与权限过滤
├─ 检索、Prompt 和工具准备
├─ 模型调用、流式输出与取消
├─ 结果校验和敏感信息处理
├─ 消息、Token、费用和 Trace 持久化
└─ 质量反馈与告警
每个阶段都需要定义输入、输出、超时、失败处理和可观测字段。
2. 失败恢复矩阵
| 失败位置 | 处理方式 | 是否重试 |
|---|---|---|
| 参数校验 | 返回客户端错误 | 否 |
| 权限检查 | 拒绝请求并审计 | 否 |
| 检索超时 | 降级或返回明确错误 | 视场景 |
| 模型限流 | 退避、切换供应商或排队 | 有条件 |
| 流式中断 | 保存部分状态并允许恢复 | 有条件 |
| 数据库写入失败 | 重试或进入补偿队列 | 有条件 |
| 工具写操作失败 | 保留执行记录,避免盲目重放 | 通常否 |
所有重试都必须考虑幂等、费用和副作用。
3. 上线前后的反馈闭环
text
发布版本
→ 运行监控
→ 用户反馈
→ 质量评估
→ 问题归因
→ Prompt / 模型 / 检索优化
→ 灰度发布
如果没有反馈闭环,系统只能靠偶然发现问题。
四、实战示例
1. 上线检查清单
可以在发布前建立如下清单:
yaml
release:
authentication: true
tenant_isolation: true
idempotency: true
rate_limit: true
timeout: true
graceful_shutdown: true
audit_log: true
token_usage: true
cost_tracking: true
quality_evaluation: true
rollback_plan: true
清单不能只由开发人员口头确认,应绑定具体测试、监控面板或配置项。
2. 设计幂等请求
java
@Service
public class IdempotencyService {
private final IdempotencyRepository repository;
public IdempotencyRecord start(String tenantId, String key) {
return repository.insertIfAbsent(
tenantId,
key,
"PROCESSING",
Instant.now());
}
public void complete(String tenantId, String key,
String resultReference) {
repository.markCompleted(tenantId, key, resultReference);
}
}
幂等键应与租户和业务操作绑定,不能只使用客户端传入的全局字符串。对于流式请求,还要记录已发送的消息状态,避免重连后重复写入。
3. 增加模型质量评估
java
public record EvaluationCase(
String id,
String input,
String expectedFacts,
Set<String> requiredCitations) {
}
java
public record EvaluationResult(
String caseId,
boolean containsExpectedFacts,
boolean citationsComplete,
int inputTokens,
int outputTokens,
long latencyMs) {
}
评估集可以先从真实问题中脱敏建立,逐步增加边界问题、越权问题、空结果问题和工具失败问题。
4. 建立发布门禁
text
单元测试通过
↓
接口与权限测试通过
↓
黄金集质量不下降
↓
Token、延迟和费用在预算内
↓
灰度流量无异常
↓
正式发布
门禁指标要有明确阈值,例如错误率、P95 首 Token 延迟、引用完整率和高风险工具误调用率。
5. 配置回滚
yaml
ai:
active-model: support-model-v3
prompt-version: support-prompt-2026-09-30
retrieval-version: kb-retrieval-v2
tool-policy-version: tool-policy-v4
模型、Prompt、召回策略和工具策略都可能影响结果,应分别记录版本。发生问题时,不一定要回滚整个应用镜像。
6. 事故处理记录
yaml
incident:
id: INC-20260930-001
detected_at: 2026-09-30T10:20:00+08:00
symptom: "模型响应延迟升高"
scope: "tenant-group-a"
impact:
error_rate: 0.08
p95_ttft_ms: 12000
mitigation:
- "切换备用模型"
- "降低批量任务并发"
follow_up:
- "增加供应商延迟告警"
- "补充模型切换演练"
事故记录要关注影响、时间线、缓解措施和后续动作,而不是只记录"重启服务"。
五、常见问题与实践建议
1. 功能都完成了,为什么还不能上线?
因为功能完成只说明主路径可用。上线还需要验证异常路径、权限边界、数据保留、成本预算、扩容、回滚和应急响应。
2. 是否需要一开始就支持所有模型?
不需要。先抽象稳定的模型契约,接入一个主模型和一个备用模型即可。过早支持大量供应商会增加测试矩阵和差异适配成本。
3. AI 应用必须保存完整对话吗?
不一定。应根据业务、合规和调试要求决定保留范围。可以只保存脱敏文本、摘要、哈希、Token 和结果引用;高敏感场景应设置加密、访问审计和自动删除。
4. 用户反馈如何进入工程流程?
把反馈分类为事实错误、引用错误、意图理解错误、工具错误、权限问题和体验问题。每类问题对应不同改进方向,不要把所有问题都归因于模型能力。
5. 生产系统是否可以完全依赖模型自我约束?
不可以。模型指令只能作为行为引导,真正的权限、金额、状态变更和数据范围必须在服务端强制校验。
六、进阶思考
1. 从可用走向可运营
AI 应用需要像业务产品一样运营:
- 按租户和应用统计使用量。
- 观察高频问题和失败问题。
- 管理 Prompt、模型和知识库版本。
- 追踪成本和预算。
- 定期评估答案质量。
- 建立反馈到发布的周期。
没有运营数据,平台无法判断哪些优化真正有效。
2. 建立数据生命周期
建议为以下数据分别定义保留期限:
| 数据 | 需要考虑的策略 |
|---|---|
| 原始文件 | 归档、删除和版本保留 |
| 文档切片 | 与原文件版本绑定 |
| 对话消息 | 脱敏、加密和过期 |
| Trace | 采样和短期保留 |
| 费用事件 | 对账和长期保留 |
| 审计日志 | 防篡改和访问审计 |
数据生命周期是安全设计的一部分,不应等上线后再补。
3. 做故障演练
至少演练以下场景:
text
模型供应商不可用
Redis 不可用
数据库连接池耗尽
向量库延迟升高
客户端大量断开 SSE
某租户突发高并发
新版本质量下降
演练的目标不是证明系统永远不出错,而是确认告警、降级、回滚和恢复路径真实有效。
4. 形成架构决策记录
记录为什么选择某个模型、数据库、队列、部署方式和权限方案。随着项目成员和供应商变化,决策记录能减少重复讨论,也方便后续复盘。
结论
一个生产级 AI 应用的最后 20% 工作,往往决定了大部分稳定性和运营成本。除了模型和业务功能,还需要幂等、权限、限流、超时、审计、质量评估、成本管理、数据生命周期、发布回滚和故障演练。
至此,"从零构建一个生产级 AI 后端"主线 13 篇文章完成。后续可以基于具体业务继续扩展多租户计费、Agent 任务编排、模型评估平台和跨区域部署。
参考资料
- Spring Boot Reference Documentation:https://docs.spring.io/spring-boot/reference/
- Spring AI Reference:https://docs.spring.io/spring-ai/reference/
- OpenTelemetry GenAI Semantic Conventions:https://opentelemetry.io/docs/specs/semconv/gen-ai/