perf: 去除冗余代码
This commit is contained in:
@@ -1,3 +1,24 @@
|
||||
export const ERROR_CODE: { [key: number]: string } = {
|
||||
400: '请求失败',
|
||||
401: '无权访问',
|
||||
403: '紧张访问',
|
||||
404: '请求不存在',
|
||||
405: '请求方法错误',
|
||||
406: '请求的格式错误',
|
||||
410: '资源已删除',
|
||||
422: '验证错误',
|
||||
500: '服务器发生错误',
|
||||
502: '网关错误',
|
||||
503: '服务器暂时过载或维护',
|
||||
504: '网关超时'
|
||||
};
|
||||
|
||||
export const TOKEN_ERROR_CODE: { [key: number]: string } = {
|
||||
506: '请先登录',
|
||||
507: '请重新登录',
|
||||
508: '登录已过期'
|
||||
};
|
||||
|
||||
export const openaiError: Record<string, string> = {
|
||||
context_length_exceeded: '内容超长了,请重置对话',
|
||||
Unauthorized: 'API-KEY 不合法',
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
import { DataItem } from '@/service/mongo';
|
||||
import { getOpenAIApi } from '@/service/utils/auth';
|
||||
import { axiosConfig } from '@/service/utils/tools';
|
||||
import { getOpenApiKey } from '../utils/openai';
|
||||
import type { ChatCompletionRequestMessage } from 'openai';
|
||||
import { DataItemSchema } from '@/types/mongoSchema';
|
||||
import { ChatModelEnum } from '@/constants/model';
|
||||
import { pushSplitDataBill } from '@/service/events/pushBill';
|
||||
|
||||
export async function generateAbstract(next = false): Promise<any> {
|
||||
if (process.env.queueTask !== '1') {
|
||||
fetch(process.env.parentUrl || '');
|
||||
return;
|
||||
}
|
||||
if (global.generatingAbstract && !next) return;
|
||||
|
||||
global.generatingAbstract = true;
|
||||
|
||||
const systemPrompt: ChatCompletionRequestMessage = {
|
||||
role: 'system',
|
||||
content: `总结助手,我会向你发送一段长文本,请从文本中归纳总结5至15条信息,如果是英文,请增加一条中文的总结,并按以下格式输出: A1:\nA2:\nA3:\n`
|
||||
};
|
||||
let dataItem: DataItemSchema | null = null;
|
||||
|
||||
try {
|
||||
// 找出一个需要生成的 dataItem
|
||||
dataItem = await DataItem.findOne({
|
||||
status: { $ne: 0 },
|
||||
times: { $gt: 0 },
|
||||
type: 'abstract'
|
||||
});
|
||||
|
||||
if (!dataItem) {
|
||||
console.log('没有需要生成 【摘要】 的数据');
|
||||
global.generatingAbstract = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新状态为生成中
|
||||
await DataItem.findByIdAndUpdate(dataItem._id, {
|
||||
status: 2
|
||||
});
|
||||
|
||||
// 获取 openapi Key
|
||||
let userApiKey, systemKey;
|
||||
try {
|
||||
const key = await getOpenApiKey(dataItem.userId);
|
||||
userApiKey = key.userApiKey;
|
||||
systemKey = key.systemKey;
|
||||
} catch (error: any) {
|
||||
if (error?.code === 501) {
|
||||
// 余额不够了, 把用户所有记录改成闲置
|
||||
await DataItem.updateMany({
|
||||
userId: dataItem.userId,
|
||||
status: 0
|
||||
});
|
||||
}
|
||||
|
||||
throw new Error('获取 openai key 失败');
|
||||
}
|
||||
|
||||
console.log('正在生成一组摘要, ID:', dataItem._id);
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
// 获取 openai 请求实例
|
||||
const chatAPI = getOpenAIApi(userApiKey || systemKey);
|
||||
// 请求 chatgpt 获取摘要
|
||||
const abstractResponse = await chatAPI.createChatCompletion(
|
||||
{
|
||||
model: ChatModelEnum.GPT35,
|
||||
temperature: 0.8,
|
||||
n: 1,
|
||||
messages: [
|
||||
systemPrompt,
|
||||
{
|
||||
role: 'user',
|
||||
content: dataItem?.text || ''
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
timeout: 180000,
|
||||
...axiosConfig
|
||||
}
|
||||
);
|
||||
|
||||
// 提取摘要内容
|
||||
const rawContent: string = abstractResponse?.data.choices[0].message?.content || '';
|
||||
// 从 content 中提取摘要内容
|
||||
const splitContents = splitText(rawContent);
|
||||
|
||||
// 插入数据库,并修改状态
|
||||
await DataItem.findByIdAndUpdate(dataItem._id, {
|
||||
status: 0,
|
||||
$push: {
|
||||
rawResponse: rawContent,
|
||||
result: {
|
||||
$each: splitContents
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log(
|
||||
`生成摘要成功,time: ${(Date.now() - startTime) / 1000}s`,
|
||||
`摘要匹配数量: ${splitContents.length}`
|
||||
);
|
||||
// 计费
|
||||
pushSplitDataBill({
|
||||
isPay: !userApiKey && splitContents.length > 0,
|
||||
userId: dataItem.userId,
|
||||
type: 'abstract',
|
||||
text: systemPrompt.content + dataItem.text + rawContent,
|
||||
tokenLen: 0
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.log('error: 生成摘要错误', dataItem?._id);
|
||||
console.log('response:', error);
|
||||
if (dataItem?._id) {
|
||||
await DataItem.findByIdAndUpdate(dataItem._id, {
|
||||
status: dataItem.times > 1 ? 1 : 0, // 还有重试次数则可以继续进行
|
||||
$inc: {
|
||||
// 剩余尝试次数-1
|
||||
times: -1
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
generateAbstract(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查文本是否按格式返回
|
||||
*/
|
||||
function splitText(text: string) {
|
||||
const regex = /A\d+:(\s*)(.*?)\s*(?=A\d+:|$)/gs;
|
||||
const matches = text.matchAll(regex); // 获取所有匹配到的结果
|
||||
|
||||
const result = []; // 存储最终的结果
|
||||
for (const match of matches) {
|
||||
if (match[2]) {
|
||||
result.push({
|
||||
abstract: match[2] as string
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (result.length === 0) {
|
||||
result.push({
|
||||
abstract: text
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
embeddingModel
|
||||
} from '@/constants/model';
|
||||
import { BillTypeEnum } from '@/constants/user';
|
||||
import type { DataType } from '@/types/data';
|
||||
import { countChatTokens } from '@/utils/tools';
|
||||
|
||||
export const pushChatBill = async ({
|
||||
@@ -81,7 +80,7 @@ export const pushSplitDataBill = async ({
|
||||
userId: string;
|
||||
tokenLen: number;
|
||||
text: string;
|
||||
type: DataType;
|
||||
type: `${BillTypeEnum}`;
|
||||
}) => {
|
||||
await connectToDatabase();
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
import { Schema, model, models, Model } from 'mongoose';
|
||||
import { DataSchema as Datatype } from '@/types/mongoSchema';
|
||||
import { DataTypeTextMap } from '@/constants/data';
|
||||
|
||||
const DataSchema = new Schema({
|
||||
userId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'user',
|
||||
required: true
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
createTime: {
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
enum: Object.keys(DataTypeTextMap)
|
||||
},
|
||||
isDeleted: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
export const Data: Model<Datatype> = models['data'] || model('data', DataSchema);
|
||||
@@ -1,69 +0,0 @@
|
||||
import type { DataItemSchema as DataItemType } from '@/types/mongoSchema';
|
||||
import { Schema, model, models, Model } from 'mongoose';
|
||||
import { DataTypeTextMap } from '@/constants/data';
|
||||
|
||||
const DataItemSchema = new Schema({
|
||||
userId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'user',
|
||||
required: true
|
||||
},
|
||||
dataId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'data',
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
enum: Object.keys(DataTypeTextMap)
|
||||
},
|
||||
times: {
|
||||
// 剩余重试次数
|
||||
type: Number,
|
||||
default: 3
|
||||
},
|
||||
text: {
|
||||
// 文本内容
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
rawResponse: {
|
||||
// 原始拆分结果
|
||||
type: [String],
|
||||
default: []
|
||||
},
|
||||
result: {
|
||||
type: [
|
||||
{
|
||||
q: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
a: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
abstract: {
|
||||
// 摘要
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
abstractVector: {
|
||||
// 摘要对应的向量
|
||||
type: [Number],
|
||||
default: []
|
||||
}
|
||||
}
|
||||
],
|
||||
default: []
|
||||
},
|
||||
status: {
|
||||
// 0-闲置,1-待生成,2-生成中
|
||||
type: Number,
|
||||
default: 1
|
||||
}
|
||||
});
|
||||
|
||||
export const DataItem: Model<DataItemType> =
|
||||
models['dataItem'] || model('dataItem', DataItemSchema);
|
||||
@@ -21,11 +21,6 @@ const ModelSchema = new Schema({
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
intro: {
|
||||
// 模型介绍
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
required: true,
|
||||
@@ -35,10 +30,6 @@ const ModelSchema = new Schema({
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
},
|
||||
trainingTimes: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
temperature: {
|
||||
type: Number,
|
||||
min: 0,
|
||||
@@ -53,11 +44,6 @@ const ModelSchema = new Schema({
|
||||
}
|
||||
},
|
||||
service: {
|
||||
trainId: {
|
||||
// 训练时需要的 ID, 不能训练的模型没有这个值。
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
chatModel: {
|
||||
// 聊天时使用的模型
|
||||
type: String,
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import { Schema, model, models, Model } from 'mongoose';
|
||||
import { TrainingSchema as TrainingType } from '@/types/mongoSchema';
|
||||
const TrainingSChema = new Schema({
|
||||
serviceName: {
|
||||
// 模型厂商名
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
tuneId: {
|
||||
// 微调进程 ID
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
modelId: {
|
||||
// 关联模型的 ID
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'model',
|
||||
required: true
|
||||
},
|
||||
status: {
|
||||
// 状态值
|
||||
type: String,
|
||||
required: true,
|
||||
enum: ['pending', 'succeed', 'errored', 'canceled']
|
||||
}
|
||||
});
|
||||
|
||||
export const Training: Model<TrainingType> =
|
||||
models['training'] || model('training', TrainingSChema);
|
||||
@@ -45,11 +45,8 @@ export * from './models/authCode';
|
||||
export * from './models/chat';
|
||||
export * from './models/model';
|
||||
export * from './models/user';
|
||||
export * from './models/training';
|
||||
export * from './models/bill';
|
||||
export * from './models/pay';
|
||||
export * from './models/data';
|
||||
export * from './models/dataItem';
|
||||
export * from './models/splitData';
|
||||
export * from './models/openapi';
|
||||
export * from './models/promotionRecord';
|
||||
|
||||
@@ -87,11 +87,9 @@ export const authOpenApiKey = async (req: NextApiRequest) => {
|
||||
/* openai axios config */
|
||||
export const axiosConfig = {
|
||||
httpsAgent: global.httpsAgent,
|
||||
headers: process.env.OPENAI_BASE_URL_AUTH
|
||||
? {
|
||||
auth: process.env.OPENAI_BASE_URL_AUTH
|
||||
}
|
||||
: {}
|
||||
headers: {
|
||||
auth: process.env.OPENAI_BASE_URL_AUTH || ''
|
||||
}
|
||||
};
|
||||
|
||||
/* delete invalid symbol */
|
||||
|
||||
Reference in New Issue
Block a user