Skip to content

智能对话 ​

能力概览 ​

image-20260930103608506

  • 多轮会话:每个用户独立维护自己的对话列表,支持置顶、重命名、删除与批量清理。
  • 流式回复:基于 SSE(Server-Sent Events)逐字输出,支持"深度思考"推理过程与正文增量展示。
  • 上下文记忆:自动携带历史消息构建上下文,上下文条数可由会话 maxContexts 控制。
  • 知识库增强:当会话角色绑定了知识库时,自动检索相关段落并注入提示词,回复中标注引用来源。
  • 联网搜索:开启后实时检索网页结果,作为补充上下文参与回答。
  • 附件理解:文档类附件解析为文本注入上下文;图片类附件以多模态方式传给支持视觉的模型。
  • 角色设定:通过聊天角色(chat role)预设系统提示词、绑定模型与知识库,一键切换对话风格。
  • 自动标题:首轮对话结束后,自动根据问答内容生成简洁的会话标题。

模块结构 ​

对话能力位于 backend/app/api/v1/module_ai/chat/,分为两个领域:

  • conversation/:会话(对话窗口)的增删改查,区分"我的"(用户端)与"管理端"。
  • message/:消息的发送、流式生成、历史拉取与删除,同样区分用户端与管理端。

核心概念 ​

会话(Conversation) ​

会话是用户与 AI 之间一段连续的对话容器。创建会话时可指定角色 roleId 与知识库 knowledgeId,服务端会自动解析并冗余存储以下信息:

  • 绑定的模型 modelId 与模型标志 model、温度 temperature、最大 Token maxTokens、上下文条数 maxContexts。
  • 角色设定 systemMessage(系统提示词)。

若未指定角色,则使用系统中状态为"启用"且类型为 CHAT 的默认模型。会话归属当前用户,用户端接口均会校验 user_id,确保数据隔离。

消息(Message) ​

消息分为 user(用户)与 assistant(助手)两类。每条助手消息可能包含:

  • 正文 content:模型的正式回答。
  • 推理内容 reasoningContent:深度思考过程(思维链),独立分区展示。
  • 知识引用 segmentIds:本次回答命中的知识库段落编号。
  • 联网搜索结果 webSearchPages:引用到的网页列表。
  • 附件 attachmentUrls / attachmentNames:随问题上传的文件。

为了前端灵活渲染,输出模型会由扁平字段派生出 contentParts(内容分区),按"联网搜索 → 思考 → 正文 → 附件 → 知识引用"的顺序组织。

SSE 事件协议 ​

发送消息提供两种接口:

  • POST /ai/chat/message/send-my:一次性返回完整结果,适合非实时场景。
  • POST /ai/chat/message/send-stream-my:流式 SSE 返回,前端聊天页默认使用此接口,获得打字机式体验。

流式接口按如下事件顺序向客户端推送,所有事件包裹在统一响应结构 { code, data, msg } 中,data 为事件对象:

事件类型说明:

  • message_created:对话开始时下发,携带 user 与 assistant 两个消息体,前端据此创建气泡骨架。
  • reasoning_delta:思考过程的增量文本,text 字段不断累积。
  • text_delta:正式回答的增量文本,text 字段不断累积。
  • message_done:生成完成,携带完整的 message(含 contentParts、知识引用、附件等),前端用其替换骨架并持久化。

异常情况下,服务端会下发 { code: 500, data: null, msg: "<错误信息>" },前端据此提示失败原因。

模型与角色解析优先级 ​

每次发送都会确定"本次使用哪个模型"和"使用哪套系统提示词",解析优先级如下:

温度、最大 Token、Top-P、惩罚系数等生成参数同理:请求传入优先,否则回退到模型配置中的默认值。

增强能力 ​

知识库增强(RAG) ​

当生效角色绑定了知识库(knowledgeIds)时,系统取用户最新提问作为检索 query,经嵌入模型向量化后,通过检索管道(含可选重排)召回相关段落,拼接为带 [引用 N] 编号的上下文注入系统提示词,并引导模型在回答中标注来源。命中的段落编号会随消息落库,前端以"知识引用"分区展示,可点击跳转原文。

检索失败、知识库关闭或向量库未配置时均会优雅降级,不影响正常对话。

联网搜索 ​

请求 useSearch=true 时,以用户最新提问为关键词调用搜索引擎工厂,把返回网页的标题、链接与摘要注入提示词。搜索失败或未开启时不阻断对话。

附件理解 ​

请求携带 attachmentUrls 时按类型分流:

  • 文档类:下载并解析为文本,作为上下文注入系统提示词(单文件超过 20000 字符截断)。
  • 图片类:转 base64 data URL,作为多模态内容分区挂在最后一条用户消息上;若当前模型不支持视觉(visionEnabled=false),则忽略图片并记录提示。

历史上下文 ​

useContext=true(默认)时,服务端从会话历史中加载最近 maxContexts(缺省 10)条用户/助手消息参与本次推理,实现多轮记忆。每次收到助手回复后,会话的更新时间会被刷新,使会话列表按"最近使用"排序。

自动标题 ​

会话标题仍为默认值("新对话")且是首轮对话时,系统会调用 LLM 根据首轮问答生成不超过 20 字的标题;手动改名或角色创建的会话不自动覆盖。

前端交互 ​

前端对话页面位于 apps/web-ele/src/views/ai/chat/:

  • index/:用户对话主界面,左侧会话列表、中间消息时间线、底部输入区。
  • manager/:管理端的"对话管理"与"消息管理",供管理员跨用户查看与清理。
  • index/message/parts/:各类内容分区的独立渲染组件(text-part、reasoning-part、web-search-part、knowledge-part),分别对应后端的 contentParts 类型。
  • index/composables/:use-chat-stream.ts 封装 SSE 流式消费,use-chat-messages.ts 管理消息列表状态。

API 封装位于 apps/web-ele/src/api/ai/chat/,关键调用:

  • sendChatMessageStream(...):基于 @vben/request 的 fetchEventSource 发起流式请求,透传 useContext、useSearch、附件等参数,并通过 onmessage 解析 message_created / reasoning_delta / text_delta / message_done 事件增量渲染。
  • getChatMessageListByConversationId(...):进入会话时拉取历史消息。
  • 会话相关:createChatConversationMy、updateChatConversationMy、getChatConversationMyList、deleteChatConversationMy 等。

流式消费的典型流程: