16G 内存带不动 Milvus:用 opencode 重写私文简搜聊天版(上篇)

16G 内存带不动 Milvus:用 opencode 重写私文简搜聊天版(上篇)

之前那版私文简搜 DocSolo 是「能搜也能聊」,靠的是 Milvus 存文本向量 + Spring AI Alibaba + Ollama。功能是有了,但 Milvus 这玩意儿是真的吃资源,我那台 16G 内存、2G 显存的机器根本扛不住。这篇记录我用 opencode 把它重写成轻量版的全过程:不碰 Milvus,向量改用本地方案,全文检索用 Lucene,模型还是本地 Ollama。上篇讲清楚为什么重做、怎么做计划、怎么编码、怎么把它第一次跑起来。全程真实记录,包括 opencode 反复犯同一个错误的那些事。

前言

先交代下背景,不熟的同学可以先看我之前的 DocSolo 系列。

私文简搜 DocSolo 是我一直在迭代的一个轻量化文档知识库:把 markdown 文档导进去,建索引,然后既能全文搜索,也能用聊天的方式问它问题。之前那版我结合 Spring AI Alibaba 和 Milvus 做过一次重构,让它「能导入、能聊天」。

问题就出在 Milvus 上。

我的主力机配置很一般:16G 内存、2G 显存,虚拟机最多只能分 8G 内存。Milvus 是分布式的向量数据库,功能强,但部署起来一套组件,内存占用居高不下。我就想做个自己用的小工具,实在没必要、也带不动这么重的东西。

所以这次的目标很明确------做一个简单版

说明
向量库 不用 Milvus,改用本地轻量方案
全文检索 Lucene + HanLP 中文分词
大模型 / 向量模型 本地 Ollama(qwen3.5:4b / nomic-embed-text),还是得用
基础框架 Spring Boot(ivy-starter-cores),不引入 Spring Cloud
AI 接入 Spring AI Alibaba
运行要求 8G 内存内必须能跑

工具我选了 opencode。为什么是它?前面几篇我用过 Trae、Qoder,免费额度用完就得换,这次干脆试试 opencode。下面开始,全程真实记录。

一. 做计划

我没有上来就让它写代码,而是先让它做计划。我把背景、约束、参照的代码都讲清楚,尤其是「内存只有 8G」这条硬约束。

vbnet 复制代码
我想编写一个上传md文档,然后结合文本向量和ollama,最终形成可以通过聊天的方式进行全文搜索,以前编写过类似代码实现方案是milvus和ollama,Lucene 全文检索,HanLP 中文分词,现在将问题是milvus太大,我想改一个小一点的版本, 因为我的脑只有16g内存2g显存,虚拟机最多只能给8g内存。
要求:
1、可以参照Double-AI-Agent-Wrapper中的ivy-service-knowledge-bootstrap代码,Spring ai alibaba访问ai
2、基础框架以ivy-simple-api中的ivy-starter-cores为准,不要求spring cloud
3、一定要在简单的8g内存可运行,ollama qwen3.5:4b nomic-embed-text
4、可以不要mysql保存上传md5检验
5、功能可以参照Double-AI-Agent-Wrapper中的ivy-service-knowledge-bootstrap
6、新建项目名  ivy-chat-docsolo-wrapper,最新项目ivy-chat-docsolo

先做计划

opencode 开始分析,先去看参照代码:

它一上来就想满世界找代码,我赶紧圈定范围------所有代码都在 opencode 目录里,别到处搜。

复制代码
所有内容都在opencode目录,不要搜索其他地方的

计划过程中我还专门问了一个关键问题:如果只用 Lucene、不用向量,那是不是就把检索到的内容直接塞给 Ollama? 这其实就是「要不要做 RAG、向量还有没有必要」的问题。

复制代码
有个问题,仅lucene不要向量,是直接将内容输入到ollama吗

opencode 给了两种方案,我都不太确定,就把我的最终诉求讲死了:先走文本向量,不够再回退 Lucene,最后把检索到的内容喂给 Ollama。我还特意反问了一句:要是把文本向量去掉,那跟我以前用 ES 有啥区别?顺便把文档、swagger 这些也交代了------swagger 不要,因为 knife4j 不支持高版本,都有缺陷。

