본문 바로가기
파이썬 프로그래밍/파이썬 개발

4. DSPy 생기부 AI 에이전트-3

by Majestyblue 2025. 5. 16.

1. 평가자(Evaluator)의 필요성

chatGPT로 생기부를 작성하다 보면 본인이 정한 규칙을 잘 지키는 경우도 있지만 그렇지 않은 경우도 많다. 그런 경우 채팅창을 다시 지우고 하면 되는 경우가 많은데 context가 길어지면 앞의 내용을 잊어버리기 때문에 생긴 일이다.

 

때문에 작성한 생활기록부를 평가하고 필요시 다시 작성하도록 명령하는 평가자(Evaluator)를 두면 더욱 효과적으로 작성할 수 있을 것이다. 평가자를 두었을 때 장점은 아래와 같다.

 

  1. AI 생성 결과물의 품질 보증:
    • AI 모델, 특히 언어 모델은 복잡하고 미묘한 규칙을 완벽하게 따르지 못할 때가 있다. 생기부 작성 프롬프트에는 명사형 종결, 특정 금지 문구(셀프 생기부 의심 문구) 제외, 특정 글자 수 제한, 교사의 객관적인 관점 유지 등 매우 중요하고 까다로운 규칙들이 포함되어 있다.
    • 작성자(Writer)가 이러한 모든 규칙을 한 번에 정확하게 지키면서 내용의 충실도까지 확보하는 것은 어렵습니다.
    • 평가자는 AI가 생성한 생활기록부가 이 모든 규칙(특히 금지 문구 사용 여부나 명사형 종결 오류)을 얼마나 잘 지켰는지, 입력 데이터(원본, 핵심요약/성취기준 등)의 내용을 얼마나 정확하고 적절하게 반영했는지 등을 검토하여 최종 결과물의 품질을 확인하고 보증하는 역할을 한다.
  2. 반복 및 개선 루프 구현:
    • 평가자는 단순히 점수를 매기는 것을 넘어, 결과물이 요구사항을 충족하지 못했을 경우('return_Yes') 재작성을 요청하는 신호를 보낸다.
    • 이때 평가자는 왜 재작성이 필요한지에 대한 구체적인 피드백을 작성자에게 전달한다.
    • 작성자는 이 피드백을 바탕으로 이전 작성의 문제점(예: 특정 금지 문구가 사용됨, 길이가 초과됨, 명사형 종결 오류가 있음 등)을 파악하고, 이를 수정하여 더 나은 품질의 생기부를 다시 작성하려고 시도하며. 이 과정이 사용자 지정에 따라 최대 3번까지 반복된다.
    • 평가자 없이는 이러한 자동화된 품질 개선 및 수정 루프를 구현하기 힘들다. 작성자가 스스로 자신의 결과물의 문제점을 완벽히 파악하고 수정하는 것은 매우 어렵기 때문에, 외부(여기서는 Evaluator 모듈)에서의 객관적인 평가와 피드백이 필요하다.
  3. 다양한 품질의 입력 데이터 처리:
    • 분류자가 'good', 'normal', 'bad', 'nothing' 등 다양한 품질의 원본 데이터를 구분하고 각기 다른 방식으로 생기부를 작성하지만, 어떤 품질의 데이터든 작성자가 실수할 가능성은 있다.
    • 평가자는 데이터 품질(quality) 정보를 함께 받아, 해당 품질 수준에 맞는 작성 지침(write_prompt)이 결과물에 잘 반영되었는지 평가한다. 예를 들어, 'good' 데이터로 작성된 결과물이 학생의 우수성을 충분히 드러내지 못했거나, 'nothing' 데이터로 작성된 결과물이 불필요한 내용을 담고 있는지 등을 평가한다.

 

 

2. 평가자(Evaluator) 구현하기

평가자는 평가 지시 프롬프트, 퀄리티('good', 'normal', 'bad', 'nothing' 중 하나를 받는다.), 학생 자료, 작성된 생활기록부를 입력받고 작성자(SR_Writer)의 피드백, 통과 여부('return_Yes', 'return_NO')를 출력한다.

import dspy
from typing import Literal
lm = dspy.LM(model="ollama_chat/gemma3:12b-it-q4_K_M", \
    api_base='http://localhost:11434', 
    api_key="", temperature=0.7)
    
dspy.configure(lm=lm)
class Evaluator(dspy.Signature):
    instruction = dspy.InputField(desc="생활기록부 작성 프로세스를 어떻게 평가하지는지에 대한 설명입니다.")
    quality = dspy.InputField(desc="생활기록부 퀄리티로 good, normal, bad, nothing 중 하나입니다")
    input_data = dspy.InputField(desc="생활기록부 작성이 필요한 실제 데이터입니다.")
    generated_output = dspy.InputField(desc="작성된 생활기록부 입니다")

    srwrite_op = dspy.OutputField(desc="작성자에 대한 피드백입니다. 반드시!! 한글로 출력하세요!!")
    rewrite_op: Literal['return_Yes', 'return_No'] = dspy.OutputField(desc="생활기록부 재작성과 관련된 의견입니다. 반드시 둘 중 하나로 선택하여 출력합니다.")

 

evaluator_prompt= r"""당신은 학생 생활기록부 작성 AI의 최종 결과물 품질을 평가하고 재작성 필요성을 판단하는 전문 검토 시스템이다. 다음 제공되는 입력 정보를 분석하여 'SR_Writer'가 생성한 생활기록부 결과의 적절성을 평가하고, 작성자 피드백 및 재작성 필요성 여부를 판단한다.

**평가에 사용될 입력 정보:**

1.  **quality:** 'Discriminator'가 판별한 학생 활동 데이터의 품질 수준 ('good', 'normal', 'bad', 'nothing' 중 하나)이다. 이 값은 'SR_Writer'가 사용한 내부 지침 및 최종 결과에 기대하는 수준을 판단하는 기준이 된다.
2.  **input_data:** 학생의 실제 활동 내용 및 교사 관찰 등이 담긴 원본 텍스트 자료이다. 'generated_output'이 이 원본의 사실과 일치하는지, 원본 내용을 제대로 반영했는지 검토하는 근거이다. (quality가 nothing일 때는 실질적인 내용이 없을 수 있다.)
3.  **generated_output:** 'SR_Writer'가 최종적으로 생성한 생활기록부 항목 텍스트이다. 평가의 주된 대상으로서, 내용의 적절성, 일관성, 형식 및 문체 적절성을 검토한다.
4.  **instruction (평가자 지침):** 평가 작업 자체에 대한 지침이다.

**평가 기준 및 출력 항목별 내용:**

제공된 입력 정보를 바탕으로 'SR_Writer'가 'quality'에 맞는 작성 전략을 잘 따랐는지, 'input_data'의 내용을 적절히 반영하여 'generated_output'을 생성했는지 평가한다.

*   **[srwrite_op] (작성자 피드백):**
    *   'generated_output'이 'input_data'의 **핵심 내용을 얼마나 정확하게 반영**하고 있는지 평가한다. 'input_data'에 있는 중요 정보가 누락되거나 잘못 기술된 부분이 있는지 구체적으로 언급한다.
    *   'generated_output'의 **내용, 깊이, 문체가 'quality' (good, normal, bad, nothing) 수준에 얼마나 적절**한지 평가한다. 예를 들어, quality가 'good'인데 내용이 부실하거나, quality가 'bad'인데 내용을 과하게 포장하지 않았는지 등을 검토하고 피드백한다.
    *   'generated_output'이 생활기록부 항목으로서 **기본적인 형태와 문체(명사형 종결 등)**를 갖추고 가독성이 있는지 평가한다. (구체적인 예시 one_shot이 없으므로 일반적인 생활기록부 형식을 기준으로 한다.)
    *   전반적으로 'generated_output'이 'input_data'와 'quality'를 고려했을 때 얼마나 잘 작성되었는지에 대한 종합적인 피드백 내용을 구성한다.

*   **[rewrite_op] (재작성 의견):**
    *   **[srwrite_op]에서 평가한 내용을 종합**하여, 생성된 'generated_output'을 **별도의 재작업 없이 그대로 사용하기에 무리가 없는지** 최종 판단한다.
    *   **재작성 필요성 판단 기준:**
        *   **'return_Yes' (재작성 필요):**
            *   'generated_output'에 'input_data'와 **모순되는 명백한 사실 오류**가 포함된 경우,
            *   'generated_output'의 품질이 'quality' 수준과 **심각하게 불일치**하여 해당 품질의 데이터로 기대할 수 없는 결과인 경우 (예: quality가 'good'인데 내용이 극히 부실하거나, quality가 'bad'인데 원본에 없는 내용을 과하게 추가한 경우 등),
            *   'generated_output'이 생활기록부로서 **기본적인 형태를 갖추지 못했거나(예: 너무 짧거나, 문체/형식 오류 심각) 가독성이 현저히 낮은 경우**에 해당한다.
        *   **'return_No' (재작성 불필요):**
            *   'generated_output'이 'input_data'의 내용을 합리적인 수준으로 반영하고, 'quality' 수준에 대체로 부합하며, 생활기록부로서 기본적인 형태와 가독성을 갖추고 있어 **수동 검토 시 약간의 수정으로 사용 가능**한 경우에 해당한다. (완벽하지 않아도 괜찮다.)
    *   **이 섹션의 출력은 반드시 'return_Yes' 또는 'return_No' 단 두 가지 중 하나여야 하며, 다른 어떠한 내용도 포함하지 않는다.**

**제공된 'quality', 'input_data', 'generated_output' 정보를 지정된 평가 기준에 따라 분석하고, 작성자 피드백 및 최종 재작성 필요성 판단 결과를 포함하여 지정된 형식으로 결과를 출력한다.**
"""

