技术博客 技术博客
  • JAVA编程
  • 设计模式
  • 人工智能
  • Spring
  • Mybatis
  • Maven
  • Git
  • Kafka
  • RabbitMQ
  • RocketMQ
  • Redis
  • Zookeeper
  • Nginx
  • 数据库套件
  • MySQL
  • Elasticsearch
  • MongoDB
  • Hadoop
  • ClickHouse
  • Hbase
  • Hive
  • Flink
  • Flume
  • SQLite
  • linux
  • Docker
  • Jenkins
  • Kubernetes
  • 工具
  • 前端
GitHub (opens new window)
  • JAVA编程
  • 设计模式
  • 人工智能
  • Spring
  • Mybatis
  • Maven
  • Git
  • Kafka
  • RabbitMQ
  • RocketMQ
  • Redis
  • Zookeeper
  • Nginx
  • 数据库套件
  • MySQL
  • Elasticsearch
  • MongoDB
  • Hadoop
  • ClickHouse
  • Hbase
  • Hive
  • Flink
  • Flume
  • SQLite
  • linux
  • Docker
  • Jenkins
  • Kubernetes
  • 工具
  • 前端
GitHub (opens new window)
  • JAVA编程

    • 基础

      • JAVA 锁 及 线程
      • JAVA NIO API
      • JVM 模块介绍
    • 版本

      • JAVA8 新特性总结
      • JAVA9 新特性总结
      • JAVA 10/11/12/13/14/15/16/17 新特性总结
    • 其他

      • jar 打包成.exe可执行文件
      • java代码混淆之 ProGuard
      • JAVA 性能监控(jvisualvm)及测试(JMeter)
      • Alibaba Arthas
      • jar启动脚本
  • 设计模式

    • 代理模式
  • 人工智能

    • 基础算法

      • 线性模型
      • 感知机
    • 框架与工具

      • ollama本地部署
      • Spring AI
        • 概述
          • 组件总览
        • ChatClient
        • ChatModel
          • 支持的 Chat Model 提供商(1.1.7)
        • EmbeddingModel
          • 支持的 Embedding 提供商
        • ImageModel
          • 支持的提供商
        • AudioModel
          • 支持的提供商
        • ModerationModel
          • 支持的提供商
        • Multimodality(多模态)
        • Prompts(提示词模板)
        • Structured Output(结构化输出转换器)
        • Advisors(顾问/拦截器 API)
          • 核心组件
          • 执行流程
        • Chat Memory(对话记忆)
          • 记忆类型
          • 存储实现(ChatMemoryRepository)
          • 记忆与 ChatClient 的配合方式
        • Tool Calling(工具调用)
          • 定义工具的三种方式
          • 核心组件
        • MCP(模型上下文协议)
          • 核心组件
          • 传输方式对比
        • RAG(检索增强生成)
          • RAG 完整流程
          • 核心组件
        • ETL Pipeline(数据管道)
          • 三个阶段
          • 内置的 DocumentReader
          • 内置的 DocumentTransformer
        • Vector Databases(向量数据库)
          • 向量数据库详细对比
          • PGvector
          • Chroma
          • Milvus
          • Redis
          • Elasticsearch
          • MongoDB Atlas
          • Neo4j
          • Pinecone
          • Qdrant
          • Weaviate
          • 其他支持的向量数据库
          • 如何选择向量数据库?
        • Observability(可观测性)
        • Model Evaluation(模型评估测试)
        • Development-time Services(开发时服务)
        • Testcontainers(测试容器集成)
目录

Spring AI

本文基于 Spring AI 1.1.7(Stable)版本,官方文档:https://docs.spring.io/spring-ai/reference/

# 概述

Spring AI 是 Spring 官方推出的 AI 应用开发框架,目标是简化 Java 应用集成 AI 能力的复杂度。它借鉴了 Python 生态的 LangChain、LlamaIndex 等项目的设计理念,但并非直接移植,而是以 Spring Boot 的风格提供了一套可移植、可插拔的 AI 抽象层。核心优势在于:通过统一的 API 抽象,只需修改配置就可以在不同的 AI 模型提供商之间切换(比如从 OpenAI 切到 Ollama),业务代码几乎不用改。

# 组件总览

组件 作用
ChatClient 对话客户端,统一的聊天 API(类似 RestClient)
ChatModel 对话模型,各大模型提供商的适配层
EmbeddingModel 嵌入模型,文本 / 图片转向量
ImageModel 图片生成模型
AudioModel 语音识别(Transcription)& 语音合成(TTS)模型
ModerationModel 内容审核 / 敏感词检测模型
Multimodality 多模态 API,混合输入(文本 + 图片 + 音频)
Prompts 提示词模板 API
Structured Output 结构化输出转换器,LLM 输出映射为 Java 对象
Advisors 顾问 / 拦截器 API,拦截增强 AI 对话链路
Chat Memory 对话记忆,多轮对话上下文保持
Tool Calling 工具调用(Function Call 升级版)
MCP 模型上下文协议,标准化 LLM 与外部系统的交互
RAG 检索增强生成
ETL Pipeline 数据抽取转换加载管道
Vector Databases 向量数据库集成(20 + 种)
Observability 可观测性(指标、追踪、日志)
Model Evaluation AI 模型评估测试
Development-time Services 开发时服务(Docker Compose 集成)
Testcontainers 测试容器集成

