File size: 5,902 Bytes
1d355ad
fabb74d
56cd9ca
22032f3
56cd9ca
 
 
1d355ad
56cd9ca
22032f3
 
fabb74d
 
56cd9ca
 
ea3eb7a
56cd9ca
fabb74d
 
 
 
ae8ada4
fabb74d
 
 
90424bc
fabb74d
8af7eda
 
115bf3e
 
8af7eda
 
 
 
 
115bf3e
 
 
 
 
 
 
 
 
 
 
 
 
 
fabb74d
39688bd
a941647
fabb74d
a941647
90424bc
fabb74d
07a1af3
a941647
fabb74d
4c541d4
fabb74d
217a78d
fabb74d
 
3b978dd
a941647
4c541d4
fabb74d
feb03cf
3b4323a
fabb74d
3b4323a
fabb74d
 
3b4323a
 
940b028
56cd9ca
 
 
a941647
56cd9ca
39688bd
03d0703
56cd9ca
 
a941647
f84d704
a941647
a4fd186
56cd9ca
 
 
 
 
 
a941647
56cd9ca
 
 
a941647
56cd9ca
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import os
import time
import streamlit as st
import google.generativeai as genai
from streamlit_extras.colored_header import colored_header
from streamlit_extras.add_vertical_space import add_vertical_space
import markdown

# Google Gemini API Key μ„€μ •
genai.configure(api_key=os.environ["GEMINI_API_KEY"])

# λͺ¨λΈ μ„€μ •
generation_config = {
    "temperature": 1,
    "top_p": 0.95,
    "top_k": 40,
    "max_output_tokens": 8192,
    "response_mime_type": "text/plain",
}

model = genai.GenerativeModel(
    model_name="gemini-2.0-flash",
    generation_config=generation_config,
)

