כיצד לבנות מערכת RAG ב-10 שורות של Python ללא מסגרות

פתח את עוצמת ה-RAG (Retrieval Augmented Generation) עם מדריך קוד פייתון בן 10 שורות זה. צלול לתוך אחזור מידע, בנה את מערכת המסמכים שלך, והשתמש ב-LLMs לתגובות עמידות - כל זאת מבלי להסתמך על מסגרות מורכבות. אופטם את התוכן שלך לאופטימיזציית מנועי חיפוש ומעורבות.

14 בפברואר 2025

party-gif

גלה כיצד לבנות מערכת חזקה של אחזור-מוגברת-יצירה (RAG) מהתחלה בתוך 10 שורות בלבד של קוד פייתון, מבלי להסתמך על כל מסגרות חיצוניות. גישה זו קצרה אך מקיפה מספקת לך הבנה עמוקה של הרכיבים הליבה, ומעצימה אותך ליצור פתרונות חזקים ומותאמים אישית מונעי-AI עבור יישומי מסמכים שלך.

הבן את המושג של יצירה מוגברת באמצעות אחזור (RAG)

אוגמנטציית שליפה (Retrieval Augmented Generation, RAG) היא טכניקה המשמשת לשליפת מידע מהמסמכים שלך. היא כוללת תהליך דו-שלבי:

  1. יצירת בסיס הידע: המסמכים מחולקים לתת-מסמכים קטנים יותר, וחישובי אמבדינג מבוצעים עבור כל חלק. אמבדינגים אלה והחלקים המקוריים נשמרים, בדרך כלל במאגר וקטורי.

  2. שליפה וייצור: כאשר מגיעה שאילתה חדשה של משתמש, מחושב אמבדינג עבור השאילתה. החלקים הרלוונטיים ביותר נשלפים על ידי השוואת אמבדינג השאילתה לאמבדינגים המאוחסנים של החלקים. החלקים שנשלפו מצורפים לשאילתה המקורית ומוזנים לתוך מודל שפה (LLM) כדי לייצר את התגובה הסופית.

הגישה הזו נקראת "צינור אוגמנטציית שליפה", מכיוון שייצור ה-LLM מתבסס על המידע הרלוונטי שנשלף מבסיס הידע.

בעוד שישנם מסגרות כמו Langchain ו-LlamaIndex שמפשטות את היישום של צינורות RAG, ניתן לבנות את הרכיבים הליבתיים באמצעות פייתון, מודל אמבדינג ו-LLM. גישה זו מספקת הבנה טובה יותר של המושגים הבסיסיים ומאפשרת גמישות רבה יותר בהתאמת הצינור.

למד לחלק מסמכים לפסקאות

בעת בניית מערכת אוגמנטציית שליפה (RAG), אחד השלבים המפתחיים הוא לחלק את המסמכים הקלט לחלקים קטנים ונוחים יותר לניהול. בדוגמה זו, אנו מחלקים את המסמך הקלט (מאמר ויקיפדיה) לפסקאות.

ההיגיון מאחורי גישה זו הוא שפסקאות לעתים קרובות מייצגות יחידות מידע לוגיות שניתן לשלוף ולהשתמש בהן בצורה יעילה כדי להעשיר את שאילתת המשתמש. על ידי פירוק המסמך בדרך זו, אנו יכולים לזהות בצורה טובה יותר את הקטעים הרלוונטיים ביותר לכלול בתגובה הסופית.

הקוד לשלב זה הוא כדלקמן:

# חלק את המסמך לפסקאות
chunks = [paragraph.strip() for paragraph in text.split('\n') if paragraph.strip()]

כאן, אנו משתמשים בגישה פשוטה של פיצול הטקסט הקלט לפי תווי החדש שורה כדי להפיק את הפסקאות הבודדות. אנו מסירים לאחר מכן רווחים מובילים או מאחור מכל פסקה כדי להבטיח ייצוג נקי.

רשימת ה-chunks המתקבלת מכילה את הפסקאות הבודדות, אשר ניתן לאמבד ולאחסן במאגר הוקטורי. זה מאפשר לנו לשלוף בצורה יעילה את הפסקאות הרלוונטיות ביותר בהתבסס על שאילתת המשתמש, ולכלול אותן בתגובה הסופית שמיוצרת על ידי מודל השפה.

הטמע מסמכים ושאילתות משתמש באמצעות ממירי משפטים

כדי לאמבד את חלקי המסמך והשאילתה של המשתמש, נשתמש בספריית Sentence Transformers. ספריה זו מספקת מודלים מאומנים מראש שיכולים ליצור אמבדינגים באיכות גבוהה לטקסט.

ראשית, נטען את מודל האמבדינג:

from sentence_transformers import SentenceTransformer
embedding_model = SentenceTransformer('all-mpnet-base-v2')

לאחר מכן, נחשב את האמבדינגים עבור חלקי המסמך:

chunk_embeddings = embedding_model.encode(chunks, normalize_embeddings=True)

כאן, chunks היא רשימה של חלקי הטקסט מהמסמך. האפשרות normalize_embeddings=True מבטיחה שהאמבדינגים מנורמלים, שזה חשוב עבור חישוב הדמיון מאוחר יותר.

כדי לקבל את האמבדינג עבור שאילתת המשתמש, פשוט נריץ:

query_embedding = embedding_model.encode([user_query], normalize_embeddings=True)[0]

כעת, יש לנו את האמבדינגים עבור חלקי המסמך והשאילתה של המשתמש, אשר ניתן להשתמש בהם בשלב השליפה.

אחזר חלקים רלוונטיים על בסיס דמיון קוסינוס

