快速搭建基于GTP的AI聊天机器人

后端使用python flask,前端使用vue,本片文章所有代码均由tongyi lingma自动完成

后端搭建:

安装flask
pip install Flask
安装flask-cors(解决跨域问题)
pip install flask-cors
安装openai
pip install openai
安装环境变量配置包
pip install python-dotenv openai

创建.env文件,配置openai的key
在这里插入图片描述
创建py文件

from openai import OpenAI
from dotenv import load_dotenv, find_dotenv
from flask import Flask, request, jsonify
from flask_cors import CORS

# 加载 .env 文件中定义的环境变量
_ = load_dotenv(find_dotenv())

# 初始化 OpenAI 客户端
client = OpenAI()  # 默认使用环境变量中的 OPENAI_API_KEY 和 OPENAI_BASE_URL

# 初始化 Flask 应用
app = Flask(__name__)

# 允许跨源请求
cors = CORS(app, resources={r"/api/*": {"origins": "http://localhost:8080"}})

def get_completion(prompt, response_format="text", model="gpt-3.5-turbo"):
    messages = [{"role": "user", "content": prompt}]  # 将 prompt 作为用户输入

    response = client.chat.completions.create(  # 注意这里是 ChatCompletion
        model=model,
        messages=messages,
        temperature=0,                                  # 模型输出的随机性,0 表示随机性最小
        # 返回消息的格式,text 或 json_object
        response_format={"type": response_format},
    )

    return response.choices[0].message.content          # 返回模型生成的文本


@app.route('/api/answer', methods=['POST'])
def answer_question():
    # 获取请求中的问题数据
    question = request.json.get('question')

    if not question:
        return jsonify(error='Missing required parameter: question'), 400

    # 调用 OpenAI GPT-3 模型
    answer = get_completion(question, response_format="text")

    return jsonify(answer=answer)

if __name__ == '__main__':
    app.run(debug=True)

启动后端服务
在这里插入图片描述

前端搭建:

安装vue
npm install -g @vue/cli
安装axios
npm install axios
创建前端项目
npx @vue/cli create dialog-robot
添加router
npm install vue-router@next

src下新增router.js文件

import { createRouter, createWebHashHistory } from 'vue-router';
import Chat from '@/views/Chat.vue';

const routes = [
  {
    path: '/chat',
    component: Chat,
  },
  {
    path: '/', // 重定向路由
    redirect: '/chat',
  },
];

const router = createRouter({
  history: createWebHashHistory(),
  routes,
});

export default router;

修改main.js

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';

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

src下创建views目录,新增Chat.vue文件

<template>
    <div class="chat-container">
      <div class="chat-header">
        <img :src="robotAvatar" alt="Robot Avatar" class="chat-avatar">
        <h3 class="chat-title">对话机器人</h3>
      </div>
  
      <div class="chat-body">
        <div v-for="(message, index) in chatHistory" :key="index" class="chat-message">
          <img v-if="message.isBot" :src="robotAvatar" alt="Robot Avatar" class="chat-message-avatar">
          <p v-if="!message.isBot" class="chat-message-user-avatar"></p>
  
          <div class="chat-message-content">
            <span class="chat-message-timestamp">{{ message.timestamp }}</span>
            <div>
                <span v-html="message.text"></span>
            </div>
          </div>
        </div>
      </div>
  
      <div class="chat-footer">
        <textarea v-model="inputText" placeholder="请输入您的问题或留言..." @keydown.enter.prevent="sendMessage"></textarea>
        <button @click="sendMessage" class="send-button">发送</button>
      </div>
    </div>
  </template>
  
  <script>
  import axios from 'axios';
  
  export default {
    name: 'ChatRobot',
    data() {
      return {
        robotAvatar: require('@/assets/robot-avatar.png'), // 替换为实际机器人头像路径
        chatHistory: [
          // 初始聊天记录(可从后端API获取或模拟数据)
        ],
        inputText: '',
      };
    },
    methods: {
      async sendMessage() {
        if (!this.inputText.trim()) return;
  
        const question = this.inputText;
        this.chatHistory.push({ isBot: false, text: question, timestamp: new Date().toLocaleTimeString() });
        this.inputText = '';
  
        try {
          const response = await axios.post('http://127.0.0.1:5000/api/answer', { question }, { timeout: 5000 }); // 设置超时时间(可选)
  
          if (response.status === 200 && response.data.answer) {
            const answer = response.data.answer;
            this.chatHistory.push({ isBot: true, text: answer, timestamp: new Date().toLocaleTimeString() });
          } else {
            console.error('Failed to get answer from server:', response.statusText);
            // 可以在这里添加错误处理,如显示错误消息或重试等
          }
        } catch (error) {
          console.error('Error while sending request:', error.message);
          // 可以在这里添加错误处理,如显示错误消息或重试等
        }
      },
    },
  };
  </script>
  
  <style scoped>
  .chat-container {
    display: flex;
    flex-direction: column;
    height: 100vh;
  }
  
  .chat-header {
    display: flex;
    align-items: center;
    padding: 1rem;
    background-color: #f5f5f5;
  }
  
  .chat-avatar {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    margin-right: 1rem;
  }
  
  .chat-title {
    font-size: 1.2rem;
    font-weight: bold;
  }
  
  .chat-body {
    flex-grow: 1;
    overflow-y: auto;
    padding: 1rem;
  }
  
  .chat-message {
    display: flex;
    align-items: flex-start;
    margin-bottom: 1rem;
  }
  
  .chat-message-avatar,
  .chat-message-user-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    margin-right: 1rem;
    font-size: 0.9rem;
    color: white;
    background-color: #6c757d;
    text-align: center;
  }
  
  .chat-message-avatar {
    object-fit: cover;
  }
  
  .chat-message-content {
    flex-grow: 1;
    min-width: 0;
  }
  
  .chat-message-text {
    display: inline-block;
    max-width: ¾;
  }
  
  .chat-message-timestamp {
    font-size: 0.½rem;
    color: #6c757d;
    margin-top: 0.25rem;
  }
  
  .chat-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem;
    background-color: #f5f5f5;
    border-top: 1px solid #dee2e6;
  }
  
  textarea {
    flex-grow: 1;
    min-height: ¼;
    padding: 0.5rem;
    resize: none;
    border: none;
    outline: none;
  }
  
  .send-button {
    padding: 0.5rem 1rem;
    border: none;
    background-color: #0d6efd;
    color: white;
    cursor: pointer;
  }
  </style>

项目结构
在这里插入图片描述

启动前端
npm run serve

本地访问http://localhost:8080/chat

开始聊天
在这里插入图片描述

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值