侧边栏壁纸
  • 累计撰写 22 篇文章
  • 累计创建 1 个标签
  • 累计收到 1 条评论
标签搜索

目 录CONTENT

文章目录

花半小时写一个属于自己的ChatGPT

程序员老潘
2023-04-05 / 0 评论 / 0 点赞 / 280 阅读 / 1,892 字

花半小时写一个属于自己的ChatGPT

最近ChatGPT爆火,未来绝对是各行各业的新趋势,对于程序员来说这是不可不学的新技术新领域,一定要把握时代的浪潮,才能不被这个卷到离谱的社会所淘汰。
废话不多说直接上演示结果!
image-1697554566247

准备

为了保证咱们得数据安全,也为了前端同学更好的开发一个前后端分离的项目,这里我们需要用到的后端框架是基于nodejs的egg后端框架,不是很了解的同学可以去egg官网了解下。
需要准备以下技术点和工具:

  1. 阿里云-FC函数计算
  2. 百度文心一言API/阿里云灵积模型API
  3. vue3+vant+vite
  4. egg框架

开始

后端部分

搭建部署后端项目

1.打开阿里云,搜索FC函数计算
2.点击应用-创建应用
3.选择web开发框架,选择egg,熟悉node开发的同学也可以选择express框架,再点立即创建。
image-1697555921207
image-1697556002234
这个选择通过代码仓库部署,可以选择自己的github也可以选择自己的私有仓库,其他选项根据自己情况填写即可。
4.创建完成后自动部署代码,并且会生成访问地址。
image-1697556309410
点击链接就可以直接访问这个项目啦~

编写代码

我们可以直接在阿里云内云端开发,也可以去我们的代码仓库开发。
下面直接上代码:

code/app/router.js

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.post('/api/v1/createBaiduAiChat', controller.v1.aichat.createBaiduAiChat); // 直接创建对话
};

code/app/controller/v1/aichat.js

'use strict';

const Controller = require('egg').Controller;
const request = require('request')

