2025 年,AI 已不再是“炫技”,而是提升产品核心竞争力的关键工具。然而,许多团队在集成 AI 时陷入困境:

  • 聊天界面粗糙,加载状态缺失;
  • 用户不知道怎么问,首次体验差;
  • AI 回复纯文本,无法操作;
  • 多轮对话上下文混乱;
  • 无法与业务系统联动。

这些问题的本质,是缺乏一套面向 GenAI 的前端交互规范与工程方案

MateChat 正是为此而生。

由华为 DevUI 团队打造,MateChat 官网 将其定义为 “前端智能化场景解决方案 UI 库” —— 它提供了一整套经过设计验证的组件、交互模式与扩展机制,让你专注业务逻辑,而非重复实现聊天 UI

本文将带你从零开始,手写一个完整的 MateChat 应用,并逐步演进为支持流式响应、快捷指令、NL2UI、RAG 引用、智能体操作的智能助手。


第一步:创建项目并安装依赖

打开终端,执行:

npm create vite@latest my-matechat-app -- --template vue-ts
cd my-matechat-app
npm install

安装 MateChat 及配套依赖(版本来自官网):

npm install @matechat/core@1.2.0 vue-devui@2.3.0 @devui-design/icons@2.3.0

验证:访问 npmjs.com/package/@matechat/core,确认 1.2.0 为最新稳定版。


第二步:入口文件(main.ts)

使用 VS Code 或任意编辑器,打开 src/main.ts逐行输入以下内容

import { createApp } from 'vue'
import App from './App.vue'
import MateChat from '@matechat/core'
import '@devui-design/icons/icomoon/devui-icon.css'
import 'vue-devui/style.css'

const app = createApp(App)
app.use(MateChat)
app.mount('#app')

注意:这是 MateChat 官方文档推荐的注册方式,确保组件全局可用。


第三步:构建基础对话界面(App.vue)

新建或替换 src/App.vue手写以下代码

<template>
  <div class="container">
    <McLayout style="width: 760px; height: 90vh; margin: 20px auto;">
      <McHeader title="企业智能助手" />
      <McLayoutContent ref="chatContainer" class="chat-area">
        <McBubble
          v-for="(item, index) in messageList"
          :key="index"
          :align="item.role === 'user' ? 'right' : 'left'"
          :content="item.content"
          :loading="item.loading"
          :avatarConfig="{
            imgSrc: item.role === 'user'
              ? 'https://matechat.gitcode.com/png/demo/userAvatar.svg'
              : 'https://matechat.gitcode.com/logo.svg'
          }"
        />
      </McLayoutContent>
      <McLayoutSender>
        <McInput
          :value="inputText"
          placeholder="请输入您的问题..."
          :maxLength="2000"
          @change="onInputChange"
          @submit="onSubmit"
        />
      </McLayoutSender>
    </McLayout>
  </div>
</template>

<script setup lang="ts">
import { ref, nextTick } from 'vue'

interface ChatMessage {
  role: 'user' | 'assistant'
  content: string
  loading?: boolean
}

const inputText = ref('')
const messageList = ref<ChatMessage[]>([])
const chatContainer = ref<HTMLDivElement | null>(null)

const onInputChange = (val: string) => {
  inputText.value = val
}

const onSubmit = (text: string) => {
  if (!text.trim()) return

  // 添加用户消息
  messageList.value.push({ role: 'user', content: text })
  inputText.value = ''

  // 添加 AI 加载态
  messageList.value.push({ role: 'assistant', content: '', loading: true })

  scrollToBottom()

  // 模拟 AI 响应
  setTimeout(() => {
    const lastMsg = messageList.value[messageList.value.length - 1]
    lastMsg.loading = false
    lastMsg.content = `您好!您刚才说:“${text}”。这是由 MateChat 渲染的模拟回复。`
    scrollToBottom()
  }, 800)
}

const scrollToBottom = () => {
  nextTick(() => {
    if (chatContainer.value) {
      chatContainer.value.scrollTop = chatContainer.value.scrollHeight
    }
  })
}
</script>

<style scoped>
.container {
  padding: 16px;
  box-sizing: border-box;
}
.chat-area {
  padding: 8px 0;
  overflow-y: auto;
}
</style>

✅ 验证运行

终端执行:

npm run dev

打开浏览器访问 http://localhost:5173,你会看到:

  • 居中的聊天窗口
  • 输入“你好” → 右侧显示用户气泡
  • 左侧出现三个点跳动的加载动画
  • 800ms 后显示 AI 回复
  • 自动滚动到底部

