Spring Boot + Spring AI 完整实战手册

Spring Boot + Spring AI 完整实战手册

**从零到生产 完整实战手册:**基础 + 进阶 + 生产踩坑 + 多模型 + 容错 + RAG + 函数调用

目录

  1. 版本适配与前置约束
  2. 完整依赖配置(BOM + 多模型)
  3. 全量配置文件详解
  4. 核心两大 API:ChatModel / ChatClient
  5. 基础对话、角色设定、Prompt 模板
  6. 流式 SSE 输出(含异常兜底)
  7. 标准多轮对话(内置 ChatMemory 防溢出)
  8. 多模型无缝切换(OpenAI / 通义 / Ollama)
  9. 函数调用 Function Calling 完整实现
  10. RAG 检索增强生成全流程
  11. 全局异常处理 & AI 专属异常
  12. 生产级:超时、重试、熔断、降级
  13. 拦截器、监控、日志可观测
  14. 企业级最佳实践 & 红线禁忌
  15. 高频踩坑问题汇总

1. 版本适配与前置约束

1.1 强版本绑定(必遵守)

  • Spring AI 1.1.x → Spring Boot 3.2.x | JDK17+
  • Spring AI 1.2.x → Spring Boot 3.3.x
  • Spring AI 2.0.x → Spring Boot 3.4+ | JDK21+

1.2 核心前置规则

  1. 必须引入 Spring AI BOM 统一版本,杜绝依赖冲突
  2. 引入对应模型 Starter 即可自动装配,无需手动创建 Bean
  3. API Key 禁止硬编码,使用环境变量 / 配置中心托管
  4. 所有 AI 接口必须配置超时、重试、异常兜底
  5. 多轮对话必须做上下文裁剪,防止 Token 溢出

2. 完整依赖配置

2.1 统一版本 BOM

xml

XML 复制代码
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>1.1.4</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

2.2 基础核心依赖

xml

XML 复制代码
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- OpenAI -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
    </dependency>

    <!-- 阿里云通义千问 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-dashscope-spring-boot-starter</artifactId>
    </dependency>

    <!-- 本地 Ollama 离线模型 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
    </dependency>

    <!-- RAG 向量库 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-pgvector-store-spring-boot-starter</artifactId>
    </dependency>

    <!-- 重试容错 -->
    <dependency>
        <groupId>org.springframework.retry</groupId>
        <artifactId>spring-retry</artifactId>
    </dependency>
</dependencies>

2.3 仓库配置

xml

XML 复制代码
<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
    </repository>
</repositories>

3. 全量配置文件(application.yml)

yaml

XML 复制代码
spring:
  ai:
    # 全局公共配置
    chat:
      options:
        temperature: 0.5
        max-tokens: 2048
        top-p: 0.9
        timeout: 30s
        system-prompt: 你是资深Java架构师,回答精简专业,附带可运行代码

    # OpenAI 配置
    openai:
      api-key: ${OPENAI_API_KEY:}
      base-url: https://api.openai.com/v1
      connection-timeout: 15000
      read-timeout: 30000
      chat:
        options:
          model: gpt-3.5-turbo

    # 通义千问配置
    dashscope:
      api-key: ${DASHSCOPE_API_KEY:}
      chat:
        options:
          model: qwen-plus

    # Ollama 本地模型
    ollama:
      base-url: http://localhost:11434
      chat:
        options:
          model: qwen2.5

# 关闭指定自动配置(排错使用)
autoconfigure:
  exclude:
    - org.springframework.ai.openai.autoconfigure.OpenAiChatAutoConfiguration

4. 核心两大 API

4.1 底层原生 ChatModel(自由度高)

java 复制代码
@RestController
@RequiredArgsConstructor
public class AiController {

    private final ChatModel chatModel;

    @GetMapping("/model/chat")
    public String modelChat(String msg) {
        ChatRequest request = ChatRequest.builder()
                .messages(List.of(new UserMessage(msg)))
                .temperature(0.5)
                .build();
        return chatModel.call(request).getResult().getOutput().getContent();
    }
}

4.2 高层推荐 ChatClient(企业首选)

自动装配、链式调用、拦截器、记忆、模板一体化

java 复制代码
private final ChatClient chatClient;

@GetMapping("/client/chat")
public String clientChat(String msg) {
    return chatClient.prompt()
            .user(msg)
            .call()
            .content();
}