# ChatClient

作用:Spring AI 提供的统一对话客户端 API,是开发者与 LLM 交互的最核心入口。设计风格类似于 Spring 的 WebClient 和 RestClient ,采用 Fluent API(链式调用),支持同步和流式两种模式。

为什么需要它:不同的大模型提供商(OpenAI、Ollama、通义千问等)各自有不同的 SDK 和调用方式,ChatClient 提供了统一的抽象层,一套代码适配所有模型。

// 注入 ChatClient(Spring Boot 自动装配)
@Bean
ChatClient chatClient(ChatClient.Builder builder) {
    return builder
        .defaultSystem("你是一个专业的Java架构师,回答问题简洁专业")
        .build();
}

// 同步调用
String answer = chatClient.prompt()
    .user("Spring AI是什么?")
    .call()
    .content();

// 流式调用(适合打字机效果)
Flux<String> stream = chatClient.prompt()
    .user("给我讲讲微服务架构")
    .stream()
    .content();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

与 ChatModel 的区别:

  • ChatClient 是高层 API,面向业务开发者,支持 Advisor 链、记忆注入、工具调用等高级功能
  • ChatModel 是底层 API,面向各模型提供商的适配层,关注的是模型参数(温度、top_p 等)

# ChatModel

作用:为每个 AI 模型提供商建立的底层适配层,每个提供商有自己的 ChatModel 实现。不同大模型在对话方面有细微区别(比如参数名不同、支持的特性不同),ChatModel 就是抹平这些差异的。

# 支持的 Chat Model 提供商(1.1.7)

提供商 说明
OpenAI GPT-4o、GPT-4、GPT-3.5 等,最主流的商业大模型
Ollama 本地部署开源模型(LLaMA、Qwen、DeepSeek 等),免费无需 API Key
Anthropic Claude 系列,长上下文能力强(200K tokens)
Azure OpenAI 微软 Azure 托管的 OpenAI 服务,企业合规场景首选
DeepSeek 国产大模型,性价比高,中文能力强
Google GenAI Gemini 系列模型
Google VertexAI Gemini 谷歌云平台托管的 Gemini
Mistral AI 法国开源大模型,轻量高效
QianFan(百度千帆) 百度文心一言等国产模型
ZhiPu AI(智谱) 智谱 GLM 系列,国内学术背景深厚
MiniMax 国产大模型提供商
Moonshot AI(月之暗面) Kimi 背后的模型提供商
Hugging Face 开源模型社区,海量模型可选
NVIDIA NVIDIA NIM 推理服务
Groq 超快推理速度,基于 LPU 硬件
Perplexity AI 搜索增强型大模型
Amazon Bedrock Converse AWS 托管的多模型服务
OCI Generative AI (Cohere) Oracle 云 AI 服务
Docker Model Runner Docker Desktop 内置模型运行(1.1.7 新增)
// 直接使用 ChatModel(底层 API)
@Autowired
OllamaChatModel chatModel;

ChatResponse response = chatModel.call(
    new Prompt("你好",
        OllamaOptions.builder()
            .model("qwen2.5:7b")
            .temperature(0.7)
            .build())
);
1
2
3
4
5
6
7
8
9
10
11

# EmbeddingModel

作用:将文本、图像等数据转换为浮点数向量(数组),这些向量能捕获语义含义。语义相近的内容,生成的向量在空间中距离更近。它是 RAG(检索增强生成)的核心基础组件。

举例:"我喜欢美丽的花朵" 和 "我喜爱漂亮的鲜花",两句话语义相近,嵌入后的向量距离会很近(余弦相似度接近 1)。

# 支持的 Embedding 提供商

提供商 说明
OpenAI text-embedding-ada-002 等,最常用
Azure OpenAI 微软托管版
Ollama 本地嵌入(nomic-embed-text 等)
Google GenAI 谷歌文本嵌入
Mistral AI Mistral 嵌入模型
MiniMax / QianFan / ZhiPu AI 国产嵌入模型
Amazon Bedrock(Cohere/Titan) AWS 嵌入服务
VertexAI(Text/Multimodal) 谷歌云,支持多模态嵌入
PostgresML 数据库内嵌入,无需外部调用
ONNX Transformers 纯本地运行,JVM 内跑 ONNX 模型,数据不出服务器