💡 这就是 MateChat 的开箱即用能力——无需 CSS 样式调整,交互细节已内置


第四步:对接真实大模型(OpenAI 兼容 API)

4.1 安装 OpenAI SDK

npm install openai

4.2 创建 AI 客户端(utils/aiClient.ts)

新建 src/utils/aiClient.ts手写以下内容

import OpenAI from 'openai'

const client = new OpenAI({
  apiKey: import.meta.env.VITE_OPENAI_API_KEY,
  baseURL: import.meta.env.VITE_OPENAI_BASE_URL || 'https://api.openai.com/v1',
  dangerouslyAllowBrowser: true, // 仅开发环境使用
})

export async function streamCompletion(
  userMessage: string,
  onChunk: (delta: string) => void,
  onComplete: () => void
) {
  try {
    const stream = await client.chat.completions.create({
      model: import.meta.env.VITE_OPENAI_MODEL || 'gpt-4o-mini',
      messages: [{ role: 'user', content: userMessage }],
      stream: true,
    })

    for await (const chunk of stream) {
      const delta = chunk.choices[0]?.delta?.content || ''
      onChunk(delta)
    }
    onComplete()
  } catch (error) {
    console.error('AI 请求失败:', error)
    throw error
  }
}

4.3 配置环境变量

在项目根目录创建 .env.local

VITE_OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx
VITE_OPENAI_BASE_URL=https://api.openai.com/v1
VITE_OPENAI_MODEL=gpt-4o-mini

⚠️ 生产环境务必通过后端代理,避免密钥泄露。

4.4 替换 onSubmit 为真实流式调用

修改 App.vue 中的 onSubmit 函数:

// 在 script setup 顶部导入
import { streamCompletion } from './utils/aiClient'

// 替换 onSubmit
const onSubmit = async (text: string) => {
  if (!text.trim()) return

  messageList.value.push({ role: 'user', content: text })
  inputText.value = ''

  const aiMsg: ChatMessage = { role: 'assistant', content: '', loading: true }
  messageList.value.push(aiMsg)
  scrollToBottom()

  try {
    await streamCompletion(
      text,
      (delta) => {
        aiMsg.content += delta
        scrollToBottom()
      },
      () => {
        aiMsg.loading = false
      }
    )
  } catch (error) {
    aiMsg.content = '服务暂时不可用,请稍后重试。'
    aiMsg.loading = false
  }
}

效果:实现真正的“打字机”式流式输出,用户体验质变。


第五步:创新功能一 —— 快捷指令(降低使用门槛)

很多用户面对空白输入框不知所措。我们提供引导:

<McLayoutContent> 上方添加:

<McPrompt
  v-if="messageList.length === 0"
  :list="[
    { label: '帮我生成登录页代码', value: 'login' },
    { label: '解释什么是 RAG', value: 'rag' },
    { label: '写一个快速排序', value: 'quick-sort' }
  ]"
  direction="horizontal"
  @itemClick="handleSuggestion"
/>

并在 script 中添加:

const handleSuggestion = (item: { label: string }) => {
  inputText.value = item.label
  onSubmit(item.label)
}

效果:首页展示三个按钮,点击自动提问,极大提升首次转化率。


第六步:创新功能二 —— 自然语言生成 UI(NL2UI)

用户说:“生成一个包含姓名和邮箱的表单”,AI 返回结构化数据,前端动态渲染。

6.1 修改 McBubble 支持自定义内容

将原 <McBubble> 替换为:

<McBubble
  v-for="(item, index) in messageList"
  :key="index"
  :align="item.role === 'user' ? 'right' : 'left'"
  :loading="item.loading"
  :avatarConfig="{
    imgSrc: item.role === 'user'
      ? 'https://matechat.gitcode.com/png/demo/userAvatar.svg'
      : 'https://matechat.gitcode.com/logo.svg'
  }"
>
  <template #default>
    <div v-if="item.uiSpec">
      <DForm :model="formModel" label-width="80px">
        <DFormItem
          v-for="field in item.uiSpec.fields"
          :key="field.name"
          :label="field.label"
          :field="field.name"
        >
          <DInput v-model="formModel[field.name]" :placeholder="`请输入${field.label}`" />
        </DFormItem>
      </DForm>
    </div>
    <div v-else v-html="item.content"></div>
  </template>
</McBubble>

6.2 解析 AI 返回的 JSON

