youngtsai commited on
Commit
1a8d8ed
·
1 Parent(s): 0a7d39a
Files changed (2) hide show
  1. app.py +158 -110
  2. educational_material.py +136 -55
app.py CHANGED
@@ -30,8 +30,6 @@ from educational_material import EducationalMaterial
30
  from storage_service import GoogleCloudStorage
31
 
32
 
33
-
34
-
35
  is_env_local = os.getenv("IS_ENV_LOCAL", "false") == "true"
36
  print(f"is_env_local: {is_env_local}")
37
 
@@ -375,7 +373,7 @@ def generate_transcription(video_id):
375
  file=audio_file,
376
  response_format="verbose_json",
377
  timestamp_granularities=["segment"],
378
- prompt="如果影片有中文,請使用繁體中文,這對於我很重要"
379
  )
380
 
381
  # get segments
@@ -858,6 +856,7 @@ def generate_summarise(df_string):
858
  如果是資料類型,請提估欄位敘述、資料樣態與資料分析,告訴學生這張表的意義,以及可能的結論與對應方式
859
 
860
  如果是影片類型,請提估影片內容,告訴學生這部影片的意義,
 
861
  小範圍切出不同段落的相對應時間軸的重點摘要,最多不超過五段
862
  注意不要遺漏任何一段時間軸的內容
863
  格式為 【start - end】: 摘要
@@ -866,9 +865,9 @@ def generate_summarise(df_string):
866
  整體格式為:
867
  🗂️ 1. 內容類型:?
868
  📚 2. 整體摘要
869
- 🔖 3. 條列式重點
870
- 🔑 4. 關鍵時刻(段落摘要)
871
- 💡 5. 結論反思(為什麼我們要學這個?)
872
  ❓ 6. 延伸小問題
873
  """
874
 
@@ -1305,102 +1304,128 @@ def chat_with_youtube_transcript(password, youtube_id, thread_id, trascript, use
1305
  error_msg = "你的訊息太長了,請縮短訊息長度至五百字以內"
1306
  raise gr.Error(error_msg)
1307
 
1308
- assistant_id = "asst_kmvZLNkDUYaNkMNtZEAYxyPq"
1309
- client = OPEN_AI_CLIENT
1310
-
1311
- # 從 file 拿逐字稿資料
1312
- # instructions = f"""
1313
- # 你是一個擅長資料分析跟影片教學的老師,user 為學生
1314
- # 請根據 assistant beta 的上傳資料
1315
- # 如果 file 內有找到 file.content["{youtube_id}"] 為資料文本,自行判斷資料的種類,
1316
- # 如果沒有資料,請告訴用戶沒有逐字稿資料,但仍然可以進行對話,使用台灣人的口與表達,及繁體中文 zh-TW
1317
- # 請嚴格執行,只根據 file.content["{youtube_id}"] 為資料文本,沒有就是沒有資料,不要引用其他資料
1318
-
1319
- # 如果是影片類型,不用解釋逐字稿格式,直接回答學生問題
1320
- # socratic_mode = {socratic_mode}
1321
- # 如果 socratic_mode = True,
1322
- # - 請用蘇格拉底式的提問方式,引導學生思考,並且給予學生一些提示
1323
- # - 不要直接給予答案,讓學生自己思考
1324
- # - 但可以給予一些提示跟引導,例如給予影片的時間軸,讓學生自己去找答案
1325
- # - 在你回答的開頭標註【蘇格拉底助教:{youtube_id} 】
1326
- # 如果 socratic_mode = False,
1327
- # - 直接回答學生問題
1328
- # - 在你回答的開頭標註【一般學習精靈:{youtube_id} 】
1329
- # 如果學生問了一些問題你無法判斷,請告訴學生你無法判斷,並建議學生可以問其他問題
1330
- # 或者你可以反問學生一些問題,幫助學生更好的理解資料
1331
- # 如果學生的問題與資料文本無關,請告訴學生你無法回答超出範圍的問題
1332
- # 最後只要是參考逐字稿資料,請在回答的最後標註【參考資料:(分):(秒)】
1333
- # """
1334
-
1335
- # 直接安排逐字稿資料 in instructions
1336
- trascript_json = json.loads(trascript)
1337
- # 移除 embed_url, screenshot_path
1338
- for entry in trascript_json:
1339
- entry.pop('embed_url', None)
1340
- entry.pop('screenshot_path', None)
1341
- trascript_text = json.dumps(trascript_json, ensure_ascii=False, indent=2)
1342
-
1343
- instructions = f"""
1344
- 逐字稿資料:{trascript_text}
1345
- -------------------------------------
1346
- 你是一個擅長資料分析跟影片教學的老師,user 為學生
1347
- 如果是影片類型,不用解釋逐字稿格式,直接回答學生問題
1348
- socratic_mode = {socratic_mode}
1349
- 如果 socratic_mode = True,
1350
- - 請用蘇格拉底式的提問方式,引導學生思考,並且給予學生一些提示
1351
- - 不要直接給予答案,讓學生自己思考
1352
- - 但可以給予一些提示跟引導,例如給予影片的時間軸,讓學生自己去找答案
1353
- - 在你回答的開頭標註【蘇格拉底助教:{youtube_id} 】
1354
- 如果 socratic_mode = False,
1355
- - 直接回答學生問題
1356
- - 在你回答的開頭標註【一般學習精靈:{youtube_id} 】
1357
- 如果學生問了一些問題你無法判斷,請告訴學生你無法判斷,並建議學生可以問其他問題
1358
- 或者你可以反問學生一些問題,幫助學生更好的理��資料
1359
- 如果學生的問題與資料文本無關,請告訴學生你無法回答超出範圍的問題
1360
- 最後只要是參考逐字稿資料,請在回答的最後標註【參考資料:(分):(秒)】
1361
- """
 