ONNX Transformers 是唯一一个纯本地运行的嵌入方案,不需要任何外部 API,适合对数据安全要求极高的场景。

@Autowired
EmbeddingModel embeddingModel;

// 文本转向量
EmbeddingResponse response = embeddingModel.call(
    new EmbeddingRequest(
        List.of("Spring AI是什么?", "Java微服务架构"),
        EmbeddingOptions.EMPTY)
);
// 拿到向量后存到向量数据库,供后续 RAG 检索使用
1
2
3
4
5
6
7
8
9
10

# ImageModel

作用:调用 AI 模型生成图片。输入文本描述(prompt),输出一张 AI 生成的图片。

# 支持的提供商

提供商 说明
OpenAI(DALL·E) 最主流的图片生成,支持 DALL・E 3
Azure OpenAI 微软托管版 DALL・E
Stability AI Stable Diffusion 系列,开源图片生成的标杆
ZhiPuAI 智谱图片生成
QianFan 百度千帆图片生成
@Autowired
ImageModel imageModel;

ImageResponse response = imageModel.call(
    new ImagePrompt("一只穿着西装的猫在写Java代码,赛博朋克风格")
);
String imageUrl = response.getResult().getOutput().getUrl();
1
2
3
4
5
6
7

# AudioModel

作用:分为两个子方向 —— 语音转文字(Transcription) 和 文字转语音(TTS)。

# 支持的提供商

方向 提供商 说明
语音转文字 OpenAI Whisper 多语言语音识别,准确率高
语音转文字 Azure OpenAI 微软托管版 Whisper
文字转语音 OpenAI TTS 多种声音可选(alloy、echo、fable 等)
文字转语音 ElevenLabs 1.1.7 新增,音质更自然逼真,支持声音克隆

OpenAI TTS 与 ElevenLabs 的区别:

  • OpenAI TTS:成本低,延迟低,适合标准场景
  • ElevenLabs:音质更好,支持声音克隆和多语言混读,适合对音质要求高的场景(如有声书、客服系统),但价格更贵
// 语音转文字
@Autowired
OpenAiAudioTranscriptionModel transcriptionModel;

AudioTranscriptionResponse response = transcriptionModel.call(
    new AudioTranscriptionPrompt(new ClassPathResource("interview.mp3"))
);
String text = response.getResult().getOutput();

// 文字转语音
@Autowired
OpenAiAudioSpeechModel speechModel;

byte[] audio = speechModel.call("欢迎使用Spring AI框架");
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# ModerationModel

作用:内容审核模型,检测用户输入或模型输出中的敏感内容(暴力、色情、仇恨言论、自残等)。在生产环境中,这是保障内容安全的关键环节。

# 支持的提供商

提供商 说明
OpenAI Moderation 免费调用,支持多种分类(暴力、色情、仇恨等)
Mistral AI Moderation Mistral 提供的内容审核

通常配合 Advisor 使用,在对话链路中自动拦截不合规的内容。

@Autowired
OpenAiModerationModel moderationModel;

ModerationResponse response = moderationModel.call(
    new ModerationPrompt("需要审核的文本内容")
);
boolean flagged = response.getResult().getOutput().isFlagged();
1
2
3
4
5
6
7

# Multimodality(多模态)

作用:支持在一次对话中混合输入多种类型的数据(文本 + 图片 + 音频等)。比如上传一张图片并问 "这张图片里有什么?",此时请求中同时包含了图片和文本两种模态的信息。

与 ChatModel 的关系:多模态是 ChatModel 的能力扩展,不是独立的 Model,而是在对话时允许消息中携带多种媒体类型。并非所有 ChatModel 都支持多模态,目前支持的包括 OpenAI(GPT-4o)、Ollama(LLaVA 等)、Anthropic(Claude 3)、Google Gemini 等。

// 上传图片进行多模态对话
UserMessage userMessage = new UserMessage(
    "请描述这张图片的内容",
    new Media(MimeTypeUtils.IMAGE_PNG, new ClassPathResource("test.png"))
);
ChatResponse response = chatModel.call(new Prompt(userMessage));
1
2
3
4
5
6

# Prompts(提示词模板)

作用:结构化的提示词管理 API,类似于 Spring MVC 的模板引擎(Thymeleaf)。支持用占位符 {变量名} 构建动态提示词,避免在代码中硬编码拼接字符串,提高可维护性和复用性。

与直接拼字符串的区别:

  • 模板可以从外部文件加载(比如 resources 目录下的 .st 文件)
  • 支持变量替换,提示词和业务逻辑分离
  • 更容易做版本管理和 A/B 测试
// 使用 PromptTemplate
PromptTemplate template = new PromptTemplate(
    "你是{role},请用{style}的风格回答以下问题:{question}"
);
Prompt prompt = template.create(Map.of(
    "role", "资深Java架构师",
    "style", "通俗易懂",
    "question", "什么是微服务?"
));
ChatResponse response = chatModel.call(prompt);