input_data1 = r"""[물리 점수] 86, 75, 72, 85 [물리의 재구성] 선정한 문제: 빛의 파장이 500nm인 
단색광을 어떤 금속판에 비추었더니 광전자가 방출되었다. 이 금속의 일함수는 2.0eV이다. 방출되는 
광전자의 최대 운동 에너지는 몇 eV인가? (단, 플랑크 상수 h = 6.63 × 10⁻³⁴ J·s, 빛의 속도
c = 3 × 10⁸ m/s, 1eV = 1.6 × 10⁻¹⁹ J로 계산한다. 또는 hc ≈ 1240 eV·nm를 사용해도 좋다.) 
1. 문제 선정 이유 광전 효과는 빛의 입자성을 명확하게 보여주는 현상으로, 현대 물리학의 중요한 개념 
중 하나라고 생각했습니다. 빛의 에너지와 금속의 일함수, 그리고 방출되는 광전자의 운동 에너지 사이의 
관계를 정확히 이해하고 싶었고, 다양한 변수를 적용하여 응용해보고자 이 문제를 선택했습니다. 
교과과정: IV 파동과 입자의 성질 - 2. 빛과 물질의 이중성 - 광전 효과 2. 문제에서 제시된 물리량과 
확인해야 하는 물리량 제시된 물리량: 입사광의 파장(λ = 500nm), 금속의 일함수(W = 2.0eV), 
플랑크 상수(h), 빛의 속도(c), 전자볼트와 줄의 환산 관계. 확인해야 하는 물리량: 광전자의 최대 운동 
에너지(K_max). 3. 확인해야 하는 물리량 구하는 법 (기존 문제 풀이) 광전 효과의 기본 공식은 
E_photon = W + K_max 입니다. 입사광의 에너지(E_photon) 계산: E_photon = hc/λ 여기서 hc ≈ 1240
eV·nm를 사용하면 편리합니다. E_photon = 1240 eV·nm / 500 nm = 2.48 eV 광전자의 최대 운동 
에너지(K_max) 계산: K_max = E_photon - W K_max = 2.48 eV - 2.0 eV = 0.48 eV 따라서 방출되는 
광전자의 최대 운동 에너지는 0.48 eV입니다. 4. 재구성한 물리 현상 방법 (새로운 문제) 어떤 금속에
빛을 비추었더니 광전자가 방출되었고, 이 광전자를 멈추게 하는 데 필요한 정지 전압(저지 전압)이
0.8V였다. 이 금속의 문턱 진동수가 6.0 × 10¹⁴ Hz라면, 이 금속에 비춘 빛의 파장은 몇 nm인가? 
(단, 플랑크 상수 h = 6.63 × 10⁻³⁴ J·s, 빛의 속도 c = 3 × 10⁸ m/s, 전자의 전하량 
e = 1.6 × 10⁻¹⁹ C, hc ≈ 1240 eV·nm를 사용해도 좋다.) 5. 재구성한 물리 현상과 기존 물리현상의 
공통점과 차이점 공통점: 두 문제 모두 광전 효과의 기본 원리(E_photon = W + K_max)를 이용합니다. 
빛의 에너지, 금속의 특성(일함수 또는 문턱 진동수), 광전자의 운동 에너지(또는 정지 전압) 사이의 관계를 
다룹니다. 차이점: 기존 문제: 파장과 일함수를 주고 최대 운동 에너지를 구하는 문제. 재구성한 문제: 
정지 전압과 문턱 진동수를 주고 입사광의 파장을 구하는 문제. 즉, 구하고자 하는 미지수와 주어진 조건이
다릅니다. 재구성한 문제는 일함수를 직접 주지 않고 문턱 진동수를 통해 계산하도록 하였고, 최대 운동
에너지를 정지 전압을 통해 구하도록 하여 한 단계 더 생각해야 합니다. 6. 재구성한 물리 현상으로 
확인해야 하는 물리량 구하기 (새로운 문제 풀이) 광전자의 최대 운동 에너지(K_max) 계산: 정지 전압 
V_s = 0.8V 이므로, K_max = eV_s = 0.8 eV 입니다. 금속의 일함수(W) 계산: 문턱 진동수 
f₀ = 6.0 × 10¹⁴ Hz 이므로, W = hf₀ 입니다. W = (6.63 × 10⁻³⁴ J·s) × (6.0 × 10¹⁴ Hz) 
= 3.978 × 10⁻¹⁹ J 이를 eV 단위로 환산하면, W = (3.978 × 10⁻¹⁹ J) / (1.6 × 10⁻¹⁹ J/eV) 
≈ 2.486 eV (약 2.49 eV로 계산) 입사광의 에너지(E_photon) 계산: E_photon = W + K_max E_photon 
= 2.49 eV + 0.8 eV = 3.29 eV 입사광의 파장(λ) 계산: E_photon = hc/λ 이므로, 
λ = hc/E_photon λ = 1240 eV·nm / 3.29 eV ≈ 376.9 nm (약 377 nm) 따라서 이 금속에 비춘 빛의 
파장은 약 377 nm입니다. 7. 탐구를 통해 무엇을 배웠는지 구체적으로 설명하기 이번 '물리의 재구성' 
활동을 통해 광전 효과의 핵심 공식을 다양한 상황에 적용하는 연습을 할 수 있었습니다. 단순히 공식을
암기하는 것을 넘어, 각 물리량(파장, 진동수, 일함수, 문턱 진동수, 최대 운동 에너지, 정지 전압)이
서로 어떻게 유기적으로 연결되는지 깊이 이해하게 되었습니다. 특히, 일함수를 문턱 진동수로, 
최대 운동 에너지를 정지 전압으로 변환하여 생각하는 과정에서 개념 간의 관계를 명확히 파악할 수 
있었습니다. 또한, 문제의 조건을 바꾸어 새로운 문제를 만들고 해결하는 과정에서 문제 해결 능력과 
응용력을 기를 수 있었습니다. 8. 추가 계획 1가지 이상 제시하기 광전 효과와 빛의 세기 관계 탐구: 
빛의 세기가 광전류의 세기에는 영향을 주지만 광전자의 최대 운동 에너지에는 영향을 주지 않는 이유를
그래프와 함께 분석하고, 이를 설명하는 실험을 설계해보고 싶습니다. 다양한 금속의 일함수 비교: 
여러 가지 금속의 일함수 값을 조사하고, 각 금속에 대해 광전 효과가 일어나기 위한 빛의 최소 진동수
(문턱 진동수)와 최대 파장(한계 파장)을 계산하여 비교 분석해보고 싶습니다. [물리 심화 탐구]
1. 주제 선정에 대해 작성하세요 수업 시간에 '전자기 유도' 현상을 배우면서 자기장의 변화가 전류를 
만들어낸다는 사실에 큰 흥미를 느꼈습니다. 특히, 코일과 자석을 이용한 간단한 실험 외에 이러한 원리가 
실생활에서 어떻게 대규모로 활용되는지 궁금해졌습니다. 그중에서도 비접촉식으로 물체를 가열할 수 있는 
'인덕션 히터(유도 가열기)'의 작동 원리가 전자기 유도와 깊은 관련이 있다는 것을 알게 되어,
"인덕션 히터의 작동 원리와 효율성에 대한 물리적 탐구"라는 주제를 선정하게 되었습니다. 
2. 자료 수집에 대해 작성하세요 고등학교 물리 교과서 및 참고서의 '전자기 유도', '교류 회로' 단원
내용을 복습했습니다. 온라인 과학 학술 데이터베이스(Google Scholar, RISS 등)에서 
'유도 가열(Induction Heating)', '와전류(Eddy Current)', '전자기 유도 효율' 등의 키워드로 관련 
논문 및 기술 자료를 검색했습니다. 유명 과학 유튜브 채널 및 교육 웹사이트에서 인덕션 히터의 작동
원리를 시각적으로 설명하는 자료들을 참고했습니다. 가전제품 제조사의 기술 설명 자료 및 특허 정보를
통해 실제 제품에 적용된 기술적 세부 사항을 파악하려 노력했습니다. 3. 자료 분석에 대해 작성하세요 
수집한 자료를 바탕으로 인덕션 히터의 핵심 원리를 다음과 같이 분석했습니다. 전자기 유도: 인덕션 
히터 내부의 코일에 고주파 교류 전류를 흘려주면, 코일 주변에 시간에 따라 빠르게 변화하는 자기장이 
형성됩니다. (패러데이의 전자기 유도 법칙) 와전류(Eddy Current) 발생: 이 변화하는 자기장이 금속
용기(냄비 등) 바닥을 통과하면서 용기 내부에 유도 전류, 즉 와전류를 발생시킵니다. (렌츠의 법칙) 
줄 발열(Joule Heating): 금속 용기는 고유한 전기 저항을 가지고 있으므로, 와전류가 흐르면서 용기
자체에서 열이 발생합니다 (P = I²R). 이 열이 음식을 조리하는 데 사용됩니다. 표피 효과(Skin Effect):
고주파 교류를 사용할 경우 전류가 도체의 표면 근처에 집중되어 흐르는 현상으로, 이로 인해 용기 표면에서
더 효과적인 가열이 일어납니다. 효율성: 인덕션 히터는 용기 자체를 직접 가열하므로 열 손실이 적어 
에너지 효율이 높습니다. 가스레인지나 일반 전기레인지(하이라이트)에 비해 예열 시간이 짧고, 주변으로 
방출되는 열이 적어 쾌적한 조리 환경을 제공합니다. 4. 결론 도출에 대해 작성하세요 인덕션 히터는 
전자기 유도 법칙에 의해 코일에서 발생한 변화하는 자기장이 금속 용기에 와전류를 유도하고, 이 와전류가 
용기의 전기 저항에 의해 줄 열을 발생시켜 음식을 가열하는 장치입니다. 고주파 교류와 표피 효과를
이용하여 가열 효율을 높이며, 직접 가열 방식으로 에너지 손실을 최소화하여 높은 열효율을 달성합니다. 
이는 물리학적 원리가 실생활의 편의를 증진시키는 대표적인 사례임을 확인했습니다. 5. 탐구 고찰에 대해
작성하세요 이번 탐구를 통해 전자기 유도 현상이 단순히 이론에 머무르지 않고, 우리 생활 깊숙이 들어와
유용하게 활용되고 있음을 실감했습니다. 인덕션 히터의 원리를 이해하면서 와전류, 표피 효과 등 심화된 
물리 개념까지 접할 수 있어 지식의 폭을 넓힐 수 있었습니다. 다만, 실제 인덕션 히터의 코일 설계, 
주파수 최적화, 사용 가능한 용기의 재질 제한(자성체 또는 특정 비자성체 금속) 등 공학적인 측면까지 
깊이 있게 다루지 못한 점은 아쉬움으로 남습니다. 앞으로 전자기학 관련 심화 학습을 통해 이러한 부분에
대한 이해를 높이고 싶다는 생각을 했습니다. 또한, 에너지 효율이 높은 인덕션 기술이 산업 현장에서는
어떻게 응용되는지(예: 금속 용해, 열처리) 추가적으로 조사해보고 싶습니다. [교과선생님 관찰내용] 
수업 참여도 적극적이며, 질문을 통해 이해를 명확히 하려는 자세가 돋보임."""

srwrite_good = r"""'**창의적 문제 해결 능력과 심도 있는 과학적 탐구 능력을 겸비한 학생입니다.
** 빛의 파장이 500nm인 단색광을 금속판에 비추어 광전 효과를 관찰하는 실험에서, 단순히 실험 결과를 
나열하는 것을 넘어, 패러데이의 전자기 유도 법칙과 렌츠의 법칙을 연계하여 와전류 발생 메커니즘을
논리적으로 설명하고, 스넬의 법칙을 활용하여 굴절률을 정확하게 계산하는 과정을 통해 뛰어난 분석력과 
문제 해결 능력을 보여주었습니다. 또한, 인덕션 히터의 작동 원리를 심층적으로 탐구하며, 와전류, 
표피 효과 등 심화된 물리 개념을 스스로 학습하고, 이를 실제 제품의 작동 방식과 연결하는 통찰력을 
보여주었습니다. 특히, 네오디뮴 자석과 건전지, 철심을 이용해 간이 전동기를 제작하며 전동기의 원리를
직관적으로 이해하고, 실험 설계 과정에서 팀원들과의 효과적인 소통을 통해 협업 능력을 발휘했습니다. 
"물리의 재구성" 활동에서 제시된 문제에 대해, 기존의 틀을 벗어나 새로운 관점에서 접근하고 해결 방안을
모색하는 능력이 돋보였습니다.  교과 선생님께서는 수업 참여도와 질문을 통해 이해를 명확히 하려는
적극적인 자세를 높이 평가하고 있습니다. 앞으로 전자기학 관련 심화 학습을 통해 공학적인 측면에 대한 
이해를 높이고, 에너지 효율이 높은 인덕션 기술이 산업 현장에서 어떻게 응용되는지 추가적으로 조사할
것으로 기대됩니다.'
"""
result = dspy.ChainOfThought(Evaluator)
output = result(instruction=evaluator_prompt, quality='good', 
                input_data=input_data1, generated_output=srwrite_good)
print(output.srwrite_op)
print(output.rewrite_op)

<출력결과>

SR_Writer는 입력 데이터의 핵심 내용을 제대로 반영하지 못했습니다.  '물리의 재구성'과 '물리 심화 탐구' 부분에서 학생이 직접 설계하고 분석한 실험 과정과 그 결과, 그리고 도출한 결론 등 구체적인 내용이 생략되어 있습니다.  학생의 탐구 활동에 대한 상세하고 객관적인 기술이 부족하여, 'good' quality에 부합하는 생활기록부라고 보기 어렵습니다.  특히,  '네오디뮴 자석과 건전지, 철심추을 이용해 간이 전동기를 제작'했다는 내용은 입력 데이터에 없는 내용으로, 사실과 다른 내용을 추가한 점은 심각한 문제입니다.  생활기록부는 명사형 종결어미를 사용하여 객관적인 기술을 유지해야 하는데, 생성된 결과물은 다소 주관적인 표현이 많습니다.  입력 데이터의 풍부한 정보를 바탕으로 학생의 능력을 객관적이고 상세하게 기술하여,  'good' quality에 걸맞는 생활기록부를 작성해야 합니다.  구체적인 실험 과정, 분석 결과, 결론 등을 명확하게 제시하여 학생의 능력을 객관적으로 평가해야 합니다.
return_Yes

 

 

이런식으로 평과 결과를 확인해 볼 수 있다.

 

 

3. 평가자를 포함한 생활기록부 작성 AI 작동 과정 살펴보기

 

 

1. 전체 목표:

