LLM 86 просмотров

Сравнение Gemini 3 и Claude Opus 4.5

Наступил 2026 год, а значит необходимо обновить мой код, который вычисляет является ли текущий день праздничным в Казахстане или нет. У нас в стране есть сайт электронного правительства, где ежегодно публикуется календарь праздников - Праздничные и выходные дни в Республике Казахстан. Уже второй год подряд я использую Agentic Coding для написания необходимой мне функции на Python. И второй год подряд лучше всех справляется LLM модель от Google - Gemini 3.

В начале прошлого года у меня появилась необходимость учитывать является ли текущий день праздничным или нет, и тогда мне в голову пришла идея скормить изображение календаря LLM моделям и на базе этой картинке получить готовую Python-функцию. На тот момент рабочий вариант функции мне удалось получить только от Gemini, причем совсем с незначительными правками с моей стороны. Модели от Anthropic выдавали нерабочий код, была даже ситуация, когда Sonnet выплюнула мне огромный словарь, где ключ это конкретная дата, а значение типа bool определяет выходной это или нет. С тех пор прошел почти год, мир увидел самую продвинутую модель для кодинга от Anthropic Opus 4.5. В связи с наступлением нового года снова возникла идея скормить изображение и получить на выходе готовый код.

Вот промт, который я использую для двух моделей

Based on the provided image calendar for 2026 year, write a python function which returns whether the particular day is a day off or not. Working day cells have light background, day offs are red/orange filled cells.

Простой промт, описывающий что необходимо сделать с небольшими подсказками, чтобы модельке было легче понять где рабочий день, а где выходной.

Результат

Claude Sonnet 4.5

def is_day_off(day: int, month: int, year: int = 2026) -> bool:
    """
    Check if a particular day is a day off in Kazakhstan for 2026.
    
    Args:
        day: Day of the month (1-31)
        month: Month (1-12)
        year: Year (default: 2026)
    
    Returns:
        True if the day is a day off (weekend or public holiday), False otherwise
    """
    
    if year != 2026:
        raise ValueError("This function only works for year 2026")
    
    # Define all days off for each month in 2026
    # Based on the calendar: red/orange cells are days off
    days_off_by_month = {
        1: [1, 2, 3, 4, 10, 11, 17, 18, 24, 25, 31],  # January
        2: [1, 7, 8, 14, 15, 21, 22, 28],  # February
        3: [1, 7, 8, 14, 15, 21, 22, 23, 24, 28, 29],  # March
        4: [4, 5, 11, 12, 18, 19, 25, 26],  # April
        5: [1, 2, 3, 7, 9, 10, 11, 16, 17, 23, 24, 27, 30, 31],  # May
        6: [6, 7, 13, 14, 20, 21, 27, 28],  # June
        7: [4, 5, 6, 11, 12, 18, 19, 25, 26],  # July
        8: [1, 2, 8, 9, 15, 16, 22, 23, 29, 30, 31],  # August
        9: [5, 6, 12, 13, 19, 20, 26, 27],  # September
        10: [3, 4, 10, 11, 17, 18, 24, 25, 26, 31],  # October
        11: [1, 7, 8, 14, 15, 21, 22, 28, 29],  # November
        12: [5, 6, 12, 13, 16, 19, 20, 26, 27],  # December
    }
    
    # Validate input
    if month < 1 or month > 12:
        raise ValueError(f"Invalid month: {month}. Must be between 1 and 12")
    
    if day < 1 or day > 31:
        raise ValueError(f"Invalid day: {day}. Must be between 1 and 31")
    
    # Check if the day exists in the given month
    try:
        date(year, month, day)
    except ValueError:
        raise ValueError(f"Invalid date: {year}-{month:02d}-{day:02d}")
    
    return day in days_off_by_month.get(month, [])

Claude Opus 4.5

from datetime import date, timedelta
from typing import Union