// 也可以从文件加载模板
PromptTemplate fileTemplate = new PromptTemplate(
    new ClassPathResource("prompts/qa.st")
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# Structured Output(结构化输出转换器)

作用:将 LLM 返回的非结构化文本自动映射为 Java 对象(POJO)。大模型默认返回的是自然语言文本,但在实际开发中,我们往往需要结构化数据(JSON 对象、List 列表)才方便后续处理。

工作原理:在提示词中自动注入格式说明(告诉模型按什么格式返回),响应后自动反序列化,开发者无需手动写 JSON 解析逻辑。

// 定义返回结构
record BookInfo(String title, String author, int year, String summary) {}

// ChatClient 直接映射为对象
BookInfo book = chatClient.prompt()
    .user("介绍一下《深入理解Java虚拟机》这本书")
    .call()
    .entity(BookInfo.class);  // 自动映射

// 也可以映射为 List
List<BookInfo> books = chatClient.prompt()
    .user("推荐3本Java入门书籍")
    .call()
    .entity(new ParameterizedTypeReference<List<BookInfo>>() {});
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# Advisors(顾问 / 拦截器 API)

作用:类似于 Spring MVC 的拦截器(Interceptor)或 AOP 切面,是应用在 AI 对话链路中的拦截增强机制。可以在请求发送给 LLM 之前、以及 LLM 返回响应之后,拦截、修改、增强数据。

典型应用场景:

  • 自动注入对话记忆(MessageChatMemoryAdvisor)
  • 自动执行 RAG 检索(QuestionAnswerAdvisor)
  • 日志审计、Token 统计
  • 内容安全过滤
  • 自定义业务逻辑拦截

# 核心组件

组件 作用
CallAdvisor / CallAdvisorChain 非流式场景的拦截器和链
StreamAdvisor / StreamAdvisorChain 流式场景的拦截器和链
Recursive Advisors 递归型 Advisor,让 LLM 多轮自我调用直到得出满意结果

# 执行流程

  1. Spring AI 框架将用户的 Prompt 封装为 ChatClientRequest
  2. 请求依次经过 Advisor 链中的每个 Advisor(按 getOrder() 排序,值小的先执行)
  3. 每个 Advisor 可以修改请求(比如注入记忆消息、追加系统提示词)
  4. 最后一个 Advisor(框架自动添加)将请求发送给 ChatModel
  5. 响应沿 Advisor 链反向传递,每个 Advisor 可以处理或修改响应
  6. 最终返回给调用方

与 Spring MVC Interceptor 的对比:思路完全一致,只是拦截的对象从 HTTP 请求变成了 AI 对话请求。

ChatClient chatClient = ChatClient.builder(chatModel)
    .defaultAdvisors(
        MessageChatMemoryAdvisor.builder(chatMemory).build(),  // 记忆注入
        QuestionAnswerAdvisor.builder(vectorStore).build()      // RAG检索
    )
    .build();

String response = chatClient.prompt()
    .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, "user-123"))
    .user("上次我们聊到哪了?")
    .call()
    .content();
1
2
3
4
5
6
7
8
9
10
11
12

# Chat Memory(对话记忆)

作用:LLM 是无状态的,每次请求都是独立的,不记得上一轮对话说了什么。Chat Memory 让大模型在多轮对话中保持上下文记忆。

Chat Memory 与 Chat History 的区别:

  • Chat Memory(对话记忆):LLM 当前需要的上下文窗口,可能只保留最近 N 条消息
  • Chat History(对话历史):完整的所有对话记录,用于存档或审计

# 记忆类型

类型 说明
MessageWindowChatMemory 滑动窗口记忆(默认),保留最近 N 条消息,超出的自动丢弃

# 存储实现(ChatMemoryRepository)

记忆的底层存储通过 ChatMemoryRepository 接口实现,Spring AI 提供了多种开箱即用的实现:

存储实现 说明 适用场景
InMemoryChatMemoryRepository 内存存储(默认),重启后丢失 开发测试、单机临时场景
JdbcChatMemoryRepository 基于 JDBC 持久化,支持 MySQL/PostgreSQL 等 生产环境最常用,直接复用现有关系库
CassandraChatMemoryRepository Apache Cassandra 存储 大规模分布式、高写入场景
Neo4jChatMemoryRepository Neo4j 图数据库存储 需要分析对话关系网络的场景
MongoChatMemoryRepository MongoDB 存储 文档型存储偏好、已有 Mongo 基础设施
CosmosDBChatMemoryRepository Azure CosmosDB 存储 Azure 云原生环境

# 记忆与 ChatClient 的配合方式

