【1902】优化后的三路径学习系统

优化后的三路径学习系统

本文提出了一种三路径学习系统优化方案,通过智能分析原始PPT内容生成三种学习路径:A路径(速通版)合并相关知识点形成精炼内容;B路径(正常版)保持原始PPT顺序;C路径(刷题版)在知识点后插入练习题。系统首先解析PPT提取内容(X slides),然后通过LLM分析生成知识点分析报告,据此构建Y slides(压缩版)和Z slides(练习版),最终自动组合成三条个性化学习路径。该方案能根据学习者需求提供差异化学习体验,提高学习效率。

阶段一:内容预处理与路径生成

1. 开始节点

yaml 复制代码
输入变量:
  - original_ppt_file: 爬取的原始PPT文件
  - course_name: 课程名称

2. 代码节点:解析原始PPT

节点类型 :代码执行
使用库:python-pptx

python 复制代码
from pptx import Presentation
import json

def main(original_ppt_file):
    """
    解析原始PPT,提取X slides
    """
    # 读取PPT文件
    prs = Presentation(original_ppt_file)
    
    x_slides = []
    
    for idx, slide in enumerate(prs.slides):
        slide_data = {
            "id": f"X{idx+1}",
            "type": "X",
            "slide_number": idx + 1,
            "title": "",
            "content": [],
            "has_image": False
        }
        
        # 提取标题
        if slide.shapes.title:
            slide_data["title"] = slide.shapes.title.text
        
        # 提取文本内容
        for shape in slide.shapes:
            if hasattr(shape, "text") and shape.text:
                slide_data["content"].append(shape.text)
        
        # 检查是否有图片
        for shape in slide.shapes:
            if shape.shape_type == 13:  # 图片
                slide_data["has_image"] = True
        
        x_slides.append(slide_data)
    
    return {
        "x_slides": x_slides,
        "total_x_slides": len(x_slides),
        "x_slides_json": json.dumps(x_slides, ensure_ascii=False)
    }

3. LLM节点:分析X slides知识点

Prompt

复制代码
你是教学内容分析专家。请分析以下PPT slides,提取核心知识点。

原始Slides (X类型):
{{x_slides_json}}

任务:
1. 为每个X slide标注核心知识点
2. 识别哪些slides可以合并(知识点相关)
3. 识别哪些知识点需要额外练习
4. 估计每个slide的难度(1-5)

输出格式(严格JSON):
{
  "slides_analysis": [
    {
      "slide_id": "X1",
      "knowledge_points": ["概念A", "概念B"],
      "difficulty": 3,
      "can_merge_with": ["X2"],
      "needs_practice": true
    }
  ],
  "merge_groups": [
    {
      "group_id": "G1",
      "source_slides": ["X1", "X2", "X3"],
      "combined_knowledge": ["概念A", "概念B", "概念C"]
    }
  ]
}

输出变量slides_analysis


4. LLM节点:生成Y slides(速通版)

Prompt

复制代码
基于以下分析结果,生成Y类型slides(压缩精炼版)。

原始分析:
{{slides_analysis}}

原始X slides:
{{x_slides_json}}

要求:
1. 合并相关知识点,减少slide数量
2. 提炼核心概念,去除冗余
3. 可以适当加入超纲但相关的高级内容
4. 每个Y slide应该覆盖2-3个原始X slide的内容

例如:
- X1 (函数基础) + X2 (函数参数) + X3 (返回值) 
  → Y1 (函数完整机制:定义、参数、返回值、高阶函数预览)

输出格式(严格JSON):
{
  "y_slides": [
    {
      "id": "Y1",
      "type": "Y",
      "title": "精炼后的标题",
      "content": [
        "核心要点1",
        "核心要点2",
        "进阶提示"
      ],
      "covers_x_slides": ["X1", "X2", "X3"],
      "advanced_topic": "高阶函数简介",
      "estimated_time": "3分钟"
    }
  ],
  "y_to_x_mapping": {
    "Y1": ["X1", "X2", "X3"],
    "Y2": ["X4", "X5"]
  }
}

