From b87b5bfd348b07c4651f010a83099a9efba3f150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E8=89=AF?= <841369634@qq.com> Date: Wed, 6 May 2026 15:41:29 +0800 Subject: [PATCH] feat: Configurable output of `reason` for `Intent recognition` --- .../flow/step_node/intent_node/i_intent_node.py | 1 + .../intent_node/impl/base_intent_node.py | 15 ++++++++++----- .../intent_node/impl/prompt_template.py | 5 +---- .../components/execution-detail-card/index.vue | 2 +- ui/src/locales/lang/en-US/workflow.ts | 7 ++++--- ui/src/locales/lang/zh-CN/workflow.ts | 7 ++++--- ui/src/locales/lang/zh-Hant/workflow.ts | 7 ++++--- .../nodes/intent-classify-node/index.vue | 17 +++++++++++++++++ 8 files changed, 42 insertions(+), 19 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 d22d321c842..30c15001bc4 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 @@ -26,6 +26,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, default=True, label=_("Output reason")) 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 b3f1608acc2..cf7ac4cabe7 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, model_id_type=None, model_id_reference=None, **kwargs) -> NodeResult: # 处理引用类型 if model_id_type == 'reference' and model_id_reference: @@ -84,7 +84,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() @@ -106,7 +106,7 @@ def execute(self, model_id, dialogue_number, history_chat_record, user_input, br '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 not False else '', 'category': matched_branch.get('content', matched_branch['id']) }, {}, _write_context=write_context) @@ -140,7 +140,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) -> str: """构建分类提示词""" classification_list = [] @@ -162,9 +162,14 @@ def build_classification_prompt(self, user_input: str, branch: List[Dict]) -> st }) classification_id += 1 + # 构建输出JSON结构, + reason_field = ',\n"reason": ""' if output_reason is not False else '' + output_json = f'{{\n"classificationId": 0{reason_field}\n}}' + return PROMPT_TEMPLATE.format( classification_list=classification_list, - user_input=user_input + user_input=user_input, + 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 1bcfd61743e..831eef61e36 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 @@ -20,10 +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, -"reason": "" -}} +{output_json} ## Limit - Please do not reply in text.""" diff --git a/ui/src/components/execution-detail-card/index.vue b/ui/src/components/execution-detail-card/index.vue index 255ec043837..61622f780ef 100644 --- a/ui/src/components/execution-detail-card/index.vue +++ b/ui/src/components/execution-detail-card/index.vue @@ -281,7 +281,7 @@ {{ $t('chat.executionDetails.currentChat') }}
- {{ data.question || '-' }} + {{ data.question || data.user_input || '-' }}
diff --git a/ui/src/locales/lang/en-US/workflow.ts b/ui/src/locales/lang/en-US/workflow.ts index a192a4faed5..71c535e4945 100644 --- a/ui/src/locales/lang/en-US/workflow.ts +++ b/ui/src/locales/lang/en-US/workflow.ts @@ -210,9 +210,9 @@ You are a master of problem optimization, adept at accurately inferring user int ##Skills ###Skill 1: Optimizing Problems -2. Receive user input questions. -3. Carefully analyze the meaning of the problem based on the context. -4. Output optimized problems. +1. Receive user input questions. +2. Carefully analyze the meaning of the problem based on the context. +3. Output optimized problems. ##Limitations: -Only return the optimized problem without any additional explanation or clarification. @@ -452,6 +452,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 3339952fd16..c3e6539503a 100644 --- a/ui/src/locales/lang/zh-CN/workflow.ts +++ b/ui/src/locales/lang/zh-CN/workflow.ts @@ -210,9 +210,9 @@ export default { ## 技能 ### 技能 1: 优化问题 -2. 接收用户输入的问题。 -3. 依据上下文仔细分析问题含义。 -4. 输出优化后的问题。 +1. 接收用户输入的问题。 +2. 依据上下文仔细分析问题含义。 +3. 输出优化后的问题。 ## 限制: - 仅返回优化后的问题,不进行额外解释或说明。 @@ -444,6 +444,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 be620e9e99e..2c9d83355eb 100644 --- a/ui/src/locales/lang/zh-Hant/workflow.ts +++ b/ui/src/locales/lang/zh-Hant/workflow.ts @@ -210,9 +210,9 @@ export default { ## 技能 ### 技能 1: 優化問題 -2. 接收用戶輸入的問題。 -3. 依據上下文仔細分析問題含義。 -4. 輸出優化後的問題。 +1. 接收用戶輸入的問題。 +2. 依據上下文仔細分析問題含義。 +3. 輸出優化後的問題。 ## 限制: - 僅返回優化後的問題,不進行額外解釋或說明。 @@ -444,6 +444,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 7ed132c959c..b452b89fd6c 100644 --- a/ui/src/workflow/nodes/intent-classify-node/index.vue +++ b/ui/src/workflow/nodes/intent-classify-node/index.vue @@ -163,6 +163,19 @@
+ +
+
+ {{ $t('workflow.nodes.intentNode.output_reason') }} +
+
+ +
+
+
@@ -322,6 +335,7 @@ const form = { ], dialogue_number: 1, content_list: [], + output_reason: true, } function refreshParam(data: any) { @@ -342,6 +356,9 @@ const form_data = computed({ if (!props.nodeModel.properties.node_data.model_id_reference) { set(props.nodeModel.properties.node_data, 'model_id_reference', []) } + if (props.nodeModel.properties.node_data.output_reason == null) { + set(props.nodeModel.properties.node_data, 'output_reason', true) + } return props.nodeModel.properties.node_data } else { set(props.nodeModel.properties, 'node_data', form)