尝试用ChatGPT开发一个聊天网站

1,036 阅读2分钟

本文正在参加 人工智能创作者扶持计划

最近想尝试使用下ChatGPT开发能力

我说:用vue开发一个可以访问ChatGPT的网页

GPT: 好的,那我们用Vue.js构建一个简单的页面,实现访问ChatGPT并传入apikey参数的功能。 首先,中装axios库。可以使用以下命令:

npm install axios

然后,打开Vue组件文件(例如App.vue),在template标签中添加一个简单的输入框和一个按钮:

template>
  <div>
   <input type="text" v-model="question" placeholder="请输入问题" />
   <button @click="getAnswer">查找答案</button>
   <div v-if="answer">{{ answer }}</div>
  </div>
</template>

接下来,在script标签中导入axios并定义 getAnswer 方法。其中,我们将传入apikey参数并发送GET请求来获取答案:

<script>
import axios from 'axios';

export default {
  name: 'App',
  data() {
    return {
      question: '',
      answer: '',
      apiKey: 'YOUR_API_KEY_HERE'
    };
  },
  methods: {
    async getAnswer() {
      try {
        const response = await axios.get(
          `https://api.openai.com/v1/answers?model=curie&prompt=${this.question}&max_tokens=5`,
          {
            headers: {
              Authorization: `Bearer ${this.apiKey}`
            }
          }
        );
        this.answer = response.data.answers[0].text;
      } catch (error) {
        console.log(error);
      }
    }
  }
};
</script>

最后,替换掉apiKey变量中的 YOUR_API_KEY_HERE,注意加上自己在OpenAI申请的密钥,保存文件并运行Vue项目即可。用户在输入问题后,点击查找答案按钮,即可获得ChatGPT给出的答案。

当然,这只是简单的演示,实际开发中还需要合理处理接口返回结果、增加错误处理等,但这应该能够给您提供一个简单的思路。

看起来好像很简单,我把代码试运行了下,报错接口访问失败。

哈哈好吧,我就知道。我查了下官方API文档,没有这个接口。可能是ChatGPT3.5素材比较老了,我参照文档修改了下

const response = await axios.post(
          `https://api.openai.com/v1/chat/completions`,
          {
          	"model":"gpt-3.5-turbo",
          	"messages": [{role: "user", content: this.question}],
          	"temperature": 0.7
          },
          {
            headers: {
              Authorization: `Bearer ${this.apiKey}`,
        	  ContentType:"application/json"
            }
          }
        );
        this.answer = response.data.choices[0].message.content;

然后就可以了

但是这样只能问答,没法聊天呀,而且样子有点丑。

找下ChatGPT:ChatGPT优化下界面,需要保存对话。

GPT: 好的,保存对话可以让用户随时查看之前的聊天记录,也便于后期分析用户行为,优化ChatGPT的表现。

新增一个dialogs数组,保存用户和ChatGPT的对话记录:

() {
  return {
    question: '',
    answer: '',
    apiKey: 'YOUR_API_KEY_HERE',
    context: [],
    dialogs: []
  };
}

在getAnswer方法中,将用户提出的问题和ChatGPT返回的答案保存到dialogs中:

// 保存对话
this.dialogs.push({
  question: this.question,
  answer: response.data.answers[0].text,
  from: 'user'
}, {
  question: this.question,
  answer: response.data.answers[0].text,
  from: 'ChatGPT'
});

// 清空
this.question = '';

这里我们将提出的问题和ChatGPT返回的答案都保存到dialogs中,用from字段标明是谁发出来的消息。

接着,我们可以在界面中增加一个消息记录的区域,实时显示用户的对话记录:

<div class="message-container">
  <div v-for="(dialog, index) in dialogs" :key="index" :class="['message', dialog.from]">
   div class="avatar"></div>
   div class="bubble">{{ dialog.answer }}</div>
  </div>
</div>

这里使用v-for遍数组将前保存的对话记录渲染到界面中。

最后在样式表中增加一些样式,美化聊天界面:

.message-container {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  height: 400px;
  overflow-y: scroll;
}

.message {
  display: flex;
  margin-top: 20px: 60%;
  min-width: 120px;
}

.user .bubble {
  background-color: var(--theme-color);
  color: #fff;
  border-radius: 20px 20px 20px 0;
  margin-left: 10px;
  margin-right: auto;
  padding: 10px 15px;
  font-size: 14px;
  line.5;
}

.ChatGPT .bubble {
  background-color: #f4f4f4;
  color: #333;
  border-radius: 20px 20px 0 20px;
  margin-right: 10px;
  margin-left: auto;
  padding: 10px 15px;
  font-size: 14px;
  line-height: 1.5;
}

.avatar {
  width: 40px;
  height:  border-radius: 50%;
  background-color: var(--theme-color);
  margin-right: 10px;
}

.user .avatar {
  margin-left: auto;
  margin-right: 0;
}

在这里,我们设置了消息记录区域的高度为400px,超出部分可以滚动显示。另外,我们为用户和ChatGPT分别设置了不同的气泡样式,并将头像设置为圆形。

这样,通过保存对话,我们不仅增加了用户体验,还能方便分析用户行为,从而优化ChatGPT的表现。

我直接搬运下,效果如图

好吧,这时候又是需要程序员的时候了,左图是ChatGPT给出的代码的效果,右图是调整过的。

好像还是有问题,他不记得我的名字了,好吧再找下ChatGPT

我:需要可以联系上下文

GPT: 好的,那我们可以结合上下文信息,完成一个更加智能的ChatGPT。

首先,我们需要保存用户之前提出的问题及ChatGPT返回的答案,以此来构建上下文。

在data中添加一个context数组:

data() {
  return {
    question: '',
    answer: '',
    apiKey: 'YOUR_API_KEY_HERE',
    context: []
  };
}

在getAnswer方法中,将返回的答案以及用户提出的问题存储到context,作为下一次请求的上下文:

this.context.push({
  question: this.question,
  answer: response.data.answers[0].text
});

然后,在发送下一次请求时,将context中最近的几个问题和答案拼接成一个较长的prompt,以便ChatGPT更好地理解上下文:

// 获取上下文
let contextPrompt = '';
if (this.context.length > 0) {
  const startIndex = Math.max(0, this.context.length - 3);
  const context = this.context.slice(startIndex).reverse();
  contextPrompt = context
    .map(item => item.question + item.answer)
    .join(' ');
}

// 发送请求
const response = await axios.get(
 .open.com/v1/answers?model=curie&prompt=${encodeURIComponent(
    this.question
  )}${encodeURIComponent(contextPrompt)}&max_tokens=5`,
  {
    headers: {
      Authorization: `Bearer ${this.apiKey}`
    }
  }
);

其中使用encodeURIComponent对prompt进行编码,以避免可能的特殊字符造成的请求问题。

这样,我们便可以使用上下文信息,让ChatGPT更好地理解用户意图,构建出更加智能的聊天应用。

当然这里的接口调用还是老问题,调整下

他现在可以认识我了。这里特殊说明下ChatGPT给出代码逻辑上下文默认最近3个,如果不限制会导致上下文过大,token数量巨大,尝试过到达一定数量会出现异常。

体验下来ChatGPT3.5总体逻辑没有问题,最大问题给出了错误的api,估计是受限于训练素材,有条件的伙伴可以用ChatGPT4试下。当然这只是最简单的聊天了,通过api文档可以发现可以设置类似于预设信息之类,还可以对文档词汇进行鉴黄等操作。本人初次尝鲜有什么问题还望指正。