输出变量y_slides_data


5. LLM节点:生成Z slides(刷题巩固版)

Prompt

复制代码
基于以下分析,为需要巩固的知识点生成Z类型slides(刷题练习版)。

原始分析:
{{slides_analysis}}

原始X slides:
{{x_slides_json}}

要求:
1. 为每个标记为needs_practice的知识点生成一个Z slide
2. Z slide包含:
   - 概念回顾(简化版)
   - 3-5道练习题(带详细解析)
   - 常见错误提示
3. 插入位置:在对应的X slide之后

输出格式(严格JSON):
{
  "z_slides": [
    {
      "id": "Z1",
      "type": "Z",
      "title": "练习:{{知识点名称}}",
      "insert_after": "X1",
      "concept_review": "概念回顾内容",
      "practice_questions": [
        {
          "question": "题目内容",
          "options": {"A": "...", "B": "...", "C": "...", "D": "..."},
          "correct": "B",
          "explanation": "详细解析"
        }
      ],
      "common_mistakes": ["错误1", "错误2"]
    }
  ]
}

输出变量z_slides_data


6. 代码节点:构建三条路径

节点类型:代码执行

python 复制代码
import json

def main(x_slides_json, y_slides_data, z_slides_data):
    """
    构建A、B、C三条学习路径
    """
    x_slides = json.loads(x_slides_json)
    y_slides = json.loads(y_slides_data)["y_slides"]
    z_slides = json.loads(z_slides_data)["z_slides"]
    y_to_x_mapping = json.loads(y_slides_data)["y_to_x_mapping"]
    
    # B路径(正常组):所有X slides按顺序
    path_b = {
        "name": "B路径 - 正常学习",
        "description": "按照原始PPT顺序学习所有内容",
        "slides": x_slides,
        "total_slides": len(x_slides),
        "estimated_time": len(x_slides) * 5  # 每个slide 5分钟
    }
    
    # A路径(速通组):Y slides + 未覆盖的X slides
    covered_x = set()
    for y_id, x_list in y_to_x_mapping.items():
        covered_x.update(x_list)
    
    path_a_slides = []
    x_idx = 0
    
    for y_slide in y_slides:
        path_a_slides.append(y_slide)
        # 跳过被覆盖的X slides
        while x_idx < len(x_slides) and x_slides[x_idx]["id"] in y_slide["covers_x_slides"]:
            x_idx += 1
        # 添加未覆盖的X slides
        while x_idx < len(x_slides) and x_slides[x_idx]["id"] not in covered_x:
            path_a_slides.append(x_slides[x_idx])
            x_idx += 1
    
    path_a = {
        "name": "A路径 - 速通学习",
        "description": "精炼内容,适合基础较好的学习者",
        "slides": path_a_slides,
        "total_slides": len(path_a_slides),
        "estimated_time": len(path_a_slides) * 3
    }
    
    # C路径(刷题组):X slides + Z slides穿插
    path_c_slides = []
    z_dict = {z["insert_after"]: z for z in z_slides}
    
    for x_slide in x_slides:
        path_c_slides.append(x_slide)
        # 如果有对应的Z slide,插入
        if x_slide["id"] in z_dict:
            path_c_slides.append(z_dict[x_slide["id"]])
    
    path_c = {
        "name": "C路径 - 强化练习",
        "description": "原始内容+额外练习,适合需要巩固的学习者",
        "slides": path_c_slides,
        "total_slides": len(path_c_slides),
        "estimated_time": len(path_c_slides) * 6
    }
    
    return {
        "path_a": path_a,
        "path_b": path_b,
        "path_c": path_c,
        "summary": {
            "x_slides_count": len(x_slides),
            "y_slides_count": len(y_slides),
            "z_slides_count": len(z_slides),
            "path_a_slides": len(path_a_slides),
            "path_b_slides": len(x_slides),
            "path_c_slides": len(path_c_slides)
        }
    }

7. 代码节点:为每个slide生成测试题

