Create app.py
Browse files
app.py
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import time
|
| 3 |
+
import streamlit as st
|
| 4 |
+
import google.generativeai as genai
|
| 5 |
+
from streamlit_extras.colored_header import colored_header
|
| 6 |
+
from streamlit_extras.add_vertical_space import add_vertical_space
|
| 7 |
+
import markdown
|
| 8 |
+
|
| 9 |
+
# Google Gemini API ν€ μ€μ
|
| 10 |
+
genai.configure(api_key=os.environ["GEMINI_API_KEY"])
|
| 11 |
+
|
| 12 |
+
# λͺ¨λΈ μ€μ
|
| 13 |
+
generation_config = {
|
| 14 |
+
"temperature": 0.7,
|
| 15 |
+
"top_p": 0.85,
|
| 16 |
+
"top_k": 64,
|
| 17 |
+
"max_output_tokens": 25000,
|
| 18 |
+
"response_mime_type": "text/plain",
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
model = genai.GenerativeModel(
|
| 22 |
+
model_name="gemini-2.0-flash-thinking-exp-01-21",
|
| 23 |
+
generation_config=generation_config,
|
| 24 |
+
)
|
| 25 |
+
|
| 26 |
+
SYSTEM_PROMPT = """
|
| 27 |
+
λμ νλ
: {grade}
|
| 28 |
+
μ±μ·¨κΈ°μ€ λ° μ£Όμ λ΄μ©: {achievement_standard}
|
| 29 |
+
|
| 30 |
+
μ μ 보λ₯Ό λ°νμΌλ‘ ν΅μ¬ μμ΄λμ΄ μ΄ν΄λ₯Ό λͺ©νλ‘ νλ {grade} μμ€μ μ ν©ν κ°λ
κΈ°λ° νꡬνμ΅μ μ€κ³ν΄ μ£ΌμΈμ. λ€μ κ΅¬μ± μμμ λ°λΌ μμΈνκ³ μ²΄κ³μ μΌλ‘ μ€λͺ
ν΄μΌ ν©λλ€.
|
| 31 |
+
κ° κ΅¬μ± μμλ μλ‘ μ°κ²°λκ³ μ κΈ°μ μΌλ‘ ꡬμ±λμ΄μΌ νλ©°, νμλ€μ ν₯λ―Έμ μ°Έμ¬λ₯Ό μ λν μ μλ μ°½μμ μ΄κ³ νμ μ μΈ νλλ€μ μ μν΄μΌ ν©λλ€.
|
| 32 |
+
νΉν, λͺ¨λ νλμ νμλ€μ΄ μ€μ€λ‘ ν΅μ¬ μμ΄λμ΄λ₯Ό λ°κ²¬νκ³ κΉμ΄ μκ² μ΄ν΄ν μ μλλ‘ μ€κ³λμ΄μΌ ν©λλ€.
|
| 33 |
+
λ¨Όμ μ€νΈλλλ₯Ό 2~3κ°λ‘ μ€μ νμΈμ.μ€νΈλλ(Strand)λ λ¨μμ μμ£Όμ μ κ°μΌλ©°, κ° μ€νΈλλλ μ¬λ¬ μ°¨μμ μμ
μΌλ‘ ꡬμ±λ©λλ€.
|
| 34 |
+
μ€νΈλλ μμμλ "κ΄κ³λ§ΊκΈ° - μ§μ€νκΈ° - μ‘°μ¬νκΈ° - μ‘°μ§ λ° μ 리νκΈ° - μΌλ°ν - μ μ΄ - μ±μ°°νκΈ°"μ λ¨κ³μ κ°λ
κΈ°λ° νꡬνμ΅μ μ€κ³ν΄μΌν©λλ€.
|
| 35 |
+
κ° λ¨κ³μμλ ν΄λΉ λ¨κ³μ λ§λ νꡬ μ§λ¬Έκ³Ό μΌλ°νκ° μ μλμ΄μΌ νκ³ , κ·Έ μΌλ°νμ λλ¬ν μ μλ λ¨κ³λ³ κ°λ
κΈ°λ° νꡬνμ΅ νλμ΄ κ΅¬μ²΄μ μ΄κ³ μμΈνκ² μ μλμ΄μΌ ν©λλ€.(κ·Έλ¦¬κ³ λ΄μ© μλ΅μ νμ§λ§κ³ λͺ¨λ λ΄μ©μ μΆλ ₯νμΈμ.)
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
1. ν΅μ¬ μμ΄λμ΄ (Key Ideas & Generalizations):
|
| 39 |
+
μ΄ μ£Όμ λ₯Ό κ΄μ°°νλ κ°μ₯ μ€μν κ΄μ (Conceptual Lens)μ 무μμΈκ°?
|
| 40 |
+
μ΄ μ£Όμ λ₯Ό ν΅ν΄ νμλ€μ΄ μ΄ν΄ν΄μΌ ν κ°μ₯ μ€μν μμ΄λμ΄(Key Ideas)λ 무μμΈκ°? 2-3κ°μ λ¬Έμ₯μΌλ‘ λͺ
ννκ² κΈ°μ νμΈμ.
|
| 41 |
+
μ μμ΄λμ΄λ€μ λ·λ°μΉ¨νλ μΌλ°νλ μ§μ(Generalizations)μ 3-5κ°μ λ¬Έμ₯μΌλ‘ μ€λͺ
νμΈμ.
|
| 42 |
+
|
| 43 |
+
2. λ§€ν¬λ‘ κ°λ
(Macro Concepts) λ° λ§μ΄ν¬λ‘ κ°λ
(Micro Concepts):
|
| 44 |
+
μ΄ μ£Όμ λ₯Ό μ΄ν΄νλ λ° νμν ν° νμ κ°λ
(λ§€ν¬λ‘ κ°λ
, Conceptual Lens)μ 무μμΈκ°?
|
| 45 |
+
μ΄ μ£Όμ μ κ΄λ ¨λ ꡬ체μ μΈ κ΅κ³Ό κ°λ
(λ§μ΄ν¬λ‘ κ°λ
, Subject-Specific Concepts)μ 무μμΈκ°?
|
| 46 |
+
λ§€ν¬λ‘ κ°λ
κ³Ό λ§μ΄ν¬λ‘ κ°λ
μ¬μ΄μ κ΄κ³λ₯Ό μ΄λ»κ² μ€λͺ
ν κ²μΈκ°? ꡬ체μ μΈ μμλ₯Ό μ¬μ©νμ¬ μ€λͺ
νμΈμ.
|
| 47 |
+
|
| 48 |
+
3. μ§μμ λ²μ£Ό (Knowledge Categories - λ¦° μλ¦μ¨μ λΆλ₯ κΈ°μ€):
|
| 49 |
+
μ¬μ€ (Facts): μ΄ μ£Όμ μ κ΄λ ¨λ μ€μν μ¬μ€λ€μ μ΅μ 10κ° μ΄μ λμ΄νμΈμ.
|
| 50 |
+
κ°λ
(Concepts): μ΄ μ£Όμ λ₯Ό μ΄ν΄νλ λ° νμν ν΅μ¬ κ°λ
λ€μ μ μνκ³ , κ° κ°λ
μ λν μμλ₯Ό μ μνμΈμ. μ΅μ 3κ° μ΄μ μ μνμΈμ.
|
| 51 |
+
μΌλ°ν (Generalizations): κ°λ
λ€ μ¬μ΄μ κ΄κ³λ₯Ό μ€λͺ
νλ μΌλ°νλ μ§μ μ μ΅μ 3κ° μ΄μ μ μνμΈμ.
|
| 52 |
+
μ리 (Principles): μΌλ°νλ₯Ό λ·λ°μΉ¨νλ κ³Όνμ μ리 λλ μ΄λ‘ λ€μ μ€λͺ
νμΈμ. μ΅μ 2κ° μ΄μ μ μνμΈμ.
|
| 53 |
+
|
| 54 |
+
4. νꡬ μ§λ¬Έ (Inquiry Questions):
|
| 55 |
+
νμλ€μ νꡬλ₯Ό μκ·Ήνκ³ ν΅μ¬ κ°λ
λ° μΌλ°νλ‘ μ λν μ μλ νꡬ μ§λ¬Έλ€μ 5κ° μ΄μ μ μνμΈμ. μ§λ¬Έμ ꡬ체μ μ΄κ³ νꡬ κ°λ₯ν΄μΌ νλ©°, λ€μν μμ€μ μ¬κ³ λ₯Ό μꡬν΄μΌ ν©λλ€. κ° μ§λ¬Έμ΄ μ΄λ€ ν΅μ¬ κ°λ
κ³Ό μ°κ²°λλμ§ λͺ
μνμΈμ.
|
| 56 |
+
|
| 57 |
+
5. μ€νΈλλλ³ κ°λ
κΈ°λ° νꡬνμ΅ κ³Όμ μ€κ³: μμ μ μλ ν΅μ¬ μμ΄λμ΄ (Key Ideas & Generalizations), λ§€ν¬λ‘ κ°λ
(Macro Concepts) λ° λ§μ΄ν¬λ‘ κ°λ
(Micro Concepts), μ§μμ λ²μ£Ό (Knowledge Categories - λ¦° μλ¦μ¨μ λΆλ₯ κΈ°μ€), νꡬ μ§λ¬Έ (Inquiry Questions)μ μΆλ ₯ λ΄μ©μ κΈ°λ°μΌλ‘ λ€μ λ¨κ³μ λ°λΌ νꡬ νμ΅ κ³Όμ μ μ€κ³νμΈμ. λͺ¨λ νλμ νμλ€μ΄ ν΅μ¬ μμ΄λμ΄λ₯Ό μ΄ν΄νλλ‘ λλ λ° μ΄μ μ λ§μΆ°μΌ ν©λλ€.
|
| 58 |
+
|
| 59 |
+
(1) κ΄κ³ λ§ΊκΈ° (Engaging):
|
| 60 |
+
ν΅μ¬ μμ΄λμ΄μ λν ν₯λ―Έμ νΈκΈ°μ¬μ μ λ°νκ³ νμλ€μ μ§μ , μ μμ μμ
μ°Έμ¬λ₯Ό μ λνλ νλμ μ μνμΈμ. (μ: ν₯λ―Έλ‘μ΄ μ΄μΌκΈ°, μκ° μλ£, κ²μ λ±)
|
| 61 |
+
νμλ€μ μ¬μ μ§μμ νμ±ννκ³ ν΅μ¬ μμ΄λμ΄μ κ΄λ ¨λ νꡬ μ§λ¬Έμ μ λνλ νλμ μ μνμΈμ. (μ: λΈλ μΈμ€ν λ°, λ§μΈλλ§΅, μ§μμλ΅ λ±)
|
| 62 |
+
|
| 63 |
+
(2) μ§μ€νκΈ° (Focusing):
|
| 64 |
+
κ΅κ³Ό κ°λ
μ λͺ
ννκ² μ μνκ³ κ΄λ ¨λ μ¬μ€μ μλ₯Ό 2-3κ° μκ°νλ νλμ μ μνμΈμ. (μ: κ°μ, μ€λͺ
, μλ² μ€ν λ±)
|
| 65 |
+
|
| 66 |
+
(3) μ‘°μ¬νκΈ° (Investigating):
|
| 67 |
+
κ°οΏ½οΏ½ κ΄λ ¨ μ¬λ‘λ€μ μ‘°μ¬νκ³ νꡬνλ νλμ μ μνμΈμ. (μ: μ€ν, κ΄μ°°, μ‘°μ¬, ν λ‘ , μλ£ λΆμ λ±)
|
| 68 |
+
μΆκ°μ μΈ μ¬λ‘ μ μλ₯Ό ν΅ν΄ κ°λ
μ΄ν΄λ₯Ό νμ₯νλ νλμ μ μνμΈμ.
|
| 69 |
+
|
| 70 |
+
(4) μ‘°μ§ λ° μ 리νκΈ° (Organizing and Sorting):
|
| 71 |
+
μ¬μ€μ , κ°λ
μ μμ€μμ μκ°μ ꡬμ±νκ³ μ 리νλ νλμ μ μνμΈμ. (μ: ν λ§λ€κΈ°, κ·Έλν 그리기, κ°λ
μ§λ μμ± λ±)
|
| 72 |
+
λ€μν μλ£μ λ°©λ², κ΅κ³Όλ₯Ό νμ©νμ¬ κ°λ
κ³Ό μκ°μ λνλ΄λ νλμ μ μνμΈμ. (μ: κ·Έλ¦Ό 그리기, κΈμ°κΈ°, λ°ν, λͺ¨ν λ§λ€κΈ° λ±)
|
| 73 |
+
|
| 74 |
+
(5) μΌλ°ννκΈ° (Generalizing):
|
| 75 |
+
μ¬μ€μ μμμμ ν¨ν΄μ λ°κ²¬νκ³ μ°κ²°μ±μ μ°Ύμ μΌλ°νλ₯Ό λμΆνλ νλμ μ μνμΈμ. (μ: λ²€ λ€μ΄μ΄κ·Έλ¨, κ·λ©μ μΆλ‘ νλ λ±)
|
| 76 |
+
μΌλ°νλ₯Ό λͺ
λ£ννκ³ λ€λ¬λ νλμ μ μνμΈμ.
|
| 77 |
+
|
| 78 |
+
(6) μ μ΄νκΈ° (Transferring):
|
| 79 |
+
μΌλ°νμ μ ν¨μ±μ κ²μ¦νκ³ μ λΉννλ νλμ μ μνμΈμ.
|
| 80 |
+
μλ‘μ΄ μν©μ μΌλ°νλ₯Ό μ μ©νκ³ , νμ΅μ λν΄ μλ―Έ μλ νλμ μ·¨νλ νλμ μ μνμΈμ. (μ: λ¬Έμ ν΄κ²°, μμ¬ κ²°μ , μ°½μμ μ°μΆλ¬Ό μ μ λ±)
|
| 81 |
+
μμΈ‘ λ° κ°μ μ νμ±νκΈ° μν΄ κ²½νκ³Ό μ΄ν΄λ₯Ό νμ©νλ νλμ μ μνμΈμ.
|
| 82 |
+
|
| 83 |
+
(7) μ±μ°°νκΈ° (Reflecting):
|
| 84 |
+
νμ΅ μ£Όμ²΄λ‘μ μμ μ μΈμνκ³ νμ΅ κ³Όμ μ κ³ννκ³ ν΅μ νλ νλμ μ μνμΈμ. (μ: νμ΅ κ³ν μΈμ°κΈ°, νμ΅ μΌμ§ μμ± λ±)
|
| 85 |
+
μμ μ νμ΅ κ³Όμ μ νκ°νκ³ κ°μ νλ νλμ μ μνμΈμ. (μ: μκΈ° νκ°, λλ£ νκ°, νΌλλ°± νμ© λ±)
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
6. νκ° κ³ν λ° μνκ³Όμ (GRASPS), νκ° λ£¨λΈλ¦(μ, μ€, ν νμ΄):
|
| 89 |
+
κ° μ€νΈλλ λ° ν΅μ¬ κ°λ
μ λν νμλ€μ μ΄ν΄λλ₯Ό νκ°ν μ μλ νκ° λ°©λ² λ° λ£¨λΈλ¦μ μ μνμΈμ. (κ΄μ°°, λ°ν, ν¬νΈν΄λ¦¬μ€, μκΈ° νκ°, λλ£ νκ°, ν΄μ¦, μν, μν κ³Όμ λ±)
|
| 90 |
+
루λΈλ¦μ μ, μ€, νμ λν ꡬ체μ μΈ νκ° κΈ°μ€κ³Ό κ° μμ€μ ν΄λΉνλ νμμ μμ
λλ μν μμλ₯Ό ν¬ν¨ν΄μΌ ν©λλ€.
|
| 91 |
+
νκ°λ λ¨μν μ§μ μκΈ° μ¬λΆλ₯Ό 묻λ κ²μ΄ μλλΌ, νμλ€μ νꡬ κ³Όμ , μ¬κ³ λ ₯, λ¬Έμ ν΄κ²° λ₯λ ₯, νλ ₯μ νλ, κ°λ
μ μ΄ν΄, μΌλ°ν λμΆ λ₯λ ₯, μ μ΄ λ₯λ ₯ λ±μ μ’
ν©μ μΌλ‘ νκ°ν΄μΌ ν©λλ€.
|
| 92 |
+
GRASPS(Goal, Role, Audience, Situation, Product/Performance, Standards) μμλ₯Ό νμ©νμ¬ μν κ³Όμ λ₯Ό μ€κ³νμΈμ.
|
| 93 |
+
|
| 94 |
+
7. κ°λ
μ μ΄ν΄λ₯Ό μν ν (Tips for Conceptual Understanding):
|
| 95 |
+
νμλ€μ΄ ν΅μ¬ κ°λ
μ κΉμ΄ μκ² μ΄ν΄νκ³ μ°κ²°νλ©°, μΌλ°νλ₯Ό λμΆνκ³ μ μ©ν μ μλλ‘ λλ ν¨κ³Όμ μΈ κ΅μ μ λ΅μ 무μμΈκ°?
|
| 96 |
+
μ€κ°λ
μ μλ°©νκ³ ν΄κ²°νλ λ°©λ²μ 무μμΈκ°?
|
| 97 |
+
νμλ€μ λ€μν νμ΅ μ€νμΌκ³Ό μꡬλ₯Ό μΆ©μ‘±νλ λ°©λ²μ 무μμΈκ°?
|
| 98 |
+
ν΅μ¬ κ°λ
κ³Ό κ΄λ ¨λ μ€μν μ¬λ‘λ₯Ό μ μνμ¬ νμ΅μ μλ―Έμ κ΄λ ¨μ±μ λμ΄λ λ°©μμ μ μνμΈμ. λ©ν°λ―Έλμ΄, μκ° μλ£, κ²μ, νλ ₯ νμ΅ λ± λ€μν κ΅μλ²μ νμ©νλ λ°©μμ μ μνμΈμ.
|
| 99 |
+
"""
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
def generate_curriculum(grade, achievement_standard):
|
| 103 |
+
prompt = [
|
| 104 |
+
SYSTEM_PROMPT.format(grade=grade, achievement_standard=achievement_standard),
|
| 105 |
+
]
|
| 106 |
+
prompt = "\n".join(prompt)
|
| 107 |
+
|
| 108 |
+
full_text = ""
|
| 109 |
+
try:
|
| 110 |
+
response = model.generate_content(prompt, stream=True)
|
| 111 |
+
for chunk in response:
|
| 112 |
+
full_text += chunk.text
|
| 113 |
+
html_text = markdown.markdown(full_text, extensions=['tables', 'fenced_code'])
|
| 114 |
+
output_area.markdown(html_text, unsafe_allow_html=True)
|
| 115 |
+
time.sleep(0.05)
|
| 116 |
+
except Exception as e:
|
| 117 |
+
st.error(f"κ³νμ μμ± μ€λ₯: {e}")
|
| 118 |
+
return ""
|
| 119 |
+
return full_text
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
# μ±λ΄ ν¨μ (μμ λ° μΆκ° μλ£ μμ±)
|
| 123 |
+
def chat_with_ai(user_input, context):
|
| 124 |
+
prompt = f"{context}\nUser: {user_input}\nAI:"
|
| 125 |
+
full_text = ""
|
| 126 |
+
try:
|
| 127 |
+
response = model.generate_content(prompt, stream=True)
|
| 128 |
+
for chunk in response:
|
| 129 |
+
full_text += chunk.text
|
| 130 |
+
except Exception as e:
|
| 131 |
+
st.error(f"μ±λ΄ μ€λ₯: {e}")
|
| 132 |
+
return ""
|
| 133 |
+
return full_text
|
| 134 |
+
|
| 135 |
+
# Streamlit μΈν°νμ΄μ€
|
| 136 |
+
st.set_page_config(page_title="κ°λ
κΈ°λ° νꡬνμ΅ AI", page_icon="\U0001F393")
|
| 137 |
+
|
| 138 |
+
# νμ΄μ§ μ€νμΌ μ»€μ€ν°λ§μ΄μ§
|
| 139 |
+
st.markdown(
|
| 140 |
+
"""
|
| 141 |
+
<style>
|
| 142 |
+
/* μ 체 λ°°κ²½μ μ€μ */
|
| 143 |
+
.stApp {
|
| 144 |
+
background-color: #fffafa;
|
| 145 |
+
}
|
| 146 |
+
/* νμ΄ν μ€νμΌ */
|
| 147 |
+
.main-title {
|
| 148 |
+
font-size: 3rem;
|
| 149 |
+
color: #000000;
|
| 150 |
+
font-weight: 700;
|
| 151 |
+
text-align: center;
|
| 152 |
+
margin-bottom: 20px;
|
| 153 |
+
}
|
| 154 |
+
/* μ±ν
λ©μμ§ μ€νμΌ */
|
| 155 |
+
.chat-message {
|
| 156 |
+
border-radius: 15px;
|
| 157 |
+
padding: 15px;
|
| 158 |
+
margin: 10px 0;
|
| 159 |
+
display: flex;
|
| 160 |
+
align-items: center;
|
| 161 |
+
flex-wrap: wrap;
|
| 162 |
+
word-break: break-word;
|
| 163 |
+
}
|
| 164 |
+
.chat-message-user {
|
| 165 |
+
background-color: #ffebef;
|
| 166 |
+
color: #8b4513;
|
| 167 |
+
justify-content: flex-end;
|
| 168 |
+
}
|
| 169 |
+
.chat-message-assistant {
|
| 170 |
+
background-color: #ffe4e6;
|
| 171 |
+
color: #6b4226;
|
| 172 |
+
justify-content: flex-start;
|
| 173 |
+
}
|
| 174 |
+
.chat-avatar {
|
| 175 |
+
width: 40px;
|
| 176 |
+
height: 40px;
|
| 177 |
+
border-radius: 50%;
|
| 178 |
+
margin-right: 10px;
|
| 179 |
+
}
|
| 180 |
+
.chat-avatar-user {
|
| 181 |
+
margin-left: 10px;
|
| 182 |
+
margin-right: 0;
|
| 183 |
+
}
|
| 184 |
+
/* λ²νΌ μ€νμΌ */
|
| 185 |
+
.stButton button {
|
| 186 |
+
background-color: #cd857f;
|
| 187 |
+
color: #fff;
|
| 188 |
+
border-radius: 15px;
|
| 189 |
+
padding: 10px 20px;
|
| 190 |
+
}
|
| 191 |
+
</style>
|
| 192 |
+
""",
|
| 193 |
+
unsafe_allow_html=True
|
| 194 |
+
)
|
| 195 |
+
|
| 196 |
+
st.markdown("<div class='main-title'>\U0001F393 κ°λ
κΈ°λ° νꡬνμ΅ AI</div>", unsafe_allow_html=True)
|
| 197 |
+
add_vertical_space(1)
|
| 198 |
+
|
| 199 |
+
with st.sidebar:
|
| 200 |
+
st.markdown("## βοΈ μ
λ ₯ μ€μ ")
|
| 201 |
+
grade_options = [f"μ΄λ±νκ΅ {i}νλ
" for i in range(1, 7)] + [f"μ€νκ΅ {i}νλ
" for i in range(1, 4)]
|
| 202 |
+
grade_selected = st.selectbox("π νλ
μ ν", grade_options, index=0)
|
| 203 |
+
achievement_standard = st.text_area("π μ±μ·¨κΈ°μ€ λ° μ£Όμ λ΄μ©", height=150)
|
| 204 |
+
generate_button = st.button("π κ³νμ μμ±")
|
| 205 |
+
|
| 206 |
+
# μΆλ ₯ λ° μ±λ΄ μμ
|
| 207 |
+
output_area = st.empty()
|
| 208 |
+
|
| 209 |
+
# μν λ³μ
|
| 210 |
+
if "messages" not in st.session_state:
|
| 211 |
+
st.session_state.messages = []
|
| 212 |
+
st.session_state.chat_mode = False
|
| 213 |
+
|
| 214 |
+
# κ³νμ μμ± λ²νΌ ν΄λ¦ μ
|
| 215 |
+
if generate_button:
|
| 216 |
+
with st.spinner("β³ κ³νμ μμ± μ€..."):
|
| 217 |
+
result = generate_curriculum(grade_selected, achievement_standard)
|
| 218 |
+
st.session_state.messages.append({"role": "assistant", "content": result})
|
| 219 |
+
st.session_state.chat_mode = True
|
| 220 |
+
|
| 221 |
+
# μ±λ΄ μΈν°νμ΄μ€
|
| 222 |
+
user_icon_url = "https://cdn-icons-png.flaticon.com/512/4323/4323008.png"
|
| 223 |
+
assistant_icon_url = "https://cdn-icons-png.flaticon.com/512/4712/4712108.png"
|
| 224 |
+
|
| 225 |
+
if st.session_state.chat_mode:
|
| 226 |
+
if prompt := st.chat_input("κ°λ
κΈ°λ° νꡬνμ΅ AIμκ² μμ λ° μΆκ° μμ²μ¬νμ μλ €μ£ΌμΈμ!"):
|
| 227 |
+
st.session_state.messages.append({"role": "user", "content": prompt})
|
| 228 |
+
with st.spinner("π€ λ΅λ³ μμ± μ€..."):
|
| 229 |
+
context = "\n".join([msg["content"] for msg in st.session_state.messages if msg["role"] == "assistant"])
|
| 230 |
+
ai_response = chat_with_ai(prompt, context)
|
| 231 |
+
st.session_state.messages.append({"role": "assistant", "content": ai_response})
|
| 232 |
+
|
| 233 |
+
for message in st.session_state.messages:
|
| 234 |
+
if message["role"] != "system":
|
| 235 |
+
role_class = "chat-message-user" if message["role"] == "user" else "chat-message-assistant"
|
| 236 |
+
avatar_url = user_icon_url if message["role"] == "user" else assistant_icon_url
|
| 237 |
+
avatar_class = "chat-avatar-user" if message["role"] == "user" else "chat-avatar"
|
| 238 |
+
html_text = markdown.markdown(message['content'], extensions=['tables', 'fenced_code'])
|
| 239 |
+
st.markdown(
|
| 240 |
+
f"<div class='chat-message {role_class}'><img src='{avatar_url}' class='chat-avatar {avatar_class}'>{html_text}</div>",
|
| 241 |
+
unsafe_allow_html=True
|
| 242 |
+
)
|
| 243 |
+
|
| 244 |
+
|
| 245 |
+
# FAQ (κ°λ
κΈ°λ° νꡬνμ΅μ λ§κ² μμ )
|
| 246 |
+
with st.expander("βκ°λ
κΈ°λ° νꡬνμ΅ AI FAQ"):
|
| 247 |
+
st.write("""
|
| 248 |
+
**Q1. κ°λ
κΈ°λ° νꡬνμ΅ AIλ μ΄λ€ κΈ°λ₯μ μ 곡νλμ?**
|
| 249 |
+
|
| 250 |
+
A. μ΄ μ±μ μ μλλ€μ **κ°λ
κΈ°λ° νꡬνμ΅** μ€κ³λ₯Ό λκΈ° μν΄ κ°λ°λ AI λꡬμ
λλ€. νλ
κ³Ό μ±μ·¨κΈ°μ€μ μ
λ ₯νλ©΄ ν΅μ¬ μμ΄λμ΄λ₯Ό μ€μ¬μΌλ‘ ν νꡬνμ΅ κ³νμ μ΄μμ μμ±ν©λλ€. κ³νμμλ ν΅μ¬ μμ΄λμ΄, λ§€ν¬λ‘/λ§μ΄ν¬λ‘ κ°λ
, μ§μ λ²μ£Ό, νꡬ μ§λ¬Έ, **κ΄κ³λ§ΊκΈ°-μ§μ€νκΈ°-μ‘°μ¬νκΈ°-μ‘°μ§ λ° μ 리νκΈ°-μΌλ°ν-μ μ΄-μ±μ°°νκΈ°**μ 7λ¨κ³ νꡬ νλ, νκ° λ°©λ², κ°λ
μ μ΄ν΄λ₯Ό μν ν λ±μ΄ ν¬ν¨λ©λλ€. λ¨μν κ³νμ μμ±λΏλ§ μλλΌ, μμ±λ κ³νμλ₯Ό μμ νκ³ μΆκ°μ μΈ μλ£λ₯Ό μμ±νλ λ°μλ λμμ λ립λλ€.
|
| 251 |
+
|
| 252 |
+
**Q2. 7λ¨κ³ νꡬνμ΅ κ³Όμ μ€κ³λ μ΄λ»κ² μ΄λ£¨μ΄μ§λμ?**
|
| 253 |
+
|
| 254 |
+
A. μ΄ AIλ **κ΄κ³λ§ΊκΈ°-μ§μ€νκΈ°-μ‘°μ¬νκΈ°-μ‘°μ§ λ° μ 리νκΈ°-μΌλ°ν-μ μ΄-μ±μ°°νκΈ°**μ 7λ¨κ³ νꡬνμ΅ λͺ¨νμ κΈ°λ°μΌλ‘ νμ΅ κ³Όμ μ μ€κ³ν©λλ€. κ° λ¨κ³λ νμλ€μ΄ ν΅μ¬ μμ΄λμ΄λ₯Ό κΉμ΄ μκ² μ΄ν΄νκ³ , μ€μ€λ‘ μ§μμ ꡬμ±νλ©°, μ€μ μν©μ μ μ©ν μ μλλ‘ μ€κ³λ©λλ€. κ° λ¨κ³λ³ νλμ νμλ€μ ν₯λ―Έμ μ°Έμ¬λ₯Ό μ λνλ μ°½μμ μ΄κ³ νμ μ μΈ νλμΌλ‘ ꡬμ±λ©λλ€.
|
| 255 |
+
|
| 256 |
+
**Q3. κ³νμ μμ± ν μμ μ μ΄λ»κ² νλμ?**
|
| 257 |
+
|
| 258 |
+
A. κ³νμ μμ± ν, νλ¨ μ±λ΄μ μ΄μ©νμ¬ μμ λ° μΆκ° μμ²μ¬νμ μ
λ ₯ν μ μμ΅λλ€. μλ₯Ό λ€μ΄, "μ‘°μ¬νκΈ° λ¨κ³μμ νμ©ν μ μλ λ€λ₯Έ νλμ μ μν΄μ€", "νκ° λ£¨λΈλ¦μ μμ€νμ λν ꡬ체μ μΈ μμμ ν¨κ» μμ ν΄μ€" μ κ°μ΄ μ
λ ₯νλ©΄ λ©λλ€.
|
| 259 |
+
|
| 260 |
+
**Q4. μ±λ΄μ μ΄μ©ν΄μ μ΄λ€ μΆκ° μλ£λ₯Ό μμ±ν μ μλμ?**
|
| 261 |
+
|
| 262 |
+
A. μ±λ΄μ ν΅ν΄ λ€μκ³Ό κ°μ μΆκ° μλ£ μμ±μ μμ²ν μ μμ΅λλ€:
|
| 263 |
+
* **λ¨κ³λ³ νλ μΆκ°:** κ° λ¨κ³μ νμ©ν μ μλ λ€μν νλμ μ μν©λλ€. *μμ: "μ‘°μ¬νκΈ° λ¨κ³μμ νμ©ν μ μλ μ€ν νλμ μ μν΄ μ€"*
|
| 264 |
+
* **μν κ³Όμ (GRASPS):** Goal, Role, Audience, Situation, Product/Performance, Standards μμλ₯Ό νμ©νμ¬ μν κ³Όμ λ₯Ό μ€κ³ν©λλ€. *μμ: "μ΄ λ¨μμ ν΅μ¬ κ°λ
μ νκ°ν μ μλ μννκ°λ₯Ό μ€κ³ν΄μ€"*
|
| 265 |
+
* **νκ° λ£¨λΈλ¦ (μ, μ€, ν νμ΄):** μμ€νμ λν ꡬ체μ μΈ νκ° κΈ°μ€κ³Ό κ° μμ€μ ν΄λΉνλ νμ μμ
λλ μν μμλ₯Ό ν¬ν¨ν 루λΈλ¦μ μμ±ν©λλ€. *μμ: "μ μ΄νκΈ° λ¨κ³λ₯Ό νκ°ν μ μλ 루λΈλ¦μ λ§λ€μ΄μ€"*
|
| 266 |
+
* **κ°λ
μ€λͺ
μλ£:** ν΅μ¬ κ°λ
μ λν μΆκ°μ μΈ μ€λͺ
, κ·Έλ¦Ό, μμ λ±μ μ 곡ν©λλ€. *μμ: "λ§€ν¬λ‘ κ°λ
μ λν μ€λͺ
μλ£λ₯Ό λ§λ€μ΄μ€"*
|
| 267 |
+
|
| 268 |
+
μ±λ΄μ ꡬ체μ μΈ μμ²μ¬νμ μ
λ ₯ν μλ‘ λμ± μ ννκ³ μ μ©ν κ²°κ³Όλ₯Ό μ»μ μ μμ΅λλ€.
|
| 269 |
+
""")
|