之前的章节算是已经比较完整的实现了聊天功能,本来打算直接结束的。前几天听说文心一言4.0开放了公测,所以也去申请了一下,2天后就收到了通过短信。通过以后,可以在之前申请的应用列表中,点击“详情”,在“服务配置”的最后一行可以看到ERNIE-Bot 4.0
目前一直到10月底,4.0接口是免费的,大家抓紧时间体验。
我们看一下API文档,发现调用方式和之前的类似,我们可以调整一下代码底层,将其配置化,以方便我们在不同的模型间进行切换。
config/config.default.js调整代码如下:
config.ernie = { client_id: '填入您的API Key', //API Key client_secret: '填入您的Secret Key',//Secret Key access_token: '', //先置空,后续由程序填充 expire_day: 30, //access_token过期时长(天) gpt_model: 'ERNIE-Bot-4', //此处值对应gpt_list中的type gpt_list: [{ type: 'ERNIE-Bot-4', //文心一言4.0 url: 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro' }, { type: 'ERNIE-Bot', //文心一言 url: 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions' }, { type: 'ERNIE-Bot-turbo', //文心一言轻量版 url: 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/eb-instant' }] }
app/service/ernie.js全部代码如下:
const { Service } = require('egg'); const moment = require('moment'); class ErnieService extends Service { async getAccessToken() { console.log('===================ErnieService getAccessToken====================='); let ctx = this.ctx; try { const res = await ctx.curl( `https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=${ctx.app.config.ernie.client_id}&client_secret=${ctx.app.config.ernie.client_secret}`, { method: 'GET', rejectUnauthorized: false, data: {}, headers: {}, timeout: 30000, contentType: 'json', dataType: 'json', }) console.log(res) if (res.data.access_token) { console.log('access_token', ctx.app.config.ernie.access_token) return res.data.access_token; } } catch (error) { console.log(error) } return null; } async sendMsg(msg) { console.log('===================ErnieService sendMsg====================='); console.log(JSON.stringify(msg)); let ctx = this.ctx; let gpt_url; for (let i of ctx.app.config.ernie.gpt_list) { if (i.type === ctx.app.config.ernie.gpt_model) { gpt_url = i.url; break; } } if (!gpt_url) { console.log('您设置的gpt_model值不存在'); return null; } try { const res = await ctx.curl( `${gpt_url}?access_token=${ctx.app.config.ernie.access_token}`, { method: 'POST', rejectUnauthorized: false, data: { "messages": msg }, timeout: 30000, contentType: 'json', dataType: 'json', }) console.log(res) if (res.data) { if (res.data.error_code == '111') { //token过期 await ctx.service.ernie.checkAccessToken(true); } return res.data; } return null; } catch (error) { console.log(error) return null; } } async checkAccessToken(forceReflesh) { //forceReflesh强制刷新 console.log('===================ErnieService checkAccessToken====================='); let ctx = this.ctx; const query = {}; const accessToken = await ctx.model.AccessToken.findOne(query); if (accessToken) { console.log('accessToken', accessToken.access_token, accessToken.updated_at); if (moment(new Date()).diff(moment(accessToken.updated_at), 'days') >= ctx.app.config.ernie.expire_day - 1 || forceReflesh) { //提前一天刷新 console.log('accessToken已失效,重新获取中') const accessTokenStr = await ctx.service.ernie.getAccessToken(); if (accessTokenStr) { await accessToken.update({ accessToken: accessTokenStr, updated_at: moment().format('YYYY-MM-DD HH:mm:ss') }); ctx.app.config.ernie.access_token = accessTokenStr; console.log('accessToken更新成功'); } else { console.log('accessToken获取失败'); } } else { ctx.app.config.ernie.access_token = accessToken.access_token; console.log('accessToken在有效期内'); } } else { console.log('accessToken不存在'); const accessTokenStr = await ctx.service.ernie.getAccessToken(); if (accessTokenStr) { const queryData = await ctx.model.AccessToken.create({ access_token: accessTokenStr }); ctx.app.config.ernie.access_token = accessTokenStr; console.log('accessToken更新成功'); } else { console.log('accessToken获取失败'); } } } } module.exports = ErnieService;
最近发现access_token有时候莫名其妙的就过期,所以我们加入了强制刷新的逻辑。我们在app.js中也可以加入强制刷新,让服务一启动就刷新access_token。
app.js部分代码:
app.ready(async () => { console.log("==app ready=="); let ctx = app.createAnonymousContext(); await ctx.service.ernie.checkAccessToken(true); //强制刷新AccessToken await ctx.service.wechat.startBot(); //初始化BOT })
至此,我们已经可以在三种不同的模型直接快速切换,仅需要调整config.ernie.gpt_model配置项。
本章完整代码在这里下载。运行前请先申请文心一言4.0测试资格,配置好config/config.default.js里面config.ernie下的client_id和client_secret配置项。
tokenappgpturlclibotcodejsonbaiduchatapicreate聊天功能gifapi文档oauth