'commit'
This commit is contained in:
178
dsLightRag/Routes/TeacherHelperRoute.py
Normal file
178
dsLightRag/Routes/TeacherHelperRoute.py
Normal file
@@ -0,0 +1,178 @@
|
||||
import json
|
||||
import logging
|
||||
|
||||
from fastapi import APIRouter, Request, HTTPException
|
||||
from fastapi.responses import StreamingResponse
|
||||
|
||||
from TeacherHelper.Kit.TeacherHelper import (
|
||||
generate_lesson_plan,
|
||||
generate_courseware,
|
||||
generate_homework
|
||||
)
|
||||
|
||||
# 创建路由器
|
||||
router = APIRouter(prefix="/api", tags=["教师辅助工具"])
|
||||
|
||||
# 配置日志
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@router.post("/teacher/daoXueAn")
|
||||
async def generate_dao_xue_an(request: Request):
|
||||
"""生成导学案接口"""
|
||||
try:
|
||||
# 解析请求体
|
||||
body = await request.body()
|
||||
data = json.loads(body) if body else {}
|
||||
|
||||
# 获取提示词参数,如果没有提供则使用默认值
|
||||
system_prompt = data.get("system_prompt")
|
||||
user_prompt = data.get("user_prompt")
|
||||
|
||||
# 生成导学案
|
||||
content_generator = await generate_lesson_plan(system_prompt, user_prompt)
|
||||
|
||||
# 定义SSE响应生成器
|
||||
async def generate_sse_response():
|
||||
try:
|
||||
yield "data: 开始生成导学案...\n\n"
|
||||
async for chunk in content_generator:
|
||||
yield f"data: {chunk}\n\n"
|
||||
yield "data: [DONE]\n\n"
|
||||
except Exception as e:
|
||||
logger.error(f"生成导学案时发生异常: {str(e)}")
|
||||
yield f"data: 生成导学案时发生异常: {str(e)}\n\n"
|
||||
|
||||
# 返回SSE响应
|
||||
return StreamingResponse(
|
||||
generate_sse_response(),
|
||||
media_type="text/event-stream",
|
||||
headers={"Cache-Control": "no-cache", "Connection": "keep-alive"}
|
||||
)
|
||||
|
||||
except json.JSONDecodeError:
|
||||
raise HTTPException(status_code=400, detail="无效的JSON格式")
|
||||
except Exception as e:
|
||||
logger.error(f"导学案接口异常: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=f"服务器内部错误: {str(e)}")
|
||||
|
||||
|
||||
@router.post("/teacher/jiaoAn")
|
||||
async def generate_jiao_an(request: Request):
|
||||
"""生成教案接口"""
|
||||
try:
|
||||
# 解析请求体
|
||||
body = await request.body()
|
||||
data = json.loads(body) if body else {}
|
||||
|
||||
# 获取提示词参数,如果没有提供则使用默认值
|
||||
system_prompt = data.get("system_prompt")
|
||||
user_prompt = data.get("user_prompt")
|
||||
|
||||
# 生成教案
|
||||
content_generator = await generate_lesson_plan(system_prompt, user_prompt)
|
||||
|
||||
# 定义SSE响应生成器
|
||||
async def generate_sse_response():
|
||||
try:
|
||||
yield "data: 开始生成教案...\n\n"
|
||||
async for chunk in content_generator:
|
||||
yield f"data: {chunk}\n\n"
|
||||
yield "data: [DONE]\n\n"
|
||||
except Exception as e:
|
||||
logger.error(f"生成教案时发生异常: {str(e)}")
|
||||
yield f"data: 生成教案时发生异常: {str(e)}\n\n"
|
||||
|
||||
# 返回SSE响应
|
||||
return StreamingResponse(
|
||||
generate_sse_response(),
|
||||
media_type="text/event-stream",
|
||||
headers={"Cache-Control": "no-cache", "Connection": "keep-alive"}
|
||||
)
|
||||
|
||||
except json.JSONDecodeError:
|
||||
raise HTTPException(status_code=400, detail="无效的JSON格式")
|
||||
except Exception as e:
|
||||
logger.error(f"教案接口异常: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=f"服务器内部错误: {str(e)}")
|
||||
|
||||
|
||||
@router.post("/teacher/keJian")
|
||||
async def generate_ke_jian(request: Request):
|
||||
"""生成课件接口"""
|
||||
try:
|
||||
# 解析请求体
|
||||
body = await request.body()
|
||||
data = json.loads(body) if body else {}
|
||||
|
||||
# 获取提示词参数,如果没有提供则使用默认值
|
||||
system_prompt = data.get("system_prompt")
|
||||
user_prompt = data.get("user_prompt")
|
||||
|
||||
# 生成课件
|
||||
content_generator = await generate_courseware(system_prompt, user_prompt)
|
||||
|
||||
# 定义SSE响应生成器
|
||||
async def generate_sse_response():
|
||||
try:
|
||||
yield "data: 开始生成课件...\n\n"
|
||||
async for chunk in content_generator:
|
||||
yield f"data: {chunk}\n\n"
|
||||
yield "data: [DONE]\n\n"
|
||||
except Exception as e:
|
||||
logger.error(f"生成课件时发生异常: {str(e)}")
|
||||
yield f"data: 生成课件时发生异常: {str(e)}\n\n"
|
||||
|
||||
# 返回SSE响应
|
||||
return StreamingResponse(
|
||||
generate_sse_response(),
|
||||
media_type="text/event-stream",
|
||||
headers={"Cache-Control": "no-cache", "Connection": "keep-alive"}
|
||||
)
|
||||
|
||||
except json.JSONDecodeError:
|
||||
raise HTTPException(status_code=400, detail="无效的JSON格式")
|
||||
except Exception as e:
|
||||
logger.error(f"课件接口异常: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=f"服务器内部错误: {str(e)}")
|
||||
|
||||
|
||||
@router.post("/teacher/zuoYe")
|
||||
async def generate_zuo_ye(request: Request):
|
||||
"""生成作业接口"""
|
||||
try:
|
||||
# 解析请求体
|
||||
body = await request.body()
|
||||
data = json.loads(body) if body else {}
|
||||
|
||||
# 获取提示词参数,如果没有提供则使用默认值
|
||||
system_prompt = data.get("system_prompt")
|
||||
user_prompt = data.get("user_prompt")
|
||||
material_path = data.get("material_path")
|
||||
|
||||
# 生成作业
|
||||
content_generator = await generate_homework(system_prompt, user_prompt, material_path)
|
||||
|
||||
# 定义SSE响应生成器
|
||||
async def generate_sse_response():
|
||||
try:
|
||||
yield "data: 开始生成作业...\n\n"
|
||||
async for chunk in content_generator:
|
||||
yield f"data: {chunk}\n\n"
|
||||
yield "data: [DONE]\n\n"
|
||||
except Exception as e:
|
||||
logger.error(f"生成作业时发生异常: {str(e)}")
|
||||
yield f"data: 生成作业时发生异常: {str(e)}\n\n"
|
||||
|
||||
# 返回SSE响应
|
||||
return StreamingResponse(
|
||||
generate_sse_response(),
|
||||
media_type="text/event-stream",
|
||||
headers={"Cache-Control": "no-cache", "Connection": "keep-alive"}
|
||||
)
|
||||
|
||||
except json.JSONDecodeError:
|
||||
raise HTTPException(status_code=400, detail="无效的JSON格式")
|
||||
except Exception as e:
|
||||
logger.error(f"作业接口异常: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=f"服务器内部错误: {str(e)}")
|
@@ -31,7 +31,7 @@ from Routes.VideoRetalkRoute import router as videoRetalk_router
|
||||
from Routes.ttsRoute import router as tts_router
|
||||
from Routes.CopyFaceRoute import router as copyFace_router
|
||||
from Routes.WenShengTu import router as wenshengtu_router
|
||||
|
||||
from Routes.TeacherHelperRoute import router as teacherHelper_router
|
||||
# 控制日志输出
|
||||
logger = logging.getLogger('lightrag')
|
||||
logger.setLevel(logging.INFO)
|
||||
@@ -89,6 +89,7 @@ app.include_router(tts_router) # 文本转语音
|
||||
|
||||
app.include_router(copyFace_router) # 抄脸
|
||||
app.include_router(wenshengtu_router) # 文生图
|
||||
app.include_router(teacherHelper_router) # 教师助手
|
||||
|
||||
# Teaching Model 相关路由
|
||||
# 登录相关(不用登录)
|
||||
|
@@ -78,17 +78,20 @@ async def save_lesson_plan(content_chunks, output_file, stream_print=False):
|
||||
return None, False
|
||||
|
||||
|
||||
async def generate_gravitation_lesson_plan():
|
||||
"""生成万有引力教案的异步函数"""
|
||||
system_prompt = """你是市级骨干教师,撰写教案时严格对标“核心素养四维度(物理观念、科学思维、探究能力、态度责任)”,并采用“目标—评价—活动”逆向设计模板(UbD)。活动设计需包含“教师行为+期望的学生行为+评价要点”三列表格。"""
|
||||
|
||||
llm_client = LLMClient(system_prompt=system_prompt)
|
||||
|
||||
prompt = """请输出“万有引力”第1课时的详案,要求:
|
||||
1. 教学重难点用“行为动词+知识内容”表述;
|
||||
2. 至少1个“演示实验”+1个“小组探究”+1个“即时反馈”技术(如Padlet);
|
||||
async def generate_lesson_plan(system_prompt=None, user_prompt=None):
|
||||
"""生成教案的异步函数,支持动态传入提示词"""
|
||||
# 默认系统提示词
|
||||
default_system_prompt = """你是市级骨干教师,撰写教案时严格对标"核心素养四维度(物理观念、科学思维、探究能力、态度责任)",并采用"目标—评价—活动"逆向设计模板(UbD)。活动设计需包含"教师行为+期望的学生行为+评价要点"三列表格。"""
|
||||
|
||||
# 使用传入的系统提示词或默认值
|
||||
system_prompt = system_prompt or default_system_prompt
|
||||
|
||||
# 默认用户提示词
|
||||
default_user_prompt = """请输出"万有引力"第1课时的详案,要求:
|
||||
1. 教学重难点用"行为动词+知识内容"表述;
|
||||
2. 至少1个"演示实验"+1个"小组探究"+1个"即时反馈"技术(如Padlet);
|
||||
3. 时间轴精确到分钟;
|
||||
4. 课后“教学反思提示”留3条空白,供教师手写。
|
||||
4. 课后"教学反思提示"留3条空白,供教师手写。
|
||||
|
||||
【格式要求】
|
||||
### 1. 教材与学情分析
|
||||
@@ -104,9 +107,121 @@ async def generate_gravitation_lesson_plan():
|
||||
教材版本:{人教版八年级下第十章第2节}
|
||||
学生基础:{已学过重力、匀速圆周运动}
|
||||
课时长度:{45分钟}"""
|
||||
|
||||
# 使用传入的用户提示词或默认值
|
||||
user_prompt = user_prompt or default_user_prompt
|
||||
|
||||
llm_client = LLMClient(system_prompt=system_prompt)
|
||||
|
||||
async def get_lesson_plan():
|
||||
async for chunk in llm_client.get_response(prompt, stream=True):
|
||||
async for chunk in llm_client.get_response(user_prompt, stream=True):
|
||||
yield chunk
|
||||
|
||||
return get_lesson_plan()
|
||||
return get_lesson_plan()
|
||||
|
||||
|
||||
async def generate_courseware(system_prompt=None, user_prompt=None):
|
||||
"""生成课件大纲的异步函数,支持动态传入提示词"""
|
||||
# 默认系统提示词
|
||||
default_system_prompt = """你是PPT视觉设计教练,遵循"6×6原则"(每页≤6行,每行≤6词),字体≥28pt,主色调#005BAC(教育蓝),强调色#FFB703(暖黄)。所有动画≤0.5s,禁止花哨。需要给出演示者备注栏(<备注>)。"""
|
||||
|
||||
# 使用传入的系统提示词或默认值
|
||||
system_prompt = system_prompt or default_system_prompt
|
||||
|
||||
# 默认用户提示词
|
||||
default_user_prompt = """为"万有引力"生成可直接导入PowerPoint的Markdown大纲,共12页,含:
|
||||
1. 封面(课程名+章节+教师姓名留白)
|
||||
2. 情境导入(1个30s短视频建议+2张图片提示)
|
||||
3. 概念建构(苹果落地+月亮绕地对比图)
|
||||
4. 规律探究(卡文迪许实验GIF占位)
|
||||
5. 公式推导(F=G·m₁m₂/r²分三步行)
|
||||
6. 例题精讲(2道,step-by-step动画)
|
||||
7. 当堂检测(Padlet二维码占位)
|
||||
8. 小结(思维导图,可一键转SmartArt)
|
||||
9. 作业二维码(链接到在线表单)
|
||||
10. 结束页("思考:如果没有万有引力?"留白)
|
||||
|
||||
【格式要求】
|
||||
每页用三级标题###表示,下方用<ul>列要点;如需图片,用! `https://via.placeholder.com/800x450?text=Image` 占位并给出版权提示;在要点后另起一行写<备注>演示者话术。"""
|
||||
|
||||
# 使用传入的用户提示词或默认值
|
||||
user_prompt = user_prompt or default_user_prompt
|
||||
|
||||
llm_client = LLMClient(system_prompt=system_prompt)
|
||||
|
||||
async def get_courseware():
|
||||
async for chunk in llm_client.get_response(user_prompt, stream=True):
|
||||
yield chunk
|
||||
|
||||
return get_courseware()
|
||||
|
||||
|
||||
async def generate_homework(system_prompt=None, user_prompt=None, material_path=None):
|
||||
"""生成课后作业的异步函数,支持动态传入提示词和材料路径"""
|
||||
# 默认系统提示词
|
||||
default_system_prompt = "你是命题专家,熟悉布鲁姆认知分类和'双减'政策。你需要根据用户提供的题目材料来生成作业,而不是自己创造题目。客观题采用'四选一'单选,难度比例易:中:难=6:3:1;主观题设置2小问,第1问'解释现象'对应'理解',第2问'方案设计'对应'创新'。题量控制为20分钟完成。"
|
||||
|
||||
# 使用传入的系统提示词或默认值
|
||||
system_prompt = system_prompt or default_system_prompt
|
||||
|
||||
# 默认材料路径
|
||||
default_material_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "static", "YunXiao.txt")
|
||||
material_path = material_path or default_material_path
|
||||
|
||||
# 读取题目材料
|
||||
try:
|
||||
with open(material_path, "r", encoding="utf-8") as f:
|
||||
question_material = f.read()
|
||||
except Exception as e:
|
||||
logger.error(f"读取题目材料失败: {str(e)}")
|
||||
question_material = ""
|
||||
|
||||
# 默认用户提示词
|
||||
default_user_prompt = f"""请根据以下'万有引力'相关题目材料,输出课后作业,满分100分,含:
|
||||
A. 客观题(8题×5分=40分)
|
||||
- 从提供的材料中选择题目,并按要求重新组织
|
||||
- 前3题考'史实&概念'识记
|
||||
- 中间3题考'公式变形&比例'理解
|
||||
- 后2题考'情境估算'应用
|
||||
B. 主观题(2题,30+30分)
|
||||
- 题1:结合'天问一号'发射新闻,解释地球与火星之间的引力如何变化
|
||||
- 题2:设计一个实验,用智能手机+免费APP估算地球质量,写出步骤与所需测量量
|
||||
C. 评分标准(主观题分点给分,每点10分)
|
||||
D. 参考答案与解析(客观题给出选项+一句话解析;主观题给出关键公式与评分关键词)
|
||||
|
||||
以下是题目材料:
|
||||
{question_material}
|
||||
|
||||
【格式要求】
|
||||
### A. 客观题
|
||||
<ul>
|
||||
<li>1. ……</li>
|
||||
……
|
||||
</ul>
|
||||
|
||||
### B. 主观题
|
||||
#### 1. ……
|
||||
#### 2. ………
|
||||
|
||||
### C. 评分标准
|
||||
……
|
||||
|
||||
### D. 参考答案与解析
|
||||
……"""
|
||||
|
||||
# 使用传入的用户提示词或默认值
|
||||
user_prompt = user_prompt or default_user_prompt
|
||||
|
||||
llm_client = LLMClient(system_prompt=system_prompt)
|
||||
|
||||
async def get_homework():
|
||||
async for chunk in llm_client.get_response(user_prompt, stream=True):
|
||||
yield chunk
|
||||
|
||||
return get_homework()
|
||||
|
||||
|
||||
# 保持向后兼容性的函数别名
|
||||
async def generate_gravitation_lesson_plan():
|
||||
"""生成万有引力教案的异步函数(向后兼容)"""
|
||||
return await generate_lesson_plan()
|
@@ -51,4 +51,78 @@ D.
|
||||
A.在A点动能等于在C点动能
|
||||
B.在A点动能大于在C点动能
|
||||
C.在A、C、E三点加速度大小
|
||||
C.在A、C、E三点加速度大小相同
|
||||
D.在A、C、E三点加速度方向相同
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
---
|
||||
|
||||
## B. 主观题(2题,每题30分)
|
||||
|
||||
### 1. 结合“天问一号”发射新闻,解释地球与火星之间的引力如何变化。
|
||||
|
||||
### 2. 设计一个实验,用智能手机+免费APP估算地球质量,写出步骤与所需测量量。
|
||||
|
||||
---
|
||||
|
||||
## C. 评分标准
|
||||
|
||||
**主观题1(30分):**
|
||||
- 正确说明引力与距离平方成反比关系(10分)
|
||||
- 能结合“天问一号”轨道变化分析引力变化趋势(10分)
|
||||
- 语言表达清晰、逻辑合理(10分)
|
||||
|
||||
**主观题2(30分):**
|
||||
- 明确实验原理(如利用重力加速度公式)(10分)
|
||||
- 合理设计实验步骤(10分)
|
||||
- 列出所需测量量(如高度、时间)(10分)
|
||||
|
||||
---
|
||||
|
||||
## D. 参考答案与解析
|
||||
|
||||
### 客观题答案
|
||||
|
||||
1. **C**
|
||||
解析:地球对物体的引力是向心力来源,向心力不是独立存在的力。
|
||||
|
||||
2. **D**
|
||||
解析:根据F=GmM/r²,当r增加为2R时,F变为原来的1/2。
|
||||
|
||||
3. **D**
|
||||
解析:轨道半径分别为2R和3R,根据F=GmM/r²得比值为9:4。
|
||||
|
||||
4. **C**
|
||||
解析:椭圆轨道远地点速度小于圆轨道速度,近地点速度可能大于第一宇宙速度。
|
||||
|
||||
5. **C**
|
||||
解析:由开普勒第三定律,r增大为2倍,周期增大为2√2倍。
|
||||
|
||||
6. **C**
|
||||
解析:根据T²∝r³/M,M=ρV,ρ相同则T与r^(3/2)成反比。
|
||||
|
||||
7. **A**
|
||||
解析:由v=2πr/T和F=mv²/r=GmM/r²,可推导出M=4π²r³/(GT²)。
|
||||
|
||||
8. **B**
|
||||
解析:空气阻力做负功,动能减小;加速度大小相同但方向不同。
|
||||
|
||||
---
|
||||
|
||||
### 主观题答案
|
||||
|
||||
**主观题1:**
|
||||
- 地球与火星之间的万有引力随距离变化而变化,遵循F=Gm₁m₂/r²
|
||||
- “天问一号”在发射初期距离地球较近,引力较大;随着远离地球,引力逐渐减小
|
||||
- 到达火星附近时,受火星引力主导,地球引力可忽略
|
||||
- 引力变化体现为探测器加速度的变化,影响其轨道设计与控制
|
||||
|
||||
**主观题2:**
|
||||
- **实验原理**:利用自由落体运动测重力加速度g,再由g=GM/R²计算地球质量M
|
||||
- **步骤**:
|
||||
1. 在智能手机上安装加速度计APP(如phyphox)
|
||||
2. 将手机固定在稳定支架上,记录自由落体过程中的加速度数据
|
||||
3. 测量下落高度h和落地时间t,计算g=2h/t²
|
||||
- **所需测量量**:下落高度h、落地时间t
|
||||
- **公式**:M = gR²/G,其中R为地球半径,G为引力常量(6.67×10⁻¹¹ N·m²/kg²)
|
Reference in New Issue
Block a user