Dify工作流节点详细配置(修正版)
节点1: 开始节点



节点类型: 开始
输入变量:
yaml
course_id:
类型: String
描述: 课程ID
必填: 是
user_id:
类型: String
描述: 用户ID
必填: 是
节点2: 代码执行 - 初始化会话

节点名称: 初始化会话
输入变量 : course_id, user_id
代码:
python
def main(course_id, user_id):
import requests
import json
# 调用外部API开始课程
api_url = "http://your-api-domain.com/api/courses/start"
try:
response = requests.post(
api_url,
json={
"course_id": course_id,
"user_id": user_id
},
headers={"Content-Type": "application/json"},
timeout=10
)
if response.status_code != 200:
return {
"session_id": None,
"current_slide_id": None,
"current_path": "B",
"error": f"API error: {response.status_code}"
}
data = response.json()
return {
"session_id": data.get("session_id"),
"current_slide_id": data.get("first_slide_id"),
"current_path": "B",
"error": None
}
except Exception as e:
return {
"session_id": None,
"current_slide_id": None,
"current_path": "B",
"error": str(e)
}
输出变量:
yaml
session_id:
类型: String
current_slide_id:
类型: String
current_path:
类型: String
error:
类型: String
节点3: 循环节点

节点名称: 学习循环
循环变量:
yaml
current_slide_id:
类型: String
初始值: {{初始化会话.current_slide_id}}
session_id:
类型: String
初始值: {{初始化会话.session_id}}
current_path:
类型: String
初始值: {{初始化会话.current_path}}
循环终止条件:
yaml
添加条件:
变量: {{current_slide_id}}
运算符: 为空 (或 等于)
值: (留空,或填 null 不加引号)
最大循环次数: 50
节点4: 代码执行 - 获取当前Slide
节点名称: 获取Slide数据
输入变量:
current_slide_id(来自循环变量)session_id(来自循环变量)
代码:
python
def main(current_slide_id, session_id):
import requests
import json
if not current_slide_id:
return {
"slide_id": None,
"slide_title": "",
"content_text": "",
"images_text": "",
"quiz_json": "{}",
"slide_type": "",
"error": "No slide_id provided"
}
api_url = f"http://your-api-domain.com/api/slides/{current_slide_id}"
try:
response = requests.get(
api_url,
params={"session_id": session_id},
headers={"Content-Type": "application/json"},
timeout=10
)
if response.status_code != 200:
return {
"slide_id": current_slide_id,
"slide_title": "Error",
"content_text": "Failed to load slide",
"images_text": "",
"quiz_json": "{}",
"slide_type": "",
"error": f"API error: {response.status_code}"
}
data = response.json()
# 格式化slide内容
headings = data.get("content", {}).get("headings", [])
paragraphs = data.get("content", {}).get("paragraphs", [])
content_text = ""
for heading in headings:
content_text += f"## {heading}\n\n"
for para in paragraphs:
content_text += f"{para}\n\n"
# 格式化图片
images = data.get("content", {}).get("images", [])
images_text = ""
for img in images:
images_text += f"[图片: {img.get('caption', '无标题')}]\n"
# 将quiz转为JSON字符串
quiz_json = json.dumps(data.get("quiz", {}), ensure_ascii=False)
return {
"slide_id": data.get("id"),
"slide_title": data.get("title", ""),
"content_text": content_text,
"images_text": images_text,
"quiz_json": quiz_json,
"slide_type": data.get("type", "X"),
"error": None
}
except Exception as e:
return {
"slide_id": current_slide_id,
"slide_title": "Error",
"content_text": "",
"images_text": "",
"quiz_json": "{}",
"slide_type": "",
"error": str(e)
}
输出变量:
yaml
slide_id:
类型: String
slide_title:
类型: String
content_text:
类型: String
images_text:
类型: String
quiz_json:
类型: String
slide_type:
类型: String
error:
类型: String
节点5: LLM - 显示Slide内容
节点名称: 展示Slide
模型: deepseek-ai/DeepSeek-V3
SYSTEM:
你是一个专业的课程讲解助手。你的任务是清晰地展示课程内容,帮助学生理解知识点。
USER:
当前Slide类型: {{获取Slide数据.slide_type}}
# {{获取Slide数据.slide_title}}
{{获取Slide数据.content_text}}
{{获取Slide数据.images_text}}
---
请仔细阅读以上内容。阅读完成后,输入"继续"进行测试。
输出变量:
yaml
text: String
usage: Object
节点6: 代码执行 - 解析测试题
节点名称: 准备测试题
输入变量 : quiz_json (来自节点4)
代码:
python
def main(quiz_json):
import json
try:
quiz = json.loads(quiz_json)
except:
return {
"quiz_text": "本slide没有测试题",
"question1": "",
"question2": "",
"question3": "",
"correct1": "",
"correct2": "",
"correct3": "",
"has_quiz": False
}
questions = quiz.get("questions", [])
if len(questions) < 3:
return {
"quiz_text": "测试题数量不足",
"question1": "",
"question2": "",
"question3": "",
"correct1": "",
"correct2": "",
"correct3": "",
"has_quiz": False
}
# 格式化测试题
quiz_text = "请回答以下3道测试题:\n\n"
for i, q in enumerate(questions[:3], 1):
quiz_text += f"**题目 {i}**: {q.get('question')}\n"
for key, value in q.get("options", {}).items():
quiz_text += f" {key}. {value}\n"
quiz_text += "\n"
quiz_text += "\n请按照格式输入答案,例如: A,B,C 或 A B C"
return {
"quiz_text": quiz_text,
"question1": questions[0].get("question", ""),
"question2": questions[1].get("question", ""),
"question3": questions[2].get("question", ""),
"correct1": questions[0].get("correct", ""),
"correct2": questions[1].get("correct", ""),
"correct3": questions[2].get("correct", ""),
"has_quiz": True
}
输出变量:
yaml
quiz_text:
类型: String
question1:
类型: String
question2:
类型: String
question3:
类型: String
correct1:
类型: String
correct2:
类型: String
correct3:
类型: String
has_quiz:
类型: Boolean
节点7: LLM - 显示测试题并获取答案
节点名称: 测试交互
模型: deepseek-ai/DeepSeek-V3
SYSTEM:
你是一个测试助手。
展示测试题目,然后等待用户输入答案。
用户会输入3个答案,格式可能是:
- A,B,C
- A B C
- ABC
你需要识别用户的3个答案选项(只提取A、B、C、D这些字母),然后按照"答案1,答案2,答案3"的格式返回。
例如:
- 用户输入"A B C" → 你返回"A,B,C"
- 用户输入"我选ABC" → 你返回"A,B,C"
- 用户输入"第一题A,第二题B,第三题C" → 你返回"A,B,C"
只返回格式化后的答案,不要有其他内容。
USER:
{{准备测试题.quiz_text}}
请输入你的答案:
输出变量:
yaml
text: String (格式化后的答案,如"A,B,C")
usage: Object
节点8: 代码执行 - 评分
节点名称: 计算分数
输入变量:
text(来自节点7,用户答案)correct1,correct2,correct3(来自节点6)
代码:
python
def main(text, correct1, correct2, correct3):
import re
# 提取答案中的字母
user_answers_raw = text.strip().upper()
answers = re.findall(r'[A-D]', user_answers_raw)
if len(answers) != 3:
return {
"correct_count": 0,
"answer1": "",
"answer2": "",
"answer3": "",
"is_correct1": False,
"is_correct2": False,
"is_correct3": False,
"error": "答案格式错误"
}
correct_answers = [correct1, correct2, correct3]
correct_count = 0
is_correct = [False, False, False]
for i in range(3):
if answers[i] == correct_answers[i]:
correct_count += 1
is_correct[i] = True
return {
"correct_count": correct_count,
"answer1": answers[0],
"answer2": answers[1],
"answer3": answers[2],
"is_correct1": is_correct[0],
"is_correct2": is_correct[1],
"is_correct3": is_correct[2],
"error": None
}
输出变量:
yaml
correct_count:
类型: Number
answer1:
类型: String
answer2:
类型: String
answer3:
类型: String
is_correct1:
类型: Boolean
is_correct2:
类型: Boolean
is_correct3:
类型: Boolean
error:
类型: String
节点9: 代码执行 - 提交分数
节点名称: 提交并获取下一步
输入变量:
current_slide_id(循环变量)correct_count(来自节点8)session_id(循环变量)
代码:
python
def main(current_slide_id, correct_count, session_id):
import requests
import json
api_url = "http://your-api-domain.com/api/quiz/submit"
try:
response = requests.post(
api_url,
json={
"session_id": session_id,
"slide_id": current_slide_id,
"correct_count": int(correct_count)
},
headers={"Content-Type": "application/json"},
timeout=10
)
if response.status_code != 200:
return {
"next_slide_id": None,
"new_path": "B",
"path_changed": False,
"message": "提交失败",
"error": f"API error: {response.status_code}"
}
data = response.json()
return {
"next_slide_id": data.get("next_slide_id"),
"new_path": data.get("new_path", "B"),
"path_changed": data.get("path_changed", False),
"message": data.get("message", ""),
"error": None
}
except Exception as e:
return {
"next_slide_id": None,
"new_path": "B",
"path_changed": False,
"message": "提交失败",
"error": str(e)
}
输出变量:
yaml
next_slide_id:
类型: String
new_path:
类型: String
path_changed:
类型: Boolean
message:
类型: String
error:
类型: String
节点10: LLM - 显示反馈
节点名称: 展示反馈
模型: deepseek-ai/DeepSeek-V3
SYSTEM:
你是一个学习反馈助手。向学生展示他们的测试结果和下一步学习路径。
USER:
测试完成!
你答对了 {{计算分数.correct_count}} 道题。
详细结果:
- 题目1: 你的答案 {{计算分数.answer1}} | 正确答案 {{准备测试题.correct1}} | {{计算分数.is_correct1}}
- 题目2: 你的答案 {{计算分数.answer2}} | 正确答案 {{准备测试题.correct2}} | {{计算分数.is_correct2}}
- 题目3: 你的答案 {{计算分数.answer3}} | 正确答案 {{准备测试题.correct3}} | {{计算分数.is_correct3}}
---
{{提交并获取下一步.message}}
当前学习路径: {{提交并获取下一步.new_path}}路径
准备进入下一个Slide...
输出变量:
yaml
text: String
usage: Object
节点11: 代码执行 - 更新循环变量
节点名称: 更新变量
输入变量:
next_slide_id(来自节点9)new_path(来自节点9)session_id(循环变量,保持不变)
代码:
python
def main(next_slide_id, new_path, session_id):
# 这个节点用于更新循环变量
# 返回的变量将被循环节点用于下一次迭代
return {
"current_slide_id": next_slide_id,
"current_path": new_path,
"session_id": session_id
}
输出变量:
yaml
current_slide_id:
类型: String
current_path:
类型: String
session_id:
类型: String
重要: 在循环节点配置中,需要设置这些变量的更新映射
节点12: 代码执行 - 获取学习报告
节点名称: 生成报告
输入变量:
session_id(循环变量)user_id(开始节点)
代码:
python
def main(session_id, user_id):
import requests
api_url = f"http://your-api-domain.com/api/session/{user_id}/report"
try:
response = requests.get(
api_url,
params={"session_id": session_id},
headers={"Content-Type": "application/json"},
timeout=10
)
if response.status_code != 200:
return {
"report_text": "生成报告失败",
"total_slides": 0,
"accuracy": 0,
"path_a_count": 0,
"path_b_count": 0,
"path_c_count": 0,
"error": f"API error: {response.status_code}"
}
data = response.json()
# 格式化报告
path_history = " → ".join(data.get("path_history", []))
report_text = f"""
# 学习报告
## 学习路径
{path_history}
## 统计数据
- 完成slides数: {data.get('total_slides_completed', 0)}
- 总答题数: {data.get('total_questions', 0)}
- 正确率: {data.get('accuracy', 0)}%
- 学习时长: {data.get('duration', 0)}分钟
## 路径分布
- A路径(速通): {data.get('path_distribution', {}).get('A', 0)} 次
- B路径(正常): {data.get('path_distribution', {}).get('B', 0)} 次
- C路径(刷题): {data.get('path_distribution', {}).get('C', 0)} 次
## 知识点掌握情况
{data.get('knowledge_summary', '无数据')}
## 学习建议
{data.get('recommendations', '继续保持!')}
"""
return {
"report_text": report_text,
"total_slides": data.get('total_slides_completed', 0),
"accuracy": data.get('accuracy', 0),
"path_a_count": data.get('path_distribution', {}).get('A', 0),
"path_b_count": data.get('path_distribution', {}).get('B', 0),
"path_c_count": data.get('path_distribution', {}).get('C', 0),
"error": None
}
except Exception as e:
return {
"report_text": f"生成报告时出错: {str(e)}",
"total_slides": 0,
"accuracy": 0,
"path_a_count": 0,
"path_b_count": 0,
"path_c_count": 0,
"error": str(e)
}
输出变量:
yaml
report_text:
类型: String
total_slides:
类型: Number
accuracy:
类型: Number
path_a_count:
类型: Number
path_b_count:
类型: Number
path_c_count:
类型: Number
error:
类型: String
节点13: LLM - 显示学习报告
节点名称: 展示报告
模型: deepseek-ai/DeepSeek-V3
SYSTEM:
你是一个学习总结助手。向学生展示他们的学习成果和建议。
USER:
恭喜你完成本次学习!
{{生成报告.report_text}}
感谢使用自适应学习系统!
输出变量:
yaml
text: String
usage: Object
节点14: 结束节点
节点类型: 结束
输出变量:
yaml
将以下变量作为最终输出:
final_report: {{展示报告.text}}
total_slides: {{生成报告.total_slides}}
accuracy: {{生成报告.accuracy}}
关键配置说明
1. 循环变量更新机制
在循环节点的配置中,需要设置变量如何在每次迭代后更新:
yaml
循环变量初始值:
current_slide_id: {{初始化会话.current_slide_id}}
session_id: {{初始化会话.session_id}}
current_path: {{初始化会话.current_path}}
每次循环后更新为:
current_slide_id: {{更新变量.current_slide_id}}
session_id: {{更新变量.session_id}}
current_path: {{更新变量.current_path}}
2. 循环终止条件
yaml
终止条件:
变量: {{current_slide_id}}
运算符: 为空 (或选择 "等于")
值: (留空,或填 null 不加引号)
3. 变量引用规则
所有变量引用都是一层扁平化的:
- 正确:
{``{节点名.变量名}} - 错误:
{``{节点名.对象.字段}}
4. API地址配置
所有代码节点中的API地址:
python
# 替换为实际地址
api_base = "http://your-api-domain.com"