1362
 
1363
- # 创建线程
1364
- if not thread_id:
1365
- thread = client.beta.threads.create()
1366
- thread_id = thread.id
1367
- else:
1368
- thread = client.beta.threads.retrieve(thread_id)
1369
-
1370
- # 向线程添加用户的消息
1371
- client.beta.threads.messages.create(
1372
- thread_id=thread.id,
1373
- role="user",
1374
- content=user_message
1375
- )
1376
 
1377
- # 运行助手,生成响应
1378
- run = client.beta.threads.runs.create(
1379
- thread_id=thread.id,
1380
- assistant_id=assistant_id,
1381
- instructions=instructions,
1382
- )
1383
 
1384
- # 等待助手响应,设定最大等待时间为 30 秒
1385
- run_status = poll_run_status(run.id, thread.id, timeout=30)
1386
- # 获取助手的响应消息
1387
- if run_status == "completed":
1388
- messages = client.beta.threads.messages.list(thread_id=thread.id)
1389
- # [MessageContentText(text=Text(annotations=[], value='您好!有什麼我可以幫助您的嗎?如果有任何問題或需要指導,請隨時告訴我!'), type='text')]
1390
- response_text = messages.data[0].content[0].text.value
1391
- else:
1392
- response_text = "學習精靈有點累,請稍後再試!"
1393
 
1394
- # 更新聊天历史
1395
- new_chat_history = (user_message, response_text)
1396
- if chat_history is None:
1397
- chat_history = [new_chat_history]
1398
- else:
1399
- chat_history.append(new_chat_history)
 
 
 
1400
 
1401
  # 返回聊天历史和空字符串清空输入框
1402
  return "", chat_history, thread.id
1403
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1404
  def poll_run_status(run_id, thread_id, timeout=600, poll_interval=5):
