
如果你准备用 Spring AI 做一个 RAG 知识库项目我劝你先别急着敲代码。任何一次环境安装环节的抖动都会在后面变成一小时又一小时的排查时间。这篇是 SpringAI 集成 RAG 实操的上篇核心只干一件事把 PostgreSQL pgvector 这套存储底座装好、验证通。选型理由我也会讲透因为你只有理解了为什么用它后面写 Spring AI 代码时才不会踩到存储设计上的坑。这篇文章适合已经有 Java 基础、想从零跑通 RAG 的开发者也适合被各种教程里先装这个再装那个绕晕的人。网上关于 RAG 的教程很多但大部分都是从 Python 生态切入的切到 Spring AI 时环境阶段就断了层有人让你装 Python有人让你装 Node还有人让你装各种依赖节点。实际把 Spring AI、RAG、postgresql、pgvector 这组词拆开看后端环境安装的刚性需求没有想象中那么多。这篇我先带你厘清什么必须装、什么可以不装再给出一套可复现的安装流程。1. 为什么选型是 PostgreSQL pgvector先把理由讲透1.1 RAG 流程里存储层到底在扛什么活RAG 的整体链路是把文档切块 → 对每一块做 embedding 向量化 → 把文本块 元数据 向量一起存起来 → 用户提问时再把问题向量化 → 在存储里做相似度召回 → 把召回结果拼进 prompt 交给大模型。这个链路里有一个隐蔽但关键的问题大多数业务系统本身就用关系型数据库而 RAG 通常不是独立存在的功能它往往要跟用户体系、权限、历史记录、业务标签耦合在一起。如果你选择专门的向量数据库等于在系统里额外引入一套存储引擎。数据双写、事务一致性、权限打通、备份恢复每一项都要单独处理。而 PostgreSQL pgvector 的思路是在现有关系库里直接增加一个 vector 列类型和配套索引一套库同时搞定业务数据与向量检索。我用一个生活类比普通数据库像一个仓库每件货都有编号只能按编号精确找向量数据库像是给每件货配了一张语义画像你可以描述大概长这样的东西来搜索。pgvector 就是给 PostgreSQL 这个传统仓库装了画像检索能力货还是那些货编号规则也没变。1.2 pgvector 与主流向量库的定位差异很多文章一上来就对比 Milvus、Qdrant、Weaviate、Elasticsearch但忽略了最重要的一点不同规模、不同团队条件选型逻辑完全不一样。我截一张常见对比表给你参考维度pgvectorMilvusQdrantElasticsearch dense_vector部署复杂度极低扩展即用高依赖 etcd、对象存储等中单机部署简单集群复杂较高ES 本身就很重向量索引HNSW / IVFFlatHNSW / IVF / DiskANN 等HNSWHNSW元数据过滤直接走 SQL WHERE能力极强支持但过滤逻辑受分区限制支持 Payload 过滤较灵活与 ES Query DSL 结合Java/Spring 生态Spring AI 原生实现有 SDK但集成代码自己写有 SDKSpring Data ES适用规模千万级以内体验良好十亿级、百亿级最佳亿级左右千万级偏日志检索运维成本随 PostgreSQL 走零额外组件高中高我的观点很直接如果你的向量规模在千万级以内团队本来就在用 PostgreSQL又不想多伺候一套中间件pgvector 是最平滑的选择。它不炫酷但稳定可靠而且你为 MySQL、Oracle 积累的 SQL 能力、备份恢复能力、监控体系都能直接复用。1.3 Spring AI 对 pgvector 的原生支持Spring AI 在 VectorStore 抽象下提供了多种实现PgVectorStore 是其中非常成熟的一个。它把表结构、索引创建、相似度检索、元数据过滤都封装好了。你在 Java 代码里只需要注入 VectorStore调用store()写入、similaritySearch()检索即可具体 SQL 由框架生成。这一点在环境阶段意味着PostgreSQL 侧必须把 vector 扩展和必要的索引类型配置好否则 Spring AI 启动时自动建表或写入向量会直接报错。这也是为什么我要把环境安装单独写一篇——很多人在 Spring AI 代码里配置了半天最后发现是底层数据库没有开启扩展这种问题看报错信息往往还不太直观。2. 环境版本矩阵先定版本再谈安装2.1 完整版本清单安装前先定版本这是我最想强调的习惯。很多环境问题都源于能装上但各个组件版本互相不认识对方。以现阶段 Spring AI 稳定线来看我建议采用这套组合组件版本建议说明JDK17LTSSpring Boot 3.x / Spring AI 硬性基线Maven3.9.x构建和依赖管理IntelliJ IDEA2024.x开发 IDEDocker Desktop最新稳定版推荐用于跑 PostgreSQL 容器PostgreSQL16pgvector 兼容性好教程资源最丰富pgvector0.7.x随镜像自带或本机编译安装这套组合我实测下来最稳无论 Windows 还是 macOS 都适用。Linux 服务器上部署时除 IDEA 不必安装外其余一致。2.2 为什么 JDK 必须 17 起步Spring AI 的底层是 Spring Boot 3.x Spring Framework 6.x这两个框架的基线就是 JDK 17。换句话说JDK 8 的老项目想直接引入 Spring AI依赖解析那关就过不去。网上还能搜到一些旧教程让你用 JDK 8那是基于早期 Spring AI 0.2.x、0.3.x 的年代现在已经没有参考价值了。有人会问那就直接上 JDK 21 不行吗可以JDK 21 也是 LTSSpring AI 在其上完全能跑。但对于大多数团队17 和 21 在 Spring AI 开发上没有本质区别反而是 17 在各类中间件、持续集成镜像里的兼容性验证更充分。如果不想当小白鼠选 17 就对了。2.3 PostgreSQL 版本怎么选15、16、17 甚至 18PostgreSQL 的版本演进比较快这几年几乎一年一个大版本。热搜词里有人搜 postgresql 15 18区别说明很多人被版本号困扰。我的建议是不是你机器上有哪个数据库版本就用哪个而是要看 pgvector 的兼容表。pgvector 是作为 PostgreSQL 扩展存在的每个 pgvector 版本支持的 PostgreSQL 主版本有限。选择 PostgreSQL 16 的原因很现实它是目前兼容验证最充分的大版本Docker 镜像 tag 成熟遇到问题在搜索引擎里几乎都能找到现成答案。17 虽然更新但在一些云数据库、老版本备份恢复工具上兼容性还没完全跟上。18 更不用急除非你有明确需求。版本选型有个原则生产环境和开发环境必须保持一致的大版本。你不能开发环境用 16、生产环境用 15否则开发时跑得好好的 SQL生产上因为扩展或语法差异翻车这种坑我见过不止一次。2.4 别急着装 Python 和 Node先搞清楚谁是必需在安装之前我把这个容易让人走弯路的问题先说掉。热搜词里大量出现 python环境安装、nodejs安装及环境配置、要安装缺失的节点、甚至 comfyui-man。如果你是从 ComfyUI 这类 Python 工作流转过来的会本能地认为跑 RAG 也要先装 Python、安装一堆 pip 依赖。这是最容易浪费半天时间的误解。Spring AI PostgreSQL pgvector 这套后端链路里Python 和 Node 都不是硬性依赖。你调用 Embedding API比如 OpenAI、通义千问的向量接口用的是 HTTP 请求Java 直接搞定不需要本地 Python 环境。只有当你想在本地跑一个 Python 的 embedding 模型或者要自己开发前端界面时才需要它们。而那个 要安装缺失的节点 的提示是 ComfyUI 这类 Python 图形化工作流特有的——Spring AI 这边对应的概念是 Maven 依赖缺失表现形式完全不同。3. 基础三件套JDK、Maven、IDEA 的安装与验证3.1 JDK 17 安装JAVA_HOME 与 Path 的优先级问题JDK 下载建议用 AdoptiumEclipse Temurin发行版或者你已有 Oracle 账号用 Oracle JDK 也行开发体验差别不大。下载时注意选对操作系统和架构Windows 用户选 x64 的 .msi 或 .zipmacOS 用户注意区分 Apple Silicon 和 Intel 两种包。安装本身没什么难度真正的坑在环境变量。Windows 下安装完要设置三个东西新建系统变量JAVA_HOME指向 JDK 安装目录例如C:\Program Files\Eclipse Adoptium\jdk-17.0.x在Path变量中新增%JAVA_HOME%\bin确保Path里旧的 JDK 路径被删除或移到最后为什么特意提顺序因为 Windows 的Path是从前往后解析的如果前面有别的 JDK 路径你输入java -version看到的可能还是旧版本。很多人的问题是我明明装了 17为什么显示 1.8基本就是Path顺序被旧路径占了。安装完打开新的命令提示符窗口验证java -version看到输出中包含openjdk version 17.0.x就算成功。如果输出 1.8 或 11回到环境变量检查顺序。macOS 如果之前装过 Homebrew 的 openjdk注意java_home工具/usr/libexec/java_home -v 17通过 Homebrew 安装的 openjdk 还需要手动软链到/Library/Java/JavaVirtualMachines否则 IDE 可能识别不到。3.2 Maven 3.9 配置阿里云镜像必须换Maven 本身是绿色软件解压就能用但有两个配置必须处理本地仓库位置和镜像地址。先到 Maven 官网下载 3.9.x 的二进制包解压到某个不带空格的路径比如D:\dev\apache-maven-3.9.9Windows或/opt/mavenLinux/macOS。然后配置系统变量MAVEN_HOME再把它加入Path。打开 Maven 安装目录下conf/settings.xml找到mirrors节点加入阿里云镜像mirror idaliyunmaven/id mirrorOf*/mirrorOf name阿里云公共仓库/name urlhttps://maven.aliyun.com/repository/public/url /mirror这段配置的意义是所有依赖都从阿里云镜像拉取而不是直连 Maven Central。国内网络环境下直连 Central 下载依赖的速度和成功率都非常不稳定。mirrorOf写成*表示所有仓库都走这个镜像。同样的思路Spring 项目里还可能用到 Spring 的里程碑仓库如果后续项目里配置了repository也可以把镜像对应添加。不要只配全局镜像就完事——如果你用过 corporate 仓库或者私服要注意私服地址可能会被 mirrorOf*劫持导致发布依赖到私服失败。这是题外话本地开发阶段用*没问题。验证 Mavenmvn -v输出能看到 Maven 版本、Java 版本、系统路径。其中 Java 版本应该显示 17。3.3 IDEA 安装与对 Spring 项目的支持差异IntelliJ IDEA 有两个版本免费开源的 Community 和收费的 Ultimate。如果你要开发 Spring Boot 项目我的建议是有条件用 Ultimate 的试用版因为内置 Spring Initializr 向导新建项目时能从 start.spring.io 直接拉骨架省去很多手动劳动。没有授权的情况下用 Community 也能开发 Spring Boot只是没有专门的 Spring 向导需要自己去 start.spring.io 网页下载项目压缩包再导入。IDEA 安装好之后要做两件小事确认 Project SDK 指向你装的 JDK 17File - Project Structure - Project - SDK里添加。配置 Maven 使用本地安装的版本Settings - Build, Execution, Deployment - Build Tools - Maven把 Maven home path 指向你的安装目录User settings file 指向conf/settings.xml。这一步特别多人忽略IDEA 自带了 Maven但如果你不手动指向你已经配置好阿里云镜像的settings.xmlIDEA 内置 Maven 会走默认仓库下载依赖依然慢。手动指过去之后你在 IDEA 里构建 Spring 项目依赖下载速度才会有本质改善。4. PostgreSQL pgvector 安装Docker 优先本机备选4.1 路线 A推荐用 Docker Compose 一次性拉起为什么我主推 Docker三个理由第一不用在宿主机上引入一堆 PostgreSQL 依赖第二版本切换成本极低想从 pg16 换 pg17 只需改一行配置第三团队协作时一个 docker-compose 文件就能让所有人都拥有相同环境。pgvector 官方提供了预装扩展的 Docker 镜像不需要在容器里手动编译。先在你项目的根目录创建docker-compose.ymlservices: postgres: image: pgvector/pgvector:pg16 container_name: rag-postgres environment: POSTGRES_USER: rag_user POSTGRES_PASSWORD: rag_password POSTGRES_DB: rag_db TZ: Asia/Shanghai ports: - 5432:5432 volumes: - pgdata:/var/lib/postgresql/data - ./init.sql:/docker-entrypoint-initdb.d/init.sql healthcheck: test: [CMD-SHELL, pg_isready -U rag_user -d rag_db] interval: 5s timeout: 5s retries: 5 volumes: pgdata:在这个目录下再创建一个init.sql内容极简CREATE EXTENSION IF NOT EXISTS vector;这个是启动初始化脚本会在 PostgreSQL 容器第一次初始化数据库时自动执行把 vector 扩展建到默认库 rag_db 里。之后每次数据卷已存在脚本不会重复执行但扩展已经生效也不影响。然后启动docker compose up -d启动后查看日志docker logs -f rag-postgres看到类似database system is ready to accept connections的日志说明启动成功。此时 PostgreSQL 已经跑在宿主机的 5432 端口上。4.2 路线 B本机安装 PostgreSQL 并手动添加扩展如果你不想用 Docker或者公司电脑不允许跑容器那么走本机安装路线。Windows 用户直接下载 EDB 的安装包EnterpriseDB 提供的一键安装器安装时注意记住端口、超级用户 postgres 的密码。安装完成后打开 SQL Shellpsql连接然后执行CREATE EXTENSION IF NOT EXISTS vector;但问题是官方 EDB 安装包默认不带 pgvector你还需要另外下载 pgvector 的 Windows 安装包或者自己编译。这正是我推荐 Docker 的原因——本机安装路线非常容易在扩展这一步卡住。Linux 用户稍好一些。以 Ubuntu 为例如果你从 PostgreSQL 官方 PGDG 源安装可以这样sudo apt install postgresql-16 postgresql-16-pgvector这样扩展会和数据库一起装好。如果没有postgresql-16-pgvector这个包说明你的源没有 PGDG需要先添加 PostgreSQL 官方源。然后同样执行CREATE EXTENSION vector;。如果你非要走源码编译路线那需要准备postgresql-server-dev-16、make、gcc然后在 pgvector 源码目录执行make sudo make install再用 psql 执行建扩展语句。这个路线踩坑率最高原因我在下一节展开讲。4.3 两种方案取舍与我的建议先用一句话总结我的建议能上 Docker 就不要本机装。尤其是 pgvector 这种需要编译的扩展本机安装的折磨并不在于装不上而在于版本对不上。pgvector 扩展本质上是一段编译好的共享库它必须和 PostgreSQL 服务端的主版本严格匹配。也就是说你装的是 PostgreSQL 16就必须用针对 PostgreSQL 16 编译的 pgvector你用 apt 或者源码编译时工具链里必须有pg_config这个程序而且它指向的版本必须正确。一个很常见的报错是could not open extension control file本质就是服务端里找不到对应版本的vector.control文件。Docker 镜像pgvector/pgvector:pg16把这些问题都封装掉了镜像维护者已经确保扩展版本和 PostgreSQL 16 匹配你只需要启动容器即可。后续 Spring AI 集成阶段你在配置文件里写数据库地址时连接的就是这个容器。如果选本机路线建议至少把 PostgreSQL 版本和 pgvector 版本写进项目的 README否则过三个月你自己都会忘。5. 装完之后验证清单与高频坑排除5.1 五条验证命令确保环境真的可用容器起来后先进入 psqldocker exec -it rag-postgres psql -U rag_user -d rag_db然后依次执行下面五条验证-- 1. 查看已经安装的扩展 SELECT extname, extversion FROM pg_extension WHERE extname vector; -- 2. 测试 vector 类型是否存在 SELECT [1,2,3]::vector; -- 3. 测试余弦距离算子 SELECT [1,2,3] [4,5,6]; -- 4. 测试欧氏距离算子 SELECT [1,2,3] - [4,5,6]; -- 5. 测试负内积算子 SELECT [1,2,3] # [4,5,6];第 2 条如果输出[1,2,3]说明 vector 类型可用第 3、4、5 条会输出标量距离值。到这里存储底座已经证明可以处理向量数据了。建议再建一张测试表验证索引能力CREATE TABLE vector_test ( id bigserial PRIMARY KEY, embedding vector(1536) ); CREATE INDEX ON vector_test USING hnsw (embedding vector_cosine_ops);vector(1536)是按 OpenAI 的 embedding 维度写的如果你后面计划用其他模型比如通义千问的 1024 维把 1536 换成对应维度。HNSW 索引是 pgvector 0.5.0 之后引入的比 IVFFlat 更适合动态插入数据RAG 场景下我建议优先用 HNSW。验证完没什么问题可以把测试表删掉DROP TABLE vector_test;Spring AI 的 PgVectorStore 会自己管理建表和索引不需要你手工建业务表。5.2 高频坑 1扩展控制文件打不开 / 版本不匹配你可能会在 psql 里执行CREATE EXTENSION vector;时报错ERROR: could not open extension control file /usr/share/postgresql/16/extension/vector.control: No such file or directory这个报错已经告诉你答案扩展文件不在它应该在的位置。原因几乎都是版本不匹配——你安装的 pgvector 是针对 PostgreSQL 15 编译的但当前服务端是 PostgreSQL 16或者你编译时用的pg_config指向了另一个 PostgreSQL 安装目录。解决办法就一个方向确保扩展包的版本和 PostgreSQL 服务端大版本一致。用 Docker 镜像时镜像 tagpg16已经帮你锁定了本机 apt 安装时确认包名是postgresql-16-pgvector而不是postgresql-15-pgvector。5.3 高频坑 25432 被占用与环境变量污染启动 Docker 容器时报错Error starting userland proxy: listen tcp4 0.0.0.0:5432: bind: address already in use说明宿主机 5432 已经被占了。先查谁在占用netstat -ano | grep 5432如果是以前装过的 PostgreSQL 服务在跑要么停掉它要么改掉 Docker 映射端口比如宿主机用5433映射容器的5432ports: - 5433:5432注意改了宿主机端口后Spring AI 的 JDBC URL 要写jdbc:postgresql://localhost:5433/rag_db这个很容易疏忽。还有一类问题是环境变量污染。比如PGHOST、PGPORT、PGUSER这些环境变量被设置过psql 连接时会被它们影响让你以为连的是本地库实际连到了其他位置。排查环境问题的时候先echo $PGHOST看看有没有残留。5.4 高频坑 3容器重启数据丢失这是 Docker 相关文章里被反复提及的问题执行了docker compose down而不是docker compose stop而且很倒霉地在down时加了-v参数数据卷被删除所有数据一夜回到解放前。我在上面的 compose 文件里定义了命名卷pgdata只要你不显式加-vdocker compose down只会删容器不会删数据。但如果你手滑执行了docker compose down -v数据卷会被清理。这个命令对 PostgreSQL 来说是毁灭性的没有后悔药。判断数据是否还在可以查看卷列表docker volume ls看到pgdata还在就说明数据还在。5.5 高频坑 4远程连接、时区、命名规则如果你从另一台机器连这个 PostgreSQLDocker 方案下只要防火墙放行 5432 端口即可镜像默认监听所有网卡。但要注意密码认证官方 PostgreSQL 镜像默认使用scram-sha-256认证方式连接时需要在 JDBC URL 里显式带上用户和密码不能依赖系统信任认证。本机安装的 PostgreSQL 默认只监听localhost远程访问必须改两个文件postgresql.conf里的listen_addresses *pg_hba.conf里新增类似host all all 0.0.0.0/0 scram-sha-256的规则改完要重启服务。注意pg_hba.conf是按顺序匹配的越靠前的规则优先级越高如果你前面有一条host all all 127.0.0.1/32 trust新增的远程规则放在它后面也不影响远程连接因为匹配范围不同。时区问题在容器环境里很常见。我在 compose 里设置了TZ: Asia/Shanghai这是为了避免 PostgreSQL 的now()返回 UTC 时间导致时间字段和业务对不上。虽然 Spring AI 的 PgVectorStore 主要存向量和文本但元数据里有时间字段时时区偏差会造成不小困扰。最后说命名规则PostgreSQL 对未加引号的标识符会自动转成小写。Spring AI 自动建表时表名是vector_store你不需要关心大小写问题。但如果你手动建表时用了驼峰命名比如VectorStore后续查询就必须带引号非常麻烦。建议环境阶段就统一使用全小写加下划线的命名风格。5.6 关于缺失依赖别把 Python 工作流的习惯带进来上面提到热搜词里有不少人是被 要安装缺失的节点请先在你的 python 环境中运行 pip install ... 这种提示带偏的。这种提示常见于 ComfyUI 等 Python 图形化工作流它检查的是 Python 环境里的 pip 包是否齐全。而 Spring AI 项目里如果缺依赖Maven 构建时会直接报错比如ClassNotFoundException或Cannot resolve symbol绝不会提示你运行 pip install。所以安装阶段的心态要摆正环境安装不是什么都要装而是按项目需要的最小集来装。Java 后端需要的最小集就是 JDK、Maven、PostgreSQL、pgvector再加一个趁手的 IDE。Docker 也不是必需品它只是让数据库环境更干净。6. 环境就绪后Spring AI 集成前还要确认的三件事6.1 连接串与账号权限Spring AI 的 PgVectorStore 需要数据库账号具备建表、插入、查询、建索引的权限。上面创建的rag_user在容器初始化时就是超级用户开发阶段用它没问题但如果你需要接入现有数据库建议单独建一个最小权限账号CREATE USER rag_app WITH PASSWORD app_password; GRANT CONNECT ON DATABASE rag_db TO rag_app; GRANT USAGE ON SCHEMA public TO rag_app; GRANT CREATE ON SCHEMA public TO rag_app;最后的CREATE权限很重要因为 Spring AI 第一次启动时如果检测到vector_store表不存在会尝试自动建表。如果没有CREATE权限启动会直接失败。JDBC 连接串格式jdbc:postgresql://localhost:5432/rag_db如果你在配置里还要指定 schema可以追加?currentSchemapublic。Spring AI 的自动建表默认在publicschema 下不需要额外配置。6.2 向量维度与 Embedding 模型准备Spring AI 的 PgVectorStore 初始化时需要知道向量维度。这个维度由你选用的 Embedding 模型决定OpenAItext-embedding-3-small1536 维通义千问text-embedding-v31024 维开源的 BGE 系列模型通常 512 维或 768 维写进配置前先去确认你在 Spring AI 里注入的是哪个 EmbeddingModel然后让向量维度与之对齐。如果配置的维度与模型实际输出维度不一致调用store()时会报维度错误的 SQL 异常。这个阶段还涉及 API Key 的准备工作。如果你使用国内模型服务商需要提前申请好 API Key并在项目配置里正确配置 Base URL 和 Key。这个环节和 RAG 的模型调用强相关下一篇讲项目集成时我会展开。6.3 下篇预告项目骨架与 PgVectorStore 实战环境这篇写到这里你已经有了一个带 pgvector 扩展的 PostgreSQL 16。下一篇我会从 Spring Initializr 创建项目开始带你搭一个完整的 Spring AI RAG 工程引入spring-ai-starter、配置PgVectorStore、实现文档上传与切块、跑通知识库问答链路。重点会放在 Spring AI 自动建表机制、相似度检索参数调优以及元数据过滤的实现方式上。下一篇真正写代码之前你只需要保证两件事第一本篇的验证命令跑出了正确结果第二准备好一个能用的 Embedding API Key。这两件事都就绪了后面的实操会顺畅很多。我自己的体会是环境安装这件事真的急不得但也不需要过度恐惧。版本对齐、镜像配置、扩展安装顺序每一样都有规矩。你只要按照版本矩阵一步步来最多半天就能把环境拉起来。等下一篇写到 Spring AI 集成时你会发现前面这些无趣的安装步骤反而才是整个项目最省心的部分。