Files
Situation-Awareness-Platfor…/docs/AI智能助手功能实现详解.md
cfy666 c1e9a4be83 chore: sync local changes and add documentation
- Update yarn.lock
- Add project implementation docs in docs/
- Add personal internship experience notes in 实习讲解/
2026-06-29 19:47:30 +08:00

365 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI 智能助手功能 — 面试版
> 简历原话:**"集成 @matechat/core 实现 AI 智能助手功能,支持多轮对话、思考过程展示、组件化消息渲染(软件详情/预警列表/智能推荐)"**
>
> 这篇文档帮你理解这句话背后到底做了什么,以及面试时怎么讲。
---
## 一、先搞清楚:这句话到底是什么意思?
拆成四部分理解:
| 关键词 | 含义 | 项目中对应 |
|--------|------|------------|
| **集成 @matechat/core** | 使用华为 MateChat 组件库提供聊天 UI | McBubble气泡、McInput输入框、McMarkdownCardMarkdown 渲染)等组件 |
| **多轮对话** | 用户可以连续提问AI 记住上下文 | 前端创建 conversationId后端维护对话历史每次请求带上 conversationId |
| **思考过程展示** | AI 回答前展示它"想"了什么步骤 | 后端返回 states 对象,前端解析为"意图分析→SQL判断→SQL执行"步骤展示 |
| **组件化消息渲染** | 不同类型的 AI 回答用不同组件展示 | 5 种消息类型:普通文本、开源软件列表、预警列表、软件详情、数据表格 |
**一句话概括**:我用 MateChat 组件库搭建了 AI 聊天界面实现了多轮对话9 个 API、思考过程可视化、以及 5 种消息类型的组件化渲染。
---
## 二、整体架构
```
┌─────────────────────────────────────────────────┐
│ AI 助手页面(/ai
│ │
│ ┌──────────┐ ┌──────────────────────────────┐ │
│ │ 左侧边栏 │ │ 对话区域 │ │
│ │ │ │ ┌──────────────────────────┐ │ │
│ │ 历史会话列表│ │ │ McBubble用户消息 │ │ │
│ │ 收藏会话 │ │ └──────────────────────────┘ │ │
│ │ 搜索/删除 │ │ ┌──────────────────────────┐ │ │
│ │ 批量管理 │ │ │ McBubbleAI回复 │ │ │
│ │ │ │ │ ├── 思考过程(可折叠) │ │ │
│ │ │ │ │ ├── OssList软件列表 │ │ │
│ │ │ │ │ ├── WarningList预警列表 │ │ │
│ │ │ │ │ ├── OssDetail软件详情 │ │ │
│ │ │ │ │ ├── AIList数据表格 │ │ │
│ │ │ │ │ └── OtherMarkdown文本 │ │ │
│ │ │ │ └──────────────────────────┘ │ │
│ │ │ │ ┌──────────────────────────┐ │ │
│ │ │ │ │ 猜你想问(推荐问题) │ │ │
│ │ │ │ └──────────────────────────┘ │ │
│ │ │ │ ┌──────────────────────────┐ │ │
│ │ │ │ │ McInput输入框 │ │ │
│ │ │ │ └──────────────────────────┘ │ │
│ └──────────┘ └──────────────────────────────┘ │
└─────────────────────────────────────────────────┘
```
---
## 三、@matechat/core 用在了哪里?
MateChat 是华为开源的 AI 聊天 UI 组件库。项目中用了这些组件:
| 组件 | 用在哪 | 干什么 |
|------|--------|--------|
| `McBubble` | 对话区域 | 消息气泡(区分用户/AI支持 loading 状态) |
| `McInput` | 底部输入框 | 文本输入,支持字数限制、回车发送、清空 |
| `McMarkdownCard` | AI 文本回复 | 渲染 Markdown 格式的 AI 回答 |
| `McLayout` / `McLayoutContent` / `McLayoutSender` | 弹窗版 AI | KnowledgeHub 的 AI 弹窗布局 |
全局注册后直接使用:
```typescript
// main.ts
import MateChat from '@matechat/core';
app.use(MateChat);
```
```vue
<!-- 直接用不需要 import -->
<McBubble :content="msg.content" :align="'right'" /> <!-- 用户消息靠右 -->
<McBubble :loading="true"> <!-- AI 回复靠左 + loading -->
<Other :content="msg.content" />
</McBubble>
<McInput @submit="onSubmit" /> <!-- 底部输入框 -->
```
---
## 四、怎么实现的?(面试核心)
### 4.1 多轮对话
**问题**用户连续问多个问题AI 要记住之前的对话内容。
**解决方案**:用 conversationId 串联整个对话,后端维护历史。
```
用户发第一条消息
前端没有 conversationId → 调用 createConversation API → 获得 conversationId
前端发送消息:{ userId, conversationId, question }
后端根据 conversationId 找到历史消息 → AI 结合历史回答
用户发第二条消息 → 带同一个 conversationId → 后端知道上下文
```
```typescript
// 1. 首次对话:创建会话
const CONV_ID = ref('');
const createConversation = async () => {
const { data } = await fetchCreateConversation({ userId: username });
CONV_ID.value = data.data.conversationId; // 保存会话 ID
};
// 2. 发送消息:带上 conversationId
const getAIAnswer = async (question) => {
const { data } = await fetchChatUseSql({
userId: username,
conversationId: CONV_ID.value, // ← 后端靠这个找到对话历史
question: question,
});
// 处理 AI 回复...
};
// 3. 切换历史会话:加载旧对话
const handleSelectConv = (convId) => {
CONV_ID.value = convId;
getConversationDetail(convId); // 从后端加载完整对话记录
};
```
**会话管理功能**(左侧边栏):
- 查看历史/收藏会话列表
- 搜索会话
- 重命名会话
- 收藏/取消收藏
- 删除会话
- 批量管理
---
### 4.2 思考过程展示
**问题**AI 回答时用户看不到它在干什么,体验像"黑盒"。
**解决方案**:后端返回 `states` 对象,前端解析为步骤列表展示。
```typescript
// 后端返回的数据包含 states
const { text, type, states } = row;
// 解析思考步骤
const processThinkStates = (states) => {
let thinkProcess = []; // 主步骤
let steps = []; // 子步骤
Object.keys(states).forEach(key => {
if (key === 'steps') {
// 子步骤
Object.keys(states[key]).forEach(subKey => {
steps.push({ name: subKey, status: states[key][subKey] });
});
} else {
// 主步骤意图分析、SQL有效性判断、SQL执行
thinkProcess.push({ name: key, status: states[key] });
}
});
return { thinkProcess, steps };
};
```
展示效果:
```
▼ 思考过程:
✓ 意图分析 成功
✓ SQL有效性判断 成功
✓ SQL执行 成功
✓ 数据查询 成功
✓ 结果格式化 成功
```
用户可以点击折叠/展开思考过程。每个步骤显示绿色"成功"或红色"失败"。
---
### 4.3 组件化消息渲染5 种消息类型)
**问题**AI 的回答不只是纯文本,还可能是表格、软件详情等不同格式。
**解决方案**:根据后端返回的 `type` 字段,用不同组件渲染。
```vue
<template v-for="(msg, idx) in messages" :key="idx">
<!-- 用户消息纯文本气泡 -->
<McBubble v-if="msg.role === 'user'" :content="msg.content" />
<!-- AI 消息根据 type 选择不同组件 -->
<McBubble v-else :loading="msg.loading">
<!-- 思考过程可折叠 -->
<div class="think-toggle-btn" @click="toggleThink(idx)">...</div>
<!-- 根据 type 渲染不同内容 -->
<OssList v-if="msg.type === 1" /> <!-- 开源软件列表 -->
<WarningList v-else-if="msg.type === 2" /> <!-- 预警列表 -->
<OssDetail v-else-if="msg.type === 'critical_software_info'" :id="msg.id" /> <!-- 软件详情 -->
<AIList v-else-if="msg.type === 'df'" :content="msg.content" /> <!-- 数据表格 -->
<Other v-else :content="msg.content" /> <!-- Markdown 文本 -->
</McBubble>
</template>
```
**5 种消息类型详解**
| type 值 | 渲染组件 | 用户看到什么 |
|---------|----------|------------|
| `1` | OssList | 开源软件列表表格(有分页、导出功能) |
| `2` | WarningList | 预警列表表格(有严重程度标签:高危/中危/低危) |
| `'critical_software_info'` | OssDetail | 软件详情页面(嵌入完整的软件详情组件) |
| `'df'` | AIList | 通用数据表格动态列名、JSON 解析) |
| `'text'` | Other | Markdown 格式的文本回答 |
| `'sql_error'` | Other | 错误信息(带错误图标) |
**type 判断逻辑**(后端返回 `df` 类型时还要二次判断):
```typescript
if (type === 'df') {
// 默认当普通表格
msg.type = 'df';
msg.content = row[type];
// 但如果表名是 critical_software_info 且只有一条数据 → 当软件详情
if (table_name.length === 1 && table_name[0] === 'critical_software_info') {
let arr = JSON.parse(row[type]);
if (arr.length === 1) {
msg.type = 'critical_software_info'; // 升级为软件详情
msg.id = arr[0].id;
msg.software_name = arr[0].software_name;
}
}
}
```
---
### 4.4 猜你想问(推荐问题)
AI 回答后,自动推荐相关后续问题:
```typescript
// AI 回答后,调用推荐问题 API
const fetchFollowupQuestions = async (question, df_id) => {
const { data } = await FetchFollowupQuestions({ question, df_id });
if (data.code === 200) {
followupQuestions.value = data.data; // 更新推荐问题列表
}
};
// 用户点击推荐问题 → 直接发送
<a v-for="q in followupQuestions" @click="onSubmit(q)">
<span>{{ q.question }}</span>
</a>
```
---
### 4.5 AI API 接口总览
项目对接了 9 个 AI 后端接口:
| 接口 | 干什么 | 调用时机 |
|------|--------|----------|
| `createConversation` | 创建新会话 | 用户发第一条消息时 |
| `chat_use_sql` | 发送消息/获取 AI 回复 | 每次用户发送消息 |
| `conversationList` | 获取会话列表 | 打开侧边栏时 |
| `conversationDetail` | 获取会话详情 | 点击历史会话时 |
| `provide_followup_questions` | 获取推荐问题 | AI 回答后 |
| `changeConversationTitle` | 重命名会话 | 用户编辑会话名 |
| `toggleConversationCollect` | 收藏/取消收藏 | 用户点击收藏 |
| `deleteConversation` | 删除会话 | 用户删除 |
| `update_recommend_questions` | 刷新推荐问题 | 用户点击"换一批" |
---
## 五、整体架构总结
```
@matechat/core 提供McBubble气泡+ McInput输入框+ McMarkdownCardMarkdown渲染
搭建聊天界面骨架
在 McBubble 内部渲染自定义内容组件:
├── OssList软件列表 ← type=1
├── WarningList预警列表 ← type=2
├── OssDetail软件详情 ← type='critical_software_info'
├── AIList数据表格 ← type='df'
└── OtherMarkdown文本 ← 默认
9 个 API 接口对接后端
conversationId 串联多轮对话
states 对象解析为思考过程
```
---
## 六、面试问答准备
### Q1"集成 @matechat/core 实现 AI 智能助手"具体做了什么?
> 我用华为开源的 MateChat 组件库搭建了 AI 聊天界面,核心组件是 McBubble消息气泡和 McInput输入框。实现了三个关键功能第一多轮对话通过 conversationId 串联整个对话,后端维护历史上下文,前端对接了 9 个 API 接口管理会话;第二,思考过程展示,后端返回 states 对象,前端解析为"意图分析→SQL判断→SQL执行"的步骤列表,支持折叠展开;第三,组件化消息渲染,根据后端返回的 type 字段,用 5 种不同组件渲染 AI 回复——开源软件列表、预警列表、软件详情、数据表格、Markdown 文本。
### Q2多轮对话怎么实现的
> 前后端配合。用户发第一条消息时,前端调 createConversation API 获取 conversationId。之后每条消息都带上这个 conversationId后端根据它找到整个对话历史AI 结合上下文回答。切换历史会话时,调 conversationDetail API 加载完整对话记录。前端还有完整的会话管理:历史列表、收藏、搜索、重命名、删除、批量管理。
### Q3思考过程展示怎么做的
> 后端 AI 接口返回的数据里有一个 states 对象包含主步骤意图分析、SQL有效性判断、SQL执行和子步骤。我写了一个 processThinkStates 函数解析这个对象,转换为 `{name, status}` 数组,存储在消息对象的 thinkProcess 和 steps 字段里。前端用可折叠的 UI 展示,每个步骤显示成功(绿色)或失败(红色)。这个功能是自定义实现的,不是 MateChat 组件库自带的。
### Q4组件化消息渲染是什么意思
> AI 的回答不只是纯文本,还可能是软件列表、预警表格、软件详情等。我根据后端返回的 type 字段判断消息类型,用 5 种不同组件渲染type=1 用 OssList 展示开源软件列表带分页和导出type=2 用 WarningList 展示预警列表带严重程度标签type='critical_software_info' 用 OssDetail 展示软件详情type='df' 用 AIList 展示通用数据表格,其他情况用 Other 组件渲染 Markdown 文本。所有这些组件都嵌在 MateChat 的 McBubble 气泡里。
### Q5为什么选 MateChat 而不是自己写聊天 UI
> 两个原因第一MateChat 提供了开箱即用的聊天气泡、输入框、Markdown 渲染等组件不用从零实现开发效率高第二MateChat 是华为开源的,和我们平台的技术方向一致,组件风格也和 DevUI 统一。不过思考过程展示、组件化消息渲染这些核心功能是自定义实现的MateChat 主要提供了 UI 骨架。
### Q6AI 后端是怎么连接的SSE 还是 WebSocket
> 用的是标准的 HTTP POST 请求,不是 SSE 也不是 WebSocket。每次用户发消息前端发一个 POST 请求,后端处理完返回完整响应。代码里有模拟流式输出的注释代码(用 setTimeout 逐字显示),但生产环境用的是同步请求-响应模式。
---
## 七、关键数字(面试时用)
| 数据 | 数字 |
|------|------|
| MateChat 组件库版本 | 1.4.0 |
| 使用的 MateChat 组件 | 5 种McBubble、McInput、McMarkdownCard、McLayout 系列) |
| 自定义消息组件 | 5 种OssList、WarningList、OssDetail、AIList、Other |
| AI API 接口数量 | 9 个 |
| 消息类型 | 6 种text、df、critical_software_info、1、2、sql_error |
| 思考过程步骤 | 3 个主步骤 + N 个子步骤 |
| 会话管理功能 | 7 个(列表/搜索/重命名/收藏/删除/批量管理/历史限制) |
---
## 八、涉及的源码文件(需要看的时候查)
| 做什么 | 文件在哪 |
|--------|----------|
| AI 助手主页面(生产版) | `src/views/Jyh/AI/Home/index.vue` |
| 软件列表组件 | `src/views/Jyh/AI/Home/components/OssList.vue` |
| 预警列表组件 | `src/views/Jyh/AI/Home/components/WarningList.vue` |
| 软件详情组件 | `src/views/Jyh/AI/Home/components/OssDetail.vue` |
| 数据表格组件 | `src/views/Jyh/AI/Home/components/AIList.vue` |
| Markdown 文本组件 | `src/views/Jyh/AI/Home/components/Other.vue` |
| 猜你想问组件 | `src/views/Jyh/AI/Home/GuessYouWantToAsk.vue` |
| 功能轮播组件 | `src/views/Jyh/AI/Home/SwiperComponent.vue` |
| 会话历史侧边栏 | `src/views/Jyh/AI/Home/components/ViewHistoryAside/ViewHistoryAsideNew.vue` |
| 批量管理弹窗 | `src/views/Jyh/AI/Home/components/ViewHistoryAside/BatchManageModal.vue` |
| AI 布局 | `src/layouts/AILayout/index.vue` |
| AI 头部导航 | `src/components/Header/AIHeader.vue` |
| AI API 接口定义 | `src/api/jyh/index.ts`380-460 行) |
| KnowledgeHub AI 弹窗 | `src/views/Jyh/KnowledgeHub/Components/AIModal.vue` |
| AI 修复建议页面 | `src/views/Jyh/AIRepair/index.vue` |