# ν”„λ‘¬ν”„νŠΈ μ„€μ •
SYSTEM_PROMPT = """
당신은 κ΅μˆ˜ν•™μŠ΅ ν™œλ™ 섀계 μ „λ¬Έκ°€, ꡐ과ꡐ윑 λ‚΄μš© μ „λ¬Έκ°€, κ΅μœ‘κ³΅ν•™μžμ΄λ©°, 특히 κ²Œμ΄λ―Έν”ΌμΌ€μ΄μ…˜(κ²Œμž„ν™”) μˆ˜μ—… 섀계 μ „λ¬Έκ°€μž…λ‹ˆλ‹€.
κ²Œμ΄λ―Έν”ΌμΌ€μ΄μ…˜(κ²Œμž„ν™”) μˆ˜μ—… 섀계 μš”μ²­:
μ„ μƒλ‹˜λ“€μ΄ ν™œλ™ μ£Όμ œμ™€ ν•™μŠ΅ λͺ©ν‘œλ₯Ό μž…λ ₯ν•˜λ©΄, ν•΄λ‹Ή μ£Όμ œμ™€ λͺ©ν‘œμ— μ΅œμ ν™”λœ κ²Œμ΄λ―Έν”ΌμΌ€μ΄μ…˜(κ²Œμž„ν™”) μš”μ†Œλ₯Ό λ°˜μ˜ν•˜μ—¬ μˆ˜μ—… ν™œλ™μ„ μƒμ„Έν•˜κ²Œ μ„€κ³„ν•©λ‹ˆλ‹€.

핡심 섀계 원칙:
μˆ˜μ—… λ‚΄μš©κ³Όμ˜ 찰떑같은 톡합: κ²Œμ΄λ―Έν”ΌμΌ€μ΄μ…˜ μš”μ†ŒλŠ” λ‹¨μˆœνžˆ ν₯λ―Έ μœ λ°œμ„ μœ„ν•œ μž₯μΉ˜κ°€ μ•„λ‹ˆλΌ, μˆ˜μ—… λ‚΄μš©κ³Ό μžμ—°μŠ€λŸ½κ²Œ μ—°κ²°λ˜μ–΄ ν•™μŠ΅ λͺ©ν‘œ 달성을 효과적으둜 지원해야 ν•©λ‹ˆλ‹€.
체계적 사고(CoT; Chain of Thought) 기반 섀계: 각 ν™œλ™ 단계λ₯Ό μ²΄κ³„μ μœΌλ‘œ μ„€κ³„ν•˜μ—¬, 학생듀이 λ‹¨κ³„λ³„λ‘œ ν•™μŠ΅ λ‚΄μš©μ„ μŠ΅λ“ν•˜κ³  사고λ ₯을 ν™•μž₯ν•  수 μžˆλ„λ‘ μœ λ„ν•©λ‹ˆλ‹€.
ν•™μŠ΅ λͺ©ν‘œ 쀑심 섀계: λͺ¨λ“  κ²Œμ΄λ―Έν”ΌμΌ€μ΄μ…˜ μš”μ†Œμ™€ ν™œλ™μ€ λͺ…ν™•ν•˜κ²Œ μ„€μ •λœ ν•™μŠ΅ λͺ©ν‘œ 달성을 μ΅œμš°μ„ μœΌλ‘œ ν•©λ‹ˆλ‹€.
κ²Œμ΄λ―Έν”ΌμΌ€μ΄μ…˜(κ²Œμž„ν™”) μš”μ†Œ: (μ•„λž˜ μš”μ†Œλ“€μ„ ν•™μŠ΅ λ‚΄μš©κ³Ό λͺ©ν‘œμ— 맞게 적절히 ν™œμš©ν•˜κ³  μ‘°μ •ν•©λ‹ˆλ‹€.)
포인트/λ°°μ§€/λ¦¬λ”λ³΄λ“œ: ν•™μŠ΅ μ„±κ³Όλ₯Ό μ‹œκ°μ μœΌλ‘œ 보여주고, 동기 λΆ€μ—¬λ₯Ό κ°•ν™”ν•©λ‹ˆλ‹€. (예: ν€΄μ¦ˆ μ •λ‹΅ μ‹œ 포인트 λΆ€μ—¬, 탐ꡬ ν™œλ™ 성곡 μ‹œ λ°°μ§€ μˆ˜μ—¬, λˆ„μ  포인트 기반 λ¦¬λ”λ³΄λ“œ 운영)
κ·œμΉ™/보상: ν•™μŠ΅ λͺ©ν‘œ 달성에 도움이 λ˜λŠ” κ·œμΉ™μ„ μ„€μ •ν•˜κ³ , 성취에 λŒ€ν•œ μ μ ˆν•œ 보상을 μ œκ³΅ν•©λ‹ˆλ‹€. (예: νŒ€ ν˜‘λ™ κ·œμΉ™, κ°œμΈλ³„ μ±Œλ¦°μ§€ 성곡 보상, 깜짝 보상)
μŠ€ν† λ¦¬ν…”λ§: ν•™μŠ΅ λ‚΄μš©μ„ ν₯미둜운 μ΄μ•ΌκΈ°λ‘œ κ΅¬μ„±ν•˜μ—¬ λͺ°μž…도λ₯Ό λ†’μž…λ‹ˆλ‹€. (예: 역사 속 인물이 λ˜μ–΄ λ―Έμ…˜ μˆ˜ν–‰, κ³Όν•™μžκ°€ λ˜μ–΄ 탐ꡬ ν™œλ™ μ§„ν–‰)
레벨/μ§„ν–‰: ν•™μŠ΅ λ‚œμ΄λ„λ₯Ό μ μ§„μ μœΌλ‘œ λ†’μ—¬ 성취감을 λŠλΌλ„λ‘ ν•©λ‹ˆλ‹€. (예: ν•™μŠ΅ λ‚΄μš© 이해도에 따라 레벨 λΆ€μ—¬, μƒˆλ‘œμš΄ 레벨 도전 과제 제곡)
경쟁/ν˜‘λ ₯: κ±΄κ°•ν•œ 경쟁과 ν˜‘λ ₯을 톡해 ν•™μŠ΅ 효과λ₯Ό λ†’μž…λ‹ˆλ‹€. (예: νŒ€ λŒ€ν•­ ν€΄μ¦ˆ λŒ€νšŒ, ν˜‘λ™ ν”„λ‘œμ νŠΈ)
λ―ΈμŠ€ν„°λ¦¬ μš”μ†Œ: 예츑 λΆˆκ°€λŠ₯ν•œ μš”μ†Œλ‚˜ λ―ΈμŠ€ν„°λ¦¬ 과제λ₯Ό 톡해 ν˜ΈκΈ°μ‹¬μ„ μžκ·Ήν•˜κ³  μ°Έμ—¬λ₯Ό μœ λ„ν•©λ‹ˆλ‹€. (예: μˆ¨κ²¨μ§„ λ‹¨μ„œ μ°ΎκΈ°, λΉ„λ°€ λ―Έμ…˜ ν•΄κ²°)
선택과 κ²°κ³Ό: ν•™μƒμ˜ 선택에 따라 κ²°κ³Όκ°€ λ‹¬λΌμ§€λŠ” μš”μ†Œλ₯Ό 톡해 주도적인 ν•™μŠ΅ μ°Έμ—¬λ₯Ό μœ λ„ν•©λ‹ˆλ‹€. (예: ν•™μŠ΅ 경둜 선택, 문제 ν•΄κ²° 방식 선택)

ν™œλ™ ꡬ성 μš”μ†Œ: (μ•„λž˜ μš”μ†Œλ“€μ„ ν¬ν•¨ν•˜μ—¬ μƒμ„Έν•˜κ²Œ μˆ˜μ—… ν™œλ™μ„ μ„€κ³„ν•©λ‹ˆλ‹€.)
ν™œλ™ 주제 및 ν•™μŠ΅ λͺ©ν‘œ: μ œμ‹œλœ ν™œλ™ μ£Όμ œμ™€ ν•™μŠ΅ λͺ©ν‘œλ₯Ό λͺ…ν™•νžˆ μ„€μ •ν•©λ‹ˆλ‹€.
ν™œλ™ 단계별 μ•ˆλ‚΄: 각 단계별 ν™œλ™ λͺ©ν‘œ, μˆ˜ν–‰ 방법, 평가 기쀀을 ꡬ체적으둜 μ œμ‹œν•©λ‹ˆλ‹€. (체계적 사고 기반)
ν™œλ™ μ€€λΉ„λ¬Ό 및 자료: ν™œλ™μ— ν•„μš”ν•œ μ€€λΉ„λ¬Ό, ν•™μŠ΅ 자료, μ°Έκ³  자료λ₯Ό μƒμ„Ένžˆ μ•ˆλ‚΄ν•©λ‹ˆλ‹€.
ν™œλ™ 유의점: 학생과 ꡐ사가 ν™œλ™ μ‹œ μœ μ˜ν•΄μ•Ό ν•  사항을 λͺ…μ‹œν•©λ‹ˆλ‹€.
학생 제곡 ν™œλ™ μ•ˆλ‚΄ 자료: 학생듀이 μ‰½κ²Œ 이해할 수 μžˆλ„λ‘ ν™œλ™ μ•ˆλ‚΄ 자료λ₯Ό ꡬ체적이고 λͺ…ν™•ν•˜κ²Œ μ œκ³΅ν•©λ‹ˆλ‹€. (μ˜ˆμ‹œ 포함)
"""

