Files
Ai/rag
2026-04-28 19:00:38 +03:30
..
2026-04-24 01:23:56 +03:30
2026-04-28 19:00:38 +03:30
2026-04-28 19:00:38 +03:30
2026-04-24 01:23:56 +03:30
2026-04-24 17:40:25 +03:30
2026-04-27 23:31:53 +03:30
2026-04-24 01:23:56 +03:30
2026-04-24 01:23:56 +03:30
2026-03-19 22:54:29 +03:30
2026-04-24 01:23:56 +03:30
2026-04-01 22:09:57 +03:30
2026-03-19 22:54:29 +03:30
2026-04-24 03:02:22 +03:30
2026-04-24 22:20:15 +03:30
2026-04-26 01:15:38 +03:30
2026-04-06 23:50:24 +03:30
2026-04-24 01:23:56 +03:30
2026-04-26 01:15:38 +03:30

مستند سیستم RAG — پایگاه دانش CropLogic

فهرست

  1. معرفی کلی
  2. معماری و ساختار
  3. منابع داده
  4. پایپ‌لاین Embedding
  5. نحوه اجرا
  6. فلوی پیام کاربر
  7. API Endpoint
  8. تنظیمات
  9. ایزوله‌سازی کاربران
  10. سرویس‌های توصیه

معرفی کلی

سیستم RAG در CropLogic یک چت هوشمند کشاورزی است که:

  • دانش پایه کشاورزی را embed و ذخیره می‌کند
  • داده‌های خاک و هواشناسی هر کاربر را از DB می‌خواند و embed می‌کند
  • وقتی کاربر سوال می‌پرسد، اطلاعات مرتبط را بازیابی و به LLM ارسال می‌کند

Vector Store: Qdrant
API Provider: GapGPT (با fallback به Avalai) — Adapter Pattern

پایگاه‌های دانش مجزا

سیستم از سه پایگاه دانش مجزا استفاده می‌کند:

KB توضیح فایل Tone
chat چت عمومی و پاسخ به سوالات متنوع config/tones/chat_tone.txt
irrigation توصیه‌های آبیاری (فرمت JSON) config/tones/irrigation_tone.txt
fertilization توصیه‌های کودهی (فرمت JSON) config/tones/fertilization_tone.txt

تشخیص هوشمند KB از روی کلمات کلیدی سوال (آبیاری، آب، کود، NPK).


معماری و ساختار

rag/
├── config.py                # بارگذاری تنظیمات از rag_config.yaml
├── api_provider.py          # Adapter Pattern برای GapGPT/Avalai
├── client.py                # ساخت کلاینت Qdrant
├── chunker.py               # تکه‌تکه کردن متن
├── embedding.py             # تعبیه‌سازی متن
├── vector_store.py          # ذخیره و جستجو در Qdrant (با فیلتر kb_name)
├── user_data.py             # خواندن داده‌های خاک/سنسور/هواشناسی از DB
├── ingest.py                # پایپ‌لاین: خواندن → چانک → embed → ذخیره
├── retrieve.py              # بازیابی: embed کوئری → جستجو
├── chat.py                  # ساخت context و چت استریمی با LLM
├── views.py                 # API endpoint
├── urls.py                  # مسیریابی
├── tasks.py                 # تسک Celery
├── services/                # سرویس‌های توصیه (بدون API)
│   ├── irrigation.py        # توصیه آبیاری
│   └── fertilization.py     # توصیه کودهی
└── management/commands/
    └── rag_ingest.py

فایل‌های تنظیمات:

config/
├── rag_config.yaml
├── tones/
│   ├── chat_tone.txt
│   ├── irrigation_tone.txt
│   └── fertilization_tone.txt
└── knowledge_base/
    ├── chat/
    ├── irrigation/
    └── fertilization/

منابع داده

سیستم از چهار منبع داده تغذیه می‌شود:

1. لحن‌های مجزا — config/tones/

هر KB یک فایل لحن مخصوص دارد که سبک خروجی LLM را تعریف می‌کند.

ذخیره با: sensor_uuid = __global__, kb_name = chat|irrigation|fertilization

2. پایگاه‌های دانش — config/knowledge_base/

  • chat/: دانش عمومی کشاورزی
  • irrigation/: دانش تخصصی آبیاری (ET0، بارش، رطوبت)
  • fertilization/: دانش تخصصی کودهی (NPK، pH، نوع خاک)

ذخیره با: sensor_uuid = __global__, kb_name = chat|irrigation|fertilization

3. داده‌های خاک کاربر — از DB