1405
  """
1406
  Polls the status of a Run and handles different statuses appropriately.
@@ -1586,22 +1611,24 @@ with gr.Blocks() as demo:
1586
  with gr.Tab("心智圖",elem_id="mind_map_tab"):
1587
  mind_map_html = gr.HTML()
1588
  with gr.Column(scale=2):
1589
- gr.Markdown("## OPEN AI 模式")
1590
- chatbot = gr.Chatbot(avatar_images=["https://assets-global.website-files.com/6405517ab71c76a232456561/6405517ab71c7635804565a3_%E9%A0%AD%E8%B2%BC%20_%E8%80%81%E5%B8%AB%20.png", "https://junyitopicimg.s3.amazonaws.com/s4byy--icon.jpe?v=20200513013523726"], label="OPEN AI 模式")
1591
- thread_id = gr.Textbox(label="thread_id", visible=False)
1592
- socratic_mode_btn = gr.Checkbox(label="蘇格拉底家教助理模式", value=True)
1593
- msg = gr.Textbox(label="Message")
1594
- send_button = gr.Button("Send")
1595
-
1596
- gr.Markdown("## GROQ 模式")
1597
- groq_chatbot = gr.Chatbot(label="groq mode chatbot")
1598
- groq_msg = gr.Textbox(label="Message")
1599
- groq_send_button = gr.Button("Send")
1600
-
1601
- gr.Markdown("## JUTOR API 模式")
1602
- jutor_chatbot = gr.Chatbot(label="jutor mode chatbot")
1603
- jutor_msg = gr.Textbox(label="Message")
1604
- jutor_send_button = gr.Button("Send")
 
 
1605
 
1606
  with gr.Tab("教師版"):
1607
  with gr.Row():
@@ -1625,10 +1652,17 @@ with gr.Blocks() as demo:
1625
  lesson_plan_btn = gr.Button("生成課程計畫 📕")
1626
  with gr.Accordion("prompt", open=False):
1627
  lesson_plan_prompt = gr.Textbox(label="worksheet_prompt", show_copy_button=True, lines=40)
 
 
 
 
 
 
1628
 
1629
  with gr.Tab("素養導向閱讀題組"):
1630
  literacy_oriented_reading_content = gr.Textbox(label="輸入閱讀材料")
1631
  literacy_oriented_reading_content_btn = gr.Button("生成閱讀理解題")
 
1632
  # with gr.Tab("自我評估"):
1633
  # self_assessment_content = gr.Textbox(label="輸入自評問卷或檢查表")
1634
  # self_assessment_content_btn = gr.Button("生成自評問卷")
@@ -1664,11 +1698,20 @@ with gr.Blocks() as demo:
1664
  # outputs=[msg, chatbot, thread_id]
1665
  # )
1666
  # chat_with_youtube_transcript
 
 
1667
  send_button.click(
1668
  chat_with_youtube_transcript,
1669
  inputs=[password, video_id, thread_id, df_string_output, msg, chatbot, socratic_mode_btn],
1670
  outputs=[msg, chatbot, thread_id]
1671
  )
 
 
 
 
 
 
 
1672
  # GROQ 模式
1673
  groq_send_button.click(
1674
  chat_with_groq,
@@ -1760,6 +1803,11 @@ with gr.Blocks() as demo:
1760
  inputs=[password, df_string_output, content_topic, content_grade, content_level, lesson_plan_time, lesson_plan_content_type_name],
1761
  outputs=[exam_result, lesson_plan_prompt, exam_result_prompt]
1762
  )
 
 
 
 
 
1763
 
1764
  # 生成結果微調
1765
  exam_result_fine_tune_btn.click(
 
30
  from storage_service import GoogleCloudStorage
31
 
32
 
 
 
33
  is_env_local = os.getenv("IS_ENV_LOCAL", "false") == "true"
34
  print(f"is_env_local: {is_env_local}")
35
 
 
373
  file=audio_file,
374
  response_format="verbose_json",
375
  timestamp_granularities=["segment"],
376
+ prompt="如果逐字稿有中文,請使用繁體中文 zh-TW",
377
  )
378
 
379
  # get segments
 
856
  如果是資料類型,請提估欄位敘述、資料樣態與資料分析,告訴學生這張表的意義,以及可能的結論與對應方式
857
 
858
  如果是影片類型,請提估影片內容,告訴學生這部影片的意義,
859
+ 整體摘要在一百字以內
860
  小範圍切出不同段落的相對應時間軸的重點摘要,最多不超過五段
861
  注意不要遺漏任何一段時間軸的內容
862
  格式為 【start - end】: 摘要
 
865
  整體格式為:
866
  🗂️ 1. 內容類型:?
867
  📚 2. 整體摘要
868
+ 🔖 3. 重點概念
869
+ 🔑 4. 關鍵時刻
870
+ 💡 5. 為什麼我們要學這個?
871
  ❓ 6. 延伸小問題
872
  """
873
 
 
1304
  error_msg = "你的訊息太長了,請縮短訊息長度至五百字以內"
1305
  raise gr.Error(error_msg)
1306
 
1307
+ try:
1308
+ assistant_id = "asst_kmvZLNkDUYaNkMNtZEAYxyPq"
1309
+ client = OPEN_AI_CLIENT
1310
+
1311
+ # file 拿逐字稿資料
1312
+ # instructions = f"""
1313
+ # 你是一個擅長資料分析跟影片教學的老師,user 為學生
1314
+ # 請根據 assistant beta 的上傳資料
1315
+ # 如果 file 內有找到 file.content["{youtube_id}"] 為資料文本,自行判斷資料的種類,
1316
+ # 如果沒有資料,請告訴用戶沒有逐字稿資料,但仍然可以進行對話,使用台灣人的口與表達,及繁體中文 zh-TW
1317
+ # 請嚴格執行,只根據 file.content["{youtube_id}"] 為資料文本,沒有就是沒有資料,不要引用其他資料
1318
+
1319
+ # 如果是影片類型,不用解釋逐字稿格式,直接回答學生問題
1320
+ # socratic_mode = {socratic_mode}
1321
+ # 如果 socratic_mode = True,
1322
+ # - 請用蘇格拉底式的提問方式,引導學生思考,並且給予學生一些提示
1323
+ # - 不要直接給予答案,讓學生自己思考
1324
+ # - 但可以給予一些提示跟引導,例如給予影片的時間軸,讓學生自己去找答案
1325
+ # - 在你回答的開頭標註【蘇格拉底助教:{youtube_id}
1326
+ # 如果 socratic_mode = False,
1327
+ # - 直接回答學生問題
1328
+ # - 在你回答的開頭標註【一般學習精靈:{youtube_id} 】
1329
+ # 如果學生問了一些問題你無法判斷,請告訴學生你無法判斷,並建議學生可以問其他問題
1330
+ # 或者你可以反問學生一些問題,幫助學生更好的理解資料
1331
+ # 如果學生的問題與資料文本無關,請告訴學生你無法回答超出範圍的問題
1332
+ # 最後只要是參考逐字稿資料,請在回答的最後標註【參考資料:(分):(秒)】
1333
+ # """
1334
+
1335
+ # 直接安排逐字稿資料 in instructions
1336
+ trascript_json = json.loads(trascript)
1337
+ # 移除 embed_url, screenshot_path
1338
+ for entry in trascript_json:
1339
+ entry.pop('embed_url', None)
1340
+ entry.pop('screenshot_path', None)
1341
+ trascript_text = json.dumps(trascript_json, ensure_ascii=False, indent=2)
1342
+
1343
+ instructions = f"""
1344
+ 逐字稿資料:{trascript_text}
1345
+ -------------------------------------
1346
+ 你是一個擅長資料分析跟影片教學的老師,user 為學生
1347
+ 如果是影片類型,不用解釋逐字稿格式,直接回答學生問題
1348
+ socratic_mode = {socratic_mode}
1349
+ 如果 socratic_mode = True,
1350
+ - 請用蘇格拉底式的提問方式,引導學生思考,並且給予學生一些提示
1351
+ - 不要直接給予答案,讓學生自己思考
1352
+ - 但可以給予一些提示跟引導,例如給予影片的時間軸,讓學生自己去找答案
1353
+ - 在你回答的開頭標註【蘇格拉底助教:{youtube_id}
1354
+ 如果 socratic_mode = False,
1355
+ - 直接回答學生問題
1356
+ - 在你回答的開頭標註【一般學習精靈:{youtube_id} 】
1357
+ 如果學生問了一些問題你無法判斷,請告訴學生你無法判斷,並建議學生可以問其他問題
1358
+ 或者你可以反問學生一些問題,幫助學生更好的理解資料
1359
+ 如果學生的問題與資料文本無關,請告訴學生你無法回答超出範圍的問題
1360
+ 最後只要是參考逐字稿資料,請在回答的最後標註【參考資料:(分):(秒)】
1361
+ """
1362
 
