Pull to refresh
32K+
-3
Алксандр Егунов@crymans

User

-0,2
Rating
1
Subscribers
Send message

На счет MCP сервера принято, но с натяжкой - там одна несчастная ручка, также, замечу, что статья про расход токенов. В материале, прошу заметить, отмечены мощности - это 16 гб и старенький i7. Замечание на счет раздувание статей принято, прошу понять и простить, это мой первый мощный существенный фидбек за 5 статей, буду писать лучше. На счет использования ГПТобидно, не знаю как вас переубедить.
На счет предыдущих статей, как минимум зайдите в профиль, там прикреплен мой веб сайт, при желании, посмотрите DNSLookUp, там есть CNAME записи к реально существовавшему проекту, все материалы написаны на основе реальных ситуаций, для этого я, как минимум собираю логи, как максимум форматирую их ГПТ шкой
Сказать задним числом «результат очевиден» несложно. Тогда покажите, как из одной только архитектуры заранее получить двукратный расход, а не, например, прибавку в 10–20%. Я проверил это на работающей интеграции и привёл числа.

Edit: @moderator бы сильно удивился, если бы ему не было пофигу.
Очевидно, ведь в моем проекте везде используются модельки. Открою секрет, разрабатываем модели на 700 тысяч параметров, которые, как показывает статистика, работают намного быстрее любого асинхронного кода на Fastapi.
Что касается конкретно подготовки статей, у меня 400ГБ логов в месяц. Самые животрепещущие инциденты сразу вношу в Markdown, после чего пишу ручками статью. Еще один анонс, ИИможно Ragать как угодно, и отвечать моделька вам будет как угодно.
Edit: Прошу, уважаемый пользователь, напиши еще раз, что это все сгенерировано ИИ.

«Вот так новость» звучит эффектно, но вы буквально пересказали вывод статьи и выдали его за разоблачение. Эксперимент как раз и показал, что дешёвая локальная модель, поставленная между двумя проходами Codex, не экономит лимит, а увеличивает расход. Отрицательный результат — тоже результат, если показана причина.

С выбором моделей претензия справедливая: 2B/4B недостаточно для серьёзной агентской работы. Поэтому следующим этапом будут Gemma 4 QAT и модели класса 8–9B на одинаковых задачах, с сырыми ответами, временем, памятью и расходом токенов.

GPT при подготовке текста использовался, скрывать это не собираюсь. Но код, запуск, замеры и неудачный результат от этого выдуманными не становятся. monospace, SHA-256 и стрелки в диаграммах — довольно странная доказательная база. Если в методике или цифрах есть конкретная ошибка, её как раз интересно обсудить.

Переносы команд поправлю. А -1 — ваше право, здесь без вопросов.

Потому что промахнулся с выбором модели: взял уже установленные Gemma 2/3 и больше сосредоточился на самой схеме делегирования. Gemma 4 QAT действительно стоило включить. Поэтому сделаю отдельную статью про более новые модели и прогоню их на одинаковых практических задачах. Следом хочу отдельно сравнить модели класса 8–9B — похоже, именно там начинается разумный минимум для локальной работы с кодом и агентских сценариев. Спасибо за наводку.

Согласен. Для самостоятельной работы с кодом 2–4B действительно слишком мало — модель быстро теряет контекст и начинает уверенно выдумывать. Моя идея была не заменить Codex локальной Gemma, а отдавать ей только узкие задачи: классификацию, краткое резюме, поиск очевидных ошибок и подготовку черновиков. Но границу стоило обозначить явно: для нормальной кодовой и тем более агентской работы начинать нужно хотя бы с 8–9B.

Можно, и для редких сохранений это вполне рабочий вариант: принять HTML, прогнать его через Tailwind CLI и сохранить результат вместе с готовым CSS.

Я отказался от этого из-за цены операции и сложности эксплуатации. Tailwind — сборочный инструмент: на каждое сохранение пришлось бы запускать отдельную сборку, изолировать пользовательский ввод, ограничивать время и память, кешировать результат и разбираться с параллельными запусками. Если контент редактируется часто, получается небольшой build-сервис внутри обычного backend.

Но для CMS с небольшим числом публикаций я бы сейчас действительно рассматривал такой подход. Особенно если сохранять CSS по хешу содержимого и пересобирать его только при изменении набора классов. В моём случае safelist оказался проще, но ваш вариант универсальнее.

Да, это хороший следующий шаг. Тогда в базе хранится не HTML, а что-то вроде { "type": "price", "props": {...} }, а Tailwind видит все классы внутри обычного Vue-компонента ещё во время сборки.

