perf: 去除冗余代码

This commit is contained in:
archer
2023-04-26 21:59:22 +08:00
parent 0540c2e46a
commit 46eb96c72e
34 changed files with 36 additions and 851 deletions

View File

@@ -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 不合法',

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);

View File

@@ -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,

View File

@@ -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);

View File

@@ -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';

View File

@@ -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 */