Skip to content

Commit 25dc898

Browse files
authored
add answer quote number (#4658)
1 parent 2a54be4 commit 25dc898

File tree

9 files changed

+215
-42
lines changed

9 files changed

+215
-42
lines changed

packages/global/core/ai/prompt/AIChat.ts

Lines changed: 90 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ export const Prompt_QuoteTemplateList: PromptTemplateItem[] = [
77
title: i18nT('app:template.standard_template'),
88
desc: i18nT('app:template.standard_template_des'),
99
value: {
10+
['4.9.7']: `{
11+
"sourceIndex": "{{sourceIndex}}",
12+
"id": "{{id}}",
13+
"sourceName": "{{source}}",
14+
"content": "{{q}}\n{{a}}"
15+
}
16+
`,
1017
['4.9.2']: `{
1118
"sourceName": "{{source}}",
1219
"updateTime": "{{updateTime}}",
@@ -31,6 +38,13 @@ export const Prompt_QuoteTemplateList: PromptTemplateItem[] = [
3138
title: i18nT('app:template.standard_strict'),
3239
desc: i18nT('app:template.standard_strict_des'),
3340
value: {
41+
['4.9.7']: `{
42+
"sourceIndex": "{{sourceIndex}}",
43+
"id": "{{id}}",
44+
"sourceName": "{{source}}",
45+
"content": "{{q}}\n{{a}}"
46+
}
47+
`,
3448
['4.9.2']: `{
3549
"sourceName": "{{source}}",
3650
"updateTime": "{{updateTime}}",
@@ -64,6 +78,21 @@ export const Prompt_userQuotePromptList: PromptTemplateItem[] = [
6478
title: i18nT('app:template.standard_template'),
6579
desc: '',
6680
value: {
81+
['4.9.7']: `使用 <Reference></Reference> 标记中的内容作为本次对话的参考:
82+
83+
<Reference>
84+
{{quote}}
85+
</Reference>
86+
87+
回答要求:
88+
- 如果你不清楚答案,你需要澄清。
89+
- 避免提及你是从 <Reference></Reference> 获取的知识。
90+
- 保持答案与 <Reference></Reference> 中描述的一致。
91+
- 使用 Markdown 语法优化回答格式。
92+
- 使用与问题相同的语言回答。
93+
- 使用 [id](QUOTE{{sourceIndex}}) 格式来引用<Reference></Reference>中的知识,其中 QUOTE 是固定常量, id 和 sourceIndex 分别为引文中的值。
94+
- 在每段结尾自然地整合引用。例如: "FastGPT 是一个基于大语言模型(LLM)的知识库问答系统[67e517e74767063e882d6861](QUOTE1)。"
95+
- 每段至少包含一个引用,也可根据内容需要加入多个引用,按顺序排列。`,
6796
['4.9.2']: `使用 <Reference></Reference> 标记中的内容作为本次对话的参考:
6897
6998
<Reference>
@@ -103,6 +132,27 @@ export const Prompt_userQuotePromptList: PromptTemplateItem[] = [
103132
title: i18nT('app:template.standard_strict'),
104133
desc: '',
105134
value: {
135+
['4.9.7']: `忘记你已有的知识,仅使用 <Reference></Reference> 标记中的内容作为本次对话的参考:
136+
137+
<Reference>
138+
{{quote}}
139+
</Reference>
140+
141+
思考流程:
142+
1. 判断问题是否与 <Reference></Reference> 标记中的内容有关。
143+
2. 如果有关,你按下面的要求回答。
144+
3. 如果无关,你直接拒绝回答本次问题。
145+
146+
回答要求:
147+
- 避免提及你是从 <Reference></Reference> 获取的知识。
148+
- 保持答案与 <Reference></Reference> 中描述的一致。
149+
- 使用 Markdown 语法优化回答格式。
150+
- 使用与问题相同的语言回答。
151+
- 使用 [id](QUOTE{{sourceIndex}}) 格式来引用<Reference></Reference>中的知识,其中 QUOTE 是固定常量, id 和 sourceIndex 分别为引文中的值。
152+
- 在每段结尾自然地整合引用。例如: "FastGPT 是一个基于大语言模型(LLM)的知识库问答系统[67e517e74767063e882d6861](QUOTE1)。"
153+
- 每段至少包含一个引用,也可根据内容需要加入多个引用,按顺序排列。
154+
155+
问题:"""{{question}}"""`,
106156
['4.9.2']: `忘记你已有的知识,仅使用 <Reference></Reference> 标记中的内容作为本次对话的参考:
107157
108158
<Reference>
@@ -157,6 +207,21 @@ export const Prompt_systemQuotePromptList: PromptTemplateItem[] = [
157207
title: i18nT('app:template.standard_template'),
158208
desc: '',
159209
value: {
210+
['4.9.7']: `使用 <Reference></Reference> 标记中的内容作为本次对话的参考:
211+
212+
<Reference>
213+
{{quote}}
214+
</Reference>
215+
216+
回答要求:
217+
- 如果你不清楚答案,你需要澄清。
218+
- 避免提及你是从 <Reference></Reference> 获取的知识。
219+
- 保持答案与 <Reference></Reference> 中描述的一致。
220+
- 使用 Markdown 语法优化回答格式。
221+
- 使用与问题相同的语言回答。
222+
- 使用 [id](QUOTE{{sourceIndex}}) 格式来引用<Reference></Reference>中的知识,其中 QUOTE 是固定常量, id 和 sourceIndex 分别为引文中的值。
223+
- 在每段结尾自然地整合引用。例如: "FastGPT 是一个基于大语言模型(LLM)的知识库问答系统[67e517e74767063e882d6861](QUOTE1)。"
224+
- 每段至少包含一个引用,也可根据内容需要加入多个引用,按顺序排列。`,
160225
['4.9.2']: `使用 <Reference></Reference> 标记中的内容作为本次对话的参考:
161226
162227
<Reference>
@@ -192,6 +257,27 @@ export const Prompt_systemQuotePromptList: PromptTemplateItem[] = [
192257
title: i18nT('app:template.standard_strict'),
193258
desc: '',
194259
value: {
260+
['4.9.7']: `忘记你已有的知识,仅使用 <Reference></Reference> 标记中的内容作为本次对话的参考:
261+
262+
<Reference>
263+
{{quote}}
264+
</Reference>
265+
266+
思考流程:
267+
1. 判断问题是否与 <Reference></Reference> 标记中的内容有关。
268+
2. 如果有关,你按下面的要求回答。
269+
3. 如果无关,你直接拒绝回答本次问题。
270+
271+
回答要求:
272+
- 避免提及你是从 <Reference></Reference> 获取的知识。
273+
- 保持答案与 <Reference></Reference> 中描述的一致。
274+
- 使用 Markdown 语法优化回答格式。
275+
- 使用与问题相同的语言回答。
276+
- 使用 [id](QUOTE{{sourceIndex}}) 格式来引用<Reference></Reference>中的知识,其中 QUOTE 是固定常量, id 和 sourceIndex 分别为引文中的值。
277+
- 在每段结尾自然地整合引用。例如: "FastGPT 是一个基于大语言模型(LLM)的知识库问答系统[67e517e74767063e882d6861](QUOTE1)。"
278+
- 每段至少包含一个引用,也可根据内容需要加入多个引用,按顺序排列。
279+
280+
问题:"""{{question}}"""`,
195281
['4.9.2']: `忘记你已有的知识,仅使用 <Reference></Reference> 标记中的内容作为本次对话的参考:
196282
197283
<Reference>
@@ -250,10 +336,10 @@ export const getQuotePrompt = (version?: string, role: 'user' | 'system' = 'user
250336
export const getDocumentQuotePrompt = (version: string) => {
251337
const promptMap = {
252338
['4.9.2']: `将 <FilesContent></FilesContent> 中的内容作为本次对话的参考:
253-
<FilesContent>
254-
{{quote}}
255-
</FilesContent>
256-
`
339+
<FilesContent>
340+
{{quote}}
341+
</FilesContent>
342+
`
257343
};
258344

259345
return getPromptByVersion(version, promptMap);

packages/global/core/workflow/template/system/aiChat/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export const AiChatModule: FlowNodeTemplateType = {
5555
showStatus: true,
5656
isTool: true,
5757
courseUrl: '/docs/guide/workbench/workflow/ai_chat/',
58-
version: '4.9.0',
58+
version: '4.9.7',
5959
inputs: [
6060
Input_Template_SettingAiModel,
6161
// --- settings modal

packages/service/core/workflow/dispatch/chat/oneapi.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,24 +338,50 @@ async function filterDatasetQuote({
338338
model: LLMModelItemType;
339339
quoteTemplate: string;
340340
}) {
341-
function getValue(item: SearchDataResponseItemType, index: number) {
341+
function getValue({
342+
item,
343+
index,
344+
sourceList
345+
}: {
346+
item: SearchDataResponseItemType;
347+
index: number;
348+
sourceList: { sourceName: string; sourceId: string; sourceIndex: number }[];
349+
}) {
350+
const source = sourceList.find((source) => source.sourceId === item.sourceId);
351+
342352
return replaceVariable(quoteTemplate, {
343353
id: item.id,
344354
q: item.q,
345355
a: item.a,
346356
updateTime: formatTime2YMDHM(item.updateTime),
347357
source: item.sourceName,
348358
sourceId: String(item.sourceId || ''),
359+
sourceIndex: source?.sourceIndex || 1,
349360
index: index + 1
350361
});
351362
}
352363

353364
// slice filterSearch
354365
const filterQuoteQA = await filterSearchResultsByMaxChars(quoteQA, model.quoteMaxToken);
355366

367+
const sourceList = Object.values(
368+
filterQuoteQA.reduce((acc: Record<string, SearchDataResponseItemType[]>, cur) => {
369+
if (!acc[cur.collectionId]) {
370+
acc[cur.collectionId] = [cur];
371+
}
372+
return acc;
373+
}, {})
374+
)
375+
.flat()
376+
.map((item, index) => ({
377+
sourceName: item.sourceName || '',
378+
sourceId: item.sourceId || '',
379+
sourceIndex: index + 1
380+
}));
381+
356382
const datasetQuoteText =
357383
filterQuoteQA.length > 0
358-
? `${filterQuoteQA.map((item, index) => getValue(item, index).trim()).join('\n------\n')}`
384+
? `${filterQuoteQA.map((item, index) => getValue({ item, index, sourceList }).trim()).join('\n------\n')}`
359385
: '';
360386

361387
return {

packages/web/i18n/en/common.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,7 @@
617617
"core.dataset.search.ReRank": "Result Re-rank",
618618
"core.dataset.search.ReRank desc": "Use the re-rank model for secondary sorting to enhance the comprehensive ranking.",
619619
"core.dataset.search.Source id": "Source ID",
620+
"core.dataset.search.Source index": "What sources",
620621
"core.dataset.search.Source name": "Quote Source Name",
621622
"core.dataset.search.Using query extension": "Use Question Optimization",
622623
"core.dataset.search.mode.embedding": "Semantic Search",

packages/web/i18n/zh-CN/common.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,7 @@
617617
"core.dataset.search.ReRank": "结果重排",
618618
"core.dataset.search.ReRank desc": "使用重排模型来进行二次排序,可增强综合排名。",
619619
"core.dataset.search.Source id": "来源 ID",
620+
"core.dataset.search.Source index": "第几个来源",
620621
"core.dataset.search.Source name": "引用来源名",
621622
"core.dataset.search.Using query extension": "使用问题优化",
622623
"core.dataset.search.mode.embedding": "语义检索",

packages/web/i18n/zh-Hant/common.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,7 @@
616616
"core.dataset.search.ReRank": "結果重新排名",
617617
"core.dataset.search.ReRank desc": "使用重新排名模型來進行二次排序,可加強綜合排名。",
618618
"core.dataset.search.Source id": "來源 ID",
619+
"core.dataset.search.Source index": "第幾個來源",
619620
"core.dataset.search.Source name": "引用來源名稱",
620621
"core.dataset.search.Using query extension": "使用問題最佳化",
621622
"core.dataset.search.mode.embedding": "語意搜尋",

projects/app/src/components/Markdown/A.tsx

Lines changed: 83 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import {
55
Popover,
66
PopoverTrigger,
77
PopoverContent,
8-
PopoverHeader,
98
PopoverBody,
109
PopoverArrow,
11-
PopoverCloseButton
10+
Box,
11+
Flex
1212
} from '@chakra-ui/react';
1313
import MyIcon from '@fastgpt/web/components/common/Icon';
1414
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
@@ -17,9 +17,9 @@ import { useTranslation } from 'next-i18next';
1717
import React, { useMemo } from 'react';
1818
import { getQuoteData } from '@/web/core/dataset/api';
1919
import MyBox from '@fastgpt/web/components/common/MyBox';
20-
import RawSourceBox from '../core/dataset/RawSourceBox';
2120
import { getCollectionSourceData } from '@fastgpt/global/core/dataset/collection/utils';
2221
import Markdown from '.';
22+
import { getSourceNameIcon } from '@fastgpt/global/core/dataset/utils';
2323

2424
const A = ({ children, ...props }: any) => {
2525
const { t } = useTranslation();
@@ -52,46 +52,99 @@ const A = ({ children, ...props }: any) => {
5252
}
5353

5454
// Quote
55-
if (props.href === 'QUOTE' && typeof children?.[0] === 'string') {
55+
if (props.href?.startsWith('QUOTE') && typeof children?.[0] === 'string') {
56+
const indexMatch = props.href.match(/QUOTE(\d+)/);
57+
const index = indexMatch ? indexMatch[1] : '1';
58+
59+
const sourceData = useMemo(
60+
() => getCollectionSourceData(quoteData?.collection),
61+
[quoteData?.collection]
62+
);
63+
const icon = useMemo(
64+
() => getSourceNameIcon({ sourceId: sourceData.sourceId, sourceName: sourceData.sourceName }),
65+
[sourceData]
66+
);
67+
5668
return (
5769
<Popover
58-
direction="rtl"
5970
isLazy
60-
placement="auto"
71+
direction="rtl"
72+
placement="bottom"
6173
strategy={'fixed'}
6274
onOpen={() => runAsync(String(children))}
6375
>
6476
<PopoverTrigger>
6577
<Button variant={'unstyled'} minH={0} minW={0} h={'auto'}>
6678
<MyTooltip label={t('common:read_quote')}>
67-
<MyIcon
68-
name={'core/chat/quoteSign'}
69-
w={'1rem'}
70-
color={'primary.700'}
71-
cursor={'pointer'}
72-
transform={'translateY(-3px)'}
73-
/>
79+
<Box
80+
w={5}
81+
h={5}
82+
border={'1px solid'}
83+
borderRadius={'full'}
84+
borderColor={'myGray.200'}
85+
color={'myGray.500'}
86+
fontSize={'10px'}
87+
display={'flex'}
88+
alignItems={'center'}
89+
justifyContent={'center'}
90+
ml={0.5}
91+
transform={'translateY(-2px)'}
92+
>
93+
{index}
94+
</Box>
7495
</MyTooltip>
7596
</Button>
7697
</PopoverTrigger>
77-
<PopoverContent boxShadow={'lg'} w={'400px'}>
78-
<MyBox isLoading={loading} minH={'300px'}>
98+
<PopoverContent boxShadow={'lg'} w={'400px'} py={4}>
99+
<MyBox isLoading={loading} minH={'224px'}>
79100
<PopoverArrow />
80-
<PopoverHeader h={'40px'} display={'flex'} alignItems={'center'}>
81-
{quoteData?.collection && (
82-
<RawSourceBox
83-
collectionId={quoteData?.collection._id}
84-
{...getCollectionSourceData(quoteData?.collection)}
85-
fontSize={'sm'}
86-
color={'black'}
87-
textDecoration={'none'}
88-
/>
89-
)}
90-
<PopoverCloseButton />
91-
</PopoverHeader>
92-
<PopoverBody fontSize={'sm'} maxH={'400px'} overflow={'auto'}>
93-
<Markdown source={quoteData?.q} />
94-
<Markdown source={quoteData?.a} />
101+
<PopoverBody
102+
px={4}
103+
py={0}
104+
fontSize={'sm'}
105+
maxW={'400px'}
106+
maxH={'224px'}
107+
overflow={'auto'}
108+
>
109+
<Box
110+
alignItems={'center'}
111+
fontSize={'xs'}
112+
border={'sm'}
113+
borderRadius={'sm'}
114+
overflow={'hidden'}
115+
display={'inline-flex'}
116+
height={6}
117+
>
118+
<Flex
119+
color={'myGray.500'}
120+
bg={'myGray.150'}
121+
w={4}
122+
justifyContent={'center'}
123+
fontSize={'10px'}
124+
h={'full'}
125+
alignItems={'center'}
126+
mr={1}
127+
flexShrink={0}
128+
>
129+
{index}
130+
</Flex>
131+
<Flex px={1.5}>
132+
<MyIcon name={icon as any} mr={1} flexShrink={0} w={'12px'} />
133+
<Box
134+
className={'textEllipsis'}
135+
wordBreak={'break-all'}
136+
flex={'1 0 0'}
137+
fontSize={'mini'}
138+
color={'myGray.900'}
139+
>
140+
{sourceData.sourceName}
141+
</Box>
142+
</Flex>
143+
</Box>
144+
<Box>
145+
<Markdown source={quoteData?.q} />
146+
{quoteData?.a && <Markdown source={quoteData?.a} />}
147+
</Box>
95148
</PopoverBody>
96149
</MyBox>
97150
</PopoverContent>

projects/app/src/components/core/chat/ChatContainer/ChatBox/components/QuoteList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const QuoteList = React.memo(function QuoteList({
5959
};
6060
}
6161

62-
return item;
62+
return { ...item, q: item.q || '', a: item.a || '' };
6363
});
6464

6565
return processedData.sort((a, b) => {

0 commit comments

Comments
 (0)