MySR_Agent는 입력된 '학생 활동 및 교사 평가 자료 (input_data)'를 바탕으로 '생활기록부(student_record)'를 작성하는 것을 목표로 한다. 이 과정에서 자료의 품질을 판단하고, 필요시 핵심 내용을 추출하며, 평가자의 피드백을 받아 최대 3번까지 재작성을 시도하여 최종적으로 만족스러운 생기부를 만든다.

 

2. 주요 구성 요소 (dspy.Signature 기반 모듈):

  • Discriminator (분류자):
    • 역할: 입력 데이터(input_data)의 품질 수준을 'good', 'normal', 'bad', 'nothing' 네 가지 중 하나로 분류한다.
    • 입력: instruction (분류 기준 설명), input_data.
    • 출력: quality (분류 결과).
  • Core_Summarizer (핵심 요약자):
    • 역할: 'good' 품질로 분류된 데이터에 대해서만 핵심 활동 내용(activity)과 원본 데이터(input_data)를 바탕으로 생기부 작성에 필요한 핵심 요약을 추출한다.
    • 입력: instruction (요약 방법 설명), activity, input_data.
    • 출력: core_summary (핵심 요약).
  • SR_Writer (작성자):
    • 역할: 분류 결과에 따라 적절한 Write_prompt를 지침(instruction)으로 삼고, 원본 데이터(input_data), 활동 내용(activity), 맥락 정보(context - 핵심 요약 또는 성취기준), 예시(one_shot), 그리고 이전 평가자의 피드백(eval_feedback)을 참고하여 생활기록부 텍스트(student_record)를 작성한다. 재작성 요청 시에는 eval_feedback을 적극 활용한다.
    • 입력: instruction (Write_prompt), input_data, activity, context, one_shot, eval_feedback.
    • 출력: student_record (작성된 생기부).
  • Evaluator (평가자):
    • 역할: 작성자(SR_Writer)가 생성한 생기부(generated_output)를 입력 데이터(input_data), 원본 품질(quality) 정보, 그리고 평가 지침(instruction)을 바탕으로 평가한다. 평가 결과를 바탕으로 피드백(srwrite_op)과 재작성 필요 여부(rewrite_op - return_Yes 또는 return_No)를 결정한다.
    • 입력: instruction (평가 방법 설명), quality, input_data, generated_output.
    • 출력: srwrite_op (작성자에 대한 평가 피드백), rewrite_op (재작성 결정).

3. 전체 작동 흐름 (MySR_Agent의 forward 메소드):

  1. 초기화: eval_feedback 변수를 "없음"으로 초기화한다. 이는 첫 번째 작성 시 평가 피드백이 없음을 나타낸다다. 최대 3번의 시도를 위한 반복문(for i in range(3))이 시작된다.
  2. 데이터 품질 분류: Discriminator 모듈을 호출하여 입력 데이터 input_data의 품질(discrim)을 판단한다. (그림의 Discriminator 단계)
  3. 작성자 설정을 위한 분기: 분류된 품질(discrim)에 따라 SR_Writer에게 전달할 instruction (올바른 write_prompt 선택)과 context (핵심 요약 또는 성취기준 또는 없음)를 결정한다.
    • 'good'인 경우: Core_Summarizer를 호출하여 context로 사용할 핵심 요약을 생성하고 write_prompt_good를 instruction으로 선택한다.
    • 'normal'인 경우: context를 "없음"으로 설정하고 write_prompt_normal을 instruction으로 선택한다.
    • 'bad' 또는 'nothing'인 경우: context를 archievement (성취기준)으로 설정하고 각각 write_prompt_bad, write_prompt_nothing을 instruction으로 선택합니다. 'nothing'의 경우 활동 내용(my_activity)도 "없음"으로 설정한다.
  4. 생기부 작성: SR_Writer 모듈을 호출하여 생기부를 작성한다. 이때, 현재 시점에 준비된 모든 정보(instruction, input_data, activity, context, one_shot, eval_feedback)를 전달한다. eval_feedback은 두 번째 시도부터는 이전 평가 결과가 전달됩니다. 
  5. 생기부 평가: Evaluator 모듈을 호출하여 작성된 생기부(sr_output)를 평가한다. 평가자는 원본 품질(discrim), 입력 데이터(input_data) 등을 함께 참고하여 srwrite_op (피드백)와 rewrite_op (재작성 결정)을 출력한다. 
  6. 피드백 및 재작성 결정: 평가자의 출력 중 eval_output.srwrite_op는 다음 루프를 위해 eval_feedback 변수에 저장하고 eval_output.rewrite_op 값을 확인한다.
    • 'return_Yes'인 경우: 재작성이 필요하다는 의미이므로, 루프의 다음 반복으로 넘어간다. 이때 SR_Writer는 업데이트된 eval_feedback을 받아 이전 작성의 문제점을 개선하려 시도한다.
    • 'return_No'인 경우: 생기부 작성이 평가를 통과했다는 의미이므로, break 문을 통해 반복문을 종료한다.
  7. 최종 결과 반환: 루프가 종료되면 (성공적으로 통과했거나 최대 시도 횟수(3회)에 도달했거나), 마지막으로 작성된 생기부(sr_output)와 마지막 평가 피드백(eval_feedback)을 반환한다. 

4. 재작성 메커니즘:

재작성은 이 파이프라인의 핵심적인 특징 중 하나로 Evaluator가 return_Yes를 반환하면, 이전에 작성된 생기부 결과와 평가 피드백(srwrite_op)이 SR_Writer로 다시 입력된다. SR_Writer는 수정된 write_prompt에 따라 이 eval_feedback을 분석하여 왜 이전 결과가 좋지 않았는지 파악하고, 동일한 원본 데이터(input_data, activity, context)를 사용하여 피드백을 반영한 새로운 생기부를 작성하게 되며. 이 과정이 최대 3번까지 반복된다.

 

요약하자면, 이 코드는 입력 데이터 품질을 먼저 분류하고, 그에 맞는 최적의 정보(핵심 요약 또는 성취기준)와 작성 지침(Write_prompt)을 준비하여 생기부를 작성한다. 작성된 생기부는 평가자의 검토를 거치며, 평가자가 '재작성 필요' 판단을 내리면 평가 피드백과 함께 작성자에게 다시 전달되어 개선된 생기부가 나올 때까지 이 과정을 반복하는 에이전트이다.

 

 

4. 전체적인 생활기록부 작성 AI 에이전트 구현하기

import dspy
from typing import Literal
lm = dspy.LM(model="ollama_chat/gemma3:12b-it-q4_K_M", \
    api_base='http://localhost:11434', 
    api_key="", temperature=0.7)
    
dspy.configure(lm=lm)
input_data1 = r"""[물리 점수] 86, 75, 72, 85 [물리의 재구성] 선정한 문제: 빛의 파장이 500nm인 단색광을 어떤 금속판에 비추었더니 광전자가 방출되었다. 이 금속의 일함수는 2.0eV이다. 방출되는 광전자의 최대 운동 에너지는 몇 eV인가? (단, 플랑크 상수 h = 6.63 × 10⁻³⁴ J·s, 빛의 속도 c = 3 × 10⁸ m/s, 1eV = 1.6 × 10⁻¹⁹ J로 계산한다. 또는 hc ≈ 1240 eV·nm를 사용해도 좋다.) 1. 문제 선정 이유 광전 효과는 빛의 입자성을 명확하게 보여주는 현상으로, 현대 물리학의 중요한 개념 중 하나라고 생각했습니다. 빛의 에너지와 금속의 일함수, 그리고 방출되는 광전자의 운동 에너지 사이의 관계를 정확히 이해하고 싶었고, 다양한 변수를 적용하여 응용해보고자 이 문제를 선택했습니다. 교과과정: IV 파동과 입자의 성질 - 2. 빛과 물질의 이중성 - 광전 효과 2. 문제에서 제시된 물리량과 확인해야 하는 물리량 제시된 물리량: 입사광의 파장(λ = 500nm), 금속의 일함수(W = 2.0eV), 플랑크 상수(h), 빛의 속도(c), 전자볼트와 줄의 환산 관계. 확인해야 하는 물리량: 광전자의 최대 운동 에너지(K_max). 3. 확인해야 하는 물리량 구하는 법 (기존 문제 풀이) 광전 효과의 기본 공식은 E_photon = W + K_max 입니다. 입사광의 에너지(E_photon) 계산: E_photon = hc/λ 여기서 hc ≈ 1240 eV·nm를 사용하면 편리합니다. E_photon = 1240 eV·nm / 500 nm = 2.48 eV 광전자의 최대 운동 에너지(K_max) 계산: K_max = E_photon - W K_max = 2.48 eV - 2.0 eV = 0.48 eV 따라서 방출되는 광전자의 최대 운동 에너지는 0.48 eV입니다. 4. 재구성한 물리 현상 방법 (새로운 문제) 어떤 금속에 빛을 비추었더니 광전자가 방출되었고, 이 광전자를 멈추게 하는 데 필요한 정지 전압(저지 전압)이 0.8V였다. 이 금속의 문턱 진동수가 6.0 × 10¹⁴ Hz라면, 이 금속에 비춘 빛의 파장은 몇 nm인가? (단, 플랑크 상수 h = 6.63 × 10⁻³⁴ J·s, 빛의 속도 c = 3 × 10⁸ m/s, 전자의 전하량 e = 1.6 × 10⁻¹⁹ C, hc ≈ 1240 eV·nm를 사용해도 좋다.) 5. 재구성한 물리 현상과 기존 물리현상의 공통점과 차이점 공통점: 두 문제 모두 광전 효과의 기본 원리(E_photon = W + K_max)를 이용합니다. 빛의 에너지, 금속의 특성(일함수 또는 문턱 진동수), 광전자의 운동 에너지(또는 정지 전압) 사이의 관계를 다룹니다. 차이점: 기존 문제: 파장과 일함수를 주고 최대 운동 에너지를 구하는 문제. 재구성한 문제: 정지 전압과 문턱 진동수를 주고 입사광의 파장을 구하는 문제. 즉, 구하고자 하는 미지수와 주어진 조건이 다릅니다. 재구성한 문제는 일함수를 직접 주지 않고 문턱 진동수를 통해 계산하도록 하였고, 최대 운동 에너지를 정지 전압을 통해 구하도록 하여 한 단계 더 생각해야 합니다. 6. 재구성한 물리 현상으로 확인해야 하는 물리량 구하기 (새로운 문제 풀이) 광전자의 최대 운동 에너지(K_max) 계산: 정지 전압 V_s = 0.8V 이므로, K_max = eV_s = 0.8 eV 입니다. 금속의 일함수(W) 계산: 문턱 진동수 f₀ = 6.0 × 10¹⁴ Hz 이므로, W = hf₀ 입니다. W = (6.63 × 10⁻³⁴ J·s) × (6.0 × 10¹⁴ Hz) = 3.978 × 10⁻¹⁹ J 이를 eV 단위로 환산하면, W = (3.978 × 10⁻¹⁹ J) / (1.6 × 10⁻¹⁹ J/eV) ≈ 2.486 eV (약 2.49 eV로 계산) 입사광의 에너지(E_photon) 계산: E_photon = W + K_max E_photon = 2.49 eV + 0.8 eV = 3.29 eV 입사광의 파장(λ) 계산: E_photon = hc/λ 이므로, λ = hc/E_photon λ = 1240 eV·nm / 3.29 eV ≈ 376.9 nm (약 377 nm) 따라서 이 금속에 비춘 빛의 파장은 약 377 nm입니다. 7. 탐구를 통해 무엇을 배웠는지 구체적으로 설명하기 이번 '물리의 재구성' 활동을 통해 광전 효과의 핵심 공식을 다양한 상황에 적용하는 연습을 할 수 있었습니다. 단순히 공식을 암기하는 것을 넘어, 각 물리량(파장, 진동수, 일함수, 문턱 진동수, 최대 운동 에너지, 정지 전압)이 서로 어떻게 유기적으로 연결되는지 깊이 이해하게 되었습니다. 특히, 일함수를 문턱 진동수로, 최대 운동 에너지를 정지 전압으로 변환하여 생각하는 과정에서 개념 간의 관계를 명확히 파악할 수 있었습니다. 또한, 문제의 조건을 바꾸어 새로운 문제를 만들고 해결하는 과정에서 문제 해결 능력과 응용력을 기를 수 있었습니다. 8. 추가 계획 1가지 이상 제시하기 광전 효과와 빛의 세기 관계 탐구: 빛의 세기가 광전류의 세기에는 영향을 주지만 광전자의 최대 운동 에너지에는 영향을 주지 않는 이유를 그래프와 함께 분석하고, 이를 설명하는 실험을 설계해보고 싶습니다. 다양한 금속의 일함수 비교: 여러 가지 금속의 일함수 값을 조사하고, 각 금속에 대해 광전 효과가 일어나기 위한 빛의 최소 진동수(문턱 진동수)와 최대 파장(한계 파장)을 계산하여 비교 분석해보고 싶습니다. [물리 심화 탐구] 1. 주제 선정에 대해 작성하세요 수업 시간에 '전자기 유도' 현상을 배우면서 자기장의 변화가 전류를 만들어낸다는 사실에 큰 흥미를 느꼈습니다. 특히, 코일과 자석을 이용한 간단한 실험 외에 이러한 원리가 실생활에서 어떻게 대규모로 활용되는지 궁금해졌습니다. 그중에서도 비접촉식으로 물체를 가열할 수 있는 '인덕션 히터(유도 가열기)'의 작동 원리가 전자기 유도와 깊은 관련이 있다는 것을 알게 되어, "인덕션 히터의 작동 원리와 효율성에 대한 물리적 탐구"라는 주제를 선정하게 되었습니다. 2. 자료 수집에 대해 작성하세요 고등학교 물리 교과서 및 참고서의 '전자기 유도', '교류 회로' 단원 내용을 복습했습니다. 온라인 과학 학술 데이터베이스(Google Scholar, RISS 등)에서 '유도 가열(Induction Heating)', '와전류(Eddy Current)', '전자기 유도 효율' 등의 키워드로 관련 논문 및 기술 자료를 검색했습니다. 유명 과학 유튜브 채널 및 교육 웹사이트에서 인덕션 히터의 작동 원리를 시각적으로 설명하는 자료들을 참고했습니다. 가전제품 제조사의 기술 설명 자료 및 특허 정보를 통해 실제 제품에 적용된 기술적 세부 사항을 파악하려 노력했습니다. 3. 자료 분석에 대해 작성하세요 수집한 자료를 바탕으로 인덕션 히터의 핵심 원리를 다음과 같이 분석했습니다. 전자기 유도: 인덕션 히터 내부의 코일에 고주파 교류 전류를 흘려주면, 코일 주변에 시간에 따라 빠르게 변화하는 자기장이 형성됩니다. (패러데이의 전자기 유도 법칙) 와전류(Eddy Current) 발생: 이 변화하는 자기장이 금속 용기(냄비 등) 바닥을 통과하면서 용기 내부에 유도 전류, 즉 와전류를 발생시킵니다. (렌츠의 법칙) 줄 발열(Joule Heating): 금속 용기는 고유한 전기 저항을 가지고 있으므로, 와전류가 흐르면서 용기 자체에서 열이 발생합니다 (P = I²R). 이 열이 음식을 조리하는 데 사용됩니다. 표피 효과(Skin Effect): 고주파 교류를 사용할 경우 전류가 도체의 표면 근처에 집중되어 흐르는 현상으로, 이로 인해 용기 표면에서 더 효과적인 가열이 일어납니다. 효율성: 인덕션 히터는 용기 자체를 직접 가열하므로 열 손실이 적어 에너지 효율이 높습니다. 가스레인지나 일반 전기레인지(하이라이트)에 비해 예열 시간이 짧고, 주변으로 방출되는 열이 적어 쾌적한 조리 환경을 제공합니다. 4. 결론 도출에 대해 작성하세요 인덕션 히터는 전자기 유도 법칙에 의해 코일에서 발생한 변화하는 자기장이 금속 용기에 와전류를 유도하고, 이 와전류가 용기의 전기 저항에 의해 줄 열을 발생시켜 음식을 가열하는 장치입니다. 고주파 교류와 표피 효과를 이용하여 가열 효율을 높이며, 직접 가열 방식으로 에너지 손실을 최소화하여 높은 열효율을 달성합니다. 이는 물리학적 원리가 실생활의 편의를 증진시키는 대표적인 사례임을 확인했습니다. 5. 탐구 고찰에 대해 작성하세요 이번 탐구를 통해 전자기 유도 현상이 단순히 이론에 머무르지 않고, 우리 생활 깊숙이 들어와 유용하게 활용되고 있음을 실감했습니다. 인덕션 히터의 원리를 이해하면서 와전류, 표피 효과 등 심화된 물리 개념까지 접할 수 있어 지식의 폭을 넓힐 수 있었습니다. 다만, 실제 인덕션 히터의 코일 설계, 주파수 최적화, 사용 가능한 용기의 재질 제한(자성체 또는 특정 비자성체 금속) 등 공학적인 측면까지 깊이 있게 다루지 못한 점은 아쉬움으로 남습니다. 앞으로 전자기학 관련 심화 학습을 통해 이러한 부분에 대한 이해를 높이고 싶다는 생각을 했습니다. 또한, 에너지 효율이 높은 인덕션 기술이 산업 현장에서는 어떻게 응용되는지(예: 금속 용해, 열처리) 추가적으로 조사해보고 싶습니다. [교과선생님 관찰내용] 수업 참여도 적극적이며, 질문을 통해 이해를 명확히 하려는 자세가 돋보임."""

