老登的永久对话系统开发日志:地基篇

7 阅读4分钟

第一次完整的本地AI系统开发实战,包含数据库设计、向量检索、可编辑提示词和性能优化


📅 开发时间:2024年3月7日

👨‍💻 开发者:neuxiang

🎯 项目目标:
1.构建一个基于大模型的永久对话系统,所有数据本地存储,重启不丢失
2.用户自定义提示词控制
3.用户知识库管理


一、项目背景与技术选型

为什么要做这个项目?

在云端AI服务盛行的今天,数据隐私、离线可用、永久记忆成为许多开发者和企业的核心诉求。本项目旨在打造一个完全本地运行的智能对话系统,所有对话历史、知识库都存储在本地文件中,拷走即迁移,重启不丢失。

📌 技术栈

技术版本用途
Spring Boot3.2.4应用框架
Java17开发语言
Spring AI1.0.0-M6AI应用框架(向量存储)
MyBatis-Plus3.5.8持久层框架
SQLite3.46.0嵌入式数据库
SimpleVectorStore1.0.0-M6文件型向量库
Ollama + Qwen34b本地大模型
Lombok-代码简化
JUnit 5-单元测试

二、核心功能实现

2.1 数据库设计(5张表)

-- 会话表:管理所有对话窗口
CREATE TABLE sessions (id PRIMARY KEY, session_id, name, summary...);

-- 消息表:存储原始对话历史
CREATE TABLE messages (id, session_id, role, content, created_at...);

-- 摘要表:保存增量总结版本
CREATE TABLE summaries (id, session_id, summary, created_at...);

-- 知识库表:存储个人知识
CREATE TABLE knowledge (id, title, content, tags, vector_id...);

-- 向量元数据表:记录向量化状态
CREATE TABLE vector_meta (id, vector_id, entity_type, entity_id...);

2.2 可编辑提示词系统

实现了一个热加载的提示词管理系统,用户可以直接修改 .md 文件,无需重启应用:

// 文件结构
./prompts/
├── system.md           # 系统角色设定
├── chat-template.md    # 对话模板
├── summary-trigger.md  # 总结时机判断
└── summary-content.md  # 总结内容模板

2.3 向量知识库(RAG)

使用 Spring AI 的 SimpleVectorStore 实现文件型向量数据库:

// 添加知识时自动保存到向量库和JSON文件
public void addKnowledge(String title, String content) {
    // 1. 保存到SQLite
    KnowledgeEntity entity = new KnowledgeEntity();
    entity.setContent(content);
    knowledgeMapper.insert(entity);
    
    // 2. 保存到向量库
    Document doc = new Document(content);
    vectorStore.add(List.of(doc));
    
    // 3. 自动持久化到JSON文件
    ((SimpleVectorStore) vectorStore).save(new File("./data/vector-store.json"));
}

2.4 本地大模型集成

选用 Ollama + Qwen3:4b 作为推理引擎,实测性能:

指标 数据 生成速度 36 tokens/秒 首字响应 1.7秒(首次加载) 内存占用 ~3GB 硬件 Apple M4 24GB


三、性能优化挑战

3.1 遇到的挑战

初期通过 Spring AI 官方 Starter 调用时,响应时间长达 10-20秒,用户体验极差。

3.2 排查过程

通过对比测试定位问题:

# 测试Spring API
time curl -X POST http://localhost:8080/api/chat -d '{"message":"Hello"}'
# 耗时: 10-20秒

# 直接测试Ollama API
time curl -X POST http://localhost:11434/api/generate -d '{"model":"qwen3:4b","prompt":"Hello"}'
# 耗时: 8-11秒 ✅ 同样慢!

关键发现:问题不在Spring集成层,而在Ollama本身


四、测试与质量保障

4.1 单元测试覆盖

测试类 测试方法 场景 KnowledgeServiceTest testAddKnowledge 添加知识 testSaveToFile 手动保存 testSearchSimilar 向量搜索 testOnShutdown 关闭自动保存 ChatServiceTest testSendMessage 发送消息 testCreateSession 创建会话 testGetHistory 获取历史

最终成果:37个测试用例全部通过,核心功能稳定可靠。

4.2 构建验证

mvn clean install  # ✅ BUILD SUCCESS

五、项目亮点总结

✅ 完全本地化(有性能问题,待定)

· 不依赖任何云端服务 · 所有数据存在 ./data/ 目录 · 拷走即迁移,重启不丢失

✅ 永久记忆

· SQLite 存储完整对话历史 · VectorStore 存储向量化知识 · 会话摘要自动压缩长对话

✅ 可扩展提示词

· 用户可编辑 .md 文件 · 热加载,修改即时生效 · REST API 支持动态更新

✅ 高性能设计

· 连接池优化 · 流式响应 · 量化模型加速


六、项目结构

persist_chat/
├── src/main/java/com/neuxiang/persistchat/
│   ├── config/          # AIConfig, VectorStoreConfig, HttpClientConfig
│   ├── controller/      # ChatController, KnowledgeController, PromptController
│   ├── service/         # ChatService, KnowledgeService, PromptService, OllamaService
│   ├── mapper/          # 5个MyBatis-Plus Mapper接口
│   └── entity/          # 5个实体类
├── data/                # SQLite数据库 + JSON向量库
├── prompts/             # 可编辑提示词文件
└── pom.xml              # 依赖管理

七、下一步计划

功能 优先级 说明 流式前端 🔥 高 实现文字逐字显示效果 对话总结 ⏸️ 中 自动生成摘要存入向量库 个人知识库⏸️ 中 个人总结数据存入向量库


🎯 最终成果

一个功能完整、性能稳定、完全本地化的永久对话系统,包含:

✅ 多会话对话管理
✅ 永久历史存储
✅ 可编辑提示词
✅ 向量知识库RAG
✅ 本地大模型推理
✅ 完整的单元测试

所有代码已通过测试,可随时部署使用!


📝 技术总结

  1. Spring Boot + MyBatis-Plus 是快速构建持久层的黄金组合
  2. SimpleVectorStore 足够满足中小规模RAG需求
  3. Ollama + Qwen3 在Apple M4上表现一般(36 tokens/秒)
  4. 流式响应 是提升AI对话体验的关键
  5. 可编辑提示词 让非技术人员也能优化AI行为

项目状态: 基础架构完成 | 流式优化中 | 持续迭代