برای هر سنسور:

  • SensorData: رطوبت، دما، pH، EC، NPK
  • SoilLocation: مختصات جغرافیایی
  • SoilDepthData: داده‌های خاک در سه عمق

تابع build_user_soil_text() این داده‌ها را به متن فارسی تبدیل می‌کند.

ذخیره با: sensor_uuid = {uuid واقعی}, kb_name = __all__

4. داده‌های هواشناسی کاربر — از DB

  • WeatherForecast: پیش‌بینی ۷ روز آینده (دما، بارش، رطوبت، باد، ET0)

تابع build_user_weather_text() این داده‌ها را به متن فارسی تبدیل می‌کند.

ذخیره با: sensor_uuid = {uuid واقعی}, kb_name = __all__


پایپلاین Embedding

منابع → load_sources() → chunk_text() → embed_texts() → Qdrant
  1. بارگذاری منابع (ingest.py:load_sources):

    • لحن‌ها از config/tones/
    • KB‌ها از config/knowledge_base/
    • داده‌های کاربران از DB (user_data.py)
  2. چانک کردن (chunker.py):

    • حداکثر ۵۰۰ توکن هر چانک
    • ۵۰ توکن همپوشانی
  3. Embedding (embedding.py):

    • استفاده از api_provider.get_embedding_client()
    • مدل: text-embedding-3-small
    • بچ‌سایز: ۳۲
  4. ذخیره در Qdrant (vector_store.py):

    • هر point: {id, vector[1536], payload{text, source, sensor_uuid, kb_name, chunk_index}}

نحوه اجرا

دستی

python manage.py rag_ingest --recreate

دوره‌ای (Celery Beat)

تسک rag_ingest_task هر ۶ ساعت اجرا می‌شود و داده‌های جدید را embed می‌کند.


فلوی پیام کاربر

POST /api/rag/chat/ {message, sensor_uuid}
  ↓
1. تشخیص KB از روی کلمات کلیدی (_detect_kb_intent)
  ↓
2. بارگذاری داده‌های فعلی کاربر از DB:
   - build_user_soil_text(sensor_uuid)
   - build_user_weather_text(sensor_uuid)
  ↓
3. Embed کردن سوال (embed_single)
  ↓
4. جستجو در Qdrant با فیلتر:
   - sensor_uuid = {uuid کاربر} OR __global__
   - kb_name = {detected_kb} OR __all__
  ↓
5. ساخت context:
   [داده‌های فعلی خاک] + [پیش‌بینی هواشناسی] + [متن‌های مرجع از RAG]
  ↓
6. ارسال به LLM (GapGPT):
   system_prompt = tone + دستورالعمل + context
  ↓
7. StreamingHttpResponse → کاربر

API Endpoint

POST /api/rag/chat/

Request:

{
  "message": "وضعیت خاک من چطوره؟",
  "sensor_uuid": "550e8400-e29b-41d4-a716-446655440000"
}

Response: Stream متنی (text/plain)


تنظیمات

config/rag_config.yaml

embedding:
  provider: "gapgpt"                      # gapgpt یا avalai
  model: "text-embedding-3-small"
  base_url: "https://api.gapgpt.app/v1"
  api_key_env: "GAPGPT_API_KEY"
  avalai_base_url: "https://api.avalai.ir/v1"
  avalai_api_key_env: "AVALAI_API_KEY"

qdrant:
  host: "localhost"
  port: 6333
  collection_name: "croplogic_kb"
  vector_size: 1536

chunking:
  max_chunk_tokens: 500
  overlap_tokens: 50

llm:
  model: "gpt-4o"
  base_url: "https://api.gapgpt.app/v1"
  api_key_env: "GAPGPT_API_KEY"
  avalai_base_url: "https://api.avalai.ir/v1"
  avalai_api_key_env: "AVALAI_API_KEY"

knowledge_bases:
  chat:
    path: "config/knowledge_base/chat"
    tone_file: "config/tones/chat_tone.txt"
  irrigation:
    path: "config/knowledge_base/irrigation"
    tone_file: "config/tones/irrigation_tone.txt"
  fertilization:
    path: "config/knowledge_base/fertilization"
    tone_file: "config/tones/fertilization_tone.txt"

متغیرهای محیطی

متغیر توضیح
GAPGPT_API_KEY کلید API برای GapGPT
AVALAI_API_KEY کلید API برای Avalai (fallback)
QDRANT_HOST آدرس Qdrant
QDRANT_PORT پورت Qdrant

