מנווט שירותי רווחה · AfifAI
מקרה בוחן · בינה מלאכותית לשירותי רווחה · ⁦2025–2026⁩

מדריך AI שמוצא לתושבים את שירות הסיוע הנכון בשתי קריאות מודל

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

⁦.NET 8⁩ / ⁦C#⁩PostgreSQLAmazon Bedrock AgentCoreClaude on BedrockPythonReact + TypeScriptAWS S3 / RDS / Lambda
לקוח
ארגון רווחה ישראלי שמרכז שירותי סיוע לאזור (חסוי)
צוות
צוות של 4 בהובלתי
התפקיד שלי
ראש צוות, ארכיטקט ומפתח בפועל
לוח זמנים
דצמבר 2025 – אוגוסט 2026 · בפרודקשן
סטטוס
באוויר
במבט מהיר
−⁦93%⁩הקשר למודל בכל קריאת דירוג: מכ־⁠245 אלף לכ־⁠17 אלף תווים
⁦3+⁩ עד 2קריאות מודל בכל סבב חיפוש (אחת כשהצ׳אט שואל שאלת המשך)
≈10 שניותזמן תשובה טיפוסי, לעומת דקות בתכנון הסוכן הראשון (הערכה)
0מזהי שירות לא מאומתים שמגיעים למשתמש. כל מזהה נבדק בקוד.
≤5 דקותמעדכון במאגר ועד שהוא מופיע בצ׳אט, בלי דיפלוי
354שירותים במאגר, לכל אחד כללי מיקום, היקף וגיל
5שפות ממשק, RTL ו־⁠LTR, כ־⁠850 מחרוזות בכל שפה
86נקודות קצה REST בשני APIs, ו־⁠31 טבלאות בבסיס הנתונים
הבעיה

מאות שירותים, ואין דרך פשוטה למצוא את המתאים

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

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

על מה הייתי אחראי

ארכיטקטורה, backend ושכבת ה־⁠AI

  • תכננתי את הפלטפורמה: שני APIs ב־⁠⁦.NET 8⁩ (לתושבים ולניהול), סכמת PostgreSQL של 31 טבלאות, worker להודעות ושלושה פרונטים ב־⁠React.
  • כתבתי את רוב ה־⁠backend: שיחות והיסטוריה, מאגר השירותים עם תרגומים, ארגונים ותפקיד ספק השירות, כניסה עם OTP, מייל ו־⁠SMS.
  • הובלתי את מנגנון ההתאמה דרך שלושה תכנונים: פרומפט ב־⁠Lambda, סוכן Bedrock, ולבסוף סוכן מבוקר ב־⁠Python על AgentCore Runtime. כתבתי runbook לכל אחד מהם.
  • בניתי את צינור המאגר: ייבוא CSV של 30 עמודות, סנכרון ל־⁠S3 מבוסס outbox, ו־⁠snapshot של המאגר שהסוכן טוען מחדש בלי דיפלוי.
  • הקמתי את סביבת הפרודקשן ב־⁠AWS: ‏RDS, ‏S3, ‏Lambda, ‏Bedrock ו־⁠IAM, והובלתי את הצוות בפרונטים ובשחרור הגרסאות.
ארכיטקטורה

המודל שואל ומדרג. הקוד מסנן.

התרשים רחב מהמסך: החליקו הצידה לצפייה בכולו →

מערכת הניהול היא מקור האמת היחיד. כל שינוי בשירות כותב שורה ל־⁠outbox. שלב הסנכרון בונה מחדש את המסמך של אותו שירות, ואחרי reindex מלא או ייבוא CSV כותב snapshot אחד של כל המאגר, שהסוכן טוען מחדש עם TTL של 5 דקות. המנוע הקודם נשאר מאחורי מתג קונפיגורציה, כך שהצוות יכול היה להשוות בין שני המסלולים ולחזור אחורה בלי דיפלוי.

החלטות תכנון

מה שחייב להיות מדויק, עושים בקוד

לשלוט בלולאה במקום סוכן אוטונומי

