Improving LLM Food Tracking Accuracy through Systematic Evaluation and Few-Shot Learning

taralli · Tech · 2025 · source Agentic: no · promotional bias: low · 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: LLM-powered nutrition extraction and evaluation-driven prompt optimization

Taralli's initial calorie-tracking endpoint returned schema-valid nutrition JSON but made severe semantic mistakes, especially around quantities such as treating 100g of peanut butter as 100 servings. The developer needed a practical way to turn real user failures into a golden dataset, evaluate output quality, optimize the prompt, and deploy the improved system without losing production logging.

Constraints:

Architecture

Taralli began with a FastAPI-style endpoint that sent a food description to GPT-4o-mini using structured outputs and a Pydantic nutrition schema. After observing failures, the developer used W&B Weave to log production inputs and outputs, curated a golden dataset from real mistakes with assistance from stronger models and manual editing, and defined a metric requiring calories within 10% plus food-group overlap. Baselines showed GPT-4o-mini at about 17% and Gemini 2.5 Flash zero-shot at about 25%. DSPy's BootstrapFewShotWithRandomSearch selected few-shot examples from training data and improved validation accuracy to about 76%. The optimized DSPy program was saved, loaded once at application startup, asyncified, deployed as /calories-v2, and kept under Weave logging for continued improvement.

Diagram confidence: reconstructed (reconstructed from prose).

flowchart LR
  User_food_description["User food description"] --> Calories_API_endpoint["Calories API endpoint"]
  Calories_API_endpoint --> GPT_4o_mini_structured_output["GPT-4o-mini structured output"]
  GPT_4o_mini_structured_output --> Pydantic_nutrition_schema["Pydantic nutrition schema"]
  GPT_4o_mini_structured_output --> W_B_Weave_logging["W&B Weave logging"]
  W_B_Weave_logging --> Golden_dataset_curation["Golden dataset curation"]
  Golden_dataset_curation --> o3_and_Gemini_2_5_Pro_assistants["o3 and Gemini 2.5 Pro assistants"]
  Golden_dataset_curation --> Dataset_visualizer["Dataset visualizer"]
  Golden_dataset_curation --> Train_validation_split["Train/validation split"]
  Train_validation_split --> Evaluation_metric["Evaluation metric"]
  Evaluation_metric --> DSPy_evaluator["DSPy evaluator"]
  DSPy_evaluator --> Gemini_2_5_Flash["Gemini 2.5 Flash"]
  DSPy_evaluator --> DSPy_optimizer["DSPy optimizer"]
  DSPy_optimizer --> DSPy_optimized_program["DSPy optimized program"]
  Gemini_2_5_Flash --> DSPy_optimized_program
  DSPy_optimized_program --> Calories_API_endpoint
  DSPy_optimized_program --> W_B_Weave_logging
  Calories_API_endpoint --> API_key_authentication["API key authentication"]
  DSPy_optimized_program --> Type_validation["Type validation"]
  Type_validation --> Pydantic_nutrition_schema
Drag to pan · scroll or use +/− to zoom · reconstructed from the source's described component topology

Components

Component Role Interacts with
User food description Free-text meal input such as '100g of peanut butter'. Calories API endpoint
Calories API endpoint Receives food descriptions and returns nutrition analysis responses. User food description, GPT-4o-mini structured output, DSPy optimized program, API key authentication
Pydantic nutrition schema Defines the structured NutritionAnalysis response with food items, calories, macros, quantity, and food groups. GPT-4o-mini structured output, DSPy optimized program, Type validation
GPT-4o-mini structured output Initial model implementation that produced schema-valid but semantically inaccurate nutrition outputs. Calories API endpoint, Pydantic nutrition schema, W&B Weave logging
W&B Weave logging Logs every input/output pair and continues tracing the improved endpoint. GPT-4o-mini structured output, Golden dataset curation, DSPy optimized program
Golden dataset curation Collects real failure cases, corrected nutritional outputs, and reviewed examples. W&B Weave logging, o3 and Gemini 2.5 Pro assistants, Dataset visualizer, Train/validation split
o3 and Gemini 2.5 Pro assistants Help generate accurate nutritional analyses for the golden dataset, with human review/editing. Golden dataset curation
Dataset visualizer Internal tool for viewing, editing, and updating golden dataset entries. Golden dataset curation
Train/validation split Separates optimization examples from held-out validation examples. Evaluation metric, DSPy optimizer
Evaluation metric Scores predictions based on calorie tolerance and food-group overlap. Train/validation split, DSPy evaluator
DSPy evaluator Runs concurrent evaluations against baselines and optimized programs. Evaluation metric, Gemini 2.5 Flash, DSPy optimizer
Gemini 2.5 Flash Cost-conscious model used for zero-shot baseline and optimized few-shot program. DSPy evaluator, DSPy optimized program
DSPy optimizer BootstrapFewShotWithRandomSearch optimizer selecting demonstrations for the prompt. Train/validation split, DSPy optimized program
DSPy optimized program Serialized few-shot classifier loaded by the production endpoint and asyncified for serving. Calories API endpoint, Gemini 2.5 Flash, W&B Weave logging, Type validation
API key authentication Protects the /calories-v2 endpoint. Calories API endpoint
Type validation Ensures model output is parsed as NutritionAnalysis before returning. Pydantic nutrition schema, DSPy optimized program

