Files
012-kaopeilian/docs/规划/dify 工作流/恩喜-01-知识点分析-考陪练.yml
111 998211c483 feat: 初始化考培练系统项目
- 从服务器拉取完整代码
- 按框架规范整理项目结构
- 配置 Drone CI 测试环境部署
- 包含后端(FastAPI)、前端(Vue3)、管理端

技术栈: Vue3 + TypeScript + FastAPI + MySQL
2026-01-24 19:33:28 +08:00

772 lines
24 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
app:
description: 上传提炼知识点
icon: 🤖
icon_background: '#E4FBCC'
mode: workflow
name: 恩喜-01-知识点分析-考陪练
use_icon_as_answer_icon: false
dependencies:
- current_identifier: null
type: marketplace
value:
marketplace_plugin_unique_identifier: langgenius/openrouter:0.0.22@99ef4cf4e08292c28806abaf24f295ed66e04e4b9e74385b487fd0767c7f56df
version: null
kind: app
version: 0.5.0
workflow:
conversation_variables: []
environment_variables: []
features:
file_upload:
allowed_file_extensions:
- .JPG
- .JPEG
- .PNG
- .GIF
- .WEBP
- .SVG
allowed_file_types:
- image
allowed_file_upload_methods:
- local_file
- remote_url
enabled: false
fileUploadConfig:
audio_file_size_limit: 50
batch_count_limit: 5
file_size_limit: 15
image_file_batch_limit: 10
image_file_size_limit: 10
single_chunk_attachment_limit: 10
video_file_size_limit: 100
workflow_file_upload_limit: 10
image:
enabled: false
number_limits: 3
transfer_methods:
- local_file
- remote_url
number_limits: 3
opening_statement: ''
retriever_resource:
enabled: true
sensitive_word_avoidance:
enabled: false
speech_to_text:
enabled: false
suggested_questions: []
suggested_questions_after_answer:
enabled: false
text_to_speech:
enabled: false
language: ''
voice: ''
graph:
edges:
- data:
isInIteration: false
isInLoop: false
sourceType: document-extractor
targetType: llm
id: 1757513748987-source-1757513757216-target
selected: false
source: '1757513748987'
sourceHandle: source
target: '1757513757216'
targetHandle: target
type: custom
zIndex: 0
- data:
isInIteration: false
isInLoop: false
sourceType: llm
targetType: code
id: 1757513757216-source-1757516212204-target
selected: false
source: '1757513757216'
sourceHandle: source
target: '1757516212204'
targetHandle: target
type: custom
zIndex: 0
- data:
isInIteration: false
isInLoop: false
sourceType: llm
targetType: end
id: 1757513757216-fail-branch-1757572091560-target
selected: false
source: '1757513757216'
sourceHandle: fail-branch
target: '1757572091560'
targetHandle: target
type: custom
zIndex: 0
- data:
isInIteration: false
isInLoop: false
sourceType: code
targetType: end
id: 1757516212204-fail-branch-1757576655478-target
selected: false
source: '1757516212204'
sourceHandle: fail-branch
target: '1757576655478'
targetHandle: target
type: custom
zIndex: 0
- data:
isInIteration: false
isInLoop: false
sourceType: code
targetType: iteration
id: 1757516212204-source-1757687332404-target
selected: false
source: '1757516212204'
sourceHandle: source
target: '1757687332404'
targetHandle: target
type: custom
zIndex: 0
- data:
isInLoop: false
sourceType: iteration
targetType: end
id: 1757687332404-source-1757522230050-target
selected: false
source: '1757687332404'
sourceHandle: source
target: '1757522230050'
targetHandle: target
type: custom
zIndex: 0
- data:
isInIteration: true
isInLoop: false
iteration_id: '1757687332404'
sourceType: iteration-start
targetType: code
id: 1757687332404start-source-1758575376121-target
selected: false
source: 1757687332404start
sourceHandle: source
target: '1758575376121'
targetHandle: target
type: custom
zIndex: 1002
- data:
isInIteration: false
isInLoop: false
sourceType: start
targetType: tool
id: 1757513649648-source-1766636080995-target
source: '1757513649648'
sourceHandle: source
target: '1766636080995'
targetHandle: target
type: custom
zIndex: 0
- data:
isInLoop: false
sourceType: tool
targetType: document-extractor
id: 1766636080995-source-1757513748987-target
source: '1766636080995'
sourceHandle: source
target: '1757513748987'
targetHandle: target
type: custom
zIndex: 0
- data:
isInLoop: false
sourceType: tool
targetType: end
id: 1766636080995-fail-branch-1764240729694-target
source: '1766636080995'
sourceHandle: fail-branch
target: '1764240729694'
targetHandle: target
type: custom
zIndex: 0
- data:
isInIteration: true
isInLoop: false
iteration_id: '1757687332404'
sourceType: code
targetType: tool
id: 1758575376121-source-1766636254081-target
source: '1758575376121'
sourceHandle: source
target: '1766636254081'
targetHandle: target
type: custom
zIndex: 1002
nodes:
- data:
desc: ''
selected: false
title: 开始
type: start
variables:
- allowed_file_extensions: []
allowed_file_types:
- document
- audio
- video
- image
allowed_file_upload_methods:
- local_file
- remote_url
label: file
max_length: 1
options: []
required: true
type: file
variable: file
- label: course_name
max_length: 255
options: []
required: true
type: text-input
variable: course_name
- default: '1'
label: course_id
max_length: 48
options: []
required: true
type: number
variable: course_id
- default: '16'
label: material_id
max_length: 48
options: []
required: true
type: number
variable: material_id
height: 187
id: '1757513649648'
position:
x: 30
y: 283
positionAbsolute:
x: 30
y: 283
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 242
- data:
desc: ''
is_array_file: true
selected: false
title: 文档提取器
type: document-extractor
variable_selector:
- '1757513649648'
- file
height: 104
id: '1757513748987'
position:
x: 934
y: 281
positionAbsolute:
x: 934
y: 281
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 242
- data:
context:
enabled: false
variable_selector: []
desc: ''
error_strategy: fail-branch
model:
completion_params:
temperature: 0.1
mode: chat
name: google/gemini-3-pro-preview
provider: langgenius/openrouter/openrouter
prompt_template:
- id: f0a75809-0e24-491f-bd19-964d8b2eae4c
role: system
text: "# 角色\n你是一个文件拆解高手擅长将用户提交的内容进行精准拆分拆分后的内容做个简单的优化处理使其更具可读性但要尽量使用原文的原词原句。\n\
\n## 技能\n### 技能 1: 内容拆分\n1. 当用户提交内容后,拆分为多段。\n2. 对拆分后的内容做简单优化,使其更具可读性,比如去掉奇怪符号(如换行符、乱码),若语句不通顺,或格式原因导致错位,则重新表达。用户可能会提交录音转文字的内容,因此可能是有错字的,注意修复这些小瑕疵。\n\
3. 优化过程中,尽量使用原文的原词原句,特别是话术类,必须保持原有的句式、保持原词原句,而不是重构。\n4. 注意是拆分而不是重写,不需要润色,尽量不做任何处理。\n\
5. 输出到 content。\n\n### 技能 2: 为每一个选段概括一个标题\n1. 为每个拆分出来的选段概括一个标题,并输出到 title。\n\
\n### 技能 3: 为每一个选段说明与主题的关联\n1. 详细说明这一段与全文核心主题的关联,并输出到 topic_relation。\n\
\n### 技能 4: 为每一个选段打上一个类型标签\n1. 用户提交的内容很有可能是一个课程、一篇讲义、一个产品的说明书,通常是用户希望他公司的员工或高管学习的知识。\n\
2. 用户通常是医疗美容机构或轻医美、生活美容连锁品牌。\n3. 你要为每个选段打上一个知识类型的标签,最好是这几个类型中的一个:\"理论知识\"\
, \"诊断设计\", \"操作步骤\", \"沟通话术\", \"案例分析\", \"注意事项\", \"技巧方法\", \"客诉处理\"\
。当然你也可以为这个选段匹配一个更适合的。\n\n## 输出要求(严格按要求输出)\n请直接输出一个纯净的 JSON 数组Array不要包含\
\ Markdown 标记(如 ```json也不要包含任何解释性文字。格式如下\n\n[\n {\n \"title\":\
\ \"知识点标题\",\n \"content\": \"知识点内容\",\n \"topic_relation\": \"\
知识点与主题的关系\",\n \"type\": \"知识点类型\"\n },\n {\n \"title\": \"第二个知识点标题\"\
,\n \"content\": \"第二个知识点内容...\",\n \"topic_relation\": \"...\"\
,\n \"type\": \"...\"\n }\n]\n\n## 限制\n- 仅围绕用户提交的内容进行拆分和关联标注,不涉及其他无关内容。\n\
- 拆分后的内容必须最大程度保持与原文一致。\n- 关联说明需清晰合理。\n- 不论如何,不要拆分超过 20 段!"
- id: bc1168ad-45de-475e-9365-8791306c8bb3
role: user
text: '课程主题:{{#1757513649648.course_name#}}
## 用户提交的内容:
{{#1757513748987.text#}}
## 注意
- 以json的格式输出
- 不论如何不要拆分超过20 段!'
selected: false
structured_output:
schema:
additionalProperties: false
properties:
content:
description: 知识点内容
type: string
title:
description: 知识点标题
type: string
required:
- title
- content
type: object
structured_output_enabled: false
title: 知识点提取
type: llm
variables: []
vision:
enabled: false
height: 124
id: '1757513757216'
position:
x: 1236
y: 283
positionAbsolute:
x: 1236
y: 283
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 242
- data:
code: "import json\nimport re\ndef main(arg1: str) -> dict:\n # --- 内部辅助函数:清洗文本以适配\
\ SQL ---\n def clean_text_for_sql(text):\n if not isinstance(text,\
\ str):\n return text\n \n # 1. 【关键修改】将物理换行符替换为\
\ SQL 转义换行符 (\\\\n)\n # 这样 SQL 语句本身是一行,但数据库会将其解释为换行\n text\
\ = text.replace('\\n', '\\\\n').replace('\\r', '')\n \n #\
\ 2. 将单引号替换为两个单引号SQL 标准转义),防止截断\n text = text.replace(\"'\", \"\
''\")\n \n return text\n try:\n if not arg1:\n \
\ return {\"data\": []}\n \n # --- 1. 提取 JSON 字符串\
\ (保持不变) ---\n json_str = arg1\n match = re.search(r'```json\\\
s*(.*?)\\s*```', arg1, re.DOTALL)\n if match:\n json_str\
\ = match.group(1)\n else:\n start = arg1.find('[')\n\
\ end = arg1.rfind(']')\n if start != -1 and end !=\
\ -1:\n json_str = arg1[start:end+1]\n # --- 2. 解析\
\ JSON ---\n data_list = json.loads(json_str)\n \n \
\ # --- 3. 校验与清洗数据 ---\n if not isinstance(data_list, list):\n \
\ if isinstance(data_list, dict) and \"items\" in data_list:\n\
\ data_list = data_list[\"items\"]\n else:\n \
\ return {\"data\": []}\n if len(data_list) >= 30:\n\
\ data_list = data_list[:29]\n \n # 遍历列表进行清洗\n\
\ cleaned_list = []\n for item in data_list:\n \
\ if isinstance(item, dict):\n cleaned_item = {\n \
\ \"title\": clean_text_for_sql(item.get(\"title\", \"\")),\n\
\ \"content\": clean_text_for_sql(item.get(\"content\"\
, \"\")),\n \"topic_relation\": clean_text_for_sql(item.get(\"\
topic_relation\", \"\")),\n \"type\": clean_text_for_sql(item.get(\"\
type\", \"\"))\n }\n cleaned_list.append(cleaned_item)\n\
\ \n return {\"data\": cleaned_list}\n \n except json.JSONDecodeError\
\ as e:\n print(f\"JSON解析错误: {str(e)}\")\n return {\"data\"\
: []}\n except Exception as e:\n print(f\"处理过程中发生错误: {str(e)}\"\
)\n return {\"data\": []}"
code_language: python3
desc: ''
error_strategy: fail-branch
outputs:
data:
children: null
type: array[object]
retry_config:
max_retries: 3
retry_enabled: true
retry_interval: 1000
selected: false
title: 转换格式
type: code
variables:
- value_selector:
- '1757513757216'
- text
value_type: string
variable: arg1
height: 117
id: '1757516212204'
position:
x: 1538
y: 283
positionAbsolute:
x: 1538
y: 283
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 242
- data:
desc: ''
outputs:
- value_selector:
- '1757687332404'
- output
value_type: array[string]
variable: output
selected: false
title: 结束
type: end
height: 88
id: '1757522230050'
position:
x: 2708
y: 572
positionAbsolute:
x: 2708
y: 572
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 242
- data:
desc: ''
outputs:
- value_selector:
- '1757513757216'
- error_message
value_type: string
variable: reasoning_content
selected: false
title: 结束 2
type: end
height: 88
id: '1757572091560'
position:
x: 1361.0212171476019
y: 472.6567992168116
positionAbsolute:
x: 1361.0212171476019
y: 472.6567992168116
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 242
- data:
desc: ''
outputs:
- value_selector:
- '1757516212204'
- error_message
value_type: string
variable: result
selected: false
title: 结束 3
type: end
height: 88
id: '1757576655478'
position:
x: 2123
y: 283
positionAbsolute:
x: 2123
y: 283
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 242
- data:
desc: ''
error_handle_mode: continue-on-error
height: 410
is_parallel: true
iterator_input_type: array[object]
iterator_selector:
- '1757516212204'
- data
output_selector:
- '1758575376121'
- title
output_type: array[string]
parallel_nums: 10
selected: false
start_node_id: 1757687332404start
title: 迭代
type: iteration
width: 1310.983478660764
height: 410
id: '1757687332404'
position:
x: 1939.6507421681436
y: 396.2369270862009
positionAbsolute:
x: 1939.6507421681436
y: 396.2369270862009
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 1311
zIndex: 1
- data:
desc: ''
isInIteration: true
selected: false
title: ''
type: iteration-start
draggable: false
height: 48
id: 1757687332404start
parentId: '1757687332404'
position:
x: 60
y: 62
positionAbsolute:
x: 1999.6507421681436
y: 458.2369270862009
selectable: false
selected: false
sourcePosition: right
targetPosition: left
type: custom-iteration-start
width: 44
zIndex: 1002
- data:
code: "def main(arg1: dict) -> dict:\n # 上一个节点已经完成了所有清洗工作(包括换行符转义 \\n 和单引号转义\
\ ''\n # 这里只需要直接透传数据即可,不要再做任何处理\n return {\n \"title\": arg1.get(\"\
title\"),\n \"content\": arg1.get(\"content\"),\n \"topic_relation\"\
: arg1.get(\"topic_relation\"),\n \"type\": arg1.get(\"type\")\n\
\ }"
code_language: python3
desc: ''
isInIteration: true
isInLoop: false
iteration_id: '1757687332404'
outputs:
content:
children: null
type: string
title:
children: null
type: string
topic_relation:
children: null
type: string
type:
children: null
type: string
selected: false
title: 内容提取
type: code
variables:
- value_selector:
- '1757687332404'
- item
value_type: object
variable: arg1
height: 52
id: '1758575376121'
parentId: '1757687332404'
position:
x: 204
y: 60
positionAbsolute:
x: 2143.6507421681436
y: 456.2369270862009
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 242
zIndex: 1002
- data:
outputs:
- value_selector:
- '1766636080995'
- text
value_type: string
variable: error_message
selected: true
title: 结束 5
type: end
height: 88
id: '1764240729694'
position:
x: 934
y: 411
positionAbsolute:
x: 934
y: 411
selected: true
sourcePosition: right
targetPosition: left
type: custom
width: 242
- data:
error_strategy: fail-branch
is_team_authorization: true
paramSchemas:
- auto_generate: null
default: null
form: llm
human_description:
en_US: ''
ja_JP: ''
pt_BR: ''
zh_Hans: ''
label:
en_US: SQL 语句
ja_JP: SQL 语句
pt_BR: SQL 语句
zh_Hans: SQL 语句
llm_description: ''
max: null
min: null
name: sql
options: []
placeholder:
en_US: ''
ja_JP: ''
pt_BR: ''
zh_Hans: ''
precision: null
required: true
scope: null
template: null
type: string
params:
sql: ''
plugin_id: null
plugin_unique_identifier: null
provider_icon:
background: '#FFEAD5'
content: 🤖
provider_id: 2e7e915c-606c-4230-b4bd-ff95efb72f39
provider_name: 恩喜-00-SQL 执行器-考陪练专用
provider_type: workflow
retry_config:
max_retries: 3
retry_enabled: true
retry_interval: 1000
selected: false
title: 恩喜-00-SQL 执行器-考陪练专用
tool_configurations: {}
tool_description: 考陪练系统专用的 sql 执行器
tool_label: 恩喜-00-SQL 执行器-考陪练专用
tool_name: SQL_executor_enxi
tool_node_version: '2'
tool_parameters:
sql:
type: mixed
value: DELETE FROM knowledge_points WHERE material_id = {{#1757513649648.material_id#}};
type: tool
height: 117
id: '1766636080995'
position:
x: 369.1162304946969
y: 472.6567992168116
positionAbsolute:
x: 369.1162304946969
y: 472.6567992168116
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 242
- data:
isInIteration: true
isInLoop: false
is_team_authorization: true
iteration_id: '1757687332404'
paramSchemas:
- auto_generate: null
default: null
form: llm
human_description:
en_US: ''
ja_JP: ''
pt_BR: ''
zh_Hans: ''
label:
en_US: SQL 语句
ja_JP: SQL 语句
pt_BR: SQL 语句
zh_Hans: SQL 语句
llm_description: ''
max: null
min: null
name: sql
options: []
placeholder:
en_US: ''
ja_JP: ''
pt_BR: ''
zh_Hans: ''
precision: null
required: true
scope: null
template: null
type: string
params:
sql: ''
plugin_id: null
plugin_unique_identifier: null
provider_icon:
background: '#FFEAD5'
content: 🤖
provider_id: 2e7e915c-606c-4230-b4bd-ff95efb72f39
provider_name: 恩喜-00-SQL 执行器-考陪练专用
provider_type: workflow
selected: false
title: 恩喜-00-SQL 执行器-考陪练专用
tool_configurations: {}
tool_description: 考陪练系统专用的 sql 执行器
tool_label: 恩喜-00-SQL 执行器-考陪练专用
tool_name: SQL_executor_enxi
tool_node_version: '2'
tool_parameters:
sql:
type: mixed
value: INSERT INTO knowledge_points (course_id, material_id, name, description,
type, source, topic_relation) VALUES ({{#1757513649648.course_id#}},
{{#1757513649648.material_id#}}, '{{#1758575376121.title#}}', '{{#1758575376121.content#}}',
'{{#1758575376121.type#}}', 1, '{{#1758575376121.topic_relation#}}');
type: tool
height: 52
id: '1766636254081'
parentId: '1757687332404'
position:
x: 552.0682037973988
y: 83.70934394330777
positionAbsolute:
x: 2491.7189459655424
y: 479.9462710295087
selected: false
sourcePosition: right
targetPosition: left
type: custom
width: 242
zIndex: 1002
viewport:
x: -154.69868384174993
y: 184.48211749520988
zoom: 0.5480921885368025
rag_pipeline_variables: []