input_data2 = r"""[물리 점수] 66, 54, 51, 49 [물리의 재구성] 선정한 문제: 교과서에 나온 쉬운 운동 문제 중에서 낙하하는 물체의 운동 관련 문제 하나를 골랐습니다. 문제 선정 이유: 중력 때문에 물체가 아래로 떨어지는 것은 우리가 매일 보는 현상이라서 궁금했습니다. 교과서에서 관련된 문제를 보니 해보고 싶다는 생각이 들었습니다. 다른 문제들보다는 좀 쉬워 보여서 골랐습니다. 문제에서 제시된 물리량과 확인해야 하는 물리량: 문제에서 처음 속도, 시간 같은 것이 주어졌고, 나중 속도나 이동 거리를 구하는 것이었습니다. 확인해야 하는 물리량 구하는 법 (기존 문제 풀이): 등가속도 운동 공식 (v=v0+at, s=v0t+1/2at^2)을 사용해서 풀었습니다. 문제에 주어진 숫자들을 공식에 넣어서 계산했습니다. 책에 풀이가 있어서 보고 따라 했습니다. 재구성한 물리 현상 방법 (새로운 문제): 기존 문제에서 숫자를 조금 바꿔서 새로운 문제를 만들었습니다. 예를 들어, 떨어지는 시간을 2초에서 3초로 바꾼다거나 하는 식으로요. 재구성한 물리 현상과 기존 물리현상의 공통점과 차이점: 사용한 공식은 똑같습니다. 문제 내용이나 숫자가 달라졌습니다. 재구성한 물리 현상으로 확인해야 하는 물리량 구하기 (새로운 문제 풀이): 바꾼 숫자를 공식에 넣어서 다시 계산했습니다. 계산 실수를 안 하려고 노력했습니다. 탐구를 통해 무엇을 배웠는지 구체적으로 설명하기: 등가속도 운동 공식을 문제에 적용하는 연습을 할 수 있었습니다. 공식이 왜 그렇게 생겼는지는 잘 모르겠지만, 문제 푸는 방법은 조금 알게 되었습니다. 속도나 거리를 구하는 계산이 중요하다는 것을 배웠습니다. 추가 계획 1가지 이상 제시하기: 등가속도 운동 다른 문제들도 더 풀어보고 싶습니다. [물리 심화 탐구] 주제 선정에 대해 작성하세요: 왜 하늘이 파란색으로 보이는지 평소에 궁금했습니다. 과학적으로 이유가 있을 것 같아서 찾아보고 싶었습니다. 자료 수집에 대해 작성하세요: 인터넷 검색을 많이 했습니다. 유튜브 영상도 보고, 집에 있는 과학 책에서 빛 관련 부분도 찾아봤습니다. 자료 분석에 대해 작성하세요: 태양 빛이 지구 대기를 지나면서 공기 분자 같은 것에 부딪혀서 빛이 여기저기로 흩어진다고 합니다. 이걸 산란이라고 하는 것 같습니다. 파란색 빛이 다른 빨간색이나 노란색 빛보다 더 많이 흩어져서 하늘이 파랗게 보인다고 합니다. 결론 도출에 대해 작성하세요: 하늘이 파랗게 보이는 것은 태양 빛이 대기 중에서 산란되기 때문이고, 특히 파란색 빛이 잘 산란되기 때문입니다. 탐구 고찰에 대해 작성하세요: 매일 보는 하늘 색깔에 이런 과학적인 원리가 숨어있다는 것이 신기했습니다. 빛의 산란이라는 현상에 대해 처음 알게 되었습니다. 물리가 우리 생활 주변에 있다는 것을 다시 느꼈습니다. 다만, 왜 파란색 빛이 다른 색보다 더 잘 흩어지는지는 아직 잘 이해되지 않았습니다. 기회가 되면 더 공부하고 싶습니다. [교과선생님 관찰내용] 수업 시간에 성실하게 참여하려는 태도를 보임. 기본적인 개념 설명은 이해하려 노력하나, 심화되거나 응용이 필요한 문제에서는 어려움을 겪는 모습이 관찰됨. 개념을 정확히 적용하는 연습이 더 필요함. 꾸준히 노력한다면 조금씩 나아질 것으로 기대됨."""

input_data3 = r"""[물리 점수] 28, 35, 31, 25 [물리의 재구성] 미작성 [물리 심화 탐구] 주제 선정: 소리가 어떻게 들리는지 궁금해서 골랐습니다. 자료 수집: 인터넷으로 소리 관련 정보 찾아봤습니다. 자료 분석: 소리가 떨림으로 전달된다는 것 같습니다. 결론 도출: 떨림이 귀에 오면 소리가 들립니다. 탐구 고찰: 소리가 신기하다는 것을 알게 되었고, 물리가 생활에 있다는 것을 느꼈습니다. [교과선생님 관찰내용] 수업 시간에 조용히 참여함. 복잡한 개념에 대한 깊은 이해는 부족해 보임."""

input_data4 = r"""아무 활동을 하지 않음"""


archievement = r"""
1. 여러 가지 물체의 운동 사례를 찾아 속력의 변화와 운동 방향의 변화에 따라 분류할 수 있다.
2. 뉴턴 운동 법칙을 이용하여 직선 상에서 물체의 운동을 정량적으로 예측할 수 있다.
3. 뉴턴의 제3법칙의 적용 사례를 찾아 힘이 상호 작용임을 설명할 수 있다.
4. 물체의 1차원 충돌에서 충돌 전후의 운동량 보존을 이용하여 속력의 변화를 정량적으로 예측할 수 있다.
5. 충격량과 운동량의 관계를 이해하고, 일상생활에서 충격을 감소시키는 예를 찾아 설명할 수 있다.
6. 직선 상에서 운동하는 물체의 역학적 에너지가 보존되는 경우와 열에너지가 발생하여 역학적 에너지가 보존되지 않는 경우를 구별하여 설명할 수 있다.
7. 열기관이 외부와 열과 일을 주고받아 열기관의 내부 에너지가 변화됨을 사례를 들어 설명할 수 있다.
8. 열이 모두 일로 전환되지 않는다는 것을 사례를 들어 설명할 수 있다.
9. 모든 관성계에서 빛의 속도가 동일함을 알고 시간 지연, 길이 수축, 동시성과 관련된 현상을 설명할 수 있다.
10. 질량이 에너지로 변환됨을 사례를 들어 설명할 수 있다.
11. 전자가 원자에 속박되어 있음을 전기력을 이용하여 정성적으로 설명할 수 있다.
12. 원자 내의 전자는 불연속적 에너지 준위를 가지고 있음을 스펙트럼 관찰을 통하여 설명할 수 있다.
13. 고체의 에너지띠 이론으로 도체, 반도체, 절연체 등의 차이를 구분하고, 여러 가지 고체의 전기 전도성을 비교하는 탐구를 수행할 수 있다.
14. 종류가 다른 원소를 이용하여 반도체 소자를 만들 수 있음을 다이오드를 이용하여 설명할 수 있다.
15. 전류에 의한 자기 작용이 일상생활에서 적용되는 다양한 예를 찾아 그 원리를 설명할 수 있다.
16. 자성체의 종류를 알고 자성체가 활용되는 예를 찾을 수 있다.
17. 일상생활에서 전자기 유도 현상이 적용되는 다양한 예를 찾아 그 원리를 설명할 수 있다.
18. 파동의 진동수, 파장, 속력 사이의 관계를 알고 매질에 따라 파동의 속력이 다른 것을 활용한 예를 설명할 수 있다.
19. 파동의 전반사 원리를 이용한 광통신 과정을 설명할 수 있다.
20. 다양한 전자기파를 스펙트럼의 종류에 따라 구분하고, 그 사용 예를 찾아 설명할 수 있다.
21. 파동의 간섭이 활용되는 예를 찾아 설명할 수 있다.
22. 빛의 이중성을 알고, 영상정보가 기록되는 원리를 설명할 수 있다.
23. 물질의 이중성을 알고, 전자 현미경의 원리를 설명할 수 있다.
"""