Data flow

A user submits a food description. The original endpoint sends it to GPT-4o-mini with a Pydantic structured-output schema and logs input/output pairs through W&B Weave. Logged failures are reviewed, corrected, and added to a golden dataset. The dataset is split into train/validation sets; a metric checks calorie tolerance and food-group overlap. DSPy evaluates baselines, runs BootstrapFewShotWithRandomSearch to select demonstrations, saves the optimized program, and the FastAPI /calories-v2 endpoint loads that program to return improved NutritionAnalysis outputs while continuing to log new examples.

3 supporting quotes
“All it did was take a user's food description as a string - pass it through gpt-4o-mini with structured outputs, and generate a JSON response.”article, stated
“Using W&B Weave and a simple decorator, I was able to log every input-output of the system.”article, stated
“After splitting my golden dataset into training and testing splits, and I had my metric ready, I could easily assess how well my current system was performing”article, stated

Why this architecture

The architecture follows a pragmatic evaluation flywheel: ship a simple structured-output model, log real use, turn observed failures into a golden dataset, define a metric aligned with the failures, optimize few-shot examples, and keep logging after deployment. This avoided guessing at prompt quality and converted real production mistakes into measurable improvement.

3 supporting quotes
“we shouldn't build complicated things before knowing if they're actually going to be used.”article, stated
“That allowed me to start capturing real-world examples of where the prompt was failing.”article, stated
“As more users interact with the app, I collect more data, I can correct/review that data and add it to my golden dataset.”article, stated

Models used: GPT-4o-mini · OpenAI o3 · Gemini 2.5 Pro · Gemini 2.5 Flash · DSPy Predict program · BootstrapFewShotWithRandomSearch

Scale

Alternatives considered (roads not taken)

Keep the naive GPT-4o-mini structured-output prompt

Rejected because: It was schema-compliant but only about 17% accurate on the validation set and made severe quantity mistakes.

“the model respected the format almost 100% of the time, cracks started showing pretty quickly”article, stated
“The score of my production system on the dataset was only about 17%, not great - we know.”article, stated

Switch to Gemini 2.5 Flash zero-shot

Rejected because: It improved the baseline but remained far below acceptable accuracy.

“Using this zero-shot approach, the score was about 25% - better than my GPT-4o mini implementation, but still far from acceptable for users.”article, stated

Design a highly refined metric upfront

Rejected because: A simple metric based on the observed failure modes was sufficient to guide meaningful improvement.

“My approach was very basic (again) - and could be even more refined.”article, stated
“Either it was calorie totals - or missing food groups.”article, stated

Optimize before shipping

Rejected because: The author's stated process was to ship early, learn from real failures, and then improve with monitoring and evals.

“My first step - is - as always - just put it out there. There are just too many unknowns to get stuck on the 0 to 1 stage.”article, stated
“Once things are out there, then it's time to start asking yourself: OK - what does good look like?”article, stated

Patterns

structured-output-contract (quality)

The system constrains model responses to a Pydantic NutritionAnalysis schema with food items, quantities, calories, macros, and food groups.

“pass it through gpt-4o-mini with structured outputs, and generate a JSON response.”article, stated
“Here's the Pydantic model that gives that JSON format”article, stated

observability-tracing (operations)

W&B Weave logs every food-analysis input/output pair so real failures can be inspected and turned into evaluation data.

“Using W&B Weave and a simple decorator, I was able to log every input-output of the system.”article, stated
“That allowed me to start capturing real-world examples of where the prompt was failing.”article, stated

data-quality-loop (data)

Production failures are reviewed, corrected, added to a golden dataset, and used to improve future prompts.

“I started collecting a golden dataset: a collection of food descriptions and their corresponding nutritional analysis.”article, stated
“As more users interact with the app, I collect more data, I can correct/review that data and add it to my golden dataset.”article, stated

eval-driven-development (quality)

A concrete metric and validation split guide baseline measurement, DSPy optimization, and production integration.

“Now that we have a metric - we can make number go up.”article, stated
“After splitting my golden dataset into training and testing splits, and I had my metric ready”article, stated

prompt-chaining (workflow-orchestration)

DSPy compiles a few-shot prompt/program from examples, then the saved program is loaded into the production API.

“This approach finds optimal examples from the training dataset to include in the prompt, which can dramatically improve performance.”article, stated
“it's essentially a few-shot approach to solving the problem, and it works surprisingly well.”article, stated

latency-optimization (operations)

The production integration loads the DSPy classifier once, asyncifies it, and uses Gemini 2.5 Flash to mitigate prompt-length latency.

“the optimized prompt includes several few-shot examples, which can impact response time.”article, stated
“using the relatively fast Gemini 2.5 Flash model, it doesn't matter that much.”article, stated

Tradeoffs

Initial product architecture