Advisor 工作方式 适用场景
MessageChatMemoryAdvisor 将历史消息作为消息列表注入(最推荐) 大多数多轮对话场景
PromptChatMemoryAdvisor 将历史消息拼入系统提示词文本 模型不支持多消息格式时
VectorStoreChatMemoryAdvisor 基于向量相似度检索相关历史记忆 超长对话、只需召回相关片段
// Spring Boot 自动装配(默认 InMemory + MessageWindow)
@Autowired
ChatMemory chatMemory;

// 配合 ChatClient 使用
ChatClient chatClient = ChatClient.builder(chatModel)
    .defaultAdvisors(
        MessageChatMemoryAdvisor.builder(chatMemory).build()
    )
    .build();

// 通过 conversationId 区分不同用户的对话
String response = chatClient.prompt()
    .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, "user-456"))
    .user("我叫张三")
    .call()
    .content();

// 下一轮对话,模型会记得你叫张三
String response2 = chatClient.prompt()
    .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, "user-456"))
    .user("我叫什么名字?")
    .call()
    .content(); // 会回答 "你叫张三"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# Tool Calling(工具调用)

作用:允许 LLM 在对话过程中请求调用客户端定义的工具 / 函数,获取实时信息或执行特定操作。这是解决 LLM "知识截止日期" 和 "无法操作外部系统" 两大问题的核心方案。

Tool Calling 是 1.1.x 版本对旧版 Function Call API 的全面升级。旧的 FunctionCallback 已迁移为 ToolCallback ,推荐使用新 API。

两大用途:

  • 信息检索:获取 LLM 不知道的实时数据(天气、股价、数据库查询)
  • 执行动作:让 LLM 触发实际操作(发邮件、下订单、调用第三方 API)

与 RAG 的区别:

  • Tool Calling:获取精确结果和执行特定操作(比如查天气得到 "30°C")
  • RAG:从大量文档中检索相关信息并整合成回答(比如从知识库中找到相关政策条文)

# 定义工具的三种方式

方式一:@Tool 注解(推荐,最简洁)

public class WeatherTools {
    @Tool(description = "获取指定城市的当前天气信息")
    public String getCurrentWeather(String city) {
        // 实际调用天气 API
        return city + ":25°C,晴天,东风3级";
    }
}

// 使用
String response = chatClient.prompt()
    .user("北京明天天气怎么样?")
    .tools(new WeatherTools())
    .call()
    .content();
1
2
3
4
5
6
7
8
9
10
11
12
13
14

方式二:MethodToolCallback(程序化定义)

ToolCallback toolCallback = MethodToolCallback.builder()
    .toolDefinition(ToolDefinition.builder()
        .name("getCurrentWeather")
        .description("获取当前天气")
        .build())
    .toolMethod(WeatherTools.class.getMethod("getCurrentWeather", String.class))
    .toolObject(new WeatherTools())
    .build();
1
2
3
4
5
6
7
8

方式三:FunctionToolCallback(函数式定义,兼容旧版)

@Bean
public ToolCallback weatherTool() {
    return FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
        .description("获取指定地点的当前天气")
        .inputType(MockWeatherService.Request.class)
        .build();
}
1
2
3
4
5
6
7

# 核心组件

组件 作用
ToolCallback 工具回调接口,定义工具的执行逻辑
ToolDefinition 工具定义,包含名称、描述、参数 Schema
ToolCallingManager 工具执行生命周期管理器
ToolCallbackResolver 动态工具名称解析器
ToolCallAdvisor 以 Advisor 方式控制工具调用流程

# MCP(模型上下文协议)

作用:MCP(Model Context Protocol)是一个标准化协议,用于让 AI 应用与外部工具 / 数据源建立标准化连接。可以理解为 **"AI 世界的 USB 接口"** —— 定义了一套统一规范,任何遵循 MCP 协议的工具 / 服务都可以即插即用地接入 AI 应用。

与 Tool Calling 的区别:

  • Tool Calling:工具定义在自己的应用代码中,是 "本地工具"
  • MCP:工具由独立的 MCP Server 提供,可以是远程服务、第三方组件,是 "远程标准化工具"。MCP 让工具的提供方和使用方彻底解耦

# 核心组件

组件 作用
MCP Client Boot Starter MCP 客户端启动器,让 Spring AI 应用作为客户端连接 MCP 服务
MCP Server Boot Starter MCP 服务端启动器,将你的服务暴露为 MCP 服务供其他 AI 应用调用
STDIO and SSE MCP Server 基于标准输入输出 + SSE 传输协议的服务端
Streamable-HTTP MCP Server 基于 HTTP 流式传输的服务端
Stateless Streamable-HTTP MCP Server 无状态版本,适合无状态微服务架构
MCP Annotations 注解式开发 MCP 客户端 / 服务端
MCP Security MCP 安全机制(开发中)

# 传输方式对比