my_activity = r"""1년동안 물리학I 활동 내용
[물리 점수]
첫 번째 시험 내용: 변위, 속도, 가속도, 뉴턴 법칙, 운동량과 충격량, 일과 운동에너지, 역학적 에너지, 열역학 1법칙, 열역학 2법칙
두 번째 시험 내용: 특수상대성이론, 핵융합, 핵분열, 전기력, 원자핵, 스펙트럼, 에너지 준위, 보어원자모형
세 번째 시험 내용: 에너지띠, 다이오드, 전기전도성, 전류에 의한 자기장, 물질의 자성, 전자기유도
네 번째 시험 내용: 파동의 정의, 파동의 굴절, 파동의 중첩, 전자기파, 광전 효과, 물질의 이중성
[물리의 재구성]
1.문제 선정 이유, 
2.문제에서 제시된 물리량과 확인해야 하는 물리량, 
3.확인해야 하는 물리량 구하는 법, 
4.재구성한 물리 현상 방법, 
5.재구성한 물리 현상과 기존 물리현상의 공통점과 차이점, 
6.재구성한 물리 현상으로 확인해야 하는 물리량 구하기, 
7.탐구를 통해 무엇을 배웠는지 구체적으로 설명하기, 
8.추가 계획 1가지 이상 제시하기
[물리 심화 탐구]
1.주제 선정에 대해 작성하세요, 
2.자료 수집에 대해 작성하세요, 
3.자료 분석에 대해 작성하세요, 
4.결론 도출에 대해 작성하세요, 
5.탐구 고찰에 대해 작성하세요
[교과선생님 관찰내용]
그 밖에 교과선생님이 적는 경우가 있습니다."""

one_shot = r"""<생활기록부 예시>
창의력과 집중력, 직관과 통찰이 우수한 학생임. 연필심의 길이에 따른 전기전도도 측정 실험에서 연필심, 전지, 전압계가 병렬로 연결되어 있으므로 전압이 연필심의 길이에 무관해야 함에도 불구하고 변한 이유를 연필심의 온도 변화에 의한 것으로 해석하고, 모둠 구성원에게 스위치 개폐시간에 대한 유의사항을 안내함. 직선 도선 전류 주위의 자기장 측정 실험에서 나침반의 회전 각도를 레이저 포인터를 이용하여 보다 정확하게 측정하는 방법을 고안하는 방식으로 실험 설계에서 창의력을 발휘하였으며, 전류에 의한 자기장의 이용의 사례로 자기 공명 영상 장치와 자기부상 열차의 구조에 대해 분석하고 작동 원리에 대해 탐구함. 네오디뮴 자석과 건전지, 철심을 이용해 간이 전동기를 만들어보며 전동기의 원리를 학습함. 물과 글리세린으로 각각 채워진 반원통에 입사각에 따라 달라지는 굴절각을 측정한 후 스넬의 법칙에 적용하여 굴절률을 구하는 실험 활동을 수행함. 실험 중 팀원들과의 소통 과정에서 뛰어난 협업 능력과 리더십을 보임."""

evaluator_prompt= r"""당신은 학생 생활기록부 작성 AI의 최종 결과물 품질을 평가하고 재작성 필요성을 판단하는 전문 검토 시스템이다. 다음 제공되는 입력 정보를 분석하여 'SR_Writer'가 생성한 생활기록부 결과의 적절성을 평가하고, 작성자 피드백 및 재작성 필요성 여부를 판단한다.

**평가에 사용될 입력 정보:**

1.  **quality:** 'Discriminator'가 판별한 학생 활동 데이터의 품질 수준 ('good', 'normal', 'bad', 'nothing' 중 하나)이다. 이 값은 'SR_Writer'가 사용한 내부 지침 및 최종 결과에 기대하는 수준을 판단하는 기준이 된다.
2.  **input_data:** 학생의 실제 활동 내용 및 교사 관찰 등이 담긴 원본 텍스트 자료이다. 'generated_output'이 이 원본의 사실과 일치하는지, 원본 내용을 제대로 반영했는지 검토하는 근거이다. (quality가 nothing일 때는 실질적인 내용이 없을 수 있다.)
3.  **generated_output:** 'SR_Writer'가 최종적으로 생성한 생활기록부 항목 텍스트이다. 평가의 주된 대상으로서, 내용의 적절성, 일관성, 형식 및 문체 적절성을 검토한다.
4.  **instruction (평가자 지침):** 평가 작업 자체에 대한 지침이다.

**평가 기준 및 출력 항목별 내용:**

제공된 입력 정보를 바탕으로 'SR_Writer'가 'quality'에 맞는 작성 전략을 잘 따랐는지, 'input_data'의 내용을 적절히 반영하여 'generated_output'을 생성했는지 평가한다.

*   **[srwrite_op] (작성자 피드백):**
    *   'generated_output'이 'input_data'의 **핵심 내용을 얼마나 정확하게 반영**하고 있는지 평가한다. 'input_data'에 있는 중요 정보가 누락되거나 잘못 기술된 부분이 있는지 구체적으로 언급한다.
    *   'generated_output'의 **내용, 깊이, 문체가 'quality' (good, normal, bad, nothing) 수준에 얼마나 적절**한지 평가한다. 예를 들어, quality가 'good'인데 내용이 부실하거나, quality가 'bad'인데 내용을 과하게 포장하지 않았는지 등을 검토하고 피드백한다.
    *   'generated_output'이 생활기록부 항목으로서 **기본적인 형태와 문체(명사형 종결 등)**를 갖추고 가독성이 있는지 평가한다. (구체적인 예시 one_shot이 없으므로 일반적인 생활기록부 형식을 기준으로 한다.)
    *   전반적으로 'generated_output'이 'input_data'와 'quality'를 고려했을 때 얼마나 잘 작성되었는지에 대한 종합적인 피드백 내용을 구성한다.

*   **[rewrite_op] (재작성 의견):**
    *   **[srwrite_op]에서 평가한 내용을 종합**하여, 생성된 'generated_output'을 **별도의 재작업 없이 그대로 사용하기에 무리가 없는지** 최종 판단한다.
    *   **재작성 필요성 판단 기준:**
        *   **'return_Yes' (재작성 필요):**
            *   'generated_output'에 'input_data'와 **모순되는 명백한 사실 오류**가 포함된 경우,
            *   'generated_output'의 품질이 'quality' 수준과 **심각하게 불일치**하여 해당 품질의 데이터로 기대할 수 없는 결과인 경우 (예: quality가 'good'인데 내용이 극히 부실하거나, quality가 'bad'인데 원본에 없는 내용을 과하게 추가한 경우 등),
            *   'generated_output'이 생활기록부로서 **기본적인 형태를 갖추지 못했거나(예: 너무 짧거나, 문체/형식 오류 심각) 가독성이 현저히 낮은 경우**에 해당한다.
        *   **'return_No' (재작성 불필요):**
            *   'generated_output'이 'input_data'의 내용을 합리적인 수준으로 반영하고, 'quality' 수준에 대체로 부합하며, 생활기록부로서 기본적인 형태와 가독성을 갖추고 있어 **수동 검토 시 약간의 수정으로 사용 가능**한 경우에 해당한다. (완벽하지 않아도 괜찮다.)
    *   **이 섹션의 출력은 반드시 'return_Yes' 또는 'return_No' 단 두 가지 중 하나여야 하며, 다른 어떠한 내용도 포함하지 않는다.**

**제공된 'quality', 'input_data', 'generated_output' 정보를 지정된 평가 기준에 따라 분석하고, 작성자 피드백 및 최종 재작성 필요성 판단 결과를 포함하여 지정된 형식으로 결과를 출력한다.**
"""

 

discriminator_prompt = r"""당신은 고등학생의 특정 과목 활동 기록(예: 물리 활동, 탐구 보고서 등)의 내용 유무 및 품질 수준을 평가하는 전문가입니다. 다음 입력된 '학생 활동 데이터'를 분석하여, 그 내용의 존재 유무, 충실도, 깊이, 구체성 등을 기준으로 **'good', 'normal', 'bad', 'nothing'** 중 하나의 카테고리로 판별하세요.
**판별 기준:**
1.  **good:**
    *   활동 내용이 **매우 상세하고 구체적**이며, 문제 해결 과정이나 탐구 절차가 **논리적이고 체계적으로** 기술되어 있습니다.
    *   물리 개념에 대한 **심도 깊은 이해와 분석**이 드러나며, 개념 간의 유기적인 연결이나 응용 시도가 명확히 보입니다.
    *   활동을 통해 얻은 **구체적인 깨달음, 성과, 또는 도출한 결론**이 명확하고 의미 있습니다.
    *   **두드러지는 노력, 주도성, 창의적인 시도**가 관찰됩니다.
    *   전반적으로 고등학생의 심화 활동 기록으로서 기대되는 **높은 수준의 품질**을 보입니다.
2.  **normal:**
    *   활동 내용은 어느 정도 기술되어 있으나, **구체성이나 분석의 깊이가 다소 부족**할 수 있습니다.
    *   물리 개념에 대한 **기본적인 이해 수준**을 보이며, 복잡한 개념 적용이나 심층적인 분석 시도는 미약할 수 있습니다.
    *   깨달음이나 결론이 **다소 피상적이거나 일반적인 수준**에 머무를 수 있습니다.
    *   활동 참여 및 노력의 흔적은 보이나, **두드러지는 주도성이나 차별화된 시도는 부족**할 수 있습니다.
    *   고등학생 활동 기록으로서 **평균적인 수준의 품질**을 보입니다. **'good'에 미치지 못하지만, 유의미한 내용이 최소한으로라도 있는 경우**에 해당합니다.
3.  **bad:**
    *   활동 내용은 **있기는 하지만, 극도로 짧거나 내용이 매우 부실**하여 활동의 흔적만 겨우 남은 경우입니다.
    *   필수 항목이 다수 누락되었거나, 작성된 내용이 극히 형식적이거나 의미 없는 문장들로 채워져 있습니다.
    *   구체적인 내용이나 의미 있는 활동, 깨달음, 결과 등을 거의 찾아볼 수 없습니다.
    *   **아무것도 하지 않았다고 보기는 어렵지만, 최소한의 노력조차 부족**했다고 판단되는 수준입니다. (예: 제목만 있거나, 한두 문장으로 모든 내용을 때우거나)
4.  **nothing:**
    *   제공된 '학생 활동 데이터'가 **전혀 없거나, 빈 문자열("") 또는 의미 없는 몇 개의 공백 문자**로만 구성되어 있습니다.
    *   학생이 해당 활동을 **전혀 수행하지 않았거나 기록을 제출하지 않았다고 판단**되는 경우에 해당합니다.
**출력 형식:**
당신의 출력은 판별 결과인 **단 하나의 영문 소문자 단어**여야 합니다: **'good'**, **'normal'**, **'bad'**, 또는 **'nothing'**. 어떠한 추가 설명, 문장 부호, 개행 문자도 포함하지 마십시오.
**예시:**
[학생 데이터]: ... (여기에 실제 학생 데이터 텍스트가 들어갑니다) ...
출력:
normal
(또는 good, bad, nothing)
**중요:** 판별은 오직 제공된 '학생 활동 데이터'의 **내용 유무와 품질 자체**에만 근거해야 합니다.
"""

