当前位置:首页 > 编程笔记 > 正文
已解决

讯飞星火大模型V3.0 WebApi使用

来自网友在路上 182882提问 提问时间:2023-10-28 18:01:58阅读次数: 82

最佳答案 问答题库828位专家为你答疑解惑

讯飞星火大模型V3.0 WebApi使用

文档说明:星火认知大模型Web文档 | 讯飞开放平台文档中心 (xfyun.cn)

实现效果

初始化

首先构建一个基础脚手架项目

npm init vue@latest

用到如下依赖

"dependencies": {"crypto-js": "^4.2.0","highlight.js": "^11.9.0","marked": "^9.1.3","pinia": "^2.1.7","pinia-plugin-persistedstate": "^3.2.0","vue": "^3.3.4","vue-router": "^4.2.5"}

修改 main.js

import './assets/main.css'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import PiniaPluginPersistedstate from "pinia-plugin-persistedstate"
import App from './App.vue'
import router from './router'
import highlight from 'highlight.js'
import "highlight.js/styles/atom-one-dark.css"const app = createApp(App)
// 配置Pinia并设置持久化缓存
const pinia = createPinia()
pinia.use(PiniaPluginPersistedstate)app.use(pinia)
app.use(router)// 配置Markdown语法高亮
app.directive("highlight",function(el){let blocks = el.querySelectorAll('pre code');blocks.forEach((block)=>{highlight.highlightBlock(block);})
})app.mount('#app')

TTSRecorder

新建 utils/TTSRecorder.js

这个文件封装了发送消息并相应消息的核心功能

import CryptoJS from "crypto-js"
const APPID = '' // 从控制台可以获取
const API_SECRET = '' // 从控制台可以获取
const API_KEY = '' // 从控制台可以获取
let total_res = "";function getWebsocketUrl() {return new Promise((resolve, reject) => {var apiKey = API_KEYvar apiSecret = API_SECRETvar url = 'ws://spark-api.xf-yun.com/v3.1/chat'var host = location.hostvar date = new Date().toGMTString()var algorithm = 'hmac-sha256'var headers = 'host date request-line'var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v3.1/chat HTTP/1.1`var signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret)var signature = CryptoJS.enc.Base64.stringify(signatureSha)var authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`var authorization = btoa(authorizationOrigin)url = `${url}?authorization=${authorization}&date=${date}&host=${host}`resolve(url)})
}export default class TTSRecorder {constructor({appId = APPID} = {}) {this.appId = appIdthis.msgStore = nullthis.msgDom = null}// 连接websocketconnectWebSocket() {return getWebsocketUrl().then(url => {let ttsWSif ('WebSocket' in window) {ttsWS = new WebSocket(url)} else if ('MozWebSocket' in window) {ttsWS = new MozWebSocket(url)} else {alert('浏览器不支持WebSocket')return}this.ttsWS = ttsWSttsWS.onopen = e => {this.webSocketSend()}ttsWS.onmessage = e => {this.result(e.data)}ttsWS.onerror = e => {alert('WebSocket报错,请f12查看详情')console.error(`详情查看:${encodeURI(url.replace('wss:', 'https:'))}`)}ttsWS.onclose = e => {console.log(e)}})}// websocket发送数据webSocketSend() {var params = {"header": {"app_id": this.appId,},"parameter": {"chat": {// 指定访问的领域,general指向V1.5版本,generalv2指向V2版本,generalv3指向V3版本 。// 注意:不同的取值对应的url也不一样!"domain": "generalv3",// 核采样阈值。用于决定结果随机性,取值越高随机性越强即相同的问题得到的不同答案的可能性越高"temperature": 0.5,// 模型回答的tokens的最大长度"max_tokens": 1024}},"payload": {"message": {"text": this.msgStore.list}}}console.log(params,'请求的参数')this.ttsWS.send(JSON.stringify(params))}start(msgStore,msgDom) {this.msgStore = msgStorethis.msgDom = msgDom.valuetotal_res = ""; // 请空回答历史this.connectWebSocket().then(r => {})}// websocket接收数据的处理result(resultData) {let jsonData = JSON.parse(resultData)jsonData.payload.choices.text.forEach(res=>{this.msgStore.aiAddMsg(res.content,jsonData.header.status)this.msgDom.scrollTop = this.msgDom.scrollHeight + 500})// 提问失败if (jsonData.header.code !== 0) {alert(`提问失败: ${jsonData.header.code}:${jsonData.header.message}`)console.error(`${jsonData.header.code}:${jsonData.header.message}`)return}if (jsonData.header.code === 0 && jsonData.header.status === 2) {// 关闭WebSocketthis.ttsWS.close()}}
}