传输方式 说明 适用场景
STDIO 标准输入输出,通过子进程通信 本地命令行工具、桌面应用
SSE Server-Sent Events,单向流 简单的远程服务
Streamable-HTTP 基于 HTTP 的双向流式通信 生产环境的远程 MCP 服务
Stateless Streamable-HTTP 无状态版本 K8s 等无状态微服务架构
<!-- 引入 MCP Client Starter -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId>
</dependency>
1
2
3
4
5
# application.yml 配置连接一个文件系统 MCP Server
spring:
  ai:
    mcp:
      client:
        stdio:
          servers:
            filesystem:
              command: npx
              args: ["-y", "@modelcontextprotocol/server-filesystem", "/data"]
1
2
3
4
5
6
7
8
9
10

配置完成后,MCP Server 提供的工具(如读取文件、搜索文件等)会自动注册为 AI 可调用的工具,无需手动编写 ToolCallback。


# RAG(检索增强生成)

作用:在 LLM 生成回答时,先从外部知识库中检索相关信息,再将检索到的内容作为上下文注入提示词,让模型基于这些真实数据生成更准确的回答。核心解决 LLM "知识过时" 和 "缺乏私有数据" 的问题。

与微调(Fine-tuning)的区别:

  • RAG:不修改模型参数,通过外部数据增强回答,实时性强,成本低
  • 微调:修改模型参数,让模型内化新知识,适合需要改变模型风格 / 能力的场景

与 Tool Calling 的区别:

  • RAG:从大量非结构化文档中模糊检索相关片段,适合问答、知识咨询
  • Tool Calling:调用精确的 API 获取精确结果,适合查天气、数据库查询、执行操作

# RAG 完整流程

  1. 数据准备阶段:文档读取 → 文本切块(Chunking) → 向量化(Embedding) → 存入向量数据库
  2. 查询阶段:用户提问 → 问题向量化 → 向量数据库检索相似文档 → 取出最相关的文档片段
  3. 生成阶段:将检索到的文档片段 + 用户问题拼接为提示词 → 调用 LLM 生成回答

# 核心组件

Spring AI 通过 QuestionAnswerAdvisor 实现 RAG 功能,它是一个 Advisor,自动完成检索和注入流程:

// 配置 RAG Advisor
ChatClient chatClient = ChatClient.builder(chatModel)
    .defaultAdvisors(
        QuestionAnswerAdvisor.builder(vectorStore)
            .searchRequest(SearchRequest.builder()
                .similarityThreshold(0.7)  // 相似度阈值
                .topK(5)                    // 返回前5个最相关文档
                .build())
            .build()
    )
    .build();

// 用户提问时,Advisor 自动检索向量库并注入上下文
String answer = chatClient.prompt()
    .user("公司的年假政策是什么?")
    .call()
    .content();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# ETL Pipeline(数据管道)

作用:ETL(Extract-Transform-Load)管道,是 RAG 数据准备阶段的核心工具。负责从各种数据源读取原始数据,转换为标准的 Document 格式,最终加载到向量数据库中。

# 三个阶段

阶段 组件 作用
Extract(抽取) DocumentReader 从各种数据源读取数据(PDF、Word、HTML、JSON、文本文件等)
Transform(转换) DocumentTransformer 对文档进行处理(文本切块、关键词提取、元数据增强等)
Load(加载) DocumentWriter 将处理后的文档写入目标(通常是向量数据库)

# 内置的 DocumentReader

Reader 说明
TextReader 读取纯文本文件
JsonReader 读取 JSON 文件
PagePdfDocumentReader 按页读取 PDF
ParagraphPdfDocumentReader 按段落读取 PDF
TikaDocumentReader 基于 Apache Tika,支持 1000+ 种文件格式(Word、Excel、PPT 等)
HtmlDocumentReader 读取 HTML 网页

# 内置的 DocumentTransformer

Transformer 说明
TokenTextSplitter 按 Token 数切块(最常用)
ContentFormatTransformer 内容格式转换
KeywordMetadataEnricher 自动提取关键词并添加到元数据
SummaryMetadataEnricher 自动生成摘要并添加到元数据
// ETL 完整流程示例:读取 PDF -> 切块 -> 存向量库
PagePdfDocumentReader reader = new PagePdfDocumentReader(
    new ClassPathResource("company-policy.pdf")
);
List<Document> documents = reader.read();

// 文本切块
TokenTextSplitter splitter = new TokenTextSplitter();
List<Document> chunks = splitter.apply(documents);

// 存入向量数据库
vectorStore.add(chunks);
1
2
3
4
5
6
7
8
9
10
11
12

# Vector Databases(向量数据库)

作用:向量数据库是专门用于存储和检索向量数据(高维浮点数组)的数据库。在 AI 场景中,文本经过 Embedding 模型转换为向量后存入向量库,查询时通过计算向量间的相似度(余弦相似度、欧氏距离等)来找到语义最相关的内容。它是 RAG 的核心基础设施。