5. 进阶能力

5.1 全局角色 + 单次临时角色

java 复制代码
@GetMapping("/system/chat")
public String systemChat(String msg) {
    return chatClient.prompt()
            .system("你是Redis高级专家,回答精简,只讲核心原理")
            .user(msg)
            .call()
            .content();
}

5.2 Prompt 模板化(杜绝硬编码)

java 复制代码
@GetMapping("/template/chat")
public String templateChat(String question) {
    String promptStr = """
            请以Java工程师视角解答问题:
            问题:{question}
            要求:精简、带代码示例、避免废话
            """;
    PromptTemplate template = new PromptTemplate(promptStr);
    Prompt prompt = template.create(Map.of("question", question));
    return chatClient.call(prompt).getResult().getOutput().getContent();
}

6. 流式 SSE 输出(生产标准写法)

自带异常兜底、SSE 标准响应头、空值防护

java 复制代码
@GetMapping(value = "/ai/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChat(String prompt) {
    return chatClient.stream()
            .user(prompt)
            .stream()
            .map(res -> Optional.ofNullable(res.getResult().getOutput().getContent()).orElse(""))
            .onErrorResume(e -> Flux.just("AI服务调用异常,请稍后重试"));
}

7. 标准多轮对话(内置 ChatMemory)

自动管理上下文、限制最大轮次、防止无限膨胀

java 复制代码
// 全局单例内存记忆,保留最近5轮
private final ChatMemory chatMemory = new InMemoryChatMemory(5);

@GetMapping("/multi/chat")
public String multiChat(String msg) {
    return chatClient.prompt()
            .user(msg)
            .chatMemory(chatMemory)
            .call()
            .content();
}

8. 多模型无缝切换

  1. 只更换 starter 依赖 + 配置
  2. 业务代码 ChatClient 完全不用改
  3. 适用:OpenAI、通义千问、文心一言、讯飞星火、Ollama

核心价值:一套代码,适配所有大模型。


9. 函数调用 Function Calling

9.1 定义业务工具

java 复制代码
@Configuration
public class AiFunctionConfig {

    @Bean
    @Description("根据用户id查询订单信息")
    public Function<OrderQueryReq, OrderResp> getOrderInfo(OrderService orderService) {
        return req -> orderService.getOrder(req.userId());
    }
}

// 请求/响应
record OrderQueryReq(String userId) {}
record OrderResp(String orderNo, String status, BigDecimal amount) {}

9.2 开启函数调用

java 复制代码
@GetMapping("/function/chat")
public String functionChat(String msg) {
    return chatClient.prompt()
            .user(msg)
            .functions("getOrderInfo")
            .call()
            .content();
}

10. RAG 检索增强生成(企业知识库)

10.1 核心流程

文档加载 → 文本分片 → 向量化 → 向量库存储 → 相似度检索 → 拼接上下文 → AI 回答

10.2 核心代码

java 复制代码
@Service
@RequiredArgsConstructor
public class RagService {
    private final ChatClient chatClient;
    private final VectorStore vectorStore;

    // 初始化文档入库
    @PostConstruct
    public void loadDoc() {
        List<Document> docs = new PagePdfDocumentReader(new ClassPathResource("company-doc.pdf")).get();
        TextSplitter splitter = new TokenTextSplitter(500, 50, 10, 100);
        vectorStore.add(splitter.apply(docs));
    }

    // RAG问答
    public String ragChat(String question) {
        List<Document> relatedDocs = vectorStore.similaritySearch(
                SearchRequest.query(question).withTopK(3).withSimilarityThreshold(0.7)
        );
        String context = relatedDocs.stream().map(Document::getContent).collect(Collectors.joining("\n"));

        String prompt = """
                严格根据下方参考资料回答问题,禁止编造内容:
                参考资料:%s
                问题:%s
                """.formatted(context, question);
        return chatClient.prompt().user(prompt).call().content();
    }
}

11. 全局异常处理

java 复制代码
@RestControllerAdvice
@Slf4j
public class AiGlobalExceptionHandler {

    @ExceptionHandler(ApiKeyInvalidException.class)
    public Result<Void> apiKeyErr() {
        return Result.fail(5001, "AI密钥配置错误或已过期");
    }

    @ExceptionHandler(TimeoutException.class)
    public Result<Void> timeoutErr() {
        return Result.fail(5002, "大模型请求超时");
    }