1363
+ # 创建线程
1364
+ if not thread_id:
1365
+ thread = client.beta.threads.create()
1366
+ thread_id = thread.id
1367
+ else:
1368
+ thread = client.beta.threads.retrieve(thread_id)
1369
+
1370
+ # 向线程添加用户的消息
1371
+ client.beta.threads.messages.create(
1372
+ thread_id=thread.id,
1373
+ role="user",
1374
+ content=user_message
1375
+ )
1376
 
1377
+ # 运行助手,生成响应
1378
+ run = client.beta.threads.runs.create(
1379
+ thread_id=thread.id,
1380
+ assistant_id=assistant_id,
1381
+ instructions=instructions,
1382
+ )
1383
 
1384
+ # 等待助手响应,设定最大等待时间为 30 秒
1385
+ run_status = poll_run_status(run.id, thread.id, timeout=30)
1386
+ # 获取助手的响应消息
1387
+ if run_status == "completed":
1388
+ messages = client.beta.threads.messages.list(thread_id=thread.id)
1389
+ # [MessageContentText(text=Text(annotations=[], value='您好!有什麼我可以幫助您的嗎?如果有任何問題或需要指導,請隨時告訴我!'), type='text')]
1390
+ response_text = messages.data[0].content[0].text.value
1391
+ else:
1392
+ response_text = "學習精靈有點累,請稍後再試!"
1393
 
1394
+ # 更新聊天历史
1395
+ new_chat_history = (user_message, response_text)
1396
+ if chat_history is None:
1397
+ chat_history = [new_chat_history]
1398
+ else:
1399
+ chat_history.append(new_chat_history)
1400
+ except Exception as e:
1401
+ print(f"Error: {e}")
1402
+ raise gr.Error(f"Error: {e}")
1403
 
1404
  # 返回聊天历史和空字符串清空输入框
1405
  return "", chat_history, thread.id
1406
 
1407
+ def process_open_ai_audio_to_chatbot(password, audio_url):
1408
+ verify_password(password)
1409
+ if audio_url:
1410
+ with open(audio_url, "rb") as audio_file:
1411
+ file_size = os.path.getsize(audio_url)
1412
+ if file_size > 2000000:
1413
+ raise gr.Error("檔案大小超過,請不要超過 60秒")
1414
+ else:
1415
+ response = OPEN_AI_CLIENT.audio.transcriptions.create(
1416
+ model="whisper-1",
1417
+ file=audio_file,
1418
+ response_format="text"
1419
+ )
1420
+ # response 拆解 dict
1421
+ print("=== response ===")
1422
+ print(response)
1423
+ print("=== response ===")
1424
+ else:
1425
+ response = ""
1426
+
1427
+ return response
1428
+
1429
  def poll_run_status(run_id, thread_id, timeout=600, poll_interval=5):
