vue仿chatgpt的ai聊天功能--通义千问(阿里云)
三狼真菌 2024-06-25 16:01:03 阅读 73
开发前的准备
1.阿里云开通模型服务灵积-获取key
阿里云-通义千问文档: 点击跳转
2.使用文档中的sse流式返回
参考:官方文档中 HTTP调用接口-请求实例(SSE开启)
1.请求地址:
'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation'
1.请求头:
--header 'Authorization: Bearer <your-dashscope-api-key>' \
--header 'Content-Type: application/json' \
--header 'X-DashScope-SSE: enable' \
3.post传值:
data{
"model": "qwen-turbo",
"input":{
"messages":[
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "你好,哪个公园距离我最近?"
}
]
},
"parameters": {
"result_format": "message"
}
}'
3.vue中使用
(1)安装请求sse 接口调用fetchEventSource
npm install @microsoft/fetch-event-source
(2)将fetchEventSource引入到项目中
import { fetchEventSource } from "@microsoft/fetch-event-source"
(3)请求接口-通义千问api
//封装调用千问api方法,data:请求bady, key:密钥
aiSse (data,key) {
let that = this
let controller = new AbortController()
const eventSource = fetchEventSource('/tyqw/api/v1/services/aigc/text-generation/generation', {
method: 'POST',
headers: {
Authorization: key,
'Content-Type': 'application/json',
'Accept':'text/event-stream',
'X-DashScope-SSE': 'enable',
},
body: JSON.stringify(
data
),
signal: controller.signal,
onopen() {
console.log('open')
},
onmessage(event) {
console.log('onMessage',event.data)
let data = event.data
let jsonData = JSON.parse(data);
// console.log('jsonData', jsonData);
// console.log('jsonData-value', jsonData.output.choices[0].message.content);
const textValue = jsonData.output.choices[0].message.content
const textStatus = jsonData.output.choices[0].finish_reason
// that.text += textValue.slice(that.text.length)
if (that.addStatus) {
that.text += textValue
that.scrollToBottom()
}
// console.log('that.text', that.text);
// console.log('that.text.length', that.text.length);
// console.log('jsonData.output.choices[0].message.content.slice(that.text.length)', textValue.slice(that.text.length));
if (textStatus == 'stop') {
console.log('完成了,需要赋值');
console.log('text--------', that.text);
that.textList[that.textList.length-1] = {
type: 'ai',
value: that.text
}
that.helpStatus = false
that.addStatus = false
// let cursorFlask = document.getElementById("cursorFlask");
// cursorFlask.style.opacity = '0'
}
},
onclose() {
controller.abort();//出错后不要重试
eventSource.close();
},
onerror(error) {
console.log('close',error)
// controller.abort();//出错后不要重试
eventSource.close();
this.$message.error(`系统错误:${ error}`)
that.helpStatus = false
}
})
},
(4)点击按钮- 获取千问key- 发送请求到api
// 获取ai回答接口key
async getAuxiliaryKeyFn () {
const res = await getAuxiliaryKey()
console.log('获取ai回答接口key', res);
if (res.status == 200) {
// 调用通义千问api
const apiKey = res.data.apiKey; // 替换为你的API密钥
const data = {
model: 'qwen-turbo',
input: {
messages: [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": this.principalActionText
}
]
},
parameters: {
result_format: 'message',
incremental_output: true
}
}
this.addStatus = true
this.aiSse(data,apiKey)
} else {
this.$message.error(res.msg || '请求错误,请检查网络或放量已到最大限额');
}
},
(5)根据个人情况-点击发送时调用
this.getAuxiliaryKeyFn()
4.最后展示ai返回的对话款需要用的vue-markdown
ai返回是markdown格式的,
npm install vue-markdown --save
import VueMarkdown from 'vue-markdown'
<template>
<div>
<vue-markdown :source="markdown"></vue-markdown>
</div>
</template>
<script>
import VueMarkdown from 'vue-markdown';
export default {
data() {
return {
markdown: '# Hello, Vue Markdown!'
}
},
components: {
VueMarkdown
}
}
</script>
最后服务器上代理的问题:
问题描述:本地上没问题,测试环境报错502,或者跨域—就是没代理成功
最后运维成功的代理, tyqw 代理标识
本身域名有证书
location ^~ /tyqw/
{
proxy_pass https://dashscope.aliyuncs.com/;
proxy_ssl_server_name on;
proxy_set_header Host dashscope.aliyuncs.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
# proxy_hide_header Upgrade;
add_header X-Cache $upstream_cache_status;
#Set Nginx Cache
set $static_file8WLuNoD1 0;
if ( $uri ~* "\.(gif|png|jpg|css|js|woff|woff2)$" )
{
set $static_file8WLuNoD1 1;
expires 1m;
}
if ( $static_file8WLuNoD1 = 0 )
{
add_header Cache-Control no-cache;
}
}
还有在ks8上下来 (不懂啥意思,如果如遇到这类问题,可以发给运维看看)
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。