    @ExceptionHandler(Exception.class)
    public Result<Void> aiCommonErr(Exception e) {
        log.error("AI调用异常", e);
        return Result.fail(5000, "AI服务暂时不可用");
    }
}

12. 生产级容错

12.1 重试机制

java 复制代码
@EnableRetry
@SpringBootApplication
public class AiApplication {}

// 业务方法
@Retryable(maxAttempts = 3, delay = 1000, retryFor = TimeoutException.class)
public String aiChat(String msg) {
    return chatClient.prompt().user(msg).call().content();
}

12.2 降级策略

  • 主模型异常自动切换备用模型
  • 高频问题本地缓存兜底
  • 限制 max-tokens 控制成本

13. 拦截器与监控

全局 AI 请求拦截器(耗时、Token、日志)

java 复制代码
@Bean
public ChatClientCustomizer chatClientCustomizer() {
    return builder -> builder.defaultInterceptors(context -> {
        long start = System.currentTimeMillis();
        // 请求前
        context.advance();
        // 响应后
        long cost = System.currentTimeMillis() - start;
        log.info("AI调用耗时:{}ms,模型:{}", cost, context.getPrompt().getChatOptions().getModel());
    });
}

14. 企业级最佳实践

  1. 环境变量托管 APIKey,杜绝明文配置
  2. 统一全局 system-prompt,规范 AI 输出风格
  3. 所有接口强制超时时间,避免线程阻塞
  4. 多轮对话限制上下文长度,控制 Token 成本
  5. RAG 必须配置相似度阈值,减少无关文档
  6. 流式接口统一 SSE 协议,增加异常熔断
  7. 接入监控:调用量、耗时、失败率、Token 消耗
  8. 敏感内容过滤、输出内容安全校验

15. 高频踩坑汇总

  1. 版本不匹配 → 自动配置失效、Bean 找不到
  2. 国内网络无法访问 OpenAI → 配置代理 / 切换国产模型
  3. 多轮对话上下文无限累积 → 使用 ChatMemory 限制轮次
  4. RAG 回答乱编 → 增加相似度阈值、强约束 prompt
  5. 流式输出乱码 / 中断 → 标准 SSE 响应头 + 异常兜底
  6. 函数调用不生效 → 缺少 @Description 注解、参数不规范
  7. 大模型接口超时 → 调整超时时间、增加重试
  8. 依赖混乱 → 必须使用 Spring AI BOM

所有模块:底层双 API、全量配置、内存会话记忆、模板提示词、拦截器监控、生产容错、异常体系、多模型、RAG 完整落地、踩坑避坑。

相关推荐
宸津-代码粉碎机4 小时前
OpenAI 连夜迎战 Grok Bot 和 Muse:AI 智能体从 “会聊天” 到 “能办事”,现在入场还来得及吗
java·大数据·人工智能·分布式·python
程序猿乐锅5 小时前
【黑马点评 | 第八篇】Redisson分布式锁
java·数据库·spring boot·redis·分布式·spring·缓存
做萤石二次开发的哈哈5 小时前
视频解码器怎么对接?解码上墙、电视墙开窗与场景切换的ISAPI接入实战
人工智能·物联网·监控·视频编解码·大屏端·萤石开放平台·蓝海aiot一站式工作台
Leo.yuan5 小时前
2026年本地化Data Agent优质厂商盘点:哪些产品更适合企业生产环境
大数据·数据库·人工智能
长谷深风1115 小时前
Tool与Skill:AI能力设计的分水岭
java·人工智能·ai·大模型·aiagent
科技观察哨6 小时前
六足平台选型与纳米定位系统集成:HEB-640六自由度位移台在半导体光刻对准中的参数边界与国产替代评估
前端·人工智能
m0_587383006 小时前
广州24小时自助健身房解决方案实战指南与系统部署要点
java·spring·小程序·架构·需求分析
云上先途6 小时前
任务智能体可以自动完成哪些类型工作,是不是只能做简单重复操作?
大数据·人工智能
明志数科6 小时前
具身智能数据供给的分层:分布式采集与入厂采集的工程边界分析
人工智能·机器学习·机器人
像风一样自由20206 小时前
41.用FastAPI搭建一个RAG后端需要哪些接口
人工智能·大模型·fastapi·rag·智能体