From 7a6d0ea65042c1aa35524d5d7ff9b32f8e54a5ff Mon Sep 17 00:00:00 2001 From: archer <545436317@qq.com> Date: Tue, 28 Mar 2023 00:07:32 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E5=87=8F=E5=B0=91=E8=81=8A=E5=A4=A9?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E9=85=8D=E7=BD=AE=EF=BC=8C=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=88=AA=E6=96=AD=E4=B8=8A=E4=B8=8B=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/response/chat.d.ts | 2 - src/components/Layout/auth.tsx | 3 +- src/constants/common.ts | 3 + src/constants/model.ts | 20 +- src/pages/api/chat/chatGpt.ts | 28 +-- src/pages/api/chat/generate.ts | 2 +- src/pages/api/chat/init.ts | 25 +-- src/pages/chat/components/SlideBar.tsx | 4 +- src/pages/chat/index.tsx | 184 +++++++----------- src/pages/data/components/ImportDataModal.tsx | 2 +- src/pages/model/components/ModelEditForm.tsx | 4 +- src/service/response.ts | 1 - src/service/utils/chat.ts | 10 +- src/service/utils/tools.ts | 28 +++ 14 files changed, 144 insertions(+), 172 deletions(-) diff --git a/src/api/response/chat.d.ts b/src/api/response/chat.d.ts index 3b41658c0..21b5725bd 100644 --- a/src/api/response/chat.d.ts +++ b/src/api/response/chat.d.ts @@ -7,9 +7,7 @@ export type InitChatResponse = { name: string; avatar: string; intro: string; - secret: ModelSchema.secret; chatModel: ModelSchema.service.chatModel; // 对话模型名 modelName: ModelSchema.service.modelName; // 底层模型 history: ChatItemType[]; - isExpiredTime: boolean; }; diff --git a/src/components/Layout/auth.tsx b/src/components/Layout/auth.tsx index 950a58fde..79f451848 100644 --- a/src/components/Layout/auth.tsx +++ b/src/components/Layout/auth.tsx @@ -7,8 +7,7 @@ import { useQuery } from '@tanstack/react-query'; const unAuthPage: { [key: string]: boolean } = { '/': true, - '/login': true, - '/chat': true + '/login': true }; const Auth = ({ children }: { children: JSX.Element }) => { diff --git a/src/constants/common.ts b/src/constants/common.ts index 5a4e5d0eb..c6bcb8207 100644 --- a/src/constants/common.ts +++ b/src/constants/common.ts @@ -44,6 +44,9 @@ export const introPage = ` `; export const chatProblem = ` +**内容长度** +单次最长 4000 tokens, 上下文最长 8000 tokens, 上下文超长时会被截断。 + **模型问题** 一般情况下,请直接选择 chatGPT 模型,价格低效果好。 diff --git a/src/constants/model.ts b/src/constants/model.ts index 157fba163..f7a2c8ca3 100644 --- a/src/constants/model.ts +++ b/src/constants/model.ts @@ -27,17 +27,17 @@ export const modelList: ModelConstantsData[] = [ trainedMaxToken: 2000, maxTemperature: 2, price: 3 - }, - { - serviceCompany: 'openai', - name: 'GPT3', - model: ChatModelNameEnum.GPT3, - trainName: 'davinci', - maxToken: 4000, - trainedMaxToken: 2000, - maxTemperature: 2, - price: 30 } + // { + // serviceCompany: 'openai', + // name: 'GPT3', + // model: ChatModelNameEnum.GPT3, + // trainName: 'davinci', + // maxToken: 4000, + // trainedMaxToken: 2000, + // maxTemperature: 2, + // price: 30 + // } ]; export enum TrainingStatusEnum { diff --git a/src/pages/api/chat/chatGpt.ts b/src/pages/api/chat/chatGpt.ts index 4063ee220..871bc4736 100644 --- a/src/pages/api/chat/chatGpt.ts +++ b/src/pages/api/chat/chatGpt.ts @@ -10,6 +10,7 @@ import type { ModelSchema } from '@/types/mongoSchema'; import { PassThrough } from 'stream'; import { modelList } from '@/constants/model'; import { pushChatBill } from '@/service/events/pushBill'; +import { openaiChatFilter } from '@/service/utils/tools'; /* 发送提示词 */ export default async function handler(req: NextApiRequest, res: NextApiResponse) { @@ -32,6 +33,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) prompt: ChatItemType; chatId: string; }; + const { authorization } = req.headers; if (!chatId || !prompt) { throw new Error('缺少参数'); @@ -46,12 +48,18 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) // 读取对话内容 const prompts = [...chat.content, prompt]; - // 上下文长度过滤 - const maxContext = model.security.contextMaxLen; - const filterPrompts = - prompts.length > maxContext ? prompts.slice(prompts.length - maxContext) : prompts; + // 如果有系统提示词,自动插入 + if (model.systemPrompt) { + prompts.unshift({ + obj: 'SYSTEM', + value: model.systemPrompt + }); + } - // 格式化文本内容 + // 控制在 tokens 数量,防止超出 + const filterPrompts = openaiChatFilter(prompts, 7500); + + // 格式化文本内容成 chatgpt 格式 const map = { Human: ChatCompletionRequestMessageRoleEnum.User, AI: ChatCompletionRequestMessageRoleEnum.Assistant, @@ -63,15 +71,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) content: item.value }) ); - - // 如果有系统提示词,自动插入 - if (model.systemPrompt) { - formatPrompts.unshift({ - role: 'system', - content: model.systemPrompt - }); - } - + // console.log(formatPrompts); // 计算温度 const modelConstantsData = modelList.find((item) => item.model === model.service.modelName); if (!modelConstantsData) { diff --git a/src/pages/api/chat/generate.ts b/src/pages/api/chat/generate.ts index ca383d514..5c3e93239 100644 --- a/src/pages/api/chat/generate.ts +++ b/src/pages/api/chat/generate.ts @@ -14,7 +14,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< const { authorization } = req.headers; if (!authorization) { - throw new Error('无权操作'); + throw new Error('无权生成对话'); } if (!modelId) { diff --git a/src/pages/api/chat/init.ts b/src/pages/api/chat/init.ts index cdacccd83..5b67ea5b9 100644 --- a/src/pages/api/chat/init.ts +++ b/src/pages/api/chat/init.ts @@ -3,10 +3,14 @@ import { jsonRes } from '@/service/response'; import { connectToDatabase, Chat } from '@/service/mongo'; import type { ChatPopulate } from '@/types/mongoSchema'; import type { InitChatResponse } from '@/api/response/chat'; +import { authToken } from '@/service/utils/tools'; -/* 获取我的模型 */ +/* 初始化我的聊天框,需要身份验证 */ export default async function handler(req: NextApiRequest, res: NextApiResponse) { try { + const { authorization } = req.headers; + const userId = await authToken(authorization); + const { chatId } = req.query as { chatId: string }; if (!chatId) { @@ -16,7 +20,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) await connectToDatabase(); // 获取 chat 数据 - const chat = await Chat.findById(chatId).populate({ + const chat = await Chat.findOne({ + _id: chatId, + userId + }).populate({ path: 'modelId', options: { strictPopulate: false @@ -27,31 +34,17 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) throw new Error('聊天框不存在'); } - if (chat.loadAmount > 0) { - await Chat.updateOne( - { - _id: chat._id - }, - { - $inc: { loadAmount: -1 } - } - ); - } - // filter 掉被 deleted 的内容 chat.content = chat.content.filter((item) => item.deleted !== true); const model = chat.modelId; jsonRes(res, { - code: 201, data: { chatId: chat._id, - isExpiredTime: chat.loadAmount === 0 || chat.expiredTime <= Date.now(), modelId: model._id, name: model.name, avatar: model.avatar, intro: model.intro, - secret: model.security, modelName: model.service.modelName, chatModel: model.service.chatModel, history: chat.content diff --git a/src/pages/chat/components/SlideBar.tsx b/src/pages/chat/components/SlideBar.tsx index 154b6ae85..04cb4f4df 100644 --- a/src/pages/chat/components/SlideBar.tsx +++ b/src/pages/chat/components/SlideBar.tsx @@ -231,12 +231,12 @@ const SlideBar = ({ - + {/* <> 分享 - + */} router.push('/number/setting')}> <> diff --git a/src/pages/chat/index.tsx b/src/pages/chat/index.tsx index 1037e14aa..7a71b83cf 100644 --- a/src/pages/chat/index.tsx +++ b/src/pages/chat/index.tsx @@ -14,7 +14,6 @@ import { Textarea, Box, Flex, - Button, useDisclosure, Drawer, DrawerOverlay, @@ -36,8 +35,8 @@ import { useCopyData } from '@/utils/tools'; import { streamFetch } from '@/api/fetch'; import SlideBar from './components/SlideBar'; import Empty from './components/Empty'; -import { getToken } from '@/utils/user'; import Icon from '@/components/Icon'; +import { encode } from 'gpt-token-utils'; const Markdown = dynamic(() => import('@/components/Markdown')); @@ -60,11 +59,9 @@ const Chat = ({ chatId }: { chatId: string }) => { name: '', avatar: '', intro: '', - secret: {}, chatModel: '', modelName: '', - history: [], - isExpiredTime: false + history: [] }); // 聊天框整体数据 const [inputVal, setInputVal] = useState(''); // 输入的内容 @@ -72,15 +69,6 @@ const Chat = ({ chatId }: { chatId: string }) => { () => chatData.history[chatData.history.length - 1]?.status === 'loading', [chatData.history] ); - const chatWindowError = useMemo(() => { - if (chatData.isExpiredTime) { - return { - text: '聊天框已过期' - }; - } - - return ''; - }, [chatData]); const { copyData } = useCopyData(); const { isPc, media } = useScreen(); const { setLoading } = useGlobalStore(); @@ -125,31 +113,6 @@ const Chat = ({ chatId }: { chatId: string }) => { onCloseSlider(); }, [chatData, onCloseSlider, router, toast]); - // gpt3 方法 - const gpt3ChatPrompt = useCallback( - async (newChatList: ChatSiteItemType[]) => { - // 请求内容 - const response = await postGPT3SendPrompt({ - prompt: newChatList, - chatId: chatId as string - }); - - // 更新 AI 的内容 - setChatData((state) => ({ - ...state, - history: state.history.map((item, index) => { - if (index !== state.history.length - 1) return item; - return { - ...item, - status: 'finish', - value: response - }; - }) - })); - }, - [chatId] - ); - // gpt 对话 const gptChatPrompt = useCallback( async (prompts: ChatSiteItemType) => { @@ -476,83 +439,74 @@ const Chat = ({ chatId }: { chatId: string }) => { {/* 发送区 */} - {!!chatWindowError ? ( - - {chatWindowError.text} - - {getToken() && } - + + {/* 输入框 */} +