# recipe-graph-engine > 그래프 DB(Neo4j) 기반 레시피 추천 엔진 구축 스킬. 재료 → 레시피 역방향 쿼리, 건강/다이어트 필터링, 페르소나별 응답 생성. Use when: - 레시피 데이터 수집/크롤링/구조화 - Neo4j 스키마 설계 및 데이터 적재 - Cypher 쿼리 개발 (재료 매칭, 건강 필터 등) - 페르소나 기반 응답 생성 (엄마밥, 다이어트코치 등) - 레시피 추천 API/앱 개발 - Author: js - Repository: trues38/recipe-graph-engine - Version: 20260102102911 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-06 - Source: https://github.com/trues38/recipe-graph-engine - Web: https://mule.run/skillshub/@@trues38/recipe-graph-engine~recipe-graph-engine:20260102102911 --- --- name: recipe-graph-engine description: | 그래프 DB(Neo4j) 기반 레시피 추천 엔진 구축 스킬. 재료 → 레시피 역방향 쿼리, 건강/다이어트 필터링, 페르소나별 응답 생성. Use when: - 레시피 데이터 수집/크롤링/구조화 - Neo4j 스키마 설계 및 데이터 적재 - Cypher 쿼리 개발 (재료 매칭, 건강 필터 등) - 페르소나 기반 응답 생성 (엄마밥, 다이어트코치 등) - 레시피 추천 API/앱 개발 --- # Recipe Graph Engine 그래프 기반 레시피 추천 엔진. RAG가 아닌 **상태 그래프**로 레시피를 구조화하여 맥락 있는 추천 제공. ## 핵심 차별점 | 기존 (RAG) | 그래프 엔진 | |------------|-------------| | 문서 청킹 + 임베딩 | 노드/엣지 구조화 | | "김치찌개 레시피 알려줘" | "냉장고에 이것만 있는데 뭐 해먹지?" | | 단방향 검색 | 역방향 쿼리 (재료 → 레시피) | ## 워크플로우 개요 ``` Phase 1: 데이터 수집 (1-2일) ↓ Phase 2: 그래프 스키마 (0.5일) ↓ Phase 3: 데이터 적재 (0.5일) ↓ Phase 4: 쿼리 엔진 (1일) ↓ Phase 5: 페르소나 엔진 (0.5일) ↓ Phase 6: API 래핑 (0.5일) ``` --- ## Phase 1: 데이터 수집 ### 1.1 공개 데이터셋 | 소스 | 내용 | 용도 | |------|------|------| | 농림축산식품부 | 한식 레시피 DB | 기본 레시피 | | 식약처 영양 DB | 한국 식품 영양정보 | 칼로리/영양소 | | Recipe1M+ | 100만+ 글로벌 레시피 | 확장용 | | USDA Food DB | 영양소 정보 | 영양 계산 | ### 1.2 크롤링 (구조만 추출) **저장하는 것** (팩트): 재료 목록, 조리 시간, 난이도, 카테고리, 태그 **저장 안 하는 것** (저작권): 레시피 원문, 조리 설명 문장, 이미지 ### 1.3 LLM 구조화 크롤링한 메타데이터를 LLM으로 정규화. **상세**: `references/data-pipeline.md` --- ## Phase 2: 그래프 스키마 ### 노드 타입 ``` (:Ingredient) - 재료 (돼지고기, 김치, 두부...) (:Recipe) - 레시피 (김치찌개, 된장찌개...) (:Goal) - 목표 (다이어트, 벌크업...) (:Condition) - 건강상태 (당뇨, 고혈압, 통풍...) (:Diet) - 식단 (비건, 락토, 페스코...) (:Technique) - 기법 (수비드, 에어프라이어...) ``` ### 엣지 타입 ``` (Ingredient)-[:REQUIRED_FOR {amount, unit}]->(Recipe) (Ingredient)-[:CAN_REPLACE {ratio}]->(Ingredient) (Recipe)-[:SUITABLE_FOR {score}]->(Goal) (Recipe)-[:SAFE_FOR | :AVOID_FOR {reason}]->(Condition) (Recipe)-[:COMPATIBLE_WITH]->(Diet) (Recipe)-[:USES_TECHNIQUE]->(Technique) ``` **상세**: `references/schema.md` --- ## Phase 3: 데이터 적재 ### 적재 순서 1. Ingredient 노드 → 2. Recipe 노드 → 3. REQUIRED_FOR 엣지 → 4. 메타 노드/엣지 **스크립트**: `scripts/neo4j_loader.py` --- ## Phase 4: 쿼리 엔진 ### 핵심 쿼리 **재료 → 레시피 (역방향)** ```cypher MATCH (r:Recipe)-[:REQUIRED_FOR]-(i:Ingredient) WHERE i.name IN $my_ingredients WITH r, count(i) AS matched, size((r)-[:REQUIRED_FOR]-()) AS total WITH r, round(matched * 100.0 / total) AS coverage WHERE coverage >= 60 RETURN r.name, coverage ORDER BY coverage DESC LIMIT 10 ``` **상세 쿼리 목록**: `references/queries.md` --- ## Phase 5: 페르소나 엔진 | 티어 | 페르소나 | 톤 | |------|----------|-----| | FREE | 엄마밥 👩‍🍳 | "우리 OO이 뭐 해먹을까~ 이거 해먹어!" | | PREMIUM | 흑백요리사 🖤 | "이 재료엔 수비드가 최적입니다" | | PREMIUM | 다이어트코치 💪 | "이거 먹으면 -300kcal 절약!" | | PREMIUM | 건강맞춤 🏥 | "당뇨에 안전한 레시피입니다" | | PREMIUM | 무지개요리사 🌈 | "동물 없이도 이렇게 맛있어요" | **상세**: `references/personas.md` --- ## Phase 6: API ```python @app.post("/recommend") async def recommend(ingredients: List[str], persona: str = "엄마밥"): results = query_engine.find_recipes(ingredients) response = persona_engine.generate(results, persona) return {"recipes": results, "message": response} ``` --- ## 파일 참조 | 파일 | 내용 | |------|------| | `references/schema.md` | Neo4j 노드/엣지 상세 스키마 | | `references/queries.md` | Cypher 쿼리 전체 목록 | | `references/personas.md` | 페르소나별 응답 스타일 | | `references/data-pipeline.md` | 데이터 수집/구조화 상세 | | `scripts/structurizer.py` | LLM 구조화 스크립트 | | `scripts/neo4j_loader.py` | 그래프 적재 스크립트 | | `scripts/query_engine.py` | 쿼리 엔진 클래스 |