添加消息持久化和服务模块分离的内容
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# AI_Chat_Assistant PRD
|
# AI_Chat_Assistant PRD
|
||||||
|
|
||||||
# AI 聊天助手需求设计文档
|
# AI 聊天助手需求设计文档(产品需求文档 PRD)
|
||||||
|
|
||||||
### 文档介绍
|
### 文档介绍
|
||||||
|
|
||||||
@@ -10,15 +10,17 @@
|
|||||||
| 版本 | v1.0.0+1 |
|
| 版本 | v1.0.0+1 |
|
||||||
| 文档版本 | v1.0 |
|
| 文档版本 | v1.0 |
|
||||||
| 创建日期 | 2025-09-23 |
|
| 创建日期 | 2025-09-23 |
|
||||||
| 产品经理 | - |
|
| 最近更新时间 | 2025-09-24 |
|
||||||
| 技术负责人 | - |
|
| 产品经理 | (待指定) |
|
||||||
| 目标平台 | Flutter (Android/iOS) |
|
| 技术负责人 | (待指定) |
|
||||||
|
| 目标平台 | Flutter (Android / iOS,首期 Android 优先) |
|
||||||
|
| 发布形态 | Flutter 第三方插件(支持示例 App) |
|
||||||
|
|
||||||
### 修订记录
|
### 修订记录
|
||||||
|
|
||||||
| 版本 | 日期 | 作者 | 内容 |
|
| 版本 | 日期 | 作者 | 内容 |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| 1.0 | 2025-09-23 | - | AI助手需求整理 |
|
| 1.0 | 2025-09-23 | - | 初版功能需求整理 |
|
||||||
|
|
||||||
## **1. 引言**
|
## **1. 引言**
|
||||||
|
|
||||||
@@ -39,25 +41,28 @@
|
|||||||
| 3 | TTS | Text-To-Speech,语音合成,将文本转换为语音。 |
|
| 3 | TTS | Text-To-Speech,语音合成,将文本转换为语音。 |
|
||||||
| 4 | SSE | Server-Sent Events,一种服务器向客户端推送数据的技术。 |
|
| 4 | SSE | Server-Sent Events,一种服务器向客户端推送数据的技术。 |
|
||||||
| 5 | 车控命令 | 通过语音或界面触发的,用于控制车辆功能(如门锁、空调)的指令。 |
|
| 5 | 车控命令 | 通过语音或界面触发的,用于控制车辆功能(如门锁、空调)的指令。 |
|
||||||
|
| 6 | 场景(Scenario)| 不同业务上下文(购车 / 用车) |
|
||||||
|
|
||||||
### **1.4 统一异常处理**
|
### **1.4 统一异常处理**
|
||||||
|
|
||||||
1. **网络异常**:语音识别或AI对话过程中出现网络错误,应有明确提示(如:“网络连接失败,请检查后重试”),并提供重试选项。
|
1. **网络异常**:语音识别或AI对话过程中出现网络错误,应有明确提示(如:“网络连接失败,请检查后重试”),并提供重试选项。
|
||||||
2. **权限拒绝**:当未授予麦克风或音频录制权限时,应引导用户前往系统设置开启权限。
|
2. **权限拒绝**:当未授予麦克风或音频录制权限时,应引导用户前往系统设置开启权限。
|
||||||
3. **语音识别失败**:识别无结果或置信度过低时,应提示用户“抱歉,我没有听清,请再说一遍”。
|
3. **语音识别失败**:返回空文本或低置信度,提示“抱歉,我没有听清,请再说一遍”。(补充:不缓存失败结果。)
|
||||||
4. **命令执行失败**:车控命令下发后执行失败,应通过TTS和UI界面明确反馈失败原因。
|
4. **命令执行失败**:车控执行失败需双通道反馈(UI + TTS),并显示失败原因或错误类型标签。(补充:通用错误尽量转化为用户友好语义。)
|
||||||
|
|
||||||
## 2. 产品概述
|
## 2. 产品概述
|
||||||
|
|
||||||
### 2.1 产品简介
|
### 2.1 产品简介
|
||||||
|
|
||||||
AI Chat Assistant 是一个功能丰富的 AI 聊天助手 Flutter 插件,提供完整的AI语音交互解决方案,支持语音识别、智能对话、车控命令执行和语音反馈等功能。
|
AI Chat Assistant 是一个集成语音识别、智能对话、车控指令解析与执行、语音反馈渲染于一体的 Flutter 插件。支持“车控助手”与“用车助手”双场景:
|
||||||
|
- 车控助手:支持 20+ 车辆控制命令(如空调、车窗、车门、座椅加热等)。
|
||||||
聊天助手现在分为车控助手和用车助手,车控助手支持 20+ 种车辆控制命令(空调、车窗、车门、座椅加热等);用车助手会根据用户手册的内容智能回复。
|
- 用车助手:基于用户手册 / 知识库进行问答。(包含 保养咨询、能耗优化建议等)
|
||||||
|
- 购车助手:基于厂家的经销政策以及车辆配置信息进行问答
|
||||||
|
|
||||||
### 2.2 产品流程图
|
### 2.2 产品流程图
|
||||||
|
|
||||||
现有的产品主要流程是用户长按点击语音按钮,经过权限判断之后,需要将语音转化为文本,然后通过分类结果来判断是普通问答(知识库)还是车控指令。
|
|
||||||
|
现有核心流程:用户长按语音按钮 → 权限校验 → 录音 + 识别 → 文本分类 → 路由到问答/车控/错误反馈 → 结果播报与展示。
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
graph TD
|
graph TD
|
||||||
@@ -89,6 +94,41 @@ graph TD
|
|||||||
- 支持自然语言车控命令识别与执行
|
- 支持自然语言车控命令识别与执行
|
||||||
- 轻量级架构,易于集成和定制
|
- 轻量级架构,易于集成和定制
|
||||||
|
|
||||||
|
### 2.4 顶层功能结构
|
||||||
|
```mermaid
|
||||||
|
graph LR
|
||||||
|
ASR[语音采集/ASR] --> CLASS[文本/意图分类]
|
||||||
|
CLASS -->|车控| CMD[车控解析/执行]
|
||||||
|
CLASS -->|问答| QA[对话引擎 SSE/WS]
|
||||||
|
CLASS -->|兜底| FALL[引导重试/澄清]
|
||||||
|
QA --> TTS[TTS 播报]
|
||||||
|
CMD --> FEED[执行反馈]
|
||||||
|
TTS --> MSG[消息渲染]
|
||||||
|
FEED --> MSG
|
||||||
|
MSG --> STORE[(本地持久化)]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### 2.5 语音交互主流程
|
||||||
|
```mermaid
|
||||||
|
graph TD
|
||||||
|
START[长按/唤醒触发] --> PERM[权限校验]
|
||||||
|
PERM -->|通过| REC[开始录音]
|
||||||
|
PERM -->|拒绝| EXIT[权限引导提示]
|
||||||
|
REC --> ASR[实时增量识别]
|
||||||
|
ASR --> RELEASE[松手/结束]
|
||||||
|
RELEASE --> CLASSIFY[分类/意图识别]
|
||||||
|
CLASSIFY -->|车控| CONTROL[结构化命令]
|
||||||
|
CLASSIFY -->|问答| STREAM[流式对话输出]
|
||||||
|
CLASSIFY -->|无匹配| GUIDE[兜底提示]
|
||||||
|
CONTROL --> EXEC[调用车控处理器]
|
||||||
|
EXEC --> RESULT[结果反馈]
|
||||||
|
STREAM --> MERGE[增量合并/渲染]
|
||||||
|
RESULT --> RENDER[消息渲染 + TTS]
|
||||||
|
MERGE --> RENDER
|
||||||
|
RENDER --> STORE[(持久化过滤保存)]
|
||||||
|
```
|
||||||
|
|
||||||
## 3. 功能需求
|
## 3. 功能需求
|
||||||
|
|
||||||
### 3.1 用户页面展示
|
### 3.1 用户页面展示
|
||||||
@@ -97,7 +137,7 @@ graph TD
|
|||||||
|
|
||||||
- **用户场景**
|
- **用户场景**
|
||||||
|
|
||||||
在主应用界面上提供一个常驻的、可随意拖拽的AI助手入口。
|
在主应用界面上提供一个常驻的、可随意拖拽的AI助手入口,作为全局统一入口,维持轻量可达性,不干扰主业务操作。
|
||||||
|
|
||||||
- **功能描述**
|
- **功能描述**
|
||||||
|
|
||||||
@@ -107,14 +147,13 @@ graph TD
|
|||||||
- **拖拽吸附**:支持在屏幕内自由拖拽,松开时自动吸附到最近的屏幕边缘。
|
- **拖拽吸附**:支持在屏幕内自由拖拽,松开时自动吸附到最近的屏幕边缘。
|
||||||
- **交互响应**:
|
- **交互响应**:
|
||||||
- **点击**: 进入全屏的聊天页面,全屏模式为一个新的页面
|
- **点击**: 进入全屏的聊天页面,全屏模式为一个新的页面
|
||||||
- **长按**:变为聆听模式,直接开始语音录制,出现聊天窗口。
|
- **长按**:变为聆听模式,直接开始语音录制,出现聊天窗口
|
||||||
|
- **位置自适应**:聊天窗口的位置需要根据浮动按钮的位置变化,如果浮动按钮位置过于靠上,则聊天窗口显示在浮动按钮的下方,默认显示在浮动按钮的上方
|
||||||
聊天窗口的位置需要根据浮动按钮的位置变化,如果浮动按钮位置过于靠上,则聊天窗口显示在浮动按钮的下方,默认情况下显示在浮动按钮的上方
|
|
||||||
|
|
||||||
- **状态指示**:通过动画(如呼吸效果)表示待机、聆听、思考等不同状态。
|
- **状态指示**:通过动画(如呼吸效果)表示待机、聆听、思考等不同状态。
|
||||||
|
|
||||||
默认为待机状态,长按会进入聆听状态,思考中的状态会在聊天显示思考中的状态聊天气泡
|
默认为待机状态,长按会进入聆听状态,思考中的状态会在聊天显示思考中的状态聊天气泡
|
||||||
|
- **补充说明**:长按阈值建议 300ms;误触策略:短按抬起不触发录音。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -128,7 +167,7 @@ graph TD
|
|||||||
|
|
||||||
- **功能描述**
|
- **功能描述**
|
||||||
|
|
||||||
提供弹出式聊天窗口,展示对话记录并提供输入方式。
|
提供弹出式聊天窗口,展示对话记录并提供输入方式,不承担复杂历史翻阅与批量操作
|
||||||
|
|
||||||
- **需求说明**
|
- **需求说明**
|
||||||
|
|
||||||
@@ -144,17 +183,17 @@ graph TD
|
|||||||
|
|
||||||
- **用户场景**
|
- **用户场景**
|
||||||
|
|
||||||
用户与AI助手进行可视化的文本和语音交互。
|
用户与AI助手进行可视化的文本和语音交互,适用于长对话、多轮引用、查看历史与多类型气泡的交互。
|
||||||
|
|
||||||
- **功能描述**
|
- **功能描述**
|
||||||
|
|
||||||
提供全屏聊天界面,展示对话记录并提供输入方式。全屏的聊天页面功能更加丰富,分为不同的场景
|
提供全屏聊天界面,展示对话记录并提供输入方式。全屏的聊天页面功能更加丰富,多类型气泡、快捷指令区、功能按钮区、历史分页加载
|
||||||
|
|
||||||
- **需求说明**
|
- **需求说明**
|
||||||
- 全屏聊天模式下会保留之前浮动聊天窗口的聊天记录
|
- 全屏聊天模式下会保留之前浮动聊天窗口的聊天记录
|
||||||
- 不同的场景为不同的AI助手,现有两种场景,购车助手和用车助手
|
- 不同的场景为不同的AI助手,现有两种场景,购车助手和用车助手(根据入口来判断)
|
||||||
- 顶部会有可配置的功能按钮区域(用户服务/购车服务)
|
- 顶部会有可配置的功能按钮区域(用户服务/购车服务)
|
||||||
- 功能按钮下方会有快捷对话的区域,可以点击换一换来更换快捷指令
|
- 功能按钮下方会有快捷对话的区域,可以点击换一换来更换快捷指令,支持“换一换”刷新策略(本地轮换或服务侧下发)
|
||||||
- 聊天页面底部会有功能栏,分别为**删除当前对话**,**按住说话**,**切换文本输入**
|
- 聊天页面底部会有功能栏,分别为**删除当前对话**,**按住说话**,**切换文本输入**
|
||||||
- 如果存在本地对话记录,点击 **显示历史对话记录** 会加载之前的5条对话记录,同样可以通过上拉来加载历史对话记录
|
- 如果存在本地对话记录,点击 **显示历史对话记录** 会加载之前的5条对话记录,同样可以通过上拉来加载历史对话记录
|
||||||
|
|
||||||
@@ -166,7 +205,7 @@ graph TD
|
|||||||
|
|
||||||
- **用户场景**
|
- **用户场景**
|
||||||
|
|
||||||
用户未绑定车辆的情况下,爱车页面变为购车页面,购车页面也会有AI助手
|
用户未绑定车辆的情况下,爱车页面变为购车页面,购车页面也会有AI助手,未绑定车辆用户获取车型配置、优惠、推荐。
|
||||||
|
|
||||||
- **功能描述**
|
- **功能描述**
|
||||||
|
|
||||||
@@ -176,7 +215,7 @@ graph TD
|
|||||||
- 浮动按钮点击可进入全屏的AI助手页面,顶部的功能按钮为热门车型推荐,同样是icon+text的按钮,点击之后会快捷输入车型的名称,AI助手会回复车型的相关信息,同时快捷对话的区域会按照对话来进行变化;
|
- 浮动按钮点击可进入全屏的AI助手页面,顶部的功能按钮为热门车型推荐,同样是icon+text的按钮,点击之后会快捷输入车型的名称,AI助手会回复车型的相关信息,同时快捷对话的区域会按照对话来进行变化;
|
||||||
- 购车助手同样可以通过文本的语义来进行推荐车型,以及解读购车的优惠信息;
|
- 购车助手同样可以通过文本的语义来进行推荐车型,以及解读购车的优惠信息;
|
||||||
- 如果在购车助手场景下,本身并没有绑定车辆,如果有车控的语音输入,则返回:您还未绑定车辆,无法使用车控指令;
|
- 如果在购车助手场景下,本身并没有绑定车辆,如果有车控的语音输入,则返回:您还未绑定车辆,无法使用车控指令;
|
||||||
- 如果是用车助手场景下,包含购车助手的全部功能,同样可以回复相应车型来获取配置信息以及购车政策。
|
- 如果是用车助手场景,包含购车助手的全部功能,同样可以回复相应车型来获取配置信息以及购车政策。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -194,7 +233,7 @@ graph TD
|
|||||||
|
|
||||||
- **需求说明**
|
- **需求说明**
|
||||||
- 用车场景下的功能按钮为官方推荐,内容包括智能场景推荐、数据埋点和运营位,其中智能场景推荐包括售后维保提醒,智能场景建议;数据埋点包括能耗报告,行为分析,用户习惯操作;运营位则是推荐的车型,用户复购建议;
|
- 用车场景下的功能按钮为官方推荐,内容包括智能场景推荐、数据埋点和运营位,其中智能场景推荐包括售后维保提醒,智能场景建议;数据埋点包括能耗报告,行为分析,用户习惯操作;运营位则是推荐的车型,用户复购建议;
|
||||||
- 点击 常见功能按钮,会输入一个常见功能的聊天记录,返回的数据为经过大数据分析之后得到的常用功能,聊天气泡中显示多个按钮,可以点击进行快捷回复;
|
- 常见功能按钮 → 发送一条“功能集合”消息气泡(含多个按钮)。
|
||||||
- 点击 更多工具按钮跟常见功能按钮一样,会返回一条聊天记录,里面会包含多个按钮,点击按钮可以进行快捷回复;
|
- 点击 更多工具按钮跟常见功能按钮一样,会返回一条聊天记录,里面会包含多个按钮,点击按钮可以进行快捷回复;
|
||||||
- 快捷回复区域是可以变化的,会根据对话的最后一个回复进行变化,快捷回复区域会跟在最后一个对话的底部;例如刚进入会跟在 功能按钮的底部,但是新的聊天记录出现后,就会自动拼接到聊天气泡的底部(聊天气泡类型分为多种,后面会详细介绍);
|
- 快捷回复区域是可以变化的,会根据对话的最后一个回复进行变化,快捷回复区域会跟在最后一个对话的底部;例如刚进入会跟在 功能按钮的底部,但是新的聊天记录出现后,就会自动拼接到聊天气泡的底部(聊天气泡类型分为多种,后面会详细介绍);
|
||||||
|
|
||||||
@@ -204,17 +243,18 @@ graph TD
|
|||||||
|
|
||||||
- **用户场景**
|
- **用户场景**
|
||||||
|
|
||||||
在开通语音唤醒功能之后,购车页面和爱车页面都可以使用语音唤醒
|
在开通语音唔醒功能之后,购车页面和爱车页面都可以使用语音唤醒,免手动触发,提高便利性
|
||||||
|
|
||||||
- **功能描述**
|
- **功能描述**
|
||||||
|
|
||||||
用户可以通过语音唤醒功能在不需要点击按钮的情况下激活AI助手,提高使用便捷性和用户体验。当用户说出设定的唤醒词(你好,众众)后,系统会自动启动AI助手并进入聆听模式。
|
用户可以通过语音唤醒功能在不需要点击按钮的情况下激活AI助手,提高使用便捷性和用户体验。唤醒词“你好,众众”,唤醒后直接进入聆听模式并高亮反馈。
|
||||||
|
|
||||||
- **需求说明**
|
- **需求说明**
|
||||||
|
- 设置页开启后常驻监听(低功耗策略)。
|
||||||
用户可通过说出"你好,众众"唤醒AI助手,系统将自动进入聆听模式。语音唤醒功能需要用户在设置(App设置页面或AI助手的设置页面)中开启,并且可以在有较高环境噪音的情况下进行降噪处理。唤醒后,助手会给予明确的视觉和声音反馈,确保用户知道系统已经准备好接收指令。
|
- 唤醒检测在本地执行,未唤醒音频不上传。
|
||||||
|
- 唤醒成功:音效 + 动画反馈。
|
||||||
语音唤醒功能需要一定的权限(例如麦克风访问权限),系统会在首次使用时提示用户授予必要权限。为保护用户隐私,语音数据会在本地进行初步处理,只有确认唤醒后才会发送到服务器。此功能在使用过程中会考虑电池消耗,在低电量模式下可能会自动降低敏感度或暂时关闭。
|
- 低电量模式:可自动降敏或暂停。
|
||||||
|
- 权限缺失:首次引导开启麦克风权限。
|
||||||
|
|
||||||
### 3.3 聊天模块
|
### 3.3 聊天模块
|
||||||
|
|
||||||
@@ -259,7 +299,9 @@ graph TD
|
|||||||
普通问答现在只有用车助手这个场景,后续增加新的场景:购车助手;需要先通过文本语义判断是哪个场景,然后根据相应场景来回复问题。
|
普通问答现在只有用车助手这个场景,后续增加新的场景:购车助手;需要先通过文本语义判断是哪个场景,然后根据相应场景来回复问题。
|
||||||
|
|
||||||
- **需求说明**
|
- **需求说明**
|
||||||
|
- 场景识别由后端完成,前端仅消费分类结果
|
||||||
|
- SSE:按流片段累积,合并为 Markdown
|
||||||
|
|
||||||
不管是购车场景还是用车场景,或者是开放式对话,都有一个问答的流程,场景的区分不是前端来判断。现在流程是将语音转化的文本通过接口发给后台服务,然后后台会根据body里面的text和conversation_id 来返回一个文件流,客户端这边会把文件流的全部数据接受完成后合并为一个markdown语法的文本。
|
不管是购车场景还是用车场景,或者是开放式对话,都有一个问答的流程,场景的区分不是前端来判断。现在流程是将语音转化的文本通过接口发给后台服务,然后后台会根据body里面的text和conversation_id 来返回一个文件流,客户端这边会把文件流的全部数据接受完成后合并为一个markdown语法的文本。
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
@@ -274,7 +316,7 @@ graph TD
|
|||||||
|
|
||||||
现在有两个新的调整方案,一个是Socket连接,另外一个方案是在现有的流程基础上新增消息类型。
|
现在有两个新的调整方案,一个是Socket连接,另外一个方案是在现有的流程基础上新增消息类型。
|
||||||
|
|
||||||
1. Socket方案
|
1. Socket方案
|
||||||
|
|
||||||
每次进入AI助手会话会创建一个随机的taskId,然后每次对话都会有一个conversationId,使用taskId 连接Socket成功后,就可以通过Socket发送语音或者文本消息。然后Socket 会返回三种不同的消息类型,`it消息 (识别文本)`,`gb消息 (回复文本)`,`tts消息 (语音数据)`。
|
每次进入AI助手会话会创建一个随机的taskId,然后每次对话都会有一个conversationId,使用taskId 连接Socket成功后,就可以通过Socket发送语音或者文本消息。然后Socket 会返回三种不同的消息类型,`it消息 (识别文本)`,`gb消息 (回复文本)`,`tts消息 (语音数据)`。
|
||||||
|
|
||||||
@@ -303,7 +345,7 @@ sequenceDiagram
|
|||||||
Note over C, S: 连接保持,可继续发送新语音或关闭
|
Note over C, S: 连接保持,可继续发送新语音或关闭
|
||||||
```
|
```
|
||||||
|
|
||||||
1. HTTP方案
|
2. HTTP方案
|
||||||
|
|
||||||
HTTP方案是保持原有流程的情况下进行扩展,chat API 不再是返回一个数据流,而是返回一个json数据,json数据里面会有不同的消息返回,对应上面不同的气泡类型,消息类似分为`stream`,`text`,`media`,`bussines`,`stream`消息就是之前的数据流的消息,通过`messageId`就可以获取到数据;`text`消息是普通的文本消息,可以实现上面的链接气泡,按钮气泡;`media`消息则可以实现负责的图文混排,或者是一个单纯的视频教程;`bussines`消息主要以业务相关的,会根据业务类型显示不一样的样式,内容和按钮也会有变化。
|
HTTP方案是保持原有流程的情况下进行扩展,chat API 不再是返回一个数据流,而是返回一个json数据,json数据里面会有不同的消息返回,对应上面不同的气泡类型,消息类似分为`stream`,`text`,`media`,`bussines`,`stream`消息就是之前的数据流的消息,通过`messageId`就可以获取到数据;`text`消息是普通的文本消息,可以实现上面的链接气泡,按钮气泡;`media`消息则可以实现负责的图文混排,或者是一个单纯的视频教程;`bussines`消息主要以业务相关的,会根据业务类型显示不一样的样式,内容和按钮也会有变化。
|
||||||
|
|
||||||
@@ -359,6 +401,243 @@ HTTP方案是保持原有流程的情况下进行扩展,chat API 不再是返
|
|||||||
- **后备箱控制**:开启、关闭
|
- **后备箱控制**:开启、关闭
|
||||||
- **特殊功能**:鸣笛、车辆定位、一键备车、一键融雪
|
- **特殊功能**:鸣笛、车辆定位、一键备车、一键融雪
|
||||||
|
|
||||||
|
|
||||||
|
#### **3.3.4 聊天信息持久化**
|
||||||
|
|
||||||
|
- **用户场景**
|
||||||
|
|
||||||
|
用户在与AI助手进行对话时,会产生多条聊天记录。为保护用户隐私和提升体验,这些聊天记录默认仅保存在本地设备,不会上传至云端。
|
||||||
|
|
||||||
|
- **功能描述**
|
||||||
|
|
||||||
|
系统支持本地化持久化存储普通问答类型的聊天记录。所有文本类消息将以结构化数据形式保存至本地数据库(推荐使用SQLite或Hive等Flutter主流轻量级数据库),便于后续检索和管理。
|
||||||
|
|
||||||
|
- **需求说明**
|
||||||
|
- **本地存储**:所有与AI助手的聊天记录(包括文本、语音、气泡类型、时间戳等)需保存在本地设备,支持持久化;
|
||||||
|
- **存储方式**:采用本地数据库(如SQLite、Hive等Flutter常用方案),或文件存储,保证数据安全和高效读写;
|
||||||
|
- **读取与展示**:用户重新进入聊天界面时,不会自动加载历史聊天记录,点击显示历史记录之后才会加载聊天记录,按时间顺序展示;
|
||||||
|
- **数据结构**:每条聊天记录需包含:消息ID、会话ID、消息类型(文本/语音/卡片/按钮/富媒体)、内容、时间戳、发送方(用户/AI)、气泡类型等;
|
||||||
|
- **删除与清理**:支持用户手动删除单条或全部聊天记录,支持定期自动清理(如超过30天自动删除);
|
||||||
|
- **持久化逻辑**:在Socket和HTTP两种消息方案下,收到消息体后,系统会优先将stream和text类型消息持久化保存,其他类型消息仅用于即时展示,不做持久化处理。
|
||||||
|
|
||||||
|
有了消息的持久化,AI助手聊天消息的显示逻辑也会跟着变化,按照上面的`Socket`方案和`HTTP`方案,收到消息体之后首先会保存到本地,特别是`HTTP`方案中会有多条消息返回,持久化只会保存stream和text消息,其他消息不会保存。
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph TD
|
||||||
|
A[收到AI助手消息] --> B[显示消息到聊天界面]
|
||||||
|
B --> C{消息类型判断}
|
||||||
|
C -->|stream/text| D[持久化保存到本地数据库]
|
||||||
|
C -->|其他类型| E[仅显示,不持久化]
|
||||||
|
D --> F[历史消息管理]
|
||||||
|
F --> G[用户点击显示历史记录]
|
||||||
|
G --> H[加载历史消息并展示]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. 非功能需求
|
||||||
|
|
||||||
|
### 4.1 服务模块
|
||||||
|
|
||||||
|
#### **4.1.1 模块设计目标**
|
||||||
|
|
||||||
|
服务模块负责“输入 → 解析 → 对话/车控 → 反馈 → 持久化”全链路的能力封装,向上提供简单一致的编程接口,向下屏蔽多种后端形态(HTTP / SSE)与原生能力(录音、TTS、权限、ASR)。
|
||||||
|
设计目标:
|
||||||
|
- 解耦:各服务单一职责,可独立替换;
|
||||||
|
- 可扩展:新协议 / 新命令 / 新气泡类型通过注册或策略扩展;
|
||||||
|
- 可裁剪:按需选择(如不需要车控,可不接入 command 子模块)。
|
||||||
|
|
||||||
|
#### **4.1.2 模块目录设计**
|
||||||
|
|
||||||
|
拟将现有核心服务抽离为独立基础包(例如:ai_chat_core),供 UI 插件依赖。
|
||||||
|
|
||||||
|
建议目录结构:
|
||||||
|
```
|
||||||
|
packages/
|
||||||
|
ai_chat_core/
|
||||||
|
ai_chat_core.dart # 对外统一入口
|
||||||
|
src/ # 代码目录
|
||||||
|
models/ # models
|
||||||
|
message.dart # 消息和消息块
|
||||||
|
message_chunk.dart
|
||||||
|
vehicle_command.dart # 车控
|
||||||
|
vehicle_command_response.dart
|
||||||
|
command_result.dart
|
||||||
|
enums/ # enums
|
||||||
|
message_type.dart
|
||||||
|
message_status.dart
|
||||||
|
command_type.dart
|
||||||
|
service_state.dart # 服务状态
|
||||||
|
input/
|
||||||
|
audio_recorder_service.dart # 录音以及保存文件
|
||||||
|
voice_recognition_service.dart # 目前项目未使用
|
||||||
|
wake_word_service.dart # 预留(可选)
|
||||||
|
nlp/ # 自然语言处理相关
|
||||||
|
text_classification_service.dart
|
||||||
|
vehicle_command_service.dart
|
||||||
|
dialog/ #对话相关的
|
||||||
|
chat_channel/
|
||||||
|
chat_sse_service.dart # SSE
|
||||||
|
chat_ws_service.dart # 预留 WebSocket(可选)
|
||||||
|
chat_http_service.dart # 批量 HTTP 方案(可选)
|
||||||
|
message_service.dart # 核心编排/状态更新
|
||||||
|
tts/ # TTS
|
||||||
|
tts_service.dart
|
||||||
|
tts_task_queue.dart
|
||||||
|
command/ # 车控相关
|
||||||
|
command_service.dart # Command Register Callback(已更新为抽象类的方式)
|
||||||
|
vehicle_command_handler.dart # 自定义实现车控命令
|
||||||
|
persistence/ # 持久化
|
||||||
|
persistence_service.dart # 提供持久化服务
|
||||||
|
dao/ # dao
|
||||||
|
message_dao.dart # 消息体的 dao 对象
|
||||||
|
infra/ # infra 的服务
|
||||||
|
config_service.dart
|
||||||
|
redis_service.dart
|
||||||
|
location_service.dart
|
||||||
|
vehicle_state_service.dart # 预留
|
||||||
|
logger.dart
|
||||||
|
error_mapper.dart
|
||||||
|
utils/ # 工具类
|
||||||
|
markdown_cleaner.dart
|
||||||
|
id_generator.dart
|
||||||
|
throttle.dart
|
||||||
|
```
|
||||||
|
|
||||||
|
对外暴露(ai_chat_core.dart)仅导出:
|
||||||
|
- models / enums
|
||||||
|
- MessageService(主入口)
|
||||||
|
- VehicleCommandHandler 抽象
|
||||||
|
- 配置初始化(initCore / setConfig)
|
||||||
|
|
||||||
|
#### **4.1.3 核心服务说明**
|
||||||
|
|
||||||
|
| 服务 | 角色 | 主要职责 | 关键点 |
|
||||||
|
| ---- | ---- | -------- | ------ |
|
||||||
|
| MessageService | 总编排 | 状态机、消息生命周期、调用链调度 | 统一入口 |
|
||||||
|
| AudioRecorderService | 输入 | 录音启动/停止、静音检测 | 录制参数配置 |
|
||||||
|
| VoiceRecognitionService | 输入处理 | 语音转文本(在线识别 / 中英判别) | 失败降级提示 |
|
||||||
|
| WakeWordService | 输入唤醒 | 本地唤醒词检测 | 低功耗策略 |
|
||||||
|
| TextClassificationService | 语义分类 | 业务场景 / 指令 / 问答判断 | 分类缓存 |
|
||||||
|
| VehicleCommandService | 语义→结构 | 解析多条车控命令列表 + 参数 | 容错解析 |
|
||||||
|
| CommandService | 执行派发 | 调用 Host 注入的 VehicleCommandHandler | 失败重试 |
|
||||||
|
| ChatSseService | 对话通道 | SSE 流接收与分片回调 | 首 Token 优化 |
|
||||||
|
| ChatWsService(预留) | 对话通道 | WebSocket 统一多类型消息 | 心跳+重连 |
|
||||||
|
| ChatHttpService(预留) | 对话通道 | 一次性批量消息 | 并行补拉 |
|
||||||
|
| TtsService + TtsTaskQueue | 输出播报 | 分句 / 排队 / 抢占 / 语言切换 | 顺序一致性 |
|
||||||
|
| PersistenceService | 持久化 | 消息落地 / 分页 / 过期清理 | schema 迁移 |
|
||||||
|
| RedisService | 辅助缓存 | 临时状态(可选) | 可替换 |
|
||||||
|
| LocationService | 扩展 | 位置信息(用于上下文) | 可选注入 |
|
||||||
|
| VehicleStateService | 扩展 | 实时车况(未来支持) | 监听通道 |
|
||||||
|
| ConfigService | 基础设施 | 端点 / 超时 / 重试策略统一 | 环境隔离 |
|
||||||
|
| Logger | 基础设施 | 分级日志 + 调试开关 | 生产开关 |
|
||||||
|
| MarkdownCleaner | 工具 | 清理/裁剪 Markdown 用于 TTS | 多语言规则 |
|
||||||
|
| ErrorMapper | 工具 | 后端错误码 → 用户友好文案 | 本地化适配 |
|
||||||
|
|
||||||
|
#### **4.1.4 服务分层**
|
||||||
|
|
||||||
|
- 链路图
|
||||||
|
```mermaid
|
||||||
|
sequenceDiagram
|
||||||
|
autonumber
|
||||||
|
participant UI as UI层
|
||||||
|
participant MS as MessageService
|
||||||
|
participant AR as AudioRecorder
|
||||||
|
participant ASR as VoiceRecognition
|
||||||
|
participant CLS as TextClassification
|
||||||
|
participant VCS as VehicleCommandService
|
||||||
|
participant DLG as ChatSse/WS/HTTP
|
||||||
|
participant CMD as CommandService
|
||||||
|
participant HND as VehicleCommandHandler(Host)
|
||||||
|
participant TTS as TtsService
|
||||||
|
participant PERS as PersistenceService
|
||||||
|
|
||||||
|
UI->>MS: startVoiceInput()
|
||||||
|
MS->>AR: start()
|
||||||
|
AR-->>MS: audioChunks / silenceEnd
|
||||||
|
MS->>AR: stop()
|
||||||
|
MS->>ASR: recognize(audio)
|
||||||
|
ASR-->>MS: recognizedText
|
||||||
|
MS->>CLS: classify(text)
|
||||||
|
CLS-->>MS: category / scenario
|
||||||
|
alt 车控指令
|
||||||
|
MS->>VCS: parseCommands(text)
|
||||||
|
VCS-->>MS: commands[]
|
||||||
|
loop each command
|
||||||
|
MS->>CMD: execute(command)
|
||||||
|
CMD->>HND: executeCommand(command)
|
||||||
|
HND-->>CMD: result(success/fail)
|
||||||
|
CMD-->>MS: executionResult
|
||||||
|
MS->>TTS: enqueue("执行结果反馈")
|
||||||
|
MS->>PERS: save(control_feedback)
|
||||||
|
end
|
||||||
|
else 普通问答
|
||||||
|
MS->>DLG: requestStream(text, convId)
|
||||||
|
DLG-->>MS: streamChunk/ finalMessage
|
||||||
|
MS->>TTS: enqueue(chunk/segments)
|
||||||
|
MS->>PERS: save(text / merged)
|
||||||
|
else 错误/兜底
|
||||||
|
MS->>TTS: enqueue(提示语)
|
||||||
|
MS->>PERS: save(system_message)
|
||||||
|
end
|
||||||
|
TTS-->>UI: 播放中事件
|
||||||
|
PERS-->>MS: persist OK
|
||||||
|
MS-->>UI: 更新消息列表
|
||||||
|
```
|
||||||
|
|
||||||
|
- 逻辑分层
|
||||||
|
```mermaid
|
||||||
|
graph TD
|
||||||
|
A[UI层] --> B[MessageService]
|
||||||
|
B --> C1[输入层 AudioRecorder / WakeWord]
|
||||||
|
B --> C2[语义层 Classification / VehicleCommand]
|
||||||
|
B --> C3[对话通道层 SSE / WS / HTTP]
|
||||||
|
B --> C4[执行层 CommandService + Host Handler]
|
||||||
|
B --> C5[输出层 TtsService]
|
||||||
|
B --> C6[存储层 PersistenceService]
|
||||||
|
B --> C7[基础设施 Config / Logger / Redis / Location]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### **4.1.5 代码示例**
|
||||||
|
|
||||||
|
- 初始化:
|
||||||
|
```dart
|
||||||
|
await AiChatCore.init(
|
||||||
|
config: CoreConfig(
|
||||||
|
endpoints: Endpoints(
|
||||||
|
classify: "...",
|
||||||
|
sse: "...",
|
||||||
|
ws: "...",
|
||||||
|
controlParse: "...",
|
||||||
|
controlExec: "...",
|
||||||
|
voice: "...",
|
||||||
|
),
|
||||||
|
timeouts: Timeouts(connectMs: 8000, receiveMs: 20000),
|
||||||
|
enablePersistence: true,
|
||||||
|
persistenceMode: PersistenceMode.hive,
|
||||||
|
retryPolicy: RetryPolicy(maxAttempts: 2, backoffBaseMs: 400),
|
||||||
|
),
|
||||||
|
commandHandler: MyVehicleCommandHandler(),
|
||||||
|
logger: CustomLogger(),
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
- 统一公共接口:
|
||||||
|
```dart
|
||||||
|
abstract class AiChatCore {
|
||||||
|
static Future<void> init({required CoreConfig config, required VehicleCommandHandler commandHandler, Logger? logger});
|
||||||
|
static MessageService get messageService;
|
||||||
|
static PersistenceService? get persistence;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageService {
|
||||||
|
Stream<List<Message>> get messageStream;
|
||||||
|
Future<void> startVoiceInput();
|
||||||
|
Future<void> stopAndProcessVoiceInput();
|
||||||
|
Future<void> sendText(String text);
|
||||||
|
Future<void> abortAnswer();
|
||||||
|
Future<void> loadHistory({required int page, required int pageSize});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## 参考文件
|
## 参考文件
|
||||||
|
|
||||||
[AI Assistant in One App.pdf](https://telekom-my.sharepoint.de/:b:/r/personal/guangfei_zhao_t-systems_com/Documents/Dokumente/AI%20Assistant%20in%20One%20App.pdf?csf=1&web=1&e=On4V2o)
|
[AI Assistant in One App.pdf](https://telekom-my.sharepoint.de/:b:/r/personal/guangfei_zhao_t-systems_com/Documents/Dokumente/AI%20Assistant%20in%20One%20App.pdf?csf=1&web=1&e=On4V2o)
|
||||||
|
|||||||
Reference in New Issue
Block a user