如今ai步及生活的方方面面,你是否也想在自己的网站接入ai呢?今天分享科大讯飞大模型3.5智能AI对接。
获取APPID、APISecret、APIKey
- 讯飞开放平台注册登录
- 控制台创建自己的应用
- 复制备用
准备工作做好,直接开始上代码了。
源码参考
<script setup lang="ts">
import { NButton } from 'naive-ui';
import CryptoJs from 'crypto-js';
import { ref, unref, h } from 'vue';
import { useMessage } from 'naive-ui';
const message = useMessage();
const {
GLOBAL_SPARK_AI_APPID,
GLOBAL_SPARK_AI_APISECRET,
GLOBAL_SPARK_AI_APIKEY,
} = import.meta.env;
const getWebsocketUrl = () => {
let url = 'wss://spark-api.xf-yun.com/v3.5/chat';
const host = 'spark-api.xf-yun.com';
const apiKeyName = 'api_key';
const date = new Date().toGMTString();
const algorithm = 'hmac-sha256';
const headers = 'host date request-line';
let signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v3.5/chat HTTP/1.1`;
let signatureSha = CryptoJs.HmacSHA256(
signatureOrigin,
GLOBAL_SPARK_AI_APISECRET
);
let signature = CryptoJs.enc.Base64.stringify(signatureSha);
let authorizationOrigin = `${apiKeyName}="${GLOBAL_SPARK_AI_APIKEY}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`;
let authorization = btoa(authorizationOrigin);
// 将空格编码
return `${url}?authorization=${authorization}&date=${encodeURI(
date
)}&host=${host}`;
};
const url = getWebsocketUrl();
const isLoading = ref(false);
const sMsg = ref();
const chartContentRef = ref<HTMLDivElement>();
const sendMsg = () => {
if (unref(isLoading)) {
message.warning('加载中...');
return;
}
if (!unref(sMsg)) {
message.warning('请输入内容');
return;
}
const userMsg = document.createElement('div');
userMsg.classList.add('msg-user');
const msgMain = document.createElement('div');
msgMain.innerHTML = unref(sMsg);
userMsg.appendChild(msgMain);
chartContentRef.value?.appendChild(userMsg);
const socket = new WebSocket(url);
socket.addEventListener('open', (e) => {
isLoading.value = true;
const params = {
header: {
app_id: GLOBAL_SPARK_AI_APPID,
uid: '星火网页测试',
},
parameter: {
chat: {
domain: 'generalv3.5',
temperature: 0.5,
max_tokens: 1024,
},
},
payload: {
// 如果想获取结合上下文的回答,需要开发者每次将历史问答信息一起传给服务端,如下示例
// 注意:text里面的所有content内容加一起的tokens需要控制在8192以内,开发者如有较长对话需求,需要适当裁剪历史信息
message: {
text: [
{ role: 'user', content: '你是谁' }, //# 用户的历史问题
{ role: 'assistant', content: '我是AI助手' }, //# AI的历史回答结果
// ....... 省略的历史对话
{ role: 'user', content: unref(sMsg) }, //# 最新的一条问题,如无需上下文,可只传最新一条问题
],
},
},
};
socket.send(JSON.stringify(params));
});
let resMsgText = '';
const resMsg = document.createElement('div');
resMsg.classList.add('msg-ai');
const resMsgMain = document.createElement('div');
resMsg.appendChild(resMsgMain);
chartContentRef.value?.appendChild(resMsg);
socket.addEventListener('message', ({ data }) => {
isLoading.value = false;
resMsgText += JSON.parse(data).payload.choices.text[0].content;
resMsgMain.innerHTML = resMsgText;
});
};
</script>
<template>
<div class="container">
<div class="chat-content" ref="chartContentRef"></div>
<div class="ask-content">
<textarea v-model="sMsg"></textarea>
<div class="opt">
<n-button type="primary" size="large" @click="sendMsg">发送</n-button>
</div>
</div>
</div>
</template>
<style lang="less" scoped>
.container {
height: 100%;
display: flex;
flex-direction: column;
background: #f2f2f2;
.chat-content {
flex: 1;
overflow-y: scroll;
.msg-ai {
background: white;
text-align: left;
}
.msg-user {
margin-bottom: 10px;
text-align: right;
}
}
.ask-content {
height: 150px;
background: white;
border: 1px solid #eee;
padding: 8px;
position: relative;
textarea {
border: none;
width: 100%;
height: 100%;
padding: 10px;
background: #f2f2f2;
outline: none;
}
.opt {
text-align: right;
position: absolute;
inset: auto 10px 10px auto;
}
}
}
</style>
相关链接
- 讯飞开放平台
- 参考教程