import os import time import google.generativeai as genai import streamlit as st from streamlit_extras.colored_header import colored_header from streamlit_extras.add_vertical_space import add_vertical_space import markdown # Google Gemini API 값 설정 genai.configure(api_key=os.environ["GEMINI_API_KEY"]) # 모델 설정 generation_config = { "temperature": 0.7, "top_p": 0.95, "top_k": 64, "max_output_tokens": 8000, "response_mime_type": "text/plain", } model = genai.GenerativeModel( model_name="gemini-2.5-flash", generation_config=generation_config, ) def generate_text(grade, num_paragraphs, sentences_per_paragraph, structure, topic): """ 주어진 조건에 따라 설명문 텍스트, 어휘 목록, 독해 문제를 생성하고 스트리밍으로 출력합니다. """ # 상세화된 프롬프트: 설명문 작성 + 어휘 목록 + 독해 문제 출제 요청 추가 prompt = f""" # 지시사항 ## 1. 설명문 작성 - **대상 독자:** 초등학교 {grade} 학생 - **주제:** '{topic}' - **글의 구조:** '{structure}' 구조를 명확히 따를 것 - **분량:** 전체 {num_paragraphs}개 문단 내외, 문단 당 {sentences_per_paragraph}개 문장 내외 - **스타일:** - 초등학생이 이해하기 쉬운 단어와 문장 사용 - 줄글 형식으로 작성, 문단 구분 명확히 (빈 줄 사용) - 각 문단의 첫 문장 또는 마지막 문장이 중심 문장이 되도록 작성 - **제목:** 글의 맨 처음에 내용을 잘 나타내는 제목을 **크고 굵은 글씨**로 작성 (Markdown 형식: '** 제목 **') ## 2. 어휘 목록 작성 - **선정 기준:** 본문 내용 중 초등학교 {grade}에게 어려울 수 있는 단어, 한자어, 학습 용어 - **설명 방식:** 해당 학년 수준에 맞는 쉬운 유의어 또는 풀이 제공 - **형식:** 설명문 본문 뒤에 '### 어휘 목록' 제목 아래 글머리 기호 목록으로 작성 ```markdown ### 어휘 목록 * 단어1: 쉬운 설명/유의어 * 단어2: 쉬운 설명/유의어 ... ``` ## 3. 독해 문제 및 정답 출제 - **출제 기반:** **반드시 위에서 생성된 설명문 내용만을 바탕으로** 출제 - **문제 수:** 총 7~8개 - **문제 유형 (균형 있게 포함):** - **사실적 이해:** 글에 명시된 정보 확인 (누가, 무엇을, 언제, 어디서 등) - **추론적 이해:** 글에 명시되지 않았지만 내용을 바탕으로 논리적으로 판단 가능한 내용 (왜, 그래서 어떻게 될까 등) - **어휘:** 본문 또는 어휘 목록에 나온 단어의 문맥상 의미 파악 - **글의 구조:** 글 전체의 짜임, 문단 간 관계, 사용된 설명 방식 등 파악 - **문제 형식 (혼합 사용):** - **단답형:** 간단한 단어, 구, 짧은 문장으로 답하는 문제 - **5지 선다형:** 5개의 선택지(①, ②, ③, ④, ⑤) 중 정답을 고르는 문제 (오답 선택지도 그럴듯하게 구성) - **형식:** - '### 독해 문제' 제목 아래 문제 번호(1., 2., ...)와 함께 문제 제시 - 모든 문제 출제 후, '### 정답' 제목 아래 문제 번호와 정답 명확히 제시 ```markdown ### 독해 문제 1. [문제 내용 - 단답형 또는 5지 선다형] ① 선택지1 ② 선택지2 ③ 선택지3 ④ 선택지4 ⑤ 선택지5 (선다형의 경우) 2. [문제 내용 - 단답형 또는 5지 선다형] ... (총 7~8개) ### 정답 1. [정답 내용 또는 번호] 2. [정답 내용 또는 번호] ... ``` ## # 출력 요구사항 - 위의 모든 지시사항(설명문, 어휘 목록, 독해 문제, 정답)을 **하나의 응답**으로 이어서 생성해주세요. - 각 섹션(제목, 본문, 어휘 목록, 독해 문제, 정답) 구분을 Markdown 제목(##, ###)과 빈 줄로 명확히 해주세요. - 모든 내용은 초등학교 {grade} 눈높이에 맞춰 작성해주세요.""" full_text = "" # 전체 텍스트 저장 변수 초기화 try: response = model.generate_content(prompt, stream=True) for chunk in response: full_text += chunk.text # Markdown to HTML 변환 html_text = markdown.markdown(full_text, extensions=['tables']) output_area.markdown(html_text, unsafe_allow_html=True) time.sleep(0.1) # 지연 추가 (필요에 따라 조절) except Exception as e: st.error(f"에러 발생: {str(e)}") return "" # 출력 및 복사 기능 추가 copy_button = st.button("출력 내용 복사") if copy_button: pyperclip.copy(full_text) st.success("클립보드에 복사되었습니다!") return full_text # Streamlit 인터페이스 설정 colored_header( label="📜 초등학생을 위한 읽기 자료 생성기", description="주제를 입력하면 초등학생이 이해하기 쉬운 읽기 자료를 만들어줍니다.", color_name="red-70", ) add_vertical_space(1) with st.sidebar: st.header("옵션 설정") grade = st.selectbox("학년", [f"초등학교 {i}학년" for i in range(1, 7)]) # 드롭다운 수정 num_paragraphs = st.number_input("문단 수", min_value=1, value=3) sentences_per_paragraph = st.number_input("문단 당 문장 수", min_value=1, value=3) # 드롭다운 수정 structure = st.selectbox("설명문 구조", ["정의와 예시", "비교와 대조", "분류", "분석", "인과", "순서"], index=0) topic = st.text_area("✏️ 주제 및 내용을 입력하세요 ", height=200) generate_button = st.button("읽기 자료 생성") # 출력 영역을 함수 외부에 정의 output_area = st.empty() if generate_button: generate_text(grade, num_paragraphs, sentences_per_paragraph, structure, topic)