1430
  """
1431
  Polls the status of a Run and handles different statuses appropriately.
 
1611
  with gr.Tab("心智圖",elem_id="mind_map_tab"):
1612
  mind_map_html = gr.HTML()
1613
  with gr.Column(scale=2):
1614
+ with gr.Tab("OPENAI"):
1615
+ gr.Markdown("## OPEN AI 模式")
1616
+ chatbot = gr.Chatbot(avatar_images=["https://junyi-avatar.s3.ap-northeast-1.amazonaws.com/live/%20%20foxcat-star-18.png?v=20231113095823614", "https://junyitopicimg.s3.amazonaws.com/s4byy--icon.jpe?v=20200513013523726"], label="OPEN AI 模式")
1617
+ thread_id = gr.Textbox(label="thread_id", visible=False)
1618
+ socratic_mode_btn = gr.Checkbox(label="蘇格拉底家教助理模式", value=True)
1619
+ openai_chatbot_audio_input = gr.Audio(sources=["microphone"], type="filepath")
1620
+ msg = gr.Textbox(label="Message")
1621
+ send_button = gr.Button("Send")
1622
+ with gr.Tab("GROQ"):
1623
+ gr.Markdown("## GROQ 模式")
1624
+ groq_chatbot = gr.Chatbot(label="groq mode chatbot")
1625
+ groq_msg = gr.Textbox(label="Message")
1626
+ groq_send_button = gr.Button("Send")
1627
+ with gr.Tab("JUTOR"):
1628
+ gr.Markdown("## JUTOR API 模式")
1629
+ jutor_chatbot = gr.Chatbot(label="jutor mode chatbot")
1630
+ jutor_msg = gr.Textbox(label="Message")
1631
+ jutor_send_button = gr.Button("Send")
1632
 
1633
  with gr.Tab("教師版"):
1634
  with gr.Row():
 
1652
  lesson_plan_btn = gr.Button("生成課程計畫 📕")
1653
  with gr.Accordion("prompt", open=False):
1654
  lesson_plan_prompt = gr.Textbox(label="worksheet_prompt", show_copy_button=True, lines=40)
1655
+ with gr.Tab("出場券"):
1656
+ exit_ticket_content_type_name = gr.Textbox(value="exit_ticket", visible=False)
1657
+ exit_ticket_time = gr.Slider(label="選擇出場券時間(分鐘)", minimum=5, maximum=10, step=1, value=8)
1658
+ exit_ticket_btn = gr.Button("生成出場券 🎟️")
1659
+ with gr.Accordion("prompt", open=False):
1660
+ exit_ticket_prompt = gr.Textbox(label="worksheet_prompt", show_copy_button=True, lines=40)
1661
 
1662
  with gr.Tab("素養導向閱讀題組"):
1663
  literacy_oriented_reading_content = gr.Textbox(label="輸入閱讀材料")
1664
  literacy_oriented_reading_content_btn = gr.Button("生成閱讀理解題")
1665
+
1666
  # with gr.Tab("自我評估"):
1667
  # self_assessment_content = gr.Textbox(label="輸入自評問卷或檢查表")
1668
  # self_assessment_content_btn = gr.Button("生成自評問卷")
 
1698
  # outputs=[msg, chatbot, thread_id]
1699
  # )
1700
  # chat_with_youtube_transcript
1701
+
1702
+ # OPENAI 模式
1703
  send_button.click(
1704
  chat_with_youtube_transcript,
1705
  inputs=[password, video_id, thread_id, df_string_output, msg, chatbot, socratic_mode_btn],
1706
  outputs=[msg, chatbot, thread_id]
1707
  )
1708
+ openai_chatbot_audio_input.change(
1709
+ process_open_ai_audio_to_chatbot,
1710
+ inputs=[password, openai_chatbot_audio_input],
1711
+ outputs=[msg]
1712
+ )
1713
+
1714
+
1715
  # GROQ 模式
1716
  groq_send_button.click(
1717
  chat_with_groq,
 
1803
  inputs=[password, df_string_output, content_topic, content_grade, content_level, lesson_plan_time, lesson_plan_content_type_name],
1804
  outputs=[exam_result, lesson_plan_prompt, exam_result_prompt]
1805
  )
1806
+ exit_ticket_btn.click(
1807
+ on_generate_ai_content,
1808
+ inputs=[password, df_string_output, content_topic, content_grade, content_level, exit_ticket_time, exit_ticket_content_type_name],
1809
+ outputs=[exam_result, exit_ticket_prompt, exam_result_prompt]
1810
+ )
1811
 
1812
  # 生成結果微調
1813
  exam_result_fine_tune_btn.click(
educational_material.py CHANGED
@@ -45,6 +45,8 @@ class EducationalMaterial:
45
  return self._generate_worksheet_prompt()
46
  elif self.content_type == 'lesson_plan':
47
  return self._generate_lesson_plan_prompt()
 
 
48
 
49
  def _generate_worksheet_prompt(self):
50
  bloom_worksheet_prompt = """
@@ -189,60 +191,83 @@ class EducationalMaterial:
189
  return worksheet_prompt
190
 
191
  def _generate_lesson_plan_prompt(self):
