优化后的三路径学习系统
本文提出了一种三路径学习系统优化方案,通过智能分析原始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: "内容预处理器"
- 上传原始PPT
- 解析X slides
- 生成Y slides(LLM)
- 生成Z slides(LLM)
- 构建三条路径
- 为每个slide生成测试题
- 保存到数据库
Workflow 2: "自适应学习系统"
- 加载课程数据
- 显示当前slide
- 用户答题
- 评分(3题全对→A,2题→B,0-1题→C)
- 切换路径(如需要)
- 循环直到结束
- 生成报告
数据结构示例
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
