【1902】0120-3 Dify变量引用只能引用一层

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"
相关推荐
满栀5852 小时前
jQuery 递归渲染多级树形菜单
前端·javascript·jquery
秋刀鱼程序编程2 小时前
Java基础入门(七)---异常处理
java·开发语言·python
遇见你的雩风2 小时前
Java---多线程(一)
java·开发语言
2501_915921432 小时前
iOS 描述文件制作过程,从 Bundle ID、证书、设备到描述文件生成后的验证
android·ios·小程序·https·uni-app·iphone·webview
这就是佬们吗2 小时前
力扣---leetcode48
java·笔记·后端·算法·leetcode·idea
冗量2 小时前
Cucumber: 参考
java·bdd·cucumber
冗量2 小时前
Cucumber:参数类型与配置详解
java·bdd·cucumber
qq_338032922 小时前
Vue/JS项目的package.json文件 和java项目里面的pom文件
java·javascript·vue.js·json
霸道流氓气质2 小时前
Java 实现折线图整点数据补全与标准化处理示例代码讲解
java·开发语言·windows