כדי לשלוף את החלקים הרלוונטיים ביותר בהתבסס על שאילתת המשתמש, עלינו תחילה לחשב את הדמיון הקוסינוסי בין אמבדינג השאילתה לאמבדינגים של חלקי המסמך. להלן כיצד ניתן לעשות זאת:

  1. חשב את אמבדינג שאילתת המשתמש באמצעות אותו מודל אמבדינג כמו של חלקי המסמך.
  2. חשב את התוצר הסקלרי בין אמבדינג השאילתה לכל אחד מאמבדינגי חלקי המסמך. זה נותן לנו את ציוני הדמיון הקוסינוסי.
  3. מיין את חלקי המסמך על פי ציוני הדמיון הקוסינוסי ובחר את ה-K החלקים הרלוונטיים ביותר.
  4. שלוף את תוכן הטקסט של החלקים הנבחרים כדי להשתמש בהם כהקשר עבור מודל השפה.

השלבים המפתחיים הם:

  1. חשב אמבדינג שאילתה
  2. חשב ציוני דמיון קוסינוסי
  3. מיין ובחר את ה-K החלקים העליונים
  4. שלוף את תוכן חלקי הטקסט

גישה פשוטה זו מאפשרת לנו לשלוף בצורה יעילה את המידע הרלוונטי ביותר מאוסף המסמכים כדי להעשיר את שאילתת המשתמש לפני העברתה למודל השפה לייצור.

הגבר את שאילתת המשתמש באמצעות חלקים שנאחזרו וייצר תגובה באמצעות OpenAI GPT-4

כדי לייצר תגובה באמצעות החלקים שנשלפו והשאילתה של המשתמש, תחילה נצור פרומפט הכולל את החלקים הרלוונטיים והשאילתה של המשתמש. לאחר מכן, נשתמש במודל OpenAI GPT-4 כדי לייצר תגובה בהתבסס על פרומפט זה.

הנה הקוד:

# קבל את שאילתת המשתמש
user_query = "מה בירת צרפת?"

# שלוף את החלקים הרלוונטיים ביותר בהתבסס על שאילתת המשתמש
top_chunk_ids = [6, 8, 5]
top_chunks = [chunks[i] for i in top_chunk_ids]

# צור את הפרומפט
prompt = "השתמש בהקשר הבא כדי לענות על השאלה בסוף. אם אינך יודע את התשובה, אמור שאינך יודע ואל תנסה להמציא תשובה.\n\nהקשר:\n"
for chunk in top_chunks:
    prompt += chunk + "\n\n"
prompt += f"\nשאלה: {user_query}"

# ייצר את התגובה באמצעות OpenAI GPT-4
response = openai_client.chat.create(
    model="gpt-4",
    messages=[
        {"role": "user", "content": prompt}
    ],
    max_tokens=1024,
    n=1,
    stop=None,
    temperature=0.7,
).choices[0].message.content

print(response)

בקוד זה, תחילה אנו שולפים את החלקים הרלוונטיים ביותר בהתבסס על שאילתת המשתמש על ידי מציאת 3 החלקים העליונים בעלי ציוני הדמיון הגבוהים ביותר. לאחר מכן, אנו יוצרים פרומפט הכולל את החלקים האלה ואת שאילתת המשתמש. לבסוף, אנו משתמשים במודל OpenAI GPT-4 כדי לייצר תגובה בהתבסס על פרומפט זה.

התגובה המיוצרת תהיה תשובה קצרה ורלוונטית לשאילתת המשתמש, תוך ניצול המידע מהחלקים שנשלפו.

מסקנה

במדריך זה למדנו כיצד לבנות מערכת צ'אט מלאה עם מערכת שליפת מסמכים באמצעות רק 10 שורות של קוד פייתון. כיסינו את הרכיבים המפתחיים של צינור אוגמנטציית שליפה (RAG), כולל יצירת בסיס הידע, חלוקת מסמכים לחלקים, אמבדינג, שליפה וייצור באמצעות מודל שפה גדול.

הלקחים העיקריים הם:

  1. ניתן ליישם צינור RAG בסיסי ללא הצורך במסגרות מורכבות כמו Langchain או LlamaIndex. פייתון טהור וכמה ספריות מספיקים.
  2. חלוקת המסמכים שלך לפי המבנה (לדוגמה, פסקאות) היא אסטרטגיה פשוטה אך יעילה עבור רוב המקרים השימוש.
  3. אמבדינג של חלקי המסמך ושאילתת המשתמש, ולאחר מכן חישוב ציוני הדמיון, מאפשרים לך לשלוף את המידע הרלוונטי ביותר להעשרת שאילתת המשתמש.
  4. שילוב החלקים שנשלפו עם שאילתת המשתמש והזנתם למודל שפה גדול מאפשרים ייצור של תגובה רלוונטית ומועילה.

בעוד שדוגמה זו מספקת בסיס איתן, ישנן הזדמנויות רבות לבניית מערכות RAG מתקדמות ומורכבות יותר. מסגרות כמו Langchain ו-LlamaIndex יכולות להיות שימושיות בעת שילוב עם מגוון מאגרי וקטורים ומודלי שפה. עם זאת, התחלה עם יישום פייתון טהור יכולה לסייע לך להבין טוב יותר את המושגים והרכיבים הליבתיים של צינור RAG.

אם אתה מעוניין לחקור טכניקות RAG מתקדמות יותר, אני ממליץ לבדוק את הקורס שלי "RAG Beyond Basics", אשר חודר לעומק בבניית מערכות RAG מוכנות לייצור.

שאלות נפוצות