Files
Ai/docs/yield_harvest_pcse_rag_api_plan.md
2026-04-29 23:54:30 +03:30

20 KiB

راهنمای پیاده‌سازی API صفحه Yield & Harvest با PCSE و RAG

این فایل برای تیم بک‌اند نوشته شده تا صفحه yield-harvest را با تکیه بر:

  • مستند psce_doc.txt پروژه
  • سرویس‌های موجود در crop_simulation/
  • معماری فعلی RAG در rag/

به شکل قابل اتکا پیاده‌سازی کند.

نکته: فایل psce_doc.txt در عمل مستند PCSE است و در این سند هم با عنوان PCSE به آن اشاره می‌شود.


جمع‌بندی سریع

برای این صفحه، بهترین معماری این است:

  1. عددها، تاریخ‌ها، درصدها و سری‌های نمودار از PCSE و داده‌های مزرعه ساخته شوند.
  2. RAG فقط برای متن‌های توضیحی، خلاصه‌سازی، و wording کاربرپسند استفاده شود.
  3. RAG اجازه نداشته باشد عدد جدید، تاریخ جدید، یا KPI جدید اختراع کند.
  4. یک endpoint خلاصه برای فرانت برگردانده شود:

GET /api/yield-harvest/summary/?farm_uuid=<uuid>

اگر لازم شد از نظر convention داخلی پروژه همه‌چیز داخل crop_simulation بماند، می‌توانید معادل زیر را هم نگه دارید:

GET /api/crop-simulation/yield-harvest-summary/?farm_uuid=<uuid>

برای فرانت فعلی، مدل summary بهتر از چند endpoint پراکنده است.


چیزی که همین الان در پروژه دارید

لایه PCSE / شبیه‌سازی

الان پروژه این اجزا را دارد:

  • crop_simulation/services.py
  • crop_simulation/growth_simulation.py
  • crop_simulation/harvest_prediction.py
  • crop_simulation/yield_prediction.py

و همین حالا از PCSE این خروجی‌ها را می‌سازید:

  • yield از TWSO
  • biomass از TAGP
  • leaf_area_index از LAI
  • development_stage از DVS
  • soil_moisture از SM

این دقیقاً با چیزی که در psce_doc.txt آمده هم‌راستا است: PCSE برای state/rate variables و خروجی روزانه مناسب است و برای ساخت KPI، trend و harvest timing گزینه خوبی است.

لایه RAG

الان پروژه الگوی خوبی برای سرویس‌های ترکیبی deterministic + RAG دارد:

  • rag/services/irrigation.py
  • rag/services/fertilization.py
  • rag/chat.py
  • config/rag_config.yaml

الگوی درست در این پروژه این است:

  • اول عددها و تصمیم‌های پایه از منطق deterministic ساخته می‌شوند
  • بعد RAG فقط متن نهایی را polish می‌کند
  • در صورت خراب شدن خروجی LLM، fallback ساختاریافته دارید

برای yield-harvest هم باید دقیقاً همین الگو تکرار شود.


اصل طراحی مهم

چه چیزی باید deterministic باشد

این فیلدها نباید از RAG بیایند:

  • daysUntil
  • readiness
  • share
  • series[].data
  • averageReadiness
  • predicted yield
  • harvest date
  • هر عددی که در progress bar، chart، KPI یا sorting استفاده می‌شود

چه چیزی می‌تواند از RAG بیاید

این فیلدها مناسب RAG هستند:

  • season_highlights_card.subtitle
  • season_highlights_card.spotlight.caption
  • harvest_prediction_card.description
  • harvest_operations_card.summary
  • steps[].note
  • badgeها و labelهای توصیفی کوتاه

قانون طلایی

RAG باید فقط روی context قطعی زیر کار کند:

  • farm details
  • خروجی‌های PCSE
  • داده‌های آب‌وهوا
  • داده‌های سنسور
  • در صورت وجود: داده کیفیت، آفات، اقتصاد، بازار

