Personalized Meal Plan Generator with LLM-Powered Recommendations
cherrypick · E-commerce · 2024 · source Agentic: no · promotional bias: med · source-backed · extracted with prompt 0.5.6 (schema v2)
Generated from extraction.json — do not edit by hand. Every claim cites verbatim source evidence; stated means the quote directly asserts the claim, implied means it supports it indirectly.
Problem
Domain: Consumer meal planning and personalized recipe recommendation
Cherrypick wanted to personalize weekly meal plans and explain recipe choices, but needed to do so in a consumer app where chatbot friction, LLM cost, hallucinated recipe IDs, dietary safety mistakes, and subjective food quality could break the product economics and user experience.
Constraints:
- The previous meal generator let customers reject meals but did not let them specify preferences.
- Consumer-app economics make many LLM calls per shopping session unviable.
- Chat interfaces can feel forced and create typing fatigue for structured meal-planning tasks.
- LLM outputs are inherently variable and can produce invalid JSON or hallucinated recipe IDs.
- Dietary restrictions and customer goals require deterministic safety filtering before generation.
- Meal quality and nutritional balance require expert human review beyond automated checks.
Architecture
Cherrypick built a structured LLM meal generator rather than a chatbot. A traditional backend filters recipes to only those a customer can eat, Liquid prompt templates package a manageable subset of recipe details and preferences into a small number of LLM calls, the LLM generates a meal plan plus natural-language reasons and pre-defined rejection options, automated validation checks JSON and recipe IDs with retries, expert food review samples plans for quality and nutrition, and stored evaluations support A/B testing, prompt refinement, and future LLM-assisted evaluation.
Diagram confidence: explicit (topology described by the source).
flowchart LR Customer_preference_input["Customer preference input"] --> Deterministic_recipe_filter["Deterministic recipe filter"] Deterministic_recipe_filter --> Prompt_template_renderer["Prompt template renderer"] Prompt_template_renderer --> LLM_meal_generator["LLM meal generator"] Prompt_template_renderer --> Prompt_experiment_runner["Prompt experiment runner"] LLM_meal_generator --> Automated_validation_and_retry["Automated validation and retry"] LLM_meal_generator --> Structured_meal_plan_UI["Structured meal-plan UI"] Automated_validation_and_retry --> LLM_meal_generator Automated_validation_and_retry --> Evaluation_store["Evaluation store"] Structured_meal_plan_UI --> Customer_preference_input Expert_food_review["Expert food review"] --> Evaluation_store Evaluation_store --> Prompt_experiment_runner Prompt_experiment_runner --> Prompt_template_renderer Prompt_experiment_runner --> Evaluation_store
Components
| Component | Role | Interacts with |
|---|---|---|
Customer preference input |
Captures the customer's weekly meal count, dietary preferences, goals, and rejection choices. | Deterministic recipe filter |
Deterministic recipe filter |
Filters recipes to the set the customer can actually eat before any LLM call. | Prompt template renderer |
Prompt template renderer |
Uses Liquid templates to combine filtered recipes, customer context, and prompt text for controlled experiments. | LLM meal generator, Prompt experiment runner |
LLM meal generator |
Generates personalized meal plans, natural explanations, and rejection options from the filtered recipe context. | Automated validation and retry, Structured meal-plan UI |
Automated validation and retry |
Checks JSON structure and recipe IDs, then retries failed generations. | LLM meal generator, Evaluation store |
Structured meal-plan UI |
Presents meal plans and LLM-generated rejection options without forcing a free-form chatbot. | Customer preference input |
Expert food review |
Samples generated plans for quality, nutritional balance, flavor combinations, and weekly coherence. | Evaluation store |
Evaluation store |
Stores automatic and expert evaluations as training data for future prompt and evaluator improvements. | Prompt experiment runner |
Prompt experiment runner |
Re-runs meal generations with new prompts and models while holding input data constant for comparison. | Prompt template renderer, Evaluation store |
Data flow
Customer preferences and dietary constraints flow into a deterministic recipe filter; the filtered recipe subset and prompt template are sent to the LLM in one or a few calls; the LLM returns a structured meal plan, personalized explanations, and contextual rejection options; automated validators check JSON structure and recipe IDs and retry failures; expert review and stored evaluations feed prompt/template A/B tests and future evaluator/prompt-improvement automation.
3 supporting quotes
Why this architecture
The architecture constrains the LLM to the parts of meal planning where it adds unique value - preference interpretation, recipe compatibility, and natural explanations - while deterministic filters, structured UI, validation, retries, and expert review handle safety, cost, and reliability. This matches Cherrypick's explicit warning that many LLM apps become demos when teams skip product fit, interface design, cost modeling, and evaluation.
3 supporting quotes
Models used: LLMs · LLM judges · Liquid templates
Scale
- The new meal generator launched in late 2024, described as last month from the article's perspective.“Last month at Cherrypick we launched a brand new meal generator”article, stated
- Customers changed their plans 30% less after the new generator launched.“Customers are changing their plans 30% less”article, stated
- Customers used generated plans in baskets 14% more.“using their plans in their baskets 14% more”article, stated
- Cherrypick had operated a meal generator since early 2023.“We have had a meal generator in Cherrypick’s app since early 2023.”article, stated
- Cherrypick has used LLM completion in the product since 2022 for recipe uploading.“We have been using them for completion in our product since 2022 for our recipe uploader.”article, stated
- The team rejected a WhatsApp grocery proof of concept because it would require hundreds of calls per shop.“we realised that to provide a good service we would need to make hundreds of calls per shop”article, stated
- The meal generator needs only a few LLM calls per plan.“It requires only a few LLM calls per meal plan generation, versus dozens of messages in a typical chat session.”article, stated
- The current generation failure rate is 25%, usually requiring one or two retries.“At the moment we are getting a 25% failure rate, which means one or two retries are needed for each meal plan generated.”article, stated
- As of December 2024, powerful LLM calls are described as a few dollars per million tokens and tens of seconds.“As of December 2024, the cost of running a powerful LLM is still a few dollars per million tokens and returns full results in tens of seconds.”article, stated
Alternatives considered (roads not taken)
Use no LLM for the problem
Rejected because: The meal planner needed natural-language preference understanding, recipe compatibility reasoning, and personalized explanations that were difficult with simpler methods.
Build a chatbot interface
Rejected because: Chat felt forced for structured meal planning, created typing fatigue, and would have increased LLM call costs.
WhatsApp grocery chatbot
Rejected because: It worked, but hundreds of LLM calls per shop would have erased profit margin.
Send the full recipe list to the LLM
Rejected because: The model could waste tokens, select wrong recipes, or choose harmful recipes for a customer.
Use tools/function calling to retrieve recipes dynamically
Rejected because: The team chose a prompt-based single-call approach because it was quicker and cheaper for their use case.
Patterns
context-engineering (context)
Cherrypick controls what enters the prompt by pre-filtering recipes to those the customer can eat and sending only a manageable subset of recipe details.
guardrails-io-filtering (reliability)
Automated validation enforces perfect JSON and checks recipe IDs against supplied context before a plan reaches the user.
eval-driven-development (evaluation)
The team built automated validation, expert review, stored evaluations, A/B tests, prompt refinement, and planned LLM judges around the meal generator.
human-in-the-loop-gate (review)
The Head of Food reviews samples for nutritional balance, flavor combinations, and weekly meal coherence that automated checks cannot judge.
prompt-versioning (prompt-operations)
Liquid templates and stored evaluations let Cherrypick re-run meal generations with new prompts/models, A/B test variations, and refine prompts based on feedback.
cost-aware-routing (optimization)
The product design minimizes LLM calls by avoiding chat, using structured rejection options, and choosing a single-call prompt over tool-based multi-call retrieval.
Tradeoffs
Use a structured interaction instead of a chatbot.
Chose Meal-plan UI with predefined LLM-generated rejection options over Free-form chat.
Rationale: The structured UI matches the back-and-forth of plan refinement without typing fatigue or many model calls.
Filter recipe eligibility before the LLM.
Chose Programmatic pre-filtering over Letting the LLM choose from the full recipe catalog.
Rationale: Deterministic filtering protects dietary safety, saves tokens, and reduces obvious bad selections.
Use one larger prompt instead of tool-based recipe lookup.
Chose Prompt with filtered recipe details over Function/tool calls to fetch recipes dynamically.
Rationale: The prompt approach is quicker and cheaper for this workflow, though it limits recipe context.
Work with model randomness instead of forcing determinism.
Chose Context curation plus validation/retry over Trying to make the LLM deterministic.
Rationale: The team accepts model variability and mitigates it through context, validation, and expert review.
Use expert food review in addition to automated validation.
Chose Automated checks plus Head-of-Food sampling over Automated structure checks alone.
Rationale: JSON validity and recipe-ID grounding do not prove meal quality, flavor compatibility, or nutritional balance.
Gotchas (what bit them)
A chatbot interface would have been a poor fit for structured meal planning.
Root cause: Users would need to type repeatedly for a task that can be guided through structured rejection options.
Resolution: Use a structured meal-plan interface with LLM-generated predefined rejection options.
LLM call volume can erase consumer-app margin.
Root cause: A chat-based grocery workflow required hundreds of model calls per shop.
Resolution: Choose a meal-plan generation workflow that needs only a few calls per weekly plan.
The LLM could select recipes customers should not eat.
Root cause: If given the full recipe catalog, the model could make dietary or allergen mistakes.
Resolution: Filter recipes deterministically before prompting so the model only sees recipes the customer can eat.
LLM outputs fail structural checks often enough to need retries.
Root cause: Even with mitigations, generation can fail JSON or recipe-ID validation.
Resolution: Automatically retry failed plan generations and keep the call count low enough that retries remain acceptable.
Token limits force incomplete recipe context.
Root cause: The single-call prompt approach is cheaper and faster, but larger prompts mean only a subset of recipes can be included.
Resolution: Accept a random subset temporarily while planning to improve recipe selection.
Evaluation
Cherrypick evaluates the meal generator with automated JSON and recipe-ID validation, retry rates, expert food review, stored evaluations, prompt/template A/B tests, success metrics per variation, business metrics such as plan changes and basket usage, and future LLM-based evaluation and prompt improvement.
Metrics: Plan change rate · Basket usage · Perfect JSON structure · Recipe ID validity · Generation failure rate · Retry count · Quality · Nutritional balance · Flavor combinations · Weekly meal coherence · A/B test success metrics · LLM call cost · Tokens per interaction
4 supporting quotes
Outcomes
- Customers changed meal plans 30% less after the new LLM-powered generator launched.
- Customers used generated plans in their baskets 14% more.
- The system avoided the margin-killing call volume of a chat-based grocery assistant.
- The validation/retry layer made a 25% generation failure rate operationally acceptable.
- Stored evaluations and Liquid templates created an experimentation base for prompt/model comparison and future LLM evaluator automation.
Cherrypick reports 30% fewer plan changes, 14% more basket usage, a 25% generation failure rate requiring one or two retries, only a few LLM calls per meal plan, hundreds of calls per shop for the rejected WhatsApp approach, and thousands of stored generated plans for future evaluation automation.