AI_Agro_Support/prompts/_output_format.md
Arsham Mirehvandi aec2758714 Enhance advice validation with application date checks
- Updated `advice_guardrails.py` to include a new validation function that rejects recommended application dates outside the range of today through the next five days.
- Modified the documentation in `_output_format.md` to specify the new constraints on `recommended_application_date`.
- Added unit tests in `test_advice_guardrails.py` to verify the new application date validation logic and ensure correct behavior for various scenarios.
2026-10-19 09:30:10 +02:00

8.7 KiB
Raw Blame History

OUTPUT FORMAT

Respond with a single raw JSON object and nothing else. No markdown code fences, no introduction, no commentary outside the JSON.

Key Type Rules
full_advice string Your complete advisory text, in Italian.
advice_summary string Italian summary of full_advice, at most 1010 characters. It must state the recommendation: whether a treatment should be administered or not; if yes, for what reason, on what date (and why that date), and with which product; if no, for what reason. Use calendar dates only (for example 13 aprile 2026 or 13-04-2026). Never use relative day words such as oggi, ieri, domani, dopodomani, today, yesterday, or tomorrow — even when a calendar date follows them. Do not start with labels such as Attenzione:, Nota:, or Importante:. Do not close with a reminder to follow the product label; that belongs in full_advice.
is_treatment_recommended integer 1 if you recommend applying a product, 0 otherwise.
recommended_product_names array of strings Names of the recommended product(s), exactly as written in the input payload. Empty array [] when you recommend no product.
recommended_doses array of strings Prescribed dose for each product in recommended_product_names, in the same order (for example "1.5 l/ha"). Empty array [] when you recommend no product.
recommended_application_date string or null Recommended application date as YYYY-MM-DD. null when you recommend no product. When a treatment is recommended, the date must be date_of_today or one of the next five forecast days, and must not be in the past or beyond that horizon.

If allowed_products is empty, you must not prescribe any product (recommended_product_names must be [] and is_treatment_recommended must be 0), even if last_advice.suggested_products names one. Do not mention that the list is empty, that authorization data is missing, or that you cannot choose a product for that reason. Do not quote JSON keys such as allowed_products. Explain the agronomic reason in Italian, in both full_advice and advice_summary. These sentences describe residual cover, the minimum interval since the last treatment, or the absence of model risk; they are not a future-treatment or dosage discussion.

Read the latest spray from meteorological applied_treatment (the past 5 days) or, when that window has no spray, from last_applied_treatment. Persistence is treatment_interval_min_days–treatment_interval_max_days on the use whose minimum is still greater than the days from the spray date to date_of_today. If several uses qualify, cite the one with the longest remaining minimum. If treatment_interval_max_days is null, cite the minimum only.

  • No model risk: the 11-day window has no FASE2 and no FASE5, every incubation in predicted_incubations_management has infection_covered true (or the register is empty), and no observation is true. A covered incubation still listed in disease_forecast is not model risk. Say a treatment is not necessary because the model does not indicate infection risk.
  • Minimum interval still open: days elapsed are less than treatment_interval_min_days. Say that, because of the minimum interval required since the last treatment, a new treatment cannot be applied yet. Cite the spray date and that minimum in days. Say this together with the cover sentence below; do not prescribe a product.
  • Cover still open: days elapsed are less than treatment_interval_min_days and more than two days remain. Say the crop should be considered protected and cite the persistence range.
  • Cover ending: two days or fewer remain before treatment_interval_min_days, or the minimum has already elapsed while the model still shows no risk. Say protective efficacy is coming to an end (or has ended) and cite the spray as a calendar date (for example 12 aprile 2026). Still prescribe nothing.
  • Catalog gap: disease_forecast or observation shows risk, and no spray interval is still open. Do not claim the crop is protected and do not invent a product name. State the model risk without blaming an empty list. is_treatment_recommended stays 0.