复制代码
你给的两种方案我不确定,但我的最终要求是:
我想先文本向量,不行再lucene,最终将内容喂给ollama,如果去掉文本向量和我以前使用es有什么区别,上传的md文件和图片放在一起,可以直接访问,当然md要替换一下images
计划形成文档放在ivy-chat-docsolo-wrapper中的doc中,按正规项目开发编写相关文档
这是全新项目ivy-chat-docsolo-wrapper没有创建
先做计划的
文档,swagger不要吧,因为knife4j不支持高版本,都有缺陷

你确定好方案我再看下。如果有选择一定要讲清优缺点,能否完全满足。

结果它又开始犯傻,跑到别的地方去找源码,我得再强调一遍:所有东西都在 opencode 目录里。

复制代码
操,怎么又犯傻了,所有文档都在opencode中,不要在其他地方找源码。
补充 
1、都要实例化,不能一重启就没了
2、ivy-starter-cores的源码复制过来,要修改可以在源码修改。

你看,它又想访问不在当前目录下的文件。这就是 AI 的幻觉,会一直犯同一个错误,真磨人的耐性。

总是犯同一个错误,怎么解??无解???

来回拉扯了几轮,计划总算成型了。整体架构是这样:上传 md → 解析分块 → 一路做向量化存本地,一路写 Lucene 全文索引;提问时先向量检索,不够再回退 Lucene,最后把命中的内容和图片组装成 Prompt 喂给 Ollama,流式返回。