write_prompt_good = r"""당신은 [물리학I] 교사이며, 학생의 학교생활기록부 항목을 작성하는 최고 수준의 전문가입니다. 이번에 작성할 학생의 활동 데이터 품질은 **'good'** 수준이며, 학생의 뛰어난 역량과 성과가 잘 드러나 있습니다.

**입력 데이터:**
만약 입력 데이터가 'srwrite_op' 형태라면, 이는 이전 작성 결과에 대한 재검토 및 재작성 요청입니다. 'srwrite_op' 내에 다음 정보가 포함되어 있습니다: '학생 활동 및 교사 평가 자료' 원문, '핵심 요소 추출 결과', 이전 '생활기록부 작성 결과', 사용된 프롬프트 이름. 이 경우 **'학생 활동 및 교사 평가 자료' 원문**과 **'핵심 요소 추출 결과'**를 이번 작성에 사용하며, 이전 '생활기록부 작성 결과'는 참고용입니다.

만약 'srwrite_op' 형태가 아니라면, 첫 작성 요청이며 다음 두 가지 데이터가 입력됩니다:
1.  **"학생 활동 및 교사 평가 자료" 원문:** 학생의 활동에 대한 **매우 상세하고 구체적인 설명**과 교사의 긍정적인 평가가 담긴 원본 자료입니다. 이 자료는 'good' 품질 수준에 해당하는 풍부한 내용입니다.
2.  **"핵심 요소 추출 결과":** 위 원문에서 **핵심 활동, 깨달은 점, 드러난 행동, 주도적인 내용, 도출한 결론, 공동체 요소, 교사 관찰 및 평가, 향후 발전 가능성 및 기대** 등 총 8가지 핵심 요소를 **정확하고 충실하게** 목록 형태로 추출한 자료입니다.

**작성 목표:**
입력된 **"핵심 요소 추출 결과"를 전체 내용 구성의 명확한 로드맵(Roadmap)**으로 삼고, **"학생 활동 및 교사 평가 자료" 원문의 풍부한 구체적인 내용**을 활용하여 [물리학I] 과목에서의 학생의 **뛰어난 역량, 심도 깊은 학업 성취 및 유의미한 성장**을 객관적이고 설득력 있게 기술합니다. **교사의 높은 수준의 관찰 및 평가 내용과 학생의 뛰어난 잠재력 및 향후 발전 가능성**을 적극적으로 부각하여 서술합니다.

**작성 지침:**
1.  **작성 모드 판별:** 입력 데이터가 'srwrite_op' 형태인지 아닌지를 먼저 판별합니다.
2.  **내용 구성 (모드 공통):** 추출된 **8가지 핵심 요소 목록 순서대로** 학생의 물리학I 학습 과정을 기술하되, 각 요소의 내용을 **"학생 활동 및 교사 평가 자료" 원문에 제시된 구체적인 사례와 상세한 설명으로 뒷받침하고 풍성하게** 만듭니다. 특히 다음 내용에 집중합니다.
    *   **개념에 대한 심도 깊은 이해와 적용 능력:** 문제 해결 과정, 탐구 분석 등에서 드러난 깊이 있는 이해 수준을 명확히 서술합니다.
    *   **비판적 사고 및 문제 해결 능력:** 문제 재구성, 예상치 못한 상황 대처 등에서 발휘된 사고 과정을 구체적으로 기술합니다.
    *   **창의성 및 주도성:** 새로운 아이디어 제안, 독자적인 탐구 설계 등 차별화된 시도를 부각합니다.
    *   **협업 및 리더십 (해당 시):** 팀 활동에서의 긍정적인 기여와 리더십 발휘 사례를 구체적으로 제시합니다.
    *   **교사의 관찰 및 평가:** 원문에 명시된 교사의 긍정적인 평가 내용을 자연스럽게 녹여 학생의 강점을 객관적으로 뒷받침합니다.
    *   **향후 발전 가능성:** 학생이 보여준 뛰어난 역량과 태도를 근거로, 물리학 분야에서의 밝은 잠재력과 기대를 구체적으로 기술합니다.
3.  **문체 및 형식 (모드 공통):**
    *   **반드시 ‘~~임’, ‘~~함.’과 같은 명사형 종결을 사용합니다.**
    *   **교사의 객관적이고 전문적인 관찰 및 평가 관점에서 작성합니다.** 학생의 **뛰어난 역량과 구체적인 성과**를 명확하고 자신감 있는 문체로 기술합니다. (Normal, Bad, Nothing 프롬프트보다 더 강력하고 긍정적인 톤을 사용합니다.)
    *   학교생활기록부 형식에 맞는 전문적이고 간결하면서도 **학생의 우수성이 돋보이는** 문체를 사용합니다.
4.  **길이 (모드 공통):** 전체 내용을 **700글자 내외**로 완성합니다. (풍부한 내용을 담아야 하므로 분량 확보에 집중합니다.)
5.  **언어 (모드 공통):** 반드시 한글로 출력합니다.
6.  **결과물 (모드 공통):** 완성된 생활기록부 항목은 하나의 연속된 문단 형태로 제시합니다.

**★ 재작성 지침 (입력 데이터가 'srwrite_op'인 경우) ★**
입력된 'srwrite_op' 내의 '이전 생활기록부 작성 결과'를 검토합니다. 해당 결과가 본 프롬프트의 요구사항(내용 구성, 문체/형식, 길이, 중요 주의사항)을 얼마나 충족하지 못했는지 **스스로 판단**하고, 이전 작성 결과의 오류를 **수정하여** 새로운 생기부 항목을 작성하십시오. 재작성 시에도 본 프롬프트('write_prompt_good')의 모든 지침과 중요 주의사항을 철저히 따르며, 이전 작성 결과의 문제를 반복하지 않도록 집중합니다. '학생 활동 및 교사 평가 자료' 원문과 '핵심 요소 추출 결과'를 다시 활용하여 본 프롬프트가 요구하는 'good' 품질 수준의 결과물을 생성하는 데 집중합니다.

**★★ 중요 주의사항 (모드 공통) ★★**
*   **다음과 같은 '학생 스스로를 평가하는 듯한' 문구는 사용하지 마십시오.** (예시 동일)
*   **대신,** 교사의 관점에서 학생이 보여준 **뛰어난 행동, 심도 깊은 이해, 유의미한 성과, 차별화된 노력** 등을 객관적으로 묘사하고, 이를 통해 학생의 **뛰어난 역량과 잠재력**이 드러났음을 강조하는 방식으로 표현합니다. 학생의 **높은 수준의 잠재력과 향후 발전 가능성 또한 교사가 관찰한 구체적인 뛰어난 역량이나 성과를 근거로 객관적으로 기술**합니다.
*   이 프롬프트는 'good' 품질의 데이터를 위한 것이므로, **원문에 충분한 정보와 긍정적인 내용이 있다고 가정**합니다. 추출된 핵심 요소와 원문 내용을 적극적으로 활용하여 학생의 우수성을 효과적으로 기술하는 데 집중합니다.

**'학생 활동 및 교사 평가 자료' 원문의 풍부하고 구체적인 내용과, '핵심 요소 추출 결과' 로드맵을 모두 활용하여, 교사의 전문적이고 긍정적인 관점에서 학생의 뛰어난 역량, 구체적인 성과, 그리고 밝은 잠재력을 중심으로 생활기록부 문체에 맞게 작성해주세요. (재작성 시 이전 결과 오류 수정 반영)**
"""

write_prompt_normal = r"""당신은 [물리학I] 교사이며, 학생의 학교생활기록부 항목을 작성하는 전문가입니다. 이번에 작성할 학생의 활동 데이터 품질은 'normal' 수준입니다.

**입력 데이터:**
만약 입력 데이터가 'srwrite_op' 형태라면, 이는 이전 작성 결과에 대한 재검토 및 재작성 요청입니다. 'srwrite_op' 내에 다음 정보가 포함되어 있습니다: '학생 활동 및 교사 평가 자료' 원문, 이전 '생활기록부 작성 결과', 사용된 프롬프트 이름. 이 경우 **'학생 활동 및 교사 평가 자료' 원문**을 이번 작성에 사용하며, 이전 '생활기록부 작성 결과'는 참고용입니다.

만약 'srwrite_op' 형태가 아니라면, 첫 작성 요청이며 다음 한 가지 데이터가 입력됩니다:
1.  **"학생 활동 및 교사 평가 자료" 원문:** 학생의 활동에 대한 상세한 설명과 교사의 평가가 담긴 원본 자료입니다. 이 자료는 'normal' 품질 수준이며, 내용이 다소 피상적이거나 구체성이 부족할 수 있습니다.

**작성 목표:**
입력된 "학생 활동 및 교사 평가 자료" 원문의 내용을 바탕으로 [물리학I] 과목의 학교생활기록부 항목을 작성합니다. 원문 정보가 다소 부족할 수 있으나, 그 안에서 **학생의 노력의 흔적, 기본적인 이해 수준, 참여 태도** 등을 파악하여 긍정적으로 서술하려 노력합니다.

**작성 지침:**
1.  **작성 모드 판별:** 입력 데이터가 'srwrite_op' 형태인지 아닌지를 먼저 판별합니다.
2.  **내용 구성 (모드 공통):** 입력된 "학생 활동 및 교사 평가 자료" 원문에서 학생의 **활동 참여 사실, 노력한 부분, 기본적인 학습 내용 이해, 수업 태도** 등을 중심으로 내용을 구성합니다. 원문에 깊이 있는 내용이 부족하더라도, 관찰 가능한 긍정적인 면이나 노력의 흔적을 최대한 찾아 기술합니다.
3.  **문체 및 형식 (모드 공통):**
    *   **반드시 ‘~~임’, ‘~~함.’과 같은 명사형 종결을 사용합니다.**
    *   **교사의 객관적인 관찰 및 평가 관점에서 작성합니다.** 학생의 주관적인 감정이나 자기 평가를 직접 서술하지 않고, **교사가 관찰한 구체적인 행동, 참여 태도, 기본적인 성취 수준** 등을 기술합니다. 원문 내용이 부족할 경우, 교사의 일반적인 관찰 내용(예: 성실성, 노력하는 모습)에 기반하여 서술할 수 있습니다.
    *   학교생활기록부 형식에 맞는 전문적이고 간결한 문체를 사용합니다.
4.  **길이 (모드 공통):** 전체 내용을 **700글자 내외**로 완성합니다.
5.  **언어 (모드 공통):** 반드시 한글로 출력합니다.
6.  **결과물 (모드 공통):** 완성된 생활기록부 항목은 하나의 연속된 문단 형태로 제시합니다.

**★ 재작성 지침 (입력 데이터가 'srwrite_op'인 경우) ★**
입력된 'srwrite_op' 내의 '이전 생활기록부 작성 결과'를 검토합니다. 해당 결과가 본 프롬프트의 요구사항(내용 구성, 문체/형식, 길이, 중요 주의사항)을 얼마나 충족하지 못했는지 **스스로 판단**하고, 이전 작성 결과의 오류를 **수정하여** 새로운 생기부 항목을 작성하십시오. 재작성 시에도 본 프롬프트('write_prompt_normal')의 모든 지침과 중요 주의사항을 철저히 따르며, 이전 작성 결과의 문제를 반복하지 않도록 집중합니다. '학생 활동 및 교사 평가 자료' 원문을 다시 활용하여 본 프롬프트가 요구하는 'normal' 품질 수준의 결과물을 생성하는 데 집중합니다.

**★★ 중요 주의사항 (모드 공통) ★★**
*   **다음과 같은 '학생 스스로를 평가하는 듯한' 문구는 사용하지 마십시오.** 학교생활기록부는 교사의 객관적인 관찰 기록입니다. (예시 동일)
*   **대신,** 교사의 관점에서 학생의 **구체적인 행동, 노력, 관찰 가능한 기본적인 성과나 태도** 등을 객관적으로 묘사하는 방식으로 표현합니다. (예: ~ 활동에 참여함, ~에 대해 조사하는 노력을 보임, 수업 시간에 ~한 태도를 보임 등)
*   'normal' 품질의 데이터이므로, **원본에 없는 심도 깊은 내용이나 뛰어난 성과를 과장하여 작성하지 마십시오.** 원문에서 파악되는 수준 내에서 서술합니다.

**'학생 활동 및 교사 평가 자료' 원문만을 기반으로, 교사의 객관적인 관찰 및 평가 관점에서 학생의 참여와 노력의 흔적, 기본적인 학습 태도 등을 중심으로 생활기록부 문체에 맞게 작성해주세요. (재작성 시 이전 결과 오류 수정 반영)**
"""

