From ea713ea4eea89b4d97d147a59681bb7f18170b23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B6=9B?= Date: Fri, 17 May 2024 18:42:37 +0800 Subject: [PATCH 1/5] chore: llm gen --- package.json | 1 + scripts/llm/code.mjs | 45 +++++++++++++++++++++ scripts/llm/coze.mjs | 80 ++++++++++++++++++++++++++++++++++++++ scripts/llm/gen.mjs | 63 ++++++++++++++++++++++++++++++ scripts/llm/log/.gitignore | 1 + 5 files changed, 190 insertions(+) create mode 100644 scripts/llm/code.mjs create mode 100644 scripts/llm/coze.mjs create mode 100644 scripts/llm/gen.mjs create mode 100644 scripts/llm/log/.gitignore diff --git a/package.json b/package.json index bcf977c0..be719c77 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "site:home": "cross-env NODE_ENV=production webpack --progress --config scripts/sites/webpack.prod.home.js", "site:mobile": "cross-env NODE_ENV=production webpack --progress --config scripts/sites/webpack.prod.mobile.js", "site:pc": "cross-env NODE_ENV=production webpack --progress --config scripts/sites/webpack.prod.pc.js", + "llm:gen": "node scripts/llm/gen.mjs", "dev:demo": "node scripts/dev/dev-demo.js $@" }, "author": "taoyiyue@bytedance.com", diff --git a/scripts/llm/code.mjs b/scripts/llm/code.mjs new file mode 100644 index 00000000..ac71d218 --- /dev/null +++ b/scripts/llm/code.mjs @@ -0,0 +1,45 @@ +import { statSync, readdirSync, readFileSync } from 'fs'; +import { join } from 'path'; + +// 递归函数来遍历文件夹 +function walkDir(dir, callback) { + readdirSync(dir).forEach(f => { + let dirPath = join(dir, f); + let isDirectory = statSync(dirPath).isDirectory(); + isDirectory ? walkDir(dirPath, callback) : callback(join(dir, f)); + }); +} + +export class SourceCode { + // 获取全部文件列表 + getFileList(dir, reg) { + const list = []; + walkDir(dir, function (filePath) { + if (filePath.match(reg)) { + list.push(filePath); + } + }); + return list; + } + + getDirectoryContent(dir, reg) {} + + // 获取某个目录下所有的源代码 + getCodeContent(dir, reg) { + const fileList = this.getFileList(dir, reg); + + // 生成目录结构 + const contents = [ + `The source code directory is ${dir}, which contains the following files:`, + ...fileList.map(i => '- ' + i), + '\n', + ]; + + // 生成每个文件内容 + for (const filePath of fileList) { + const fileContent = readFileSync(filePath, { encoding: 'utf-8' }).trim(); + contents.push(`Code for ${filePath}: `, fileContent, '\n'); + } + return contents.join('\n'); + } +} diff --git a/scripts/llm/coze.mjs b/scripts/llm/coze.mjs new file mode 100644 index 00000000..0122765d --- /dev/null +++ b/scripts/llm/coze.mjs @@ -0,0 +1,80 @@ +import axios from 'axios'; +import _ from 'lodash'; +import { writeFileSync, appendFileSync } from 'fs'; +import { message } from 'gulp-typescript/release/utils'; + +///// 环境变量 ///// +const CHAT_URL = 'https://bots.byteintl.net/open_api/v2/chat'; + +// 记录日志 +export class ChatLog { + constructor() { + // 初始化变量 + this.chatHistory = []; + this.chatId = `${_.now()}${_.random(100000, 999999)}`; + this.logFiles = [ + `./scripts/llm/log/realtime.log`, + `./scripts/llm/log/${new Date().toISOString()}.log`, + ]; + + // 初始化文件 + this.logFiles.forEach(i => { + writeFileSync(i, `${new Date().toISOString()} Chat Id:\n${this.chatId}\n\n`); + }); + } + + // 写入日志文件,内部方法 + _append(content) { + this.logFiles.forEach(i => appendFileSync(i, content)); + } + + // 写入查询日志 + query(query) { + this._append(`${new Date().toISOString()} Query:\n${query} \n\n`); + this.chatHistory.push({ role: 'user', content_type: 'text', content: query }); + } + + // 写入响应日志 + response(data) { + this._append(`${new Date().toISOString()} `); + data?.messages?.forEach(({ type, content }) => { + if (type === 'verbose') return; + this._append(`${_.startCase(type)}:\n${content}\n\n`); + this.chatHistory.push({ role: 'assistant', content_type: 'text', type, content }); + }); + } +} + +export class AiBot { + constructor(botId, token) { + this.log = new ChatLog(); + this.botId = botId; + this.token = token; + } + + // 非流式对话 + async chat(query, withHistory = true) { + query = query.trim(); + + const headers = { Authorization: `Bearer ${this.token}` }; + const body = { + conversation_id: this.log.chatId, + bot_id: this.botId, + user: 'Aex', + query, + chat_history: withHistory ? this.log.chatHistory : [], + // stream: true, + }; + this.log.query(query); + + // 开始请求 + const res = await axios.post(CHAT_URL, body, { headers }); + this.log.response(res.data); + + // 拼装结果 + const messages = data?.messages?.map(({ type, content }) => { + return type === 'answer' ? content : ''; + }); + return messages.join(''); + } +} diff --git a/scripts/llm/gen.mjs b/scripts/llm/gen.mjs new file mode 100644 index 00000000..757f5597 --- /dev/null +++ b/scripts/llm/gen.mjs @@ -0,0 +1,63 @@ +import { SourceCode } from './code.mjs'; +import { AiBot } from './coze.mjs'; + +const BOT_ID = '7369473402367361041'; // GPT-4 模型 +const TOKEN = process.env.COZE_TOKEN_ADM; + +const code = new SourceCode(); + +// 一个游戏,测试 AI 上下文能力 +const prompt_game = ` +现在我们玩一个游戏: + +当我发送一个数字,你应该将这个数字+1,并将结果发给我。 +当我发送 "Next",你应该继续+1,并将结果发给我。 +当再次接收到数字后,游戏重新开始。 + +严格按照游戏规则回复,不要回复其他内容。 + +首先我给你一个数字是 1 + +`; + +// 指令一 +const prompt1 = ` + +你是一个优秀的前端工程师,关注于编写 Arco Design Mobile 代码,熟悉 React 和 Vue 框架,擅长将 React 代码改写为 Vue 代码。 + +当你将 React 代码改写为 Vue 代码时,你会严格遵守如下要求: +- 组件的功能和表现应与 React 代码完全一致 +- 需要将 React 的 JSX/TSX 转换为 Vue 文件要使用模版语法 +- 生成的代码代码的首行需要添加注释 "Note: Generated by AI, needs verification" +- 生成的代码需要添加中英文双语注释 +- 代码风格和命名习惯需要参考 Cell 组件和 Notify 组件的源代码 + +接下来我为你提供一些示例,你会学习这两个示例的源代码、目录结构、代码风格和命名习惯。 + +第一个是 Notify 组件示例,下面是 React 版本的源代码 +${code.getCodeContent('packages/arcodesign/components/notify/', /.(ts|tsx|js|jsx|less)$/)} +将其转换为 Vue 版本后的代码如下 +${code.getCodeContent('packages/arcodesign-vue/components/notify/', /.(vue|ts|js|less)$/)} + +第二个是 Cell 组件的示例,下面是 React 版本的源代码 +${code.getCodeContent('packages/arcodesign/components/cell/', /.(ts|tsx|js|jsx|less)$/)} +将其转换为 Vue 版本后的代码如下 +${code.getCodeContent('packages/arcodesign-vue/components/cell/', /.(vue|ts|js|less)$/)} + +下面你将开始自己的工作,我为你提供一个全新的组件,这个组件名为 Loading ,组件的 React 源代码为 +${code.getCodeContent('packages/arcodesign/components/cell/', /.(ts|tsx|js|jsx|less)$/)} + +你需要严格按照 Cell 组件和 Notify 组件的两个版本的代码的代码风格、目录结构、命名习惯,来进行 Loading 组件 vue 版本代码的编写。 + +当你准备好了,请回复 Ready。 +当我发送 Start,你需要告诉我 Loading 组件的目录结构和所有源代码文件名称,请注意需要回复完整的文件名称,包括文件路径。除了文件路径外,不要回答任何其他语句。 +当我发送一个文件路径,你需要完成这个文件的代码编写,记住你需要回复这个文件的完整源代码,不要做任何的省略,其代码风格和命名习惯要严格参考 Cell 组件和 Notify 组件,要和 React 版本功能完全一致。 + +`; + +///// 主流程开始 ///// +const bot = new AiBot(BOT_ID, TOKEN); + +await bot.chat(prompt1); +await bot.chat('Start'); +await bot.chat('packages/arcodesign-vue/components/loading/Loading.vue'); diff --git a/scripts/llm/log/.gitignore b/scripts/llm/log/.gitignore new file mode 100644 index 00000000..bf0824e5 --- /dev/null +++ b/scripts/llm/log/.gitignore @@ -0,0 +1 @@ +*.log \ No newline at end of file From a7172132b1e4a8bc36cc5306fcae3044a917c473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B6=9B?= Date: Wed, 22 May 2024 15:46:28 +0800 Subject: [PATCH 2/5] chore: improve coze bot --- scripts/llm/code.mjs | 63 ++++++++++++++---- scripts/llm/coze.mjs | 124 ++++++++++++++++++++++++++++++++---- scripts/llm/gen-article.mjs | 18 ++++++ scripts/llm/gen-game.mjs | 28 ++++++++ scripts/llm/gen.mjs | 84 ++++++++++++------------ 5 files changed, 251 insertions(+), 66 deletions(-) create mode 100644 scripts/llm/gen-article.mjs create mode 100644 scripts/llm/gen-game.mjs diff --git a/scripts/llm/code.mjs b/scripts/llm/code.mjs index ac71d218..c49b7337 100644 --- a/scripts/llm/code.mjs +++ b/scripts/llm/code.mjs @@ -1,6 +1,8 @@ +import _ from 'lodash'; import { statSync, readdirSync, readFileSync } from 'fs'; import { join } from 'path'; +///// 辅助函数 ///// // 递归函数来遍历文件夹 function walkDir(dir, callback) { readdirSync(dir).forEach(f => { @@ -10,27 +12,44 @@ function walkDir(dir, callback) { }); } -export class SourceCode { - // 获取全部文件列表 - getFileList(dir, reg) { - const list = []; - walkDir(dir, function (filePath) { - if (filePath.match(reg)) { - list.push(filePath); +// 源代码相关处理类,获取文件列表 +class Code { + constructor(dir, fileReg) { + this._dir = dir; + this._fileReg = fileReg; + } + // 获取文件列表 + fileList() { + const fileList = []; + walkDir(this._dir, filePath => { + if (filePath.match(this._fileReg)) { + fileList.push(filePath); } }); - return list; + return fileList; } - getDirectoryContent(dir, reg) {} + // 获取目录内容 + directory() { + const fileList = this.fileList(); + + // 生成目录结构 + const contents = [ + `The source code directory is ${this._dir}, which contains the following files:`, + ...fileList.map(i => '- ' + i), + '\n', + ]; - // 获取某个目录下所有的源代码 - getCodeContent(dir, reg) { - const fileList = this.getFileList(dir, reg); + return contents.join(','); + } + + // 获取目录内容和文件内容 + directoryAndContent() { + const fileList = this.fileList(); // 生成目录结构 const contents = [ - `The source code directory is ${dir}, which contains the following files:`, + `The source code directory is ${this.fileList}, which contains the following files:`, ...fileList.map(i => '- ' + i), '\n', ]; @@ -43,3 +62,21 @@ export class SourceCode { return contents.join('\n'); } } + +// React 源代码 +export class ReactCode extends Code { + constructor(comp) { + const dir = `packages/arcodesign/components/${_.snakeCase(comp)}/`; + const fileReg = /.(ts|tsx|js|jsx|less)$/; + super(dir, fileReg); + } +} + +// Vue 源代码 +export class VueCode extends Code { + constructor(comp) { + const dir = `packages/arcodesign-vue/components/${_.snakeCase(comp)}/`; + const fileReg = /.(vue|ts|js|less)$/; + super(dir, fileReg); + } +} diff --git a/scripts/llm/coze.mjs b/scripts/llm/coze.mjs index 0122765d..74626126 100644 --- a/scripts/llm/coze.mjs +++ b/scripts/llm/coze.mjs @@ -1,13 +1,12 @@ import axios from 'axios'; import _ from 'lodash'; import { writeFileSync, appendFileSync } from 'fs'; -import { message } from 'gulp-typescript/release/utils'; -///// 环境变量 ///// +///// 一些常量 ///// const CHAT_URL = 'https://bots.byteintl.net/open_api/v2/chat'; -// 记录日志 -export class ChatLog { +// 对话日志,基础类 +class ChatLog { constructor() { // 初始化变量 this.chatHistory = []; @@ -27,27 +26,85 @@ export class ChatLog { _append(content) { this.logFiles.forEach(i => appendFileSync(i, content)); } +} - // 写入查询日志 +// 对话日志(非流式) +class ChatLogNonStream extends ChatLog { + // 处理查询日志 query(query) { this._append(`${new Date().toISOString()} Query:\n${query} \n\n`); this.chatHistory.push({ role: 'user', content_type: 'text', content: query }); } - // 写入响应日志 + // 处理响应日志(非流式),并返回 answer response(data) { this._append(`${new Date().toISOString()} `); + let answer = ''; data?.messages?.forEach(({ type, content }) => { if (type === 'verbose') return; + if (type === 'answer') answer += content; this._append(`${_.startCase(type)}:\n${content}\n\n`); this.chatHistory.push({ role: 'assistant', content_type: 'text', type, content }); }); + return answer; } } -export class AiBot { +// 对话日志(流式) +class ChatLogStream extends ChatLog { + // 处理查询日志 + query(query) { + this._append(`${new Date().toISOString()} Query:\n${query} \n\n`); + this.chatHistory.push({ role: 'user', content_type: 'text', content: query }); + } + + // 开始写入响应日志(分块) + responseChunkStart() { + this._chunk = {}; + this._append(`${new Date().toISOString()} Response:\n`); + } + // 写入响应日志(分块) + responseChunk(raw) { + const regex = /data:(\{.*?\})(?=\s|$)/g; + const matches = String(raw).match(regex); + + for (const match of matches) { + const data = JSON.parse(match.replace('data:', '')); + + const event = data?.event, + type = data?.message?.type, + content = data?.message?.content; + + // 拼接数据 + if (event === 'message' && content) { + if (!this._chunk?.[type]) this._chunk[type] = ''; + this._chunk[type] += content; + + // 处理 answer + if (type === 'answer') { + this._append(content); + } + } + } + } + // 结束响应(分块) + responseChunkEnd() { + this._append(`\n\n`); + _.forEach(this._chunk, (content, type) => { + if (type === 'verbose') return; + if (type !== 'answer') { + this._append(`${_.startCase(type)}:\n${content}\n\n`); + } + this.chatHistory.push({ role: 'assistant', content_type: 'text', type, content }); + }); + return this._chunk['answer']; + } +} + +// AI 机器人 +export class AiBotNonStream { constructor(botId, token) { - this.log = new ChatLog(); + this.log = new ChatLogNonStream(); this.botId = botId; this.token = token; } @@ -69,12 +126,53 @@ export class AiBot { // 开始请求 const res = await axios.post(CHAT_URL, body, { headers }); - this.log.response(res.data); + const answer = this.log.response(res.data); + + return answer; + } +} + +export class AiBot { + constructor(botId, token) { + this.log = new ChatLogStream(); + this.botId = botId; + this.token = token; + } + + // 流式对话 + async chat(query, withHistory = true) { + query = query.trim(); + + const headers = { Authorization: `Bearer ${this.token}` }; + const body = { + conversation_id: this.log.chatId, + bot_id: this.botId, + user: 'Aex', + query, + chat_history: withHistory ? this.log.chatHistory : [], + stream: true, // 将请求变为流式 + }; + this.log.query(query); + + // 开始请求 - 注意这里使用流式处理方式 + const res = await axios.post(CHAT_URL, body, { headers, responseType: 'stream' }); + + this.log.responseChunkStart(); + + // 设置一个数组来收集流式数据片段 + res.data.on('data', chunk => { + this.log.responseChunk(chunk.toString('utf-8')); + }); + + return new Promise((resolve, reject) => { + res.data.on('end', () => { + const data = this.log.responseChunkEnd(); + resolve(data); + }); - // 拼装结果 - const messages = data?.messages?.map(({ type, content }) => { - return type === 'answer' ? content : ''; + res.data.on('error', err => { + reject(err); + }); }); - return messages.join(''); } } diff --git a/scripts/llm/gen-article.mjs b/scripts/llm/gen-article.mjs new file mode 100644 index 00000000..668d6745 --- /dev/null +++ b/scripts/llm/gen-article.mjs @@ -0,0 +1,18 @@ +import { cwd } from 'process'; +import { AiBot } from './coze.mjs'; + +const BOT_ID = '7369473402367361041'; // GPT-4 模型 +const TOKEN = process.env.COZE_TOKEN_ADM; + +const prompt_article = ` +今天又是努力工作的一天,帮我写一篇今天的日记,10 字左右 + +`; + +///// 主流程开始 ///// + +const bot = new AiBot(BOT_ID, TOKEN); +// 主指令 +const answer = await bot.chat(prompt_article); + +console.log(answer); diff --git a/scripts/llm/gen-game.mjs b/scripts/llm/gen-game.mjs new file mode 100644 index 00000000..4b430054 --- /dev/null +++ b/scripts/llm/gen-game.mjs @@ -0,0 +1,28 @@ +import { AiBot } from './coze.mjs'; + +const BOT_ID = '7369473402367361041'; // GPT-4 模型 +const TOKEN = process.env.COZE_TOKEN_ADM; + +// 一个游戏,测试 AI 上下文能力 +const prompt_game = ` +现在我们玩一个游戏: + +当我发送一个数字,你应该将这个数字+1,并将结果发给我。 +当我发送 "Next",你应该继续+1,并将结果发给我。 +当再次接收到数字后,游戏重新开始。 + +严格按照游戏规则回复,不要回复其他内容。 + +首先我给你一个数字是 1 + +`; + +///// 主流程开始 ///// + +const bot = new AiBot(BOT_ID, TOKEN); +// 主指令 +await bot.chat(prompt_game); +await bot.chat('Next'); +await bot.chat('Next'); +await bot.chat('Next'); +await bot.chat('Next'); diff --git a/scripts/llm/gen.mjs b/scripts/llm/gen.mjs index 757f5597..bbb32bdd 100644 --- a/scripts/llm/gen.mjs +++ b/scripts/llm/gen.mjs @@ -1,63 +1,67 @@ -import { SourceCode } from './code.mjs'; +import { writeFileSync } from 'fs'; +import { ReactCode, VueCode } from './code.mjs'; import { AiBot } from './coze.mjs'; const BOT_ID = '7369473402367361041'; // GPT-4 模型 const TOKEN = process.env.COZE_TOKEN_ADM; -const code = new SourceCode(); +// 指令一,以下指令为示例代码 +const prompt1 = ` -// 一个游戏,测试 AI 上下文能力 -const prompt_game = ` -现在我们玩一个游戏: +你是一个优秀的前端工程师,熟悉 React 和 Vue 框架,你的主要工作是将 Arco Design Mobile 已有的 React 组件改写为 Vue 组件。 -当我发送一个数字,你应该将这个数字+1,并将结果发给我。 -当我发送 "Next",你应该继续+1,并将结果发给我。 -当再次接收到数字后,游戏重新开始。 +接下来我为你提供 Arco Design Mobile 某些组件的源代码,你需要学习这些源代码的目录结构、代码风格和命名习惯。 -严格按照游戏规则回复,不要回复其他内容。 +第一个是 Notify 组件,下面是 React 版本的源代码 +${new ReactCode('notify').directoryAndContent()} +将其改写为 Vue 版本后的代码如下 +${new VueCode('notify').directoryAndContent()} -首先我给你一个数字是 1 +第二个是 Cell 组件,下面是 React 版本的源代码 +${new ReactCode('cell').directoryAndContent()} +将其改写为 Vue 版本后的代码如下 +${new VueCode('cell').directoryAndContent()} -`; +第三个是 Loading 组件,这个组件只有 React 版本的源代码 +${new ReactCode('loading').directoryAndContent()} -// 指令一 -const prompt1 = ` +根据以上的代码,开始你的工作:你需要严格参考 Cell 组件和 Notify 组件两个版本源代码的目录结构、命名习惯,将 Loading 的 React 组件改写为 Vue 组件。 -你是一个优秀的前端工程师,关注于编写 Arco Design Mobile 代码,熟悉 React 和 Vue 框架,擅长将 React 代码改写为 Vue 代码。 +我帮你完成了 Loading 组件 Vue 版本的目录结构,具体如下 +${new VueCode('loading').directory()} -当你将 React 代码改写为 Vue 代码时,你会严格遵守如下要求: +在进行改写的时候,你需要严格遵守并满足以下要求: - 组件的功能和表现应与 React 代码完全一致 - 需要将 React 的 JSX/TSX 转换为 Vue 文件要使用模版语法 -- 生成的代码代码的首行需要添加注释 "Note: Generated by AI, needs verification" +- 生成的代码首行需要添加注释 "Note: Generated by AI, needs verification" - 生成的代码需要添加中英文双语注释 -- 代码风格和命名习惯需要参考 Cell 组件和 Notify 组件的源代码 - -接下来我为你提供一些示例,你会学习这两个示例的源代码、目录结构、代码风格和命名习惯。 - -第一个是 Notify 组件示例,下面是 React 版本的源代码 -${code.getCodeContent('packages/arcodesign/components/notify/', /.(ts|tsx|js|jsx|less)$/)} -将其转换为 Vue 版本后的代码如下 -${code.getCodeContent('packages/arcodesign-vue/components/notify/', /.(vue|ts|js|less)$/)} - -第二个是 Cell 组件的示例,下面是 React 版本的源代码 -${code.getCodeContent('packages/arcodesign/components/cell/', /.(ts|tsx|js|jsx|less)$/)} -将其转换为 Vue 版本后的代码如下 -${code.getCodeContent('packages/arcodesign-vue/components/cell/', /.(vue|ts|js|less)$/)} - -下面你将开始自己的工作,我为你提供一个全新的组件,这个组件名为 Loading ,组件的 React 源代码为 -${code.getCodeContent('packages/arcodesign/components/cell/', /.(ts|tsx|js|jsx|less)$/)} - -你需要严格按照 Cell 组件和 Notify 组件的两个版本的代码的代码风格、目录结构、命名习惯,来进行 Loading 组件 vue 版本代码的编写。 +- 源代码要完整清晰,关键部分不要做任何的省略 +- 代码的格式和内容要符合业界最佳实践,特别要注意 TS 的一些类型 当你准备好了,请回复 Ready。 -当我发送 Start,你需要告诉我 Loading 组件的目录结构和所有源代码文件名称,请注意需要回复完整的文件名称,包括文件路径。除了文件路径外,不要回答任何其他语句。 -当我发送一个文件路径,你需要完成这个文件的代码编写,记住你需要回复这个文件的完整源代码,不要做任何的省略,其代码风格和命名习惯要严格参考 Cell 组件和 Notify 组件,要和 React 版本功能完全一致。 - +接着我会引导你一步一步完成代码编写,每当我发送文件路径时,你需要直接回复该文件的代码,回复的格式满足以下要求: +- 回复的内容必须是代码,如果有额外的补充说明或解析,需要使用注释的方式 +- 除了源代码和注释本身,不要回复任何其他无关的内容 `; ///// 主流程开始 ///// -const bot = new AiBot(BOT_ID, TOKEN); +const bot = new AiBot(BOT_ID, TOKEN); +// 主指令 await bot.chat(prompt1); -await bot.chat('Start'); -await bot.chat('packages/arcodesign-vue/components/loading/Loading.vue'); + +// 单文件代码生成 +for (const filePath of new VueCode('loading').fileList()) { + console.log('即将生成文件代码:', filePath); + const content = await bot.chat(filePath); + + // 匹配代码部分并写入文件 + const match = content.match(/```(?:\w*\n)?([\s\S]*?)```/); + writeFileSync(filePath, match?.[1] ?? content); +} + +// const a = readFileSync('scripts/llm/log/1.log', 'utf-8'); +// // writeFileSync(filePath, match[1] ?? content); +// // console.log(a); +// const match = a.match(/```(?:\w*\n)?([\s\S]*?)```/); +// console.log(match[1]); From a612d57aa4e720dd92b7fb7da788f0aeb49e336c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B6=9B?= Date: Thu, 23 May 2024 15:33:29 +0800 Subject: [PATCH 3/5] chore: remove useless code --- scripts/llm/gen.mjs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/scripts/llm/gen.mjs b/scripts/llm/gen.mjs index bbb32bdd..13c9b543 100644 --- a/scripts/llm/gen.mjs +++ b/scripts/llm/gen.mjs @@ -8,6 +8,8 @@ const TOKEN = process.env.COZE_TOKEN_ADM; // 指令一,以下指令为示例代码 const prompt1 = ` +# 角色 + 你是一个优秀的前端工程师,熟悉 React 和 Vue 框架,你的主要工作是将 Arco Design Mobile 已有的 React 组件改写为 Vue 组件。 接下来我为你提供 Arco Design Mobile 某些组件的源代码,你需要学习这些源代码的目录结构、代码风格和命名习惯。 @@ -59,9 +61,3 @@ for (const filePath of new VueCode('loading').fileList()) { const match = content.match(/```(?:\w*\n)?([\s\S]*?)```/); writeFileSync(filePath, match?.[1] ?? content); } - -// const a = readFileSync('scripts/llm/log/1.log', 'utf-8'); -// // writeFileSync(filePath, match[1] ?? content); -// // console.log(a); -// const match = a.match(/```(?:\w*\n)?([\s\S]*?)```/); -// console.log(match[1]); From 2c82e4f3e8301cfd32452ae0d5761500d5f03dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B6=9B?= Date: Tue, 28 May 2024 11:33:59 +0800 Subject: [PATCH 4/5] chore: add bots --- scripts/llm/gen-article.mjs | 5 ++++- scripts/llm/gen-game.mjs | 4 +++- scripts/llm/gen.mjs | 5 ++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/scripts/llm/gen-article.mjs b/scripts/llm/gen-article.mjs index 668d6745..10cb6523 100644 --- a/scripts/llm/gen-article.mjs +++ b/scripts/llm/gen-article.mjs @@ -1,7 +1,10 @@ import { cwd } from 'process'; import { AiBot } from './coze.mjs'; -const BOT_ID = '7369473402367361041'; // GPT-4 模型 +// const BOT_ID = '7372403809576009729'; // Claude 3 Opus 模型 +// const BOT_ID = '7369473402367361041'; // GPT-4 Turbo 模型 +const BOT_ID = '7373886057160753169'; // GPT-4o 模型 + const TOKEN = process.env.COZE_TOKEN_ADM; const prompt_article = ` diff --git a/scripts/llm/gen-game.mjs b/scripts/llm/gen-game.mjs index 4b430054..8df19cff 100644 --- a/scripts/llm/gen-game.mjs +++ b/scripts/llm/gen-game.mjs @@ -1,6 +1,8 @@ import { AiBot } from './coze.mjs'; -const BOT_ID = '7369473402367361041'; // GPT-4 模型 +const BOT_ID = '7372403809576009729'; // Claude 3 Opus 模型 +// const BOT_ID = '7369473402367361041'; // GPT-4 Turbo 模型 +// const BOT_ID = '7373886057160753169'; // GPT-4o 模型 const TOKEN = process.env.COZE_TOKEN_ADM; // 一个游戏,测试 AI 上下文能力 diff --git a/scripts/llm/gen.mjs b/scripts/llm/gen.mjs index 13c9b543..dff10a35 100644 --- a/scripts/llm/gen.mjs +++ b/scripts/llm/gen.mjs @@ -2,7 +2,10 @@ import { writeFileSync } from 'fs'; import { ReactCode, VueCode } from './code.mjs'; import { AiBot } from './coze.mjs'; -const BOT_ID = '7369473402367361041'; // GPT-4 模型 +// const BOT_ID = '7372403809576009729'; // Claude 3 Opus 模型 +// const BOT_ID = '7369473402367361041'; // GPT-4 Turbo 模型 +const BOT_ID = '7373886057160753169'; // GPT-4o 模型 + const TOKEN = process.env.COZE_TOKEN_ADM; // 指令一,以下指令为示例代码 From dd0a4a077aad90e41bd974981145f25e8cf6e9fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B6=9B?= Date: Tue, 28 May 2024 11:36:26 +0800 Subject: [PATCH 5/5] chore: test non stream --- scripts/llm/gen-article.mjs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/scripts/llm/gen-article.mjs b/scripts/llm/gen-article.mjs index 10cb6523..35629c32 100644 --- a/scripts/llm/gen-article.mjs +++ b/scripts/llm/gen-article.mjs @@ -1,5 +1,4 @@ -import { cwd } from 'process'; -import { AiBot } from './coze.mjs'; +import { AiBotNonStream } from './coze.mjs'; // const BOT_ID = '7372403809576009729'; // Claude 3 Opus 模型 // const BOT_ID = '7369473402367361041'; // GPT-4 Turbo 模型 @@ -8,13 +7,13 @@ const BOT_ID = '7373886057160753169'; // GPT-4o 模型 const TOKEN = process.env.COZE_TOKEN_ADM; const prompt_article = ` -今天又是努力工作的一天,帮我写一篇今天的日记,10 字左右 +今天又是努力工作的一天,帮我写一篇今天的日记,100 字左右 `; ///// 主流程开始 ///// -const bot = new AiBot(BOT_ID, TOKEN); +const bot = new AiBotNonStream(BOT_ID, TOKEN); // 主指令 const answer = await bot.chat(prompt_article);