修改流完成回调:

onComplete: () => {
  aiMsg.loading = false

  // 尝试解析 JSON
  const trimmed = aiMsg.content.trim()
  if (trimmed.startsWith('{') && trimmed.endsWith('}')) {
    try {
      const spec = JSON.parse(trimmed)
      if (spec.type === 'form' && Array.isArray(spec.fields)) {
        aiMsg.uiSpec = spec
        aiMsg.content = '' // 清空文本

        // 初始化表单模型
        const model: Record<string, string> = {}
        spec.fields.forEach((f: any) => model[f.name] = '')
        formModel = reactive(model)
      }
    } catch (e) {
      // 不是有效 JSON,保留原文本
    }
  }
}

并在顶部声明 formModel

import { reactive } from 'vue'
const formModel = reactive<Record<string, string>>({})

测试提示词

“请返回一个 JSON,type 为 'form',fields 包含 name 和 email”

AI 返回:

{
  "type": "form",
  "fields": [
    { "name": "name", "label": "姓名" },
    { "name": "email", "label": "邮箱" }
  ]
}

效果:页面自动渲染可交互表单!


第七步:创新功能三 —— RAG 引用展示

为提升可信度,展示知识来源。

假设后端返回:

{
  "content": "根据公司制度,年假为 15 天。",
  "sources": [
    { "title": "员工手册 v3.2", "url": "/docs/handbook.pdf" }
  ]
}

我们在 McBubble 中添加 footer 插槽:

<template #footer v-if="item.sources">
  <div class="citation-list">
    <span v-for="(src, i) in item.sources" :key="i" class="citation-item">
      <a :href="src.url" target="_blank" rel="noopener">{{ src.title }}</a>
    </span>
  </div>
</template>

并添加样式:

.citation-list {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px dashed #ccc;
  font-size: 12px;
  color: #666;
}
.citation-item:not(:last-child)::after {
  content: "|";
  margin: 0 6px;
  color: #999;
}

实现需后端配合,在 SSE 流中携带 sources 字段。


第八步:创新功能四 —— 智能体操作(AI 执行动作)

AI 不仅回答,还能触发业务操作。

示例:部署服务

AI 返回:

{
  "action": {
    "type": "deploy",
    "serviceId": "svc-789",
    "label": "立即部署"
  }
}

我们在 bubble 中渲染按钮:

<template #actions v-if="item.action">
  <DButton type="primary" size="sm" @click="executeAction(item.action)">
    {{ item.action.label }}
  </DButton>
</template>

并实现 executeAction

const executeAction = (action: any) => {
  if (action.type === 'deploy') {
    alert(`正在部署服务 ${action.serviceId}...`)
    // 实际调用部署 API
  }
}

意义:AI 从“信息提供者”变为“任务执行者”。


第九步:性能优化与主题适配

9.1 流式防抖(避免频繁重绘)

let buffer = ''
let timer: NodeJS.Timeout | null = null

const onChunk = (delta: string) => {
  buffer += delta
  if (timer) clearTimeout(timer)
  timer = setTimeout(() => {
    aiMsg.content += buffer
    buffer = ''
    scrollToBottom()
    timer = null
  }, 20)
}

9.2 暗黑模式切换

McLayout 上绑定主题:

<McLayout :data-theme="theme">

添加切换按钮:

<DButton @click="toggleTheme">切换{{ theme === 'dark' ? '亮色' : '暗色' }}</DButton>
const theme = ref<'light' | 'dark'>('light')
const toggleTheme = () => {
  theme.value = theme.value === 'light' ? 'dark' : 'light'
}

MateChat 自动适配 CSS 变量,无需额外样式。


结语:MateChat,让智能触手可及

通过本文,我们从零构建了一个功能完整的 AI 助手,并逐步集成了:

  • 真实流式响应
  • 快捷指令引导
  • 自然语言生成 UI
  • RAG 引用展示
  • 智能体操作执行
  • 主题与性能优化

这一切,都建立在 提供的标准化组件与交互范式之上。

它不是玩具,而是经过华为内部多个产品验证的企业级解决方案。无论你是开发内部知识库、AI 编码插件,还是 SaaS 智能客服,MateChat 都能大幅缩短你的交付周期,提升用户体验。

现在就访问 MateChat 官网,开启你的智能前端之旅!


相关链接
MateChat:https://gitcode.com/DevCloudFE/MateChat
MateChat官网:https://matechat.gitcode.com
DevUI官网:https://devui.design/home

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