无它,只是想看看官方的api如何使用,顺便测试下让chatgpt调用本机api并分析输出而已。 最后,简单封装了个方便使用调用的API类。
import { v4 as uuidv4 } from 'uuid'; import moment from 'moment-timezone'; import {exec} from 'child_process'; import { Configuration, OpenAIApi } from "openai"; import Keyv from "keyv"; import QuickLRU from "quick-lru"; function execShellCommand(cmd) { return new Promise((resolve, reject) => { exec(cmd, {maxBuffer: 1024 * 1024*500}, (error, stdout, stderr) => { if (error) { console.log(error); reject(error); } resolve(stdout? stdout : stderr); }); }); } function wait(time) { return new Promise((resolve)=> { let t = setTimeout(()=> { clearTimeout(t); resolve(t); }, time); }); } class MyChatGpt { constructor(opts) { this.config = opts; const configuration = new Configuration(opts); this.api = new OpenAIApi(configuration); this.people_data = {}; this._messageStore = new Keyv({ store: new QuickLRU({ maxSize: 1e4 }) }); } async getMessageById(id) { const res = await this._messageStore.get(id); return res; } async setMessage(message) { await this._messageStore.set(message.messageId, message); } // 获取消息及其所有父消息 async getAllMessageById(messageId) { const messages = []; // 递归获取父消息 let getParents = async (currentMessageId) => { const message = await this._messageStore.get(currentMessageId); if (message) { messages.push(message); if (message.parentMessageId) { await getParents(message.parentMessageId); } } }; await getParents(messageId); return messages.reverse(); } async sendMessage(people, msg, opts={}) { let real_opt = null; if(this.people_data[people]) { real_opt = {... this.people_data[people], ...opts }; } else { real_opt = { ...opts, nick: people, parentMessageId: uuidv4(), start_at: moment(new Date()).tz('Asia/Shanghai'), last_at: moment(new Date()).tz('Asia/Shanghai'), }; this.people_data[people] = real_opt; } let messages = []; let functions = opts.functions || []; if(real_opt.parentMessageId) { messages = await this.getAllMessageById(real_opt.parentMessageId); } let messageId = uuidv4(); let message = { "body": { "role":"user", "content": msg, }, messageId, "parentMessageId": real_opt.parentMessageId }; await this.setMessage(message); messages.push(message); let send_msg = async()=> { let m_s = messages.map(v=>v.body); let chat_ret = await this.api.createChatCompletion({ model: this.config.completionParams.model, messages: m_s,//messages.map(v=>v.body), functions, }); let resp = chat_ret.data.choices[0].message; let m = { "body": resp, messageId: uuidv4(), parentMessageId: messageId }; messages.push(m); messageId = m.messageId; await this.setMessage(m); await wait(getRandomInt(10000,30000)); if(resp.function_call) { let func_name = resp.function_call.name; let args = resp.function_call.arguments; if(real_opt.api&& real_opt.api[func_name]) { let f = real_opt.api[func_name]; let result = await f(args); m = { body: { "role": "function", "name": func_name, "content": result, }, messageId: uuidv4(), parentMessageId: messageId }; messages.push(m); messageId = m.messageId; await this.setMessage(m); return await send_msg(); } } return m; }; let m = await send_msg(); real_opt.parentMessageId = m.messageId; real_opt.last_at = moment(new Date()).tz('Asia/Shanghai'); this.people_data[people] = real_opt; return m; } } async function test() { let api = new MyChatGpt({ apiKey: 'sk-xxx', completionParams: { model: 'gpt-3.5-turbo-16k-0613' } }); let functions = [ { "name": "exec", "description": "执行linux命令,并返回执行输出结果,如果要执行复杂命令,需要将复杂命令创建为脚本,然后再执行", "parameters": { "type": "object", "properties": { "cmd": { "type": "string", "description": "用于执行的linux命令" }, "args": { "type": "string", "description": "用于执行的linux命令的参数" } }, "required": ["cmd"], } }]; let my_opts = {functions, api:{ "exec":async (args)=> { console.log("exec args=", args); try { let result = await execShellCommand(`${args.cmd} ${args.args}`); return result; } catch (e) { return `命令执行出错:${e}`; } } } }, let ret = await api.sendMessage("me", `我的当前目录是什么?`, my_opts); console.log("ret=", ret); await wait(getRandomInt(10000,30000)); ret = await api.sendMessage("me", `我的当前IP是什么?`, my_opts); console.log("ret=", ret); } try { await test(); } catch (e) { console.error(e); }