و prompt آن باید صریح بگوید:

  • عدد جدید نساز
  • فقط از مقادیر داده‌شده استفاده کن
  • اگر داده کافی نیست، کمبود را بگو
  • خروجی را در JSON معتبر برگردان

پیشنهاد معماری برای این صفحه

بهترین راه این است که یک orchestrator service جدید بسازید:

  • crop_simulation/yield_harvest_summary.py

و داخل آن چند builder کوچک داشته باشید:

  • _build_yield_prediction_block()
  • _build_harvest_prediction_block()
  • _build_yield_prediction_chart_block()
  • _build_harvest_readiness_zones_block()
  • _build_yield_quality_bands_block()
  • _build_harvest_operations_block()
  • _build_season_highlights_block()

و یک facade نهایی:

  • YieldHarvestSummaryService.get_summary(farm_uuid, season_year=None, crop_name=None)

این service باید:

  1. داده مزرعه را از farm_data.services.get_farm_details() بگیرد.
  2. خروجی شبیه‌سازی را از CurrentFarmChartSimulator و سرویس‌های فعلی بگیرد.
  3. بلوک‌های deterministic را بسازد.
  4. اگر RAG فعال بود، متن‌های narrative را enrich کند.
  5. یک payload نهایی برای فرانت برگرداند.

Mapping پیشنهادی هر کارت به منبع داده

بلوک منبع اصلی وضعیت امکان پیاده‌سازی
yield_prediction crop_simulation/yield_prediction.py + chart metrics قابل پیاده‌سازی همین الآن
harvest_prediction_card crop_simulation/harvest_prediction.py قابل پیاده‌سازی همین الآن
yield_prediction_chart CurrentFarmChartSimulator + historical baseline نیمه‌آماده، نیاز به تصمیم درباره سری مقایسه‌ای
season_highlights_card aggregate از بقیه بلوک‌ها + RAG قابل پیاده‌سازی اگر بقیه بلوک‌ها حاضر باشند
harvest_readiness_zones داده قطعه/زون + PCSE per zone فعلاً gap داده‌ای دارد
yield_quality_bands quality model / grading rules / lab data فعلاً gap داده‌ای دارد
harvest_operations_card rules + optimizer + RAG قابل پیاده‌سازی به‌صورت اولیه

نکته مهم: همه بلوک‌ها را PCSE به‌تنهایی تولید نمی‌کند

PCSE برای این بخش‌ها خیلی مناسب است:

  • زمان برداشت
  • روند رشد
  • عملکرد پیش‌بینی‌شده
  • stage / maturity / readiness proxy
  • trend chart

اما PCSE به‌صورت پیش‌فرض برای این‌ها کافی نیست:

  • بریکس
  • گرید ممتاز / درجه یک / فرآوری
  • پتانسیل صادرات
  • قیمت فروش
  • premium
  • readiness per block وقتی مدل block-level ندارید

پس برای صفحه کامل، باید سه لایه را از هم جدا ببینید:

  1. PCSE layer: عددهای زیستی و رشد
  2. Rules/Aggregation layer: تبدیل خروجی PCSE به KPIهای محصولی
  3. RAG layer: توضیح، جمع‌بندی، و متن قابل نمایش

طراحی endpoint پیشنهادی

Route

پیشنهاد اصلی:

  • GET /api/yield-harvest/summary/?farm_uuid=<uuid>&season_year=1404&crop_name=wheat

Query params

  • farm_uuid: اجباری
  • season_year: اختیاری
  • crop_name: اختیاری
  • include_narrative: اختیاری، پیش‌فرض true

چرا include_narrative خوب است

چون اگر RAG کند یا موقتاً غیرفعال باشد، باز هم فرانت می‌تواند با داده deterministic رندر شود.


ساختار پیشنهادی response

همان envelope فعلی پروژه مناسب است:

{
  "code": 200,
  "msg": "success",
  "data": {
    "farm_uuid": "11111111-1111-1111-1111-111111111111",
    "season_highlights_card": {},
    "yield_prediction": {},
    "harvest_prediction_card": {},
    "harvest_readiness_zones": {},
    "yield_quality_bands": {},
    "harvest_operations_card": {},
    "yield_prediction_chart": {}
  }
}

