인간의 게이트 뒤에 숨겨진 AI 제작 아동 콘텐츠: 그림책, 스토리 과제 및 연습표 (Plain PHP로 구현)
요약
본 글은 AI로 제작한 아동 학습 콘텐츠(그림책, 스토리 과제, 연습표)를 어떻게 안전하게 구현했는지 설명합니다. LLM 사용의 어려움보다 '큐레이션'과 '안전성'이 중요하며, 모든 콘텐츠는 사전에 사람이 검토하고 승인된 형태로 제공됩니다.
핵심 포인트
- AI 제작 아동 콘텐츠도 가능하지만, 안전한 큐레이션이 핵심입니다.
- 모든 콘텐츠는 PHP와 MariaDB로 구현되어 외부 API 연결 없이 작동합니다.
- 아이들이 자유롭게 입력하는 것을 막고, 사전에 승인된 형태로만 제공됩니다.

LLM을 사용하여 아동 학습 콘텐츠를 제작할 때, 모델 자체는 쉬운 부분입니다. 어려운 부분은 그 주변의 모든 것들입니다: 누가 그 결과물을 볼 수 있는지, 어떻게 실수를 잡아낼지, 그리고 무엇을 가르치지 않을지 결정하는 것입니다. 여기서는 저희가 아동들을 위한 큐레이션되고 광고 없는 검색 엔진인 kids.findnix.eu에 추가한 세 가지 요소—AI 제작 그림책, 9세에서 14세를 위한 '스토리 과제', 그리고 연습표—에 대한 글을 작성합니다. 이 모든 것은 프레임워크나 계정 없이 순수한 PHP와 MariaDB로만 구성되어 있습니다.
나머지 모든 것이 따르는 규칙
아이들은 AI에 직접 타이핑하지 않습니다. 아이가 페이지를 보고 있는 동안 아무것도 생성되지 않습니다. 모든 텍스트와 모든 이미지는 사전에 제작되고, 사람이 검토한 후에야 게시됩니다. 채팅 상자도 없고, 'AI에게 질문하기' 기능도 없으며, 아이가 답변 필드에 입력하는 내용은 절대로 브라우저를 벗어나지 않습니다.
저희는 사이트의 (독일어) 위키에 그 이유들을 문서화했습니다: 모델은 자신 있게 틀릴 수 있고, 자유 형식 질문에 대한 모든 답을 필터링할 수 없으며, 자유 텍스트 상자는 아이들이 자신의 이름이나 학교나 걱정거리를 제3자 API에 입력하도록 유도합니다. 사전에 생성되고 승인된 콘텐츠는 이 세 가지 위험을 모두 회피합니다. Kinder KI 주제 카드 역시 같은 방식으로 작동합니다.
요소 1: 번역 연습이 포함된 그림책