与传统关系型数据库的区别:

  • 关系型数据库(MySQL):精确匹配, WHERE name = '张三'
  • 向量数据库:语义相似匹配,"搜索与 ' 如何提高代码质量 ' 语义最接近的文档片段"

Spring AI 1.1.7 支持 20+ 种向量数据库,通过统一的 VectorStore 接口抽象,切换数据库只需更换依赖和配置:

# 向量数据库详细对比

# PGvector

项目 说明
是什么 PostgreSQL 的向量搜索扩展插件
核心优势 直接在现有 PostgreSQL 上添加向量能力,无需引入新数据库;SQL 生态成熟,运维团队熟悉
适用场景 已有 PostgreSQL 基础设施的团队、中小规模数据集(百万级以下)、希望一个库同时存业务数据和向量数据
劣势 大规模向量检索性能不如专业向量库(千万级以上会有瓶颈)
与其他的区别 最大优势是 "零额外基础设施",对于已有 PG 的团队来说成本最低

# Chroma

项目 说明
是什么 轻量级开源向量数据库,专为 AI 应用设计
核心优势 部署简单(Docker 一键启动)、API 友好、支持内存和持久化两种模式
适用场景 开发测试环境、个人项目、快速原型验证
劣势 不适合大规模生产环境,集群能力弱
与其他的区别 开发体验最好,上手最快,但生产能力不如 Milvus、Qdrant

# Milvus

项目 说明
是什么 高性能分布式向量数据库,国内 Zilliz 公司开源
核心优势 十亿级向量秒级检索、分布式架构、支持多种索引类型(IVF、HNSW、GPU 索引等)
适用场景 大规模生产环境、十亿级向量数据、对检索性能要求极高的场景
劣势 部署复杂度高(依赖 etcd、MinIO 等组件)、运维成本较高
与其他的区别 性能天花板最高,国内社区活跃,中文文档丰富,是国内企业级 RAG 的首选

# Redis

项目 说明
是什么 Redis Stack 提供的向量搜索模块(RediSearch)
核心优势 极低延迟(内存操作)、已有 Redis 集群可直接复用、支持混合查询(向量 + 标签过滤)
适用场景 对延迟要求极高的实时场景、已有 Redis 基础设施、中小规模数据集
劣势 内存成本高、数据规模受内存限制
与其他的区别 延迟最低,但成本最高(纯内存),适合对响应速度有极端要求的场景

# Elasticsearch

项目 说明
是什么 Elasticsearch 8.x+ 原生支持向量检索(dense_vector 字段 + kNN 搜索)
核心优势 同时支持全文检索 + 向量检索的混合搜索、生态成熟、运维工具丰富
适用场景 已有 ES 集群的团队、需要全文检索 + 语义检索混合的场景
劣势 向量检索性能不如 Milvus 等专业向量库、JVM 内存占用大
与其他的区别 最大优势是 "全文检索 + 向量检索" 一体化,不用维护两套系统

# MongoDB Atlas

项目 说明
是什么 MongoDB Atlas 的向量搜索服务(Atlas Vector Search)
核心优势 文档型存储天然适合存储非结构化数据和元数据、与 MongoDB 生态无缝集成
适用场景 已有 MongoDB 基础设施、需要灵活 Schema 的场景
劣势 需要 Atlas 云服务(本地部署的 MongoDB 不支持向量搜索)
与其他的区别 适合 "文档 + 向量" 混合存储的场景,Schema-free 的灵活性是优势

# Neo4j

项目 说明
是什么 图数据库 + 向量搜索能力
核心优势 同时支持图关系查询和向量检索、适合知识图谱 + RAG 的融合场景
适用场景 知识图谱应用、需要关系推理 + 语义检索的复杂场景
劣势 纯向量检索性能不如专业向量库
与其他的区别 唯一一个支持 "图关系 + 向量" 融合查询的选项

# Pinecone

项目 说明
是什么 全托管的云原生向量数据库
核心优势 零运维、自动扩缩容、全球分布式部署
适用场景 不想运维向量库、追求开箱即用的团队
劣势 纯云服务,数据在海外、价格较贵、网络延迟
与其他的区别 最省心的方案(全托管),但对国内用户有网络和数据合规问题

# Qdrant

项目 说明
是什么 Rust 编写的高性能向量搜索引擎
核心优势 性能极高(Rust 无 GC)、支持丰富的过滤条件、云服务和私有化部署都支持
适用场景 对性能要求高、需要复杂过滤条件的场景
劣势 社区相比 Milvus 较小、中文资料较少
与其他的区别 性能与 Milvus 同级,但更轻量,单机部署更简单

# Weaviate

项目 说明
是什么 开源向量搜索引擎,支持模块化扩展
核心优势 内置向量化模块(不需要单独调 Embedding API)、GraphQL 查询接口
适用场景 希望数据库自带向量化能力、偏好 GraphQL 的团队
劣势 性能不如 Milvus/Qdrant
与其他的区别 唯一一个内置向量化的数据库,其他都需要先调 Embedding 模型再存入

