백엔드 엔지니어가 Prompt Enginnering으로 LLM Application을 구축한 여정
이야기의 시작과 no-code 툴을 활용한 앞단 작업의 단순화
땅우수학은 수능 준비하는 학생들을 위한 온라인 학원입니다. 온라인 학원이기 때문에 자기주도적으로 학습을 해야하고, 학습한 내용을 업로드해야 합니다. 제가 처음 해야했던 일은 회원 등급에 따라 권한을 부여하여 강의를 보고, 숙제를 제출하고, 숙제 제출 승인이 나는 Learning Management System을 구축해야 하는 일이었습니다. 백엔드 위주로 개발을 해왔기 때문에 프론트를 어떻게 구현할지 알아보다가, no-code 툴인 bubble.io를 알게됩니다. 그리고 대단한 트래픽을 받거나 화려한 UI/UX가 들어갈 것이 아니기 때문에 차라리 이것으로 개발하는 것이 더 적합하겠다는 결론을 내렸습니다. 그리고 Bubble을 학습하려던 차에 Bubble을 기존부터 잘 하시던 분에게 이 작업을 일임하고, 뒷단에서 제출된 숙제를 검사하는 flow에만 집중하게 됩니다.
목표 설정
땅우수학의 ‘숙제’는 단순히 문제를 풀어오는 것이 아닙니다. 우리 모두 ‘남을 가르친다는 생각으로 공부를 해라’라는 말을 들어봤을 것이라고 생각합니다. 땅우수학에서는 학생들에게 남에게 설명한다고 생각하고 영상을 찍어오는 것을 숙제로 내줍니다. 지금까지는 이 숙제를 사람이 하나하나 확인했습니다. 하지만 AI를 이용한 유튜브 요약 기술이 발전하는 시점에서 이를 AI를 활용해 자동화할 수 있겠다고 판단했습니다. 이를 통해 더 많은 가치를 창출해낼 수 있겠다는 생각도 들었습니다. 예를 들어 수학이라는 과목 특성상 앞에서 기초를 탄탄히 하지 않으면 뒤에서 이해하지 못하는 상황이 발생합니다. 이 숙제를 할 때 단순히 했냐 안 했냐를 판단하는 것이 아니라, AI가 학생들이 얼마나 이해하고 있는지를 측정하고 개별적인 피드백을 줄 수 있다면 좋겠다고 생각했습니다. 또한 장기적으로는 이를 바탕으로 선생님들에게도 피드백을 줄 수 있을 것이라 판단했습니다. 모든 학생이 전반적으로 설명하지 못하는 개념이 있다면, 향후 강의에서 그 개념에 대한 설명을 더 자세히 다루도록 피드백을 제공할 수 있을 것입니다.
너의 input을 알라
처음 계획은 교과서나 이상적인 설명과의 유사도를 측정하여 숙제의 정확도를 평가하는 것이었습니다. 하지만 이 one-shot 방식은 기대만큼 효과적이지 않았습니다. 가장 큰 원인은 input 설정을 잘못 이해한 데 있었습니다. 학생들의 설명은 대본에 기반한 유려한 설명이 아니라, 더듬거나 반복하는 등의 특징을 가진 지극히 자연어에 가까운 형태였습니다. 특히 땅우수학은 3등급 이하의 학생들을 받아 성적을 끌어올리는 데 집중하는 학원이기 때문에, 이들의 설명은 흔히 ‘최상위권 학생’들의 설명과도 거리가 있었습니다. 이러한 학생들의 설명을 교과서와 단순히 비교하려 하다 보니, 성실하다고 평가되던 학생들의 숙제조차 LLM이 기준 미달로 평가하는 문제가 발생했습니다.
이를 해결하기 위해 피드백을 단계적으로 생성하도록 프롬프트를 재작성했습니다. 먼저, 숙제별로 반드시 포함되어야 하는 개념 keyword를 사전에 정의한 뒤, 제출된 숙제에 이 keyword들이 포함되어 있는지를 true/false로 판단하도록 설계했습니다. 이후 이 true/false 데이터를 기반으로 학생들에게 적절한 피드백을 생성하도록 하여, 보다 공정하고 유의미한 평가를 제공할 수 있도록 개선했습니다.
reasoning과 reasoning의 근거
이 작업을 하면서 다양한 LLM 관련 아티클과 발표를 참고했는데, 특히 컬리 테크 블로그의 LLM Application 구축 도전기 (feat. 소중한 고객님들의 리뷰) - 1부가 큰 도움이 되었습니다. 처음에는 true/false로 구분하는 아이디어까지만 생각했지만, 그 이유를 설명하도록 프롬프트를 작성해 LLM이 판단한 결과를 다시 평가하는 방법에서 중요한 힌트를 얻었습니다. 이를 통해 보다 정확한 판단과 피드백을 생성할 수 있었으며, 이 단계에서 완성된 LLM output은 다음과 같습니다.
항목 | 포함여부 | 설명내용 |
---|---|---|
이산확률분포 | true | 자료를 분석하는 것과 관련하여 전체 확률을 더하면 1이 나온다고 설명했어. |
평균 | true | 평균을 구하는 과정과 곱해진 것을 더한 후 전체를 나누는 방식으로 평균을 설명했어. |
분산 | true | 분산 관련하여 상수를 곱했을 때 평균과의 관계를 설명했지만, 일부 원리에서 혼란스러운 부분이 있었어. |
확률분포의 성질 | false | 확률분포의 성질에 대한 설명은 포함되어 있지 않았어. |
이항분포 | true | 이항분포의 조건인 독립 시행과 성공 횟수, 성공 확률 등을 언급했어. |
이항분포의 성질 | true | 이항분포의 평균과 분산이 각각 np와 n(1-p)로 구해진다고 설명했어. |
이 표를 보면, 학생은 이산확률분포, 평균, 분산, 이항분포 및 이항분포의 성질에 관해서 잘 설명했어.
특히, 평균을 구하는 방법과 이항분포의 특성을 언급한 부분이 좋았고 확률분포의 성질에 대한 부분에서는 조금 아쉬움이 남아.
다음에는 확률분포의 성질에 대해서도 잘 설명해보면 좋겠어.
확률분포의 성질은 확률분포를 이해하는 데 중요한 기본이니까 꼭 다뤄보도록 해!
항상 수학 열심히 하고 있다는 게 느껴져서 기분이 좋아.
다음에도 좋은 내용 많이 기대할게!
이 상태에서 여러 input을 넣어가며 다시 테스트를 진행하던 중, 흥미로운 점을 발견했습니다. 동일한 input임에도 불구하고 사용한 LLM 모델에 따라 keyword 포함 여부에 대한 판단이 달라졌으며, 심지어 이 결과는 모델별로 재현 가능했습니다. 피드백의 일관성은 학원업에서 매우 중요한 요소입니다. 이러한 문제를 해결하기 위해 각 keyword가 포함되었는지를 판단하는 기준, 즉 reasoning의 기준을 LLM 모델에게 맡기지 않고, 이 기준까지 명확히 프롬프트로 제공하기로 결정했습니다. 이를 통해 피드백의 일관성을 높이고 신뢰성을 확보할 수 있었습니다.
LLM으로 강의 요약해서 reasoning의 근거 제공하기
처음에는 reasoning의 기준으로 기존 수학 교과서의 내용을 그대로 사용하는 방법을 고려했습니다. 그러나 곧 이 방법이 효과적이지 않다는 것을 깨닫고, 대신 강의 내용을 요약하여 reasoning의 근거를 작성하는 데 활용하기로 했습니다. 이를 위해 강의 내용을 음성 인식한 텍스트를 map-reduce 방식으로 요약하는 방법을 채택했습니다. 첫 input과 최종 output은 한글로 이루어지지만, 중간 산출물이 영어로 생성되더라도 문제가 없다고 판단하여 언어를 별도로 지정하지 않았습니다. 실제 결과물을 보면 영어(한국어)와 같은 형식으로 생성되는 것을 확인할 수 있었습니다. 최종 output을 생성하기 위해 사용한 프롬프트의 예시는 다음과 같습니다.
This is a lecture of a Korean high school math class regarding "순열과 조합".
I want to create a "handout" for students.
Write a summary of the following in Korean.
SUMMARIZE contents that ONLY regarding "순열과 조합". we don't need details about how to taking this class and how to study.
DO NOT USE English term
DO NOT USE content from external resources. Only summarize the content of the input.
Organize the summary in an outline format:
1. Keyword: description
2. Keyword: description
3. Continue this structure as needed.
SUMMARY as detailed as possible:
"{text}"
CONCISE SUMMARY:
기본적으로 프롬프트는 영어로 작성하되, keyword들은 한글로 입력했습니다. 강조해야 하는 부분은 대문자를 사용하거나 quotation mark로 표시했습니다. 프롬프트는 강의 내용만 요약하는 것을 목적으로 설계되었으며, 외부 검색 내용을 포함하지 않도록 했습니다. 또한, 강의 내용 중 영단어가 포함된 경우가 많아 이를 제외하도록 설정했습니다. 인터넷 강의의 특성상 해당 단원의 학습 내용 외에도 수업의 전반적인 분위기나 수험생활에 대한 조언 등이 포함되는 경우가 많은데, 이러한 내용은 요약에서 제외하도록 했습니다. 최종적으로 생성된 결과물을 그대로 사용하는 것이 아니라, 실제 강사가 생성된 요약본을 검토한 뒤 채점 기준을 결정했습니다. 이 기준은 예를 들어 ‘A에 대한 내용이 B라고 설명되었는가’와 같은 형태로 정리하여 활용했습니다.
일반적으로 소프트웨어 엔지니어라고 해서 AI나 LLM에 대한 경력이 있는 것은 아니지만, 소프트웨어 개발을 할 때 많이 하던 배경 지식 및 테크 블로그 탐색, 그리고 가설을 세우고 검증해가며 개선하는 절차를 통해 동작하는 LLM Application을 만들 수 있는 것 같습니다. 혹시 만들고 싶은게 있는데 가능할까 싶은 분들이 있다면 일단 시도해보시길 추천해드립니다!