Минус в том, что каждый новый тип блока сначала нужно реализовать и задеплоить. HTML я оставил как быстрый вариант для редких уникальных вставок, но для повторяющихся блоков ваш подход действительно лучше. И не поздно: можно добавить blocks рядом с body_html, постепенно мигрировать контент, а HTML оставить временным fallback.

Да, если контент меняется через Git и деплой, файлы были бы проще базы — спорить не буду.

У меня HTML является только одним полем сущности. Рядом лежат slug, порядок, статус публикации, цена, категории и остальные данные, которые редактируются через админку. Если перенести это на диск, придётся отдельно решать запись из приложения, конкурентное редактирование, persistent volume, резервные копии и работу нескольких экземпляров.

Поэтому база нужна не ради хранения строки HTML, а ради модели управления контентом. Для статического сайта с техническим редактором я бы действительно выбрал файлы.

Мощный ресёрч, особенно про canary и две копии std в одном процессе.

Есть небольшое уточнение по поводу FFI и extern "C". Вы пишете, что в 1.81 границу закрыли окончательно и теперь это принудительный abort. Но разве это спасает от ситуации, когда Сишный код, вызванный из Rust, сам бросает longjmp (или плюсовый код кидает эксепшен через extern "C" обратно в раст)? Насколько я помню, Itanium ABI в таких случаях все равно может сломать стек, если на пути окажутся фреймы раст без правильного landing pad. То есть C-unwind обязателен не только для проброса паники наружу, но и для безопасного пролета чужого unwind внутрь раст кода?

Идея с self-service отличная, но есть пара инфраструктурных нюансов по реализации:

  1. Под каким пользователем запущен сам фласк? Если сервис работает от root, чтобы иметь права на os.kill — это очень опасный паттерн для веб-приложения. Гораздо безопаснее запускать сам Flask (через systemd/gunicorn) строго под юзером hcl. Тогда проверка if owner != PROCESS_OWNER становится просто страховкой от ошибок логики — ядро ОС на уровне прав само не даст фласку убить чужие процессы, даже если кто-то подделает запрос.

  2. Вы пишете, что выбрали SIGTERM как "менее жесткий вариант". Но если флоучарт реально намертво «завис» (например, случился дедлок или процесс повис на I/O-операциях), он с большой вероятностью просто проигнорирует мягкий SIGTERM, и процесс останется висеть. В таких хелперах обычно реализуют паттерн graceful shutdown: отправляют SIGTERM (у psutil для этого есть удобный метод proc.terminate()), ждут пару секунд через proc.wait(timeout=3), и если процесс всё ещё жив — добивают уже жестким proc.kill(). Иначе вашим инженерам всё равно придется периодически заходить и делать kill -9 руками.

Свой gRPC-wire вместо стандартного стека — это круто, но есть один архитектурный нюанс по безопасности.

В секции про Tsak вы пишете: «берётся самый правый хоп X-Forwarded-For, тот, который дописал доверенный прокси и который клиент подделать не может».

Если перед вашим приложением стоит цепочка балансировщиков (например, внешний Anti-DDoS -> ваш краевой Nginx), то самым правым хопом в заголовке окажется IP-адрес внешнего шлюза, а не реального атакующего. Выдав бан по этому IP при переборе, вы положите доступ вообще всем легитимным пользователям, идущим через этот узел.

Безопаснее парсить заголовок X-Forwarded-For справа налево, последовательно отбрасывая статические IP-адреса ваших собственных доверенных прокси. Первый же неизвестный адрес в цепочке с конца — это и есть настоящий IP клиента.

Травма от джанговских строк очень понятна)

Но фишка современных DI на питоне (той же Dishka) как раз в том, что там под капотом нет никакой строковой магии. Всё резолвится исключительно по type hints.

Вы просто указываете в init юзкейса зависимость вида repo: UserRepository. В итоге IDE, mypy и автокомплит работают идеально, потому что типы прописаны явно и строго. Так что компромиссов с типизацией тут не будет, реально советую потыкать.

Запихивать репозитории в TransactionManager через @property — это прямой путь к god-object. При росте приложения этот класс раздует, и его придется модифицировать при добавлении каждой новой таблички (явное нарушение OCP). Гораздо изящнее разруливать это через нормальный DI-контейнер (ту же Dishka). Провайдишь сессию куда надо, а управление транзакцией вешаешь декоратором прямо на юзкейс. И базовый класс чистый, и бойлерплейта меньше.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Registered
Activity

Specialization

Бэкенд разработчик, Веб-разработчик
Младший
From 150,000 ₽
Git
Docker
Linux
Python
Английский язык
ООП
Базы данных
Nginx
Высоконагруженные системы
REST