סוכן הוקרת מתנדבים · AfifAI
מקרה בוחן · הנדסת AI · 2026

סוכן Copilot שמכין לרכזים תדריך על כל מתנדב לפני אירוע

רכזי מתנדבים בעמותות שואלים ב־⁠Teams או ב־⁠Microsoft 365 Copilot Chat ומקבלים דוסייה קצרה ואישית לכל מתנדב במשמרת: מה הוא עשה עד היום, למה הוא רשום ואיך כדאי להודות לו או לחזק את הקשר. כל עובדה מגיעה מרשומות המתנדבים של הארגון עצמו, וארגונים לא רואים את הנתונים אחד של השני.

⁦.NET 8⁩Microsoft 365 Agents SDKAzure AI Foundry AgentsAzure AI SearchAzure OpenAI gpt-4oContainer AppsKey Vault
לקוח
ספקית SaaS אמריקאית לניהול מתנדבים בעמותות (חסוי)
התפקיד שלי
ראש צוות, ארכיטקט ומפתח בפועל
שלב
שלבים ⁦0–3⁩ הושלמו; פיילוט חי בטננט ההשקה, אמצע 2026
סטטוס
פיילוט חי
במבט אחד
פחות מדקהלהכנה לאירוע, במקום ≈30 דקות של חיפוש ידני ברשומות (הערכה)
6 שעותסנכרון אוטומטי של נתוני כל לקוח, במקום ייצוא ידני
0שינויי קוד לקליטת לקוח: שורה ברישום, שני סודות בכספת וסבב סנכרון אחד
1 עד 0קריאות הקמת סוכן לכל לקוח בכל סנכרון שוטף
0מסלולי fallback בין טננטים. טננט לא מוכר נדחה, ו־⁠8 טסטי בידוד נועלים את זה
500מסמכים בכל אצוות upsert לאינדקס, בהזרמה מ־⁠API מדופדף
13מוקשי פריסה שנמצאו ונכנסו ל־⁠runbook ולסקריפטים

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

הבעיה

הנתונים היו קיימים, אבל לאף אחד לא היה זמן לקרוא אותם לפני אירוע

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

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

מה הובלתי

ארכיטקטורה, קוד ומסירה, מקצה לקצה

  • תכננתי את הארכיטקטורה של שני השירותים ואת מודל הבידוד לכל לקוח, ובניתי את תוכנית המסירה בשלבים (⁦0–3⁩).
  • כתבתי את רוב קוד ה־⁠⁦.NET 8⁩: שירות ה־⁠ingestion, הסוכן השיחתי, החוזים המשותפים וטסטי הבידוד.
  • כתבתי סקריפטים להקמה ולפריסה (משאבי Azure, Container App, App Service, Bot Service, חבילת Teams) ואת ה־⁠runbook התפעולי.
  • הרצתי את הפריסה הראשונה מההתחלה ועד הסוף, תיקנתי כל כשל של הרשאות, RBAC ואריזה, והפכתי כל אחד מהם לשלב ב־⁠runbook.
מה בניתי

שני שירותים, חוזה משותף אחד

ארכיטקטורה

בידוד לכל לקוח ברמת הנתונים

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

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

החלטות תכנון

קודם בידוד, אחר כך מודל

בידוד פיזי, לא רק סינון

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

הטננט מגיע מהטוקן, אף פעם לא מהטקסט

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

שני שירותים שחולקים רק חוזה

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

מודל איפה שהוא עוזר, כללים איפה שחייבים

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

יומן הנדסי

מה נשבר בדרך לתשובה החיה הראשונה

הפריסה הראשונה מההתחלה ועד הסוף חשפה את רוב העבודה האמיתית. מבחר:

בידוד

fallback למייל שיכול היה לחצות טננטים

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

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

Ingestion

כל סנכרון היה תלוי ב־⁠RBAC איטי

הקמת סוכן דורשת הרשאות data-plane ב־⁠Foundry, שלקח להן ⁦5–15⁩ דקות להתפשט. קריאת list-or-create בכל סבב גרמה לכל סנכרון להיכשל עד אז.

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

