专栏目录

耗时一下午,我完成了 GPT Terminal,真正具有了专属于我的 GPT 终端!

怎么用 GPT 在 5 分钟内 ”调教“ 出一个专属于你的 ”小黑子“?

怎么丝滑完成 GPT 打字机流式回复?Server-Sent Events!

我是怎么让我的 GPT Terminal “长回忆” 的?仍是老配方!

一个合格的类 GPT 使用需求具有什么?一文带你打通 GPT 产品功用!

开发一个 ChatGPT 真的仅仅当 “接口侠” 吗?GPT Terminal 细节共享!

怎么借助于 OpenAI 以指令的方法在 GPT 终端上画一只 “坤”?

不满足当 ChatGPT “接口侠”?轻松可视化 Fine-tuning 练习你的模型!

项目地址:github.com/ltyzzzxxx/g…

最新进度:现在已完成 GPT 在线人物 DIY 功用,还在处理细节中…

欢迎咱们Star、提出 Issue & PR,一起快乐地用 GPT Terminal 游玩吧~

前言

今日继续来教咱们怎么玩转 OpenAI 接口!

自从 ChatGPT 横空出世之后,市面上就出现了大量的类 GPT 使用(网站、公众号、小程序、App等等),它们和 ChatGPT 供给的功用简直平起平坐。这一切都是源于 OpenAI 为开发者们供给了 SDKAPI 服务,使得咱们能够欢乐地调用接口~

但是,假如你不懂得怎么使用它供给的服务,那么做出来的 GPT 使用与市面上的比较,可能有许多缺陷。今日,我就先带咱们功克第一个缺陷:怎么让你做的 GPT 使用长长 “回忆” !我会从理论与实战的角度,带咱们制作出有 “回忆” 功用的 GPT

接口分析

咱们在发送音讯时,都是恳求 OpenAI 供给的 createChatCompletion SDK 或 去调用 https://api.openai.com/v1/chat/completions API 然后获取 GPT 呼应。想必咱们假如看过我之前写的文章,必定对这种方法不陌生。但是,假如你仅仅单纯地将当时用户的提问作为恳求参数传递给接口中,GPT 只会给你回来当时问题的呼应,它自身没有记载上下文的才能。因为,咱们关于 GPT 的每次恳求与呼应,都是单独的,并不会被 GPT存储

但是,在真实的聊天场景,与你聊天的人必定会知道对话的上下文。要想使得 GPT 更加智能,必须得具有这一特色。莫非 OpenAI 团队不知道这一点吗?其实,解决计划仍是老配方,答案仍是藏在 createChatCompletion接口参数中!

咱们应该还记得我在上上一篇文章中,我通过以下流程完成了人物定制:

  1. Markdown 中依照模板格式,预先界说好人物信息以及详细问答 Case
  2. 将其从 Markdown 格式转为了 JSON 对象数组
  3. 恳求 createChatCompletion 接口,参数 messages 即为转化好的对象数组

这时候聪明的咱们估计现已想到了,这些预先界说好的人物信息和问答 Case,就是 GPT 能够参考的上下文啊!这样看来,要想让 GPT “长回忆”,也能够通过这一思路完成!

咱们只需求记载当时这次会话中,用户与 GPT 的聊天记载,并在下一次用户向 GPT 发送音讯时,将之前的聊天记载与这次发送的音讯一起作为 createChatCompletionmessages 参数,即可完成这一功用。

话不多说,咱们开端实战环节!

GPT Terminal 实战

存储计划

在前文中咱们说到,需求将用户与 GPT 的聊天记载进行存储,所以咱们需求确认存储计划。

GPT Terminal 项目中,我采用了 LocalStorage 前端存储技术以及 Pinia 状况管理框架来完成。

咱们假如不熟悉 Pinia 语法,能够先看看基础教程或许直接跟着项目做一遍,用法很简略。

如下部分代码对应项目途径为:src/core/commands/gpt/messagesStore.ts

import { defineStore } from "pinia";
interface Message {
  name: string;
  role: string;
  content: string;
}
export const useMessagesStore = defineStore("messages", {
  state: () => ({
    messages: [] as Message[]
  }),
  getters: {},
  persist: {
    key: "gpt-messages",
    storage: window.localStorage,
  },
  actions: {
    addMessage(msg: Message) {
      const {messages} = this.$state
      if (messages.length >= 20) {
        messages.shift()
      }
      messages.push(msg)
    },
    clearMessages() {
      this.$state.messages = []
    }
  }
})

在上面这段代码中,我界说了 messages 状况,增加了两个 action,分别为增加音讯与清除音讯, 并确认了 LocalStorage 的耐久化方法。

其间,为了防止上下文堆积,我约束了 messages 数组的最大长度,也就是说最多只能存储 20 条聊天记载。假如超出 20 条之后,首元素就会被移除(类似于固定长度的双端行列)。

恳求 GPT 服务

确认好存储计划后,咱们需求在对应的 Vue3 组件中引进 useMessagesStore

如下部分代码对应项目途径为:src/core/commands/gpt/subCommands/chat/ChatBox.vue

// 引进 useMessagesStore
import { useMessagesStore } from "../../messagesStore"
// 用于将 messages 状况转为 Vue3 的 呼应式数据
import { storeToRefs } from "pinia";
// 取出 messages
const messagesStore = useMessagesStore();
// 转化为 messages 呼应式数据
const { messages } = storeToRefs(messagesStore);

引进之后,咱们需求改动原先恳求中传入的 body 参数,咱们需求将 messages 前史聊天记载增加到 body 中。

const response = await fetch('http://127.0.0.1:7345/api/gpt/get', {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  // 投喂前史音讯
  body: JSON.stringify({
    message: [...(messages.value.map(({ role, content }) => ({ role, content }))), {
      role: "user",
      content: message.value
    }],
    role: role.value,
  }),
});

原有的后端服务不需求发生变化,其只需承受参数,并恳求 GPT 服务即可。

请必定要记得,在咱们恳求完毕后,将这次恳求的对话记载到 messages 状况中!

// 记载前史音讯
messagesStore.addMessage({
  name: role.value,
  role: "user",
  content: message.value
})
messagesStore.addMessage({
  name: role.value,
  role: "assistant",
  content: output.value
})

通过以上简略的改造,咱们便轻松地完成了有状况的 GPT

成果

让咱们检验一下咱们实战的成果吧!

我是如何让我的 GPT “长记性” 的?轻松实现有 “记忆” 的 GPT!

此外,我还引进了查询前史对话记载的功用,即便你清屏或许封闭当时终端,也能够找回最近的对话记载(最多记载 20 条)。这里的计划也是通过 Pinia 完成的,咱们只需求获取 messages 状况即可。下面简略为咱们演示一下!详细完成计划,咱们能够进入 GPT Terminal 查看详细代码完成细节哦!

我是如何让我的 GPT “长记性” 的?轻松实现有 “记忆” 的 GPT!

总结

今日给咱们展现了我在 GPT Terminal 中,是怎么完成让 GPT 具有上下文的 “回忆” 功用。原理非常简略,只需求在恳求接口的参数中传入前史聊天记载即可。

最后再小小地提一下,GPT Terminal 现在现已根本完成了主体功用啦,还有一些 Bug 需求修正,假如咱们想要了解 GPT Terminal 项目的更多细节与解锁更多玩法的话,请到其主页查看哦。对了,假如各位小伙伴关于文章或项目有什么不懂的地方,直接提出 Issue,我会在 24 小时内回复!

看在我这么认真的份上,咱们点个 Star、点个赞不过分吧(磕头!)下期再见!