# AI 智能助手功能 — 面试版
> 简历原话:**"集成 @matechat/core 实现 AI 智能助手功能,支持多轮对话、思考过程展示、组件化消息渲染(软件详情/预警列表/智能推荐)"**
>
> 这篇文档帮你理解这句话背后到底做了什么,以及面试时怎么讲。
---
## 一、先搞清楚:这句话到底是什么意思?
拆成四部分理解:
| 关键词 | 含义 | 项目中对应 |
|--------|------|------------|
| **集成 @matechat/core** | 使用华为 MateChat 组件库提供聊天 UI | McBubble(气泡)、McInput(输入框)、McMarkdownCard(Markdown 渲染)等组件 |
| **多轮对话** | 用户可以连续提问,AI 记住上下文 | 前端创建 conversationId,后端维护对话历史,每次请求带上 conversationId |
| **思考过程展示** | AI 回答前展示它"想"了什么步骤 | 后端返回 states 对象,前端解析为"意图分析→SQL判断→SQL执行"步骤展示 |
| **组件化消息渲染** | 不同类型的 AI 回答用不同组件展示 | 5 种消息类型:普通文本、开源软件列表、预警列表、软件详情、数据表格 |
**一句话概括**:我用 MateChat 组件库搭建了 AI 聊天界面,实现了多轮对话(9 个 API)、思考过程可视化、以及 5 种消息类型的组件化渲染。
---
## 二、整体架构
```
┌─────────────────────────────────────────────────┐
│ AI 助手页面(/ai) │
│ │
│ ┌──────────┐ ┌──────────────────────────────┐ │
│ │ 左侧边栏 │ │ 对话区域 │ │
│ │ │ │ ┌──────────────────────────┐ │ │
│ │ 历史会话列表│ │ │ McBubble(用户消息) │ │ │
│ │ 收藏会话 │ │ └──────────────────────────┘ │ │
│ │ 搜索/删除 │ │ ┌──────────────────────────┐ │ │
│ │ 批量管理 │ │ │ McBubble(AI回复) │ │ │
│ │ │ │ │ ├── 思考过程(可折叠) │ │ │
│ │ │ │ │ ├── OssList(软件列表) │ │ │
│ │ │ │ │ ├── WarningList(预警列表) │ │ │
│ │ │ │ │ ├── OssDetail(软件详情) │ │ │
│ │ │ │ │ ├── AIList(数据表格) │ │ │
│ │ │ │ │ └── Other(Markdown文本) │ │ │
│ │ │ │ └──────────────────────────┘ │ │
│ │ │ │ ┌──────────────────────────┐ │ │
│ │ │ │ │ 猜你想问(推荐问题) │ │ │
│ │ │ │ └──────────────────────────┘ │ │
│ │ │ │ ┌──────────────────────────┐ │ │
│ │ │ │ │ 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
```
---
## 四、怎么实现的?(面试核心)
### 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
...
```
**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; // 更新推荐问题列表
}
};
// 用户点击推荐问题 → 直接发送
{{ q.question }}
```
---
### 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(输入框)+ McMarkdownCard(Markdown渲染)
↓
搭建聊天界面骨架
↓
在 McBubble 内部渲染自定义内容组件:
├── OssList(软件列表) ← type=1
├── WarningList(预警列表) ← type=2
├── OssDetail(软件详情) ← type='critical_software_info'
├── AIList(数据表格) ← type='df'
└── Other(Markdown文本) ← 默认
↓
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 骨架。
### Q6:AI 后端是怎么连接的?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` |