پیشنهاد فنی برای ساخت هر بلوک

1) yield_prediction

منبع

  • YieldPredictionService
  • یا مستقیم CurrentFarmChartSimulator.simulate()

منطق پیشنهادی

  • predicted yield از TWSO
  • harvest readiness از DVS و فاصله تا maturity
  • quality score فعلاً rule-based، نه RAG-based
  • loss risk از ترکیب moisture/weather/pest signals اگر دارید، وگرنه با fallback ساده

توصیه

اگر الآن فقط داده قطعی می‌خواهید:

  • KPI اول را دقیق بسازید
  • KPIهای دوم تا چهارم را با rules ساده و شفاف بسازید
  • آن‌ها را به عنوان estimated در کد داخلی mark کنید

2) harvest_prediction_card

منبع

  • crop_simulation/harvest_prediction.py

وضعیت

این بلوک تقریباً آماده است.

توصیه

  • dateFormatted را از serializer-ready formatter بگیرید
  • daysUntil حتماً number بماند
  • متن description اگر خواستید با RAG بهتر شود، version deterministic را هم نگه دارید

یعنی بهتر است این دو فیلد را داشته باشید:

  • description
  • descriptionSource = "deterministic" | "rag"

این source flag برای debugging خیلی کمک می‌کند.


3) yield_prediction_chart

واقعیت فعلی

خروجی chart فعلی شما در CurrentFarmChartSimulator بیشتر این‌ها را می‌دهد:

  • leaf count estimate
  • biomass
  • storage organ weight
  • lai
  • soil moisture

اما payload فرانت yield-harvest در سند شما نمودار سال قبل / سال جاری می‌خواهد.

نتیجه

این بخش هنوز one-to-one با کد فعلی آماده نیست.

راه درست

یکی از این دو مسیر را انتخاب کنید:

مسیر A - سریع‌تر

همان chart فعلی را به contract فرانت نزدیک کنید و فعلاً به‌جای سال قبل/سال جاری از:

  • عملکرد تجمعی پیش‌بینی‌شده
  • بیوماس

استفاده کنید.

مسیر B - محصولی‌تر

دو سری واقعی تولید کنید:

  • سال جاری: از simulation جاری
  • سال قبل: از historical scenario یا historical harvest data

اگر داده سال قبل ندارید، این سری را fake نکنید.

توصیه نهایی

برای production بهتر است تا وقتی historical source ندارید، label سری‌ها را صادقانه تغییر دهید.


4) harvest_readiness_zones

بزرگ‌ترین gap فعلی

مدل داده فعلی شما عمدتاً farm-level است:

  • SensorData
  • center_location
  • farm_details

اما این کارت block-level data می‌خواهد:

  • A1
  • A2
  • cultivar per block
  • readiness per block

نتیجه

بدون model یا source جدید برای block/zone، این کارت را نباید fake کنید.

راه درست

یا باید یکی از این‌ها را اضافه کنید:

  1. مدل FarmBlock یا FarmZone
  2. چند sensor/polygon برای هر مزرعه
  3. block metadata در JSON مزرعه

پیاده‌سازی پیشنهادی

برای هر block:

  1. weather/location را resolve کنید
  2. crop parameters block-specific بسازید
  3. یک simulation جدا اجرا کنید
  4. DVS, TWSO, SM, maturity date را بگیرید
  5. readiness را از rule زیر بسازید

مثال rule:

readiness = clamp((current_dvs / 2.0) * 100, 0, 100)

یا:

readiness = clamp(100 - days_until_harvest * 4, 0, 100)

بهتر است این rule داخل code comment شفاف توضیح داده شود.


5) yield_quality_bands

نکته مهم

PCSE به‌صورت پیش‌فرض grade یا brix تولید نمی‌کند.

پس این کارت را باید از یکی از این منابع ساخت:

  1. داده آزمایشگاهی
  2. rule engine بر اساس moisture + disease risk + maturity + crop profile
  3. مدل quality جدا

