GLM-4-9B-Chat-1M与Vue3前端集成:打造智能问答平台

1. 项目概述与价值

智能问答平台已经成为现代应用的标准配置,无论是客服系统、知识库检索还是在线教育,都需要一个能够理解用户意图并给出准确回应的智能助手。GLM-4-9B-Chat-1M作为支持百万级上下文的大语言模型,为我们提供了强大的自然语言处理能力,而Vue3的响应式特性和组合式API则让前端开发变得更加高效。

将这两个技术结合起来,你可以构建出既能处理复杂长文本对话,又能提供流畅用户体验的智能问答系统。想象一下,用户可以在一个界面中连续提问,模型能够记住之前的对话上下文,给出更加精准的回答,而且整个交互过程就像在和真人交流一样自然。

这种技术组合特别适合需要处理大量文本信息的场景,比如法律咨询、医疗问答、教育辅导等专业领域。用户不需要反复解释背景信息,系统能够基于完整的对话历史提供个性化的服务。

2. 环境准备与项目搭建

在开始编码之前,我们需要准备好开发环境。首先确保你的系统已经安装了Node.js(建议版本16以上)和npm包管理器。然后创建一个新的Vue3项目:

npm create vue@latest glm4-vue-chat
cd glm4-vue-chat
npm install

接下来安装项目所需的关键依赖。除了Vue3本身,我们还需要一些辅助库来处理网络请求和用户界面:

npm install axios pinia @element-plus/icons-vue
npm install -D @types/node

对于后端服务,你可以选择使用Python的FastAPI框架来搭建GLM-4-9B-Chat-1M的API接口。这里提供一个简单的后端示例:

from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

device = "cuda" if torch.cuda.is_available() else "cpu"
tokenizer = AutoTokenizer.from_pretrained("THUDM/glm-4-9b-chat-1m", trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
    "THUDM/glm-4-9b-chat-1m",
    torch_dtype=torch.bfloat16,
    low_cpu_mem_usage=True,
    trust_remote_code=True
).to(device).eval()

@app.post("/chat")
async def chat_endpoint(message: str):
    try:
        inputs = tokenizer.apply_chat_template(
            [{"role": "user", "content": message}],
            add_generation_prompt=True,
            tokenize=True,
            return_tensors="pt",
            return_dict=True
        )
        inputs = inputs.to(device)
        
        with torch.no_grad():
            outputs = model.generate(**inputs, max_length=2500, do_sample=True, top_k=1)
            response = tokenizer.decode(outputs[0], skip_special_tokens=True)
        
        return {"response": response}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

3. 前端架构设计

一个好的前端架构是项目成功的关键。我们采用Pinia进行状态管理,将聊天记录、用户设置等数据集中管理。首先创建聊天存储模块:

import { defineStore } from 'pinia'

export const useChatStore = defineStore('chat', {
  state: () => ({
    messages: [],
    isLoading: false,
    error: null
  }),
  actions: {
    async sendMessage(content) {
      this.isLoading = true
      this.error = null
      
      try {
        const response = await axios.post('http://localhost:8000/chat', {
          message: content
        })
        
        this.messages.push({
          role: 'assistant',
          content: response.data.response,
          timestamp: new Date()
        })
      } catch (error) {
        this.error = '发送消息失败,请重试'
      } finally {
        this.isLoading = false
      }
    }
  }
})

接下来创建主要的聊天组件。这个组件负责渲染聊天界面和处理用户交互:

<template>
  <div class="chat-container">
    <div class="messages-area">
      <div v-for="(message, index) in chatStore.messages" :key="index" 
           :class="['message', message.role]">
        <div class="message-content">{{ message.content }}</div>
        <div class="message-time">{{ formatTime(message.timestamp) }}</div>
      </div>
    </div>
    
    <div class="input-area">
      <el-input
        v-model="inputMessage"
        placeholder="输入您的问题..."
        :disabled="chatStore.isLoading"
        @keyup.enter="sendMessage"
      />
      <el-button 
        type="primary" 
        :loading="chatStore.isLoading"
        @click="sendMessage"
      >
        发送
      </el-button>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { useChatStore } from '@/stores/chat'

const chatStore = useChatStore()
const inputMessage = ref('')

const sendMessage = async () => {
  if (!inputMessage.value.trim()) return
  
  await chatStore.sendMessage(inputMessage.value)
  inputMessage.value = ''
}

const formatTime = (timestamp) => {
  return new Date(timestamp).toLocaleTimeString()
}
</script>

4. 流式响应实现

传统的问答接口需要等待整个响应生成完毕才能返回结果,这会导致用户等待时间过长。流式响应可以让模型一边生成一边返回结果,大大提升用户体验。

在后端,我们需要修改API接口以支持流式输出:

@app.post("/chat/stream")
async def chat_stream(message: str):
    def generate():
        inputs = tokenizer.apply_chat_template(
            [{"role": "user", "content": message}],
            add_generation_prompt=True,
            tokenize=True,
            return_tensors="pt",
            return_dict=True
        )
        inputs = inputs.to(device)
        
        for output in model.generate(**inputs, max_length=2500, do_sample=True, top_k=1, stream=True):
            yield tokenizer.decode(output, skip_special_tokens=True)
    
    return StreamingResponse(generate(), media_type="text/plain")