ایزوله‌سازی کاربران

  • هر چانک یک فیلد sensor_uuid در metadata دارد
  • داده‌های عمومی: sensor_uuid = __global__
  • داده‌های کاربر: sensor_uuid = {uuid واقعی}
  • هنگام جستجو، فیلتر should اعمال می‌شود:
    • sensor_uuid = {uuid کاربر} OR __global__
    • kb_name = {detected_kb} OR __all__
  • نتیجه: هر کاربر فقط داده‌های خودش + دانش عمومی را می‌بیند

سرویس‌های توصیه

سرویس‌های آبیاری و کودهی بدون API هستند و از RAG استفاده می‌کنند.

توصیه آبیاری

from rag.services import get_irrigation_recommendation

result = get_irrigation_recommendation(
    sensor_uuid="550e8400-...",
    query="توصیه آبیاری برای مزرعه من چیست؟"  # اختیاری
)

خروجی:

{
    "irrigation_needed": True,
    "amount_mm": 25.0,
    "reason": "رطوبت خاک پایین و بارش پیش‌بینی نشده",
    "next_check_date": "2026-03-20",
    "raw_response": "..."
}

توصیه کودهی

from rag.services import get_fertilization_recommendation

result = get_fertilization_recommendation(
    sensor_uuid="550e8400-...",
    query="توصیه کودهی برای مزرعه من چیست؟"  # اختیاری
)

خروجی:

{
    "fertilizer_needed": True,
    "fertilizer_type": "NPK 20-10-10",
    "amount_kg_per_hectare": 150.0,
    "reason": "سطح ازت پایین",
    "npk_status": {
        "nitrogen": "low",
        "phosphorus": "normal",
        "potassium": "normal"
    },
    "raw_response": "..."
}

نمودار معماری

┌─────────────────────────────────────────────────────────┐
│                     منابع داده                          │
│                                                         │
│  ┌──────────┐  ┌──────────────┐  ┌───────────────────┐  │
│  │ tones/   │  │ knowledge_   │  │ Django DB         │  │
│  │ 3 files  │  │ base/        │  │ SensorData        │  │
│  │          │  │ chat/irrig/  │  │ SoilLocation      │  │
│  │          │  │ fertiliz/    │  │ SoilDepthData     │  │
│  │          │  │              │  │ WeatherForecast   │  │
│  └────┬─────┘  └──────┬───────┘  └────────┬──────────┘  │
│       │               │                   │             │
│       └───────────┬────┘                   │             │
│            __global__              sensor_uuid           │
│         kb_name=chat/              kb_name=__all__       │
│         irrigation/                                      │
│         fertilization                                    │
└───────────────┬────────────────────────┬────────────────┘
                │                        │
                ▼                        ▼
┌─────────────────────────────────────────────────────────┐
│                  ingest pipeline                        │
│                                                         │
│  load_sources() → chunk_text() → embed_texts()         │
│  (با Adapter Pattern: GapGPT/Avalai)                   │
│                                                         │
│  کامند: python manage.py rag_ingest --recreate         │
│  تسک:   rag_ingest_task.delay(recreate=True)           │
└────────────────────────┬────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────┐
│                    Qdrant                               │
│           collection: croplogic_kb                      │
│                                                         │
│  هر point = {id, vector[1536], payload{text,           │
│              source, sensor_uuid, kb_name,              │
│              chunk_index}}                              │
└────────────────────────┬────────────────────────────────┘
                         │
           (هنگام سوال کاربر)
                         │
                         ▼
┌─────────────────────────────────────────────────────────┐
│               فلوی پاسخ به کاربر                        │
│                                                         │
│  1. POST /api/rag/chat/ {message, sensor_uuid}         │
│  2. تشخیص KB از کلمات کلیدی (_detect_kb_intent)       │
│  3. build_user_soil_text() + build_user_weather_text() │
│  4. embed_single(message) → query vector               │
│  5. Qdrant search با فیلتر sensor_uuid + kb_name      │
│  6. system_prompt = tone + دستورالعمل + context         │
│  7. GapGPT LLM (gpt-4o) → streaming response          │
│  8. StreamingHttpResponse → کاربر                      │
└─────────────────────────────────────────────────────────┘

تغییرات اخیر:

  • Adapter Pattern برای سوئیچ بین GapGPT و Avalai
  • سه پایگاه دانش مجزا (chat/irrigation/fertilization)
  • داده‌های هواشناسی embed می‌شوند
  • فیلتر kb_name در جستجوی Qdrant
  • سرویس‌های توصیه آبیاری و کودهی (بدون API)