چیزی که نباید انجام شود

این‌که RAG خودش بگوید:

  • 46% گرید ممتاز
  • 34% گرید یک

بدون منطق deterministic

این کار برای dashboard اشتباه است.

پیشنهاد عملی

فاز اول:

  • اگر quality data ندارید، این کارت را با flag unavailable برگردانید
  • یا bands را از rule-based scoring بسازید و در backend صریح mark کنید که estimated هستند

مثلاً:

  • quality_score >= 85 -> premium
  • 70..84 -> grade_1
  • < 70 -> processing

اما این rule باید crop-specific باشد، نه universal.


6) harvest_operations_card

بهترین جا برای ترکیب deterministic + RAG

این کارت candidate خیلی خوبی برای RAG است، چون:

  • order و timing می‌تواند از rules و simulation بیاید
  • متن summary و noteها می‌تواند از RAG بیاید

طراحی پیشنهادی

ابتدا backend یک payload قطعی بسازد:

{
  "recommended_shift_count": 2,
  "sorting_capacity_ton_per_day": 15,
  "required_workers": 12,
  "max_transfer_hours": 6,
  "priority_blocks": ["A1", "A2"],
  "reasoning": [
    "A1 readiness بالاتر دارد",
    "moisture در محدوده مناسب است"
  ]
}

بعد این payload را به RAG بدهید تا فقط این‌ها را تولید کند:

  • summary
  • steps[].note
  • steps[].status

و حتی‌المقدور:

  • outputs[] را deterministic نگه دارید

7) season_highlights_card

بهترین روش

این کارت را از بقیه بلوک‌ها derive کنید، نه از یک منبع مستقل.

یعنی:

  • seasonLabel از ورودی season
  • badges از readiness/quality/risk
  • spotlight.value از harvest window یا best sale window
  • metrics از yield, grade, revenue estimate

نکته

اگر هنوز economy data ندارید، فیلدهایی مثل:

  • درآمد هدف
  • پنجره طلایی فروش

نباید با RAG اختراع شوند.

یا باید:

  • حذف شوند
  • یا با null
  • یا با fallback business rule

برگردند.


پیشنهاد برای RAG service جدید

مثل irrigation و fertilization یک سرویس جدید اضافه کنید:

  • rag/services/yield_harvest.py

و در config/rag_config.yaml هم service جدید تعریف کنید:

  • yield_harvest

نقش این سرویس

این سرویس نباید خودش KPI بسازد.

فقط باید:

  • summary بنویسد
  • subtitle بسازد
  • operation notes تولید کند
  • badge text را human-friendly کند

ورودی پیشنهادی به RAG

{
  "farm_uuid": "...",
  "plant_name": "...",
  "deterministic_metrics": {
    "predicted_yield_tons": 42.8,
    "days_until_harvest": 18,
    "readiness_avg": 84,
    "quality_score": 91,
    "loss_risk_percent": 6.5
  },
  "operations": {
    "shift_count": 2,
    "required_workers": 12,
    "max_transfer_hours": 6
  }
}

خروجی پیشنهادی از RAG

فقط این بخش‌ها:

{
  "season_highlights_card": {
    "subtitle": "...",
    "spotlight": {
      "caption": "..."
    },
    "badges": ["...", "..."]
  },
  "harvest_prediction_card": {
    "description": "..."
  },
  "harvest_operations_card": {
    "summary": "...",
    "steps": [
      {
        "title": "...",
        "note": "...",
        "status": "..."
      }
    ]
  }
}

Rule مهم

اگر JSON RAG خراب بود:

  • fallback deterministic برگردان
  • endpoint fail نکند

فایل‌هایی که پیشنهاد می‌شود تغییر کنند

در crop_simulation/

  • crop_simulation/apps.py

    • اضافه کردن getter برای summary service
  • crop_simulation/serializers.py

    • serializer درخواست و پاسخ summary
  • crop_simulation/views.py

    • view جدید برای summary
  • crop_simulation/urls.py

    • route جدید
  • crop_simulation/yield_harvest_summary.py

    • orchestrator اصلی

