הרצת סוכן AI מקומי עם Docker
בניסוי היום אני רוצה להראות איך להריץ סוכן AI מקומי עם דוקר. הסוכן הוא בסך הכל קוד TypeScript שמשתמש בספריית ה ai של ורסל והמודל איתו הוא מתקשר זה מודל מקומי.
אפשר לראות את קוד הדוגמה בגיטהאב:
https://github.com/ynonp/docker-model-runner-demo
ארכיטקטורה
הראיתי פה לפני כמה ימים איך לבנות סוכן AI בעזרת הספריה של ורסל. בדוגמה ההיא הסוכן התחבר לרדיט והציע רעיונות לדיונים חדשים ותגובות לפי נושאים שהגדרנו מראש.
נכון, כל אחד יודע היום להריץ טייפסקריפט ו openai זמינים דרך API כך שאפשר להתחבר אליהם כמעט מכל מקום, אבל המפתח פה הוא ה"כמעט". בשביל לשלוט בסקייל של הסוכנים שלנו יש ייתרון להרצה מתוך דוקר, ואם אנחנו רוצים שהסוכנים גם ישתמשו במידע ארגוני רגיש או ירוצו On Prem אז יש ייתרון בשימוש ב LLM מקומי.
גירסאות חדשות של דוקר יודעות להריץ LLM מקומי ולחבר אותו לכל קונטיינר שרץ בתוך אותו compose, וזה מה שנראה בדוגמה היום.
קוד הסוכן
הלב של הדוגמה הוא הדוקר ולכן הסוכן עושה מעט מאוד, הוא צריך רק להתחבר למודל LLM מקומי ולשאול אותו שאלה. בעולם האמיתי כנראה תרצו שהסוכן ימשיך לרוץ ויתעורר פעם בכמה זמן עם cron או יטפל בבקשות HTTP. זה הקוד ב main.ts:
שימו לב לשני משתני סביבה חשובים: המשתנה
הקובץ docker-compose.yml
תחנה אחרונה בדוגמה היא הקובץ
מאוד קצר ולדעתי קסום:
1. הקובץ מגדיר את הסוכן ואת ה LLM המקומי ומחבר ביניהם.
2. כל מה שצריך בשביל לבחור LLM אחר זה לשנות את שם המודל. כל השאר מגיע ליישום אוטומטית דרך משתני הסביבה.
3. דוקר דואג לבד להריץ את המודל ולשתף אותו בין היישומים שצריכים גישה.
4. ה LLM נגיש רק מתוך דוקר.
5. כאן אפשר למצוא רשימה של מודלים שנתמכים ב Docker ותוכלו להריץ:
https://hub.docker.com/u/ai
בניסוי היום אני רוצה להראות איך להריץ סוכן AI מקומי עם דוקר. הסוכן הוא בסך הכל קוד TypeScript שמשתמש בספריית ה ai של ורסל והמודל איתו הוא מתקשר זה מודל מקומי.
אפשר לראות את קוד הדוגמה בגיטהאב:
https://github.com/ynonp/docker-model-runner-demo
ארכיטקטורה
הראיתי פה לפני כמה ימים איך לבנות סוכן AI בעזרת הספריה של ורסל. בדוגמה ההיא הסוכן התחבר לרדיט והציע רעיונות לדיונים חדשים ותגובות לפי נושאים שהגדרנו מראש.
נכון, כל אחד יודע היום להריץ טייפסקריפט ו openai זמינים דרך API כך שאפשר להתחבר אליהם כמעט מכל מקום, אבל המפתח פה הוא ה"כמעט". בשביל לשלוט בסקייל של הסוכנים שלנו יש ייתרון להרצה מתוך דוקר, ואם אנחנו רוצים שהסוכנים גם ישתמשו במידע ארגוני רגיש או ירוצו On Prem אז יש ייתרון בשימוש ב LLM מקומי.
גירסאות חדשות של דוקר יודעות להריץ LLM מקומי ולחבר אותו לכל קונטיינר שרץ בתוך אותו compose, וזה מה שנראה בדוגמה היום.
קוד הסוכן
הלב של הדוגמה הוא הדוקר ולכן הסוכן עושה מעט מאוד, הוא צריך רק להתחבר למודל LLM מקומי ולשאול אותו שאלה. בעולם האמיתי כנראה תרצו שהסוכן ימשיך לרוץ ויתעורר פעם בכמה זמן עם cron או יטפל בבקשות HTTP. זה הקוד ב main.ts:
import { createOpenAICompatible } from "npm:@ai-sdk/openai-compatible";
import { generateText } from "npm:ai";
const aiRunner = createOpenAICompatible({
name: "ai",
baseURL: Deno.env.get("AI_RUNNER_URL")!,
});
const model = aiRunner(Deno.env.get("AI_RUNNER_MODEL")!);
export const askLocalLLMQuestion = async (
input: string,
) => {
const { text } = await generateText({
model,
prompt: input,
maxRetries: 0,
});
return text;
};
const input = \Tell me a story about your grandmother.\;
const localLLMResult =
await askLocalLLMQuestion(input);
console.log(localLLMResult);
שימו לב לשני משתני סביבה חשובים: המשתנה
AI_RUNNER_MODEL מחזיק את המודל והמשתנה AI_RUNNER_URL מחזיק את ה URL לגישה למערכת ה LLM. שניהם הגיעו מדוקר מהקובץ docker-compose.yml.הקובץ docker-compose.yml
תחנה אחרונה בדוגמה היא הקובץ
docker-compose.yml וזה תוכנו:services:
chat:
build: ./agent
depends_on:
- ai_runner
ai_runner:
provider:
type: model
options:
model: ai/smollm2
מאוד קצר ולדעתי קסום:
1. הקובץ מגדיר את הסוכן ואת ה LLM המקומי ומחבר ביניהם.
2. כל מה שצריך בשביל לבחור LLM אחר זה לשנות את שם המודל. כל השאר מגיע ליישום אוטומטית דרך משתני הסביבה.
3. דוקר דואג לבד להריץ את המודל ולשתף אותו בין היישומים שצריכים גישה.
4. ה LLM נגיש רק מתוך דוקר.
5. כאן אפשר למצוא רשימה של מודלים שנתמכים ב Docker ותוכלו להריץ:
https://hub.docker.com/u/ai
GitHub
GitHub - ynonp/docker-model-runner-demo
Contribute to ynonp/docker-model-runner-demo development by creating an account on GitHub.
❤1🔥1
תתחילו עם פונקציות
בהינתן שיש לנו מכונה שיכולה לממש פונקציות פשוטות כמעט בלי טעויות, הגיע הזמן שנשנה את סדר הנושאים כשאנחנו מלמדים תכנות. האמת, את השינוי הזה היה צריך לעשות עוד הרבה לפני ה AI, אבל עכשיו באמת שאי אפשר לדחות אותו.
תתחילו עם פונקציות.
ישבתי לעזור לילד בעבודה בפייתון. הם קיבלו קטע קוד עם כמה שורות ריקות והיו צריכים להשלים, ככה זה נראה אחרי השלמה:
הקוד קורא מספר מהמשתמש ובודק אם המספר שווה לסכום מחלקיו, מה שנקרא מספר מושלם. תרגיל חמוד שלגמרי מפספס את המטרה, כי מה שחשוב ללמד בשלבים הראשונים של חשיפה למדעי המחשב הוא התרגום משפה טבעית לשפה פורמלית. הצעד הראשון היה צריך להיות בסך הכל:
עכשיו יש לנו שתי בעיות חדשות:
1. לא הגדרנו את divisors
2. בשביל להגדיר את divisors אנחנו צריכים לחשוב על ממשקים, מה זה פונקציה, מה פונקציה מקבלת ומחזירה, איך פונקציה מתקשרת עם הסביבה שלה.
ועוד כמה שאלות חדשות:
1. אולי גם קלט צריך להיות פונקציה?
2. מה לגבי ה if?
3. וה print? למה אנחנו מדפיסים ולא "מחזירים" ערך? מה ההבדל בין שתי הפעולות?
ואלה בדיוק הדברים שאנחנו צריכים ללמוד וללמד, הרבה לפני שמדברים על מימוש ספציפי של משתנים, לולאות ו Control Flow. ממילא בשביל הלולאה הם רק צריכים ללחוץ Tab.
בהינתן שיש לנו מכונה שיכולה לממש פונקציות פשוטות כמעט בלי טעויות, הגיע הזמן שנשנה את סדר הנושאים כשאנחנו מלמדים תכנות. האמת, את השינוי הזה היה צריך לעשות עוד הרבה לפני ה AI, אבל עכשיו באמת שאי אפשר לדחות אותו.
תתחילו עם פונקציות.
ישבתי לעזור לילד בעבודה בפייתון. הם קיבלו קטע קוד עם כמה שורות ריקות והיו צריכים להשלים, ככה זה נראה אחרי השלמה:
num = int(input("select a number: "))
sum = 0
x = 1
while x < num:
if num % x == 0:
sum += x
x += 1
if num == sum:
print("Perfect number")
else:
print("Not a perfect number")
הקוד קורא מספר מהמשתמש ובודק אם המספר שווה לסכום מחלקיו, מה שנקרא מספר מושלם. תרגיל חמוד שלגמרי מפספס את המטרה, כי מה שחשוב ללמד בשלבים הראשונים של חשיפה למדעי המחשב הוא התרגום משפה טבעית לשפה פורמלית. הצעד הראשון היה צריך להיות בסך הכל:
num = int(input("select a number: "))
if num == sum(divisors(num))
print("Perfect number")
else:
print("Not a perfect number")
עכשיו יש לנו שתי בעיות חדשות:
1. לא הגדרנו את divisors
2. בשביל להגדיר את divisors אנחנו צריכים לחשוב על ממשקים, מה זה פונקציה, מה פונקציה מקבלת ומחזירה, איך פונקציה מתקשרת עם הסביבה שלה.
ועוד כמה שאלות חדשות:
1. אולי גם קלט צריך להיות פונקציה?
2. מה לגבי ה if?
3. וה print? למה אנחנו מדפיסים ולא "מחזירים" ערך? מה ההבדל בין שתי הפעולות?
ואלה בדיוק הדברים שאנחנו צריכים ללמוד וללמד, הרבה לפני שמדברים על מימוש ספציפי של משתנים, לולאות ו Control Flow. ממילא בשביל הלולאה הם רק צריכים ללחוץ Tab.
👌2
הזמנה לוובינר: פיתוח בעזרת AI
הי חברים,
לפעמים החיים מרגישים כמו תוכנית ריאליטי, נקרא לה המירוץ ל AI. כולם מדברים על ה AI שאתה חייב לאמץ, ואיך לכתוב 30 בדיקות יחידה ב-30 שניות או להפוך את הרעיונות שלך למוצרים תוך דקות. מנהלים בכל מיני חברות התחילו למדוד כמה אחוז מהקוד נכתב על ידי AI.
ואתה עוד מנסה להבין מי נגד מי, ואיך לשכנע את ה AI לכתוב איזה חצי משחק או כמה בדיקות ולא מבין למה הקוד שיוצא לא נראה כמו בפירסומת.
אם גם אתם מרגישים קצת מבולבלים מכל הרעידת אדמה שהולכת סביבנו אני רוצה להזמין אתכם לשיחה קצרה עם הדגמות על איך לשלב AI בתהליך הפיתוח ולקבל תוצאות טובות. נדבר קצת על כלים ואז אראה כמה דוגמאות עם Cursor על פרויקט קוד פתוח דרכן נבין יותר טוב מה החוזקות והחולשות של AI בפיתוח קוד. זה הולך להיות וובינר מאוד ידידותי למתחילים עם הרבה זמן לשאול שאלות אז תבואו עם מיקרופונים פתוחים.
הוובינר יתקיים ביום חמישי הבא ה 29.5 בשעה 10 בבוקר.
לא תהיה הקלטה. בעיקר כי אני חושב שהאווירה יותר רגועה כשאנשים לא מרגישים שמקליטים אותם וככה השיחה באווירה יותר ידידותית. אם יהיה מעניין זה אולי יהפוך למפגש שבועי.
הוובינר יתקיים בזום ואפשר למצוא את הלינק לפגישה יחד עם כל הפרטים בדף אירוע בפייסבוק שיצרתי בקישור כאן:
https://www.facebook.com/events/9481501425305658/
אין צורך להירשם מראש אבל אם תסמנו בפייסבוק שאתם באים הוא בטח ישלח לכם תזכורת קרוב לאירוע.
הי חברים,
לפעמים החיים מרגישים כמו תוכנית ריאליטי, נקרא לה המירוץ ל AI. כולם מדברים על ה AI שאתה חייב לאמץ, ואיך לכתוב 30 בדיקות יחידה ב-30 שניות או להפוך את הרעיונות שלך למוצרים תוך דקות. מנהלים בכל מיני חברות התחילו למדוד כמה אחוז מהקוד נכתב על ידי AI.
ואתה עוד מנסה להבין מי נגד מי, ואיך לשכנע את ה AI לכתוב איזה חצי משחק או כמה בדיקות ולא מבין למה הקוד שיוצא לא נראה כמו בפירסומת.
אם גם אתם מרגישים קצת מבולבלים מכל הרעידת אדמה שהולכת סביבנו אני רוצה להזמין אתכם לשיחה קצרה עם הדגמות על איך לשלב AI בתהליך הפיתוח ולקבל תוצאות טובות. נדבר קצת על כלים ואז אראה כמה דוגמאות עם Cursor על פרויקט קוד פתוח דרכן נבין יותר טוב מה החוזקות והחולשות של AI בפיתוח קוד. זה הולך להיות וובינר מאוד ידידותי למתחילים עם הרבה זמן לשאול שאלות אז תבואו עם מיקרופונים פתוחים.
הוובינר יתקיים ביום חמישי הבא ה 29.5 בשעה 10 בבוקר.
לא תהיה הקלטה. בעיקר כי אני חושב שהאווירה יותר רגועה כשאנשים לא מרגישים שמקליטים אותם וככה השיחה באווירה יותר ידידותית. אם יהיה מעניין זה אולי יהפוך למפגש שבועי.
הוובינר יתקיים בזום ואפשר למצוא את הלינק לפגישה יחד עם כל הפרטים בדף אירוע בפייסבוק שיצרתי בקישור כאן:
https://www.facebook.com/events/9481501425305658/
אין צורך להירשם מראש אבל אם תסמנו בפייסבוק שאתם באים הוא בטח ישלח לכם תזכורת קרוב לאירוע.
Facebook
וובינר למפתחים - איך לקבל קוד טוב מ AI
Event by ינון פרק ToCode on Thursday, May 29 2025
👍5❤1🏆1
הבנה היא הקפיצה הבאה
תנועת הפיתוח האייג'יילית קמה ב 2001 במטרה להרוג את מודל מפל המים. הם מפורסמים בהעדפה של תהליכים אורגניים על פני תכנון מראש, העדפה של קוד עובד על פני מסמכים ושיטת הספרינטים לפיה אנחנו מתקדמים בצעדים קטנים לכיוון תוכנה שעובדת, כאשר השינוי המתמיד הוא חלק בלתי נפרד מהתהליך. הם אומרים:
> Agile processes promote sustainable development.
> The sponsors, developers, and users should be able
> to maintain a constant pace indefinitely.
אבל מה אם אנחנו נכנסים לעולם בו יותר קל לבנות תוכנה חדשה מאפס מאשר לעדכן ולתקן את הקיימת?
אם את אותו מוצר שפעם לקח שנתיים לכתוב היום AI כותב בשעה ובחינם, אז בשביל מה להשקיע בקוד שאפשר לתחזק? בשביל מה להשקיע באנשים ותהליכים? המערכת תעבוד עד שה AI ייתקע ואז ניתן לו לבנות מערכת חדשה.
הפיל שבחדר הוא הבעיה של הבנה. מערכות ה AI היום טובות מאוד בייצור טקסט חדש אבל לא מספיק טובות בהבנת קוד קיים. זאת הסיבה שהם לא מצליחים למצוא אפילו באגים פשוטים ושלא משנה מה ננסה לבנות תמיד ייגמר תקציב ההודעות לפני שמגיעים לקוד שעובד 100%.
ואחרי שאמרנו את כל זה ושמנו את הדאגה בצד צריך להודות שהביצועים של צוותי פיתוח מבוססי AI מרשימים. אם יש לכם כמה דקות כדאי לנסות את זה:
https://app.emergent.sh
קוד הפעלה: VIBEWITHRUNWAY
תנועת הפיתוח האייג'יילית קמה ב 2001 במטרה להרוג את מודל מפל המים. הם מפורסמים בהעדפה של תהליכים אורגניים על פני תכנון מראש, העדפה של קוד עובד על פני מסמכים ושיטת הספרינטים לפיה אנחנו מתקדמים בצעדים קטנים לכיוון תוכנה שעובדת, כאשר השינוי המתמיד הוא חלק בלתי נפרד מהתהליך. הם אומרים:
> Agile processes promote sustainable development.
> The sponsors, developers, and users should be able
> to maintain a constant pace indefinitely.
אבל מה אם אנחנו נכנסים לעולם בו יותר קל לבנות תוכנה חדשה מאפס מאשר לעדכן ולתקן את הקיימת?
אם את אותו מוצר שפעם לקח שנתיים לכתוב היום AI כותב בשעה ובחינם, אז בשביל מה להשקיע בקוד שאפשר לתחזק? בשביל מה להשקיע באנשים ותהליכים? המערכת תעבוד עד שה AI ייתקע ואז ניתן לו לבנות מערכת חדשה.
הפיל שבחדר הוא הבעיה של הבנה. מערכות ה AI היום טובות מאוד בייצור טקסט חדש אבל לא מספיק טובות בהבנת קוד קיים. זאת הסיבה שהם לא מצליחים למצוא אפילו באגים פשוטים ושלא משנה מה ננסה לבנות תמיד ייגמר תקציב ההודעות לפני שמגיעים לקוד שעובד 100%.
ואחרי שאמרנו את כל זה ושמנו את הדאגה בצד צריך להודות שהביצועים של צוותי פיתוח מבוססי AI מרשימים. אם יש לכם כמה דקות כדאי לנסות את זה:
https://app.emergent.sh
קוד הפעלה: VIBEWITHRUNWAY
app.emergent.sh
Emergent - Build Apps with AI
AI-powered app development platform
מה שה Commit Message לא סיפר
במהלך תיקון באג אצל לקוח הגענו לקובץ שנראה קשור ומיד עלו השאלות - מי שם את הקובץ הזה שם? למה? מה אנחנו מפספסים?
הצעד הבא במצבים כאלה הוא git log על הקובץ:
ובאמת הופיעה הודעת קומיט שמסבירה שהקובץ הוכנס בעקבות המלצה מהאינטרנט ואפילו לינק לעמוד הרלוונטי עם ההמלצה, רק שזה לא מספיק:
1. דפי אינטרנט יכולים להשתנות. במקרה שלנו הקומיט יחסית עדכני לכן אני חושב שהגענו לאותו מדריך, אבל באופן כללי בכתיבת הודעת קומיט עדיף שהסיפור המלא ישב בתוך הודעת הקומיט. אין בעיה עם הודעות קומיט ארוכות מי שלא רוצה לא קורא. אם מימשתם פיתרון לפי דף אינטרנט בקשו מאיזה GPT לסכם לכם את עמוד האינטרנט ושתלו את זה בהודעת הקומיט.
2. דפי אינטרנט יכולים לכלול מספר הצעות (זה היה הסיפור במקרה שלנו). הלינק באמת פתח דף עם הסבר על הבעיה ומספר הצעות לפיתרון, אבל אנחנו לא יודעים למה נבחר הפיתרון שנבחר. זה סיפור אחד אם מישהו לקח את הפיתרון הראשון שהוא ראה וסיפור אחר אם מישהו ניסה את כל הפיתרונות ורק אחד עבד. אם אתם מקשרים למסמך חיצוני שכולל מספר אפשרויות הסבירו בהודעת הקומיט מה המחקר שעשיתם ולמה בחרתם באפשרות שבחרתם.
3. מומלץ מאוד לחבר הודעות קומיט לבעיות ב Jira או במערכת ניהול פנימית אחרת שלכם כך שעבור כל שינוי נוכל להבין מה הבאג שגרם למישהו לשבת לחקור את זה ולשנות ואיזה בדיקות נעשו אחרי השינוי כדי לוודא שאין רגרסיות. חיבור כזה עוזר למי שמגיע להמשיך או לשנות תיקון להבין איזה רגרסיות עלולות לקפוץ חזרה.
הודעת קומיט היא הזדמנות, זו מתנה שאתם נותנים לחברים שלכם מהעתיד. בכתיבת כל קומיט דמיינו מי אמור לקרוא את זה ואיזה מידע הקוראים העתידיים יצטרכו.
במהלך תיקון באג אצל לקוח הגענו לקובץ שנראה קשור ומיד עלו השאלות - מי שם את הקובץ הזה שם? למה? מה אנחנו מפספסים?
הצעד הבא במצבים כאלה הוא git log על הקובץ:
git log -- file
ובאמת הופיעה הודעת קומיט שמסבירה שהקובץ הוכנס בעקבות המלצה מהאינטרנט ואפילו לינק לעמוד הרלוונטי עם ההמלצה, רק שזה לא מספיק:
1. דפי אינטרנט יכולים להשתנות. במקרה שלנו הקומיט יחסית עדכני לכן אני חושב שהגענו לאותו מדריך, אבל באופן כללי בכתיבת הודעת קומיט עדיף שהסיפור המלא ישב בתוך הודעת הקומיט. אין בעיה עם הודעות קומיט ארוכות מי שלא רוצה לא קורא. אם מימשתם פיתרון לפי דף אינטרנט בקשו מאיזה GPT לסכם לכם את עמוד האינטרנט ושתלו את זה בהודעת הקומיט.
2. דפי אינטרנט יכולים לכלול מספר הצעות (זה היה הסיפור במקרה שלנו). הלינק באמת פתח דף עם הסבר על הבעיה ומספר הצעות לפיתרון, אבל אנחנו לא יודעים למה נבחר הפיתרון שנבחר. זה סיפור אחד אם מישהו לקח את הפיתרון הראשון שהוא ראה וסיפור אחר אם מישהו ניסה את כל הפיתרונות ורק אחד עבד. אם אתם מקשרים למסמך חיצוני שכולל מספר אפשרויות הסבירו בהודעת הקומיט מה המחקר שעשיתם ולמה בחרתם באפשרות שבחרתם.
3. מומלץ מאוד לחבר הודעות קומיט לבעיות ב Jira או במערכת ניהול פנימית אחרת שלכם כך שעבור כל שינוי נוכל להבין מה הבאג שגרם למישהו לשבת לחקור את זה ולשנות ואיזה בדיקות נעשו אחרי השינוי כדי לוודא שאין רגרסיות. חיבור כזה עוזר למי שמגיע להמשיך או לשנות תיקון להבין איזה רגרסיות עלולות לקפוץ חזרה.
הודעת קומיט היא הזדמנות, זו מתנה שאתם נותנים לחברים שלכם מהעתיד. בכתיבת כל קומיט דמיינו מי אמור לקרוא את זה ואיזה מידע הקוראים העתידיים יצטרכו.
👍2
פרידה ולקחים מ Spanish Panda
לפני כמה שנים התחלתי לעבוד על פרויקט צד שיעזור לי לזכור מילים בשפות זרות. חשבתי שיהיה נחמד אם יהיה לי מילון זמין שגם יוכל לזכור את המילים שחיפשתי ואחרי כמה ימים להמשיך להזכיר לי את אותן מילים עד שאני כבר אזכור טוב את משמעותן.
השבוע הורדתי את השרת שהריץ אותו אחרי שהבנתי טוב יותר מה באמת אני צריך ובניתי פיתרון מדויק בהרבה. זה הסיפור בקצרה וכמה לקחים.
הכל התחיל בטכנולוגיה
את המוטיבציה לכתוב מילון קיבלתי כשהתחלתי ללמוד על בסיסי נתונים גרפיים. חשבתי שחיבור בין מילים בשפה זה שימוש ממש מושלם לבסיס נתונים גרפי ומאוד אהבתי את הממשק של neo4j וככה חשבתי לפתור שתי בעיות בפרויקט צד אחד: גם אוכל ללמוד neo4j וגם לזכור מילים בשפה זרה. בשביל הזמינות ובשביל לחסוך עבודה על הממשק החלטתי שזה יהיה בוט לטלגרם, וכך נולדה הפנדה הספרדית.
באותו זמן ה AI היה עוד בחיתולים ואי אפשר היה להשתמש ב ChatGPT כדי לתרגם. גוגל טרנסלייט גם החזיר תוצאות בינוניות ולכן השקעתי המון עבודה בלמצוא ולטייב תרגומים ולחבר תוצאות מכמה מילונים. זה היה כיף אבל גם מיותר לגמרי כי עד שסיימתי את הפיתוח כבר היה AI וכל בעיות התרגום שלי נפתרו בשיחה עם קלוד, אבל לא בטוח שאפשר היה לדעת איך דברים יתפתחו באותו זמן.
מבחינת בסיס הנתונים העבודה עם neo4j נראתה מבטיחה בהתחלה אבל מהר מאוד האבסטרקציה נשברה. הבעיה עם neo4j עבורי היתה שהשאילתות היו כתובות בשפה מיוחדת שלהם והיה קשה לבנות שאילתות בסיסיות ולהשתמש בהן כדי לבנות שאילתות מורכבות יותר. מצאתי שאני משכפל הרבה מקוד השאילתות וכך המערכת הפכה לקשה עד בלתי אפשרית לתחזוקה.
בגלל שאחת המטרות של הפרויקט היתה ללמוד טכנולוגיה, המחסום נראה כמו הזדמנות ועברתי לשכתב את המערכת על בסיס נתונים גרפי אחר שנקרא JanusGraph. הוא כתוב ב Java וזו נראתה הזדמנות טובה ללמוד סקאלה וכך נכנסתי להרפתקאה חדשה של לימוד סקאלה, JanusGraph ושפת שאילתות שנקראת גרמלין.
המוצר היה רק תירוץ
סקאלה היתה בשבילי אהבה ממבט ראשון. שפה זורמת, אבסטרקציות טובות, קלה להרחבה ועם מערכת טיפוסים חזקה. הבעיה עם סקאלה זה האקוסיסטם אבל זה סיפור לפוסט אחר.
בגלל שזה היה כיף המשכתי להוסיף פיצ'רים לבוט בעיקר בשביל לשחק עם הכלים: יצרתי חידוני אוצר מילים שהבוט שלח, בניתי תשתית גנרית כדי שאפשר יהיה בקלות לבנות בוטים מקבילים לפלטפורמות אחרות כמו ווטסאפ או סלאק, בניתי מנגנון של Spaced Repetition שעושה מאמץ לשלוח למשתמשים בדיוק את המילים שהם צריכים לתרגל, חיברתי חיפוש תמונה ואפשרות להגדיר אוספים שונים של מילים וגם הסברים ואטימיולוגיה לכל מילה שמחפשים ומערכת לניהול אוצר המילים ששמור בבוט ואפשרות לייצא ולייבא את המילים, כמובן שאפשרות לבחור את השפה של הבוט וקבצי הודעות בכל השפות ועוד המון דברים שאני אפילו לא זוכר. כל פעם כשהיה קצת זמן הוספתי עוד פיצ'ר קטן, סך הכל הפרויקט עמד על קצת מעל 10 אלף שורות.
עד שהבנתי שאני בעצם לא משתמש בכל הפיצ'רים האלה
השימוש בבוט היה קצת פחות מהנה מהפיתוח שלו. ככל ששמרתי יותר מילים גיליתי שהשיטה של בחני אוצר מילים לא ממש עובדת עבורי. לא משנה כמה פעמים אני מצליח לענות על המילה בבוחן, זה לא עוזר לי להיזכר בה בשיחה אמיתית.
לאט לאט הבנתי שאני משתמש בו רק בתור מילון בטלגרם, ואני חייב להודות שבתור מילון בטלגרם הוא כן היה נחמד, אבל בשביל מילון בטלגרם לא צריך 10 אלף שורות קוד, לא צריך בסיס נתונים גרפי וגם לא שרת. אפשר להסתפק ב val.town.
וככה נפרדתי מכל הטכנולוגיה המתוחכמת והחלפתי אותה בסקריפט הבא, שרץ בחינם לגמרי על val.town (אפילו לא צריך לשלם על הטוקנים ל OpenAI כי גם זה עליהם):
לפני כמה שנים התחלתי לעבוד על פרויקט צד שיעזור לי לזכור מילים בשפות זרות. חשבתי שיהיה נחמד אם יהיה לי מילון זמין שגם יוכל לזכור את המילים שחיפשתי ואחרי כמה ימים להמשיך להזכיר לי את אותן מילים עד שאני כבר אזכור טוב את משמעותן.
השבוע הורדתי את השרת שהריץ אותו אחרי שהבנתי טוב יותר מה באמת אני צריך ובניתי פיתרון מדויק בהרבה. זה הסיפור בקצרה וכמה לקחים.
הכל התחיל בטכנולוגיה
את המוטיבציה לכתוב מילון קיבלתי כשהתחלתי ללמוד על בסיסי נתונים גרפיים. חשבתי שחיבור בין מילים בשפה זה שימוש ממש מושלם לבסיס נתונים גרפי ומאוד אהבתי את הממשק של neo4j וככה חשבתי לפתור שתי בעיות בפרויקט צד אחד: גם אוכל ללמוד neo4j וגם לזכור מילים בשפה זרה. בשביל הזמינות ובשביל לחסוך עבודה על הממשק החלטתי שזה יהיה בוט לטלגרם, וכך נולדה הפנדה הספרדית.
באותו זמן ה AI היה עוד בחיתולים ואי אפשר היה להשתמש ב ChatGPT כדי לתרגם. גוגל טרנסלייט גם החזיר תוצאות בינוניות ולכן השקעתי המון עבודה בלמצוא ולטייב תרגומים ולחבר תוצאות מכמה מילונים. זה היה כיף אבל גם מיותר לגמרי כי עד שסיימתי את הפיתוח כבר היה AI וכל בעיות התרגום שלי נפתרו בשיחה עם קלוד, אבל לא בטוח שאפשר היה לדעת איך דברים יתפתחו באותו זמן.
מבחינת בסיס הנתונים העבודה עם neo4j נראתה מבטיחה בהתחלה אבל מהר מאוד האבסטרקציה נשברה. הבעיה עם neo4j עבורי היתה שהשאילתות היו כתובות בשפה מיוחדת שלהם והיה קשה לבנות שאילתות בסיסיות ולהשתמש בהן כדי לבנות שאילתות מורכבות יותר. מצאתי שאני משכפל הרבה מקוד השאילתות וכך המערכת הפכה לקשה עד בלתי אפשרית לתחזוקה.
בגלל שאחת המטרות של הפרויקט היתה ללמוד טכנולוגיה, המחסום נראה כמו הזדמנות ועברתי לשכתב את המערכת על בסיס נתונים גרפי אחר שנקרא JanusGraph. הוא כתוב ב Java וזו נראתה הזדמנות טובה ללמוד סקאלה וכך נכנסתי להרפתקאה חדשה של לימוד סקאלה, JanusGraph ושפת שאילתות שנקראת גרמלין.
המוצר היה רק תירוץ
סקאלה היתה בשבילי אהבה ממבט ראשון. שפה זורמת, אבסטרקציות טובות, קלה להרחבה ועם מערכת טיפוסים חזקה. הבעיה עם סקאלה זה האקוסיסטם אבל זה סיפור לפוסט אחר.
בגלל שזה היה כיף המשכתי להוסיף פיצ'רים לבוט בעיקר בשביל לשחק עם הכלים: יצרתי חידוני אוצר מילים שהבוט שלח, בניתי תשתית גנרית כדי שאפשר יהיה בקלות לבנות בוטים מקבילים לפלטפורמות אחרות כמו ווטסאפ או סלאק, בניתי מנגנון של Spaced Repetition שעושה מאמץ לשלוח למשתמשים בדיוק את המילים שהם צריכים לתרגל, חיברתי חיפוש תמונה ואפשרות להגדיר אוספים שונים של מילים וגם הסברים ואטימיולוגיה לכל מילה שמחפשים ומערכת לניהול אוצר המילים ששמור בבוט ואפשרות לייצא ולייבא את המילים, כמובן שאפשרות לבחור את השפה של הבוט וקבצי הודעות בכל השפות ועוד המון דברים שאני אפילו לא זוכר. כל פעם כשהיה קצת זמן הוספתי עוד פיצ'ר קטן, סך הכל הפרויקט עמד על קצת מעל 10 אלף שורות.
עד שהבנתי שאני בעצם לא משתמש בכל הפיצ'רים האלה
השימוש בבוט היה קצת פחות מהנה מהפיתוח שלו. ככל ששמרתי יותר מילים גיליתי שהשיטה של בחני אוצר מילים לא ממש עובדת עבורי. לא משנה כמה פעמים אני מצליח לענות על המילה בבוחן, זה לא עוזר לי להיזכר בה בשיחה אמיתית.
לאט לאט הבנתי שאני משתמש בו רק בתור מילון בטלגרם, ואני חייב להודות שבתור מילון בטלגרם הוא כן היה נחמד, אבל בשביל מילון בטלגרם לא צריך 10 אלף שורות קוד, לא צריך בסיס נתונים גרפי וגם לא שרת. אפשר להסתפק ב val.town.
וככה נפרדתי מכל הטכנולוגיה המתוחכמת והחלפתי אותה בסקריפט הבא, שרץ בחינם לגמרי על val.town (אפילו לא צריך לשלם על הטוקנים ל OpenAI כי גם זה עליהם):
import { OpenAI } from "https://esm.town/v/std/openai";
import { telegramSendMessage } from "https://esm.town/v/vtdocs/telegramSendMessage?v=5";
import {
Bot,
webhookCallback,
} from "https://deno.land/x/grammy@v1.35.0/mod.ts";
const bot = new Bot(Deno.env.get("SPANISH_PANDA_BOT_TOKEN")!);
const SECRET_TOKEN = Deno.env.get("SPANISH_PANDA_BOT_TOKEN")!.split(":")[1];
let isEndpointSet = false;
bot.command("start", (ctx) => ctx.reply("Welcome! Up and running."));
bot.on("message", async (ctx) => {
const text = await ctx.message.text
console.log(\received: ${text}\)
if (text) {
const response = await translateToSpanishWithOpenAI(text);
console.log(\translated to: ${response}\);
ctx.reply(response);
}
});
const handleUpdate = webhookCallback(
bot,
"std/http",undefined,
undefined,
SECRET_TOKEN
);
async function translateToSpanishWithOpenAI(text: string) {
const openai = new OpenAI();
const completion = await openai.chat.completions.create({
messages: [
{
role: 'system',
content: 'You are a Spanish/English dictionary but you also know all the languages in the world. When you receive a word or phrase in Spanish respond with its English translation. When you receive a word or phrase in another language translate it to Spanish'
},
{
role: "user",
content: "hola"
},
{ role: "assistant", content: \hello\ },
{
role: "user",
content: "יש לי חבר"
},
{
role: "assistant",
content:
\tengo un amigo\,
},
{
role: "user",
content: text
},
],
model: "gpt-4",
});
return completion.choices[0].message.content || "Translation Error";
}
export default async (req: Request): Promise<Response> => {
// Set webhook if it is not set yet
// Do this in the HTTP handler so we get the endpoint url from req.url
// This is a no-op if nothing's changed
if (!isEndpointSet) {
await bot.api.setWebhook(req.url, {
secret_token: SECRET_TOKEN,
});
isEndpointSet = true;
}
if (req.method === "POST") {
return await handleUpdate(req);
}
return new Response("TODO GET", { status: 200 });
};
פחות מ 100 שורות קוד, שאומנם עושות הרבה פחות אבל מבחינה פרקטית זה כל מה שאני צריך.
מסקנות ומחשבות קדימה
1. חלק גדול מהכיף בפרויקט צד הוא המשחק עם טכנולוגיה חדשה ופה היה לי הרבה מזה: סקאלה, גרמלין, neo4j, ג'נוס, מילונים, תרגומים ובוטים לטלגרם. אני מקווה שגם בפרויקט הבא שאכתוב אשבור את השיניים ואלמד כלים חדשים.
2. תקופה ארוכה חשבתי לסדר את הפרויקט ולפרסם אותו בקוד פתוח. איכשהו דווקא לזה לא הגעתי כי תמיד היה נראה יותר כיף לבנות עוד פיצ'ר. אולי זה עוד יקרה אבל אני חושב שבפרויקט צד הבא כדאי להתחיל מלפתוח עמוד גיטהאב מסודר ותיעוד ולבנות את זה כקוד פתוח נקי מההתחלה.
3. התחלתי את העבודה על הבוט לפני שנתיים או שלוש. מעניין מאוד לחשוב איך העולם השתנה וכמה הייתי צריך להתאמץ בשביל דברים שהיום הם טריוויאליים לגמרי.
👍2
טיפ LLM - ואם נריץ 100 פעמים?
שון הלן כתב פוסט מדהים על השימוש ב LLM כדי למצוא בעיית אבטחה בקוד. כל מילה שם שווה זהב ואני ממליץ לקרוא:
https://sean.heelan.io/2025/05/22/how-i-used-o3-to-find-cve-2025-37899-a-remote-zeroday-vulnerability-in-the-linux-kernels-smb-implementation/
אחד הטריקים המעניינים שלו היה להריץ את השאילתה 100 פעמים. הנה מה שהוא כותב (תרגום ועיבוד שלי):
1. בהרצת השאילתה 100 פעמים עם פרומפט יחסית קצר, כלומר באזור ה 3,000 שורות קוד, o3 מצא את בעיית האבטחה ב 8 מתוך 100 ריצות. ב 66 מהריצות o3 חשב שאין שום בעיה בקוד ובעוד 28 ריצות o3 זיהה בעיות שלא באמת היו בעיות. (הערת המתרגם - שמתי לב שהמספרים לא מסתדרים אבל משאיר אותם כמו בפוסט המקורי).
2. בהרצת השאילתה 100 פעמים עם פרומפט ארוך יותר, באזור ה 12 אלף שורות קוד, o3 מצא את בעיית האבטחה רק בריצה אחת מתוך 100, אבל באחת הריצות האחרות הוא מצא בעיית אבטחה אחרת שהחוקר לא הכיר.
שימו לב למספרים האלה אם אתם משתמשים ב AI למחקר או כדי לייצר קוד או בהקשר של מערכת אג'נטית. כן ריצה חוזרת של אותה שאילתה עולה כסף ומכניסה רעש למערכת, ואולי נצטרך לקחת את כל ה 100 תוצאות ולהעביר אותן לעוד LLM שיסכם את הכל, אבל זה סוג הטכניקות שאנחנו עדיין צריכים היום כדי להגיע לתוצאות טובות.
שון הלן כתב פוסט מדהים על השימוש ב LLM כדי למצוא בעיית אבטחה בקוד. כל מילה שם שווה זהב ואני ממליץ לקרוא:
https://sean.heelan.io/2025/05/22/how-i-used-o3-to-find-cve-2025-37899-a-remote-zeroday-vulnerability-in-the-linux-kernels-smb-implementation/
אחד הטריקים המעניינים שלו היה להריץ את השאילתה 100 פעמים. הנה מה שהוא כותב (תרגום ועיבוד שלי):
1. בהרצת השאילתה 100 פעמים עם פרומפט יחסית קצר, כלומר באזור ה 3,000 שורות קוד, o3 מצא את בעיית האבטחה ב 8 מתוך 100 ריצות. ב 66 מהריצות o3 חשב שאין שום בעיה בקוד ובעוד 28 ריצות o3 זיהה בעיות שלא באמת היו בעיות. (הערת המתרגם - שמתי לב שהמספרים לא מסתדרים אבל משאיר אותם כמו בפוסט המקורי).
2. בהרצת השאילתה 100 פעמים עם פרומפט ארוך יותר, באזור ה 12 אלף שורות קוד, o3 מצא את בעיית האבטחה רק בריצה אחת מתוך 100, אבל באחת הריצות האחרות הוא מצא בעיית אבטחה אחרת שהחוקר לא הכיר.
שימו לב למספרים האלה אם אתם משתמשים ב AI למחקר או כדי לייצר קוד או בהקשר של מערכת אג'נטית. כן ריצה חוזרת של אותה שאילתה עולה כסף ומכניסה רעש למערכת, ואולי נצטרך לקחת את כל ה 100 תוצאות ולהעביר אותן לעוד LLM שיסכם את הכל, אבל זה סוג הטכניקות שאנחנו עדיין צריכים היום כדי להגיע לתוצאות טובות.
Sean Heelan's Blog
How I used o3 to find CVE-2025-37899, a remote zeroday vulnerability in the Linux kernel’s SMB implementation
In this post I’ll show you how I found a zeroday vulnerability in the Linux kernel using OpenAI’s o3 model. I found the vulnerability with nothing more complicated than the o3 API ̵…
איך יראה חיפוש עבודה בהייטק ב 2026?
כמה מגמות שקורות כבר היום ודורשות תשומת לב:
1. סוכני AI מתאימים את קורות החיים שלנו אישית לכל משרה ושולחים את קורות החיים בצירוף Cover Letter אישי למנהלי הגיוס.
2. תוכנות AI שרצות על המחשב שלנו מאפשרות לענות "נכון" על כל שאלה בראיון הטכני שמתבצע בזום.
3. מראיינים משתמשים ב AI כדי לסנן קורות חיים ובוטים מבוססי AI מבצעים ראיונות בפועל (לאותם מועמדים שנעזרים ב AI כדי לענות על השאלות).
4. פרויקטי Take Home למועמדים מבוצעים על ידי AI או בצורת Vibe Coding מלא או עם הנחיה של המועמד. מאחר וממילא הפרויקטים האלה לא גדולים אין שום דרך להעריך את המועמד על בסיסם.
בנקודה הזאת אפשר לעצור ולשאול - "אולי זה בסדר?", אולי זה הגיוני לתת למועמד הזדמנות להראות את היכולות שלו תוך שימוש בכל ארגז הכלים המקצועי שהוא או היא מביאים לשולחן. אם אני מגייס למשרת פיתוח, וממילא בעבודה עצמה יהיה שימוש בכלי AI, אז למה לא לאפשר אותם בראיון? והתשובה כאן היא שהראיון הוא לא באמת סביבת "עבודה". אף אחד לא פותר שאלות LeetCode אחרי הקפה של הבוקר ביום עבודה רגיל, אנחנו משתמשים בהן בתור מייצג מתוך מחשבה שאנשים שיודעים לפתור שאלות כאלה יוכלו להתמודד גם עם האתגרים הגדולים יותר איתם צריך להתמודד בעבודה האמיתית. שימוש בכלי AI במסגרת קבלה לעבודה מרסק את הקשר הזה (וממילא רבים יטענו שהיה מקרי). היום כשאני מסתכל על פרויקט Take Home של מועמד אין לי דרך להסיק מהקוד הזה שום דבר לגבי התאמה או אי התאמה של המועמד. אותו דבר לגבי ראיון בזום או קריאה של קורות חיים.
אז מה כן עובד? אני לא יודע. אבל אלה כמה רעיונות שהייתי מנסה:
1. אם יש פרויקט קוד משמעותי שהבן אדם כתב או היה שותף בו הייתי שמח להעיף מבט על הקוד, ובמיוחד על היסטוריית הגיט כדי להבין איזה קוד המועמד או המועמדת שלי הכניסו למערכת.
2. אם אפשר לדבר עם הבן אדם פנים אל פנים זה יכול לעזור. וכן ה Bias פה מוכר אבל אני לא רואה איך אפשר לסמוך על כל מדיום אחר.
3. אם אפשר לתת "משימת ניסיון" על הפרויקט האמיתי זה יכול לעזור, כי שם אין בעיה שישתמשו ב AI.
ומה אתכם? איך אתם מסתכלים על אתגר הגיוס בשנים הקרובות? באיזה שיטות תשתמשו כדי להבין רמה מקצועית של הבן אדם שמולכם ולהחליט את מי לגייס?
כמה מגמות שקורות כבר היום ודורשות תשומת לב:
1. סוכני AI מתאימים את קורות החיים שלנו אישית לכל משרה ושולחים את קורות החיים בצירוף Cover Letter אישי למנהלי הגיוס.
2. תוכנות AI שרצות על המחשב שלנו מאפשרות לענות "נכון" על כל שאלה בראיון הטכני שמתבצע בזום.
3. מראיינים משתמשים ב AI כדי לסנן קורות חיים ובוטים מבוססי AI מבצעים ראיונות בפועל (לאותם מועמדים שנעזרים ב AI כדי לענות על השאלות).
4. פרויקטי Take Home למועמדים מבוצעים על ידי AI או בצורת Vibe Coding מלא או עם הנחיה של המועמד. מאחר וממילא הפרויקטים האלה לא גדולים אין שום דרך להעריך את המועמד על בסיסם.
בנקודה הזאת אפשר לעצור ולשאול - "אולי זה בסדר?", אולי זה הגיוני לתת למועמד הזדמנות להראות את היכולות שלו תוך שימוש בכל ארגז הכלים המקצועי שהוא או היא מביאים לשולחן. אם אני מגייס למשרת פיתוח, וממילא בעבודה עצמה יהיה שימוש בכלי AI, אז למה לא לאפשר אותם בראיון? והתשובה כאן היא שהראיון הוא לא באמת סביבת "עבודה". אף אחד לא פותר שאלות LeetCode אחרי הקפה של הבוקר ביום עבודה רגיל, אנחנו משתמשים בהן בתור מייצג מתוך מחשבה שאנשים שיודעים לפתור שאלות כאלה יוכלו להתמודד גם עם האתגרים הגדולים יותר איתם צריך להתמודד בעבודה האמיתית. שימוש בכלי AI במסגרת קבלה לעבודה מרסק את הקשר הזה (וממילא רבים יטענו שהיה מקרי). היום כשאני מסתכל על פרויקט Take Home של מועמד אין לי דרך להסיק מהקוד הזה שום דבר לגבי התאמה או אי התאמה של המועמד. אותו דבר לגבי ראיון בזום או קריאה של קורות חיים.
אז מה כן עובד? אני לא יודע. אבל אלה כמה רעיונות שהייתי מנסה:
1. אם יש פרויקט קוד משמעותי שהבן אדם כתב או היה שותף בו הייתי שמח להעיף מבט על הקוד, ובמיוחד על היסטוריית הגיט כדי להבין איזה קוד המועמד או המועמדת שלי הכניסו למערכת.
2. אם אפשר לדבר עם הבן אדם פנים אל פנים זה יכול לעזור. וכן ה Bias פה מוכר אבל אני לא רואה איך אפשר לסמוך על כל מדיום אחר.
3. אם אפשר לתת "משימת ניסיון" על הפרויקט האמיתי זה יכול לעזור, כי שם אין בעיה שישתמשו ב AI.
ומה אתכם? איך אתם מסתכלים על אתגר הגיוס בשנים הקרובות? באיזה שיטות תשתמשו כדי להבין רמה מקצועית של הבן אדם שמולכם ולהחליט את מי לגייס?
צהריים טובים כולם אני מזכיר ביום חמישי בבוקר אעביר וובינר בחינם ואראה לכם איך לקבל קוד טוב מ AI (וגם מה גורם לפרומפטים שלכם לייצר קוד בינוני או אפילו גרוע)
אדביק פה את הלינק בחמישי בבוקר אבל כדאי כבר לשריין ביומן
אדביק פה את הלינק בחמישי בבוקר אבל כדאי כבר לשריין ביומן
🔥1
הבעיה עם default scope ב Rails
הסיפור של היום הוא על Rails כי ריילס היא כמו פלסטלינה ומאפשרת לעצב את הפרויקט איך שרוצים, וכי קוד שאילתות בריילס יכול להיות מפוזר בין הרבה קבצים. אבל הסיפור הוא גם על AI ואיך כלי פיתוח מבוססי AI יכולים לעזור גם למפתחים עצלנים לכתוב קוד נכון יותר. וזאת גם הזדמנות טובה להזכיר שמחר בבוקר אני מעביר וובינר על עבודה עם כלי AI בפיתוח שמיועד למתחילים. אשמח לראות גם אתכם שם (הלינק יעלה לקבוצת טלגרם בחמישי בבוקר או שתשלחו לי מייל ואשלח לכם). עכשיו נחזור לריילס.
ב Rails בשביל לשלוף מידע מבסיס הנתונים אני משתמש בשכבת ORM שנקראת Active Record. לדוגמה ניקח שתי טבלאות, אחת של מוצרים ואחת של קטגוריות, ובטבלת המוצרים יש עמודת משקל. בדף הקטגוריה עלינו להציג את המוצרים מסודרים לפי משקל מהקטן לגדול.
אפשר לכתוב את הגדרת ה ORM בריילס באופן הבא:
ואז בקוד של העמוד נוכל להסתכל על רשימת המוצרים באופן הבא:
והכל עובד ומוצג לפי הסדר הנכון. אז איפה פה הבעיה? עכשיו אם במקום אחר בקוד אני רוצה להציג את המוצרים בסדר הפוך אני כבר לא יכול סתם לשלוף אותם מבסיס הנתונים עם:
אלא צריך לבטל את ה order של הסקופ הדיפולטי קודם עם:
בעצם ריילס אומר לנו - תבחרו, או שתקבלו את ה order בחינם בכל השאילתות ואז תצטרכו לעבוד קשה כשתרצו משהו עם order אחר, או שתצטרכו לכתוב עוד מילה של order בכל שאילתה שצריכה את המוצרים לפי סדר.
הבעיה כאן היא שבמערכת קיימת אפילו לא גדולה הרבה יותר קל להגדיר default scope ולקבל את ה order הנכון בכל המערכת במכה אחת מאשר להגדיר order על כל שאילתה, אבל הגדרה כזאת תהיה מבלבלת בעוד חודש (או כמה חודשים) כשנצטרך להוסיף שאילתה חדשה ולא נזכור את מיון ברירת המחדל.
ופה נכנס לתמונה החבר שלי קלוד: כי ברגע שאנחנו עובדים עם כלי פיתוח מבוססי AI ויודעים לנסח את האתגר והארכיטקטורה שאנחנו רוצים, לעדכן order על כל השאילתות בפרויקט נהיה קל כמו להוסיף default scope - ובצורה כזאת יש יותר מוטיבציה להגיע לקוד הנכון.
הסיפור של היום הוא על Rails כי ריילס היא כמו פלסטלינה ומאפשרת לעצב את הפרויקט איך שרוצים, וכי קוד שאילתות בריילס יכול להיות מפוזר בין הרבה קבצים. אבל הסיפור הוא גם על AI ואיך כלי פיתוח מבוססי AI יכולים לעזור גם למפתחים עצלנים לכתוב קוד נכון יותר. וזאת גם הזדמנות טובה להזכיר שמחר בבוקר אני מעביר וובינר על עבודה עם כלי AI בפיתוח שמיועד למתחילים. אשמח לראות גם אתכם שם (הלינק יעלה לקבוצת טלגרם בחמישי בבוקר או שתשלחו לי מייל ואשלח לכם). עכשיו נחזור לריילס.
ב Rails בשביל לשלוף מידע מבסיס הנתונים אני משתמש בשכבת ORM שנקראת Active Record. לדוגמה ניקח שתי טבלאות, אחת של מוצרים ואחת של קטגוריות, ובטבלת המוצרים יש עמודת משקל. בדף הקטגוריה עלינו להציג את המוצרים מסודרים לפי משקל מהקטן לגדול.
אפשר לכתוב את הגדרת ה ORM בריילס באופן הבא:
class Category < ApplicationRecord
has_many :products
end
class Product < ApplicationRecord
belongs_to :category
# Default scope to always order products by weight
default_scope { order(:weight) }
end
ואז בקוד של העמוד נוכל להסתכל על רשימת המוצרים באופן הבא:
category = Category.first
category.products
והכל עובד ומוצג לפי הסדר הנכון. אז איפה פה הבעיה? עכשיו אם במקום אחר בקוד אני רוצה להציג את המוצרים בסדר הפוך אני כבר לא יכול סתם לשלוף אותם מבסיס הנתונים עם:
category.products.order(weight: :desc)
אלא צריך לבטל את ה order של הסקופ הדיפולטי קודם עם:
category.products.unscope(:order).order(weight: :desc)
בעצם ריילס אומר לנו - תבחרו, או שתקבלו את ה order בחינם בכל השאילתות ואז תצטרכו לעבוד קשה כשתרצו משהו עם order אחר, או שתצטרכו לכתוב עוד מילה של order בכל שאילתה שצריכה את המוצרים לפי סדר.
הבעיה כאן היא שבמערכת קיימת אפילו לא גדולה הרבה יותר קל להגדיר default scope ולקבל את ה order הנכון בכל המערכת במכה אחת מאשר להגדיר order על כל שאילתה, אבל הגדרה כזאת תהיה מבלבלת בעוד חודש (או כמה חודשים) כשנצטרך להוסיף שאילתה חדשה ולא נזכור את מיון ברירת המחדל.
ופה נכנס לתמונה החבר שלי קלוד: כי ברגע שאנחנו עובדים עם כלי פיתוח מבוססי AI ויודעים לנסח את האתגר והארכיטקטורה שאנחנו רוצים, לעדכן order על כל השאילתות בפרויקט נהיה קל כמו להוסיף default scope - ובצורה כזאת יש יותר מוטיבציה להגיע לקוד הנכון.
👍1
טיפ npm - תמיד לבדוק מספרי חבילות בגיטהאב
כן אני יודע זה לא בדיוק טיפ אם אני רק מוסיף לכם עבודה, אבל תקשיבו רגע כי זה חשוב. צ'ארלי אריקסון פרסם בתחילת החודש את הממצא הזה:
https://www.aikido.dev/blog/catching-a-rat-remote-access-trojian-rand-user-agent-supply-chain-compromise
בקצרה מישהו מצא חבילת npm בשם rand-user-agent שכבר לא נתמכת אבל טוקן העדכון שלה היה פרוץ, לקח את הטוקן והתחיל לפרסם גירסאות "חדשות" של הספריה שכללו סוס טרויאני. מי שמריץ את אותן גירסאות חדשות לצורך Web Scraping יגרום למחשב שלו עצמו להפוך לזומבי עבור מרכז השליטה החללי של אותו מפרסם גירסאות מסתורי.
בין הסימנים החשודים לגבי החבילה:
1. היא מסומנת בתור "Deprecated"
2. לפי התיעוד הגירסה האחרונה אמורה להיות 2.0.82 אבל ב npm היו גירסאות חדשות יותר.
3. הקישור לגיטהאב הוביל לדף ריק.
אני יודע שאתם כבר מסתכלים על סימון Deprecated ולא הייתם לוקחים חבילה שכבר לא נתמכת, אבל מסתבר שמספר הגירסה הוא גם סימן אזהרה קל: כנסו לגיטהאב של הפרויקט (תמיד יש לינק מ npm) ותראו מה הגירסה הכי עדכנית ואם זה תואם למה שאתם רואים ב npm. מיטיבי לכת יכולים גם להיכנס לרשימת הקומיטים ולראות אם יש תורם קוד חדש בגירסאות האחרונות, ונינג'ות AI יכולים כבר לכתוב סוכן AI שיעשה את זה בשבילכם לכל החבילות ב package-lock.json.
כן אני יודע זה לא בדיוק טיפ אם אני רק מוסיף לכם עבודה, אבל תקשיבו רגע כי זה חשוב. צ'ארלי אריקסון פרסם בתחילת החודש את הממצא הזה:
https://www.aikido.dev/blog/catching-a-rat-remote-access-trojian-rand-user-agent-supply-chain-compromise
בקצרה מישהו מצא חבילת npm בשם rand-user-agent שכבר לא נתמכת אבל טוקן העדכון שלה היה פרוץ, לקח את הטוקן והתחיל לפרסם גירסאות "חדשות" של הספריה שכללו סוס טרויאני. מי שמריץ את אותן גירסאות חדשות לצורך Web Scraping יגרום למחשב שלו עצמו להפוך לזומבי עבור מרכז השליטה החללי של אותו מפרסם גירסאות מסתורי.
בין הסימנים החשודים לגבי החבילה:
1. היא מסומנת בתור "Deprecated"
2. לפי התיעוד הגירסה האחרונה אמורה להיות 2.0.82 אבל ב npm היו גירסאות חדשות יותר.
3. הקישור לגיטהאב הוביל לדף ריק.
אני יודע שאתם כבר מסתכלים על סימון Deprecated ולא הייתם לוקחים חבילה שכבר לא נתמכת, אבל מסתבר שמספר הגירסה הוא גם סימן אזהרה קל: כנסו לגיטהאב של הפרויקט (תמיד יש לינק מ npm) ותראו מה הגירסה הכי עדכנית ואם זה תואם למה שאתם רואים ב npm. מיטיבי לכת יכולים גם להיכנס לרשימת הקומיטים ולראות אם יש תורם קוד חדש בגירסאות האחרונות, ונינג'ות AI יכולים כבר לכתוב סוכן AI שיעשה את זה בשבילכם לכל החבילות ב package-lock.json.
www.aikido.dev
RATatouille: A Malicious Recipe Hidden in rand-user-agent (Supply Chain Compromise)
🔥2👍1