# 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` |