bash 复制代码
┌───────────────────────────── 浏览器 / HTTP 客户端 ─────────────────────────────┐
│  上传 md  │   聊天提问(SSE)   │   访问 /api/data/** 图片与文档                      │
└─────┬────────┴────────┬───────┴───────────────▲───────────────────────────────┘
      │                 │                        │
      ▼                 ▼                        ▼
┌──────────────────────────────────────────────────────────────────────────────┐
│  ivy-chat-docsolo 应用(单进程 Spring Boot,内嵌 Tomcat)                          │
│                                                                              │
│  Controller 层: Import / Chat / File / ModelSwitch                              │
│  ├─ ImportService: 接收上传 → Tika 解析 → 按标题分块                              │
│  ├─ 双写步骤: ① 向量化(nomic-embed-text) 写入 SimpleVectorStore(JSON 文件)         │
│  │           ② 写入 Lucene 全文索引(HanLP + BM25, 磁盘目录)                        │
│  ├─ ChatService: 先向量检索 → 不足回退 Lucene → 提取来源+图片 → 组装 Prompt          │
│  │   ├─ VectorRetriever (SimpleVectorStore)                                       │
│  │   ├─ LuceneSearch  (Lucene BM25 BooleanQuery OR)                             │
│  │   └─ ChatClientProvider (Ollama / DashScope 切换) → 流式回答                    │
│  └─ FileService.netty 静态映射数据目录                                              │
└──────────────────────────────────┬───────────────────────────────────────────┘
                                   │ HTTP (ollama /localhost:11434)
                                   ▼
                     ┌─────────────────────────────┐
                     │  Ollama 本机服务                 │
                     │  对话: qwen3.5:4b               │
                     │  向量: nomic-embed-text         │
                     └─────────────────────────────┘

二. 编码

计划确认完,我让它开始执行。

复制代码
好吧,开始执行计划

它闷头写了一阵,我去看代码,发现目录结构不对

我的项目目录是有固定规矩的:外层用复数,里层用单数,比如 cores → core、services → service、models → model。ivy-simple-api 和 Double-AI-Agent-Wrapper 都是这个结构。这个必须写进 skills,不然后面还会乱。

rust 复制代码
你这个目录结构是不对的,看ivy-simple-api以及Double-AI-Agent-Wrapper,都是s,再放单数的。
如 cores-> core  services->service  models->model
必须按这种目录结构,写进skills

所以说,AI 编码还真不能完全不懂的人来做。当然它是可以完成任务的,这个前面我也说过------就是能完成当前任务,至于以后的任务,以后再说。

AI 编码一定要做非常多的限制,也就是 skills。我管这叫夹逼定律:用规范把代码夹成我们想要的样子。这点很重要。你讲了,它是能写出来的;但你不说,它就瞎搞。

这不就对了吗,结构多清晰。

你看,其实它是可以做得很好的,只是懒(省算力)。这时候就要求我们自己的实力了------你得知道什么是对的,才能把它掰回来。

编码过程中我确认了下进度:

复制代码
什么情况,前面任务完成了吗

Ollama 我也在另一台机器上部署好了,告诉它地址,让它对着这个来:

复制代码
192.168.55.130 ollama部署成功,已启动
目录结构没问题

后面就是等它慢慢生成,反正是要很长时间。

前端页面它也给搞出来了:

我来看源码的时候,又发现一个问题:Maven 的 module 配置不对。

arduino 复制代码
  <module>ivy-starter-cores/ivy-starter-core</module>
        <module>ivy-services/ivy-chat-docsolo</module>
        这样配置不对,要一级一级配置,这样会乱的。

ivy-starter-coresivy-services 这些得一级一级配,不能图省事一把梭,不然会乱。

这种基础错误它也会犯,这个也是铁律,你怎么会这么傻呢。

复制代码
这个也是铁律,你怎么会这么傻呢

三. 初步跑起来

代码写得差不多了,接下来就是验证能不能跑。

3.1 后端代码

先启动 Ollama,把模型拉起来。

后端代码能直接运行,这点还是值得肯定的,没有一上来就报错。

3.2 前端

前端就是常规操作,装依赖、起服务。

arduino 复制代码
npm i
npm run dev

到这一步,后端能跑、前端能跑,看起来一切顺利------好像已经成功了。

但别高兴太早。真正一测试,问题就开始一个接一个地冒出来了。这些问题,以及后面为了「到底几个功能」跟 opencode 反复拉扯的过程,都放下篇讲。

小结

上篇先把背景和搭建过程交代清楚:

关于为什么重做

  • 之前那版 DocSolo 用 Milvus 存向量,功能是全的,但 Milvus 太重,16G 内存、2G 显存的机器带不动
  • 这次目标就是做轻量版:不碰 Milvus,向量用本地方案,全文检索用 Lucene + HanLP,模型还是本地 Ollama,8G 内存内必须能跑

关于做计划和编码

  • 先做计划再动手,把「内存 8G」这条硬约束讲死,把「先向量后 Lucene 再喂 Ollama」的检索链路讲死
  • AI 会反复犯同一个错误(到处找源码、目录结构不规范、Maven 配置乱),得靠 skills 和人工纠偏把它夹回来------这就是「夹逼定律」
  • 好消息是后端能直接跑起来,前端也能起来,第一步算是成了

下篇《说好 3 个功能做成 2 个:用 opencode 调试私文简搜聊天版(下篇)》进入正题:一开始测试,deploy 理解偏差、界面太丑、Ollama 内存不足退出、说好三个功能只做两个......一堆问题排队上场。想看 opencode 怎么被反复「教育」的,下篇见。

end


这篇是「私文简搜 DocSolo」轻量化重写的上篇:因为 Milvus 太重、机器带不动,改用 opencode 重做一个本地轻量聊天知识库。上篇把计划、编码、首次跑通讲完了,真正的考验在下篇。感谢阅读。

相关推荐
愚公搬代码1 小时前
【愚公系列】《WorkBuddy从上手到变现》017-用AI Agent实现公众号自动化运营(从1个号到矩阵:规模化的可能和边界)
运维·人工智能·自动化·小龙虾·workbuddy
6曦轩1 小时前
AI 第一次强到被自己人喊停:它可能自主黑入你的系统
人工智能
GrowthRadar1 小时前
海外广告精细化投放:支持曝光量估算的素材监测工具深度对比
大数据·人工智能·移动广告情报工具·广告素材监测工具·海外广告情报
奈斯先生Vector1 小时前
2026 开发者效能革命:基于创源AIGC 与开源生态的工程化实践、安全沙箱与代码智能体协同
人工智能·算法·架构·prompt·aigc
等一朵映山红1 小时前
深入理解 OpenCV 卷积与滤波:高斯、中值、双边滤波对比
人工智能·opencv·计算机视觉
寒蝉1281 小时前
我要的不是更强的 AI,而是更懂我的 AI
ai编程
znhb991 小时前
焦化厂如何做好脱硫脱硝的精准控制?
大数据·人工智能
别动我齐刘海1 小时前
“三层同步审计”判定掉帧缺失
c语言·c++·人工智能·深度学习·学习·机器学习·机器人
专注数据的痴汉2 小时前
「数据下载」武汉统计年鉴(2009-2025)
大数据·人工智能·信息可视化