הסוכן המנוהל החליט לבד כמה פעמים לחפש בבסיס הידע, בדרך כלל 3 פעמים או יותר בכל סבב. ה־⁠runtime החדש מריץ רצף קבוע: תשאול, סינון, דירוג. שום דבר לא נשלף לפני שידועים היישוב, הגיל והצורך. המחיר: שירות Python לצד backend ב־⁠⁦.NET⁩, ותחזוקת התזמור עלינו.

מיקום וגיל בקוד, לא בפרומפט

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

קובץ snapshot של המאגר במקום אינדקס וקטורי

במאגר של 354 רשומות קצרות ומובנות, הסינון מצמצם את הרשימה לחציון של כ־⁠70 מועמדים עוד לפני שהמודל רואה משהו. קובץ JSON אחד ב־⁠S3 חסך chunking, משימות ingestion ובעיות של citation tokens. המחיר: זה עובד כל עוד המאגר נכנס לזיכרון; מאגר גדול בהרבה יחזיר את ה־⁠retrieval.

לאמת כל מזהה שהמודל מחזיר

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

מסלול חירום בלי מודל בכלל

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

יומן הנדסי

שלושה מנועים, ומה דחף אותנו לעבור לבא אחריו

רוב הבעיות הקשות צצו כשההתאמה רצה על נתוני מאגר אמיתיים ושאלות אמיתיות. מבחר:

ינואר 2026

כל המאגר בכל פרומפט

המנוע הראשון היה Lambda ששלחה את כל המאגר המכווץ עם כל בקשה: כ־⁠245 אלף תווים של נתוני שירותים, ב־⁠cache אבל נשלחים שוב בכל סבב, וגדלים עם כל שירות חדש.

השארנו אותו כבסיס עובד ועברנו לתכנון מבוסס retrieval על בסיס ידע מנוהל.

אפריל 2026

מזהי שירות הפכו ל־⁠citation tokens

ה־⁠chunking שבברירת המחדל הפריד בין שורת המזהה של כל שירות לבין הטקסט שלו. המודל החזיר את ה־⁠citation tokens של בסיס הידע במקום מזהים אמיתיים, ה־⁠backend לא הצליח לפענח אותם, והתאמות נכונות נעלמו.

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

מאי 2026

כפילויות ו־⁠JSON גולמי בצ׳אט

הסוכן רץ עם temperature 1. התשובות חרגו מחוזה ה־⁠JSON, חזרו על שירותים שכבר הוצגו, ולפעמים הציגו למשתמש {"answer": …} גולמי.

הורדנו את ה־⁠temperature ל־⁠0, הוספנו parser מוקשח ב־⁠backend, ורשימת המזהים שכבר הוצגו נשלחת בכל סבב כמקור האמת.

יוני 2026

תחום נכון, רשות לא נכונה

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

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

יוני 2026

תשובות שלקחו דקות

ה־⁠traces הראו כמה איטרציות אוטונומיות על בסיס הידע, ועוד pre- ו־⁠post-processing בכל סבב, ומעל זה throttling וניסיונות חוזרים.

החלפנו את הסוכן המנוהל בסוכן מבוקר על AgentCore Runtime: קריאה אחת לתשאול, אחת לדירוג, system prompt ב־⁠cache, ושאלות של ספירה או חיפוש לפי שם נענות מהמאגר בלי retrieval.

יוני 2026

הצ׳אט שאל שוב ושוב על היישוב

כשלא נשארו מועמדים, הסוכן שאל שוב על היישוב, והשיחה נכנסה ללולאה.

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

יוני 2026

שירותים ארציים דחקו החוצה שירותים מקומיים

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

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

יולי 2026

שינויים במאגר דרשו דיפלוי

ה־⁠runtime יצא עם קובץ CSV מובנה, כך שכל עדכון במאגר חייב דיפלוי מחדש של הסוכן.

ה־⁠backend כותב snapshot של המאגר ל־⁠S3 בכל reindex וייבוא CSV. הסוכן טוען אותו מחדש כל 5 דקות, וה־⁠CSV המובנה נשאר רק כגיבוי קר.