각 책은 표지와 6세에서 9세 아동을 대상으로 용기, 우정, 감정, 학급에 새로 오기, 취침 시간과 같은 주제를 다루는 두세 문장으로 구성된 여덟 페이지로 되어 있습니다. 이 내용은 독일어로 작성됩니다. 각 페이지 아래에는 아이가 텍스트를 영어로 번역해 보고 '솔루션 보기(show solution)' 버튼을 클릭할 수 있으며, 이때의 영어 텍스트는 오직 정답지로서만 존재합니다. 인쇄용으로 쓰기 줄과 솔루션 페이지가 포함된 PDF 파일이 생성됩니다.
생성 파이프라인은 의도적으로 지루합니다:
- LLM이 엄격한 JSON을 반환합니다: 제목, 개요(blurb), 여덟 페이지, 팁, 학부모를 위한 메모, 영어 번역 및 캐릭터 시트. 잘못되거나 불완전한 JSON은 최대 세 번까지 재시도됩니다.
- 두 번째 패스에서 최종 독일어 텍스트를 기반으로 페이지당 하나의 이미지 프롬프트를 도출합니다. 모델이 이야기와 함께 프롬프트를 작성했을 때, 이들은 가끔 한 페이지씩 밀리거나 텍스트가 수정되는 순간 구식이 되었습니다.
- 이미지 모델은 여섯 가지 스타일 프리셋(플랫, 수채화, 색연필, 종이 콜라주, 구아시, 파스텔 초크) 중 하나로 페이지를 그려서 책들이 모두 똑같이 보이지 않게 합니다.
- 사람이 모든 텍스트를 읽고 모든 그림을 해당 페이지와 대조하여 확인합니다. 잘못된 부분이 있으면 재생성됩니다.
- 관리자만 게시할 수 있습니다. PDF는 작고 의존성이 없는 PHP 작성기(약 180줄: A5 페이지, 핵심 Helvetica, 내장 JPEG, 텍스트 선택 가능)에 의해 구축됩니다.
실제 검토 루프가 잡아낸 것들:
모든 장면에 전체 출연진을 보여주는 그림, '내용 없음' 지침에도 불구하고 삽화에 그려진
스토리 과제(story task)는 짧은 이야기와 첫 번째부터 세 번째까지 난이도가 높아지는 정확히 세 가지 과제로 구성되어 있으며, 아이가 직접 풀이를 적을 수 있는 필드와 정답 및 풀이 과정을 보여주는 '풀이 보기' 버튼이 있습니다. 이 과제는 수학, 물리 및 IT, 화학, 생물학, 지리, 역사, 독일어의 일곱 개 주제를 다루며 9세부터 14세까지 다섯 가지 레벨로 구성되어 있습니다. 특히 수학 트랙은 돈과 시간 문제에서 시작하여 비례식(rule of three), 백분율, 간단한 방정식으로 난이도가 올라갑니다.
LLM은 산술 계산을 틀리곤 하며, 오답 정답지는 학습 제품에서 최악의 실패 사례입니다. 따라서 모든 수치 과제는 서술형 답 옆에 기계가 읽을 수 있는 표현(machine-readable expression)을 포함하고, 서버가 이를 재계산합니다:
// calc는 "(12*4)+8"와 같은 단순 산술 표현식입니다. result는 모델이 주장하는 숫자입니다.
$v = kids_task_calc($task['calc']); // 작은 shunting-yard 평가기, eval() 사용 안 함
if (abs($v - $task['result']) > 1e-6 * max(1, abs($v))) $warn[] = 'result mismatch';
...
만약 이 확인 과정이 실패하면 초안은 폐기되고 최대 세 번까지 재생성됩니다. 이는 여전히 사람이 각 과제를 직접 재계산하는 것을 대체하지는 못하지만, 사람이 보기 전에 대부분의 실수를 잡아냅니다.
프로젝트 전체에서 가장 재미있는 버그가 발생했습니다: 지리, 화학, 생물학, 역사에 대한 첫 번째 배치 자료가 코스튬을 입은 수학 단어 문제로 돌아왔습니다. 한 역사 과제는 아이에게 2026에서 1450을 빼도록 요구했습니다. 이것이 '역사 과제'를 의미하는 것은 아닙니다. 현재는 오직 수학 트랙만 계산을 수행하며, 다른 주제들은 매칭(matching), 순서 배열(ordering), 설명 및 지도 읽기(explaining and reading maps)를 사용합니다. 사양을 글자 그대로 따르면서도 그 핵심을 놓치는 것은 인간만이 할 수 있는 재능이 아닙니다.
파트 3: 연습표
각 과목별로 학습 모드(모든 내용 표시)와 연습 모드(한 열을 숨기고 아동이 답을 입력하고 확인하는 방식)를 갖춘 참고표가 있습니다. 현재 15가지 기능이 활성화되어 있습니다: 모든 UN 회원국 193개국의 수도 및 국기 정보(‘국기 맞히기’ 모드 포함), 118개 원소 전체를 다루는 주기율표, 수학 및 물리 공식 모음, 단위 변환기, 주요 날짜 타임라인, 그리고 품사, 격, 관사, 시제, 문장 성분별 독일어 문법표, 여기에 몇 가지 생물학 표가 더 있습니다.
표는 행마다 한 줄씩의 일반 텍스트로 저장됩니다:
Europe | Germany | Berlin | 1 | de
Geometry | Area of a rectangle | A = a · b ## a*b ## ab | 1
## 부분에는 정답으로 간주되지만 표시되지 않는 철자가 포함되어 있습니다. 흥미로운 문제는 입력된 답이 언제 정확한지 결정하는 것입니다. 이름은 완화적으로 비교됩니다(대소문자, 움라우트 및 악센트는 무시되며, 여러 개가 있는 국가의 모든 수도도 마찬가지입니다). 공식은 반대의 처리가 필요합니다. 초기 버전에서는 비교하기 전에 문자와 숫자만 남기고 모든 것을 제거했는데, 이로 인해 a+b가 직사각형 넓이에 대한 정답이 되었습니다. 이제 공식 열은 자체 정규화기(normalizer)를 사용하며, 연산자와 괄호는 계산되고 곱셈, 거듭제곱 및 그리스 문자의 철자만 유연합니다:
function normF(s) {
s = String(s).toLowerCase().replace(/\s+/g, '');
s = s.replace(/²/g, '^2').replace(/π/g, 'pi');
...
}
주기율표에는 색상별 개요도 있습니다: 고전적인 레이아웃의 118개 버튼으로 구성된 CSS 그리드, 다른 모든 것을 어둡게 표시하는 범례가 있는 10개의 원소 그룹, 그리고 셀을 탭할 때까지 기호나 이름이 숨겨지는 자체 테스트 모드가 있습니다. 국기는 MIT 라이선스의 flag-icons 프로젝트에서 가져온 자가 호스팅 SVG 파일입니다. 이모지 국기가 첫 번째 아이디어였지만, Windows에서는 이를 두 개의 문자로 표시합니다. PDF 작성기는 JPEG만 지원하고 서버에 있는 변환기들이 여러 국기를 잘못 그렸기 때문에, 인쇄 가능한 시트에는 오류를 발생시키기보다는 국기 정보를 생략했습니다.
솔직한 한계점: 깃발들은 장식용 이미지이므로, 스크린 리더를 사용해서는 "깃발 맞히기" 모드를 사용할 수 없습니다. 일반 텍스트 모드는 가능합니다.
의도적으로 제외한 부분과 그 이유
전쟁, 전쟁 지역, 성교육, 그리고 무기, 폭발물, 독극물 또는 마약으로 오용될 수 있는 생물학적 또는 화학적 과정에 대한 설명은 없습니다. 역사 타임라인에는 발명품, 발견, 전환점들이 포함되어 있으며; 지리에서는 평화로운 목적지와 자연을 다룹니다. 국가표는 주와 수도를 나열할 뿐 분쟁에 대해서는 아무것도 언급하지 않습니다.
이유는 이념적이라기보다는 실용적입니다. 혼자서 책을 읽는 아이가 무서운 것이 있을 때 누구에게 물어볼 수 없고, 세 문장짜리 과제가 전쟁을 중립적으로 또는 필요한 맥락과 함께 다룰 수 없습니다. 성교육은 부모님과 먼저, 그리고 학교에서 이루어져야 하며, 이때 시기, 어휘, 개별 아동의 성숙도를 고려할 수 있습니다. 또한 위험 물질에 대한 레시피처럼 보이는 것은 법적 및 안전상의 위험이므로, 화학은 소금, 설탕, 물, 모래로만 제한되며 전기 실험은 배터리만을 사용합니다.
강화(Enforcement)는 세 가지 계층으로 이루어져 있습니다. 규칙들은 모든 LLM 프롬프트에 포함됩니다. 단어 필터가 전쟁, 무기 및 위험 물질, 성교육 관련 용어를 모든 텍스트에서 스캔하며, 적중이 발생하면 초안은 폐기되거나 플래그가 지정됩니다. 게시 버튼은 필터에 적중이 있을 경우 게재를 거부합니다. 그리고 사람이 라이브로 나가기 전에 모든 것을 읽습니다. 이 필터는 의미가 아닌 단어를 일치시키며, 의도적으로 엄격합니다: 예전에 사용된 단어 목록 중 하나는 'nude'라는 단어를 포함한다는 이유로 독일어 국수라는 단어를 플래그 지정한 적이 있습니다. 우리는 적중을 허용하기보다는 무해한 문장을 재구성하는 것을 선호할 것입니다.
현황
2026년 10월 11일 기준으로, 그림책은 총 33권이 존재하며 그중 13권이 출판되었고; 일곱 가지 주제에 걸쳐 이야기 과제는 36개가 활성화되어 있으며; 연습표는 15개입니다. 위키에서는 독일어로 다음과 같은 결정 사항들을 문서화하고 있습니다: 그림책, 이야기 과제 (제외된 내용에 대한 섹션 포함), 그리고 연습표.
만약 얻을 수 있는 교훈이 있다면: 모델에게 초안 작성을 맡기고, 서버가 기계적으로 확인할 수 있는 부분을 검사하게 하며, 출력물과 아동 사이에 사람을 두는 것입니다. kids.findnix.eu/aufgaben.php에서 직접 시도해 보세요; 콘텐츠가 독일어인 이유는 그 대상이 독일어권이기 때문입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기