基于ChatGPT的命令行工具(一)

最近ChatGPT在世界范围内炒得如火如荼(虽然我都用上好几个月了),也正因为ChatGPT的火爆,最近官网的使用体验极其糟糕,5分钟一掉线不说,历史记录有时候都刷不出来,这助长了我自己造轮子摆脱网页端的想法,正好会那么一点点的Python,为什么不做呢。

放心,这个博客不是AI写的,百分百纯手工

ChatGPT API申请

OpenAI的账号怎么申请已经有无数篇文章阐述过了这里就不浪费时间,但是右上角明明有个大大的API申请摆在那却很少有人会注意到,这也足够能说明ChatGPT所带来的舒适圈之强了(说来惭愧,我也是网站崩了后才开始认真考虑这件事),总而言之,点进[API申请页](OpenAI API)后就能申请到密钥让你进行后续开发。

PS:千万不要把你的密钥暴露在Github等公共平台,一旦被检测到就会直接失效。

使用openai库向ChatGPT发送请求

做好了一切准备后,终于开始写码环节,根据OpenAI的官方文档,要使用Python发送请求,需要在开发环境安装openai库并用内置的连接。
官方示例:

1
2
3
4
5
6
7
8

import openai

response = openai.Completion.create(
model="text-davinci-003",
prompt=generate_prompt(animal),
temperature=0.6
)

但是不幸的是,大陆的IP因为不可抗力,已经无法访问OpenAI了,更别说发送请求,因此必须要设置代理服务器。

1
2
os.environ["HTTP_PROXY"] = "代理服务器IP:端口"
os.environ["HTTPS_PROXY"] = "代理服务器IP:端口"```

业务开发阶段

在了解了API的使用方式后就可以进行实际代码的编写了,之所以选择开发成命令行的形式,也是注重效率的考虑,我的目标是可以不打开浏览器按下一个键就能直接使用,并且尽量要即时响应,正因如此,命令行工具的高效率、高相应、可扩展性成了不二之选。

但是不能为了命令行而放弃官网对于使用者最重要的功能——对话记录,没有上下文分析的ChatGPT就跟new Bing没有任何区别(请微软赶紧把会话限制去掉),因此在用命令行进行操作的同时,我们同时要想一个办法让AI明白之前的内容,在说出解决方案之前,先看一下官方文档中的请求标准吧。

1
2
3
4
{
"model": "gpt-3.5-turbo",
"messages": [{"role": "user", "content": "Hello!"}]
}

在由json数组组成的消息参数中,每条消息由最简单的两个参数”role”和”content”组成,role是告诉AI这条信息扮演的角色(system-系统,user-用户,assistant-AI),content就是具体内容,而将这些信息放在一个数组里让AI连续读取就是让AI读懂上下文的秘诀(我猜官网的历史记录也是差不多的原理)。因此,依照这个设计思路,我们将对话内容储存为json并保持更新,并在每次使用的时候读取,我们就能获得一个不会丢失记忆的本地端ChatGPT(而且哪怕算上传输与读取的时间,生成速度也是吊打被挤爆的官网),多个这样的记录(我称之为实例)之间的切换就可以模拟原本的使用体验——但是更加迅捷,更加高效。

说到实例那必然就能想到类与对象的设计模式,首先程序启动的时候从实例文件夹中扫描可用实例(处于效率考虑,这里并不涉及实际的文件读写),由用户选择实例后程序将对应记录读出存储在内存中,那之后用户输入的每条信息以及ChatGPT发来的返回值都会被记录在实例中。不光如此,还能实现不同实例中的切换(我敢保证切换速度比官网快100倍)满足用户对话题迅速切换的渴望。

关于具体设计,首先可以确定的就是需要一个ChatGPT类来管理ChatGPT相关的所有内容(密钥,回复,实例切换),以及一个可以存放单个实例的类(接受路径从中读出消息记录),程序运行后首先由玩家指定实例,实例类获得具体内容后传参给ChatGPT类,ChatGPT负责等待用户的输入以及ChatGPT的回复,对此有不解的读者可以将整个程序视作一个管道,数据从json文件中流出,流经实例类后储存在ChatGPT类中,再由ChatGPT类流向ChatAPI,这样的思考也有益于我们的程序设计。

总结以及一些经验之谈

因为篇幅原因,具体的代码部分就不贴上来了(而且设计思路也给明了,复刻一个非常容易)。我并不是一个Python高手,但是这个程序我花了不到两天就开发完毕了,这还是归功于ChatGPT老师对我的大力指导,以前遇到错误只能一筹莫展到处去搜(还都是一些老掉牙的文章),有了ChatGPT的归纳总结后,很多问题反而能靠独立思考去解决了(和小黄鸭分析法异曲同工吧),也是多亏了我是个C++程序员,在因为代理卡住的时候第一时间怀疑内核有问题,及时排查了故障原因(就是Python的内核问题,更新就能解决)。

在开发的过程中,我也偶尔会想,自己耗费这么多时间去做这种事情有什么意义,明明打开官网输入问题就能水到渠成,我为什么要单独把功能分离出来自己造轮子,但是当开发完毕的那一刻,一切都豁然开朗,保守估计这个命令行工具也节省了我80%去官网折腾那神秘的服务器的时间,那一刻ChatGPT真正成为了生产力工具,Productivity Evolution!果然偶尔极客一把也没什么不好的。

那么为什么这篇文章的标题上有个“(一)”呢?很简单,这只是第一步,ChatGPT的潜能远不止这些,当然这都是后话了。

也是多亏了ChatGPT,我重拾了写博客的动力(虽然这篇博客不是AI写的),之后几天还会更新一篇编译器的还有一篇游戏引擎相关的博客,敬请期待。

哦对了,项目地址:https://github.com/Ancaeus-whisper/ChatGPTCommand,欢迎各位来捧场喵