192
- # lesson_plan_prompt = """
193
- # 你是一位專業教師,
194
- # 請根據以上要教學的項目細節
195
- # 幫我安排一個 lesson plan
196
-
197
- # 規則如下,請嚴格遵守
198
- # 1. 請使用 zh-TW
199
- # 2. 該換行就換行,盡量滿足 word .doc 的格式
200
- # 3. 【課程大綱】的工作項目請嚴格遵守【課程時間】的時間長度,總和時間不要超過或不足
201
- # 4. 時間安排盡量以五分鐘的倍數為一個單位
202
- # 5. 並且根據課程目標安排教學內容
203
-
204
- # 範例:
205
- # 【課程主題】計算面積的創意設計
206
-
207
- # 【課程目標】
208
- # - 理解不同形狀(正方形、長方形、三角形)的面積計算方法。
209
- # - 學會如何通過對摺改變形狀並計算新形狀的面積。
210
- # - 鼓勵創造力和實際操作,將數學知識應用於創作中。
211
-
212
- # 【年級】國小三年級
213
-
214
- # 【難度】基礎
215
 
216
- # 【課程時間】60 分鐘
217
-
218
- # 【課程大綱】
219
- # - 開場介紹 (5 分鐘)
220
- # 簡短介紹今天的課程主題和目標。
221
-
222
- # - 講解與示範 (15 分鐘)
223
- # 形狀與面積:介紹基本幾何形狀(正方形、長方形、三角形)的面積計算公式。
224
- # 對摺技巧:示範如何通過對摺正方形貼紙創造新的形狀(半正方形、三角形)並解釋面積如何改變。
225
- # 應用討論:討論如何使用這些形狀創造不同的圖案或設計,特別是斜屋頂的設計。
226
-
227
- # - 實作活動 (25 分鐘)
228
- # 材料準備:每位學生發放正方形貼紙、剪刀、膠水和紙張。
229
- # 創意剪貼:學生使用對摺技巧製作不同的幾何形狀,並將它們組合成一個有關斜屋頂的圖案或其他創意設計。
230
- # 面積計算:學生計算他們設計中每種形狀的面積,以及整體設計的總面積。
231
-
232
- # - 分享與討論 (10 分鐘)
233
- # 學生展示他們的創作並分享他們的設計過程,包括面積如何影響他們的設計選擇。
234
- # 討論學生在創作過程中遇到的挑戰和他們如何解決。
235
-
236
- # - 總結 (5 分鐘)
237
- # 回顧課程學到的主要概念。
238
- # 鼓勵學生在家中嘗試更多的創意組合和面積計算。
239
-
240
- # - 課後活動
241
- # 建議學生使用家中的材料(如報紙、雜誌等)進行更多的創意剪貼,並嘗試計算不同形狀的面積,進一步鞏固今天學到的知識。
242
-
243
- # 【教學策略總結】
244
- # 通過這個課程計劃,學生不僅能夠學習數學知識,還能夠將這些知識應用於實際生活中,從而增強他們的創造力和問題解決能力。
245
- # """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
 
247
  lesson_plan_5E_prompt = """
248
  你是一位專業教師,
@@ -323,10 +348,63 @@ class EducationalMaterial:
323
  - 形成性評估:探索和細化階段的觀察以及討論和演示將深入了解學生對相同分母分數加法和減法的理解。
324
  - 總結性評估:收集並審查學生的工作表和任務卡,以評估他們解決涉及具有相同分母的分數的加法和減法問題的能力。
325
  """
326
- lesson_plan_prompt = lesson_plan_5E_prompt
327
 
328
  return lesson_plan_prompt
329
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  def create_ai_content(self, ai_client, request_payload):
331
  user_content = self.build_user_content()
332
  messages = self.build_messages(user_content)
@@ -339,7 +417,9 @@ class EducationalMaterial:
339
  if self.content_type == 'worksheet':
340
  specific_feature_text = f"理論模型: {self.specific_feature}"
341
  elif self.content_type == 'lesson_plan':
342
- specific_feature_text = f"時間: {self.specific_feature}分鐘"
 
 
343
 
344
  # 根据属性构建用户内容
345
  user_content = f"""
@@ -352,6 +432,7 @@ class EducationalMaterial:
352
  請根據逐字稿進行以下工作:
353
  不要提到 【逐字稿】 這個詞,直接給出工作內容即可
354
  如果是中文素材,請嚴格使用 zh-TW
 
355
  {self.generate_content_prompt()}
356
  """
357
  print("====User content====")
 
45
  return self._generate_worksheet_prompt()
46
  elif self.content_type == 'lesson_plan':
47
  return self._generate_lesson_plan_prompt()
48
+ elif self.content_type == 'exit_ticket':
49
+ return self._generate_exit_ticket_prompt()
50
 
51
  def _generate_worksheet_prompt(self):
52
  bloom_worksheet_prompt = """
 
191
  return worksheet_prompt
192
 
193
  def _generate_lesson_plan_prompt(self):
194
+ lesson_plan_ADDIE_prompt = """
195
+ 你是一位專業教師,
196
+ 請根據以上要教學的項目細節(主題、年級、課程時間、課程目標)
197
+ 幫我安排一個 lesson plan
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
 
