20 KiB
راهنمای پیادهسازی API صفحه Yield & Harvest با PCSE و RAG
این فایل برای تیم بکاند نوشته شده تا صفحه yield-harvest را با تکیه بر:
- مستند
psce_doc.txtپروژه - سرویسهای موجود در
crop_simulation/ - معماری فعلی RAG در
rag/
به شکل قابل اتکا پیادهسازی کند.
نکته: فایل psce_doc.txt در عمل مستند PCSE است و در این سند هم با عنوان PCSE به آن اشاره میشود.
جمعبندی سریع
برای این صفحه، بهترین معماری این است:
- عددها، تاریخها، درصدها و سریهای نمودار از PCSE و دادههای مزرعه ساخته شوند.
- RAG فقط برای متنهای توضیحی، خلاصهسازی، و wording کاربرپسند استفاده شود.
- RAG اجازه نداشته باشد عدد جدید، تاریخ جدید، یا KPI جدید اختراع کند.
- یک 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.pycrop_simulation/growth_simulation.pycrop_simulation/harvest_prediction.pycrop_simulation/yield_prediction.py
و همین حالا از PCSE این خروجیها را میسازید:
yieldازTWSObiomassازTAGPleaf_area_indexازLAIdevelopment_stageازDVSsoil_moistureازSM
این دقیقاً با چیزی که در psce_doc.txt آمده همراستا است: PCSE برای state/rate variables و خروجی روزانه مناسب است و برای ساخت KPI، trend و harvest timing گزینه خوبی است.
لایه RAG
الان پروژه الگوی خوبی برای سرویسهای ترکیبی deterministic + RAG دارد:
rag/services/irrigation.pyrag/services/fertilization.pyrag/chat.pyconfig/rag_config.yaml
الگوی درست در این پروژه این است:
- اول عددها و تصمیمهای پایه از منطق deterministic ساخته میشوند
- بعد RAG فقط متن نهایی را polish میکند
- در صورت خراب شدن خروجی LLM، fallback ساختاریافته دارید
برای yield-harvest هم باید دقیقاً همین الگو تکرار شود.
اصل طراحی مهم
چه چیزی باید deterministic باشد
این فیلدها نباید از RAG بیایند:
daysUntilreadinessshareseries[].dataaverageReadinesspredicted yieldharvest date- هر عددی که در progress bar، chart، KPI یا sorting استفاده میشود
چه چیزی میتواند از RAG بیاید
این فیلدها مناسب RAG هستند:
season_highlights_card.subtitleseason_highlights_card.spotlight.captionharvest_prediction_card.descriptionharvest_operations_card.summarysteps[].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 باید:
- داده مزرعه را از
farm_data.services.get_farm_details()بگیرد. - خروجی شبیهسازی را از
CurrentFarmChartSimulatorو سرویسهای فعلی بگیرد. - بلوکهای deterministic را بسازد.
- اگر RAG فعال بود، متنهای narrative را enrich کند.
- یک 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 ندارید
پس برای صفحه کامل، باید سه لایه را از هم جدا ببینید:
PCSE layer: عددهای زیستی و رشدRules/Aggregation layer: تبدیل خروجی PCSE به KPIهای محصولی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ازTWSOharvest readinessازDVSو فاصله تا maturityquality scoreفعلاً rule-based، نه RAG-basedloss 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 را هم نگه دارید
یعنی بهتر است این دو فیلد را داشته باشید:
descriptiondescriptionSource = "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 است:
SensorDatacenter_locationfarm_details
اما این کارت block-level data میخواهد:
A1A2- cultivar per block
- readiness per block
نتیجه
بدون model یا source جدید برای block/zone، این کارت را نباید fake کنید.
راه درست
یا باید یکی از اینها را اضافه کنید:
- مدل
FarmBlockیاFarmZone - چند sensor/polygon برای هر مزرعه
- block metadata در JSON مزرعه
پیادهسازی پیشنهادی
برای هر block:
- weather/location را resolve کنید
- crop parameters block-specific بسازید
- یک simulation جدا اجرا کنید
DVS,TWSO,SM,maturity dateرا بگیرید- 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 تولید نمیکند.
پس این کارت را باید از یکی از این منابع ساخت:
- داده آزمایشگاهی
- rule engine بر اساس moisture + disease risk + maturity + crop profile
- مدل quality جدا
چیزی که نباید انجام شود
اینکه RAG خودش بگوید:
- 46% گرید ممتاز
- 34% گرید یک
بدون منطق deterministic
این کار برای dashboard اشتباه است.
پیشنهاد عملی
فاز اول:
- اگر quality data ندارید، این کارت را با flag
unavailableبرگردانید - یا bands را از rule-based scoring بسازید و در backend صریح mark کنید که estimated هستند
مثلاً:
quality_score >= 85 -> premium70..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 بدهید تا فقط اینها را تولید کند:
summarysteps[].notesteps[].status
و حتیالمقدور:
outputs[]را deterministic نگه دارید
7) season_highlights_card
بهترین روش
این کارت را از بقیه بلوکها derive کنید، نه از یک منبع مستقل.
یعنی:
seasonLabelاز ورودی seasonbadgesاز readiness/quality/riskspotlight.valueاز harvest window یا best sale windowmetricsاز 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
- service جدید
-
config/tones/yield_harvest_tone.txt- tone مخصوص summary صفحه
-
در صورت نیاز:
config/knowledge_base/yield_harvest/
ترتیب پیشنهادی پیادهسازی
فاز 1 - سریع و قابل اتکا
فقط این بلوکها را واقعی کنید:
yield_predictionharvest_prediction_cardyield_prediction_chartharvest_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 کمریسکترین مسیر را انتخاب کنم:
- یک summary service در
crop_simulationبسازید. yield_predictionوharvest_prediction_cardرا از سرویسهای فعلی reuse کنید.yield_prediction_chartرا فعلاً با داده واقعی current simulation برگردانید، نه مقایسه fake سال قبل.harvest_operations_cardرا با rules deterministic + optional RAG summary بسازید.season_highlights_cardرا از همین بلوکها aggregate کنید.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 قابل اعتماد میشود، هم توسعه بعدی آن تمیز و قابل نگهداری میماند.