├── .env.example
├── .gitignore
├── README.md
├── backup
└── card.html.bak
├── package-lock.json
├── package.json
├── prompts
└── card.js
├── public
├── css
│ ├── card-styles.css
│ └── style.css
├── icon
│ ├── android
│ │ ├── play_store_512.png
│ │ └── res
│ │ │ ├── mipmap-anydpi-v26
│ │ │ └── ic_launcher.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_background.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_monochrome.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_background.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_monochrome.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_background.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_monochrome.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_background.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_monochrome.png
│ │ │ └── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_background.png
│ │ │ ├── ic_launcher_foreground.png
│ │ │ └── ic_launcher_monochrome.png
│ ├── ios
│ │ ├── AppIcon-20@2x.png
│ │ ├── AppIcon-20@2x~ipad.png
│ │ ├── AppIcon-20@3x.png
│ │ ├── AppIcon-20~ipad.png
│ │ ├── AppIcon-29.png
│ │ ├── AppIcon-29@2x.png
│ │ ├── AppIcon-29@2x~ipad.png
│ │ ├── AppIcon-29@3x.png
│ │ ├── AppIcon-29~ipad.png
│ │ ├── AppIcon-40@2x.png
│ │ ├── AppIcon-40@2x~ipad.png
│ │ ├── AppIcon-40@3x.png
│ │ ├── AppIcon-40~ipad.png
│ │ ├── AppIcon-60@2x~car.png
│ │ ├── AppIcon-60@3x~car.png
│ │ ├── AppIcon-83.5@2x~ipad.png
│ │ ├── AppIcon@2x.png
│ │ ├── AppIcon@2x~ipad.png
│ │ ├── AppIcon@3x.png
│ │ ├── AppIcon~ios-marketing.png
│ │ ├── AppIcon~ipad.png
│ │ └── Contents.json
│ └── web
│ │ ├── README.txt
│ │ ├── apple-touch-icon.png
│ │ ├── favicon.ico
│ │ ├── icon-192-maskable.png
│ │ ├── icon-192.png
│ │ ├── icon-512-maskable.png
│ │ └── icon-512.png
├── img
│ └── donation_qrcode.png
├── index.html
├── js
│ ├── card.js
│ └── script.js
└── manifest.json
├── routes
└── api.js
├── server.js
└── services
└── aiService.js
/.env.example:
--------------------------------------------------------------------------------
1 | # API Credentials
2 | ARK_API_KEY=your_ark_api_key_here
3 | ARK_MODEL_ID=your_ark_model_id_here
4 |
5 | # u5154u5b50APIu914du7f6e
6 | TUZI_API_KEY=your_tuzi_api_key_here
7 |
8 | # Server Configuration
9 | PORT=3001
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # 环境变量文件
2 | .env
3 |
4 | # 依赖目录
5 | node_modules/
6 |
7 | # 日志文件
8 | logs
9 | *.log
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # 运行时数据
15 | pids
16 | *.pid
17 | *.seed
18 | *.pid.lock
19 |
20 | # 目录用于缓存的工具
21 | .npm
22 | .eslintcache
23 |
24 | # 可选的 REPL 历史记录
25 | .node_repl_history
26 |
27 | # 输出的二进制文件
28 | dist/
29 | build/
30 |
31 | # 操作系统文件
32 | .DS_Store
33 | Thumbs.db
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Cards-Go
2 |
3 | 一个基于 AI 的知识卡片生成工具,支持多种风格和自定义选项。
4 |
5 | ## 功能特点
6 |
7 | - **多 AI 提供商支持**:支持 ARK AI 和 Tuzi AI,可以灵活切换
8 | - **多种卡片风格**:支持多种设计风格,包括极简主义、复古风、赛博朋克等
9 | - **自定义选项**:可调整卡片比例、每行卡片数量等参数
10 | - **查看源代码和提示词**:可以查看生成的卡片 HTML 源代码和使用的提示词
11 | - **下载和分享**:支持将生成的卡片下载为图片
12 | - **响应式设计**:适配各种屏幕尺寸的设备
13 | - **PWA 支持**:可以安装到设备上作为独立应用使用
14 |
15 | ## 技术栈
16 |
17 | - **前端**:原生 JavaScript、HTML、CSS、Tailwind CSS
18 | - **后端**:Node.js、Express.js
19 | - **API**:ARK AI API、Tuzi AI API
20 | - **依赖**:axios、express-session、dotenv 等
21 |
22 | ## 安装和运行
23 |
24 | ### 前提条件
25 |
26 | - Node.js (v14.0.0 或更高版本)
27 | - npm 或 yarn
28 | - ARK AI 和/或 Tuzi AI 的 API 密钥
29 |
30 | ### 安装步骤
31 |
32 | 1. 克隆仓库
33 | ```bash
34 | git clone https://github.com/yourusername/cards-go.git
35 | cd cards-go
36 | ```
37 |
38 | 2. 安装依赖
39 | ```bash
40 | npm install
41 | ```
42 |
43 | 3. 创建 `.env` 文件并添加以下环境变量
44 | ```
45 | PORT=3001
46 | ARK_API_KEY=your_ark_api_key
47 | TUZI_API_KEY=your_tuzi_api_key
48 | ```
49 |
50 | 4. 启动服务器
51 | ```bash
52 | node server.js
53 | ```
54 |
55 | 5. 访问应用
56 | 在浏览器中打开 `http://localhost:3001`
57 |
58 | ## 使用指南
59 |
60 | 1. **生成卡片**:
61 | - 在首页输入主题
62 | - 选择 AI 提供商(ARK 或 Tuzi)
63 | - 选择卡片风格和其他选项
64 | - 点击生成卡片按钮
65 |
66 | 2. **查看源代码和提示词**:
67 | - 生成卡片后,点击右上角的代码图标查看源代码
68 | - 点击魔法棒图标查看提示词
69 |
70 | 3. **下载卡片**:
71 | - 生成卡片后,点击下载按钮将卡片保存为图片
72 |
73 | ## 自定义选项说明
74 |
75 | - **卡片比例**:支持 16:9、4:3、1:1、9:16、3:4、2:1 等多种比例
76 | - **每行卡片数**:可选 1-4 张卡片每行
77 | - **生成模式**:
78 | - 提取模式:从输入主题中提取知识点
79 | - 字面模式:直接使用输入内容生成卡片
80 | - 创造模式:基于输入主题创造新内容
81 |
82 | ## 项目结构
83 |
84 | ```
85 | /
86 | |-- public/ # 静态资源
87 | | |-- css/ # 样式文件
88 | | |-- js/ # 前端 JavaScript 文件
89 | | |-- index.html # 首页
90 | | |-- manifest.json # PWA 配置文件
91 | |
92 | |-- routes/ # 路由处理
93 | | |-- api.js # API 路由
94 | |
95 | |-- services/ # 服务层
96 | | |-- aiService.js # AI 服务封装
97 | |
98 | |-- prompts/ # 提示词模板
99 | | |-- card.js # 卡片生成提示词
100 | |
101 | |-- server.js # 服务器入口文件
102 | |-- package.json # 项目依赖
103 | |-- .env # 环境变量文件
104 | |-- README.md # 项目说明
105 | ```
106 |
107 | ## 更新日志
108 |
109 | ### 2025-03-30
110 |
111 | - 将默认 AI 提供商从 Tuzi 改为 ARK
112 | - 将首页 logo 改为纯文本形式
113 | - 修复卡片生成 HTML 内容显示问题
114 | - 添加查看源代码和提示词的图标
115 | - 添加 PWA 支持,包括 manifest.json 和图标
116 |
117 | ## 许可证
118 |
119 | MIT License
120 |
121 | ## 联系方式
122 |
123 | 如有问题或建议,请提交 Issue 或联系项目维护者。
124 |
--------------------------------------------------------------------------------
/backup/card.html.bak:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
24 |
39 |
40 |
41 |
42 |
正在生成卡片,请稍候...
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
54 |
57 |
58 |
59 |
60 | 或标签
614 | if (response.includes('
生成卡片时出错,请重试
`;
620 | }
621 | }
622 | }
623 |
624 | // 如果成功解析到卡片数据,生成新的HTML
625 | if (cards.length > 0) {
626 | console.log('开始生成卡片HTML...');
627 | try {
628 | // 获取设计风格映射
629 | const { DESIGN_STYLES } = await import('../prompts/card.js');
630 | const styleMap = {};
631 | DESIGN_STYLES.forEach(style => {
632 | styleMap[style.code] = style;
633 | });
634 | console.log('加载了', DESIGN_STYLES.length, '种设计风格');
635 |
636 | // 生成卡片HTML
637 | const cardsPerRow = config.cardsPerRow || 2;
638 | const aspectRatio = config.aspectRatio || '16:9';
639 | const aspectClass = 'aspect-' + aspectRatio.replace(':', '-');
640 | console.log('卡片设置: 每行', cardsPerRow, '张, 比例', aspectRatio);
641 |
642 | // 创建卡片容器
643 | html = `
644 |
645 | ${cards.map((card, index) => {
646 | // 确定卡片风格
647 | let styleCode = card.style || 'MINI';
648 | let styleClass = '';
649 |
650 | // 根据风格代码映射到CSS类
651 | switch(styleCode) {
652 | case 'VINT': styleClass = 'vintage'; break;
653 | case 'TECH': styleClass = 'futuristic'; break;
654 | case 'BOLD': styleClass = 'bold-modern'; break;
655 | case 'DECO': styleClass = 'art-deco'; break;
656 | case 'MINI': styleClass = 'minimalist'; break;
657 | case 'SCAN': styleClass = 'constructivism'; break;
658 | case 'PUNK': styleClass = 'cyberpunk'; break;
659 | case 'JPNM': styleClass = 'neo-futurism'; break;
660 | case 'BRIT': styleClass = 'british-rock'; break;
661 | default: styleClass = 'minimalist';
662 | }
663 |
664 | // 生成卡片HTML
665 | return `
666 |
667 | ${getStyleSpecificElements(styleClass)}
668 |
669 |
${card.quote}
670 |
${card.context}
671 |
672 |
`;
673 | }).join('')}
674 |
675 | `;
676 | } catch (styleError) {
677 | console.error('生成卡片HTML时出错:', styleError);
678 | html = `
生成卡片时出错,请重试
`;
679 | }
680 | }
681 |
682 | // 将卡片数据存储到会话中,以便加载页面可以检测到生成完成
683 | req.session.cardData = {
684 | html: html,
685 | cards: cards,
686 | timestamp: new Date().toISOString()
687 | };
688 |
689 | // 将原始HTML存储到会话中,以便查看源代码
690 | // 保存未添加工具图标的原始HTML
691 | req.session.originalHtml = html;
692 | // 同时保存原始响应,以便查看源代码
693 | req.session.originalResponse = response;
694 |
695 | // 返回HTML内容
696 | console.log('生成完成,返回HTML内容,长度:', html.length);
697 |
698 | // 如果HTML内容为空,则使用原始AI响应
699 | if (!html || html.trim() === '') {
700 | console.log('HTML内容为空,尝试使用原始AI响应');
701 |
702 | // 检查原始AI响应是否包含标签
703 | if (response.includes(' 标签
731 | if (html && html.includes(',在 body 标签后插入工具图标
733 | const toolsHtml = `
734 |
735 |
768 |
776 | `;
777 |
778 | // 检查是否已经包含 Font Awesome
779 | if (!html.includes('font-awesome')) {
780 | // 如果没有 Font Awesome,在 head 标签中添加
781 | html = html.replace('', '\n
');
782 | }
783 |
784 | // 在 body 标签后插入工具图标
785 | html = html.replace('', '\n' + toolsHtml);
786 | } else {
787 | // 如果不包含 ,则在内容开头添加工具图标
788 | const toolsHtml = `
789 |
790 |
823 |
824 |
832 | `;
833 |
834 | // 在内容开头添加工具图标
835 | html = toolsHtml + html;
836 | }
837 |
838 | res.json({ html: html });
839 |
840 | // 返回风格特定元素
841 | function getStyleSpecificElements(styleClass) {
842 | switch(styleClass) {
843 | case 'vintage':
844 | return '
';
845 | case 'futuristic':
846 | return '
';
847 | case 'bold-modern':
848 | return '
';
849 | case 'art-deco':
850 | return '
';
851 | case 'constructivism':
852 | return '
';
853 | case 'cyberpunk':
854 | return '
';
855 | case 'neo-futurism':
856 | return '
';
857 | case 'british-rock':
858 | return '
';
859 | default:
860 | return '';
861 | }
862 | }
863 |
864 | } catch (error) {
865 | console.error('生成卡片时出错:', error);
866 | res.status(500).json({ error: error.message });
867 | }
868 | });
869 |
870 | // 查看原始HTML代码
871 | router.get('/view-source', (req, res) => {
872 | try {
873 | // 获取存储在会话中的原始 HTML 代码和原始响应
874 | const originalHtml = req.session.originalHtml;
875 | const originalResponse = req.session.originalResponse;
876 |
877 | if (!originalHtml && !originalResponse) {
878 | return res.status(404).send('未找到HTML代码,请先生成卡片');
879 | }
880 |
881 | // 处理原始响应中的代码块
882 | let displayHtml = originalHtml;
883 |
884 | // 如果原始HTML为空但有原始响应,尝试从响应中提取HTML代码块
885 | if ((!displayHtml || displayHtml.trim() === '') && originalResponse) {
886 | const htmlCodeBlockRegex = /```html([\s\S]*?)```/;
887 | const match = originalResponse.match(htmlCodeBlockRegex);
888 |
889 | if (match && match[1]) {
890 | displayHtml = match[1].trim();
891 | console.log('从原始响应中提取到HTML代码块');
892 | } else {
893 | // 如果没有找到HTML代码块,就使用原始响应
894 | displayHtml = originalResponse;
895 | console.log('使用原始响应作为显示内容');
896 | }
897 | }
898 |
899 | // 安全转义HTML字符
900 | function escapeHtml(unsafe) {
901 | return unsafe
902 | .replace(/&/g, '&')
903 | .replace(//g, '>')
905 | .replace(/"/g, '"')
906 | .replace(/'/g, ''');
907 | }
908 |
909 | // 返回一个简单的页面,显示HTML代码
910 | res.send(`
911 |
912 |
913 |
914 |
915 |
查看源代码
916 |
917 |
977 |
978 |
979 |
983 |
984 |
985 |
988 |
989 |
990 |
1020 |
1021 | `);
1022 | } catch (error) {
1023 | console.error('查看源代码时出错:', error);
1024 | res.status(500).send(`查看源代码时出错: ${error.message}`);
1025 | }
1026 | });
1027 |
1028 | // 查看提示词
1029 | router.get('/view-prompt', (req, res) => {
1030 | try {
1031 | // 获取存储在会话中的提示词
1032 | const systemPrompt = req.session.systemPrompt;
1033 | const fullSystemPrompt = req.session.fullSystemPrompt;
1034 | const userPrompt = req.session.userPrompt;
1035 |
1036 | if (!systemPrompt || !userPrompt) {
1037 | return res.status(404).send('未找到提示词,请先生成卡片');
1038 | }
1039 |
1040 | // 安全转义HTML字符
1041 | function escapeHtml(unsafe) {
1042 | return unsafe
1043 | .replace(/&/g, '&')
1044 | .replace(//g, '>')
1046 | .replace(/"/g, '"')
1047 | .replace(/'/g, ''');
1048 | }
1049 |
1050 | // 返回一个简单的页面,显示提示词
1051 | res.send(`
1052 |
1053 |
1054 |
1055 |
1056 |
查看提示词
1057 |
1058 |
1142 |
1143 |
1144 |
1155 |
1156 |
1157 |
基础系统提示词
1158 |
${escapeHtml(systemPrompt)}
1159 |
1162 |
1163 |
1164 |
1165 |
完整系统提示词(包含模式调整)
1166 |
${escapeHtml(fullSystemPrompt)}
1167 |
1170 |
1171 |
1172 |
1173 |
用户提示词
1174 |
${escapeHtml(userPrompt)}
1175 |
1178 |
1179 |
1180 |
1239 |
1240 | `);
1241 | } catch (error) {
1242 | console.error('查看提示词时出错:', error);
1243 | res.status(500).send(`查看提示词时出错: ${error.message}`);
1244 | }
1245 | });
1246 |
1247 | // 自定义卡片样式 API
1248 | router.get('/custom-card-styles', async (req, res) => {
1249 | try {
1250 | // 从请求中获取主题词
1251 | const theme = req.query.theme;
1252 |
1253 | if (!theme) {
1254 | return res.status(400).json({ error: '主题词是必需的' });
1255 | }
1256 |
1257 | // 生成基于主题的自定义样式
1258 | const primaryColor = generateColorFromString(theme);
1259 | const secondaryColor = generateComplementaryColor(primaryColor);
1260 |
1261 | // 返回自定义样式
1262 | res.json({
1263 | primaryColor,
1264 | secondaryColor,
1265 | // 可以添加更多基于主题的样式属性
1266 | });
1267 | } catch (error) {
1268 | console.error('生成自定义样式时出错:', error);
1269 | res.status(500).json({ error: error.message });
1270 | }
1271 | });
1272 |
1273 | // 辅助函数:HTML转义
1274 | function escapeHtml(unsafe) {
1275 | return unsafe
1276 | .replace(/&/g, "&")
1277 | .replace(//g, ">")
1279 | .replace(/"/g, """)
1280 | .replace(/'/g, "'");
1281 | }
1282 |
1283 | // 从字符串生成颜色
1284 | // @param {string} str 输入字符串
1285 | // @returns {string} 颜色代码
1286 | function generateColorFromString(str) {
1287 | let hash = 0;
1288 | for (let i = 0; i < str.length; i++) {
1289 | hash = str.charCodeAt(i) + ((hash << 5) - hash);
1290 | }
1291 |
1292 | // 确保颜色不会太暗或太亮
1293 | let r = (hash & 0xFF0000) >> 16;
1294 | let g = (hash & 0x00FF00) >> 8;
1295 | let b = hash & 0x0000FF;
1296 |
1297 | // 调整亮度
1298 | const minBrightness = 30; // 避免太暗
1299 | const maxBrightness = 220; // 避免太亮
1300 |
1301 | r = Math.max(minBrightness, Math.min(maxBrightness, r));
1302 | g = Math.max(minBrightness, Math.min(maxBrightness, g));
1303 | b = Math.max(minBrightness, Math.min(maxBrightness, b));
1304 |
1305 | return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;
1306 | }
1307 |
1308 | // 生成互补色
1309 | // @param {string} hexColor 原始颜色
1310 | // @returns {string} 互补颜色
1311 | function generateComplementaryColor(hexColor) {
1312 | // 移除#前缀
1313 | const hex = hexColor.replace('#', '');
1314 |
1315 | // 转换为RGB
1316 | const r = parseInt(hex.substring(0, 2), 16);
1317 | const g = parseInt(hex.substring(2, 4), 16);
1318 | const b = parseInt(hex.substring(4, 6), 16);
1319 |
1320 | // 计算互补色 (255 - 原色)
1321 | const compR = 255 - r;
1322 | const compG = 255 - g;
1323 | const compB = 255 - b;
1324 |
1325 | // 转换回十六进制
1326 | return `#${((1 << 24) + (compR << 16) + (compG << 8) + compB).toString(16).slice(1)}`;
1327 | }
1328 |
1329 | export default router;
1330 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | // server.js
2 | import express from 'express';
3 | import path from 'path';
4 | import { fileURLToPath } from 'url';
5 | import dotenv from 'dotenv';
6 | import session from 'express-session';
7 | import compression from 'compression';
8 | import apiRoutes from './routes/api.js';
9 |
10 | // 配置环境变量
11 | dotenv.config();
12 |
13 | const __filename = fileURLToPath(import.meta.url);
14 | const __dirname = path.dirname(__filename);
15 |
16 | const app = express();
17 | const PORT = process.env.PORT || 3001;
18 |
19 | // 中间件
20 | app.use(compression()); // 添加压缩中间件
21 | app.use(express.static(path.join(__dirname, 'public')));
22 | app.use(express.json());
23 |
24 | // 添加会话支持
25 | app.use(session({
26 | secret: 'cards-go-secret-key',
27 | resave: false,
28 | saveUninitialized: true,
29 | cookie: { maxAge: 3600000 } // 1小时过期
30 | }));
31 |
32 | // API路由
33 | app.use('/api', apiRoutes);
34 |
35 | // 前端路由 - 返回主页
36 | app.get('/', (req, res) => {
37 | res.sendFile(path.join(__dirname, 'public', 'index.html'));
38 | });
39 |
40 | // 卡片展示页面路由已备份并删除
41 |
42 | // 加载页面路由
43 | app.get('/loading', (req, res) => {
44 | // 直接返回一个简单的加载页面,实际内容会由前端 JavaScript 处理
45 | res.send(`
46 |
47 |
48 |
49 |
50 |
51 |
正在加载...
52 |
53 |
54 |
55 |
58 |
59 |
60 | `);
61 | });
62 |
63 | // 启动服务器
64 | app.listen(PORT, () => {
65 | console.log(`Server running on http://localhost:${PORT}`);
66 | });
67 |
--------------------------------------------------------------------------------
/services/aiService.js:
--------------------------------------------------------------------------------
1 | // AIu670du52a1u5c01u88c5u6a21u5757
2 | import dotenv from 'dotenv';
3 | import fetch from 'node-fetch';
4 | import https from 'https';
5 | import { promisify } from 'util';
6 | import axios from 'axios';
7 |
8 | // u52a0u8f7du73afu5883u53d8u91cf
9 | dotenv.config();
10 |
11 | // u68c0u67e5APIu5bc6u94a5
12 | if (!process.env.ARK_API_KEY) {
13 | console.error('Error: ARK_API_KEY is not set in the .env file');
14 | process.exit(1);
15 | }
16 |
17 | // 定义可用的AI服务提供商
18 | export const AI_PROVIDERS = {
19 | ARK: 'ark',
20 | TUZI: 'tuzi'
21 | };
22 |
23 | // 定义模型列表
24 | export const AVAILABLE_MODELS = {
25 | [AI_PROVIDERS.ARK]: [
26 | { id: 'ep-20250330093147-r2gkz', name: 'ARK 默认模型' }
27 | ],
28 | [AI_PROVIDERS.TUZI]: [
29 | { id: 'claude-3-7-sonnet-20250219-o', name: 'Claude 3.7 Sonnet' },
30 | { id: 'claude-3-7-sonnet-thinking', name: 'Claude 3.7 Sonnet Thinking' },
31 | { id: 'claude-3-7-sonnet-20250219-fast', name: 'Claude 3.7 Sonnet Fast' },
32 | { id: 'deepseek-v3-0324', name: 'DeepSeek V3' },
33 | { id: 'gpt-4o-all', name: 'GPT-4 All' }
34 | ]
35 | };
36 |
37 | // 默认AI提供商和模型
38 | export const DEFAULT_PROVIDER = AI_PROVIDERS.ARK;
39 | export const DEFAULT_MODEL = 'ep-20250330093147-r2gkz';
40 | console.log('默认AI提供商已设置为:', DEFAULT_PROVIDER, '默认模型:', DEFAULT_MODEL);
41 |
42 | /**
43 | * u8c03u7528ARK APIu7684u901au7528u51fdu6570
44 | * @param {string} prompt - u7528u6237u8f93u5165u7684u63d0u793au8bcd
45 | * @param {string} systemPrompt - u7cfbu7edfu63d0u793au8bcduff0cu5b9au4e49AIu7684u884cu4e3a
46 | * @param {string} model - u6a21u578bu540du79f0uff0cu9ed8u8ba4u4f7fu7528u73afu5883u53d8u91cfu4e2du7684u6a21u578bID
47 | * @param {object} options - u5176u4ed6u9009u9879uff0cu5982u6e29u5ea6u3001u6700u5927tokensu7b49
48 | * @returns {Promise