100 行代码手写 ChatGPT 应用

69 阅读4分钟

这几天,ChatGPT 推出了面向企业和个人的 API 服务 gpt-3.5-turbo,立马教大家动手实现

手写 ChatGPT ?这里当然不是实现 AI 算法与大模型这些核心能力。仅仅演示如何使用开放 API 实现自己的 ChatGPT 问答小工具,作为 AI 产品化探索的第一步,抛砖引玉。

学会了,你也可以定制自己的阿猫阿狗 GPT、ChatPPT、PUA GPT ...

源码仓库:👉 github.com/turkyden/de…

1. 开发准备

3 月 2 日,OpenAI 发布了最新的 GPT 3.5 turbo API,该款产品更快、更强、更便宜。本文基于官方文档使用 JavaScript 调用官方 API 接口,仅 100 行前端代码的 index.html,实现定制版的 ChatGPT 问答工具。

Step 1 注册 OpenAI 账号

首先需要注册 openai 账号,可以参考这个教程:sms-activate.org/cn/info/Cha…

由于注册 OpenAI 需要使用海外的手机号,可以使用 sms-activate 这个网站购买一个印度的手机号接收验证码即可,充值1美元(大概7块钱人民币)即可获得 70+ 卢布,足够了。

如果嫌以上注册太麻烦,直接淘宝 15 块一个购买即可

Step 2 获取 API KEY

登录 OPenAI 个人中心,platform.openai.com/signup 获取自己的 API_KEY 以及查看使用量额度。

Tips:目前每个新账户有 18$ 的免费额度,价格是 $0.002 / 1k tokens

每输出 100 万个单词,价格才 2.7 美元(约 18 元人民币)

image.png

image.png

2. 代码实现

前端实现一个单聊对话 Web 应用,其实难度不大,尤其使用 Vue 等现代前端框架后,只需要维护好聊天数据源 Array 与请求逻辑即可,渲染这块无需过多关注。

高端的食材,往往只需要简单的烹饪,废话少说,直接上代码:

<!DOCTYPE html>
<html>
  <head>
    <title>100 行代码手写 chatgpt</title>
    <meta charset="UTF-8" />
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no,viewport-fit=cover"
    />
  </head>

  <body>
    <div id="app" style="padding: 4rem 0;">
      <h1 style="text-align: center;">Dengju GPT 🤖</h1>
      <p style="text-align: center;">@dengjudeng</p>

      <br />

      <div style="text-align: center;">
        <input
	  :disabled="isTyping"
          v-model="message"
          style="width: calc(100% - 4rem); padding: 0.5rem;"
          autofocus
          :placeholder="isTyping ? 'ChatGPT 正在组织语言 ...' : '问问 ChatGPT ...'"
          type="text"
	  @blur="handleSend"
          @keyup.enter="handleSend"
        />
      </div>

      <br />

      <ul v-for="(message, key) in [...messages].reverse()" :key="key">
        <li>
          <div style="color: #6b7280;">{{ message.role }}</div>
          <div style="white-space: pre-wrap;">{{message.content}}</div>
        </li>
      </ul>
    </div>
    <script>
      new Vue({
        el: "#app",
        data() {
          return {
            message: "",
            isTyping: false,
            messages: [
              {
                content: "Hi, 我是 ChatGPT!你可以问我任何事情!👋",
                role: "assistant"
              }
            ]
          };
        },
        methods: {
          handleSend: async function () {
            if(!this.message) return
            const newMessage = {
              content: this.message,
              role: "user"
            };
            const newMessages = [...this.messages, newMessage];
            this.messages = newMessages;
            this.isTyping = true;
            await this.processMessageToChatGPT(newMessages);
            this.isTyping = false;
          },
          processMessageToChatGPT: async function (messages) {
            const API_KEY = "sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
            const apiRequestBody = {
              model: "gpt-3.5-turbo",
              messages: messages
            };
            this.message = "";
            const data = await fetch(
              "https://api.openai.com/v1/chat/completions",
              {
                method: "POST",
                headers: {
                  Authorization: "Bearer " + API_KEY,
                  "Content-Type": "application/json"
                },
                body: JSON.stringify(apiRequestBody)
              }
            ).then((data) => data.json());
            this.messages = [
              ...messages,
              {
                content: data.choices[0].message.content,
                role: "assistant"
              }
            ];
          }
        }
      });
    </script>
  </body>
</html>

写到这里,刚好是 100 行代码,直接落地一个 ChatGPT 聊天应用 ~

Edit 100 行代码手写 chagpt

3. 重点难点

一)不建议前端直接调用

虽然直接调用官方 OpenAPI 不会跨域,但实际生产中不建议在前端直接调用 API,会泄露你的 API_KEY,需要后台同学包一个接口给前端使用。

[POST] https://api.openai.com/v1/chat/completions

二)返回内容文本如何换行?

返回结果文本换行,可以使用 CSS white-space: pre-wrap;

<div style="white-space: pre-wrap;">{{message.content}}</div>

三)如何实现返回结果打字动画效果?

推荐一个我之前使用过的库 typical,仅仅 55 行代码一气呵成。

四)返回结果是代码格式的话,如何实现代码高亮效果?

这里推荐使用 prism.js 进行语法高亮,还能使用最近比较火的 WebContainer 在聊天中运行代码。

image.png

4. 小结

AIGC 大模型时代来临了,在日常办公协同中,一定程度上确实能提升工作效率,辅助我们做很多事情。

这波浪潮,使得 AI 应用落地的门槛非常低。无需再招聘百万高薪的 NLP 工程师来训练和调参,只需找人不断用人类自然语言 Prompts 调优就能完成这一过程。

理论上,你只需要找一个做前端的老婆,结合一个应用场景,你们俩就能做一家 AI 创业公司。

AI 是一把双刃剑,还需要注意信息安全,谨防数据泄露,触犯公司安全高压线。

前端是直接面向用户交互层的工种,天然对用户体验敏感,还有非常多的细节需要打磨。

AI 时代,人机交互还是键盘、鼠标方式么?UI 革命,会给前端开发带来哪些挑战?

🎁 源代码已开源,尽情享用 DIY 你自己的 ChatGPT 吧 ~