Spring AI 接入实践:先封装边界,再替换模型

📅 2026/7/6 6:17:58
Spring AI 接入实践:先封装边界,再替换模型
Spring AI 接入实践先封装边界再替换模型一、别把模型 SDK 写进业务层企业 Java 后端接入大模型时最容易做的是直接在业务 service 里调用某个供应商 SDK。短期能跑长期会把业务和模型供应商绑死。模型切换、限流、审计、重试、降级都会散落在各个业务类里。Spring AI 或任何模型接入框架都应该先变成后端边界层而不是直接渗透到业务代码里。二、先定义模型调用接口flowchart TD A[业务服务] -- B[AI 应用服务] B -- C[模型调用接口] C -- D[供应商适配器] D -- E[模型 API]业务服务只关心任务语义比如摘要、分类、问答不关心具体模型名和供应商参数。public interface AiTaskClient { SummaryResult summarize(SummaryCommand command); ClassificationResult classify(ClassificationCommand command); }接口按任务定义比按模型 API 定义更稳定。三、适配器负责供应商差异Component public class OpenAiTaskClient implements AiTaskClient { Override public SummaryResult summarize(SummaryCommand command) { // build prompt, call model, parse result return new SummaryResult(); } }不同供应商的参数、错误码、流式协议、上下文限制都可以在适配器里处理。业务层不应该到处判断“如果是某某模型就这样”。还要在适配器外面加统一能力超时、限流、审计、成本统计、输出校验。这样每个任务都能走同一套治理。四、配置和路由要独立模型路由不要写死在代码里。任务类型、租户等级、成本预算、模型健康状态都可能影响选择。ai_route: summary: primary: model-fast fallback: model-stable contract_review: primary: model-reasoning require_human_review: true高风险任务还要标记人工复核。不是所有生成结果都应该直接进入业务流程。同时要记录每次调用任务类型、模型、输入 token、输出 token、延迟、错误码和 trace_id。企业系统最怕事后不知道模型到底做过什么。最后替换模型前要跑评测集。接口封装好了并不代表模型可以随便换。不同模型输出风格、稳定性和错误类型都不同必须用任务级评测验证。边界层还要统一异常语义。供应商 A 返回 429供应商 B 返回quota_exceeded供应商 C 直接超时业务层不应该感知这些差异。适配器要把它们转换成统一错误码。enum AiErrorCode { RATE_LIMITED, CONTEXT_TOO_LONG, MODEL_TIMEOUT, OUTPUT_INVALID }统一错误码之后降级、告警、审计和用户提示都更容易做。否则每接一个模型业务逻辑就多一套 if 分支。还要区分同步和异步任务。短文本分类可以同步调用长文档摘要、批量审查、复杂 Agent 任务更适合异步化。边界层最好同时提供同步接口和任务接口避免业务方把长推理硬塞进 HTTP 请求。最后调用边界要有契约测试。给一组固定输入检查解析、错误映射、审计字段和超时行为是否稳定。模型输出本身可能变化但边界行为不能跟着乱。封装边界时还要考虑 Trade-offs。接口抽象层数增加后排查链路会变长新成员理解系统也需要更多时间。如果团队规模小、模型调用场景单一过度封装反而会降低开发效率。判断是否要引入完整适配层可以看两个信号是否已经在多个地方写了同样的供应商 SDK 调用以及是否预计 6 个月内会引入第二个模型供应商。如果两个答案都是否先用工厂模式或简单抽象可能更合适不必一开始就建设完整的边界层。模型供应商的 SDK 版本升级也是现实成本。适配器绑定的 SDK 版本、API 参数、错误码映射都可能随供应商升级而失效。封装边界时要记录每个适配器对应的 SDK 版本和测试通过时间避免出现一年前写的适配器供应商 API 已经迭代了三代却没人知道的情况。可以在 CI 里加一个周期性冒烟测试定期用真实 API 跑一遍核心调用路径即使不检查输出质量至少确认接口没挂。五、总结Spring AI 接入时先把模型调用封装成任务级边界再用适配器处理供应商差异并统一治理路由、审计、限流和评测。模型可以换业务语义不能乱。边界封装好后端系统才有长期演进空间。