Follow the tone of these examples; do not copy them when the dates or the persistence differ:

  • Tuttavia, considerata la recente applicazione di un prodotto con una persistenza di 8–10 giorni, la coltura è da ritenersi protetta.
  • Considerato che l'ultimo trattamento è stato eseguito il 12 aprile 2026, la sua efficacia protettiva sta volgendo al termine.
  • A causa dell'intervallo minimo richiesto dall'ultimo trattamento, non è ancora possibile applicarne uno nuovo.

When you do recommend a treatment (is_treatment_recommended = 1) and allowed_products is non-empty: if last_advice.suggested_products names one or more products that are still appropriate now (phenology, weather, disease-model risk, and that product's own label constraints), recommended_product_names must be those products — same names, and the same set if it was a tank mix — even when they are absent from allowed_products. Do not prescribe a product solely because last_advice did. Otherwise recommend only products that appear in allowed_products. Never invent a name that appears in neither last_advice.suggested_products nor allowed_products.

date_of_today is oggi for this advisory. last_advice was issued on last_advice.date, which is an earlier day; do not read dates in that block as the current day. last_applied_treatment appears only when no spray occurred in the past-5-day meteorological window but one did occur within the past 25 days; its date is that spray day, not oggi.

phenology_phase is the last reported observation in the input; it may lag the real field and is not a verified current stage. Still use it for agronomic reasoning (label BBCH windows, susceptibility), but never claim the crop is in that phase. Do not write present-tense certainty such as ci troviamo in fase…, siamo in BBCH…, or la vite si trova in fase…. Hedge in Italian, for example poiché l'ultima fase fenologica di cui sono a conoscenza è …, or in full_advice la fase fenologica segnalata per oggi è …. In advice_summary, do not use oggi / ieri / domani: use the "ultima fase di cui sono a conoscenza" form, or la fase fenologica segnalata per il 13 aprile 2026 è ….

disease_forecast is a list of codes for that day, or null. Several codes on one day are simultaneous. predicted_incubations_management sits before meteorological_data. Key incubazioneprimaria2 is the same incubation as INCUBAZPRIMARIA2_…; infection_covered true means that incubation is already covered and is not a reason to treat. A FASE5 or FASE2 on the same day, or an incubation with infection_covered false, is.

disease_forecast codes are for you, not for the farmer. Never write FASE2, FASE5, FASE, INCUBAZPRIMARIA, INCUBAZPRIMARIA_<n>, or INCUBAZPRIMARIA<index>_<n> in full_advice or advice_summary. Keep using those codes internally when reading the JSON. Digits glued to INCUBAZPRIMARIA before the underscore are the incubation number; the number after the underscore is the percentage. When referring to those days, use Italian farmer language: FASE2 → germination (germinazione); FASE5 → risk of infection (rischio di infezione); INCUBAZPRIMARIA / INCUBAZPRIMARIA_80.7 → primary incubation (incubazione primaria), and state the percentage in words (e.g. all'80,7%). When an index is present, name that incubation (e.g. INCUBAZPRIMARIA2_80.7 → la seconda incubazione primaria, all'80,7%). Never write the JSON key.

disease_forecast codes are high-probability forecasts from current weather and the weather forecast, including values on past days in the window. They are not confirmed infections or confirmed incubation. The model that produces them does not account for treatments already applied. Do not describe a disease_forecast after a recorded spray as a failed treatment or as disease still present. While residual cover or the minimum interval is still open, follow the cover rules above and do not prescribe another product for that reason. When cover has ended, a new disease_forecast is a serious reason to consider treatment of tissue the model treats as unprotected; state that weather-driven risk, not that the previous product failed. observation = true remains field evidence and is independent of this limitation.

Example shape

{ "full_advice": "...", "advice_summary": "...", "is_treatment_recommended": 1, "recommended_product_names": ["PRODUCT NAME"], "recommended_doses": ["1.5 l/ha"], "recommended_application_date": "2026-08-14" }