This commit is contained in:
2025-09-04 15:24:38 +08:00
parent 2bb1aefe8b
commit 4e1d695ecb
11 changed files with 225 additions and 282 deletions

View File

@@ -0,0 +1,109 @@
import asyncio
import logging
import os
import aiofiles
from openai import AsyncOpenAI
from Config.Config import ALY_LLM_API_KEY, ALY_LLM_BASE_URL, ALY_LLM_MODEL_NAME
# 配置日志
logger = logging.getLogger(__name__)
class LLMClient:
"""
大语言模型客户端封装类提供与LLM的交互功能
"""
def __init__(self, api_key=None, base_url=None, model_name=None, system_prompt=""):
self.api_key = api_key or ALY_LLM_API_KEY
self.base_url = base_url or ALY_LLM_BASE_URL
self.model_name = model_name or ALY_LLM_MODEL_NAME
self.system_prompt = system_prompt
async def get_response(self, query_text: str, knowledge_content: str = "", stream: bool = True):
"""异步获取大模型响应"""
try:
client = AsyncOpenAI(api_key=self.api_key, base_url=self.base_url)
full_query = query_text
if knowledge_content:
full_query = f"选择作答的相应知识内容:{knowledge_content}\n下面是用户提的问题:{query_text}"
completion = await client.chat.completions.create(
model=self.model_name,
messages=[
{'role': 'system', 'content': self.system_prompt},
{'role': 'user', 'content': full_query}
],
stream=stream
)
if stream:
async for chunk in completion:
if chunk and chunk.choices and len(chunk.choices) > 0:
delta = chunk.choices[0].delta
if delta and delta.content and delta.content.strip():
yield delta.content
else:
if completion and completion.choices and len(completion.choices) > 0:
message = completion.choices[0].message
if message and message.content and message.content.strip():
yield message.content
except Exception as e:
logger.error(f"大模型请求异常: {str(e)}")
yield f"处理请求时发生异常: {str(e)}"
async def save_lesson_plan(content_chunks, output_file):
"""异步保存导学案内容到文件"""
try:
output_dir = os.path.dirname(output_file)
if output_dir and not os.path.exists(output_dir):
os.makedirs(output_dir, exist_ok=True)
logger.info(f"创建输出目录: {output_dir}")
async with aiofiles.open(output_file, 'w', encoding='utf-8') as f:
full_content = []
async for chunk in content_chunks:
full_content.append(chunk)
await f.write(chunk)
await f.flush()
logger.info(f"导学案已保存到: {os.path.abspath(output_file)}")
return ''.join(full_content), True
except Exception as e:
logger.error(f"保存导学案失败: {str(e)}")
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
3. 时间轴精确到分钟;
4. 课后“教学反思提示”留3条空白供教师手写。
【格式要求】
### 1. 教材与学情分析
### 2. 四维目标(对应核心素养)
### 3. 重难点
### 4. 教学准备(器材+数字资源)
### 5. 教学过程(时间轴表格)
### 6. 板书设计ASCII示意图
### 7. 作业布置(与导学案分层衔接)
### 8. 教学反思提示(空白)
【变量】
教材版本:{人教版八年级下第十章第2节}
学生基础:{已学过重力、匀速圆周运动}
课时长度:{45分钟}"""
async def get_lesson_plan():
async for chunk in llm_client.get_response(prompt, stream=True):
yield chunk
return get_lesson_plan()

View File

View File

@@ -0,0 +1,56 @@
import asyncio
import logging
import os
import sys
# 导入教学辅助工具
from TeacherHelper.Kit.TeacherHelper import (
generate_gravitation_lesson_plan,
save_lesson_plan
)
# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# 测试生成导学案的函数
async def test_generate_lesson_plan():
print("\n===== 测试生成万有引力导学案 =====")
try:
# 调用教学辅助工具生成导学案
lesson_plan_chunks = await generate_gravitation_lesson_plan()
output_file = "./markdown/万有引力导学案.md"
# 调用教学辅助工具保存文件
print("\n生成的导学案:")
full_content, success = await save_lesson_plan(lesson_plan_chunks, output_file)
if success:
print(full_content)
print(f"\n导学案已保存到:{os.path.abspath(output_file)}")
else:
print("\n导学案保存失败")
except Exception as e:
print(f"生成导学案时发生异常: {str(e)}", file=sys.stderr)
# 主函数
async def main():
try:
# 直接生成导学案,不进行交互式测试
await test_generate_lesson_plan()
except KeyboardInterrupt:
print("\n程序被用户中断")
except Exception as e:
print(f"测试过程中发生异常: {str(e)}", file=sys.stderr)
finally:
print("\n测试程序结束")
if __name__ == '__main__':
# 运行异步主函数
asyncio.run(main())

View File

@@ -0,0 +1,56 @@
import asyncio
import logging
import os
import sys
# 导入教学辅助工具
from TeacherHelper.Kit.TeacherHelper import (
generate_gravitation_lesson_plan,
save_lesson_plan
)
# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# 测试生成教案的函数
async def test_generate_lesson_plan():
print("\n===== 测试生成万有引力教案 =====")
try:
# 调用教学辅助工具生成教案
lesson_plan_chunks = await generate_gravitation_lesson_plan()
output_file = "./markdown/万有引力教案.md"
# 调用教学辅助工具保存文件
print("\n生成的教案:")
full_content, success = await save_lesson_plan(lesson_plan_chunks, output_file)
if success:
print(full_content)
print(f"\n教案已保存到:{os.path.abspath(output_file)}")
else:
print("\n教案保存失败")
except Exception as e:
print(f"生成教案时发生异常: {str(e)}", file=sys.stderr)
# 主函数
async def main():
try:
# 直接生成教案,不进行交互式测试
await test_generate_lesson_plan()
except KeyboardInterrupt:
print("\n程序被用户中断")
except Exception as e:
print(f"测试过程中发生异常: {str(e)}", file=sys.stderr)
finally:
print("\n测试程序结束")
if __name__ == '__main__':
# 运行异步主函数
asyncio.run(main())

View File

View File

@@ -0,0 +1,4 @@
### 1. 教材与学情分析
**教材分析**
本节课内容为人教版八年级物理下册第十章第2节“万有引力

View File

@@ -1,193 +0,0 @@
import asyncio
import logging
import os
import sys
import aiofiles # 添加aiofiles导入
from openai import AsyncOpenAI
from Config.Config import *
# 配置日志
logger = logging.getLogger(__name__)
class LLMClient:
"""
大语言模型客户端封装类提供与LLM的交互功能
"""
def __init__(self, api_key=None, base_url=None, model_name=None, system_prompt=""):
"""
初始化LLM客户端
@param api_key: API密钥默认为配置文件中的ALY_LLM_API_KEY
@param base_url: API基础URL默认为配置文件中的ALY_LLM_BASE_URL
@param model_name: 模型名称默认为配置文件中的ALY_LLM_MODEL_NAME
@param system_prompt: 系统提示词,默认使用预设的学伴角色提示词
"""
self.api_key = api_key or ALY_LLM_API_KEY
self.base_url = base_url or ALY_LLM_BASE_URL
self.model_name = model_name or ALY_LLM_MODEL_NAME
self.system_prompt = system_prompt # 添加这一行来初始化system_prompt属性
async def get_response(self, query_text: str, knowledge_content: str = "", stream: bool = True):
"""
异步获取大模型响应
@param query_text: 查询文本
@param knowledge_content: 可选的知识内容,将作为上下文提供给模型
@param stream: 是否使用流式输出
@return: 流式响应生成器或完整响应文本
"""
try:
# 创建AsyncOpenAI客户端
client = AsyncOpenAI(
api_key=self.api_key,
base_url=self.base_url,
)
# 构建完整的查询文本
full_query = query_text
if knowledge_content:
full_query = f"选择作答的相应知识内容:{knowledge_content}\n下面是用户提的问题:{query_text}"
# 创建请求
completion = await client.chat.completions.create(
model=self.model_name,
messages=[
{'role': 'system', 'content': self.system_prompt},
{'role': 'user', 'content': full_query}
],
stream=stream
)
if stream:
# 流式输出模式,返回生成器
async for chunk in completion:
# 确保 chunk.choices 存在且不为空
if chunk and chunk.choices and len(chunk.choices) > 0:
# 确保 delta 存在
delta = chunk.choices[0].delta
if delta:
# 确保 content 存在且不为 None 或空字符串
content = delta.content
if content is not None and content.strip():
print(content, end='', flush=True)
yield content
else:
# 非流式处理
if completion and completion.choices and len(completion.choices) > 0:
message = completion.choices[0].message
if message:
content = message.content
if content is not None and content.strip():
yield content
except Exception as e:
print(f"大模型请求异常: {str(e)}", file=sys.stderr)
yield f"处理请求时发生异常: {str(e)}"
# 保留原有接口以保持兼容性
async def get_response_async(query_text: str, stream: bool = True):
"""
异步获取学伴角色的大模型响应(兼容旧接口)
@param query_text: 查询文本
@param stream: 是否使用流式输出
@return: 流式响应生成器或完整响应文本
"""
# 创建LLM客户端实例
llm_client = LLMClient()
# 打开文件读取知识内容
try:
with open(r"D:\dsWork\dsProject\dsLightRag\static\YunXiao.txt", "r", encoding="utf-8") as f:
zhishiContent = f.read()
except Exception as e:
print(f"读取知识文件失败: {str(e)}", file=sys.stderr)
zhishiContent = ""
# 调用封装的方法
async for chunk in llm_client.get_response(query_text, zhishiContent, stream):
yield chunk
# 生成万有引力导学案函数(修改为异步函数)
async def generate_gravitation_lesson_plan():
"""
生成万有引力导学案
@return: 生成的导学案文本
"""
# 创建LLM客户端实例设置专门的系统提示词
system_prompt = """你是'国家中级教师资格'持证教研员熟悉《中国义务教育物理课程标准2022版擅长设计'先学后教、以学定教'的导学案。请用'问题链'驱动学生自学,体现'学习目标—前置学习—问题探究—自主检测—疑问记录'五环节。"""
llm_client = LLMClient(system_prompt=system_prompt)
# 构建生成导学案的提示词
prompt = """请围绕'万有引力'一节课输出一份适用于八年级下的导学案供学生课前45分钟完成。要求
1. 语言亲切,用''称呼学生;
2. 问题难度梯度:识记→理解→应用;
3. 至少2个生活化情境问题
4. 留3行空白让学生写'我还有哪些困惑'
【格式要求】
严格按以下Markdown层级输出
### 1. 学习目标
### 2. 前置学习(知识链接+阅读指引)
### 3. 问题探究(问题链)
### 4. 自主检测5道客观题+1道开放题
### 5. 疑问记录区(留空)
【变量】
教材版本:{人教版八年级下第十章第2节}
学生基础:{已学过重力、匀速圆周运动}
课时长度:{45分钟}"""
# 修改为流式获取响应
# 确保这是一个异步生成器函数
async def get_lesson_plan():
async for chunk in llm_client.get_response(prompt, stream=True):
yield chunk
return get_lesson_plan()
# 测试生成导学案的函数
async def test_generate_lesson_plan():
print("\n===== 测试生成万有引力导学案 =====")
try:
# 必须await生成器函数
lesson_plan_chunks = await generate_gravitation_lesson_plan()
full_response = ""
output_file = "万有引力导学案.md"
# 使用aiofiles进行异步文件写入
async with aiofiles.open(output_file, 'w', encoding='utf-8') as f:
print("\n生成的导学案:")
async for chunk in lesson_plan_chunks:
# 实时打印chunk并刷新缓冲区
print(chunk, end='', flush=True)
full_response += chunk
await f.write(chunk)
await f.flush() # 刷新文件缓冲区
print(f"\n导学案已保存到:{os.path.abspath(output_file)}")
except Exception as e:
print(f"生成导学案时发生异常: {str(e)}", file=sys.stderr)
# 修改主函数以包含导学案生成测试
async def main():
try:
# 直接生成导学案,不进行交互式测试
await test_generate_lesson_plan()
except KeyboardInterrupt:
print("\n程序被用户中断")
except Exception as e:
print(f"测试过程中发生异常: {str(e)}", file=sys.stderr)
finally:
print("\n测试程序结束")
if __name__ == '__main__':
# 运行异步主函数
asyncio.run(main())

View File

@@ -1,89 +0,0 @@
### 1. 学习目标
通过本节课的自学,你将能够:
- 说出万有引力的概念及其提出者;
- 理解万有引力定律的基本内容;
- 能用万有引力解释一些生活和自然现象;
- 初步了解万有引力与重力的关系。
---
### 2. 前置学习
**知识链接:**
你已经学过“重力”和“匀速圆周运动”的相关知识,这将有助于你理解为什么地球会绕太阳转、为什么月亮不会飞走等问题。
**阅读指引:**
请认真阅读人教版八年级下册第十章第2节《万有引力》相关内容边读边思考以下问题
- 什么是万有引力?
- 它是由哪位科学家提出的?
- 万有引力定律适用于哪些物体之间?
---
### 3. 问题探究(问题链)
**识记类问题:**
1. 你知道是谁最早提出“万有引力”这一概念的吗?他提出了什么著名的定律?
2. 万有引力定律的基本内容是什么?你能用自己的话简单说一说吗?
**理解类问题:**
3. 为什么月亮不会飞离地球,而是绕着地球转?你能用万有引力来解释吗?
4. 如果没有万有引力,我们的生活会发生什么变化?试着想象一下。
**应用类问题:**
5. 你在跳起来的时候,为什么还会落回地面?这与万有引力有什么关系?
6. 想象一个生活场景:宇航员在太空中“漂浮”,这是不是说明他们不受万有引力?为什么?
---
### 4. 自主检测
**选择题:**
1. 提出万有引力定律的科学家是(  )
A. 爱因斯坦B. 伽利略C. 牛顿D. 哥白尼
2. 万有引力的作用对象是(  )
A. 地球上的物体B. 天体之间C. 所有物体之间D. 只有行星之间
3. 下列现象中,能用万有引力解释的是(  )
A. 风吹动树叶B. 苹果从树上落下C. 汽车加速行驶D. 电灯发光
4. 关于万有引力,下列说法正确的是(  )
A. 只有质量大的物体才有万有引力
B. 万有引力只存在于地球和月亮之间
C. 任何两个物体之间都存在万有引力
D. 万有引力是一种看不见、不存在的力
5. 在太空中漂浮的宇航员是否受到地球的万有引力?(  )
A. 不受,因为没有空气
B. 受到,但感觉不到
C. 受到,并且有明显重力感
D. 不受,因为距离太远
**开放题:**
6. 请你举出一个生活中体现万有引力的例子,并尝试用所学知识解释它。
---
### 5. 疑问记录区
你自学过程中还有哪些问题或困惑?请写下来,便于课堂上与老师和同学一起探讨:
1. _______________________________________
2. _______________________________________
3. _______________________________________