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:

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
Drag to pan · scroll or use +/− to zoom · reconstructed from the source's described component topology

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
“Instead with each prompt we send the customer the details of only the recipes the customer can actually eat.”article, stated
“Customers can reject a meal with a pre-defined set of options, that are generated by the LLM along with the plan.”article, stated
“We verified perfect JSON structure in all responses and checked recipe IDs against our provided context”article, stated

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
“For our meal planning feature, we needed the model to understand dietary preferences, combine compatible recipes, and generate natural explanations”article, stated
“They are overkill for simpler problems that could be solved with traditional programming or basic ML approaches.”article, stated
“Too many applications are poorly thought through and end up becoming cool demos for investor decks or just another chatbot.”article, stated

Models used: LLMs · LLM judges · Liquid templates

Scale

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.

“It would have been difficult to get this kind of impact using another method.”article, stated
“tasks that clearly benefited from an LLM’s capabilities.”article, stated

Build a chatbot interface

Rejected because: Chat felt forced for structured meal planning, created typing fatigue, and would have increased LLM call costs.

“The first instinct of most teams building with LLMs has been to build a chatbot. Resist this urge.”article, stated
“This creates friction in the user experience that can lead to decreased engagement over time.”article, stated

WhatsApp grocery chatbot

Rejected because: It worked, but hundreds of LLM calls per shop would have erased profit margin.

“We experimented with chat-based grocery tools in 2023.”article, stated
“hundreds of calls per shop, which would have entirely eroded our profit margin from that shop.”article, stated

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.

“We could have given the model a full list of recipes and asked it to select the best ones”article, stated
“selecting recipes that were obviously wrong, or (worse) choosing recipes that were harmful for the customer to eat.”article, stated

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.

“We explored avoiding using the prompt, and instead use tools (previously called function calling) to find particular types of recipes”article, stated
“We eventually chose to use the prompt as it is quicker and cheaper - only one LLM call is required.”article, stated

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.

“Instead of fighting against the model’s variability, we learned to work with it. The key was providing the right context. For us, this meant carefully curating what we sent to the LLM.”article, stated
“To get around this, we did not send the model the full list. Instead with each prompt we send the customer the details of only the recipes the customer can actually eat. This avoiding wasting tokens on recipes that should never be selected.”article, stated

guardrails-io-filtering (reliability)

Automated validation enforces perfect JSON and checks recipe IDs against supplied context before a plan reaches the user.

“Our first line of defense was automated validation. We verified perfect JSON structure in all responses and checked recipe IDs against our provided context to ensure they were not hallucinated by the LLM.”article, stated
“We verified perfect JSON structure in all responses and checked recipe IDs against our provided context to ensure they were not hallucinated by the LLM. When generations failed, our system automatically retried the plan.”article, stated

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.

“We built a multi-layered evaluation system to manage this. For more on how to do this, see Eugene Yan’s excellent eval articles and Hamel Husain’s definitive guide on building LLM Judges.”article, stated
“All evaluations were stored to build training data for future improvements. We kept version of our templates for A/B testing and tracked success metrics for each variation. Regular prompt refinement, based on this accumulated feedback, helped us continuously enhance the system’s performance.”article, stated

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.

“The next evaluation layer was expert review by a person. Our Head of Food Sophie assesses a sample of generated plans for quality and nutritional balance.”article, stated
“Our Head of Food Sophie assesses a sample of generated plans for quality and nutritional balance. She looked at flavor combinations and ensured the meals would work well together over the week.”article, stated

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.

“All evaluations were stored to build training data for future improvements. We kept version of our templates for A/B testing and tracked success metrics for each variation. Regular prompt refinement, based on this accumulated feedback, helped us continuously enhance the system’s performance.”article, stated
“By using Liquid templates for our prompts, it was straightforward to continue to include the same data in each prompt run”article, stated

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.