使用迭代器遍历所有slides

python 复制代码
def main(slide_content, slide_type):
    """
    根据slide类型生成不同难度的测试题
    """
    # 对于Y类型(速通),题目更难
    # 对于X类型(正常),题目中等
    # 对于Z类型(刷题),题目已经包含在内容中
    
    if slide_type == "Z":
        # Z slide已有题目,直接返回
        return {"quiz": slide_content.get("practice_questions", [])}
    
    # 否则需要LLM生成
    return {"needs_generation": True}

阶段二:用户交互流程

1. 会话初始化

yaml 复制代码
输入变量:
  - user_id: 用户ID
  - course_id: 课程ID
  
初始化变量:
  - current_path: "B"  # 默认从B路径开始
  - current_slide_index: 0
  - user_history: []
  - performance_scores: []

2. 显示Slide节点

节点类型:模板

复制代码
【当前路径:{{current_path}}路径】
进度:{{current_slide_index + 1}} / {{total_slides}}

---

# {{current_slide.title}}

{{#each current_slide.content}}
• {{this}}
{{/each}}

{{#if current_slide.type == "Y"}}
本页覆盖原始内容:{{current_slide.covers_x_slides}}
进阶内容:{{current_slide.advanced_topic}}
{{/if}}

{{#if current_slide.type == "Z"}}
概念回顾:{{current_slide.concept_review}}
常见错误:{{current_slide.common_mistakes}}
{{/if}}

---

准备好后,点击"开始测试"

3. 显示测试题

节点类型:问题节点

yaml 复制代码
展示:当前slide的3道测试题
输入格式:A,B,C 或 A B C
变量名:user_answers

4. 代码节点:评分与路径切换

python 复制代码
def main(user_answers, quiz, current_path, current_slide, all_paths):
    """
    评分并决定路径切换
    """
    # 解析答案
    answers = [a.strip().upper() for a in user_answers.replace(',', ' ').split()]
    correct_answers = [q["correct"] for q in quiz]
    
    # 计算正确数
    correct_count = sum(1 for i in range(3) if answers[i] == correct_answers[i])
    
    # 路径切换逻辑
    next_path = current_path
    switch_message = ""
    
    if correct_count == 3:
        # 答对3题
        if current_path != "A":
            next_path = "A"
            switch_message = "全对!切换到A路径(速通模式)"
        else:
            switch_message = "继续保持A路径"
    
    elif correct_count == 2:
        # 答对2题
        if current_path != "B":
            next_path = "B"
            switch_message = "不错!切换到B路径(正常模式)"
        else:
            switch_message = "继续保持B路径"
    
    else:
        # 答对0-1题
        if current_path != "C":
            next_path = "C"
            switch_message = "需要巩固,切换到C路径(强化练习)"
        else:
            switch_message = "继续C路径,加强练习"
    
    # 计算下一个slide索引
    # 如果切换了路径,需要找到对应位置
    next_index = calculate_next_index(
        current_slide, 
        current_path, 
        next_path, 
        all_paths
    )
    
    return {
        "correct_count": correct_count,
        "next_path": next_path,
        "next_index": next_index,
        "switch_message": switch_message,
        "path_changed": next_path != current_path
    }

def calculate_next_index(current_slide, old_path, new_path, all_paths):
    """
    计算路径切换后的对应位置
    """
    if old_path == new_path:
        # 路径未变,直接下一个
        return current_slide["index"] + 1
    
    # 路径变化,找到对应的知识点位置
    current_knowledge = current_slide.get("knowledge_points", [])
    new_path_slides = all_paths[new_path]["slides"]
    
    # 找到新路径中覆盖相同知识点的下一个slide
    for idx, slide in enumerate(new_path_slides):
        if any(kp in slide.get("knowledge_points", []) for kp in current_knowledge):
            return idx + 1
    
    # 如果找不到,从新路径的下一个位置开始
    return 0

5. 条件分支:是否结束

yaml 复制代码
判断条件:
  IF {{next_index}} >= {{total_slides}}:
    → 进入"生成学习报告"
  ELSE:
    → 返回"显示Slide"(循环继续)

6. LLM节点:生成学习报告

复制代码
用户完成了课程学习!

学习数据:
- 起始路径:B
- 最终路径:{{current_path}}
- 路径切换历史:{{path_history}}
- 总答题数:{{total_questions}}
- 正确率:{{overall_accuracy}}%

请生成学习报告:
1. 学习路径可视化
2. 知识点掌握情况
3. 强项与弱项分析
4. 后续学习建议

格式:Markdown

路径示例(假设有10个X slides)

原始PPT(X slides)

复制代码
X1: Python简介
X2: 变量与类型
X3: 运算符
X4: 条件语句
X5: 循环基础
X6: 循环高级
X7: 函数定义
X8: 函数参数
X9: 函数返回值
X10: 模块导入

B路径(正常组)- 10个slides

复制代码
X1 → X2 → X3 → X4 → X5 → X6 → X7 → X8 → X9 → X10

A路径(速通组)- 6个slides

复制代码
Y1 (覆盖X1+X2+X3: 基础语法精炼)
→ X4
→ Y2 (覆盖X5+X6: 循环完整机制+列表推导式)
→ Y3 (覆盖X7+X8+X9: 函数全貌+装饰器预览)
→ X10

C路径(刷题组)- 15个slides

复制代码
X1 → Z1 (Python安装练习)
→ X2 → Z2 (类型转换练习)
→ X3
→ X4 → Z3 (条件判断练习)
→ X5 → Z4 (循环练习1)
→ X6 → Z5 (循环练习2)
→ X7 → Z6 (函数练习)
→ X8
→ X9
→ X10

Dify实现要点

两个Workflow

Workflow 1: "内容预处理器"

  1. 上传原始PPT
  2. 解析X slides
  3. 生成Y slides(LLM)
  4. 生成Z slides(LLM)
  5. 构建三条路径
  6. 为每个slide生成测试题
  7. 保存到数据库

Workflow 2: "自适应学习系统"

  1. 加载课程数据
  2. 显示当前slide
  3. 用户答题
  4. 评分(3题全对→A,2题→B,0-1题→C)
  5. 切换路径(如需要)
  6. 循环直到结束
  7. 生成报告

数据结构示例

json 复制代码
{
  "course_id": "python_basics_001",
  "paths": {
    "A": {
      "slides": [...],
      "total": 6
    },
    "B": {
      "slides": [...],
      "total": 10
    },
    "C": {
      "slides": [...],
      "total": 15
    }
  },
  "user_session": {
    "current_path": "B",
    "current_index": 3,
    "history": ["B", "A", "A"],
    "scores": [2, 3, 3]
  }
}

这个设计的优势:

不需要指数级节点

三条清晰的路径

动态路径切换

基于真实PPT内容

LLM只生成必要的Y和Z

相关推荐
仰泳之鹅2 小时前
【PID学习】多环PID
学习·pid
testpassportcn2 小时前
CompTIA A+ 220-1201 認證介紹|CompTIA A+ Core 1 考試內容、題型與高效備考指南
网络·学习·改行学it
Digitally2 小时前
如何将文件从 iPhone 传输到 Android
android·ios·iphone
2501_944934732 小时前
数据洞察力:职业转型的核心竞争力
学习
a3158238062 小时前
Android修改调试屏幕的选择方向
android·adb·屏幕旋转
AI视觉网奇2 小时前
ue5 默认相机设置
笔记·学习·ue5
山土成旧客2 小时前
【Python学习打卡-Day44】站在巨人的肩膀上:玩转PyTorch预训练模型与迁移学习
pytorch·python·学习
星河天欲瞩3 小时前
【深度学习Day1】环境配置(CUDA、PyTorch)
人工智能·pytorch·python·深度学习·学习·机器学习·conda
木木木一3 小时前
Rust学习记录--C12 实例:写一个命令行程序
学习·算法·rust