diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index 016b5c445..f3d2bd193 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -35,7 +35,7 @@ const Layout = ({ children, isPcDevice }: { children: JSX.Element; isPcDevice: b return ( <> - + {isPc ? ( pcUnShowLayoutRoute[router.pathname] ? ( {children} diff --git a/src/components/Layout/navbar.tsx b/src/components/Layout/navbar.tsx index 7a86ff1c1..56c826001 100644 --- a/src/components/Layout/navbar.tsx +++ b/src/components/Layout/navbar.tsx @@ -102,9 +102,7 @@ const Navbar = () => { justifyContent={'center'} onClick={() => { if (item.link === router.asPath) return; - router.push(item.link, undefined, { - shallow: true - }); + router.push(item.link); }} cursor={'pointer'} w={'60px'} diff --git a/src/pages/api/chat/chat.ts b/src/pages/api/chat/chat.ts index 640ea0fd3..c6da26596 100644 --- a/src/pages/api/chat/chat.ts +++ b/src/pages/api/chat/chat.ts @@ -55,7 +55,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) // 使用了知识库搜索 if (model.chat.useKb) { - const { code, searchPrompt } = await searchKb({ + const { code, searchPrompts } = await searchKb({ userOpenAiKey, prompts, similarity: ModelVectorSearchModeMap[model.chat.searchMode]?.similarity, @@ -65,10 +65,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) // search result is empty if (code === 201) { - return res.send(searchPrompt?.value); + return res.send(searchPrompts[0]?.value); } - searchPrompt && prompts.unshift(searchPrompt); + prompts.splice(prompts.length - 1, 0, ...searchPrompts); } else { // 没有用知识库搜索,仅用系统提示词 model.chat.systemPrompt && @@ -103,8 +103,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) stream, chatResponse: streamResponse, prompts, - systemPrompt: - showModelDetail && prompts[0].obj === ChatRoleEnum.System ? prompts[0].value : '' + systemPrompt: showModelDetail + ? prompts + .filter((item) => item.obj === ChatRoleEnum.System) + .map((item) => item.value) + .join('\n') + : '' }); // 只有使用平台的 key 才计费 diff --git a/src/pages/api/openapi/chat/chat.ts b/src/pages/api/openapi/chat/chat.ts index bcacbb65f..14d688e55 100644 --- a/src/pages/api/openapi/chat/chat.ts +++ b/src/pages/api/openapi/chat/chat.ts @@ -73,7 +73,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) if (model.chat.useKb) { const similarity = ModelVectorSearchModeMap[model.chat.searchMode]?.similarity || 0.22; - const { code, searchPrompt } = await searchKb({ + const { code, searchPrompts } = await searchKb({ prompts, similarity, model, @@ -82,10 +82,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) // search result is empty if (code === 201) { - return res.send(searchPrompt?.value); + return res.send(searchPrompts[0]?.value); } - - searchPrompt && prompts.unshift(searchPrompt); + prompts.splice(prompts.length - 1, 0, ...searchPrompts); } else { // 没有用知识库搜索,仅用系统提示词 if (model.chat.systemPrompt) { diff --git a/src/pages/api/openapi/chat/lafGpt.ts b/src/pages/api/openapi/chat/lafGpt.ts index 15a37f82c..f11cec20d 100644 --- a/src/pages/api/openapi/chat/lafGpt.ts +++ b/src/pages/api/openapi/chat/lafGpt.ts @@ -122,14 +122,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) const prompts = [prompt]; // 获取向量匹配到的提示词 - const { searchPrompt } = await searchKb({ + const { searchPrompts } = await searchKb({ similarity: ModelVectorSearchModeMap[model.chat.searchMode]?.similarity, prompts, model, userId }); - searchPrompt && prompts.unshift(searchPrompt); + prompts.splice(prompts.length - 1, 0, ...searchPrompts); // 计算温度 const temperature = (modelConstantsData.maxTemperature * (model.chat.temperature / 10)).toFixed( diff --git a/src/pages/chat/index.tsx b/src/pages/chat/index.tsx index f6caa882a..ff4af3563 100644 --- a/src/pages/chat/index.tsx +++ b/src/pages/chat/index.tsx @@ -508,7 +508,7 @@ const Chat = ({ isLeavePage.current = true; controller.current?.abort(); }; - }, []); + }, [modelId, chatId]); return ( - + - + diff --git a/src/pages/model/components/detail/components/SelectFileModal.tsx b/src/pages/model/components/detail/components/SelectFileModal.tsx index 8bd5acce3..56c53ed17 100644 --- a/src/pages/model/components/detail/components/SelectFileModal.tsx +++ b/src/pages/model/components/detail/components/SelectFileModal.tsx @@ -61,13 +61,7 @@ const SelectFileModal = ({ const { openConfirm, ConfirmChild } = useConfirm({ content: `确认导入该文件,需要一定时间进行拆解,该任务无法终止!如果余额不足,未完成的任务会被直接清除。一共 ${ splitRes.chunks.length - } 组。${ - splitRes.tokens - ? `大约 ${splitRes.tokens} 个tokens, 约 ${formatPrice( - splitRes.tokens * modeMap[mode].price - )} 元` - : '' - }` + } 组。${splitRes.tokens ? `大约 ${splitRes.tokens} 个tokens。` : ''}` }); const onSelectFile = useCallback( diff --git a/src/pages/model/share/index.tsx b/src/pages/model/share/index.tsx index f1a6d44e2..534389b1b 100644 --- a/src/pages/model/share/index.tsx +++ b/src/pages/model/share/index.tsx @@ -101,9 +101,9 @@ const modelList = () => { - + - + diff --git a/src/pages/number/components/BillTable.tsx b/src/pages/number/components/BillTable.tsx index aa1ba74ba..cd0a2e499 100644 --- a/src/pages/number/components/BillTable.tsx +++ b/src/pages/number/components/BillTable.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Card, Box, Table, Thead, Tbody, Tr, Th, Td, TableContainer } from '@chakra-ui/react'; +import { Card, Box, Table, Thead, Tbody, Tr, Th, Td, TableContainer, Flex } from '@chakra-ui/react'; import { BillTypeMap } from '@/constants/user'; import { getUserBills } from '@/api/user'; import type { UserBillType } from '@/types/user'; @@ -48,9 +48,9 @@ const BillTable = () => { - + - + ); }; diff --git a/src/pages/promotion/index.tsx b/src/pages/promotion/index.tsx index be2c1a4ec..bba23053b 100644 --- a/src/pages/promotion/index.tsx +++ b/src/pages/promotion/index.tsx @@ -139,9 +139,9 @@ const OpenApi = () => { - + - + diff --git a/src/service/plugins/searchKb.ts b/src/service/plugins/searchKb.ts index 692281185..9f0bccf89 100644 --- a/src/service/plugins/searchKb.ts +++ b/src/service/plugins/searchKb.ts @@ -23,10 +23,10 @@ export const searchKb = async ({ similarity?: number; }): Promise<{ code: 200 | 201; - searchPrompt?: { - obj: `${ChatRoleEnum}`; + searchPrompts: { + obj: ChatRoleEnum; value: string; - }; + }[]; }> => { async function search(textArr: string[] = []) { // 获取提示词的向量 @@ -85,17 +85,38 @@ export const searchKb = async ({ }; const filterRate = filterRateMap[systemPrompts.length] || filterRateMap[0]; - // count fixed system prompt - const fixedSystemPrompt = ` -${model.chat.systemPrompt} -${ - model.chat.searchMode === ModelVectorSearchModeEnum.hightSimilarity ? '不回答知识库外的内容.' : '' -} -知识库内容为:`; + // 计算固定提示词的 token 数量 + const fixedPrompts = [ + ...(model.chat.systemPrompt + ? [ + { + obj: ChatRoleEnum.System, + value: model.chat.systemPrompt + } + ] + : []), + ...(model.chat.searchMode === ModelVectorSearchModeEnum.noContext + ? [ + { + obj: ChatRoleEnum.System, + value: `知识库是关于"${model.name}"的内容,根据知识库内容回答问题.` + } + ] + : [ + { + obj: ChatRoleEnum.System, + value: `我们来玩问答游戏,规则为: +1.你忘记你已有的知识 +2.你只能回答关于"${model.name}"的问题 +3.你只能从知识库中选择内容进行回答 +4.如果问题不在知识库中,你会回答"我不知道。" +务必遵守规则` + } + ]) + ]; const fixedSystemTokens = modelToolMap[model.chat.chatModel].countTokens({ - messages: [{ obj: 'System', value: fixedSystemPrompt }] + messages: fixedPrompts }); - const maxTokens = modelConstantsData.systemMaxToken - fixedSystemTokens; const filterSystemPrompt = filterRate @@ -111,31 +132,38 @@ ${ if (!filterSystemPrompt && model.chat.searchMode === ModelVectorSearchModeEnum.hightSimilarity) { return { code: 201, - searchPrompt: { - obj: ChatRoleEnum.AI, - value: '对不起,你的问题不在知识库中。' - } + searchPrompts: [ + { + obj: ChatRoleEnum.System, + value: '对不起,你的问题不在知识库中。' + } + ] }; } /* 高相似度+无上下文,不添加额外知识,仅用系统提示词 */ if (!filterSystemPrompt && model.chat.searchMode === ModelVectorSearchModeEnum.noContext) { return { code: 200, - searchPrompt: model.chat.systemPrompt - ? { - obj: ChatRoleEnum.System, - value: model.chat.systemPrompt - } - : undefined + searchPrompts: model.chat.systemPrompt + ? [ + { + obj: ChatRoleEnum.System, + value: model.chat.systemPrompt + } + ] + : [] }; } /* 有匹配 */ return { code: 200, - searchPrompt: { - obj: ChatRoleEnum.System, - value: `${fixedSystemPrompt}'${filterSystemPrompt}'` - } + searchPrompts: [ + { + obj: ChatRoleEnum.System, + value: `知识库:'${filterSystemPrompt}'` + }, + ...fixedPrompts + ] }; }; diff --git a/src/service/utils/chat/claude.ts b/src/service/utils/chat/claude.ts index 9aab8f313..f5735f3f2 100644 --- a/src/service/utils/chat/claude.ts +++ b/src/service/utils/chat/claude.ts @@ -27,7 +27,7 @@ export const lafClaudChat = async ({ .join('\n'); const systemPromptText = systemPrompt ? `\n知识库内容:'${systemPrompt}'\n` : ''; - const prompt = `${systemPromptText}我的问题:'${messages[messages.length - 1].value}'`; + const prompt = `${systemPromptText}\n我的问题是:'${messages[messages.length - 1].value}'`; const lafResponse = await axios.post( 'https://hnvacz.laf.run/claude-gpt',