원천 데이터 — 어디서 긁어오나 (합법 3층)
유치원/어린이집 식단은 국가 단일 포털이 없다. NEIS는 학교만, 시설 메타는 정보공개포털, 메뉴는 분산. 그래서 합법성으로 3층으로 나눈다.
open.neis.go.kr/hub keyless · 전국 초·중·고 일자별 메뉴·영양·알레르기. 라이선스 '제한없음'=CC0급. ⚠️ 유치원·어린이집 미포함(학교만) — 이미 초등 식판 수집·사용 중.data.go.kr 15118061(유아)·15118065(어린이) · 식단구분·식단이름·조리법·재료·영양소·사진. ★유치원 식단축을 'API로' 채우는 가장 유력 후보. 활용신청 후 인증키.nong_foods 3,272 적재)·전통향토음식 3,248·조리식품 레시피. 노드 영양·궁합 backbone.dietary4u.mfds.go.kr · 연령군별(만1~2·만3~5·유치원) 표준 월간식단·표준레시피·영양표. 형태=HWP/ZIP/XLSX(API 아님). NEIS가 못 채우는 영유아 메뉴 코퍼스 1순위. 대량수집은 공공누리 유형 확인·기관 협조.데이터 파이프라인 — 원천에서 네트워크까지
메뉴 문자열 → 표준 식재료로 분해되는 흐름. 0~2차는 전부 결정론(환각 0), LLM은 미지 메뉴·OCR에만. 제안 = 사용자 요청한 웹 식재료 추정 + 검수 게이트.
pull-neis-full.py)·식약처 표준식단 API·학부모 식단표 이미지. 이미지는 CLOVA OCR(표 셀 인식) → ocr_logs 로깅.is_menu 판정(비식단 거절)·전수 로깅. 추출 메뉴는 S2~S4로 다시 결정론 검증.lib/lexicon.ts(77개)·도감 표준명 일관. 캐논누수 9,992메뉴 감사 튜닝.learned_menus 학습사전 → (1)menu-dict.json 정확일치+룰 → (2)scanIngredients substring 최장일치(양념·물·기름 EXCLUDE). 여기서 대부분 무료 히트, 환각 0.[]인 처음 보는 메뉴만 호출. 3단 환각 차단: 프롬프트 명시금지('확실치 않으면 []'·환각 금지) → canon 정규화 → CANON_VOCAB 어휘검증(도감 밖 식재료 자동 제외). 빈 결과는 저장 거부.CANON_VOCAB 필터 → 검수 게이트(아래 S3.5)로. 지식 환각보다 실제 레시피에 그라운딩돼 정확↑.boostFromName(메뉴명에 숨은 곡물 강제: 밥/죽→쌀·튀김→밀 튀김옷)·meatFix(불고기+닭 명시→닭고기)·dedupCanon.learned_menus 초기화. 런타임: 2시 크론이 ingredients 빈 행을 learned→rule→scan→LLM(예산가드 max 8콜·6초) 순으로 채움. 부모 교정 행은 보존.lift=c·N/(na·nb)(떡+달걀 0.72=weak 차단)·tray=식판 공동출현(upgrade-only)·bridge=사촌 수기 → food-graph.json. 음식×식재료 = kit-dish-matrix.json.ERD — 식재료 · 음식 · 음식↔식재료 · 식재료↔식재료
식재료(INGREDIENT)를 중심 허브로, 음식이 식재료를 담고(contains), 식재료끼리 궁합/사촌(pair·bridge)으로 잇고, 아이가 끼니에서 먹는다(eats). 운영 테이블(파랑·SQL)과 지식 네트워크(초록/주황·빌드 JSON)가 만난다.
- PKmenu_key 정규화 메뉴명
- ingredients[] 표준 식재료 배열
- processed · source(learned/dict/rule/scan/llm)
- ≈9,992개 · 분해 결과 영구 캐시 · learn_menu RPC 멱등
- PKnm 표준명(192/도감 204)
- grade·category·💎 · nutrient · season · cuisine
- freqMap 또래 인기음식(ingredient-recipes.json)
- 제안 식감·색·알레르겐·질식·연령 메타
- edges[] = {a, b}
- kind pair(궁합)·bridge(사촌)·tray(식판)
- lift·grade·strength·basis
- self-relationship N:M · 추천 네트워크
- dishes[] {key, em, n}
- cells {archetype:{식재료:count}}
- 음식 형태별 메인 식재료 빈도 행렬
- '당근→가장 많이 쓰는 음식 2개' 근거
- FKchild_id · log_date · slot
- menus[](원문) → ingredients[](분해)
- refused·place(home/daycare)·ate_well·texture
- source home / daycare_menu(OCR)
- ocr_logs image·ocr_text·is_menu·model → meal_logs
- children PK id · FK institution_id · age·질환·알레르기
- institutions 31,819 · type · name_norm
- affinity_cache 정적 그래프 부족분 LLM 폴백
LLM은 딱 3곳에만 — 각자 환각 가드
파이프라인 전체에서 LLM 개입은 (A)미지 메뉴 분해 · (B)식단표 OCR · (C)편지 작문/검증뿐. 나머지는 전부 결정론. 각 지점마다 환각·괴식 차단 가드가 붙는다.
A. 미지 메뉴 → 식재료 추정 Haiku 4.5
B. 식단표 OCR 구조화 Sonnet 4-6 Vision
C. 편지 작문 + 검증 Haiku / intro만 Sonnet
편지가 DB를 끌어다 쓰는 경로 (1건 생성)
2시 크론이 자녀별로 — 읽고(결정론) → 신호 파생 → 재료 결정론 조립 → LLM 작문 → 4중 검증 → 발행. '재료=결정론, 문장=LLM'이 코드로 구현된 전 과정.
meal_logs 최근 7일(어제까지) + freqMap·food-graph·ingredients-light fetch + coach_letters 3일(중복 회피용).serializeMaterials가 [타깃·조합·근거]를 LLM 대입 불가 텍스트로 + materialFoods 화이트리스트 확정.coach_letters upsert. 다음 아침 부모 앱 노출.시스템 아키텍처 — 8층
원천부터 앱까지 8개 층. 핵심 분담 = 2시 크론은 런타임 백필(적용) · /mealfred-food-mapping 스킬은 빌드 산출물 개선. learned_menus는 양쪽 공용 단일 진실.
원천 Sources
NEIS 급식 API(학교만) · 식약처 영유아 식단 API(15118061/65) · CCFSM 표준식단 · 학부모 식단표 이미지. 합법 3층: 완전합법→조건부→금지(알림장·카페).
수집 Ingestion
pull-neis-*.py(keyless 전수)·import-nong-foods.py·ocr/route.ts(CLOVA+Sonnet Vision)·seed-institutions.py. OCR만 LLM, 나머지 결정론.
가공 Normalize·Decompose
lexicon(표준명)·createMapper(4단 폴백 dict→rule→scan→LLM)·boostFromName/meatFix·2시 크론 백필. 0~2차 결정론(환각 0)·3차만 Haiku(3단 차단).
저장 Store (이중)
런타임 SQL: learned_menus·meal_logs·ocr_logs·affinity_cache·coach_letters·institutions·nong_foods. 빌드 JSON: menu-dict·food-graph·kit-dish-matrix·ingredient-recipes·corpus-stats·lexicon.
검수 게이트 Curation·Safety
CANON_VOCAB 어휘검증·빈배열 저장거부·food-graph lift 게이트·kit-matrix cells·도감 영유아 안전스크린(질식·보툴리누스). 제안: 엑셀 검수 게이트(사람 판정).
추천 네트워크 Recommendation
coachRecos(strongPairsOf·verifiedCousinsOf)·coachMaterials(4기준 랭킹·3일 회전·validatedCombos)·food-graph·kit-matrix·affinity_cache 폴백. '잘 먹는 음식에 결핍 섞기'를 검증된 동시출현으로.
편지 Coaching Letter
재료=결정론(plan·materials·facts·mirror·serialize) · 문장=LLM(generate·proofread). 4중 게이트(정규식→자카드→LLM 의미→품질). S7 우아한 강등(발행>완벽).
앱·운영 App·Ops
care(식단 입력·OCR·달력)·홈 코칭 스레드(3일 FOMO)·도감·마을·/admin(funnel·compare·모더레이션)·Vercel 크론(coach 2시 외 통합 배치)·예산 가드·CRON_SECRET.
원천(합법축 = NEIS + 식약처 영유아 API + 학부모 OCR) → 메뉴를 0~2차 결정론으로 분해(환각 0), 미지 메뉴만 웹 그라운딩+LLM 추정 → 엑셀 검수 게이트 → learned_menus(음식↔식재료)·food-graph(식재료↔식재료)·kit-matrix(음식×식재료)에 저장 → 편지는 이 네트워크를 읽어 재료를 결정론으로 조립하고 문장만 LLM이 자유 작문, 4중 게이트로 괴식·반복·환각을 막고 발행. LLM은 미지분해·OCR·작문 3곳에만.