Ingestion

רשומות חלקיות מה־⁠API

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

המיפוי null-safe. רשומות חלקיות מדולגות ונספרות בלוג הסנכרון, כך שהן לא מפילות את הסבב ולא יוצרות כפילויות.

הרשאות

תשובות הבוט נדחו עם 401

ה־⁠SDK החדש התעלם מההגדרות הישנות של Bot Framework, וה־⁠host נכשל בעלייה עד שנוספה הפניה לחבילת MSAL. אחרי שעלה, טוקנים יוצאים הונפקו אבל כל תשובה נכשלה עם 401.

עברנו לקונפיגורציית ה־⁠connections של ה־⁠SDK, נתנו לסוד בכספת שם שנוחת על מפתח הקונפיגורציה הנכון, וכיוונו את ה־⁠authority לטננט הבית של הבוט, כפי שבוט single-tenant מחייב.

פריסה

כל נתיב החזיר 404

ה־⁠App Service של הסוכן נוצר על runtime stack לא נכון, ולכן אפליקציית ה־⁠⁦.NET⁩ אף פעם לא עלתה.

תיקנתי את ה־⁠stack והוספתי ל־⁠runbook בדיקת health, כדי לתפוס את זה לפני שמחברים את הבוט.

אריזה

Teams דחה את החבילה

סוכני custom engine דורשים סכמת מניפסט 1.20 ומעלה, ו־⁠scope של Copilot דורש 1.21. בנוסף, zip שנבנה בכלי הלא נכון יצר נתיבים שהוולידטור דחה.

עברנו לסכמה 1.21 וכתבנו סקריפט build ששם את שלושת הקבצים בשורש ה־⁠zip. הממצא הזה ועוד 12 נכנסו ל־⁠runbook.

נסו בעצמכם

איך פנייה מטופלת

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

תוצאה

איפה זה עומד

מדדלפניאחרימקור
הכנה לאירועחיפוש ידני ברשומות, ≈30 דק׳דוסייה בפחות מדקההערכה
עדכניות הנתוניםייצוא אד־הוקסנכרון אוטומטי כל 6 שעותקונפיגורציה
קליטת לקוחמוצר חדש, אין תהליךקונפיגורציה בלבד: שורה + 2 סודותנגזר
קריאות הקמה בכל סנכרון1 לכל לקוח0 אחרי הסבב הראשוןנגזר
מסלולי fallback בין טננטים1 (דומיין מייל)0, עם 8 טסטיםקוד
עריכת דוסייהשליפה וכתיבה מחדששכתוב הטקסט השמור, 0 שליפותקוד

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

  • שלבים ⁦0–3⁩ נמסרו: חוזים משותפים, ingestion, סוכן וחבילת Teams, כל אחד עם סקריפטי פריסה.
  • חי בטננט ההשקה, עם דוסיות מבוססות נתונים ב־⁠Teams וב־⁠Microsoft 365 Copilot Chat מחבילה אחת.
  • השעיית לקוח היא שינוי סטטוס אחד, שנכנס לתוקף תוך 30 השניות של ה־⁠cache של הרישום.
  • Runbook שמכסה הקמה, RBAC, פריסה וקליטת לקוחות, כולל 13 המוקשים מההשקה הראשונה.
  • הצעדים הבאים: רישום משותף ועמיד במקום העתקת קובץ, session state מתמשך לצורך scale-out, והרחבה ללקוחות נוספים בפרודקשן.
טכנולוגיות

טכנולוגיות

סוכן
⁦ASP.NET Core⁩ (⁦.NET 8⁩), Microsoft 365 Agents SDK, Azure Bot Service
AI
Azure AI Foundry Agents, Azure OpenAI gpt-4o
שליפה
Azure AI Search, אינדקס לכל לקוח
Ingestion
⁦.NET 8⁩ Worker Service; Azure Container Apps או App Service
אבטחה
Entra ID, managed identities, Key Vault, RBAC
תפעול
סקריפטי Bash, ACR builds, Application Insights, xUnit

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

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

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

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

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

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

כל הפרויקטים