איך הפכתי קבוצת וואטסאפ לאתר ידע

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

לקחתי את ההיסטוריה של קבוצת וואטסאפ של בוגרי קורס טיס — 10,951 הודעות מפברואר 2023 עד יוני 2026 — והפכתי אותה לאתר חיפוש עם 1,494 המלצות מסודרות לפי קטגוריות, כולל ספירה של כמה אנשים המליצו על כל דבר. הדבר הכי מעניין שיצא מהפרויקט הוא דווקא כישלון: הוספתי לאתר צ׳אטבוט שמכיר את כל הטיפים, הקבוצה התלהבה, והשימוש בו נשאר דל. אנשים מחפשים בשדה החיפוש הרגיל.

הבעיה: וואטסאפ לא בנוי לשמור ידע

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

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

ה-pipeline: מזרם הודעות לאינדקס

הזרימה היא: Export Chat של הקבוצה, סקריפט שמפרסר את קובץ הטקסט ל-JSON מובנה, סקריפט שמפצל את הייצוא הראשון — שהיה מעט קטן מהמספר שמופיע היום בתחתית האתר — ל-87 באצ׳ים חופפים, ואז חילוץ מרובה-סוכנים שמוציא מכל באצ׳ את ההמלצות שבו.

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

החילוץ הראשוני החזיר 2,436 טיפים גולמיים. השלב המעניין הוא המיזוג: כשחמישה אנשים ממליצים על אותו יועץ משכנתאות בשלוש שיחות שונות לאורך שנתיים, זה לא חמישה טיפים — זה טיפ אחד עם חמישה ממליצים. מיזוג לפי קטגוריה שהמודל עשה, בתוספת איחוד תכנותי בין באצ׳ים, הוריד את זה ל-1,511 טיפים קנוניים בבנייה הראשונה.

מה שיצא בפועל, בגרסה שרצה היום:

קטגוריה טיפים
נותני שירות 497
פיננסים והטבות 433
בירוקרטיה ומדינה 372
טיפים ומדריכים 192

מתוך 1,494 הטיפים, ל-824 יש פרטי קשר, ו-331 קיבלו יותר מהמלצה אחת. השיא הוא תשע המלצות נפרדות על אותו דבר (הנחה בארנונה למשרתי מילואים). ספירת הממליצים היא הסיגנל הכי שימושי באתר, והיא לא הייתה קיימת באף הודעה בודדת — היא נוצרה רק מהמיזוג.

החלק שלקח הכי הרבה זמן היה פרטיות, לא חילוץ

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

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

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

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

בגרסה הרב-דיירית שבניתי אחר כך — MVP מקומי, control plane אחד שמנהל שתי קבוצות, כשהעיצוב עצמו הוא דאטה — השער הוא חוסם פרסום קשה: קריאת publish מחזירה 409 כל עוד קיים ולו ממצא חמור אחד. ממצא ברמת אזהרה, למשל טלפון של נותן שירות שנכתב בתוך פסקה, לא חוסם אלא נכנס לתור בדיקה.

העדכון של יום חמישי

יש routine task שמרעננת את האתר מההודעות החדשות בכל יום חמישי. היא במכוון לא אוטונומית מקצה לקצה: היא מושכת את התגובות שממתינות באתר ומגישה לי אותן עם המלצה, מחכה שאשלח לה ייצוא עדכני של הצ׳אט, קוראת את ההודעות מאז העדכון האחרון, מציעה טיפים להוספה — ורק אחרי אישור מדפלוית לאתר.

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

הצ׳אט שכולם רצו ובקושי משתמשים בו

הצ׳אט רץ על Claude Sonnet דרך Bedrock של AWS (יש לי שם מלא קרדיטים), בתוך Lambda מאחורי API Gateway. יש לו כלי אחד בלבד: חיפוש בתוך הטיפים המעובדים. הקורפוס הגולמי של ההודעות לא נטען אליו בכוונה — גופי ההודעות יכולים לחשוף שמות של חברי קבוצה.

יש הגבלת קצב לפי IP (עשר שאלות בשעה, עשרים וחמש ביום) ותקרה גלובלית יומית, כדי שמבקר משועמם לא ידפוק לי חשבון. השאלות והתשובות נשמרות אנונימית לגמרי — חותמת זמן, שאלה, תשובה, בלי IP ובלי זהות — וממשק הצ׳אט אומר את זה במפורש.

ואז: התלהבות בקבוצה, שימוש דל בפועל. מה שניצח הוא שדה החיפוש. שדה החיפוש הוא includes על מחרוזת lowercase, מעל מערך שיושב כולו בדפדפן, עם השהיה של 120 מילישניות בין הקלדות. אין שרת, אין מודל, אין עלות.

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

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

ידע גם מתיישן

הרצתי ביקורת תוכן על כל המאגר: 63 סוכנים עברו על כל טיפ בנפרד, לפי תוכן ולא רק לפי תאריך, וסימנו 174 טיפים כפוטנציאלית לא רלוונטיים. הקבוצה הגדולה ביותר היא אירועים תחומי-זמן (72) — מבצעים, וובינרים ומשרות שמועדם חלף — ואחריה רגולציה שהוחלפה (33) ובקשות חד-פעמיות (25).

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

מה נשאר מזה

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

ואם יש לכם קבוצה או ערוץ פנימי שצובר ידע ומאבד אותו — ככה בדיוק נראית העבודה הזאת אצלי, שלב אחרי שלב.

שאלות שחוזרות

איך הופכים קבוצת וואטסאפ לאתר עם כל הטיפים?

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

האם כדאי להוסיף צ׳אטבוט לאתר ידע?

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

איך שומרים על פרטיות כשמפרסמים תוכן מקבוצת וואטסאפ?

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