두부
경력근거: “우리는 세상을 바꾸는 일만 합니다. 모든 아이가 성장할 수 있는 가능성을 엽니다.” 두부(DUBU; Diverse
※ 실제 산출물이 아닌 AI 예측 시안입니다.
두부는 발달이 느린 아이의 학습 경험을 다룬 두브레인 데이터를 가진 팀이라, 활동 기록에서 발달 신호를 짚고 다음 활동을 추천하는 이 도구는 그 아동 발달·활동 데이터가 있어야 추천을 검증합니다.
'모든 아이가 성장하는 가능성을 엽니다'가 미션. 활동 기록에서 성장 신호를 읽고 다음 단계를 제안하는 게 직접적 가치.
'아이들의 발달과 학습 경험을 더 깊이 이해하고 더 나은 방식으로 돕기'가 목표. 데이터로 신호를 짚는 도구가 정확히 그 방향.
TypeScript·Next.js·LLM(Claude) 풀스택으로 제품을 만드는 직무. 활동 로그 ingest→코칭 추천 흐름이 직무와 정렬.
아이의 학습 활동 기록(놀이·문제풀이·반응)에 발달 영역 기준을 붙여, 영역별 강점·도움이 필요한 신호를 짚고 다음 활동을 근거와 함께 추천하는 1주 포트폴리오입니다. 진단·단정은 하지 않습니다.
두부 PE. 아이별 활동 기록을 매번 손으로 살펴 다음 활동을 정하던 상황을 끝내고, 그 판단을 근거 있는 자동 추천으로 옮기고 싶은 사람입니다.
활동 로그에 발달 영역 기준(언어·수·소근육 등)을 붙이면, LLM 이 (a) 영역별 강점/도움 필요 신호를 근거와 함께 짚고 (b) 다음 활동을 추천하되 의료·발달 진단으로는 단정하지 않습니다.
아이 활동 기록에서 영역별 강점·도움 신호를 짚고 다음 활동을 근거와 함께 추천하는 동작하는 도구(진단·단정 금지).
보호자·교사 피드백으로 신호·추천 타당도 일치도를 재고, 진단 단정 가드 위반율을 보여주는 대시보드입니다.
영역별 발달 신호를 시계열로 추적하고 주간 보호자 리포트를 자동 발송하는 단계입니다.
'~발달 지연이다' 같은 단정 표현 유도 입력 30종을 넣어도 가드가 단정 대신 완곡·검토 권고로 바꾸는 걸 시연합니다.
아이 활동 기록을 넣으면 영역별 신호 요약과 다음 활동 추천이 근거와 함께 몇 초 안에 나오는 걸 시연합니다.
모든 코칭 출력이 형식 검증(Zod)을 통과
측정: 자동 parse, 표본: 추천 50건
영역별 신호 라벨 30개 중 23개가 내가 만든 정답과 일치합니다. 단, 정답·데이터를 작성자가 만든 합성 기준이라 '성능 검증'이 아니라 '데모 조건 동작'
위 수치는 더미데이터 자가채점이며, 실제 신호·추천 적정성은 두부 실제 활동 데이터 + 발달 전문가 검수가 있어야 측정 가능합니다. 이 포트폴리오는 그 검증을 바로 돌릴 수 있는 상태까지 만듭니다.
수치는 합성 데이터 자가채점이라 성능 증명이 아닙니다. 면접에서는 데모 동작과 실검증 준비 상태로 솔직히 설명합니다.
정답을 작성자가 만들었으니 잘 맞는 것이 당연합니다. 결측 활동·이상 반응·미등록 활동코드 같은 헷갈리는 케이스를 더미에 일부러 섞어 쉬운 문제만 푸는 게 아님을 보여줍니다.
발달은 의료 영역과 맞닿아 단정이 위헙니다. '지연/장애' 진단을 강제로 차단하고, 신호는 항상 '보호자·전문가 확인 권장'으로 완곡 표현입니다.
실제 도입 시 달라지는 것: 실 아동 활동 분포·연령대가 더미와 다르므로 발달 영역 기준과 가드 규칙을 실데이터·전문가 자문으로 다시 맞춰야 한다(도입 단계 과제)
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
아이의 학습 활동 한 건 로그. 신호 요약·추천 LLM 이 가장 먼저 보는 표. 결측·이상·미등록 활동을 일부러 섞었다.
| log_id | child_id | activity_raw | activity_id | domain | result_score | duration_sec |
|---|---|---|---|---|---|---|
| a_001 | k_01 | 낱말 카드 맞추기 | act_word | language | 0.8 | 320 |
| a_002 | k_01 | 숫자 세기 | act_count | number | 0.4 | 280 |
| a_003 | k_02 | 단어카드 | act_word | language | 0.9 | 300 |
| a_004 | k_02 | 블록 쌓기 | act_block | fine_motor | — | 150 |
| a_005 | k_03 | 친구와 역할놀이 | act_role | social | 0.7 | 600 |
아래 Zod 스키마에 맞는 아이 학습 활동 로그 80행 JSON 배열로 생성.
{"type":"object","properties":{"log_id":{"type":"string"},"child_id":{"type":"string"},"activity_raw":{"type":"string"},"activity_id":{"type":["string","null"]},"domain":{"type":"string","enum":["language","number","fine_motor","social","unknown"]},"result_score":{"type":["number","null"]},"duration_sec":{"type":["number","null"]}},"required":["log_id","child_id","activity_raw","activity_id","domain","result_score","duration_sec"]}
쉬운 데이터만 만들지 말 것. 하드 케이스 의도적 혼입: (1) result_score/duration_sec=null 결측 각 1~2건, (2) activity_raw 표기 흔들림('숫자 세기' vs '숫자세기', '블록 쌓기' vs '블럭쌓기') 2쌍과 빈 문자열 1건, (3) 미등록 신규 활동(activity_id=null, domain=unknown) 1~2건, (4) 경계 점수 0.0/1.0 각 1건, (5) 비정상 duration(>3600s 또는 <60s) 각 1건. JSON 배열만.{"type":"object","properties":{"log_id":{"type":"string"},"child_id":{"type":"string"},"activity_raw":{"type":"string"},"activity_id":{"type":["string","null"]},"domain":{"type":"string","enum":["language","number","fine_motor","social","unknown"]},"result_score":{"type":["number","null"]},"duration_sec":{"type":["number","null"]}},"required":["log_id","child_id","activity_raw","activity_id","domain","result_score","duration_sec"]}| TypeScript | 활동 로그 ingest + 코칭 카드 렌더 + Zod 런타임 검증 |
| Next.js | 보호자/교사용 코칭 대시보드(App Router) |
| AWS | 로그 저장 + 서버리스 추천 API |
| LLM | Claude 로 영역별 신호 요약·활동 추천 및 진단 단정 가드 |
✓ pass → 그대로 멈춰도 완성품입니다. 더 키우려면 2주차(발달 신호·추천이 타당한지 검증)로 갑니다.
✓ pass → 여기서 멈춰도 완결입니다. 더 키우려면 3주차(성장 시계열 + 주간 리포트)로 갑니다.
아이별 영역 신호 요약 + 다음 활동 추천 출력. 근거 인용 + 완곡 표현(진단 단정 금지).
{"type":"object","properties":{"child_id":{"type":"string"},"area_signals":{"type":"array","items":{"type":"object","properties":{"domain":{"type":"string"},"signal":{"type":"string","enum":["strength","needs_support","insufficient_data"]},"note":{"type":"string","minLength":8}},"required":["domain","signal","note"]},"minItems":1},"next_activities":{"type":"array","items":{"type":"string","minLength":4},"minItems":1,"maxItems":3},"evidence":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"quote":{"type":"string"}},"required":["field","quote"]},"minItems":1},"hedge":{"type":"string","minLength":8}},"required":["child_id","area_signals","next_activities","evidence","hedge"]}[
{
"child_id": "k_01",
"area_signals": [
{
"domain": "language",
"signal": "strength",
"note": "낱말 활동 점수 높음"
},
{
"domain": "number",
"signal": "needs_support",
"note": "수 세기 점수가 낮은 편"
}
],
"next_activities": [
"수 세기 게임 반복",
"수량 비교 놀이"
],
"evidence": [
{
"field": "result_score",
"quote": "0.4"
}
],
"hedge": "한두 번 기록 기반이라 발달 단정은 아니며 보호자 관찰 권장"
},
{
"child_id": "k_03",
"area_signals": [
{
"domain": "unknown",
"signal": "insufficient_data",
"note": "미등록 활동이라 영역 판단 보류"
}
],
"next_activities": [
"활동 분류 확인 후 재평가"
],
"evidence": [
{
"field": "activity_id",
"quote": "null"
}
],
"hedge": "활동이 분류되지 않아 신호 해석을 단정하지 않음"
},
{
"child_id": "k_04",
"area_signals": [
{
"domain": "number",
"signal": "insufficient_data",
"note": "수 활동 기록이 한 건뿐이라 신호로 읽지 않습니다"
}
],
"next_activities": [
"수 세기 놀이 기록을 두 주 더 모으기"
],
"evidence": [
{
"field": "result_score",
"quote": "0.6"
}
],
"hedge": "기록이 모자라 강점·도움 필요 어느 쪽으로도 읽지 않았습니다. 보호자 관찰과 함께 봅니다."
}
]자동: (1) Zod parse, (2) evidence.field 가 입력 스키마 실제 필드명인지, (3) 진단·장애 단정 토큰 검출 시 reject. 수동/judge: 추천 적정성·완곡함은 LLM-as-judge + 5% 사람 확인(전문가 자문은 도입 단계).