mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-27 08:25:07 +00:00
perf: keys
This commit is contained in:
@@ -26,7 +26,8 @@ MONGODB_NAME=fastgpt
|
|||||||
ADMIN_USER=username
|
ADMIN_USER=username
|
||||||
ADMIN_PASS=password
|
ADMIN_PASS=password
|
||||||
ADMIN_SECRET=any
|
ADMIN_SECRET=any
|
||||||
VITE_PUBLIC_SERVER_URL=http://localhost:3001 # 和server.js一致
|
PARENT_URL=http://localhost:3000
|
||||||
|
PARENT_ROOT_KEY=rootkey
|
||||||
```
|
```
|
||||||
|
|
||||||
## sealos 部署
|
## sealos 部署
|
||||||
|
@@ -86,18 +86,6 @@ const modelSchema = new mongoose.Schema({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const SystemSchema = new mongoose.Schema({
|
const SystemSchema = new mongoose.Schema({
|
||||||
openAIKeys: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
openAITrainingKeys: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
gpt4Key: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
vectorMaxProcess: {
|
vectorMaxProcess: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 10
|
default: 10
|
||||||
|
@@ -45,9 +45,6 @@ export const ModelFields = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export const SystemFields = [
|
export const SystemFields = [
|
||||||
createTextField('openAIKeys', { label: 'openAIKeys,逗号隔开' }),
|
|
||||||
createTextField('openAITrainingKeys', { label: 'openAITrainingKeys' }),
|
|
||||||
createTextField('gpt4Key', { label: 'gpt4Key' }),
|
|
||||||
createTextField('vectorMaxProcess', { label: '向量最大进程' }),
|
createTextField('vectorMaxProcess', { label: '向量最大进程' }),
|
||||||
createTextField('qaMaxProcess', { label: 'qa最大进程' }),
|
createTextField('qaMaxProcess', { label: 'qa最大进程' }),
|
||||||
createTextField('pgIvfflatProbe', { label: 'pg 探针数量' }),
|
createTextField('pgIvfflatProbe', { label: 'pg 探针数量' }),
|
||||||
|
@@ -21,8 +21,6 @@ ROOT_KEY=fdafasd
|
|||||||
# OPENAI_BASE_URL=http://ai.openai.com/v1
|
# OPENAI_BASE_URL=http://ai.openai.com/v1
|
||||||
# OPENAI_BASE_URL_AUTH=可选安全凭证,会放到 header.auth 里
|
# OPENAI_BASE_URL_AUTH=可选安全凭证,会放到 header.auth 里
|
||||||
OPENAIKEY=sk-xxx
|
OPENAIKEY=sk-xxx
|
||||||
OPENAI_TRAINING_KEY=sk-xxx
|
|
||||||
GPT4KEY=sk-xxx
|
|
||||||
# db
|
# db
|
||||||
MONGODB_URI=mongodb://username:password@0.0.0.0:27017/?authSource=admin
|
MONGODB_URI=mongodb://username:password@0.0.0.0:27017/?authSource=admin
|
||||||
MONGODB_NAME=fastgpt
|
MONGODB_NAME=fastgpt
|
||||||
|
@@ -96,8 +96,7 @@ export async function appKbSearch({
|
|||||||
// get vector
|
// get vector
|
||||||
const promptVector = await openaiEmbedding({
|
const promptVector = await openaiEmbedding({
|
||||||
userId,
|
userId,
|
||||||
input: [prompt.value],
|
input: [prompt.value]
|
||||||
type: 'chat'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// search kb
|
// search kb
|
||||||
|
@@ -29,8 +29,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
|
|||||||
|
|
||||||
const vector = await openaiEmbedding({
|
const vector = await openaiEmbedding({
|
||||||
userId,
|
userId,
|
||||||
input: [text],
|
input: [text]
|
||||||
type: 'training'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const response: any = await PgClient.query(
|
const response: any = await PgClient.query(
|
||||||
|
@@ -21,8 +21,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
|
|||||||
if (q) {
|
if (q) {
|
||||||
return openaiEmbedding({
|
return openaiEmbedding({
|
||||||
userId,
|
userId,
|
||||||
input: [q],
|
input: [q]
|
||||||
type: 'chat'
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
|
@@ -6,26 +6,24 @@ import { getOpenAIApi } from '@/service/utils/chat/openai';
|
|||||||
import { embeddingModel } from '@/constants/model';
|
import { embeddingModel } from '@/constants/model';
|
||||||
import { axiosConfig } from '@/service/utils/tools';
|
import { axiosConfig } from '@/service/utils/tools';
|
||||||
import { pushGenerateVectorBill } from '@/service/events/pushBill';
|
import { pushGenerateVectorBill } from '@/service/events/pushBill';
|
||||||
import { ApiKeyType } from '@/service/utils/auth';
|
|
||||||
import { OpenAiChatEnum } from '@/constants/model';
|
import { OpenAiChatEnum } from '@/constants/model';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
input: string[];
|
input: string[];
|
||||||
type?: ApiKeyType;
|
|
||||||
};
|
};
|
||||||
type Response = number[][];
|
type Response = number[][];
|
||||||
|
|
||||||
export default withNextCors(async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
export default withNextCors(async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||||
try {
|
try {
|
||||||
const { userId } = await authUser({ req });
|
const { userId } = await authUser({ req });
|
||||||
let { input, type } = req.query as Props;
|
let { input } = req.query as Props;
|
||||||
|
|
||||||
if (!Array.isArray(input)) {
|
if (!Array.isArray(input)) {
|
||||||
throw new Error('缺少参数');
|
throw new Error('缺少参数');
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonRes<Response>(res, {
|
jsonRes<Response>(res, {
|
||||||
data: await openaiEmbedding({ userId, input, type, mustPay: true })
|
data: await openaiEmbedding({ userId, input, mustPay: true })
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@@ -39,14 +37,12 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
|
|||||||
export async function openaiEmbedding({
|
export async function openaiEmbedding({
|
||||||
userId,
|
userId,
|
||||||
input,
|
input,
|
||||||
mustPay = false,
|
mustPay = false
|
||||||
type = 'chat'
|
|
||||||
}: { userId: string; mustPay?: boolean } & Props) {
|
}: { userId: string; mustPay?: boolean } & Props) {
|
||||||
const { userOpenAiKey, systemAuthKey } = await getApiKey({
|
const { userOpenAiKey, systemAuthKey } = await getApiKey({
|
||||||
model: OpenAiChatEnum.GPT35,
|
model: OpenAiChatEnum.GPT35,
|
||||||
userId,
|
userId,
|
||||||
mustPay,
|
mustPay
|
||||||
type
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 获取 chatAPI
|
// 获取 chatAPI
|
||||||
|
@@ -33,7 +33,7 @@ export async function sensitiveCheck({ input }: Props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const response = await axios({
|
const response = await axios({
|
||||||
...axiosConfig(getSystemOpenAiKey('chat')),
|
...axiosConfig(getSystemOpenAiKey()),
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `/moderations`,
|
url: `/moderations`,
|
||||||
data: {
|
data: {
|
||||||
|
@@ -7,11 +7,9 @@ import { ChatModelMap, OpenAiChatEnum } from '@/constants/model';
|
|||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
const chatModelList: ChatModelItemType[] = [];
|
const chatModelList: ChatModelItemType[] = [];
|
||||||
|
|
||||||
if (global.systemEnv.openAIKeys) {
|
if (process.env.OPENAIKEY) {
|
||||||
chatModelList.push(ChatModelMap[OpenAiChatEnum.GPT3516k]);
|
chatModelList.push(ChatModelMap[OpenAiChatEnum.GPT3516k]);
|
||||||
chatModelList.push(ChatModelMap[OpenAiChatEnum.GPT35]);
|
chatModelList.push(ChatModelMap[OpenAiChatEnum.GPT35]);
|
||||||
}
|
|
||||||
if (global.systemEnv.gpt4Key) {
|
|
||||||
chatModelList.push(ChatModelMap[OpenAiChatEnum.GPT4]);
|
chatModelList.push(ChatModelMap[OpenAiChatEnum.GPT4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -256,7 +256,7 @@ const SelectFileModal = ({
|
|||||||
)}
|
)}
|
||||||
{/* chunk size */}
|
{/* chunk size */}
|
||||||
{mode === TrainingModeEnum.index && (
|
{mode === TrainingModeEnum.index && (
|
||||||
<Flex w={'100%'} px={5} alignItems={'center'} mt={4}>
|
<Flex mt={5}>
|
||||||
<Box w={['70px']} flexShrink={0}>
|
<Box w={['70px']} flexShrink={0}>
|
||||||
段落长度
|
段落长度
|
||||||
</Box>
|
</Box>
|
||||||
|
@@ -55,7 +55,6 @@ export async function generateQA(): Promise<any> {
|
|||||||
const { systemAuthKey } = await getApiKey({
|
const { systemAuthKey } = await getApiKey({
|
||||||
model: OpenAiChatEnum.GPT35,
|
model: OpenAiChatEnum.GPT35,
|
||||||
userId,
|
userId,
|
||||||
type: 'training',
|
|
||||||
mustPay: true
|
mustPay: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -58,7 +58,6 @@ export async function generateVector(): Promise<any> {
|
|||||||
const vectors = await openaiEmbedding({
|
const vectors = await openaiEmbedding({
|
||||||
input: dataItems.map((item) => item.q),
|
input: dataItems.map((item) => item.q),
|
||||||
userId,
|
userId,
|
||||||
type: 'training',
|
|
||||||
mustPay: true
|
mustPay: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1,18 +1,6 @@
|
|||||||
import { Schema, model, models } from 'mongoose';
|
import { Schema, model, models } from 'mongoose';
|
||||||
|
|
||||||
const SystemSchema = new Schema({
|
const SystemSchema = new Schema({
|
||||||
openAIKeys: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
openAITrainingKeys: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
gpt4Key: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
vectorMaxProcess: {
|
vectorMaxProcess: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 10
|
default: 10
|
||||||
|
@@ -15,9 +15,6 @@ export async function connectToDatabase(): Promise<void> {
|
|||||||
global.qaQueueLen = 0;
|
global.qaQueueLen = 0;
|
||||||
global.vectorQueueLen = 0;
|
global.vectorQueueLen = 0;
|
||||||
global.systemEnv = {
|
global.systemEnv = {
|
||||||
openAIKeys: process.env.OPENAIKEY || '',
|
|
||||||
openAITrainingKeys: process.env.OPENAI_TRAINING_KEY || '',
|
|
||||||
gpt4Key: process.env.GPT4KEY || '',
|
|
||||||
vectorMaxProcess: 10,
|
vectorMaxProcess: 10,
|
||||||
qaMaxProcess: 10,
|
qaMaxProcess: 10,
|
||||||
pgIvfflatProbe: 10,
|
pgIvfflatProbe: 10,
|
||||||
|
@@ -11,7 +11,6 @@ import { ERROR_ENUM } from '../errorCode';
|
|||||||
import { ChatModelType, OpenAiChatEnum } from '@/constants/model';
|
import { ChatModelType, OpenAiChatEnum } from '@/constants/model';
|
||||||
import { hashPassword } from '@/service/utils/tools';
|
import { hashPassword } from '@/service/utils/tools';
|
||||||
|
|
||||||
export type ApiKeyType = 'training' | 'chat';
|
|
||||||
export type AuthType = 'token' | 'root' | 'apikey';
|
export type AuthType = 'token' | 'root' | 'apikey';
|
||||||
|
|
||||||
export const parseCookie = (cookie?: string): Promise<string> => {
|
export const parseCookie = (cookie?: string): Promise<string> => {
|
||||||
@@ -163,37 +162,19 @@ export const authUser = async ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* random get openai api key */
|
/* random get openai api key */
|
||||||
export const getSystemOpenAiKey = (type: ApiKeyType) => {
|
export const getSystemOpenAiKey = () => {
|
||||||
const keys = (() => {
|
return process.env.OPENAIKEY || '';
|
||||||
if (type === 'training') {
|
|
||||||
return global.systemEnv.openAITrainingKeys?.split(',') || [];
|
|
||||||
}
|
|
||||||
return global.systemEnv.openAIKeys?.split(',') || [];
|
|
||||||
})();
|
|
||||||
|
|
||||||
// 纯字符串类型
|
|
||||||
const i = Math.floor(Math.random() * keys.length);
|
|
||||||
return keys[i] || (global.systemEnv.openAIKeys as string);
|
|
||||||
};
|
|
||||||
export const getGpt4Key = () => {
|
|
||||||
const keys = global.systemEnv.gpt4Key?.split(',') || [];
|
|
||||||
|
|
||||||
// 纯字符串类型
|
|
||||||
const i = Math.floor(Math.random() * keys.length);
|
|
||||||
return keys[i] || (global.systemEnv.openAIKeys as string);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 获取 api 请求的 key */
|
/* 获取 api 请求的 key */
|
||||||
export const getApiKey = async ({
|
export const getApiKey = async ({
|
||||||
model,
|
model,
|
||||||
userId,
|
userId,
|
||||||
mustPay = false,
|
mustPay = false
|
||||||
type = 'chat'
|
|
||||||
}: {
|
}: {
|
||||||
model: ChatModelType;
|
model: ChatModelType;
|
||||||
userId: string;
|
userId: string;
|
||||||
mustPay?: boolean;
|
mustPay?: boolean;
|
||||||
type?: ApiKeyType;
|
|
||||||
}) => {
|
}) => {
|
||||||
const user = await User.findById(userId);
|
const user = await User.findById(userId);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
@@ -203,19 +184,19 @@ export const getApiKey = async ({
|
|||||||
const keyMap = {
|
const keyMap = {
|
||||||
[OpenAiChatEnum.GPT35]: {
|
[OpenAiChatEnum.GPT35]: {
|
||||||
userOpenAiKey: user.openaiKey || '',
|
userOpenAiKey: user.openaiKey || '',
|
||||||
systemAuthKey: getSystemOpenAiKey(type) as string
|
systemAuthKey: getSystemOpenAiKey()
|
||||||
},
|
},
|
||||||
[OpenAiChatEnum.GPT3516k]: {
|
[OpenAiChatEnum.GPT3516k]: {
|
||||||
userOpenAiKey: user.openaiKey || '',
|
userOpenAiKey: user.openaiKey || '',
|
||||||
systemAuthKey: getSystemOpenAiKey(type) as string
|
systemAuthKey: getSystemOpenAiKey()
|
||||||
},
|
},
|
||||||
[OpenAiChatEnum.GPT4]: {
|
[OpenAiChatEnum.GPT4]: {
|
||||||
userOpenAiKey: user.openaiKey || '',
|
userOpenAiKey: user.openaiKey || '',
|
||||||
systemAuthKey: getGpt4Key() as string
|
systemAuthKey: getSystemOpenAiKey()
|
||||||
},
|
},
|
||||||
[OpenAiChatEnum.GPT432k]: {
|
[OpenAiChatEnum.GPT432k]: {
|
||||||
userOpenAiKey: user.openaiKey || '',
|
userOpenAiKey: user.openaiKey || '',
|
||||||
systemAuthKey: getGpt4Key() as string
|
systemAuthKey: getSystemOpenAiKey()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
3
client/src/types/index.d.ts
vendored
3
client/src/types/index.d.ts
vendored
@@ -23,9 +23,6 @@ declare global {
|
|||||||
var vectorQueueLen: number;
|
var vectorQueueLen: number;
|
||||||
var OpenAiEncMap: Record<string, Tiktoken>;
|
var OpenAiEncMap: Record<string, Tiktoken>;
|
||||||
var systemEnv: {
|
var systemEnv: {
|
||||||
openAIKeys: string;
|
|
||||||
openAITrainingKeys: string;
|
|
||||||
gpt4Key: string;
|
|
||||||
vectorMaxProcess: number;
|
vectorMaxProcess: number;
|
||||||
qaMaxProcess: number;
|
qaMaxProcess: number;
|
||||||
pgIvfflatProbe: number;
|
pgIvfflatProbe: number;
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
# host 版本。
|
||||||
version: '3.3'
|
version: '3.3'
|
||||||
services:
|
services:
|
||||||
pg:
|
pg:
|
||||||
@@ -31,10 +32,9 @@ services:
|
|||||||
- /root/fastgpt/mongo/data:/data/db
|
- /root/fastgpt/mongo/data:/data/db
|
||||||
- /root/fastgpt/mongo/logs:/var/log/mongodb
|
- /root/fastgpt/mongo/logs:/var/log/mongodb
|
||||||
fastgpt:
|
fastgpt:
|
||||||
# image: ghcr.io/c121914yu/fastgpt:latest # github
|
|
||||||
# image: c121914yu/fast-gpt:latest # docker hub
|
# image: c121914yu/fast-gpt:latest # docker hub
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:latest # 阿里云
|
image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:latest # 阿里云
|
||||||
network_mode: host
|
# network_mode: host #
|
||||||
restart: always
|
restart: always
|
||||||
container_name: fastgpt
|
container_name: fastgpt
|
||||||
environment: # 可选的变量,不需要的话需要去掉
|
environment: # 可选的变量,不需要的话需要去掉
|
||||||
@@ -55,9 +55,9 @@ services:
|
|||||||
- CLIENT_GOOGLE_VER_TOKEN=xxx
|
- CLIENT_GOOGLE_VER_TOKEN=xxx
|
||||||
- SERVICE_GOOGLE_VER_TOKEN=xx
|
- SERVICE_GOOGLE_VER_TOKEN=xx
|
||||||
# token加密凭证(随便填,作为登录凭证)
|
# token加密凭证(随便填,作为登录凭证)
|
||||||
- TOKEN_KEY=xxxx
|
- TOKEN_KEY=any
|
||||||
# root key, 最高权限,可以内部接口互相调用
|
# root key, 最高权限,可以内部接口互相调用
|
||||||
- ROOT_KEY=xxx
|
- ROOT_KEY=root_key
|
||||||
# 和上方mongo镜像的username,password对应
|
# 和上方mongo镜像的username,password对应
|
||||||
- MONGODB_URI=mongodb://username:password@0.0.0.0:27017/?authSource=admin
|
- MONGODB_URI=mongodb://username:password@0.0.0.0:27017/?authSource=admin
|
||||||
- MONGODB_NAME=fastgpt
|
- MONGODB_NAME=fastgpt
|
||||||
@@ -68,14 +68,34 @@ services:
|
|||||||
- PG_PASSWORD=1234
|
- PG_PASSWORD=1234
|
||||||
- PG_DB_NAME=fastgpt
|
- PG_DB_NAME=fastgpt
|
||||||
# openai
|
# openai
|
||||||
# 对话用的key,多个key,逗号分开
|
- OPENAIKEY=sk-xxxxx
|
||||||
- OPENAIKEY=sk-xxxxx,sk-xxx
|
|
||||||
# 训练用的key
|
|
||||||
- OPENAI_TRAINING_KEY=sk-xxx,sk-xxxx
|
|
||||||
- GPT4KEY=sk-xxx
|
|
||||||
- OPENAI_BASE_URL=https://api.openai.com/v1
|
- OPENAI_BASE_URL=https://api.openai.com/v1
|
||||||
- OPENAI_BASE_URL_AUTH=可选的安全凭证
|
- OPENAI_BASE_URL_AUTH=可选的安全凭证
|
||||||
nginx:
|
fastgpt-admin:
|
||||||
|
image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-admin:latest
|
||||||
|
container_name: fastgpt-admin
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- 3001:3001
|
||||||
|
environment:
|
||||||
|
- MONGODB_URI=mongodb://username:password@0.0.0.0:27017/?authSource=admin
|
||||||
|
- MONGODB_NAME=fastgpt
|
||||||
|
- ADMIN_USER=username
|
||||||
|
- ADMIN_PASS=password
|
||||||
|
- ADMIN_SECRET=any
|
||||||
|
- PARENT_URL=http://0.0.0.0:3000
|
||||||
|
- PARENT_ROOT_KEY=root_key
|
||||||
|
key-admin:
|
||||||
|
container_name: key-admin
|
||||||
|
image: justsong/one-api
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- 3002:3000
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
volumes:
|
||||||
|
- /home/ubuntu/data/one-api:/data
|
||||||
|
nginx: # 宝塔不需要额外装 nginx
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/fastgpt/nginx:alpine3.17
|
image: registry.cn-hangzhou.aliyuncs.com/fastgpt/nginx:alpine3.17
|
||||||
# image: nginx:alpine3.17
|
# image: nginx:alpine3.17
|
||||||
container_name: nginx
|
container_name: nginx
|
||||||
|
Reference in New Issue
Block a user