聊天助手模块是 RAG-Agent 系统的 核心组件之一,承担用户与系统之间的主要交互。
模块通过 WebSocket 协议实现双向通信,支持大语言模型(接入了 DeepSeek)以 流式方式返回内容;为支持多轮连续对话,模块集成 Redis 来存储和维护用户会话上下文,使大模型生成回答时能够“记住”前文并保持语义连贯。
模块还深度集成 Elasticsearch,为结构化文本提供全文索引和关键词匹配。借助混合检索,RAG-Agent 能在海量本地知识中快速定位与用户问题相关的信息片段。

为了更好地引导大语言模型生成高质量回答,系统特别强化了 Prompt 构建与模板管理能力:
-
根据检索结果动态生成 Prompt;
-
支持多种 Prompt 模板配置与调优;
-
确保内容组织清晰、有重点,引导模型围绕核心信息生成响应。
这一机制是实现 RAG 的关键保障,确保模型回答既有语义逻辑,又有知识依据。
一、功能需求

二、技术选型
| 功能模块 | 技术选型 | 备注 |
|---|---|---|
| 实时通信 | WebSocket(基于Spring WebSocket) | 支持STOMP子协议 |
| 对话上下文存储 | Redis(使用Spring Data Redis) | 高性能缓存,支持TTL |
| 本地知识库(当前) | Elasticsearch | 支持混合检索 |
| 本地知识库(规划) | Faiss | 提升向量检索性能 |
| 语言模型调用 | DeepSeek API | 通过WebClient调用 |
|---|---|---|
| Prompt管理 | 自研模板引擎 | 支持动态模板和变量替换 |
| 异步处理 | Spring WebFlux | 支持响应式编程 |
| 安全认证 | JWT | 确保WebSocket连接安全 |
三、关键流程
01、用户发起对话流程
用户在页面上开始对话时,客户端会主动发起 WebSocket 连接请求,并携带 JWT 身份认证信息。
服务端收到请求后先验证用户身份和权限,验证通过后与客户端建立稳定的 WebSocket 长连接,用于后续实时对话。

连接建立后,用户就可以提问。客户端通过 WebSocket 将问题发给服务端;服务端解析消息后获取当前会话 ID,如果是新对话,就创建一个。
接着,系统会调用内部的 /api/search/hybrid 接口进行“混合检索”,结合关键词匹配和语义匹配,从本地知识库中快速找出与用户问题最相关的文档。这些结果还会再经过筛选、排序,并提取出关键内容和出处信息,为后面生成回答做准备。
拿到检索结果后,系统开始构建 Prompt,也就是发送给大模型的提问模板。系统会根据问题类型选择合适的模板,填入检索内容和系统级指令或限制条件,并管理上下文长度,保证多轮对话的连贯性,最终生成一份结构化的 Prompt。
准备好 Prompt 之后,系统会把它发送给大语言模型的 API(比如 DeepSeek)。大模型会开始生成回答,系统这边则以流式的方式逐段接收内容。为了保证体验,还会处理模型返回中的异常或错误,比如超时、内容为空等问题。
生成回答后,系统会将内容分段,通过 WebSocket 实时推送给客户端。用户可以一边查看已生成的内容,一边等待后续内容,体验上就像在“实时对话”一样流畅。客户端也会逐段渲染返回的内容,提升整体交互体验。
最后,为支持后续上下文对话,系统会将本轮用户提问和模型回答完整存入 Redis,更新对话历史记录。 同时也会设置或刷新这个会话的过期时间,以便未来再次使用或者进行归档。
02、新建会话流程
当用户打开对话页面,准备开始一次新的交流时,客户端会先通过一个 REST 接口向服务端发送“创建会话”的请求。这时候,服务端首先会对用户的身份进行校验,确保这是一个合法登录的用户。
验证通过后,系统会为这次新对话生成一个全局唯一的 conversationId,用作这轮会话的身份标识。同时,会为这次对话准备一份空的历史记录结构,方便后续存储每轮提问和回答内容。

