בואו נטוס גבוה. אתם בעלי עסק, ויש לכם בעיה שחוזרת על עצמה: לקוחות שואלים את אותן שאלות שוב ושוב. "מתי אתם פתוחים?", "כמה עולה משלוח לחיפה?", "יש לכם את הנעל הזאת במידה 42?". התשובות כבר קיימות אצלכם — בקטלוג, במחירון, במסמך מדיניות ההחזרות. הן פשוט קבורות בקבצים שאף לקוח לא יקרא. כאן נבנה צ'אטבוט שעונה מתוך המידע שלכם — לא מתוך ידע כללי של האינטרנט.
הדרכות
לבנות צ'אטבוט לעסק: שירות לקוחות 24/7 שעונה מהמידע שלכם
איך מקימים בוט שעונה מתוך מסמכי העסק שלכם — מחירון, שעות, מדיניות — בלי שירות מתכנת, מתי RAG הוא הפתרון, ואיך מונעים את התשובה השגויה שתעלה לכם בלקוח.

למה אי אפשר פשוט לשאול את ChatGPT?
נתחיל מהבעיה, כי בלי להבין אותה כל הפתרון נראה כמו קסם.
מודל שפה גדול (LLM — Large Language Model, מנוע ה-AI שמייצר טקסט כמו ChatGPT או Claude) הוא בעצם מכונת ניחוש מילים. הוא קרא חתיכה עצומה מהאינטרנט ולמד לנחש איזו מילה הכי סבירה לבוא אחרי הקודמת. זה מרשים — אבל יש כאן שתי בעיות שהורגות אותו לעסק שלכם.
ראשית, המודל לא יודע כלום על העסק שלכם הספציפי. הוא לא ראה את המחירון שלכם, לא את שעות הפתיחה, לא את מדיניות ההחזרות. שאלתם אותו "כמה עולה משלוח אליי?" — הוא ימציא מספר שנשמע סביר. זה נקרא הזיה (hallucination): כשהמודל פולט תשובה בטוחה בעצמה אבל שגויה לחלוטין, כי אין לו את העובדה האמיתית והוא "ניחש" אותה. הזיה היא לא באג נדיר — זו התנהגות ברירת המחדל של מכונת ניחוש כשחסר לה מידע.
שנית, גם אם המודל איכשהו ידע את המחיר היום — מחר תעלו מחירים, והוא יישאר תקוע על הישן. הידע שלו "קפוא" ברגע שבו אימנו אותו (שלב שבו הזינו לו את כל הטקסט שילמד ממנו). הוא לא מתעדכן לבד.
הרעיון הגדול: תן למודל לקרוא לפני שהוא עונה
הנה האינטואיציה, בלי שום מתמטיקה. דמיינו עובד חדש מבריק שמתחיל אצלכם היום בבוקר. הוא חכם, מנסח יפה, אדיב — אבל הוא לא יודע כלום על העסק. מה תעשו? לא תבקשו ממנו לענות מהבטן. תיתנו לו את התיקייה הנכונה לקרוא רגע לפני שהוא עונה ללקוח.
זה בדיוק הטריק. במקום לקוות שהמודל "יזכור" את המידע שלכם, אנחנו שולפים את הקטע הרלוונטי מהמסמכים שלכם ומדביקים אותו לתוך השאלה — ואז מבקשים מהמודל לענות רק על סמך הקטע הזה. השם המקצועי לטכניקה הוא RAG — ראשי תיבות של Retrieval-Augmented Generation, כלומר "יצירת תשובה שמועשרת בשליפת מידע". "שליפה" (Retrieval) = למצוא את הקטע הנכון. "יצירה" (Generation) = לנסח ממנו תשובה. זהו. הכול שם בשם.
איך המכונה "מוצאת את הקטע הנכון"?
כאן החלק היחיד שדורש מושג אחד חדש, ואני אסביר אותו עד הסוף.
הבעיה: לקוח שואל "אתם מחזירים כסף?" אבל במסמך שלכם כתוב "מדיניות ביטולים והשבת תמורה". חיפוש מילים רגיל (כמו Ctrl+F, שמחפש התאמה מדויקת של אותיות) ייכשל — אין אף מילה משותפת. אנחנו צריכים חיפוש שמבין משמעות, לא רק אותיות.
הפתרון נקרא embedding (אֶמְבֶּדינג, "הטמעה"). זה רכיב שלוקח קטע טקסט והופך אותו לרשימת מספרים — מעין "קואורדינטות" שמייצגות את המשמעות של הטקסט. המהות: שני טקסטים בעלי משמעות דומה מקבלים מספרים קרובים זה לזה, גם אם המילים שונות לגמרי. כמו ערים על מפה — "החזר כסף" ו"השבת תמורה" יושבים קרוב, ו"שעות פתיחה" רחוק משם. כשלקוח שואל, אנחנו ממירים את שאלתו לאותן קואורדינטות ומחפשים את קטעי המסמך הכי קרובים על המפה. אלה הקטעים שנדביק למודל.
איפה שומרים את כל הקואורדינטות האלה? בVector Database (וקטור-דאטה-בייס) — מסד נתונים שבנוי במיוחד לחפש "מי הכי קרוב על המפה" במהירות, גם אם יש לכם מיליון קטעים. ("וקטור" = פשוט המילה המקצועית לאותה רשימת מספרים.)
התהליך מקצה לקצה
עכשיו נחבר הכול לתהליך אחד ברור. שימו לב שהוא מתפצל לשני שלבים: הכנה (פעם אחת מראש) ומענה (בכל שאלה).
הצינור בפועל — דוגמה שאפשר להריץ
אל תפחדו מהקוד, אני אסביר כל שורה. נניח שיש לכם קובץ faq.txt עם השאלות הנפוצות. הנה השלד ב-Python:
# שלב הכנה — רץ פעם אחת
from openai import OpenAI
client = OpenAI()
# 1. חותכים את המסמך לקטעים קטנים (chunks) של ~200 מילה
chunks = open("faq.txt").read().split("\n\n") # פסקה ריקה מפרידה = קטע
# 2. ממירים כל קטע לאמבדינג (רשימת מספרים) ושומרים
db = []
for chunk in chunks:
vec = client.embeddings.create(
model="text-embedding-3-small", input=chunk
).data[0].embedding
db.append((chunk, vec))
מה קרה כאן? חתכנו את המסמך לפסקאות קצרות, כי מדביקים למודל קטע ממוקד — לא ספר שלם. כל פסקה הומרה לאמבדינג ונשמרה. עכשיו שלב המענה:
import numpy as np
def answer(question):
# 3. ממירים את השאלה לאמבדינג
q = client.embeddings.create(
model="text-embedding-3-small", input=question
).data[0].embedding
# 4. מוצאים את הקטע הכי קרוב. המכפלה (np.dot) מודדת כמה שני
# הווקטורים מצביעים לאותו כיוון: ערך גבוה = משמעות דומה.
# זה עובד כי אמבדינגים של OpenAI מגיעים באורך אחיד (מנורמלים),
# ולכן המכפלה כאן שווה בדיוק ל"דמיון קוסינוס" — מדד הזווית בין הכיוונים.
best = max(db, key=lambda x: np.dot(q, x[1]))[0]
# 5. נותנים למודל את הקטע + השאלה, ומגבילים אותו אליו
prompt = f"ענה רק לפי המידע הבא. אם אין תשובה, אמור 'אין לי מידע'.\n\n{best}\n\nשאלה: {question}"
return client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}]
).choices[0].message.content
השורה החשובה ביותר היא ההוראה בפרומפט: "ענה רק לפי המידע הבא, ואם אין — אמור שאין לך". זה הבלם נגד הזיות: אנחנו מורידים מהמודל את ההרשאה להמציא, ומכריחים אותו להישען על המקור שנתנו. בלי המשפט הזה, המודל ימלא חורים מהדמיון שלו — וזה בדיוק האסון שרצינו למנוע.
כמה כללי אצבע שיצילו אתכם
גודל הקטע (chunk) קובע הכול. קטע ענק = המודל טובע במידע ולא מוצא את הרלוונטי. קטע זעיר = חותכים משפט באמצע ומאבדים הקשר. ~200–500 מילה זה איזון טוב להתחיל ממנו.
"מקור לכל תשובה" בונה אמון. הציגו ללקוח מאיזה מסמך הגיעה התשובה ("מתוך: מדיניות משלוחים"). זה מאפשר לכם וללקוח לתפוס טעות מיד.
עדכון = החלפת קובץ. העליתם מחירים? תחליפו את פסקת המחירון ותריצו מחדש את שלב ההכנה רק עליה. אין צורך לאמן שום דבר — וזה היופי של RAG על פני "ללמד מחדש את המודל" (תהליך יקר ואיטי שדורש להזין לו מחדש המון דוגמאות).
זה הכול. לקחתם מודל ש"לא יודע כלום על העסק שלכם", ובמקום לקוות שינחש — נתתם לו לקרוא את התיקייה הנכונה רגע לפני שהוא עונה. בואו נטוס.
אמ;לק
5 הדברים שצריך לדעת
במקום להמציא, הבוט קודם שולף את המידע מהמסמכים שלכם ורק אז מנסח. ככה הוא מסתמך על מקור ולא מנחש.
מחירון, שעות, מדיניות ושאלות נפוצות במסמך אחד מעודכן. הבוט טוב בדיוק כמו המידע שאתם מזינים לו.
System Prompt שמורה לבוט לענות רק מהמקור ולהודות כשאין מידע — זה מה שמבדיל בוט אמין מבוט מסוכן.
כסף, תלונה רגשית, מקרה רפואי או משפטי, וכל מה שאין במסמכים — הבוט עוצר ומעביר לנציג עם סיכום.
כולל שאלות מלכודת. רק כשהבוט עונה נכון ומודה כשאין מידע — משחררים. ומעדכנים מסמכים כל חודש.
פניות תקשורת
לראיונות, שיתופי פעולה והרצאות — נשמח לדבר.



