ps:(1)现在AI发展太快了,获取知识的方式比前些年更加便捷,但是AI容易出现幻觉,所以学习过程中大家要有分辨是非的能力
(2)先广再深:因为技术实在太多了,发展实在太快了,你不可能啥都能掌握的很深。所以,我感觉目前的学习方式,是先提升自己的知识面,提升知识的广度,然后你用到的时候再去深挖(当然我是根据自己一个普通人的观点去看的,如果是那些天才与大神,可以忽略,毕竟每个人的学习方式有所不同,仅供参考!)
(3)这里通过ai辅助,和大家一块学习Java AI Agent 开发------共勉!!!
其他篇章推荐:
RAG 没死,只是进化了------四种知识库存储方案选型指南
一、先搞清楚一件事:RAG 到底在干嘛?
你去图书馆找答案,有两种方式:
- 方式A:凭记忆回答(容易记错、瞎编)
- 方式B:先翻书找到相关章节,再根据书里的内容回答(靠谱多了)
RAG 就是方式B。它的全称叫 Retrieval-Augmented Generation,翻译过来就是"检索增强生成"。
说白了就是三步:
TypeScript
用户提问 → 先去"知识库"里翻资料 → 把翻到的资料喂给大模型,让它回答
就这么简单,别被英文名词吓到。
二、几个核心概念,用人话解释一遍
在动手之前,先把这几个高频词搞明白。后面反复会用到,现在花10分钟看懂,后面省很多弯路。
什么是大模型(LLM)?
大模型就是 ChatGPT、DeepSeek 这类 AI 对话背后的东西。
你可以把它理解为一个读过海量书籍、什么都知道一点的"文科生"。它能理解你说的话,也能生成文字回答你。
但它有个毛病:记忆停留在训练的那一刻。
比如它2024年训练的,你问它2026年的公司政策,它答不上来,但它不会说"我不知道",而是会一本正经地瞎编。这就叫幻觉(Hallucination)。
RAG 要解决的就是这个问题------给它真实的资料,让它别瞎编。
什么是 Embedding(向量化)?
先说一个前提:计算机不认识文字,只认识数字。
那怎么让计算机"理解"一段文字的意思?答案是把文字变成一串数字,这串数字就叫向量(Vector) ,把文字变成向量的过程就叫 Embedding。
举个例子,下面三句话变成向量后(简化示意,真实向量有上千个数字):
TypeScript
"今天天气真好" → [0.92, 0.15, 0.03, ...]
"今天阳光明媚" → [0.89, 0.18, 0.05, ...] ← 和上面很接近,因为意思相近
"公司年假有5天" → [0.11, 0.02, 0.95, ...] ← 和上面差很远,因为意思完全不同
关键点:意思相近的文字,向量也相近;意思不同的文字,向量差很远。
这样计算机就能通过比较两串数字的"距离",判断两段话是不是在说同一件事。
什么是向量检索?
有了上面的基础,向量检索就好理解了:
用户提了一个问题 → 问题也变成向量 → 去数据库里找跟它最"接近"的几个文档段落
就像你去图书馆,不是按书名一个一个比对,而是直接"闻味道"------"这个书架上的书跟我问的问题最像",然后把那几本书抽出来。
向量数据库就是干这个事的:存向量、找最接近的向量。
什么是 Prompt(提示词)?
Prompt 就是你给大模型的"指令"。
RAG 里的 Prompt 长这样:
TypeScript
你是一个公司政策助手。请根据以下资料回答用户的问题,不要编造信息。
【参考资料】
入职满一年享有5天年假,满五年享有10天年假,满十年享有15天年假。
年假需提前3天申请,经直属主管审批后生效。
...
【用户问题】
我入职三年了,有几天年假?
你看,参考资料是检索来的,用户问题是用户输入的,两个拼在一起就是 Prompt,发给大模型,它就能基于真实资料回答了。
三、不管用哪个框架,RAG 的核心流程都一样
理解了上面的概念,再看这个流程就一目了然了:
TypeScript
┌──────────────────────────────────────────────────────┐
│ 离线准备阶段(一次性) │
│ │
│ 原始文档 → 文档解析 → 文本切块 → 向量化(Embedding) → 存入向量数据库 │
│ (PDF/Word) (提取文字) (切成小段) (变成数字) (存起来) │
└──────────────────────────────────────────────────────┘
↓
┌──────────────────────────────────────────────────────┐
│ 在线问答阶段(每次提问) │
│ │
│ 用户提问 → 问题向量化 → 向量检索相似文档 → 拼Prompt → 大模型生成回答 │
│ ("年假几天") (变成数字) (找到相关段落) (组装问题) (生成答案) │
└──────────────────────────────────────────────────────┘
举个具体例子:
公司有个《员工手册.pdf》,你想让员工用自然语言查政策。
离线阶段(一次性处理):
- 把 PDF 解析成纯文字
- 把文字切成一段一段的(比如每段200字,前后重叠50字)【注意:这里的分段/分割,如果只是简单的去分,会有问题,后面我们抽空再去讨论!!】
- 每段文字通过 Embedding 模型转成向量(一串数字)
- 存到向量数据库里,标好编号
在线阶段(每次有人提问):
- 员工问:"入职两年有多少天年假?"
- 这个问题也转成向量
- 去向量数据库里找最相似的几个段落(比如找到"年假政策"那一段)
- 把段落内容 + 问题一起组装成 Prompt,交给大模型
- 大模型回答:"入职满两年享有 10 天年假,需提前3天申请。"
四、Java 生态里的三大 RAG 框架
目前 Java 生态做 RAG,主流就三条路。各有各的适用场景,不存在谁碾压谁。
方案一:Spring AI
一句话概括:Spring 官方出的 AI 框架,Spring Boot 项目用它最丝滑。
能干什么:
- 和 Spring Boot 自动配置集成,加个依赖就能用
- 原生支持 Milvus、Elasticsearch、PostgreSQL(pgvector)等向量数据库
- 安全、监控、限流这些企业级的东西,直接复用 Spring 生态现有的
- 流式对话(打字机效果)几行代码就搞定
长什么样(核心代码):
java
@Service
public class RagService {
@Autowired
private ChatClient chatClient;
@Autowired
private VectorStore vectorStore;
public String ask(String question) {
// 第一步:去向量数据库里找相关文档
List<Document> docs = vectorStore.similaritySearch(question);
// 第二步:把找到的内容拼起来当上下文
String context = docs.stream()
.map(Document::getContent)
.collect(Collectors.joining("\n\n"));
// 第三步:带上上下文问大模型
return chatClient.prompt()
.system("根据以下资料回答问题:\n" + context)
.user(question)
.call()
.content();
}
}
适合谁:
- 公司项目本身就是 Spring Boot 技术栈
- 需要对接企业级基础设施(权限、监控、日志)
- 团队都是 Java 后端,不想折腾新东西
方案二:LangChain4j
一句话概括:把 Python 那边 LangChain 的思路搬到了 Java,功能最全、最灵活。
能干什么:
- 提供三种 RAG 模式------简单模式、原生模式、高级模式,从入门到精通全覆盖
- 文档处理链路很完整:PDF、Word、TXT、Markdown、HTML 都能解析
- 支持 20 多个模型供应商(OpenAI、通义千问、ChatGLM 等),随时切换
- 不绑定 Spring,Quarkus、纯 Java 项目也能用
长什么样(核心代码):
java
// 1. 把文档塞进向量数据库
EmbeddingStore<TextSegment> store = new InMemoryEmbeddingStore<>();
EmbeddingModel embeddingModel = new AllMiniLmL6V2EmbeddingModel();
Document doc = new Document("公司规定:年假入职满一年享有5天...");
List<TextSegment> segments = new DocumentByCharacterSplitter(200, 50).split(doc);
List<Embedding> embeddings = embeddingModel.embedAll(segments).content();
store.addAll(embeddings, segments);
// 2. 用户提问时,先检索再生成
Embedding questionEmbedding = embeddingModel.embed(question).content();
List<EmbeddingMatch<TextSegment>> matches = store.findRelevant(questionEmbedding, 3);
String context = matches.stream()
.map(m -> m.embedded().text())
.collect(Collectors.joining("\n"));
String answer = chatModel.generate(
"根据以下资料回答:\n" + context + "\n问题:" + question);
适合谁:
- 快速做原型验证,想尽快跑通一个 demo
- 需要对接多种模型(今天用通义,明天换 OpenAI)
- 项目不是 Spring 体系,或者想要更细粒度的控制
方案三:Spring AI Alibaba
ps:之前写过一篇学习文档,可以参考:Spring AI Alibaba 个人学习笔记
一句话概括:阿里在 Spring AI 基础上做的"增强版",针对阿里云生态和企业级 Agent 场景做了大量扩展。
它不只是一个框架,是一整套生态系统:
| 组件 | 干什么用的 | 大白话 |
|---|---|---|
| Agent Framework | 构建单 Agent 和多 Agent 应用 | 让你搭"智能员工",能自己思考、调工具 |
| Graph | 有状态 Agent 的编排框架(用图来编排 AI 工作流 / 多智能体的框架) | 管理"智能员工"的工作流程,有记忆、能长期运行:工作流 + 图结构 + AI 场景"的结合 |
| Studio | 可视化聊天调试窗口 | 给你一个界面,看到 Agent 每一步在想什么、调了什么工具 |
| Admin | 本地可视化管理工具 | 项目管理、运行时追踪、Agent 效果评估,一套全搞定 |
| Spring AI 扩展 | DashScope 模型、MCP 注册中心等 | 对接阿里云百炼平台(通义千问),开箱即用 |
已经有人用它做了什么:
- JManus(Java 多智能体框架):Java 版 Manus,阿里巴巴内部多条业务线在用
- Copilot:AI 编程助手,帮开发者写代码
- DataAgent:用自然语言查数据库,不用写 SQL
- DeepResearch:深度研究工具,自动搜索、分析、总结
适合谁:
- 项目要对接阿里云百炼(通义千问)大模型
- 需要做复杂的 Agent 应用,不只是简单的 RAG 问答
- 团队想要完整的开发工具链(调试、监控、评估)
- 企业级生产环境,需要成熟的落地方案
三个框架怎么选?一张表说清楚
| 你的情况 | 选这个 |
|---|---|
| Spring Boot 项目,需求不复杂 | Spring AI |
| 快速验证想法,功能要求全 | LangChain4j |
| 对接阿里云生态,做复杂 Agent | Spring AI Alibaba |
| 非 Spring 项目 | LangChain4j |
| 要做多 Agent 协作、有状态工作流 | Spring AI Alibaba |
| 什么都想要 | 可以组合用,比如 Spring AI Alibaba 做框架 + LangChain4j 做文档处理 |
五、向量数据库怎么选
向量数据库就是存那些"数字版文档"的地方,常见的选择:
| 向量数据库 | 特点 | 建议 |
|---|---|---|
| Milvus | 开源,云原生,大规模数据首选 | 数据量大、生产环境 |
| Qdrant | 性能好,API 友好 | 中等规模,追求性能 |
| pgvector | PostgreSQL 插件,不用额外部署 | 项目已经在用 PostgreSQL |
| Elasticsearch | 兼容全文检索和向量检索 | 已有 ES 集群 |
| 阿里云 AnalyticDB | 托管服务,Spring AI Alibaba 原生支持 | 用阿里云全家桶的团队 |
| 内存存储 | 不需要部署,直接用 | 开发测试、小规模验证 |
小白建议:先用内存存储跑通流程,搞明白原理了再换真正的数据库。
六、入门路线图
ps:后续有空的话,会把这些demo补上
第 1 周:搞懂概念
要搞懂的东西:
| 概念 | 一句话解释 | 详细看哪 |
|---|---|---|
| 大模型(LLM) | 就是 ChatGPT、通义千问这类 AI 背后的"大脑",能理解问题、生成回答,但可能会瞎编 | 本文第二章 |
| Embedding(向量化) | 把文字变成一串数字,让计算机能"理解"文字的意思。意思相近的文字,数字也相近 | 本文第二章 |
| 向量检索 | 用户提问也变成数字,去数据库里找跟它最"接近"的文档段落。就像图书馆里闻味道找书 | 本文第二章 |
| Prompt(提示词) | 你给大模型的"指令"。RAG 里就是把检索到的资料 + 用户问题拼在一起,喂给大模型 | 本文第二章 |
| RAG | 先翻资料再回答,三步:存文档 → 检索相关内容 → 带着内容问大模型 | 本文第一章和第三章 |
这周不用写代码,把上面的概念看明白就行。
第 2 周:跑通第一个 Demo
选一个框架(建议从 Spring AI 或 LangChain4j 开始),照着官方文档跑通最简单的 RAG:
目标:把一个 txt 文件的内容存进向量库,然后用自然语言提问,得到基于文档内容的回答
这一步大概率会遇到的问题:
- API Key 怎么申请(去对应模型平台注册就行,通义千问有免费额度)
- 依赖冲突(Maven 加依赖时版本对齐就好)
- 网络问题(大模型 API 在国外的话可能需要代理)
这些都是正常经历,耐心解决就好。能跑通第一个 Demo,后面就顺了。
第 3 周:换你自己的真实数据
把 txt 换成你公司的真实文档(PDF、Word),体验一下:
ps:这个关于分段/分割问题、检索准确率问题。后续会补充一篇文章详细来说!!
你会踩到的第一个坑------文档解析:
- PDF 提取文字可能乱码(扫描版 PDF 更麻烦)
- Word 里的表格、图片提取不出来
- 建议先拿纯文字的 PDF 试
你会踩到的第二个坑------文本切块:
- 切太大(比如1000字一段)→ 检索不精确,一段话里混了很多无关内容
- 切太小(比如50字一段)→ 上下文不完整,大模型理解不了
- 一般建议 200~500 字一段,前后重叠 50~100 字
你会踩到的第三个坑------检索效果:
- 用户问"放假几天",但文档里写的是"年假政策",能不能匹配上?
- 向量检索是语义匹配,不是关键词匹配,大部分情况能匹配
- 但如果同一个概念换了很多种说法,效果可能会打折
第 4 周:优化和扩展
基础流程跑通之后,可以开始优化了:
| 优化方向 | 具体做法 |
|---|---|
| 切块策略 | 试试不同的切块大小和重叠比例,看哪个效果好 |
| Embedding 模型 | 试试不同的模型,中文场景可以试通义的 text-embedding 系列 |
| 检索数量 | 找 Top 3 还是 Top 5?太多了会引入噪声,太少可能漏掉关键信息 |
| Prompt 优化 | 在 Prompt 里加上"只根据资料回答,不要编造"之类的约束 |
| 混合检索 | 向量检索 + 关键词检索一起用,提高准确率 |
如果用的是 Spring AI Alibaba,可以打开 Studio 调试界面,直观看到每一步的输入输出,调试效率高很多。
七、容易踩的坑,提前知道不吃亏
坑1:Embedding 模型和大模型是两个东西,都要配
- Embedding 模型 :把文字变成数字(向量),用于检索,不生成文字
- 大模型(Chat Model):理解问题、生成回答的
两个是不同的服务,两个都要配置。新手经常只配了一个,然后报错找不到原因。
坑2:切块大小是门学问
ps:(1)这个关于分段/分割问题。后续会补充一篇文章详细来说!!
(2)但是这里感觉AI有点太死板了,真正的生产场景,肯定不能按"值"进行直接切割的!我记得有个语义切割,后面再讨论
没有万能值,取决于你的文档特点。但有个经验:
TypeScript
技术文档:切小一点(200~300字),因为信息密度高
叙事性文档:切大一点(400~500字),因为需要上下文
坑3:大模型会编造信息,即使你给了资料
即使你把资料喂给它了,它也可能"看漏"或者"过度发挥"。在 Prompt 里加一句约束能缓解:
TypeScript
请严格根据以下资料回答,如果资料中没有相关信息,请直接回答"根据现有资料无法回答该问题"。
坑4:API Key 别硬编码
把 Key 写在 application.yml 里(不是本地yml,其实更安全的做法就是写在nacos中,或者直接写在服务器本地,读的时候直接读本地环境变量配置),别直接写在 Java 代码里。不然提交到 Git 仓库,Key 就暴露了。
TypeScript
# application.yml
spring:
ai:
openai:
api-key: ${AI_API_KEY} # 从环境变量读取
坑5:Token 有上限
大模型一次能接受的输入长度是有限的。如果你检索到了很多段落,全塞进 Prompt,可能超限。一般控制在模型上下文窗口的 60%~70% 以内比较安全。
八、一句话总结
RAG 的本质就是"先翻书再回答"。Java 生态里 Spring AI、LangChain4j、Spring AI Alibaba 三选一,核心流程都一样:文档切块 → 向量化存储 → 检索 → 拼 Prompt → 大模型生成。先跑通 Demo,再逐步优化。