📌 סיכום וובינר מודלים פתוחים
במפגש מדברים AI האחרון דיברנו על מודלים חינמיים ומודלים פתוחים. השבוע אין מפגש (בלי קשר למלחמה, זה דילוג שתוכנן מראש ויצא לנו טוב). שבוע הבא מתוכנן מפגש חשוב על גישת שלושת השכבות ואיך לקבל קוד טוב מסוכן קידוד אני אעדכן כאן ובמייל לקראת חמישי הבא אם יתקיים לפי המצב.
עכשיו בואו נזכר מה היה לנו בשבוע שעבר.
✏ מהם מודלים פתוחים
שלוש החברות הגדולות שבונות כלי AI הן גוגל, אנטרופיק ו OpenAI ולכל אחת מודל מוביל משלה. חברות אלה ואחרות בונות גם אקוסיסטם שלם סביב המודלים - סוכני קידוד, APIs, פרוטוקולים ועולם שלם של כלים.
מודל הוא החלק שמקבל טקסט ומחזיר את המשך הטקסט. אפשר להגיד שזה "המוח" של כל כלי בינה מלאכותית. הכלי עצמו עוטף את המודל ומלביש לו פונקציונאליות או חיבור לעולם, לדוגמה קלוד קוד הוא סוכן קידוד שעוטף מודל ומחבר אותו לקוד. גם ממשק הווב לשיחה עם AI הוא סוכן, הוא עוטף את המודל ביכולות שמאפשרות חיפוש ברשת או הרצת קוד.
המודל, או המוח של הכלי, מביא איתו סוג מסוים של הטיות, תשובות, גישה וחשיבה. מודל GPT-5.2 לא יחזיר את אותן תשובות כמו Gemini Flash. יש כאלה שחושבים ששלוש חברות זה מספיק ואפילו יותר מדי אבל לדעתי תחרות פה היא חיובית ומוסיפה עניין למשחק. אבל זה לא כל כך פשוט.
כשאני שולח שאלה למודל שרץ בענן אני סומך על ספק המודל שישמור על השאלה שלי והתשובה של המודל באופן מאובטח. אם השאלה כוללת מידע פרטי או קוד של המערכת אני סומך על ספק המודל שלא ישתמש בקוד הזה לדברים שלא הרשיתי. סיכוי טוב שאנחנו לא מוכנים לסמוך כך על כל אחד שטוען שיש לו מודל חדש.
מודלים פתוחים מציעים לנו דרך לעבוד עם מודלים חדשים ולבנות מחדש אמון. מודל פתוח הוא מודל שכל אחד יכול להריץ ולכן אני יכול להריץ אותו על המחשב שלי או על מחשב בספק ענן עליו אני סומך. קיימים מודלים פתוחים שיספרו לכם איך הם פיתחו את המודל ונותנים לכם את כל הכלים לבנות את המודל לבד אצלכם, ויש מודלים פתוחים קצת פחות ידידותיים שנותנים לכם רק את מטריצת המשקלים של המודל, כלומר נוכל להריץ את המודל על המחשב שלנו אבל לא נוכל לבנות מטריצה כזאת מאפס ולא נדע מאיזה מידע המודל נוצר.
מודלים פתוחים מוסיפים לתחרות - חלקם מוכנים לענות על שאלות בנושאים ששלושת המודלים הרגילים לא עונים, חלקם יציגו תשובות חדשות ויצירתיות לשאלות וכולם יהיו הרבה יותר זולים משלושת המודלים הגדולים כי אתם יכולים להריץ אותם על חומרה שלכם.
בנוסף למודלים הפתוחים יש גם מודלים חינמיים. אלה מודלים שחברות מציעות לצורך בדיקה וקידום מכירות, לרוב הם יוצעו תחת שם בדוי ודרך אתר OpenRouter במקום דרך אתר החברה עצמה. המודל החינמי מאפשר לכם גישה בלי תשלום ובתמורה הם משתמשים בשיחות כדי לשפר את המודל או לאסוף מידע על שאלות שנשלחות. שימו לב שמודל חינמי אינו מודל פתוח, לפעמים התשובות שלו יהיו טובות יותר ותמיד יהיה פה איזשהו וויתור על פרטיות בעבודה איתם.
✏ איך עובדים עם מודלים פתוחים
הכלי האהוב עליי לעבודה עם מודלים פתוחים נקרא Ollama (יש עוד. אולמה הוא פשוט האהוב עליי). אפשר להוריד אותו מהאתר שלהם כאן:
https://ollama.com/
אולמה מציע שני מסלולים לעבודה עם המודלים הפתוחים:
1. ניתן להוריד ולהריץ באמצעותו מודלים על המחשב שלכם.
2. ניתן להשתמש בו כדי להתחבר למודלים פתוחים שרצים על שרת הענן שלהם.
במחיר סמלי של 20$ לחודש תקבלו גישה כמעט ללא הגבלה לענן של Ollama ותוכלו לעבוד עם כל המודלים הפתוחים שם. בשביל להריץ מודלים אצלכם על המחשב לא צריך לשלם שקל אבל דרושה חומרה חזקה. איכות המודל נקבעת לפי סוג המודל ולפי מספר הפרמטרים במטריצת המשקלים. אם נסתכל לדוגמה על deepseek אז נראה באתר של אולמה שיש לו מספר גרסאות, הראשיות הן 1, 2 ו-3. בכל גרסה יש כמה אפשרויות למודל ולפרמטרים לדוגמה deepseek-coder שזו גרסה של המודל מלפני שנתיים המיועדת לקידוד ניתנת להורדה בגרסת 1.3 מיליארד פרמטרים, 6.7 מיליארד פרמטרים או 33 מיליארד פרמטרים. מספר הפרמטרים משפיע על הגודל והגרסה הגדולה ביותר 33 מיליארד פרמטרים תופסת 19 ג׳יגה.
מודל gpt-oss שהוא מודל פתוח מבית OpenAI מגיע בגרסת 20 מיליארד פרמטרים ו 120 מיליארד וגרסת ה 120 מיליארד היא בגודל 65 ג'יגה.
בשביל לשאול שאלות בשיחה תספיק לנו גרסה קטנה של 6-7 מיליארד פרמטרים. בשביל סוכן קידוד אפילו ה 120 מיליארד עלול להיות בסיסי מדי.
אולמה מספק אפליקציה גרפית דרכה אפשר לדבר עם מודלים, לשאול שאלות ולראות את התשובות שלהם באפליקציה. שווה להשתמש בה כשמתייעצים עם מודלים מקומיים וכך לקבל פרטיות מירבית בשיחה עם ה AI.
✏ איך לכתוב קוד עם מודל פתוח
במפגש מדברים AI האחרון דיברנו על מודלים חינמיים ומודלים פתוחים. השבוע אין מפגש (בלי קשר למלחמה, זה דילוג שתוכנן מראש ויצא לנו טוב). שבוע הבא מתוכנן מפגש חשוב על גישת שלושת השכבות ואיך לקבל קוד טוב מסוכן קידוד אני אעדכן כאן ובמייל לקראת חמישי הבא אם יתקיים לפי המצב.
עכשיו בואו נזכר מה היה לנו בשבוע שעבר.
✏ מהם מודלים פתוחים
שלוש החברות הגדולות שבונות כלי AI הן גוגל, אנטרופיק ו OpenAI ולכל אחת מודל מוביל משלה. חברות אלה ואחרות בונות גם אקוסיסטם שלם סביב המודלים - סוכני קידוד, APIs, פרוטוקולים ועולם שלם של כלים.
מודל הוא החלק שמקבל טקסט ומחזיר את המשך הטקסט. אפשר להגיד שזה "המוח" של כל כלי בינה מלאכותית. הכלי עצמו עוטף את המודל ומלביש לו פונקציונאליות או חיבור לעולם, לדוגמה קלוד קוד הוא סוכן קידוד שעוטף מודל ומחבר אותו לקוד. גם ממשק הווב לשיחה עם AI הוא סוכן, הוא עוטף את המודל ביכולות שמאפשרות חיפוש ברשת או הרצת קוד.
המודל, או המוח של הכלי, מביא איתו סוג מסוים של הטיות, תשובות, גישה וחשיבה. מודל GPT-5.2 לא יחזיר את אותן תשובות כמו Gemini Flash. יש כאלה שחושבים ששלוש חברות זה מספיק ואפילו יותר מדי אבל לדעתי תחרות פה היא חיובית ומוסיפה עניין למשחק. אבל זה לא כל כך פשוט.
כשאני שולח שאלה למודל שרץ בענן אני סומך על ספק המודל שישמור על השאלה שלי והתשובה של המודל באופן מאובטח. אם השאלה כוללת מידע פרטי או קוד של המערכת אני סומך על ספק המודל שלא ישתמש בקוד הזה לדברים שלא הרשיתי. סיכוי טוב שאנחנו לא מוכנים לסמוך כך על כל אחד שטוען שיש לו מודל חדש.
מודלים פתוחים מציעים לנו דרך לעבוד עם מודלים חדשים ולבנות מחדש אמון. מודל פתוח הוא מודל שכל אחד יכול להריץ ולכן אני יכול להריץ אותו על המחשב שלי או על מחשב בספק ענן עליו אני סומך. קיימים מודלים פתוחים שיספרו לכם איך הם פיתחו את המודל ונותנים לכם את כל הכלים לבנות את המודל לבד אצלכם, ויש מודלים פתוחים קצת פחות ידידותיים שנותנים לכם רק את מטריצת המשקלים של המודל, כלומר נוכל להריץ את המודל על המחשב שלנו אבל לא נוכל לבנות מטריצה כזאת מאפס ולא נדע מאיזה מידע המודל נוצר.
מודלים פתוחים מוסיפים לתחרות - חלקם מוכנים לענות על שאלות בנושאים ששלושת המודלים הרגילים לא עונים, חלקם יציגו תשובות חדשות ויצירתיות לשאלות וכולם יהיו הרבה יותר זולים משלושת המודלים הגדולים כי אתם יכולים להריץ אותם על חומרה שלכם.
בנוסף למודלים הפתוחים יש גם מודלים חינמיים. אלה מודלים שחברות מציעות לצורך בדיקה וקידום מכירות, לרוב הם יוצעו תחת שם בדוי ודרך אתר OpenRouter במקום דרך אתר החברה עצמה. המודל החינמי מאפשר לכם גישה בלי תשלום ובתמורה הם משתמשים בשיחות כדי לשפר את המודל או לאסוף מידע על שאלות שנשלחות. שימו לב שמודל חינמי אינו מודל פתוח, לפעמים התשובות שלו יהיו טובות יותר ותמיד יהיה פה איזשהו וויתור על פרטיות בעבודה איתם.
✏ איך עובדים עם מודלים פתוחים
הכלי האהוב עליי לעבודה עם מודלים פתוחים נקרא Ollama (יש עוד. אולמה הוא פשוט האהוב עליי). אפשר להוריד אותו מהאתר שלהם כאן:
https://ollama.com/
אולמה מציע שני מסלולים לעבודה עם המודלים הפתוחים:
1. ניתן להוריד ולהריץ באמצעותו מודלים על המחשב שלכם.
2. ניתן להשתמש בו כדי להתחבר למודלים פתוחים שרצים על שרת הענן שלהם.
במחיר סמלי של 20$ לחודש תקבלו גישה כמעט ללא הגבלה לענן של Ollama ותוכלו לעבוד עם כל המודלים הפתוחים שם. בשביל להריץ מודלים אצלכם על המחשב לא צריך לשלם שקל אבל דרושה חומרה חזקה. איכות המודל נקבעת לפי סוג המודל ולפי מספר הפרמטרים במטריצת המשקלים. אם נסתכל לדוגמה על deepseek אז נראה באתר של אולמה שיש לו מספר גרסאות, הראשיות הן 1, 2 ו-3. בכל גרסה יש כמה אפשרויות למודל ולפרמטרים לדוגמה deepseek-coder שזו גרסה של המודל מלפני שנתיים המיועדת לקידוד ניתנת להורדה בגרסת 1.3 מיליארד פרמטרים, 6.7 מיליארד פרמטרים או 33 מיליארד פרמטרים. מספר הפרמטרים משפיע על הגודל והגרסה הגדולה ביותר 33 מיליארד פרמטרים תופסת 19 ג׳יגה.
מודל gpt-oss שהוא מודל פתוח מבית OpenAI מגיע בגרסת 20 מיליארד פרמטרים ו 120 מיליארד וגרסת ה 120 מיליארד היא בגודל 65 ג'יגה.
בשביל לשאול שאלות בשיחה תספיק לנו גרסה קטנה של 6-7 מיליארד פרמטרים. בשביל סוכן קידוד אפילו ה 120 מיליארד עלול להיות בסיסי מדי.
אולמה מספק אפליקציה גרפית דרכה אפשר לדבר עם מודלים, לשאול שאלות ולראות את התשובות שלהם באפליקציה. שווה להשתמש בה כשמתייעצים עם מודלים מקומיים וכך לקבל פרטיות מירבית בשיחה עם ה AI.
✏ איך לכתוב קוד עם מודל פתוח
Ollama
Ollama is the easiest way to automate your work using open models, while keeping your data safe.
מודלים פתוחים שמסוגלים לכתוב קוד הם ענקיים ולרוב לא תרצו להריץ אותם על המחשב אלא בענן של Ollama (או בשרת ענן אחר). המודלים הרלוונטיים היום לפיתוח קוד הם:
1. glm-5
2. minimax-2.5
3. kimi-k2.5
4. qwen3-coder-next
אולמה מגיע עם אינטגרציה מובנית לסוכני קידוד ואפשר לקרוא עליה כאן:
https://docs.ollama.com/integrations
בשביל להריץ את קלוד קוד עם מודל של אולמה נפעיל:
או כל מודל אחר שתרצו. אני שמתי לב שמינימקס עובד ממש טוב עם קלוד קוד.
סוכן קידוד מתחרה של קלוד קוד נקרא OpenCode וגם אותו אפשר להריץ עם אולמה, פה שמתי לב ש glm-5 עובד טוב יותר:
נ.ב. אני לא יודע למה קלוד קוד עובד יותר טוב עם מינימקס ואופןקוד עובד יותר טוב עם glm. אני כן יודע שהמפתחים של קלוד קוד עובדים מול קלוד וחושד שמינימקס יותר דומה לקלוד בתשובות שלו והמפתחים של אופןקוד עובדים עם glm ולכן כנראה הפרומפטים והכלים שהם בונים נבדקו ועברו אופטימיזציה למודל זה.
אם אתם מעדיפים לעבוד בתוך VS Code יש מספר אינטגרציות ל Ollama שתוכלו להתקין כמו cline, kilocode ו Roo Code כולן יודעות להתחבר ל Ollama. ל VS Code עצמו יש אינטגרציה עם Ollama אבל בינתיים היא עובדת במצב ask בלבד ולא במצב סוכן אז פחות רלוונטית.
✏ כלים, אקוסיסטם והעתיד
כמו שדברים נראים עכשיו האקוסיסטם מאוד אינטראופרבילי כלומר יש הפרדה בין המודל לסוכן. לכן כלי כמו Ollama נותן לנו אפשרות לחבר מודל שלנו לכל סוכן שנבחר - בין אם זה אוטומציה (n8n), שיחה (onyx) או הכי פופולרי סוכן קידוד.
לאחרונה אנטרופיק יצאה במתקפה משפטית על החברות הסיניות בטענה שהן מאמנות את המודלים שלהן מתוך המודלים הקיימים של אנטרופיק וכך חוסכות לעצמן עלויות באמצעות מתקפה שנקראת דיסטילציה. אני לא מבין מספיק בשביל להרחיב על זה אבל יכול לשער שאם אפשר "להעתיק" מודלים יהיו מי שישמחו לעשות את זה ולהפיץ כך מודלים פתוחים. אפילו בלי דיסטילציות יש היום המון מודלים פתוחים במאגרים של Ollama ושל Hugging Face כך שנראה שהם לא הולכים להיעלם.
אין ספק שהעולם של כלי פיתוח וכלים מבוססי AI עובר רעידת אדמה משמעותית בתקופה זו וקשה לדעת איך דברים יראו אפילו בעוד חודש. אבל האינטראופרביליות פועלת מאוד לטובתנו. אין שום בעיה להתקין Ollama ולנסות לדבר עם סוכן שיחה פתוח שרץ אצלכם על המחשב או עם סוכן קידוד בענן של אולמה כדי להשוות תוצאות.
1. glm-5
2. minimax-2.5
3. kimi-k2.5
4. qwen3-coder-next
אולמה מגיע עם אינטגרציה מובנית לסוכני קידוד ואפשר לקרוא עליה כאן:
https://docs.ollama.com/integrations
בשביל להריץ את קלוד קוד עם מודל של אולמה נפעיל:
ollama launch claude --model minimax-2.5:cloud
או כל מודל אחר שתרצו. אני שמתי לב שמינימקס עובד ממש טוב עם קלוד קוד.
סוכן קידוד מתחרה של קלוד קוד נקרא OpenCode וגם אותו אפשר להריץ עם אולמה, פה שמתי לב ש glm-5 עובד טוב יותר:
ollama launch opencode --model glm-5:cloud
נ.ב. אני לא יודע למה קלוד קוד עובד יותר טוב עם מינימקס ואופןקוד עובד יותר טוב עם glm. אני כן יודע שהמפתחים של קלוד קוד עובדים מול קלוד וחושד שמינימקס יותר דומה לקלוד בתשובות שלו והמפתחים של אופןקוד עובדים עם glm ולכן כנראה הפרומפטים והכלים שהם בונים נבדקו ועברו אופטימיזציה למודל זה.
אם אתם מעדיפים לעבוד בתוך VS Code יש מספר אינטגרציות ל Ollama שתוכלו להתקין כמו cline, kilocode ו Roo Code כולן יודעות להתחבר ל Ollama. ל VS Code עצמו יש אינטגרציה עם Ollama אבל בינתיים היא עובדת במצב ask בלבד ולא במצב סוכן אז פחות רלוונטית.
✏ כלים, אקוסיסטם והעתיד
כמו שדברים נראים עכשיו האקוסיסטם מאוד אינטראופרבילי כלומר יש הפרדה בין המודל לסוכן. לכן כלי כמו Ollama נותן לנו אפשרות לחבר מודל שלנו לכל סוכן שנבחר - בין אם זה אוטומציה (n8n), שיחה (onyx) או הכי פופולרי סוכן קידוד.
לאחרונה אנטרופיק יצאה במתקפה משפטית על החברות הסיניות בטענה שהן מאמנות את המודלים שלהן מתוך המודלים הקיימים של אנטרופיק וכך חוסכות לעצמן עלויות באמצעות מתקפה שנקראת דיסטילציה. אני לא מבין מספיק בשביל להרחיב על זה אבל יכול לשער שאם אפשר "להעתיק" מודלים יהיו מי שישמחו לעשות את זה ולהפיץ כך מודלים פתוחים. אפילו בלי דיסטילציות יש היום המון מודלים פתוחים במאגרים של Ollama ושל Hugging Face כך שנראה שהם לא הולכים להיעלם.
אין ספק שהעולם של כלי פיתוח וכלים מבוססי AI עובר רעידת אדמה משמעותית בתקופה זו וקשה לדעת איך דברים יראו אפילו בעוד חודש. אבל האינטראופרביליות פועלת מאוד לטובתנו. אין שום בעיה להתקין Ollama ולנסות לדבר עם סוכן שיחה פתוח שרץ אצלכם על המחשב או עם סוכן קידוד בענן של אולמה כדי להשוות תוצאות.
Ollama
Overview - Ollama
🔥1
📌 האם Test Driven Development עדיין רלוונטי?
פיתוח מונחה בדיקות או TDD הוא הרעיון שכדאי לי לכתוב קודם את הבדיקות ואז לראות את הקוד, ואז אני מרוויח גם בדיקות של הקוד וגם קוד טוב יותר שיותר קל לבדוק אותו. ניסיתי את זה היום עם AI וזה עבד יופי, כלומר כתבתי כמה בדיקות שמשתמשות בפונקציות ומחלקות שהמצאתי, נתתי ל AI לכתוב את הקוד, לפעמים זה הצליח לו, לפעמים הוא התלונן שהבדיקות שלי לא הגיוניות. כשהוא הצליח הכל היה טוב הכנסתי את הקוד לגיט והתקדמתי. כשהוא התלונן ניקיתי את מה שהוא כתב, תיקנתי את הבדיקות ושלחתי אותו לייצר שוב.
בסוף קיבלתי קוד עובד שעשה בדיוק את מה שרציתי ובמבנה מחלקות שאני בחרתי. לפני שנתיים הייתי חותם על זה. חלום. היום אני לא כל כך בטוח.
האלטרנטיבה של TDD בה גם אני משתמש וגם אני רואה בתעשייה היא PDD, כלומר Prompt Driven Development. כותבים פרומפט, נותנים ל AI לייצר קוד ובדיקות, קוראים את הבדיקות והקוד, אם אוהבים שומרים ואם לא אוהבים מנקים ומתקנים את הפרומפט.
לדוגמה עבור משחק איקס עיגול ב TDD אני מתחיל עם קובץ בדיקות כזה:
ואז בפרומפט מאוד פשוט מקבל את GameLogic שבדיוק מתאים לממשק שהגדרתי.
פיתוח מונחה בדיקות או TDD הוא הרעיון שכדאי לי לכתוב קודם את הבדיקות ואז לראות את הקוד, ואז אני מרוויח גם בדיקות של הקוד וגם קוד טוב יותר שיותר קל לבדוק אותו. ניסיתי את זה היום עם AI וזה עבד יופי, כלומר כתבתי כמה בדיקות שמשתמשות בפונקציות ומחלקות שהמצאתי, נתתי ל AI לכתוב את הקוד, לפעמים זה הצליח לו, לפעמים הוא התלונן שהבדיקות שלי לא הגיוניות. כשהוא הצליח הכל היה טוב הכנסתי את הקוד לגיט והתקדמתי. כשהוא התלונן ניקיתי את מה שהוא כתב, תיקנתי את הבדיקות ושלחתי אותו לייצר שוב.
בסוף קיבלתי קוד עובד שעשה בדיוק את מה שרציתי ובמבנה מחלקות שאני בחרתי. לפני שנתיים הייתי חותם על זה. חלום. היום אני לא כל כך בטוח.
האלטרנטיבה של TDD בה גם אני משתמש וגם אני רואה בתעשייה היא PDD, כלומר Prompt Driven Development. כותבים פרומפט, נותנים ל AI לייצר קוד ובדיקות, קוראים את הבדיקות והקוד, אם אוהבים שומרים ואם לא אוהבים מנקים ומתקנים את הפרומפט.
לדוגמה עבור משחק איקס עיגול ב TDD אני מתחיל עם קובץ בדיקות כזה:
import pytest
import GameUI
def test_first_player_plays(game_logic):
game_logic.play(0, 0)
assert not game_logic.game_over()
assert game_logic.winner() is None
def test_second_player_plays_in_taken_square(game_logic):
game_logic.play(0, 0)
with pytest.raises(Exception):
game_logic.play(0, 0)
def test_player1_wins_first_row(game_logic):
game_logic.play(0, 0)
game_logic.play(1, 0)
game_logic.play(0, 1)
game_logic.play(1, 1)
game_logic.play(0, 2)
assert game_logic.game_over()
assert game_logic.winner() == game_logic.players[0]
def test_player2_wins_diagonal(game_logic):
game_logic.play(0, 1)
game_logic.play(0, 0)
game_logic.play(1, 0)
game_logic.play(1, 1)
game_logic.play(1, 2)
game_logic.play(2, 2)
assert game_logic.game_over()
assert game_logic.winner() == game_logic.players[1]
def test_cant_play_after_win(game_logic):
game_logic.play(0, 1)
game_logic.play(0, 0)
game_logic.play(1, 0)
game_logic.play(1, 1)
game_logic.play(1, 2)
game_logic.play(2, 2)
with pytest.raises(Exception):
game_logic.play(2, 0)
def test_show_empty_board(game_logic, capsys):
GameUI.print_current_game(game_logic)
printed_text = capsys.readouterr().out
assert printed_text == """Waiting for player X
. . .
. . .
. . .
"""
def test_show_board_after_play(game_logic, capsys):
game_logic.play(0, 0)
game_logic.play(1, 1)
game_logic.play(2, 0)
GameUI.print_current_game(game_logic)
printed_text = capsys.readouterr().out
assert printed_text == """Waiting for player O
X . .
. O .
X . .
"""
def test_show_draw(game_logic, capsys):
game_logic.play(0, 0) # X
game_logic.play(1, 1) # O
game_logic.play(2, 0) # X
game_logic.play(1, 0) # O
game_logic.play(1, 2) # X
game_logic.play(2, 1) # O
game_logic.play(0, 1) # X
game_logic.play(0, 2) # O
game_logic.play(2, 2) # X
GameUI.print_current_game(game_logic)
printed_text = capsys.readouterr().out
assert printed_text == """Game Over. It's a draw
X X O
O O X
X O X
"""
def test_show_player_1_won(game_logic, capsys):
game_logic.play(0, 0)
game_logic.play(1, 0)
game_logic.play(0, 1)
game_logic.play(1, 1)
game_logic.play(0, 2)
GameUI.print_current_game(game_logic)
printed_text = capsys.readouterr().out
assert printed_text == """Bravo! X Won
X X X
O O .
. . .
"""
def test_read_move_from_player(game_logic, monkeypatch, capsys):
monkeypatch.setattr("builtins.input", lambda _: "0, 0")
next_move = GameUI.read_next_move(game_logic)
game_logic.play(*next_move)
capsys.readouterr() # clear the buffer
GameUI.print_current_game(game_logic)
printed_after = capsys.readouterr().out
assert printed_after == """Waiting for player O
X . .
. . .
. . .
"""
ואז בפרומפט מאוד פשוט מקבל את GameLogic שבדיוק מתאים לממשק שהגדרתי.
ב PDD אני פשוט כותב "תבנה לי משחק איקס עיגול עם בדיקות בפייתון" ומתקן בלולאה את הפרומפט עד שיוצא משחק שאני רוצה. צריך בדיקה ספציפית? אוסיף אותה לפרומפט. צריך מחלקה ספציפית? נגדיר אותה בפרומפט.
ההבדלים המרכזיים בין הגישות:
1. ב TDD אני לוקח שליטה על הקוד. אני יודע מה אני כותב ומה צריך להיכתב. אני קובע את המבנה של הקוד ויודע בדיוק איך יראה הקוד שה AI יבנה. כמעט לא הולך לי זמן על לחכות לסוכן הקידוד או לקרוא את הקוד שלו.
2. ב PDD אני מוותר על השליטה ובוחר מתפריט, בסגנון "תראה לי מה אפשר". פה הרבה יותר זמן הולך על להסתכל על סוכן הקידוד עובד ולקרוא את הקוד שלו. לפעמים אפשר ללמוד מהקוד שהוא יצר ולגלות דברים חדשים. לפעמים לא. בהיבט של בדיקות בגישת PDD יהיו לי הרבה יותר בדיקות אבל איכות חבילת הבדיקות הכללית תהיה פחות טובה. בדוגמה של האיקס עיגול כשנתתי ל AI לבנות את הקוד הוא באמת כתב לבד את הבדיקות ללוגיקה אבל לא מימש בדיקות לכתיבה למסך.
אז עשיתי ניסוי, נתתי לסוכן הקידוד את הפרומפט הבא:
מאוד רציתי שהוא יכתוב בדיקות תצוגה פשוטות כמו שאני כתבתי בדוגמה שהדבקתי, אבל זה לא מה שקרה. מודול התצוגה שסוכן הקידוד יצר כולל פונקציה שמציירת את הלוח למערך של שורות ופונקציה אחרת שמדפיסה את המערך. הבדיקה היא עדיין בדיקת data שבודקת רק את מערך השורות כלומר:
נראה ש glm עבד מאוד קשה רק בשביל לא להשתמש ב capsys של pytest והפך את קוד המשחק ליותר מסורבל.
אז בחזרה לשאלה שבכותרת, האם TDD עדיין רלוונטי? לפעמים. בעזרת TDD אני יכול להעביר את המסר לסוכן הקידוד בצורה הרבה יותר מדויקת מאשר בעזרת פרומפט ואני חוסך את הוויכוחים עם הסוכן, במיוחד כשאני יודע איזה קוד אני מצפה לראות.
ההבדלים המרכזיים בין הגישות:
1. ב TDD אני לוקח שליטה על הקוד. אני יודע מה אני כותב ומה צריך להיכתב. אני קובע את המבנה של הקוד ויודע בדיוק איך יראה הקוד שה AI יבנה. כמעט לא הולך לי זמן על לחכות לסוכן הקידוד או לקרוא את הקוד שלו.
2. ב PDD אני מוותר על השליטה ובוחר מתפריט, בסגנון "תראה לי מה אפשר". פה הרבה יותר זמן הולך על להסתכל על סוכן הקידוד עובד ולקרוא את הקוד שלו. לפעמים אפשר ללמוד מהקוד שהוא יצר ולגלות דברים חדשים. לפעמים לא. בהיבט של בדיקות בגישת PDD יהיו לי הרבה יותר בדיקות אבל איכות חבילת הבדיקות הכללית תהיה פחות טובה. בדוגמה של האיקס עיגול כשנתתי ל AI לבנות את הקוד הוא באמת כתב לבד את הבדיקות ללוגיקה אבל לא מימש בדיקות לכתיבה למסך.
אז עשיתי ניסוי, נתתי לסוכן הקידוד את הפרומפט הבא:
create a text based tic tac toe game in python with pytest. use uv
Use multiple modules for game logic and display
Implement pytest tests for both logic and display
מאוד רציתי שהוא יכתוב בדיקות תצוגה פשוטות כמו שאני כתבתי בדוגמה שהדבקתי, אבל זה לא מה שקרה. מודול התצוגה שסוכן הקידוד יצר כולל פונקציה שמציירת את הלוח למערך של שורות ופונקציה אחרת שמדפיסה את המערך. הבדיקה היא עדיין בדיקת data שבודקת רק את מערך השורות כלומר:
def test_render_board_with_markers(self):
board = Board()
board.place_marker("A1", "X")
board.place_marker("B2", "O")
rendered = Display.render_board(board)
assert "X" in rendered
assert "O" in rendered
נראה ש glm עבד מאוד קשה רק בשביל לא להשתמש ב capsys של pytest והפך את קוד המשחק ליותר מסורבל.
אז בחזרה לשאלה שבכותרת, האם TDD עדיין רלוונטי? לפעמים. בעזרת TDD אני יכול להעביר את המסר לסוכן הקידוד בצורה הרבה יותר מדויקת מאשר בעזרת פרומפט ואני חוסך את הוויכוחים עם הסוכן, במיוחד כשאני יודע איזה קוד אני מצפה לראות.
👍1
📌 גם ה GPL כנראה לא ישרוד
אני מבין איך מרגיש מארק פילגרים.
מארק כתב את Dive Into Python וגם כתב מודול פייתון בשם chardet שמגלה מה הקידוד של מחרוזת. מארק רצה להשאיר מתנה לקהילה ובנה את הפרויקט ברשיון LGPL כדי לוודא שאם אחרים לוקחים את הקוד ובונים על בסיסו ספריה אחרת גם הספריה שלהם צריכה להיות חופשית.
ואני גם מבין איך מרגיש דן בלנשרד. עוד ב 2014 הוא ראה ש chardet הוא בסך הכל מימוש מחדש בפייתון של קוד ישן של מוזילה ולכן ממילא היה צריך להיות רשום ב MPL. בלנשרד הוא המתחזק של הפרויקט מ 2014, כלומר ב 12 השנים האחרונות. בלנשרד הוא זה שקיבל פניות ממשתמשים שרוצים להשתמש ב chardet ולא יכולים בגלל הרישיון כי אצלם בחברה אסור להשתמש ב LGPL, או כי הם משתמשים ב pyinstaller, וזה מייצר קובץ exe ולכן כל המודולים חייבים להיות חופשיים. ב 2021 היה זה בלנשרד שניסה לקדם את שינוי הרישיון שוב וראה איך ספריית requests הפופולרית נפרדת ב chardet בדיוק בגלל נושא זה.
אז מה הפלא שעם כל הדיבורים על קלוד קוד גם בלנשרד לא עמד בפיתוי? הוא בא לקלוד עם פרומפט שאומר "תבנה לי ספריה חדשה שעושה בדיוק מה ש chardet עושה אבל בלי לקחת כלום מהקוד המקורי". קלוד יצר מימוש פי 43 מהיר יותר ואמין באותה מידה בלי שום קוד משותף. כך נולדה גרסה 7 של chardet ואיתה ריב מתוקשר עם היוצר המקורי:
https://github.com/chardet/chardet/issues/327
אנחנו לא יודעים מה יהיה העתיד של עולם הקוד הפתוח. הניחוש שלי הוא שכל שיטת הרשיונות המגבילים הולכת להיעלם עקב חוסר יכולת אכיפה.
אני מבין איך מרגיש מארק פילגרים.
מארק כתב את Dive Into Python וגם כתב מודול פייתון בשם chardet שמגלה מה הקידוד של מחרוזת. מארק רצה להשאיר מתנה לקהילה ובנה את הפרויקט ברשיון LGPL כדי לוודא שאם אחרים לוקחים את הקוד ובונים על בסיסו ספריה אחרת גם הספריה שלהם צריכה להיות חופשית.
ואני גם מבין איך מרגיש דן בלנשרד. עוד ב 2014 הוא ראה ש chardet הוא בסך הכל מימוש מחדש בפייתון של קוד ישן של מוזילה ולכן ממילא היה צריך להיות רשום ב MPL. בלנשרד הוא המתחזק של הפרויקט מ 2014, כלומר ב 12 השנים האחרונות. בלנשרד הוא זה שקיבל פניות ממשתמשים שרוצים להשתמש ב chardet ולא יכולים בגלל הרישיון כי אצלם בחברה אסור להשתמש ב LGPL, או כי הם משתמשים ב pyinstaller, וזה מייצר קובץ exe ולכן כל המודולים חייבים להיות חופשיים. ב 2021 היה זה בלנשרד שניסה לקדם את שינוי הרישיון שוב וראה איך ספריית requests הפופולרית נפרדת ב chardet בדיוק בגלל נושא זה.
אז מה הפלא שעם כל הדיבורים על קלוד קוד גם בלנשרד לא עמד בפיתוי? הוא בא לקלוד עם פרומפט שאומר "תבנה לי ספריה חדשה שעושה בדיוק מה ש chardet עושה אבל בלי לקחת כלום מהקוד המקורי". קלוד יצר מימוש פי 43 מהיר יותר ואמין באותה מידה בלי שום קוד משותף. כך נולדה גרסה 7 של chardet ואיתה ריב מתוקשר עם היוצר המקורי:
https://github.com/chardet/chardet/issues/327
אנחנו לא יודעים מה יהיה העתיד של עולם הקוד הפתוח. הניחוש שלי הוא שכל שיטת הרשיונות המגבילים הולכת להיעלם עקב חוסר יכולת אכיפה.
GitHub
No right to relicense this project · Issue #327 · chardet/chardet
Hi, I'm Mark Pilgrim. You may remember me from such classics as "Dive Into Python" and "Universal Character Encoding Detector." I am the original author of chardet. First of...
😱1
📌 נ.ב. עלויות של AI
לפני בערך שנה בניתי פרויקט שיוצר תרגול אוצר מילים בשפה מסרטים קצרים ביוטיוב. חיברתי אותו לחשבון גוגל שלי כי ג'מיני פרו של אותו זמן היה הדבר היחיד שהצליח לתמלל בצורה טובה סרטים מיוטיוב ובאפריל 2025 קיבלתי מגוגל חשבון של 350 ש"ח על שימוש באותו ג'מיני פרו רק לפרויקט פנאי הקטן הזה.
בחודשים שאחרי כבר נזהרתי יותר בשימוש בג'מיני פרו ובמאי שילמתי להם רק 3 ש"ח, יוני 25 ש"ח, יולי 76 ש"ח ואוגוסט 50. חלק מזה קשור לאופטימיזציה במערכת שהיתה צריכה פחות AI כדי ליצור את השיעורים, חלק קשור לזה שהעברתי חלקים מהקוד לעבוד עם מודלים יותר זולים וחלק לזה שפשוט היה לי פחות זמן לעבוד על הפלטפורמה. סך הכל לפני אופטימיזציה שילמתי בערך 20 ש"ח לעבודה על וידאו אחד ואחרי אופטימיזציה זה ירד ל 2-3 ש"ח לוידאו.
מאז גוגל השיקו את ג'מיני פלאש לייט 3.1 ואולמה השיקו את תוכנית Ollama Cloud. שילוב שני אלה הוריד את העלות של יצירת וידאו לפחות מאגורה, ללא שינוי בקוד.
שני התהליכים הגדולים שכבר החלו וילוו אותנו בשנים הקרובות הם שיפור בצריכת המשאבים של המודלים (מודלים יותר קטנים עם תוצאות טובות יותר) ותחרות בין יותר ספקיות מודלים. שילוב שני הדברים אומר שעלות העבודה עם LLM ירדה פלאים ועוד תמשיך לרדת. ספקי ה AI רואים את זה ומנסים לפצות באמצעות הוספת שירותי ערך מוסף ל API כמו "שימוש במחשב", "חיפוש ברשת" ואחסון קבצים. קשה לדעת כמה טוב זה יצליח להם.
בינתיים מה שבטוח הוא שהעלות של Inference יורדת ומהר. ייתכן ולא רחוק היום שגם על יישומי AI נתחיל לשלם במודל של מנוי במקום על בסיס טוקנים.
לפני בערך שנה בניתי פרויקט שיוצר תרגול אוצר מילים בשפה מסרטים קצרים ביוטיוב. חיברתי אותו לחשבון גוגל שלי כי ג'מיני פרו של אותו זמן היה הדבר היחיד שהצליח לתמלל בצורה טובה סרטים מיוטיוב ובאפריל 2025 קיבלתי מגוגל חשבון של 350 ש"ח על שימוש באותו ג'מיני פרו רק לפרויקט פנאי הקטן הזה.
בחודשים שאחרי כבר נזהרתי יותר בשימוש בג'מיני פרו ובמאי שילמתי להם רק 3 ש"ח, יוני 25 ש"ח, יולי 76 ש"ח ואוגוסט 50. חלק מזה קשור לאופטימיזציה במערכת שהיתה צריכה פחות AI כדי ליצור את השיעורים, חלק קשור לזה שהעברתי חלקים מהקוד לעבוד עם מודלים יותר זולים וחלק לזה שפשוט היה לי פחות זמן לעבוד על הפלטפורמה. סך הכל לפני אופטימיזציה שילמתי בערך 20 ש"ח לעבודה על וידאו אחד ואחרי אופטימיזציה זה ירד ל 2-3 ש"ח לוידאו.
מאז גוגל השיקו את ג'מיני פלאש לייט 3.1 ואולמה השיקו את תוכנית Ollama Cloud. שילוב שני אלה הוריד את העלות של יצירת וידאו לפחות מאגורה, ללא שינוי בקוד.
שני התהליכים הגדולים שכבר החלו וילוו אותנו בשנים הקרובות הם שיפור בצריכת המשאבים של המודלים (מודלים יותר קטנים עם תוצאות טובות יותר) ותחרות בין יותר ספקיות מודלים. שילוב שני הדברים אומר שעלות העבודה עם LLM ירדה פלאים ועוד תמשיך לרדת. ספקי ה AI רואים את זה ומנסים לפצות באמצעות הוספת שירותי ערך מוסף ל API כמו "שימוש במחשב", "חיפוש ברשת" ואחסון קבצים. קשה לדעת כמה טוב זה יצליח להם.
בינתיים מה שבטוח הוא שהעלות של Inference יורדת ומהר. ייתכן ולא רחוק היום שגם על יישומי AI נתחיל לשלם במודל של מנוי במקום על בסיס טוקנים.
❤2
📌 כן הקוד שלי
אנתוני מאננינג כתב פוסט ארוך ומשכנע נגד שימוש ב AI לקידוד. ממליץ לקרוא אותו כאן:
https://antman-does-software.com/i-will-never-use-ai-to-code-or-write
אנתוני משווה בין קידוד לכתיבת ספר. כמו שלא היית נותן ל AI לכתוב את הרומן הבא שלך ומבקש ממנו "רק שפר קצת את הדמות הזאת", כי בכתיבה כל מילה חשובה, כך גם בקידוד אם תתן ל AI לכתוב בשבילך את הקוד זה כבר לא יהיה הקוד שלך. כל מילה חשובה.
זה טיעון מעניין אבל לדעתי שגוי, לא משקף את החיים האמיתיים של מפתחים גם לפני AI ולא עוזר לנו לכתוב קוד טוב יותר.
בחיים האמיתיים, גם לפני AI רוב הקוד שכתבנו לא היה 100% יצירה שלנו. עבודה על מערכות קיימות, עבודה בצוות, שימוש בספריות שלא תמיד אנחנו בחרנו ואילוצי לו"ז הביאו לכך שמערכות תוכנה של העולם האמיתי הן לא בדיוק יצירות אומנות. יש בהן יופי אני לא מכחיש, אבל תמיד יש מה לשפר. לא קורה שמפתח חדש מגיע לפרויקט ואומר "וואו איזה קוד מדהים יש פה". קוד הוא לא יצירת מופת של מפתח בודד אלא תוצאה של אילוצים. מפתחים טובים יודעים איך לדחוף את מערכת האילוצים הזאת לכיוון קצת יותר בריא ולהשפיע על המערכת עצמה כדי שהקוד יגדל בצורה טבעית בצורה טובה יותר.
כשאנחנו מיישמים את אותם עקרונות על פיתוח באמצעות AI אנחנו מגלים שמפתחים טובים לא הולכים לאיבוד אלא להיפך, מוצאים יותר דרכים להביע את עצמם:
1. מפתחים טובים מגדירים תבניות בקוד אותן ה AI ישכפל.
2. מפתחים טובים מגדירים שיטות עבודה - איך עושים Deployment, מה בודקים, איך בודקים. סוכני קידוד ישתמשו בשיטות עבודה אלה באמצעות MCP ויחסכו עבודה של בני אדם.
3. מפתחים טובים מגדירים אבסטרקציות ורכיבי קוד בסיסיים, בהם סוכני הקידוד ישתמשו כדי לבנות את הדברים הבאים.
העובדה שאני יכול לבקש מסוכן קידוד לבנות לי פיצ'ר חדש במערכת, בכל פרויקט לא טריוויאלי, היא לא תוצאה של החוכמה של סוכן הקידוד אלא של מבנה טוב של המערכת. ולראיה בהרבה פרויקטים סוכני הקידוד לא מצליחים לייצר תוצאות טובות ומפתחים מבזבזים שעות בריבים עם הסוכנים.
כן הקוד שלי, המערכת שלי, המבנה שלי. אני מכיר כל שורה בו ומכתיב את הכיוון, אפילו שאת רובו לא הקלדתי בעצמי.
אנתוני מאננינג כתב פוסט ארוך ומשכנע נגד שימוש ב AI לקידוד. ממליץ לקרוא אותו כאן:
https://antman-does-software.com/i-will-never-use-ai-to-code-or-write
אנתוני משווה בין קידוד לכתיבת ספר. כמו שלא היית נותן ל AI לכתוב את הרומן הבא שלך ומבקש ממנו "רק שפר קצת את הדמות הזאת", כי בכתיבה כל מילה חשובה, כך גם בקידוד אם תתן ל AI לכתוב בשבילך את הקוד זה כבר לא יהיה הקוד שלך. כל מילה חשובה.
זה טיעון מעניין אבל לדעתי שגוי, לא משקף את החיים האמיתיים של מפתחים גם לפני AI ולא עוזר לנו לכתוב קוד טוב יותר.
בחיים האמיתיים, גם לפני AI רוב הקוד שכתבנו לא היה 100% יצירה שלנו. עבודה על מערכות קיימות, עבודה בצוות, שימוש בספריות שלא תמיד אנחנו בחרנו ואילוצי לו"ז הביאו לכך שמערכות תוכנה של העולם האמיתי הן לא בדיוק יצירות אומנות. יש בהן יופי אני לא מכחיש, אבל תמיד יש מה לשפר. לא קורה שמפתח חדש מגיע לפרויקט ואומר "וואו איזה קוד מדהים יש פה". קוד הוא לא יצירת מופת של מפתח בודד אלא תוצאה של אילוצים. מפתחים טובים יודעים איך לדחוף את מערכת האילוצים הזאת לכיוון קצת יותר בריא ולהשפיע על המערכת עצמה כדי שהקוד יגדל בצורה טבעית בצורה טובה יותר.
כשאנחנו מיישמים את אותם עקרונות על פיתוח באמצעות AI אנחנו מגלים שמפתחים טובים לא הולכים לאיבוד אלא להיפך, מוצאים יותר דרכים להביע את עצמם:
1. מפתחים טובים מגדירים תבניות בקוד אותן ה AI ישכפל.
2. מפתחים טובים מגדירים שיטות עבודה - איך עושים Deployment, מה בודקים, איך בודקים. סוכני קידוד ישתמשו בשיטות עבודה אלה באמצעות MCP ויחסכו עבודה של בני אדם.
3. מפתחים טובים מגדירים אבסטרקציות ורכיבי קוד בסיסיים, בהם סוכני הקידוד ישתמשו כדי לבנות את הדברים הבאים.
העובדה שאני יכול לבקש מסוכן קידוד לבנות לי פיצ'ר חדש במערכת, בכל פרויקט לא טריוויאלי, היא לא תוצאה של החוכמה של סוכן הקידוד אלא של מבנה טוב של המערכת. ולראיה בהרבה פרויקטים סוכני הקידוד לא מצליחים לייצר תוצאות טובות ומפתחים מבזבזים שעות בריבים עם הסוכנים.
כן הקוד שלי, המערכת שלי, המבנה שלי. אני מכיר כל שורה בו ומכתיב את הכיוון, אפילו שאת רובו לא הקלדתי בעצמי.
📌 טיפ פייתון: לא צריך לכתוב את כל הקוד ב init
כשאנחנו כותבים מודול בפייתון מאוד נוח שמשתמשים יכולים לייבא את המודול ולהפעיל פקודות ישירות על שם החבילה, כלומר נניח שיש לי מודול בשם mymodule אז משתמשים מאוד אוהבים לכתוב:
דרך אחת לכתוב את mymodule כדי שזה יעבוד היא פשוט לכתוב קובץ בשם
ועכשיו משתמשים של המודול צריכים לטעון את הקובץ הפנימי מתוך החבילה ולכתוב:
העצלנים יותר ישתמשו ב alias ויכתבו ביבוא:
אבל זה לא נראה נכון ועדיין מעצבן את המשתמשים.
כותבים מודולים יצירתיים יודעים לשים את הקוד בקובץ ה
ובתוך הקובץ
אבל כותבים חבילות יותר יצירתיים דווקא מעדיפים להשתמש בשם קובץ מסודר עבור הקודם שלהם. במצב כזה נכתוב קובץ
ושוב הכל עובד אבל עכשיו גם מסודר - משתמשים יכולים לייבא את המודול mymodule ולקרוא לפונקציה add ישירות דרך היבוא, אפילו שהפונקציה מוגדרת בקובץ פנימי
כשאנחנו כותבים מודול בפייתון מאוד נוח שמשתמשים יכולים לייבא את המודול ולהפעיל פקודות ישירות על שם החבילה, כלומר נניח שיש לי מודול בשם mymodule אז משתמשים מאוד אוהבים לכתוב:
import mymodule
print(mymodule.add(10, 20))
דרך אחת לכתוב את mymodule כדי שזה יעבוד היא פשוט לכתוב קובץ בשם
mymodule.py ובתוכו להגדיר את הפונקציה add. אבל אם אתם רוצים לכתוב פרויקט ולשתף עם חברים סיכוי טוב שתרצו לשים את המודול שלכם בתוך תיקייה מסודרת ששמה יהיה כשם הפרויקט. ופה העסק מתחיל להסתבך, כי אם אני יוצר תיקייה בשם mymodule ובתוכה קובץ בשם utils.py עם הפונקציה שלי אז יש לי מבנה תיקיות:mymodule/
__init__.py
utils.py
ועכשיו משתמשים של המודול צריכים לטעון את הקובץ הפנימי מתוך החבילה ולכתוב:
import mymodule.utils
print(mymodule.utils.add(10, 20))
העצלנים יותר ישתמשו ב alias ויכתבו ביבוא:
import mymodule.utils as mymodule
print(mymodule.add(10, 20))
אבל זה לא נראה נכון ועדיין מעצבן את המשתמשים.
כותבים מודולים יצירתיים יודעים לשים את הקוד בקובץ ה
__init__.py של החבילה, וכך לא צריכים אפילו להמציא שם לקובץ המקור האמיתי והכל מסתדר עם היבוא, כלומר יהיה לנו בצד של החבילה:mymodule/
__init__.py
ובתוך הקובץ
__init__.py תופיע הגדרת הפונקציה add, ואז משתמשים של החבילה יוכלו שוב לכתוב:import mymodule
print(mymodule.add(10, 20))
אבל כותבים חבילות יותר יצירתיים דווקא מעדיפים להשתמש בשם קובץ מסודר עבור הקודם שלהם. במצב כזה נכתוב קובץ
utils.py עם הגדרת הפונקציה add, וקובץ __init__.py שיכיל רק את פקודת היבוא והיצוא מחדש:from .utils import add
ושוב הכל עובד אבל עכשיו גם מסודר - משתמשים יכולים לייבא את המודול mymodule ולקרוא לפונקציה add ישירות דרך היבוא, אפילו שהפונקציה מוגדרת בקובץ פנימי
mymodule/utils.py בתוך החבילה.❤1👍1
📌 אם קוד נכתב ביער ואף אחד לא משתמש בו
בפרויקט בשם chatwoot (ריילס) מצאתי את הקוד הבא:
הקוד לא עובד מכמה סיבות:
1. הפונקציה
2. הפונקציה
אין אף בדיקה על הקוד ולא מפעילים אותו משום מקום אבל הוא כן מחובר ל API Endpoint לכן אדם (או סוכן קידוד) שמסתכל רק עליו עלול לקבל את הרושם שהפונקציה והקובץ קיימים. ואם אותו אדם (או יותר סביר סוכן קידוד) יגיע לכתוב עכשיו פיצ'ר חדש הוא עלול להשתמש באותם רכיבים מדומיינים. וכן זאת בעיה של סוכני קידוד הרבה יותר מאשר של בני אדם, וזו הופכת להיות בעיה של בני אדם כשאותם בני אדם מפעילים סוכני קידוד בלי להכיר את הקוד ובלי לעבור מראש על תוכנית העבודה.
עכשיו אפשר לטעון שבני אדם הם הבעיה של סוכני קידוד ואם רק ניתן לסוכני קידוד לעבוד בשקט העולם יהיה מקום טוב יותר. אמרו דבר דומה על מכוניות אוטונומיות ובכל מקרה זה לא הולך לקרות ולא יקדם אותנו.
יותר חכם לשים לב שהיום הקוד הוא הפרומפט. קוד יכול להיות שבור גם אם אף אחד לא מפעיל אותו ויכול בקלות לקלקל את התוצאות של סוכן הקידוד. בעולם שבו הקוד הוא הפרומפט, קוד נקי הוא יעד חשוב מתמיד.
בפרויקט בשם chatwoot (ריילס) מצאתי את הקוד הבא:
class Api::V1::Accounts::WorkingHoursController < Api::V1::Accounts::BaseController
before_action :check_authorization
before_action :fetch_webhook, only: [:update]
def update
@working_hour.update!(working_hour_params)
end
private
def working_hour_params
params.require(:working_hour).permit(:inbox_id, :open_hour, :open_minutes, :close_hour, :close_minutes, :closed_all_day)
end
def fetch_working_hour
@working_hour = Current.account.working_hours.find(params[:id])
end
end
הקוד לא עובד מכמה סיבות:
1. הפונקציה
fetch_webhook לא קיימת. אי אפשר להפעיל אותה לפני update.2. הפונקציה
check_authorization מחפשת קובץ בשם working_hours_policy.rb שגם לא קיים.אין אף בדיקה על הקוד ולא מפעילים אותו משום מקום אבל הוא כן מחובר ל API Endpoint לכן אדם (או סוכן קידוד) שמסתכל רק עליו עלול לקבל את הרושם שהפונקציה והקובץ קיימים. ואם אותו אדם (או יותר סביר סוכן קידוד) יגיע לכתוב עכשיו פיצ'ר חדש הוא עלול להשתמש באותם רכיבים מדומיינים. וכן זאת בעיה של סוכני קידוד הרבה יותר מאשר של בני אדם, וזו הופכת להיות בעיה של בני אדם כשאותם בני אדם מפעילים סוכני קידוד בלי להכיר את הקוד ובלי לעבור מראש על תוכנית העבודה.
עכשיו אפשר לטעון שבני אדם הם הבעיה של סוכני קידוד ואם רק ניתן לסוכני קידוד לעבוד בשקט העולם יהיה מקום טוב יותר. אמרו דבר דומה על מכוניות אוטונומיות ובכל מקרה זה לא הולך לקרות ולא יקדם אותנו.
יותר חכם לשים לב שהיום הקוד הוא הפרומפט. קוד יכול להיות שבור גם אם אף אחד לא מפעיל אותו ויכול בקלות לקלקל את התוצאות של סוכן הקידוד. בעולם שבו הקוד הוא הפרומפט, קוד נקי הוא יעד חשוב מתמיד.
📌 הצפנה ב Rails - הטוב, הרע והמכוער
לריילס יש מנגנון מובנה להצפין מידע שנשמר בבסיס הנתונים. המנגנון מגדיר שני מפתחות הצפנה וביטים של מלח כדי לבלבל את האויב, כלומר אנחנו מגדירים בקונפיגורציה:
ואז מהקוד אפשר להשתמש ב ActiveRecord::Encryption כדי להצפין או לפענח עם המפתחות האלה, או להגדיר שדות שאוטומטית יוצפנו בשמירה לבסיס הנתונים ויפוענחו בקריאה. במדריך השימוש יש להם אינסוף מידע על החלפת מפתחות, מתי להשתמש בהצפנה דטרמניסטית ומתי לא דטרמניסטית ושאר היבטים של אבטחת מידע. קל, זמין וטוב כמו שריילס יודע.
יש גם קלאס ישן ומכוער יותר להצפנה בשם MessageEncryptor. דוגמת השימוש מהתיעוד נראית כך:
זה קוד מכוער כי הוא מכריח אותי להגדיר לבד את המלח ולגזור בעצמי את המפתחות ועוד מציג את הבסיס ליצירת המפתח בצורה מפורשת בקוד. כן אפשר לכתוב הצפנה מאובטחת עם MessageEncryptor אבל זה ידרוש עבודה וידע שלא מופיעים בתיעוד.
וכשאנשים לא מספיק מקצועיים או סוכני קידוד נתקלים בכאלה בעיות הם נוטים לזרוק את החלקים הקשים ולהפוך את הקוד המכוער לקוד רע, לדוגמה קוד שקיבלתי מ ChatGPT:
לאן נעלמו הביטים האקראיים של המלח? צ'אט כנראה לא חשב שזה מספיק חשוב. פרומפט נוסף אגב החזיר לי את הקוד הזה:
הפעם הבסיס למפתח הוא
לקחים? בהחלט. כשקוד תשתית דורש מיומנות ועדינות כדי להשתמש בו נכון יהיו בני אדם וסוכני קידוד שישברו אותו.
לריילס יש מנגנון מובנה להצפין מידע שנשמר בבסיס הנתונים. המנגנון מגדיר שני מפתחות הצפנה וביטים של מלח כדי לבלבל את האויב, כלומר אנחנו מגדירים בקונפיגורציה:
Add this entry to the credentials of the target environment:
active_record_encryption:
primary_key: YehXdfzxVKpoLvKseJMJIEGs2JxerkB8
deterministic_key: uhtk2DYS80OweAPnMLtrV2FhYIXaceAy
key_derivation_salt: g7Q66StqUQDQk9SJ81sWbYZXgiRogBwS
ואז מהקוד אפשר להשתמש ב ActiveRecord::Encryption כדי להצפין או לפענח עם המפתחות האלה, או להגדיר שדות שאוטומטית יוצפנו בשמירה לבסיס הנתונים ויפוענחו בקריאה. במדריך השימוש יש להם אינסוף מידע על החלפת מפתחות, מתי להשתמש בהצפנה דטרמניסטית ומתי לא דטרמניסטית ושאר היבטים של אבטחת מידע. קל, זמין וטוב כמו שריילס יודע.
יש גם קלאס ישן ומכוער יותר להצפנה בשם MessageEncryptor. דוגמת השימוש מהתיעוד נראית כך:
len = ActiveSupport::MessageEncryptor.key_len
salt = SecureRandom.random_bytes(len)
key = ActiveSupport::KeyGenerator.new('password').generate_key(salt, len) # => "\x89\xE0\x156\xAC..."
crypt = ActiveSupport::MessageEncryptor.new(key) # => #<ActiveSupport::MessageEncryptor ...>
encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
crypt.decrypt_and_verify(encrypted_data)
זה קוד מכוער כי הוא מכריח אותי להגדיר לבד את המלח ולגזור בעצמי את המפתחות ועוד מציג את הבסיס ליצירת המפתח בצורה מפורשת בקוד. כן אפשר לכתוב הצפנה מאובטחת עם MessageEncryptor אבל זה ידרוש עבודה וידע שלא מופיעים בתיעוד.
וכשאנשים לא מספיק מקצועיים או סוכני קידוד נתקלים בכאלה בעיות הם נוטים לזרוק את החלקים הקשים ולהפוך את הקוד המכוער לקוד רע, לדוגמה קוד שקיבלתי מ ChatGPT:
secret_key = Rails.application.key_generator.generate_key("my-secret", 32)
encryptor = ActiveSupport::MessageEncryptor.new(secret_key)
# Encrypt + sign
encrypted = encryptor.encrypt_and_sign("Hello world")
# Decrypt + verify
decrypted = encryptor.decrypt_and_verify(encrypted)
puts encrypted
puts decryptedלאן נעלמו הביטים האקראיים של המלח? צ'אט כנראה לא חשב שזה מספיק חשוב. פרומפט נוסף אגב החזיר לי את הקוד הזה:
secret_key_base = Rails.application.secret_key_base
# Derive a key
key_len = ActiveSupport::MessageEncryptor.key_len
salt = "my-encryption-salt"
key = ActiveSupport::KeyGenerator.new(secret_key_base).generate_key(salt, key_len)
encryptor = ActiveSupport::MessageEncryptor.new(key)
הפעם הבסיס למפתח הוא
secret_key_base שכבר נמצא בשימוש כדי להצפין את הקוקיז וכך קיבלנו מיחזור של בסיס למפתח הצפנה לשימושים שונים. רק אם אני מבקש במפורש את שיטת ההצפנה החדשה עם ActiveRecord::Encryption אני באמת מקבל אותה.לקחים? בהחלט. כשקוד תשתית דורש מיומנות ועדינות כדי להשתמש בו נכון יהיו בני אדם וסוכני קידוד שישברו אותו.
🤡1
הי חברים תגידו מה דעתכם על קוד ופוליטיקה? הייתם משתמשים בספריית קוד פתוח עם באנר של פרי פלסטין? מה לגבי סלבה אוקראינה? ולמה?
📌 באבטחת מידע לא שואלים מה כבר יכול לקרות
הרבה יותר קל לראות חולשות בקוד מאשר להבין איך לנצל את אותן חולשות כדי לעשות נזק, אבל כשאנחנו משאירים חולשות בקוד שלנו רק בגלל שאנחנו לא רואים מה כבר הנזק שהן יכולות לגרום אנחנו בסך הכל נותנים יותר מוטיבציה לאנשים שמבינים בזה.
הסיפור הבא נכנס אצלי לאוסף בעיות אבטחת מידע שקשורות ל AI והוא מדגים בדיוק את הפער בין החולשה לניצול. סיליין החליטו לתת לקלוד למיין את ה Issues שמשתמשים פותחים בעזרת קונפיגורציה כזאת:
ראיתם את הבעיה? אני בטוח שכן. לוקחים את ה title של ה Issue ושולחים אותו לסוכן שיכול להריץ פקודות Shell ולגשת לאינטרנט.
עכשיו להגנתם הסוכן רץ על מכונה של Github Actions בלי הרשאות לעשות שום דבר. ופה אני שומע בראש את השאלה שבטח גם הם חשבו "מה כבר יכול להישבר?". נו, מסתבר שגם מכונת גיטהאב אקשן בלי הרשאות יכולה לעשות נזק והתוצאה היתה גירסה מלוכלכת של cline שעלתה ל npm.
הסיפור הטכני המלא למתעניינים נמצא בלינק הזה:
https://neciudan.dev/cline-ci-got-compromised-here-is-how#what-is-openclaw-and-why-should-you-care
הלקח הוא ישן ומלווה אותנו עוד הרבה לפני ימי ה AI. באבטחת מידע לא שואלים "מה כבר יכול לקרות". סוגרים את החולשות לפני שמישהו אחר ימצא את התשובה.
הרבה יותר קל לראות חולשות בקוד מאשר להבין איך לנצל את אותן חולשות כדי לעשות נזק, אבל כשאנחנו משאירים חולשות בקוד שלנו רק בגלל שאנחנו לא רואים מה כבר הנזק שהן יכולות לגרום אנחנו בסך הכל נותנים יותר מוטיבציה לאנשים שמבינים בזה.
הסיפור הבא נכנס אצלי לאוסף בעיות אבטחת מידע שקשורות ל AI והוא מדגים בדיוק את הפער בין החולשה לניצול. סיליין החליטו לתת לקלוד למיין את ה Issues שמשתמשים פותחים בעזרת קונפיגורציה כזאת:
allowed_non_write_users: "*"
claude_args: >-
--allowedTools "Bash,Read,Write,Edit,Glob,Grep,WebFetch,WebSearch"
prompt: |
**Issue:** #${{ github.event.issue.number }}
**Title:** ${{ github.event.issue.title }}
ראיתם את הבעיה? אני בטוח שכן. לוקחים את ה title של ה Issue ושולחים אותו לסוכן שיכול להריץ פקודות Shell ולגשת לאינטרנט.
עכשיו להגנתם הסוכן רץ על מכונה של Github Actions בלי הרשאות לעשות שום דבר. ופה אני שומע בראש את השאלה שבטח גם הם חשבו "מה כבר יכול להישבר?". נו, מסתבר שגם מכונת גיטהאב אקשן בלי הרשאות יכולה לעשות נזק והתוצאה היתה גירסה מלוכלכת של cline שעלתה ל npm.
הסיפור הטכני המלא למתעניינים נמצא בלינק הזה:
https://neciudan.dev/cline-ci-got-compromised-here-is-how#what-is-openclaw-and-why-should-you-care
הלקח הוא ישן ומלווה אותנו עוד הרבה לפני ימי ה AI. באבטחת מידע לא שואלים "מה כבר יכול לקרות". סוגרים את החולשות לפני שמישהו אחר ימצא את התשובה.
Neciu Dan
How to steal npm publish tokens by opening GitHub issues
A chain of vulnerabilities and pretty clever attack strategies led to the compromise of the Cline CLI. Let me explain what happened and what you can do to protect yourself.