Test parse cite and add tool call parallel (#4737)

* add quote response filter (#4727)

* chatting

* add quote response filter

* add test

* remove comment

* perf: cite hidden

* perf: format llm response

* feat: comment

* update default chunk size

* update default chunk size

---------

Co-authored-by: heheer <heheer@sealos.io>
This commit is contained in:
Archer
2025-04-30 17:43:50 +08:00
committed by GitHub
parent 683ab6c17d
commit fdd4e9edbd
53 changed files with 1131 additions and 716 deletions

View File

@@ -0,0 +1,18 @@
export const checkPasswordRule = (password: string) => {
const patterns = [
/\d/, // Contains digits
/[a-z]/, // Contains lowercase letters
/[A-Z]/, // Contains uppercase letters
/[!@#$%^&*()_+=-]/ // Contains special characters
];
const validChars = /^[\dA-Za-z!@#$%^&*()_+=-]{6,100}$/;
// Check length and valid characters
if (!validChars.test(password)) return false;
// Count how many patterns are satisfied
const matchCount = patterns.filter((pattern) => pattern.test(password)).length;
// Must satisfy at least 2 patterns
return matchCount >= 2;
};

View File

@@ -88,8 +88,8 @@ export const Prompt_userQuotePromptList: PromptTemplateItem[] = [
- 保持答案与 <Reference></Reference> 中描述的一致。
- 使用 Markdown 语法优化回答格式。
- 使用与问题相同的语言回答。
- 使用 [id](QUOTE) 格式来引用<Reference></Reference>中的知识,其中 QUOTE 是固定常量, id 为引文中的 id。
- 在每段结尾自然地整合引用。例如: "FastGPT 是一个基于大语言模型(LLM)的知识库问答系统[67e517e74767063e882d6861](QUOTE)。"
- 使用 [id](CITE) 格式来引用<Reference></Reference>中的知识,其中 CITE 是固定常量, id 为引文中的 id。
- 在每段结尾自然地整合引用。例如: "FastGPT 是一个基于大语言模型(LLM)的知识库问答系统[67e517e74767063e882d6861](CITE)。"
- 每段至少包含一个引用,也可根据内容需要加入多个引用,按顺序排列。`,
['4.9.2']: `使用 <Reference></Reference> 标记中的内容作为本次对话的参考:
@@ -146,8 +146,8 @@ export const Prompt_userQuotePromptList: PromptTemplateItem[] = [
- 保持答案与 <Reference></Reference> 中描述的一致。
- 使用 Markdown 语法优化回答格式。
- 使用与问题相同的语言回答。
- 使用 [id](QUOTE) 格式来引用<Reference></Reference>中的知识,其中 QUOTE 是固定常量, id 为引文中的 id。
- 在每段结尾自然地整合引用。例如: "FastGPT 是一个基于大语言模型(LLM)的知识库问答系统[67e517e74767063e882d6861](QUOTE)。"
- 使用 [id](CITE) 格式来引用<Reference></Reference>中的知识,其中 CITE 是固定常量, id 为引文中的 id。
- 在每段结尾自然地整合引用。例如: "FastGPT 是一个基于大语言模型(LLM)的知识库问答系统[67e517e74767063e882d6861](CITE)。"
- 每段至少包含一个引用,也可根据内容需要加入多个引用,按顺序排列。
问题:"""{{question}}"""`,
@@ -217,8 +217,8 @@ export const Prompt_systemQuotePromptList: PromptTemplateItem[] = [
- 保持答案与 <Reference></Reference> 中描述的一致。
- 使用 Markdown 语法优化回答格式。
- 使用与问题相同的语言回答。
- 使用 [id](QUOTE) 格式来引用<Reference></Reference>中的知识,其中 QUOTE 是固定常量, id 为引文中的 id。
- 在每段结尾自然地整合引用。例如: "FastGPT 是一个基于大语言模型(LLM)的知识库问答系统[67e517e74767063e882d6861](QUOTE)。"
- 使用 [id](CITE) 格式来引用<Reference></Reference>中的知识,其中 CITE 是固定常量, id 为引文中的 id。
- 在每段结尾自然地整合引用。例如: "FastGPT 是一个基于大语言模型(LLM)的知识库问答系统[67e517e74767063e882d6861](CITE)。"
- 每段至少包含一个引用,也可根据内容需要加入多个引用,按顺序排列。`,
['4.9.2']: `使用 <Reference></Reference> 标记中的内容作为本次对话的参考:
@@ -271,8 +271,8 @@ export const Prompt_systemQuotePromptList: PromptTemplateItem[] = [
- 保持答案与 <Reference></Reference> 中描述的一致。
- 使用 Markdown 语法优化回答格式。
- 使用与问题相同的语言回答。
- 使用 [id](QUOTE) 格式来引用<Reference></Reference>中的知识,其中 QUOTE 是固定常量, id 为引文中的 id。
- 在每段结尾自然地整合引用。例如: "FastGPT 是一个基于大语言模型(LLM)的知识库问答系统[67e517e74767063e882d6861](QUOTE)。"
- 使用 [id](CITE) 格式来引用<Reference></Reference>中的知识,其中 CITE 是固定常量, id 为引文中的 id。
- 在每段结尾自然地整合引用。例如: "FastGPT 是一个基于大语言模型(LLM)的知识库问答系统[67e517e74767063e882d6861](CITE)。"
- 每段至少包含一个引用,也可根据内容需要加入多个引用,按顺序排列。
问题:"""{{question}}"""`,
@@ -321,24 +321,13 @@ export const Prompt_systemQuotePromptList: PromptTemplateItem[] = [
}
];
export const getQuotePrompt = (
version?: string,
role: 'user' | 'system' = 'user',
parseQuote = true
) => {
export const getQuotePrompt = (version?: string, role: 'user' | 'system' = 'user') => {
const quotePromptTemplates =
role === 'user' ? Prompt_userQuotePromptList : Prompt_systemQuotePromptList;
const defaultTemplate = quotePromptTemplates[0].value;
return parseQuote
? getPromptByVersion(version, defaultTemplate)
: getPromptByVersion(version, defaultTemplate).replace(
`- 使用 [id](QUOTE) 格式来引用<Reference></Reference>中的知识,其中 QUOTE 是固定常量, id 为引文中的 id。
- 在每段结尾自然地整合引用。例如: "FastGPT 是一个基于大语言模型(LLM)的知识库问答系统[67e517e74767063e882d6861](QUOTE)。"
- 每段至少包含一个引用,也可根据内容需要加入多个引用,按顺序排列。`,
''
);
return getPromptByVersion(version, defaultTemplate);
};
// Document quote prompt

View File

@@ -60,7 +60,7 @@ export const getExtractJsonToolPrompt = (version?: string) => {
"""
- {{description}}
- 不是每个参数都是必须生成的,如果没有合适的参数值,不要生成该参数,或返回空字符串。
- 需要结合前面的对话内容,一起生成合适的参数。
- 需要结合历史记录,一起生成合适的参数。
"""
本次输入内容: """{{content}}"""

View File

@@ -1,6 +1,5 @@
export const getDatasetSearchToolResponsePrompt = (parseQuote: boolean) => {
return parseQuote
? `## Role
export const getDatasetSearchToolResponsePrompt = () => {
return `## Role
你是一个知识库回答助手,可以 "quotes" 中的内容作为本次对话的参考。为了使回答结果更加可信并且可追溯,你需要在每段话结尾添加引用标记。
## Rules
@@ -9,16 +8,7 @@ export const getDatasetSearchToolResponsePrompt = (parseQuote: boolean) => {
- 保持答案与 "quotes" 中描述的一致。
- 使用 Markdown 语法优化回答格式。尤其是图片、表格、序列号等内容,需严格完整输出。
- 使用与问题相同的语言回答。
- 使用 [id](QUOTE) 格式来引用 "quotes" 中的知识,其中 QUOTE 是固定常量, id 为引文中的 id。
- 在每段话结尾自然地整合引用。例如: "FastGPT 是一个基于大语言模型(LLM)的知识库问答系统[67e517e74767063e882d6861](QUOTE)。"
- 每段话至少包含一个引用,也可根据内容需要加入多个引用,按顺序排列。`
: `## Role
你是一个知识库回答助手,可以 "quotes" 中的内容作为本次对话的参考。
## Rules
- 如果你不清楚答案,你需要澄清。
- 避免提及你是从 "quotes" 获取的知识。
- 保持答案与 "quotes" 中描述的一致。
- 使用 Markdown 语法优化回答格式。尤其是图片、表格、序列号等内容,需严格完整输出。
- 使用与问题相同的语言回答。`;
- 使用 [id](CITE) 格式来引用 "quotes" 中的知识,其中 CITE 是固定常量, id 为引文中的 id。
- 在每段话结尾自然地整合引用。例如: "FastGPT 是一个基于大语言模型(LLM)的知识库问答系统[67e517e74767063e882d6861](CITE)。"
- 每段话至少包含一个引用,也可根据内容需要加入多个引用,按顺序排列。`;
};

View File

@@ -60,6 +60,7 @@ export type ChatCompletionAssistantToolParam = {
tool_calls: ChatCompletionMessageToolCall[];
};
export type ChatCompletionMessageToolCall = ChatCompletionMessageToolCall & {
index?: number;
toolName?: string;
toolAvatar?: string;
};

View File

@@ -1,9 +1,15 @@
import { DispatchNodeResponseType } from '../workflow/runtime/type';
import { FlowNodeTypeEnum } from '../workflow/node/constant';
import { ChatItemValueTypeEnum, ChatRoleEnum, ChatSourceEnum } from './constants';
import { ChatHistoryItemResType, ChatItemType, UserChatItemValueItemType } from './type.d';
import {
AIChatItemValueItemType,
ChatHistoryItemResType,
ChatItemType,
UserChatItemValueItemType
} from './type.d';
import { sliceStrStartEnd } from '../../common/string/tools';
import { PublishChannelEnum } from '../../support/outLink/constant';
import { removeDatasetCiteText } from '../../../service/core/ai/utils';
// Concat 2 -> 1, and sort by role
export const concatHistories = (histories1: ChatItemType[], histories2: ChatItemType[]) => {
@@ -77,6 +83,7 @@ export const getHistoryPreview = (
});
};
// Filter workflow public response
export const filterPublicNodeResponseData = ({
flowResponses = [],
responseDetail = false
@@ -112,6 +119,40 @@ export const filterPublicNodeResponseData = ({
});
};
// Remove dataset cite in ai response
export const removeAIResponseCite = <T extends AIChatItemValueItemType[] | string>(
value: T,
retainCite: boolean
): T => {
if (retainCite) return value;
if (typeof value === 'string') {
return removeDatasetCiteText(value, false) as T;
}
return value.map<AIChatItemValueItemType>((item) => {
if (item.text?.content) {
return {
...item,
text: {
...item.text,
content: removeDatasetCiteText(item.text.content, false)
}
};
}
if (item.reasoning?.content) {
return {
...item,
reasoning: {
...item.reasoning,
content: removeDatasetCiteText(item.reasoning.content, false)
}
};
}
return item;
}) as T;
};
export const removeEmptyUserInput = (input?: UserChatItemValueItemType[]) => {
return (
input?.filter((item) => {

View File

@@ -8,7 +8,7 @@ import {
export const minChunkSize = 64; // min index and chunk size
// Chunk size
export const chunkAutoChunkSize = 1500;
export const chunkAutoChunkSize = 1000;
export const getMaxChunkSize = (model: LLMModelItemType) => {
return Math.max(model.maxContext - model.maxResponse, 2000);
};

View File

@@ -58,7 +58,7 @@ export type ChatDispatchProps = {
chatConfig: AppSchema['chatConfig'];
lastInteractive?: WorkflowInteractiveResponseType; // last interactive response
stream: boolean;
parseQuote?: boolean;
retainDatasetCite?: boolean;
maxRunTimes: number;
isToolCall?: boolean;
workflowStreamResponse?: WorkflowResponseType;

View File

@@ -54,7 +54,7 @@ export const DatasetSearchModule: FlowNodeTemplateType = {
key: NodeInputKeyEnum.datasetMaxTokens,
renderTypeList: [FlowNodeInputTypeEnum.hidden],
label: '',
value: 1500,
value: 5000,
valueType: WorkflowIOValueTypeEnum.number
},
{