class AichatController extends Controller {
async createBaiduAiChat() {
    const { ctx } = this;
    const key = this.app.config.baiduAiKey.key; //这里直接替换成自己百度的key
    const secret = this.app.config.baiduAiKey.secret;  //这里直接替换成自己百度的secret
    const { data } = ctx.request.body;

   const res = await new Promise((resolve,reject)=>{
      var options = {
          'method': 'POST',
          'url': 'https://aip.baidubce.com/oauth/2.0/token?client_id='+key+'&client_secret='+secret+'&grant_type=client_credentials',
          'headers': {
            'Content-Type': 'application/json',
            'Accept': 'application/json'
          }
      };
      request(options, function (error, response) {
        if(error) reject(error)
        resolve(response.body)
      });
    })
    const resToJson = JSON.parse(res)
    if(!resToJson.error){
      const result = await new Promise((resolve,reject)=>{
        var options = {
          'method': 'POST',
          'url': 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions?access_token='+resToJson.access_token,
          'headers': {
                  'Content-Type': 'application/json'
          },
          'body':JSON.stringify(data)
        };
    
        request(options, function (error, response) {
          if(error) reject(error)
          resolve(response.body)
        });
      })
      const resultToJson = JSON.parse(result)
      if(!resultToJson.error_code){
        ctx.body = {
          code: 200,
          msg: 'success',
          data: resultToJson
        };
      }else{
        ctx.body = {
          code: -1,
          msg: 'error',
          data: resultToJson
        };
      } 
    }else{
      ctx.body = {
        code: -1,
        msg: 'error',
        data: resToJson
      };
    }
  }
  module.exports = AichatController;

最后修改配置接口调用方式
s.yaml
image-1697557363184

关于使用百度文心一言调用接口API可以看这里
https://cloud.baidu.com/doc/WENXINWORKSHOP/s/flfmc9do2
关于使用阿里云千义通问调用接口API可以看这里
https://help.aliyun.com/zh/dashscope/developer-reference/api-details?spm=a2c4g.11186623.0.0.51364bc1DGkLIH#341800c0f8w0r

这里主要都是需要去注册key和secret,注册都是免费的,但是调用token是收费的,具体收费标准可以去看看文档,前期都有免费额度可以进行调用。

按照上面的代码直接提交代码到仓库,阿里云内会自动部署,这样一个后端接口
完整的接口地址应该类似如下:
http://egg.web-framework-bjct.1873764751702483.cn-hangzhou.fc.devsapp.net/api/v1/createBaiduAiChat
后面我们也可以通过绑定自定义域名调整接口地址

前端部分

编写代码

全局安装create-vite 方便我们创建项目

npm install -g create-vite

使用 create-vite 命令创建一个新的 Vite 项目,选择 Vue 3 和 TypeScript 作为选项:

create-vite my-aichat --template vue-ts

进入项目

cd my-aichat

安装依赖vantvue-markdown-editor

npm install
npm i vant
npm i @kangc/v-md-editor@next -S

/src/main.ts 配置

import { createApp } from 'vue'
import 'vant/lib/index.css';
import './style.css'
import App from './App.vue'

import VMdPreview from '@kangc/v-md-editor/lib/preview';
import '@kangc/v-md-editor/lib/style/preview.css';

import githubTheme from '@kangc/v-md-editor/lib/theme/github.js';
import '@kangc/v-md-editor/lib/theme/style/github.css';

import createCopyCodePlugin from '@kangc/v-md-editor/lib/plugins/copy-code/index';
import '@kangc/v-md-editor/lib/plugins/copy-code/copy-code.css';

// import vuepressTheme from '@kangc/v-md-editor/lib/theme/vuepress.js';
import '@kangc/v-md-editor/lib/theme/style/vuepress.css';

// highlightjs
import hljs from 'highlight.js';

VMdPreview.use(githubTheme, {
  Hljs: hljs,
});
// VMdPreview.use(vuepressTheme)
VMdPreview.use(createCopyCodePlugin())
createApp(App).use(VMdPreview).mount('#app')

/src/App.vue

<template>
  <div class="page_content">
    <div class="page_bottom">
      <template v-for="(item, index) in chatList">
        <div class="pad_05rem" v-if="item.type === 'sys'" :key="index">
          <div class="flex_item_center">
            <van-image class="padright_05rem" round width="2rem" height="2rem" :src="avatarurl" />
            AI智能机器人
          </div>
          <v-md-preview :text="item.text" preview-class="vuepress-markdown-body"></v-md-preview>
        </div>
        <div class="pad_05rem" v-if="item.type === 'user'" :key="index">
          <div class="flex_item_center">
            <van-image class="padright_05rem" round width="2rem" height="2rem" :src="myavatarurl" />
            我
          </div>
          <v-md-preview :text="item.text" preview-class="vuepress-markdown-body"></v-md-preview>
        </div>
      </template>
      <div class="btn_bottom">
        <van-cell-group inset>
          <van-field v-model="message" rows="1" autosize type="textarea" placeholder="请输入您要问的问题">
            <template #button>
              <van-button size="small" icon="guide-o" :loading="isLoading" type="primary" @click="getAIchatFun"
                loading-text="发送中...">发送</van-button>
            </template>
          </van-field>
        </van-cell-group>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { showToast } from 'vant';
import axios from 'axios';

interface chatObj {
  type: 'sys' | 'user'
  text: string
}

const message = ref('')
const isLoading = ref(false)
const chatList = ref<Array<chatObj>>([])
const avatarurl = "https://img0.baidu.com/it/u=1180901446,1801124233&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=501"
const myavatarurl = "http://www.eftik.com/wp-content/uploads/2023/10/202106290021.jpg"

onMounted(() => {
  setTimeout(() => {
    chatList.value.push({
      type: 'sys',
      text: '您好,我是AI智能机器人,请问有什么可以帮您?'
    })
  }, 500);
})

onUpdated(() => {
  // 让页面滚动到底部
  document.documentElement.scrollTop = document.documentElement.scrollHeight
})

const getAIchatFun = () => {
  if (message.value === '') {
    showToast('请输入您要问的问题');
    return false;
  }
  chatList.value.push({
    type: 'user',
    text: message.value
  })
  isLoading.value = true
  axios.post("http://egg.web-framework-bjct.1873764751702483.cn-hangzhou.fc.devsapp.net/api/v1/createBaiduAiChat",
    {
      data: {
        "messages": [
          { "role": "user", "content": message.value }
        ]
      }
    },
  ).then(res => {
    console.log(res);
    if (res.status === 200) {
      if (res.data.code === 200) {
        chatList.value.push({
          type: 'sys',
          text: res.data.data.result
        })
      } else {
        chatList.value.push({
          type: 'sys',
          text: res.data.data.error_description || res.data.data.error_msg
        })
      }
    } else {
      chatList.value.push({
        type: 'sys',
        text: res.data.data.error_description || res.data.data.error_msg
      })
    }

    isLoading.value = false
    message.value = ''
  }).catch(e => {
    chatList.value.push({
      type: 'sys',
      text: e.message
    })
    isLoading.value = false
    message.value = ''
  })
}
</script>


<style scoped>
.page_content{
  height: 100%;
  width: 100%;
}
.page_bottom{
  padding-bottom: 6rem;
}
.pad_05rem{
  padding: .5rem;
}
.padright_05rem{
  padding-right: .5rem;
}
.flex_item_center{
  display: flex;
  align-items: center;
}
.btn_bottom{
  bottom: 1rem;
  position: fixed;
  width: 100%;
  z-index: 9999;
}
</style>

启动项目

npm run dev

部署项目

npm run build

大功告成!

0

评论区