Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
赵月辉
/
fastgpt-migrated
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
83d755ad
authored
Jun 24, 2023
by
archer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: limit prompt
parent
ec9852fc
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
110 additions
and
52 deletions
+110
-52
client/src/api/response/chat.d.ts
+1
-0
client/src/components/Select/index.tsx
+1
-1
client/src/constants/model.ts
+1
-0
client/src/pages/api/chat/init.ts
+1
-0
client/src/pages/api/openapi/kb/appKbSearch.ts
+22
-10
client/src/pages/api/openapi/v1/chat/completions.ts
+31
-16
client/src/pages/chat/index.tsx
+7
-6
client/src/pages/model/components/detail/components/Settings.tsx
+41
-18
client/src/service/models/model.ts
+4
-1
client/src/types/mongoSchema.d.ts
+1
-0
No files found.
client/src/api/response/chat.d.ts
View file @
83d755ad
...
...
@@ -5,6 +5,7 @@ export interface InitChatResponse {
chatId
:
string
;
modelId
:
string
;
systemPrompt
?:
string
;
limitPrompt
?:
string
;
model
:
{
name
:
string
;
avatar
:
string
;
...
...
client/src/components/Select/index.tsx
View file @
83d755ad
...
...
@@ -26,7 +26,7 @@ const MySelect = ({ placeholder, value, width = 'auto', list, onchange, ...props
return
(
<
Menu
autoSelect=
{
false
}
onOpen=
{
onOpen
}
onClose=
{
onClose
}
>
<
MenuButton
as=
{
'span'
}
>
<
MenuButton
style=
{
{
width
:
'100%'
}
}
as=
{
'span'
}
>
<
Button
width=
{
width
}
px=
{
3
}
...
...
client/src/constants/model.ts
View file @
83d755ad
...
...
@@ -82,6 +82,7 @@ export const defaultModel: ModelSchema = {
searchLimit
:
5
,
searchEmptyText
:
''
,
systemPrompt
:
''
,
limitPrompt
:
''
,
temperature
:
0
,
maxToken
:
4000
,
chatModel
:
OpenAiChatEnum
.
GPT35
...
...
client/src/pages/api/chat/init.ts
View file @
83d755ad
...
...
@@ -101,6 +101,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
},
chatModel
:
model
.
chat
.
chatModel
,
systemPrompt
:
isOwner
?
model
.
chat
.
systemPrompt
:
''
,
limitPrompt
:
isOwner
?
model
.
chat
.
limitPrompt
:
''
,
history
}
});
...
...
client/src/pages/api/openapi/kb/appKbSearch.ts
View file @
83d755ad
...
...
@@ -28,7 +28,11 @@ type Response = {
userSystemPrompt
:
{
obj
:
ChatRoleEnum
;
value
:
string
;
};
}[];
userLimitPrompt
:
{
obj
:
ChatRoleEnum
;
value
:
string
;
}[];
quotePrompt
:
{
obj
:
ChatRoleEnum
;
value
:
string
;
...
...
@@ -130,17 +134,24 @@ export async function appKbSearch({
// 计算固定提示词的 token 数量
const
userSystemPrompt
=
model
.
chat
.
systemPrompt
// user system prompt
?
{
obj
:
ChatRoleEnum
.
Human
,
value
:
model
.
chat
.
systemPrompt
}
:
{
obj
:
ChatRoleEnum
.
Human
,
value
:
`知识库是关于
${
model
.
name
}
的内容,参考知识库回答问题。与 "
${
model
.
name
}
" 无关内容,直接回复: "我不知道"。`
};
?
[
{
obj
:
ChatRoleEnum
.
System
,
value
:
model
.
chat
.
systemPrompt
}
]
:
[];
const
userLimitPrompt
=
[
{
obj
:
ChatRoleEnum
.
Human
,
value
:
model
.
chat
.
limitPrompt
?
model
.
chat
.
limitPrompt
:
`知识库是关于
${
model
.
name
}
的内容,参考知识库回答问题。与 "
${
model
.
name
}
" 无关内容,直接回复: "我不知道"。`
}
];
const
fixedSystemTokens
=
modelToolMap
[
model
.
chat
.
chatModel
].
countTokens
({
messages
:
[
userSystem
Prompt
]
messages
:
[
...
userSystemPrompt
,
...
userLimit
Prompt
]
});
// filter part quote by maxToken
...
...
@@ -164,6 +175,7 @@ export async function appKbSearch({
return
{
rawSearch
,
userSystemPrompt
,
userLimitPrompt
,
quotePrompt
:
{
obj
:
ChatRoleEnum
.
System
,
value
:
quoteText
...
...
client/src/pages/api/openapi/v1/chat/completions.ts
View file @
83d755ad
...
...
@@ -108,11 +108,12 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
const
{
rawSearch
=
[],
userSystemPrompt
=
[],
userLimitPrompt
=
[],
quotePrompt
=
[]
}
=
await
(
async
()
=>
{
// 使用了知识库搜索
if
(
model
.
chat
.
relatedKbs
?.
length
>
0
)
{
const
{
rawSearch
,
userSystemPrompt
,
quote
Prompt
}
=
await
appKbSearch
({
const
{
rawSearch
,
quotePrompt
,
userSystemPrompt
,
userLimit
Prompt
}
=
await
appKbSearch
({
model
,
userId
,
fixedQuote
:
history
[
history
.
length
-
1
]?.
quote
,
...
...
@@ -123,21 +124,29 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
return
{
rawSearch
,
userSystemPrompt
:
userSystemPrompt
?
[
userSystemPrompt
]
:
[],
userSystemPrompt
,
userLimitPrompt
,
quotePrompt
:
[
quotePrompt
]
};
}
if
(
model
.
chat
.
systemPrompt
)
{
return
{
userSystemPrompt
:
[
{
obj
:
ChatRoleEnum
.
System
,
value
:
model
.
chat
.
systemPrompt
}
]
};
}
return
{};
return
{
userSystemPrompt
:
model
.
chat
.
systemPrompt
?
[
{
obj
:
ChatRoleEnum
.
System
,
value
:
model
.
chat
.
systemPrompt
}
]
:
[],
userLimitPrompt
:
model
.
chat
.
limitPrompt
?
[
{
obj
:
ChatRoleEnum
.
Human
,
value
:
model
.
chat
.
limitPrompt
}
]
:
[]
};
})();
// search result is empty
...
...
@@ -167,7 +176,13 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
}
// api messages. [quote,context,systemPrompt,question]
const
completePrompts
=
[...
quotePrompt
,
...
prompts
.
slice
(
0
,
-
1
),
...
userSystemPrompt
,
prompt
];
const
completePrompts
=
[
...
quotePrompt
,
...
userSystemPrompt
,
...
prompts
.
slice
(
0
,
-
1
),
...
userLimitPrompt
,
prompt
];
// chat temperature
const
modelConstantsData
=
ChatModelMap
[
model
.
chat
.
chatModel
];
// FastGpt temperature range: 1~10
...
...
@@ -176,7 +191,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
);
await
sensitiveCheck
({
input
:
`
${
prompt
.
value
}
`
input
:
`
${
userSystemPrompt
[
0
]?.
value
}
\
n$
{
userLimitPrompt
[
0
]?.
value
}
\
n$
{
prompt
.
value
}
`
});
// start model api. responseText and totalTokens: valid only if stream = false
...
...
@@ -259,7 +274,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
...(showAppDetail
? {
quote: rawSearch,
systemPrompt
:
userSystemPrompt
?.[
0
]?.
value
systemPrompt:
`
$
{
userSystemPrompt
[
0
]?.
value
}
\
n
\
n$
{
userLimitPrompt
[
0
]?.
value
}
`
}
: {})
}
...
...
client/src/pages/chat/index.tsx
View file @
83d755ad
...
...
@@ -219,7 +219,7 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => {
...
item
,
status
:
'finish'
,
quoteLen
,
systemPrompt
:
chatData
.
systemPrompt
systemPrompt
:
`
${
chatData
.
systemPrompt
}
\n\n
${
chatData
.
limitPrompt
}
`
};
})
}));
...
...
@@ -234,13 +234,14 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => {
[
chatId
,
modelId
,
chatData
.
systemPrompt
,
setChatData
,
loadHistory
,
loadMyModels
,
generatingMessage
,
setForbidLoadChatData
,
router
router
,
chatData
.
systemPrompt
,
chatData
.
limitPrompt
,
loadHistory
,
loadMyModels
]
);
...
...
@@ -749,7 +750,7 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => {
px={[2, 4]}
onClick={() => setShowSystemPrompt(item.systemPrompt || '')}
>
提示词
提示词
& 限定词
</Button>
)}
{!!item.quoteLen && (
...
...
client/src/pages/model/components/detail/components/Settings.tsx
View file @
83d755ad
import
React
,
{
useCallback
,
useState
,
useMemo
}
from
'react'
;
import
{
Box
,
Flex
,
Button
,
FormControl
,
Input
,
Textarea
,
Divider
}
from
'@chakra-ui/react'
;
import
{
Box
,
Flex
,
Button
,
FormControl
,
Input
,
Textarea
,
Divider
,
Tooltip
}
from
'@chakra-ui/react'
;
import
{
QuestionOutlineIcon
}
from
'@chakra-ui/icons'
;
import
{
useQuery
}
from
'@tanstack/react-query'
;
import
{
useForm
}
from
'react-hook-form'
;
import
{
useRouter
}
from
'next/router'
;
...
...
@@ -20,6 +30,11 @@ import Avatar from '@/components/Avatar';
import
MySelect
from
'@/components/Select'
;
import
MySlider
from
'@/components/Slider'
;
const
systemPromptTip
=
'模型固定的引导词,通过调整该内容,可以引导模型聊天方向。该内容会被固定在上下文的开头。'
;
const
limitPromptTip
=
'限定模型对话范围,会被放置在本次提问前,拥有强引导和限定性。例如:\n1. 知识库是关于 Laf 的介绍,参考知识库回答问题,与 "Laf" 无关内容,直接回复: "我不知道"。\n2. 你仅回答关于 "xxx" 的问题,其他问题回复: "xxxx"'
;
const
Settings
=
({
modelId
}:
{
modelId
:
string
})
=>
{
const
{
toast
}
=
useToast
();
const
router
=
useRouter
();
...
...
@@ -60,7 +75,7 @@ const Settings = ({ modelId }: { modelId: string }) => {
}
return
max
;
},
[
getValues
,
setValue
,
refresh
]);
},
[
getValues
,
setValue
]);
// 提交保存模型修改
const
saveSubmitSuccess
=
useCallback
(
...
...
@@ -211,7 +226,7 @@ const Settings = ({ modelId }: { modelId: string }) => {
介绍
</Box>
<Textarea
rows={
5
}
rows={
4
}
maxLength={500}
placeholder={'给你的 AI 应用一个介绍'}
{...register('intro')}
...
...
@@ -225,11 +240,14 @@ const Settings = ({ modelId }: { modelId: string }) => {
对话模型
</Box>
<MySelect
width={['
200px', '24
0px']}
width={['
100%', '28
0px']}
value={getValues('chat.chatModel')}
list={chatModelList.map((item) => ({
id: item.chatModel,
label: item.name
label: `
$
{
item
.
name
}
(
$
{
formatPrice
(
ChatModelMap
[
getValues
(
'chat.chatModel'
)]?.
price
,
1000
)}
元
/
1
k
tokens
)
`
}))}
onchange={(val: any) => {
setValue('chat.chatModel', val);
...
...
@@ -237,15 +255,6 @@ const Settings = ({ modelId }: { modelId: string }) => {
}}
/>
</Flex>
<Flex alignItems={'center'} mt={5}>
<Box w={['60px', '100px', '140px']} flexShrink={0}>
价格
</Box>
<Box fontSize={['sm', 'md']}>
{formatPrice(ChatModelMap[getValues('chat.chatModel')]?.price, 1000)}
元/1K tokens(包括上下文和回答)
</Box>
</Flex>
<Flex alignItems={'center'} my={10}>
<Box w={['60px', '100px', '140px']} flexShrink={0}>
温度
...
...
@@ -269,7 +278,7 @@ const Settings = ({ modelId }: { modelId: string }) => {
</Flex>
<Flex alignItems={'center'} mt={12} mb={10}>
<Box w={['60px', '100px', '140px']} flexShrink={0}>
最大长度
回复上限
</Box>
<Box flex={1} ml={'10px'}>
<MySlider
...
...
@@ -292,15 +301,29 @@ const Settings = ({ modelId }: { modelId: string }) => {
<Flex mt={10} alignItems={'flex-start'}>
<Box w={['60px', '100px', '140px']} flexShrink={0}>
提示词
<Tooltip label={systemPromptTip}>
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
</Tooltip>
</Box>
<Textarea
rows={8}
placeholder={
'模型默认的 prompt 词,通过调整该内容,可以引导模型聊天方向。\n\n如果使用了知识库搜索,没有填写该内容时,系统会自动补充提示词;如果填写了内容,则以填写的内容为准。'
}
placeholder={systemPromptTip}
{...register('chat.systemPrompt')}
></Textarea>
</Flex>
<Flex mt={5} alignItems={'flex-start'}>
<Box w={['60px', '100px', '140px']} flexShrink={0}>
限定词
<Tooltip label={limitPromptTip}>
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
</Tooltip>
</Box>
<Textarea
rows={5}
placeholder={limitPromptTip}
{...register('chat.limitPrompt')}
></Textarea>
</Flex>
<Flex mt={5} alignItems={'center'}>
<Box w={['60px', '100px', '140px']} flexShrink={0}></Box>
...
...
client/src/service/models/model.ts
View file @
83d755ad
...
...
@@ -43,7 +43,10 @@ const ModelSchema = new Schema({
default
:
''
},
systemPrompt
:
{
// 系统提示词
type
:
String
,
default
:
''
},
limitPrompt
:
{
type
:
String
,
default
:
''
},
...
...
client/src/types/mongoSchema.d.ts
View file @
83d755ad
...
...
@@ -43,6 +43,7 @@ export interface ModelSchema {
searchLimit
:
number
;
searchEmptyText
:
string
;
systemPrompt
:
string
;
limitPrompt
:
string
;
temperature
:
number
;
maxToken
:
number
;
chatModel
:
ChatModelType
;
// 聊天时用的模型,训练后就是训练的模型
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment