攻略文章去年12月初了解了ChatGPT,注册了一个账号,但是一直没用(懒).相信即使没用过,也听过它的传说。简单来说,就是一个接听聊天机器人。最近有好几个朋友问我一些关于ChatGPT的问题。思前想后,我就做一个小应用,带大家了解和使用ChatGPT。声明一下,这篇文章真的不是用ChatGPT生成的。在注册篇中,很多高手都介绍过这种注册方法,这里简单说一下步骤。准备科学在线节点(香港和越南除外);在https://sms-activate.org/验证码平台充值1$;前往https://chat.openai.com/auth/login,通过邮箱注册(推荐谷歌直接注册);在验证码平台找个openai验证码服务(最便宜的是印尼语,20分钟有效);在验证码平台输入手机号进行验证;等待验证码出现,粘贴后即可完成注册;apiKey可以直接在https://platform.openai.com/account/api-keys生成;实战篇这次做的小工具是一个终端对话助手。通过用户的输入内容,让ChatGPT识别出答案并输出。效果图准备工作初始化yarninit-y安装插件openai(对话功能)inquirer(处理命令行输入等操作)cli-spinner(加载效果)准备openai的apiKey对接OpenAI介绍openai,写一个调用入口函数.const{Configuration,OpenAIApi}=require("openai");asyncfunctionmain(){//创建openai配置constconfiguration=newConfiguration({apiKey:'apiKey'});//初始化openaiconstopenai=newOpenAIApi(configuration);const{data:{choices}}=awaitopenai.createCompletion({model:'text-davinci-003',//对话机器人模型提示:'whatisjs?',//问题温度:0.5,//概率accuracy,0最准确max_tokens:150,//输出内容长度top_p:1.0,//避免重复和不相关的内容frequency_penalty:0.0,//控制词在语言模型中出现的频率,并进行惩罚presence_penalty:0.0,//控制单词在语言模型中出现的频率,并进行惩罚})console.log(choices[0].text);//输出内容}main()的输出如下图所示。这一步已经连接了openai。让用户配置和提问我们要让用户提问,不能直接把问题写在文件里,缺乏与用户的交互。这时,询问者出现了。它是一个命令行交互工具,可以做很多事情,比如各种clis的一些问题和选择配置的方式。比如VueCli创建的多选和单选就可以搞定。用法也很简单const{prompt}=awaitinquirer.prompt({type:'input',//可以是密码|list等name:'prompt',//定义的字段名message:'请输入问题',//提示信息});console.log('Input=>>>',prompt)现在我们可以得到用户的输入,我们可以做很多事情。获取用户输入的apiKey;获取用户选择的对话机器人模型;获取用户提问的内容;引入并定义配置constinquirer=require('inquirer');//定义配置configconstconfig=Object.create(null);constfs=require('fs');将密钥写入文件,供用户输入密钥。对于持久化存储,我选择直接创建一个文件来保存密钥,这样就不用每次都重新输入了。//判断文件是否存在constkeysIsExist=fs.existsSync('openai_keys');//如果不存在if(!keysIsExist){const{apiKey}=awaitinquirer.prompt({type:'password',name:'apiKey',message:'PleaseentertheKeyofOpenAI',})//写入覆盖fs.writeFile('openai_keys',apiKey.trim(),{flag:'w'},(err)=>{if(err)console.error(err)elsemain()//重新执行})}else{//这个文件存在,直接读取赋给config.apiKeyfs.readFile('openai_keys',(err,data)=>{if(err){console.error(err)return}config.apiKey=data.toString();})}让用户选择robotconst{model}=awaitinquirer.prompt({type:'list',name:'model',message:'请选择聊天机器人',choices:[{name:'text-ada-001',value:'text-ada-001'},{name:'text-curie-001',值:'text-curie-001'},{名称:'text-babbage-001',值:'text-babbage-001'},{名称:'text-davinci-003',值:'text-davinci-003'},],默认:'text-davinci-003'})config.model=model;让用户提问const{prompt}=awaitinquirer.prompt({type:'input',name:'prompt',message:'PleaseenterQuestion',});添加一个Loading效果,因为openai的响应有点慢,所以为了减少香蕉绿,引入了一个cli-spinnerconstSpinner=require('cli-spinner').Spinner;//%s将被使用下面的▂▃▄▅▆▇█相反,它是一个占位符constspinner=newSpinner('Loading..%s');//这里是加载字符,按照这个顺序渲染spinner。setSpinnerString('▂▃▄▅▆▇█');请求openai之前调用//请求启动spinner.start();//请求完成后暂停spinner.stop(true);//参数bool,是否清除输出内容所有代码终于写完了,现在已经是凌晨一点半了const{配置,OpenAIApi}=require("openai");constinquirer=require('inquirer');constfs=require('fs');constconfig=Object.create(null);constSpinner=require('cli-spinner').Spinner;constspinner=newSpinner('Loading..%s');spinner.setSpinnerString('▂▃▄▅▆▇█');asyncfunctionmain(){//判断文件是否存在constkeysIsExist=fs.existsSync('openai_keys');if(!keysIsExist){const{apiKey}=awaitinquirer.prompt({type:'password',name:'apiKey',message:'PleaseentertheKeyofOpenAI',})//写入覆盖fs.writeFile('openai_keys',apiKey.trim(),{flag:'w'},(err)=>{if(err)console.error(err)elsemain()})}else{fs.readFile('openai_keys',(err,data)=>{if(err){console.error(err)return}config.apiKey=data.toString();})}const{model}=awaitinquirer.prompt({type:'list',name:'model',message:'请选择聊天机器人',选择:[{name:'text-ada-001',value:'text-ada-001'},{name:'text-curie-001',value:'text-curie-001'},{name:'text-babbage-001',值:'text-babbage-001'},{名称:'text-davinci-003',值:'text-davinci-003'},],默认值:'text-davinci-003'})config.model=模型;const{apiKey}=配置;console.log('\033[42;30mLGOIN\033[40;32m登录成功\033[0m');constconfiguration=newConfiguration({apiKey});config.openai=newOpenAIApi(配置);start()}asyncfunctionstart(){const{model}=config;const{prompt}=awaitinquirer.prompt({type:'input',name:'prompt',message:'请输入问题',});if(!prompt.trim()){start()返回false}try{spinner.start();const{data:{choices}}=awaitconfig.openai.createCompletion({模型,提示,temperature:0.5,max_tokens:150,top_p:1.0,frequency_penalty:0.0,presence_penalty:0.0,})constanswer=choices[0]?.text?.replace(/\+/g,'');微调器停止(真);console.log('\033[32mOpenAI:'+answer?.trim()+'\033[0m');start()}catch(错误){spinner.stop(true);控制台日志(错误);}}主要的();