前端也需要相应的调整来处理流式响应。我们创建一个专门的处理函数:

async sendStreamMessage(content) {
  this.isLoading = true
  this.error = null
  
  // 添加用户消息
  this.messages.push({
    role: 'user',
    content: content,
    timestamp: new Date()
  })
  
  // 添加空的助手消息占位符
  const assistantMessageIndex = this.messages.push({
    role: 'assistant',
    content: '',
    timestamp: new Date()
  }) - 1

  try {
    const response = await fetch('http://localhost:8000/chat/stream', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ message: content })
    })
    
    const reader = response.body.getReader()
    const decoder = new TextDecoder()
    
    while (true) {
      const { done, value } = await reader.read()
      if (done) break
      
      const chunk = decoder.decode(value)
      this.messages[assistantMessageIndex].content += chunk
    }
  } catch (error) {
    this.error = '流式请求失败'
    this.messages[assistantMessageIndex].content = '抱歉,回答生成失败'
  } finally {
    this.isLoading = false
  }
}

5. 用户体验优化细节

一个优秀的智能问答平台不仅要功能强大,还要有良好的用户体验。以下是一些实用的优化建议:

首先是加载状态的处理。在模型生成回答时,给用户明确的反馈:

<template>
  <div class="typing-indicator" v-if="chatStore.isLoading">
    <span></span>
    <span></span>
    <span></span>
  </div>
</template>

<style>
.typing-indicator {
  display: flex;
  padding: 10px;
}

.typing-indicator span {
  height: 8px;
  width: 8px;
  background: #999;
  border-radius: 50%;
  margin: 0 2px;
  animation: typing 1s infinite;
}

.typing-indicator span:nth-child(2) {
  animation-delay: 0.2s;
}

.typing-indicator span:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes typing {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-5px); }
}
</style>

其次是错误处理机制。网络请求可能会失败,模型也可能生成不理想的结果,我们需要妥善处理这些情况:

// 在Pinia store中添加错误处理
actions: {
  async sendMessage(content) {
    // ... 之前的代码
    try {
      // 请求逻辑
    } catch (error) {
      if (error.response?.status === 429) {
        this.error = '请求过于频繁,请稍后再试'
      } else if (error.response?.status >= 500) {
        this.error = '服务器暂时不可用,请稍后重试'
      } else {
        this.error = '网络错误,请检查连接'
      }
    }
  }
}

最后是对话历史的管理。GLM-4-9B-Chat-1M支持长上下文,但过长的对话历史会影响性能,需要合理管理:

// 限制对话历史长度
const MAX_HISTORY_LENGTH = 20

actions: {
  async sendMessage(content) {
    // 添加新消息前检查历史长度
    if (this.messages.length >= MAX_HISTORY_LENGTH) {
      // 保留最近的对话,移除较早的历史
      this.messages = this.messages.slice(-MAX_HISTORY_LENGTH + 1)
    }
    // ... 其余逻辑
  }
}

6. 部署与性能考虑

当你的智能问答平台开发完成后,需要考虑如何部署到生产环境。前端可以使用Vite进行构建优化:

npm run build

生成的dist目录可以部署到任何静态文件服务器。对于后端服务,建议使用Docker容器化部署:

FROM python:3.9-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

性能方面,有几点需要特别注意。首先是模型推理的优化,可以考虑使用vLLM等推理加速框架:

from vllm import LLM, SamplingParams

llm = LLM(
    model="THUDM/glm-4-9b-chat-1m",
    tensor_parallel_size=1,
    max_model_len=131072,
    trust_remote_code=True
)

sampling_params = SamplingParams(temperature=0.95, max_tokens=1024)

其次是API的速率限制。为了防止滥用,应该添加适当的限流机制:

from slowapi import Limiter
from slowapi.util import get_remote_address

limiter = Limiter(key_func=get_remote_address)

@app.post("/chat")
@limiter.limit("10/minute")
async def chat_endpoint(message: str):
    # ... 原有逻辑

7. 总结

将GLM-4-9B-Chat-1M与Vue3集成创建智能问答平台,确实需要一些技术工作,但最终的效果是值得的。你不仅得到了一个能够处理复杂对话的智能系统,还拥有了现代化的用户界面和流畅的交互体验。

在实际使用中,你可能会发现一些需要调整的地方。比如对话历史的长度限制可能需要根据具体场景调整,流式响应的速度可能受网络环境影响,错误处理机制可能需要更加完善。这些都是正常的迭代过程,重要的是保持系统的可扩展性和可维护性。

如果你想要进一步提升系统的能力,可以考虑添加多轮对话管理、情感分析、或者与其他知识库系统集成。GLM-4-9B-Chat-1M的强大能力为这些扩展提供了很好的基础,而Vue3的灵活性让前端开发变得更加简单。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