Spaces:
Runtime error
Runtime error
Claude commited on
Refactor: prompts.py 연결 및 ci.yml 업데이트
Browse files- services/prompts.py: build_summary_prompt 추가
- components/teacher_dashboard.py: 인라인 프롬프트 → prompts.py 함수로 교체
- ci.yml: checkout v4→v5, 신규 파일 문법검사 목록 추가
https://claude.ai/code/session_018WXW8M8SMsWcHtj1RynUi4
- .github/workflows/ci.yml +9 -1
- components/teacher_dashboard.py +4 -21
- services/prompts.py +13 -0
.github/workflows/ci.yml
CHANGED
|
@@ -10,7 +10,7 @@ jobs:
|
|
| 10 |
lint:
|
| 11 |
runs-on: ubuntu-latest
|
| 12 |
steps:
|
| 13 |
-
- uses: actions/checkout@
|
| 14 |
|
| 15 |
- name: Python 설정
|
| 16 |
uses: actions/setup-python@v5
|
|
@@ -24,8 +24,16 @@ jobs:
|
|
| 24 |
run: |
|
| 25 |
python -m py_compile app.py
|
| 26 |
python -m py_compile db.py
|
|
|
|
| 27 |
python -m py_compile validators.py
|
| 28 |
python -m py_compile utils.py
|
| 29 |
python -m py_compile wordcloud.py
|
| 30 |
python -m py_compile services/ai.py
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
echo "✅ 문법 점검 통과!"
|
|
|
|
| 10 |
lint:
|
| 11 |
runs-on: ubuntu-latest
|
| 12 |
steps:
|
| 13 |
+
- uses: actions/checkout@v5
|
| 14 |
|
| 15 |
- name: Python 설정
|
| 16 |
uses: actions/setup-python@v5
|
|
|
|
| 24 |
run: |
|
| 25 |
python -m py_compile app.py
|
| 26 |
python -m py_compile db.py
|
| 27 |
+
python -m py_compile config.py
|
| 28 |
python -m py_compile validators.py
|
| 29 |
python -m py_compile utils.py
|
| 30 |
python -m py_compile wordcloud.py
|
| 31 |
python -m py_compile services/ai.py
|
| 32 |
+
python -m py_compile services/prompts.py
|
| 33 |
+
python -m py_compile views/home.py
|
| 34 |
+
python -m py_compile views/lobby.py
|
| 35 |
+
python -m py_compile views/admin.py
|
| 36 |
+
python -m py_compile components/sidebar.py
|
| 37 |
+
python -m py_compile components/chat_board.py
|
| 38 |
+
python -m py_compile components/teacher_dashboard.py
|
| 39 |
echo "✅ 문법 점검 통과!"
|
components/teacher_dashboard.py
CHANGED
|
@@ -16,6 +16,7 @@ from db import (
|
|
| 16 |
_get_secret,
|
| 17 |
)
|
| 18 |
from services.ai import generate_ai_response
|
|
|
|
| 19 |
from validators import with_fallback_author_role
|
| 20 |
from utils import compact_ai_report_output, get_kst_now, get_kst_now_str, log_audit
|
| 21 |
from config import (
|
|
@@ -92,11 +93,7 @@ def render_teacher_dashboard(supabase, room_name, user_role, student_name, curre
|
|
| 92 |
st.toast("👀 AI가 대화 맥락을 읽고 있습니다...", icon="⏳")
|
| 93 |
with st.spinner("✍️ 예리한 질문을 작성하고 있습니다..."):
|
| 94 |
context = "\n".join(df_all['content'].tail(5).tolist()) if not df_all.empty else "대화 없음"
|
| 95 |
-
prompt = (
|
| 96 |
-
f"당신은 고등학교 {act_type} 조력자입니다. '{current_topic}' 주제로 {act_type} 중입니다. "
|
| 97 |
-
"학생들의 균형을 맞추거나 더 깊은 생각을 유도할 수 있는 예리한 질문을 1문장만 제안하세요. "
|
| 98 |
-
f"번호 매기기나 번잡한 서론 없이 질문 자체만 출력하세요.\n최근 대화: {context}"
|
| 99 |
-
)
|
| 100 |
res_text = generate_ai_response(
|
| 101 |
prompt, model_name=AI_MODEL_NAME, api_key=_get_secret("GEMINI_API_KEY", ""),
|
| 102 |
log_message="AI 힌트 생성 실패", room_name=room_name,
|
|
@@ -131,16 +128,7 @@ def render_teacher_dashboard(supabase, room_name, user_role, student_name, curre
|
|
| 131 |
f"[{row['student_name']} - {row['sentiment']}] {row['content']}"
|
| 132 |
for _, row in df_all.iterrows()
|
| 133 |
])
|
| 134 |
-
prompt = (
|
| 135 |
-
f"'{current_topic}' 주제의 고등학교 {act_type} 기록입니다.\n\n"
|
| 136 |
-
"[출력 형식 - 반드시 그대로]\n"
|
| 137 |
-
"핵심요약 1: ...\n핵심요약 2: ...\n핵심요약 3: ...\n베스트 학생: ...\n선정 이유: ...\n\n"
|
| 138 |
-
"[엄격한 규칙]\n"
|
| 139 |
-
"- 핵심요약 1,2,3과 베스트 학생, 선정이유를 줄바꿈을 하여 보기 편하게 합니다.\n"
|
| 140 |
-
"- 5~10줄로 출력합니다.\n- 제목/헤더(#,##,###), 소제목을 절대 쓰지 않습니다.\n"
|
| 141 |
-
"- 불필요한 서론/결론 없이 바로 결과만 출력합니다.\n\n"
|
| 142 |
-
f"기록:\n{full_history}"
|
| 143 |
-
)
|
| 144 |
res_text = generate_ai_response(
|
| 145 |
prompt, model_name=AI_MODEL_NAME, api_key=_get_secret("GEMINI_API_KEY", ""),
|
| 146 |
log_message="AI 요약 리포트 생성 실패", room_name=room_name,
|
|
@@ -197,12 +185,7 @@ def render_teacher_dashboard(supabase, room_name, user_role, student_name, curre
|
|
| 197 |
try:
|
| 198 |
student_data = df_all[df_all['student_name'] == selected_student]
|
| 199 |
debate_history = "\n".join([f"- [{row['sentiment']}] {row['content']}" for _, row in student_data.iterrows()])
|
| 200 |
-
prompt = (
|
| 201 |
-
f"당신은 정보 교사입니다. '{current_topic}' 주제 {act_type}에 참여한 "
|
| 202 |
-
f"'{selected_student}' 학생의 활동 기록입니다. 이를 바탕으로 생활기록부 "
|
| 203 |
-
f"교과세특 초안을 약 300자 내외로 작성하세요. 교육적 성장을 강조하세요.\n\n"
|
| 204 |
-
f"[활동 기록]\n{debate_history}"
|
| 205 |
-
)
|
| 206 |
res_text = generate_ai_response(
|
| 207 |
prompt, model_name=AI_MODEL_NAME, api_key=_get_secret("GEMINI_API_KEY", ""),
|
| 208 |
log_message="AI 세특 생성 실패", room_name=room_name, student=selected_student,
|
|
|
|
| 16 |
_get_secret,
|
| 17 |
)
|
| 18 |
from services.ai import generate_ai_response
|
| 19 |
+
from services.prompts import build_hint_prompt, build_summary_prompt, build_record_prompt
|
| 20 |
from validators import with_fallback_author_role
|
| 21 |
from utils import compact_ai_report_output, get_kst_now, get_kst_now_str, log_audit
|
| 22 |
from config import (
|
|
|
|
| 93 |
st.toast("👀 AI가 대화 맥락을 읽고 있습니다...", icon="⏳")
|
| 94 |
with st.spinner("✍️ 예리한 질문을 작성하고 있습니다..."):
|
| 95 |
context = "\n".join(df_all['content'].tail(5).tolist()) if not df_all.empty else "대화 없음"
|
| 96 |
+
prompt = build_hint_prompt(act_type, current_topic, context)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
res_text = generate_ai_response(
|
| 98 |
prompt, model_name=AI_MODEL_NAME, api_key=_get_secret("GEMINI_API_KEY", ""),
|
| 99 |
log_message="AI 힌트 생성 실패", room_name=room_name,
|
|
|
|
| 128 |
f"[{row['student_name']} - {row['sentiment']}] {row['content']}"
|
| 129 |
for _, row in df_all.iterrows()
|
| 130 |
])
|
| 131 |
+
prompt = build_summary_prompt(act_type, current_topic, full_history)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
res_text = generate_ai_response(
|
| 133 |
prompt, model_name=AI_MODEL_NAME, api_key=_get_secret("GEMINI_API_KEY", ""),
|
| 134 |
log_message="AI 요약 리포트 생성 실패", room_name=room_name,
|
|
|
|
| 185 |
try:
|
| 186 |
student_data = df_all[df_all['student_name'] == selected_student]
|
| 187 |
debate_history = "\n".join([f"- [{row['sentiment']}] {row['content']}" for _, row in student_data.iterrows()])
|
| 188 |
+
prompt = build_record_prompt(act_type, current_topic, selected_student, debate_history)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
res_text = generate_ai_response(
|
| 190 |
prompt, model_name=AI_MODEL_NAME, api_key=_get_secret("GEMINI_API_KEY", ""),
|
| 191 |
log_message="AI 세특 생성 실패", room_name=room_name, student=selected_student,
|
services/prompts.py
CHANGED
|
@@ -9,6 +9,19 @@ def build_hint_prompt(act_type, current_topic, context):
|
|
| 9 |
)
|
| 10 |
|
| 11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
def build_record_prompt(act_type, current_topic, selected_student, debate_history):
|
| 13 |
return (
|
| 14 |
f"당신은 정보 교사입니다. "
|
|
|
|
| 9 |
)
|
| 10 |
|
| 11 |
|
| 12 |
+
def build_summary_prompt(act_type, current_topic, full_history):
|
| 13 |
+
return (
|
| 14 |
+
f"'{current_topic}' 주제의 고등학교 {act_type} 기록입니다.\n\n"
|
| 15 |
+
"[출력 형식 - 반드시 그대로]\n"
|
| 16 |
+
"핵심요약 1: ...\n핵심요약 2: ...\n핵심요약 3: ...\n베스트 학생: ...\n선정 이유: ...\n\n"
|
| 17 |
+
"[엄격한 규칙]\n"
|
| 18 |
+
"- 핵심요약 1,2,3과 베스트 학생, 선정이유를 줄바꿈을 하여 보기 편하게 합니다.\n"
|
| 19 |
+
"- 5~10줄로 출력합니다.\n- 제목/헤더(#,##,###), 소제목을 절대 쓰지 않습니다.\n"
|
| 20 |
+
"- 불필요한 서론/결론 없이 바로 결과만 출력합니다.\n\n"
|
| 21 |
+
f"기록:\n{full_history}"
|
| 22 |
+
)
|
| 23 |
+
|
| 24 |
+
|
| 25 |
def build_record_prompt(act_type, current_topic, selected_student, debate_history):
|
| 26 |
return (
|
| 27 |
f"당신은 정보 교사입니다. "
|