def generate_curriculum(topic, grade):
    """
    ν™œλ™ μ£Όμ œμ™€ 학년을 μž…λ ₯λ°›μ•„ κ²Œμ΄λ―Έν”ΌμΌ€μ΄μ…˜ μˆ˜μ—…μ„ μƒμ„±ν•©λ‹ˆλ‹€.
    
    Args:
        topic (str): ν™œλ™ 주제
        grade (str): ν•™λ…„ μˆ˜μ€€
    Returns:
        str: μƒμ„±λœ ν™œλ™
    """

    prompt = [
        SYSTEM_PROMPT,
        f"**ν™œλ™ 주제:** {topic}",
        f"**ν•™λ…„ μˆ˜μ€€:** {grade}",
        "**ν™œλ™:**", 
    ]

    response = model.generate_content(prompt, stream=True)
    collected_text = ""
    for token in response:
        chunk = token.text
        collected_text += chunk
        yield collected_text  # μ‹€μ‹œκ°„ 좜λ ₯을 μœ„ν•΄ yield μ‚¬μš©
        time.sleep(0.03)  # 좜λ ₯ 속도 쑰절

# Streamlit Interface
colored_header(
    label="κ²Œμ΄λ―Έν”ΌμΌ€μ΄μ…˜ μˆ˜μ—… 섀계 λ„μš°λ―Έ",
    description="μ„ μƒλ‹˜μ΄ ν™œλ™ μ£Όμ œμ™€ ν•™λ…„ μˆ˜μ€€μ„ μž…λ ₯ν•˜μ‹œλ©΄ κ²Œμ΄λ―Έν”ΌμΌ€μ΄μ…˜ μš”μ†Œλ₯Ό ν¬ν•¨ν•˜μ—¬ μˆ˜μ—…μ„ ꡬ체적으둜 μ„€κ³„ν•΄μ€λ‹ˆλ‹€.",
    color_name="red-70",
)

add_vertical_space(1)

# ν•™λ…„ 선택 μΆ”κ°€
grade_level = st.selectbox("ν•™λ…„ μˆ˜μ€€μ„ μ„ νƒν•˜μ„Έμš”", ["μ΄ˆλ“±ν•™κ΅ 1ν•™λ…„", "μ΄ˆλ“±ν•™κ΅ 2ν•™λ…„", "μ΄ˆλ“±ν•™κ΅ 3ν•™λ…„", "μ΄ˆλ“±ν•™κ΅ 4ν•™λ…„", "μ΄ˆλ“±ν•™κ΅ 5ν•™λ…„", "μ΄ˆλ“±ν•™κ΅ 6ν•™λ…„"])

topic = st.text_area("ν™œλ™ 주제", height=100)

generate_button = st.button("κ²Œμ΄λ―Έν”ΌμΌ€μ΄μ…˜ μˆ˜μ—… 섀계")

# 좜λ ₯ μ˜μ—­ μ •μ˜
output_area = st.empty()

if generate_button and topic and grade_level:
    output_text = ""
    output_area.markdown(output_text)
    try:
        for partial_output in generate_curriculum(topic, grade_level):
            output_text = partial_output
            output_area.markdown(output_text)
    except Exception as e:
        st.error(f"였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€: {str(e)}")

    # 볡사 λ²„νŠΌ μΆ”κ°€
    if output_text:
        if st.button("좜λ ₯ λ‚΄μš© 볡사"):
            st.write(output_text)
            st.success("좜λ ₯ λ‚΄μš©μ΄ λ³΅μ‚¬λ˜μ—ˆμŠ΅λ‹ˆλ‹€!")