در Schemas/

  • Schemas/crop_simulation_yield_harvest_summary.py

    • contract برای مستندسازی route
  • Schemas/__init__.py

    • register کردن contract جدید

در rag/

  • rag/services/yield_harvest.py
    • narrative enrichment

در config

  • config/rag_config.yaml

    • service جدید yield_harvest
  • config/tones/yield_harvest_tone.txt

    • tone مخصوص summary صفحه
  • در صورت نیاز:

    • config/knowledge_base/yield_harvest/

ترتیب پیشنهادی پیاده‌سازی

فاز 1 - سریع و قابل اتکا

فقط این بلوک‌ها را واقعی کنید:

  • yield_prediction
  • harvest_prediction_card
  • yield_prediction_chart
  • harvest_operations_card با rules ساده

و برای بقیه اگر داده ندارید:

  • null
  • یا available: false

برگردانید.

فاز 2 - RAG narrative

به summary و operation notes متن کاربرپسند اضافه کنید.

فاز 3 - block-level readiness

بعد از اضافه شدن مدل zone/block، harvest_readiness_zones را واقعی کنید.

فاز 4 - quality/economy

بعد از اضافه شدن منبع quality یا market:

  • yield_quality_bands
  • revenue
  • sale window

را کامل کنید.


توصیه مهم درباره contract

اگر بعضی بلوک‌ها هنوز data source واقعی ندارند، بهتر است از همین حالا response را این‌طور طراحی کنید:

{
  "harvest_readiness_zones": {
    "available": false,
    "reason": "block_level_data_missing",
    "averageReadiness": null,
    "blocks": []
  }
}

این بهتر از mock پنهان است، چون:

  • فرانت می‌فهمد چرا کارت کامل نیست
  • QA راحت‌تر تست می‌کند
  • بعداً migration ساده‌تر می‌شود

ریسک‌های اصلی

1. استفاده از RAG برای عددسازی

بزرگ‌ترین خطر این صفحه همین است. RAG فقط برای narrative مناسب است.

2. نبود داده block-level

harvest_readiness_zones بدون مدل block عملاً دقیق نمی‌شود.

3. نبود quality source

yield_quality_bands بدون مدل کیفیت یا rule engine crop-specific قابل اتکا نیست.

4. ناهماهنگی chart contract

chart فعلی backend دقیقاً همان chart مورد انتظار فرانت نیست.


پیشنهاد نهایی من

اگر بخواهم برای همین repo کم‌ریسک‌ترین مسیر را انتخاب کنم:

  1. یک summary service در crop_simulation بسازید.
  2. yield_prediction و harvest_prediction_card را از سرویس‌های فعلی reuse کنید.
  3. yield_prediction_chart را فعلاً با داده واقعی current simulation برگردانید، نه مقایسه fake سال قبل.
  4. harvest_operations_card را با rules deterministic + optional RAG summary بسازید.
  5. season_highlights_card را از همین بلوک‌ها aggregate کنید.
  6. harvest_readiness_zones و yield_quality_bands را فقط وقتی source واقعی دارید production کنید.

این مسیر با معماری فعلی پروژه، با psce_doc.txt، و با pattern موجود RAG بیشترین سازگاری را دارد.


یک pseudo flow پیشنهادی

GET /api/yield-harvest/summary/?farm_uuid=...
  ->
load farm details
  ->
run/reuse PCSE simulation outputs
  ->
build deterministic blocks
  ->
optionally call RAG for narrative fields only
  ->
merge response
  ->
return code/msg/data

نتیجه

برای این صفحه:

  • PCSE باید موتور عددها باشد
  • rules باید موتور KPIهای محصولی باشد
  • RAG باید موتور متن و explanation باشد

اگر این مرزبندی رعایت شود، هم dashboard قابل اعتماد می‌شود، هم توسعه بعدی آن تمیز و قابل نگهداری می‌ماند.