赞
踩
登录注册的过程很简单,这里不再进行讲述,节省大家的时间(官网:https://open.bigmodel.cn/ )。进入首页后会赠送资源包,资源包可以用来免费调用质谱AI的gbt模型。在页面的右上角可以获取到API密钥。如图
参考官方文档https://open.bigmodel.cn/dev/api#http_para
官方文档利用http做请求,需要携带 API Key发送请求,就可以获得AI模型返回的数据。这里我们用fetch来实现(为什么不用axios后面会说明),代码示例如下:
- const response = await fetch('https://open.bigmodel.cn/api/paas/v4/chat/completions', {
- method: 'POST',
- headers: {
- 'Authorization': `Bearer ${apiKey}`,
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify(data)
- });
- //传入的data数据
- const data = {
- model: "glm-4",
- messages: [
- {
- role: "user",
- content: inputValue.value
- }
- ]
- };
返回数据的大概格式如下
在choices里面可以获取到AI模型返回的字符串。
构建一个简单的聊天页面,利用@click获取到用户输入框的内容并且发送请求,效果如下
这个时候发现了一个问题,在质谱AI在返回数据的时候,是将整个响应的数据都返回的,但是chatgbt是类似于实时回答的数据流展示,如何实现这个效果呢,查阅官方文档,我发现在智谱AI开放平台里面有一段参数描述
我将stream设置为true,再次发送请求
- const data = {
- model: "glm-4",
- messages: [
- {
- role: "user",
- content: inputValue.value
- }
- ],
- stream: true
- };
获取到的数据格式如下:
我们需要使用 ReadableStream
的 reader
读取流数据,并使用 TextDecoder
解码文本。逐行处理流数据,解析 JSON 并将内容推入 messages
数组。之所以不用axios,是因为axios
的 response.data
默认是一个 JavaScript 对象,而不是一个 ReadableStream
。这样,就可以拿到每次推流的数据,通过修改messgae数组内的子项的内容,来实现一个加载文字的效果。
全部代码如下,如果对你有帮助,请帮我点一个赞,谢谢!:
- <template>
- <div class="chat-container">
- <div class="chat-display">
- <div class="msg" v-for="(msg, index) in messages" :key="index"><pre style="display: block;">{{ msg }}</pre></div>
-
- </div>
- <div class="chat-input">
- <input type="text" placeholder="请输入内容" v-model="inputValue">
- <button @click="sendMessage">发送</button>
- </div>
- </div>
- </template>
-
- <script setup>
- import { ref } from 'vue';
- import axios from 'axios';
-
- const apiKey = ''; // 替换为你的 API Key
- const inputValue = ref('');
- const messages = ref([]);
-
- const sendMessage = async () => {
-
- if (inputValue.value.trim() !== '') {
- const data = {
- model: "glm-4",
- messages: [
- {
- role: "user",
- content: inputValue.value
- }
- ],
- stream: true
- };
-
- try {
- const response = await fetch('https://open.bigmodel.cn/api/paas/v4/chat/completions', {
- method: 'POST',
- headers: {
- 'Authorization': `Bearer ${apiKey}`,
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify(data)
- });
- messages.value.push(inputValue.value)
- let len=messages.value.length;
- if (!response.body) {
- throw new Error('Response has no body');
- }
- inputValue.value=''
- const reader = response.body.getReader();
- const decoder = new TextDecoder();
- let partialMessage = '';
-
- const processStream = async () => {
- let result;
- while (!(result = await reader.read()).done) {
- const text = decoder.decode(result.value, { stream: true });
- partialMessage += text;
-
- const lines = partialMessage.split('\n');
- partialMessage = lines.pop(); // 保留最后一个部分消息
- console.log(lines,',',partialMessage);
- lines.forEach(line => {
-
- if (line.startsWith('data: ')) {
- const json = line.replace('data: ', '');
- if (json === '[DONE]') {
-
- return;
- }
-
- try {
- const parsedData = JSON.parse(json);
- const content = parsedData.choices[0].delta.content;
- if(!messages.value[len]){
- messages.value[len]=''
- }
- messages.value[len]+=content
- console.log(messages);
- } catch (error) {
- console.error('解析 JSON 出错:', error);
- }
- }
- });
- }
- };
-
- processStream();
- } catch (error) {
- console.error('请求失败:', error);
- }
- }
- };
- </script>
-
- <style scoped>
- .chat-container {
- display: flex;
- flex-direction: column;
- align-items: center;
- width: 500px;
-
- }
-
- .chat-display {
- border: 1px solid #ccc;
- width: 500px;
- height: 300px;
- overflow-y: auto;
- margin-bottom: 10px;
- padding: 10px;
-
- }
- /* 隐藏滚动条 - Chrome, Safari 和 Opera */
- .chat-display::-webkit-scrollbar {
- display: none;
- }
- /* 隐藏滚动条 - Firefox */
- .chat-display {
- scrollbar-width: none; /* Firefox */
- }
- /* 隐藏滚动条 - IE 10+ */
- .chat-display {
- -ms-overflow-style: none; /* IE and Edge */
- }
- .chat-input {
- display: flex;
- }
-
- .chat-input input {
- flex: 1;
- padding: 10px;
- border: 1px solid #ccc;
- border-radius: 4px 0 0 4px;
- }
-
- .chat-input button {
- padding: 10px;
- border: 1px solid #ccc;
- border-radius: 0 4px 4px 0;
- background-color: #007bff;
- color: white;
- cursor: pointer;
- }
-
- .chat-input button:hover {
- background-color: #0056b3;
- }
- .msg{
- text-align: left;
- width: 100%;
- }
- pre{
- width: 500px;
- white-space: pre-wrap; /* 允许换行 */
- word-break: break-word; /* 超出宽度时换行 */
- overflow-wrap: break-word; /* 超出宽度时换行 */
- }
- </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。