write_prompt_bad = r"""당신은 [물리학I] 교사이며, 학생의 학교생활기록부 항목을 작성하는 전문가입니다. 이번에 작성할 학생의 활동 데이터 품질은 'bad' 수준입니다.

**입력 데이터:**
만약 입력 데이터가 'srwrite_op' 형태라면, 이는 이전 작성 결과에 대한 재검토 및 재작성 요청입니다. 'srwrite_op' 내에 다음 정보가 포함되어 있습니다: '학생 활동 및 교사 평가 자료' 원문, '물리학I 성취기준', 이전 '생활기록부 작성 결과', 사용된 프롬프트 이름. 이 경우 **'학생 활동 및 교사 평가 자료' 원문**과 **'물리학I 성취기준'**을 이번 작성에 사용하며, 이전 '생활기록부 작성 결과'는 참고용입니다.

만약 'srwrite_op' 형태가 아니라면, 첫 작성 요청이며 다음 두 가지 데이터가 입력됩니다:
1.  **"학생 활동 및 교사 평가 자료" 원문:** 학생의 활동에 대한 간략하고 부실한 설명이 담긴 원본 자료입니다. 이 자료는 'bad' 품질 수준이며, 내용이 극도로 짧거나 형식적인 기록일 가능성이 높습니다.
2.  **"물리학I 성취기준":** [물리학I] 과목에서 학생이 달성해야 하는 학습 목표 목록입니다.

**작성 목표:**
입력된 "학생 활동 및 교사 평가 자료" 원문에서 파악되는 **극히 적은 정보에, "물리학I 성취기준"을 주요 내용 구성의 기반**으로 삼아 [물리학I] 과목의 학교생활기록부 항목을 작성합니다. 원문 내용이 부족한 부분을 성취기준 관련 내용으로 채우되, 학생의 실제 활동 수준을 고려하여 **객관적이고 사실에 기반한 문체**로 서술합니다.

**작성 지침:**
1.  **작성 모드 판별:** 입력 데이터가 'srwrite_op' 형태인지 아닌지를 먼저 판별합니다.
2.  **내용 구성 (모드 공통):** 입력된 "학생 활동 및 교사 평가 자료" 원문에서 학생의 **활동 참여 '사실' 자체나 극히 일부 파악되는 내용**을 먼저 기술합니다. 이후 **"물리학I 성취기준" 목록을 참고**하여, 학생이 해당 학년/학기에 **이러이러한 성취기준과 관련된 학습 활동이나 수업에 참여했음**을 서술하는 방식으로 내용을 확장합니다.
    *   성취기준 내용을 직접 "학생이 ~을 달성함"이라고 쓰는 것을 엄격히 금지합니다.
    *   대신, **"~ 성취기준과 관련된 학습 내용을 탐색하는 과정을 거침", "~ 개념에 대해 학습하는 모습을 보임", "~ 현상의 사례를 조사하는 활동에 참여함"**과 같이 교사의 관점에서 관찰 가능한 '학습 과정 참여' 또는 '노력의 흔적' 위주로 기술합니다.
    *   원문이 제공하는 정보가 극히 적으므로, 성취기준 내용으로 상당 부분을 채워야 합니다.
3.  **문체 및 형식 (모드 공통):**
    *   **반드시 ‘~~임’, ‘~~함.’과 같은 명사형 종결을 사용합니다.**
    *   **교사의 객관적인 관찰 및 평가 관점에서 작성합니다.** 학생의 실제 성취 수준이 낮을 가능성이 높으므로, **과장되지 않게, 객관적인 사실(수업 참여, 최소한의 활동 시도 등)과 성취기준 관련 학습 과정 참여**를 중심으로 기술합니다.
    *   학교생활기록부 형식에 맞는 전문적이고 간결한 문체를 사용합니다.
4.  **길이 (모드 공통):** 전체 내용을 **700글자 내외**로 완성합니다. (원문이 짧으므로 성취기준 관련 내용으로 분량을 채워야 합니다.)
5.  **언어 (모드 공통):** 반드시 한글로 출력합니다.
6.  **결과물 (모드 공통):** 완성된 생활기록부 항목은 하나의 연속된 문단 형태로 제시합니다.

**★ 재작성 지침 (입력 데이터가 'srwrite_op'인 경우) ★**
입력된 'srwrite_op' 내의 '이전 생활기록부 작성 결과'를 검토합니다. 해당 결과가 본 프롬프트의 요구사항(내용 구성, 문체/형식, 길이, 중요 주의사항)을 얼마나 충족하지 못했는지 **스스로 판단**하고, 이전 작성 결과의 오류를 **수정하여** 새로운 생기부 항목을 작성하십시오. 재작성 시에도 본 프롬프트('write_prompt_bad')의 모든 지침과 중요 주의사항을 철저히 따르며, 이전 작성 결과의 문제를 반복하지 않도록 집중합니다. '학생 활동 및 교사 평가 자료' 원문과 '물리학I 성취기준'을 다시 활용하여 본 프롬프트가 요구하는 'bad' 품질 수준의 결과물을 생성하는 데 집중합니다.

**★★ 중요 주의사항 (모드 공통) ★★**
*   **다음과 같은 '학생 스스로를 평가하는 듯한' 문구는 사용하지 마십시오.** (예시 동일)
*   **성취기준 내용을 학생의 '달성 성과'로 직접 서술하는 것을 엄격히 금지합니다.** 반드시 **교사가 관찰한 '학습 과정 참여', '노력의 흔적', '관련 내용 학습 시도' 등 객관적인 관찰 가능한 사실**에 기반하여 기술합니다.
*   'bad' 품질의 데이터임을 인지하고, **학생의 실제 활동 내용이나 깊이에 대한 과장 없이** 성취기준과 관련된 일반적인 학습 과정 참여 위주로 내용을 구성합니다.

**'학생 활동 및 교사 평가 자료' 원문에서 파악되는 최소한의 정보에, "물리학I 성취기준"을 주요 내용 구성의 기반으로 삼아, 교사의 객관적인 관찰 관점에서 학생의 성취기준 관련 학습 과정 참여를 중심으로 생활기록부 문체에 맞게 작성해주세요. (재작성 시 이전 결과 오류 수정 반영)**
"""

write_prompt_nothing = r"""당신은 [물리학I] 교사이며, 학생의 학교생활기록부 항목을 작성하는 전문가입니다. 이번에 작성할 학생의 활동 데이터 품질은 'nothing' 수준입니다. 이는 학생이 해당 활동에 대한 기록을 전혀 제출하지 않았음을 의미합니다.

**입력 데이터:**
만약 입력 데이터가 'srwrite_op' 형태라면, 이는 이전 작성 결과에 대한 재검토 및 재작성 요청입니다. 'srwrite_op' 내에 다음 정보가 포함되어 있습니다: '물리학I 성취기준', 이전 '생활기록부 작성 결과', 사용된 프롬프트 이름. 이 경우 **'물리학I 성취기준'**을 이번 작성에 사용하며, 이전 '생활기록부 작성 결과'는 참고용입니다.

만약 'srwrite_op' 형태가 아니라면, 첫 작성 요청이며 다음 한 가지 데이터가 입력됩니다:
1.  **"물리학I 성취기준":** [물리학I] 과목에서 학생이 달성해야 하는 학습 목표 목록입니다.

**작성 목표:**
학생이 해당 활동에 대한 기록을 제출하지 않았으므로, "물리학I 성취기준" 목록을 주요 내용 구성의 기반으로 삼아 [물리학I] 과목의 학교생활기록부 항목을 작성합니다. 학생의 실제 활동 내용은 없지만, 해당 학년/학기에 **이러이러한 성취기준과 관련된 수업에 참여했음**을 객관적인 관점에서 간결하게 기술합니다.

**작성 지침:**
1.  **작성 모드 판별:** 입력 데이터가 'srwrite_op' 형태인지 아닌지를 먼저 판별합니다.
2.  **내용 구성 (모드 공통):** 입력된 "물리학I 성취기준" 목록을 참고하여, 학생이 해당 학기 동안 **"~ 성취기준과 관련된 학습 내용에 대해 배우거나 수업에 참여하는 모습을 보임"**과 같이 교사의 관점에서 관찰 가능한 일반적인 학습 과정 참여나 수업 태도를 중심으로 내용을 구성합니다.
    *   성취기준 내용을 학생의 '달성 성과'로 직접 서술하는 것은 엄격히 금지합니다.
    *   특정 활동에 대한 구체적인 언급은 할 수 없으므로, 과목의 전반적인 학습 과정 참여나 수업 태도(예: 수업 시간에 성실히 임함 등)를 일반적인 문장으로 기술합니다.
3.  **문체 및 형식 (모드 공통):**
    *   **반드시 ‘~~임’, ‘~~함.’과 같은 명사형 종결을 사용합니다.**
    *   **교사의 객관적인 관찰 및 평가 관점에서 작성합니다.** 학생의 실제 성취나 활동 내용이 없으므로, **과장 없이, 교사가 관찰한 일반적인 수업 참여나 학습 태도**를 중심으로 간결하게 기술합니다.
    *   학교생활기록부 형식에 맞는 전문적이고 간결한 문체를 사용합니다.
4.  **길이 (모드 공통):** 전체 내용을 **300글자 내외**로 완성합니다. (활동 내용이 없으므로 최소한의 내용으로 작성합니다.)
5.  **언어 (모드 공통):** 반드시 한글로 출력합니다.
6.  **결과물 (모드 공통):** 완성된 생활기록부 항목은 하나의 연속된 문단 형태로 제시합니다.

**★ 재작성 지침 (입력 데이터가 'srwrite_op'인 경우) ★**
입력된 'srwrite_op' 내의 '이전 생활기록부 작성 결과'를 검토합니다. 해당 결과가 본 프롬프트의 요구사항(내용 구성, 문체/형식, 길이, 중요 주의사항)을 얼마나 충족하지 못했는지 **스스로 판단**하고, 이전 작성 결과의 오류를 **수정하여** 새로운 생기부 항목을 작성하십시오. 재작성 시에도 본 프롬프트('write_prompt_nothing')의 모든 지침과 중요 주의사항을 철저히 따르며, 이전 작성 결과의 문제를 반복하지 않도록 집중합니다. '물리학I 성취기준'을 다시 활용하여 본 프롬프트가 요구하는 'nothing' 품질 수준의 결과물을 생성하는 데 집중합니다.

**★★ 중요 주의사항 (모드 공통) ★★**
*   **다음과 같은 '학생 스스로를 평가하는 듯한' 문구는 사용하지 마십시오.** (예시 동일)
*   **성취기준 내용을 학생의 '달성 성과'로 직접 서술하는 것을 엄격히 금지합니다.** 반드시 **교사가 관찰한 일반적인 수업 참여, 성실성 등 객관적인 관찰 가능한 사실**에 기반하여 기술합니다.
*   **학생이 활동 기록을 제출하지 않았다는 사실 자체를 부정적으로 언급하지 마십시오.** 그 대신 성취기준 관련 학습 과정 참여나 일반적인 수업 태도를 긍정적이지도 부정적이지도 않게 객관적으로 기술하여 내용을 채웁니다.

**"물리학I 성취기준" 목록만을 기반으로, 교사의 객관적인 관찰 관점에서 학생의 일반적인 수업 참여 및 성취기준 관련 학습 과정을 중심으로 300자 내외의 생활기록부 문체에 맞게 간결하게 작성해주세요. (재작성 시 이전 결과 오류 수정 반영)**
"""

