【WMS 仓储系统集成 AI Agent 实战】第 1 讲
系列开篇,这一讲把项目跑起来的地基打好:PostgreSQL 17 + pgvector、Ollama + 三个模型、Spring Boot 3 后端骨架、Vue3 前端骨架。看似是"下载安装"这种没技术含量的活,说实话,我在这步耗掉的时间比写业务代码还多------光 pgvector 就折腾了半天。
本讲复现环境与版本
所有问题都在下面这套真实环境里踩出来、复现并验证过。对不上版本先别急着套解法:
| 项 | 版本/说明 | | --- | --- | | 操作系统 | Windows 11 开发机(消费级显卡,跑 7B q4_K_M 量化) | | JDK | 项目要求 17(本机默认 JAVA_HOME 指向 JDK 8,编译需显式指定------第 8 讲会因此炸一次) | | Maven | 3.9.9(内网 Nexus 私服) | | PostgreSQL | 17.10(Windows 安装版,端口 5432) | | pgvector | v0.8.5-pg17(手动安装编译产物) | | Redis | 7.x | | Ollama | Windows 版,端口 11434 | | Spring Boot | 3.2.10(项目初期)→ 3.5.16(终版) | | Spring AI | 1.0.9 | | 前端 | Vue 3.5.13 + Vite 6.2.4 + pnpm |
本系列每个坑都按四要素记录:版本号 → 复现环境 → 真实报错 → 项目实际现象。报错信息均为项目日志原文(长报错节选关键行)。
我要做什么
先交代背景。我要做的是一个 WMS 仓储系统 + AI 智能体:用户对 AI 说"查询物料 ZL001 的库存",AI 自动调用工具查数据库返回真实数据;说"帮我建一张入库单",AI 真的会把单据写进数据库。
选型思路很朴素:
-
数据不能出企业 → 本地 Ollama 部署,不调任何云端 API
-
业务数据在 PostgreSQL → 向量存储直接用 pgvector 扩展,不引入独立的向量数据库
-
后端 Spring 生态 → Spring AI 1.0.9(当时最新稳定版)
-
前端团队熟 Vue → Vue3 + Element Plus + Vite
听起来很美好。然后我开始装环境,一天踩了三个大坑。
一、PostgreSQL 17 + pgvector:第一个坑
装 PostgreSQL
这个没悬念,官网下载 Windows 安装包,下一步下一步,设好 postgres 用户密码(我用的 123456,测试环境别学),端口默认 5432。
建库:
装 pgvector------坑来了
pgvector 在 Windows 上没有预编译包,需要自己从 GitHub 下载源码对应的 release 产物(或自己编译)。我从 release 页面下了 pgvector-v0.8.5-pg17 的产物,照着网上的教程把 SQL 文件复制过去,然后执行:
📋 问题档案
版本:PostgreSQL 17.10(Windows 安装版)+ pgvector v0.8.5-pg17(手动复制安装)
复现环境 :psql 连接 erp_ai 库,执行
CREATE EXTENSION IF NOT EXISTS vector;,必现
真实报错(psql 原文):
折腾了半天才发现:pgvector 安装需要三部分,我只复制了 SQL 定义,漏了共享库。
| 文件 | 目标路径 | 作用 | | --- | --- | --- | | vector.dll | PostgreSQL/17/lib/ | 共享库(缺了就报 58P01) | | vector.control + vector--*.sql | PostgreSQL/17/share/extension/ | SQL 定义 | | 头文件(可选) | PostgreSQL/17/include/server/extension/vector/ | 编译用 |
补上 vector.dll 重新执行,通过。
划重点 :报 58P01 就是 $libdir 下缺 dll,跟 SQL 文件没关系。另外验证扩展装没装好,直接查:
二、Ollama 安装与模型选型:第二个坑,也是最贵的
装 Ollama
官网下载 Windows 安装包,一路下一步,默认端口 11434。装完 ollama --version 能出版本号就行。
模型怎么选------这里我交了学费
一开始我的方案是"一个模型打天下",选了 hermes3:latest(8B),理由是它在 Ollama 模型库里标注支持 Function Calling。
跑起来之后发现一个诡异的问题:用户问"查询物料 ZL001 的库存",AI 有时候正常调用工具,有时候反问"请输入物料编码"。看日志,反问的那几次,工具调用参数是 param=null。
数字 ID 参数 100% 成功,字符串编码参数时好时坏。
📋 问题档案
版本 :
hermes3:latest(8B,出错)/qwen2.5:7b-instruct-q4_K_M(对照验证)· Spring AI 1.0.9 · Ollama Windows 版复现环境:对话页反复发送同一句「查询物料 ZL001 的库存」
真实报错:无异常抛出------后端日志里工具调用参数是这样的:
- 项目实际现象:同一句话问几次,正常回答与反问「请输入物料编码」交替出现;换成「查 1 号物料的库存」(数字 ID)从未失败。这个规律是定位根因的关键线索。
排查了两天,最后确认是 Hermes3 对字符串参数填充不可靠 。换了 qwen2.5:7b-instruct-q4_K_M 之后,5 次测试 0 次 param=null,问题根治。
最终的三模型配置:
选型依据说清楚:
| 模型 | 为什么选它 | 踩的坑 | | --- | --- | --- | | qwen2.5:7b-instruct-q4_K_M | 中文 + 工具调用参数绑定稳定,q4_K_M 量化约 4.7GB,消费级显卡能跑 | Hermes3 字符串参数填充不可靠 | | qwen2.5:7b | RAG 问答和查询改写不需要 Function Calling | 最初两个场景共用一个模型,浪费显存 | | bge-m3 | 中文 Embedding 效果最好的开源模型之一,1024 维,约 1.2GB | 不配它的话 Spring AI 默认调 mxbai-embed-large,本地没装直接 404 |
📋 问题档案(embedding 404)
版本 :Spring AI 1.0.9(未配置 embedding 模型时默认调
mxbai-embed-large)· Ollama Windows 版复现环境:本地 Ollama 只装了三个模型(见上文),知识库页上传任意文档
真实报错(后端日志):
- 项目实际现象 :上传进度条走到一半失败------文档解析成功、向量化 404。用户第一反应是文件损坏,实际是 embedding 模型没配。报错发生在流程中段而不是开头,是这个问题有迷惑性的原因。
血泪教训:选模型别只看"支持 Function Calling"这个标签,要拿自己真实的业务参数(尤其是字符串编码类)实测参数绑定稳定性。
三、Spring Boot 3 后端骨架:第三个坑
用 Spring Initializr 生成项目,JDK 17,依赖勾了 Web、Security、Validation、Redis。然后手动加 Spring AI、MyBatis-Plus 等依赖。
坑 1:springdoc 版本带崩全家桶
📋 问题档案
版本 :
springdoc-openapi-starter-webmvc-ui 3.0.3(出错)→ 2.5.0(修复)· Spring Boot 3.5.16复现环境 :Win11 + JDK 17 + Maven 3.9.9,
mvn spring-boot:run启动即现
真实报错(启动日志节选):
项目实际现象:引入 springdoc 3.0.3 之后,原本能启动的项目完全起不来,报错信息里没有一个字提到 springdoc。
mvn dependency:tree 一查,springdoc-openapi-starter-webmvc-ui:3.0.3 传递依赖拉进了 Spring Boot 4.0.5 和 Jackson 3.1.0(新包名 tools.jackson),跟项目的 Spring Boot 3.5.x 严重冲突。
解决:降级 springdoc 2.5.0。springdoc 2.x 对应 Spring Boot 3.x,3.0.x 对应 Spring Boot 4.x,版本线千万别搞错。
坑 2:MyBatis-Plus starter 名字差一个词
又一个 factoryBeanObjectType: java.lang.String,这次根因是用了 mybatis-plus-boot-starter------这是 Spring Boot 2 专用版,传递引入的 mybatis-spring 2.1.2 在 Spring 6.x 下 MapperFactoryBean 行为异常。
改成:
artifactId 就差 spring-boot3 这一个词,天壤之别。
📋 问题档案
版本 :
mybatis-plus-boot-starter(误用,传递引入 mybatis-spring 2.1.2)→mybatis-plus-spring-boot3-starter 3.5.8复现环境:Spring Boot 3.5.16 + Spring 6.x,启动必现
真实报错 :与坑 1 完全相同的
factoryBeanObjectType: java.lang.String项目实际现象 :降级 springdoc 后重新启动,一模一样的报错又来了。两个坑叠着出现,一度以为是 springdoc 没降干净,差点走弯路------同一个报错可以有多个根因。
最终 pom.xml 核心依赖
注意 Tika 那个 junrar 排除------它会拖进一堆日志框架冲突,不解压 rar 就没必要留。
application.yml 最小可用配置
三个配置项是血泪换来的,一个都不能少:
-
timeout: 300s------ 默认 90s,模型冷加载时直接超时 -
embedding.options.model: bge-m3------ 不配默认调 mxbai-embed-large -
dimensions: 1024------ bge-m3 输出 1024 维,配错维度向量写入直接报错
📋 问题档案
版本:Spring Boot 3.2.10 / 3.5.16 的 ScriptUtils + PostgreSQL 17
复现环境 :schema.sql 中包含任何
$$ ... $$包裹的函数或触发器,启动即现真实报错:
- 项目实际现象 :schema.sql 里写了触发器(入库单插入后自动更新库存),启动时 SQL 初始化失败。position 65 正是第一个
$$的位置------ScriptUtils 按分号切割语句,把函数体拦腰截断。
还有一个坑提前说:schema.sql 里不要写 $$ ... $$ 美元引用的函数 。Spring Boot 的 ScriptUtils 不认识 PostgreSQL 的 $$ 语法,按分号切割导致语句未闭合报 Unterminated dollar quote。触发器之类的逻辑我全部改用 MyBatis-Plus 的 MetaObjectHandler 在应用层实现。
四、Vue3 前端骨架
前端初始化没什么坑,pnpm 一把梭:
vite.config.js 关键配置是代理------开发环境把 /api 和 /ai 都转发到后端 8089:
这里埋一个后面会炸的雷:前端 SPA 路由我用了 /ai/chat、/ai/knowledge,跟后端 API 的 /ai/** 前缀重叠了。开发环境有 Vite 代理区分不明显,上了 Nginx 之后刷新页面直接 401 JSON 白屏------这个坑留到第 8 讲部署篇细说,先卖个关子。
五、验证环境是否 OK
四步验证:
四步全过,地基打完。
本讲踩坑清单
|
| 坑 | 涉及版本 | 根因 | 解法 | | --- | --- | --- | --- | --- | | 1 | CREATE EXTENSION 报 58P01 | PG 17.10 + pgvector v0.8.5-pg17 | 只复制了 SQL 定义,漏了 vector.dll | lib/vector.dll 必须就位 | | 2 | 工具调用 param=null | hermes3:latest 8B · Spring AI 1.0.9 | Hermes3 字符串参数填充不可靠 | 换 qwen2.5:7b-instruct-q4_K_M | | 3 | 启动报 factoryBeanObjectType | springdoc 3.0.3 · Boot 3.5.16 | 传递依赖拉进 Spring Boot 4 | 降级 springdoc 2.5.0 | | 4 | 同样的报错再犯一次 | mybatis-plus-boot-starter(Boot2 版) | mybatis-spring 2.1.2 与 Spring 6 冲突 | 换 mybatis-plus-spring-boot3-starter 3.5.8 | | 5 | 上传文档向量化 404 | Spring AI 1.0.9(未配 embedding) | 默认调 mxbai-embed-large | embedding.options.model: bge-m3 | | 6 | schema.sql 报 Unterminated dollar quote | Boot 3.2/3.5 ScriptUtils + PG 17 | 不支持 $$ 语法 | 函数逻辑改应用层实现 |
写在最后
环境搭建这步没有"技术含量",但坑密度全场最高。我的建议:每装一个组件立刻验证一次,别攒到最后一起测,出了问题都不知道是谁的锅。
下一篇讲整个系统最核心的架构设计:为什么要两个 ChatClient、keepAlive 怎么配才能让首 token 从 57 秒降到 1 秒、以及一套不重启就能调参的三层配置热加载方案。