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 完整落地、踩坑避坑。

相关推荐
wu8587734571 小时前
Java AI Harness 落地:拥抱框架还是回归本质?深度解析选型之道
java·人工智能·回归
北风toto1 小时前
SpringBoot 获取配置文件值、获取环境变量的方式
java·spring boot·后端
互联网推荐官1 小时前
上海小程序开发实践:技术选型、场景分化与平台能力的全面审视
人工智能·软件工程
俊哥V1 小时前
每日 AI 研究简报 · 2026-04-28
人工智能·ai
chaofan9801 小时前
OpenAI重塑设计生产力!GPT-image-2发布:从像素拼接到代理推理的范式跃迁
人工智能·gpt·深度学习·计算机视觉·api
凤山老林1 小时前
Spring Boot 集成国产开源图库 HugeGraph 实现图谱分析的技术方案
spring boot·后端·开源·hugegraph·图谱分析
网瘾新之助1 小时前
Sub-agent 和 Agent-team:从一个例子开始
人工智能
想ai抽1 小时前
Agent记忆架构设计剖析系列:原理、权衡与场景适配(hermes设计原理)
人工智能·harness·hermes
Raink老师1 小时前
【AI面试临阵磨枪-27】Agent 通用抽象架构:感知、规划、行动、记忆 四个模块如何闭环?
人工智能·ai 面试