如果撇开科技大厂的业务线不谈,我们还可以用 ChatGPT、GPT-4来干什么?除了逗趣、生成代码、聊天之外,这届网友已经尝试雇佣了 GPT-4当老板,开启从零的创业之旅......当然,还有一些极客、编程爱好者势必不会错过这次机会。
(资料图)
这不,一名新加坡的创客、程序员 Yeo Kheng Meng 再次“整活”,用 ChatGPT 打开时空之门,为 MS-DOS 平台开发了一个 ChatGPT 客户端,让老式的计算机系统也可以运行当前最为先进的大模型,开启一场独特的对话方式。
同时,作者将相关代码在 github 上开源出来:https://github.com/yeokm1/doschgpt,也希望通过本文为玩转 ChatGPT 的不同方式带来一些借鉴与思考。
应用程序的屏幕截图
定目标硬件
DosvjMhiMGG是很多老程序员的青春记忆。之所以选择 Dos 平台开发,Yeo Kheng Meng 表示,“2019年,我曾为 Windows3.1创建了一个Slack 客户端(https://yeokhengmeng.com/2019/12/building-a-new-win-3-1-app-in-2019-part-1-slack-client/)。这次我想尝试一些不同的东西,也想要开启为更旧的平台开发的挑战。”
值得注意的是,DOS 没有原生联网的能力,而且系统的处理能力也较弱,所以选择它为目标平台,包括编码之类的所有处理任务处理都会有额外的困难和挑战。
在硬件选择上,Yeo Kheng Meng 使用的 MS-DOS 电脑是1984年的 IBM5155便携式电脑,它拥有 Intel80884.77Mhz CPU、640KB 常规内存(使用升级套件)、CGA ISA 图形、NE2000兼容的 ISA 以太网适配器、XT-IDE ISA 驱动器控制器和 MS-DOS6.22系统等配置。
“如果我的应用程序可以在这台 IBM 机器上运行,它应该可以在几乎所有其他 DOS 机器上运行”,Yeo Kheng Meng 说道。
开干!
编译vjMhiMGG器
为了创建客户端,Yeo 使用了Open Watcom C/C++,这是一种在 Windows11上运行的现代编译器,可以应用在16位 DOS 平台上。
不过,16位 DOS 程序的问题是,现代64位版本的 Windows 默认不能执行它们。在开发过程中,Yeo仍然需要一种方法来测试编译后的二进制文件。虽然把二进制文件传送到 IBM DOS PC 上是有可能的,但这会大大增加开发过程中的编程复杂性。
测试环境搭建
从技术上来讲,已有现成的第三方解决方案,如 winevdm(https://github.com/otya128/winevdm),但它在这种使用情况下是行不通的,后面会解释。
因此,出于测试目的,Yeo通过搜索,找到了运行 DOS6.22的VirtualBox虚拟机来简化开发过程,然后将编译后的二进制文件传输到目标 IBM DOS PC 上进行测试。
完整的 VM 配置信息详见:https://github.com/yeokm1/retro-configs/tree/master/vms/vbox-dos622
Yeo把它设置成与主机在一个桥接网络上,这样两者之间就可以很容易地进行通信,而且虚拟机可以访问Yeo 个人的互联网连接。
在带有已编译好的二进制文件的主机上,Yeo用 python 启动了一个简单的网络服务器,为二进制文件服务。代码为:
python3-mhttp.server8000
在虚拟机上,Yeo使用 MTCP 的一个程序来下载二进制文件进行测试:
htget-odoschgpt.exehttps://X.X.X.X:8000/doschgpt.exe
编码
正如文章伊始所述,与现代 Windows/MAC/linux 相比,MS-DOS 平台的编码提出了一些额外的挑战。最大的问题是网络 API,因为 DOS 本身并不附带这些 API。
然而,具有 TCP/IP 网络功能的 DOS 程序以前已经编写过,所以这绝对是可能的。
应用架构
为了在 IBM PC 上处理网络问题,Yeo 也穿梭于多个层级之间。在做了一些研究之后,Yeo 使用了1983年发明的“Packet Driver API”标准。
如果要使用低级别的 Packet Driver API,网卡制造商通常会发布一个实现该 API 的驱动程序。然后,应用程序开发人员使用该 API 与网卡通信。
最初,Yeo 认为要掌握这个低级别的 API 是一个巨大的挑战,但幸运的是,有一个现有的开源网络库可以帮助完成这个任务。这个库是由 Michael B. Brutman 编写的 MTCP(https://brutmanlabs.org/mTCP/)。
MTCP 库必须被集成到应用程序中。然后,它将与制造商提供的数据包驱动程序进行通信,该驱动程序作为一个常驻程序(TSR)运行。TSR 在后台保持休眠状态,直到被一个应用程序调用。然后,数据包驱动程序直接与网卡进行通信。
不过,Yeo 没有找到可以安装在现代64位 Windows 操作系统上的数据包驱动程序。因此,即使16位 DOS 二进制文件可以使用 winevdm 等工具执行,它也不会连接到网络,所以这也是为什么不直接用第三方解决方案的原因。
另一方面,对于较旧的网卡,比如在 IBM5155中使用的 NE2000兼容网卡,数据包驱动程序相对常见。
开始联网
在尝试开始联网的过程中,要注意在 DOS 中没有多线程的概念,所以没有任何东西在后台运行来为服务于网络堆栈,所以,网络堆栈主要由应用程序控制,因此这种服务也必须在内部完成。
为驱动较低的网络层,这组函数必须定期被调用:
PACKET_PROCESS_SINGLE;Arp::driveArp();Tcp::drivePackets();
MTCP 提供的原始套接字 API,具有基本的 send() 和 recv() 函数,足以让人使用。
ChatGPT API
不久之前,OpenAI 宣布开放 API。在这里,Yeo 只选择了 Chat Completion API(https://platform.openai.com/docs/api-reference/making-requests)。
官方也提供了一个很好的使用示例供参考:
curlhttps://api.openai.com/v1/chat/completions-H"Content-Type:application/json"-H"Authorization:Bearersk-XXX"-d"{"model":"gpt-3.5-turbo","messages":[{"role":"user","content":"WhatisMS-DOS?"}],"temperature":0.7}"
使用这个 API,Yeo 将需要构建整个 POST 请求。与现代开发平台不同,这里没有可以使用的辅助函数,所以 Yeo 选择用 C 语言手动构建整个 POST 请求,如下所示:
#defineAPI_CHAT_COMPLETION"POST/v1/chat/completionsHTTP/1.1\r\nContent-Type:application/json\r\nAuthorization:Bearer%s\r\nHost:api.openai.com\r\nContent-Length:%d\r\nConnection:close\r\n\r\n%s"#defineAPI_BODY"{\"model\":\"%s\",\"messages\":[{\"role\":\"phpuser\",\"content\":\"%s\"}],\"temperature\":%.1f}"
JSON 解析
ChatGPT API 将返回以下 JSON 输出:
{"id":"chatcmpl-XXXXX","object":"chat.completion","created":1679326062,"model":"gpt-3.5-turbo-0301","usage":{"prompt_tokens":13,"completion_tokens":114,"total_tokens":127},"choices":[{"message":{"role":"assistant","content":"\n\nMS-DOS(MicrosoftDiskOperatingSystem)isacommand-lineoperatingsystem....."},"finish_reason":"stop","index":0}]}
在这个过程中,Yeo 遇到了一个重大障碍:ChatGPT API 需要加密的 HTTPS 连接。由于 MS-DOS 没有本地 HTTPS 库,Yeo 创建了一个 HTTP-to-HTTPS 代理(https://github.com/yeokm1/http-to-https-proxy),可以在现代计算机上运行,并在 MS-DOS 客户端和 ChatGPT 的安全 API 之间转换请求和响应,充当透明的中间人在沟通过程中。
Yeo 表示,由于 DOS 应用程序的单线程特性,向控制台读取和写入输入带来了另一个挑战。为此,他使用 MTCP 页面(https://brutmanlabs.org/Adventures_In_Code/Adventures_In_Code.html)和在线示例(https://jmagic.tistory.com/982)作为参考,设计了一种无需暂停程序即可检查和接收按键的方法:
intcurrentMessagePos=0;char*messageToSend=(char*)androidcalloc(SIZE_MESSAGE_TO_SEND,sizeof(char));
while(true){
if ( _bIOS_keybrd(_KEYBRD_READY) ) {
char character = _bios_keybrd(_KEYBRD_READ);
...
messageToSend[currentMessagePos] = character;
currentMessagePos++;
printf("%c", character);
fflush(stdout);
}
}
_bios_keybrd 是一个通向 INT16h BIOS 键盘中断的通道。
如果检测到一个按键,该按键将被存储到一个本地缓冲区并打印到控制台。现在 Yeo 可以在不暂停程序的情况下检查和接收按键。
最后
最终,这款程序的运行的效果,远超 Yeo 的预期。他表示,“编写这个聊天客户端是一种有趣的体验。让编译器能够在现代 Windows 操作系统上运行肯定会让事情变得更容易。事实上,这一次比我以前做的 Windows3.1Slack 应用程序更容易。考虑到这是我第一次在 DOS 平台上编写代码,我对这样的旧机器的性能印象深刻。经历了这一切,我以后肯定会写更多复古软件。”
那么要问 ChatGPT 是否能够直接解决自己在旧的平台上运行的问题,其回答道:
请记住,创建 DOS ChatGPT 客户端可能具有挑战性,因为 DOS 是一个过时的操作系统,可能没有开发现代应用程序所需的工具和资源。
不过,人类工程师还是用实现了 ChatGPT 感觉不可能的事情。反过来看,或许只需一点创造力,人工智能语言模型的最新技术就不必局限于前沿的硬件,它可以打通过去、现在和未来。
来源:
https://yeokhengmeng.com/2023/03/building-a-dos-chatgpt-client-in-2023/
GitHub 地址:https://github.com/yeokm1/doschgpt
关键词: