שינויים קטנים שמצטברים

29/08/2025

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

class UserSelectionsController < ApplicationController
  before_action :require_login
  before_action :find_chat_and_message

  def create
    # Handle initial selection creation (if needed in the future)
    # For now, redirect to chat
    redirect_to chat_path(@chat)
  end

  def update
    # Use the service to handle the selection
    service = UserSelectionService.new(
      chat: @chat,
      message: @message,
      user: current_user
    )

    if params[:text_input].present?
      service.handle_selection(text_input: params[:text_input].strip)
    elsif params[:option_id].present?
      service.handle_selection(option_id: params[:option_id])
    else
      redirect_to chat_path(@chat), alert: "Invalid selection"
      return
    end

    redirect_to chat_path(@chat)
  rescue => e
    Rails.logger.error "UserSelection error: #{e.message}"
    Rails.logger.error e.backtrace.join("\n")
    redirect_to chat_path(@chat), alert: "Something went wrong"
  end

  private

  def find_chat_and_message
    @chat = current_user.chats.find(params[:chat_id])
    @message = @chat.messages.find(params[:message_id])
  rescue ActiveRecord::RecordNotFound
    redirect_to new_chat_path, alert: t('chat.not_found')
  end
end

לא צריך להכיר רובי בשביל לראות את הבעיות:

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

  2. הפונקציה השניה update מסתיימת בפקודת rescue שכותבת ללוג את השגיאה ומחזירה למשתמש הודעה Something went wrong. פונקציית find_chat_and_messag תופסת שגיאה ומחזירה למשתמש הודעה מתוך קובץ ההודעות המתורגמות. בן אדם היה בוחר דרך אחת ומשתמש בה בשתי הפונקציות. כש AI כותב קוד הוא לא יודע מה הוא כתב קודם.

  3. הפונקציה require_login מוודאת שיש משתמש נוכחי מחובר. הפונקציה find_chat_and_message משתמשת במשתמש הנוכחי כדי להגיע לשיחה. אין טעם לקרוא לשתיהן כי השנייה כבר כוללת גם את הלוגיקה של הראשונה. AI לא יכול לראות את זה.

  4. הפונקציה update כוללת שני מנגנונים לטיפול בשגיאות, יש שם if else שמטפל במצב בו לא עבר פרמטר שהפונקציה ציפתה לקבל וגם rescue שמטפל בבעיות אחרות. בן אדם היה מוודא שקוד הטיפול בשגיאה, כלומר הקריאה ל redirect_to תופיע רק פעם אחת.

  5. בפונקציה update קוד הטיפול בשגיאות מטפל בכל Exception. ב find_chat_and_message יש טיפול רק ב ActiveRecord::RecordNotFound.

  6. הטיפול בשגיאות הוא תמיד מקומי. כש AI כותב את קוד הטיפול בשגיאות הוא לא יכול לשים לב שאפשר לכתוב קוד טיפול בשגיאות במקום יותר "גבוה" בשרשרת הקריאות כדי לכסות יותר מקרים.

  7. הפונקציה update כוללת את הבלוק הזה:

    if params[:text_input].present?
      service.handle_selection(text_input: params[:text_input].strip)
    elsif params[:option_id].present?
      service.handle_selection(option_id: params[:option_id])
    ...

הפונקציה handle_selection שמופעלת מתוך הבלוק כוללת את הבלוק הזה:

 def handle_selection(option_id: nil, text_input: nil)
    if text_input.present?
      handle_text_selection(text_input)
    elsif option_id.present?
      handle_option_selection(option_id)
    else
      raise ArgumentError, "Either option_id or text_input must be provided"
    end
  end

קיבלנו את אותה בדיקה בשני מקומות עם שני מנגנוני זריקת שגיאה שונים. בן אדם היה כותב ב update:

service.handle_selection(params)

ונותן ל if הפנימי לבדוק מה עבר, או מפצל את הקוד ב service לשתי פונקציות ומוותר על ה if שם. AI לא יודע מה הוא כבר כתב אז הוא משכפל.

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

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

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