AI가 처리하는 식사 계획을 위한 친구를 위한 플래너
요약
이 글은 AI를 활용하여 일상생활의 '결정 피로' 문제를 해결하는 식사 계획 앱 'Weeknight'을 소개합니다. 사용자의 가족 구성원, 알레르기, 냉장고 재료 등을 입력하면 Gemma와 Ollama 같은 오픈 웨이트 모델이 주간 식단과 쇼핑 목록을 자동으로 생성해줍니다.
핵심 포인트
- AI를 활용하여 일상적인 결정 피로(Decision Fatigue) 문제를 해결합니다.
- Gemma와 Ollama를 사용하여 냉장고 사진 인식 및 식단 제안 기능을 구현했습니다.
- 사용자 맞춤형 알레르기 및 재료 기반의 주간 계획을 제공합니다.
_이것은 Hacktoberfest Weekend Challenge: Build for a Friend에 제출하는 내용입니다.
제가 만든 것
제 친구는 무엇을 요리할지 결정하는 데 너무 많은 시간을 씁니다. '요리'가 아니라, '결정'하는 것이죠. 그는 아내와 아이가 있고, 연체동물 알레르기가 있으며, 매일 밤 끝날 때마다 똑같은 질문에 직면합니다. 또한 그는 AI가 일상생활에서 자신에게 무엇을 해줄지 이해하지 못하는데, 저는 그 이유를 압니다. AI에 대해 언급되는 대부분의 내용은 저녁 식사와는 아무 관련이 없습니다.
그래서 저는 논쟁하지 않았습니다. 제가 생각할 수 있는 가장 평범한 것을 그에게 만들어 주었습니다.
Weeknight은 일요일 저녁에 한 주의 저녁 식사를 계획하고 쇼핑 목록을 건네줍니다. 몇 명이 먹는지, 알레르기 유무, 누군가 먹지 않을 음식, 가족들이 좋아하는 것, 그리고 바쁜 날이 언제인지 알려주면 됩니다. 냉장고 사진을 보여줄 수도 있습니다. Google의 오픈 웨이트 모델인 Gemma가 Mac 자체를 통해 Ollama로 저녁 식사를 제안합니다. 그런 다음 일반 코드가 모든 요리를 확인하고 통로별로 목록을 합산합니다.
제가 그에게 프로토타입을 보여주었을 때, 마지막 수정 단계를 거치기 전이었는데, 그는 시간을 되찾게 되어 기쁘고 머릿속에서 이 질문을 더 이상 안고 다닐 필요가 없어서 기쁘다고 말했습니다.
그 문장의 후반부가 진짜 사양입니다. 도구를 사용해서 저녁 식사에 대해 '생각하는 것'을 멈추는 사람은 그것을 교정하지 않을 것입니다. 그는 화요일의 볶음 요리에서 굴 소스를 스캔하지 않을 겁니다. 따라서 앱이 해야 합니다.
나중에 제가 그에게 Weeknight에서 만든 쇼핑 목록을 보내주자, 그는 만족스러워하는 것 같았습니다. 첫 번째 데모에서 나온 제안 중 하나도 자리 잡았습니다: 타코입니다. 그는 예전에는 집에서 절대 만들지 않았습니다. 하지만 이제는 만드는데, 자신과 아들이 그것에 매우 행복하다고 저에게 말합니다.
시연
이 데모는 친구의 수치(3명, 연체동물 알레르기)를 사용하며, 상황을 위해 꾸며낸 취향으로 진행됩니다.
먼저 Gemma가 냉장고 사진을 읽고 보이는 것을 목록화합니다. 스피나치가 있어야 할 곳에 상추가 보여서 제가 그 단어 하나를 수정했습니다.

그다음으로 주간 식단을 계획합니다. 코드는 이 집에서 먹지 않을 올리브가 들어갔기 때문에 토요일 메뉴를 다시 보내고, 그와 함께 쇼핑 목록이 담긴 한 주가 도착합니다. 이 목록은 아마도 이미 냉장고에 있는 것들을 구분해 줍니다.