אותה שאלה, שני מנועים

מה קורה בסבב חיפוש אחד

שחזור מפושט של בקשה אחת: ”פיזיותרפיה לאישה בת 30 ביישוב באזור”. השלבים להמחשה בלבד. המספרים מגיעים מהקוד וממאגר של 354 שירותים. לא מוצגים נתוני לקוח.

תוצאות

איפה זה נחת

תחוםלפניאחרישינוימקור
הקשר בכל קריאת דירוגכל המאגר, כ־⁠245 אלף תוויםעד 60 מועמדים מסוננים, כ־⁠17 אלף תווים−⁦93%⁩נגזר מהקוד
קריאות מודל בסבב חיפוש3 איטרציות אוטונומיות או יותר2 (תשאול + דירוג), 1 לשאלת המשךירידה של ⁦33%⁩+נגזר מהקוד
זמן תשובה טיפוסידקותכ־⁠10 שניותפי 10 ויותרהערכה
מזהי שירות לא תקיניםcitation tokens, התאמות נזרקורק מזהים מרשימת המועמדים0 בתכנוןנגזר מהקוד
משינוי במאגר ועד הצ׳אטדיפלוי של הסוכןטעינה מחדש של snapshot כל 300 שניותעד 5 דקותנמדד
תוצאות מחוץ לאזורהמודל מסיק את המיקוםסינון דטרמיניסטי לפי רשות והיקף0 בבדיקותנגזר מהקוד
טעינת המאגרהזנה שירות אחר שירותייבוא CSV אחד (30 שדות) + reindex אוטומטימימים לדקותהערכה
תשובת חירוםדרך המודלרשימה מוגדרת, בלי קריאת מודל0 קריאות מודלנגזר מהקוד
  • בפרודקשן, עם ענפי dev, QA, stage ו־⁠prod בכל ריפו.
  • שלושה תפקידים על backend אחד: תושבים, ארגוני ספקי שירות שמנהלים את השירותים שלהם, ומנהלים שמאשרים אותם.
  • דוחות שימוש ושיחות שמיוצאים ממערכת הניהול לדיווח של הלקוח.
  • המאגר גדל מ־⁠318 ל־⁠354 שירותים בין גרסאות הנתונים, בלי שום שינוי בסוכן.
  • מסמכי runbook להקמת פרודקשן, לדיפלוי הסוכן ולמעבר בין המנועים, כדי שצוות הלקוח יוכל לתפעל את המערכת.
  • הצעדים הבאים: זיכרון מנוהל למשתמשים רשומים בין שיחות, וסט בדיקות של שאלות בכל חמש השפות.
טכנולוגיות

טכנולוגיות

Backend
שרתים ב־⁠⁦.NET 8⁩ ו־⁠⁦C#⁩ עם EF Core, בסיס נתונים PostgreSQL על RDS ו־⁠background worker
AI
סוכן Python על Bedrock AgentCore Runtime, מודל Claude Sonnet דרך Converse עם prompt caching; קודם לכן Bedrock Agents עם Knowledge Bases ו־⁠Lambda
פרונט
אפליקציות ב־⁠React ו־⁠TypeScript עם Vite, Redux Toolkit ו־⁠i18next, בעברית, ערבית, אנגלית, רוסית ואמהרית
AWS
העלאות pre-signed ו־⁠snapshot של המאגר ב־⁠S3, וגם RDS, ‏Lambda, ‏IAM ו־⁠CDK
אינטגרציות
מייל טרנזקציוני, שער SMS ל־⁠OTP, ייצוא לאקסל
היקף
5 ריפוזיטוריז, כ־⁠73 אלף שורות קוד, 1,248 קומיטים בכ־⁠8 חודשים

שיחת אבחון חינם · 30 דקות · ללא התחייבות

הביאו תהליך אחד. קבלו תוכנית ומספר לשפר.

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

לשיחת אבחון חינםafif.mansour@gmail.com

נפתח מייל מוכן מראש · מענה תוך יום עסקים

ה־AI קורא. הקוד סופר.

כל הפרויקטים