'use strict'; const superagent = require('superagent'); const { Readable } = require('stream'); const { getFastGptToken } = require('../utils/fastgptToken'); /** * 修改过标题、标签等信息的图片,定时同步到fastgpt知识库(创建新文件、删除原文件) */ module.exports = { conf: { interval: '0 */30 * * * *', // 每30分钟执行一次 /** * * * * * * * ┬ ┬ ┬ ┬ ┬ ┬ │ │ │ │ │ │ │ │ │ │ │ └ day of week (0 - 7) (0 or 7 is Sun) │ │ │ │ └───── month (1 - 12) │ │ │ └────────── day of month (1 - 31) │ │ └─────────────── hour (0 - 23) │ └──────────────────── minute (0 - 59) └───────────────────────── second (0 - 59, OPTIONAL) */ immediate: true, // 启动时是否立即执行一次 env: ['dev', 'prod'], disabled: false, // 是否禁用该定时任务 }, callback: async function (app, conf) { // if (process.env.NODE_ENV !== 'production') return; // 仅在生产环境执行 try { const { models } = app.fs.dc; const { apiUrl, imageDatasetId } = conf.fastGpt; const fastgptToken = await getFastGptToken(conf); // 查询需要同步的图片 const images = await models.TenderImages.findAll({ where: { status: ['waitSync', 'trainingFailure'] }, include: [ { model: models.TenderImageTagRelation, include: [ { model: models.TenderImageTags, attributes: ['id', 'tagName'] } ] } ], }); for (const image of images) { console.log('[sync-imgs-collection] 正在同步图片:', image.id); // 构建txt文件内容 const tagsTxt = image.tenderImageTagRelations.map((r) => r.tenderImageTag.tagName).join(', '); const txtContent = `图片URL:${image.imageUrl}\n图片标题:${image.title}\n图片描述:${image.description}\n图片标签:${tagsTxt}`; // 调用 FastGPT 上传文件接口(带重试逻辑) // const fileName = encodeURIComponent(`${image.id}-${image.title}.txt`); //修改部分 const fileName = `${image.id}-${image.title}`; // 确认参数开始训练 const qaPrompt = ` 标记中是一段文本,学习和分析它,并整理学习成果: - 提出问题并给出每个问题的答案。 - 答案需详细完整,尽可能保留原文描述 - 答案可以包含普通文字、链接、代码、表格、公示、媒体链接等 Markdown 元素。 - 生成的问题和答案和源文本语言相同。 - 如果实在找不到问题的答案则留空,不要胡乱填写 - 问题1:图片URL是什么? - 问题2:请从文本中"图片标题:"后面提取图片标题是什么? - 问题3:图片描述是什么?`; const trainRes = await superagent //修改部分,修改训练传参为qa问答 // .post(`${apiUrl}/api/core/dataset/collection/create/fileId`) //修改部分 .post(`${apiUrl}/api/core/dataset/collection/create/text`) .set("Content-Type", "application/json") .set("Accept", "application/json, text/plain, */*") .set("Cookie", `fastgpt_token=${fastgptToken}`) //修改部分 .send({ datasetId: imageDatasetId, text: txtContent, name: fileName, trainingType: "qa", chunkSettingMode: "auto", qaPrompt, }); const newDatasetCollectionId = trainRes.body.data.collectionId; // 删除原文件(忽略不存在的情况) // 删除原文件(忽略不存在的情况) if (image.datasetCollectionId) { try { await superagent .delete(`${apiUrl}/api/core/dataset/collection/delete?id=${image.datasetCollectionId}`) .set("Cookie", `fastgpt_token=${fastgptToken}`) } catch (e) { console.log(`[sync-imgs-collection] 删除旧collection失败(可忽略): ${e?.response?.body?.message || e.message}`); } } // 更新图片表 await models.TenderImages.update( { datasetCollectionId: newDatasetCollectionId, status: 'trainingSuccess' }, { where: { id: image.id } } ); } console.log('[sync-imgs-collection] schedule success, images.length:', images.length, Date.now(),); } catch (error) { console.error('[sync-imgs-collection] schedule error:', error); } }, };