This commit is contained in:
2026-04-24 03:02:22 +03:30
parent a76af4e766
commit f04a9fe71f
6 changed files with 246 additions and 79 deletions
+45 -22
View File
@@ -1,12 +1,14 @@
"""
چت RAG برای API چت عمومی — استفاده مستقیم از داده مزرعه بدون retrieval/embedding.
چت RAG برای API چت عمومی — با ارسال کامل داده مزرعه و retrieval تکمیلی از KB.
"""
import json
import logging
from pathlib import Path
from .api_provider import get_chat_client
from .chunker import chunk_text
from .config import RAGConfig, ServiceConfig, get_service_config, load_rag_config
from .retrieve import search_with_texts
logger = logging.getLogger(__name__)
@@ -61,6 +63,17 @@ def _format_farm_context_from_details(farm_details: dict) -> str:
return "[اطلاعات کامل مزرعه]\n" + serialized
def _load_farm_details_context(
sensor_uuid: str | None,
farm_details: dict | None = None,
) -> str:
if not sensor_uuid:
return ""
if farm_details is not None:
return _format_farm_context_from_details(farm_details)
return _format_farm_context(sensor_uuid)
def _build_system_prompt(
service: ServiceConfig,
query: str,
@@ -72,8 +85,10 @@ def _build_system_prompt(
if service.system_prompt:
system_parts.append(service.system_prompt)
system_parts.append(
"با استفاده از اطلاعات کامل مزرعه که در ادامه آمده به سوال کاربر پاسخ بده. "
"با استفاده از اطلاعات کامل مزرعه و اطلاعات بازیابی‌شده از پایگاه دانش که در ادامه آمده "
"به سوال کاربر پاسخ بده. "
"اگر داده‌ای در اطلاعات مزرعه وجود دارد، همان را مبنای پاسخ قرار بده و چیزی حدس نزن. "
"نتایج بازیابی‌شده از پایگاه دانش را برای تکمیل یا توضیح پاسخ استفاده کن. "
"اگر داده کافی نبود، این کمبود را شفاف بگو. "
"پاسخ را به زبان کاربر بنویس."
)
@@ -141,13 +156,15 @@ def build_rag_context(
limit: int = 8,
kb_name: str | None = None,
service_id: str | None = None,
farm_details: dict | None = None,
) -> str:
"""
ساخت context برای سرویس‌های توصیه با استفاده از RAG قدیمی.
این تابع برای سازگاری با irrigation/fertilization حفظ شده است.
ساخت context مشترک برای همه سرویس‌های RAG.
شامل:
- اطلاعات کامل مزرعه از farm_data/services.py
- جستجوی KB بر اساس پیام کاربر
- جستجوی KB بر اساس chunk های کامل داده مزرعه
"""
from .retrieve import search_with_query
from .user_data import build_user_soil_text, build_user_weather_text
logger.info(
"Building RAG context sensor_uuid=%s kb_name=%s limit=%s query_len=%s",
@@ -161,20 +178,23 @@ def build_rag_context(
service = get_service_config(service_id, cfg) if service_id else None
include_user_embeddings = service.use_user_embeddings if service else True
resolved_kb_name = kb_name or (service.knowledge_base if service else None)
farm_context = _load_farm_details_context(
sensor_uuid=sensor_uuid,
farm_details=farm_details,
)
if include_user_embeddings and sensor_uuid:
user_soil = build_user_soil_text(sensor_uuid)
if user_soil and user_soil.strip():
parts.append("[داده‌های فعلی خاک شما]\n" + user_soil.strip())
if farm_context:
parts.append(farm_context)
weather_text = build_user_weather_text(sensor_uuid)
if weather_text and weather_text.strip():
parts.append("[پیش‌بینی هواشناسی]\n" + weather_text.strip())
search_texts = [query]
if farm_context:
search_texts.extend(chunk_text(farm_context, config=cfg))
results = search_with_query(
query,
results = search_with_texts(
search_texts,
sensor_uuid=sensor_uuid,
limit=limit,
per_text_limit=3,
config=cfg,
kb_name=resolved_kb_name,
service_id=service_id,
@@ -230,20 +250,23 @@ def chat_rag_stream(
len(query or ""),
)
if farm_details is None:
farm_context = _format_farm_context(farm_uuid)
else:
farm_context = _format_farm_context_from_details(farm_details)
context = build_rag_context(
query=query,
sensor_uuid=farm_uuid,
config=cfg,
service_id=service_id,
farm_details=farm_details,
)
logger.info(
"Loaded farm context for farm_uuid=%s context_len=%s",
"Loaded augmented context for farm_uuid=%s context_len=%s",
farm_uuid,
len(farm_context),
len(context),
)
if system_override is not None:
system_prompt = system_override
else:
system_prompt = _build_system_prompt(service, query, farm_context, cfg)
system_prompt = _build_system_prompt(service, query, context, cfg)
messages = [
{"role": "system", "content": system_prompt},