多多读书
461 字
2 分钟
Bun实现一个命令行AI聊天工具

与其他 JavaScript 运行时环境相比,Bun 确实简洁高效。它不仅兼容于浏览器 API,还兼容于 Node API,因此,学习起来也非常容易上手。当然了,要深刻理解 Bun,还是要实际使用一下才能体会到它的优点。因此,我决定尝试用 Bun 来开发一个命令行的 AI 聊天工具。

代码#

主要代码量还是fetch请求接口的处理,首先创建index.ts文件,然后输入如下代码:

const prompt = '🤔:'
console.write(prompt)
const API_KEY = 'sk-xxx'

for await (const line of console) {
  console.write('🤖:')
  await fetch('https://api.openai.com/v1/chat/completions', {
    method: 'post',
    body: JSON.stringify({
      stream: true,
      model: 'gpt-3.5-turbo',
      messages: [
        {
          role: 'user',
          content: line,
        },
      ],
    }),
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${API_KEY}`,
    },
  }).then(async (resp) => {
    const reader = resp.body?.getReader()
    if (!reader) {
      return
    }
    while (true) {
      const { done, value } = await reader.read()
      if (done) {
        console.write('\n\n')
        break
      }
      const decoder = new TextDecoder()
      const datas = decoder.decode(value).split('\n\n')
      datas.forEach((list: string) => {
        const data = list.replace('data: ', '')
        if (data.startsWith('{')) {
          const json = JSON.parse(data)
          console.write(json.choices[0].delta?.content || '')
        }
      })
    }
  })
  console.write(prompt)
}

运行命令:

bun run index.ts

效果如图:

Console#

在 bun 中,console可以被用作一个异步迭代器读取你在控制台的标准输入。

for await (const line of console) {
  console.log(line)
}

console.logconsole.write 的区别是:console.log输出之后会自动换行,而console.write则是继续尾部接着输入。

当执行命令,第二行console.write输出🤔:,接着等待用户输入,用户输入换行后输出🤖:,接着请求ChatGPT请求,请求结果通过console.write持续输出到控制台,结尾添加\n\n,最后又console.write回到🤔:等待输入。

fetch#

fetch请求数据跟浏览器使用完全一样,这个使用起来真的很方便。在这里获取使用的stream数据,response.body是一个ReadableStream实例,可通过reader.read进行数据读取,然后使用TextDecoder转成字符串。这些方法在浏览器同样适用。

Bun实现一个命令行AI聊天工具
https://fuwari.vercel.app/posts/20230910/
作者
我也困了
发布于
2023-09-10
许可协议
CC BY-NC-SA 4.0