疏导篇
从去年12月初理解到 ChatGPT
,也注册了账号,然而始终没去应用(真是太懒了)。
置信大家就算没应用过,也听闻过它的传说,简略来说就是一个解答性聊天机器人。
最近呢,有几位敌人也始终在向我征询一些 ChatGPT
的问题,想了想还是做个小利用,带各位来理解并应用上ChatGPT
。
申明一下,此篇文章真不是用
ChatGPT
生成的。
注册篇
曾经有很多大佬来介绍这个注册形式了,我简略的说一下步骤吧。
- 筹备好迷信上网的节点(香港、越南的不行);
- 在 https://sms-activate.org/ 验证码平台上充值个1$;
- 去 https://chat.openai.com/auth/login 通过邮箱注册(举荐谷歌间接注册);
- 在验证码平台上找一个
openai
的验证码服务(最便宜的是印尼的,有效期20分钟); - 输出验证码平台上的手机号进行验证;
- 期待验证码呈现,粘贴之后即可实现注册;
- 能够间接在 https://platform.openai.com/account/api-keys 生成
apiKey
;
实战篇
本次做的小工具,是一个终端对话助手。通过用户的输出内容,让 ChatGPT
进行辨认答复并输入。
效果图
筹备工作
初始化
yarn init -y
装置插件
openai
(对话性能)inquirer
(解决命令行输出等操作)cli-spinner
(Loading成果)
筹备 openai
的 apiKey
对接 OpenAI
引入 openai,并且写一个调用入口函数。
const { Configuration, OpenAIApi } = require("openai");
async function main() {
// 创立 openai 配置
const configuration = new Configuration({
apiKey: 'apiKey'
});
// 初始化 openai
const openai = new OpenAIApi(configuration);
const { data: { choices } } = await openai.createCompletion({
model: 'text-davinci-003', // 对话机器人模型
prompt: 'js 是什么?', // 问题
temperature: 0.5, // 准确性的概率,0是最精准的
max_tokens: 150, // 输入内容长度
top_p: 1.0, // 防止反复和不相干的内容
frequency_penalty: 0.0, // 管制语言模型中呈现的词语频率,惩办
presence_penalty: 0.0, // 管制语言模型中呈现的词语频率,惩办
})
console.log(choices[0].text); // 输入的内容
}
main()
输入的后果如下图
这一步曾经将 openai
对接完了。
让用户配置和发问
咱们须要让用户发问,不应该间接将问题写在文件里,短少与用户之间的交互。
这时候 inquirer
呈现了,它是一个命令行交互工具,能够做很多事件,比方各种 cli
的一些问题及抉择配置的形式,如 VueCli
的创立的这种多选、单选它都能够做到。
应用形式也很简略
const { prompt } = await inquirer.prompt({
type: 'input', // 能够是 password|list 等
name: 'prompt', // 定义的字段名
message: '请输出问题', // 提示信息
});
console.log('输出的内容 =>>>', prompt)
当初能够拿到用户的输出内容了,咱们就能够做很多事件了。
- 获取用户输出的
apiKey
; - 获取用户抉择的对话机器人模型;
- 获取用户发问内容;
引入&定义配置
const inquirer = require('inquirer');
// 定义一个配置 config
const config = Object.create(null);
const fs = require('fs');
写入 Key 到文件
让用户输出密钥,为了长久化存储,我抉择间接创立文件来进行存 key
,免得每次都须要从新输出。
// 判断文件是否存在
const keysIsExist = fs.existsSync('openai_keys');
// 如果不存在
if (!keysIsExist) {
const { apiKey } = await inquirer.prompt({
type: 'password',
name: 'apiKey',
message: '请输出 Open AI 的 Key',
})
// 笼罩写入
fs.writeFile('openai_keys', apiKey.trim(), { flag: 'w' }, (err) => {
if (err) console.error(err)
else main() // 从新执行
})
} else {
// 存在此文件间接读取赋值给 config.apiKey
fs.readFile('openai_keys', (err, data) => {
if (err) {
console.error(err)
return
}
config.apiKey = data.toString();
})
}
让用户抉择机器人
const { model } = await inquirer.prompt({
type: 'list',
name: 'model',
message: '请抉择对话机器人',
choices: [
{ name: 'text-ada-001', value: 'text-ada-001' },
{ name: 'text-curie-001', value: 'text-curie-001' },
{ name: 'text-babbage-001', value: 'text-babbage-001' },
{ name: 'text-davinci-003', value: 'text-davinci-003' },
],
default: 'text-davinci-003'
})
config.model = model;
让用户发问
const { prompt } = await inquirer.prompt({
type: 'input',
name: 'prompt',
message: '请输出问题',
});
加个 Loading 成果
因为 openai
响应有点慢,所以为了缩小蕉绿,引入了 cli-spinner
const Spinner = require('cli-spinner').Spinner;
// %s 会被上面的 ▂ ▃ ▄ ▅ ▆ ▇ █ 代替,是个占位符
const spinner = new Spinner('Loading.. %s');
// 这里是loading字符,依照这个程序去渲染
spinner.setSpinnerString('▂ ▃ ▄ ▅ ▆ ▇ █');
在申请openai
之前调用
// 申请开始
spinner.start();
// 申请实现之后暂停
spinner.stop(true); // 参数 bool ,是否须要革除输入内容
全副代码
终于完结撒花了,当初曾经是凌晨一点半了。
const { Configuration, OpenAIApi } = require("openai");
const inquirer = require('inquirer');
const fs = require('fs');
const config = Object.create(null);
const Spinner = require('cli-spinner').Spinner;
const spinner = new Spinner('Loading.. %s');
spinner.setSpinnerString('▂ ▃ ▄ ▅ ▆ ▇ █');
async function main() {
// 判断文件是否存在
const keysIsExist = fs.existsSync('openai_keys');
if(!keysIsExist) {
const { apiKey } = await inquirer.prompt({
type: 'password',
name: 'apiKey',
message: '请输出 Open AI 的 Key',
})
// 笼罩写入
fs.writeFile('openai_keys', apiKey.trim(), { flag: 'w' }, (err) => {
if (err) console.error(err)
else main()
})
} else {
fs.readFile('openai_keys', (err, data) => {
if (err) {
console.error(err)
return
}
config.apiKey = data.toString();
})
}
const { model } = await inquirer.prompt({
type: 'list',
name: 'model',
message: '请抉择对话机器人',
choices: [
{ name: 'text-ada-001', value: 'text-ada-001' },
{ name: 'text-curie-001', value: 'text-curie-001' },
{ name: 'text-babbage-001', value: 'text-babbage-001' },
{ name: 'text-davinci-003', value: 'text-davinci-003' },
],
default: 'text-davinci-003'
})
config.model = model;
const { apiKey } = config;
console.log('\033[42;30m LGOIN \033[40;32m 登录胜利\033[0m');
const configuration = new Configuration({
apiKey
});
config.openai = new OpenAIApi(configuration);
start()
}
async function start() {
const { model } = config;
const { prompt } = await inquirer.prompt({
type: 'input',
name: 'prompt',
message: '请输出问题',
});
if(!prompt.trim()) {
start()
return false
}
try {
spinner.start();
const { data: { choices } } = await config.openai.createCompletion({
model,
prompt,
temperature: 0.5,
max_tokens: 150,
top_p: 1.0,
frequency_penalty: 0.0,
presence_penalty: 0.0,
})
const answer = choices[0]?.text?.replace(/\ +/g, '');
spinner.stop(true);
console.log('\033[32mOpen AI:' + answer?.trim() + '\033[0m');
start()
} catch (error) {
spinner.stop(true);
console.log(error);
}
}
main();
发表回复