פיתוח מיקרו-שירות AI מקצה לקצה: FastAPI, Docker, סקיילינג

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

תחומי פיתוח AI

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1359
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    776
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח לוגו חברת AIDER
    פיתוח לוגו חברת AIDER
    1022
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113

פיתוח מיקרו-שירות AI: מה נשבר תחת עומס

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

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

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

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

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

מה משתנה אחרי הטמעה: השפעות מדידות

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

זמן הוצאת השינויים מתקצר פי כמה

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

השחזור הופך לצפוי

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

נעלם סוג שלם של כשלים בעומס יתר

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

פחות פעולות תחזוקה ידניות

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

מצבי עבודה של השירות: סינכרוני, זורם, אצווה

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

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

מה לקחת בחשבון לפני ההתחלה

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

סדר העבודה: אבחון, תרשים, פיתוח, מסירה

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

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

מה נשאר אצלכם: קונפיגורציות, תרשימים, נהלים

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

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

מקרה בוחן: איך השירות הפסיק ליפול תחת עומס שיא

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

בזרם יציב הוא עבד באופן צפוי, אבל בשיאים, כשהבקשות הגיעו פי 4–5 מהרגיל, הוא התחיל להתדרדר: זמן התגובה ל-95% מהבקשות עלה מ-0.4 שניות ל-8–9, שיעור הכשלים הגיע ל-12%, וחלק מהמשימות אבדו בהפעלה מחדש של הקונטיינר.

איפה היה צוואר הבקבוק

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

מה שינו ואילו מדדים התקבלו

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

אחרי הבנייה מחדש התפוקה גדלה פי 3.5 על אותו צי מכונות. בשיאים הקודמים זמן התגובה ל-95% מהבקשות נשמר בטווח של 0.5 שניות, שיעור הכשלים ירד מתחת ל-0.5%, וניסיונות חוזרים מצד הלקוח כמעט נעלמו.

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

מה לעשות אם השירות כבר פרוס אבל לא מתרחב?

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

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

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

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

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

ספקות לגבי עומס, הרשאות ותחזוקה

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

העיקרון אחד: מתן תחזיות ואימון המודל מופרדים. סביבת העבודה משרתת בקשות, וסביבה נפרדת מכינה ובודקת גרסאות חדשות, ולכן אפשר להחליף מודל, מפתחות וקונפיגורציה прямо תחת העומס הנוכחי.

איך מעבירים מודל עובד בלי לעצור את השירות?

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

איזו גישה לנתונים נדרשת לשירות?

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

למה לבודד סביבות?

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

מה קורה עם אימון נוסף אחרי ההשקה?

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

מי אחראי לשירות אחרי המסירה?

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

נדון במשימה ונחזור עם הערכה ותוכנית

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

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

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

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

תארו את המשימה בכתב או בשיחה — נחזור עם הערכה ותוכנית.