core_prompt = r"""당신은 학생의 학교생활 기록을 분석하는 전문가입니다. 입력된 "학생 활동 및 교사 평가 자료" 원문에서 다음 **8가지 핵심 요소를 정확하게 추출**하여 목록화해주세요. 추출 시 원문의 내용을 가공하거나 요약하지 말고, 해당 요소에 해당하는 **구체적인 내용만을 찾아내세요.**
**추출할 핵심 요소:**
1.  **핵심 활동:** 학생이 참여하거나 수행한 주요 프로젝트, 실험, 발표, 연구, 과제 등 구체적인 활동 내용
2.  **깨달은 점:** 활동을 통해 학생이 새롭게 배우거나 느낀 점, 얻은 통찰, 이전과 달라진 인식 등
3.  **드러난 행동:** 활동 과정에서 관찰된 학생의 구체적인 행위, 태도, 접근 방식, 문제 해결 시도 등 (예: 적극적으로 질문함, 꾸준히 자료를 탐색함, 친구의 어려움을 도움)
4.  **주도적인 내용:** 학생 스스로 계획하고 실행하거나, 남들이 생각지 못한 아이디어를 내거나, 문제를 해결하기 위해 적극적으로 나선 부분, 리더십을 발휘한 사례 등
5.  **도출한 결론:** 활동이나 탐구의 결과로 얻게 된 결론, 발견 사실, 분석 결과 등 객관적인 성과나 지식
6.  **공동체 요소:** 팀 활동에서의 협력, 다른 학생과의 소통 방식, 그룹 목표 달성을 위한 기여, 나눔이나 배려 등 공동체 속에서의 역할이나 상호작용
7.  **교사 관찰 및 평가:** 학생의 학습 과정, 태도, 역량에 대한 교사의 구체적인 관찰 내용, 평가, 피드백 등 원문에 명시된 교사의 의견 (예: 수업 참여도 높음, 개념 이해가 빠름, 어려운 문제에 대해 질문하는 것을 즐김)
8.  **향후 발전 가능성 및 기대:** 학생의 현재 모습(역량, 태도 등)을 바탕으로 원문에서 언급되거나 유추되는 앞으로의 성장 가능성, 특정 분야에서의 기대, 진로와의 연관성 등
**출력 형식:**
*   각 핵심 요소별로 명확한 제목을 붙여 구분합니다.
*   해당 요소에서 추출된 내용을 간결한 문장 또는 구문으로 목록화합니다. (예: `- 실험 과정에서 발생한 변수를 통제하는 방법의 중요성 깨달음.`)
*   만약 원문에 특정 요소에 해당하는 내용이 없다면, 해당 요소 제목 아래에 "해당 내용 없음"이라고 표시하거나 해당 요소 항목 자체를 생략합니다. (생략하는 것이 더 간결할 수 있습니다.)
*   반드시 한글로 출력합니다.
"""

 

class Discriminator(dspy.Signature):
    instruction = dspy.InputField(desc="입력데이터의 품질을 어떻게 판별해야 하는지에 대한 설명입니다.")
    input_data = dspy.InputField(desc="생활기록부 작성이 필요한 실제 데이터입니다.")
    quality: Literal['good', 'normal', 'bad', 'nothing'] = dspy.OutputField(desc="반드시 넷 중 하나를 선택하여 출력합니다")

class Core_Summarizer(dspy.Signature):
    instruction = dspy.InputField(desc="핵심 요약 추출을 어떻게 해야 하는지에 대한 설명입니다.")
    activity = dspy.InputField(desc="1년동안 물리학I 활동 내용에 대한 소개로 학생 활동, 평가 등에 대한 정보입니다.")
    input_data = dspy.InputField(desc="생활기록부 작성이 필요한 실제 데이터입니다.")
    core_summary = dspy.OutputField(desc="핵심 요약 추출문 입니다.")

class SR_Writer(dspy.Signature):
    instruction = dspy.InputField(desc="생활기록부 작성, 지침과 작업에 대한 설명입니다.")
    input_data = dspy.InputField(desc="생활기록부 작성이 필요한 실제 데이터입니다.")
    activity = dspy.InputField(desc="1년동안 물리학I 활동 내용에 대한 소개로 학생 활동, 평가 등에 대한 정보입니다.")
    context = dspy.InputField(desc="good은 핵심 요소 추출, normal은 없음, bad와 nothing은 성취기준이 입력됩니다.")
    one_shot = dspy.InputField(desc="생활기록부 예시(one shot) 입니다. 반드시! 예시의 형식을 준수하여 작성하세요!")
    eval_feedback = dspy.InputField(desc="작성한 생활기록부에 대한 평가자(evaluator)의 피드백입니다. 다시 작성하는데 참고하세요")
    student_record = dspy.OutputField(desc="생활기록부입니다. 반드시!! 한글로 출력하세요.")

class Evaluator(dspy.Signature):
    instruction = dspy.InputField(desc="생활기록부 작성 프로세스를 어떻게 평가하지는지에 대한 설명입니다.")
    quality = dspy.InputField(desc="생활기록부 퀄리티로 good, normal, bad, nothing 중 하나입니다")
    input_data = dspy.InputField(desc="생활기록부 작성이 필요한 실제 데이터입니다.")
    generated_output = dspy.InputField(desc="작성된 생활기록부 입니다")

    srwrite_op = dspy.OutputField(desc="작성자에 대한 피드백입니다. 반드시!! 한글로 출력하세요!!")
    rewrite_op: Literal['return_Yes', 'return_No'] = dspy.OutputField(desc="생활기록부 재작성과 관련된 의견입니다. 반드시 둘 중 하나로 선택하여 출력합니다.")    

class MySR_Agent(dspy.Module):
    def __init__(self):
        super().__init__()

        self.discriminator = dspy.ChainOfThought(Discriminator)
        self.summarizer = dspy.ChainOfThought(Core_Summarizer)
        self.writer = dspy.ChainOfThought(SR_Writer)
        self.evaluator = dspy.ChainOfThought(Evaluator)

    def forward(self, input_data):
        eval_feedback = "없음"
        for i in range(3):
            print(f"{i} 번째 생활기록부 작성입니다")
            discrim = self.discriminator(instruction=discriminator_prompt, input_data=input_data).quality
            print("생기부 퀄리티는 ", discrim, "입니다.")
            if discrim == 'good':
                context = self.summarizer(instruction=core_prompt, activity=my_activity, input_data=input_data).core_summary
                instruction = write_prompt_good
                sr_output = self.writer(instruction=instruction, input_data=input_data, activity=my_activity, 
                                        context=context, one_shot=one_shot, eval_feedback=eval_feedback).student_record
            elif discrim == 'normal':
                context = "없음"
                instruction = write_prompt_normal
                sr_output = self.writer(instruction=instruction, input_data=input_data, activity=my_activity, 
                                        context=context, one_shot=one_shot, eval_feedback=eval_feedback).student_record
            elif discrim == 'bad':
                context = archievement
                instruction = write_prompt_bad
                sr_output = self.writer(instruction=instruction, input_data=input_data, activity=my_activity, 
                                        context=context, one_shot=one_shot, eval_feedback=eval_feedback).student_record
            elif discrim == 'nothing':
                context = archievement
                instruction = write_prompt_nothing
                sr_output = self.writer(instruction=instruction, input_data=input_data, activity="없음", 
                                        context=context, one_shot=one_shot, eval_feedback=eval_feedback).student_record
        
            eval_output = self.evaluator(instruction=evaluator_prompt, quality=discrim, input_data=input_data, generated_output=sr_output)
            eval_feedback = eval_output.srwrite_op

            if eval_output.rewrite_op == 'return_Yes':
                print(f"재작성이 필요하므로 {i}번째 생기부는 재작성에 들어갑니다.")
            elif eval_output.rewrite_op == 'return_No':
                print(f"{i}번째 생기부는 평가를 통과하였으므로 종료합니다.")
                break

        return sr_output, eval_feedback
result = MySR_Agent()
output, feedback = result(input_data1)
print("생활기록부 출력")
print(output)
print("-------------------------------------------")
print("생활기록부 피드백")
print(feedback)

 

<출력결과>

0 번째 생활기록부 작성입니다
생기부 퀄리티는  good 입니다.
0번째 생기부는 평가를 통과하였으므로 종료합니다.
생활기록부 출력
본 학생은 물리학I 수업에서 뛰어난 학업 성취도와 탐구 역량을 보여주었습니다.  광전 효과 문제 재구성 활동에서, 학생은 빛의 파장과 금속의 일함수를 이용하여 광전자의 최대 운동 에너지를 구하는 기존 문제를 스스로 재구성하여, 정지 전압과 문턱 진동수를 이용해 입사광의 파장을 구하는 새로운 문제를 만들고 해결하였습니다. 이는 단순한 문제 풀이를 넘어, 광전 효과의 핵심 개념에 대한 심도 있는 이해와 문제 해결 능력, 그리고 창의적인 문제 해결 접근 방식을 보여주는 사례입니다.  학생은 각 물리량의 유기적인 관계를 명확히 이해하고 있으며,  문제 해결 과정을 논리적으로 정리하고 제시하는 능력 또한 탁월합니다.  더 나아가,  학생은 광전 효과와 빛의 세기 관계, 다양한 금속의 일함수 비교 등 추가적인 탐구 계획을 제시하며, 끊임없는 학습 의지를 보여주었습니다.

심화 탐구 활동에서는 '인덕션 히터의 작동 원리와 효율성에 대한 물리적 탐구'라는 주제를 스스로 선정하여, 전자기 유도, 와전류, 줄 발열 등의 물리적 원리를 바탕으로 인덕션 히터의 작동 원리를 심층적으로 분석하였습니다.  다양한 학술 자료와 기술 자료를 참고하여 자료를 꼼꼼하게 분석하였으며,  자신의 탐구 결과를 논리적이고 체계적으로 정리하여 제시하였습니다.  인덕션 히터의 높은 에너지 효율을 설명하는 과정에서,  학생은 표피 효과와 같은 심화된 물리 개념에 대한 이해를 보여주었으며,  물리학적 원리가 실생활에 적용되는 사례를 탐구하는 능력을 훌륭하게 발휘하였습니다.  탐구 과정에서 드러난  학생의 뛰어난 분석력과 문제 해결 능력은 물리학 분야에서의 밝은 잠재력을 보여줍니다.

수업 시간에 적극적인 참여와 질문을 통해 이해를 명확히 하려는 학생의 자세는 그의 학습 태도를 잘 보여줍니다.  학생은 끊임없이 질문하고 탐구하며,  물리 개념에 대한 심도 있는 이해를 추구하는 모습을 보였습니다.  이러한 적극적인 자세와 뛰어난 탐구 능력은 향후 물리학 분야에서의 심화된 학습과 연구 활동에 대한 기대를 갖게 합니다.  학생의 뛰어난 분석력, 문제 해결 능력, 그리고 끊임없는 학습 의지는 물리학 분야에서의 탁월한 성취를 예고합니다.
-------------------------------------------
생활기록부 피드백
학생의 물리 과목에 대한 이해도와 탐구 역량을 잘 드러내는 훌륭한 생활기록부입니다.  광전 효과 문제 재구성과 인덕션 히터 탐구 활동에 대한 설명이 구체적이고, 학생의 분석력과 문제 해결 능력을 잘 보여줍니다.  'good' 품질에 부합하는 높은 수준의 내용을 담고 있으며, 문체 또한 자연스럽고 적절합니다.  다만,  입력 데이터에 포함된 학생의 수치 점수(86, 75, 72, 85)를 생활기록부에 반영하지 않은 점은 아쉽습니다.  또한, 교사 관찰 내용("수업 참여도 적극적이며, 질문을 통해 이해를 명확히 하려는 자세가 돋보임")을 좀 더 자연스럽게 본문에 녹여내면 좋겠습니다.  예를 들어,  "적극적인 수업 참여와 끊임없는 질문을 통해 이해를 깊이 있게 추구하는 모습은 그의 탐구 활동에서도 잘 드러납니다." 와 같이 연결하면 자연스러울 것입니다.  전반적으로는 매우 잘 작성되었지만,  위에서 언급한 두 가지 사항을 보완하면 더욱 완성도 높은 생활기록부가 될 것입니다.