מי שפיתח מערכת Embedded מכיר את הקצב הישן. כותבים דרייבר, בונים את הפרויקט, צורבים קושחה, מבצעים reset, מחכים ל־log, מגלים שהתקלה זזה שלב אחד קדימה וחוזרים לקוד. גם כשהתיקון עצמו קטן, המעבר הידני בין העורך, כלי הבנייה, הצורב, הטרמינל והמעבדה מצטבר לימים או לשבועות. חלק גדול מן הזמן אינו מושקע בהמצאת האלגוריתם, אלא בהעברת ראיות מן החומרה אל הראש של המהנדס ובחזרה.
בפרויקט שלנו התחושה הייתה לפעמים קיצונית: עבודה שבשיטה המסורתית הייתה תופסת כמעט את כל השבוע התקדמה בערך בעשירית מן הזמן, ובשלבים מסוימים אפילו מהר יותר. זה אינו benchmark, לא מחקר ולא הבטחה שכל פרויקט יתקצר פי עשרה או פי עשרים. זו דוגמה לפוטנציאל שראינו כאשר Codex קיבל סביבת עבודה נכונה, יכול היה לבצע בעצמו את הפעולות החוזרות, ולא נאלץ לחכות שאעתיק אליו כל קובץ וכל שורת UART.
קל להסיק מכאן שהמודל נעשה לפתע מומחה לכל בקר, לכל מערכת הפעלה ולכל ציוד מעבדה. זה לא מה שקרה. המהנדס בנה עבורו מסלול עבודה: קוד ודרייברים קיימים, פקודות build ו־flash יציבות, ערוץ תצפית מן הלוח וקריטריון הצלחה שאינו תלוי בדעתו של הסוכן. השאלה המעניינת לכן אינה כמה קוד ה־AI יודע לכתוב, אלא מה קורה כשהוא מקבל דרך סדורה לפעול בעולם הפיזי.
הקיצור האמיתי אינו בכתיבת הקוד. בעבר ה־AI היה יועץ מרוחק: אני בחרתי איזה קובץ להראות לו, העתקתי שגיאת קומפילציה, צרבתי את התיקון והחזרתי כמה שורות מן ה־log. האדם היה גם השליח וגם עורך הראיות. אם העתקתי רק את סוף התקלה, או צרבתי בטעות image ישן, המודל יכול היה לנתח בצורה הגיונית לחלוטין מציאות שלא באמת הייתה על הלוח.
Agentic AI, או AI שפועל כסוכן, משנה את חלוקת העבודה הזאת. במקום להסתפק בתשובה, הסוכן יכול לבחור פעולה, להפעיל כלי, לקרוא את התוצאה ולהחליט מה לעשות אחר כך. Tool-Using Agent הוא פשוט סוכן שקיבל ממשקים מוגדרים לחיפוש בקוד, קריאת מסמך, בניית הפרויקט, צריבת הקושחה או פתיחת ערוץ תקשורת. הכוח אינו בפקודת Shell אחת, אלא בכך שתוצאה של פעולה אחת קובעת את הפעולה הבאה.
כדי שזה יעבוד, הסוכן אינו אמור להתחיל כל רכיב מאפס. הוא צריך להשתמש בדרייברים שכבר נבדקו, בקוד הקיים, בדוגמאות היצרן ובמבנה הפרויקט שהמהנדסים כבר בנו. כתיבה מחדש של שכבת חומרה שלמה אולי נראית מרשימה בצ׳אט, אבל היא מוסיפה משתנים בדיוק במקום שבו אנחנו רוצים לצמצם אותם. סביבת עבודה טובה אומרת לסוכן מה כבר קיים, מה מותר לשנות ואילו אבני בניין הן נקודת המוצא הסמכותית.
כאן מתחיל החיסכון הגדול. הסוכן יכול לערוך שינוי ממוקד, לבנות ולקמפל, לחתום את קובצי הקושחה אם צריך, לצרוב אותם, לבצע reset ולקרוא את הפלט בלי שהאדם יתזמן כל צעד. במקום שאחזור לעמדה רק כדי לגלות שה־build נכשל לפני הצריבה, הלולאה נעצרת בעצמה, מתקנת את שגיאת הבנייה ורק אז נוגעת בחומרה. הזמן שנחסך אינו רק זמן הקלדה; זה הזמן המת שבין ניסוי לניסוי.
כשהלוגים מפסיקים לעבור דרך האדם, נוצרת לולאה סגורה — Closed Loop. הסוכן משנה קוד, בונה את קובץ הקושחה המדויק, צורב אותו, מאתחל את הלוח וקורא COM, UART, RTT או debugger. התוצאה חוזרת אל אותו תהליך שקיבל את ההחלטה הקודמת ומשנה את ההחלטה הבאה. זו הנקודה שבה אוסף כלי פיתוח הופך למערכת דיבאג רציפה.
אין צורך, וגם אין בסיס אמין, לטעון שאפשר לצפות בשרשרת המחשבה הסודית של המודל. מה שאפשר לבדוק הוא תהליך העבודה הגלוי: השערה, פעולה באמצעות כלי, תצפית, השוואה לציפייה, עדכון ההשערה וניסיון נוסף. Autonomous Debugging אינו קסם שמוצא תמיד את סיבת השורש בניסיון הראשון; זו היכולת לבחור שוב ושוב ניסוי שמפריד בין האפשרויות, ולשמור תיעוד של מה כבר הוכח ומה עדיין רק ניחוש.
בשביל לבדוק עד כמה העבודה עם סוכן עדיפה על רצף ה־Copy/Paste הרגיל, הלכנו בכוונה לקיצון. בחרנו פרויקט המבוסס על STM32N6 — בקר חדש מאוד ובעל ארכיטקטורה מורכבת, אבל כזה שכבר יש עבורו מספיק תיעוד ודוגמאות עובדות. לא רצינו לבדוק אם המודל מסוגל להמציא ידע, אלא אם הוא יכול לקחת ידע מפוזר של היצרן, לחבר אותו למערכת אחת ולהוכיח על חומרה אמיתית שהחיבור עובד.
הסוכן נדרש לאחד שרשרת boot מאובטחת, חיישן עומק שמעביר נתונים דרך DMA, עיבוד מקבילי תחת RTOS, USB מהיר למחשב ושכבת תקשורת אלחוטית אופציונלית. כל חלק עבד בדוגמה נפרדת, אך לכל דוגמה היו הנחות אחרות לגבי שעונים, זיכרון וסדר אתחול. כדי להפוך את האיחוד לניסוי אמין, נתנו לסוכן פעולות קבועות שבונות, חותמות וצורבות את כל קובצי הקושחה, מבצעות reset ומחזירות log מלא. כך הוא ידע בכל איטרציה איזה קוד באמת רץ ומה החומרה עשתה איתו.
כאשר ה־USB לא הופיע ב־Windows, הסוכן לא ניחש מיד שהבעיה בקוד. הוא הריץ את דוגמת היצרן על אותו לוח וכבל, ראה שהיא מופיעה כ־COM וכך שלל את המסלול הפיזי. רק אז הוא השווה בין הפרויקטים וגילה ששלב מוקדם ב־boot כיבה שעון שה־USB נזקק לו מאוחר יותר. הוא תיקן, בנה, צרב ובדק שוב. זו בדיוק היעילות של Closed Loop: ניסוי אחד מצמצם משפחה שלמה של השערות ומוביל ישירות לבדיקה הבאה.
תקלה אחרת הפילה את הלוח ל־HardFault. במקום לחפש בעיניים בין אלפי שורות, הסוכן קיבל מן ה־UART את סימני התקלה, מיפה את כתובות הריצה מול קובץ ה־ELF והשווה אותן לדוחות השימוש בזיכרון. כך התברר שכלי יצירת הקוד החזיר stack לערך קטן מדי. אחרי התיקון נוספה גם בדיקת preflight שחוסמת את אותה טעות בעתיד — דוגמה לכך שהלולאה אינה רק פותרת תקלה, אלא הופכת את הידע שנלמד להגנה קבועה.
אותה שיטה עבדה גם על בעיות מסוגים אחרים. כאשר ה־USB נפתח אך הנתונים נתקעו, מונים הראו שהעברה נשלחה אך callback לא חזר, והפנו את החיפוש אל גודל ה־FIFO ואל סדר העדיפויות בין המשימות. כאשר עיבוד החיישן לא עמד בקצב, מדידות זמן מן החומרה הובילו לחלוקת העבודה בין DMA, משימת איסוף ומשימת עיבוד מקבילה. בכל המקרים הסוכן לא היה צריך לנחש את התשובה מראש; הוא היה צריך לקבל ראיה שמפרידה בין השערות, לשנות דבר אחד ולמדוד שוב.
אלה אינן שגיאות קומפילציה אלא תקלות שדורשות מומחיות מצטברת ב־boot, בשעונים, ב־RTOS, בזיכרון, ב־USB ובכלי דיבאג. זו אינה שאלה של אינטליגנציה או של תואר. גם סטודנט מצטיין שסיים תואר שני יכול להכיר היטב את התאוריה ועדיין לא לחשוד שיצירת קוד החזירה stack לברירת מחדל, או ששינוי ב־FSBL כיבה שעון שפריפריה תצטרך רק מאוחר יותר. הנדסאי או מהנדס שעבר עשר שנות bring-up כנראה כבר פגש ריח דומה וידע אילו register, מפה או מונה לבדוק.
היתרון של הסוכן הוא שחלק גדול מן המומחיות הזאת כבר קיים במקום כלשהו: ב־reference manual, בדוגמת היצרן, בקוד ה־HAL, ב־release notes, בקובץ ה־linker ובדיון שמסביר התנהגות של middleware. אם יניחו לפני אדם את אלפי העמודים האלה כספר ויבקשו ממנו לחבר הכול בזמן אמת, אין לו סיכוי מעשי להחזיק כל פרט בראש. הסוכן יכול לחפש בכל החומר, להשוות קבצים ולשמור כמה שכבות של ראיות פעילות בו־זמנית. זה עדיין לא הופך כל תשובה שלו לנכונה; זו בדיוק הסיבה שכל מסקנה חזרה ל־build, לצריבה ולמדידה על הלוח.
לכן ה־STM32N6 אינו נושא הכתבה אלא ניסוי קצה שממחיש את השיטה. הוא סיפק מספיק מורכבות כדי לדרוש מומחיות אמיתית, ומספיק תיעוד ודוגמאות כדי שהסוכן לא יצטרך להמציא את העולם. החלק המעניין הוא שהסוכן לא הסתפק בהצעת קוד: הוא השתמש בפרויקט ייחוס, ב־fault registers, בקובץ ELF, בדוחות זיכרון, במונים ובפלט פיזי כדי לצמצם את מרחב החיפוש. ברגע שהניסוי הבא נבחר לפי הראיה הקודמת, הדיבאג מתחיל להיראות פחות כמו שיחה ויותר כמו תהליך הנדסי שאפשר להאיץ, לתעד ולשחזר.
כדי שסוכן ידבג, המערכת צריכה לדעת לדבר. Observability — היכולת לראות מה קורה בתוך המוצר — אינה תוספת שמכינים בסוף לקראת תקלה נדירה. הלוגים, המונים, ה־assertions, נקודות הבדיקה וממשקי השליטה הם חלק מן הארכיטקטורה שמאפשרת לסוכן לעבוד. לעיתים כדאי להשקיע בהם כמעט כמו בפונקציונליות עצמה, מפני שבלי תצפית גם קוד נכון וגם קוד תקול נראים מבחוץ כמו קופסה שקטה.
המשפט 'ה־USB לא עובד' כמעט חסר ערך למכונה וגם למהנדס. לעומת זאת, רצף של סימנים יכול לומר שהכבל זוהה, בקר ה־USB התחיל, ההתקן עבר להגדרה, buffer נכנס לתור, transfer נשלח אך callback לא חזר. כל breadcrumb כזה מחלק תקלה רחבה לשאלה צרה יותר. כך אפשר להבדיל בין בעיית clock, זיכרון, תזמון, הרשאה או חיבור פיזי בלי לשנות חמישה דברים באותה צריבה.
החומרה שעל השולחן נקראת DUT, קיצור של Device Under Test — המוצר או הלוח שנבדקים. כדי שה־DUT יהיה חלק אמיתי מן הלולאה, הסוכן צריך לקבל ממנו Hardware Feedback, כלומר עדות מן העולם הפיזי ולא רק הודעה שהקומפיילר הצליח. זו יכולה להיות קריאה של register דרך debugger, חבילת נתונים שהגיעה למחשב, waveform שנמדד ב־scope, שינוי בצריכת הזרם או תגובה של חיישן לגירוי ידוע.
כאן נכנס Test Oracle, הבוחן שקובע אם הניסוי באמת הצליח. Build ירוק הוא oracle טוב לשאלה אם הקוד מתקמפל, אבל הוא אינו מוכיח שהפין החליף מצב, שהודעת CAN יצאה בזמן או שהחיישן ראה מטרה. לכל טענה צריך להתאים עדות: host שמקבל packet, logic analyzer שסופר פולסים, מד זרם שבודק מצב שינה או fixture שמפעיל כפתור ומודד יציאה.
עדיף שה־Test Oracle יהיה בלתי תלוי ככל האפשר בקוד שאותו הוא בודק. קושחה שגויה יכולה להדפיס PASS, וסוכן שכתב גם את המימוש וגם את הבדיקה עלול לגרום לשניהם להסכים על אותה טעות. ככל שהטענה חשובה יותר, כך העדות צריכה להגיע רחוק יותר מן הקוד שמנסה להוכיח אותה. זו הסיבה ש־Hardware Feedback חיצוני משנה את איכות הלולאה, ולא רק את מהירותה.
המעבדה הופכת לממשק תוכנה כאשר מוסיפים ללולאה גם גירויים וציוד בדיקה. HIL, או Hardware-in-the-Loop, הוא שם ותיק לשיטה שבה חומרה אמיתית מחוברת לסביבה שמדמה או מפעילה את העולם שסביבה. אני משתמש ב־Agentic HIL כמונח מטרייה, לא כתקן חדש: סוכן שמפעיל את שרשרת הפיתוח, מפעיל את ה־DUT או את סביבתו, קורא את המדידה וממשיך עד ש־oracle חיצוני מאשר הצלחה.
מנקודת המבט של הסוכן, ספק כוח, debugger, UART, CAN, ממסרים, scope וציוד בדיקה אינם חלונות GUI אלא פעולות. לכל פעולה יש קלט מוגדר, תשובה מובנית ושגיאות ברורות: הדלק מתח עם מגבלת זרם, צרוב image לכתובת מאושרת, אסוף log מלא מן ה־reset או מדוד תדר בנקודת בדיקה. כשהפעולות האלה יציבות, המעבדה מתחילה להתנהג כמו API שאפשר להרכיב ממנו ניסויים.
אפשר להתחיל מסקריפטים קטנים ומכלי CLI קיימים. כאשר המעבדה גדלה, MCP — Model Context Protocol — יכול לספק דרך אחידה לחבר את הסוכן לכלים ולהקשר, במקום ללמד אותו מחדש את התחביר של כל programmer וכל מכשיר. המטרה אינה לתת לו Shell פתוח לכל המעבדה, אלא לחשוף פעולות צרות כמו build, flash, reset, capture ו־measure, עם הרשאות, timeouts ופלט שקל למכונה לפרש.
ברגע שנוסף ציוד שמסוגל להפעיל גירויים פיזיים, או stimuli — למשל הודעת CAN, שינוי מתח, לחיצה באמצעות fixture, תנועה מול חיישן או ניתוק וחיבור מבוקרים — הסוכן יכול לבדוק לא רק אם התוכנה עלתה, אלא אם המוצר מגיב לעולם. זה החיבור בין Closed-Loop Debugging לבין Agentic HIL: הקוד משתנה בתוך הלולאה, אבל ההכרעה מגיעה מן החומרה ומהסביבה שסביבה.
החיבור הזה מחייב בטיחות כחלק מן הממשק. פקודת flash צריכה לדעת אילו כתובות מותרות; מחיקה מלאה צריכה להיות חסומה כברירת מחדל; ספק כוח צריך current limit; ממסר שמפעיל מנוע צריך interlock; וכל פעולה זקוקה ל־timeout ולמסלול התאוששות. אם הסוכן יכול לשנות גם את הקוד, גם את הבדיקה וגם את מגבלת המתח שמגינה על הלוח, אין לנו שלוש שכבות הגנה אלא שלוש שכבות שמאמינות זו לזו.
הידע שמכוון את הסוכן אינו חייב להישאר בתוך המודל. RAG, או אחזור ממוקד של מידע בזמן העבודה, יכול להביא לכל שאלה את ה־reference manual הנכון, את דוגמת היצרן ללוח המסוים ואת גרסת הדרייבר שבאמת נמצאת בפרויקט. זה חשוב במיוחד ב־Embedded: תשובה נכונה למשפחת בקר אחרת או לגרסה ישנה של HAL עלולה להיות מסוכנת. RAG משפר את חומר הגלם של ההחלטה, אבל הוא אינו צורב לוח ואינו מוכיח שה־interrupt הגיע; בשביל זה עדיין צריך את הלולאה הפיזית.
AGENTS.md פותר בעיה אחרת: הוא משמש כחוזה העבודה של הפרויקט. אפשר לתעד בו את הארכיטקטורה, גבולות השינוי, סדר ה־boot, כתובות ה־Flash, מגבלות בטיחות, שינויים שכלי יצירת קוד עלול לדרוס וה־Definition of Done. במקום לבקש מן הסוכן 'להיות מומחה STM32', נותנים לו מצב פרויקט מפורש וכללים שנקראים לפני העבודה. כך הוא אינו מתחיל כל משימה כאילו המאגר נולד היום.
Skills ו־Runbooks מקודדים את הידע המעשי שחוזר על עצמו. AGENTS.md מסביר מה נכון ומה אסור; Skill או runbook מסבירים איך לבצע משימה: לאתר את ערוץ ה־COM בלי להניח מספר קבוע, לאסוף log מלא מן ה־reset, למפות fault מול ה־ELF המדויק, או להריץ רצף צריבה ובדיקה שאי אפשר לדלג על שלב בו. זה המקום להפוך הרגלים של מהנדס מנוסה לתהליך שהסוכן יכול לבצע בעקביות.
אם הייתי בונה סביבת עבודה כזאת היום, הייתי מתחיל דווקא מן היסודות הפשוטים: משתמש בדרייברים ובקוד הקיים, מגדיר פקודות build ו־flash קטנות ויציבות, מוסיף תצפית ו־Test Oracle חיצוני, ורק אז מקבע את הרצפים החוזרים כ־Skills או מחבר ציוד רב דרך MCP. אין צורך להשקיע חודש ב'בניית סוכן' לפני הניסוי הראשון. צריך להפוך את הפרויקט לקריא ואת הפעולות החשובות לבנות־ביצוע.
המהנדס לא יוצא מהלולאה — הוא עולה קומה. בפרויקט שלנו אני קבעתי מה בונים, חיברתי את החומרה, בדקתי jumpers ואביזרים, החלטתי אילו פעולות מסוכנות והגדרתי מה ייחשב הצלחה. הסוכן היה חזק בקריאת הרבה קבצים, בשמירת רצף ההוכחות, בביצוע פעולות חוזרות ובהצעת הניסוי הבא. זו חלוקת עבודה של Human-on-the-Loop: האדם מגדיר מטרה, גבולות, בטיחות ואחריות; הסוכן עובד בתוך המעטפת ומזעיק אותו כאשר חסרה עובדה פיזית או החלטה הנדסית.
גם האמירה על קיצור של בערך סדר גודל — ולעיתים יותר — תלויה בכל המעטפת הזאת. בלי build שחוזר על עצמו, בלי ערוץ דיבאג אמין ובלי oracle ברור, הסוכן רק מייצר יותר הצעות בקצב גבוה יותר. ההאצה מופיעה כאשר כל ניסיון זול, מתועד ומבחין בין השערות. המחיר האמיתי נמצא בבניית observability, בתחזוקת הכלים, בהגדרת הרשאות ובבחירת בדיקות שלא יאשרו בטעות מוצר שאינו עובד.
מחקרי Embedded מן השנים האחרונות מחזקים את הזהירות הזאת: מודלים לבדם עדיין מתקשים לעבור באופן עקבי בין בקרים, גרסאות וכלי פיתוח, בעוד משוב מן הקומפיילר, אחזור תיעוד, Skills של מומחים ומדידה מחומרה משפרים את התוצאות במסגרות שנבדקו. אלה benchmarks מוגדרים, לא הבטחה ל־bring-up אוטונומי של כל מוצר. הם כן מצביעים על אותו כיוון שראינו בעבודה: ידע טוב עוזר להציע ניסוי, אבל ראיה חיצונית מחזירה את הסוכן מן ההשערה אל העובדה.
השלב הבא אינו מעבדה חשוכה שבה לוחצים Start וחוזרים אחרי שבוע למוצר גמור. הוא Autonomous Bring-up, הפעלה ראשונית אוטונומית של חומרה חדשה, ו־Autonomous Debugging, דיבאג אוטונומי ושקוף יותר: סוכן שמסוגל לעבוד שעות על DUT, לשמור איזה image רץ עם איזה log, לבצע fault injection מבוקר, להשוות מדידות, לזהות regression ולבקש מן האדם פעולה פיזית אחת כאשר באמת צריך אותה. ככל שהכלים, הראיות והגבולות יהיו טובים יותר, כך יותר מן הלולאה יוכל לפעול באופן עצמאי בלי לוותר על אחריות הנדסית.
זה בעיניי הסיפור הגדול של Agentic HIL. לא מודל שיודע הכול, ולא AI שמחליף מהנדס, אלא סביבת עבודה שמחברת ידע, כלים וחומרה ללולאה שאפשר לבדוק. המהנדס מתכנן את המערכת כך שתהיה ניתנת לתצפית ולשליטה; הסוכן מבצע את המחזור שוב ושוב; וה־Test Oracle קובע מתי יש הוכחה. המעבר הגדול הוא מ־AI שמסביר למה החומרה לא עובדת, ל־AI שמסוגל לבדוק בעצמו למה היא לא עובדת.
הזווית ההנדסית
למה זה מעניין
החלק המעניין כאן אינו עוד שיפור במהירות כתיבת הקוד, אלא קיצור מחזור ההנדסה כולו: שינוי, build, צריבה, גירוי, תצפית והחלטה. ברגע שהמערכת מתוכננת עם observability, כלים יציבים ו־Test Oracle חיצוני, סוכן יכול לבצע חלק גדול מן הדיבאג החוזר בלי שהאדם יעביר ידנית כל ראיה. זה פותח דרך מעשית ל־Autonomous Bring-up ולמעבדות אוטונומיות יותר, אבל גם מבהיר שהאצה אמיתית תלויה בעבודת תשתית, בגבולות בטיחות ובמהנדס שנשאר Human-on-the-Loop.

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