25 августа 2026 в русскоязычных ИИ-лентах снова всплыл слоган LLMScience 1044: «RL с нуля на C». Рядом в поиске стоят «reinforcement learning c», «reinforce на чистом C» и старые гайды по Atari. Живой репозиторий 2026 года это не Gym, не Stable-Baselines и не конспект Sutton & Barto. Это harshbhatt7585/cRL Харша Бхатта: autograd, политика, rollout и шаг по весам в стандартном C, плюс двухчасовое видео на канале freeCodeCamp от 19 августа 2026. Ниже сверка с кодом, не пересказ змейки и не дамп курса.

Зачем вайб-кодеру RL на C, если уже есть агент в редакторе

Когда вы просите модель «добавь RL», она почти всегда тянет Python, Gymnasium, тензор и готовый PPO. Цикл прячется за env.step и loss.backward(). Вы видите кривую награды и не видите, куда делся градиент. Вайб-кодинг здесь не «собери сайт за вечер». Это умение читать петлю, которую агент вам нагенерил, и понять, где она врёт. Каркас самого вайб-цикла мы разбирали отдельно: как собрать сайт с нуля через AI.

Чистый C снимает три слоя сразу. Нет интерпретатора. Нет фреймворка. Нет среды, которая сама считает столкновение и награду за кадром. Остаётся то, из чего собран любой современный RL, включая GRPO у reasoning-моделей: состояние, действие, награда, траектория, обновление политики. Если этот контур не держится в голове, разговоры про PPO и RLHF остаются слоганами.

Какой репозиторий настоящий. Сверка 25 августа 2026

Репозиторий на месте. Автор Harsh Bhatt, аккаунт harshbhatt7585. Создан 7 июля 2026, последний пуш 17 июля 2026. На странице GitHub в день сверки 34 звезды и 7 форков. Язык один: C. Лицензии в карточке нет. Это не зеркало PyTorch, не обёртка над BLAS и не порт Atari. Состав, который мы открыли:

Сборка из README: clang env.c -o env -lm, затем ./env. Makefile нет. env.c подключает model.c, тот подключает остальные .c как один translation unit. Внешних библиотек нет, только libc и libm. Видео курса: Code a Reinforcement Learning Library in C from Scratch на freeCodeCamp, около двух часов двадцати минут. Анонс: Building a Reinforcement Learning Framework from Scratch in Pure C. Код в ролике и код в репозитории это один проект. Не смотрите ролик как силлабус. Смотрите файл.

Рядом в поиске часто всплывает antirez/ttt-rl: крестики-нолики, меньше 400 строк C, март 2025. Это другой атом. Там нет вычислительного графа, есть ручной backward и награда за партию. Полезный сосед, не «тот самый репозиторий 2026». Двоюродный брат по духу «с нуля на C», уже про GPT, не про политику: MicroGPT-C, GPT Карпаты на чистом C.

Петля, которую вы должны увидеть, а не змейка

Слово Snake в README сбивает. В SnakeENV нет хвоста и нет роста. Агент это одна клетка на квадратной сетке. create_env(36) даёт поле 6 на 6. Еда это вторая клетка. Стена это выход за край. Награда в get_reward: плюс 20 за еду, минус 10 за край. Эпизод рвётся на game_over или на лимите 100 шагов. Это не гайд «как научить змейку». Это крошечная среда, чтобы петля уместилась в один файл.

Цикл в train() читается сверху вниз. Сначала 64 rollout по 100 шагов. На каждом шаге: собрать вектор состояния, forward_pass по графу политики, сэмплировать действие из softmax, шаг среды, записать в траекторию. Потом с конца эпизода считают reward-to-go с gamma = 0.99. По всему rollout считают среднее и стандартное отклонение возвратов. Преимущество действия: (G - mean) / (std + 1e-8), пишут только в слот выбранного действия. Дальше forward по графу лосса, backward_pass, в конце SGD: веса минус lr / N на накопленный градиент, lr = 0.05. Эпох 2000. Это и есть петля. Игра здесь только датчик награды.

  1. Сброс среды: агент в центре, еда в случайной клетке.
  2. Состояние в вектор: one-hot клетки агента, one-hot еды, направление взгляда.
  3. Политика выдаёт 5 чисел, softmax, сэмпл действия.
  4. Среда двигает клетку, считает награду, ставит done.
  5. После пачки эпизодов: возвраты, базовая линия, REINFORCE, шаг по весам.

Пять действий в enum: влево, вправо, вверх, вниз и NONE. Если модель выбрала NONE, среда идёт дальше в текущем направлении. Вектор входа 76 чисел: 36 плюс 36 плюс четыре слота на направление. Выход политики 5 логитов. Это не баг в статье. Это то, что лежит в create_actor_model и в build_state_vector. Если будете форкать, сначала сверьте размер входа с максимальным индексом pov.

Autograd в C: граф, а не магия .backward()