# 其他支持的向量数据库

数据库 说明
Azure AI Service 微软 Azure 的 AI 搜索服务,企业级,与 Azure 生态深度集成
Azure Cosmos DB 微软全球分布式数据库的向量搜索能力
Apache Cassandra 分布式 NoSQL 数据库 + 向量扩展,适合超大规模写入场景
Couchbase 分布式文档数据库 + 向量搜索
GemFire VMware 的内存数据平台 + 向量能力
MariaDB MariaDB 11.7+ 支持向量字段,与 PGvector 类似的 "关系库 + 向量" 方案
OpenSearch AWS 开源的搜索引擎(ES 分支),与 ES 类似但 AWS 生态更友好
Oracle Oracle 23ai 版本原生支持向量,适合已有 Oracle 基础设施的企业
SAP Hana SAP 内存数据库 + 向量能力,适合 SAP 企业客户
Typesense 轻量级开源搜索引擎 + 向量检索

# 如何选择向量数据库?

场景 推荐方案
已有 PostgreSQL,中小规模 PGvector
已有 Elasticsearch Elasticsearch
已有 Redis,对延迟要求极高 Redis
十亿级数据,国内生产环境 Milvus
追求性能 + 轻量部署 Qdrant
开发测试、快速原型 Chroma
知识图谱 + RAG Neo4j
不想运维,全托管 Pinecone(海外)/ Milvus Cloud(国内)
已有 MongoDB MongoDB Atlas
// 统一的 VectorStore 接口,切换数据库只需换实现
@Autowired
VectorStore vectorStore;

// 存入向量
vectorStore.add(List.of(
    new Document("Spring AI是一个AI应用开发框架"),
    new Document("它支持20多种向量数据库")
));

// 相似度搜索
List<Document> results = vectorStore.similaritySearch(
    SearchRequest.builder()
        .query("什么是Spring AI?")
        .topK(3)
        .similarityThreshold(0.7)
        .build()
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# Observability(可观测性)

作用:对 AI 相关操作提供指标(Metrics)、追踪(Traces)、日志(Logs) 三个维度的可观测能力。可以监控 Token 使用量、请求延迟、模型调用次数、Advisor 执行情况等。

集成方式:基于 Spring Boot Actuator + Micrometer,天然支持 Prometheus + Grafana 的监控体系。Advisor 也参与 Observability 栈,可以查看每个 Advisor 的执行指标和追踪信息。

监控维度:

  • ChatModel 调用次数、延迟、Token 消耗
  • Embedding 请求量、向量维度
  • Tool Calling 执行次数、成功 / 失败率
  • Advisor 链路追踪
  • 向量数据库查询延迟

# Model Evaluation(模型评估测试)

作用:评估 AI 模型生成内容的质量和准确性,防止模型幻觉(hallucination)。典型用法是对加载到 Vector Store 中的文档执行 RAG 查询,然后评估响应是否与用户问题相关、是否忠于原始文档。

评估方式:

  • 相关性评估:回答是否与问题相关
  • 忠实度评估:回答是否忠于检索到的源文档(没有编造内容)
  • LLM-as-a-Judge:用一个 LLM 来评估另一个 LLM 的输出质量

# Development-time Services(开发时服务)

作用:类似 Spring Boot 的 Docker Compose 集成,在开发阶段自动启动依赖的 AI 基础设施。比如启动项目时自动拉起 Ollama 容器、向量数据库容器等,免去手动管理开发环境的麻烦。

工作方式:在 compose.yaml 中定义好依赖的服务,Spring Boot 启动时自动检测并启动这些容器。

# compose.yaml
services:
  ollama:
    image: ollama/ollama
    ports:
      - "11434:11434"
  chroma:
    image: chromadb/chroma
    ports:
      - "8000:8000"
1
2
3
4
5
6
7
8
9
10

# Testcontainers(测试容器集成)

作用:在自动化测试阶段,通过 Testcontainers 自动拉起 AI 相关的 Docker 容器(如 Ollama、Chroma、PGvector、Milvus 等),实现集成测试的自动化。测试完成后容器自动销毁,环境干净无残留。

与 Development-time Services 的区别:

  • Development-time Services:用于开发阶段,容器一直运行
  • Testcontainers:用于测试阶段,容器随测试生命周期创建和销毁
@SpringBootTest
@Testcontainers
class RagIntegrationTest {

    @Container
    static ChromaDBContainer chroma = new ChromaDBContainer("chromadb/chroma");

    @Test
    void testRagQuery() {
        // 测试 RAG 查询逻辑
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
上次更新: 5/24/2026, 2:55:39 PM
ollama本地部署

← ollama本地部署

Theme by Vdoing | Copyright © 2023-2026
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式