199
+ 規則如下,請嚴格遵守
200
+ 1. 請使用繁體中文溝通 zh-TW,並使用台灣人的用語
201
+ 2. 該換行就換行,盡量滿足 word .doc 的格式
202
+ 3. 【課程大綱】的工作項目請嚴格遵守【課程時間】的時間長度,總和時間不要超過或不足
203
+ 4. 時間安排盡量以五分鐘的倍數為一個單位
204
+ 5. 並且根據課程目標安排教學內容
205
+ Step1. 你是一個精通於課程設計的老師,能夠運用 ADDIE 教學策略來設計一門適合學生的課程。
206
+ Step2. 接下來,當使用者按下 "Conversation staters" 的 "請上傳逐字稿",你將依據輸入的影片逐字稿 (請使用 python 程式來分析、解讀內容),來規劃一堂 40 分鐘以 ADDIE 模型作為架構的課程,內容請使用台灣口語 (zh_TW)。
207
+ - 以下是 ADDIE 的說明:
208
+
209
+ ADDIE 教學設計模式是一種廣泛應用於教育和訓練領域的系統化教學設計流程。ADDIE 代表分析(Analysis)、設計(Design)、開發(Development)、實施(Implementation)、評估(Evaluation)五個階段:
210
+ 1. 分析(Analysis)階段:在這一階段,設計者需評估教學需求和學習者的背景,包括學習者的知識水平、學習風格及教學目標等。
211
+ 2. 設計(Design)階段:基於分析階段的資料,開始構��教學計劃,包括課程目標、教學策略、內容架構、評估方法等。
212
+ a. 轉化課程目標為:單元目標和表現的結果
213
+ b. 決定可以涵括這些目標的主題或單元,計算實際實施教學時會花費的時間
214
+ c. 依課程目標安排課程順序
215
+ d. 設計教學的單元,並確認在這些單元中所要達到的主要目標
216
+ e. 規劃各單元的學習活動
217
+ f. 發展特定的評量以確認學生的學習情況
218
+ 3. 開發(Development)階段:這個階段主要是製作教學材料,如課程內容、學習活動、多媒體素材等。
219
+ 4. 實施(Implementation)階段:在此階段,實際執行教學計劃,這包括教授課程、指導學習者及管理學習過程。
220
+
221
+ 5 評估(Evaluation)階段:評估整個教學設計和實施的有效性,這不僅包括學習成果的評估,還要檢視整個教學過程的有效性與可改進之處。
222
+ a. 教材:是否達到教學目標?
223
+ b. 過程:設計過程中的品質是否OK?
224
+ c. 學習者的反應/感受
225
+ d. 學習者在學習後達成之成就
226
+ e. 教學實施的結果
227
+
228
+ Step3. 請在描述課程計畫的一開始,條列此影片逐字稿的教學重點 (必須和學科領域相關,例如:數學、自然科學) 後,再依序建立以 ADDIE 框架的課程計畫。
229
+ Step4. 請在「設計」和「實施」階段請使用合適的範例做說明。
230
+ Step5. 請使用 Markdown 語法,標題與段落文字的字級需有所區隔。
231
+
232
+ example:
233
+ # 課程設計:面積的實測與估測
234
+
235
+ # 教學重點
236
+ 1. 面積的概念:解釋什麼是面積,以及它在日常生活中的應用。
237
+ 2. 面積的計算:教授如何計算不同形狀的面積(例如矩形、三角形)。
238
+ 3. 實測與估測的區別:比較實際測量面積和估算面積的不同方法。
239
+ 4. 應用實例:使用日常生活中的例子,例如給麥麥的生日卡片大小的比較,來說明面積的重要性。
240
+
241
+ # 分析(Analysis)
242
+ - 目標學習者:小學高年級學生。
243
+ - 學習需求:理解面積概念,掌握基本面積計算方法。
244
+ - 學習風格:結合視覺教材和互動活動。
245
+
246
+ # 設計(Design)
247
+ - 課程目標:學生能夠理解面積概念,並能透過實際操作學會估算和計算面積。
248
+ - 學習單元:(a)面積基礎概念(b)計算面積(c)實測與估測的比較。
249
+ - 教學策略:透過互動遊戲、案例討論和實作活動進行教學。
250
+ - 評估方法:透過小測驗和課堂參與情況進行評估。
251
+
252
+ # 開發(Development)
253
+ - 教材準備:準備視覺化教學幻燈片,設計互動遊戲和實作活動。
254
+ - 教學活動:設計面積估測遊戲,讓學生在實際操作中學習。
255
+
256
+ # 實施(Implementation)
257
+ - 課程時間分配:(a)面積基礎概念(10分鐘)(b)計算面積(15分鐘)(c)實測與估測比較(10分鐘)(d)總結與回顧(5分鐘)。
258
+ - 教學範例:
259
+ - 面積基礎概念:介紹面積是如何在日常生活中應用,例如計算桌布的大小。
260
+ - 計算面積:透過計算教室黑板或門的面積來教學。
261
+ - 實測與估測比較:讓學生估計並實際測量教室中物品的面積,比較結果。
262
+
263
+ # 評估(Evaluation)
264
+ - 教材評估:確保教材能清楚傳達面積概念。
265
+ - 學習者反應:觀察學生參與情況,收集反饋以改善教學。
266
+ - 學習成就:透過小測驗評估學生對面積概念的理解。
267
+ - 教學實施結果:評估課程的整體有效性,並根據學生的學習成果進行調整。
268
+
269
+ 這個課程計畫將幫助學生透過互動和實作活動來深入理解面積的概念和計算方法
270
+ """
271
 
272
  lesson_plan_5E_prompt = """
