К ленте · Россия

РоссияСтатьяМодели

Как я закрыл от ИИ-агента часть кода и проверил это кодом, а не промптом

aiedit — настольный редактор кода на Python (PySide6 и PyQt6), в котором ИИ-модели работают со всем проектом, но не видят закрытые части. Закрыть можно не только файл, но и отдельные строки. Проверку делает код редактора, а не просьба в промпте: закрытое просто не попадает в запрос к модели. Код открыт под лицензией MIT. Честно сразу: по качеству кода он пока уступает Claude Code на той же модели, ниже разбираю почему.

Зачем

В ИИ-редакторах обычно есть файлы-исключения, но они не запрещают доступ, и сами авторы этого не скрывают. Cursor пишет, что команды терминала и MCP-инструменты «могут прочитать» файлы из .cursorignore (документация Cursor). Cline и вовсе убирает .clineignore: файл «никогда не задумывался как запрет доступа», и проект не хочет давать ложное чувство безопасности (документация Cline). И работают такие файлы только с целыми файлами.

Если разделить проект на «можно ИИ» и «нельзя», ИИ работает вслепую. aiedit оставляет проект целым и закрывает ровно то, что важно: до одной строки. Например, формулу расчёта цены или работу с платежами, а всё остальное ИИ видит и правит.

Как работает защита

Строки закрываются прямо в поле с номерами строк. Есть пять уровней:

Уровень

Что получает модель

hidden

только метку: здесь что-то есть, N строк

interface

имена и сигнатуры без тел функций (Python)

readonly

весь код, но любая правка отклоняется

confirm

весь код, правки только с моего одобрения

explain

модель объясняет этот код

Слева файл в редакторе: наценка и функция price закрыты как hidden, функция discount как interface. Модель получает вот это:

def total(items):
 return sum(items)

<<ai-hidden:0:5 lines>>

<<ai-hidden:1:5 lines | def discount(user, amount):>>

def checkout(user, cart):
 s = total(cart)
 return s - discount(user, s)

Защита не одна, а цепочка:

  • У модели нет терминала. Она работает только через инструменты редактора (читать, искать, править). Закрытые папки для неё просто не существуют, а зоны вырезаются из каждого ответа.
  • Каждая правка проверяется diff-ом. Если модель задела закрытую строку, правка отклоняется. На диск ничего не пишется без моего одобрения.
  • Команды идут в песочнице. Тесты и сама программа запускаются под bubblewrap на копии проекта, в которой закрытого кода физически нет. Без сети, без домашней папки, без ключей. Даже команда, которая выведет все файлы в base64, ничего закрытого не покажет: его там нет.
  • Фильтр исходящего. Последняя проверка перед отправкой: ищет ключи, слова из моего списка и строки закрытого кода, вставленные в чат. Предлагает замаскировать, отправить как есть или отменить.
  • Журнал. Каждый запрос записывается локально: какие файлы, сколько строк скрыто, сколько символов ушло. Любую применённую работу ИИ можно откатить.

Ещё в редакторе есть цепочка из нескольких моделей: одна пишет код, редактор сам гоняет тесты в песочнице, модель другого производителя ищет ошибки и дыры. Я вижу изменения только после этого, вместе с честным результатом тестов, а не со словами модели «всё работает».

Как сделано

Я начинающий: Python учу с конца сентября 2026 года. Код писал ИИ (Claude) под моим руководством. Мои: идея, модель защиты, требования и решения, что делать, а что убрать. Разбирать код я учусь на этом же проекте.

В цифрах:

  • около 11 тысяч строк кода и около 10 тысяч строк тестов;
  • 857 тестов, проходят на PySide6 и на PyQt6;
  • без SDK: к моделям идут обычные HTTPS-запросы, подходит любая модель (Anthropic, OpenAI и совместимые с OpenAI серверы).

Проверка на настоящих моделях. Проверял через API на задаче «написать простое приложение на Flask»: код писал Claude Opus 5.5, проверял GLM 5.3.

Сравнение с Claude Code. По написанию кода aiedit проиграл Claude Code, хотя и там, и там код писал Opus 5.5. В aiedit правки дополнительно проверял GLM 5.3. Задача была та же: простое приложение на Flask. Причину я нашёл в журнале, и она в моей же защите. В тестах модель написала "password": "secret123", а фильтр секретов принял эту строку за настоящий пароль. В песочнице она заменялась на raise NotImplementedError прямо внутри словаря, и файл переставал быть корректным Python. Из 22 запусков в песочнице 13 упали, pytest ни разу не дошёл до самих тестов. Модель не понимала, почему, и написала ещё шесть файлов с тестами в обход. То есть защита сломала код, который модель писала сама. Исправил: теперь в песочнице заменяется только само значение, "password": "<hidden>", и файл остаётся правильным Python. Повторный прогон я не делал. Исправление проверено тестом, который повторяет этот случай.

Что пошло не так ещё. На первом живом тесте локальная qwen2.5-coder 7B не смогла держать формат вызова инструментов. Версия 32B справилась с простыми задачами, но задачу на несколько файлов не доделала за 14 шагов.

Какие дыры нашлись. Когда я читал код, нашлись две дыры, и обе уже закрыты:

  • если переименовать или скопировать файл не в редакторе, зоны терялись. Теперь закрытый код узнаётся по отпечаткам (хешам строк);
  • проект, установленный в свой же .venv через pip install ., лежал там целиком, и команда в песочнице могла его прочитать. Теперь такие копии скрыты.

Чего защита не делает

  • Фильтр ловит только то, что может сравнить: шаблоны ключей, слова из списка и закрытые строки, вставленные дословно. Секрет, пересказанный своими словами, уйдёт.
  • Имена несут смысл: сигнатура вроде calc_discount_for_client_x() в зоне interface уже много рассказывает.
  • Всё, что не закрыто, уходит провайдеру модели.
  • Если закрытый код скопировали и изменили, редактор его не узнает.
  • Отпечатки закрытых строк в *.aimarks.json — обычные хеши без соли: короткую строку вроде rate = 0.15 можно подобрать перебором. Модели эти файлы не отдаются, но выкладывать их в публичный репозиторий не стоит.
  • Песочница работает на Linux. На macOS она экспериментальная и на настоящем Mac не проверялась, на Windows только через WSL.

Версия ранняя. Код: GitHub · GitFlic. Если найдёте, как достать закрытый код в обход защиты, напишите мне: для меня это самая ценная помощь.

Источник: Хабр · статьиПубликуется с разрешения правообладателя, подтверждённого редакцией.Оригинал: Как я закрыл от ИИ-агента часть кода и проверил это кодом, а не промптом ↗

Есть кому отправить?

Скопируется постоянная ссылка на этот материал.

Комментарии

0

Обсудите материал с другими читателями.

Загружаем комментарии…

Ваш комментарий

Для публикации потребуется вход через Яндекс ID.