基于 AI 小说工坊项目从零搭建 RAG + Agent 系统的完整记录。
- 时间跨度:持续迭代
- 技术栈:Vue 3 + Spring Boot + LangChain4j + Ollama + Qdrant + 智谱 GLM
一、项目背景与目标
1.1 项目定位
AI 小说工坊 —— 一个面向长篇创作场景的智能助手,核心能力:
- 知识库检索:从私有资料(小说内容、设定、笔记)中检索信息
- RAG 问答:基于检索结果回答问题,避免 LLM 幻觉
- AI 写作:写小说时自动检索设定,保持前后一致
- 创作归档:写完章节后自动摘要、入库,形成"记忆闭环"
1.2 创作痛点分析
典型创作闭环:
- 输入设定 → AI 生成章节草稿
- 阅读、修改 → 保存到草稿或正文
- 定稿提交 → 归档为正文,并写入知识库(文章摘要 + 角色信息更新)
- 写下一章 → 模型通过工具检索角色库、历史正文,再续写
1.3 产品形态定位
产品形态上,前端采用 移动优先 的「创作 / 书架 / 书库 + 全屏阅读」结构,接近常见阅读类 App 的信息架构,而不是单页堆功能的编辑器。
二、整体架构
2.1 核心架构设计
系统分为三层:浏览器 SPA、业务后端、外部 AI 与存储。
flowchart TB
subgraph client [用户端]
SPA[Vue 单页应用]
end
subgraph backend [业务后端]
API[REST 与流式接口]
Write[写作与归档服务]
Files[章节文件服务]
Ingest[文档入库服务]
Search[混合检索服务]
Agent[写作 Agent]
Tools[检索工具]
end
subgraph storage [存储与模型]
Disk[(草稿与正文文件)]
Vector[(向量数据库)]
Embed[嵌入模型]
LLM[写作大模型]
end
SPA --> API
API --> Write
API --> Files
API --> Ingest
Write --> Agent
Agent --> Tools
Tools --> Search
Search --> Vector
Write --> Files
Files --> Disk
Ingest --> Vector
Ingest --> Embed
Agent --> LLM
两条「真相来源」要分开理解:
| 类型 | 作用 | 特点 |
|---|---|---|
| 章节文件 | 当前可编辑的草稿、已定稿正文 | 人类可读、可 diff、是编辑与发布的源 |
| 向量知识库 | 角色设定、历史章节语义片段 | 供 Agent 检索,不替代完整章节文件 |
三、后端:Spring Boot + LangChain4j
3.1 整体架构设计
后端是常规的 Controller → Service → 集成层 结构,核心能力集中在几块。
3.2 章节与文件管理
- 列出草稿 / 正文
- 读取、保存内容
- 提交定稿:移动文件、触发归档流水线
3.3 写作与流式输出
创作入口对接 写作 Agent(LangChain4j),支持:- 一次性返回整章(适合简单调用)
- SSE 流式输出(适合前端逐字展示)
3.4 Agent 与 RAG 工具
写作 Agent 挂载 工具(Tool),典型能力是 按关键词检索知识库:- 查 角色设定
- 查 历史正文 / 摘要
- 或 同时查
3.5 提交归档流水线
用户「提交」一章后,大致顺序:- 生成或兜底 章节摘要
- 正文 写入文章类向量集合
- 从正文中 抽取 / 合并角色信息,同步 角色库
3.6 书库与异步入库
除写作产生的归档外,还支持 主动导入:- 角色资料(文件或文本)
- 参考文章(文件或文本)
- 删除文章库条目等
3.7 外部依赖(概念)
- 嵌入模型(常见部署为本地 Ollama):文本向量化
- 向量数据库(如 Qdrant):分集合存放角色 / 文章
- 写作大模型(如智谱 GLM 等):实际生成正文
四、前端:Vue 3 轻量 SPA
4.1 技术栈选择
技术栈刻意保持简单:Vue 3 + Vue Router + TypeScript + Vite,无 Pinia、无重型 UI 框架。
4.2 信息架构设计
| 模块 | 职责 |
|---|---|
| 创作 | 章节名 + 创作指令,触发流式生成,完成后跳转书架 |
| 书架 | 草稿 / 正文切换,章节列表;移动端为文字按钮列表 + 底部类型切换 |
| 书库 | 角色与文章的导入、任务状态、删除等 |
| 阅读 | 全屏阅读,无底部主导航;编辑、提交、写下一章、上传角色、目录与更多操作 |
4.3 与后端的协作
- 章节增删改查、提交:REST JSON
- 创作:SSE 解析 token / status 事件
- 生产环境推荐 同域反向代理(静态站点与 API 同一域名),减少跨域与缓存问题
4.4 UI 设计要点
- 主题色、安全区(刘海、底部横条)、最小触控高度
- 弹窗分两类:底部 Sheet(目录、操作菜单)与 居中 Dialog(生成新章节、上传角色)
五、一次完整用户旅程
5.1 用户流程分析
sequenceDiagram
participant U as 用户
participant F as 前端
participant B as 后端
participant A as 写作Agent
participant V as 向量库
participant D as 章节文件
U->>F: 填写指令并创作
F->>B: 流式写作请求
B->>A: 生成章节
A->>V: 工具检索设定与前文
V-->>A: 检索片段
A-->>B: 流式正文
B-->>F: SSE token
B->>D: 保存草稿
U->>F: 阅读并修改
F->>B: 保存草稿
U->>F: 提交定稿
B->>D: 转为正文
B->>V: 摘要与正文入库
B->>V: 角色信息同步
六、优点
6.1 核心优势分析
- 闭环完整:从生成、改稿、定稿到入库、再检索,适合长篇而不是单次对话。
- Agent + RAG 分工清楚:模型负责写,工具负责查;比手工拼 prompt 更稳定。
- 正文与向量分离:文件易备份、易编辑;向量库只做「记忆检索」。
- 前端轻、部署简单:静态资源 + 独立 API 服务,适合个人服务器托管。
- 关键纯逻辑有单元测试:如角色摘要合并、解析器等,降低归档链路改动的风险。
七、缺点与局限
7.1 当前限制
- 无用户与权限:API 若暴露公网,需靠网关或内网隔离。
- 章节组织偏扁平:以文件名为单位,多本书、多卷需要后续引入「作品维度」。
- 文档与遗留代码:早期简易 Node 文件服务与现行 Spring 栈并存,新人易混淆。
- 部署易踩坑:前端构建产物必须覆盖 网站实际对外目录,并配置 单页应用回退;只上传到子目录而根目录仍是旧入口时,会出现「打包了但页面不变」。
- 跨域配置偏开发态:生产更应用同域反代,而不是无限扩大 CORS 白名单。
- 测试以单元为主:Agent、SSE、端到端链路仍依赖手工验证。
- 外部服务依赖多:嵌入、向量、写作模型任一不可用,体验依赖各处的降级策略。
八、改进方向(按优先级)
8.1 短期(稳定上线)
- 写清部署清单:静态资源目录、API 反代、SPA 路由回退、缓存刷新
- 生产同源访问 API;密钥仅环境变量
- 标注或移除遗留 Node 文件服务
8.2 中期(可维护)
- 拆分阅读页为 composables 与子组件
- 统一 API 客户端与错误格式
- 补充接口说明或与 TypeScript 类型对齐
8.3 长期(产品化)
- 作品 / 卷 / 章节层级
- 鉴权与多用户(若开源则至少 API Key)
- 入库与写作任务的可观测性(进度、耗时、检索次数)
- CI 与可选容器编排(向量库 + 后端 + 静态资源)
九、适合谁参考
9.1 目标受众
- 想用 LangChain4j Agent + Tool + RAG 做垂直创作工具的全栈开发者
- 需要 「文件草稿 + 向量记忆」双轨 的个人知识 / 创作项目
- 正在把 Vue 移动阅读式 UI 接到 Spring SSE 流式生成 的团队
十、小结
10.1 项目总结
这不是「聊天框里写小说」的 Demo,而是一条 可反复迭代的创作流水线:Agent 负责写,向量库负责记,文件系统负责存,前端负责移动场景下的读写与提交。架构清晰、依赖现代但组件数量可控;下一步价值主要在 部署规范、阅读页拆分、权限与作品维度,而不是再堆一个大模型。
附录:仓库结构(概念)
11.1 项目结构说明
| 部分 | 说明 |
|---|---|
| 后端服务 | Spring Boot,提供章节、聊天流式、入库等 API |
| 前端应用 | Vue 3 单页应用,构建为静态资源,可部署在站点子路径下 |
| 章节数据 | 配置目录下的草稿与正文文件 |
| 向量数据 | 独立向量数据库中的角色库与文章库 |