273
  你是一位專業教師,
 
348
  - 形成性評估:探索和細化階段的觀察以及討論和演示將深入了解學生對相同分母分數加法和減法的理解。
349
  - 總結性評估:收集並審查學生的工作表和任務卡,以評估他們解決涉及具有相同分母的分數的加法和減法問題的能力。
350
  """
351
+ lesson_plan_prompt = lesson_plan_ADDIE_prompt
352
 
353
  return lesson_plan_prompt
354
 
355
+ def _generate_exit_ticket_prompt(self):
356
+ exit_ticket_prompt = """
357
+ 你是一位專業教師,
358
+ 請根據以上要教學的項目細節及逐字稿
359
+ 在一節課結束前用上述的時間(10分鐘內)
360
+ 運用出場券 (exit ticket) 來檢核學生的學習是否有對上學習目標,有哪些知識點或技能還不熟悉
361
+ 目的是讓教學更加精準;出場券能夠檢視每一堂課的學習成效,從學生的答題狀況,
362
+ 可以觀察班上有多少比例學生沒學會,沒學會的地方又是什麼。
363
+
364
+ 規則如下,請嚴格遵守:
365
+ 1. 內容請使用台灣口語的繁體中文 (zh_TW),不可以使用大陸用語,也不可以使用簡體字。
366
+ 2. 該換行就換行,盡量滿足 word .doc 的格式
367
+ 3. 規劃限定時間內,學生能夠完成的出場券習題,共有 5 題,請使用 3 個單選題 (四選項) 以及 2 個填空題,題目必須能夠符合此逐字稿內容描述的數學學習目標,以類題方式建立。
368
+ 4. 此出場券習題最末請公布各題的答案。
369
+
370
+ example:
371
+ 出場券習題:公里、公尺和公分的換算
372
+ 選擇題(請從四個選項中選出一個正確答案)
373
+
374
+ 1. 1公里等於多少公尺?
375
+ A) 100公尺
376
+ B) 1000公尺
377
+ C) 10,000公尺
378
+ D) 100公分
379
+
380
+ 2. 5公尺等於多少公分?
381
+ A) 50公分
382
+ B) 500公分
383
+ C) 5,000公分
384
+ D) 50,000公分
385
+
386
+ 3. 如果你走了2.5公里的路程,這段路程等於多少公尺?
387
+ A) 250公尺
388
+ B) 2,500公尺
389
+ C) 25,000公尺
390
+ D) 250,000公尺
391
+
392
+ 填空題
393
+ 1. 100公分等於___公尺?(請填入數字)
394
+ 2. 1公尺等於___公分?(請填入數字)
395
+
396
+
397
+ 答案公布
398
+ 答案:B) 1000公尺
399
+ 答案:B) 500公分
400
+ 答案:B) 2,500公尺
401
+ 答案:A) 3公尺
402
+ 答案:1公尺
403
+
404
+ 這套出場券習題旨在幫助學生掌握公里、公尺、和公分之間的換算關係,通過實際的例子加深學生對這些單位之間轉換的理解。
405
+ """
406
+ return exit_ticket_prompt
407
+
408
  def create_ai_content(self, ai_client, request_payload):
409
  user_content = self.build_user_content()
410
  messages = self.build_messages(user_content)
 
417
  if self.content_type == 'worksheet':
418
  specific_feature_text = f"理論模型: {self.specific_feature}"
419
  elif self.content_type == 'lesson_plan':
420
+ specific_feature_text = f"時間: {self.specific_feature} 分鐘"
421
+ elif self.content_type == 'exit_ticket':
422
+ specific_feature_text = f"時間: {self.specific_feature} 分鐘"
423
 
424
  # 根据属性构建用户内容
425
  user_content = f"""
 
432
  請根據逐字稿進行以下工作:
433
  不要提到 【逐字稿】 這個詞,直接給出工作內容即可
434
  如果是中文素材,請嚴格使用 zh-TW
435
+ 請用 {self.grade} 年級的口吻,不要用太難的詞彙
436
  {self.generate_content_prompt()}
437
  """
438
  print("====User content====")