feedback-analysis-agent / ARCHITECTURE.md
galbendavids's picture
עדכון: הסרת RAG, הוספת ארכיטקטורה מפורטת, תיקון לינקים, שינוי שם פרויקט ל-SQL-based
f073efc

ארכיטקטורת המערכת - Feedback Analysis SQL-Based Agent

סקירה כללית

המערכת היא מערכת ניתוח משובי משתמשים מבוססת SQL ו-LLM. המערכת מקבלת שאלות בשפה טבעית, יוצרת שאילתות SQL, מבצעת אותן על הנתונים, ומחזירה תשובות מפורטות.

זרימת הנתונים - מהפרונט לאחור

1. Frontend (1_frontend/)

index.html

תפקיד: ממשק המשתמש הראשי סיבה לקיום: מספק ממשק ווב אינטראקטיבי למשתמש תפקידים:

  • הצגת שדה קלט לשאלות
  • הצגת תשובות, שאילתות SQL, תוצאות, וגרפים
  • ניהול היסטוריית שאלות
  • אנימציית loading

app.js

תפקיד: לוגיקת Frontend סיבה לקיום: מטפל באינטראקציות המשתמש ותקשורת עם ה-Backend תפקידים:

  • שליחת שאלות ל-/query-sql endpoint
  • הצגת תשובות וגרפים
  • ניהול היסטוריה (טעינה ושחזור)
  • עיבוד ויזואליזציות עם Chart.js

זרימת נתונים:

משתמש מזין שאלה → sendQuery() → POST /query-sql → קבלת תשובה → הצגה

2. Backend API (2_backend_llm/app/api.py)

api.py

תפקיד: FastAPI endpoints - נקודת הכניסה של ה-Backend סיבה לקיום: מספק API RESTful לתקשורת בין Frontend ל-Backend תפקידים:

  • GET / - מחזיר את index.html
  • POST /query-sql - מקבל שאלה, מחזיר תשובה מפורטת
  • GET /history - מחזיר היסטוריית שאלות
  • POST /health - בדיקת תקינות השרת

זרימת נתונים:

Frontend → POST /query-sql {query: "..."} 
  → api.py:query_sql() 
  → SQLFeedbackService.analyze_query() 
  → SQLQueryResponse {summary, sql_queries, query_results, visualizations}
  → Frontend

מודלים/פונקציות קרואות:

  • SQLFeedbackService - השירות הראשי לניתוח
  • save_history() - שמירת היסטוריה לדיסק
  • load_history() - טעינת היסטוריה מהדיסק

3. SQL Service (2_backend_llm/app/sql_service.py)

sql_service.py

תפקיד: הליבה של המערכת - ניתוח SQL מבוסס LLM סיבה לקיום: מטפל בכל הלוגיקה של יצירת שאילתות SQL, ביצוען, וסינתזת תשובות תפקידים:

  • analyze_query() - הפונקציה הראשית - מנהלת את כל התהליך
  • _get_schema_info() - יוצר מידע מפורט על כל השדות בטבלה
  • _generate_sql_queries() - משתמש ב-LLM ליצירת שאילתות SQL
  • _execute_sql_queries() - מבצע שאילתות SQL על הנתונים
  • _synthesize_answer() - משתמש ב-LLM ליצירת תשובה מפורטת
  • _evaluate_answer_quality() - מעריך את איכות התשובה
  • _generate_visualizations() - יוצר מפרטי ויזואליזציות

זרימת נתונים:

analyze_query(query)
  ↓
1. _generate_sql_queries(query)
   → LLM (Gemini/OpenAI) מקבל: schema_info + query
   → מחזיר: ["SELECT ...", "SELECT ..."]
  ↓
2. _execute_sql_queries(sql_queries)
   → טוען DataFrame ל-SQLite in-memory
   → מבצע כל שאילתה
   → מחזיר: [SQLQueryResult, ...]
  ↓
3. _synthesize_answer(query, sql_queries, query_results)
   → LLM (Gemini/OpenAI) מקבל: query + sql_queries + results
   → מחזיר: תשובה מפורטת בעברית
   → (אופציונלי) _evaluate_answer_quality() + שיפור אם נדרש
  ↓
4. _generate_visualizations(query_results)
   → מנתח את התוצאות
   → מחזיר: [visualization_spec, ...]
  ↓
AnalysisResult {user_query, sql_queries, query_results, summary, visualizations}

מודלים/פונקציות קרואות:

  • LLM (Gemini/OpenAI) - ליצירת שאילתות SQL וסינתזת תשובות
  • pandas.DataFrame - לניהול הנתונים
  • sqlite3 - לביצוע שאילתות SQL

4. Data Loader (2_backend_llm/app/data_loader.py)

data_loader.py

תפקיד: טעינת נתונים מ-CSV סיבה לקיום: מטפל בטעינת וניקוי הנתונים מהקובץ תפקידים:

  • load_feedback() - טוען CSV, בודק שדות נדרשים, מנקה נתונים