def is_day_off(check_date: Union[date, str]) -> bool:
    """
    Check if a given date is a day off in Kazakhstan for 2026.
    
    Args:
        check_date: Either a date object or a string in 'YYYY-MM-DD' format
        
    Returns:
        True if the date is a day off, False if it's a working day
        
    Raises:
        ValueError: If the date is not in 2026 or invalid format
    """
    if isinstance(check_date, str):
        check_date = date.fromisoformat(check_date)
    
    if check_date.year != 2026:
        raise ValueError("This calendar is only valid for 2026")
    
    # Set of all days off in 2026 (month, day)
    # Extracted from the Kazakhstan 2026 holiday calendar
    
    days_off = {
        # January - New Year holidays
        (1, 1), (1, 2), (1, 3), (1, 4),  # Thu-Sun (New Year)
        (1, 7),  # Wed - Orthodox Christmas
        (1, 10), (1, 11),  # Sat-Sun
        (1, 17), (1, 18),  # Sat-Sun
        (1, 24), (1, 25),  # Sat-Sun
        (1, 31),  # Sat
        
        # February
        (2, 1),  # Sun
        (2, 7), (2, 8),  # Sat-Sun
        (2, 14), (2, 15),  # Sat-Sun
        (2, 21), (2, 22),  # Sat-Sun
        (2, 28),  # Sat
        
        # March
        (3, 1),  # Sun
        (3, 7), (3, 8),  # Sat-Sun (March 8 - International Women's Day)
        (3, 14), (3, 15),  # Sat-Sun
        (3, 21), (3, 22),  # Sat-Sun (March 21-23 - Nauryz)
        (3, 23),  # Mon - Nauryz holiday
        (3, 28), (3, 29),  # Sat-Sun
        
        # April
        (4, 4), (4, 5),  # Sat-Sun
        (4, 11), (4, 12),  # Sat-Sun
        (4, 18), (4, 19),  # Sat-Sun
        (4, 25), (4, 26),  # Sat-Sun
        
        # May
        (5, 1),  # Fri - Kazakhstan People's Unity Day
        (5, 2), (5, 3),  # Sat-Sun
        (5, 7),  # Thu - Defender of the Fatherland Day
        (5, 9), (5, 10),  # Sat-Sun (May 9 - Victory Day)
        (5, 16), (5, 17),  # Sat-Sun
        (5, 23), (5, 24),  # Sat-Sun
        (5, 27),  # Wed - Eid al-Fitr (Oraza Ait) - variable Islamic holiday
        (5, 30), (5, 31),  # Sat-Sun
        
        # June
        (6, 6), (6, 7),  # Sat-Sun
        (6, 13), (6, 14),  # Sat-Sun
        (6, 20), (6, 21),  # Sat-Sun
        (6, 27), (6, 28),  # Sat-Sun
        
        # July
        (7, 4), (7, 5),  # Sat-Sun
        (7, 6),  # Mon - Capital City Day
        (7, 11), (7, 12),  # Sat-Sun
        (7, 18), (7, 19),  # Sat-Sun
        (7, 25), (7, 26),  # Sat-Sun
        
        # August
        (8, 1), (8, 2),  # Sat-Sun
        (8, 3),  # Mon - Eid al-Adha (Kurban Ait) - variable Islamic holiday
        (8, 8), (8, 9),  # Sat-Sun
        (8, 15), (8, 16),  # Sat-Sun
        (8, 22), (8, 23),  # Sat-Sun
        (8, 29), (8, 30),  # Sat-Sun (Aug 30 - Constitution Day)
        
        # September
        (9, 5), (9, 6),  # Sat-Sun
        (9, 12), (9, 13),  # Sat-Sun
        (9, 19), (9, 20),  # Sat-Sun
        (9, 26), (9, 27),  # Sat-Sun
        
        # October
        (10, 3), (10, 4),  # Sat-Sun
        (10, 10), (10, 11),  # Sat-Sun
        (10, 17), (10, 18),  # Sat-Sun
        (10, 24), (10, 25),  # Sat-Sun (Oct 25 - Republic Day)
        (10, 31),  # Sat
        
        # November
        (11, 1),  # Sun
        (11, 7), (11, 8),  # Sat-Sun
        (11, 14), (11, 15),  # Sat-Sun
        (11, 21), (11, 22),  # Sat-Sun
        (11, 28), (11, 29),  # Sat-Sun
        
        # December
        (12, 5), (12, 6),  # Sat-Sun
        (12, 12), (12, 13),  # Sat-Sun
        (12, 16),  # Wed - Independence Day
        (12, 19), (12, 20),  # Sat-Sun
        (12, 26), (12, 27),  # Sat-Sun
    }
    
    return (check_date.month, check_date.day) in days_off

Радует, что обе модели выдали рабочий код в отличии от прошлогоднего результата, где у меня не получилось с первого раза добиться желаемого. Но обе функции повторяют один и тот же паттерн - создают массивы выходных дней из-за чего код получается более громоздким. Что же на это скажет LLM от Google?

Gemini 3

from datetime import date

def is_dayoff_kazakhstan_2026(check_date: date):
    """
    Returns True if the date is a day-off in Kazakhstan 2026,
    based on the provided visual calendar.
    """
    if check_date.year != 2026:
        return "This function only supports the year 2026."

    # 1. Check for weekends (Saturday = 5, Sunday = 6)
    if check_date.weekday() >= 5:
        return True

    # 2. List of specific holidays and transferred rest days (Red/Orange cells)
    # Format: (Month, Day)
    holidays_2026 = {
        (1, 1), (1, 2), (1, 7),           # January
        (3, 8), (3, 9), (3, 21), (3, 22), 
        (3, 23), (3, 24), (3, 25),        # March (Nauryz)
        (5, 1), (5, 7), (5, 9), (5, 11),  # May
        (7, 6),                           # July
        (8, 30), (8, 31),                 # August
        (25, 10), (26, 10),               # October
        (12, 16)                          # December
    }

    if (check_date.month, check_date.day) in holidays_2026:
        return True

    return False

Как по мне у Gemini 3 получилось сгенерировать лаконичный и понятный код без лишних данных. Модель показала себя как "думающая" в отличии от Sonnet 4.5 и Opus 4.5. Мне нравится, что код не дублирует выходные дни (субботу и воскресенье), а проверяет их через условие:

if check_date.weekday() >= 5:
        return True

Вывод

В этом ни на что не претендующем тесте более выигрышно явно смотрится Gemini 3. Думаю причина в том, что у Gemini более продвинутые способности по распознаванию изображений чем у моделей Anthropic. Код от Opus и Sonnet показался мне более многословным и менее читабельным, но прогресс в любом случае на лицо. По итогу я взял в продакшен решение от Gemini как самое оптимальное решение как с точки зрения читабельности так и производительности.

Яндекс.Метрика