From 029a9f4734fc84e677f63efc00cd39e7bd7d3d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 13:51:17 +0800 Subject: [PATCH 01/26] feat: Configurable output of `reason` for `Intent recognition` --- .../flow/step_node/intent_node/i_intent_node.py | 1 + .../step_node/intent_node/impl/base_intent_node.py | 9 +++++---- .../step_node/intent_node/impl/prompt_template.py | 3 +-- ui/src/locales/lang/en-US/workflow.ts | 1 + ui/src/locales/lang/zh-CN/workflow.ts | 1 + ui/src/locales/lang/zh-Hant/workflow.ts | 1 + .../workflow/nodes/intent-classify-node/index.vue | 14 ++++++++++++++ 7 files changed, 24 insertions(+), 6 deletions(-) diff --git a/apps/application/flow/step_node/intent_node/i_intent_node.py b/apps/application/flow/step_node/intent_node/i_intent_node.py index de09826b392..2e556fc5f56 100644 --- a/apps/application/flow/step_node/intent_node/i_intent_node.py +++ b/apps/application/flow/step_node/intent_node/i_intent_node.py @@ -23,6 +23,7 @@ class IntentNodeSerializer(serializers.Serializer): model_params_setting = serializers.DictField(required=False, label=_("Model parameter settings")) branch = IntentBranchSerializer(many=True) + output_reason = serializers.BooleanField(required=False, label=_("Output reason"), default=True) class IIntentNode(INode): diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index f3bc38d74e2..05e2b592635 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -52,7 +52,7 @@ def save_context(self, details, workflow_manage): self.context['branch_id'] = details.get('branch_id') self.context['category'] = details.get('category') - def execute(self, model_id, dialogue_number, history_chat_record, user_input, branch, + def execute(self, model_id, dialogue_number, history_chat_record, user_input, branch, output_reason, model_params_setting=None, **kwargs) -> NodeResult: # 设置默认模型参数 @@ -73,7 +73,7 @@ def execute(self, model_id, dialogue_number, history_chat_record, user_input, br self.context['user_input'] = user_input # 构建分类提示词 - prompt = self.build_classification_prompt(user_input, branch) + prompt = self.build_classification_prompt(user_input, branch, output_reason) # 生成消息列表 system = self.build_system_prompt() @@ -129,7 +129,7 @@ def build_system_prompt(self) -> str: """构建系统提示词""" return "你是一个专业的意图识别助手,请根据用户输入和意图选项,准确识别用户的真实意图。" - def build_classification_prompt(self, user_input: str, branch: List[Dict]) -> str: + def build_classification_prompt(self, user_input: str, branch: List[Dict], output_reason: bool) -> str: """构建分类提示词""" classification_list = [] @@ -153,7 +153,8 @@ def build_classification_prompt(self, user_input: str, branch: List[Dict]) -> st return PROMPT_TEMPLATE.format( classification_list=classification_list, - user_input=user_input + user_input=user_input, + output_reason=',\n"reason": ""' if output_reason is True else "" ) def generate_message_list(self, system: str, prompt: str, history_message): diff --git a/apps/application/flow/step_node/intent_node/impl/prompt_template.py b/apps/application/flow/step_node/intent_node/impl/prompt_template.py index 1bcfd61743e..3989ee704b2 100644 --- a/apps/application/flow/step_node/intent_node/impl/prompt_template.py +++ b/apps/application/flow/step_node/intent_node/impl/prompt_template.py @@ -21,8 +21,7 @@ - Do not add prefix ```json or suffix ``` - The answer needs to include the following fields such as: {{ -"classificationId": 0, -"reason": "" +"classificationId": 0{output_reason} }} ## Limit diff --git a/ui/src/locales/lang/en-US/workflow.ts b/ui/src/locales/lang/en-US/workflow.ts index 74fa49f04b4..3f6581b61a5 100644 --- a/ui/src/locales/lang/en-US/workflow.ts +++ b/ui/src/locales/lang/en-US/workflow.ts @@ -447,6 +447,7 @@ You are a master of problem optimization, adept at accurately inferring user int classify: { label: 'Intent classify', }, + output_reason: 'Output Reason', input: { label: 'Input', }, diff --git a/ui/src/locales/lang/zh-CN/workflow.ts b/ui/src/locales/lang/zh-CN/workflow.ts index 0f069ddeccd..239bf468212 100644 --- a/ui/src/locales/lang/zh-CN/workflow.ts +++ b/ui/src/locales/lang/zh-CN/workflow.ts @@ -439,6 +439,7 @@ export default { classify: { label: '意图分类', }, + output_reason: '输出理由', input: { label: '输入', }, diff --git a/ui/src/locales/lang/zh-Hant/workflow.ts b/ui/src/locales/lang/zh-Hant/workflow.ts index 25d844d783f..989a77ae051 100644 --- a/ui/src/locales/lang/zh-Hant/workflow.ts +++ b/ui/src/locales/lang/zh-Hant/workflow.ts @@ -439,6 +439,7 @@ export default { classify: { label: '意圖分類', }, + output_reason: '輸出理由', input: { label: '輸入', }, diff --git a/ui/src/workflow/nodes/intent-classify-node/index.vue b/ui/src/workflow/nodes/intent-classify-node/index.vue index ba8ca3547d8..89833d96b1a 100644 --- a/ui/src/workflow/nodes/intent-classify-node/index.vue +++ b/ui/src/workflow/nodes/intent-classify-node/index.vue @@ -138,6 +138,19 @@ + +
+
+ {{ $t('workflow.nodes.intentNode.output_reason') }} +
+
+ +
+
+
@@ -295,6 +308,7 @@ const form = { ], dialogue_number: 1, content_list: [], + output_reason: true, } function refreshParam(data: any) { From eba4501e6e42d47044d7d8de39bfcf17d41977a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 14:24:04 +0800 Subject: [PATCH 02/26] show the system prompt in the execution detail --- .../flow/step_node/intent_node/impl/base_intent_node.py | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index 05e2b592635..c1825dd028b 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -74,6 +74,7 @@ def execute(self, model_id, dialogue_number, history_chat_record, user_input, br # 构建分类提示词 prompt = self.build_classification_prompt(user_input, branch, output_reason) + self.context['system'] = prompt # 生成消息列表 system = self.build_system_prompt() From df360a5811b6ffa9bda05dcbfdc68bcadbe23dfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 14:32:30 +0800 Subject: [PATCH 03/26] =?UTF-8?q?=E5=B0=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flow/step_node/intent_node/impl/base_intent_node.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index c1825dd028b..93dc61053d6 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -155,7 +155,7 @@ def build_classification_prompt(self, user_input: str, branch: List[Dict], outpu return PROMPT_TEMPLATE.format( classification_list=classification_list, user_input=user_input, - output_reason=',\n"reason": ""' if output_reason is True else "" + output_reason=',\n"reason": ""' if output_reason is True else '' ) def generate_message_list(self, system: str, prompt: str, history_message): From a4005c3e78b9d82db9b95a894581fefda6a94a93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 17:36:22 +0800 Subject: [PATCH 04/26] feat: The prompt template for the `Intent Recognition` is configurable --- .../step_node/intent_node/i_intent_node.py | 1 + .../intent_node/impl/base_intent_node.py | 17 +++-- .../intent_node/impl/prompt_template.py | 6 +- .../locales/lang/en-US/views/application.ts | 5 ++ ui/src/locales/lang/en-US/workflow.ts | 1 + .../locales/lang/zh-CN/views/application.ts | 5 ++ ui/src/locales/lang/zh-CN/workflow.ts | 1 + .../locales/lang/zh-Hant/views/application.ts | 5 ++ ui/src/locales/lang/zh-Hant/workflow.ts | 1 + .../nodes/intent-classify-node/index.vue | 65 +++++++++++++++++++ 10 files changed, 97 insertions(+), 10 deletions(-) diff --git a/apps/application/flow/step_node/intent_node/i_intent_node.py b/apps/application/flow/step_node/intent_node/i_intent_node.py index 2e556fc5f56..7132a8c4e1d 100644 --- a/apps/application/flow/step_node/intent_node/i_intent_node.py +++ b/apps/application/flow/step_node/intent_node/i_intent_node.py @@ -17,6 +17,7 @@ class IntentBranchSerializer(serializers.Serializer): class IntentNodeSerializer(serializers.Serializer): model_id = serializers.CharField(required=True, label=_("Model id")) + prompt_template = serializers.CharField(required=False, allow_blank=True, allow_null=True, label=_("Prompt template")) content_list = serializers.ListField(required=True, label=_("Text content")) dialogue_number = serializers.IntegerField(required=True, label= _("Number of multi-round conversations")) diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index 93dc61053d6..fc99faa2507 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -12,7 +12,7 @@ from application.flow.step_node.intent_node.i_intent_node import IIntentNode from models_provider.models import Model from models_provider.tools import get_model_instance_by_model_workspace_id, get_model_credential -from .prompt_template import PROMPT_TEMPLATE +from .prompt_template import DEFAULT_PROMPT_TEMPLATE def get_default_model_params_setting(model_id): @@ -52,7 +52,7 @@ def save_context(self, details, workflow_manage): self.context['branch_id'] = details.get('branch_id') self.context['category'] = details.get('category') - def execute(self, model_id, dialogue_number, history_chat_record, user_input, branch, output_reason, + def execute(self, model_id, prompt_template, dialogue_number, history_chat_record, user_input, branch, output_reason, model_params_setting=None, **kwargs) -> NodeResult: # 设置默认模型参数 @@ -73,7 +73,8 @@ def execute(self, model_id, dialogue_number, history_chat_record, user_input, br self.context['user_input'] = user_input # 构建分类提示词 - prompt = self.build_classification_prompt(user_input, branch, output_reason) + prompt_template = self.workflow_manage.generate_prompt(prompt_template) + prompt = self.build_classification_prompt(prompt_template, user_input, branch, output_reason) self.context['system'] = prompt # 生成消息列表 @@ -130,7 +131,7 @@ def build_system_prompt(self) -> str: """构建系统提示词""" return "你是一个专业的意图识别助手,请根据用户输入和意图选项,准确识别用户的真实意图。" - def build_classification_prompt(self, user_input: str, branch: List[Dict], output_reason: bool) -> str: + def build_classification_prompt(self, prompt_template: str, user_input: str, branch: List[Dict], output_reason: bool) -> str: """构建分类提示词""" classification_list = [] @@ -152,10 +153,14 @@ def build_classification_prompt(self, user_input: str, branch: List[Dict], outpu }) classification_id += 1 - return PROMPT_TEMPLATE.format( + # 构建输出JSON结构 + output_reason = ', "reason": ""' if output_reason is True else '' + output_json = f'{{"classificationId": 0{output_reason}}}' + + return (prompt_template or DEFAULT_PROMPT_TEMPLATE).format( classification_list=classification_list, user_input=user_input, - output_reason=',\n"reason": ""' if output_reason is True else '' + output_json=output_json ) def generate_message_list(self, system: str, prompt: str, history_message): diff --git a/apps/application/flow/step_node/intent_node/impl/prompt_template.py b/apps/application/flow/step_node/intent_node/impl/prompt_template.py index 3989ee704b2..79062022edb 100644 --- a/apps/application/flow/step_node/intent_node/impl/prompt_template.py +++ b/apps/application/flow/step_node/intent_node/impl/prompt_template.py @@ -1,6 +1,6 @@ -PROMPT_TEMPLATE = """# Role +DEFAULT_PROMPT_TEMPLATE = """# Role You are an intention classification expert, good at being able to judge which classification the user's input belongs to. ## Skills @@ -20,9 +20,7 @@ - Strictly ensure that the output is in a valid JSON format. - Do not add prefix ```json or suffix ``` - The answer needs to include the following fields such as: -{{ -"classificationId": 0{output_reason} -}} +{output_json} ## Limit - Please do not reply in text.""" diff --git a/ui/src/locales/lang/en-US/views/application.ts b/ui/src/locales/lang/en-US/views/application.ts index 072779082e7..aa181d17dff 100644 --- a/ui/src/locales/lang/en-US/views/application.ts +++ b/ui/src/locales/lang/en-US/views/application.ts @@ -87,6 +87,11 @@ export default { - Please use concise and professional language to answer the user's question. `, }, + prompt_template: { + label: 'Prompt Template', + requiredMessage: 'Please enter Prompt template', + tooltip: 'Please pay attention to the placeholders `{xxx}` in the template', + }, historyRecord: { label: 'Chat History', }, diff --git a/ui/src/locales/lang/en-US/workflow.ts b/ui/src/locales/lang/en-US/workflow.ts index 3f6581b61a5..45e6b89ce09 100644 --- a/ui/src/locales/lang/en-US/workflow.ts +++ b/ui/src/locales/lang/en-US/workflow.ts @@ -542,6 +542,7 @@ You are a master of problem optimization, adept at accurately inferring user int }, SystemPromptPlaceholder: 'System Prompt, can reference variables in the system, such as', UserPromptPlaceholder: 'User Prompt, can reference variables in the system, such as', + PromptTemplatePlaceholder: 'Prompt Template, can reference variables in the system, such as', initiator: 'Iniiator', abnormalInformation: 'Abnormal Information', } diff --git a/ui/src/locales/lang/zh-CN/views/application.ts b/ui/src/locales/lang/zh-CN/views/application.ts index 6ebe33d24ce..3527aaad907 100644 --- a/ui/src/locales/lang/zh-CN/views/application.ts +++ b/ui/src/locales/lang/zh-CN/views/application.ts @@ -80,6 +80,11 @@ export default { 回答要求: - 请使用中文回答用户问题`, }, + prompt_template: { + label: '提示词模板', + requiredMessage: '请输入提示词模板', + tooltip: '请注意模板中的占位符 `{xxx}`', + }, historyRecord: { label: '历史聊天记录', }, diff --git a/ui/src/locales/lang/zh-CN/workflow.ts b/ui/src/locales/lang/zh-CN/workflow.ts index 239bf468212..f26c485455d 100644 --- a/ui/src/locales/lang/zh-CN/workflow.ts +++ b/ui/src/locales/lang/zh-CN/workflow.ts @@ -533,6 +533,7 @@ export default { }, SystemPromptPlaceholder: '系统提示词,可以引用系统中的变量:如', UserPromptPlaceholder: '用户提示词,可以引用系统中的变量:如', + PromptTemplatePlaceholder: '提示词模板,可以引用系统中的变量:如', initiator: '发起人', abnormalInformation: '异常信息' diff --git a/ui/src/locales/lang/zh-Hant/views/application.ts b/ui/src/locales/lang/zh-Hant/views/application.ts index 9a613106305..ab3b9ed2217 100644 --- a/ui/src/locales/lang/zh-Hant/views/application.ts +++ b/ui/src/locales/lang/zh-Hant/views/application.ts @@ -80,6 +80,11 @@ export default { 回答要求: - 請使用中文回答用戶問題`, }, + prompt_template: { + label: '提示詞模板', + requiredMessage: '請輸入提示詞模板', + tooltip: '請注意模板中的佔位符 `{xxx}`', + }, historyRecord: { label: '歷史對話紀錄', }, diff --git a/ui/src/locales/lang/zh-Hant/workflow.ts b/ui/src/locales/lang/zh-Hant/workflow.ts index 989a77ae051..7ca169be920 100644 --- a/ui/src/locales/lang/zh-Hant/workflow.ts +++ b/ui/src/locales/lang/zh-Hant/workflow.ts @@ -527,6 +527,7 @@ export default { }, SystemPromptPlaceholder: '系統提示詞,可以引用系統中的變量:如', UserPromptPlaceholder: '用戶提示詞,可以引用系統中的變量:如', + PromptTemplatePlaceholder: '提示詞模板,可以引用系統中的變量:如', initiator: '發起人', abnormalInformation: '異常信息', } diff --git a/ui/src/workflow/nodes/intent-classify-node/index.vue b/ui/src/workflow/nodes/intent-classify-node/index.vue index 89833d96b1a..d809aac1b1d 100644 --- a/ui/src/workflow/nodes/intent-classify-node/index.vue +++ b/ui/src/workflow/nodes/intent-classify-node/index.vue @@ -51,6 +51,38 @@ :model-type="'LLM'" > + + + + { } } +const defaultPromptTemplate = `# Role +You are an intention classification expert, good at being able to judge which classification the user's input belongs to. + +## Skills +Skill 1: Clearly determine which of the following intention classifications the user's input belongs to. +Intention classification list: +{classification_list} + +Note: +- Please determine the match between the user's input content and the Intention classification list content, without judging or categorizing the match with the classification ID. +- **When classifying, you must give higher weight to the context and intent continuity shown in the historical conversation. Do not rely solely on the literal meaning of the current input; instead, prioritize the most consistent classification with the previous dialogue flow.** + +## User Input +{user_input} + +## Reply requirements +- The answer must be returned in JSON format. +- Strictly ensure that the output is in a valid JSON format. +- Do not add prefix \`\`\`json or suffix \`\`\` +- The answer needs to include the following fields such as: +{output_json} + +## Limit +- Please do not reply in text.` + const form = { model_id: '', + prompt_template: defaultPromptTemplate, branch: [ { id: randomId(), @@ -315,6 +373,10 @@ function refreshParam(data: any) { set(props.nodeModel.properties.node_data, 'model_params_setting', data) } +function submitTemplateDialog(val: string) { + set(props.nodeModel.properties.node_data, 'prompt_template', val) +} + const openAIParamSettingDialog = (modelId: string) => { if (modelId) { AIModeParamSettingDialogRef.value?.open(modelId, id, form_data.value.model_params_setting) @@ -323,6 +385,9 @@ const openAIParamSettingDialog = (modelId: string) => { const form_data = computed({ get: () => { if (props.nodeModel.properties.node_data) { + if (!props.nodeModel.properties.node_data.prompt_template) { + set(props.nodeModel.properties.node_data, 'prompt_template', defaultPromptTemplate) + } return props.nodeModel.properties.node_data } else { set(props.nodeModel.properties, 'node_data', form) From 41f77a501a3b9aa031a1b5535b7301fbd9e429a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 17:53:38 +0800 Subject: [PATCH 05/26] optimize --- .../intent_node/impl/base_intent_node.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index fc99faa2507..fd3c3f461bf 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -189,8 +189,14 @@ def get_branch_by_id(category_id: int): return None try: - result_json = json.loads(result) - classification_id = result_json.get('classificationId') + # 先尝试解析为数字(自定义提示词模板时,可提示大模型只输出ID值) + classification_id = self.to_int(result) + + # 再尝试解析为 JSON + if classification_id is None: + result_json = json.loads(result) + classification_id = result_json.get('classificationId') + # 如果是 0 ,返回其他分支 matched_branch = get_branch_by_id(classification_id) if matched_branch: @@ -230,6 +236,12 @@ def parse_result_reason(self, result: str): return '' + def to_int(self, str): + try: + return int(str) + except ValueError: + return None + def find_other_branch(self, branch: List[Dict]) -> Dict[str, Any] | None: """查找其他分支""" for b in branch: From 6209d1fa5c0e57f7c445a890f5e2eddc916ce7d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 17:58:36 +0800 Subject: [PATCH 06/26] =?UTF-8?q?=E5=B0=8F=E8=B0=83=E6=95=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../step_node/intent_node/impl/base_intent_node.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index fd3c3f461bf..c2c78cbebc4 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -189,10 +189,13 @@ def get_branch_by_id(category_id: int): return None try: - # 先尝试解析为数字(自定义提示词模板时,可提示大模型只输出ID值) - classification_id = self.to_int(result) + classification_id = None - # 再尝试解析为 JSON + # 如果返回长度小于5,先尝试解析为数字(增加自由度:自定义提示词模板时,可提示大模型只输出ID值) + if len(result) < 5: + classification_id = self.to_int(result) + + # 尝试解析为 JSON if classification_id is None: result_json = json.loads(result) classification_id = result_json.get('classificationId') @@ -202,7 +205,7 @@ def get_branch_by_id(category_id: int): if matched_branch: return matched_branch - except Exception as e: + except Exception: # json 解析失败,re 提取 numbers = re.findall(r'"classificationId":\s*(\d+)', result) if numbers: From b5fce70cee1f11c2a23dba517bad0719b4efd3ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 18:01:45 +0800 Subject: [PATCH 07/26] =?UTF-8?q?=E4=BF=AE=E5=A4=8DNPE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flow/step_node/intent_node/impl/base_intent_node.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index c2c78cbebc4..dcb0e64748d 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -73,7 +73,7 @@ def execute(self, model_id, prompt_template, dialogue_number, history_chat_recor self.context['user_input'] = user_input # 构建分类提示词 - prompt_template = self.workflow_manage.generate_prompt(prompt_template) + prompt_template = self.workflow_manage.generate_prompt(prompt_template) if prompt_template else None prompt = self.build_classification_prompt(prompt_template, user_input, branch, output_reason) self.context['system'] = prompt From 7168af41a2449da73da3508aefecb1986b06331c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 18:18:16 +0800 Subject: [PATCH 08/26] fix tooltip --- ui/src/locales/lang/en-US/views/application.ts | 2 +- ui/src/locales/lang/zh-CN/views/application.ts | 2 +- ui/src/locales/lang/zh-Hant/views/application.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/src/locales/lang/en-US/views/application.ts b/ui/src/locales/lang/en-US/views/application.ts index aa181d17dff..46f2abfd0c7 100644 --- a/ui/src/locales/lang/en-US/views/application.ts +++ b/ui/src/locales/lang/en-US/views/application.ts @@ -90,7 +90,7 @@ export default { prompt_template: { label: 'Prompt Template', requiredMessage: 'Please enter Prompt template', - tooltip: 'Please pay attention to the placeholders `{xxx}` in the template', + tooltip: 'Please pay attention to the placeholders `{{xxx}}` in the template', }, historyRecord: { label: 'Chat History', diff --git a/ui/src/locales/lang/zh-CN/views/application.ts b/ui/src/locales/lang/zh-CN/views/application.ts index 3527aaad907..fae5a92645e 100644 --- a/ui/src/locales/lang/zh-CN/views/application.ts +++ b/ui/src/locales/lang/zh-CN/views/application.ts @@ -83,7 +83,7 @@ export default { prompt_template: { label: '提示词模板', requiredMessage: '请输入提示词模板', - tooltip: '请注意模板中的占位符 `{xxx}`', + tooltip: '请注意模板中的占位符 `{{xxx}}`', }, historyRecord: { label: '历史聊天记录', diff --git a/ui/src/locales/lang/zh-Hant/views/application.ts b/ui/src/locales/lang/zh-Hant/views/application.ts index ab3b9ed2217..5f9441de33d 100644 --- a/ui/src/locales/lang/zh-Hant/views/application.ts +++ b/ui/src/locales/lang/zh-Hant/views/application.ts @@ -83,7 +83,7 @@ export default { prompt_template: { label: '提示詞模板', requiredMessage: '請輸入提示詞模板', - tooltip: '請注意模板中的佔位符 `{xxx}`', + tooltip: '請注意模板中的佔位符 `{{xxx}}`', }, historyRecord: { label: '歷史對話紀錄', From 51a198fbcfd44219a6b2178e02373ed8d328ba4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 19:27:34 +0800 Subject: [PATCH 09/26] =?UTF-8?q?=E5=B0=8F=E8=B0=83=E6=95=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flow/step_node/intent_node/impl/base_intent_node.py | 6 +++--- ui/src/locales/lang/en-US/views/application.ts | 2 +- ui/src/locales/lang/zh-CN/views/application.ts | 2 +- ui/src/locales/lang/zh-Hant/views/application.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index dcb0e64748d..803af7b6ed8 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -154,11 +154,11 @@ def build_classification_prompt(self, prompt_template: str, user_input: str, bra classification_id += 1 # 构建输出JSON结构 - output_reason = ', "reason": ""' if output_reason is True else '' - output_json = f'{{"classificationId": 0{output_reason}}}' + output_reason = ',\n "reason": ""' if output_reason is True else '' + output_json = f'{{\n "classificationId": 0{output_reason}\n}}' return (prompt_template or DEFAULT_PROMPT_TEMPLATE).format( - classification_list=classification_list, + classification_list=json.dumps(classification_list, ensure_ascii=False), user_input=user_input, output_json=output_json ) diff --git a/ui/src/locales/lang/en-US/views/application.ts b/ui/src/locales/lang/en-US/views/application.ts index 46f2abfd0c7..666b623b5ea 100644 --- a/ui/src/locales/lang/en-US/views/application.ts +++ b/ui/src/locales/lang/en-US/views/application.ts @@ -90,7 +90,7 @@ export default { prompt_template: { label: 'Prompt Template', requiredMessage: 'Please enter Prompt template', - tooltip: 'Please pay attention to the placeholders `{{xxx}}` in the template', + tooltip: 'Please pay attention to the placeholders in the template', }, historyRecord: { label: 'Chat History', diff --git a/ui/src/locales/lang/zh-CN/views/application.ts b/ui/src/locales/lang/zh-CN/views/application.ts index fae5a92645e..8b1cbf5244a 100644 --- a/ui/src/locales/lang/zh-CN/views/application.ts +++ b/ui/src/locales/lang/zh-CN/views/application.ts @@ -83,7 +83,7 @@ export default { prompt_template: { label: '提示词模板', requiredMessage: '请输入提示词模板', - tooltip: '请注意模板中的占位符 `{{xxx}}`', + tooltip: '请注意模板中的占位符', }, historyRecord: { label: '历史聊天记录', diff --git a/ui/src/locales/lang/zh-Hant/views/application.ts b/ui/src/locales/lang/zh-Hant/views/application.ts index 5f9441de33d..984549ce911 100644 --- a/ui/src/locales/lang/zh-Hant/views/application.ts +++ b/ui/src/locales/lang/zh-Hant/views/application.ts @@ -83,7 +83,7 @@ export default { prompt_template: { label: '提示詞模板', requiredMessage: '請輸入提示詞模板', - tooltip: '請注意模板中的佔位符 `{{xxx}}`', + tooltip: '請注意模板中的佔位符', }, historyRecord: { label: '歷史對話紀錄', From 2f5c472532d5b7c15f828cb7bc29d786be38dffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 19:54:52 +0800 Subject: [PATCH 10/26] =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/components/execution-detail-card/index.vue | 8 ++++---- ui/src/styles/app.scss | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ui/src/components/execution-detail-card/index.vue b/ui/src/components/execution-detail-card/index.vue index e68bc472e78..931f6df3cc9 100644 --- a/ui/src/components/execution-detail-card/index.vue +++ b/ui/src/components/execution-detail-card/index.vue @@ -193,7 +193,7 @@ {{ $t('views.application.form.roleSettings.label') }}
- {{ data.system || '-' }} +
{{ data.system || '-' }}
@@ -256,7 +256,7 @@ {{ $t('views.application.form.roleSettings.label') }}
- {{ data.system || '-' }} +
{{ data.system || '-' }}
@@ -545,7 +545,7 @@ {{ $t('views.application.form.roleSettings.label') }}
- {{ data.system || '-' }} +
{{ data.system || '-' }}
@@ -631,7 +631,7 @@ {{ $t('views.application.form.roleSettings.label') }}
- {{ data.system || '-' }} +
{{ data.system || '-' }}
diff --git a/ui/src/styles/app.scss b/ui/src/styles/app.scss index 6faec97f19c..b56acff0718 100644 --- a/ui/src/styles/app.scss +++ b/ui/src/styles/app.scss @@ -18,7 +18,7 @@ html { font-size: 100%; } -body { +body, .card-never pre { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; font-family: 'PingFang SC', AlibabaPuHuiTi !important; From 5e3d5955f1566dd6884c7b3985ab62bb521bf3ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 20:06:56 +0800 Subject: [PATCH 11/26] =?UTF-8?q?=E5=BD=93=E4=B8=8D=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E7=90=86=E7=94=B1=E6=97=B6=EF=BC=8C=E6=97=A0=E9=9C=80=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E7=90=86=E7=94=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flow/step_node/intent_node/impl/base_intent_node.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index 803af7b6ed8..6a65720727f 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -97,7 +97,7 @@ def execute(self, model_id, prompt_template, dialogue_number, history_chat_recor 'history_message': history_message, 'user_input': user_input, 'branch_id': matched_branch['id'], - 'reason': self.parse_result_reason(r.content), + 'reason': self.parse_result_reason(r.content) if output_reason is True else '', 'category': matched_branch.get('content', matched_branch['id']) }, {}, _write_context=write_context) @@ -154,8 +154,8 @@ def build_classification_prompt(self, prompt_template: str, user_input: str, bra classification_id += 1 # 构建输出JSON结构 - output_reason = ',\n "reason": ""' if output_reason is True else '' - output_json = f'{{\n "classificationId": 0{output_reason}\n}}' + output_reason = ', "reason": ""' if output_reason is True else '' + output_json = f'{{"classificationId": 0{output_reason}}}' return (prompt_template or DEFAULT_PROMPT_TEMPLATE).format( classification_list=json.dumps(classification_list, ensure_ascii=False), From a39b3a5038ff44d921a2156fcb659c627a8a1e2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 20:08:14 +0800 Subject: [PATCH 12/26] =?UTF-8?q?=E5=B0=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flow/step_node/intent_node/impl/base_intent_node.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index 6a65720727f..28b4ac1a6dc 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -154,8 +154,8 @@ def build_classification_prompt(self, prompt_template: str, user_input: str, bra classification_id += 1 # 构建输出JSON结构 - output_reason = ', "reason": ""' if output_reason is True else '' - output_json = f'{{"classificationId": 0{output_reason}}}' + output_reason = ',\n"reason": ""' if output_reason is True else '' + output_json = f'{{\n"classificationId": 0{output_reason}\n}}' return (prompt_template or DEFAULT_PROMPT_TEMPLATE).format( classification_list=json.dumps(classification_list, ensure_ascii=False), From 425d82b62003ec312adaca1723b9ece40ae15160 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 20:21:20 +0800 Subject: [PATCH 13/26] =?UTF-8?q?=E9=A1=BA=E4=BE=BF=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=87=A0=E4=B8=AA=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/application/serializers/application_chat_record.py | 3 +-- apps/chat/serializers/chat_record.py | 2 +- apps/knowledge/serializers/paragraph.py | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/application/serializers/application_chat_record.py b/apps/application/serializers/application_chat_record.py index 540d9310dd9..92946bbdc01 100644 --- a/apps/application/serializers/application_chat_record.py +++ b/apps/application/serializers/application_chat_record.py @@ -104,7 +104,6 @@ def is_valid(self, *, raise_exception=False): def list(self, with_valid=True): if with_valid: self.is_valid(raise_exception=True) - QuerySet(ChatRecord).filter(chat_id=self.data.get('chat_id')) order_by = 'create_time' if self.data.get('order_asc') is None or self.data.get( 'order_asc') else '-create_time' return [ChatRecordSerializerModel(chat_record).data for chat_record in @@ -169,7 +168,7 @@ def reset_chat_record(chat_record, show_source, show_exec): 'padding_problem_text': chat_record.details.get('problem_padding').get( 'padding_problem_text') if 'problem_padding' in chat_record.details else None, **(show_source_dict if show_source else {}), - **(show_exec_dict if show_exec else show_exec_dict) + **(show_exec_dict if show_exec else {}) } def page(self, current_page: int, page_size: int, with_valid=True, show_source=None, show_exec=None): diff --git a/apps/chat/serializers/chat_record.py b/apps/chat/serializers/chat_record.py index d094216f53f..dd7e4acafee 100644 --- a/apps/chat/serializers/chat_record.py +++ b/apps/chat/serializers/chat_record.py @@ -76,7 +76,7 @@ def vote(self, instance: Dict, with_valid=True): chat_record_details_model.vote_reason = vote_reason chat_record_details_model.vote_other_content = vote_other_content - if vote_status == VoteChoices.TRAMPLE: + elif vote_status == VoteChoices.TRAMPLE: # 点踩 chat_record_details_model.vote_status = VoteChoices.TRAMPLE chat_record_details_model.vote_reason = vote_reason diff --git a/apps/knowledge/serializers/paragraph.py b/apps/knowledge/serializers/paragraph.py index a1df1bd8100..c3a36c2b2ba 100644 --- a/apps/knowledge/serializers/paragraph.py +++ b/apps/knowledge/serializers/paragraph.py @@ -226,7 +226,6 @@ def edit(self, instance: Dict): return self.one(), instance, self.data.get('knowledge_id') def get_problem_list(self): - ProblemParagraphMapping(ProblemParagraphMapping) problem_paragraph_mapping = QuerySet(ProblemParagraphMapping).filter( paragraph_id=self.data.get("paragraph_id")) if len(problem_paragraph_mapping) > 0: From bc1113d4c366bf72725192a85d9b33a66abacef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 20:52:32 +0800 Subject: [PATCH 14/26] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E7=82=B9=E7=9A=84y=E5=9D=90=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/workflow/nodes/intent-classify-node/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/src/workflow/nodes/intent-classify-node/index.ts b/ui/src/workflow/nodes/intent-classify-node/index.ts index c39167e9294..5b1a3e18bb1 100644 --- a/ui/src/workflow/nodes/intent-classify-node/index.ts +++ b/ui/src/workflow/nodes/intent-classify-node/index.ts @@ -48,11 +48,11 @@ class IntentModel extends AppNodeModel { if (branch_condition_list) { - const FORM_ITEMS_HEIGHT = 397 // 上方表单占用高度 - + const FORM_ITEMS_HEIGHT = 543 // 上方表单占用高度 + for (let index = 0; index < branch_condition_list.length; index++) { const element = branch_condition_list[index] - + anchors.push({ x: x + width / 2 - 10, y: showNode From 9c891130aaefd9bdb59f08c8282ef6a62ef27069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 20:59:38 +0800 Subject: [PATCH 15/26] =?UTF-8?q?=E5=B0=8F=E8=B0=83=E6=95=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flow/step_node/intent_node/impl/base_intent_node.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index 28b4ac1a6dc..52814190586 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -191,7 +191,7 @@ def get_branch_by_id(category_id: int): try: classification_id = None - # 如果返回长度小于5,先尝试解析为数字(增加自由度:自定义提示词模板时,可提示大模型只输出ID值) + # 如果返回长度小于5,先尝试解析为数字(增加自由度:自定义提示词模板时,可提示大模型只输出意图分类的ID值) if len(result) < 5: classification_id = self.to_int(result) @@ -223,7 +223,7 @@ def parse_result_reason(self, result: str): try: result_json = json.loads(result) return result_json.get('reason', '') - except Exception as e: + except Exception: reason_patterns = [ r'"reason":\s*"([^"]*)"', # 标准格式 r'"reason":\s*"([^"]*)', # 缺少结束引号 From 625ce9b97248e68761274b9d6c9079b845caafca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 21:09:49 +0800 Subject: [PATCH 16/26] =?UTF-8?q?=E5=B0=8F=E8=B0=83=E6=95=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/workflow/nodes/intent-classify-node/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/workflow/nodes/intent-classify-node/index.ts b/ui/src/workflow/nodes/intent-classify-node/index.ts index 5b1a3e18bb1..406a66f5278 100644 --- a/ui/src/workflow/nodes/intent-classify-node/index.ts +++ b/ui/src/workflow/nodes/intent-classify-node/index.ts @@ -48,7 +48,7 @@ class IntentModel extends AppNodeModel { if (branch_condition_list) { - const FORM_ITEMS_HEIGHT = 543 // 上方表单占用高度 + const FORM_ITEMS_HEIGHT = 542 // 上方表单占用高度 for (let index = 0; index < branch_condition_list.length; index++) { const element = branch_condition_list[index] From 384024ae585eceeffe9d8d0183e04248f2da0b48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 21:41:00 +0800 Subject: [PATCH 17/26] =?UTF-8?q?=E7=AE=80=E5=8C=96=E6=84=8F=E5=9B=BE?= =?UTF-8?q?=E8=AF=86=E5=88=AB=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../intent_node/impl/base_intent_node.py | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index 52814190586..38ea4df1ed0 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -66,7 +66,7 @@ def execute(self, model_id, prompt_template, dialogue_number, history_chat_recor ) # 获取历史对话 - history_message = self.get_history_message(history_chat_record, dialogue_number) + history_message = self.get_history_message(history_chat_record, dialogue_number) if history_chat_record and dialogue_number > 0 else [] self.context['history_message'] = history_message # 保存问题到上下文 @@ -78,8 +78,7 @@ def execute(self, model_id, prompt_template, dialogue_number, history_chat_recor self.context['system'] = prompt # 生成消息列表 - system = self.build_system_prompt() - message_list = self.generate_message_list(system, prompt, history_message) + message_list = self.generate_message_list(prompt, history_message) self.context['message_list'] = message_list # 调用模型进行分类 @@ -127,10 +126,6 @@ def get_history_message(history_chat_record, dialogue_number): message.content = re.sub('[\d\D]*?<\/form_rander>', '', message.content) return history_message - def build_system_prompt(self) -> str: - """构建系统提示词""" - return "你是一个专业的意图识别助手,请根据用户输入和意图选项,准确识别用户的真实意图。" - def build_classification_prompt(self, prompt_template: str, user_input: str, branch: List[Dict], output_reason: bool) -> str: """构建分类提示词""" @@ -163,13 +158,9 @@ def build_classification_prompt(self, prompt_template: str, user_input: str, bra output_json=output_json ) - def generate_message_list(self, system: str, prompt: str, history_message): + def generate_message_list(self, prompt: str, history_message): """生成消息列表""" - if system is None or len(system) == 0: - return [*history_message, HumanMessage(self.workflow_manage.generate_prompt(prompt))] - else: - return [SystemMessage(self.workflow_manage.generate_prompt(system)), *history_message, - HumanMessage(self.workflow_manage.generate_prompt(prompt))] + return [*history_message, HumanMessage(self.workflow_manage.generate_prompt(prompt))] def parse_classification_result(self, result: str, branch: List[Dict]) -> Dict[str, Any]: """解析分类结果""" From c98eb261e99f31ee5cc9ce04378acb6068c828f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Wed, 25 Mar 2026 09:20:03 +0800 Subject: [PATCH 18/26] =?UTF-8?q?=E6=B3=A8=E9=87=8A=E5=B0=8F=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flow/step_node/intent_node/impl/base_intent_node.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index 38ea4df1ed0..79d6e92e061 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -182,7 +182,7 @@ def get_branch_by_id(category_id: int): try: classification_id = None - # 如果返回长度小于5,先尝试解析为数字(增加自由度:自定义提示词模板时,可提示大模型只输出意图分类的ID值) + # 如果长度小于5,先尝试解析为数字(增加自由度,在自定义提示词模板时,可提示大模型只输出意图分类的ID值) if len(result) < 5: classification_id = self.to_int(result) From 3fdb5a7ea97e448585447498f9cfccfe6f1def8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Tue, 24 Mar 2026 15:19:41 +0800 Subject: [PATCH 19/26] fix: fix the style of the ai-chat-node --- ui/src/workflow/nodes/ai-chat-node/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/workflow/nodes/ai-chat-node/index.vue b/ui/src/workflow/nodes/ai-chat-node/index.vue index 32347b2d07e..b9f74448a7f 100644 --- a/ui/src/workflow/nodes/ai-chat-node/index.vue +++ b/ui/src/workflow/nodes/ai-chat-node/index.vue @@ -44,7 +44,7 @@
-
+
Date: Wed, 25 Mar 2026 10:44:43 +0800 Subject: [PATCH 20/26] =?UTF-8?q?=E6=84=8F=E5=9B=BE=E8=AF=86=E5=88=AB?= =?UTF-8?q?=EF=BC=9A=E6=8F=90=E7=A4=BA=E8=AF=8D=E6=A8=A1=E6=9D=BF=EF=BC=8C?= =?UTF-8?q?=E5=8C=BA=E5=88=86=E8=AF=AD=E8=A8=80=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/locales/lang/en-US/workflow.ts | 26 ++++++++++++++++- ui/src/locales/lang/zh-CN/workflow.ts | 24 +++++++++++++++ ui/src/locales/lang/zh-Hant/workflow.ts | 24 +++++++++++++++ .../nodes/intent-classify-node/index.vue | 29 ++----------------- 4 files changed, 76 insertions(+), 27 deletions(-) diff --git a/ui/src/locales/lang/en-US/workflow.ts b/ui/src/locales/lang/en-US/workflow.ts index 45e6b89ce09..7b24d918972 100644 --- a/ui/src/locales/lang/en-US/workflow.ts +++ b/ui/src/locales/lang/en-US/workflow.ts @@ -188,7 +188,7 @@ export default { result: 'Search Results', searchParam: 'Search Parameters', select_variable: 'Select Variable', - valueMessage: `Value or name `, + valueMessage: 'Value or name', searchQuestion: { label: 'Search Question', @@ -451,6 +451,30 @@ You are a master of problem optimization, adept at accurately inferring user int input: { label: 'Input', }, + default_prompt_template: `# Role +You are an intention classification expert, good at being able to judge which classification the user's input belongs to. + +## Skills +Skill 1: Clearly determine which of the following intention classifications the user's input belongs to. +Intention classification list: +{classification_list} + +Note: +- Please determine the match between the user's input content and the Intention classification list content, without judging or categorizing the match with the classification ID. +- **When classifying, you must give higher weight to the context and intent continuity shown in the historical conversation. Do not rely solely on the literal meaning of the current input; instead, prioritize the most consistent classification with the previous dialogue flow.** + +## User Input +{user_input} + +## Reply requirements +- The answer must be returned in JSON format. +- Strictly ensure that the output is in a valid JSON format. +- Do not add prefix \`\`\`json or suffix \`\`\` +- The answer needs to include the following fields such as: +{output_json} + +## Limit +- Please do not reply in text.`, }, applicationNode: { label: 'Agent Node', diff --git a/ui/src/locales/lang/zh-CN/workflow.ts b/ui/src/locales/lang/zh-CN/workflow.ts index f26c485455d..3fa4e620d27 100644 --- a/ui/src/locales/lang/zh-CN/workflow.ts +++ b/ui/src/locales/lang/zh-CN/workflow.ts @@ -443,6 +443,30 @@ export default { input: { label: '输入', }, + default_prompt_template: `# 角色 +你是一位意图分类专家,擅长判断用户输入属于哪个分类。 + +## 技能 +技能1:明确判断用户输入属于以下哪种意图分类。 +意图分类列表: +{classification_list} + +注: +- 请判断用户输入内容与意图分类列表内容之间的匹配度,注意不要以分类ID作为评判或归类的依据。 +- **在分类时,必须更加重视历史对话中表现的上下文和意图连贯性。不要仅依赖当前输入的字面意思;相反,应优先考虑与先前对话流程最匹配的分类。** + +## 用户输入 +{user_input} + +## 回复要求 +- 回复内容必须以JSON格式返回。 +- 严格确保输出为有效的JSON格式。 +- 不要添加前缀 \`\`\`json 或 后缀 \`\`\` +- 回复内容需要包含以下字段: +{output_json} + +## 限制 +- 请勿以文本形式回复。`, }, applicationNode: { label: '智能体节点', diff --git a/ui/src/locales/lang/zh-Hant/workflow.ts b/ui/src/locales/lang/zh-Hant/workflow.ts index 7ca169be920..3d01130e9b5 100644 --- a/ui/src/locales/lang/zh-Hant/workflow.ts +++ b/ui/src/locales/lang/zh-Hant/workflow.ts @@ -443,6 +443,30 @@ export default { input: { label: '輸入', }, + default_prompt_template: `# 角色 +你是一位意圖分類專家,擅長判斷用戶輸入屬於哪個分類。 + +## 技能 +技能1:明確判斷用戶輸入屬於以下哪種意圖分類。 +意圖分類列表: +{classification_list} + +注: +- 請判斷用戶輸入內容與意圖分類列表內容之間的匹配度,注意不要以分類ID作爲評判或歸類的依據。 +- **在分類時,必須更加重視歷史對話中表現的上下文和意圖連貫性。不要僅依賴當前輸入的字面意思;相反,應優先考慮與先前對話流程最匹配的分類。** + +## 用戶輸入 +{user_input} + +## 回覆要求 +- 回覆內容必須以JSON格式返回。 +- 嚴格確保輸出爲有效的JSON格式。 +- 不要添加前綴 \`\`\`json 或 後綴 \`\`\` +- 回覆內容需要包含以下字段: +{output_json} + +## 限制 +- 請勿以文本形式回覆。`, }, applicationNode: { label: '智能體節點', diff --git a/ui/src/workflow/nodes/intent-classify-node/index.vue b/ui/src/workflow/nodes/intent-classify-node/index.vue index d809aac1b1d..e9143f35f32 100644 --- a/ui/src/workflow/nodes/intent-classify-node/index.vue +++ b/ui/src/workflow/nodes/intent-classify-node/index.vue @@ -324,34 +324,11 @@ const model_change = (model_id?: string) => { } } -const defaultPromptTemplate = `# Role -You are an intention classification expert, good at being able to judge which classification the user's input belongs to. - -## Skills -Skill 1: Clearly determine which of the following intention classifications the user's input belongs to. -Intention classification list: -{classification_list} - -Note: -- Please determine the match between the user's input content and the Intention classification list content, without judging or categorizing the match with the classification ID. -- **When classifying, you must give higher weight to the context and intent continuity shown in the historical conversation. Do not rely solely on the literal meaning of the current input; instead, prioritize the most consistent classification with the previous dialogue flow.** - -## User Input -{user_input} - -## Reply requirements -- The answer must be returned in JSON format. -- Strictly ensure that the output is in a valid JSON format. -- Do not add prefix \`\`\`json or suffix \`\`\` -- The answer needs to include the following fields such as: -{output_json} - -## Limit -- Please do not reply in text.` +const default_prompt_template = t('workflow.nodes.intentNode.other') const form = { model_id: '', - prompt_template: defaultPromptTemplate, + prompt_template: default_prompt_template, branch: [ { id: randomId(), @@ -386,7 +363,7 @@ const form_data = computed({ get: () => { if (props.nodeModel.properties.node_data) { if (!props.nodeModel.properties.node_data.prompt_template) { - set(props.nodeModel.properties.node_data, 'prompt_template', defaultPromptTemplate) + set(props.nodeModel.properties.node_data, 'prompt_template', default_prompt_template) } return props.nodeModel.properties.node_data } else { From 5380ff3f3d5807b9b3386b0a859d87e9d339e674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Wed, 25 Mar 2026 11:01:40 +0800 Subject: [PATCH 21/26] =?UTF-8?q?=E5=B0=8F=E8=B0=83=E6=95=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/workflow/nodes/intent-classify-node/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/workflow/nodes/intent-classify-node/index.vue b/ui/src/workflow/nodes/intent-classify-node/index.vue index e9143f35f32..f8fe0a6cfb0 100644 --- a/ui/src/workflow/nodes/intent-classify-node/index.vue +++ b/ui/src/workflow/nodes/intent-classify-node/index.vue @@ -324,7 +324,7 @@ const model_change = (model_id?: string) => { } } -const default_prompt_template = t('workflow.nodes.intentNode.other') +const default_prompt_template = t('workflow.nodes.intentNode.default_prompt_template') const form = { model_id: '', From 596485b6d0db7ed61d2c3740f85e76be50e268c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Wed, 25 Mar 2026 11:12:21 +0800 Subject: [PATCH 22/26] =?UTF-8?q?=E5=B0=8F=E8=B0=83=E6=95=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flow/step_node/intent_node/impl/base_intent_node.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index 79d6e92e061..415fc69ba3d 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -126,7 +126,7 @@ def get_history_message(history_chat_record, dialogue_number): message.content = re.sub('[\d\D]*?<\/form_rander>', '', message.content) return history_message - def build_classification_prompt(self, prompt_template: str, user_input: str, branch: List[Dict], output_reason: bool) -> str: + def build_classification_prompt(self, prompt_template: str, user_input: str, branch: List[Dict], reason_field: bool) -> str: """构建分类提示词""" classification_list = [] @@ -149,8 +149,8 @@ def build_classification_prompt(self, prompt_template: str, user_input: str, bra classification_id += 1 # 构建输出JSON结构 - output_reason = ',\n"reason": ""' if output_reason is True else '' - output_json = f'{{\n"classificationId": 0{output_reason}\n}}' + reason_field = ',\n"reason": ""' if reason_field is True else '' + output_json = f'{{\n"classificationId": 0{reason_field}\n}}' return (prompt_template or DEFAULT_PROMPT_TEMPLATE).format( classification_list=json.dumps(classification_list, ensure_ascii=False), From 19cb98f7e0bd206443b7e354c343b64183bae5a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Wed, 25 Mar 2026 11:24:58 +0800 Subject: [PATCH 23/26] =?UTF-8?q?=E5=B0=8F=E8=B0=83=E6=95=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/workflow/nodes/intent-classify-node/index.vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ui/src/workflow/nodes/intent-classify-node/index.vue b/ui/src/workflow/nodes/intent-classify-node/index.vue index f8fe0a6cfb0..b2c17cb334c 100644 --- a/ui/src/workflow/nodes/intent-classify-node/index.vue +++ b/ui/src/workflow/nodes/intent-classify-node/index.vue @@ -324,7 +324,11 @@ const model_change = (model_id?: string) => { } } -const default_prompt_template = t('workflow.nodes.intentNode.default_prompt_template') +const default_prompt_template = t('workflow.nodes.intentNode.default_prompt_template', { + classification_list: '{classification_list}', + user_input: '{user_input}', + output_json: '{output_json}', +}) const form = { model_id: '', From 480277e0d43b88ae64aa952aa4f565b39dd46ed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Wed, 25 Mar 2026 12:52:12 +0800 Subject: [PATCH 24/26] =?UTF-8?q?=E6=8F=90=E7=A4=BA=E8=AF=8D=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/locales/lang/en-US/views/application.ts | 2 +- ui/src/locales/lang/zh-CN/views/application.ts | 2 +- ui/src/locales/lang/zh-Hant/views/application.ts | 2 +- ui/src/workflow/nodes/intent-classify-node/index.vue | 6 +++++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ui/src/locales/lang/en-US/views/application.ts b/ui/src/locales/lang/en-US/views/application.ts index 666b623b5ea..7bd7272cae2 100644 --- a/ui/src/locales/lang/en-US/views/application.ts +++ b/ui/src/locales/lang/en-US/views/application.ts @@ -90,7 +90,7 @@ export default { prompt_template: { label: 'Prompt Template', requiredMessage: 'Please enter Prompt template', - tooltip: 'Please pay attention to the placeholders in the template', + tooltip: 'Please pay attention to the placeholders in the template: {classification_list}、{user_input}、{output_json}', }, historyRecord: { label: 'Chat History', diff --git a/ui/src/locales/lang/zh-CN/views/application.ts b/ui/src/locales/lang/zh-CN/views/application.ts index 8b1cbf5244a..72e414202ed 100644 --- a/ui/src/locales/lang/zh-CN/views/application.ts +++ b/ui/src/locales/lang/zh-CN/views/application.ts @@ -83,7 +83,7 @@ export default { prompt_template: { label: '提示词模板', requiredMessage: '请输入提示词模板', - tooltip: '请注意模板中的占位符', + tooltip: '请注意模板中的占位符: {classification_list}、{user_input}、{output_json}', }, historyRecord: { label: '历史聊天记录', diff --git a/ui/src/locales/lang/zh-Hant/views/application.ts b/ui/src/locales/lang/zh-Hant/views/application.ts index 984549ce911..c2fc674ca07 100644 --- a/ui/src/locales/lang/zh-Hant/views/application.ts +++ b/ui/src/locales/lang/zh-Hant/views/application.ts @@ -83,7 +83,7 @@ export default { prompt_template: { label: '提示詞模板', requiredMessage: '請輸入提示詞模板', - tooltip: '請注意模板中的佔位符', + tooltip: '請注意模板中的佔位符: {classification_list}、{user_input}、{output_json}', }, historyRecord: { label: '歷史對話紀錄', diff --git a/ui/src/workflow/nodes/intent-classify-node/index.vue b/ui/src/workflow/nodes/intent-classify-node/index.vue index b2c17cb334c..4bbca4a2369 100644 --- a/ui/src/workflow/nodes/intent-classify-node/index.vue +++ b/ui/src/workflow/nodes/intent-classify-node/index.vue @@ -69,7 +69,11 @@ >
- +
From cc9bbfb65f8a1e51d51f1cb50dfa0b740ba6341d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Wed, 25 Mar 2026 13:15:07 +0800 Subject: [PATCH 25/26] revert --- apps/application/serializers/application_chat_record.py | 3 ++- apps/chat/serializers/chat_record.py | 2 +- apps/knowledge/serializers/paragraph.py | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/application/serializers/application_chat_record.py b/apps/application/serializers/application_chat_record.py index 92946bbdc01..540d9310dd9 100644 --- a/apps/application/serializers/application_chat_record.py +++ b/apps/application/serializers/application_chat_record.py @@ -104,6 +104,7 @@ def is_valid(self, *, raise_exception=False): def list(self, with_valid=True): if with_valid: self.is_valid(raise_exception=True) + QuerySet(ChatRecord).filter(chat_id=self.data.get('chat_id')) order_by = 'create_time' if self.data.get('order_asc') is None or self.data.get( 'order_asc') else '-create_time' return [ChatRecordSerializerModel(chat_record).data for chat_record in @@ -168,7 +169,7 @@ def reset_chat_record(chat_record, show_source, show_exec): 'padding_problem_text': chat_record.details.get('problem_padding').get( 'padding_problem_text') if 'problem_padding' in chat_record.details else None, **(show_source_dict if show_source else {}), - **(show_exec_dict if show_exec else {}) + **(show_exec_dict if show_exec else show_exec_dict) } def page(self, current_page: int, page_size: int, with_valid=True, show_source=None, show_exec=None): diff --git a/apps/chat/serializers/chat_record.py b/apps/chat/serializers/chat_record.py index dd7e4acafee..d094216f53f 100644 --- a/apps/chat/serializers/chat_record.py +++ b/apps/chat/serializers/chat_record.py @@ -76,7 +76,7 @@ def vote(self, instance: Dict, with_valid=True): chat_record_details_model.vote_reason = vote_reason chat_record_details_model.vote_other_content = vote_other_content - elif vote_status == VoteChoices.TRAMPLE: + if vote_status == VoteChoices.TRAMPLE: # 点踩 chat_record_details_model.vote_status = VoteChoices.TRAMPLE chat_record_details_model.vote_reason = vote_reason diff --git a/apps/knowledge/serializers/paragraph.py b/apps/knowledge/serializers/paragraph.py index c3a36c2b2ba..a1df1bd8100 100644 --- a/apps/knowledge/serializers/paragraph.py +++ b/apps/knowledge/serializers/paragraph.py @@ -226,6 +226,7 @@ def edit(self, instance: Dict): return self.one(), instance, self.data.get('knowledge_id') def get_problem_list(self): + ProblemParagraphMapping(ProblemParagraphMapping) problem_paragraph_mapping = QuerySet(ProblemParagraphMapping).filter( paragraph_id=self.data.get("paragraph_id")) if len(problem_paragraph_mapping) > 0: From 6e457590f30b2929818dab751004499f9bcec19b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Wed, 25 Mar 2026 17:39:48 +0800 Subject: [PATCH 26/26] =?UTF-8?q?=E5=90=91=E4=B8=8B=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flow/step_node/intent_node/impl/base_intent_node.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py index 254fc5935fb..454e60ea18f 100644 --- a/apps/application/flow/step_node/intent_node/impl/base_intent_node.py +++ b/apps/application/flow/step_node/intent_node/impl/base_intent_node.py @@ -105,7 +105,7 @@ def execute(self, model_id, prompt_template, dialogue_number, history_chat_recor 'history_message': history_message, 'user_input': user_input, 'branch_id': matched_branch['id'], - 'reason': self.parse_result_reason(r.content) if output_reason is True else '', + 'reason': self.parse_result_reason(r.content) if output_reason is not False else '', 'category': matched_branch.get('content', matched_branch['id']) }, {}, _write_context=write_context) @@ -135,7 +135,7 @@ def get_history_message(history_chat_record, dialogue_number): message.content = re.sub('[\d\D]*?<\/form_rander>', '', message.content) return history_message - def build_classification_prompt(self, prompt_template: str, user_input: str, branch: List[Dict], reason_field: bool) -> str: + def build_classification_prompt(self, prompt_template: str, user_input: str, branch: List[Dict], output_reason: bool) -> str: """构建分类提示词""" classification_list = [] @@ -158,7 +158,7 @@ def build_classification_prompt(self, prompt_template: str, user_input: str, bra classification_id += 1 # 构建输出JSON结构 - reason_field = ',\n"reason": ""' if reason_field is True else '' + reason_field = ',\n"reason": ""' if output_reason is not False else '' output_json = f'{{\n"classificationId": 0{reason_field}\n}}' return (prompt_template or DEFAULT_PROMPT_TEMPLATE).format(