זרימת נתונים:

load_feedback()
  → קורא CSV מ-settings.csv_path
  → בודק שדות: ID, ServiceName, Level, Text
  → מסיר שורות עם Text ריק
  → מחזיר: pd.DataFrame

5. Config (2_backend_llm/app/config.py)

config.py

תפקיד: הגדרות מערכת סיבה לקיום: מרכז את כל ההגדרות (API keys, נתיבי קבצים) תפקידים:

  • טעינת API keys מ-.env
  • הגדרת נתיב CSV ברירת מחדל
  • הגדרת שמות עמודות

זרימה מלאה - דוגמה

שאילתת משתמש: "מה הדירוג הממוצע לפי שירות?"

  1. Frontend (app.js):

    sendQuery() → POST /query-sql {query: "מה הדירוג הממוצע לפי שירות?"}
    
  2. Backend API (api.py):

    @app.post("/query-sql")
    def query_sql(request: QueryRequest):
        result = sql_svc.analyze_query(request.query)
        save_history(result)  # שמירה להיסטוריה
        return SQLQueryResponse(...)
    
  3. SQL Service (sql_service.py):

    analyze_query("מה הדירוג הממוצע לפי שירות?")
    
  4. שלב 1 - יצירת SQL:

    _generate_sql_queries(query)
    → LLM מקבל: schema_info + query
    → LLM מחזיר: ["SELECT ServiceName, AVG(Level) as avg_rating FROM Feedback_transformed GROUP BY ServiceName"]
    
  5. שלב 2 - ביצוע SQL:

    _execute_sql_queries(["SELECT ServiceName, AVG(Level)..."])
    → טוען DataFrame ל-SQLite
    → מבצע שאילתה
    → מחזיר: DataFrame עם ServiceName ו-avg_rating
    
  6. שלב 3 - סינתזת תשובה:

    _synthesize_answer(query, sql_queries, query_results)
    → LLM מקבל: query + SQL + results
    → LLM מחזיר: "הדירוג הממוצע לפי שירות: שירות X - 4.2, שירות Y - 3.8..."
    → (אופציונלי) _evaluate_answer_quality() + שיפור
    
  7. שלב 4 - יצירת ויזואליזציות:

    _generate_visualizations(query_results)
    → מחזיר: [{type: "bar", x: "ServiceName", y: "avg_rating", ...}]
    
  8. חזרה ל-Frontend:

    קבלת תשובה → הצגת summary → הצגת גרף → עדכון היסטוריה
    

מבנה הנתונים

AnalysisResult

{
  user_query: str,
  sql_queries: List[str],
  query_results: List[SQLQueryResult],
  summary: str,
  visualizations: Optional[List[Dict]]
}

SQLQueryResult

{
  query: str,
  result: pd.DataFrame,
  error: Optional[str]
}

LLM Models בשימוש

  1. יצירת SQL (_generate_sql_queries):

    • Model: Gemini 2.0 Flash / GPT-4o-mini
    • Input: schema_info + user_query
    • Output: JSON עם רשימת שאילתות SQL
  2. סינתזת תשובה (_synthesize_answer):

    • Model: Gemini 2.0 Flash / GPT-4o-mini
    • Input: user_query + sql_queries + query_results
    • Output: תשובה מפורטת בעברית
  3. הערכת איכות (_evaluate_answer_quality):

    • Model: Gemini 2.0 Flash / GPT-4o-mini
    • Input: user_query + answer + context
    • Output: score (0-100) + reasoning

Database Schema

טבלה: Feedback_transformed (SQLite in-memory)

שדות:

  • ID (UUID)
  • ServiceName (TEXT)
  • Level (INTEGER 1-5)
  • Text (TEXT)
  • ReferenceNumber (INTEGER, nullable)
  • RequestID (UUID, nullable)
  • ProcessID (UUID, nullable)
  • Year (INTEGER)
  • Month (INTEGER 1-12)
  • DayInMonth (INTEGER 1-31)
  • DayOfWeek (TEXT: Monday-Sunday)
  • Hour (INTEGER 0-23)
  • DayOrNight (TEXT: 'יום'/'לילה')

תלויות בין מודולים

Frontend (app.js)
  ↓ HTTP POST
API (api.py)
  ↓
SQL Service (sql_service.py)
  ↓
  ├─→ Data Loader (data_loader.py) - טעינת נתונים
  ├─→ Config (config.py) - הגדרות
  └─→ LLM (Gemini/OpenAI) - יצירת SQL וסינתזת תשובות

נקודות כניסה

  1. Frontend: 1_frontend/index.html - נקודת הכניסה למשתמש
  2. Backend: 2_backend_llm/run.py - מפעיל את FastAPI server
  3. API: 2_backend_llm/app/api.py - מגדיר את ה-endpoints