Chose ship a naive structured-output endpoint first over build complex LLMOps infrastructure before proving usage.

Rationale: The author prioritized validating that people would use the app, then improved quality based on real failures.

“we shouldn't build complicated things before knowing if they're actually going to be used.”article, stated
“Taralli's first system for calorie counting was embarrassingly simple.”article, stated

Metric simplicity

Chose 10% calorie tolerance plus food-group overlap over a more refined nutrition metric.

Rationale: The simple metric captured the dominant observed failures and was sufficient to drive large improvement.

“My approach was very basic (again) - and could be even more refined.”article, stated
“If the answer to both questions is 'Yes' - then the prediction is good.”article, stated

Few-shot optimized prompt

Chose DSPy BootstrapFewShotWithRandomSearch over zero-shot Gemini 2.5 Flash.

Rationale: The optimizer raised validation accuracy from roughly 25% to 75.9% by selecting demonstrations.

“Using this zero-shot approach, the score was about 25% - better than my GPT-4o mini implementation”article, stated
“After a few minutes of optimization and testing, we achieved 76% accuracy on our validation dataset”article, stated

Few-shot examples versus response time

Chose accept a larger few-shot prompt with Gemini 2.5 Flash over keep a shorter lower-accuracy prompt.

Rationale: The fast model made the latency hit acceptable for this use case.

“the optimized prompt includes several few-shot examples, which can impact response time.”article, stated
“using the relatively fast Gemini 2.5 Flash model, it doesn't matter that much.”article, stated

Gotchas (what bit them)

Schema-valid outputs can still be wildly wrong.

Root cause: The model followed the JSON format but misinterpreted quantities as multipliers.

Resolution: Create a semantic evaluation metric and optimize examples against real quantity failures.

“the model respected the format almost 100% of the time, cracks started showing pretty quickly”article, stated
“It should have set name to "100g of peanut butter" and quantity to 1.”article, stated

Synthetic assumptions would miss real user edge cases.

Root cause: Failures emerged from actual user inputs after launch.

Resolution: Log production input/output pairs and curate the golden dataset from observed failures.

“I did warn users that I was logging all of their inputs into the food tracking model.”article, stated
“That allowed me to start capturing real-world examples of where the prompt was failing.”article, stated

A model swap alone did not solve accuracy.

Root cause: Gemini 2.5 Flash zero-shot improved over GPT-4o-mini but remained far from acceptable.

Resolution: Use DSPy few-shot optimization rather than relying on zero-shot model selection.

“Using this zero-shot approach, the score was about 25% - better than my GPT-4o mini implementation, but still far from acceptable for users.”article, stated
“I decided to try another DSPy optimization technique called BootstrapFewShotWithRandomSearch.”article, stated

Few-shot optimization adds latency pressure.

Root cause: The optimized prompt includes several examples, increasing token count.

Resolution: Use a relatively fast model and load/asyncify the optimized DSPy program in the API.

“There is a trade-off: the optimized prompt includes several few-shot examples, which can impact response time.”article, stated
“since we're using the relatively fast Gemini 2.5 Flash model, it doesn't matter that much.”article, stated

The improved system is not finished despite a large lift.

Root cause: A 76% validation score still leaves a meaningful error rate and the validation set is small.

Resolution: Keep Weave logging and add new reviewed data to the golden dataset as more users interact.

“After a few minutes of optimization and testing, we achieved 76% accuracy on our validation dataset”article, stated
“Still room for improvement though!”article, stated

Evaluation

The author built a golden dataset from real logged failures, split it into training and validation sets, and used a binary metric requiring both calorie totals within 10% and food-group overlap. Baselines were measured for GPT-4o-mini and zero-shot Gemini 2.5 Flash before DSPy's BootstrapFewShotWithRandomSearch optimized few-shot demonstrations.

Metrics: calorie totals within 10% of the golden example · predicted food groups overlap expected food groups · GPT-4o-mini production baseline: 17.24% · Gemini 2.5 Flash zero-shot baseline: about 25% · DSPy optimized validation score: 22/29, 75.9% · format compliance: almost 100%

4 supporting quotes
“Is the total calories of the prediction within 10% of the total calories of the golden example?”article, stated
“Is there an overlap between the food groups of the golden example vs. the predicted one?”article, stated
“Score: 17.24%` The score of my production system on the dataset was only about 17%, not great - we know.”article, stated
“Average Metric: 22.00 / 29 (75.9%): 100%|██████████| 29/29 [00:00<00:00, 3096.37it/s]”article, stated

Outcomes

This is a small independent application, not a large-enterprise system. Its value is the clarity of the LLMOps loop: production traces, golden data, metric, baseline, optimization, deployment, and continued logging.

4 supporting quotes
“After some work, I managed to improve tracking accuracy from 17% to 76%.”article, stated
“Prediction(food_items=[FoodItem(name='Peanut butter (100g)', quantity=1.0, calories=588.0”article, stated
“I integrated this new API endpoint, and now all users of the app benefit from our improved food prediction model”article, stated
“This flywheel allows me to continuously update the prompt as we go.”article, stated