Почему мы классифицируем движение руки, а не картинки со светофорами — и как встроить это в форму двумя строкамиКартиночные капчи в 2026-м решаются моделями компьютерного зрения за миллисекунды, а каждый ваш клик по «выберите автобусы» бесплатно размечает чужой датасет. Плюс две свежие проблемы: Google в начале 2025 срезал бесплатный лимит reCAPTCHA с 1 000 000 до 10 000 проверок в месяц, а с апреля 2026 ужесточил модель ответственности за данные по GDPR. Из России reCAPTCHA к тому же нестабильна.Общая проблема для сети — как доказать, что ты человек, не сдавая паспорт, лицо и номер телефона. Мы предлагаем: drop-in капчу, которую посетитель не кликает, а рисует. В описании — архитектура, ML-часть, приватность и код интеграции. Проект открытый. Буду рад аргументированным замечаниям. Читать далее
Почему мы классифицируем движение руки, а не картинки со светофорами — и как встроить это в форму двумя строками
Картиночные капчи в 2026-м решаются моделями компьютерного зрения за миллисекунды, а каждый ваш клик по «выберите автобусы» бесплатно размечает чужой датасет. Плюс две свежие проблемы: Google в начале 2025 срезал бесплатный лимит reCAPTCHA с 1 000 000 до 10 000 проверок в месяц, а с апреля 2026 ужесточил модель ответственности за данные по GDPR. Из России reCAPTCHA к тому же нестабильна.
В сети существует общая проблема — как доказать, что ты человек, не сдавая паспорт, лицо и номер телефона. Предлагаемое решение: drop‑in капча, которую посетитель не кликает, а рисует. Ниже — архитектура, ML‑часть, приватность и код интеграции. Проект открытый. Визуальное описание процесса ниже
Идея: классифицировать моторику, а не формуПользователь рисует произвольный жест ~10 секунд. Мы смотрим не на то, ЧТО нарисовано, а на то, КАК: разброс скорости, паузы, микрокоррекции, ритм, остановки движения руки. Боты двигаются слишком гладко; человек нерегулярен — и эта нерегулярность и есть доказательство. Это та часть, которую боту пока дорого подделать убедительно.
Архитектура: почему iframe с нашего originГлавная инженерная тонкость встраивания на чужой сайт — cross‑origin. Если бы виджет стучался на наш API напрямую со страницы клиента, ловил бы CORS/Origin‑локи и антибот‑фильтры.
Решение следующее: виджет — это <iframe>, который грузится с нашего домена, а не со страницы клиента. Внутри рамки все запросы идут к нашему же серверу, поэтому никаких cross‑origin проблем нет.
Чтобы понять, чей это сайт, у каждого клиента два ключа (как у reCAPTCHA):
публичный (pk_live_…) — вставляется в HTML, привязан к списку разрешённых доменов клиента. С чужого домена он бесполезен.
секретный (sk_live_…) — только на сервере клиента; им подтверждается токен.
Свой домен виджет узнаёт от родительской страницы и перепроверяет на сервере по списку разрешённых — подделать нельзя.

Блок‑схема работы системы верификации по движению руки
ML: локальный GBM + LLM только для серой зоныИз жеста считаются 8 признаков (velocity variance, pause entropy, rhythm irregularity, correction count и так далее).
Локальная градиентно‑бустинговая модель решает уверенные случаи за миллисекунды.
Языковая модель подключается только в серой зоне — где GBM не уверен.
Fail‑closed: если классификатор недоступен, endpoint отвечает 503, а не «человек: да». Лучше отказать, чем пропустить бота при сбое.
Координаты жеста не покидают браузер — на сервер уходит только производная статистика. Никаких картиночных наборов, трекинг‑кук и хранимых биометрических шаблонов. Токен не несёт идентичности. Для GDPR это означает отсутствие передачи данных Google и, для самой проверки, отсутствие требования cookie‑баннера.
Интеграция: две строки + одна серверная проверкаКлиент (в форму, которую защищаем):
<script src="https://homosapience.org/embed/v2/aptogon.js"></script><div data-aptogon-captcha data-aptogon-key="pk_live_..."></div><div data-aptogon-captcha data-aptogon-key="pk_live_..."></div>
На успехе загрузчик добавляет в форму скрытое поле aptogon-response. Сервер клиента проверяет токен, как у reCAPTCHA:
curl -s https://homosapience.org/api/captcha/siteverify \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{"token": "<aptogon-response из формы>"}'# → {"success": true, "human": true, "band": "...", "hostname": "https://ваш-сайт"}-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"token": "<aptogon-response из формы>"}'
# → {"success": true, "human": true, "band": "...", "hostname": "https://ваш-сайт"}Токен одноразовый (повтор — 409), живёт 120 секунд. Секретный ключ — только на сервере.
Честные ограниченияПредлагаемое решение повышает планку, а не делает систему непробиваемой. Мотивированный противник со временем сможет имитировать динамику — как и для любого программного proof‑of‑human. Виджет сам по себе не останавливает распределённые флуды через резидентные прокси. И у «рисования» есть свои ограничения по доступности — встроена толерантность к моторным нарушениям, но это область, где можно проводить исследования и накапливать обратную связь для коррекции алгоритма.
RU‑контекстВ российском сегменте интернета наиболее популярна — Yandex SmartCaptcha (локализация данных, привязка к Yandex Cloud). Наша ниша — те, кому нужна приватность и self‑serve, а reCAPTCHA не подходит по доступности/GDPR.
ИтогОткрытый код (AGPL-3.0), бесплатный тариф 1000 проверок/мес. (на стадии тестирования возможно больше). Живое демо: https://homosapience.org/embed/captcha‑demo.html. Документация: https://homosapience.org/developers. Исходники и примеры интеграции (HTML/React/ Node/Python/PHP): https://github.com/tulubyev/aptogon‑captcha.
Буду рад разбору в комментариях — особенно кейсам, где классификатор ошибается, и мнению, действительно ли «нарисовать» ощущается лучше невидимой проверки.
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | Почему сайт невидим для роботов: проблемы вайб-кодинга | 0 | 9.36 | 24-07-2026 |
| 2 | Как я навайбкодил каталог бесплатных парковок Петербурга и России | 5 | 7 | 07-07-2026 |
| 3 | Дизайн сайта с управлением жестами без Фигмы: как остаться автором, когда руки — ИИ | 0 | 11.88 | 18-07-2026 |
| 4 | [Перевод] Аутентификация в MCP в 2026: как было, как есть и как будет | 0 | 7 | 07-07-2026 |
| 5 | ИграКОД: Генератор судоку на TypeScript: почему найти решение проще, чем доказать единственность | -1 | 17.78 | 01-08-2026 |
| 6 | Еще более чебурнетистые законопроекты | 0 | 7.7 | 05-08-2026 |
| 7 | Картинка грузится, а fetch к тому же хосту — нет: как CSP тихо сломала три интеграции | 0 | 7.2 | 04-08-2026 |
| 8 | Две недели я делал народную карту заправок. Написать код оказалось самой скучной частью работы | 0 | 5 | 07-07-2026 |
| 9 | Как мы вынесли алгоритм ценообразования из кода Яндекс Такси (и почему это не было очевидно с самого начала) | 0 | 6.17 | 05-08-2026 |