From 472a3034a032305ed871ec5654a0d148614c6ed6 Mon Sep 17 00:00:00 2001 From: Piotr Oleszczyk Date: Wed, 4 Mar 2026 02:22:39 +0100 Subject: [PATCH] feat(routines): refine therapeutic and travel-mode prompt rules --- backend/innercontext/api/routines.py | 61 +++++++++++++++++++--------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/backend/innercontext/api/routines.py b/backend/innercontext/api/routines.py index 3292ca1..c71fd00 100644 --- a/backend/innercontext/api/routines.py +++ b/backend/innercontext/api/routines.py @@ -414,11 +414,14 @@ CEL: Twórz realistyczne, bezpieczne i krótkie rutyny o wysokiej zgodności z danymi wejściowymi. PRIORYTETY DECYZYJNE (od najwyższego): -1) Bezpieczeństwo i przeciwwskazania -2) Zgodność ze schematem JSON i listą dostępnych produktów -3) Reguły częstotliwości oraz odstępów czasowych -4) Cel użytkownika (np. broda/wąsy, nawilżenie, tolerancja) -5) Prostota rutyny +1) Bezpieczeństwo (brak realnego ryzyka klinicznego) +2) Cel terapeutyczny użytkownika +3) Reguły częstotliwości i odstępów +4) Zarządzanie inwentarzem +5) Prostota + +> Cel terapeutyczny oznacza maksymalizację realnego efektu klinicznego, +> nie tylko zgodność z deklarowanymi targetami produktu. WYMAGANIA ODPOWIEDZI: - Zwracaj wyłącznie poprawny JSON (bez markdown, bez komentarzy, bez preambuły). @@ -432,12 +435,23 @@ ZASADY PLANOWANIA: - Respektuj: incompatible_with (same_step / same_day / same_period), context_rules, min_interval_hours, max_frequency_per_week, usage_notes. - Zarządzanie inwentarzem: - - najpierw zużywaj produkty już otwarte, - - minimalizuj liczbę jednocześnie otwartych produktów funkcjonalnie podobnych, - - nie rozpoczynaj nowego produktu, jeśli istnieje funkcjonalny odpowiednik otwarty i kompatybilny, - - JEDNAKŻE: jeśli zamknięty produkt drastycznie lepiej odpowiada na aktualne priorytety i stan skóry niż jakikolwiek otwarty, możesz zaproponować jego otwarcie. - - jeśli nearest_open_pao_deadline lub nearest_open_expiry jest dostępne, preferuj produkt z wcześniejszą datą w swojej kategorii, - - rotuj tylko gdy daje to wartość terapeutyczną. + - Preferuj produkty już otwarte (miękka preferencja). + - Zamknięty produkt otwieraj tylko wtedy, gdy: + a) bezpieczeństwo jest zachowane oraz + b) daje wyraźnie lepszy efekt terapeutyczny dla głównego priorytetu + (>= +1 poziom siły w effect_profile) lub wnosi inną klinicznie istotną klasę aktywną. + - Jeśli istnieje porównywalny produkt otwarty (różnica < +1 poziomu), + nie otwieraj nowego. + - nearest_open_pao_deadline i nearest_open_expiry wykorzystuj jako tie-breaker + między produktami już otwartymi. +- Unikaj funkcjonalnej redundancji (np. wielokrotne źródła panthenolu, ceramidów lub niacynamidu w tej samej rutynie), + chyba że istnieje wyraźne uzasadnienie terapeutyczne. +- Maksymalnie 2 serum w rutynie. + Jeśli 2: jedno jako główny aktywny bodziec, drugie wyłącznie wspierające. +- Dla mildly_compromised nie eliminuj automatycznie umiarkowanych aktywnych; + decyzję opieraj na effect_profile (irritation_risk, barrier_disruption_risk) i regułach bezpieczeństwa. +- Nie zwiększaj intensywności terapii (retinoid/kwasy) dzień po dniu, + jeśli brak wyraźnej poprawy stanu skóry lub brak wskazań klinicznych. - Nie łącz retinoidów i kwasów w tej samej rutynie ani tego samego dnia (dla planu wielodniowego). - W AM zawsze uwzględnij SPF, jeśli kompatybilny produkt SPF istnieje na liście. Wybór filtra (na podstawie KONTEKST DNIA): @@ -454,9 +468,12 @@ ZASADY PLANOWANIA: Dla standardowych kroków pielęgnacji całej twarzy pozostaw region puste. JAK ROZWIĄZYWAĆ KONFLIKTY: -- Gdy cel użytkownika koliduje z bezpieczeństwem, wybierz bezpieczeństwo. -- Gdy dwa produkty są podobne, wybierz łagodniejszy lub prostszy wariant. -- Gdy dane są niepełne lub niejednoznaczne, wybierz wariant konserwatywny. +- Bezpieczeństwo > wszystko. +- Jeśli MODE=travel: logistyka podróży > różnorodność terapeutyczna. +- W MODE=travel odejdź od minimalizacji produktów tylko gdy wymaga tego bezpieczeństwo + lub bez dodatkowego produktu nie da się osiągnąć głównego celu terapeutycznego. +- Jeśli MODE=standard i bezpieczeństwo jest zachowane, preferuj różnorodność terapeutyczną. +- Przy niepełnych danych wybierz wariant konserwatywny. """ @@ -545,15 +562,17 @@ def suggest_routine( ) objectives_ctx = _build_objectives_context(data.include_minoxidil_beard) - notes_line = f"\nUSER CONTEXT: {data.notes}\n" if data.notes else "" + mode_line = "MODE: standard" + notes_line = f"USER CONTEXT: {data.notes}\n" if data.notes else "" day_name = _DAY_NAMES[weekday] prompt = ( f"Zaproponuj rutynę pielęgnacyjną {data.part_of_day.value.upper()} " f"na {data.routine_date} ({day_name}).\n\n" + f"{mode_line}\n" "INPUT DATA:\n" f"{skin_ctx}\n{grooming_ctx}\n{history_ctx}\n{day_ctx}\n{products_ctx}\n{objectives_ctx}" - f"{notes_line}\n" + f"{notes_line}" f"{_ROUTINES_SINGLE_EXTRA}\n" "Zwróć JSON zgodny ze schematem." ) @@ -643,15 +662,19 @@ def suggest_batch( date_range_lines.append(f" {d} ({_DAY_NAMES[d.weekday()]})") dates_str = "\n".join(date_range_lines) - notes_line = f"\nUSER CONTEXT: {data.notes}\n" if data.notes else "" + notes_line = f"USER CONTEXT: {data.notes}\n" if data.notes else "" + mode_line = "MODE: travel" if data.minimize_products else "MODE: standard" minimize_line = ( - "\nCONSTRAINTS:\n - Minimize number of unique products (reuse the same products multiple times)\n" + "\nCONSTRAINTS (TRAVEL MODE):\n" + "- To tryb podróżny: minimalizuj liczbę unikalnych produktów w całym planie (wszystkie dni, AM+PM).\n" + "- Preferuj reużycie tych samych produktów między dniami, jeśli bezpieczeństwo i główny cel terapeutyczny są zachowane.\n" + "- Dodaj nowy produkt tylko gdy to konieczne dla bezpieczeństwa albo realizacji głównego celu terapeutycznego.\n" if data.minimize_products else "" ) prompt = ( - f"Zaproponuj plan pielęgnacji AM + PM dla każdego dnia z zakresu:\n{dates_str}\n\n" + f"Zaproponuj plan pielęgnacji AM + PM dla każdego dnia z zakresu:\n{dates_str}\n\n{mode_line}\n" "INPUT DATA:\n" f"{skin_ctx}\n{grooming_ctx}\n{history_ctx}\n{products_ctx}\n{objectives_ctx}" f"{notes_line}{minimize_line}"