“Another reason not to use chatbots is that they typically require multiple LLM calls for each interaction as the conversation progresses.”article, stated
“We eventually chose to use the prompt as it is quicker and cheaper - only one LLM call is required. This means larger prompts with more tokens, but it works reliably for our use case and gives us confidence in the system’s effectiveness.”article, stated

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.

“The process of generating a plan and then tweaking and improving it is a natural back-and-forth interaction that does not require constant typing from users.”article, stated
“Customers can reject a meal with a pre-defined set of options, that are generated by the LLM along with the plan.”article, stated

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.

“To get around this, we did not send the model the full list. Instead with each prompt we send the customer the details of only the recipes the customer can actually eat. This avoiding wasting tokens on recipes that should never be selected.”article, stated
“To get around this, we did not send the model the full list. Instead with each prompt we send the customer the details of only the recipes the customer can actually eat. This avoiding wasting tokens on recipes that should never be selected.”article, stated

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.

“We explored avoiding using the prompt, and instead use tools (previously called function calling) to find particular types of recipes”article, stated
“This means larger prompts with more tokens, but it works reliably for our use case and gives us confidence in the system’s effectiveness.”article, stated

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.

“Many developers initially try to force these models into producing deterministic output all the time. This is a mistake”article, stated
“Instead of fighting against the model’s variability, we learned to work with it. The key was providing the right context. For us, this meant carefully curating what we sent to the LLM.”article, stated

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.

“She looked at flavor combinations and ensured the meals would work well together over the week. This helps maintain high standards that automated checks alone could not guarantee.”article, stated
“This helps maintain high standards that automated checks alone could not guarantee.”article, stated

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.

“Chatting works well for open-ended discussions, and therefore naturally lends itself to customer support interfaces for example.”article, stated
“The interaction model of chatbots often feels unnatural for many common tasks. Chatting works well for open-ended discussions, and therefore naturally lends itself to customer support interfaces for example. However, it can feel forced and cumbersome for more structured interactions.”article, stated

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.

“However we realised that to provide a good service we would need to make hundreds of calls per shop, which would have entirely eroded our profit margin from that shop.”article, stated
“It requires only a few LLM calls per meal plan generation, versus dozens of messages in a typical chat session.”article, stated

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.

“This could have caused many problems if the model made mistakes, selecting recipes that were obviously wrong, or (worse) choosing recipes that were harmful for the customer to eat.”article, stated
“This could have caused many problems if the model made mistakes, selecting recipes that were obviously wrong, or (worse) choosing recipes that were harmful for the customer to eat.”article, stated

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.

“When generations failed, our system automatically retried the plan. 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
“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

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.

“The disadvantage is that we can only send a subset of recipes in order to keep the token count manageable. This is a random set at the moment, but we are working on improving this.”article, stated
“This is a random set at the moment, but we are working on improving this.”article, stated

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
“It has been a great success and we are pleased with the results. Customers are changing their plans 30% less and using their plans in their baskets 14% more.”article, stated
“We verified perfect JSON structure in all responses and checked recipe IDs against our provided context to ensure they were not hallucinated by the LLM.”article, stated
“Our Head of Food Sophie assesses a sample of generated plans for quality and nutritional balance. She looked at flavor combinations and ensured the meals would work well together over the week.”article, stated
“All evaluations were stored to build training data for future improvements. We kept version of our templates for A/B testing and tracked success metrics for each variation. Regular prompt refinement, based on this accumulated feedback, helped us continuously enhance the system’s performance.”article, stated

Outcomes

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.

3 supporting quotes
“It has been a great success and we are pleased with the results. Customers are changing their plans 30% less and using their plans in their baskets 14% more.”article, stated
“As only only LLM call is required per plan or change, we decided this was an acceptable level of speed and cost.”article, stated
“We have thousands of generated plans stored along with automatic and expert evaluations, so it is now possible to prompt an LLM with sufficient examples to learn how to both evaluate plans and improve prompts.”article, stated