一句话先说结论:pgvector 的
VECTOR(N)维数是建表时写死的,之后不能改;插入的向量维度必须和它精确一致,否则直接expected 1536 dimensions, not 1024报错。这个坑几乎都出在“embedding 模型没固定”或“换模型后旧表没重建”上——而且光改application.yml里的dimensions是不生效的,因为 Spring AI 只在表不存在时才按配置建表,表在就照旧复用。
背景
RAG 里向量数据库存的是 embedding 结果。pgvector 在建列时就要声明维度 VECTOR(1536),它是个硬类型约束——插入一个 1024 维的向量进去,就像往 int 列塞字符串,直接拒。每个 embedding 模型输出的维度是固定的(OpenAI 的 text-embedding-3-small 是 384、text-embedding-3-large 是 3072,通义的 text-embedding-v1 是 1536),所以“模型输出维度”和“表的维度”必须严格一致。
现象
启动或写入时报:
org.springframework.dao.DataIntegrityViolationException:
PreparedStatementCallback; SQL [INSERT INTO public.vector_store ...];
ERROR: expected 1536 dimensions, not 1024
典型特征:
- 有时第一次启动能成功,重启后立刻失败。
- 报错维度在
1536 / 1024 / 1532之间反复横跳。 - 日志里有
Is empty: false,说明表已经存在、维度对不上。
根因分析
坑 1:embedding 模型没固定,输出维度漂移
有些模型本身维度可变。比如通义 text-embedding-v3 可以输出 1024 / 1536 / 2048,如果不显式指定 model,SDK 自动选,第一次启输出 1024、第二次输出 1536——这就是“刚成功又失败”的来源。
坑 2:Spring AI 建表策略——表在就复用
Spring AI 的逻辑是:
if (表存在) {
直接复用现有表结构,完全无视 dimensions 配置
} else {
只有表不存在时才按 dimensions 建表
}
所以你在配置文件里把 dimensions 从 1024 改成 1536,只要旧表还留着,这个配置就完全不生效,照样拿旧维度去校验。
坑 3:明明删了表还在报错
常见于阿里云 RDS 这类多 schema 环境:默认 search_path 可能指向别的 schema,你删的是 postgres 库的表,应用实际连的是业务库;或者另一个 schema 里还有同名表。
解决方案
按这条链顺序来:
Step 1:显式固定 embedding 模型
spring:
ai:
dashscope:
embedding:
options:
model: text-embedding-v1 # 固定 1536 维
Step 2:维度与模型强绑定 + 允许初始化 schema
spring:
ai:
vectorstore:
pgvector:
dimensions: 1536
initialize-schema: true
index-type: HNSW
distance-type: COSINE_DISTANCE
Step 3:彻底删掉旧表重建
DROP TABLE IF EXISTS public.vector_store CASCADE;
删完重启,Spring AI 会按新维度建表。成功标志是启动日志里看到:
Creating table: vector_store
embedding VECTOR(1536)
只要还看到 Is empty: false 或旧维度,就说明删错了库/没删干净。
Step 4:排查 schema 干扰
spring.sql.init.mode: never防止schema.sql抢先建表。- JDBC URL 用
?currentSchema=public锁定 schema。 - 确认你删的表和应用实际连的表是同一张(用
SELECT ... WHERE relname='vector_store'查真实维度核对)。
顺带一提:RAG 返回空的坑
维度对上了,还可能有“问什么都说没相关信息”的问题,常见两因:
- 向量库是空的:要先
add/load 文档,再查询;SimpleVectorStore是内存态,重启就丢,得重新灌或改用 PGVector/Redis 这类持久化实现。 - topK 设太大 / 文档 chunk 没切好:
QuestionAnswerAdvisor会把检索到的文档“塞”进 prompt,topK 太大导致 prompt 撑爆 context window,又慢又费 token。切块要做小、检索要有similarityThreshold过滤。
小结
- pgvector 维度是建表写死的,插入必须精确匹配;报维度冲突,先想“模型是不是换了/没固定”。
- 改了
dimensions配置不生效,是因为表已经存在、Spring AI 复用旧 schema——DROP 表重建才对。 - 固定 embedding 模型、锁定 schema、确认删对库,三件事一起做才能根治。
- RAG 空结果先查“向量库是不是空的”和“topK/切块是否合理”。