В Python autograd это воздух. Здесь узел это структура Var: значение, градиент, флаги, до двух входов, таблица операций. Типы: add, sub, matmul, ReLU, softmax, reinforce_loss. Параметры помечены VAR_FLAG_PARAMETER | VAR_FLAG_REQUIRES_GRAD. Вход и вектор преимущества градиента не копят как веса. build_graph собирает порядок узлов от выхода. Отдельный граф до softmax это инференс политики. Отдельный граф до лосса это обучение. Forward идёт по списку. Backward ставит градиент выхода в 1 и идёт с конца. Веса чистят один раз на эпоху, затем копят градиент по всем шагам всех траекторий. Это и есть «replay buffer» из README: буфер на 1024 траектории, в обучении берут текущие 64. Off-policy DQN здесь нет. Это on-policy REINFORCE с нормализацией возвратов по пачке.

Сеть крошечная. Два скрытых слоя по 128, ReLU, выход 5, softmax. Инициализация в духе Xavier: sqrt(6 / (fan_in + fan_out)). Оптимизатор не Adam. Это вычитание градиента. Автор в ролике сам говорит: без value-головы дисперсия высокая, учиться будет долго и шумно. В логе эпохи печатают средний возврат первого шага, сколько еды съели за пачку, число сэмплов и return_std. Если std огромный, а еды ноль, петля жива, политика ещё нет.

Как собрать и что вы увидите

Нужны clang или gcc, libm, гигабайт свободной оперативки под арену. GPU не нужен. Из корня репозитория: clang env.c -o env -lm && ./env. На экране строки вида Epoch 12 | Average return: -3.140 | Foods: 0 | Samples: 1842 | Return std: 8.221. Картинка в README показывает, что кривая со временем уходит из минуса. Это не бенчмарк и не таблица ток/с. Здесь нет очереди запросов и нет prefill. Если вы привыкли мерить живой инференс LLM, это другой контур: time to first token и запуск инференса.

Практические ловушки из кода, не из рекламы курса.

Чего в этом репозитории нет. Чтобы не ждать Atari и ChatGPT

cRL не учит играть в Breakout. Нет пикселей, нет CNN, нет frame-skip. Нет PPO, clip, GAE как в статье Schulman. В ролике мелькает actor-critic как заголовок главы, в model.c value-головы нет: один актор и REINFORCE. Нет Gym-интерфейса, который вы потом подключите к своему боту. Нет RLHF, нет reward-модели на предпочтениях, нет GRPO по группам ответов LLM.

Путаница из одной склейки запросов. Человек клонирует cRL и ждёт, что через час получит агента уровня AlphaGo. Либо просит Cursor «добавить PPO как в курсе» и получает импорт stable_baselines3 поверх этого C. Либо открывает ttt-rl Антиреза и думает, что freeCodeCamp переехал в 400 строк. Три разных атома:

Если вам нужен посттренинг языковой модели, это уже другая полка: группа ответов, проверяемая награда, KL к референсу. cRL туда не масштабируется сменой сетки на токены. Он нужен раньше: чтобы слово «траектория» перестало быть слайдом.

Как читать файл, если вы пишете с LLM

Не смотрите двухчасовое видео от нуля, если уже читаете C. Откройте четыре точки и пройдите их с агентом в редакторе как по карте, не как по конспекту.

  1. get_reward и take_action. Это контракт среды. Пока он не ясен, сеть ни при чём.
  2. build_state_vector. Что модель вообще видит. Если вектор врёт, политика учит шум.
  3. create_actor_model и var_reinforce_loss. Где политика, где лосс, где преимущество.
  4. Два вложенных цикла в train: сбор опыта, затем проход по той же пачке с backward.

Просите модель не «объясни RL», а «покажи, где в этом файле считается G и куда оно попадает в градиент». Если ответ ссылается на Gym, вы не в том репозитории. Если ответ пересказывает Atari, вы не в той статье. Полезный тест на понимание: замените награду за еду на 1 и за край на 0, пересоберите, посмотрите, умерла ли кривая. Это проверка петли, не исследование игр.

Когда петля уже держится, C можно закрыть. Дальше вы снова имеете право на Python. Разница в том, что loss.backward() перестанет быть заклинанием. Вы будете знать, какой граф он прячет.

Коротко

cRL на 25 августа 2026 это живой учебный RL на чистом C: autograd, REINFORCE, арена, поле 6 на 6, один бинарь, без лицензии в карточке. Репозиторий harshbhatt7585/cRL, автор Harsh Bhatt, создан в июле 2026, на странице 34 звезды. Видео freeCodeCamp от 19 августа 2026 ходит вокруг этого кода, не вокруг ALE и не вокруг университетского силлабуса. Запрос «RL с нуля на C» закрывается этим деревом файлов. «Научить змейку» и «пройти Atari» здесь ложные цели. Цель одна: увидеть петлю агента так, чтобы следующий раз, когда редактор нагенерит PPO из десяти импортов, вы знали, чего в этой куче на самом деле нет.