接下来,系统会在 Redis 里建立用户和这个会话 ID 之间的映射关系,也就是说:这个会话是属于哪个用户的。为了防止会话无限制增长,系统还会给这个会话设置一个过期时间,比如 24 小时或 7 天,超时后自动清理。
最后,系统会把新生成的 conversationId 返回给客户端,表示这轮对话已经正式创建成功,用户可以开始提问啦。
03、查询历史对话流程
当用户想要查看之前的聊天记录时,客户端会向服务端发送一个查询历史记录的 REST 请求。服务端收到请求后,第一步还是先对用户的身份进行校验,确认用户是合法且有权限访问对应数据的。
接着,系统会去 Redis 中查找当前用户对应的 conversationId,也就是这位用户当前正在使用的那一轮对话的标识。 如果 Redis 中没有查到,或者这条会话已经过期失效,系统会及时返回提示信息 ,避免出现无效请求。
如果会话是有效的,那系统就会继续从 Redis 中读取这个会话对应的聊天历史记录,包括之前用户问过什么、系统是怎么回答的。这些内容会经过一轮格式化处理,比如按时间顺序排列、结构整理清晰,最后统一打包成接口返回数据发回给客户端,方便前端展示成对话列表,帮助用户快速回顾之前的交流内容。
四、Redis 结构设计
01、用户到会话的映射
-
Key:
user:{userId}:current_conversation -
Value: 当前用户的 conversationId
-
TTL: 7 天
-
用途: 快速查找某个用户的当前会话 ID
-
示例:
02、对话历史记录:
-
Key:
conversation:{conversationId} -
Value: JSON 格式的对话历史记录数组,每个元素包含 role、content、timestamp 字段
-
TTL: 7 天
-
用途: 存储用户的对话上下文,支持多轮对话,限制最多保存 20 条消息
-
示例:
03、历史会话列表:
-
Key:
user:{userId}:conversations -
Value: 用户的所有 conversationId 列表(JSON 格式)
-
TTL: 7 天
-
用途: 支持用户查看历史会话记录
04、Prompt 模板缓存:
-
Key:
prompt_templates:{templateName} -
Value: 模板内容
-
TTL: 无(或较长时间)
-
用途: 存储系统定义的 Prompt 模板
-
示例:
五、接口设计
01、WebSocket 接口
-
URL:
/chat/{token} -
协议: WebSocket
-
功能: 用户通过 WebSocket 发送消息,服务端逐段返回回答内容
客户端发送消息格式:
①、普通聊天消息, 格式为纯文本字符串,比如:“沉默王二是沙雕吗?”
②、停止响应指令, 格式为 JSON 对象(需要先获取停止令牌) 示例:
服务端返回格式:
①、AI 响应内容块(流式), 示例:
②、响应完成通知, 格式: JSON对象, 示例:
③、停止确认通知, 格式: JSON对象, 示例:
④、错误消息, 格式: JSON 对象, 示例:
02、获取中止回答 Token
-
URL:
/api/chat/websocket-token -
Method: GET
-
请求头:
-
Response:
03、获取对话历史
-
URL:
/api/v1/users/conversation -
Method: GET
-
请求头:
-
查询参数(可选):
-
Response:
-
说明: 根据用户的userId获取其当前会话的对话历史
04、获取对话历史(admin)
-
URL:
/api/v1/admin/conversation -
Method: GET
-
请求头:
-
查询参数(可选):
-
Response:
六、Prompt构建与管理设计
七、小结
聊天助手模块是RAG-Agent系统中最关键的交互中枢,它整合了 WebSocket 实时通信、Redis 对话存储、本地知识库检索以及大语言模型(如 DeepSeek)的强大能力,为用户提供了一种基于知识库的智能问答体验。
这个模块的最大特点在于,它不仅能“回答问题”,更能结合知识库内容,生成有依据、有深度的回答。这背后,得益于我们对 Prompt 构建与管理机制 的深度设计——系统内置了一整套结构化的 Prompt 模板体系,能够智能拼接检索结果、对话上下文和系统指令,从而构建出更适合语言模型理解和输出的 Prompt。
这一整套机制的存在,使得RAG-Agent真正具备了 RAG 的完整能力:
-
回答更精准、相关性更强:通过把知识库中最相关的信息“喂”给大模型,回答内容更聚焦、更靠谱。
-
合理引用知识内容,增强可信度:回答中会引用具体文档或段落,让用户清楚回答来源,提升可信度和专业性。
-
支持多轮连续对话,理解上下文:借助 Redis 保存历史记录,系统可以持续理解用户上下文,做到“前后呼应”。
-
适配多种问题类型与场景:无论是专业知识问答、业务流程咨询,还是日常闲聊,Prompt 模板都能灵活适配。