msgStore

新建 stores/msgStore.js

用于存放历史问题

import { defineStore } from 'pinia'
import { marked } from 'marked'export const userMsgStore = defineStore("userMsgStore",{// 持久化persist: true,state: () => {return {list:[]}},actions: {userAddMsg(msg) {this.list.push({role:"user",content:marked(msg),status:2})},aiAddMsg(content,status){let runMsg = this.list.find(i=>i.status !== 2)if(!runMsg){this.list.push({role:"assistant",content:content,status:status})}else{runMsg.content += contentrunMsg.status = statusif(status === 2){runMsg.content = marked(runMsg.content)}}}},
})

编写界面代码

<template><div class="content"><div class="message" id='message-box'><div v-for="(msg,index) in msgList" :key="index" :class="{'user':msg.role === 'user','assistant':msg.role === 'assistant'}"><div><div><img class='role-img' :src="userImg" v-if="msg.role === 'user'"/></div><div class='imgbox' v-if="msg.role === 'assistant'"><img class='role-img' :src="aiImg" /><div class='name'>讯飞AI</div></div></div><div v-highlight v-html='msg.content'></div></div></div><div class="footer"><textarea rows="5" placeholder="请输入问题" class="text" v-model="msgValue"></textarea><button class="btn" @click="submitMsg">发送</button></div></div>
</template><script setup>
import userImg from "@/assets/user.png"
import aiImg from "@/assets/ai.png"
import { nextTick, onMounted, ref } from 'vue'
import TTSRecorder from "@/utils/TTSRecorder"
import { userMsgStore } from '@/stores/msgStore'
const msgStore = userMsgStore()
const msgValue = ref("")
let ttsRecorder = new TTSRecorder()
const msgList = ref([])
let msgDom = ref(null)onMounted(()=>{msgDom.value = document.getElementById("message-box")msgList.value = msgStore.listscroll()
})// 滚动到最底部
const scroll = () => {nextTick(()=>{msgDom.value.scrollTop = msgDom.value.scrollHeight})
}// 发送消息
const submitMsg = async () => {msgStore.userAddMsg(msgValue.value)msgValue.value = ""// 开始提问ttsRecorder.start(msgStore,msgDom)scroll()
}
</script><style scoped lang="less">.content{height: 100%;position: relative;.message{position: absolute;top: 0;left: 20%;right: 20%;bottom: 150px;display: flex;overflow: auto;flex-direction: column;.user{background-color: #ebf7f8;padding: 15px;box-sizing: border-box;display: flex;flex-direction: column;align-items: flex-end;border-bottom: 1px solid #dfdfdf;}.assistant{background-color: #f7f7f7;padding: 15px;box-sizing: border-box;border-bottom: 1px solid #dfdfdf;}}.footer{position: absolute;bottom: 50px;left: 20%;right: 20%;display: flex;align-items: flex-end;gap: 15px;.text{width: 100%;}.btn{width: 100px;height: 40px;background-color: #1a60ea;color: white;border: none;}}@media screen and (max-width: 768px) {.message,.footer {left: 0;right: 0;}.message{bottom: 100px;}.footer{bottom: 10px;}}
}.imgbox{display: flex;align-items: center;gap: 10px;margin-bottom: 10px;.name{font-size: 13px;color: #fd919e;font-weight: 400;}
}.role-img{width: 40px;height: 40px;border-radius: 50%;overflow: hidden;
}</style>
查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"讯飞星火大模型V3.0 WebApi使用":http://eshow365.cn/6-26984-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!