전체 과정이 1분 만에 완료됩니다:
냉장고 사진: Alabama Extension, CC0, via Wikimedia Commons.
코드
GitHub logo sintineddi / weeknight
로컬 오픈 모델(Gemma via Ollama)을 사용하여 일요일 저녁에 가족 저녁 식사를 계획합니다: 알레르기 유발 물질 확인, 쇼핑 목록, A2A 준비 완료.
Weeknight은 표준 라이브러리만으로 구축된 Python 서버이며, 순수 JavaScript 페이지 하나로 이루어져 있습니다. pip install이나 npm install이 필요 없습니다. Ollama를 실행하면 다음과 같이 합니다:
ollama pull gemma4:e4b
python3 server.py
구축 방법
Gemma가 제안하고, 코드가 확인합니다
| | Gemma | 순수 코드 (Plain code) | |
| --- | --- | --- | |
| 아이디어 | 요리, 재료, 양 및 레시피 단계 | |
| ... |
Gemma 4는 Ollama을 통해 실행되며, 그 답변은 JSON 스키마로 제한되므로 코드는 산문(prose)을 파싱할 필요가 없습니다. 어떤 프롬프트보다도 한 가지 설정이 더 중요했습니다. Gemma 4는 기본적으로 답변하기 전에 생각하는 과정을 거치며, 이 '생각' 기능이 활성화된 상태에서 e4b는 일주일 계획에 74초에서 84초가 걸린 반면, 12b 모델은 10분을 넘겨 실행되다가 끊겼습니다. "think": false로 설정했을 때, e4b는 제 M3 Max에서 30초에서 50초 만에 일주일 계획을 세우는데, 이는 검사(checks)가 몇 가지 요리를 반환하느냐에 따라 달라집니다. 냉장고 사진은 동일한 모델에게 전달되며 약 7초 만에 읽힙니다. 이 사진은 디스크에 절대 기록되지 않습니다. Weeknight 역시 A2A(Agent-to-Agent, 에이전트 간) 통신을 지원하기 때문에, 다른 에이전트가 쇼핑 목록을 요청하거나 받을 수 있습니다.
알레르겐 검사는 EU 식품 라벨에서 의무적으로 표시해야 하는 14가지 알레르겐에 대한 키워드 목록입니다. 이 모델은 일반적인 숨겨진 출처를 알고 있습니다: 페스토(pesto)는 견과류, 간장(soy sauce)은 밀, 우스터 소스(Worcestershire sauce)는 생선, 굴소스(oyster sauce)는 연체동물. 또한 "땅콩 프리(peanut-free)"라는 문구를 '라벨을 읽어라'로 해석하며, 결코 보장으로 받아들이지 않습니다. 그리고 유당 제거 우유가 여전히 우유라는 사실도 알고 있습니다. 이 모델은 요리의 이름보다 재료를 신뢰하는데, 왜냐하면 실제로 구매하는 것은 재료이기 때문입니다. 두 번의 시도 후에도 실패하는 요리는 빨간색으로 계획에 남아있습니다. 숨겨진 것은 아무것도 없습니다.
제가 실패하게 만들려고 노력했습니다
한 번도 실패하는 것을 본 적이 없는 검사기는 테스트하지 않은 검사기입니다. 그래서 저는 모델을 유혹하기 위해 가상의 가구를 구축했습니다. 한 가정은 견과류 알레르기가 있지만 사테와 페스토를 좋아합니다. 다른 가정은 우유나 달걀을 먹지 못하지만 카르보나라를 좋아합니다. 또 다른 가정은 셀리악병 환자이며 피자를 좋아합니다. 세 번째 가정은 참깨와 생선 알레르기가 있지만 초밥과 후무스를 좋아합니다. 마지막 가정은 제 친구의 알레르기(연체동물)가 있으며, 파에야, 칼라마리, 굴소스 볶음 요리를 좋아하는 가족입니다. 세 가지 크기의 Gemma 4 모델이 각 가구에 대해 3주간 계획을 세웠고, 저는 어떤 검사도 수행되기 전 모델의 첫 답변에서 발견된 문제점들을 계산했습니다.
| 첫 번째 답변: 알레르기가 있는 식사 (dinners with an allergen) | 셀리악병(coeliac) | 유제품-계란(dairy-egg) | 견과류(nuts) | 참깨-생선(sesame-fish) | 연체동물(molluscs) |
|---|---|---|---|---|---|
| gemma4:e2b | 3/18 | 0/18 | 0/18 | 5/18 | 0/18 |
| ... |
모델과 가구(household)가 패턴을 파악하기에는 3주 정도면 충분하며, 비율(rate)을 측정하기는 부족합니다.
저는 모델이 알레르기를 잊어버릴 것이라고 예상했습니다. 하지만 그렇지 않았습니다. 그냥 포기하는 겁니다. e4b는 그 가구가 셀리악병 환자라는 것을 알고 있었음에도 불구하고, 식사 중 절반에 일반 파스타, 번(buns) 또는 토르티야를 넣었습니다. 이는 그 가구가 요청했던 바로 그 음식들이었습니다. 심지어 한 요리는 성분 목록에는 일반 빵이나 스파게티라고 되어 있는데도 '(글루텐 프리)'라고 불렸습니다. 쇼핑 리스트는 성분을 따라가므로, 이것이 구매되었을 것입니다.
제 친구의 알레르기는 쉬운 편이었습니다. 연체동물 가구는 빠에야(paella), 오징어 튀김(calamari), 해산물 파스타, 굴소스 볶음 요리를 요청했고, 54번의 식사 동안 어떤 모델도 단 하나의 연체동물도 제공하지 못했습니다. 두 개의 작은 모델은 주로 그러한 취향을 무시하고 소시지, 타코, 케사디야를 계획했습니다. 큰 모델만이 이를 조정했습니다. 즉, 닭고기와 피망이 들어간 스페인식 밥 요리, 대구로 만든 '해산물 파스타', 그리고 성분 목록에 굴소스가 없는 소고기 및 브로콜리 볶음 요리였습니다. 제가 내릴 수 있는 최선의 설명은 오징어나 홍합 같은 음식들은 이름으로 불리고 명확한 대체품이 있다는 것이지만, 글루텐은 가족이 매주 먹는 주식(staples) 안에 숨어 있다는 것입니다. 모델은 '파스타'를 생각할 뿐이지 '밀가루'를 생각하지 않습니다. 9주가 그것을 증명할 수는 없지만, 제가 걱정하는 부분을 바꾸었습니다. 알레르기 유발 물질이 눈에 띄지 않는 곳에서 확인(check)하는 것이 가장 중요합니다.
가장 큰 모델은 18주 동안 알레르기 성분 누락이 없었다. 글루텐 프리 파스타와 타마리, 코코넛 아미노스를 선택했다. 하지만 다른 곳에서 실패했다. 18주 중 17주 동안 답변의 첫 수량, 즉 첫 저녁 식사의 첫 재료가 불가능한 양으로 나왔는데, 보통 네 사람에게는 너무 많은 5000g의 닭 가슴살이었다. 두 개의 작은 모델은 처음 숫자를 틀린 적이 없었다. 내 추측으로는 스키마 하에서 첫 숫자가 디코딩되는 방식에 문제가 있는 것 같지만, 그저 추측일 뿐이다. 고치라고 요청해도 12b는 거의 시도하지 않았다. 그리고 배가 두 배로 걸리는 시간 때문에 e4b가 기본값으로 유지된다: 이 모델의 실수는 코드가 잡아낼 수 있는 종류이기 때문이다.
마지막 테스트에서는 프롬프트에 있던 숨겨진 알레르겐에 대한 문장을 제거했다. 누락률은 거의 변하지 않았지만, 누락된 성분의 종류는 바뀌었다. 간장(soy sauce)이 네 번 나타났고, 마요네즈가 한 번 나왔다. 검사 시스템이 이를 되돌렸다. 두 번의 시도 끝에 두 번 포기했고, 그 두 저녁 식사는 빨간색으로 남아 있었다.
검사기가 자체 숙제를 평가하다
검사 후의 수치들은 청소 작업을 했던 것과 동일한 키워드 목록으로 측정되기 때문에, 놓친 것을 보여줄 수는 없다. 이를 알아내기 위해 알레르기 가구들의 모든 최종 저녁 식사가 하나씩 읽혀져 저장소에 나열되었고, 누구나 확인할 수 있게 되었다: 342개의 저녁 식사. 제가 Weeknight와 함께 만든 Claude Code가 이 읽기를 수행했다. 어떤 알레르겐도 플래그 없이 통과하지 못했다.
하지만 그 읽기 과정에서 검사기 자체의 버그를 발견했다. 글루텐 프리 파스타로 만든 '닭고기 파스타(Chicken pasta)'는 단순히 요리 이름만으로도 되돌려졌다. 그것은 '추가된 밀 없음(no-added-wheat)'이나 '타히니 무첨가(tahini-free)'를 이해하지 못했다. 우유 대신 빵을, 글루텐 대신 육수를 통과시켰고, 이 경우라면 라벨을 읽으라고 요청했어야 했다. 그 모든 것 이후에 진행된 테스트 주에는 읽기가 놓친 또 다른 간극이 발견되었다: 타코 쉘(taco shells). 모두 수정되었으며, 43개의 테스트가 이를 고정하고 있다.
여전히 키워드 목록일 뿐 의사도 아니며, 영어만 읽는다. 프랑스어로 작성된 요리는 그냥 지나칠 것이다. 모든 계획 아래에는 앱이 없어도 얻을 수 있는 조언으로 끝난다: 라벨을 읽으세요.
Open Innovation은 왜 중요할까요?
저는 Weeknight를 폐쇄형 모델과 비교하지 않았기 때문에, 폐쇄형 모델이 더 나쁜 저녁 식사를 계획할 것이라고 주장하지는 않겠습니다. 제가 설명할 수 있는 것은 Mac에서 오픈 모델을 실행하면서 변화한 점입니다.
가족의 세부 정보는 집에 머뭅니다. 친구의 알레르기, 가족들의 바쁜 밤, 그리고 냉장고 내부 사진은 이 모델이 구동되는 Mac을 벗어나지 않습니다. 심지어 냉장고 사진도 저장되지 않습니다. 쇼핑 목록은 그가 어딘가로 보내기로 결정했을 때만 나갑니다.
테스트 비용은 0원이므로, 저는 많이 테스트했습니다. 벤치마크는 의도적으로 까다로운 가정을 배경으로 한 66주, 약 400번의 저녁 식사, 그리고 검사기 수정 후 재실행된 모든 경우를 포함합니다. 측정되는 API(metered API)였다면 저는 그 실행들을 아껴썼을 것입니다. 이 모델들을 직접 돌려보면서 제가 만든 검사기가 좋은 요리들을 버리고 있다는 것과 12b가 첫 번째 숫자를 처리하는 데 어려움을 겪는 것을 발견했습니다.
모델은 계약이 아니라 설정입니다. e2b, e4b, 그리고 12b는 세 가지 크기의 같은 계열 모델이므로, 속도, 알레르겐 오류, 산술 계산 사이의 상충 관계(trade-off)는 제가 추측한 것이 아니라 측정한 것입니다. 만약 다음 달에 더 나은 오픈 모델이 나온다면, 그것을 시도하는 것은 하나의 신호일 뿐이며, 벤치마크가 그것을 유지할지 말지를 알려줍니다.
제 친구에게는 그런 것들이 필요하지 않으며, 그럴 필요도 없습니다. 그가 필요한 것은 오징어가 없는 화요일 저녁 식사와 일요일 밤에 준비된 목록입니다. 타코는 보너스였습니다.
제 에이전트 세션
저는 Claude Code를 사용해 하루 만에 Weeknight를 만들었습니다.
수상 부문
Gemma의 최고의 활용 사례.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기