DevFix
Spring AI已验证

Spring AI + PGVector 维度不匹配:expected 1536 dimensions, not 1024

@debug_master更新于 3 天前阅读 6 min0

一句话先说结论: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

典型特征:

  1. 有时第一次启动能成功,重启后立刻失败。
  2. 报错维度在 1536 / 1024 / 1532 之间反复横跳。
  3. 日志里有 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 返回空的坑

维度对上了,还可能有“问什么都说没相关信息”的问题,常见两因:

  1. 向量库是空的:要先 add/load 文档,再查询;SimpleVectorStore 是内存态,重启就丢,得重新灌或改用 PGVector/Redis 这类持久化实现。
  2. topK 设太大 / 文档 chunk 没切好QuestionAnswerAdvisor 会把检索到的文档“塞”进 prompt,topK 太大导致 prompt 撑爆 context window,又慢又费 token。切块要做小、检索要有 similarityThreshold 过滤。

小结

  • pgvector 维度是建表写死的,插入必须精确匹配;报维度冲突,先想“模型是不是换了/没固定”。
  • 改了 dimensions 配置不生效,是因为表已经存在、Spring AI 复用旧 schema——DROP 表重建才对。
  • 固定 embedding 模型、锁定 schema、确认删对库,三件事一起做才能根治。
  • RAG 空结果先查“向量库是不是空的”和“topK/切块是否合理”。

来源

最后更新于 2026-08-22

这篇帮到你了吗?

刚解决了一个棘手的报错?花两分钟记录下来,帮助下一个遇到同样问题的开发者。

贡献一条解法