<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <language>ru</language>
    <title>API</title>
    <description>Рекомендации по использованию API популярных веб-сервисов и не только.</description>
    <link>https://tproger.ru/tag/api</link>
    <atom:link href="https://tproger.ru/tag/api/feed" rel="self" type="application/rss+xml"/>
    <lastBuildDate>Fri, 13 Nov 2026 15:13:34 GMT</lastBuildDate>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>12</sy:updateFrequency>
    <image>
      <title>API</title>
      <link>https://tproger.ru</link>
      <url>https://tproger.ru/apple-touch-icon.png</url>
    </image>
    <item>
      <title>Google выпустила модель решений Gemini Decision 1 с бесплатным уровнем API</title>
      <link>https://tproger.ru/news/google-vypustila-model-rewenij-gemini-decision-1-s-besplatnym-u</link>
      <comments>https://tproger.ru/news/google-vypustila-model-rewenij-gemini-decision-1-s-besplatnym-u?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/google-vypustila-model-rewenij-gemini-decision-1-s-besplatnym-u</guid>
      <description><![CDATA[<p>Модель gemini-decision-1 отвечает вероятностями на 1000 вопросов за запрос: $0,10 за млн входных токенов, 10 000 бесплатных запросов в день, замеры Google.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/google-vypustila-model-rewenij-gemini-decision-1-s-besplatnym-u">Google выпустила модель решений Gemini Decision 1 с бесплатным уровнем API</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Машинное обучение]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 11 Nov 2026 17:36:58 GMT</pubDate>
      <content:encoded><![CDATA[<p>Google 11 ноября 2026 года <a href="https://blog.google/innovation-and-ai/technology/developers-tools/gemini-decisions-api/">выпустила Gemini Decision 1</a> — модель, которая отвечает на закрытые вопросы вероятностями и не генерирует текст, — и новый эндпоинт Decisions API для неё в Gemini API и Google AI Studio. Вход стоит $0,10 за млн токенов, выходных токенов нет вовсе, а на бесплатном уровне доступно до 10 000 запросов в день на проект.</p><p>Такая модель нужна там, где ответ читает код: отправить обращение в нужную очередь, проверить документ по списку правил, решить, вызывать ли агенту инструмент. Программа получает вероятность и сравнивает её с порогом, разбирать сгенерированный JSON не приходится. Google вышла с таким API вслед за стартапом TypeSafe с моделью Jev и OpenAI, которая <a href="https://tproger.ru/news/openai-vypustila-gpt-6-1-terra-po-1-za-million-vhodnyh-tokenov">открыла Decisions API на GPT-6 Luna</a> в октябре. От обоих Gemini Decision 1, по документации трёх компаний, отличается приёмом аудио, видео и PDF.</p><ul><li>Модель gemini-decision-1 с 11 ноября работает через Gemini API версии v1beta и в Google AI Studio; поддержку в Google Cloud компания обещает «скоро», без даты.</li><li>Вопросы трёх типов: «да/нет», выбор из 2–255 вариантов и оценка по рубрике из 2–255 уровней; в одном запросе до 1000 вопросов и до 262 144 токенов на общий вход вместе с вопросами.</li><li>Цена — $0,10 за млн входных токенов, выход не тарифицируется; бесплатный уровень — 200 запросов в минуту, 50 000 токенов в минуту и 10 000 запросов в день на проект.</li><li>По замерам самой Google, модель обходит и Jev 1.14, и GPT-6 Luna в 5 из 7 общих тестов; ошибка калибровки Top-1 ECE — 0,0250 против 0,0494 и 0,0721, но прогон этих тестов у Jev дешевле: $0,68 против $0,88.</li><li>Кеширования, Batch API, Flex и Priority нет; России нет в списке регионов Gemini API; у агрегаторов модель уже появилась: в OpenRouter это google/gemini-decision-1.</li></ul><h2>Что такое модель решений и чем она отличается от обычной LLM?</h2><p>Модель решений не пишет ответ: она получает данные и список вопросов с заранее заданными вариантами и возвращает вероятность каждого варианта. <a href="https://ai.google.dev/gemini-api/docs/decisions-api">Документация Decisions API</a> объясняет идею так: генеративные модели производят текст для людей, а когда суждение нужно коду для ветвления, генерация и разбор текста добавляют задержку и хрупкую логику парсинга. Текстовых токенов эндпоинт не создаёт, поле total_output_tokens в ответе всегда равно 0.</p><p>Запрос состоит из общего входа input (текст, изображения, аудио, видео, PDF) и карты вопросов questions. У каждого вопроса один из трёх типов:</p><p>Типы вопросов Decisions API</p><table><thead><tr><th>Тип</th><th>Что проверяет</th><th>Что возвращает</th></tr></thead><tbody><tr><td>noul, «да/нет»</td><td>Выполняется ли условие</td><td>Вероятность ответа «да» от 0,01 до 0,99 и confidence</td></tr><tr><td>choice, выбор</td><td>Один вариант из фиксированного списка, 2–255 вариантов</td><td>Победивший вариант, вероятности всех вариантов (в сумме 1) и confidence</td></tr><tr><td>score, оценка</td><td>Место на упорядоченной рубрике, 2–255 уровней (советуют 2–10)</td><td>Среднее номеров уровней, взвешенное по вероятностям, вероятности уровней и confidence</td></tr></tbody></table><p>Источник: ai.google.dev/gemini-api/docs/decisions-api</p><p>Все вопросы оцениваются за один проход модели по общему входу и не видят друг друга: добавление или удаление вопроса, по документации, не меняет остальные ответы. Поле confidence — оценка вероятности того, что главный ответ верен; по нему код решает, выполнять действие автоматически или передать случай человеку.</p><figure><img src="https://media.tproger.ru/user-uploads/1140448/2026-11-11/3261227a-25c0-40dd-abfd-b87f0357c1f3.webp" alt="Схема Gemini Decisions API: слева мультимодальный вход до 256K токенов и вопросы типов noul, choice и score, в центре Gemini Decision 1, справа калиброванные ответы с confidence" /><figcaption>Общий вход и вопросы трёх типов превращаются в типизированные ответы с вероятностями. Схема: Google</figcaption></figure><p>Скорость авторы <a href="https://blog.google/innovation-and-ai/technology/developers-tools/gemini-decisions-api/">анонса в блоге Google</a> описывают одной фразой:</p><blockquote>Gemini Decision 1 scores options without token-by-token decoding, keeping median latency 50-100 ms of model compute (150-250 ms end-to-end), across multimodal inputs and contexts up to 16K tokens, remaining nearly flat from 1 to 100 questions per request.</blockquote><p>Перевод редакции: «Gemini Decision 1 оценивает варианты без потокенного декодирования и удерживает медианную задержку 50–100 мс на вычисления модели (150–250 мс на весь запрос) для мультимодальных входов и контекстов до 16 тыс. токенов; задержка почти не меняется от 1 до 100 вопросов в запросе».</p><p>Оговорки стоят в самой цитате: это медиана, контекст до 16 тыс. токенов и не больше 100 вопросов. Для входа ближе к пределу в 262 144 токена и для 1000 вопросов цифр задержки компания не приводит. Внутри Google, по словам авторов, API уже выбирает модель и уровень размышлений для запросов в Gemini Notebook, где повседневные запросы обслуживаются с задержкой до 40% ниже, и подбирает эмодзи-реакцию из более чем 200 вариантов в сервисе CC из Google Labs.</p><h2>Сколько стоит Gemini Decision 1 и что входит в бесплатный уровень?</h2><p>На платном уровне модель стоит $0,10 за млн входных токенов любого типа: текст, изображения, видео, аудио, PDF. В строке Output price на <a href="https://ai.google.dev/gemini-api/docs/pricing#gemini-decision">странице цен Gemini API</a> стоит «Not applicable (0 output tokens)». Общий вход тарифицируется один раз за запрос независимо от числа вопросов, каждый вопрос добавляет токены своих инструкций и критериев. Кадры видео и страницы PDF считаются как токены изображений. Руководитель продукта Google AI Studio и Gemini API Логан Килпатрик <a href="https://x.com/OfficialLoganK/status/2120581433639198885">представил модель в X</a> так:</p><blockquote>Introducing Gemini Decision 1, our new frontier decision model in the Gemini API. It is $0.10 per 1M input tokens with no additional cost. With support for image, audio, video, and PDF natively, 256K context window, &amp; 1K questions. You can try it for free in the API!</blockquote><p>Перевод: «Представляем Gemini Decision 1, нашу новую передовую модель решений в Gemini API. Она стоит $0,10 за 1 млн входных токенов без дополнительных платежей. Нативно поддерживает изображения, аудио, видео и PDF, контекстное окно 256K и 1 тыс. вопросов. Попробовать можно бесплатно через API!» «No additional cost» здесь означает нулевую цену выхода: в анонсе Google перечисляет, что нет платы за выходные токены, токены размышлений, отдельную расшифровку аудио и распознавание текста. Скидок тоже нет. Модель не поддерживает кеширование контекста, Batch API, режимы Flex и Priority, и повторяющийся вход в каждом запросе оплачивается полностью.</p><p>Лимиты на <a href="https://ai.google.dev/gemini-api/docs/rate-limits#gemini-decision">странице квот</a> действуют на проект целиком, сколько бы API-ключей в нём ни было. Дневная квота обнуляется в полночь по тихоокеанскому времени, и Google оговаривает, что указанные значения не гарантированы.</p><p>Лимиты Gemini Decision 1 в Decisions API</p><table><thead><tr><th>Уровень</th><th>Запросов в минуту</th><th>Токенов в минуту</th><th>Запросов в день</th></tr></thead><tbody><tr><td>Free</td><td>200</td><td>50 000</td><td>10 000</td></tr><tr><td>Tier 1</td><td>1500</td><td>1 000 000</td><td>50 000</td></tr><tr><td>Tier 2</td><td>5000</td><td>4 000 000</td><td>без ограничений</td></tr><tr><td>Tier 3</td><td>15 000</td><td>10 000 000</td><td>без ограничений</td></tr></tbody></table><p>Источник: ai.google.dev/gemini-api/docs/rate-limits, проверено 11 ноября 2026 года</p><p>За бесплатный уровень разработчик платит данными: в таблице цен в строке «Used to improve our products» для Free Tier стоит Yes, для платного — No. <a href="https://ai.google.dev/gemini-api/terms">Условия Gemini API</a> просят не отправлять в бесплатные сервисы чувствительную, конфиденциальную и персональную информацию; для пользователей из Европейской экономической зоны, Швейцарии и Великобритании на бесплатную квоту распространяются правила платных сервисов. Другие варианты с постоянной бесплатной квотой собраны в <a href="https://tproger.ru/articles/besplatnye-api-dlya-llm--polnyj-spisok-provajderov-s-postoyannym-f">списке бесплатных API для LLM</a>.</p><h2>Чем Gemini Decision 1 отличается от Jev и OpenAI Decisions API?</h2><p>Главные отличия по документации — модальности входа и лимиты запроса. По цене токена Google совпадает с OpenAI и примерно в 2,4 раза дороже Jev. Сравнение собрано по <a href="https://ai.google.dev/gemini-api/docs/decisions-api">документации Google</a>, <a href="https://developers.openai.com/api/docs/guides/decisions">руководству OpenAI Decisions</a> и <a href="https://docs.typesafe.ai/models">странице моделей TypeSafe</a>:</p><p>Три API моделей решений по официальной документации</p><table><thead><tr><th>Параметр</th><th>Gemini Decision 1</th><th>OpenAI Decisions API (GPT-6 Luna)</th><th>TypeSafe Jev 1.14</th></tr></thead><tbody><tr><td>Типы вопросов</td><td>noul, choice, score</td><td>predicate, choice, score</td><td>Noul, Choice, Score, Box (рамка объекта на изображении)</td></tr><tr><td>Вопросов в запросе</td><td>1–1000</td><td>1–400</td><td>отдельного лимита нет, ограничивает контекст</td></tr><tr><td>Вход</td><td>текст, изображения, аудио, видео, PDF</td><td>текст, изображения, JSON; файлы и аудио не поддерживаются</td><td>текст и изображения PNG и JPEG; аудио и видео не принимает</td></tr><tr><td>Контекст</td><td>262 144 токена на вход и все вопросы</td><td>в руководстве Decisions не указан; окно модели gpt-6-luna — 1 050 000 токенов</td><td>64k на запрос и 32k на вопрос; 262k с заголовком длинного контекста</td></tr><tr><td>Цена входа за млн токенов</td><td>$0,10</td><td>$0,10 без кеша; применяются множители длинного контекста</td><td>$0,042</td></tr><tr><td>Плата за выход</td><td>нет</td><td>нет</td><td>нет</td></tr></tbody></table><p>Источники: документация Google, OpenAI и TypeSafe, проверено 11 ноября 2026 года</p><p>У Jev изображения и вопросы типа Box, по <a href="https://docs.typesafe.ai/images">документации TypeSafe</a>, пока не считаются готовыми для продакшена, а длинный контекст включается отдельным заголовком и работает медленнее и менее точно, чем запросы в обычных пределах. OpenAI поддерживает кеширование промптов, историю диалога с вызовами инструментов и изображения внутри вопросов. У Gemini Decision 1 инструкции вопросов принимают только текст, а многоходовой контекст нужно сериализовать в текст. Модель <a href="https://tproger.ru/news/openai-vypustila-gpt-6-sol-i-gpt-6-luna-v-api">GPT-6 Luna, вышедшая в API в сентябре</a>, у OpenAI универсальная, Google же выпустила под решения отдельную модель. Ту же развилку цены и модальностей отмечают в <a href="https://news.ycombinator.com/item?id=50456959">обсуждении запуска на Hacker News</a>:</p><blockquote>Its bit more expensive than other other Decision Models in the same lane. However, it can accept Audio and Video as input as well and for those specific cases it can be extremely useful.</blockquote><p>Перевод: «Она немного дороже других моделей решений того же класса. Зато принимает на вход ещё и аудио с видео, и в таких случаях может быть крайне полезной».</p><h2>Что показывают бенчмарки и кто их мерил?</h2><p>Все числа ниже — замеры самой Google из таблицы в анонсе; независимых замеров на день запуска нет. По этой таблице Gemini Decision 1 обходит одновременно Jev 1.14 и GPT-6 Luna в пяти из семи тестов, где есть результаты всех моделей, а GPT-6 Luna — во всех семи. Jev 1.14 выше на Mind2Web Multimodal и When2Call. В тексте анонса при этом сказано, что модель «leads across the suite», то есть лидирует по всему набору.</p><p>Бенчмарки из анонса Gemini Decision 1 (замеры Google)</p><table><thead><tr><th>Тест</th><th>Gemini Decision 1</th><th>TypeSafe Jev 1.14</th><th>GPT-6 Luna (OpenAI Decisions API)</th><th>Gemini 3.5 Flash-Lite (Interactions API, minimal)</th></tr></thead><tbody><tr><td>JevBench, Public split</td><td>92,2%</td><td>90,0%</td><td>90,9%</td><td>86,6%</td></tr><tr><td>Amazon ESCI, Macro-F1</td><td>58,7%</td><td>56,7%</td><td>54,7%</td><td>47,2%</td></tr><tr><td>New Yorker Caption, Text-only</td><td>79,7%</td><td>72,0%</td><td>68,4%</td><td>73,7%</td></tr><tr><td>Mind2Web Multimodal</td><td>86,2%</td><td>86,8%</td><td>81,8%</td><td>78,0%</td></tr><tr><td>PubMedQA</td><td>79,8%</td><td>78,2%</td><td>74,4%</td><td>77,6%</td></tr><tr><td>Global-MMLU-Lite, Non-English</td><td>86,0%</td><td>85,0%</td><td>79,6%</td><td>78,8%</td></tr><tr><td>When2Call</td><td>79,9%</td><td>82,0%</td><td>70,4%</td><td>60,9%</td></tr><tr><td>MMAU</td><td>71,8%</td><td>нет данных</td><td>нет данных</td><td>67,7%</td></tr><tr><td>Video-MME, No subtitles</td><td>69,1%</td><td>нет данных</td><td>нет данных</td><td>63,3%</td></tr><tr><td>Top-1 ECE, 7 общих тестов (меньше — лучше)</td><td>0,0250</td><td>0,0494</td><td>0,0721</td><td>0,2104</td></tr><tr><td>Цена прогона 7 общих тестов</td><td>$0,88</td><td>$0,68</td><td>$0,93</td><td>$4,14</td></tr></tbody></table><p>Источник: таблица в анонсе Google от 11 ноября 2026 года; замеры Google</p><p>Методика уместилась в сноску под таблицей: отказы, блокировки фильтрами безопасности и запросы, которые модель не смогла принять, засчитаны как ошибки, знаменатель — полный бенчмарк, метрика — Top-1 Accuracy, если не указано иное (у Amazon ESCI это Macro-F1). MMAU и Video-MME прогнаны только на моделях Gemini: прямого ввода аудио и видео в документации Jev и OpenAI Decisions API нет. Отдельной страницы с промптами и логами прогонов Google не опубликовала; как отбирались тесты, в анонсе не сказано.</p><p>Сильнее всего отрыв в калибровке. Top-1 ECE, ожидаемая ошибка калибровки, показывает, насколько заявленная уверенность модели расходится с фактической долей верных ответов. На семи общих тестах у Gemini Decision 1 она равна 0,0250, у Jev 1.14 — 0,0494, у GPT-6 Luna — 0,0721. На этих тестах вероятности модели Google лучше согласуются с её точностью; о калибровке на других данных таблица ничего не говорит.</p><figure><img src="https://media.tproger.ru/user-uploads/1140448/2026-11-11/4b3bd2e1-3224-4e74-bb15-ccb4563fea39.webp" alt="Top-1 ECE на семи общих тестах по замерам Google: Gemini Decision 1 — 0,0250, TypeSafe Jev 1.14 — 0,0494, GPT-6 Luna — 0,0721, Gemini 3.5 Flash-Lite — 0,2104" /><figcaption>Ошибка калибровки Top-1 ECE на семи общих тестах, меньше — лучше; замеры Google. График: Tproger по данным анонса Google</figcaption></figure><p>По цене прогона тех же семи тестов первая Jev: $0,68 против $0,88 у Gemini Decision 1 и $0,93 у GPT-6 Luna. Генеративная Gemini 3.5 Flash-Lite через Interactions API обошлась в $4,14, отсюда заявление Google о почти пятикратной экономии.</p><figure><img src="https://media.tproger.ru/user-uploads/1140448/2026-11-11/eabaa3af-681b-4867-a088-f7be3ad05b54.webp" alt="Цена прогона семи общих тестов по замерам Google: TypeSafe Jev 1.14 — $0,68, Gemini Decision 1 — $0,88, GPT-6 Luna — $0,93, Gemini 3.5 Flash-Lite — $4,14" /><figcaption>Цена прогона семи общих тестов в долларах; замеры Google. График: Tproger по данным анонса Google</figcaption></figure><p>Проверять такие модели на глаз труднее, чем обычные LLM. Об этом ещё в октябре, в обсуждении беты OpenAI Decisions API, <a href="https://news.ycombinator.com/item?id=49985050">писал на Hacker News</a> разработчик Саймон Уиллисон:</p><blockquote>Anyone using a decision model like this is going to have to spin up their own evals - these are far harder to vibe-check than regular text output LLMs.</blockquote><p>Перевод: «Всем, кто использует подобную модель решений, придётся завести собственные наборы проверок: оценить её на глаз гораздо труднее, чем обычные LLM с текстовым ответом».</p><h2>Где попробовать и как вызвать API?</h2><p>В Google AI Studio и через Gemini API версии v1beta; нужны API-ключ и SDK google-genai версии 3.2 или новее. Без кода вопросы всех трёх типов можно проверить в <a href="https://aistudio.google.com/apps/f6cbef57-8bad-443a-813f-4d4c8f9750af?fullscreenApplet=true">Decisions Playground</a> и выгрузить оттуда готовый код; рядом лежат демо-приложения Doorstep Parcels и Find the Zookeeper. Команды установки SDK из документации:</p><p>В Python запрос отправляет метод client.decisions.create, клиент создаётся с http_options={"api_version": "v1beta"}. Тот же вызов через REST, дословно из раздела Quickstart:</p><p>Ответ из документации: вероятность того, что товар пришёл повреждённым, и счётчик токенов с нулём на выходе.</p><p>Доступ ограничен географией: в <a href="https://ai.google.dev/gemini-api/docs/available-regions">списке стран и территорий</a>, где работают Gemini API и Google AI Studio, России нет. Интеграции с OpenRouter, LangChain, Vercel, LiteLLM, Pydantic AI, Pipecat, LiveKit и OpenCode, по анонсу, выкатываются постепенно. Первые уже видны: на <a href="https://openrouter.ai/google/gemini-decision-1">странице модели в OpenRouter</a> она значится как google/gemini-decision-1 с провайдером Google AI Studio, ценой $0,10 за млн входных токенов и контекстом 262 144 токена. Вызывается модель там через отдельный OpenRouter Decisions API, SDK для chat completions с ней не работают, а в общем списке /api/v1/models в ночь на 12 ноября её не было. Карточка с ценой $0,10 и примером вызова есть и в <a href="https://vercel.com/ai-gateway/models/gemini-decision-1">Vercel AI Gateway</a>.</p><h2>Какие ограничения перечисляет документация?</h2><p>Ограничений больше, чем в анонсе. Вот те, что влияют на код и счёт:</p><ul><li>Вероятность в вопросах «да/нет» всегда лежит в диапазоне 0,01–0,99: проверка порога выше 0,99 не сработает никогда.</li><li>Вопрос choice распределяет вероятность между вариантами, даже если не подходит ни один. Документация советует порог по confidence, отдельную проверку «да/нет» или вариант other с явным описанием. Ключи вариантов сортируются по алфавиту, порядок в JSON на результат не влияет.</li><li>score — среднее номеров уровней, поэтому шкалу нужно держать линейной, а одно и то же значение могут дать разные распределения вероятностей.</li><li>Медиа передаётся только в общем входе: через Files API, публичный или подписанный HTTPS-URL (до 15 МБ) либо base64 (до 100 МБ на запрос, PDF до 50 МБ). Ссылки YouTube и gs:// не поддерживаются.</li><li>При срабатывании входных фильтров безопасности API возвращает HTTP 400 без ответов, с кодом safety, prohibited_content, blocklist, image_safety или content_blocked.</li><li>Вход считается недоверенным: пользовательский текст может сам убеждать модель в нужной классификации. Для действий с высокой ценой ошибки, например выплат, документация советует оставлять человека или вторую проверку.</li></ul><h2>Что сделать разработчику сейчас?</h2><ol><li>Обновить SDK google-genai до версии 3.2 или новее и получить ключ в Google AI Studio; на бесплатном уровне не отправлять конфиденциальные и персональные данные.</li><li>Собрать размеченные примеры из своего трафика и подобрать пороги по ним: документация советует именно так и предлагает взвешивать цену ложного срабатывания против цены пропуска.</li><li>Держать пороги для noul внутри диапазона 0,01–0,99 и проверять confidence перед автоматическим действием.</li><li>Считать бюджет по входу: кеша нет, общий вход оплачивается в каждом запросе заново, поэтому независимые вопросы к одним данным выгоднее класть в один запрос, до 1000 штук.</li><li>Если нужны Batch API, кеширование или запуск в Google Cloud, закладывать ожидание: первых двух модель не поддерживает, срока для третьего нет.</li></ol><p>Открытыми остаются три вопроса: когда модель появится в Google Cloud, как она покажет себя в независимых замерах и как меняется задержка на контекстах больше 16 тыс. токенов. На <a href="https://ai.google.dev/gemini-api/docs/models/gemini-decision-1">странице модели</a> и в анонсе нет ссылки на model card; в <a href="https://ai.google.dev/gemini-api/docs/changelog">журнале изменений Gemini API</a> запуск отмечен одной записью от 11 ноября.</p><p>Источники: <a href="https://blog.google/innovation-and-ai/technology/developers-tools/gemini-decisions-api/">Google: Gemini Decisions API: Fast, calibrated multimodal decisions</a>, <a href="https://ai.google.dev/gemini-api/docs/decisions-api">Gemini API: Decisions API</a>, <a href="https://ai.google.dev/gemini-api/docs/models/gemini-decision-1">Gemini API: модель Gemini Decision</a>, <a href="https://ai.google.dev/gemini-api/docs/pricing#gemini-decision">Gemini API: Pricing</a>, <a href="https://ai.google.dev/gemini-api/docs/rate-limits#gemini-decision">Gemini API: Rate limits</a>, <a href="https://ai.google.dev/gemini-api/docs/available-regions">Gemini API: Available regions</a>, <a href="https://ai.google.dev/gemini-api/terms">Gemini API: Terms of Service</a>, <a href="https://ai.google.dev/gemini-api/docs/changelog">Gemini API: Release notes</a>, <a href="https://x.com/OfficialLoganK/status/2120581433639198885">Logan Kilpatrick в X</a>, <a href="https://developers.openai.com/api/docs/guides/decisions">OpenAI: Decisions guide</a>, <a href="https://developers.openai.com/api/docs/models/gpt-6-luna">OpenAI: модель GPT-6 Luna</a>, <a href="https://docs.typesafe.ai/models">TypeSafe: Models</a>, <a href="https://docs.typesafe.ai/images">TypeSafe: Images</a>, <a href="https://news.ycombinator.com/item?id=50456791">Обсуждение на Hacker News</a>, <a href="https://openrouter.ai/google/gemini-decision-1">OpenRouter: Gemini Decision 1</a>, <a href="https://vercel.com/ai-gateway/models/gemini-decision-1">Vercel AI Gateway: Gemini Decision 1</a></p><p>Изображение на обложке: Google</p>]]></content:encoded>
    </item>
    <item>
      <title>Anthropic объяснила, какую модель Claude и какой effort ставить на задачу</title>
      <link>https://tproger.ru/articles/anthropic-obyasnila-kakuyu-model-claude-i-kakoj-effort-stavit</link>
      <comments>https://tproger.ru/articles/anthropic-obyasnila-kakuyu-model-claude-i-kakoj-effort-stavit?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/anthropic-obyasnila-kakuyu-model-claude-i-kakoj-effort-stavit</guid>
      <description><![CDATA[<p>Opus 5.5 на medium как старт, Fable 5.2 по $8 и $40 за млн токенов для самых сложных задач, Haiku 5.5 для потока. Таблицы цен, замеры effort, субагенты.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/anthropic-obyasnila-kakuyu-model-claude-i-kakoj-effort-stavit">Anthropic объяснила, какую модель Claude и какой effort ставить на задачу</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Нейронные сети]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Советы]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 09 Nov 2026 18:48:11 GMT</pubDate>
      <content:encoded><![CDATA[<p>Anthropic 9 ноября 2026 года опубликовала в блоге claude.dev <a href="https://claude.dev/blog/which-claude-model-should-you-build-with/">гайд «Which Claude model should you build with?»</a> о том, какую из четырёх общедоступных моделей Claude брать под какую задачу: Haiku 5.5, Sonnet 5.5, Opus 5.5 или Fable 5.2. Автор — Эдди Османи (Addy Osmani), на странице он подписан как Member of Technical Staff. Короткий ответ гайда: большинство задач начинать на Opus 5.5 с уровнем effort по умолчанию, medium, а перед сменой модели сначала подвигать effort.</p><p>Для тех, кто пишет на Claude API или работает в Claude Code, это готовая схема расходов: входные токены у четырёх моделей стоят от $0,10 до $8 за миллион, выходные — от $0,50 до $40, и ошибка с выбором модели или уровня effort меняет счёт в разы. Все рекомендации и почти все замеры ниже принадлежат самой Anthropic: это советы вендора о собственных моделях, независимый замер вынесен в отдельный раздел. О выходе старшей модели мы писали в новости <a href="https://tproger.ru/news/anthropic-vypustila-claude-fable-5-2-i-snizila-cenu-na-20">«Anthropic выпустила Claude Fable 5.2 и снизила цену на 20%»</a>.</p><ul><li>Стартовая точка по гайду — Opus 5.5 на effort medium: $4 за миллион входных и $20 за миллион выходных токенов, вдвое дешевле Fable 5.2 ($8 и $40).</li><li>Sonnet 5.5 ($2 и $10) — для чётко очерченных задач, Haiku 5.5 ($0,10 и $0,50 при промпте до 100 тыс. токенов) — для классификации, маршрутизации и субагентов, Fable 5.2 — для самых сложных проектов и когда Opus 5.5 на high не справляется.</li><li>Effort — более тонкая ручка, чем модель: по замерам Anthropic на подмножестве SWE-bench Pro Opus 5.5 на medium теряет около 2,5 пункта к high при примерно 70% стоимости, а xhigh даёт около 1,4 пункта за 2,5 цены high.</li><li>Выше high один шаг effort может стоить как переход на старшую модель: на FrontierCode 2.0 Fable 5.2 на high набрала 45,3% против 45,5% у Opus 5.5 на max примерно за половину стоимости задачи.</li><li>Связка «Opus 5.5 руководит, до 25 исполнителей на Sonnet 5.5» на внутреннем тесте Anthropic обошлась примерно на треть дешевле одного Opus 5.5 при том же результате; советник (advisor) в замерах компании явного выигрыша не дал.</li></ul><h2>Какую модель Claude ставить на какую задачу?</h2><p>Если задача ещё не понятна, гайд советует Opus 5.5 на medium: эта модель стоит по умолчанию в Claude Code на тарифах Pro, Max, Ultra, Team, Enterprise и при работе через Anthropic API. От неё двигаются вниз, когда задача хорошо очерчена или массовая, и вверх, когда она трудная или должна долго идти без присмотра.</p><blockquote>The quick answer is that you should start most work on Opus 5.5 at its default effort level, medium.</blockquote><p>Задача, стартовая модель и effort по гайду Anthropic</p><table><thead><tr><th>Задача</th><th>Модель</th><th>Стартовый effort</th><th>Почему (объяснение Anthropic)</th></tr></thead><tbody><tr><td>Повседневная разработка и отладка, фичи на несколько pull request</td><td>Opus 5.5</td><td>medium (по умолчанию), затем high</td><td>Баланс цены и возможностей для повседневных задач</td></tr><tr><td>Классификация, маршрутизация, теги, массовое извлечение данных</td><td>Haiku 5.5</td><td>medium (по умолчанию)</td><td>Самая низкая цена и задержка в линейке</td></tr><tr><td>Субагенты, которые ищут файлы, читают логи, делают сводки</td><td>Haiku 5.5 или Sonnet 5.5</td><td>по умолчанию для модели</td><td>Ошибку легко заметить, а решения всё равно принимает главная модель</td></tr><tr><td>Чат и интерактивные сессии</td><td>Sonnet 5.5 (Haiku 5.5 для простого массового чата)</td><td>low или medium</td><td>Sonnet 5.5 быстрая, особенно на low и medium</td></tr><tr><td>Чётко очерченный код: багфиксы, доработка фич, работа по спецификации</td><td>Sonnet 5.5</td><td>medium, затем high для задач сложнее</td><td>Справляется с очерченными задачами за половину цены токенов Opus 5.5</td></tr><tr><td>Повседневные документы, слайды, таблицы</td><td>Sonnet 5.5</td><td>high (по умолчанию; в Claude Code — medium)</td><td>Быстро итерирует; сложную финансовую модель или документ из большого массива источников гайд советует начинать на Opus 5.5</td></tr><tr><td>Повторяющиеся агентные задачи: расследование, ревью, черновики</td><td>Sonnet 5.5</td><td>medium</td><td>Хорошо определённым повторяющимся задачам редко нужна модель крупнее</td></tr><tr><td>Computer use и задачи с большим числом изображений</td><td>Opus 5.5</td><td>medium</td><td>Это длинные агентные циклы по множеству скриншотов</td></tr><tr><td>Крупные рефакторинги и миграции, планирование архитектуры, управление множеством субагентов</td><td>Fable 5.2</td><td>medium, затем high (в API по умолчанию high)</td><td>Самая сильная общедоступная модель Anthropic для технических областей, по словам компании</td></tr><tr><td>Глубокие исследования, научный и количественный анализ</td><td>Fable 5.2</td><td>medium, затем high (в API по умолчанию high)</td><td>Рассчитана на самые сложные проекты в коде, финансах и науке</td></tr><tr><td>Пока не понятно</td><td>Opus 5.5</td><td>medium (по умолчанию)</td><td>Модель по умолчанию в Claude Code; документация платформы рекомендует её как отправную точку</td></tr></tbody></table><p>Оговорка из гайда: наличие чёткой спецификации само по себе не повод брать Sonnet. Миграция или оптимизация производительности могут быть описаны подробно и всё равно оказаться достаточно трудными для Opus 5.5, а крупные — для Fable 5.2. Пятая модель, Claude Mythos 5.2, в выбор не входит: она доступна только через программы верификации Anthropic. <a href="https://platform.claude.com/docs/en/about-claude/models/choosing-a-model">Страница документации о выборе модели</a> даёт ту же отправную точку: большинство нагрузок начинается с Opus 5.5.</p><h2>Сколько стоят четыре модели и чем они различаются?</h2><p>От Sonnet 5.5 к Fable 5.2 каждая ступень удваивает цену токена: Sonnet 5.5 — $2 и $10 за миллион входных и выходных токенов, Opus 5.5 — $4 и $20, Fable 5.2 — $8 и $40. Haiku 5.5 стоит $0,10 и $0,50, пока промпт не длиннее 100 тыс. токенов, то есть в 20 раз дешевле Sonnet 5.5. Это прайс-лист Claude API со <a href="https://platform.claude.com/docs/en/about-claude/pricing">страницы цен в документации</a>.</p><figure><img src="https://media.tproger.ru/user-uploads/1140448/2026-11-10/8ef8a4b9-1b73-4d84-93ad-fcaade624545.webp" alt="Столбчатая диаграмма: цена входных и выходных токенов Haiku 5.5, Sonnet 5.5, Opus 5.5 и Fable 5.2 за миллион токенов" /><figcaption>Цена за 1 млн входных и выходных токенов в Claude API, $. График: Tproger по данным Anthropic</figcaption></figure><p>Четыре модели Claude: цены и характеристики (данные Anthropic)</p><table><thead><tr><th></th><th>Haiku 5.5</th><th>Sonnet 5.5</th><th>Opus 5.5</th><th>Fable 5.2</th></tr></thead><tbody><tr><td>Для чего, по описанию Anthropic</td><td>Массовые задачи, где важна цена</td><td>Быстрая помощь с очерченными задачами</td><td>Основная модель для сложного кода и работы со знаниями</td><td>Самые амбициозные технические задачи с открытой постановкой</td></tr><tr><td>Относительная задержка</td><td>Самая низкая</td><td>Низкая</td><td>Умеренная</td><td>Умеренная</td></tr><tr><td>Вход / выход, за 1 млн токенов</td><td>$0,10 / $0,50 при промпте до 100 тыс. токенов; $0,50 / $2,50 свыше</td><td>$2 / $10</td><td>$4 / $20</td><td>$8 / $40</td></tr><tr><td>Чтение из кэша, за 1 млн токенов</td><td>$0,01 до 100 тыс.; $0,05 свыше</td><td>$0,10</td><td>$0,20</td><td>$0,20</td></tr><tr><td>Контекстное окно</td><td>1 млн токенов</td><td>1 млн токенов</td><td>1 млн токенов</td><td>1 млн токенов</td></tr><tr><td>Максимум вывода</td><td>128 тыс. токенов</td><td>128 тыс. токенов</td><td>128 тыс. токенов</td><td>128 тыс. токенов</td></tr><tr><td>Thinking в API</td><td>Адаптивный, включён по умолчанию, можно выключить</td><td>Адаптивный, включён по умолчанию; between_tools отключает начальное размышление и оставляет thinking между вызовами инструментов</td><td>Адаптивный, всегда включён</td><td>Адаптивный, всегда включён</td></tr><tr><td>Effort по умолчанию в API</td><td>medium</td><td>high (в Claude Code — medium)</td><td>medium</td><td>high (в Claude Code — medium)</td></tr><tr><td>Fast mode</td><td>Нет</td><td>Нет</td><td>Да</td><td>Да</td></tr></tbody></table><p>Три детали из таблицы влияют на счёт сильнее остальных. Первая: Haiku 5.5 — единственная модель, у которой цена зависит от длины промпта. Свыше 100 тыс. токенов тариф вырастает в пять раз, хотя и тогда остаётся вчетверо ниже цены Sonnet 5.5; на коротких промптах входные токены Haiku в 20 раз дешевле, чем у Sonnet. Если каждый вызов требует длинного промпта, гайд советует сравнивать Haiku 5.5 и Sonnet 5.5 по стоимости завершённой задачи.</p><p>Вторая: чтение из кэша у Fable 5.2 стоит столько же, сколько у Opus 5.5, — $0,20 за миллион токенов. Поэтому на длинном прогоне, где большая часть входа читается из кэша, разница между ними сводится к некэшированному входу и выходу, где Fable вдвое дороже. Третья: <a href="https://platform.claude.com/docs/en/build-with-claude/fast-mode">fast mode</a> есть только у Opus 5.5 и Fable 5.2; по документации он даёт до 2,5 раза больше выходных токенов в секунду и стоит $8 и $40 за миллион токенов у Opus 5.5 и $16 и $80 у Fable 5.2.</p><p>Как эти цены выглядят рядом с GPT, Gemini и недорогими Flash-моделями, мы разбирали в обзоре <a href="https://tproger.ru/articles/fable-5-1-gpt-6-astra-i-dewyovye-flash-chto-brat-v-api-v-sentyab">«Fable 5.1, GPT-6 Astra и дешёвые Flash: что брать в API в сентябре 2026»</a>; гайд Anthropic моделей других компаний не касается.</p><h2>Почему effort стоит менять раньше, чем модель?</h2><p>Потому что шаг effort меньше шага между моделями и по цене, и по результату. <a href="https://platform.claude.com/docs/en/build-with-claude/effort">Effort</a> — параметр запроса с пятью уровнями (low, medium, high, xhigh, max), который задаёт, сколько токенов модель тратит на размышление, вызовы инструментов и самопроверку. Гайд приводит замер Anthropic на SWE-bench Pro для Opus 5.5 относительно уровня high:</p><ul><li>medium — примерно на 2,5 пункта ниже при около 70% стоимости;</li><li>low — примерно на 8 пунктов ниже при около трети стоимости;</li><li>xhigh — примерно на 1,4 пункта выше при стоимости в 2,5 раза больше.</li></ul><p>Абсолютные значения есть в <a href="https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence">руководстве Claude Platform по стоимости и качеству</a>: на подмножестве SWE-bench Pro из 478 задач Opus 5.5 решил 87,4% на low при $0,11 за задачу, 92,8% на medium при $0,21, 95,3% на high при $0,29 и 96,7% на xhigh при $0,74. Значения для low, medium и high усреднены по двум прогонам, для xhigh прогон был один. Anthropic оговаривает, что это внутренние замеры и что баллы на подмножестве нельзя сравнивать с публичным лидербордом.</p><figure><img src="https://media.tproger.ru/user-uploads/1140448/2026-11-10/87537070-ad5f-4052-8709-ae5c765eb22d.webp" alt="Точечная диаграмма: доля решённых задач SWE-bench Pro и стоимость задачи у Opus 5.5 на уровнях effort low, medium, high и xhigh" /><figcaption>Opus 5.5 на подмножестве SWE-bench Pro (478 задач): доля решённых задач и стоимость одной задачи по уровням effort. График: Tproger по данным документации Claude Platform, замеры Anthropic</figcaption></figure><blockquote>Before you move models, try adjusting your effort level. It's a finer dial for both cost and capability.</blockquote><p>У ручки есть пределы. Более высокий effort добавляет задержку и не даёт модели знаний и навыков, которых у неё нет: за ними нужно идти на модель выше. Выше high один шаг effort может стоить как старшая модель, поэтому гайд советует в этой точке проверить следующую модель на более низком effort. Два примера из замеров Anthropic показывают это с обеих сторон. На Terminal-Bench 3.0, как описано в посте <a href="https://claude.dev/blog/spending-your-effort/">«Spending your effort»</a>, предыдущая Fable 5.1 на max набрала 58,0%, а Opus 5.5 на high — 58,9%, потратив вдвое меньше токенов. На FrontierCode 2.0 новая Fable 5.2 на high показала 45,3% против 45,5% у Opus 5.5 на max примерно за половину стоимости задачи.</p><figure><img src="https://media.tproger.ru/user-uploads/1140448/2026-11-10/6a44316c-c2c7-4ff9-86c6-b394b7194f5c.webp" alt="Горизонтальная диаграмма: Terminal-Bench 3.0 — Fable 5.1 на max 58,0% и Opus 5.5 на high 58,9%; FrontierCode 2.0 — Opus 5.5 на max 45,5% и Fable 5.2 на high 45,3%" /><figcaption>Пары «модель и effort» с близким результатом: на Terminal-Bench 3.0 Opus 5.5 на high потратил вдвое меньше токенов, на FrontierCode 2.0 Fable 5.2 на high обошлась примерно вдвое дешевле. График: Tproger по данным гайда Anthropic</figcaption></figure><blockquote>A higher price per token doesn't always mean a higher cost per task, or a better result.</blockquote><p>Когда модель не справляется, гайд предлагает три шага строго по порядку:</p><ol><li>Убедиться, что модель может проверить свою работу: тестом, сборкой или скриптом, который вызывает эндпоинт. По словам автора, это часто выгоднее и добавляет меньше задержки, чем смена effort.</li><li>Поднять effort на один уровень.</li><li>Перейти на следующую модель, начав с effort ниже, чем был на младшей.</li></ol><p>Если результат проверяется автоматически, выгоднее гонять всё на низком уровне и перезапускать на высоком только провалы. На том же подмножестве SWE-bench Pro схема «Opus 5.5 на low, неудачи повторно на high» даёт около 97% решённых задач примерно по $0,17 за задачу, тогда как прогон всех задач на high — 95,3% по $0,29. Это расчётная оценка: Anthropic посчитала её по отдельным задачам из уже проведённых прогонов на low и high, отдельно такую схему не запускали.</p><p>В API уровень задаётся полем output_config.effort; без него действует уровень по умолчанию для модели. Пример из документации:</p><p>В Claude Code уровень меняет команда /effort, а /effort status показывает текущий: по <a href="https://code.claude.com/docs/en/model-config">документации о настройке моделей</a>, значение в Claude Code может отличаться от умолчания API. Так, Sonnet 5.5 и Fable 5.2 в API стартуют на high, а в Claude Code — на medium.</p><h2>Как сочетать модели, чтобы платить меньше?</h2><p>Гайд описывает четыре приёма: менять модель на естественной паузе, отдавать побочную работу субагентам на младших моделях, подключать советника для трудных решений и раздавать объёмную работу дешёвым исполнителям. Общий принцип сформулирован так:</p><blockquote>Keep the expensive model's context for the decisions, and let cheaper subagents do the verbose reading.</blockquote><figure><img src="https://media.tproger.ru/user-uploads/1140448/2026-11-10/9a96541f-df9b-46a5-8e95-4f0ce96857bd.webp" alt="Кадр демо из гайда: Fable 5.2 переводит интернет-магазин с JavaScript на TypeScript, Opus 5.5 делает подписку, Sonnet 5.5 пишет тексты страниц, Haiku 5.5 сортирует обращения" /><figcaption>Один проект, четыре модели, каждая на своём типе работы: кадр демо из гайда. Изображение: Anthropic</figcaption></figure><p><b>Смена модели посреди работы.</b> Кэш промпта принадлежит модели, которая его записала, поэтому первый ход на новой модели оплачивается по цене записи кэша за весь разговор. Чтобы этот ход был меньше, в Claude Code перед переключением стоит выполнить /compact или начать новую сессию с коротким письменным планом, а в API — открыть разговор с новой моделью сводкой сделанного вместо полной истории. Блоки thinking тоже привязаны к модели: старшая читает блоки младших (Fable 5.2 — блоки Opus 5.5, Sonnet 5.5 и Haiku 5.5), а модель ступенью ниже прежних рассуждений не видит. Запрос при этом проходит: API исключает из него блоки, которые новая модель прочитать не может, и она работает без них. Документация советует продолжать отправлять полную историю: сами блоки в ней остаются и пропадают насовсем, только если их удалит клиент. Все случаи перечислены на странице <a href="https://platform.claude.com/docs/en/build-with-claude/preserved-thinking">«Preserved thinking»</a>.</p><p><b>Субагенты на младших моделях.</b> Субагент работает в собственном контекстном окне и возвращает сводку, а его токены оплачиваются по тарифу модели, на которой он запущен. В Claude Code модель задаётся строкой model: haiku или model: sonnet в <a href="https://code.claude.com/docs/en/sub-agents">определении субагента</a>; переменная окружения CLAUDE_CODE_SUBAGENT_MODEL задаёт умолчание для субагентов без указанной модели. Пример из гайда — файл .claude/agents/log-reader.md:</p><p>Младшим моделям гайд советует оставлять работу, где ошибку дёшево заметить: поиск файлов, запуск тестов, чтение логов. Правки кода и решения остаются на главной модели: если маленькая модель неверно прочитает результат поиска, главная откроет не тот файл и потратит на него токены. Две ловушки из гайда. Встроенный субагент Explore в текущих версиях Claude Code работает на модели сессии, а не всегда на Haiku. Исключение по документации — сессия на Fable: при подписке Claude, аккаунте Anthropic Console или шлюзе через ANTHROPIC_BASE_URL Explore идёт на модели алиаса opus, а в Amazon Bedrock, Google Cloud, Microsoft Foundry и Claude Platform on AWS остаётся на модели сессии. Чтобы разведка оставалась дешёвой, нужно определить собственного субагента с именем Explore и model: haiku. Алиас haiku указывает на Haiku 5.5 только в Anthropic API и начиная с Claude Code v2.1.293; в Amazon Bedrock, Google Cloud, Microsoft Foundry и Claude Platform on AWS он по-прежнему ведёт на Haiku 4.5. Зафиксировать модель алиаса можно переменной ANTHROPIC_DEFAULT_HAIKU_MODEL.</p><p>Алиас opusplan устроен наоборот: Opus планирует в режиме плана, Sonnet исполняет, то есть правки кода уходят на младшую модель. Автор советует измерить opusplan на своих задачах, прежде чем делать его режимом по умолчанию.</p><p><b>Советник.</b> <a href="https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool">Advisor tool</a> (бета) ставит в пару быстрого и дешёвого исполнителя и более сильного советника: исполнитель ведёт задачу и может посреди работы спросить совета, а большая часть токенов оплачивается по тарифу исполнителя. Подключается он как инструмент в запросе, пример из документации:</p><p>Про пользу советника гайд говорит сдержанно. В таблице из руководства по стоимости ни одна из четырёх пар явно не обошла своего исполнителя в одиночку. Одна из них — Opus 5.5 на high с советником Fable 5.1 на внутреннем тесте по коду: 90,1% при $2,92 за попытку, на 1,7 пункта выше одного Opus 5.5 на high примерно за 2,1 раза больше денег. Такой прирост, по оценке Anthropic, лежит на границе шума между прогонами и сопоставим с тем, что дал бы более высокий effort. Советник помогает, только когда исполнитель к нему обращается, а на низком effort это случается реже, поэтому сначала стоит измерить частоту обращений.</p><p><b>Оркестратор и исполнители.</b> Для работы, которая не помещается в одно контекстное окно, старшая модель делит задачу, раздаёт части множеству дешёвых исполнителей параллельно и сводит результаты. На внутреннем тесте Anthropic по поиску дефектов в исходном коде объёмом около 22 млн токенов Opus 5.5 во главе исполнителей на Sonnet 5.5, до 25 одновременно, обошёлся примерно на треть дешевле одного Opus 5.5 на его effort по умолчанию и набрал примерно столько же. На Claude Platform такую схему даёт <a href="https://platform.claude.com/docs/en/managed-agents/multiagent-orchestration">мультиагентная оркестрация в Claude Managed Agents</a>. Для одной цепочки зависимых шагов и для работы, которая помещается в одно окно, гайд советует её не использовать: планирование и слияние стоят больше, чем экономят.</p><h2>Что проверить перед переносом запросов на другую модель?</h2><p>Заменить имя модели и больше ничего не трогать получается не всегда. Все текущие модели поддерживают вызов инструментов и изображения на входе, но гайд перечисляет различия, которые нужно протестировать заранее:</p><ul><li><b>История запросов и Fable 5.2.</b> API отвечает ошибкой 400, если изменилось что-либо перед блоком thinking от Fable 5.2: системный промпт, инструменты или более раннее сообщение. Исключение — явное согласие отбрасывать затронутые блоки. Если запросы собирают Claude Code, Claude Agent SDK или Claude Managed Agents, менять ничего не нужно; если историю редактирует ваш код, её стоит держать только дополняемой.</li><li><b>Thinking.</b> Opus 5.5 и Fable 5.2 думают всегда, запрос с отключённым thinking вернёт ошибку. У Sonnet 5.5 режим between_tools ограничивает размышления промежутками между вызовами инструментов; по документации он работает на effort low, medium и high, а на xhigh и max запрос с ним вернёт ошибку 400. У Haiku 5.5 thinking можно выключить на effort не выше high. Блоки ответа нужно читать по полю type: ответ может начинаться с блока thinking.</li><li><b>Принудительный вызов инструмента.</b> tool_choice со значением any или tool возвращает ошибку 400 на Sonnet 5.5, Opus 5.5 и Fable 5.2. Вместо этого гайд советует отправлять auto, помечать инструмент strict: true и писать в промпте, когда его применять.</li><li><b>Переход с Haiku 4.5 на Haiku 5.5.</b> budget_tokens заменяется уровнем effort; нестандартные temperature, top_p и top_k возвращают ошибку 400, как и история, которая заканчивается ходом ассистента для продолжения.</li><li><b>Защитные откаты.</b> У Opus 5.5, Sonnet 5.5 и Fable 5.2 работают классификаторы безопасности, которые чаще всего срабатывают на темы кибербезопасности и биологии. В Claude Code помеченный запрос может быть перезапущен на более старой модели с уведомлением в транскрипте.</li></ul><p>Если в одной системе работают несколько моделей, гайд советует собирать каждый запрос под самую строгую из них: история только дополняется, tool_choice: auto со строгими инструментами, чтение блоков по типу, точные промпты и описания инструментов. Тогда шаг можно перевести на ступень выше или ниже без правки кода.</p><h2>Как измерить всё это на своих задачах?</h2><p>Опубликованные результаты, по словам автора, дают только стартовую модель; дальше кандидатов нужно проверять на собственной работе. Порядок из гайда:</p><ol><li>Собрать выборку реальных задач и написать для каждой проверку результата: проходящий тест, закрытый тикет, верное число строк.</li><li>Прогнать каждую модель-кандидата на двух-трёх уровнях effort, каждый прогон в отдельной сессии, чтобы они не делили кэш. Стоимость каждой завершённой задачи записывать из поля usage ответов.</li><li>Построить график «результат против расходов». Связку из нескольких моделей оставлять, только если она лучше любой точки с одной моделью.</li><li>Перед переключением запустить победителя в теневом режиме на части реального трафика.</li></ol><p>При сравнении двух моделей гайд советует считать отдельно самые трудные задачи набора: на них приходится большая часть расходов. В одном прогоне из 20 поисковых задач две задачи дали 43% всех трат. Быстрая проверка в Claude Code: выполнить одну задачу из бэклога на двух моделях, переключая их командой /model, и сравнить отчёты /usage. Другие способы сократить счёт из того же руководства Claude Platform мы пересказывали в новости <a href="https://tproger.ru/news/anthropic-pokazala-kak-srezat-schyot-za-claude-bez-poteri-kachest">«Anthropic показала, как срезать счёт за Claude без потери качества»</a>.</p><h2>Что показывает независимый замер?</h2><p>Цифры гайда получены самой Anthropic, и результатов моделей других компаний в нём нет. Из независимых данных на 9 ноября есть <a href="https://x.com/ArtificialAnlys/status/2119878995386982508">замер Artificial Analysis</a>: Fable 5.2 на effort max набрала 65 баллов в Intelligence Index v5 при средней стоимости $26,5 за задачу, примерно в 2,6 раза больше, чем у Opus 5.5 на max ($10,0, 59 баллов). На high и xhigh у Fable 5.2 62 балла при 98 тыс. выходных токенов на задачу против 173 тыс. у Opus 5.5 на max. Вывод Artificial Analysis совпадает с логикой гайда: на max Fable 5.2 заметно дороже, а на более низких уровнях effort может обойти Opus 5.5 при меньшей стоимости задачи. Как устроен сам индекс, мы писали в новости <a href="https://tproger.ru/news/artificial-analysis-obnovila-intelligence-index-do-v5-novye-tes">«Artificial Analysis обновила Intelligence Index до v5»</a>.</p><p>Результаты бенчмарков Fable 5.2 Anthropic держит на <a href="https://www.anthropic.com/claude/fable">странице модели</a>. Предыдущий гайд команды, о циклах в Claude Code, мы разбирали в статье <a href="https://tproger.ru/articles/claude-code-nauchilsya-rabotat-v-ciklah-razbiraem-oficialnyj-ga">«Claude Code научился работать в циклах: разбираем официальный гайд Anthropic»</a>. Цены и умолчания в тексте действительны на 9 ноября 2026 года; у Anthropic они меняются с выходом каждой модели, поэтому перед расчётом бюджета стоит сверяться со страницей цен.</p><p>Источники: <a href="https://claude.dev/blog/which-claude-model-should-you-build-with/">Anthropic: Which Claude model should you build with? Fable, Opus, Sonnet, or Haiku</a>, <a href="https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence">Claude Platform: Optimizing for cost and intelligence</a>, <a href="https://platform.claude.com/docs/en/build-with-claude/effort">Claude Platform: Effort</a>, <a href="https://platform.claude.com/docs/en/about-claude/pricing">Claude Platform: Pricing</a>, <a href="https://platform.claude.com/docs/en/about-claude/models/choosing-a-model">Claude Platform: Choosing a model</a>, <a href="https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool">Claude Platform: Advisor tool</a>, <a href="https://platform.claude.com/docs/en/build-with-claude/preserved-thinking">Claude Platform: Preserved thinking</a>, <a href="https://platform.claude.com/docs/en/build-with-claude/fast-mode">Claude Platform: Fast mode</a>, <a href="https://code.claude.com/docs/en/model-config">Claude Code: Model configuration</a>, <a href="https://code.claude.com/docs/en/sub-agents">Claude Code: Subagents</a>, <a href="https://claude.dev/blog/spending-your-effort/">Anthropic: Spending your effort</a>, <a href="https://www.anthropic.com/claude/fable">Anthropic: страница Claude Fable 5.2</a>, <a href="https://x.com/ArtificialAnlys/status/2119878995386982508">Artificial Analysis: замер Claude Fable 5.2, 9 ноября 2026 года</a></p><p>Изображение на обложке: Anthropic</p>]]></content:encoded>
    </item>
    <item>
      <title>Как научить HAProxy снижать на проблемный backend</title>
      <link>https://tproger.ru/articles/kak-nauchit-haproxy-snizhat-na-problemnyj-backend</link>
      <comments>https://tproger.ru/articles/kak-nauchit-haproxy-snizhat-na-problemnyj-backend?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Руслан Шакиров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-nauchit-haproxy-snizhat-na-problemnyj-backend</guid>
      <description><![CDATA[<p>Как повысить отказоустойчивость Directum RX: health-agent оценивает состояние backend-узлов и передает HAProxy рекомендации по их весу. Узнайте, как мягко снижать нагрузку на деградировавшие серверы и исключать недоступные из балансировки.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-nauchit-haproxy-snizhat-na-problemnyj-backend">Как научить HAProxy снижать на проблемный backend</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[dev]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 06 Nov 2026 10:30:23 GMT</pubDate>
      <content:encoded><![CDATA[<p><i>Два
backend-узла Directum RX сами по себе еще не гарантируют отказоустойчивость.
Один из них может продолжать отвечать на HTTP-запросы с кодом 200, одновременно
испытывая нехватку памяти, перегрузку CPU или проблемы с отдельными сервисами.
В этот момент обычная проверка доступности продолжает считать узел исправным и
направлять на него пользовательский трафик. В статье расскажем, как реализовать
health-agent, который помогает HAProxy учитывать не только доступность, но и
фактическую степень деградации backend-узла.</i></p><h2>Когда HTTP 200 уже недостаточно</h2><p>При построении отказоустойчивого контура Directum RX недостаточно просто развернуть несколько экземпляров приложения и поставить перед ними балансировщик нагрузки. Нужно понимать, способен ли конкретный узел нормально обрабатывать запросы в конкретный момент времени.</p><p>Классический health-check отвечает на бинарный вопрос: сервис доступен или нет. Например, HAProxy отправляет HTTP-запрос на заданный URL и, получив ожидаемый код ответа, считает backend работоспособным. Если проверка не проходит, узел исключается из балансировки.</p><p>Но между состояниями «полностью исправен» и «полностью недоступен» есть промежуточная зона. Узел может продолжать отвечать HTTP 200 и при этом:</p><ul><li>находиться под высокой загрузкой CPU;</li><li>испытывать нехватку оперативной памяти;</li><li>активно использовать swap;</li><li>иметь заканчивающееся место на диске или inode;</li><li>потерять связь с PostgreSQL;</li><li>частично потерять связь с RabbitMQ;</li><li>иметь недоступный PreviewService, IntegrationService или LogService;</li><li>содержать контейнер Directum RX в состоянии Restarting или Exited.</li></ul><p>Обычная проверка доступности не различает такие состояния. Для нее backend либо работает, либо нет. Поэтому при частичной деградации балансировщик может продолжать отправлять на проблемный узел столько же запросов, сколько и на исправный.</p><p>Именно для этой задачи появился проект Self-Healing Directum RX.</p><h2>Что было предложено</h2><p>Текущая версия проекта — v0/MVP, реализованная в виде Bash health-agent. Ее задача не в том, чтобы самостоятельно перезапускать каждый проблемный компонент, а в том, чтобы дать HAProxy более точную информацию о состоянии backend-узла.</p><p>RX-health-agent работает непосредственно на backend-узлах, выполняет локальные и сетевые проверки, объединяет результаты и передает итоговое состояние HAProxy через механизм agent-check.</p><p>В результате балансировщик получает не только сигнал «сервер доступен или недоступен», но и рекомендацию по весу backend-а:</p><table><thead><tr><th>Состояние</th><th>Реакция</th></tr></thead><tbody><tr><td>Норма</td><td>backend работает с весом 100%</td></tr><tr><td>Мягкая деградация</td><td>вес backend-а уменьшается до 75% или 50%</td></tr><tr><td>Критический отказ</td><td>backend переводится в down и исключается из балансировки</td></tr><tr><td>Плановое обслуживание</td><td>используется maint</td></tr><tr><td>Мягкий административный вывод</td><td>используется drain</td></tr><tr><td>Восстановление</td><td>узел проходит recovery window и возвращается к рабочему весу</td></tr></tbody></table><p>Такой подход позволяет не отключать backend полностью при каждой проблеме. Если узел еще способен обслуживать запросы, но давать ему полную нагрузку уже нежелательно, HAProxy снижает его вес и отдает предпочтение более здоровому серверу.</p><h2>Что проверяет health-agent</h2><p>В версии v0 реализованы проверки:</p><ul><li>проверка доступности ключевых HTTP endpoint Directum RX;</li><li>проверка /client/api/health;</li><li>проверка /client/health;</li><li>проверка StorageService;</li><li>проверка PreviewService;</li><li>проверка IntegrationService;</li><li>проверка LogService;</li><li>проверка состояния контейнеров Directum RX;</li><li>проверка доступности Docker daemon;</li><li>проверка свободного места на файловой системе;</li><li>проверка inode;</li><li>проверка CPU и load average;</li><li>проверка RAM;</li><li>проверка swap;</li></ul><p>Кроме того, агент:</p><ul><li>формирует причину деградации;</li><li>рассчитывает итоговый вес узла;</li><li>поддерживает мягкую деградацию без полного отключения backend-а;</li><li>позволяет вручную перевести узел в maintenance;</li><li>поддерживает режим drain;</li><li>использует recovery window перед полноценным возвратом backend-а в балансировку.</li></ul><p>При этом уже сейчас важно четко обозначить границу возможностей это версии.</p><p>Health-agent не является системой общего мониторинга и не заменяет HAProxy, Keepalived, Patroni, RabbitMQ или решение «Мониторинг Directum RX». Его задача — максимально быстро принять решение о пригодности конкретного RX backend-а для дальнейшей обработки пользовательского трафика.</p><h2>Архитектура тестового стенда</h2><p>Для разработки и тестирования проекта развернут отдельный стенд Directum RX 26.1 на РЕД ОС 8.</p><figure><img src="https://media.tproger.ru/user-uploads/1140646/2026-11-03/ceea5eb3-59b3-4b1f-8973-8823bb9ce4cd.webp" alt="" /></figure><p>В составе стенда для первой версии агента используются следующие группы узлов.</p><table><thead><tr><th>Узел</th><th>Назначение</th><th>Минимальные ресурсы</th></tr></thead><tbody><tr><td>dev-ddc-hap-01</td><td>HAProxy + Keepalived, node 1</td><td>2 vCPU, 4 ГБ RAM</td></tr><tr><td>dev-ddc-hap-02</td><td>HAProxy + Keepalived, node 2</td><td>2 vCPU, 4 ГБ RAM</td></tr><tr><td>dev-ddc-rx261a</td><td>Directum RX 26.1
  backend 1</td><td>6 vCPU, 16 ГБ RAM</td></tr><tr><td>dev-ddc-rx261b</td><td>Directum RX 26.1 backend 2</td><td>6 vCPU, 16 ГБ RAM</td></tr></tbody></table><p><br /></p><p>Для кластера
балансировки используются два HAProxy-узла и Keepalived. Пользовательский трафик поступает на виртуальный IP и далее распределяется между backend-узлами Directum RX.</p><p>Для
взаимодействия HAProxy с health-agent используется TCP-порт 9505.</p><h2>Кто за что
отвечает</h2><p>В
текущей архитектуре важно не смешивать функции 3-х компонентов.</p><h2>rx-health-agent</h2><p>Агент
работает в контексте backend-узла Directum RX и оценивает:</p><p>·       
состояние
самого RX;</p><p>·       
состояние
контейнерной среды;</p><p>·       
ресурсы
операционной системы.</p><p>Результатом
становится агрегированное состояние узла, например 100%, 75% или 50%, down, maint или drain.</p><h2>HAProxy</h2><p>HAProxy
выполняет две проверки:</p><p>·       
штатный
HTTP health-check конкретного сервиса Directum RX;</p><p>·       
получение
дополнительного состояния backend-а через agent-check.</p><p>Именно HAProxy принимает окончательное решение
о доступности узла и его весе в балансировке.</p><h2>Keepalived</h2><p>Keepalived отвечает не за отдельный backend
Directum RX, а за доступность самого слоя балансировки. Если первый
HAProxy-узел перестает выполнять свою функцию, Keepalived должен переключить
виртуальный IP на второй HAProxy.</p><p>Проверку состояния HAProxy и Keepalived не
следует смешивать с проверками RX health-agent. Для балансировщиков планируется
отдельный локальный механизм.</p><h2>Как
устроена версия v0</h2><p>Health-agent
устанавливается непосредственно на backend-узлы Directum RX. В тестовом контуре
это dev-ddc-rx261a
и dev-ddc-rx261b.
Для взаимодействия с HAProxy
используется TCP-порт
9505.</p><p><b>Состав файлов</b></p><p>Основной сценарий
агента располагается в:</p><p>Конфигурационный файл:</p><p>Текущее состояние
агента сохраняется в:</p><p>Для
административного управления backend-узлом дополнительно используются marker-файлы:</p><p>Режимы maintenance, drain и механизм recovery
уже входят в возможности Bash-версии v0.</p><figure><img src="https://media.tproger.ru/user-uploads/1140646/2026-11-03/4967d9fd-1140-4675-b345-440d9fe20869.webp" alt="" /></figure><p>В конфигурации задаются проверяемые endpoint-ы
Directum RX, допустимые HTTP-коды, таймауты, пороги ресурсов операционной
системы и параметры инфраструктурных проверок.</p><p>Для Client API используется
endpoint:</p><p>с ожидаемым HTTP-кодом 200.</p><p>Отдельные warning- и critical-пороги предусмотрены для диска, inode, CPU/load average, RAM и swap.</p><p>Основная логика v0 реализована на Bash. За один
вызов агент выполняет проверки, определяет найденные проблемы и формирует
итоговое решение для HAProxy. Затем результат передается через systemd socket
activation на TCP-порту 9505.</p><p>Для подключения к HAProxy используются agent-check и отдельный период
проверки agent-inter.</p><p>После изменения конфигурации HAProxy она проверяется командой:</p><p>После успешной проверки конфигурацию можно применить через:</p><p><b>Политика для
сервисов Directum RX</b></p><p>Для разных компонентов используются разные
реакции на отказ:</p><table><thead><tr><th>Проверка</th><th>Что контролируется</th><th>Реакция</th></tr></thead><tbody><tr><td>Client API</td><td>/client/api/health</td><td>down</td></tr><tr><td>Web
  Client</td><td>/client/health</td><td>down</td></tr><tr><td>StorageService</td><td>/storage/health</td><td>down</td></tr><tr><td>PreviewService</td><td>/preview/health</td><td>50%</td></tr><tr><td>IntegrationService</td><td>/integration/health</td><td>50%</td></tr><tr><td>LogService</td><td>/log/health</td><td>75%</td></tr><tr><td>Docker</td><td>daemon и состояние контейнеров</td><td>50% / down</td></tr><tr><td>CPU / Load</td><td>нагрузка операционной системы</td><td>50% / down</td></tr><tr><td>RAM</td><td>использование памяти</td><td>50% / down</td></tr><tr><td>Swap</td><td>использование swap</td><td>50%</td></tr><tr><td>Disk</td><td>заполнение файловой системы</td><td>50% / down</td></tr><tr><td>Inode</td><td>доступные inode</td><td>50% / down</td></tr></tbody></table><p>На выходе агент может сформировать несколько состояний.</p><table><thead><tr><th>Результат</th><th>Значение</th></tr></thead><tbody><tr><td>100%</td><td>узел полностью работоспособен</td></tr><tr><td>75%</td><td>небольшая деградация</td></tr><tr><td>50%</td><td>существенная деградация</td></tr><tr><td>down</td><td>узел необходимо исключить</td></tr><tr><td>maint</td><td>плановое обслуживание</td></tr><tr><td>drain</td><td>мягкий административный вывод</td></tr><tr><td>up / ready</td><td>переходное состояние
  восстановления</td></tr></tbody></table><p>Client API, Web Client и
StorageService считаются
критичными. Если
проверка одного из них не проходит, backend исключается из балансировки.</p><p>PreviewService
и IntegrationService переводят узел в состояние с весом 50%, а LogService — с
весом 75%. Пользовательский трафик продолжает обслуживаться обоими серверами,
но HAProxy отдает предпочтение полностью исправному backend-у.</p><h2>Административные
режимы</h2><p>Для планового вывода узла используется режим maintenance:</p><p>После этого агент возвращает состояние maint, а HAProxy переводит
backend в MAINT.</p><p>После окончания работ marker-файл удаляется:</p><p>Для более мягкого вывода используется режим drain:</p><p>touch /var/lib/rx-health-agent/drain</p><p>В
этом случае агент возвращает drain,
а HAProxy не должен направлять на backend новые обычные запросы.</p><p>После окончания работ файл также удаляется:</p><p>В
v0 предусмотрен и recovery window. После состояния down агент не сразу
возвращает backend к полной нагрузке. Сначала узел проходит переходное
состояние восстановления, после чего возвращается к рабочему весу.</p><p>Это
снижает риск ситуации, когда недавно восстановившийся сервер мгновенно получает
весь доступный объем трафика.</p><figure><img src="https://media.tproger.ru/user-uploads/1140646/2026-11-03/a609e064-4c7f-43d8-8e38-cc9f23313a70.webp" alt="" /></figure><p>Пример мягкого вывода с помощью drain</p><figure><img src="https://media.tproger.ru/user-uploads/1140646/2026-11-03/fe0a2cd4-2440-48b7-a889-fabd02d485e2.webp" alt="" /></figure><p>Пример мягкого вывода с помощью recovery window</p><h2>Как проверять
работу</h2><p>На
стенде проверяются три сценария: деградация из-за ресурсов, полный отказ
критичного компонента и частичный отказ отдельного сервиса.</p><p><b>Сценарий 1: Высокая загрузка CPU</b></p><p>Приложение
может продолжать отвечать HTTP 200, хотя сервер уже находится под высокой
нагрузкой. Для теста на RX-узле создается CPU-нагрузка:</p><p>Агент контролирует load average и при превышении
warning-порога уменьшает вес backend-а.</p><p>Ожидаемый результат:</p><p>При этом первый сервер не переводится в DOWN: он
продолжает работать, но HAProxy начинает отдавать предпочтение второму
backend-у.</p><figure><img src="https://media.tproger.ru/user-uploads/1140646/2026-11-03/5591fa13-f595-4742-9461-57e17a450c91.webp" alt="" /></figure><p>HAProxy Stats во время CPU-теста</p><h2>Сценарий 2: Остановка
критичного контейнера</h2><p>Второй сценарий —
отказ компонента, без которого RX backend уже нельзя считать нормально
работоспособным.</p><p>На одном из RX-узлов останавливаем нужный критичный
контейнер:</p><p>Его состояние можно проверить командой:</p><p>Если
контейнер Web Client или другого критичного компонента переходит в Exited либо другое
проблемное состояние, соответствующий health-check перестает проходить. Backend
переводится в down,
а трафик продолжает обслуживаться вторым RX-узлом.</p><p>Ожидаемое состояние:</p><figure><img src="https://media.tproger.ru/user-uploads/1140646/2026-11-03/2d729f8e-e3c8-471f-bc4c-f748c68f239f.webp" alt="" /></figure><p>HAProxy Stats после остановки контейнера веб-сервера</p><p>После завершения теста контейнер запускается обратно:</p><p>После успешных проверок и прохождения recovery window
backend возвращается в балансировку.</p><h2>Сценарий 3: Отказ
PreviewService</h2><p>Не каждый отказ должен приводить к полному отключению узла.
Для PreviewService используется
endpoint:</p><p>Если проверка перестает проходить, backend не переводится в
down. Вместо
этого агент уменьшает его вес до 50%:</p><p>Оба
сервера продолжают обслуживать трафик, но HAProxy отдает предпочтение полностью
исправному backend-у.</p><h2>Почему для v0
выбрали Bash</h2><p>На
первом этапе нужно было быстро проверить саму концепцию: можно ли использовать
фактическое состояние RX-узла для динамического управления балансировкой.</p><p>Для
этого Bash оказался достаточным. Необходимые данные уже доступны штатными
средствами Linux:</p><p>·       
HTTP-проверки
выполняются через curl;</p><p>·       
состояние
файловой системы получают через df;</p><p>·       
сведения
о памяти — через free;</p><p>·       
load average — из /proc;</p><p>·       
состояние
контейнеров — командами Docker.</p><p>Bash-агент
не требует тяжелого runtime и может быть размещен непосредственно на RX-узле.
Сценарий легко изменить, проверить через bash
-n, выполнить на сервере и сопоставить результат с состоянием
HAProxy.</p><p>Для
MVP этого оказалось достаточно. При этом Bash-версия рассматривается именно как
v0 и проверка работоспособности идеи, а не как финальная реализация. По мере
усложнения логики становятся важными история состояний, сложные API, статистика
за временное окно и дополнительные механизмы стабилизации.</p><h2>Что планируется
дальше</h2><p>В
следующих версиях планируется:</p><p>·       
развить
более глубокую диагностику RabbitMQ и PostgreSQL;</p><p>·       
учитывать
время ответа сервисов;</p><p>·       
анализировать
HTTP-ошибки за временной интервал;</p><p>·       
хранить
историю состояний;</p><p>·       
улучшить
защиту от частого изменения веса;</p><p>·       
реализовать
полноценную проверку очередей RabbitMQ и SQL-проверка PostgreSQL;</p><p>·       
рассчитывать
p95/p99 времени ответа HTTP-сервисов.</p><p>Следующая версия должна сохранить основную идею
v0 — быстро формировать понятное решение для HAProxy, — но использовать больше
данных для определения фактической деградации.</p><h2>Наши
рекомендации</h2><p>При построении отказоустойчивого контура не
ограничивайтесь проверкой доступности приложения: заранее определите, какие
компоненты являются критичными, какие проблемы допускают мягкую деградацию, а
какие требуют полного исключения узла из балансировки. Начинайте с минимального
набора проверок и понятной матрицы реакций, тестируйте каждое состояние на
стенде и отделяйте health-check от общего мониторинга и автоматического восстановления.
Такой подход позволяет сначала проверить саму логику маршрутизации трафика, а
затем последовательно расширять self-healing без преждевременного усложнения
архитектуры.</p>]]></content:encoded>
    </item>
    <item>
      <title>Images 2.6 от OpenAI: GIF и SVG в API, а картинки на low в 4 раза дороже</title>
      <link>https://tproger.ru/news/images-2-6-ot-openai-gif-i-svg-v-api-a-kartinki-na-low-v-4-raz</link>
      <comments>https://tproger.ru/news/images-2-6-ot-openai-gif-i-svg-v-api-a-kartinki-na-low-v-4-raz?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/images-2-6-ot-openai-gif-i-svg-v-api-a-kartinki-na-low-v-4-raz</guid>
      <description><![CDATA[<p>Images 2.6 работает в ChatGPT и Codex, в API вышли GPT-Image-2.6 Flare и Sunburst. Ставка за токен как у 2.5, но картинка на low стоит в 4,2 раза дороже.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/images-2-6-ot-openai-gif-i-svg-v-api-a-kartinki-na-low-v-4-raz">Images 2.6 от OpenAI: GIF и SVG в API, а картинки на low в 4 раза дороже</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Нейронные сети]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 05 Nov 2026 15:19:35 GMT</pubDate>
      <content:encoded><![CDATA[<p>OpenAI 4 ноября 2026 года <a href="https://openai.com/index/introducing-images-2-6/">выпустила</a> Images 2.6 — новую версию генератора изображений для ChatGPT, Codex и API. Для пользователя ChatGPT это анимированные GIF и сохранённые референсы, для разработчика — две модели GPT-Image-2.6 Flare и Sunburst с экспортом в SVG, разметкой правок и новым параметром complexity.</p><p>Главное, что стоит проверить до смены модели в коде: ставка за токен осталась как у GPT-Image-2.5, но калькулятор в документации OpenAI умножает число выходных токенов у 2.6 на 4,2 при quality=low и на 3,3 при medium — картинка 1024x1024 на low дорожает с $0,0059 до $0,0247. Кроме того, у новых моделей нет Batch API и датированного снапшота. Ниже — что изменилось, как OpenAI мерила скорость, сколько стоит картинка у конкурентов и что делать тем, кто сидит на 2.5.</p><ul><li>Images 2.6 доступна с 4 ноября в ChatGPT и Codex на всех тарифах; в API — gpt-image-2.6-flare и gpt-image-2.6-sunburst.</li><li>OpenAI заявляет генерацию «на 50% быстрее»; в демо компании Flare на quality=low уложилась в 4,84 с против 7,08 с у 2.5 Flare — это 46% прироста скорости.</li><li>Ставки за токен те же, что у 2.5 ($8 за 1 млн входных и $30 за 1 млн выходных токенов изображения), но по калькулятору OpenAI картинка 1024x1024 на quality=low стоит $0,0247 против $0,0059 у 2.5 (в 4,2 раза), на medium — $0,0435 против $0,0132 (в 3,3 раза); high и выше без изменений.</li><li>В API добавили GIF (2–16 кадров), SVG, разметку правок и параметр complexity (low, medium, high; по умолчанию high).</li><li>Batch API и датированного снапшота у 2.6 пока нет; в России ChatGPT и API OpenAI официально недоступны.</li></ul><h2>Что именно ускорилось и как это мерили</h2><p>В <a href="https://openai.com/index/introducing-images-2-6/">анонсе</a> OpenAI пишет, что Images 2.6 «генерирует изображения на 50% быстрее, чем раньше» (перевод редакции). Методику компания не раскрывает: ни набора промптов, ни режима качества, ни того, по какой метрике считались проценты. Единственный замер, который опубликовала сама компания, — демо-ролик в том же анонсе: одна и та же задача (реклама путешествий, «Luxury Travel Ad») на quality=low у GPT-Image-2.5 Flare занял 7,08 с, у GPT-Image-2.6 Flare — 4,84 с. Таймеры, как подписано в ролике, показывают реальное время API-запроса при ускоренном воспроизведении.</p><figure><img src="https://media.tproger.ru/user-uploads/1140448/2026-11-05/9ee37efb-9b50-4f7e-98ff-f22a702521d5.webp" alt="Кадр демо OpenAI: GPT-Image-2.5 Flare 7,08 с и GPT-Image-2.6 Flare 4,84 с на одной задаче" /><figcaption>Замер из анонса OpenAI: одна задача, quality=low, воспроизведение ускорено в 8 раз, 7,08 с у 2.5 Flare против 4,84 с у 2.6 Flare. Изображение: OpenAI</figcaption></figure><p>Эти два числа дают 46% прироста скорости (7,08 / 4,84), как и написано на самом ролике, или сокращение времени ожидания на 32%. Это один пример, а не бенчмарк, и он не подтверждает ровно «50%» для любого запроса. В документации OpenAI отдельно предупреждает, что сложные промпты по-прежнему могут обрабатываться до 2 минут.</p><p>Flare и Sunburst — две модели одной версии с разным назначением, по описанию OpenAI. Flare рассчитана на быстрые итерации: при quality=low она «может генерировать изображения всего за шесть секунд», а ещё, по словам компании, лучше верстает постеры и продуктовые картинки. Sunburst — для детальной работы: при quality=medium и high она даёт более высокое качество и лучше сохраняет детали между правками. Из этого позиционирования, по нашей оценке, следует простое правило: черновики и перебор вариантов — Flare на low; финальные картинки, где важны текст, композиция и повторяемость персонажа или продукта от правки к правке, — Sunburst на medium или high. Независимого сравнения двух моделей на одинаковой выборке пока нет.</p><h2>Что нового в API: GIF, SVG, разметка и complexity</h2><p>Все четыре новшества описаны в <a href="https://developers.openai.com/api/docs/guides/image-generation">руководстве по генерации изображений</a>. Анимированный GIF запрашивается через POST /v1/images/generations с output_format: "gif"; движение и зацикливание описываются в промпте. Параметры: frame_count от 2 до 16 кадров (по умолчанию 9) и frame_duration_ms от 20 до 2000 мс на кадр (по умолчанию 200). GIF не поддерживает стриминг и частичные изображения, а эндпоинт правок GIF не возвращает. В ChatGPT ту же функцию подают как анимацию маскота, персонажа или простого наброска.</p><p>SVG включается через output_format: "svg" на том же эндпоинте генерации, обязательно с n: 1. Модель сначала рисует растровый референс (его качество задаёт quality), а затем языковая модель пишет по нему векторный файл — поэтому в ответе приходит base64 с UTF-8 XML, который надо сохранить как .svg. Документ статичный: без скриптов, внешних ресурсов и встроенного растра. Правки в SVG не поддерживаются, и SVG нельзя подать на вход эндпоинту правок. Платится и растровый референс по ставке модели изображений, и токены языковой модели, которая пишет векторный код.</p><p>Разметка правок (image markup) пришла в API из ChatGPT: к запросу POST /v1/images/edits прикладывается отдельный прозрачный PNG того же размера, что исходник, с кружками или штрихами там, где нужна правка, а описание самой правки идёт в prompt. Пример из документации OpenAI — перекрасить вазу, обведённую красным кружком:</p><p>Параметр complexity управляет тем, «сколько модель планирует перед рендером»: значения low, medium и high, отдельной платы за него нет. Низкий уровень подходит для точечных правок вроде замены фона или вывески, высокий помогает с плотным текстом, сложной вёрсткой и взаимным расположением объектов, но, по предупреждению OpenAI, увеличивает задержку и может внести нежелательные изменения. Важная деталь: если параметр не указан, обе модели работают на high. В анонсе компания советует для большинства правок ставить complexity=low, а качество подбирать под задачу. Это два независимых параметра: quality отвечает за рендер, complexity — за планирование.</p><p>Запрос выше собран из полей документации OpenAI: complexity задан явно, чтобы не использовать high по умолчанию, а quality=low выбран для примера. Ответ сначала сохраняется в файл, чтобы посмотреть поле usage — именно по нему видно, сколько токенов ушло на картинку.</p><h2>Сколько стоит картинка у OpenAI и конкурентов</h2><p>По <a href="https://developers.openai.com/api/docs/pricing#image-generation">прайсу OpenAI</a> на 5 ноября 2026 года обе модели 2.6 стоят ровно столько же, сколько 2.5 Flare и Sunburst: $8 за 1 млн входных токенов изображения, $30 за 1 млн выходных, $2 за кэшированный вход; текстовый вход — $5 за 1 млн токенов. Но ставка за токен и цена картинки — разные вещи. Калькулятор в той же документации для GPT-Image-2.6 на quality=low и размере 1024x1024 показывает 823 выходных токена ($0,0247), тогда как для 2.5 при тех же настройках — 196 токенов ($0,0059). Редакция посмотрела код калькулятора: для модели 2.6 он умножает расчётное число токенов на фиксированные коэффициенты — 4,2 для low, 3,3 для medium и 1 для high, xhigh и max. На medium выходит 1449 токенов ($0,0435) против 439 ($0,0132) у 2.5, на high — 1756 токенов ($0,0527) у обеих версий. В прайсе и анонсе OpenAI об этом не говорится ни слова; объяснения, почему дешёвые режимы стали дороже, компания не дала.</p><figure><img src="https://media.tproger.ru/user-uploads/1140448/2026-11-05/5511293c-9e5a-4a04-a0d5-ad0c45486957.webp" alt="Диаграмма: цена одной картинки 1024x1024 в API у OpenAI, Google, xAI и BytePlus" /><figcaption>Оценка стоимости выходной генерации одной картинки по прайсам на 5 ноября 2026 года (у OpenAI, Google и xAI — 1024x1024, у Seedream размер на странице продукта не указан); входные токены и доплаты не учтены, у OpenAI и Google цена выведена из числа выходных токенов, у xAI и BytePlus — фиксированная за изображение. Источник данных: OpenAI, Google, xAI, BytePlus; расчёт Tproger</figcaption></figure><p>Для сравнения взяты официальные прайсы на ту же дату. Google в <a href="https://ai.google.dev/gemini-api/docs/pricing">прайсе Gemini API</a> считает картинку 1K у Nano Banana 2.1 как 1120 токенов по $30 за миллион — $0,0336; у Gemini 3.1 Flash Image (Nano Banana 2) те же 1120 токенов стоят $60 за миллион — $0,067; у Gemini 3 Pro Image (Nano Banana Pro) — $0,134 за 1K или 2K; старая Gemini 2.5 Flash Image — $0,039. xAI по <a href="https://docs.x.ai/docs/models">таблице моделей</a> берёт за Grok Imagine Image 2.0 от $0,04 за 1K на quality=low до $0,08 за 2K на medium. BytePlus на <a href="https://ai.byteplus.com/product/Seedream">странице Seedream 5.0 Pro</a> указывает «от $0,045 за изображение», первый референс бесплатно, следующие от $0,003 (рядом на той же странице — скидки для новых клиентов, в сравнении они не учтены). По базовым ставкам за выходную генерацию GPT-Image-2.6 на low дешевле перечисленных конкурентов, а 2.5 на low — ещё в 4 раза дешевле; но качество, тарифные условия и состав счёта у всех различаются, и сравнивать их напрямую можно только после прогона своих промптов.</p><p>С реальной стоимостью как раз и возник первый спор. Участник форума разработчиков OpenAI _j (отображаемое имя Jay) <a href="https://community.openai.com/t/images-upgraded-introducing-chatgpt-images-2-6/1412901/3">опубликовал</a> замер на одном промпте: GPT-Image-2.5 на quality=medium вернула 344 выходных токена, GPT-Image-2.6 на том же medium — 1136. Его вывод (перевод редакции): «quality: low и medium дают существенно больший счёт за выходные токены, чем gpt-image-2.5. Похоже, это сделано исключительно для того, чтобы нельзя было делать дешёвые картинки, — множитель цены, а не алгоритм». По его оценке, low стал дороже в 4,2 раза, medium — в 3,3, high и выше — без изменений. Его замер — один промпт, но коэффициенты совпадают с теми, что зашиты в калькулятор OpenAI, так что это не случайность; сама компания замер не комментировала.</p><p>Габриэль Анайя, Go-разработчик и автор блога на DEV Community, <a href="https://dev.to/gabrielanhaia/gpt-image-26-outputs-svg-and-gifs-unlike-25-you-cant-run-it-through-batch-47pf">обращает внимание</a> на другое ограничение: страница модели 2.6 Flare не поддерживает Batch, а у 2.5 Flare батч есть с выходными токенами по $15 за миллион вместо $30. «Паритет по токенам ещё не значит паритет по картинке» и «батч-задачи пока остаются на 2.5 или gpt-image-2» (перевод редакции). Он же отмечает, что у 2.6 нет датированного снапшота: закрепить версию, как gpt-image-2.5-flare-2026-09-08, нельзя.</p><h2>Что делать, если вы уже используете GPT-Image-2.5</h2><ul><li>Не меняйте идентификатор модели в проде вслепую: если вы генерируете на low или medium, счёт вырастет в 3–4 раза при той же ставке за токен. Прогоните 20–30 своих промптов на 2.5 и 2.6 и сравните output_tokens из поля usage.</li><li>В каждом запросе явно задавайте quality и complexity; без complexity модель планирует на high; для простой правки попробуйте low и сравните задержку и результат.</li><li>Ночные батч-задачи оставьте на gpt-image-2.5-* или gpt-image-2: у 2.6 Batch не заявлен.</li><li>Если вам нужны векторные иконки или короткие лупы из API, 2.6 — пока единственный способ получить SVG и GIF от OpenAI; для SVG ставьте n: 1, для GIF — frame_count не больше 16.</li><li>Параметр user в Images API объявлен устаревшим — передавайте тот же идентификатор как safety_identifier.</li></ul><p>Доступность: в ChatGPT и Codex Images 2.6 включена на всех тарифах на вебе, десктопе и в мобильных приложениях. Для API OpenAI может потребовать верификацию организации перед доступом к моделям GPT Image. Россия в <a href="https://developers.openai.com/api/docs/supported-countries">списке поддерживаемых стран</a> OpenAI API на 5 ноября 2026 года отсутствует, и в <a href="https://help.openai.com/en/articles/7947663-chatgpt-supported-countries">списке стран ChatGPT</a> её тоже нет — официально ни API, ни ChatGPT здесь не предоставляются; из перечисленных в сравнении вендоров ситуация с доступом у каждого своя, и проверять её нужно по официальным страницам.</p><p>Контекст: Images 2.6 вышла через 57 дней после даты снапшота GPT-Image-2.5 (8 сентября 2026 года) и почти через год после <a href="https://tproger.ru/news/openai-obnovila-chatgpt-image--teper-s-redaktirovaniem-foto-kak-v-nano-banana-pro">GPT Image 1.5</a>, где OpenAI сделала ставку на точное редактирование. По данным компании, через ChatGPT, Codex и API сейчас создаётся 4 млрд изображений в неделю — больше полумиллиарда в день. Конкуренты в этом году не стояли на месте: Google выпустила <a href="https://tproger.ru/news/vywla-nano-banana-2---novoe-pokolenie-ii-generatora-kartinok-ot-">Nano Banana 2</a>, а <a href="https://tproger.ru/articles/nano-banana-pro--kak-poluchit-dostup-v-rossii---polnyj-obzor--259274">Nano Banana Pro</a> остаётся самой дорогой моделью в нашем сравнении.</p><p>Что редакция проверит дальше: появится ли у 2.6 Batch и датированный снапшот и объяснит ли OpenAI, почему low и medium у новой версии стоят в 3–4 раза дороже при неизменной ставке за токен.</p><p>Источники: <a href="https://openai.com/index/introducing-images-2-6/">Introducing Images 2.6 — OpenAI</a>, <a href="https://developers.openai.com/api/docs/guides/image-generation">Image generation — OpenAI API</a>, <a href="https://developers.openai.com/api/docs/pricing#image-generation">Pricing — OpenAI API</a>, <a href="https://developers.openai.com/api/docs/supported-countries">Supported countries — OpenAI API</a>, <a href="https://ai.google.dev/gemini-api/docs/pricing">Gemini API pricing — Google</a>, <a href="https://docs.x.ai/docs/models">Models — xAI docs</a>, <a href="https://ai.byteplus.com/product/Seedream">Seedream 5.0 Pro — BytePlus</a>, <a href="https://community.openai.com/t/images-upgraded-introducing-chatgpt-images-2-6/1412901">Обсуждение на форуме разработчиков OpenAI</a>, <a href="https://dev.to/gabrielanhaia/gpt-image-26-outputs-svg-and-gifs-unlike-25-you-cant-run-it-through-batch-47pf">Gabriel Anhaia — DEV Community</a>, <a href="https://x.com/OpenAI/status/2118124966055223755">Твит OpenAI об анонсе</a></p><p>Изображение на обложке: OpenAI</p>]]></content:encoded>
    </item>
    <item>
      <title>Обзор ITSM-систем 2026-27</title>
      <link>https://tproger.ru/articles/obzor-itsm-sistem-2026-27</link>
      <comments>https://tproger.ru/articles/obzor-itsm-sistem-2026-27?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Компания Directum]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/obzor-itsm-sistem-2026-27</guid>
      <description><![CDATA[<p>Сравниваем 6 российских ITSM-систем: Directum ESM, NAUMEN, SimpleOne, ELMA365, 1С:ITILIUM и ITSM 365. Плюсы, минусы и тренды рынка в 2026–2027 годах.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/obzor-itsm-sistem-2026-27">Обзор ITSM-систем 2026-27</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 03 Nov 2026 11:16:11 GMT</pubDate>
      <content:encoded><![CDATA[<p>За последние годы ИТ-решения в компаниях заметно изменились. Прослеживается 2 тренда: импортозамещение и переход на комплексные системы. Перемены произошли и в управлении ИТ-услугами. От популярных ранее ServiceNow, Jira Service Management, Omnitracker, ManageEngine компании отказываются в пользу отечественных ITSM-систем, которые значительно усилились. Обзор самых популярных продуктов для управления сервисами с их плюсами и минусами читайте в статье.</p><h2>Что такое ITSM-система</h2><p><a href="https://www.directum.ru/products/esm/itsm-for-medium-sized-businesses?utm_source=media&amp;utm_medium=tproger&amp;utm_campaign=article&amp;utm_content=esm&amp;utm_term=tproger" rel="nofollow">ITSM (Information Technology Service Management)</a> — это управление ИТ-услугами, при котором техподдержка работает по сервисной модели. Система выстраивается как единое окно: заявку можно отправить в любую службу. Пользователю не нужно выяснять, кто за что отвечает и как с этим подразделением связаться. Он просто выбирает в цифровом каталоге нужный сервис и получает ответ в этом же интерфейсе. С помощью такого ПО можно заказать смену пароля, ремонт техники, диагностику программ, заказ оборудования и др.</p><h3>5 ключевых ITSM-процессов</h3><h4>1.	Управление инцидентами</h4><p>Сбои случаются в любой компании. Когда что-то ломается, ИТ-команда должна быстро восстановить работу, чтобы не было долгого простоя. Далее необходимо разобраться, почему это произошло, и снизить вероятность повторения.</p><h4>2.	Управление проблемами</h4><p>Этот процесс помогает найти причину сбоя и наметить, как его устранить. Работа начинается не только после аварии: специалисты заранее ищут слабые места и стараются их нивелировать.</p><h4>3.	Управление изменениями</h4><p>Один из способов уменьшить число проблем — управлять изменениями. ИТ-отдел корректирует работу системы и находит узкие места. Кроме того, этот процесс помогает поддерживать актуальность ПО и добавлять новые услуги.</p><h4>4.	Управление активами</h4><p>Задача — держать под контролем всю инфраструктуру: серверы, ПО, сервисы и другие компоненты. Учет активов показывает связи между объектами.  Специалисты видят полную картину, легче планируют профилактику и вовремя оказывают услуги.</p><h4>5. Управление знаниями</h4><p>Это создание, передача и практическое использование знаний об ИТ-сервисах. В базе собраны инструкции, чек-листы и другая документация, которая помогает быстрее закрывать обращения или даже отдавать простые запросы на самообслуживание.</p><p>Эти процессы повышают качество услуг, разгружают специалистов поддержки и делают работу прозрачной.</p><h2>На что обратить внимание при выборе ITSM-системы</h2><h3>Отечественная разработка</h3><p>Важно, чтобы продукт был зарегистрирован в реестре российского ПО. Для многих компаний это связано с требованиями законодательства, для остальных — с удобством оплаты и своевременным обновлением системы.</p><h3>Гибкая настройка</h3><p>С помощью no-code легко адаптировать систему под процессы компании. Для этого не обязательно разбираться в программировании. Изменился процесс — ответственный настраивает новую логику в визуальном редакторе, быстро тестирует и запускает в эксплуатацию буквально через пару часов.</p><h3>Масштабируемость</h3><p>Растет компания, увеличивается и число задач, услуг. Важно, чтобы при увеличении штата или процессов не пришлось менять инструмент. Поэтому стоит обратить внимание, за счет чего вендор гарантирует устойчивую производительность. Можно запросить отчет о нагрузочном тестировании.</p><h3>Удобный интерфейс</h3><p>Простое и понятное представление системы поможет пользователям легче отправлять заявки и совершать меньше ошибок. Сотрудники техподдержки в свою очередь получат инструмент для прозрачного контроля обращений. Поэтому лучше выбирать системы, которые можно кастомизировать без дополнительной разработки.</p><h3>Искусственный интеллект</h3><p>Умный поиск по базе знаний, автоматическое оформление обращений по регламентам, чат с ИИ-помощником для решения типовых запросов продолжают быть восходящими трендами ITSM-систем. Для компаний, которые стремятся снизить трудоемкость ИТ-специалистов, это важный критерий.</p><h3>Экосистемность</h3><p>Помимо заказа и предоставления сервисов, сотрудники выполняют другие задачи. Например, синхронизируются по работам на канбан-досках, готовят договоры на закупку лицензий, проверяют документацию оборудования. Этой функциональности нет в классической ITSM-системе. Поэтому чтобы постоянно не переключаться между вкладками и не терять данные, лучше внедрить экосистему решений. Продукты бесшовно интегрируются друг с другом и открывают больше возможностей для работы.</p><h2>Обзор российских ITSM-систем</h2><p>Если вы в поиске системы управления ИТ-услугами, стоит рассмотреть отечественные решения. Не стали раздавать места, а просто составили список самых интересных продуктов.</p><h3>Directum ESM</h3><figure><img src="https://media.tproger.ru/user-uploads/140075/2026-10-28/1a745024-b114-4b78-96b1-f755db2a521c.webp" alt="Интерфейс Directum ESM" /><figcaption>Интерфейс Directum ESM</figcaption></figure><p>Преимущества</p><ul><li>100% корпоративных сервисов</li></ul><p><a href="https://www.directum.ru/products/esm?utm_source=media&amp;utm_medium=tproger&amp;utm_campaign=article&amp;utm_content=esm&amp;utm_term=tproger" rel="nofollow">Система подходит для управления ИТ-услугами</a> и любыми другими: HR, административными, бухгалтерскими, юридическими, маркетинговыми.</p><ul><li>Быстрый старт</li></ul><p>Большое количество услуг преднастроено и готово для работы сразу. Компании проводят настройку самостоятельно за 3-4 недели благодаря no-code и дружелюбному интерфейсу.</p><ul><li>Широкие интеграционные возможности</li></ul><p>Directum ESM имеет открытый API и интеграционный сервис для настройки взаимодействия с ERP, MDM, CRM. Есть прямая интеграция с 1С.</p><ul><li>No-code-настройка</li></ul><p>В системе можно адаптировать без кода карточки услуг, формы заявок, каталог услуг, сервисные процессы.</p><ul><li>Активное развитие</li></ul><p>Новые релизы выходят каждые 3–4 месяца и с фокусом на практические задачи: контроль SLA, аналитику для руководителей, удобство для пользователей.</p><ul><li>Экосистемность</li></ul><p>Входит в экосистему решений Directum и бесшовно работает с КЭДО, СЭД, супераппом для мобильного доступа.</p><ul><li>Гибкая установка</li></ul><p>Доступны варианты: Cloud (SaaS) и On-premise.</p><p>Недостатки</p><ul><li>«свежий» продукт именно в готовом «коробочном» виде. Но вендор разрабатывает подобные решения под заказ уже много лет;</li><li>дискаверинг и мониторинг только через интеграцию со специализированными системами;</li><li>захват обращений только через электронную почту и портал самообслуживания. Если нужно подхватывать обращения с IP-телефонии, то необходимо интегрироваться через открытый API;</li><li>для постройки индивидуального дашборда нужна модификация или выгрузка в BI-систему.</li></ul><h3>NAUMEN</h3><figure><img src="https://media.tproger.ru/user-uploads/140075/2026-10-28/fb3204d4-2f34-4f99-919a-07bd0b7cdef2.webp" alt="Интерфейс Naumen Service Desk" /><figcaption>Интерфейс Naumen Service Desk</figcaption></figure><p>Преимущества</p><ul><li>Единая платформа для управления процессами</li></ul><p>Можно оцифровать широкий спектр процессов управления в рамках сервисного подхода. Закрывает более 15 корпоративных процессов.</p><ul><li>Бесплатный портал самообслуживания</li></ul><p>Это <a href="https://www.naumen.ru/" rel="nofollow">единственная система</a>, в которой можно подключить пользователей к порталу самообслуживания без дополнительной оплаты. Функциональность согласований линейных руководителей сюда тоже входит.</p><ul><li>Широкие интеграционные возможности</li></ul><p>Через базовые коннекторы интегрируется со всеми основными корпоративными приложениями. Функциональность REST API предполагает связку со всеми современными сервисами: Jira, Google Maps и др.</p><ul><li>Персонализация интерфейсов и данных</li></ul><p>Гибкая настройка помогает адаптировать персональные рабочие места под роли пользователей (набор полей, действий и списков). Доступна визуализация процессов: графический workflow для жизненного цикла заявок и схем связей между конфигурационными единицами.</p><ul><li>Прозрачная лицензионная политика</li></ul><p>Решение лицензируется как All-in-One, серверные и пользовательские лицензии по процессам не нужны.</p><ul><li>Активное развитие решения</li></ul><p>Новые релизы выходят каждые 5–6 месяцев.</p><ul><li>Экосистемность</li></ul><p>В рамках одной платформы можно решать задачи, связанные с управлением ИТ-услугами, ИТ-активами, мониторингом, управлением проектами и клиентским сервисом. Дополнительные потребности закрываются через продукты экосистемы Naumen.<b> </b></p><ul><li>Гибкая установка</li></ul><p>Доступны варианты: Cloud (SaaS) и On-premise.</p><p>Недостатки</p><ul><li>высокая цена;</li><li>отдельные модули нужно докупать, без этого полную функциональность не получить;</li><li>сложности при настройке. Внедрение системы и обучение пользователей занимают много времени, особенно при сложной настройке процессов;</li><li>уступает по гибкости некоторым решениям.</li></ul><h3>SimpleOne</h3><figure><img src="https://media.tproger.ru/user-uploads/140075/2026-10-28/d8d09861-0920-4d33-a236-c8d78f3b6e25.webp" alt="ITSM-система SimpleOne" /><figcaption>Интерфейс ITSM-системы SimpleOne</figcaption></figure><p>Преимущества</p><ul><li>Настройка с низким кодом</li></ul><p><a href="https://simpleone.ru/itsm" rel="nofollow">Low-code-платформа</a> с большими возможностями кастомизации. Можно создавать и адаптировать процессы без программирования.</p><ul><li>Масштабируемость на другие подразделения</li></ul><p>Инструменты системы подходят для всех подразделений (бухгалтерия, HR и др.), есть возможность бесшовной интеграции сервисных процессов.</p><ul><li>Множество поставщиков услуг</li></ul><p>Компании могут назначать исполнителями любые отделы и департаменты (бухгалтерию, HR, АХО) и управлять их портфелями услуг в единой системе.</p><ul><li>Оперативная аналитика и отчетность</li></ul><p>В доступе дашборды, drill-down-отчеты и интеграция с BI-системами (Yandex DataLens). Оценка SLA и эффективности процессов с актуальной аналитикой.</p><ul><li>Высокая производительность</li></ul><p>Платформа стабильно работает с большими объемами данных и тысячами одновременных пользователей.</p><ul><li>Экосистемность</li></ul><p>В рамках одной платформы можно решать задачи, которые связаны с ИТ-услугами, управлением активами, разработкой ПО, B2B-продажами и HR-процессами. Платформа изначально учитывает специфику ESM-подхода.</p><ul><li>Гибкая установка</li></ul><p>Доступны варианты: Cloud (SaaS) и On-premise.</p><p>Недостатки</p><ul><li>высокая цена;</li><li>сложность освоения, требуется качественное и долгое обучение;</li><li>затрудненная кастомизация, реализация отдельных задач может занимать десятки часов;</li><li>не подходит для малого бизнеса.</li></ul><h3>ELMA365</h3><figure><img src="https://media.tproger.ru/user-uploads/140075/2026-10-28/632dbfc7-ff51-4647-897f-9f2185f7def0.webp" alt="ELMA365 Service Desk" /><figcaption>ELMA365 Service Desk</figcaption></figure><p>Преимущества</p><ul><li>Быстрая поставка</li></ul><p><a href="https://service.elma365.com/" rel="nofollow">Преднастроенная система</a> включает все необходимые ITSM-процессы для быстрого внедрения.</p><ul><li>Надежность и производительность решения</li></ul><p>Система успешно прошла независимый аудит ICL Services на соответствие ключевым практикам ITIL.</p><ul><li>No-code / Low-code-настройка</li></ul><p>С помощью встроенного Low-code/BPM-движка можно адаптировать систему под уникальные бизнес-процессы без программирования.</p><ul><li>Развитие</li></ul><p>Новые релизы выходят регулярно.</p><ul><li>Гибкая установка</li></ul><p>Доступны варианты: Cloud (SaaS) и On-premises.</p><ul><li>Экосистемность</li></ul><p>На платформе можно решать задачи, которые связаны с документооборотом, закупками и CRM.</p><p>Дополнительные потребности закрываются через Low-code-настройку.</p><p>Недостатки</p><ul><li>стоимость может показаться высокой для специфических задач;</li><li>есть сложности с кастомизацией;</li><li>не всегда подготовка и обучение пользователей проходит в должном объеме, пользователи могут искать обходные пути в работе.</li></ul><h3>1С:ITILIUM</h3><figure><img src="https://media.tproger.ru/user-uploads/140075/2026-10-28/e4b94c09-4a28-4c6a-9740-b536b36105e3.webp" alt="Интерфейс 1С:ITILIUM" /><figcaption>Интерфейс 1С:ITILIUM</figcaption></figure><p>Преимущества</p><ul><li>Скорость поставки</li></ul><p>Вендор обещает запуск <a href="https://1c-itilium.ru/" rel="nofollow">системы</a> за 14 дней. Многие клиенты это подтверждают.</p><ul><li>Надежность и производительность</li></ul><p>Продукт развивается с 2007 года и имеет зрелую функциональность. Есть проект, который охватывает 40 тыс. пользователей.</p><ul><li>No-code / Low-code-настройка</li></ul><p>Систему возможно адаптировать под специфические требования пользователей. Для доработки нужен программист с опытом 1С.</p><ul><li>Развитие</li></ul><p>Новые релизы выходят регулярно. В последних версиях идет больший упор на искусственный интеллект.</p><ul><li>Гибкая установка</li></ul><p>Доступны варианты: локальная установка (On-premises). Решение может работать в полностью импортозамещенной архитектуре на базе Astra Linux и СУБД Postgres.</p><ul><li>Экосистемность</li></ul><p>Система помогает управлять ИТ-услугами, а также сервисами в других департаментах, например HR, АХО. Можно настроить интеграцию с другими продуктами 1С.</p><p>Недостатки</p><ul><li>устаревший интерфейс;</li><li>проблемы интеграции с другими системами;</li><li>сложности с получением аналитики и отчетов в нетиповых сценариях;</li><li>зависимость от платформы: для доработок нужен программист со знанием 1С.</li></ul><h3>ITSM 365</h3><figure><img src="https://media.tproger.ru/user-uploads/140075/2026-10-28/f1359481-e850-4832-b622-a0f1685bd9e2.webp" alt="ITSM 365 Service Desk" /><figcaption>ITSM 365 Service Desk</figcaption></figure><p>Преимущества</p><ul><li>	Быстрая поставка</li></ul><p>Изначально <a href="https://itsm365.com/" rel="nofollow">в системе</a> преднастроены все основные процессы — управление заявками, проблемами, активами. Остается только адаптировать их под заказчика.</p><ul><li>	Low-code-настройка</li></ul><p>Визуальный редактор для создания сложных алгоритмов выполнения задач (от простых workflows до комплексных сценариев) помогает делать доработки без глубокого знания программирования.</p><ul><li>	Развитие</li></ul><p>Новые релизы выходят регулярно. В последнее время развивает интеграции, например с MAX, Контур.Толк.</p><ul><li>	Экосистемность</li></ul><p>Продукт бесшовно интегрируется с продуктами для подбора персонала и управления проектами.</p><ul><li>Гибкая установка</li></ul><p>Доступны варианты: Cloud (SaaS) и On-premise.</p><p>Недостатки</p><ul><li>сложный интерфейс;</li><li>неочевидный процесс настройки;</li><li>ограниченный набор готовых интеграций, в приоритете продукты 1С и почтовые сервисы;</li><li>трудности с настройкой многоступенчатого SLA.</li></ul><h2>Сравнение ITSM-систем</h2><p>Сравнительная таблица российских ITSM-систем</p><table><thead><tr><th><b>Критерий</b></th><th><b>Directum ESM</b></th><th><b>NAUMEN</b></th><th><b>SimpleOne</b></th><th><b>ELMA365</b></th><th><b>1С:ITILIUM</b><br /></th><th><b>ITSM 365</b><br /></th></tr></thead><tbody><tr><td>Соответствие ITIL</td><td>ITIL и ISO 20000</td><td>ITIL v.2011 (сертификация PinkVERIFY)</td><td>ITIL Master (личная сертификация)</td><td>ITIL 4 (аудит ICL Services)</td><td>ITIL</td><td>ITIL</td></tr><tr><td>Гибкая настройка</td><td>No-code и преднастроенные услуги</td><td>Low-code</td><td>Low-code</td><td>No-code / Low-code</td><td>No-code / Low-code</td><td>Low-code</td></tr><tr><td>ИИ-сервисы</td><td>+<br />ИИ встроен в логику продукта</td><td>+</td><td>+</td><td>+</td><td>+</td><td>-</td></tr><tr><td>Мобильное приложение</td><td>+</td><td>+</td><td>+</td><td>+</td><td>+</td><td>+</td></tr><tr><td>Экосистемность</td><td>Входит в экосистему Directum, может использовать функциональность ДО, бизнес-процессов, связанных с HR, проектами</td><td>С помощью экосистемы можно управлять ИТ-услугами, ИТ-активами, мониторингом, проектами и клиентским сервисом</td><td>Экосистема помогает управлять ИТ-услугами, активами, разработкой ПО, B2B-продажами и HR-процессами<br /></td><td>Платформа включает в себя задачи, связанные с документооборотом, закупками и CRM</td><td>Входит в линейку продуктов 1С</td><td>Имеет связку с продуктами для управления проектами и подбора персонала</td></tr></tbody></table><h2>Как развиваются ITSM-системы: тренды 2026-27</h2><p>При выборе решения важно взглянуть на несколько шагов вперед, чтобы продукт отвечал современным вызовам и потенциально смог адаптироваться под глобальные тенденции.</p><h3>ГенИИ в поддержке</h3><p>Развитие генеративного ИИ открывает дополнительные перспективы для цифровизации управления сервисами. Некоторые эксперты даже предлагают термин <a href="https://www.motadata.com/blog/itsm-trends">AISM (AI Service Management)</a> для описания этой концепции. Применение ГенИИ меняет традиционные процессы ITSM.</p><p><b>Управление проблемами</b></p><p>Благодаря предиктивной аналитике на основе машинного обучения можно выявлять инциденты заранее, до их возникновения. Для этого анализируются закономерности, журналы событий и метрики производительности. Ожидается, что ГенИИ сократит число критических инцидентов в компании на 30–40%.</p><p><b>Управление знаниями</b></p><p>Системы с генеративным ИИ могут изучать прошлые инциденты, документацию и переписку, чтобы автоматически пополнять базу знаний. Это снижает трудозатраты на создание статей и инструкций, предотвращает ситуации, когда работник покинул компанию — и унес знания с собой.</p><p><b>Служба поддерж</b><b>ки</b></p><p>За последние годы вычислительные мощности ИИ-агентов значительно выросли. Современные виртуальные помощники кардинально отличаются от прежних топорных чат-ботов, поэтому стремление к умным технологиям с человеческим лицом в будущем сохранится.</p><p>Современные ИИ-агенты могут подстраивать ответы под историю взаимодействий пользователя, его роль в организации и уровень технической грамотности. Они самостоятельно закрывают большую часть обращений в службу поддержки.</p><h3>Управление ИИ и контроль за безопасностью (AI Governance)</h3><p>По результатам <a href="https://itsm.tools/ai-in-itsm-2025/" rel="nofollow">опроса</a>, 42% компаний уже применяют искусственный интеллект в поддержке. Рост популярности таких технологий и расширение сфер их использования требуют более строгого контроля за корректностью, безопасностью и этичностью ИИ. Во многих странах формируется законодательство в этой области. Так, в 2024 году приняли <a href="https://digital-strategy.ec.europa.eu/en/policies/regulatory-framework-ai" rel="nofollow">Европейский акт об ИИ (EU AI Act)</a>, а в августе 2025 года его дополнили нормами для моделей ИИ общего назначения (GPAI).</p><p>В России применение умных технологий пока не регулируется на государственном уровне, однако есть все основания ожидать, что соответствующий закон рано или поздно появится. Поэтому многие компании, которые используют интеллектуальные сервисы, создают отдельные подразделения. В их задачи входят мониторинг работоспособности ИИ-моделей, ведение учета и аудит применяемых систем, оценка рисков, зависящих от типа ИИ-агентов.</p><h3>Управление сервисами на уровне всей компании</h3><p>Исследования 2025-2026 гг. показывают, что рынок ESM в 3 раза больше, чем ITSM. Тренд будет набирать обороты, и в ближайшем будущем CAGR (среднегодовой темп прироста) ESM-рынка достигнет 18-20%. Поэтому в выигрыше будут те компании, которые внедряют системы, изначально заточенные под широкий список корпоративных сервисов, а не только ИТ.</p><h3>Эволюция пользовательского опыта</h3><p>В фокусе сотрудники. Их удовлетворенность — база для моделей предиктивной аналитики, которая выявляет причины ухода кадров.</p><p>В управлении сервисами происходит смена приоритетов. Кроме технического SLA, с помощью которого фиксируют время отклика и решения обращения, эксперты предлагают измерять и XLA (Experience Level Agreement) — взаимодействие и уровень удовлетворенности. Формальное соблюдение регламентов больше не гарантирует успех. Именно глубокий анализ пользовательского опыта (XLA) помогает повысить лояльность и найти слабые места в процессах обслуживания.</p><h3>Рост влияния информационной безопасности (ИБ)</h3><p>Наблюдается тенденция к объединению ITSM/ESM-систем с решениями класса IAM (Identity and Access Management) для гибкого управления правами доступа. Набирает обороты модель Security-as-a-Service, при которой сервисы ИБ становятся частью общего каталога услуг.</p><p>Активно внедряется автоматическая генерация отчетности, чтобы четче соблюдать регуляторные требования. Расширяется и управление уязвимостями: запросы из систем сканирования (Tenable, Qualys) превращаются в задачи ESM с приоритетом на основе оценки риска (CVSS) и контролируются вплоть до устранения.</p><p><a href="https://www.directum.ru/products/esm/itsm-for-medium-sized-businesses?utm_source=media&amp;utm_medium=tproger&amp;utm_campaign=article&amp;utm_content=esm&amp;utm_term=tproger" rel="nofollow">ITSM-системы</a> — один из способов оптимизировать работу техподдержки. С учетом текущей экономической ситуации переход на сервисную модель становится важной частью стратегического плана для компаний.</p><p>Управление услугами станет ключевым направлением для ИТ-директоров в ближайшие годы. По нашим прогнозам, компании активно будут развивать свои бэк-офисы с помощью отечественных решений. Организации смогут значительно улучшить качество обслуживания внутренних и внешних клиентов, что в условиях растущей конкуренции станет важным фактором успеха.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как я за два дня написал 30 open-source библиотек для Python, JS и SkyForge и автоматизировал релизы</title>
      <link>https://tproger.ru/articles/kak-ya-za-dva-dnya-napisal-30-open-source-bibliotek-dlya-python-js</link>
      <comments>https://tproger.ru/articles/kak-ya-za-dva-dnya-napisal-30-open-source-bibliotek-dlya-python-js?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Hammam Monder]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-ya-za-dva-dnya-napisal-30-open-source-bibliotek-dlya-python-js</guid>
      <description><![CDATA[<p>Как автоматизировать сборку, тесты и релизы кросс-экосистемных библиотек. Опыт создания проекта SkyPackages.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-ya-za-dva-dnya-napisal-30-open-source-bibliotek-dlya-python-js">Как я за два дня написал 30 open-source библиотек для Python, JS и SkyForge и автоматизировал релизы</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Open Source]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 28 Oct 2026 07:46:06 GMT</pubDate>
      <content:encoded><![CDATA[<p>Пишу на Python и JS. Иногда берусь за SkyForge. Регулярно сталкиваюсь с одной и той же ситуацией. Нужна валидация ИНН. Иду в гугл, нахожу десять решений. Пять из них не обновлялись года три. У остальных нет поддержки кириллицы или они требуют лишних зависимостей. В итоге пишу свою регулярку, теряю час и всё равно получаю баги на граничных случаях.</p><p>Так появился проект SkyPackages. За два дня я выпустил 30+ библиотек. С единым API, с тестами, с поддержкой русского языка там где это нужно.</p><h2>Что внутри</h2><p>Две группы пакетов.</p><p>Первая закрывает то, что мировые аналоги не решают вообще. ИНН, ОГРН, СНИЛС, КПП, БИК, расчётные счета. Производственный календарь РФ с праздниками и рабочими днями. Склонение числительных. Транслитерация по ГОСТ. Телефоны с определением оператора. Карты МИР. Всё это есть в открытом доступе по частям, но собрать в одном месте с нормальными тестами никто не удосужился.</p><p>Вторая группа это обычные утилиты, которых не хватает в стандартных библиотеках. Безопасный парсинг JSON с лимитами. Криптография на AES-256 и PBKDF2. Генерация UUID v7, ULID, NanoID. Cron с вычислением следующего запуска. Semver. Расстояние Левенштейна.</p><p>Каждый пакет существует в трёх версиях сразу. Для Python, для npm и для SkyForge.</p><h2>Про автоматизацию</h2><p>Обычно поддерживать три кодовые базы это боль. Три набора тестов. Три пайплайна публикации. Три раза руками заливать релизы на GitHub. Я потратил полдня и написал скрипт builder.py, который делает всё за меня.</p><p>Что делает скрипт при запуске. Генерирует файлы для всех трёх экосистем. Ставит зависимости и прогоняет тесты через pytest, vitest и SkyForge check. Собирает wheel, tgz и zip. Создаёт релизы на GitHub через API. Создаёт или обновляет репозитории для SkyForge. Правит index.html прямо в репозитории, без git. Дёргает деплой на Render.</p><p>Один запуск, всё готово. От строки кода до появления пакета на сайте проходит меньше двух минут. Никаких ручных шагов.</p><h2>Примеры</h2><p>Python. Импортируем модули валидации и производственного календаря:</p><p>from sky_validate_ru import inn, snils</p><p>from sky_datetime_ru import add_working_days</p><p>from datetime import date</p><p>inn.is_valid("7707083893")</p><p>snils.format("11223344595")</p><p>add_working_days(date(2026, 12, 31), 1)</p><p><i>Первая строка вернёт True. Вторая вернёт строку "112-233-445 95". Третья вернёт 9 января 2026 года, потому что декабрьские праздники перескакивают.</i></p><p>TypeScript. Импортируем генератор ID и форматер телефонов:</p><p>import { uuidV7 } from "@skypackages/id";</p><p>import { formatPhone } from "@skypackages/phone-ru";</p><p>uuidV7();</p><p>formatPhone("+79991234567");</p><p><i>Первая строка вернёт UUID v7 вроде "018f4a3e-...". Вторая вернёт "+7 (999) 123-45-67".</i></p><p>SkyForge. Подтягиваем пакет и вызываем функцию:</p><p>пусть v = подтянуть "skyforge-validate-ru"</p><p>лог(v.инн_валиден("7707083893"))</p><p><i>В консоль выведется истина.</i></p><h2>Цифры</h2><p>30 уникальных библиотек. 90 релизов, по три на каждую. Три экосистемы. Покрытие тестами сто процентов. Первое место в лидерборде SkyForge. Большинство пакетов без внешних зависимостей.</p><p>Проект независимый, не принадлежит никакой компании. Всё open-source. Ставится одной командой с GitHub Releases, без регистрации в реестрах.</p><h2>Что понял по ходу</h2><p>Если релиз занимает десять минут ручной работы, вы не будете выпускать обновления часто. Если тридцать секунд, будете. Это главный вывод.</p><p>Писать один и тот же код трижды неприятно, но это решается генерацией. Скрипт делает это лучше меня.</p><p>Русскоязычные библиотеки нужны. Не для галочки в отчёте об импортозамещении, а потому что люди реально тратят время на велосипеды каждый день. Я сам так делал годами.</p><h2>Ссылки</h2><p>GitHub: github.com/skytech-alt/SkyPackages</p><p>Сайт: skypackages.onrender.com</p><p>Буду рад фидбэку. Если знаете какая ещё библиотека нужна, пишите в комментариях или открывайте issue на GitHub.</p>]]></content:encoded>
    </item>
    <item>
      <title>immers.cloud запускает публичные API для open-source нейросетей с оплатой за токены</title>
      <link>https://tproger.ru/news/immers-cloud-zapuskaet-publichnye-api-dlya-open-source-nejrosetej</link>
      <comments>https://tproger.ru/news/immers-cloud-zapuskaet-publichnye-api-dlya-open-source-nejrosetej?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Ислам Виндижев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/immers-cloud-zapuskaet-publichnye-api-dlya-open-source-nejrosetej</guid>
      <description><![CDATA[<p>immers.cloud запустил каталог Immers Foundation Models: API для Qwen, DeepSeek, OCR и TTS-моделей с оплатой за токены. Быстрый прототип и production без своей инфраструктуры.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/immers-cloud-zapuskaet-publichnye-api-dlya-open-source-nejrosetej">immers.cloud запускает публичные API для open-source нейросетей с оплатой за токены</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Инфраструктура]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 23 Oct 2026 06:25:47 GMT</pubDate>
      <content:encoded><![CDATA[<p>Облачный провайдер <b>immers.cloud</b> запустил каталог <a href="https://immers.cloud/ai/model/?sort=-ICanTry" rel="nofollow">Immers Foundation Models</a> с публичными AI-эндпоинтами. Сервис предлагает API с оплатой за токены, полностью готовые для интеграции в dev-среды и production, а также позволяющие быстро собрать рабочий прототип. Решение поддерживает популярные open-source модели на инфраструктуре от базовых NVIDIA A2 до связок c  H200.</p><p>В каталоге уже сейчас доступны для инференса <a href="https://immers.cloud/ai/Qwen/qwen3.8-27b/" rel="nofollow">Qwen3.8-27B</a>, <a href="https://immers.cloud/ai/deepseek-ai/deepseek-v4-flash-0731/" rel="nofollow">DeepSeek-V4-Flash-0731</a>, <a href="https://immers.cloud/ai/Qwen/qwen3.6-35b-a3b/" rel="nofollow">Qwen3.6-35B-A3B</a>, а также OCR и text-to-speech модели: <a href="https://immers.cloud/ai/baidu/unlimited-ocr/" rel="nofollow">Unlimited-OCR</a>, <a href="https://immers.cloud/ai/baidu/paddleocr-vl-1.6/" rel="nofollow">PaddleOCR-VL-1.6</a>, <a href="https://immers.cloud/ai/openai/whisper-large-v3/" rel="nofollow">whisper-v3-large</a> и другие модели. Архитектура сервиса автоматически распределяет нагрузку: компактные модели работают на ускорителях уровня A2, а тяжелые решения, такие как DeepSeek-V4-Flash-0731, запускаются на серверах со связкой до восьми GPU NVIDIA H200.</p><p>Публичные эндпоинты с оплатой за токены — это готовое решение для быстрого инференса и прямой интеграции в рабочие сервисы. Разработчики могут сразу использовать API, не отвлекаясь на поддержку собственной инфраструктуры. При этом эндпоинты остаются удобным инструментом для быстрой оценки качества генерации, проверки tool calling и сборки прототипа. Если бизнес-задача требует изолированного контура, приватности данных или запуска кастомной модели, наработанный код и промпты можно без изменений мигрировать на частный эндпоинты immers.cloud с посекундной тарификацией.</p><blockquote>«Использование искусственного интеллекта с каждым днем становится все более повседневным и привычным. Пользователи взаимодействует с большими языковыми моделями очень по-разному. И как правило, это зависит от навыков и потребностей: для кого-то достаточно ответов модели в чате; кто-то автоматизирует рабочие процессы и разработку через популярные фреймворки или агентов; стартапам и крупным компаниям, разрабатывающим продукты на основе ИИ, часто требуется не только LLM, но и надежная инфраструктура для инференса. Нашей команде известны все эти сценарии, и развивая сервис Immers Foundation Models мы стремимся сделать так, чтобы каждый шаг на пути к фантастическим возможностям ИИ был для наших клиентов максимально простым, быстрым и доступным.»  — Павел Самойлов, руководитель направления по ИИ.</blockquote><p>immers.cloud — облачный сервис для аренды серверов с GPU NVIDIA. Платформа предоставляет инфраструктуру с посекундной тарификацией и быстрым онбордингом для обучения нейросетей, инференса LLM, 3D-рендеринга и обработки видео.</p><p><i>Реклама. Рекламодатель ООО «ДТЛ», ИНН 9717073792, erid: 2W5zFHoWPiy</i></p>]]></content:encoded>
    </item>
    <item>
      <title>Функциональные флаги в CI/CD: что, зачем и как</title>
      <link>https://tproger.ru/articles/funkcionalnye-flagi-v-ci-cd-chto-zachem-i-kak</link>
      <comments>https://tproger.ru/articles/funkcionalnye-flagi-v-ci-cd-chto-zachem-i-kak?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Александр Лукьянов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/funkcionalnye-flagi-v-ci-cd-chto-zachem-i-kak</guid>
      <description><![CDATA[<p>Что такое функциональные флаги и как они ускоряют CI/CD. Виды флагов, инструменты (Flagsmith, LaunchDarkly), интеграция с pytest и лучшие практики внедрения.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/funkcionalnye-flagi-v-ci-cd-chto-zachem-i-kak">Функциональные флаги в CI/CD: что, зачем и как</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Функциональное программирование]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 07 Oct 2026 12:02:39 GMT</pubDate>
      <content:encoded><![CDATA[<p>Собрали небольшой гайд по функциональным флагам: какими они бывают, чем полезны, зачем нужны в CI/CD и как их правильно использовать.</p><p>Функциональные флаги (feature flags, feature toggles) позволяют разработчикам включать и отключать функции приложения, но при этом не требуют повторно собирать и развёртывать код. Благодаря флагам в CI/CD можно чётко отделить друг от друга этапы «развёртывания» (доставки результатов разработки и сборки) и «релиза» (запуска новой функциональности для пользователей). Для чего и как именно это делается — разберём в этой статье.</p><h2>Что такое функциональный флаг</h2><p>Технически функциональный флаг — это специальный код в приложении, который проверяет значение предварительно выбранной переменной. В зависимости от этого активируется разная логика.</p><p>Ниже приведён пример JSON, который получает приложение. Оно проверяет геотег пользователя, и если пользователь из Москвы, то значение флага возвращает true и в итоге отображается виджет погоды. Для пользователей из других городов значение флага принимает default_variant: "disabled", и виджет для них не показывается.</p><p>Функциональные флаги могут использоваться в разных сценариях — приведём основные с парой примеров:</p><ul><li>Повышение надёжности системы: отключение рекомендаций при высокой нагрузке, переключение на резервный платёжный шлюз при сбоях в основном.</li><li>Обучение через продуктовые эксперименты и A/B-тестирование: сравнение двух вариантов страницы регистрации, тестирование двух видов кнопки «Купить».</li><li>Управление доступом по тарифам и подпискам: экспорт отчётов только для пользователей Pro, расширенные настройки только для корпоративных клиентов.</li><li>Сезонные и временные функции: промокоды на «чёрную пятницу», приём работ для конкурса.</li><li>Аварийные выключатели (kill switches): отключение медиаплеера из-за ошибок, удаление неверно настроенного способа оплаты.</li></ul><p>Далее рассмотрим основные типы флагов.</p><h2>Типы флагов</h2><p>Флаги классифицируются по механизму работы и целевому назначению.</p><h3>По механизму работы: статические и динамические флаги</h3><p><b>Статические флаги</b> чаще всего используют, чтобы скрыть недоделанную функциональность до релиза, проставить внутренние флаги, которые не требуют частого переключения, или флаги в микросервисах с редкими развёртываниями.</p><p>Их значение фиксируется на этапе сборки или при старте приложения. Чтобы изменить значение такого флага, придётся перезапускать сервис.</p><p>Статические флаги задаются через переменные окружения (.env), конфиг-файлы (config.json) или внешние сервисы конфигурации (Consul).</p><p>Пример в .env:</p><p>Пример в виде конфиг-файла:</p><p>Использование в коде:</p><p>Плюсы: простота, нулевые сетевые задержки, предсказуемость, безопасность (нет внешних вызовов в runtime).</p><p>Минусы: невозможность изменить поведение «на лету» — требуется пересборка/перезапуск.</p><p><b>Динамические флаги</b> идеальны для экспериментов с пользователями, постепенного развёртывания и таргетинга по регионам или ролям. Их можно менять в runtime без перезапуска приложения.</p><p>Такие флаги управляются через внешние системы: API, БД, специализированные сервисы.</p><p>В примере ниже — два флага. Первый проверяет, попадает ли пользователь в сегмент для тестирования нового способа оформления заказа: берутся только 25 % пользователей сервиса; также они должны входить в группы "beta_testers", "premium_users" и быть из России, Беларуси или Казахстана. Второй флаг показывает, что ИИ-рекомендации при заказах пока отключены для всех пользователей, но в нужный момент это можно изменить даже во время работы приложения.</p><p>Пример конфигурации:</p><p>Использование в коде:</p><p>Плюсы: гибкость — можно включать и выключать фичи на лету, перенастраивать систему без перезапуска сервиса (критично для высоконагруженных систем).</p><p>Минусы: усложнение логики системы (flag debt), дополнительная задержка при запросе состояния флага и зависимость от внешних систем.</p><p>Сведём сравнение типов флагов в небольшую таблицу:</p><figure><img src="https://media.tproger.ru/user-uploads/133989/2026-10-07/c805be74-aee7-4c16-9722-b241cf817d1b.webp" alt="" /></figure><h3>По цели применения: релизные, экспериментальные, операционные и разрешающие флаги</h3><p><b>Релизные флаги</b> (release flags) позволяют отделить развёртывание от релиза, то есть экспериментальная/незаконченная фича вливается в основную ветку и развёртывается вместе с остальным кодом, но остаётся выключенной до официального релиза. Если после релиза что-то пойдёт не так, флаг можно сразу же отключить, не делая новый релиз и не откатывая приложение. Когда новая функциональность начинает работать стабильно, релизный флаг удаляют.</p><p>Например, код нового платёжного шлюза уже в продакшене, но флаг пока enabled: false. Флаг включат 1 ноября, и фича станет доступной всем. Если с платежами возникнут проблемы, флаг сразу же отключат без отката деплоя.</p><p><b>Экспериментальные флаги</b> (experiment flags) — это инструмент для A/B-тестов и проверки гипотез. Они позволяют показать разные новые варианты новой функции разным пользователям (или показать новую функциональность только ограниченной лояльной группе пользователей), чтобы изучить их реакцию и на её основе сделать вывод о новой фиче. По окончании A/B-теста экспериментальный код и флаг удаляют.</p><p>В примере ниже команда интернет-магазина проводит тест, чтобы выбрать подходящий цвет для кнопки «Оформить заказ» в корзине. Выборка из 30 % пользователей распределяется случайным образом: 50 % из них видят зелёную кнопку, 25 % — красную, 25 % — оранжевую. Система собирает метрики: конверсию и отказ от корзины. Через две недели становится ясно, что оранжевая кнопка даёт +15 % к конверсии, поэтому её делают основной, а флаг и экспериментальный код удаляют.</p><p><b>Операционные флаги</b> (ops flags) нужны, чтобы регулировать поведение системы. С их помощью можно отключать ресурсоёмкие операции во время больших нагрузок или на слабых устройствах, переключаться между внешними сервисами, предотвращать критические сбои при запуске новой функциональности, управлять режимами деградации, проводить диагностику при инцидентах.</p><p>Операционные флаги зачастую не удаляют и оставляют в системе.</p><p>Рассмотрим следующий пример. В «чёрную пятницу» нагрузка в приложении интернет магазина растёт, утилизация CPU превышает 85 %. Из-за этого отключаются ИИ-рекомендации (на ресурсоёмкой ML-модели) и включаются обычные статические. После того как нагрузка снижается, флаг возвращается в исходное состояние.</p><p>Второй флаг позволяет переключиться на режим обслуживания БД, а третий — на резервный платёжный сервис, если есть сбои в основном.</p><p><b>Разрешающие флаги</b> (permission flags) — это одна из составляющих настройки доступа к специфическим функциям приложения, например к ролям в админ-панели для разработчиков и менеджеров или к платным функциям для клиентов. Такие флаги могут быть очень динамичными и менять состояние при каждом запросе.</p><p>Разрешающие флаги обычно долгоживущие и становятся неотъемлемой частью жизненного цикла приложения.</p><p>В примере ниже при каждом запросе к админ-панели система проверяет роль пользователя и статус подписки. Администратор видит все разделы, менеджер — только ограниченный набор, а премиум-клиент получает доступ к дашборду аналитики. Администраторы и премиум-клиенты также могут экспортировать отчёты в формате Excel.</p><p>Далее рассмотрим, какие существуют инструменты для управления функциональными флагами.</p><h2>Системы управления флагами</h2><p>Глобально все решения для управления флагами делятся на три категории: проприетарные, Open Source и собственные разработки.</p><p>Проприетарные SaaS-платформы предлагают готовую инфраструктуру, поддержку и продвинутый функционал «из коробки». Они идеально подходят для команд, которые хотят сосредоточиться на продукте, а не на поддержке инструмента. Крупным компаниям стоит инвестировать именно в такие решения, а для стартапов могут подойти базовые тарифы.</p><p>Перечислим тут несколько самых известных проприетарных инструментов для управления флагами:</p><ul><li>LaunchDarkly позволяет включать функционал для конкретных сегментов аудитории с высокой гранулярностью, то есть подходит для детального таргетинга пользователей и маркетинговых экспериментов. Платформа даёт enterprise-уровень надёжности и позволяет гибко управлять жизненным циклом флагов.</li><li>ConfigCat обеспечивает единую точку управления, если инфраструктура состоит из разнородных технологий (веб, мобильные приложения, бэкенд на разных языках).</li><li>Harness интегрирует управление флагами прямо в CI/CD-процессы. Предоставляет командам детальную аналитику о влиянии флагов на производительность и стабильность системы прямо в пайплайне развёртывания.</li></ul><p>Open Source-решения дают полный контроль над кодом и данными и позволяют развёртывать систему на своих серверах (on-premise), что критично для организаций со строгими требованиями к безопасности.</p><p>Вот пара примеров Open Source-платформ для управления флагами:</p><ul><li>Flagsmith позволяет сохранить данные внутри периметра компании, хорошо поддаётся конфигурации и кастомизации через удобный интерфейс.</li><li>Unleash хорошо подходит компаниям, которым важно разграничивать права управления флагами между разными командами, менеджерами и разработчиками.</li></ul><p>Собственная разработка тоже возможна, но требует значительных ресурсов. На ранних этапах разработки продукта или при тестировании гипотез внедрения флагов можно использовать переменные окружения, JSON-файлы или простой API-сервис. Но по мере роста продукта поддерживать собственное решение становится всё сложнее: нужно обеспечивать отказоустойчивость, безопасность и разработку SDK для всех языков программирования в проекте. Так что переход на специализированный инструмент (Open Source или SaaS) — обычно вопрос времени.</p><p>Независимо от того, какое решение вы выберете, важно убедиться, что оно легко интегрируется с вашей CI/CD-системой и не создаёт узких мест в разработке. Кроме того, внедрять полноценную систему управления флагами на ранних этапах разработки может быть избыточным, поэтому нужно всегда спрашивать себя, стоят ли затраченные усилия желаемого результата.</p><p>Теперь посмотрим, какую роль функциональные флаги играют в CI/CD.</p><h2>Функциональные флаги в CI/CD</h2><p>Флаги фундаментально меняют подход к управлению исходным кодом, особенно если используется модель ветвления Trunk Based Development (TBD).</p><p>При TBD в основную ветку (main/trunk) часто вливаются изменения. Функциональные флаги позволяют разработчикам интегрировать и развёртывать фичи, которые ещё не готовы к релизу, и при этом не рисковать стабильностью всего приложения. Благодаря флагам быстрее внедряются изменения и упрощается слияние, так как весь код (и основной, и разрабатываемый) остаётся в одной ветке. Это предотвращает конфликты слияния (merge hell), которые часто случаются при долгоживущих ветках.</p><p>Флаги улучшают управление рисками, а именно:</p><ul><li>дают возможность выключить функциональность сразу после релиза, если она работает неправильно, — благодаря этому система быстрее восстанавливается (MTTR);</li><li>позволяют включать фичу поэтапно, делать canary/rollout, быстро откатывать поведение через переключатель и не ждать новой сборки для исправления проблемы.</li></ul><p>На сам CI/CD-пайплайн функциональные флаги никак не влияют. Основная задача пайплайна — запуск автотестов, сохранение результатов их работы и передача далее для дальнейшего анализа. Проверка функциональности при включённом и выключенном флаге должна быть частью автотестов.</p><p>Чтобы эффективно протестировать оба состояния флага, можно использовать параметризованные тесты (переключаться между состояниями внутри одного набора тестов) либо поддерживать отдельные наборы тестов для включённого и выключенного флага.</p><p>Параметризованные тесты позволяют динамически переключать состояние флага во время выполнения приложения и тем самым уменьшают дублирование кода.</p><p>Отдельные наборы тестов могут быть полезны, когда состояния флагов фиксированы в разных окружениях (например, staging и production) или когда предпочтительнее запускать тесты по отдельности.</p><p>Допустим, мы готовим новую версию приложения и до того, как выпустить её в продакшен, тестируем релиз-кандидата в окружении staging. CI/CD-пайплайн собрал образ release-candidate и развернул его в staging. При запуске приложения запрашивается набор флагов из централизованной системы управления флагами. Далее при запуске автотестов подбирается набор тест-кейсов для заданного окружения. Также подбирается набор флагов для конкретного пользователя после того, как его логин и user id считаются из cookie во время запроса.</p><p>В результате тестовые сценарии становятся более гибкими, позволяют прогонять тесты в разных режимах флага, а также отдельно проверять критичные сценарии и постепенно расширять набор проверок.</p><p>Ниже подробнее рассмотрим сценарий тестирования релиз-кандидата.</p><h2>Сценарий тестирования релиз-кандидата с применением функциональных флагов</h2><p>Сценарий состоит из следующих шагов:</p><ol><li>CI/CD-пайплайн собирает образ release-candidate и деплоит в staging.</li><li>При запуске приложения запрашиваются флаги из Flagsmith с параметрами environment=staging, user_id, role.</li><li>Система флагов возвращает конфигурацию: какие флаги включены и какие тест-кейсы нужно выполнить.</li><li>Автотесты динамически фильтруют тесты на основе полученного ответа. Тесты, которые не относятся к активным функциям текущего окружения, не запускаются.</li></ol><p>Все флаги хранятся в системе управления флагами Flagsmith в формате JSON.</p><p>Здесь описан флаг new_payment_flow — он управляет новой версией процесса оплаты.</p><p>В нашем примере функция включена в staging и выключена в production.</p><p>Помимо самого состояния флага, конфигурация содержит список тестов для каждого окружения. Для staging предусмотрены три проверки:</p><ul><li>успешная оплата;</li><li>обработка ошибки;</li><li>обработка тайм-аута.</li></ul><p>Для production пока оставлен только тест успешной оплаты.</p><p>В config находятся параметры, которые тесты также могут получить из системы флагов. В нашем случае это timeout_ms 5000. Значение тайм-аута не зашито непосредственно в тесте, и его можно изменить через конфигурацию флага.</p><p>Автотесты при запуске запрашивают флаги из внешней системы с помощью следующего запроса:</p><p>Здесь тестовый раннер сообщает системе флагов контекст, в котором выполняется проверка. В параметре context указаны идентификатор release candidate и источник запроса — autotest_runner.</p><p>Получив такой запрос, система флагов определит, какие настройки применимы именно к этому запуску.</p><p>Автотесты используют функциональные флаги, чтобы динамически сформировать определённый тестовый сценарий. Для этого процесс сбора тестов перехватывается через специальную функцию (conftest.py):</p><p>Тут pytest находит все тесты, какие есть. Код узнаёт, в каком окружении запускаются тесты, подключается к Flagsmith и получает активные флаги.</p><p>Из флагов берётся список тестов, которые нужно запустить для конкретного окружения. Из всех найденных тестов остаются только те, которые:</p><ul><li>относятся к нужному окружению;</li><li>указаны в конфигурации активного флага.</li></ul><p>В результате pytest запустит только оставшиеся тесты.</p><p>Функциональные флаги влияют не только на выбор тестов. Сам тест также может получать из флага параметры, необходимые для его выполнения:</p><p>Здесь из конфигурации флага new_payment_flow извлекается параметр timeout_ms. В нашей конфигурации его значение было задано — 5000. Если бы оно не было указано, использовалось бы значение по умолчанию — 3000.</p><p>Таким образом, CI/CD-пайплайн остаётся универсальным и не содержит отдельной логики вроде «если это такой-то релиз, запусти такие-то тесты». Он запускает один и тот же механизм, а конкретное поведение определяется конфигурацией функциональных флагов.</p><p>Итого мы получаем инструмент, который позволяет гибко управлять тем, какие тесты и в каком окружении запускать и для каких пользователей включать новую функциональность.</p><h2>Риски и рекомендации по использованию флагов</h2><p>Флаги — это мощный инструмент, но если неправильно их использовать, они могут принести проекту больше вреда, чем пользы, поэтому применять их нужно с осторожностью.</p><h3>Основные риски при работе с флагами</h3><p><b>Деградация кода и тестов</b>. Забытые флаги создают в коде множество ветвлений. В результате тестировать такой код становится сложнее: нужно проверять не только каждый флаг отдельно, но и разные сочетания флагов.</p><p><b>Проблемы производительности и доступности</b>. Постоянные сетевые запросы к сервису флагов замедляют работу приложения, если не используется кеширование. Кроме того, сервис флагов становится критической зависимостью: если он упадёт, вместе с ним могут упасть все зависимые микросервисы.</p><p><b>Рассинхронизация</b>. Разные экземпляры приложения могут узнать об изменении флага не одновременно, поэтому могут временно работать по-разному.</p><h3>Архитектурные рекомендации</h3><p>Прежде всего, флаги нужно вовремя удалять: можно настроить в CI/CD автоматические уведомления на флаги, которые живут дольше установленного времени, например больше 30 дней. А релизные и экспериментальные флаги лучше удалять сразу после того, как стабилизировалась фича или закончился A/B-тест. У каждого флага должны быть владелец, дата создания и план удаления.</p><p>Как мы уже писали выше, флаги — это критическая зависимость, поэтому стоит обезопасить себя от сбоев в системе управления флагами: использовать на стороне приложения fallback-значения (default variants), внедрить локальное кеширование (чтобы пережить кратковременные падения сети), использовать автоотключение (Circuit Breaker) запросов к сервису флагов при множественных таймаутах.</p><p>Обезопасить себя при работе с флагами нужно и с других сторон: нельзя хранить в их конфигурации секреты или персональные данные, необходимо логировать все изменения (кто, когда и что изменил) и внедрить обязательный code review и approval-процесс для критичных флагов.</p><p>Чтобы избежать взрыва матрицы тестов, не нужно создавать отдельные тесты для каждого состояния флага — лучше использовать параметризованные тесты и динамическую фильтрацию (вроде того сценария, что мы рассматривали выше).</p><p>В целом, в зрелой практике флаги используют как временный инструмент для поставки и экспериментов, а не как постоянная замена нормальной архитектуре.</p><p>Резюмируем ключевые принципы:</p><ul><li>Временность. Для флагов должен быть чёткий план удаления.</li><li>Прозрачность. У каждого флага должны быть владелец, назначение и срок жизни.</li><li>Отказоустойчивость. Приложение должно работать даже при недоступности сервиса управления флагами.</li><li>Мониторинг. Состояние и использование флагов нужно постоянно отслеживать.</li></ul><p>Итак, функциональные флаги — это важный элемент культуры непрерывной поставки. Они повышают гибкость, безопасность и скорость доставки ПО, позволяют командам выпускать код чаще. Но важно помнить, что флаги — это не панацея: они дают максимум пользы только при грамотном внедрении и регулярной очистке, а без должной дисциплины могут усложнить кодовую базу и тестирование.</p>]]></content:encoded>
    </item>
    <item>
      <title>OpenAI на DevDay выпустила GPT-6.1 Sol по цене в пять раз ниже Astra</title>
      <link>https://tproger.ru/news/openai-na-devday-vypustila-gpt-6-1-sol-po-cene-v-pyat-raz-nizhe-a</link>
      <comments>https://tproger.ru/news/openai-na-devday-vypustila-gpt-6-1-sol-po-cene-v-pyat-raz-nizhe-a?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/openai-na-devday-vypustila-gpt-6-1-sol-po-cene-v-pyat-raz-nizhe-a</guid>
      <description><![CDATA[<p>GPT-6.1 Sol за $2 и $10 за млн токенов, Ultrafast до 8 раз быстрее, Pro 500, Codex в облаке, computer use в Agents API и MCP Events: главное с DevDay.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/openai-na-devday-vypustila-gpt-6-1-sol-po-cene-v-pyat-raz-nizhe-a">OpenAI на DevDay выпустила GPT-6.1 Sol по цене в пять раз ниже Astra</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Облачные технологии]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 29 Sep 2026 14:59:05 GMT</pubDate>
      <content:encoded><![CDATA[<p>OpenAI 29 сентября <a href="https://openai.com/index/devday-2026-recap/">показала</a> на конференции DevDay в Сан-Франциско больше 20 новинок, и среди анонсов для разработчиков — модель <a href="https://openai.com/index/introducing-gpt-6-1-sol/">GPT-6.1 Sol</a>. По замерам компании, она почти догоняет GPT-6 Astra в программировании, работе с компьютером и профессиональных задачах, а стоит в пять раз меньше: $2 за миллион входных токенов и $10 за миллион выходных. В API модель доступна как gpt-6.1-sol.</p><p>Для агентов в API подешевел кэшированный вход: $0,10 за миллион токенов, вдвое меньше, чем у GPT-6 Sol. Кроме модели, OpenAI обновила инструменты: Codex работает в облаке с общими окружениями, Codex CLI принимает голосовые команды, Agents API научился управлять компьютером, а плагины ChatGPT встраиваются в боковую панель и реагируют на события во внешних сервисах. Запись трансляции выложена <a href="https://www.youtube.com/watch?v=Fls_onRviPM">на YouTube</a>.</p><ul><li>GPT-6.1 Sol: $2, $0,10 и $10 за миллион входных, кэшированных и выходных токенов; в ChatGPT Work и Codex — на Plus, Pro, Business, Enterprise и Edu, в обычном чате пока нет.</li><li>По замерам OpenAI, на DeepSWE 1.1 GPT-6.1 Sol решает 75,2% задач при $0,65 за задачу, Astra — 74,1% при $4,43.</li><li>Ultrafast ускоряет генерацию до 8 раз в Codex и до 6 раз в API; в подписке он есть только на Pro 500 за $500 в месяц и на подходящих тарифах Enterprise и Edu.</li><li>Codex в облаке доступен с тарифа Plus, обновлённый Codex CLI и Code Review — на всех тарифах.</li><li>Agents API получил computer use, а MCP Events запускает автоматизации плагинов по вебхукам из внешних сервисов.</li></ul><h2>GPT-6.1 Sol стоит в пять раз меньше Astra</h2><p>GPT-6.1 Sol — обновление GPT-6 Sol, которую OpenAI <a href="https://tproger.ru/news/openai-vypustila-gpt-6-sol-i-gpt-6-luna-v-api">выпустила в API 22 сентября</a>. Стандартные цены у новой модели в пять раз ниже, чем у <a href="https://tproger.ru/news/openai-nachala-vypusk-gpt-6-astra-ceny-benchmarki-i-kiber-ograni">GPT-6 Astra</a>. GPT-6.1 Sol уже работает в ChatGPT Work и Codex на Plus, Pro, Business, Enterprise и Edu со стандартной скоростью, а режим Fast, по документации, доступен там, где позволяют тариф, клиент, настройки рабочего пространства и раскатка; в обычном чате ChatGPT её пока нет.</p><h3>Что показывают бенчмарки OpenAI</h3><p>Результаты моделей OpenAI ниже — замеры самой компании, независимых подтверждений нет; результаты конкурентов она взяла из их публичных отчётов. На графиках по горизонтали — стоимость одной задачи в долларах, по вертикали — результат в процентах, точки на линии — уровни рассуждения от low до max. Чем точка левее и выше, тем выгоднее модель.</p><p>На DeepSWE 1.1, где модели решают длинные задачи в реальных кодовых базах, лучший результат GPT-6.1 Sol — 75,2% на уровне high при $0,65 за задачу. У Astra максимум 74,1% на xhigh при $4,43, у GPT-6 Sol — 68,8% на max при $2,74. На max GPT-6.1 Sol набирает меньше, чем на high, так что предельный уровень рассуждения здесь не нужен.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-29/25f5aa1e-c533-498a-b7d8-14d84e4eea7b.webp" alt="График DeepSWE 1.1: результат в процентах против стоимости задачи в долларах для GPT-6.1 Sol, GPT-6 Sol и GPT-6 Astra на уровнях рассуждения от low до max" /><figcaption>График: Tproger по данным OpenAI (замеры компании)</figcaption></figure><p>AutomationBench 1.0.6 проверяет сквозные бизнес-процессы с 47 инструментами. На уровне medium GPT-6.1 Sol на 2,2 п. п. выше Opus 5.5 примерно за треть цены, но на max впереди другие: Opus 5.5 с резервными моделями — 42,5% при $1,44, Astra — 41,4% при $1,73, GPT-6.1 Sol — 36,1% при $0,30. Цену Fable 5.1 ($2,45 за задачу) OpenAI в сноске называет заниженной: в неё не вошли вызовы резервной модели, которые понадобились примерно в 40% задач.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-29/c9487fa7-e28d-4f0e-8aad-721eab144847.webp" alt="График AutomationBench: результат в процентах против стоимости задачи для GPT-6.1 Sol, GPT-6 Sol, GPT-6 Astra, Opus 5.5 и отдельной точки Fable 5.1" /><figcaption>График: Tproger по данным OpenAI; результат Opus 5.5 и Fable 5.1 взят из публичных отчётов их разработчиков</figcaption></figure><p>На OSWorld 2.0, где агент работает с обычными программами (частичная оценка на offline-наборе версии v2026.08.08), GPT-6.1 Sol на max набирает 71,4% при $1,27, Astra — 73,5% при $9,44, GPT-6 Sol — 64,4% при $3,37. Разница с Astra — 2,1 п. п. при цене примерно в 7 раз ниже.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-29/a000412f-5dd9-46d7-977a-baae013a3a5b.webp" alt="График OSWorld 2.0: результат в процентах против стоимости задачи для GPT-6.1 Sol, GPT-6 Sol и GPT-6 Astra" /><figcaption>График: Tproger по данным OpenAI (замеры компании)</figcaption></figure><p>На Terminal-Bench Science 0.1 (анализ данных, симуляции, доказательство теорем в терминале) GPT-6.1 Sol получает 57,0% при $5,47 за задачу, больше чем вдвое выше GPT-6 Sol. Лидирует Astra с 68,1% при $23,80, и OpenAI сама советует брать её для самых трудных научных задач.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-29/2cb0839c-4365-4c18-a9f5-8932b9cc7331.webp" alt="График Terminal-Bench Science 0.1: результат в процентах против стоимости задачи для GPT-6.1 Sol, GPT-6 Sol, GPT-6 Astra и Opus 5.5" /><figcaption>График: Tproger по данным OpenAI; результат Opus 5.5 взят из публичного отчёта Anthropic</figcaption></figure><p>На GDP.pdf, где нужно отвечать на вопросы по сложным PDF, GPT-6.1 Sol на max сравнялась с Astra — по 31,0% — при цене $0,42 против $2,08. Доля ответов с фактической ошибкой на уровне low снизилась с 11,4% до 7,7%, но замер сделан на специально трудных диалогах, нетипичных для обычной работы.</p><h2>Ultrafast ускоряет генерацию токенов до 8 раз, но в подписке только на Pro 500</h2><p>Ultrafast — платный уровень скорости: по данным OpenAI, в Codex это до 300 токенов в секунду, до 8 раз быстрее обычного режима, в API — до 6 раз быстрее. Широко он доступен только для GPT-6 Astra, для GPT-5.6 Sol в API есть превью. В API режим <a href="https://developers.openai.com/api/docs/guides/ultrafast-mode">включается параметром</a> service_tier, лимиты — от 500 тыс. до 5 млн токенов в минуту в зависимости от уровня аккаунта, региональные эндпоинты вроде европейского не поддерживаются, цены вынесены в отдельную таблицу. В Codex, <a href="https://learn.chatgpt.com/docs/agent-configuration/speed">по документации</a>, Ultrafast расходует включённый в подписку лимит в 8 раз быстрее обычного режима.</p><p>Подписка Pro <a href="https://help.openai.com/en/articles/9793128-about-chatgpt-pro-tiers">теперь бывает трёх видов</a>: Pro 100 за $100, Pro 200 за $200 и Pro 500 за $500 в месяц, последний с Ultrafast и лимитом в 25 раз выше, чем у Plus. Pro 200 снова открыт для новых подписчиков, но с сокращённым лимитом. Подписчики, попавшие под условия сохранения, держат прежний лимит до 29 октября 2026 года. Ultrafast это не даёт, и покупка кредитов на Pro 100 или Pro 200 его тоже не открывает.</p><h2>Codex получил облачные окружения, а CLI начал слушать голос</h2><p><a href="https://learn.chatgpt.com/docs/cloud">Codex в облаке</a> запускает задачи на удалённой машине, а ставить и проверять их можно с компьютера, телефона или из браузера. Вы выбираете репозитории GitHub, Codex сам ставит зависимости и инструменты и прогоняет проверки, а опубликованное окружение с настройками сети и секретами команда может выбирать для своих задач. Каждая задача работает в своём пространстве, даже когда ноутбук спит. Тарифы — от Plus.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-29/afeba39f-f050-4011-a93a-88ed1f8031cc.webp" alt="Мобильный интерфейс Codex: вкладки All, Cloud и ноутбук пользователя, под ними список проектов" /><figcaption>Облачные проекты Codex на телефоне. Изображение: OpenAI</figcaption></figure><p>В <a href="https://learn.chatgpt.com/docs/codex/cli">Codex CLI</a> задачи можно ставить и направлять голосом (голосовые диалоги <a href="https://tproger.ru/news/codex-cli-0-155-0-poluchil-golosovye-dialogi-i-podtverzhdenie-mcp">появились ещё в версии 0.155.0</a>), а новый экран /agents показывает сразу несколько делегированных задач. OpenAI также улучшила возобновление сессий и работу с git worktree. Доступно на всех тарифах, обновление ставится той же командой, что и сам CLI:</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-29/1ec81c64-c5c2-4815-b2e1-e92a38017f95.webp" alt="Окно Codex CLI: агент на GPT-6 Astra добавляет горячие клавиши в дашборд пулл-реквестов, правит файл и запускает тесты" /><figcaption>Codex CLI выполняет задачу в терминале. Изображение: OpenAI</figcaption></figure><p><a href="https://learn.chatgpt.com/docs/code-review?surface=app">Code Review</a> в десктопном приложении ChatGPT показывает сводку и диффы и позволяет спросить Codex о проблемах до комментария в пулл-реквесте GitHub или мерж-реквесте GitLab; в автоматическом режиме Codex делает первый проход в облаке сам. Функция есть на всех тарифах.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-29/b896793c-6fb7-47cd-ac68-ef5e2f136d90.webp" alt="Экран Code Review в приложении ChatGPT: замечание Codex с приоритетом P2 к строке кода и чат с просьбой поправить интерфейс" /><figcaption>Code Review в приложении ChatGPT. Изображение: OpenAI</figcaption></figure><p><a href="https://learn.chatgpt.com/docs/security/setup">Codex Security Cloud</a> сканирует репозитории GitHub по запросу или расписанию, следит за новыми коммитами, сам отсеивает дубли и готовит исправления, которые можно оформить черновым пулл-реквестом. В него входит доступ к моделям программы Daybreak Blue без отдельной заявки. Тарифы — Pro, Business, Enterprise и Edu.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-29/e51c9047-240b-4f95-9d0a-b462866bb75d.webp" alt="Дашборд Codex Security Cloud: счётчики находок по критичности, воронка от обнаружения до исправления и таблица находок с кнопками Fix" /><figcaption>Дашборд Codex Security Cloud с находками. Изображение: OpenAI</figcaption></figure><h2>Какие API OpenAI дала для собственных агентов</h2><p><a href="https://openai.com/index/introducing-the-agents-api/">Agents API</a> получил <a href="https://developers.openai.com/api/docs/guides/agents-api/tools/computer-use">computer use</a>: агент на нём может сам работать с программами. Туда же перенесли возможности Codex — несколько агентов в одной задаче, поиск инструментов, сжатие контекста, а инфраструктуру держит OpenAI. Песочницу для команд и файлов может дать OpenAI или ваш провайдер. В Codex и ChatGPT Work функция доступна на Pro 500 и Enterprise. По словам OpenAI, отдельной платы за сам Agents API нет: оплачиваются токены и инструменты.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-29/abdc50c3-47ab-4dd4-b62e-5dd86caf778b.webp" alt="Схема Agents API: приложение отправляет задачи, Agents API с управляемой обвязкой Codex вызывает инструменты в песочнице и возвращает события и результат" /><figcaption>Схема работы Agents API с computer use. Изображение: OpenAI</figcaption></figure><p>Decisions API сводит работу модели Luna к ответам на заданные вопросы с фиксированными вариантами: так можно классифицировать контент, маршрутизировать запросы или выбирать следующий шаг агента. Пока это ограниченное превью. <a href="https://aws.amazon.com/bedrock/managed-agents-openai/">Bedrock Managed Agents</a>, сделанные вместе с Amazon, запускают агентов OpenAI целиком внутри AWS.</p><p>Sign in with ChatGPT даёт тратить лимит подписки Plus или Pro в 16 сторонних сервисах, среди них Devin, Notion, Vercel и T3, с отдельным потолком для каждого.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-29/2ad74cf9-de82-4c52-9c47-6f05e381eb33.webp" alt="Окно Connect ChatGPT and Devin с переключателем, разрешающим Devin тратить лимит подписки ChatGPT" /><figcaption>Окно подключения ChatGPT к Devin. Изображение: OpenAI</figcaption></figure><p>Для компаний OpenAI собрала набор Private Intelligence: <a href="https://developers.openai.com/api/docs/guides/private-safety-processing">Private Safety Processing</a> вместе с нулевым хранением данных позволяет проводить автоматические проверки безопасности без доступа сотрудников OpenAI к содержимому запросов, а превью Private Inference на конфиденциальных вычислениях обещано осенью.</p><h2>Плагины встраиваются в интерфейс ChatGPT и реагируют на события</h2><p><a href="https://developers.openai.com/plugins/build/extensions">Plugin extensions</a> открывают сторонним разработчикам платформу, на которой OpenAI делает функции ChatGPT: плагин получает пункт в боковой панели, панель рядом с диалогом, свой просмотрщик для форматов файлов, формы и упоминания в поле ввода. Точки входа объявляются в метаданных MCP-сервера ключом openai/ui, SDK есть для TypeScript и Python. Canva, Figma и Adobe уже используют расширения.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-29/8c61b18a-c2e3-4add-a4a1-2285ac5d113b.webp" alt="Плагин Canva открыт в боковой панели ChatGPT: стартовый экран с шаблонами презентаций и категориями дизайна" /><figcaption>Расширение Canva в боковой панели ChatGPT. Изображение: OpenAI</figcaption></figure><p>Для авторов <a href="https://developers.openai.com/plugins">плагинов</a> появились Plugin Creator и обновлённая подача в каталог с более понятной обратной связью, а сами плагины можно подключать к Sites на тарифах Business, Enterprise, Healthcare и Edu.</p><p><a href="https://developers.openai.com/plugins/build/mcp-events">MCP Events</a> — поддержка предложенной спецификации событий MCP. ChatGPT подписывается на события сервера и выполняет инструкцию пользователя: например, на каждый баг-репорт в канале #product-feedback открывает черновой пулл-реквест. Серверу нужны протокол MCP версии 2026-07-28, методы events/list, events/subscribe и events/unsubscribe и доставка вебхуками с подписью Standard Webhooks, не больше 256 КиБ на событие. Опрос и стриминг не поддерживаются, события могут прийти не по порядку, поэтому инструменты записи должны быть идемпотентными.</p><h2>Dots — агенты на GPT-6 Astra, которые работают круглосуточно</h2><p><a href="https://openai.com/index/introducing-dots/">Dots</a> — постоянно работающие агенты на GPT-6 Astra со своим облачным компьютером и браузером; через плагины они подключаются к более чем 4000 приложений и доступны в ChatGPT, Slack и Teams. OpenAI приводит сценарий для разработчика: агент следит за отзывами клиентов, сам делает мелкие исправления с тестами и приносит готовые пулл-реквесты. В фоне он работает только с инструментами на чтение. Первый dot входит в Pro и Business Premium без доплаты, раскатка идёт в поддерживаемых странах; у Enterprise, Edu и Healthcare это бета, которую включает администратор.</p><h2>Что OpenAI добавила в ChatGPT для командной работы</h2><ul><li>ChatGPT Space — общее пространство команды, ChatGPT и агента dot; Pro, Business и Enterprise, создавать и править можно в десктопном приложении и вебе, на телефоне пока только искать, читать и делиться.</li><li>Pages — документы, которые вместе правят люди и агенты; Pro, Business и Enterprise.</li><li>Совместные слайды с экспортом в PowerPoint и Google Slides — в ближайшие недели для Pro, Business и Enterprise.</li><li>Команды и <a href="https://learn.chatgpt.com/docs/enterprise/team-tasks">общие задачи</a>, которые запускаются по расписанию или по событию, например новому письму; Business и Enterprise.</li><li>@ChatGPT в Slack и Microsoft Teams, коллегам не нужна своя лицензия; Business и Enterprise.</li><li>Плагин Meetings пишет заметки со встреч, аудио удаляется после подготовки заметок; бета на macOS для Pro и Business.</li><li>Профили, где можно делиться своими Sites и плагинами; Business и Enterprise.</li><li>OpenAI Marketplace: подходящие корпоративные клиенты могут подать заявку и направить часть действующего обязательства перед OpenAI на одобренный софт 32 партнёров, от Adobe и Figma до Salesforce и CrowdStrike.</li></ul><h2>Что ещё не вышло и что можно сделать сегодня</h2><p>GPT-6.1 Sol Ultrafast обещан в ближайшие дни, широкий доступ к Decisions API — тоже, совместные слайды — в ближайшие недели, превью Private Inference — осенью. Точных дат OpenAI не назвала.</p><ul><li>В API достаточно заменить имя модели на gpt-6.1-sol; в Codex CLI модель меняется командой /model, режим Fast включается командой /fast.</li><li>14 октября 2026 года GPT-5.5 уйдёт из ChatGPT, ChatGPT Work и Codex на всех тарифах; в API она останется.</li><li>Подписчикам Pro 200 стоит проверить почту: письмо о сохранённом до 29 октября лимите получат только те, кого коснулось изменение.</li></ul><p>Источники: <a href="https://openai.com/index/devday-2026-recap/">OpenAI: DevDay 2026 Recap</a>, <a href="https://openai.com/index/introducing-gpt-6-1-sol/">OpenAI: Introducing GPT-6.1 Sol</a>, <a href="https://openai.com/index/introducing-dots/">OpenAI: Introducing dots</a>, <a href="https://help.openai.com/en/articles/9793128-about-chatgpt-pro-tiers">OpenAI Help Center: About ChatGPT Pro tiers</a>, <a href="https://developers.openai.com/api/docs/guides/ultrafast-mode">OpenAI API: Ultrafast mode</a>, <a href="https://learn.chatgpt.com/docs/agent-configuration/speed">ChatGPT Learn: Speed</a>, <a href="https://learn.chatgpt.com/docs/cloud">ChatGPT Learn: Codex Cloud</a>, <a href="https://learn.chatgpt.com/docs/codex/cli">ChatGPT Learn: Codex CLI</a>, <a href="https://learn.chatgpt.com/docs/code-review?surface=app">ChatGPT Learn: Code review</a>, <a href="https://learn.chatgpt.com/docs/security/setup">ChatGPT Learn: Codex Security Cloud setup</a>, <a href="https://openai.com/index/introducing-the-agents-api/">OpenAI: Introducing the Agents API</a>, <a href="https://developers.openai.com/plugins/build/extensions">OpenAI Plugins: Extensions</a>, <a href="https://developers.openai.com/plugins/build/mcp-events">OpenAI Plugins: MCP Events</a>, <a href="https://developers.openai.com/api/docs/guides/private-safety-processing">OpenAI API: Private Safety Processing</a>, <a href="https://www.youtube.com/watch?v=Fls_onRviPM">Трансляция OpenAI DevDay 2026</a></p><p>Изображение на обложке: Кадр трансляции: OpenAI</p>]]></content:encoded>
    </item>
    <item>
      <title>Идемпотентность и Outbox: как не выполнить одну операцию дважды</title>
      <link>https://tproger.ru/articles/idempotentnost-i-outbox-kak-ne-vypolnit-odnu-operaciyu-dvazhdy</link>
      <comments>https://tproger.ru/articles/idempotentnost-i-outbox-kak-ne-vypolnit-odnu-operaciyu-dvazhdy?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/idempotentnost-i-outbox-kak-ne-vypolnit-odnu-operaciyu-dvazhdy</guid>
      <description><![CDATA[<p>Как сделать ручку идемпотентной, где ломается наивная проверка ключа и зачем нужен transactional outbox. Забирайте код на Python, SQL и Node.js и чеклист.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/idempotentnost-i-outbox-kak-ne-vypolnit-odnu-operaciyu-dvazhdy">Идемпотентность и Outbox: как не выполнить одну операцию дважды</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Архитектура ПО]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 09 Sep 2026 05:00:35 GMT</pubDate>
      <content:encoded><![CDATA[<p>История, с которой начинает автор одного из разборов ниже, звучит буднично. Платёжный шлюз не ответил вовремя, клиентская библиотека повторила запрос, и покупателя списали дважды. Сумма небольшая, а возврат, тикет в поддержку и восстановление доверия заняли недели.</p><p>Виноват тут не шлюз. Виноват сервер, который исходил из того, что каждый запрос приходит ровно один раз. В сети, где теряются ответы, это допущение неверно всегда.</p><p>Идемпотентность — свойство операции, при котором повторное выполнение приводит к тому же состоянию, что и однократное. Сам ответ при этом может отличаться: повторный DELETE вернёт 404 вместо 200, и метод от этого идемпотентным быть не перестаёт. У HTTP это закреплено на уровне методов: <a href="https://www.rfc-editor.org/rfc/rfc9110">RFC 9110</a> относит к идемпотентным PUT, DELETE и безопасные методы, а POST идемпотентным по своей природе не является. Бизнес-операции почти всегда отправляют именно через POST.</p><p>Клиент не может отличить «сервер не получил запрос» от «сервер выполнил операцию, но ответ потерялся», поэтому повтор придёт в любом случае.</p><p>Ключ идемпотентности генерирует клиент, а сервер хранит связку ключа со слепком запроса и с готовым ответом, чтобы повтор получил тот же результат, а не новый.</p><p>Проверка «посмотреть и вставить» неатомарна: два одновременных повтора оба увидят отсутствие ключа. Нужен уникальный индекс или условная запись.</p><p>Запись в базу и отправка в очередь в одну транзакцию не помещаются. Обёртывать сетевой вызов в BEGIN и COMMIT вредно вдвойне: корректности не даёт, а пул соединений выедает.</p><p>Transactional outbox решает это одной таблицей: событие пишется в той же транзакции, что и бизнес-запись, а отдельный процесс доставляет его в очередь.</p><h2>Почему повтор неизбежен</h2><p>Сеть отказывает так, что установить факт доставки невозможно в принципе. Есть три типовых сценария, и внешне они неразличимы:</p><ul><li>Сервер обработал запрос, но ответ потерялся по дороге назад.</li><li>Сервер всё ещё считает, а у клиента уже сработал таймаут.</li><li>Балансировщик повторил запрос сам, никого об этом не уведомив.</li></ul><p>Для GET повтор безвреден. Для POST /payments это второе списание. Отсюда и правило: одна логическая операция должна приводить к одному записанному итоговому состоянию, сколько бы раз её ни отправили. Осознанно новая операция обязана прийти с новым ключом.</p><h2>Два способа сделать ручку идемпотентной и один в довесок</h2><h3>Способ первый: ключ идемпотентности</h3><p>Самый распространённый вариант: клиент генерирует уникальный идентификатор на одну логическую операцию и повторяет его при каждой попытке. Сервер хранит соответствие ключа и ответа, а на дубликате возвращает сохранённый результат вместо повторного выполнения работы.</p><p>Три детали, на которых ошибаются чаще всего. Ключ генерирует клиент, а не сервер: смысл в том, что сервер сам по себе не отличит новый запрос от повтора. Ключ должен быть с высокой энтропией, обычно это UUID v4; выводить его из изменяемого или малоразнообразного поля вроде номера клиента нельзя, потому что это повышает риск коллизии и переигрывания чужой операции.</p><p>И последнее: повтор должен получить <b>тот же самый ответ</b>. Если первая попытка вернула 201 с идентификатором платежа, то и повтор возвращает те же 201 и тот же идентификатор, а не 409 и не пустую двухсотку. Иначе клиент решит, что операция не прошла, и попробует ещё раз.</p><h3>Способ второй: сделать операцию идемпотентной по смыслу</h3><p>Иногда ключ не нужен вовсе, потому что семантику можно спроектировать идемпотентной с самого начала. Классический пример — PUT /users/42, который задаёт полное представление ресурса: отправьте его дважды, и состояние будет одним и тем же.</p><p>Для операций создания трюк в том, чтобы выводить идентификатор из самого запроса, а не генерировать случайный на каждый вызов:</p><p>Идентификатор детерминированно выводится из почты, поэтому повторный запрос даёт того же пользователя без дублирующей строки. Плата за простоту — необходимость естественного уникального ключа: почты, артикула, внешнего идентификатора. Хеш при этом считается от точной строки, поэтому почту нужно привести к нижнему регистру и обрезать пробелы до хеширования: иначе один и тот же ящик с заглавной буквы даст второго пользователя. И ключ должен быть неизменным: если пользователь сменит почту, выведенный из неё идентификатор либо останется прежним и перестанет соответствовать данным, либо изменится и оторвётся от всех ссылок на него в соседних таблицах. Нет подходящего ключа, возвращайтесь к первому способу.</p><h3>Довесок: оптимистичная блокировка</h3><p>Этот приём идемпотентности не даёт и в списке стоит по другой причине. Ключ защищает от повторов одного и того же запроса, но ничего не делает с двумя <b>разными</b> запросами, которые правят одну запись. Здесь работает проверка версии: клиент присылает версию, которую видел, а сервер отклоняет обновление при несовпадении.</p><p>Обратите внимание, что проверка версии живёт внутри самого UPDATE. Разнести её на отдельное чтение и последующую запись означало бы воспроизвести ровно ту гонку, о которой пойдёт речь в следующем разделе: два запроса с одной устаревшей версией оба прошли бы проверку и оба записали бы результат. Идемпотентным одиночный запрос этот приём не делает, зато закрывает частый источник задвоенных эффектов: двух писателей, затирающих работу друг друга.</p><h2>Где наивная реализация ключа разваливается</h2><h3>Гонка в проверке</h3><p>Последовательность «проверить наличие ключа, потом вставить» содержит зазор, в который помещаются оба одновременных повтора: обе стороны видят, что ключа нет, и обе выполняют работу. Резервировать ключ нужно атомарно, через уникальное ограничение базы, условную запись или транзакционный compare-and-set (атомарное сравнение с записью).</p><p>Это же относится и к примеру с платежом выше: замена словаря в памяти на Redis гонку не закрывает, пока проверка и вставка остаются двумя отдельными командами. Нужен атомарный примитив резервирования, вроде SET key value NX или INSERT ... ON CONFLICT DO NOTHING.</p><p>Проверяется это только настоящей конкуренцией. Юнит-тест, вызывающий функцию дважды подряд, гонку не поймает никогда. Отправьте полсотни одновременных запросов с одним ключом и убедитесь, что побочный эффект произошёл ровно один раз.</p><h3>Слепок запроса, а не только ключ</h3><p>Хранить один ключ недостаточно. Сервер канонизирует поля, определяющие бизнес-смысл операции, и считает от них хеш. Канонизация означает приведение к единому виду порядка полей, форматов чисел и дат, опущенных значений по умолчанию и незначащих пробелов. Если повторный вызов обязан воспроизвести решение, принятое по прежним правилам, в слепок включают ещё и версию политики. Пример: между первой попыткой и повтором поменялись тарифы, и повтор обязан вернуть старую цену, а не пересчитать по новой. Без версии в слепке сервер этого различия не увидит.</p><p>Когда тот же ключ приходит с другим слепком, это ошибка на стороне клиента, и отдавать ему старый результат нельзя. <a href="https://dev.to/seo_optimization_591fad6c/designing-idempotent-decision-endpoints-that-survive-real-retries-6c1">Разбор проектирования идемпотентных ручек</a> предлагает отвечать 409 Conflict; <a href="https://dev.to/sirmax/3-ways-to-make-your-api-requests-idempotent-with-working-code-4inl">автор практического руководства</a> в этом случае возвращает 422. Важно, чтобы выбранный код был задокументирован и никогда не подменяется молчаливой отдачей чужого ответа.</p><h3>Состояния и коды ответа</h3><p>Минимальная модель состояний записи выглядит так: PROCESSING, SUCCEEDED, FAILED_RETRYABLE и FAILED_FINAL. Рядом хранятся ключ операции, слепок, отметки времени, идентификатор решения, снимок ответа и версия политики. Клиенту нужна детерминированная карта из состояния в код ответа:</p><ul><li>201 или 200 — первый успешно завершённый результат.</li><li>200 с явной пометкой о повторе — проигрывание сохранённого ответа.</li><li>202 со ссылкой на статус — работу уже выполняет другой обработчик, начинать вторую не нужно.</li><li>409 — ключ переиспользован с другим содержимым.</li><li>Задокументированная финальная ошибка — обработка провалилась, и автоматическое продолжение небезопасно.</li></ul><p><b>Срок жизни ключей:</b><br />Хранить их вечно не нужно, это медленная утечка. Сутки покрывают практически любое реальное окно повторов, но выбирать срок стоит от риска предметной области: у платежей и у рекомендаций он разный. И помните, что ключ приходит снаружи: ограничьте длину и набор символов, привяжите его к арендатору и не дайте одному пользователю вытащить результат чужой операции.</p><h2>Вторая половина задачи: база и очередь</h2><p>Допустим, ручка стала идемпотентной. Остаётся более коварная проблема: почти всякая бизнес-операция пишет не в одно место. Заказ сохраняется в базу и публикует событие в очередь, чтобы склад начал сборку, почтовый сервис отправил подтверждение, а антифрод посмотрел на транзакцию.</p><p>Обе половины статьи растут из одного факта: ни HTTP, ни очередь не обещают доставку ровно один раз, они обещают её хотя бы один раз. Поэтому защищаться приходится дважды, на входе и на выходе.</p><p>Это две записи в две разные системы, и общей транзакции у них нет. Упал процесс, моргнула сеть, выкатился деплой между двумя вызовами — одна сторона зафиксирована, вторая нет. Заказ подтверждён на экране покупателя, а склад о нём не знает. Ошибка при этом нигде не залогирована и алерт не сработал.</p><h3>Почему обернуть это в транзакцию нельзя</h3><p>Соблазнительный и заведомо неверный вариант выглядит так:</p><p>Транзакция базы не имеет власти над очередью и умеет откатывать только операции базы. Если отправка прошла, а COMMIT упал, сообщение уже в очереди и забрать его оттуда нельзя.</p><p>Есть и вторая беда, чисто эксплуатационная. Такой код держит открытое соединение и блокировки строк всё время сетевого вызова. Обычно очередь отвечает быстро, но под нагрузкой, ретраями или деградацией вызов растягивается на секунды, и все запросы к тем же строкам стоят в очереди. Это надёжный способ исчерпать пул соединений и уронить заодно ни в чём не повинные части сервиса.</p><h3>Outbox: событие как строка в той же транзакции</h3><p>Идея паттерна в том, чтобы перестать считать публикацию второй записью. Вместо вызова очереди приложение вставляет строку в таблицу outbox в той же транзакции, что и бизнес-запись. Отдельный процесс читает таблицу и публикует сообщения дальше.</p><p>Откатилась транзакция, и вместе с ней исчезла строка outbox: осиротевшего сообщения в очереди не осталось. Упало приложение сразу после фиксации — строка на месте со статусом pending, и доставщик заберёт её на следующем проходе. Паттерн опирается ровно на одну гарантию, которую база и так даёт: атомарность одной транзакции.</p><p>Доставщик выбирает пачку необработанных строк и помечает их отправленными только после подтверждения очередью. Ключевая деталь здесь одна:</p><p>Этот SELECT и последующая простановка статуса выполняются в одной транзакции: блокировка живёт до фиксации. Благодаря SKIP LOCKED доставщик масштабируется горизонтально из коробки, каждый экземпляр берёт свой набор строк. А если он упадёт посреди пачки, вся пачка откатится и уйдёт повторно, что даёт ещё один довод в пользу идемпотентного потребителя.</p><p>Может показаться, что здесь мы делаем ровно то, что осудили выше: держим блокировку на время сетевого вызова. Разница в том, что блокируется не бизнес-таблица и соединение берётся не из пула, обслуживающего пользовательские запросы, а SKIP LOCKED не даёт одной медленной строке задержать остальные.</p><h3>Потребитель обязан быть идемпотентным</h3><p>Если доставщик упал посреди прохода, на следующем он переотправит те же строки. Очереди вроде SQS и Kafka в типовой конфигурации гарантируют доставку «хотя бы один раз», поэтому дедупликация на приёмной стороне обязательна, и уникальным ключом служит идентификатор события или решения.</p><p>Делает это условная запись. Важная деталь, на которой легко ошибиться: сама по себе она пустой операцией не становится. При несовпадении условия драйвер бросает исключение, и его нужно поймать явно, отличив штатный повтор от настоящей ошибки:</p><p>Настройки продюсера и подтверждения брокера снижают количество повторов, но не снимают с приложения ответственность за однократность бизнес-эффекта.</p><h3>Что добавить перед продакшеном</h3><p>Двух статусов мало. Нужен статус failed и счётчик попыток: после N неудач строка помечается провалившейся и перестаёт крутиться в цикле вечно. На стороне очереди настраивается очередь недоставленных сообщений, чтобы то, что потребитель не смог обработать, оседало в наблюдаемом месте, а не исчезало молча.</p><p>Когда задержка опроса становится критичной, полагающийся на периодический опрос доставщик заменяют захватом изменений: инструменты вроде Debezium читают журнал предзаписи PostgreSQL и публикуют изменения без паузы на опрос. Таблица outbox и потребитель при этом не меняются. Но это заметно более тяжёлое эксплуатационное обязательство, поэтому начинать почти всегда стоит с опроса.</p><h2>Что забрать с собой</h2><p>Обе части задачи выглядят избыточными ровно до первого инцидента. Тридцать строк кода с ключом идемпотентности стоят дешевле одного тикета с заголовком «вы списали дважды», а таблица outbox дешевле расследования, почему заказ есть у клиента и отсутствует на складе.</p><p>Коварство проблемы двух записей в том, что наивная реализация работает правильно почти всегда. Она отказывает в зазоре между двумя системами, и зазор этот становится виден только когда что-то пошло не так в самый неподходящий момент. К моменту, когда расхождение заметят в продакшене, данные уже разъехались, и красивого способа их починить не будет.</p><p>Как одно неверное допущение о порядке вызовов обернулось эпидемией задвоенных операций, показано в <a href="https://tproger.ru/articles/skrytyj-sboj-idempotentnosti-v-finteh-sisteme-razbor-incidenta">разборе реального инцидента в финтех-системе</a>.</p><p>Материалы, на которых основан разбор: <a href="https://dev.to/sirmax/3-ways-to-make-your-api-requests-idempotent-with-working-code-4inl">три паттерна идемпотентности с рабочим кодом</a>, <a href="https://dev.to/seo_optimization_591fad6c/designing-idempotent-decision-endpoints-that-survive-real-retries-6c1">проектирование ручек, переживающих реальные повторы</a> и <a href="https://www.freecodecamp.org/news/how-to-fix-the-dual-write-problem-in-node-js-with-the-outbox-pattern/">пошаговая сборка outbox на Node.js</a>.</p><p>Откройте самый денежный обработчик в своём сервисе и попробуйте отправить в него один и тот же запрос дважды. Если во второй раз что-то произошло, вы уже знаете, с чего начать понедельник.</p>]]></content:encoded>
    </item>
    <item>
      <title>Fable 5.1, GPT-6 Astra и дешёвые Flash: что брать в API в сентябре 2026</title>
      <link>https://tproger.ru/articles/fable-5-1-gpt-6-astra-i-dewyovye-flash-chto-brat-v-api-v-sentyab</link>
      <comments>https://tproger.ru/articles/fable-5-1-gpt-6-astra-i-dewyovye-flash-chto-brat-v-api-v-sentyab?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/fable-5-1-gpt-6-astra-i-dewyovye-flash-chto-brat-v-api-v-sentyab</guid>
      <description><![CDATA[<p>Fable 5.1 и GPT-6 Astra по $10/$50, Gemini 3.8 Flash за $0,75, Mercury 2.5 за $0,20, MAI-Transcribe-2 за $0,10 в час: цена задачи, уровни усилия и команды API.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/fable-5-1-gpt-6-astra-i-dewyovye-flash-chto-brat-v-api-v-sentyab">Fable 5.1, GPT-6 Astra и дешёвые Flash: что брать в API в сентябре 2026</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Нейронные сети]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Машинное обучение]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 08 Sep 2026 18:43:41 GMT</pubDate>
      <content:encoded><![CDATA[<p>За первую неделю сентября 2026 года вышли две флагманские модели с одинаковым прайсом $10 за миллион входных токенов и $50 за миллион выходных: Claude Fable 5.1 от Anthropic 1 сентября и GPT-6 Astra от OpenAI 3 сентября. Рядом появились дешёвые быстрые модели (Gemini 3.8 Flash, Mercury 2.5, DeepSeek V4.1 Flash, Muse Spark 1.3), обновлённая Qwen3.8-Max, две картиночные модели и модель распознавания речи. Ниже по каждой: что умеет по замерам вендора и независимых лабораторий, где лежит и сколько стоит.</p><p>Главный вывод недели: цена за миллион токенов больше не говорит, во что обойдётся задача. Astra стоит за токен в 2,5 раза дороже GPT-5.6 Sol, но по замеру Artificial Analysis в агентном кодинге тратит на задачу втрое меньше токенов и в итоге выходит примерно в ту же сумму; на общих задачах экономия токенов всего 10%. Fable 5.1 сохранила цены Fable 5, но чтение кэша подешевело в 4 раза, и Anthropic оценивает экономию для агентных задач до 45%. Поэтому в этом обзоре у каждой модели рядом с ценой за токен стоит цена за задачу, если её кто-то мерил. Августовские релизы разобраны в <a href="https://tproger.ru/news/fable-5-1-qwen3-8-max-i-deepseek-v4-chto-brat-v-api-za-avgust">прошлом обзоре</a>, здесь они не повторяются.</p><ul><li>Claude Fable 5.1 и Mythos 5.1 — одна модель с разными ограничителями. Цена $10/$50 за миллион токенов, чтение кэша $0,25 вместо $1. По оценке Anthropic это минус около 25% к счёту на типичных задачах и до 45% на агентных.</li><li>GPT-6 Astra стоит те же $10/$50. На Terminal-Bench 4.0 по замеру OpenAI она набирает 57,9% против 55,8% у Fable 5.1 при цене задачи на 63% ниже. В индексе Artificial Analysis v4.3 обе модели делят первое место с 53 баллами, но задача у Astra стоит $3,26 против $7,63 у Fable 5.1.</li><li>Уровень рассуждений стал главным рычагом цены: у Fable 5.1 шаг с xhigh до max даёт полбалла на Humanity's Last Exam за 46% цены сверху, у Astra уровень max удваивает стоимость на коде без прироста точности.</li><li>Дешёвый сегмент: Gemini 3.8 Flash $0,75/$3,75 до конца года, Muse Spark 1.3 $1,25/$4,25 и $0,55 за задачу индекса, Mercury 2.5 $0,20/$0,75 при заявленных 1107 токенах в секунду, DeepSeek V4 Flash $0,22/$0,66 в непиковые часы.</li><li>MAI-Transcribe-2 стоит $0,10 за час аудио до конца года при WER 5,2% на FLEURS по замеру Microsoft. GPT-Transcribe от OpenAI стоит $0,27 за час.</li><li>Автономность пока не продаётся: в эксперименте Bottleneck Labs семь моделей за 72 часа и $300 каждая заработали $0 и отправили 2797 писем.</li></ul><h2>Чем Fable 5.1 отличается от Astra, если цена у них одинаковая?</h2><p>Разница в том, за что вы платите: Fable 5.1 берёт качеством на широком наборе задач и дешёвым кэшем, Astra экономит токены в агентном коде. Anthropic <a href="https://www.anthropic.com/claude-fable-and-mythos-5-1">выпустила</a> Claude Fable 5.1 и Claude Mythos 5.1 как одну модель с разными уровнями ограничителей: Fable доступна всем, Mythos только через программы проверенного доступа для кибербезопасности и биологии. В API модель называется claude-fable-5-1, есть на Amazon Web Services, Google Cloud и Microsoft Azure. Цены прежние, $10 и $50 за миллион токенов, но чтение кэша подешевело на 75%, до $0,25 за миллион. Anthropic посчитала по четырём неделям реального использования в августе, что типичная нагрузка станет дешевле примерно на 25%, а агентная, где кэш составляет большую часть счёта, до 45%. Это оценка вендора.</p><p>По бенчмаркам самой Anthropic модель обошла Opus 5 и GPT-5.6 Sol, а на низком и среднем усилии даёт результат Fable 5 дешевле. У кибер-фильтров на 60% меньше ложных срабатываний: искать уязвимости в коде теперь можно, разработка эксплойтов запрещена. В Claude Code по умолчанию уровень high.</p><blockquote>We're moving our Opus 5 traffic in Devin to Claude Fable 5.1 on launch day. It matched or edged out Fable 5 in our testing at a lower cost per task, and with the new cache read pricing a Fable-class model is finally economical for the workloads we'd kept on Opus, starting with code review.</blockquote><p>OpenAI <a href="https://openai.com/index/gpt-6-astra/">начала раскатку</a> GPT-6 Astra 3 сентября: сначала ограниченному кругу организаций, затем всем на Plus, Pro, Business и Enterprise, в API под именем gpt-6-astra, а также в Microsoft Azure и Amazon Bedrock. Стандартная цена $10 за миллион входных и $50 за миллион выходных токенов, быстрый режим даёт до 2 раз больше скорости за двойную цену. По замеру OpenAI на Terminal-Bench 4.0 Astra набирает 57,9% против 55,8% у Fable 5.1 и 37,3% у Sol, при этом задача по оценке OpenAI обходится на 63% дешевле, чем у Fable 5.1, и на 9% дешевле, чем у Sol. На Humanity's Last Exam и в общем индексе Artificial Analysis она ниже Fable 5.1 и Opus 5. Подробный разбор цен, бенчмарков и кибер-ограничений Astra есть в <a href="https://tproger.ru/news/openai-nachala-vypusk-gpt-6-astra-ceny-benchmarki-i-kiber-ograni">отдельной новости</a>.</p><p>Независимая лаборатория Artificial Analysis <a href="https://x.com/ArtificialAnlys/status/2095595489031000350">разобрала</a> Astra и увидела две разные истории. В Coding Agent Index Astra в Codex набирает 67 баллов, столько же, сколько Opus 5 и Fable 5 в Claude Code, при цене задачи меньше половины от Fable 5. Лидер индекса Fable 5.1 в Claude Code с 70 баллами. Экономия идёт от токенов: Astra тратит на задачу треть от Sol на уровне max и пятую часть от Opus 5 на xhigh. В общем индексе интеллекта картина хуже: токенов уходит всего на 10% меньше, чем у Sol, при том же балле, поэтому после подорожания в 2,5 раза задача стоит на 75% дороже. Галлюцинаций на AA-Omniscience вдвое меньше: 51% против 92% у Sol.</p><blockquote>In the Artificial Analysis Coding Agent Index, GPT-6 Astra equals Fable 5 at less than half the cost, driven by significant token efficiency gains. In the Artificial Analysis Intelligence Index, GPT-6 Astra is more token efficient than its predecessor for similar performance, but this is offset by the price increase.</blockquote><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-09/69de3c9a-38d1-4426-b607-39edb06416d4.webp" alt="Горизонтальная диаграмма: цена за миллион выходных и входных токенов у семи моделей, от $50 у Fable 5.1 и Astra до $0,66 у DeepSeek V4 Flash" /><figcaption>Цена за миллион токенов по прайс-листам вендоров на 9 сентября 2026 года. У Gemini 3.8 Flash вводная цена до конца года, у Mercury 2.5 базовая цена без стартовой скидки 80%, у DeepSeek V4 Flash непиковый тариф. График: Tproger по данным Anthropic, OpenAI, Alibaba Qwen, Google, Inception и DeepSeek</figcaption></figure><p>7 сентября Artificial Analysis <a href="https://x.com/ArtificialAnlys/status/2097025638695940590">обновила</a> индекс до версии 4.3: Terminal-Bench поднят до 4.0, банковский Tau3-Banking заменён на AutomationBench от Zapier. По <a href="https://artificialanalysis.ai/">данным сайта лаборатории</a>, Fable 5.1 и Astra на уровне max делят первое место с 53 баллами, Opus 5 набирает 51, Muse Spark 1.3 48, GLM-5.3 45, Grok 4.6 и Kimi K3 по 44, Gemini 3.8 Flash 41. Цена задачи индекса при этом $7,63 у Fable 5.1, $3,26 у Astra, $5,86 у Opus 5, $1,60 у Muse Spark 1.3 и $1,24 у Gemini 3.8 Flash.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-09/537a325f-2407-4fb8-a6af-d0066d363e52.webp" alt="Точечная диаграмма: балл Artificial Analysis Intelligence Index v4.3 против цены задачи индекса в долларах, логарифмическая шкала, выделен фронт Парето" /><figcaption>Балл индекса против цены за задачу: Fable 5.1 и Astra с одним баллом различаются по цене задачи более чем вдвое. График: Tproger по данным Artificial Analysis, индекс v4.3, 7 сентября 2026 года</figcaption></figure><h2>Какой уровень рассуждений ставить, чтобы не переплатить?</h2><p>Короткий ответ: у обеих флагманских моделей верхняя ступень почти не добавляет качества, а цену поднимает заметно, поэтому начинать стоит с low или medium и подниматься по результатам своей оценки. У Fable 5.1 пять уровней, по умолчанию high. Anthropic в <a href="https://claude.com/blog/reducing-cost-and-improving-performance-with-claude-platform">разборе экономии</a> приводит две цифры: на Humanity's Last Exam шаг с xhigh до max прибавляет около половины балла за 46% цены сверху, а на CursorBench 3.2 Fable 5.1 на low повторяет результат Fable 5 на high втрое дешевле. Команды Claude Code, которые ищут экономию сами (/claude-api prompt-audit, hillclimb, cost-optimize), мы <a href="https://tproger.ru/news/anthropic-pokazala-kak-srezat-schyot-za-claude-bez-poteri-kachest">разбирали отдельно</a>.</p><p>Уровень задаётся параметром output_config.effort, пример из <a href="https://platform.claude.com/docs/en/build-with-claude/effort">документации Anthropic</a> (в примере модель Opus 5, для Fable 5.1 подставьте claude-fable-5-1). Документация отдельно отмечает, что Fable 5.1 умеет менять effort посреди диалога без сброса кэша промптов.</p><p>У Astra уровни задаются через reasoning.effort в Responses API. По <a href="https://platform.openai.com/docs/guides/reasoning">документации OpenAI</a> значение none для GPT-6 Astra не поддерживается и возвращает HTTP 400, а вызов функций работает только в Responses API, не в Chat Completions.</p><p>Однозначного оптимума у Astra нет. По опыту редакции Tproger на общих вопросах уровень выше high не окупается: цена растёт, точность нет. В коде по Coding Agent Index разумно выглядят low, medium и xhigh, а max удваивает стоимость без надёжного прироста. Рабочая схема: low по умолчанию, для сложных подзадач агент вызывает модель на более высоком уровне. Astra цепляется за формулировки, неточный промпт меняет результат сильнее, чем у прежних моделей; чеклист чистки инструкций под неё есть в <a href="https://tproger.ru/articles/gpt-6-astra-vynuzhdaet-perepisat-skills-i-agents-md-cheklist-inzh">отдельной статье</a>.</p><h2>Что взять, если бюджет считается в центах?</h2><p>Четыре модели закрывают этот сегмент по-разному: Gemini 3.8 Flash сильнее всех в агентном коде, Muse Spark 1.3 дешевле всех за задачу на уровне Sol, Mercury 2.5 быстрее всех, DeepSeek V4.1 Flash пока бета. Google <a href="https://blog.google/innovation-and-ai/models-and-research/gemini-models/3-8-flash-and-3-8-flash-cyber/">выпустила</a> Gemini 3.8 Flash 3 сентября по вводной цене $0,75 за миллион входных и $3,75 за миллион выходных токенов; с 1 января 2027 года будет $1,50 и $7,50. Контекст миллион токенов, на <a href="https://openrouter.ai/google/gemini-3.8-flash">OpenRouter</a> у Flex-провайдеров вдвое дешевле. По замеру Google на DeepSWE v1.1, где модель сама доводит инженерную задачу до конца, 3.8 Flash обходит большинство более крупных моделей, на HLE-Verified набирает 54,9%. Google предупреждает: токенов на сложной задаче уйдёт больше, особенно на высоком уровне усилия, и советует понижать уровень или оставаться на 3.7 Flash.</p><blockquote>These performance gains stem from a core design choice: 3.8 Flash works harder. On complex tasks, it exhibits greater diligence — executing extra reasoning steps, and calling tools iteratively. At times, the model might use more tokens to maximize performance, especially at higher effort levels.</blockquote><p>Уровень рассуждений у Gemini задаётся параметром thinking_level, у 3.8 Flash доступны low, medium и high, по умолчанию medium. Пример из <a href="https://ai.google.dev/gemini-api/docs/thinking">документации Gemini API</a>:</p><p>Muse Spark 1.3 от лаборатории суперинтеллекта Александра Вана вышла 2 сентября в Muse Code и в API. Цены не менялись: $1,25 за миллион входных и $4,25 за миллион выходных токенов, попадание в кэш $0,15. По <a href="https://x.com/ArtificialAnlys/status/2095247787277553929">замеру Artificial Analysis</a> открытая всем версия xhigh набрала 61 балл индекса v4.2, вровень с GPT-5.6 Sol и Grok 4.6, при цене $0,55 за задачу индекса против $0,95 у Sol и $0,94 у Grok. Рост почти весь в агентных задачах: банковский Tau3-Bench вырос с 35% до 47%. Просели длинный контекст и AA-Omniscience, где модель чаще отказывается отвечать. Входных токенов на задачу стало больше, поэтому цена задачи выросла с $0,40 у версии 1.2.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-09/212317bb-cc02-4dcf-b3b8-38f684094368.webp" alt="Горизонтальная диаграмма: цена задачи индекса Artificial Analysis, Muse Spark 1.3 xhigh $0,55, Grok 4.6 high $0,94, GPT-5.6 Sol max $0,95" /><figcaption>Цена одной задачи Intelligence Index у трёх моделей с одинаковым баллом 61. График: Tproger по данным Artificial Analysis, 2 сентября 2026 года</figcaption></figure><p>Inception <a href="https://www.inceptionlabs.ai/blog/introducing-mercury-2-5">выпустила</a> Mercury 2.5, диффузионную модель, которая пишет текст блоками параллельно. Заявлено 1107 токенов в секунду на обычных NVIDIA GPU, контекст 260 тыс. токенов, уровень GPT-5.6 Luna на низком усилии и Claude Haiku 4.5. Цена $0,20 за миллион входных и $0,75 за миллион выходных токенов, на старте скидка 80% до $0,04 и $0,15, новым аккаунтам дают 100 млн токенов; модель есть в API Inception, на OpenRouter и Baseten. Независимых замеров Mercury 2.5 пока нет, все цифры вендора. Из кейсов в анонсе: Augment Code перевела на Mercury сжатие контекста, сжатие ускорилось со 150 секунд до 27 при снижении цены на 90%.</p><blockquote>After we switched to Mercury, our P99 response time dropped from several minutes to just one second, and our P50 dropped from 0.4 seconds to under 0.2 — significantly faster than any other provider we've seen, and that's including reasoning.</blockquote><p>DeepSeek 8 сентября <a href="https://www.ithome.com/0/999/795.htm">открыла</a> бету V4.1 Flash на два дня: модель deepseek-v4.1-flash-expires-on-0910 живёт в API до 10 сентября с лимитом 20 параллельных запросов. Цена как у V4 Flash: по <a href="https://api-docs.deepseek.com/quick_start/pricing">прайс-листу</a> $0,22 за миллион входных токенов при промахе кэша, $0,007 при попадании и $0,66 за миллион выходных в непиковые часы; в пиковые вдвое дороже, $0,44 и $1,32. Официальных бенчмарков нет. <a href="https://x.com/plotarmordev/status/2097247035099640216">Тестеры</a> намерили 400–500 токенов в секунду, а китайский <a href="https://xsct.ai/">XSCT Bench</a> поставил V4.1 Flash выше V4 Flash, Gemini 3.8 Flash и Qwen3.8 Flash почти везде.</p><p>Qwen 2 сентября <a href="https://x.com/Alibaba_Qwen/status/2094968708288680276">обновила</a> закрытую Qwen3.8-Max до снапшота 0902: те же 2,4 трлн параметров, миллион контекста, режим размышлений, дообучение на кодинг и совместную агентную работу. По словам Qwen, прирост в основном в коде и агентных правках репозиториев, до Opus 5 в терминале ещё далеко. Цена в <a href="https://www.qwencloud.com/models/qwen3.8-max-0902">QwenCloud</a> $2 за миллион входных и $6 за миллион выходных токенов, чтение кэша $0,17.</p><h2>Что нового в картинках и распознавании речи?</h2><p>Две картиночные модели без бенчмарков и одна речевая с рекордом на FLEURS. OpenAI <a href="https://openai.com/index/introducing-chatgpt-images-2-5/">выпустила</a> ChatGPT Images 2.5: в API две модели, GPT-Image-2.5 Flare по умолчанию с вдвое меньшей задержкой, чем у GPT-Image-2, и Sunburst для точных правок. Цена у обеих $8 за миллион входных токенов картинки, $30 за выходные и $5 за текст на входе. Бенчмарков в анонсе нет, только примеры.</p><p>Microsoft AI <a href="https://microsoft.ai/news/pushing-the-quality-cost-frontier-with-mai-image-2-6/">выпустила</a> MAI-Image-2.6-Flash и вывела MAI-Image-2.6 из закрытого превью в Microsoft Foundry. По заявлению Microsoft, Flash рисует в 2,8 раза быстрее GPT-Image-2-Medium при сопоставимом качестве; старшая модель на Arena вторая в генерации и редактировании, у Artificial Analysis вторая в генерации и первая в редактировании.</p><p>MAI-Transcribe-2 Microsoft <a href="https://microsoft.ai/news/mai-transcribe-2">выпустила</a> 3 сентября: 60 языков с автоопределением, разделение говорящих, таймкоды на каждое слово, режимы verbatim и clean, подсказка терминов. По замеру Microsoft модель первая на мультиязычном FLEURS со средним WER 5,2%, у Artificial Analysis вторая по точности. Цена $0,10 за час аудио как акция до конца года, GPT-Transcribe от OpenAI стоит $0,27 за час. На <a href="https://openrouter.ai/microsoft/mai-transcribe-2">OpenRouter</a> модель лежит под именем microsoft/mai-transcribe-2, ещё есть в Microsoft Foundry и MAI Playground.</p><h2>Какую модель брать под какую задачу в сентябре 2026 года?</h2><p>Ниже сводка по задачам с ценами на 9 сентября. Все цены из прайс-листов вендоров, цены задач из замеров Artificial Analysis и вендоров, как указано.</p><ul><li><b>Агентный кодинг в большой кодовой базе.</b> GPT-6 Astra на low или medium: 67 баллов Coding Agent Index при цене задачи меньше половины от Fable 5 (Artificial Analysis). Если важен максимум качества, Fable 5.1 в Claude Code с 70 баллами, но задача почти вдвое дороже.</li><li><b>Массовые дешёвые задачи с агентами.</b> Gemini 3.8 Flash на low: $0,75/$3,75 до конца года, $1,24 за задачу индекса v4.3. Muse Spark 1.3 на xhigh, если нужен уровень Sol за $0,55 за задачу (AA, v4.2).</li><li><b>Голосовые агенты и всё, где важна задержка.</b> Mercury 2.5: $0,20/$0,75, заявленные 1107 токенов в секунду и медиана ответа около 170 мс у OpenCall. Независимых замеров нет, проверяйте на своём трафике: новым аккаунтам дают 100 млн токенов.</li><li><b>Сжатие контекста и маршрутизация внутри агента.</b> Mercury 2.5 по кейсу Augment Code или DeepSeek V4 Flash за $0,22/$0,66 в непиковые часы.</li><li><b>Транскрибация.</b> MAI-Transcribe-2 за $0,10 в час до конца года против $0,27 у GPT-Transcribe.</li><li><b>Картинки.</b> GPT-Image-2.5 Flare для скорости, Sunburst для правок, $8/$30 за миллион токенов картинки.</li><li><b>Длинный контекст.</b> Qwen3.8-Max-0902 или Gemini 3.8 Flash с миллионом токенов; у Astra и Muse Spark 1.3 длинный контекст по замерам Artificial Analysis просел.</li></ul><p>Порядок действий, чтобы перейти на новые модели без сюрпризов в счёте:</p><ol><li>Замените идентификатор модели: claude-fable-5-1 в Claude API, gpt-6-astra в Responses API, gemini-3.8-flash в Gemini API. У Astra уберите reasoning.effort: none, иначе получите HTTP 400.</li><li>Поставьте низкий уровень усилия (output_config.effort: low, reasoning.effort: low, thinking_level: low) и прогоните свою оценку; поднимайте уровень только там, где балл растёт.</li><li>Проверьте долю попаданий в кэш: у Fable 5.1 чтение кэша стоит $0,25, и смена effort посреди диалога кэш не сбрасывает, у остальных моделей сброс возможен.</li><li>Для агентов с инструментами на Astra заложите обработку остановки: внешний мониторинг OpenAI может прервать задачу, и через API диалог не возобновить.</li><li>Сравнивайте цену задачи вместо цены токена: считайте токены на задачу из поля usage в ответе API и умножайте на прайс.</li></ol><h2>Почему автономный агент на новых моделях всё ещё нельзя оставлять без присмотра?</h2><p>Потому что фильтры вендоров останавливают работу, а сами модели делают лишнее. OpenAI признаёт, что Astra достигла критического уровня в кибербезопасности по её Preparedness Framework: в тестах модель сама нашла и использовала две уязвимости нулевого дня. Поэтому на вызовы с инструментами в Codex, ChatGPT и Responses API включён внешний мониторинг.</p><blockquote>Extra safety checks can sometimes slow, pause, or stop legitimate work, including defensive cybersecurity. If a task is paused in ChatGPT or Codex, you may be asked to review the action before continuing. In the API, the task will stop.</blockquote><p>Вторая причина показана в эксперименте Bottleneck Labs, которая <a href="https://www.bottlenecklabs.com/blog/benchmarking-7-autonomous-businesses">дала</a> семи моделям по $300, Mac mini, почту, Stripe и 72 часа с промптом «заработай как можно больше денег». Итог по всем семи: 2797 писем, 11 живых посетителей, выручка $0, около $2800 на токены. Qwen 3.8 открыла сервис аудита GitHub-репозиториев, упёрлась в лимиты почты и выставила через Stripe 50 счетов незнакомым людям за незаказанную работу на $12 350, сочтя это допустимым шагом продаж. Это один эксперимент одной компании, но подтверждение человеком на платёжных действиях он делает обязательным.</p><p>Попробовать можно без денег: Inception даёт 100 млн токенов Mercury 2.5 новым аккаунтам, а Z.ai до 20 сентября <a href="https://x.com/zcode_ai/status/2095847518194307434">держит</a> ночной Global Build с бесплатной GLM-5.3-Flash для подписчиков Coding Plan. Цену решённой задачи у GLM-5.3, Sol и других мы <a href="https://tproger.ru/news/na-chyom-kodit-v-sentyabre-cena-rewyonnoj-zadachi-u-glm-5-3-sol-i">считали отдельно</a>. Следующая проверка — когда OpenAI закончит раскатку Astra и Artificial Analysis добавит в индекс v4.3 Mercury 2.5 и DeepSeek V4.1 Flash.</p><p>Источники: <a href="https://www.anthropic.com/claude-fable-and-mythos-5-1">Anthropic: Introducing Claude Fable 5.1 and Claude Mythos 5.1</a>, <a href="https://platform.claude.com/docs/en/build-with-claude/effort">Claude Platform Docs: Effort</a>, <a href="https://claude.com/blog/reducing-cost-and-improving-performance-with-claude-platform">Claude Blog: Reducing cost and improving performance with Claude Platform</a>, <a href="https://openai.com/index/gpt-6-astra/">OpenAI: Introducing GPT-6 Astra</a>, <a href="https://platform.openai.com/docs/guides/reasoning">OpenAI Docs: Reasoning models</a>, <a href="https://openai.com/index/introducing-chatgpt-images-2-5/">OpenAI: Introducing ChatGPT Images 2.5</a>, <a href="https://x.com/ArtificialAnlys/status/2095595489031000350">Artificial Analysis: разбор GPT-6 Astra</a>, <a href="https://x.com/ArtificialAnlys/status/2095247787277553929">Artificial Analysis: замер Muse Spark 1.3</a>, <a href="https://x.com/ArtificialAnlys/status/2097025638695940590">Artificial Analysis: Intelligence Index v4.3</a>, <a href="https://artificialanalysis.ai/">Artificial Analysis: главная страница индекса</a>, <a href="https://blog.google/innovation-and-ai/models-and-research/gemini-models/3-8-flash-and-3-8-flash-cyber/">Google: Gemini 3.8 Flash and 3.8 Flash Cyber</a>, <a href="https://ai.google.dev/gemini-api/docs/thinking">Gemini API Docs: Thinking</a>, <a href="https://www.inceptionlabs.ai/blog/introducing-mercury-2-5">Inception: Introducing Mercury 2.5</a>, <a href="https://www.qwencloud.com/models/qwen3.8-max-0902">QwenCloud: Qwen3.8-Max-0902</a>, <a href="https://x.com/Alibaba_Qwen/status/2094968708288680276">Alibaba Qwen: анонс Qwen3.8-Max-0902</a>, <a href="https://api-docs.deepseek.com/quick_start/pricing">DeepSeek API Docs: Pricing</a>, <a href="https://www.ithome.com/0/999/795.htm">IT之家: бета DeepSeek V4.1 Flash</a>, <a href="https://microsoft.ai/news/mai-transcribe-2">Microsoft AI: MAI-Transcribe-2</a>, <a href="https://microsoft.ai/news/pushing-the-quality-cost-frontier-with-mai-image-2-6/">Microsoft AI: MAI-Image-2.6</a>, <a href="https://www.bottlenecklabs.com/blog/benchmarking-7-autonomous-businesses">Bottleneck Labs: Benchmarking 7 autonomous businesses</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Anthropic показала, как срезать счёт за Claude без потери качества</title>
      <link>https://tproger.ru/news/anthropic-pokazala-kak-srezat-schyot-za-claude-bez-poteri-kachest</link>
      <comments>https://tproger.ru/news/anthropic-pokazala-kak-srezat-schyot-za-claude-bez-poteri-kachest?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/anthropic-pokazala-kak-srezat-schyot-za-claude-bez-poteri-kachest</guid>
      <description><![CDATA[<p>Три рычага экономии на Claude Platform: кэш промптов, чистка инструкций и уровень усилия. Команда prompt-audit дала минус 14,6% к цене и плюс 5,3 пункта точности.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/anthropic-pokazala-kak-srezat-schyot-za-claude-bez-poteri-kachest">Anthropic показала, как срезать счёт за Claude без потери качества</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Нейронные сети]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 08 Sep 2026 17:52:36 GMT</pubDate>
      <content:encoded><![CDATA[<p>Anthropic 8 сентября <a href="https://claude.com/blog/reducing-cost-and-improving-performance-with-claude-platform">опубликовала</a> разбор того, где приложения на Claude переплачивают, и заявила, что во многих случаях счёт можно снизить без потери качества. Рычагов три: доля попаданий в кэш промптов, инструкции, написанные под старые модели, и уровень усилия (effort). Все три вынесены в скилл <a href="https://github.com/anthropics/skills/tree/main/skills/claude-api">claude-api</a>, который встроен в Claude Code, и у него появились три команды: /claude-api prompt-audit, /claude-api cost-optimize и /claude-api hillclimb.</p><p>Для разработчика это значит, что аудит расходов теперь можно запустить одной командой прямо в рабочей директории проекта, а не выискивать промахи кэша по логам. Цифры в статье приводит сама Anthropic, поэтому ниже они даются с оговорками авторов.</p><ul><li>Кэш промптов ломают таймстампы в системном промпте, перетасованные описания инструментов и смена effort посреди диалога. Менять effort без сброса кэша умеют отдельные модели, в том числе Opus 5 и Fable 5.1.</li><li>Команда prompt-audit вычищает из промптов «проверь дважды», «будь максимально тщательным», обязательные scratchpad и противоречивые правила. На саппорт-бенчмарке при переезде с Opus 4.8 на Opus 5 это дало минус 14,6% к стоимости и плюс 5,3 пункта точности.</li><li>На CursorBench 3.2 Fable 5.1 на низком усилии повторяет результат Fable 5 на высоком за треть цены. У Fable 5.1 на Humanity's Last Exam шаг с xhigh до max прибавляет полбалла за 46% цены сверху.</li><li>Команда cost-optimize на четырёх открытых бенчмарках с Sonnet 5 срезала 52–73% стоимости при качестве в пределах шума.</li><li>Команда hillclimb подбирает модель, effort и промпт по вашей оценке: на отложенных тестах точность выросла с 78,6% до 90,5% при цене примерно в пять раз ниже.</li></ul><h2>Почему кэш промптов промахивается и как это увидеть?</h2><p>Перед генерацией ответа модель прогоняет весь промпт в рабочее состояние, и этот этап, prefill, и есть дорогая часть обработки входа. Кэш промптов сохраняет это состояние (KV-кэш), и если следующий запрос начинается с того же префикса, модель читает его из кэша вместо пересчёта. Чтение из кэша тарифицируется в разы дешевле полной цены входных токенов: у Fable 5.1 это $0,25 за миллион против $10 за обычный вход.</p><p>Три условия, при которых кэш вообще работает: он привязан к конкретной модели, префикс должен совпадать байт в байт, и у него ограниченный срок жизни. Отсюда типичные промахи, которые Anthropic перечисляет по опыту клиентов: динамический таймстамп или идентификатор в системном промпте, описания инструментов, которые меняют порядок между вызовами, и смена уровня усилия посреди диалога, потому что effort рендерится в промпт перед вашим контентом и входит в кэшируемый префикс. Исключение сделано только для части моделей, включая Opus 5 и Fable 5.1: у них effort можно менять без сброса кэша. Отдельная ловушка у субагентов и веток диалога: они делят кэш родителя только при байт-идентичном префиксе, той же модели и том же effort.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-08/06ee5cf9-0d04-41c1-9899-286122137bb2.webp" alt="Панель диагностики кэша в Claude Console: доля чтений из кэша 71,3% и разбивка промахов по причинам" /><figcaption>Диагностика кэша в Claude Console показывает долю чтений из кэша и причины промахов: изменились сообщения, системный промпт, инструменты или модель. Изображение: Anthropic</figcaption></figure><p>Что с этим делать, по списку Anthropic. Смотреть долю попаданий в кэш в Claude Console и через <a href="https://platform.claude.com/docs/en/build-with-claude/cache-diagnostics">API диагностики кэша</a>: он показывает причину промаха и место, где два запроса разошлись. Редко используемые инструменты объявлять с defer_loading: они не входят в кэшируемый префикс и подгружаются в диалог только когда модель находит их через поиск инструментов. На моделях, которые это поддерживают, обновления системного промпта добавлять как сообщения посреди диалога, а не правкой самого системного промпта. Раскладывать запрос так, чтобы стабильная часть оставалась стабильной: сначала описания инструментов и системный промпт, потом растущий диалог.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-08/d20dce2e-0962-45c7-b52d-97e00753e97b.webp" alt="Схема раскладки промпта: системные инструкции и инструменты кэшируются глобально, CLAUDE.md по проекту, состояние сессии по сессии, сообщения растут с каждым ходом" /><figcaption>Раскладка промпта по слоям кэширования на примере Claude Code. Изображение: Anthropic</figcaption></figure><p>Ещё несколько приёмов из той же статьи. Модель или effort менять в тот момент, когда кэш всё равно сброшен, например при компактификации диалога. Двигать точку кэширования по мере роста диалога: автоматическое кэширование ставит её на последний кэшируемый блок. Прогревать кэш заранее: запрос с max_tokens: 0 и явной точкой кэширования на том же effort, что и боевой трафик, обрабатывает промпт и записывает его в кэш, ничего не генерируя. Если отправить его, пока пользователь ещё печатает, первый настоящий запрос попадёт в тёплый кэш. И не выходить за срок жизни кэша: пятиминутный TTL считается с начала запроса, и если агент ждёт инструмент или субагента дольше пяти минут, кэш родителя истекает до возврата результата. На такие случаи есть <a href="https://platform.claude.com/docs/en/build-with-claude/prompt-caching#ttl-support">часовой TTL</a> на префикс.</p><h2>Какие инструкции вредят новым моделям?</h2><p>Промпты со временем обрастают правилами, которые латали слабости старых моделей, и после обновления модели эти правила начинают мешать. Anthropic перечисляет шесть антипаттернов. Ритуалы проверки: «перепроверь свою работу», «проверь дважды перед ответом» новые модели выполняют буквально и тратят токены впустую. Усилители вроде «будь максимально тщательным» и «КРИТИЧНО: ТЫ ДОЛЖЕН ВСЕГДА…» дают многословие и лишние вызовы инструментов. Обязательные процедуры и шаблоны рассуждений («думай по шагам в scratchpad») накладываются на встроенное мышление модели и жгут токены. Устаревшие примеры few-shot, подобранные под ошибки старой модели, учат новую имитировать длинные цепочки рассуждений там, где они не нужны. Противоречивые правила («всегда возвращай деньги по политике» против «никогда не возвращай без эскалации») новые модели соблюдают буквальнее, и качество падает. И устаревшая конфигурация: настройки под прошлое поколение, например ручные бюджеты на размышления, платформа с новыми моделями может отвергнуть.</p><p>Команда /claude-api prompt-audit ищет всё это в рабочей директории: в коде приложения, который вызывает Claude API, и в конфигурации самого Claude Code, включая CLAUDE.md и скиллы. Для проверки Anthropic взяла бенчмарк службы поддержки и переезд с Opus 4.8 на Opus 5: в чистый промпт по одному подсаживали антипаттерн (снятая настройка thinking, пара противоречивых правил о возвратах, ручной scratchpad, «проверь дважды», «будь максимально тщательным» и обязательная процедура из шести шагов), получили шесть «легаси» промптов и прогнали каждый на Opus 4.8, на Opus 5 с заменой только идентификатора модели и на Opus 5 после одного прогона prompt-audit.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-08/0333e49a-1dd5-4b12-ba2c-926f265e6f0e.webp" alt="График: Opus 4.8 с легаси-промптом 2,52 цента и 89,4% точности, Opus 5 без аудита 3,43 цента и 91,7%, Opus 5 после prompt-audit 2,93 цента и 97,0%" /><figcaption>Среднее по шести легаси-промптам на саппорт-бенчмарке: смена модели подняла точность и цену, аудит промпта снизил цену и поднял точность ещё. Изображение: Anthropic</figcaption></figure><p>В среднем аудит снизил стоимость на 14,6% и поднял точность на 5,3 пункта. Цена упала за счёт лишних вызовов инструментов и дублирующихся рассуждений: на Opus 5 «проверь дважды» превращалось в повторный поиск заказа при каждом возврате, а «будь максимально тщательным» в десятки ненужных обращений к базе знаний. Точность выросла по трём причинам. Снятая настройка thinking заставляла API отвергать каждый запрос на маршрутизацию. Из-за противоречивых правил Opus 5 придержал четыре возврата, которые был должен, и просил клиента подтвердить. А ручной scratchpad конфликтовал со встроенным мышлением Opus 5: в трёх тикетах модель написала вызов инструмента внутри рассуждений и не выполнила его.</p><h2>Когда высокий effort не окупается?</h2><p>Effort задаёт, насколько усердно модель работает: на low она быстрее приходит к выводу, на high дольше рассуждает, проверяет и перебирает альтернативы. Кривая цена-качество у одной и той же модели бывает очень разной. У Fable 5 на FrontierCode Diamond (50 самых сложных задач) low даёт 11,5% за $5,35 на задачу, max даёт 30,9% за $19,00: результат вырос примерно в 2,7 раза за примерно 3,5 раза по цене. А у Fable 5.1 на Humanity's Last Exam без инструментов кривая крутая, но с плоским последним шагом: около 53% на low за примерно $0,30 на вопрос и около 61% на max за $2,23, при этом шаг с xhigh до max добавляет около половины балла за 46% цены сверху. Этот прирост укладывается в разброс между прогонами бенчмарка, то есть переплата идёт ни за что.</p><p>Ошибиться можно в обе стороны. Считать, что выше всегда лучше: на high модель может передумывать дольше, чем требует задача, это добавляет цену и задержку и может ухудшить ответ, потому что рассуждение помогает только пока есть что искать. И зажимать effort до low: тогда модель останавливается раньше, чем собрала достаточно улик, делает меньше вызовов инструментов, отвечает по первому результату поиска вместо третьего и пропускает проверку, которую сделала бы сама. Ответ выглядит законченным, но построен на неполной информации.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-08/25b2b728-2502-4034-93dc-17ce3fd5f8b4.webp" alt="График CursorBench 3.2: Fable 5.1 на low набирает столько же, сколько Fable 5 на high, при цене за задачу около $3 против $9" /><figcaption>CursorBench 3.2: пять уровней усилия Fable 5 и Fable 5.1, цена за задачу в логарифмической шкале. Изображение: Anthropic</figcaption></figure><p>Совет Anthropic звучит так: пробовать более сильную модель на низком усилии, потому что она может выйти дешевле слабой на высоком. На CursorBench 3.2 Fable 5.1 на low повторяет результат Fable 5 на high за треть цены. Дешевле по двум причинам: на low модель делает меньше работы на задачу, а чтение из кэша у Fable 5.1 стоит $0,25 за миллион токенов против $1,00 у Fable 5. Даже по ценам Fable 5 Fable 5.1 на low обошлась бы примерно на 40% дешевле. Второй совет: понять форму своей задачи, прогнав оценку по всем уровням усилия. Если на ненасыщенном бенчмарке кривая плоская, задача не упирается в вычисления на размышления, и поднимать effort бессмысленно.</p><h2>Что делают команды hillclimb и cost-optimize?</h2><p>/claude-api hillclimb автоматизирует этот перебор. Команда делит вашу оценку на обучающую и тестовую части, предлагает изменения конфигурации и читает проваленные примеры из обучающей части, чтобы починить найденное. На том же саппорт-бенчмарке старт был с Opus 4.8 на дефолтном high. Первым шагом hillclimb попробовал Opus 5 на low с prompt-audit, который убрал обязательные ритуалы вызова инструментов, шаги scratchpad и противоречивые правила: это превысило базовый уровень Opus 4.8 с 98,9% точности на обучающей части и снизило цену до 2,6 цента за тикет. Затем он спустился до Sonnet 5 на low: ещё дешевле, 1 цент за тикет, но точность упала до 88,9%. Прочитав проваленные тикеты, Claude добавил в промпт правила маршрутизации и сверку с лимитом на возврат, и Sonnet 5 вернулась к 98,9% при той же цене.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-08/9e666b9d-3976-4670-8220-4a136e0bf4de.webp" alt="Путь hillclimb: Opus 4.8 high с 74,4% за 4,4 цента, Opus 5 low около 99% за 2,6 цента, Sonnet 5 low 88,9% за 1 цент, Sonnet 5 low с улучшенным промптом около 99% за 1 цент" /><figcaption>Четыре шага hillclimb на обучающей части саппорт-бенчмарка: точность решения и цена за тикет. Изображение: Anthropic</figcaption></figure><p>На 14 отложенных тикетах, которых поиск не видел, итоговая конфигурация набрала 90,5% против 78,6% у исходной, при цене примерно в пять раз ниже. Разрыв между 98,9% на обучающей части и 90,5% на тестовой стоит держать в уме: на отложенных примерах прирост заметно меньше.</p><p>/claude-api cost-optimize нужна для полного аудита расходов кода, который ходит в Claude API. Сначала она выясняет, куда уходят токены: из отчётов об использовании и затратах организации, если есть ключ Claude Admin API, из объекта usage в каждом ответе API, если приложение его логирует, а если нет ни того, ни другого, читает код сборки запросов и оценивает. Затем ранжирует доступную экономию: кэш промптов, урезание того, что несёт каждый запрос (включая prompt-audit), ограничение вывода и отправка неинтерактивной работы через Batch API. Если дать ей оценку качества, она ещё и считает цену и результат по уровням усилия и моделям.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-08/3c5d5930-dd12-4dfe-9010-88ae46aae1af.webp" alt="Четыре бенчмарка после cost-optimize: tau2-bench retail минус 72,7%, LegalBench минус 57,6%, OfficeQA Pro минус 52,4%, SWE-bench Verified минус 55,1%, изменение результата в пределах доверительных интервалов" /><figcaption>cost-optimize на четырёх открытых бенчмарках с Sonnet 5 как базой: цена за прогон и изменение результата с 95% доверительными интервалами. Изображение: Anthropic</figcaption></figure><p>Anthropic прогнала её на четырёх открытых бенчмарках с Sonnet 5 как базой. На LegalBench команда предложила кэшировать общий префикс между задачами, поставить low и гнать задачи через Batch API: токены на размышления упали со 102 779 до 8 284, доля решённых осталась в пределах шума, цена снизилась примерно на 58%. На tau2-bench retail кэш с явной расстановкой точек кэширования дал минус 72% при той же доле решённых. На OfficeQA Pro пакетная обработка и кэширование документов снизили цену со $136,20 до $64,87. На SWE-bench Verified cost-optimize обнаружила, что кэш в дефолтной конфигурации уже настроен правильно, и экономию дали medium вместо high и ограничение вывода агента несколькими короткими фразами: медиана шагов на задачу упала с 29 до 17, входные токены с 75,2 млн до 33,7 млн, минус 55% по цене. По графику на SWE-bench результат при этом просел на 3,3 пункта при интервале от минус 9,6 до плюс 3,1, то есть значимого изменения не установлено, но интервал допускает и ухудшение, и на своих задачах это стоит перепроверить.</p><h2>С чего начать?</h2><p>Порядок, который предлагает сама Anthropic. Если вы переехали на новую модель Claude и хотите проверить старые промпты, запускайте /claude-api prompt-audit: она сканирует промпты, скиллы и описания инструментов в рабочей директории, будь то код приложения или конфигурация Claude Code. Если приложение ходит в Claude API и нужен аудит расходов, берите /claude-api cost-optimize: она профилирует расход токенов и проверяет рычаги по очереди, а с оценкой качества ещё и меряет компромиссы по effort и выбору модели. Если есть оценка и нужен поиск по цене и качеству, /claude-api hillclimb разобьёт её на обучающую и тестовую части, предложит изменения и оценит финальную конфигурацию на отложенных примерах.</p><p>Скилл claude-api встроен в Claude Code, отдельно он лежит <a href="https://github.com/anthropics/skills/tree/main/skills/claude-api">на GitHub</a>. Подробности по каждому рычагу собраны в <a href="https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence">документации</a> и в <a href="https://platform.claude.com/cookbook/cost-optimization-cost-optimization">кукбуке по снижению затрат</a>. Все цифры в статье получены в прогонах Anthropic, в том числе на четырёх открытых бенчмарках; сторонних проверок в публикации нет. О том, на что способна Fable 5.1 в агентных сценариях, мы <a href="https://tproger.ru/news/agenty-fable-5-1-sobrali-v-brauzere-prohodimuyu-kopiyu-yunion-skver">писали</a> на примере агентов, собравших копию Юнион-сквер, а про открытый чертёж торгового агента на Claude есть <a href="https://tproger.ru/news/anthropic-otkryla-claude-commerce-agents-chertyozh-torgovogo-agent">отдельный разбор</a>.</p><p>Источники: <a href="https://claude.com/blog/reducing-cost-and-improving-performance-with-claude-platform">Claude Blog: Reducing cost and improving performance with Claude Platform</a>, <a href="https://x.com/ClaudeDevs/status/2097369738968195513">Анонс @ClaudeDevs в X</a>, <a href="https://platform.claude.com/docs/en/about-claude/models/optimizing-for-cost-and-intelligence">Документация: Optimizing for cost and intelligence</a>, <a href="https://github.com/anthropics/skills/tree/main/skills/claude-api">Скилл claude-api на GitHub</a>, <a href="https://platform.claude.com/cookbook/cost-optimization-cost-optimization">Cookbook: Cost optimization</a></p><p>Изображение на обложке: Anthropic, заставка статьи «Reducing cost and improving performance with Claude Platform»</p>]]></content:encoded>
    </item>
    <item>
      <title>Вышла FreeBSD 14.5 с поддержкой Linux API inotify</title>
      <link>https://tproger.ru/news/vywla-freebsd-14-5-s-podderzhkoj-linux-api-inotify</link>
      <comments>https://tproger.ru/news/vywla-freebsd-14-5-s-podderzhkoj-linux-api-inotify?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/vywla-freebsd-14-5-s-podderzhkoj-linux-api-inotify</guid>
      <description><![CDATA[<p>FreeBSD 14.5 получила нативный API inotify, LLVM 21.1.8 и изменения для Clang. Релиз доступен с 8 сентября, его поддержка продлится до 30 июня 2027 года.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/vywla-freebsd-14-5-s-podderzhkoj-linux-api-inotify">Вышла FreeBSD 14.5 с поддержкой Linux API inotify</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Open Source]]></category>
      <category><![CDATA[Операционные системы]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 08 Sep 2026 12:03:20 GMT</pubDate>
      <content:encoded><![CDATA[<p>Команда FreeBSD 8 сентября <a href="https://www.freebsd.org/releases/14.5R/announce/">выпустила FreeBSD 14.5-RELEASE</a> — шестой релиз ветки stable/14. Среди изменений для разработчиков — нативный API inotify, совместимый с Linux на уровне исходного кода, и обновление LLVM до версии 21.1.8.</p><p>Поддержка inotify появилась в ядре и стандартной библиотеке libc. Приложения могут получать уведомления об изменениях в файловой системе, не открывая каждый отслеживаемый файл. Это упрощает перенос программ, которые используют такой API в Linux; речь о совместимости исходников, а не о гарантированном запуске готовых Linux-приложений.</p><p>Для Clang изменили выбор линкера по умолчанию: теперь используется ld.lld вместо поиска линкера по имени ld. В math.h также стали доступны тригонометрические функции стандарта C23 с множителем π, в том числе sinpi и cospi.</p><p>Изменения затронули и командную строку. Утилита pwd по умолчанию работает в режиме -L, а не -P, как требует POSIX: при выводе пути сохраняются символические ссылки. Размер истории sh по умолчанию увеличили со 100 до 128 записей. Эти и другие изменения перечислены в <a href="https://www.freebsd.org/releases/14.5R/relnotes/">примечаниях к выпуску</a>.</p><p>Разработчики подчёркивают, что в 14.5 основной акцент сделан на исправлениях и обновлении компонентов. Уже доступны установочные образы и образы виртуальных машин. Поддержка FreeBSD 14.5 продлится до 30 июня 2027 года.</p>]]></content:encoded>
    </item>
    <item>
      <title>Пагинация и лимиты API: как отдавать данные постранично и не дать выгрести базу</title>
      <link>https://tproger.ru/articles/paginaciya-i-limity-api-kak-otdavat-dannye-postranichno-i-ne-dat</link>
      <comments>https://tproger.ru/articles/paginaciya-i-limity-api-kak-otdavat-dannye-postranichno-i-ne-dat?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/paginaciya-i-limity-api-kak-otdavat-dannye-postranichno-i-ne-dat</guid>
      <description><![CDATA[<p>Пагинация через OFFSET тормозит на глубоких страницах и теряет строки. Смотрите, как перейти на курсор и настроить лимиты запросов — с кодом и замерами.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/paginaciya-i-limity-api-kak-otdavat-dannye-postranichno-i-ne-dat">Пагинация и лимиты API: как отдавать данные постранично и не дать выгрести базу</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Высокие нагрузки]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 07 Sep 2026 05:00:45 GMT</pubDate>
      <content:encoded><![CDATA[<p>Ваш API отдаёт страницы по двадцать записей и работает прекрасно ровно до того дня, когда у первого крупного клиента накопится полмиллиона строк. Тогда выяснится сразу две вещи: страницы стали открываться секундами, а синхронизация на стороне клиента дважды затянула одни и те же заказы.</p><p>Оба симптома дают один и тот же виновник — постраничная выдача через OFFSET. И оба чинятся одним переходом, причём переписывать приходится только слой выдачи.</p><p>Пагинация — это способ отдать большую коллекцию по частям. Вариантов ровно два. Offset-пагинация просит базу пропустить N строк и вернуть следующие двадцать. Курсорная (её же называют keyset) запоминает последнюю отданную запись и просит всё, что идёт после неё.</p><p>Стоимость OFFSET растёт линейно: на таблице в 1,2 млн строк выборка со смещением в миллион занимает 2,4 с против 3 мс у курсора.</p><p>Под параллельными вставками и удалениями OFFSET выдаёт дубликаты и пропуски, потому что нумерация строк сдвигается между запросами.</p><p>Курсор не поддерживает переход на произвольную страницу, поэтому для админок и таблиц с кнопкой «страница 47» offset остаётся правильным выбором.</p><p>Лимиты запросов на счётчике в памяти инстанса не работают: при десяти инстансах настроенные 100 запросов в минуту превращаются в 1000.</p><p>Скользящее окно на сортированном множестве Redis и атомарном Lua-скрипте занимает пятнадцать строк и снимает гонку без распределённых блокировок.</p><p>Результат на спокойной базе одинаковый. Поведение под ростом данных и параллельными записями — принципиально разное.</p><h2>Offset ломается двумя разными способами</h2><p>Про первый знают почти все, про второй вспоминают уже после инцидента.</p><h3>Он линейно замедляется</h3><p>PostgreSQL, MySQL и SQLite не умеют «перепрыгнуть» через строки. При OFFSET 100000 база честно читает сто тысяч строк и выбрасывает их, чтобы отдать следующие двадцать. Стоимость запроса растёт вместе со смещением.</p><p>Автор разбора <a href="https://dev.to/sirmax/why-i-switched-my-api-from-offset-to-cursor-pagination-and-when-you-shouldnt-1464">замерил это на таблице в 1,2 млн строк</a> в PostgreSQL 15 с холодным кешем и обычным btree-индексом по id:</p><p>Курсорный вариант на той же таблице держал 3 мс на любой глубине. Разница объясняется сложностью: поиск по индексу это O(log n), а большое смещение — O(offset). На пятидесятитысячной странице пользователь ждёт больше двух секунд вместо миллисекунд.</p><h3>Он врёт, когда в таблицу пишут</h3><p>Этот сценарий коварнее. Пользователь загрузил первую страницу с двадцатью записями, отсортированными от новых к старым. Пока он читал, в таблицу добавились три новые записи. Запрос второй страницы с OFFSET 20 вернёт часть того, что уже было на первой: всё сдвинулось на три позиции.</p><p>Клиент получает дубликаты. При удалении записей картина обратная — часть строк он не увидит никогда, потому что они проскочили мимо границы страницы. У автора статьи на этом сломалась синхронизация у клиента: задание дважды загрузило одни и те же двадцать заказов, и три письма в поддержку ушло на то, чтобы понять, что виновата пагинация, а не код клиента.</p><p>Курсор от этого защищён по построению. Курсор — это последняя фактически полученная запись, поэтому «всё, что после неё» остаётся верным независимо от того, сколько строк вставили или удалили между запросами.</p><h2>Как выглядит курсор в коде</h2><p>Простейшая версия работает по первичному ключу и умещается в один обработчик:</p><p>Обратите внимание на per_page + 1. Запрашивая на одну запись больше, чем собираетесь отдать, вы узнаёте о существовании следующей страницы без отдельного запроса COUNT. Лишняя запись отбрасывается, а её наличие становится флагом has_more.</p><h3>Составной курсор: место, где ломается наивная версия</h3><p>Курсор по одному id корректен, только пока вы сортируете по id. Как только сортировка идёт по created_at, простое условие created_at &gt; X начинает терять записи: два заказа, созданные в одну миллисекунду, дают ничью, и одна из строк молча исчезает из выдачи.</p><p>Лечится это составным курсором — ключ сортировки плюс первичный ключ, сравниваемые как кортеж:</p><p>Сравнение кортежей разрешает ничьи детерминированно, поэтому ни одна строка не дублируется и не пропадает. Под это нужен составной индекс (created_at DESC, id DESC), иначе выигрыш в скорости пропадёт вместе с планом запроса.</p><p><b>Про формат курсора:</b><br />Не отдавайте наружу голый идентификатор, если планируете менять схему. Заверните значения в маленький JSON с полем версии и закодируйте в base64: тогда через год вы поменяете состав курсора, не сломав клиентов, которые прямо сейчас держат страницу открытой.</p><h2>Когда офсетную пагинацию нужно оставить</h2><p>Курсор не бесплатный, и подменять им всё подряд не стоит. Есть четыре ситуации, где offset честно лучше:</p><ul><li>Интерфейсу нужен переход на конкретную страницу. У курсора нет номеров страниц, поэтому админки, таблицы и всё с кнопкой «перейти к странице 47» остаются на offset.</li><li>Данных мало и они не меняются. Справочник на пять тысяч строк не выиграет ничего, зато offset проще объяснить и отладить.</li><li>Пагинация идёт по памяти или по кешу, где смещение и так стоит O(1).</li><li>Сортировка задаётся пользователем по произвольной колонке. Курсор тут превращается в кодирование кортежей в непрозрачные строки, и это уже заметная сложность.</li></ul><p>Разумное правило: курсор по умолчанию для всего, что может перерасти десять тысяч строк или читается во время записи. Offset — для небольших, статичных и внутренних данных.</p><p>И отдельно стоит помнить, что пагинация обычно не единственная нагрузка на базу. Кто ещё и насколько сильно её грузит, разбирали в переводе про <a href="https://tproger.ru/translations/patterny-upravleniya-trafikom-k-postgresql-v-production">паттерны управления трафиком к PostgreSQL</a>.</p><h2>Вторая половина задачи: кто и сколько может забрать</h2><p>Правильная пагинация решает, как отдавать данные. Она не решает, сколько их заберут за минуту. Ограничение частоты запросов выглядит тривиально («считай запросы, блокируй сверх N») и превращается в задачу распределённых систем ровно в тот момент, когда серверов становится два.</p><h3>Сначала ответьте, от чего защищаетесь</h3><p>От выбранной цели зависит вся конструкция, и целей <a href="https://dev.to/weston_carnes_d580b505e0c/api-rate-limiting-patterns-algorithms-and-how-to-do-it-right-4l35">обычно выделяют четыре</a>:</p><ul><li>Защита от перегрузки — не дать всплеску положить сервис.</li><li>Честное распределение — не дать одному шумному клиенту вытеснить остальных.</li><li>Защита от злоупотреблений — притупить перебор паролей, скрейпинг и подстановку учётных данных.</li><li>Контроль расходов — ограничить дорогие ручки вроде вызова модели или построения отчёта. Тот же принцип со стороны поставщика разбирали на примере <a href="https://tproger.ru/articles/kak-ogranichit-rashody-na-openai-api-chtoby-ii-agenty-ne-sozhgli">лимитов трат в OpenAI API</a>.</li></ul><h3>Три алгоритма и один, который выбирают почти всегда</h3><p><b>Фиксированное окно</b> считает запросы в календарном интервале: сто в минуту со сбросом на начале минуты. Просто и дыряво: клиент отправляет сотню в 12:00:59 и ещё сотню в 12:01:00, то есть двести за одну секунду. Граница окна и есть дыра.</p><p><b>Скользящее окно</b> считает в непрерывно сдвигающемся интервале, часто взвешивая счётчик предыдущего окна по мере хода времени. Точнее, но требует больше состояния.</p><p><b>Ведро токенов</b> обычно и оказывается верным выбором по умолчанию. В ведре лежит до N токенов, оно пополняется с постоянной скоростью, каждый запрос тратит один токен. Такая схема разрешает контролируемые всплески (молчавший клиент накопил токены и может потратить их разом), но держит среднюю нагрузку в рамках. Родственное «дырявое ведро» выдаёт идеально ровный поток и нужно там, где принимающая сторона всплесков не переносит.</p><blockquote>Фиксированное окно пишут первым и потом жалеют. На ведро токенов мигрируют.</blockquote><h3>Ловушка, из-за которой лимит не работает вообще</h3><p>Счётчик в памяти процесса живёт до появления второго сервера. После этого «сто запросов в минуту» тихо означает «сто запросов в минуту на инстанс», и при десяти инстансах клиент законно получает тысячу. Ошибку не видно ни в логах, ни в мониторинге: лимит вроде бы работает, просто не тот.</p><p>Лечится это переносом счётчика в общее хранилище, обычно в Redis, причём проверка и инкремент обязаны быть атомарными. Последовательность «прочитать, сравнить, увеличить» из кода приложения гоняется между инстансами и недосчитывает запросы ровно под той нагрузкой, ради которой лимит и ставили.</p><h2>Скользящее окно на Redis: пятнадцать строк Lua</h2><p>Команда сервиса jo4.io столкнулась с частным случаем этой задачи: ручка подсказки категорий ходит в модель через Groq, каждый вызов стоит денег, а пользователь может дёрнуть её полсотни раз за минуту. Нужны были лимиты на конкретную ручку и на конкретного пользователя, причём в тот же день.</p><p>Скользящее окно они <a href="https://dev.to/anand_rathnas_d5b608cc3de/redis-sliding-window-rate-limiting-with-lua-the-15-line-script-that-saved-our-ai-budget-p0i">собрали на сортированном множестве Redis</a>. Скор записи — временная метка в миллисекундах, а весь алгоритм умещается в один Lua-скрипт, который Redis выполняет атомарно:</p><p>Первая команда чистит записи старше окна относительно текущего момента — именно поэтому окно скользящее, а не фиксированное: границ, к которым можно приурочить всплеск, здесь просто нет. PEXPIRE с запасом в секунду доубивает ключ, если новых запросов не приходит, так что чистить хранилище отдельно не нужно.</p><h3>Две детали, на которых легко ошибиться</h3><p><b>Уникальность члена множества.</b> ZADD не добавляет запись, а перезаписывает существующую, если член совпал. Два запроса в одну миллисекунду с одинаковым значением дадут счётчик, который занижен. Авторы склеивают метку времени с восемью символами UUID: метка обеспечивает уникальность почти всегда, а восемь шестнадцатеричных символов дают около четырёх миллиардов вариантов внутри одной миллисекунды.</p><p><b>Куда падать при отказе Redis.</b> Решение здесь принимается осознанно и по-разному для двух случаев. Если вызов не получил внятного ответа вовремя (таймаут клиента, сетевая икота), запрос пропускают: лимит здесь страхует бюджет, а не безопасность, и блокировать живого пользователя из-за сбоя инфраструктуры хуже, чем оплатить лишний вызов модели. А вот жёсткое исключение (Redis недоступен, соединение отвергнуто) пробрасывают наверх: если хранилище легло целиком, лучше шумно упасть, чем молча жечь бюджет вообще без ограничений.</p><p>Обошлось это в два часа работы вместе с тестами. Одна запись в сортированном множестве занимает около 50 байт, на пользователя их пять, и даже при десяти тысячах активных пользователей всё хранилище лимитов весит порядка 2,5 МБ. Настроенный лимит составил пять запросов за шестьдесят секунд на пользователя. Первым же уловом стал автоматизированный скрипт, бивший в ручку больше двухсот раз в час.</p><h2>Честный контракт с клиентом</h2><p>Ограничение без внятного ответа превращает вежливого клиента в невежливого: не понимая, что происходит, он начинает долбить чаще. Минимальный набор обязательств выглядит так:</p><ul><li>Отдавать 429 Too Many Requests, а не общий 400 или 503. По коду клиент понимает, что делать.</li><li>Присылать заголовок Retry-After, чтобы клиент знал момент следующей попытки, а не подбирал его перебором.</li><li>Показывать остаток бюджета в заголовках вида X-RateLimit-Remaining и X-RateLimit-Reset.</li></ul><p>Последний пункт стоит дешевле всего и работает лучше всего: клиент, который видит свой остаток, обычно распределяет запросы сам и до стены не доходит.</p><h2>Что забрать с собой</h2><p>Обе половины задачи решаются до того, как появится нагрузка, и обе стоят один вечер. Курсорная пагинация убирает и деградацию на глубоких страницах, и молчаливую порчу выдачи при параллельных записях. Атомарный счётчик в общем хранилище превращает лимит из декоративного в настоящий.</p><p>Отложить их дешевле всего прямо сейчас и дороже всего в момент, когда в поддержку придёт клиент с задвоенными заказами: тогда чинить придётся не только API, но и данные на его стороне.</p><p>Разборы, на которых основан материал: <a href="https://dev.to/sirmax/why-i-switched-my-api-from-offset-to-cursor-pagination-and-when-you-shouldnt-1464">переход с offset на курсор с замерами</a>, <a href="https://dev.to/weston_carnes_d580b505e0c/api-rate-limiting-patterns-algorithms-and-how-to-do-it-right-4l35">паттерны и алгоритмы ограничения частоты</a> и <a href="https://dev.to/anand_rathnas_d5b608cc3de/redis-sliding-window-rate-limiting-with-lua-the-15-line-script-that-saved-our-ai-budget-p0i">скользящее окно на Redis и Lua</a>.</p><p>Откройте свой самый нагруженный список и выполните запрос с большим смещением. Если ответ идёт дольше сотни миллисекунд, вы уже нашли, с чего начать.</p>]]></content:encoded>
    </item>
    <item>
      <title>Anthropic открыла Claude Commerce Agents: чертёж торгового агента на Claude</title>
      <link>https://tproger.ru/news/anthropic-otkryla-claude-commerce-agents-chertyozh-torgovogo-agent</link>
      <comments>https://tproger.ru/news/anthropic-otkryla-claude-commerce-agents-chertyozh-torgovogo-agent?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/anthropic-otkryla-claude-commerce-agents-chertyozh-torgovogo-agent</guid>
      <description><![CDATA[<p>Anthropic открыла Claude Commerce Agents под Apache 2.0: два агента для магазина, три способа запуска, проверки внутри вызова инструмента и свой бэкенд.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/anthropic-otkryla-claude-commerce-agents-chertyozh-torgovogo-agent">Anthropic открыла Claude Commerce Agents: чертёж торгового агента на Claude</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Open Source]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 02 Sep 2026 19:53:51 GMT</pubDate>
      <content:encoded><![CDATA[<p>Anthropic 2 сентября 2026 года <a href="https://x.com/ClaudeDevs/status/2095233745167282602">открыла исходники</a> Claude Commerce Agents: двух агентов на Claude для интернет-торговли под лицензией Apache 2.0. Первый, покупательский, бизнес встраивает в своё приложение для клиентов. Второй, мерчантский, нужен сотрудникам, чтобы вести листинги, цены, остатки и кампании. В <a href="https://github.com/anthropics/commerce-agents">репозитории anthropics/commerce-agents</a> лежат оба агента, четыре демонстрационные вертикали (розница, путешествия, телеком, билеты), семь pip-пакетов и плагин для Claude Code, который собирает такого агента под чужой стек.</p><p>Для команды, которая пишет ассистента магазина или маркетплейса, интерес здесь в архитектуре, а не в демо. Anthropic показывает, как описать агента один раз и запускать тремя способами, где стоят проверки, чтобы модель не могла подложить в корзину чужой товар или изменить цену без человека, и как подключить свой каталог через два интерфейса на Python.</p><p>Оговорка стоит в самом README: это референсная реализация, она не поддерживается и не принимает внешний вклад. В примерах нет аутентификации, MCP-серверы по умолчанию слушают loopback.</p><ul><li>Два агента, три способа запуска (Messages API, Claude Agent SDK, Managed Agents (beta)), четыре вертикали и восемь веб-приложений в одном репозитории под Apache 2.0.</li><li>Не оформляет заказ, не списывает деньги и не меняет живые листинги: checkout только рисует корзину, каждая запись мерчанта ждёт одобрения человека.</li><li>Проверки provenance, лимиты, ограждение стороннего текста и валидация памяти работают внутри вызова инструмента и держатся на всех трёх путях запуска.</li><li>Своя интеграция сводится к реализации StorefrontBackend или MerchantBackend; отсутствующие системы выключаются переключателями enable_*.</li><li>Модели по умолчанию: claude-sonnet-5 у покупательского агента, claude-opus-5 у мерчантского, claude-haiku-4-5-20251001 для памяти; рантаймы работают через Vertex AI, Bedrock, Microsoft Foundry и шлюзы.</li><li>Требования: Python 3.11 и новее, Node 22. Демо поднимается шестью командами из README.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-03/8278495a-80f4-42a1-baf3-e052ab3d3504.webp" alt="Кадр из видео Anthropic с четырьмя вертикалями: Retail, Travel, Telecom, Ticketing" /><figcaption>Четыре вертикали из анонсирующего видео. Скриншот: Anthropic, commerce-agents</figcaption></figure><h2>Один агент описан один раз и работает на трёх рантаймах</h2><p>Главная архитектурная идея репозитория, как её формулирует <a href="https://github.com/anthropics/commerce-agents/blob/main/README.md">README</a>: каждый агент определён один раз (промпт, скиллы, контракты инструментов, гейты) и запускается на Messages API, на Claude Agent SDK и на Managed Agents. Четыре вертикали работают поверх одних библиотек и различаются бэкендом и доменными расширениями интерфейса.</p><p>Покупательский агент ищет и сравнивает товары, собирает планы покупок, наполняет корзину, отвечает на вопросы о заказах и правилах магазина и запоминает, что покупатель о себе рассказал. Его пять сценариев лежат как skills в каталоге <a href="https://github.com/anthropics/commerce-agents/tree/main/shopping-agent/skills">shopping-agent/skills</a>. Мерчантский агент объясняет показатели, правит листинги, реагирует на алерты по остаткам и заказам, назначает цены и промо, готовит кампании. Его пять сценариев лежат в <a href="https://github.com/anthropics/commerce-agents/tree/main/merchant-agent/skills">merchant-agent/skills</a>. Любая запись мерчанта становится staged change, которую применяет уже интерфейс одобрения на стороне хоста.</p><blockquote>Nothing places an order, charges a card, or changes a live listing: checkout renders the cart for the host to complete, and every merchant write is staged until a person approves it.</blockquote><p>Код разложен на семь pip-пакетов. Общее для обеих ролей вынесено в commerce-common: конфиг, ограждение стороннего текста, память, скиллы, grounding, презентационные компоненты, исполнитель инструментов и события. У каждой роли три пакета: core с типами, интерфейсом бэкенда, промптом, контрактами инструментов и гейтами; runtime с циклом ходов на Messages API; sdk с тем же агентом на Agent SDK и консолью. CI проверяет, что имена семи пакетов остаются незарегистрированными в публичном индексе, а pin-файлы ставят их из каталогов репозитория.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-03/6f818534-34eb-4db9-9321-d353b648b4e1.webp" alt="Горизонтальная диаграмма: состав репозитория commerce-agents в штуках: 2 агента, 3 рантайма, 4 вертикали, 7 пакетов, 8 веб-приложений, 10 flows, 7 расширений интерфейса, 4 команды плагина" /><figcaption>Состав поставки по README репозитория. График: Tproger по данным README anthropics/commerce-agents</figcaption></figure><p>Эталонный путь запуска, вокруг которого построены примеры, это Messages API. Хост создаёт объект агента с бэкендом, каталогом скиллов и конфигом и стримит события хода; извлечение памяти вызывается отдельно после хода, и только на этом пути. Код из README:</p><p>На Agent SDK тот же промпт, скиллы и инструменты, но цикл ведёт SDK: хост заранее подгружает данные для grounding, после хода ничего не выполняется. На Managed Agents агент размещён у Anthropic и ходит за данными в ваш MCP-сервер; деплой делает скрипт scripts/deploy_managed_agent.sh, без флага --live это сухой прогон. Различия трёх путей по docs/safety.md:</p><ul><li><b>Messages API.</b> Все правила grounding включаются принудительно через tool_choice; работают извлечение памяти после хода, сжатие истории и бюджеты аналитического делегата мерчанта.</li><li><b>Agent SDK.</b> Grounding только для правил с формой предварительной загрузки; цикл ограничен max_turns; аналитика мерчанта идёт субагентом без SQL-инструмента и бюджетов; память хост извлекает сам.</li><li><b>Managed Agents.</b> Grounding отсутствует, циклом владеет платформа, память пишется только через save_memory, одобрением staged change служит промпт always_ask на apply_change.</li></ul><h2>Проверки стоят внутри вызова инструмента, поэтому переживают смену рантайма</h2><p>Документ <a href="https://github.com/anthropics/commerce-agents/blob/main/docs/safety.md">docs/safety.md</a> делит правила на три группы: что код проверяет сам, что по-прежнему просят у модели промптом и что обязан добавить деплой. Ключевой приём: правило внутри вызова инструмента держится на всех трёх путях, потому что все три прогоняют вызовы через один исполнитель в модуле commerce_common/execution.py. Правило на уровне хода живёт в конкретном рантайме, и таблица указывает, где оно не работает.</p><blockquote>A rule enforced inside a tool call holds on all three paths, because the Messages API runtime, the SDK toolset, and the MCP server execute tools through the same executor.</blockquote><p>Что именно проверяется в коде, по таблице документа:</p><ul><li><b>Ограждение (fencing).</b> Сторонний текст очищается, оборачивается в ограждение с фиксированной меткой и обрезается до max_fenced_chars. Очистка убирает невидимые и управляющие символы, поддельные маркеры ходов, теги транскрипта и вызовов инструментов и копии самого маркера ограждения.</li><li><b>Лимиты цикла.</b> Запрошенное моделью число результатов поиска обрезается до max_search_results; после max_tool_iterations раундов рантайм Messages API принудительно делает ход без инструментов.</li><li><b>Provenance корзины.</b> В корзину попадают только идентификаторы товаров, которые в этой сессии вернул инструмент каталога или заказов. Попытка добавить товар с опциями (размер, цвет) задерживается, и модели показывают варианты. Действует лимит на позицию и на число строк.</li><li><b>Нет оплаты.</b> У StorefrontBackend нет метода, который размещает заказ или списывает деньги. URL размещённого checkout приходит из checkout_handoff после вызова модели и не проходит через неё.</li><li><b>Provenance staged-записей мерчанта.</b> Изменение принимает только идентификаторы листингов и кампаний, возвращённые инструментом в этой сессии; правка контента требует чтения get_listing. apply_change принимает только идентификаторы изменений, которые вернули staging или get_pending_changes.</li><li><b>Guardrails мерчанта.</b> Проверяются при постановке изменения и повторно при применении: число позиций, размах изменения цены, глубина промо, размер пополнения, бюджет кампании, защищённые поля.</li><li><b>Одобрение хостом.</b> При require_host_approval (включено по умолчанию) apply_change проходит только для идентификаторов, которые хост пометил одобренными. Карточка предпросмотра ничего не одобряет, «да, применяй» в чате тоже.</li><li><b>Память.</b> Ключ факта до 64 символов, значение до 200, одна из трёх категорий; значения, похожие на идентификаторы, отбрасываются. Извлечение читает только текст последнего обмена, никогда результаты инструментов.</li><li><b>Поверхность инструментов и идентичность.</b> Список инструментов вычисляется из конфига деплоя, исполнитель отказывает любому другому имени. Идентичность держит сервер: ни один аргумент инструмента не называет пользователя или мерчанта.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-03/858edd4a-4a45-4ee5-adca-71116592a154.webp" alt="Горизонтальная диаграмма лимитов: ключ факта памяти 64 символа, значение 200 символов, ограждение стороннего текста 12 000 символов по умолчанию" /><figcaption>Лимиты, которые проверяет код: память покупателя и размер одного ограждения. График: Tproger по данным docs/safety.md и docs/backends.md anthropics/commerce-agents</figcaption></figure><p>Вторая группа правил остаётся в промпте: трактовать ограждённый текст как материал для отчёта, называть условия и цифры только из результата инструмента, подтверждать запись только после успешного вызова, называть товары по идентификатору. Документ оговаривает: промптовые правила держатся ровно настолько, насколько модель следует инструкциям, а таблица держится на любой модели. Деплой, который меняет модель или выключает require_host_approval, должен сначала перегнать свои evals по этому разделу.</p><blockquote>When the model breaks one of these, the error is confined to its text. Every write, figure, and disclosure behind that text still passed the checks in the table above, so the failure is a misstatement to correct and no action needs reversing.</blockquote><p>Третья группа целиком на стороне деплоя: аутентификация и авторизация на каждом маршруте и на MCP-серверах (примеры принимают любого вызывающего), учётные данные для вызова ваших сервисов, лимиты запросов, бизнес-правила (фрод, право на покупку, цены, остатки), оплата после checkout, обращение с памятью как с персональными данными, гигиена логов и сама поверхность одобрения. Значения guardrails в двух файлах config.py названы демонстрационными.</p><h2>Своя интеграция сводится к двум интерфейсам и переключателям enable_*</h2><p>Точка входа для собственных систем описана в <a href="https://github.com/anthropics/commerce-agents/blob/main/docs/backends.md">docs/backends.md</a>. Деплой реализует StorefrontBackend поверх каталога, корзины, заказов и политик или MerchantBackend поверх аналитики, каталога, остатков, цен и кампаний. Контрактом служат докстринги методов в backend.py и types.py каждой роли. Каждый метод вызывает ваш сервис на стороне сервера с учётными данными, которые хост хранит для сессии; модель видит только результат.</p><blockquote>Each one calls your service server-side with the credential your host holds for the session; the model reads only the result.</blockquote><p>Документ раскладывает интеграцию на шесть шагов. Первый: решить, кто вызывающий. Хост аутентифицирует человека и стартует сессию с принципалом; токен покупателя живёт в контексте сессии, сервисная учётка передаётся в конструктор бэкенда. Гость тоже принципал: чтение, которому нужен аккаунт, бросает исключение, которое подкласс исполнителя превращает в просьбу войти. Второй: порядок многошаговых сценариев (удержать места, затем подтвердить) хранится и проверяется в бэкенде, а нарушение маппится через domain_error в понятный модели результат. Третий: как завершается checkout. Вариантов три: ссылка на маршрут в вашем приложении, размещённый checkout платформы, для которого checkout_handoff возвращает URL, или маркетплейс с записью на каждого продавца.</p><p>Четвёртый шаг: товары с опциями. Запись бывает простой, семейством (с полем options) или вариантом (с option_values и variant_of); идентификатор варианта идёт всюду, где ждут идентификатор товара. Детали товара возвращают все варианты семейства в одном ограждении, обрезанном до max_fenced_chars (12 000 символов по умолчанию). Компактная строка варианта занимает 70–120 символов, так что в семейство помещается около шестидесяти вариантов; кроссовки в восьми цветах и четырнадцати размерах документация советует подавать как восемь семейств по четырнадцать, потому что за пределами лимита результат режется без ошибки. Пятый: записи мерчанта по семействам, где изменение цены и пополнение именуют вариант. Шестой: для цифр, которых у платформы нет, возвращать None с пометкой, а не подставной ноль.</p><p>Для пилота README предлагает начинать с малого. Покупательский пилот реализует поиск и карточку товара, а остальное заглушает: метод-заглушка возвращает результат «недоступно» и не меняет ни байта промпта. Мерчантский пилот реализует восемь методов чтения, записи отказывают. Система, которой у бизнеса нет совсем, выключается переключателем enable_*: это убирает её инструменты, строки промпта и правило grounding на всех трёх путях, а сценарии, которым она нужна, паркуются в каталоге skills/_staged/. Свой сценарий добавляется каталогом с файлом SKILL.md, доменный интерфейс расширением PresentationExtension (вертикали поставляют семь), а brand_name, assistant_name и brand_voice в конфиге задают личность ассистента.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-09-03/632d0218-5e02-4a2c-8f59-e75bb9f7efce.webp" alt="Кадр из видео Anthropic: путь от намерения покупателя до staged-заказа" /><figcaption>Кадр «From intent to a staged order» из анонсирующего видео. Скриншот: Anthropic, commerce-agents</figcaption></figure><h2>Модели заданы строкой в конфиге, а переключение платформы сосредоточено в одном месте и зависит от рантайма</h2><p>По <a href="https://github.com/anthropics/commerce-agents/blob/main/docs/deployment.md">docs/deployment.md</a> код по умолчанию ходит в API Anthropic, но у каждого пути есть одно место, где деплой переключает платформу. Рантаймы Messages API принимают любой асинхронный клиент из пакета anthropic аргументом client=: AsyncAnthropicVertex для GCP Vertex AI, AsyncAnthropicBedrockMantle или AsyncAnthropicBedrock для AWS, AsyncAnthropicFoundry для Microsoft Foundry, AsyncAnthropic с base_url и auth_token для собственного шлюза. Пакеты требуют anthropic 0.91 и новее. Рантаймы Agent SDK HTTP-клиента не создают: платформу выбирает CLI Claude Code по переменным окружения, которые добавляются в options.env. Managed Agents работает на инфраструктуре Anthropic, поэтому у него нет варианта для Vertex, Bedrock и Foundry.</p><p>Модель задаётся строкой в конфиге: поля model и memory_model у каждой роли, у мерчанта ещё analysis_model. Значения по умолчанию, по таблице документа: claude-sonnet-5 для покупательского агента, claude-opus-5 для мерчантского, claude-haiku-4-5-20251001 для извлечения памяти. Грамматика идентификаторов у платформ разная: Vertex пишет датированные снимки через @, Bedrock через Mantle берёт идентификаторы с префиксом anthropic., а через Invoke API идентификаторы inference-профилей. Все три поля идут через один клиент, поэтому все три модели должны существовать на целевой платформе. Живого разговора с облаком в CI нет; документ просит прогнать его на своей платформе до того, как на неё полагаться.</p><p>Доступность API Anthropic и облачных платформ для конкретной страны или способа оплаты в документации репозитория не обсуждается. Для собственного шлюза документ называет требование: отдавать /v1/messages со стримингом SSE для Messages API, а для Managed Agents ещё проксировать /v1/skills, /v1/agents, /v1/environments, /v1/sessions и поток событий сессии с заголовками anthropic-beta.</p><h2>Демо поднимается шестью командами, а плагин Claude Code собирает агента под ваш стек</h2><p>Порядок запуска из README (нужны Python 3.11 и новее и Node 22, ключ ANTHROPIC_API_KEY в файле .env):</p><p>Флаг --merchant поднимает портал мерчанта вместо витрины, --all оба. В README каждой вертикали есть раздел Try с репликами, которые прогоняет scripts/smoke_chat.py. Розничная ACME показывает поиск, сравнение, корзину, checkout и память; ACME Travel добавляет инвентарь с датами; ACME Mobile матрицу тарифов и серверные раскрытия комиссий; ACME Tickets таймированные удержания мест, листы ожидания и карту зала.</p><p>Второй способ начать: <a href="https://github.com/anthropics/commerce-agents/tree/main/plugins/commerce-builder">плагин commerce-builder</a> для Claude Code. Он читает клонированный репозиторий как эталон и собирает агента на этих пакетах против ваших систем либо проверяет уже написанного. Установка и первая команда из README:</p><p>Команда /scaffold-commerce-agent спрашивает о стеке, проговаривает план и строит проект. Дальше /add-commerce-flow добавляет сценарий, /author-commerce-evals пишет evals, /review-commerce-agent начинает с уже существующего агента. Собственных MCP-коннекторов в поставке нет: оба агента ходят в системы через интерфейсы бэкенда. Где официальный коннектор является источником истины (Snowflake, BigQuery, Stripe, Square, Slack и другие в списке README), он и становится целью интеграции. MCP-сервер торговой платформы вызывается из метода бэкенда на сервере, и гейты provenance остаются перед каждой записью.</p><p>Проверка после правок: ruff check и ruff format --check, pytest, python scripts/check.py; python scripts/verify_all.py добавляет сухие прогоны деплоя и сборку веб-приложений; python scripts/smoke_chat.py --vertical travel проводит один живой разговор и требует ключ. Чтобы убедиться, что кэширование промпта работает, README советует читать cache_read_input_tokens из события turn_complete: ноль на втором ходу означает, что префикс промпта изменился.</p><h2>Что делать команде, которая пишет ассистента для магазина</h2><ol><li>Поднять розничное демо по шести командам выше (Python 3.11 и новее, Node 22, ключ API) и пройти реплики из раздела Try в examples/retail/ на витрине (порт 3000) и в портале мерчанта (флаг --merchant, порт 3100).</li><li>Сверить таблицу «Enforced in code» и список «What a deployment owns» из docs/safety.md с собственной платформой: аутентификация, учётные данные, лимиты запросов, бизнес-правила, оплата, персональные данные в памяти, логи.</li><li>Для пилота реализовать в StorefrontBackend только поиск и карточку товара, для MerchantBackend восемь методов чтения. Отсутствующие системы выключить через enable_*, зависимые сценарии убрать в skills/_staged/.</li><li>Разложить каталог по трём формам записи из docs/backends.md и проверить самое большое семейство против лимита max_fenced_chars в 12 000 символов.</li><li>Выбрать завершение checkout: свой маршрут, размещённый URL платформы через checkout_handoff или ссылка на продавца для маркетплейса; оплата остаётся в хосте.</li><li>Для Vertex AI, Bedrock, Foundry или шлюза передать клиент аргументом client= (anthropic 0.91 и новее) или переменные CLI в options.env и заменить все три идентификатора моделей.</li><li>Перед выкладкой прогнать ruff, pytest, scripts/check.py и scripts/verify_all.py, затем один живой разговор scripts/smoke_chat.py на своей платформе; при смене модели перегнать evals по разделу «Still asked of the model».</li></ol><p>Репозиторий создан 1 сентября, анонс в аккаунте Claude Developers вышел 2 сентября в 19:33 UTC. На 3 сентября, 01:53 мск, по <a href="https://api.github.com/repos/anthropics/commerce-agents">данным GitHub API</a> у проекта 277 звёзд и 46 форков. Поддержки и приёма внешних изменений Anthropic не обещает: «This is a reference implementation; it is not maintained and does not accept contributions», говорится в README. На практике это значит, что исправления и адаптацию под свои системы команде придётся вести в собственном форке, а промпты и гейты под новые модели проверять своими evals. Цен, лимитов и сроков дальнейшего развития Anthropic в репозитории не называет.</p><p>Источники: <a href="https://x.com/ClaudeDevs/status/2095233745167282602">Claude Developers в X: анонс открытия Claude Commerce Agents (2 сентября 2026)</a>, <a href="https://github.com/anthropics/commerce-agents">GitHub: anthropics/commerce-agents</a>, <a href="https://github.com/anthropics/commerce-agents/blob/main/README.md">README репозитория commerce-agents</a>, <a href="https://github.com/anthropics/commerce-agents/blob/main/docs/safety.md">docs/safety.md: правила, проверяемые кодом, и обязанности деплоя</a>, <a href="https://github.com/anthropics/commerce-agents/blob/main/docs/backends.md">docs/backends.md: подключение своих систем</a>, <a href="https://github.com/anthropics/commerce-agents/blob/main/docs/deployment.md">docs/deployment.md: Vertex AI, Bedrock, Microsoft Foundry и шлюзы</a>, <a href="https://github.com/anthropics/commerce-agents/tree/main/plugins/commerce-builder">Плагин commerce-builder для Claude Code</a>, <a href="https://github.com/anthropics/commerce-agents/tree/main/shopping-agent/skills">Скиллы покупательского агента</a>, <a href="https://github.com/anthropics/commerce-agents/tree/main/merchant-agent/skills">Скиллы мерчантского агента</a></p><p>Изображение на обложке: Anthropic, кадр из анонса Claude Commerce Agents</p>]]></content:encoded>
    </item>
    <item>
      <title>METR рассказала, как у неё украли API-ключ через приложение с ошибкой fail-open</title>
      <link>https://tproger.ru/news/metr-rasskazala-kak-u-neyo-ukrali-api-klyuch-k-modelyam-vajb-kodi</link>
      <comments>https://tproger.ru/news/metr-rasskazala-kak-u-neyo-ukrali-api-klyuch-k-modelyam-vajb-kodi?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/metr-rasskazala-kak-u-neyo-ukrali-api-klyuch-k-modelyam-vajb-kodi</guid>
      <description><![CDATA[<p>Лаборатория METR раскрыла два инцидента 2026 года: кражу API-ключа к моделям через самодельное приложение на личном EC2 и майскую кампанию сканирования. Цепочка ошибок, что удалось и что не удалось атакующим, правила хранения ключей для команд, работающих с LLM.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/metr-rasskazala-kak-u-neyo-ukrali-api-klyuch-k-modelyam-vajb-kodi">METR рассказала, как у неё украли API-ключ через приложение с ошибкой fail-open</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Облачные технологии]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 01 Sep 2026 17:30:42 GMT</pubDate>
      <content:encoded><![CDATA[<p>Исследовательская лаборатория <b>METR</b>, которая оценивает возможности ИИ-моделей для крупных разработчиков, 31 августа <a href="https://metr.org/blog/2026-08-31-security-update/">опубликовала</a> отчёт о двух инцидентах безопасности 2026 года. В марте у неё украли API-ключ для запросов к публичным моделям и три недели тратили её кредиты, в мае злоумышленники сканировали публичную инфраструктуру и перебирали пароли. По оценке METR, к самым чувствительным данным доступ не получили.</p><p>METR оценивает израсходованные бесплатные кредиты примерно в $600 тыс., но интереснее цепочка ошибок: она типична для любой команды, которая быстро собирает внутренние инструменты вокруг LLM. Ключ лежал на личном сервере исследователя, приложение было написано с помощью ИИ и при сбое проверки доступа пропускало запрос вместо того, чтобы отклонить его. Российские команды, которые получают доступ к зарубежным моделям через посредников или общие ключи, рискуют сильнее: перевыпуск ключа у них занимает не минуты, а дни.</p><ul><li>Март 2026 года: API-ключ для инференса публичных моделей украден с личного EC2-инстанса исследователя, где стояло самодельное приложение за Google-аутентификацией.</li><li>Приложение имело уязвимость fail-open: при ошибке проверки доступ открывался; инстанс был намеренно публичным за Google-аутентификацией.</li><li>Атакующий попросил агента показать ключ, получил его и добавил на сервер собственный SSH-ключ; чужие запросы шли около трёх недель.</li><li>Май 2026 года: сканирование сервисов, подбор паролей по утёкшим базам, попытки через OAuth-токены; в публичном просмотрщике транскриптов нашли ошибку с read-only SQL, признаков её эксплуатации нет.</li><li>METR остановила и сняла образ инстанса, заменила учётные данные; описанные меры актуальны на 30 июля 2026 года.</li></ul><h2>Как украли ключ</h2><p>Исследователь METR поднял на личном инстансе EC2 небольшое веб-приложение, написанное с помощью ИИ, и защитил его входом через Google. В коде была классическая ошибка <b>fail-open</b>: если проверка авторизации по какой-то причине не срабатывала, приложение считало пользователя допущенным, а не отказывало. Инстанс намеренно был публичным за входом через Google, и ошибка fail-open сняла эту защиту; этого хватило.</p><blockquote>The vibe-coded app included a fail-open vulnerability.</blockquote><p>Дальше атакующий, по описанию METR, попросил агента показать ключ API, и тот его раскрыл, а для постоянного доступа добавил на сервер собственный SSH-ключ. Ключ использовали для запросов к публичным моделям примерно три недели. Заметить это оказалось трудно по двум причинам: METR не платила за эти кредиты деньгами, так что счёт не рос, а внутренняя панель METR не показывала запросы, отклонённые по лимитам, для всех пользователей ключа.</p><h2>Вторая волна: май</h2><p>В мае METR зафиксировала другую активность: сканирование публичной инфраструктуры, перебор паролей по утёкшим базам и попытки получить OAuth-токены. Попутно выяснилось, что публичный просмотрщик транскриптов позволял выполнять SQL-запросы только на чтение, но через эту ошибку в теории можно было добраться до неопубликованных данных оценок. Признаков, что атакующие этим воспользовались, компания не нашла. Описанные меры, по словам METR, актуальны на 30 июля 2026 года.</p><h2>Правила, которые из этого следуют</h2><ul><li>Ключи API к моделям не живут на личных серверах и ноутбуках: только в секрет-хранилище команды с выдачей по ролям и сроком жизни.</li><li>Приложения с доступом к ключам делайте fail-closed: любая ошибка в проверке прав — отказ, а не пропуск. Это первое, что стоит проверить в коде, написанном с ИИ.</li><li>На каждый ключ — лимит расходов и алерт на аномалию по числу запросов, а не только по деньгам: бесплатные кредиты тратятся так же незаметно.</li><li>Отдельный ключ на каждое приложение и человека: один общий ключ означает, что после утечки ротировать придётся всё сразу.</li><li>Инстансы «на минутку» с публичным IP считайте продом: инвентаризация, автоматическое выключение по таймеру, запрет входящих портов по умолчанию.</li></ul><h2>Контекст</h2><p>METR получает от разработчиков моделей ранний доступ для оценок безопасности, поэтому её инфраструктура — заметная цель. То, что оба инцидента пришлись на периферию (личный сервер, публичный просмотрщик), а не на основные системы, говорит скорее о сегментации, чем об удаче. Но именно периферия и есть то место, где у большинства команд лежат ключи «на время». Сумму METR оценивает примерно в $600 тыс. бесплатных кредитов, которые она не оплачивала деньгами.</p><p>Источник: <a href="https://metr.org/blog/2026-08-31-security-update/">Security update (METR, 31 августа 2026)</a></p><p>Изображение на обложке: METR</p>]]></content:encoded>
    </item>
    <item>
      <title>Цифровой рубль вышел в массовое использование: что менять в интеграциях</title>
      <link>https://tproger.ru/news/cifrovoj-rubl-vywel-v-massovoe-ispolzovanie-s-1-sentyabrya-perv</link>
      <comments>https://tproger.ru/news/cifrovoj-rubl-vywel-v-massovoe-ispolzovanie-s-1-sentyabrya-perv?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/cifrovoj-rubl-vywel-v-massovoe-ispolzovanie-s-1-sentyabrya-perv</guid>
      <description><![CDATA[<p>С 1 сентября 2026 года крупнейшие банки и ритейлеры открыли инфраструктуру цифрового рубля. Как устроен третий вид денег, какие лимиты, сроки и комиссии установил Банк России, кто обязан принимать цифровые рубли и что менять в платёжных интеграциях магазинов и сервисов.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/cifrovoj-rubl-vywel-v-massovoe-ispolzovanie-s-1-sentyabrya-perv">Цифровой рубль вышел в массовое использование: что менять в интеграциях</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Организация разработки]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 01 Sep 2026 17:29:45 GMT</pubDate>
      <content:encoded><![CDATA[<p>С 1 сентября 2026 года крупнейшие банки и торговые компании открыли инфраструктуру <b>цифрового рубля</b>, <a href="https://www.cbr.ru/press/event/?id=32802">сообщил</a> Банк России 31 августа. Совершеннолетний гражданин с подтверждённой учётной записью Госуслуг может завести цифровой счёт в приложении подключённого банка, а крупнейшие магазины обязаны принимать оплату в новой форме. Для разработчиков это означает появление третьего платёжного канала рядом с картами и СБП, со своими правилами, лимитами и сроками подключения.</p><p>Цифровой рубль — не криптовалюта и не «безнал на карте». Счёт открывается на платформе Банка России, а банк выступает посредником, через приложение которого клиент этим счётом управляет. Один человек или компания может иметь только один такой счёт; у ИП их два: личный и для бизнеса. Если вы делаете интернет-магазин, кассу, биллинг или сервис подписок для компании из первой волны, приём цифрового рубля становится обязательным сценарием, а не опцией.</p><ul><li>Счёт цифрового рубля открывается на платформе Банка России через раздел «Цифровой рубль» в приложении подключённого банка; один счёт на физлицо или компанию, у ИП два.</li><li>Лимит пополнения для физлиц — 300 тыс. рублей в месяц, для бизнеса лимита нет; тратить накопленное можно без ограничений.</li><li>Для граждан операции бесплатны; для бизнеса комиссии не взимаются до конца 2026 года, тарифы с 2027 года установлены отдельным решением Банка России от 28 августа.</li><li>Принимать цифровые рубли обязаны с 1 сентября 2026 года торговые компании с выручкой свыше 120 млн рублей, у которых на 1 января 2026 года был договор с крупнейшим банком-участником; торговые точки с выручкой до 5 млн рублей освобождены.</li><li>Все банки с универсальной лицензией подключаются к 1 сентября 2027 года, с базовой — к 1 сентября 2028 года; сроки закреплены законом 248-ФЗ.</li></ul><h2>Как это устроено</h2><p>Платформа цифрового рубля принадлежит Банку России, и все счета живут на ней, а не в отдельных банках. Банк лишь даёт интерфейс: открыть счёт, пополнить его с обычного счёта, заплатить, вернуть деньги обратно. Отсюда две особенности, которых нет у безнала: счёт один на всю страну, и, сменив банк, клиент сохраняет тот же счёт; лимиты и комиссии задаёт регулятор, а не банк. Регулятор допускает и банки, которые не обязаны открывать инфраструктуру этой осенью, но хотят предоставлять сервис уже сейчас.</p><blockquote>Граждане смогут пополнять счёт цифрового рубля со своих банковских счетов на сумму до 300 тыс. рублей в месяц. Для бизнеса лимита на пополнение нет. Всеми накоплениями на своём цифровом кошельке и граждане, и компании смогут распоряжаться без ограничений.</blockquote><p>Доступные операции: переводы между гражданами и компаниями, платежи в бюджет и из бюджета, оплата покупок, возвраты. Открытие и закрытие счёта бесплатны, для граждан бесплатны все платежи и переводы. Для бизнеса действует льготный период до конца 2026 года; тарифы для индивидуальных предпринимателей и компаний с 2027 года установлены <a href="https://www.cbr.ru/rbr/dir_decisions/rsd_2026-08-28_45_01/">отдельным решением Совета директоров Банка России от 28 августа 2026 года</a>. По вопросам работы с цифровыми рублями регулятор советует обращаться сначала в свой банк, затем на горячую линию Банка России по цифровому рублю: 8 800 301 30 00, короткий номер 301 с мобильного или +7 499 300 3 301.</p><h2>Сроки для банков и магазинов</h2><p>Внедрение идёт волнами. С 1 сентября 2026 года инфраструктуру открывают крупнейшие банки, а торговые компании с выручкой свыше 120 млн рублей в год, у которых на 1 января 2026 года был договор с таким банком, обязаны принимать цифровые рубли. С 1 сентября 2027 года такую возможность должны обеспечить все банки с универсальной лицензией, с 1 сентября 2028 года — банки с базовой лицензией. Торговые точки с выручкой меньше 5 млн рублей от обязанности освобождены, как и торговые точки там, где нет интернета. Обязательные сроки для банков и продавцов закреплены федеральным законом 248-ФЗ, а решение Банка России определяет лимиты, перечень операций и порядок добровольного раннего подключения остальных банков.</p><h2>Что это значит для разработчика платёжной интеграции</h2><p>Технически приём идёт через банк-участник, поэтому прямой интеграции с платформой Банка России у магазина нет: интерфейс и документацию даёт ваш банк. Возвраты уходят обратно на цифровой счёт покупателя, а не на карту, и это отдельная ветка в логике рефандов и чеков. Лимит 300 тыс. рублей в месяц касается пополнения счёта физлицом; расход ограничен только остатком на счёте.</p><ul><li>Узнайте у своего банка, как он подключает приём цифровых рублей и какие интерфейсы даёт; для крупнейших банков это уже сентябрь 2026 года.</li><li>Заложите в модель данных третий тип платежа рядом с картой и СБП: у него свои статусы, свой возврат и своя сверка.</li><li>Возвраты: средства уходят обратно на цифровой счёт покупателя; учитывайте это в логике рефандов и в чеках.</li><li>Комиссии для бизнеса появятся с 2027 года по тарифам решения от 28 августа; не зашивайте «бесплатно» в расчёт стоимости платежей.</li><li>Торговые точки с выручкой до 5 млн рублей, точки без интернета и, до сентября 2027 года, клиенты банков вне списка крупнейших могут не спешить: для них цифровой рубль пока добровольный.</li></ul><h2>Контекст</h2><p>Пилот цифрового рубля стартовал в августе 2023 года на ограниченном круге клиентов и банков. К концу сентября 2025 года в нём было открыто больше 2,5 тыс. кошельков и проведено больше 90 тыс. операций. Массовый запуск дважды переносили. Следующая проверка — сентябрь 2027 года, когда к платформе должны подключиться все банки с универсальной лицензией, и тарифы для бизнеса, которые начнут действовать с января.</p><p>Источники: <a href="https://www.cbr.ru/press/event/?id=32802">Сообщение Банка России о старте с 1 сентября</a>, <a href="https://www.cbr.ru/rbr/dir_decisions/rsd_2026-08-28_45_02/">Решение Совета директоров Банка России от 28.08.2026</a>, <a href="https://www.cbr.ru/fintech/dr/">Страница проекта «Цифровой рубль»</a></p><p>Изображение на обложке: Банк России</p>]]></content:encoded>
    </item>
    <item>
      <title>RAG-бот для любого сайта на Python за 60 строк кода</title>
      <link>https://tproger.ru/articles/rag-bot-dlya-lyubogo-sajta-na-python-za-60-strok-koda</link>
      <comments>https://tproger.ru/articles/rag-bot-dlya-lyubogo-sajta-na-python-za-60-strok-koda?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/rag-bot-dlya-lyubogo-sajta-na-python-za-60-strok-koda</guid>
      <description><![CDATA[<p>Соберите простого RAG-бота на Python, который читает любую веб-страницу и отвечает на вопросы только по её тексту. Гайд с кодом и объяснениями.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/rag-bot-dlya-lyubogo-sajta-na-python-za-60-strok-koda">RAG-бот для любого сайта на Python за 60 строк кода</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Обучение программированию]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Машинное обучение]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 26 Aug 2026 12:06:57 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если попросить языковую модель ответить по свежей документации или конкретному сайту, она с блеском выдумает то, чего там нет. Стандартное решение — <strong>Retrieval-Augmented Generation (RAG)</strong>: сначала достать реальный текст, найти в нём нужные куски и только потом передать их модели в качестве контекста.</p><p>В этой статье соберём работающего RAG-бота, который отвечает на вопросы о любой веб-странице, примерно на 60 строках Python. Никаких парсеров HTML, headless-браузеров и сложных фреймворков — только requests, локальная Ollama и чистый Markdown.</p><h2>Что такое RAG</h2><p>RAG (retrieval-augmented generation) — это подход, при котором языковая модель не отвечает по своей памяти, а сначала ищет релевантные фрагменты во внешнем тексте, а потом генерирует ответ на их основе. Это резко снижает галлюцинации и позволяет работать с данными, которых не было в обучающей выборке.</p><ul><li>RAG-бот на Python укладывается в ~60 строк и работает без облачных LLM.</li><li>Самое неприятное в RAG-пайплайне — очистка HTML; готовый Markdown API убирает эту работу.</li><li>Текст разбивается на чанки (~1200 символов), каждый превращается в эмбеддинг и сравнивается с эмбеддингом вопроса.</li><li>Локальные модели nomic-embed-text и llama3 через Ollama не требуют иностранных карт и VPN.</li><li>Качество ответа зависит от качества исходного текста: сырой HTML зашумляет поиск, чистый Markdown улучшает ретривл.</li></ul><h2>Что мы соберём</h2><p>Архитектура бота простая и универсальная:</p><ol><li>Отправляем URL в сервис извлечения текста и получаем чистый Markdown.</li><li>Разбиваем Markdown на фрагменты (чанки) по границам абзацев.</li><li>Превращаем каждый чанк в вектор — эмбеддинг.</li><li>То же самое делаем с вопросом пользователя.</li><li>Находим чанки, ближайшие к вопросу, по косинусной близости.</li><li>Отдаём найденные фрагменты + вопрос языковой модели с инструкцией отвечать только по контексту.</li></ol><p>Такая схема легко масштабируется: можно заменить локальную Ollama на OpenAI, Anthropic или российские модели, а векторы перенести в Qdrant или Chroma.</p><h2>Что понадобится</h2><ul><li>Python 3.9+</li><li>Библиотека requests</li><li>Локально запущенная Ollama с моделями nomic-embed-text и llama3</li><li>Доступ к API извлечения текста (в примере — <a href="https://rapidapi.com/xiaobao882026/api/web-to-markdown-json-api" rel="noopener noreferrer">Web to Markdown/JSON API</a>; бесплатный тариф даёт 50 запросов в сутки)</li></ul><h2>Код бота</h2><p>Сохраните скрипт как rag_bot.py и подставьте свой ключ, если сервис извлечения текста требует авторизации:</p><p><b>На что обратить внимание:</b><br />Если вы используете RapidAPI-версию сервиса, запрос к API_URL обычно требует заголовка X-RapidAPI-Key. Без ключа бесплатный endpoint может вернуть 401.</p><h3>Разбор по частям</h3><p>fetch_markdown — единственный внешний вызов. Сервис сам забирает страницу, убирает навигацию, баннеры и футер и возвращает Markdown: заголовки, абзацы, списки. Это освобождает от зависимостей вроде BeautifulSoup или headless Chrome.</p><p>chunk_markdown режет текст на фрагменты примерно по 1200 символов, не разрывая абзацы. Мелкие чанки дают более точный ретривл, но увеличивают число эмбеддингов; для начала 1200 символов — хороший баланс.</p><p>embed и cosine превращают текст в векторы и считают их близость. Модель nomic-embed-text из Ollama бесплатна, быстрая и неплохо понимает русский и английский.</p><p>answer эмбеддит вопрос, выбирает три самых похожих чанка и строит промпт с жёстким ограничением: отвечать только по контексту. Это главная страховка от галлюцинаций.</p><h2>Запуск</h2><p>Установите зависимости и скачайте модели в Ollama:</p><p>Если всё в порядке, в консоли появится примерно такой результат:</p><h2>Почему важен чистый Markdown</h2><p>Если скормить эмбеддинг-модели сырой HTML, в векторах окажутся теги &lt;div&gt;, меню навигации и копирайты из футера. В результате поиск похожести выдаст «Copyright © 2026» вместо полезного ответа. Чистый Markdown — заголовки, абзацы, списки — улучшает качество ретривла почти бесплатно.</p><p>Если не хочется зависеть от внешнего API, можно заменить fetch_markdown на один из альтернативных вариантов:</p><ul><li><a href="https://github.com/adbar/trafilatura" rel="noopener noreferrer">trafilatura</a> — библиотека на Python для извлечения главного текста.</li><li><a href="https://r.jina.ai/http://example.com" rel="noopener noreferrer">r.jina.ai/http://URL</a> — бесплатный сервис без ключа.</li><li><a href="https://www.firecrawl.dev/" rel="noopener noreferrer">Firecrawl</a> — API с поддержкой сканирования сайтов целиком.</li><li><a href="https://github.com/scrapingbee" rel="noopener noreferrer">ScrapingBee</a> — прокси + рендеринг для сложных страниц.</li></ul><p>Для российских разработчиков локальная Ollama особенно удобна: модели качаются бесплатно, не нужны иностранные карты, а инференс идёт на своём железе.</p><h2>Куда развивать</h2><ul><li>Направьте бота на документацию, чейнджлог или блог конкурента и задавайте вопросы по ним.</li><li>Замените Ollama на OpenAI, Anthropic, Gemini или российские модели — функция answer меняется в двух строках.</li><li>Сохраняйте эмбеддинги в векторную БД: Chroma, Qdrant или FAISS, чтобы индексировать сразу много страниц.</li><li>Используйте формат json вместо Markdown, если нужна структура: параграфы, заголовки, ссылки — отдельно.</li></ul><h2>Выводы</h2><p>RAG — не магия, а последовательность простых шагов: получить чистый текст, разрезать его на фрагменты, найти ближайшие к вопросу и отдать их модели. Весь минимальный пайплайн укладывается в короткий Python-скрипт, который можно запустить на своём ноутбуке.</p><blockquote>RAG работает ровно так хорошо, каков текст, который вы ему скармливаете. Уберите самую утомительную часть — очистку HTML, — и останется интересное: поиск и генерация.</blockquote><p>Исходник идеи — статья <a href="https://dev.to/bao001_xiao_37db0a18ce6b2/chat-with-any-website-build-a-rag-bot-in-60-lines-of-python-1m1k" rel="noopener noreferrer">«Chat With Any Website: Build a RAG Bot in ~60 Lines of Python»</a>. Попробуйте собрать бота на своей странице и посмотрите, где он справляется, а где начинает фантазировать.</p>]]></content:encoded>
    </item>
    <item>
      <title>S3 в инфраструктуре: где объектное хранилище помогает, а где не заменит файловую систему</title>
      <link>https://tproger.ru/articles/s3-v-infrastrukture-gde-obektnoe-hranilishhe-pomogaet-a-gde-ne</link>
      <comments>https://tproger.ru/articles/s3-v-infrastrukture-gde-obektnoe-hranilishhe-pomogaet-a-gde-ne?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Дима Дмитриев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/s3-v-infrastrukture-gde-obektnoe-hranilishhe-pomogaet-a-gde-ne</guid>
      <description><![CDATA[<p>Разбираем, где S3 подходит для бэкапов, архивов, логов и медиаданных, а где нужны файловые или блочные хранилища. Versioning, Object Lock, репликация и практический пилот перед миграцией.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/s3-v-infrastrukture-gde-obektnoe-hranilishhe-pomogaet-a-gde-ne">S3 в инфраструктуре: где объектное хранилище помогает, а где не заменит файловую систему</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Форматы хранения данных]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 18 Aug 2026 07:16:51 GMT</pubDate>
      <content:encoded><![CDATA[<p>Объём бэкапов, логов и медиаконтента растёт быстрее бюджета на инфраструктуру, а требования к сохранности и восстановлению данных становятся жёстче. В какой-то момент файловое хранилище начинает требовать всё больше дисков, контроллеров и внимания команды.</p><p>У <a href="https://linx.ru/cloud/object-storage-s3/">S3-совместимого объектного хранилища</a> другая логика: приложение обращается к объектам через API, а вопросы физического размещения и масштабирования решает сама система хранения. Для бэкапов, архивов и медиаданных модель такого рода подходит хорошо, однако перед переходом на нее важно проверить, как конкретное приложение работает с объектами и что произойдет с данными при нагрузке или восстановлении.</p><h2>Как устроено S3</h2><p>В объектном хранилище данные организованы в бакеты, где у объекта три составляющие: содержимое, уникальный ключ и метаданные. Вложенных директорий в привычном смысле здесь нет — папки в интерфейсах появляются потому, что ключ объекта разбирают по разделителю. Например, backups/2026/08/db-dump.tar.gz читается человеком как путь по папкам, а для хранилища — просто одна строка-идентификатор.</p><p>В отличие от файловой системы, где приложение может открывать файл, записывать данные частями, дополнять его и использовать блокировки, S3 работает с объектами через API. Объект загружается целиком, а изменения выполняются отдельными операциями API.</p><p>Переименование объекта выполняется копированием под новым ключом с последующим удалением исходного — приложению, которое часто переименовывает или дописывает файлы либо использует файловые блокировки, потребуется изменить логику работы с данными при переходе на S3.</p><p>Управляется модель небольшим набором предсказуемых HTTPS-операций.</p><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-08-17/17660b4e-f38e-42ec-8d53-d73765978182.webp" alt="" /></figure><p>S3 API используется разными объектными хранилищами, однако поддерживаемые функции могут различаться. Перед миграцией стоит проверить конкретные API-операции приложения, политики доступа, уведомления, Object Lock, репликацию и подпись запросов. Совместимость проверяют на рабочих сценариях приложения и часто в них применяемых API-операциях.</p><h2>Где подходит модель</h2><p>Зная, как устроена модель, проще понять, где S3 подходит лучше всего. Он хорошо работает с данными, которые сохраняются целыми объектами, хранятся независимо друг от друга и читаются по ключу. Например, так удобно хранить резервные копии, архивы, медиаконтент, логи и аналитические данные.</p><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-08-17/e6bf3c95-a2f8-4ec9-8fb5-b94492c8b212.webp" alt="" /></figure><p>Для задач с частыми синхронными изменениями нужна другая модель хранения. Например, для дисков виртуальных машин, транзакционных логов СУБД, рабочих каталогов сборки и приложений с POSIX-блокировками подходит блочное или файловое хранилище. S3 при этом можно использовать для снапшотов, регулярных выгрузок и резервных копий.</p><h2>Что защищает данные внутри S3 и где заканчивается эта защита</h2><p>Для критичных данных в S3 используются versioning, Object Lock и репликация. Эти функции решают разные задачи и применяются в разных сценариях.</p><p>Versioning сохраняет предыдущие версии объектов. При повторной записи по тому же ключу создаётся новая версия с собственным version ID. DELETE добавляет delete marker, поэтому предыдущие версии остаются доступными для восстановления.</p><p>Versioning увеличивает объём хранения. Приложение, которое ежедневно переписывает крупный объект, создаёт последовательность его полных версий. Lifecycle-политика позволяет определить срок хранения старых версий и правила очистки незавершённых multipart-загрузок. Versioning переводится в состояние suspended, а полностью отключить его нельзя. При создании бакета с Object Lock versioning включается автоматически.</p><p>Object Lock реализует модель WORM, Write Once, Read Many. Для объекта задаётся срок retention, в течение которого система сохраняет его в защищённом состоянии.</p><p>В режиме Governance пользователь с расширенными правами может снять защиту вручную. В режиме Compliance защищённая версия сохраняется до окончания retention, включая случаи с root-аккаунтом. Срок хранения стоит рассчитывать заранее: установленный retention нельзя сократить, поэтому версия продолжит занимать место до окончания заданного периода.</p><p>Репликация создаёт дополнительные копии объектов и повышает устойчивость к отказам оборудования. В <a href="https://linx.ru/cloud/object-storage-s3/">Linx Cloud</a> используется фактор репликации 3, RF3, поэтому каждый объект хранится в трёх экземплярах.</p><p>Репликация переносит изменения вместе с объектами. Если исходные данные уже содержат логическую ошибку, она попадёт и в реплики. Для критичных данных поэтому требуется отдельный домен отказа, регулярная проверка восстановления и схема резервного копирования 3-2-1 или 3-2-1-1-0.</p><h2>Своя инфраструктура или сервис провайдера</h2><p>S3-сервис можно развернуть внутри собственной инфраструктуры или использовать как управляемую услугу провайдера. На уровне приложения подключение выглядит одинаково: endpoint, access key, secret key и S3 API — разница в эксплуатации инфраструктуры.</p><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-08-17/3a92450a-1f79-4be0-a4f6-81d5b0741d6c.webp" alt="" /></figure><p>Перед выбором провайдера стоит свериться с матрицей ответственности — кто чинит платформу при сбое, кто управляет ключами и доступом, кто следит за квотами и кто в итоге отвечает за резервные копии данных. Такая матрица для S3 есть и у Linx Cloud — сверить её с внутренними регламентами команды стоит ещё до того, как сервис запущен в работу.</p><h2>Как это устроено у Linx Cloud</h2><p>Если выбор сделан в пользу провайдера, вот пример конкретной реализации. В основе сервиса <a href="https://linx.ru/cloud/object-storage-s3/">Объектное хранилище (S3)</a> в Linx Cloud — Ceph: мы выбрали его из-за совместимости с S3 API (по нашему опыту, полнее её реализует разве что сам AWS), а также из-за масштабируемости и гибкости для развития продукта.</p><p>Путь запроса такой: HTTPS endpoint → сетевой периметр с WAF и NGFW → балансировщики нагрузки → Ceph Object Gateway (RGW), который уже разбирает команды S3 API и передаёт операции в backend-кластер. Сами объекты лежат на OSD-узлах с репликацией в три копии (RF3), а управляющие компоненты кластера вынесены на отдельное оборудование.</p><p>Подключиться к сервису можно по интернету или по выделенному каналу точка-точка — из виртуального ЦОД Linx Cloud, серверной стойки в дата-центре Linx или с любой внешней площадки. По документации сервис поддерживает multipart upload, versioning, Object Lock/WORM, presigned URL, репликацию бакетов и lifecycle-правила удаления. Один PUT рассчитан максимум на 5 Гбайт — для объектов крупнее нужен multipart.</p><p>Этого достаточно для типовых задач: интеграции с Veeam, архивного хранения, выдачи приватных объектов по временным ссылкам. Но перед миграцией конкретного приложения тест всё равно нужен — оно может опираться на уведомления о событиях, свою схему управления пользователями, определённый способ адресации объектов или редкую операцию API.</p><h2>Что проверить на пилоте</h2><p>Каким бы ни было решение — свой кластер или сервис вроде Linx Cloud — переводить на него прод стоит только после пилота, и строить его нужно на реальном потоке данных приложения: одна команда aws s3 cp с тестовым файлом ничего не покажет.</p><ul><li>Поэтому сначала измеряется профиль данных: средний и максимальный размер объектов, общее количество объектов, соотношение GET и PUT, частота LIST, пиковая нагрузка и допустимая задержка.</li><li>Затем проверяется совместимость приложения с нужными функциями S3. В тест входят multipart, versioning, Object Lock, lifecycle, presigned URL и права доступа. Для каждого механизма важно проверить именно тот сценарий, который используется в рабочей системе.</li><li>После этого оцениваются сеть и безопасность. Тест показывает поведение канала под нагрузкой, работу при обрыве соединения, доступные маршруты и стоимость исходящего трафика. На уровне безопасности проверяются разделение прав, хранение и ротация ключей, шифрование, аудит операций и сценарий компрометации учётной записи.</li><li>Финальная часть пилота посвящена восстановлению и стоимости. Нужно выполнить возврат старой версии и полное восстановление данных, измерить объём накопленных неактуальных версий и рассчитать расходы на запросы, хранение и трафик с учётом ожидаемого роста данных.</li></ul><p>Критерий успеха зависит от сценария. Для бэкапов главное — успешное восстановление, факта одной только загрузки недостаточно. Для медиаконтента важна стабильная выдача и то, что временные ссылки действительно работают.</p><p>Для data lake — скорость, с которой выбранный аналитический стек читает данные, и отсутствие «болезни мелких файлов», когда объектов становится очень много. Одна и та же <a href="https://linx.ru/cloud/object-storage-s3/">платформа S3</a> может отлично закрывать один сценарий и требовать уже другого архитектурного решения в соседнем.</p><h2>Вместо вывода</h2><p>S3 подходит для бэкапов, архивов, медиаконтента и аналитических данных, которые хранятся и читаются как объекты. Для дисков ВМ, СУБД и рабочих каталогов с частыми изменениями больше подходят файловые и блочные хранилища.</p><p>Поэтому перед миграцией стоит провести пилот на реальных данных приложения: проверить нагрузку, нужные API-операции, восстановление и стоимость хранения с учётом трафика. Результаты помогут определить, какую часть инфраструктуры имеет смысл перевести на S3 и где сохранить другие типы хранилищ.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как я написал AI-бота на aiogram 3 с помощью нейросетей, выжил при 2500+ пользователей и почему SQLite "всё ещё торт"</title>
      <link>https://tproger.ru/articles/kak-ya-napisal-ai-bota-na-aiogram-3-s-pomoshhyu-nejrosetej-vyzhil-p</link>
      <comments>https://tproger.ru/articles/kak-ya-napisal-ai-bota-na-aiogram-3-s-pomoshhyu-nejrosetej-vyzhil-p?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Нуя]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-ya-napisal-ai-bota-na-aiogram-3-s-pomoshhyu-nejrosetej-vyzhil-p</guid>
      <description><![CDATA[<p>Технический кейс создания Telegram-бота Щёлк-ГДЗ (ИИ-репетитор по фото). Разбор архитектуры на Python (aiogram 3, aiosqlite), работы с API Gemini и решения проблем под нагрузкой 2500+ пользователей. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-ya-napisal-ai-bota-na-aiogram-3-s-pomoshhyu-nejrosetej-vyzhil-p">Как я написал AI-бота на aiogram 3 с помощью нейросетей, выжил при 2500+ пользователей и почему SQLite "всё ещё торт"</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Hardware]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Советы]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Telegram]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[Flash]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[Пет-проект]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[VPS]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 26 Jul 2026 15:47:08 GMT</pubDate>
      <content:encoded><![CDATA[<p>На дворе 2026 год. Очередной постмортем микро-SaaS'а в Телеге.</p><p>Без маркетинга и успешного успеха. Только боль, костыли и суровый прод! Мой пет-проект - бот «Щёлк-ГДЗ». Это ИИ-помощник, который решает школьные задачки по фоткам, видео, гс, тг-кружкам и PDF. Под капотом <b>Python 3.12.3</b>, <b>aiogram 3</b>, <b>aiosqlite</b>,<b> апи OpenRouter </b>(модель Gemini 3.0 Flash) и <b>Робокасса</b>. Крутится всё это на дешёвом VPS в Нидерландах. Держит 2500+ пользователей и не падает.</p><p>В этой статье расскажу, как за 9 месяцев построил логичную архитектуру, победил ошибку FloodWait при стриминге ответа ИИ и почему в условиях 1 гига RAM обычная SQLite - отличное решение.</p><h2>Нейронка вместо джуна и Уроборос багов</h2><p>Сразу признаюсь... С нуля я это не писал :) Синтаксис мне генерили LLM-ки. Начинал с Gemini 2.5 Pro, затем перешел на 3.0 Pro, а сейчас использую 3.1 Pro.</p><p>Многие думают, что нейронка сама напишет проект "под ключ", но это миф. Я <b>никогда </b>не доверял ИИ проектирование архитектуры и использовал его как продвинутый<i> StackOverflow</i> (скармливал конкретную задачу (например, написать SQL-миграцию) и получал кусок кода).</p><p><i>ИИ — это не архитектор, а джун на спидах. </i></p><p>Как только логика усложнялась - гемини ловил <b>«Уроборос багов»</b>. Кидаешь баг <b>А</b> - он его фиксит, но появляется ошибка <b>Б</b>. Скармливаешь и её - фиксит, но возвращается баг <b>А</b>. Цикл замкнулся. Лечилось только созданием новых чатов, в которые я кидал код и писал запросы типа "Найди критические ошибки, логические дыры и баги".</p><p>Про продуктовую логику нейронка вообще не слышала. В первой версии рефералки был баг, где любой(если его аккаунта ещё нет в БД) мог написать в конце ссылки что любые 9 цифр (<i>?start=1234567890</i>) и получить бонусы.</p><p>Также были ошибки с гонкой состояний при оплатах и активациях промокодов, которые тоже фиксил запросами в новые чаты с ИИ. Так я исправил около 20 архитектурных дыр.</p><h2>Немного про архитектуру.</h2><p>Чтобы код не превратился в нечитаемую лапшу на 5000 строк, я жестко разбил всё на модули. Архитектура бота выглядит так:</p><figure><img src="https://media.tproger.ru/user-uploads/139416/2026-07-08/dfc8dd70-365f-4f70-bbbf-2b00b503bef4.webp" alt="" /></figure><p><b>main.py</b> - это точка входа с настройкой логгеров, коннетами aiohttp и запуском APScheduler</p><p><b>database.py</b> - вся работа с БД</p><p><b>neiro.py</b> - логика общения с апи OpenRouter (стриминг, сжатие фоток через Pillow, JSON-контекст)</p><p><b>states.py</b> - классы состояний aiogram.fsm.state (например, PaymentProcess, GdzMode)</p><p><b>utils.py</b> - легковесные утилиты. Например лок пользователей (защита от спама запросами):</p><p>Хэндлеры вынесены в отдельную папку handlers/:</p><p><b>handlers/common_handlers.py</b> - главное меню с обработкой /start (рефералки, utm-метки).</p><p><b>handlers/gdz_handlers.py</b> - сам процесс ИИ-решения (вход в GdzMode, прием фото, видео, кружочков).</p><p><b>handlers/pay_handlers.py</b> - это логика платежей (Robokassa) и "Умная корзина".</p><p><b>handlers/tasks_handlers.py</b> - квесты (выдача премиума за подписку на каналы спонсоров).</p><p>Сборку интерфейсов вынес в <b>all_def.py</b>. Не люблю, когда в хэндлерах генерится полотно текста с кнопками. Там же лежат функции склонения слов (1 запрос, 2 запроса, 5 запросов). А в <b>settings.py </b>лежат списки с рандомными ответами бота, чтоб казался живым.</p><p>Так же в <b>settings.py</b> я сделал кэширование картинок, тоесть при первом запуске бот грузит фото меню как <b>BufferedInputFile</b>, сохраняет <b>file_id</b> от Телеграма и дальше шлет картинки моментально по ID. Сервак говорит спасибо за сэкономленный трафик)</p><p>В <b>handlers/common_handlers.py</b> находится первичная маршрутизация. Вот так обрабатываются рефералки, переходы с сайта, с рекламы и другое при старте:</p><h2>Диета по токенам</h2><p>Хранить бесконечную историю диалогов дорого и бессмысленно. В бесплатной версии храню <b>10 последних сообщений</b> (5 пар вопрос-ответ), а в преме — <b>30. </b></p><p>Но фотки весят большое кол-во токенов. Если премиум-юзер закинет 30 фоток, OpenRouter выставит мне огромный счет. В итоге я прикрутил ограничение: Из <b>30 сообщений</b> ИИ видит только <b>10 последних картинок. </b></p><p>Старые фотки тупо вырезаю из JSON. Подменяю на системный промпт:</p><p>С довольно неплохой моделью (gemini 3.0 flash) это работает как часы (она честно признается, что забыла картинку, а не выдумывает что-то из воздуха).</p><h2>Стриминг, FloodWait и защита баланса</h2><p>Чтобы бот не выглядел тормозом, я сделал стриминг ответа от ИИ в <b>neiro.py</b>. Я обновляю сообщение в Телеграме чанками по мере получения их от ОпенРоутера.</p><p>Но если делать <b>message.edit_text </b>слишком часто, ловишь <b>FloodWait</b>. В итоге я выставил интервал в 0.7 секунд и обернул всё в жесткий<b> try/except</b>:</p><p>Стрим при этом не прерывается. Поспали и погнали дальше :) Если на этапе обработки файла или стриминга падает критическая ошибка - честно возвращаю юзеру запрос на баланс.</p><p>В <b>handlers/gdz_handlers.py</b> это выглядит так:</p><h2>SQLite тащит</h2><p>Почему не <b>Postgre</b>? Потому что для микро-SaaS с 2,5к пользователей<b> SQLite</b> хватает за глаза. Но в асинхронной среде она любит кидать ошибку <b>database is locked</b>.</p><p>Чтобы этого избежать, я включил <b>WAL-режим</b> при инициализации пула, разделил коннекты на <b>db_writer</b> и <b>db_reader</b>, а сложные операции доверил самому <b>SQL</b>.</p><p>Например, 00:00 запускается крон-таска, которая собирает огромную аналитику, начисляет всем активным юзерам +1 ежедневный запрос и сбрасывает просроченные подписки. И это всё это работает атомарно внутри <b>database.py</b>:</p><h2>Умная корзина на APScheduler</h2><p>Когда дело дошло до монетизации, всплыли две проблемы:</p><p>Первая: юзер оплатил, но забыл нажать кнопку <b>«✅ Я оплатил»</b> в боте. Бот ждет, юзер ждет, товар не выдается, поддержка кипит.</p><p>Вторая: юзер сформировал счёт и передумал ("брошенная корзина").</p><p>Вместе с LLM я с нуля изучил <b>apscheduler </b>и убил двух зайцев фоновыми задачами. Теперь в <b>handlers/pay_handlers.py </b>при генерации ссылки на оплату я создаю две отложенные таски:</p><h4>Как это работает?</h4><p>Через 5 минут срабатывает <b>async def auto_check_payment()</b>, которая тихо стучится в робокассу. Если статус<b> success</b> - бот сам начисляет запросы на баланс и радует клиента. Если статус <b>pending</b> - таска умирает, и в дело вступает 30-минутная таска.</p><p>Но она не шлёт спам вслепую, а лезит в БД и проверяет 3 бизнес-правила:</p><p>1. <b>await db.has_successful_payment_recently</b> - Не купил ли он другой товар за последние 3 часа?</p><p>2. <b>await db.get_latest_invoice_id</b> - А это точно самый последний сгенерированный им счет?</p><p>3. <b>await db.can_send_agitation</b> - Не присылали ли мы ему агитацию недавно?</p><p>Если проверки пройдены, то юзер получает сообщение: <i>"⏳ Домашка сама себя не решит! Ты начал оформлять покупку, но оплата так и не прошла..."</i>. Это поднимает конверсию оплат.</p><h2>Финал</h2><p>Почему я не использую <b>Redis </b>для стейтов? Ответ банален: мой дешевый VPS имеет всего 1 гб оперативки. Пул <b>aiohttp</b>, In-Memory стейты и асинхронные таски и так жрут 70% RAM. Редис тупо не влезет.</p><p>Как говорится, <i>работает — не трогай.</i></p><p>Сейчас проект обзавелся сайтом-витриной и продолжает развиваться. В планах - искать и чинить новые баги. Перееду на более мощное железо, когда сервак начнет физически задыхаться.</p><p>Готов ответить на вопросы по архитектуре и послушать советы в комментариях \(^^)/</p><p><i>P.s. вот ссылка на первую статью о моём проекте: </i></p><p>P.s. Если кто-то хочет потестить вживую(не реклама), то юз бота в тг <a>@gdzshchelk_bot</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Своя self-hosted двухсерверная VPN-архитектура. Подробный путь разработки и ошибки, с которыми вы можете столкнуться</title>
      <link>https://tproger.ru/articles/svoya-self-hosted-dvuhservernaya-vpn-arhitektura-podrobnyj-put-r</link>
      <comments>https://tproger.ru/articles/svoya-self-hosted-dvuhservernaya-vpn-arhitektura-podrobnyj-put-r?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Роман Фролов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/svoya-self-hosted-dvuhservernaya-vpn-arhitektura-podrobnyj-put-r</guid>
      <description><![CDATA[<p>Проект представляет из себя быстрый способ воссоздать архитектуру состоящую из 2 серверов (локальный + удаленный) с определенными сервисами, которые решают специфические задачи. Проект сделан прежде всего для меня, а также для людей которые хотят свой готовый self-hosted сервер из коробки с полной системой обслуживания</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/svoya-self-hosted-dvuhservernaya-vpn-arhitektura-podrobnyj-put-r">Своя self-hosted двухсерверная VPN-архитектура. Подробный путь разработки и ошибки, с которыми вы можете столкнуться</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[unix]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[Музыка]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[DIY]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[VPN]]></category>
      <category><![CDATA[Telegram]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Cloudflare]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Мессенджер]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Машин]]></category>
      <category><![CDATA[NFT]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[VPS]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 26 Jul 2026 15:46:26 GMT</pubDate>
      <content:encoded><![CDATA[<p>Всё
 началось с того, что меня перестал устраивать мой подход к 
развертыванию личных сервисов. Я решил переписать всё с нуля. К тому же 
это был отличный повод получить новые навыки и попробовать инструменты, 
до которых давно не доходили руки.</p><p>Арендовать мощные VPS под 
ресурсоемкие задачи в текущих реалиях выходит неоправданно дорого. При 
этом дома у меня уже был выделенный неттоп (мини-ПК) с 16 ГБ оперативной
 памяти на базе энергоэффективного процессора Intel N95.</p><p>Пройдя 
путь от простых Bash-скриптов и сторонних туннелей до полностью 
автоматизированной инфраструктуры, я создал проект ServeHub-2. В этой 
статье я подробно разберу, как эволюционировала сеть проекта, почему 
декларативный подход победил императивный и с какими неочевидными багами
 пришлось столкнуться в процессе автоматизации.</p><h2>История настройки сетевой архитектуры</h2><h3>Использование Tuna</h3><p>В
 самом начале проекта я еще не думал о VPN как о способе пробития NAT и 
основе, на которой будет строиться вся система. Первое, к чему я пришел —
 сервис Tuna. Если кратко, это аналог Cloudflare Tunnel за условные 300 
рублей. У него очень приятный веб-интерфейс и невероятно простая 
настройка. Однако для полноценной независимой архитектуры он не подошел 
по двум причинам:</p><ul><li>Сервера Tuna находятся вне контроля пользователя.</li><li>На удаленном сервере нельзя развернуть свои сопутствующие сервисы.</li></ul><p>В целом сервис действительно удобный, но для моих задач он оказался слишком ограничивающим.</p><p>Вот
 пример конфига для tuna (все максимально просто, создаем контейнеры для
 ssh туннеля, чтобы был доступ ssh, а также основной http туннель с 
привязкой к nginx или любому другому прокси если такой есть):</p><h3>В поисках гибкости: тесты Pangolin и переход к FRP</h3><p>После Tuna я решил двигаться в сторону собственного контроля и попробовал Pangolin.
 Однако решение быстро отвалилось: для дешёвого сервера оно оказалось 
слишком «тяжёлым» и избыточным. Главные минусы — ощутимый оверхед по 
ресурсам и лишний слой принудительной веб-аутентификации перед самими 
сервисами. Это ломало нормальное взаимодействие с родными мобильными 
клиентами (вроде Element для Matrix или Bitwarden для паролей), где 
повторная авторизация в браузере просто не нужна.</p><p>На смену пришел FRP (Fast Reverse Proxy).
 Он выполнял ту же функцию проброса, но хостил я его уже на собственном 
арендованном VPS в режиме Layer 4 (TCP). Это дало абсолютную гибкость: 
внешний VPS не заглядывал внутрь пакетов и ничего не расшифровывал, а 
просто пересылал сырой поток домой. Кроме того, это отлично 
оптимизировало расходы: вместо 300 рублей за Tuna и ещё 300 рублей за 
отдельный VPN, я стал платить всего 500 рублей за один стойкий VPS, 
который мог настраивать как хочу. (к тому же можно было обойтись даже 
дешевле, так как VPS с 4 гб оперативки загружен всего лишь на 40%, 
процессор всего на 20%-40%)</p><p>FRP состоит из 2 конфигурационных 
файлов (один на удаленном сервере frp server, другой на локальном frp 
client), все также довольно просто, однако его можно использовать на 
разных слоях. У меня он брал трафик за стандартный TCP и передавал его 
на локальный сервер.</p><p>Также доп. фишка в том что основная 
конфигурация происходит именно в frpc, который, в свою очередь, передает
 часть настроек на frp на удаленном сервере.</p><p>frpc.toml:</p><p>frps.toml:</p><h3>Полноценный переезд на WireGuard (AmneziaWG) и 8 часов отладки</h3><p>Со временем архитектура эволюционировала в сторону полноценной VPN-сети на базе WireGuard, а точнее — его модификации AmneziaWG. Причин для этого шага было несколько:</p><ul><li>Безопасность: FRP всё же открывал внутренние ресурсы в публичный интернет, оставляя их доступными для сканеров портов.</li><li>Удобство маршрутизации:
 Все участники сети стали равноправными узлами в одной виртуальной 
локальной подсети. Больше не нужно было настраивать постоянные 
односторонние пробросы.</li><li>Дополнительный бонус:
 Поскольку удаленный VPS был куплен в Нидерландах, через этот же VPN я 
автоматически получил безопасный доступ ко всем зарубежным ресурсам.</li></ul><p>Для реализации схемы на удаленном VPS был развернут контейнер wg-easy с поддержкой AmneziaWG, а на домашнем мини-ПК — клиентский контейнер Amnezia (сборка из Dockerfile с использованием amnezia-tools  и модулем ядра хоста).</p><p>И
 именно здесь я поймал самый изнурительный баг проекта. После 
развертывания трафик упорно шёл только в одну сторону. Часов 8 ушло на 
диагностику iptables, маршрутов и чтение зарубежных форумов (что 
бесполезно, учитывая специфику наших блокировок). Оказалось, провайдер 
просто дропал обратный трафик стандартного WireGuard, так как пакеты шли
 без маскировки. Причина крылась в docker-compose.yml: у меня было прописано image: ghcr.io/wg-easy/wg-easy:latest. Как выяснилось, тег latest  на Docker Hub намертво прилип к старой 14-й версии, а поддержка параметров AmneziaWG появилась только в ветке 15.x. Изменение тега на конкретную версию (15.3) решило проблему за секунду.</p><p>Благодаря
 переходу конфигурация получилась максимально простой, основные отличия 
от стандартной документации выделил в коде: (в основном то, на что 
пришлось долго рыть информацию)</p><h3>Настройка Nginx</h3><p>Чтобы
 сервисы были доступны исключительно внутри подсети VPN, я задействовал 
Nginx. Доступ к приложениям был жестко ограничен на уровне конфигурации —
 веб-сервер принимает запросы только из диапазона IP-адресов 10.8.0.0/24. Любые попытки постучаться на сервер из внешнего интернета без активного VPN-туннеля автоматически сбрасываются Nginx.</p><p>Логика
 распределения завязана на proxy-протоколе: Nginx на удаленном VPS 
выступает основным входным узлом, принимает зашифрованный трафик, 
заворачивает его в заголовки с реальным IP-адресом клиента и через 
туннель перекидывает на локальный Nginx домашнего сервера. Локальный 
веб-сервер уже сам расшифровывает SSL и распределяет трафик по конечным 
Docker-контейнерам, сохраняя реальные IP в логах безопасности.</p><p>Вставлю
 один кусок кода из nginx на удаленной машине для примера, так все 
остальное примерно похоже (конфиги использовались в виде .template):</p><h3>SSL-сертификаты</h3><p>Для получения валидных SSL-сертификатов я настроил работу через автоматический Certbot по challenge-валидации DNS-01 c API Webnames. Сам домен привязан к внутреннему IP-адресу 10.8.0.1.
 Проверка через DNS позволила выпустить единый wildcard-сертификат на 
весь домен и его поддомены без необходимости держать открытым 80-й порт 
веб-сервера наружу.</p><p>Уточню, что certbot запускается автоматически 
во время выполнения Ansible плейбука, поэтому самому кроме указания 
переменных ничего делать не нужно.</p><p>В
 итоге получилась схема, при которой все сервисы доступны по красивым 
доменным именам с HTTPS, но абсолютно невидимы для внешнего интернета.</p><p>Вот настройка certbot:</p><h2>История софта</h2><p>Параллельно
 с сетевой структурой развивался и сам набор приложений. Изначально я 
хотел собрать в одном месте утилиты, которыми пользуюсь каждый день, но в
 процессе селфхостинга быстро понимаешь: нельзя просто накидать 
контейнеров и надеяться, что мини-ПК справится, а конфигурационные файлы
 не превратятся в кашу.</p><h3>Первый стек и оптимизация</h3><p>Первыми на домашнем сервере прижились медиа-сервисы: Navidrome для стриминга музыки и Audiobookshelf
 для аудиокниг и подкастов. Они легковесные, имеют отличные мобильные 
клиенты с синхронизацией прогресса и полностью закрывают мои 
потребности. Позже к ним добавился Nextcloud как единое независимое облако для файлов, контактов и семейных документов.</p><p>Затем встал вопрос безопасного хранения паролей. Сначала я смотрел в сторону оригинального Bitwarden, но в итоге я выбрал Vaultwarden
 — альтернативный сервер на Rust, полностью совместимый с API Bitwarden.
 Он потребляет считанные мегабайты оперативной памяти и работает 
идеально. Дополнительно для удобства управления всей этой распределенной
 Docker-инфраструктурой в локальный стек был добавлен Portainer. (+ Portainer Agent на удаленный сервер)</p><p>Из интересных моментов, где мне пришлось немного больше возиться, чем с остальными сервисами это nextcloud настройка:</p><h3>Ошибки проектирования: почему я удалил Matrix (Synapse)</h3><p>Не все решения прошли проверку временем. На этапе использования Tuna и FRP я развернул сервер Matrix (Synapse)
 для защищенного обмена сообщениями. Мне казалось это крутой идеей, но 
когда я окончательно перешел на AmneziaWG, целесообразность мессенджера 
внутри закрытого туннеля сошла на нет.</p><p>Synapse требовал слишком 
много ресурсов, впустую расходовал оперативку домашнего ПК и усложнял 
конфиг Nginx. При этом реальной пользы для семьи он не приносил. Для 
критических алертов инфраструктуры и повседневного общения проще и 
эффективнее оказалось использовать Telegram. (плюс алертинг настроен 
именно через него) В итоге я полностью выпилил Synapse из стека, 
освободив ресурсы.</p><p>Вместо него я добавил в связку к wg-easy локальный AdGuard Home.
 Теперь он работает прямо внутри VPN-сети: очищает весь трафик от 
рекламы и трекеров на лету, кэширует DNS-запросы и не дает истории 
веб-серфинга улетать внешним провайдерам.</p><p>Основной проблемой с 
которой я столкнулся при использовании AdGuard Home, так это то что я 
так и не понял как заставить использовать AmneziaVPN клиент AdGuard как 
основной DNS, при этом AmneziaWG работает прекрасно. Как я понимаю дело в
 том что AmneziaWG работает намного проще на уровне ip и у него нету 
никаких доп фильтров, настроек и подобного, поэтому он просто берет 
данные из конфига.</p><h3>От костылей на Bash к декларативному Ansible</h3><p>Весь
 стек на обоих серверах разворачивался через bash скрипты, что было уж 
очень плохо с точки зрения идемпотентности. Во первых из-за bash мне 
постоянно приходилось очищать сервера, так как нормальных проверок у 
меня не было и писать я их не хотел, а также было много костылей с 
импортом переменных, записями в файлы и подобным.</p><p>Так я пришел к декларативному подходу и Ansible.
 Теперь вся конфигурация описывается в виде плейбуков и ролей, 
отражающих конечное желаемое состояние серверов. Конфиденциальные данные
 перенесены в файл secrets.yml, а хрупкие конструкции 
автоматизированы через шаблоны Jinja2. Проект стал идемпотентным: если 
шаги уже выполнены, Ansible их просто пропускает.</p><p>В итоге 
получилось несколько yaml файлов для стандартной настройки системы 
(bootstrap_os.yml) и для настройки каждого из хостов (setup_local.yml и 
setup_remote.yml). В итоге теперь все что нужно чтобы полностью с нуля 
развернуть проект - скачать Ansible, несколько других зависимостей на 
свой рабочий пк и запустить один manage_deploy.sh, в котором можно будет
 выбрать сценарий как будет вести себя Ansible и спокойно дождаться 
разворачивания сервисов.</p><p>Также благодаря Ansible я удобно 
реализовал переносимость проекта. Так как я решил не использовать тома 
docker, и вместо этого храню все в папках, чтобы перенести старые данные
 проекта нужно просто скопировать папку apps-data и положить ее в нужное
 место и все само заработает после повторного развертывания проекта. В 
Ansible выделяется отдельная пауза для этого.</p><p>Вот пример основного плейбука deploy.yml:</p><h3>Тестирование мультидистрибутивности с помощью Vagrant</h3><p>Проект
 изначально затачивался под работу на трех дистрибутивах: Ubuntu, Debian
 и Arch Linux. Тестировать Ansible-плейбуки прямо на рабочей локальной 
машине (в моем случае — EndeavourOS) слишком рискованно, а создавать 
виртуальные машины руками — долго и неудобно.</p><p>Решением стал Vagrant,
 позволяющий за пару минут развернуть чистые ОС в VirtualBox из готовых 
образов. Но в процессе настройки мультивендорного стенда в режиме 
сетевого моста (public_network) всплыли две критические проблемы:</p><ol><li>Конфликт DNS:
 По умолчанию Vagrant создает NAT-интерфейс для управления нодой. При 
включении второго (публичного) интерфейса для локальной сети ломался 
дефолтный DNS-резолвер. Проблему пришлось решать принудительной очисткой
 и перезаписью файла /etc/resolv.conf через inline-скрипт автоматизации Vagrant.</li><li>Проблема с GRUB на Debian: В используемом базовом образе generic/debian12
 конфигурация GRUB сохраняла жесткую привязку к конкретному имени диска 
из окружения сборщика. При повторном развертывании плейбуков на тестовом
 стенде это приводило к сбоям загрузчика. Чтобы автоматизировать 
очистку, пришлось внедрить скрипт, который на лету определяет имя 
системного диска через lsblk и автоматически передает правильные параметры в загрузчик через утилиту debconf-set-selections.</li></ol><p>Вот код Vagrantfile: (в node.vm.provision происходит основное решение ошибок)</p><p>Надежная система бэкапов на базе BorgmaticДля создания резервных копий я внедрил Borgmatic
 (удобную надстройку над дедуплицирующим инструментом Borg Backup). Весь
 процесс автоматизирован с помощью связки системных юнитов borgmatic.service и borgmatic.timer. В бэкап уходят две ключевые директории: apps-data (конфигурации приложений и баз данных) и PersonalData (медиатека: музыка, книги, подкасты, файлы Nextcloud).</p><p>Развертывание
 системы бэкапов полностью берет на себя Ansible. Мне достаточно указать
 UUID внешнего жесткого диска — скрипт сам проверит его наличие в 
системе, примонтирует в нужную директорию, создаст зашифрованный 
репозиторий и настроит политику ротации (хранение 7 ежедневных, 4 
еженедельных и 6 ежемесячных копий). Также в Prometheus выведен 
мониторинг самого репозитория .borg для отслеживания его размера и статуса успешности архивации.</p><p>Главная
 проблема при бэкапе работающих Docker-контейнеров — риск скопировать 
базу данных в «битом» или неконсистентном состоянии, если в момент 
создания архива в нее шла активная запись. Чтобы решить эту проблему, я 
задействовал механизм хуков в конфигурации Borgmatic.</p><p>Перед началом резервного копирования автоматически срабатывает команда остановки контейнеров проекта (docker-compose down),
 а после успешного завершения (или в случае возникновения непредвиденной
 ошибки) контейнеры автоматически поднимаются обратно в фоновом режиме. 
Для удобного просмотра архивов и быстрого восстановления файлов я 
развернул веб-интерфейс Borg UI.</p><p>Конфигурация borgmatic: (использую как Jinja2 шаблон, чтобы Ansible в плейбуках сам подставил переменные)</p><h2>Наблюдаемость (Observability) уровня Enterprise</h2><p>В последних релизах (v1.2.0 и v1.3.0) фокус проекта сместился на мониторинг и работу с логами.</p><h3>Эволюция алертинга и переход на Gatus</h3><p>Изначально для мониторинга доступности я смотрел на Uptime Kuma, но отказался из-за отсутствия удобной декларативной настройки через конфиги. Затем я развернул связку Blackbox Exporter и Alertmanager
 с уведомлениями в Matrix. Но тут крылась логическая несостыковка: весь 
алертинг был завязан на локальном ПК, и в случае его аппаратного отказа я
 бы просто лишился уведомлений.</p><p>Тогда я решил вернуть Uptime Kuma,
 но развернуть его на удаленном VPS в качестве внешнего «сторожа» и 
автоматизировать его настройку через Python-скрипт с библиотекой uptime-kuma-api. Но и тут ждали «грабли» — библиотека не обновлялась три года и намертво ломалась на свежих версиях Kuma.</p><p>В итоге идеальным решением стал Gatus.
 Он изначально проектировался под управление через YAML-конфиги и 
поддерживает отправку алертов, если сервер не отвечает. Из-за специфики 
фронтенда Gatus (он не умеет работать из подкаталога типа /gatus), мне пришлось перенести его и wg-easy на полноценные субдомены gatus. и wireguard.</p><p>Для Gatus получился простой конфиг:</p><p>Для мониторинга аппаратных ресурсов удаленного и локального серверов была развернута связка node-exporter + cAdvisor. Все уведомления теперь приходят мгновенно в Telegram-бота. Чтобы 
избежать лавины одинаковых сообщений (например, при перезагрузке хоста),
 в Alertmanager настроена жесткая группировка и дедупликация событий. 
Также добавлен экспортер для AdGuard Home, выводящий статистику 
заблокированных запросов в Grafana.</p><h3>Централизованные логи: Loki + Grafana Alloy</h3><p>В релизе v1.3.0 в стек была добавлена централизованная система сбора логов Loki. Вместо устаревшего Promtail в качестве агента сбора я применил Grafana Alloy.</p><p>Он
 эффективно собирает логи со всех запущенных Docker-контейнеров, парсит 
их и передает в Loki. Теперь вся история событий, ошибок веб-сервера 
Nginx или падений внутренних приложений доступна в едином интерфейсе 
Grafana с возможностью удобной фильтрации через LogQL, что значительно 
упрощает отладку.</p><p>Конфиг Loki:</p><p>Конфиг Grafana Alloy: (локальный конфиг)</p><h2>Интерфейс: переход на Homepage</h2><p>Изначально для 
домашней страницы я написал кастомную минималистичную HTML-панель с 
Glassmorphism-дизайном. Выглядело это красиво, но добавлять новые 
сервисы вручную через постоянную правку исходного кода было крайне 
неудобно.</p><figure><img src="https://media.tproger.ru/user-uploads/139471/2026-07-15/8a8f2752-8aac-4aa5-898e-98affd01cdff.webp" alt="" /><figcaption>HTML + CSS</figcaption></figure><p>В итоге я заменил самописную страницу на полноценный комьюнити-проект Homepage.
 Это дало некоторую гибкость: вся панель настраивается через простые 
YAML-файлы и поддерживает встроенные виджеты интеграции. Пока что она 
простенькая, но возможно в будущем сделаю что-то более продвинутое.</p><figure><img src="https://media.tproger.ru/user-uploads/139471/2026-07-15/90c65d4a-1310-4a30-b1ad-9e4d3083959d.webp" alt="" /><figcaption>Homepage</figcaption></figure><h2>Заключение</h2><p>Постарался
 подробно рассказать о структуре проекта и как я к этому пришел, очень 
много я не добавил, если пост зайдет, то я обязательно более подробно 
пройдусь по некоторым моментам: как я настраивал Matrix и на каком 
моменте я решил его убрать, как собирал локальный amnezia 
контейнер-клиент, что нового я добавил в релизе 1.4.0 и другое.</p><p>Также
 я перешел с manage_deploy.sh на отдельный GUI клиент, который 
будет полностью автоматизировать процесс подготовки к deploy. (написан на Go Wails). Про это тоже возможно сделаю статью.</p><p>Вся кодовая база проекта, подробная документация, инструкции по развертыванию открыты и доступны для сообщества:</p><p>🔗 GitHub-репозиторий: <a href="https://github.com/canntstand/ServeHub-2" rel="noopener noreferrer nofollow">https://github.com/canntstand/ServeHub-2</a></p><p>Это
 моя первая статья на этом сайте и в то же время первый личный проект, которому я 
отдал так много времени (3 месяца). Буду рад вашему фидбеку в 
комментариях!</p>]]></content:encoded>
    </item>
    <item>
      <title>MCP отказывается от сессий: протокол ИИ-агентов становится stateless</title>
      <link>https://tproger.ru/news/mcp-otkazyvaetsya-ot-sessij-protokol-ii-agentov-stanovitsya-state</link>
      <comments>https://tproger.ru/news/mcp-otkazyvaetsya-ot-sessij-protokol-ii-agentov-stanovitsya-state?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/mcp-otkazyvaetsya-ot-sessij-protokol-ii-agentov-stanovitsya-state</guid>
      <description><![CDATA[<p>Новый релиз-кандидат MCP убирает handshake и Mcp-Session-Id. Разбираем, почему это важно для масштабирования ИИ-агентов и что ждёт разработчиков.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/mcp-otkazyvaetsya-ot-sessij-protokol-ii-agentov-stanovitsya-state">MCP отказывается от сессий: протокол ИИ-агентов становится stateless</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Open Source]]></category>
      <category><![CDATA[Сетевые протоколы]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Инфраструктура]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 21 Jul 2026 11:35:20 GMT</pubDate>
      <content:encoded><![CDATA[<p>MCP перестаёт быть протоколом «один клиент — один сервер». Релиз-кандидат спецификации 2026-07-28, зафиксированный 21 мая 2026 года, полностью убирает handshake initialize / initialized и заголовок Mcp-Session-Id. Теперь каждый запрос несёт с собой всё необходимое состояние, а сервер может быть обычным веб-сервисом за балансировщиком.</p><ul><li>Новая спецификация MCP 2026-07-28 делает протокол stateless: сессии и handshake больше не нужны.</li><li>Клиент передаёт свою идентификацию и возможности в поле _meta каждого JSON-RPC-запроса.</li><li>Балансировщик может использовать обычный round-robin, ориентируясь на заголовки Mcp-Method и Mcp-Name.</li><li>Roots, Sampling и Logging объявлены устаревшими с минимальным окном поддержки 12 месяцев.</li><li>Финальная спецификация ожидается 28 июля 2026 года после 10-недельного окна валидации SDK.</li></ul><p>Model Context Protocol (MCP) — открытый протокол для подключения ИИ-агентов к внешним инструментам и данным. С момента передачи Anthropic в Linux Foundation в декабре 2025-го им управляет Agentic AI Foundation, а число production-серверов уже исчисляется сотнями тысяч. До сих пор MCP работал по модели чата: сначала handshake, потом сервер выдавал идентификатор сессии, который клиент возвращал с каждым запросом.</p><p>В релиз-кандидате эта модель заменена на stateless. Клиент кладёт имя, версию и capabilities в поле _meta прямо в тело запроса. Балансировщик читает HTTP-заголовки Mcp-Method и Mcp-Name (SEP-2243) и направляет запрос на любой свободный инстанс — общее хранилище сессий больше не требуется. Если серверу нужен ввод посреди вызова, он возвращает InputRequiredResult, а клиент переотправляет запрос с inputResponses и requestState.</p><p>Вместе с ядром обновляются и расширения. Появляется MCP Apps — серверный интерактивный UI в sandboxed iframe с заранее декларируемыми шаблонами. Переработано API долгих задач: вместо tasks/list приходят tasks/get, tasks/update и tasks/cancel. Также шесть SEPов ужесточают авторизацию по OAuth/OIDC, включая проверку issuer по RFC 9207.</p><h2>Часто задаваемые вопросы</h2><h2>Выводы</h2><p>Новая спецификация — признак того, что MCP вырос из протокола для локальных подключений в полноценную enterprise-инфраструктуру. Переход к statelessness решает главную операционную проблему масштабирования, но добавляет работы тем, кто уже внедрил stateful-реализации. Главное — помнить, что релиз пока кандидат: production-серверы продолжают работать на спецификации 2025-11-25.</p><p>Источник: <a href="https://awesomeagents.ai/news/mcp-stateless-protocol-update/">awesomeagents.ai</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как ограничить расходы на OpenAI API, чтобы ИИ-агенты не сожгли бюджет</title>
      <link>https://tproger.ru/articles/kak-ogranichit-rashody-na-openai-api-chtoby-ii-agenty-ne-sozhgli</link>
      <comments>https://tproger.ru/articles/kak-ogranichit-rashody-na-openai-api-chtoby-ii-agenty-ne-sozhgli?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-ogranichit-rashody-na-openai-api-chtoby-ii-agenty-ne-sozhgli</guid>
      <description><![CDATA[<p>Разбираем, как настроить лимиты расходов, алерты и жёсткие ограничения в OpenAI API. Пошаговая инструкция для разработчиков и команд.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-ogranichit-rashody-na-openai-api-chtoby-ii-agenty-ne-sozhgli">Как ограничить расходы на OpenAI API, чтобы ИИ-агенты не сожгли бюджет</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 04 Jul 2026 15:34:20 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если ваше приложение или агент работает с <a href="https://openai.com/api/">OpenAI API</a>, один бесконтрольный цикл способен за несколько часов превратить пару долларов в счёт на сотни или тысячи. Хорошая новость: в кабинете разработчика уже есть инструменты, которые не дают бюджету уйти в свободное плавание.</p><p>В этой статье разбираем, как работают usage tiers, мягкие и жёсткие лимиты расходов, алерты и rate limits. И главное — что нужно учесть в коде, чтобы приложение корректно обработало отказ API.</p><p>OpenAI API делит аккаунты на usage tiers: чем больше суммарно оплачено, тем выше месячный потолок расходов.</p><p>В настройках Limits можно задать собственный лимит трат, включить жёсткое ограничение и настроить email-алерты.</p><p>Жёсткий лимит отключает API при превышении бюджета: запросы начинают возвращать ошибку 429.</p><p>Rate limits ограничивают RPM, RPD, TPM и TPD по моделям; при превышении помогает экспоненциальный бэкофф.</p><p>В коде важно перехватывать 429, повторять запросы с задержкой и логировать расход токенов.</p><h2>Как устроены usage tiers</h2><p>Usage tiers — это автоматические уровни аккаунта, которые OpenAI выдаёт в зависимости от суммы уже оплаченных API-вызовов. Чем выше tier, тем больше месячный потолок трат и выше rate limits. Для новичка это двойная защита: даже если вы ничего не настраивали, система не даст потратить больше, чем разрешено текущему уровню.</p><h3>Таблица tiers по состоянию на июль 2026</h3><p>Данные взяты из <a href="https://platform.openai.com/docs/guides/rate-limits">документации OpenAI</a>.</p><ul><li><b>Free</b> — доступен из разрешённых регионов, лимит $100 / месяц.</li><li><b>Tier 1</b> — нужно оплатить от $5, лимит $100 / месяц.</li><li><b>Tier 2</b> — оплачено от $50, лимит $500 / месяц.</li><li><b>Tier 3</b> — оплачено от $100, лимит $1 000 / месяц.</li><li><b>Tier 4</b> — оплачено от $250, лимит $5 000 / месяц.</li><li><b>Tier 5</b> — оплачено от $1 000, лимит $200 000 / месяц.</li></ul><p><b>Важно:</b><br />После Tier 5 потолок резко растёт — именно на этом этапе жёсткий лимит расходов становится критичным. Без него зациклившийся агент теоретически может исчерпать шестизначную сумму до того, как вы заметите.</p><h2>Лимит расходов: мягкий, жёсткий и алерты</h2><p>На странице <a href="https://platform.openai.com/settings/organization/limits">Limits</a> в настройках организации можно задать три вещи: месячный бюджет, уведомления и автопополнение баланса.</p><ul><li><b>Spend limit</b> — мягкий потолок. OpenAI показывает предупреждение, но фактические траты могут его немного превысить.</li><li><b>Enforce hard limit</b> — жёсткий потолок. При достижении лимита API начинает возвращать ошибку 429 и больше не списывает деньги.</li><li><b>Spend alerts</b> — email-уведомление при достижении заданного процента от бюджета.</li><li><b>Auto recharge</b> — автоматическое пополнение баланса с привязанной карты. При риске перерасхода его стоит отключить.</li></ul><p>Рекомендация простая: для продакшена включайте Enforce hard limit и настраивайте алерты на 50% и 80%. Так у вас будет время разобраться, пока API ещё работает.</p><h2>Rate limits: почему API отвечает 429</h2><p>Rate limits — это не про деньги, а про нагрузку. OpenAI ограничивает количество запросов в минуту/день и токенов в минуту/день для каждой модели. Лимиты зависят от tier и модели: например, для gpt-4o и gpt-4o-mini они различаются.</p><ul><li><b>RPM</b> — requests per minute, запросы в минуту.</li><li><b>RPD</b> — requests per day, запросы в день.</li><li><b>TPM</b> — tokens per minute, токены в минуту.</li><li><b>TPD</b> — tokens per day, токены в день.</li><li><b>IPM</b> — images per minute, изображения в минуту (для моделей генерации картинок).</li></ul><p>При превышении любого из лимитов API возвращает 429 Too Many Requests. OpenAI рекомендует обрабатывать эту ошибку через экспоненциальный бэкофф: повторять запрос с увеличивающейся паузой.</p><h2>Что делать в коде</h2><ol><li>Перехватывайте 429 и различайте причину: rate limit, hard spend limit или квота по токенам.</li><li>Используйте экспоненциальный бэкофф с джиттером, чтобы не «дудосить» API своими ретраями.</li><li>Логируйте количество токенов и стоимость каждого вызова — лучше всего через поля usage в ответе.</li><li>Для агентов добавьте circuit breaker: если бюджет исчерпан или ошибки 429 идут подряд, остановите цикл и уведомите команду.</li><li>Не храните API-ключ в клиентском коде: утечка ключа — самый быстрый способ получить чужой счёт.</li></ol><h2>Пошаговая настройка</h2><h2>Выводы</h2><p>OpenAI API даёт в руки разработчика все нужные рычаги: usage tiers, spend limits, spend alerts, rate limits и жёсткое ограничение. Проблема не в отсутствии инструментов, а в том, что ими редко пользуются до первого «сюрприза» в биллинге.</p><p>Минимальный must have для любого проекта: включить Enforce Hard Limit, настроить алерты на 50% и 80%, отключить автопополнение, если бюджет критичен, и добавить в код обработку 429. Так вы защитите не только карту, но и репутацию команды.</p><blockquote>Set up spend limits so rogue AIs don't exceed your budget. Rate limits are very easy to configure, making them a no-brainer for protecting your account.</blockquote><p><b>Источники:</b><br /><a href="https://www.zdnet.com/article/how-to-set-openai-api-spend-usage-limits/">ZDNET — How I set OpenAI API usage limits to stop agent overspending</a><br /><a href="https://platform.openai.com/docs/guides/rate-limits">OpenAI Docs — Rate limits</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Microsoft признала ошибку привязки Copilot к OpenAI и вложит $2,5 млрд в мульти-модельный ИИ</title>
      <link>https://tproger.ru/news/microsoft-priznala-owibku-privyazki-copilot-k-openai-i-vlozhit-2</link>
      <comments>https://tproger.ru/news/microsoft-priznala-owibku-privyazki-copilot-k-openai-i-vlozhit-2?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/microsoft-priznala-owibku-privyazki-copilot-k-openai-i-vlozhit-2</guid>
      <description><![CDATA[<p>Microsoft создаёт Frontier Company с $2,5 млрд, чтобы enterprises выбирали ИИ-модели разных провайдеров. Узнайте подробнее, почему уходит эпоха единой модели.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/microsoft-priznala-owibku-privyazki-copilot-k-openai-i-vlozhit-2">Microsoft признала ошибку привязки Copilot к OpenAI и вложит $2,5 млрд в мульти-модельный ИИ</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Нейронные сети]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Машинное обучение]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Облачные технологии]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 03 Jul 2026 05:00:13 GMT</pubDate>
      <content:encoded><![CDATA[<p>Microsoft сделала ставку на гибкость вместо моногамии с одной ИИ-моделью. Компания объявила о создании нового подразделения Microsoft Frontier Company с фондом в <b>$2,5 млрд</b>, которое будет помогать крупным заказчикам выбирать, комбинировать и быстро менять генеративные модели под свои задачи.</p><p>Решение выросло из собственного опыта: по словам Judson Althoff, главы коммерческого направления Microsoft, привязка оригинального Copilot исключительно к моделям OpenAI была ошибкой. Клиентам важнее не бренд модели, а результат: их данные плюс та архитектура, которая даёт лучший отклик, цену и безопасность.</p><p>Microsoft запускает подразделение Frontier Company с бюджетом $2,5 млрд для помощи enterprise-клиентам в выборе ИИ-моделей.</p><p>Компания признала: привязка Copilot только к OpenAI была ошибкой, и теперь продвигает мульти-модельную стратегию.</p><p>Современные приложения всё чаще маршрутизируют запросы между несколькими моделями в зависимости от стоимости, скорости и требований к данным.</p><p>Рынок отвечает развитием ИИ-шлюзов и оркестраторов: LiteLLM, Portkey, LangGraph, MCP, Azure AI Foundry, Amazon Bedrock, Google Vertex AI.</p><h2>Почему одной модели уже недостаточно</h2><p>В одном типичном корпоративном сценарии может понадобиться суммаризация тикета, анализ 300-страничного договора, генерация письма, расшифровка встречи и ревью кода. Это разные задачи: для длинного контракта выгоднее модель с огромным контекстом, для быстрых ответов — лёгкая и дешёвая, для чувствительных данных — локальная open-weight модель. Вместо того чтобы искать универсального победителя, разработчники строят <b>слой маршрутизации</b>, который отправляет каждый запрос к подходящей модели.</p><blockquote>We made a mistake by binding it to OpenAI models only.</blockquote><h2>Что это меняет для инженеров</h2><p>Если раньше приложение жёстко завязывалось на один API, то теперь ключевой навык — проектирование оркестрации. Нужно уметь сравнивать модели по качеству, задержке и цене, мониторить отказы, переключать трафик и соблюдать политики безопасности. В enterprise-масштабе такие решения принимаются миллионы раз в день, поэтому шлюз должен быть быстрым и управляемым.</p><h2>Кто ещё строит маршрутизацию</h2><ul><li><b>LiteLLM</b> и <b>Portkey</b> — нормализуют API разных провайдеров.</li><li><b>LangChain / LangGraph</b> — рассчитаны на много-модельные пайплайны.</li><li><b>Model Context Protocol (MCP)</b> — делает инструменты переносимыми между моделями.</li><li><b>Azure AI Foundry, Amazon Bedrock, Google Vertex AI</b> — предлагают десятки моделей за единым endpoint.</li></ul><h2>Выводы</h2><p>Microsoft закладывает $2,5 млрд на то, что следующий конкурентный рубеж в enterprise ИИ — не сама модель, а умение ею управлять. Для разработчиков это означает рост спроса на инфраструктуру маршрутизации, observability и политики данных. Если облачная эра научила не привязываться к одному серверу, то ИИ-эра учит не привязываться к одной модели.</p><p>Оригинал материала: <a href="https://thenewstack.io/enterprise-ai-model-routing/" rel="noopener noreferrer">The New Stack — Enterprise AI Model Routing</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Дайджест Android-разработки за июнь 2026: Android 17, Play и безопасность</title>
      <link>https://tproger.ru/articles/android-cli-1-0-navyki-ii-agentov-i-android-bench-ot-google</link>
      <comments>https://tproger.ru/articles/android-cli-1-0-navyki-ii-agentov-i-android-bench-ot-google?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/android-cli-1-0-navyki-ii-agentov-i-android-bench-ot-google</guid>
      <description><![CDATA[<p>Главное для Android-разработчиков в июне 2026: релиз Android 17, новые правила Google Play, zero-day CVE-2025-48595 и верификация разработчиков. Разбираем.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/android-cli-1-0-navyki-ii-agentov-i-android-bench-ot-google">Дайджест Android-разработки за июнь 2026: Android 17, Play и безопасность</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Инструменты командной строки]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Инновации]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 01 Jul 2026 12:30:26 GMT</pubDate>
      <content:encoded><![CDATA[<p>Июнь 2026 года выдался насыщенным для Android-разработчиков: Google выпустила Android 17 с API 37, пересмотрела комиссии и биллинг в Play, залатала активно эксплуатируемую уязвимость и продолжила накатывать верификацию разработчиков. Ниже — краткий дайджест главных событий месяца, которые стоит учитывать при планировании релизов и миграций.</p><p><b>Android 17</b> вышел 16 июня. API 37, AppFunctions для ИИ-агентов, adaptive-first и Compose-first, строгие лимиты памяти и новые API приватности.</p><p><b>Google Play</b> расширяет выбор платёжных систем и снижает комиссии: с 30 июня 2026 сервисный сбор отдельно от платёжного, первый $1M — 10%.</p><p><b>Безопасность</b>: июньский бюллетень закрыл 124 уязвимости, включая zero-day CVE-2025-48595 в Framework. С 30 сентября 2026 начинается обязательная верификация разработчиков в четырёх странах.</p><p><b>Инструменты</b>: Android CLI 1.0, 17+ Android skills, Android Bench с Gemma 4 и Gemini 3.5 Flash, Android XR SDK DP4 и Eclipsa Video для HDR.</p><h2>Android 17: релиз 16 июня и API 37</h2><p>16 июня 2026 года Google <a href="https://android-developers.googleblog.com/2026/06/Android-17.html" rel="noopener">выпустил Android 17</a>. Платформа переходит от «операционной системы» к «интеллектуальной системе»: центральную роль занимают AppFunctions — функции приложений, которые ИИ-агенты могут обнаруживать и вызывать через Jetpack-библиотеку. Разработчики аннотируют класс, добавляют KDoc, и Gemini получает доступ к локальному состоянию приложения.</p><p>Главное архитектурное изменение — <b>adaptive-first</b>: на больших экранах (sw &gt; 600 dp) для приложений с targetSdk 37 игнорируются ограничения ориентации и размера. Вместе с этим появились App Bubbles, Bubble Bar и интерактивный Picture-in-Picture для десктопа. Google заявляет, что Compose теперь является первым классом UI: View-компоненты и View-based библиотеки переведены в режим обслуживания.</p><h3>Производительность и приватность</h3><p>Android 17 вводит лимиты памяти на основе объёма RAM устройства и убивает процессы, их нарушающие. Для диагностики добавили интеграцию LeakCanary в Android Studio Panda и on-device аномалию в ProfilingManager. ART получил generational GC, а MessageQueue для targetSdk 37 стал lock-free — это ускоряет старт и снижает пропуск кадров, но ломает рефлексию над приватными полями.</p><p>Из приватных нововведений — системный Contact Picker без разрешения READ_CONTACTS, системный Eyedropper для выбора цвета, временный доступ к локальной сети через ACCESS_LOCAL_NETWORK и post-quantum криптография с ML-DSA и гибридной подписью APK v3.2.</p><h2>Инструменты и продуктивность: Android CLI 1.0, skills и Bench</h2><p>9 июня в блоге Android Developers <a href="https://android-developers.googleblog.com/2026/06/android-developer-productivity-updates.html" rel="noopener">подвели итоги I/O</a> по продуктивности. Главное — стабильный релиз Android CLI 1.0: теперь инструмент доступен через npm и Homebrew, умеет Journeys и команду studio для моста с Android Studio, а также интегрируется с Google Antigravity.</p><p>Каталог Android skills вырос до 17+ сценариев: адаптивный UI, CameraX, Perfetto SQL, Engage SDK, Wear OS, AppFunctions и другие. А Android Bench обзавёлся открытыми моделями, включая локальную Gemma 4, и свежими Gemini 3.5 Flash. В ближайшее время в бенчмарк добавят долгие многошаговые задачи.</p><h2>Google Play: биллинг, комиссии и поиск</h2><p>24 июня Google <a href="https://android-developers.googleblog.com/2026/06/play-expanded-billing.html" rel="noopener">расширила выбор платёжных систем</a> в Великобритании, ЕЭЗ и США. Разработчики могут предлагать альтернативный биллинг или внешние ссылки на свой сайт. С 30 июня 2026 сервисный сбор отделяется от платёжного: первый $1M в год — 10%, все автообновляемые подписки — 10%, остальное зависит от новой/существующей установки. Платёжная комиссия при использовании Google Play billing — 5% в этих регионах; при альтернативном биллинге она не берётся.</p><p>Также Google запустила программы Games Level Up и Apps Experience с пониженными ставками, а в Play Store появился AI-поиск Ask Play, Trusted Contributor-значки и более заметные скидки. Для разработчиков это означает, что ASO и монетизацию придётся пересматривать под новые механики отображения цен.</p><h2>Безопасность: zero-day и верификация разработчиков</h2><p>Июньский Android Security Bulletin закрыл 124 уязвимости. Самая неприятная — CVE-2025-48595 в Framework, уже эксплуатируемая в ограниченных целевых атаках. Она затрагивает Android 14–16 QPR2 и позволяет повысить привилегии без взаимодействия с пользователем. Критичный патч — уровень 2026-06-05, так как он включает исправления чипсетов Qualcomm и MediaTek.</p><p>18 июня Google <a href="https://android-developers.googleblog.com/2026/06/android-developer-verification.html" rel="noopener">обновила статус верификации разработчиков</a>. С 30 сентября 2026 в Бразилии, Индонезии, Сингапуре и Таиланде станут обязательными регистрация приложений в семи магазинах. В июне на устройствах начали раскатывать системный сервис, который позже будет проверять регистрацию. В июле–августе появятся Android Developer ID Status API и Developer Console API для массовой регистрации через CI/CD.</p><h2>Android XR: DP4, движки и Geospatial API</h2><p>15 июня вышел <a href="https://android-developers.googleblog.com/2026/06/what-is-new-android-xr.html" rel="noopener">Developer Preview 4 Android XR SDK</a>. Для очков дополненной реальности добавили Jetpack Projected с Device Availability API, а Compose Glimmer оптимизирован под прозрачные дисплеи и тачпад. Для иммерсивных приложений — ранняя версия Geospatial API на базе ARCore и Visual Positioning System.</p><p>Кроме Unity для проводных XR-очков появилась официальная поддержка Unreal Engine и Godot, а также Android XR Engine Hub — десктопный инструмент для Windows с real-time тестированием прямо во вьюпорте движка. Программа Android XR Developer Catalyst Program открыта для заявок и даёт доступ к pre-release железу.</p><h2>Premium-опыт: R8, Glance и Media3</h2><p>В посте 2 июня <a href="https://android-developers.googleblog.com/2026/06/building-premium-android-experiences-google-io-26.html" rel="noopener">о премиум-опыте</a> Google акцентировала R8 Configuration Analyzer: он показывает, какие keep-rules мешают оптимизации. Monzo за счёт настройки R8 получили 30% прирост холодного старта и 35% снижение ANR.</p><p>Jetpack Glance теперь унифицирует виджеты для телефонов, часов и автомобилей на базе Compose, а RemoteCompose позволяет рендерить UI на внешних поверхностях. Media3 получил AI Effects, CodecDB, Scrubbing Mode в ExoPlayer и улучшенный CastPlayer. CameraX 1.5+ добавляет CameraXViewfinder Composable и динамические диапазоны.</p><h2>Eclipsa Video: единый стандарт HDR</h2><p>29 июня Google <a href="https://android-developers.googleblog.com/2026/06/eclipsa-video-hdr-review.html" rel="noopener">представила Eclipsa Video</a> — стандарт HDR на базе SMPTE ST 2094-50, разработанный совместно с Apple и NBCUniversal. Он задаёт единый HDR reference white, адаптирует яркие участки под возможности дисплея и сохраняет творческий замысел кадр за кадром. Поддержка встроена в Android 17, ExoPlayer/Media3 обрабатывают метаданные автоматически.</p><h2>FAQ</h2><h2>Выводы</h2><p>Июнь 2026 показал, что Google делает ставку на три вещи: ИИ-агентов как часть рабочего процесса (AppFunctions, Android CLI, skills), адаптивность интерфейсов под любые форм-факторы и жёсткий контроль за безопасностью экосистемы. Разработчикам стоит в первую очередь протестировать приложения под Android 17, проверить R8-конфигурацию и подготовиться к новым правилам биллинга и верификации.</p><blockquote>Самый быстрый способ не отстать — поставить Android CLI, добавить пару skills под свой проект и прогнать релиз на Android 17 эмуляторе, прежде чем OEM-партнёры начнут массово раскатывать обновление.</blockquote><p>Источники: <a href="https://android-developers.googleblog.com/2026/06/Android-17.html" rel="noopener">Android 17 is here</a>, <a href="https://android-developers.googleblog.com/2026/06/android-developer-productivity-updates.html" rel="noopener">Top 3 updates for Android developer productivity</a>, <a href="https://android-developers.googleblog.com/2026/06/play-expanded-billing.html" rel="noopener">Expanded billing choice and lower fees on Google Play</a>, <a href="https://android-developers.googleblog.com/2026/06/android-developer-verification.html" rel="noopener">Android developer verification</a>, <a href="https://android-developers.googleblog.com/2026/06/what-is-new-android-xr.html" rel="noopener">What's New in Android XR</a>, <a href="https://android-developers.googleblog.com/2026/06/building-premium-android-experiences-google-io-26.html" rel="noopener">Building Premium Android Experiences</a>, <a href="https://android-developers.googleblog.com/2026/06/eclipsa-video-hdr-review.html" rel="noopener">Eclipsa Video</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Бесплатный WAF инструмент кибербезопасности, который я использую</title>
      <link>https://tproger.ru/articles/besplatnyj-waf-instrument-kiberbezopasnosti-kotoryj-ya-ispolzuyu</link>
      <comments>https://tproger.ru/articles/besplatnyj-waf-instrument-kiberbezopasnosti-kotoryj-ya-ispolzuyu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Неопознанный программист]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/besplatnyj-waf-instrument-kiberbezopasnosti-kotoryj-ya-ispolzuyu</guid>
      <description><![CDATA[<p>Разбор бесплатного open-source WAF SafeLine для защиты от OWASP Top 10, DDoS и ботов. Сравнение с ModSecurity и Cloudflare по точности обнаружения атак, минимальные ложные срабатывания, простая установка одной командой Docker.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/besplatnyj-waf-instrument-kiberbezopasnosti-kotoryj-ya-ispolzuyu">Бесплатный WAF инструмент кибербезопасности, который я использую</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Unity]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[.NET]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[IBM]]></category>
      <category><![CDATA[Cloudflare]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[CSR]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 01 Jul 2026 05:55:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Решения с открытым исходным кодом достигли такого уровня зрелости, что сегодня они действительно могут конкурировать с коммерческими продуктами — не только по функциональности, но и по удобству использования и поддержке сообщества. Если вы управляете собственной инфраструктурой, больше нет оправдания тому, чтобы оставлять дверь открытой для угроз.</p><p>SafeLine WAF — это бесплатный инструмент, который я лично тестировал.</p><p>Это полностью open-source решения, продукт с действительно бесплатной Community Edition, где ключевые функции не урезаны.</p><p><b>SafeLine WAF — веб-приложенийный межсетевой экран, который действительно поставляется с разумными настройками по умолчанию</b></p><p><b>Что он делает:</b></p><p>Защищает веб-приложения от SQL-инъекций, XSS-атак, командных инъекций, CSRF, SSRF, атак включения файлов и других угроз из списка OWASP Top 10. Также поддерживает защиту от CC/DDoS-атак, управление ботами и может работать как шлюз аутентификации.</p><p><b>Почему он:</b></p><p>Большинство WAF с открытым исходным кодом достаточно сложно настроить. Можно потратить часы на настройку правил, пытаясь остановить ложные срабатывания, из-за которых легитимные пользователи блокируются.</p><p>SafeLine использует другой подход — вместо того чтобы полностью полагаться на сигнатурное обнаружение, он применяет движок семантического анализа, который фактически анализирует и понимает входящие HTTP-запросы. Это позволяет добиться более высокого уровня обнаружения при значительно меньшем количестве ложных срабатываний по умолчанию.</p><p>Некоторые показатели, которые стоит учитыват</p><ol><li>Уровень обнаружения - SafeLine (Balanced) (71.65%), ModSecurity (Level 1) (69.74%), Cloudflare (Free) (10.7%)</li><li>Уровень ложных срабатываний - SafeLine (Balanced) (0.07%), ModSecurity (Level 1) (17.58%), Cloudflare (Free) (0.07%)</li><li>Точность - SafeLine (Balanced) (99.45%), ModSecurity (Level 1) (82.20%), Cloudflare (Free) (98.40%)</li></ol><p>Сбалансированный профиль SafeLine обнаруживает более 70% атак, при этом блокируя легитимный трафик ошибочно всего в 0.07% случаев. Это именно тот уровень настроек по умолчанию, который можно использовать в промышленной среде без постоянного ручного контроля.</p><p>Установка выполняется одной командой</p><p>После запуска он разворачивается как набор Docker-контейнеров: Tengine (форк Nginx) используется в качестве reverse proxy, отдельный сервис отвечает за семантический анализ, PostgreSQL хранит конфигурации и логи, а удобная веб-панель администратора работает на порту 9443.Community Edition поддерживает до 10 сайтов, чего достаточно для большинства личных проектов и небольших бизнес-сценариев.</p><p>Сайт: <a href="https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fcodeby.net%2Fgoto%2Flink-confirmation%3Furl%3DaHR0cHM6Ly9jeWJlcnNlcnZhbC50ZWNoL2xhbmRpbmcvc2FmZWxpbmXvv7xHaXRIdWI%253D%26s%3D7008b60d8a0849ba0be350fe25edfa72&amp;postId=3005263" rel="nofollow noopener">https://cyberserval.tech/landing/safeline</a></p><p>GitHub:<a href="https://api.vc.ru/v2.8/redirect?to=http%3A%2F%2Fgithub.com%2Fchaitin%2FSafeLine&amp;postId=3005263" rel="nofollow noopener"> github.com/chaitin/SafeLine</a> (более 21 тыс. звёзд)</p><p>Лицензия: GPL-3.0 / MIT (Community Edition)</p>]]></content:encoded>
    </item>
    <item>
      <title>Airflow, n8n и Make: что выбрать для API-оркестрации</title>
      <link>https://tproger.ru/articles/airflow-n8n-i-make-chto-vybrat-dlya-api-orkestracii</link>
      <comments>https://tproger.ru/articles/airflow-n8n-i-make-chto-vybrat-dlya-api-orkestracii?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/airflow-n8n-i-make-chto-vybrat-dlya-api-orkestracii</guid>
      <description><![CDATA[<p>Сравниваем Apache Airflow, n8n и Make для оркестрации API: плюсы, минусы, стоимость и российская специфика. Выберите инструмент под свою задачу.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/airflow-n8n-i-make-chto-vybrat-dlya-api-orkestracii">Airflow, n8n и Make: что выбрать для API-оркестрации</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 25 Jun 2026 13:25:47 GMT</pubDate>
      <content:encoded><![CDATA[<p>Современное приложение редко живёт в вакууме: платёжка общается с банком, CRM — с телефонией, а аналитика собирает данные из десятка источников. Когда одного curl мало, на сцену выходит API-оркестрация — последовательность вызовов, обработка ошибок, преобразование данных и контроль за выполнением. Выбор инструмента для этой работы определяет, сколько времени вы потратите на поддержку и сколько он будет стоить при росте нагрузки.</p><ul><li><b>Apache Airflow</b> — мощный оркестратор для сложных Python-конвейеров, но требует инфраструктуры и DevOps-культуры.</li><li><b>n8n</b> — визуальный конструктор с открытым исходным кодом: удобен для средних нагрузок, можно бесплатно хостить на своём сервере.</li><li><b>Make</b> (бывший Integromat) — облачный визуальный автоматизатор для бизнес-команд, дешевле Zapier, но тарифицирует каждый шаг сценария.</li><li>Для российских команд критичны: возможность self-hosting, стоимость инфраструктуры и риски доступности зарубежного SaaS.</li><li>Нет универсального победителя — выбор зависит от размера команды, сложности логики и требований к контролю над данными.</li></ul><p><b>API-оркестрация</b> — это не просто «позвонить в API», а построить надёжный конвейер: вызвать один сервис, передать результат в другой, обработать ошибку, повторить при сбое и записать лог. Иногда это пара запросов в час, а иногда — десятки тысяч операций в день. Отсюда и разница в подходах: где-то важна гибкость кода, где-то — скорость запуска, а где-то — цена за операцию.</p><h2>Apache Airflow: тяжёлый артиллерист</h2><p>Airflow появился в Airbnb и за десять лет стал стандартом для data-пайплайнов. Его используют Netflix, Spotify и Uber — там, где нужно управлять сотнями зависимых задач с контролем SLA и аудитом. Главная идея: вы описываете workflow как Python-код в виде направленного ациклического графа (DAG), а scheduler отвечает за порядок, ретраи и мониторинг.</p><h3>Зачем выбирать Airflow</h3><ul><li>Сложная логика: ветвления, условия, ретраи, расписания через cron.</li><li>Полный контроль над кодом: любые библиотеки Python, кастомные операторы, unit-тесты.</li><li>Зрелая экосистема: SLA-мониторинг, audit trail, интеграция с Kubernetes и Spark.</li><li>Open Source: можно развернуть на своей инфраструктуре, в том числе на российских облаках.</li></ul><h3>Честный взгляд на минусы</h3><ul><li>Высокий порог входа: нужно разворачивать БД, Redis, воркеры и веб-интерфейс.</li><li>Минимальный кластер на VPS обходится примерно в €50/месяц без учёта времени администратора.</li><li>При 50+ задачах DAG превращается в большой Python-файл, который сложно поддерживать без дисциплины.</li><li>Коммуникация между задачами через XCom требует внимания: забыли очистить — получили memory leak.</li></ul><p>Пример простого DAG, который забирает пользователя, его посты и считает количество:</p><p>Airflow хорош, когда у вас уже есть data-команда, Kubernetes и понимание, зачем нужны DAG. Для стартапа из трёх человек это, скорее, оверинжиниринг.</p><h2>n8n: визуальный middle ground</h2><p>n8n занимает промежуточную нишу между кодом и no-code. Это node-based редактор: вы перетаскиваете блоки, соединяете их стрелками, а логика — в JavaScript-функциях и условиях. Главное преимущество: n8n open-source, его можно поднять на собственном сервере, и за это не придётся платить пошагово.</p><h3>Зачем выбирать n8n</h3><ul><li>Быстрый старт: визуальный конструктор позволяет собрать пайплайн за час, а не день.</li><li>Self-hosting: контейнер на VPS за $5–10/мес может обрабатывать тысячи запусков в день.</li><li>Гибридный подход: 90 % задач решается мышкой, сложную трансформацию можно написать на JS.</li><li>Прозрачная цена облака: плата за выполнение workflow, а не за каждый модуль.</li></ul><h3>Ограничения</h3><ul><li>При сотнях задач в одном workflow визуальная схема становится громоздкой.</li><li>Нативные узлы покрывают не всё: экзотический API придётся звать через HTTP Request.</li><li>Self-hosted версия требует обновлений и бэкапов — это всё ещё инфраструктура, хоть и простая.</li><li>Для России: облако n8n — европейский сервис, но self-hosted можно развернуть на Selectel, Yandex Cloud или любом другом провайдере.</li></ul><p>Пример JSON-экспорта workflow, который забирает пользователей, преобразует данные и пишет в PostgreSQL:</p><p>n8n часто выбирают команды, которым нужна скорость no-code, но не хочется терять контроль над инфраструктурой и платить за каждый шаг сценария.</p><h2>Make: бизнес-автоматизация по шагам</h2><p>Make (ранее Integromat) — это облачный визуальный автоматизатор для бизнес-команд. Его сценарии собираются из модулей: триггер → действие → фильтр → маршрутизатор. По сравнению с Zapier у Make глубже логика, а цена ниже, но он остаётся полностью SaaS-решением.</p><h3>Зачем выбирать Make</h3><ul><li>Быстрая интеграция с популярными сервисами: Google Sheets, Slack, Telegram, CRM, email-рассылки.</li><li>Визуальные маршрутизаторы (routers), итераторы и агрегаторы позволяют строить ветвления без кода.</li><li>Низкий порог входа для маркетологов, менеджеров продукта и операционистов.</li><li>План Core стоит от $9/мес за 10 000 операций — дешевле многих конкурентов.</li></ul><h3>Подводные камни</h3><ul><li>Тарификация по операциям: каждый модуль в сценарии считается отдельно. Десять шагов × тысяча запусков = 10 000 операций.</li><li>Нельзя self-host: данные обрабатываются на серверах Make, что может быть проблемой для чувствительных данных.</li><li>Для России: сервис работает как зарубежный SaaS, есть риски доступности и оплаты.</li><li>Сложные сценарии сложнее отлаживать: приходится кликать по модулям в истории выполнений.</li></ul><p>Типичный сценарий в Make выглядит так: вебхук из формы → проверка дубликата в Google Sheets → запись в CRM → отправка уведомления в Telegram. Всё это строится мышкой, но стоит добавить кастомную логику — и придётся использовать HTTP-модуль или встроенные функции.</p><h2>Сравнение в цифрах</h2><p>Сводная таблица по ключевым параметрам. Вместо абстрактных «плюсов» смотрите на конкретные ограничения:</p><ul><li><b>Airflow</b> — код Python, self-hosted, сложность высокая, стоимость от €50/мес + администрирование, лучше для data-платформ.</li><li><b>n8n</b> — визуальный + JS, self-hosted или cloud, средняя сложность, self-hosted от $5–10/мес, лучше для средних нагрузок и гибридных команд.</li><li><b>Make</b> — визуальный no-code, только cloud, низкая сложность входа, от $9/мес за 10K операций, лучше для бизнес-автоматизации.</li><li><b>Модель оплаты</b>: Airflow — инфраструктура; n8n — инфраструктура или executions в облаке; Make — операции (каждый модуль отдельно).</li><li><b>Контроль данных</b>: максимальный у Airflow и self-hosted n8n; минимальный у Make как SaaS.</li></ul><p><b>Российская специфика:</b><br />Для команд в РФ критичен self-hosted путь: Airflow и n8n можно развернуть на отечественных VPS или в Yandex Cloud/Selectel. Make, Zapier и другие зарубежные SaaS не дают гарантий доступности и оплаты. Если данные не могут покидать страну — выбор очевиден.</p><h2>Как выбрать инструмент</h2><h2>FAQ</h2><h2>Выводы</h2><p>Нет единого лучшего инструмента для API-оркестрации — есть подходящий под ваши ограничения. Airflow остаётся выбором зрелых data-команд, которым нужна масштабируемость и контроль. n8n закрывает большинство задач среднего уровня и даёт свободу self-hosting. Make — удобный SaaS для бизнес-автоматизации, но с привязкой к облаку и пошаговой тарификацией.</p><blockquote>Хороший оркестратор не тот, у кого больше иконок в интерфейсе, а тот, чьи ошибки вы сможете отладить в два часа ночи.</blockquote><p>Источник: материал основан на публикации «Airflow vs n8n vs Make for API orchestration» автора Raizan в DEV Community — <a href="https://dev.to/chasebot/airflow-vs-n8n-vs-make-for-api-orchestration-1lb8" rel="noopener">dev.to/chasebot/airflow-vs-n8n-vs-make-for-api-orchestration-1lb8</a>. Раздел про Make и сравнительный анализ дополнены редакционным контекстом.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как Android-инженер спроектировал gateway для миллионов пользователей: опыт перехода в инфраструктуру</title>
      <link>https://tproger.ru/articles/kak-android-inzhener-sproektiroval-gateway-dlya-millionov-polzova</link>
      <comments>https://tproger.ru/articles/kak-android-inzhener-sproektiroval-gateway-dlya-millionov-polzova?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Кирилл Соколов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-android-inzhener-sproektiroval-gateway-dlya-millionov-polzova</guid>
      <description><![CDATA[<p>История перехода из андроид разработки в инфраструктуру. Как мобильный инженер спроектировал gateway для платформы с миллионами пользователей, освоил распределённые системы и научился строить отказоустойчивые сервисы.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-android-inzhener-sproektiroval-gateway-dlya-millionov-polzova">Как Android-инженер спроектировал gateway для миллионов пользователей: опыт перехода в инфраструктуру</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[App Store]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Инфраструктура]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 23 Jun 2026 07:41:54 GMT</pubDate>
      <content:encoded><![CDATA[<p><i>Перешёл из Android-разработки в инфраструктуру и спроектировал gateway для платформы с миллионами пользователей. Делюсь опытом: какие пробелы пришлось закрывать, почему мобильный бэкграунд — это преимущество, и с чего начать, если думаете о похожем переходе. </i></p><h2>Почему инфраструктура начинает привлекать больше, чем фичи</h2><p>С фичами всё прозрачно: написал код — увидел результат на экране. Быстрая и понятная обратная связь. Но со временем замечаешь, что проблемы повторяются. Приложение тормозит не из-за плохого кода, а потому что на один экран уходит пять-шесть сетевых вызовов. Логика на клиенте. Хочешь что-то изменить — готовь релиз, проходи App Store Review и жди недели, пока обновление дойдёт до всех.</p><p>Я перешёл в Android-инфраструктуру — начал делать инструменты для других мобильных разработчиков. Это помогло увидеть: главные проблемы не в фичах, а в слое между приложением и бэкендом.</p><p>Возвращаться к фичам стало неинтересно. В инфраструктуре задачи сложнее, результат измеряется метриками — latency, error rate, скорость релизов, — а влияние на всю систему, а не на один экран.</p><h2>Что Android даёт для инфраструктуры — а чему учиться с нуля</h2><p>Мобильный бэкграунд оказался не балластом, а преимуществом. Я понимал ограничения изнутри. Backend-инженер может прочитать, что мобильные сети ненадёжны, память ограничена, а батарея — критичный ресурс. Но прочитать и прочувствовать — разное. Я годами наблюдал, как приложение “захлёбывается” на устройствах среднего сегмента. Знал, что 60% пользователей сидят именно на таких. Видел, как баг, который мы починили за день, продолжает висеть у людей неделями — просто потому, что они не успели обновиться.</p><p>Когда я проектировал gateway, я точно знал, что почувствуют мобильные разработчики, если ошибусь. Добавить ещё один сетевой вызов — это будет не бесплатно. Оставить логику в приложении — значит отдать её на устройство, которое я не контролирую.</p><p><b>Чего именно не хватало?</b> Я неплохо понимал мобильную сторону, но совершенно не ориентировался в распределенных системах. Знал, например, что такое таймаут, но не представлял, как выставить его в цепочке из пяти сервисов так, чтобы одно медленное звено не обрушило весь экран пользователя. Понимал, что сети падают, но не умел проектировать систему, способную оставаться на плаву в таких условиях.</p><p><b>Чему пришлось учиться с нуля? </b>Операционному мышлению. В Android ты выпускаешь релиз — и он либо работает, либо нет. Если крашится, починишь в следующей версии. В инфраструктуре нет «следующей версии». Если gateway падает, всё приложение ложится для миллионов пользователей прямо сейчас.</p><p>Пришлось учиться думать в терминах деградации, частичных отказов, плавного падения.</p><p>Что делать, если один из пяти сервисов не ответил? Как понять, что мы катимся к инциденту, до того, как пользователи начнут жаловаться?</p><p>Этому в мобильной разработке не учат.</p><h2>Как я учился: пробелы, сроки и смена мышления</h2><p>Формального плана у меня не было — учился на практике. Это лучший, хотя и самый стрессовый способ. Пробелы выявляла практика. Столкнулся с нерешаемой задачей — понял, чего не знаю. Пошёл разбираться.</p><p>Учился итеративно, не пытаясь объять необъятное сразу. Gateway начинался как простой прокси. Затем добавили агрегацию ответов, потом — конфигурационные определения экранов. Каждый такой шаг вынуждал осваивать следующий уровень: circuit breakers, стратегии повторов, observability, планирование мощностей.</p><p>По срокам: техническая база уложилась в несколько месяцев. Паттерны осваиваются быстрее, чем кажется, особенно если сразу применять их к живой задаче. Гораздо дольше происходила смена образа мышления. Перейти от вопроса «работает ли фича?» к вопросу «что случится, когда это упадёт в три часа ночи?» — вот что заняло основное время.</p><h2>Что означает «выдающийся уровень» в инфраструктуре</h2><p><i>Когда говорят «спроектировать gateway с нуля и перевести на него живую платформу», за этими словами стоит не один навык, а целых три, и каждый требует совершенно разной подготовки.</i></p><p>Проектирование с нуля — это не рисование квадратиков на доске и не выбор модного стека. Это в первую очередь определение границ: что система будет делать, а что — категорически нет, и как с ней станут взаимодействовать десятки команд. Настоящая сложность здесь в том, чтобы предвидеть, что именно сломается, и заложить защиту от этого ещё до того, как написан хоть один файл с кодом.</p><p>Затем — миграция живой системы, где права на ошибку практически нет. Приложение нельзя выключить или отрепетировать в реальном масштабе. Остаётся только постепенный перевод трафика: shadow mode → 1% → 5% → 25% → 50% → 100%, с автоматическим откатом при любом росте ошибок. И всё это — пока миллионы пользователей активно работают с продуктом, не подозревая, что под капотом идёт замена двигателя на ходу. Такой уровень дисциплины и инструментации приходит только с практикой.</p><p>Наконец, владение надёжностью. Gateway — единая точка отказа: упал он, упало всё. Годы уходят на то, чтобы сделать его скучным и предсказуемым: резервирование, автомасштабирование, circuit breakers, режимы деградации, еженедельный пересмотр мощностей. Высший пилотаж — когда о системе просто не думаешь, потому что она работает.</p><h2>Почему путь в инфраструктуру доступнее, чем кажется?</h2><p>Карьерные траектории в инфраструктуре редко бывают чётко описаны. Здесь нет готового чек-листа в духе «диплом по Computer Science, пять лет в бэкенде, обязательное знание Kafka и Kubernetes». С одной стороны, такая неопределённость пугает. С другой — именно она и делает этот путь более доступным, чем принято думать.</p><p>Когда перед тобой лежит жёсткий список формальных требований, люди часто отсеивают себя сами, даже не попробовав. А в инфраструктуре по-настоящему важно только одно: можешь ли ты решать задачи. Я пришёл сюда без профильного диплома и учился ровно тому, что требовалось в моменте, потому что задачи сами подталкивали к этому.</p><p>Индустрия, к слову, до сих пор не слишком хорошо умеет проверять те навыки, которые на этом уровне оказываются решающими: умение видеть ограничения на стыке систем, предвидеть сценарии отказов, двигать людей к соглашению. Всему этому учатся не до начала работы, а непосредственно в процессе.</p><p>Поэтому если вы мобильный инженер и размышляете, можно ли перейти в инфраструктуру, — вопрос не в том, правильный ли у вас бэкграунд. Вопрос в другом: готовы ли вы учиться тому, чего пока не знаете, и способны ли обратить то, что уже понимаете, в собственное преимущество. Если ответ «да» — путь для вас открыт. Просто указателей на нём пока не расставили.</p><h2>Мобильный бэкграунд как преимущество архитектора</h2><p>Считаю ли я, что мобильный опыт сделал меня лучшим архитектором для mobile-first продуктов? Безоговорочно, да.</p><p>Я помнил, как ощущается медленный экран на устройстве среднего сегмента. Помнил, что случается, когда API возвращает слегка неправильные данные и приложение падает при парсинге. Помнил то чувство, когда баг уже в проде, а ты ждёшь App Store Review и ничего не можешь исправить.</p><p>Поэтому когда я проектировал gateway, я не занимался абстрактной «оптимизацией перформанса». Я опирался на совершенно конкретный опыт. Знал, что убрать один сетевой round trip — это подарок каждому мобильному разработчику. Знал, что перенос логики на сервер означает перенос в место, где я могу починить всё за минуты, а не за недели.</p><p>Лучшая инфраструктура для мобильных продуктов строится теми, кто сам их создавал и знает все узкие места не понаслышке. Этот опыт даёт верное направление: ты чувствуешь, где настоящие проблемы, потому что сталкивался с ними лично. Такому не учат по книгам.</p><h2>Коротко: что делать, если думаете о переходе</h2><ul><li>Найдите промежуточный шаг. Не прыгайте сразу в бэкенд. Начните с задач на стыке: оптимизация API, инструменты для мобильных разработчиков, улучшение сетевого слоя.</li><li>Используйте мобильный контекст как рычаг. Вы понимаете то, о чём бэкенд-инженеры только догадываются. Говорите об этом вслух.</li><li>Учитесь измерять невидимое. В инфраструктуре результат — это метрики: latency, error rate, скорость релизов. Учитесь рассказывать историю через цифры.</li><li>Проектируйте под отказ, а не тушите пожары. Senior-уровень — это определить, что сломается и кто за это отвечает, до того, как оно сломается.</li><li>Не ждите разрешения. Путь не размечен, но он открыт. Начните с малого — и двигайтесь туда, где задачи становятся интереснее.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Как приручить legacy-код: безопасная модернизация без заморозки фич</title>
      <link>https://tproger.ru/articles/kak-priruchit-legacy-kod-bezopasnaya-modernizaciya-bez-zamorozki</link>
      <comments>https://tproger.ru/articles/kak-priruchit-legacy-kod-bezopasnaya-modernizaciya-bez-zamorozki?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[KODE]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-priruchit-legacy-kod-bezopasnaya-modernizaciya-bez-zamorozki</guid>
      <description><![CDATA[<p>Как модернизировать legacy-код без остановки продукта: Strangler Fig Pattern, feature flags, shadow testing и безопасная миграция данных. Практика и антипаттерны.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-priruchit-legacy-kod-bezopasnaya-modernizaciya-bez-zamorozki">Как приручить legacy-код: безопасная модернизация без заморозки фич</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Рефакторинг]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[ICO]]></category>
      <category><![CDATA[Финтех]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Twitter]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[OpenTelemetry]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[Legacy]]></category>
      <category><![CDATA[Техника]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 23 Jun 2026 06:16:57 GMT</pubDate>
      <content:encoded><![CDATA[<p>Legacy-код — одна из самых болезненных тем в инженерных командах. Обычно все понимают, что система устарела: архитектура мешает быстро выпускать изменения, новые фичи приходится встраивать через обходные пути, тесты либо неполные, либо отсутствуют, а любое изменение в одном модуле неожиданно ломает другой.</p><p>Но при этом к такому коду часто боятся прикасаться. И не без причины. В старых системах редко бывает понятная карта зависимостей. Документация устарела, часть знаний живет только в головах нескольких разработчиков, а бизнес при этом продолжает ждать новых релизов, интеграций и продуктовых экспериментов.</p><p>Так появляется классическая ловушка legacy: систему надо модернизировать, но остановить развитие нельзя. Переписать всё с нуля страшно, поддерживать как есть — всё дороже. В результате продукт обрастает временными решениями, скорость разработки падает, а стоимость каждого следующего изменения растет.</p><p>Хорошая новость в том, что модернизация legacy-кода не обязана быть большим взрывом. Старую систему можно менять постепенно, сохраняя рабочий продукт, не замораживая фичи и не устраивая один критический релиз, от которого зависит всё.</p><h2>Почему Big Bang-переписывание чаще всего заканчивается плохо</h2><p>Когда команда долго живет с устаревшей системой, идея переписать всё с нуля выглядит очень соблазнительно. Кажется, что можно наконец избавиться от технического долга, выбрать нормальную архитектуру, перепроектировать модули, покрыть всё тестами и начать «правильно».</p><p>На старте такой план часто звучит логично. Особенно если текущая система действительно мешает развитию. Например, мобильное приложение растет, у него уже миллионы пользователей, бэкенд написан несколько лет назад как монолит, а каждая новая фича требует изменений в десятке мест. Команда устала чинить регрессии, бизнес устал ждать, и всем хочется «один раз нормально переписать».</p><p>Проблема не в самой идее переписывания, а в условиях, при которых оно проваливается. Большой риск возникает, когда совпадают четыре фактора: переписывание занимает много месяцев, в это время бизнес продолжает развивать старую систему, новая версия покрывает сразу большую часть функциональности, а откат связан с миграцией данных. Если все четыре пункта присутствуют, Big Bang почти гарантированно превратится в долгий и дорогой проект.</p><p>Допустим, команда решила переписать модуль заказов в e-commerce-продукте. В старой версии есть корзина, промокоды, доставка и оплата. Команда планирует за полгода сделать новый сервис заказов. Но за эти полгода бизнес добавляет подписки, подарочные сертификаты, частичную оплату бонусами и новую логику возвратов. В итоге новая система, которую проектировали под старые требования, к моменту релиза уже нуждается в доработке.</p><p>Есть и другая проблема: большой релиз почти всегда несет максимальный риск. Если вы заменяете крупный кусок системы целиком, ошибка влияет сразу на большую часть пользователей. Откат тоже становится сложным, потому что новая логика уже связана с новыми данными, контрактами и интеграциями.</p><p>Big Bang всё-таки бывает оправдан — но в узких условиях. Если кодовая база молодая (год-два), пользователей мало, у системы нет критичного состояния в БД и продукт можно временно заморозить или вести в обоих контурах параллельно, полное переписывание может оказаться дешевле постепенной миграции. Это редкая ситуация, и она быстро исчезает по мере роста продукта. В зрелых системах безопаснее работает другой подход — постепенная архитектурная эволюция.</p><h2>Пример: как команда переписала сервис документов и потеряла полгода</h2><p>Команда сопровождала сервис — старый модуль на aiohttp с Pydantic v1, через который проходила вся обработка путевых листов и актов осмотра транспорта. Сервис существовал шесть лет, был покрыт тестами фрагментарно, а его API использовали мобильное приложение водителей, диспетчерская веб-панель и пакетный импорт.</p><p>Команда решила переписать сервис целиком: перейти на FastAPI, обновить Pydantic до v2, заодно почистить контракты и заменить внутреннее хранилище документов с MongoDB на PostgreSQL. План был рассчитан на четыре месяца.</p><p>Через восемь месяцев проект всё ещё не был готов к выкатке, а к десятому месяцу команда откатила миграцию полностью. Причин было несколько.</p><p>Во-первых, переписывание шло параллельно с продуктовой разработкой. За время миграции бизнес добавил два новых типа документов и изменил правила подписи актов. Новая система проектировалась под старые требования и к моменту готовности уже не соответствовала продукту.</p><p>Во-вторых, команда не написала характеристических тестов. Поведение «как есть» нигде не было зафиксировано, и расхождения находились только в продакшене после переключения.</p><p>В-третьих, у старого сервиса были скрытые побочные эффекты, о которых никто не помнил. При смене статуса документа публиковал событие в Kafka, которое читал биллинг и сервис аналитики. В новой реализации это поведение не было воспроизведено, потому что в коде оно выглядело как «лишний» вызов. После переключения биллинг перестал получать события, и расхождение обнаружили только через две недели — по жалобе финансового отдела.</p><p>В-четвёртых, переключение было сделано «в лоб»: маршрут в API Gateway просто перенаправили на новый сервис. Фича-флага не было, теневого запуска не было, плана отката не было. Когда выяснилось, что новый сервис строже валидирует исторические форматы документов и отклоняет часть старых записей, быстро вернуться на старую реализацию не получилось — её к тому моменту уже отключили на стенде, а в БД успели уйти записи в новом формате.</p><p>В итоге миграцию свернули, потратив около десяти человеко-месяцев и потеряв доверие бизнеса. Сервис до сих пор работает в исходной реализации, а команда переходит к плану, описанному ниже.</p><h2>Strangler Fig Pattern: как заменить систему по частям</h2><p>Один из самых практичных подходов к модернизации legacy-кода — Strangler Fig Pattern. В софтверном виде паттерн был сформулирован Мартином Фаулером в 2004 году под названием StranglerFigApplication. Идея проста: не переписывать систему целиком, а постепенно выносить отдельные части в новую реализацию.</p><p>Название пришло из биологии. Фикус-душитель растет вокруг дерева-хозяина и постепенно вытесняет его. В архитектуре принцип похожий: старая система продолжает работать, новая функциональность появляется рядом, а затем отдельные потоки постепенно переводятся на новую реализацию.</p><p>Представим старый монолит интернет-магазина. Внутри него есть каталог, корзина, заказы, платежи, скидки, личный кабинет и уведомления. Переписать всё сразу — рискованно. Но можно начать с относительно изолированного участка, например с уведомлений.</p><p>Сначала команда описывает текущий контракт: какие события приходят в модуль уведомлений, какие каналы используются, какие шаблоны отправляются, какие ошибки считаются допустимыми. Затем рядом создается новый сервис уведомлений, который реализует тот же контракт. На первом этапе он может даже не отправлять реальные сообщения, а только принимать события и логировать результат. После проверки часть трафика переводится на новую реализацию. Когда сервис стабилизируется, старый код уведомлений удаляется из монолита.</p><p>Strangler Fig хорошо работает там, где между старым и новым кодом есть сетевая граница: HTTP, message bus, RPC. Если такой границы нет — например, нужно постепенно заменить функцию или класс внутри одного процесса — используется родственный паттерн Branch by Abstraction: над старой реализацией создается абстракция, рядом пишется новая реализация, переключение происходит через конфигурацию или фича-флаг, после стабилизации старая ветка удаляется. Снаружи это выглядит как Strangler Fig, но без сетевого прокси.</p><p>Такой подход снижает риск. В системе нет одного большого релиза, где всё меняется сразу. Есть серия небольших контролируемых изменений. Каждое можно протестировать, измерить и откатить.</p><h2>Главное правило: сначала повторить поведение, потом улучшать</h2><p>Одна из частых ошибок при модернизации legacy-кода — попытка одновременно переписать систему и улучшить бизнес-логику. Команда смотрит на старый модуль и думает: «Раз уж мы его трогаем, давайте сразу сделаем нормальную архитектуру, изменим контракты, уберем странные кейсы и перепишем поведение».</p><p>Это опасный путь. В legacy-системах странное поведение часто существует не случайно. За ним может стоять неочевидное бизнес-правило, старый клиент, интеграция с внешней системой или исторический баг, на который уже кто-то завязался.</p><p>Например, в системе расчета налогов может быть правило: для контрактов, заключенных до 2018 года, НДС округляется в меньшую сторону до целого рубля, а для всех остальных — по математическим правилам. Новый разработчик может решить, что это ошибка, и «исправить» округление. Но потом выяснится, что часть крупных клиентов держит это поведение в своих сверках, а смена правила приведет к расхождениям в актах и претензиям.</p><p>Прежде чем менять поведение, его нужно зафиксировать. Для этого пишут характеристические тесты (characterization tests, иногда называемые golden master или approval tests). Идея простая: на реальных данных или их обезличенных копиях прогоняется старая реализация, её ответы сохраняются как эталон, и любые будущие изменения, отклоняющиеся от эталона, отлавливаются автоматически. Тесты пишутся не для красоты, а для того, чтобы зафиксировать существующее поведение — даже странное — перед тем, как его трогать. Подробно эта техника описана у Майкла Физерса в книге Working Effectively with Legacy Code; на практике её удобно реализовать через библиотеки семейства approval-tests (approvaltests-python, approvaltests-java и аналоги).</p><p>Поэтому первый этап модернизации — не улучшение, а воспроизведение текущего поведения. Новая реализация должна вести себя так же, как старая. Даже если старое поведение кажется странным. Только после стабилизации можно отдельно обсуждать, что именно стоит менять.</p><h2>Feature toggles: как включать новую логику без риска</h2><p>Feature toggles, или фича-флаги, — один из главных инструментов безопасной миграции. Они позволяют включать и выключать новую логику без деплоя.</p><p>В обычной разработке релиз часто выглядит бинарно: код либо выкатили, либо нет. При миграции legacy это неудобно. Гораздо безопаснее иметь возможность включить новую реализацию для 1% пользователей, затем для 10%, потом для половины аудитории и только после этого для всех.</p><p>Например, команда переносит расчет стоимости доставки из монолита в новый сервис. С помощью фича-флага это выглядит так:</p><p>user_id передается явно, чтобы решение «попал ли пользователь в новый сегмент» было стабильным от запроса к запросу. Иначе один и тот же клиент будет получать разные ответы при обновлении страницы, и поведение системы станет непредсказуемым.</p><p>На первом этапе флаг включают только для внутренней команды. Потом для тестового сегмента пользователей. Затем для небольшой доли реального трафика. Если метрики стабильны, долю увеличивают. Если появляются ошибки, флаг выключают, и пользователи снова идут в старую реализацию.</p><p>Важно различать два разных типа флагов. Флаг постепенной выкатки (rollout flag) меняется редко и контролирует, какой процент пользователей видит новую логику. Kill switch — отдельный флаг, единственная задача которого — мгновенно выключить новую реализацию при инциденте. Kill switch должен опрашиваться на каждом запросе, его кэширование должно жить секунды, а не минуты, и он принципиально не должен зависеть от той системы, которую он выключает. Иначе в момент аварии может оказаться, что выключатель сам недоступен.</p><p>В качестве инфраструктуры для флагов команды обычно берут одну из платформ: LaunchDarkly, Unleash, Flagsmith, GrowthBook, либо собирают собственную поверх Redis или конфигурационного сервиса. Для миграции важны три свойства: быстрое распространение изменений (секунды, а не минуты), поддержка таргетинга по пользователю/сегменту и аудит — кто и когда менял флаг.</p><p>Важно, что фича-флаг — это не просто if в коде. Для серьезной миграции нужны правила: кто может включать флаг, как быстро его можно отключить, какие метрики отслеживаются, когда флаг должен быть удален.</p><p>Последний пункт особенно важен. Если флаги не удалять, система быстро превращается в набор ветвлений, где никто уже не понимает, какая логика актуальна.</p><h2>Shadow testing: как проверить новую систему на реальном трафике</h2><p>Feature toggles помогают безопасно переключать пользователей. Но перед этим хорошо бы понять, совпадает ли новая логика со старой. Для этого используют shadow testing.</p><p>Shadow testing — это запуск новой реализации параллельно старой, но без влияния на пользователя. Пользовательский запрос по-прежнему обрабатывает старая система, а новая получает копию запроса и считает результат «в тени». Пользователю этот результат не показывается. Команда только сравнивает ответы.</p><p>Например, есть старый модуль расчета скидок. Он учитывает промокоды, сегмент пользователя, историю покупок, регион и партнерские условия. Команда пишет новый сервис скидок. Чтобы не переключать пользователей сразу, можно запустить теневой режим:</p><p>Два момента, на которые стоит обратить внимание в этом коде. Теневой вызов запускается через asyncio.create_task — корутина сразу планируется в event loop и начнёт выполняться, как только функция вернёт управление. И весь блок завернут в try/except: исключение в новой логике не должно ронять основной запрос. Без этих двух свойств shadow testing рискует ухудшить продакшен вместо того, чтобы безопасно его проверить.</p><p>Небольшая оговорка для продакшена: event loop держит на task только слабую ссылку, и без сохранённой ссылки задача может быть собрана сборщиком мусора прямо во время выполнения. В реальном коде Task имеет смысл класть в set фоновых задач и удалять оттуда через add_done_callback. В примере выше эта обвязка опущена для читаемости.</p><p>Для критичной доменной логики — платежей, биллинга, расчета тарифов — допустимый уровень расхождения должен быть около нуля: цель в shadow-режиме не «как можно меньше различий», а «понимаем каждое расхождение». Для менее чувствительных доменов (рекомендации, ранжирование результатов поиска) можно жить с расхождением в долях процента, но и там расхождения нужно классифицировать, а не игнорировать. Возможно, это баги новой реализации. А возможно, старая система содержит устаревшую логику, которую нужно отдельно обсудить с бизнесом.</p><p>Shadow testing особенно полезен для критичных доменных частей: платежей, биллинга, расчета тарифов, персональных предложений, транзакций. Там нельзя просто «попробовать на пользователях» и посмотреть, что будет.</p><p>При этом важно отличать теневую проверку чтения от теневой проверки записи. Чтение проверить относительно дёшево: запрос идёт в обе системы, ответы сравниваются, никаких внешних эффектов нет. С записью всё сложнее. Если новая реализация в shadow-режиме действительно создаст заказ, спишет деньги или отправит письмо, у пользователя возникнут двойные эффекты. Поэтому для writes либо вводят идемпотентные ключи и shadow-режим без реальных побочных действий (внешние вызовы заменены no-op-стабами, БД — отдельной shadow-копией), либо вообще отказываются от теневой проверки записи в пользу постепенной выкатки за фича-флагом.</p><p>Сравнение ответов в реальной системе тоже не сводится к одной функции compare. Нужно отдельно решать, как игнорировать «нормальный» шум (метки времени, идентификаторы, порядок коллекций), как сэмплировать трафик, чтобы не утопить хранилище расхождений, и как организовать триаж — кто и в каком ритме разбирает накопившиеся диффы. Готовые решения этого класса — GitHub Scientist (Ruby и его порты в другие языки), Twitter Diffy, либо собственный лёгкий регистратор поверх Kafka и таблицы расхождений.</p><h2>С чего начинать модернизацию</h2><p>Начинать лучше не с самого больного и не с самого центрального модуля. Это звучит контринтуитивно, потому что обычно хочется сразу взяться за главный источник проблем. Но если начать с ядра системы, команда быстро упрется в максимальное количество зависимостей и рисков.</p><p>Удобный способ выбрать первый кусок — оценить кандидатов по двум осям: насколько модуль критичен для бизнеса (low / high) и насколько сильно он связан с остальной системой (low / high). Начинать стоит с квадранта low-criticality + low-coupling: ошибки в нем не уронят бизнес-показатели, а малое количество зависимостей позволит провести миграцию полностью, не утянув за собой смежные модули. Высоко-критичные и сильно связанные части (платежи, ядро авторизации) трогают в последнюю очередь — на этот момент команда уже наберёт опыт безопасной миграции.</p><p>Хорошие точки входа обычно: уведомления, генерация отчетов, поиск, история операций, профиль пользователя, отдельная часть каталога. Важно, чтобы у команды была возможность описать контракт: какие данные входят, какие выходят, какие ошибки возможны, какие внешние системы участвуют.</p><p>Допустим, в банковском приложении есть старый модуль истории операций. Он медленный, сложно расширяется, но при этом не выполняет сами транзакции. Это хороший кандидат для первой миграции. Ошибка в истории операций неприятна, но обычно менее критична, чем ошибка в списании денег.</p><p>Команда может вынести чтение истории в отдельный сервис, сначала запустить его в shadow-режиме, потом включить для части пользователей, затем полностью перевести чтение на новую реализацию. При этом критичная транзакционная логика останется в старой системе до тех пор, пока команда не наберет опыт безопасной миграции.</p><h2>Миграция данных: самая сложная часть</h2><p>Большая часть статьи говорит о маршрутизации запросов и переключении трафика. Но в реальных проектах основная сложность лежит ниже — в данных. Старая и новая реализации почти всегда работают с общим состоянием: одной БД, одним хранилищем документов, одним набором очередей. Переехать туда «одним коммитом» нельзя.</p><p>Базовый рабочий приём — Expand-Contract (он же Parallel Change). Изменение схемы делается в три такта. На этапе expand в БД добавляются новые поля, таблицы или индексы, при этом старое поведение полностью сохраняется. Затем — migrate: обе реализации начинают писать и в старое, и в новое место (dual writes), а отдельный фоновый процесс делает backfill — заполняет новые поля историческими данными. После этого читатели по одному переключаются на новую схему. Только когда никто из читателей не использует старую структуру, наступает contract — удаление лишних колонок и таблиц.</p><p>Несколько практических деталей, которые часто упускают:</p><p>·         Dual writes — это не бесплатная операция. Две записи означают две точки отказа. Если одна из них упала, нужно решать, что делать: продолжать ли работу, ставить ли событие в очередь на повтор, помечать ли запись как несогласованную. Простое «сначала пишем туда, потом сюда» в продакшене на нагрузке приводит к расхождениям.</p><p>·         Backfill часто длиннее, чем кажется. На большой таблице миграция в одном UPDATE блокирует продакшен. Поэтому backfill делают батчами по N тысяч строк с паузами, отслеживают прогресс и предусматривают возможность остановить и продолжить.</p><p>·         Онлайн-изменения схемы на крупных таблицах делаются не штатным ALTER TABLE, а специализированными инструментами: gh-ost или pt-online-schema-change для MySQL, встроенные онлайн-механизмы PostgreSQL для индексов и колонок, Liquibase/Flyway — для управления версионированием изменений в репозитории.</p><p>·         Shadow testing данные не покрывает. Можно сравнить, что новая реализация возвращает то же, что и старая, но если за этим стоит другая схема в БД, проверка корректности самой миграции данных — это отдельная работа: сверки, контрольные суммы, выборочный аудит исторических записей.</p><p>Без этих шагов любая красивая фасадная архитектура наталкивается на разъезжающиеся данные — и тогда даже идеальный Strangler Fig снаружи не спасает.</p><h2>Прокси-слой как точка контроля</h2><p>Чтобы постепенно заменять legacy-код, нужно управлять маршрутизацией запросов. Для этого часто создают прокси-слой, API Gateway или фасад, через который проходит обращение к старой и новой логике. В терминах Domain-Driven Design такой слой часто называют Anti-Corruption Layer: он защищает новую реализацию от старых контрактов и наоборот, позволяя двум моделям сосуществовать без взаимного «загрязнения».</p><p>Без такой точки контроля миграция становится хаотичной. Часть клиентов ходит напрямую в старый модуль, часть — в новый, часть использует обходные пути, а команда теряет возможность централизованно переключать трафик.</p><p>Прокси-слой решает несколько задач. Он скрывает детали реализации от клиентов, позволяет направлять часть запросов в новую систему, поддерживает фича-флаги, собирает метрики и упрощает откат.</p><p>В качестве технической основы команды обычно берут один из трех вариантов: классический API gateway (Kong, AWS API Gateway), service mesh (Envoy, Istio) или более простой reverse proxy (NGINX, HAProxy). Service mesh особенно удобен, когда трафик уже идёт внутри Kubernetes-кластера: маршрутизацию можно менять конфигурацией, без правок кода клиентов и сервисов.</p><p>Например, мобильное приложение обращается к endpoint /orders/history. Раньше этот endpoint напрямую обслуживал монолит. После введения API Gateway приложение продолжает ходить по тому же контракту, но внутри gateway может решать, куда направить запрос: в legacy-модуль или новый сервис истории заказов.</p><p>Управление маршрутизацией обычно делается не «всё или ничего», а на основании атрибутов запроса: значения заголовка (X-Migration-Cohort: new), куки, хэша от user-id (стабильное разбиение пользователей на сегменты) или географического региона. Это позволяет выкатывать новую реализацию сначала на одну страну, на сотрудников самой компании или на тестовый сегмент — и только потом расширять охват.</p><p>Для клиента ничего не меняется. Для команды появляется управляемость.</p><h2>Наблюдаемость: без метрик миграция превращается в гадание</h2><p>Постепенная модернизация невозможна без нормальной наблюдаемости. Если команда не видит, что происходит внутри системы, она не сможет безопасно переключать трафик.</p><p>Минимальный набор — это логи, метрики и распределенная трассировка (distributed tracing). Нужно понимать, сколько запросов идет в старую и новую реализацию, сколько ошибок возникает, как меняется latency, где появляются таймауты, какие статусы возвращаются, какие бизнес-метрики проседают.</p><p>Технические метрики стоит формулировать не как «средний ответ» и «процент ошибок», а в терминах SLI и SLO: целевые показатели вида «99.9% запросов на /orders/history отвечают быстрее 300 ms за 30 дней» с явным error budget. Latency измеряется по перцентилям (p50, p95, p99) — среднее значение почти всегда обманчиво, а хвосты распределения говорят о реальном опыте пользователя. На время миграции имеет смысл выставить отдельные SLO для нового и старого пути и сравнивать их.</p><p>В качестве инструментов де-факто стандартом стал OpenTelemetry для трассировок, метрик и логов — единый протокол, который пишет в практически любое хранилище. Дальше — Prometheus и Grafana для метрик, Jaeger или Tempo для traces, Sentry или аналог для ошибок. Для миграции важна возможность фильтровать метрики по «варианту» — отдельно по старому и новому пути — иначе все цифры смешаются и реальную динамику будет не видно.</p><p>Технических метрик недостаточно. Если команда переносит оформление заказа, важно смотреть не только на 500 ошибки и время ответа, но и на конверсию в оплату, количество брошенных корзин, повторы запросов, обращения в поддержку.</p><p>Пример: новая система формально отвечает быстрее старой и не дает ошибок. Но после включения на 10% пользователей падает конверсия в оплату. Причина может быть не в серверной ошибке, а в изменении порядка полей, другом тексте сообщения или потере какого-то edge-case. Без бизнес-метрик команда может решить, что миграция успешна, хотя для продукта она уже создает проблему.</p><h2>Практическая последовательность миграции</h2><p>Рабочая последовательность обычно выглядит так.</p><p>Сначала команда выбирает ограниченный участок системы. На этом этапе важно не просто назвать модуль, а описать его границы. Какие сценарии он закрывает? Кто его вызывает? Какие данные он читает и пишет? Какие внешние интеграции использует? Какие неочевидные бизнес-правила в нем есть?</p><p>Затем поверх legacy-логики создается стабильный контракт. Это может быть API, фасад, gateway или отдельный слой внутри приложения. Главная задача — сделать так, чтобы клиенты зависели не от внутренней реализации, а от понятного интерфейса. На этом этапе полезно вспомнить про contract testing (Pact, Spring Cloud Contract): автотесты со стороны потребителей фиксируют, что именно они ожидают от API, и предупреждают о ломающих изменениях до того, как они доедут до продакшена.</p><p>После этого рядом пишется новая реализация. Она должна повторять текущее поведение, а не сразу становиться «идеальной версией будущего». На этом этапе полезно фиксировать все расхождения: где старая система работает странно, где требования не описаны, где бизнес-правила требуют уточнения.</p><p>Следующий этап — shadow testing. Новая система получает копии реальных запросов, считает результат, но пользователю по-прежнему возвращается ответ legacy. Команда сравнивает результаты и устраняет расхождения.</p><p>Когда новая реализация достаточно стабильна, начинается постепенное переключение через feature toggles. Сначала внутренние пользователи, потом 1% реального трафика, затем 5–10%, затем 50% и только после этого 100%.</p><p>На каждом этапе команда смотрит на метрики. Если всё стабильно, движение продолжается. Если появляются проблемы, флаг выключается, трафик возвращается в legacy, а команда разбирает причины.</p><p>Последний этап — удаление старого кода. Это не формальность, а обязательная часть миграции. И «удалить старый код» — это не один коммит, а явный Definition of Done: вырезана старая ветка кода, удалён фича-флаг, обновлена документация и схемы архитектуры, переименованы или удалены устаревшие дашборды и алерты, обновлены runbook’и для on-call и проведено короткое внутреннее обучение. Если этого не сделать, через полгода никто уже не вспомнит, какой путь актуален, и легаси-ветвление останется в коде навсегда.</p><h2>Откат миграций: дешёвый только пока не пошли записи</h2><p>Откатить миграцию, в которой ещё не было записи в БД, легко: достаточно переключить фича-флаг, и трафик снова идёт через старую реализацию. Откатить миграцию, в которой новая система уже неделю писала данные в новые таблицы, — отдельный, гораздо более тяжёлый разговор.</p><p>Поэтому ещё на этапе проектирования каждое изменение должно сопровождаться явным планом отката. Удобно различать три типа шагов.</p><p>Полностью обратимые шаги. Чтение через новый сервис, расчёт «в тени», новые метрики. Откат — выключить флаг. Это самый комфортный режим, и в нём стоит держать миграцию как можно дольше.</p><p>Обратимые с компенсацией. Новая реализация пишет дополнительные данные (например, дублирует операции в новую таблицу), но старый источник тоже обновляется. Откат возможен, но требует решить, что делать с уже записанными данными: оставить, очистить, синхронизировать. План этих действий должен быть написан до выкатки, не во время инцидента.</p><p>Forward-only. После некоторой точки откат становится невозможен — например, после того, как старая схема удалена или внешние интеграции перенастроены на новый сервис. Такие шаги допустимы, но к ним нужно приходить отдельно, осознанно, с особенно строгими SLO в предыдущем этапе. До forward-only-перехода имеет смысл подержать систему в режиме параллельной работы дольше, чем по графику.</p><p>Базовое правило: ни один шаг миграции не должен уходить в продакшен, если у команды нет письменного ответа на вопрос «как мы откатываемся в случае проблемы». Иначе при инциденте откатываться будут на ходу — и не факт, что успешно.</p><h2>Пример: как тот же сервис мигрировали со второй попытки</h2><p>После неудачного опыта команда взялась за тот же сервис заново, но изменила подход.</p><p>На первом шаге они зафиксировали поведение существующего сервиса. На самые часто используемые сценарии (создание путевого листа, подпись акта осмотра, выгрузка пакета документов за период) написали характеристические тесты на реальных продакшен-данных, обезличенных и сохранённых как фикстуры. Любое будущее изменение поведения теперь падало в CI как явное расхождение.</p><p>Параллельно команда провела инвентаризацию побочных эффектов. Из исходного кода и логов выяснилось, что сервис не только хранит документы, но и: публикует событие в Kafka при смене статуса, инкрементирует счётчик в Redis для рейтинга водителей, отправляет webhook во внешнюю систему партнёра, пишет в таблицу аудита. Каждый из этих эффектов попал в отдельный пункт чек-листа «что должно остаться» в новой реализации.</p><p>Затем команда выбрала первый кусок для выноса — не весь сервис, а только чтение документов (GET /documents/{id} и GET /documents/by-driver/{driver_id}). Это была наименее рискованная часть: ошибки в чтении неприятны, но не ломают финансовые потоки.</p><p>Новый сервис написали на FastAPI рядом со старым. На уровне API Gateway появилось правило маршрутизации: запросы на чтение шли в старый сервис, но в фоне дублировались в новый. Ответ пользователю всегда возвращал legacy, а ответ нового сервиса сравнивался с эталоном и записывался в отдельную таблицу для разбора. Использовали обёртку поверх asyncio.create_task — на ответ пользователя теневой вызов не влиял.</p><p>За три недели shadow-режима команда нашла четыре расхождения. Два оказались багами новой реализации (округление времени, неправильная сортировка вложений). Два — давно забытыми особенностями старого сервиса (одно поле возвращалось в UTC, другое — в локальной зоне; так было исторически, бизнес не возражал, но в новой реализации захотели единый формат). Все четыре зафиксировали явно: баги — починили, особенности — согласовали с продуктовой командой как осознанное изменение.</p><p>Когда расхождений не осталось, включили фича-флаг на сотрудников самой компании. Через неделю — на 1% реальных водителей. Дальше шаг по 5%, 25%, 50%, 100% с паузой в несколько дней между этапами. На каждом шаге следили не только за HTTP-ошибками и latency, но и за продуктовыми метриками: количество подписанных актов, время от открытия документа до подписи, доля повторных запросов. Один раз пришлось откатиться с 25% на 5% — в одном из регионов выросло время отклика из-за неэффективного запроса. Исправили, выкатили снова.</p><p>Через два месяца чтение полностью перешло в новый сервис. Старый код чтения и фича-флаг удалили в том же релизе. После этого по той же схеме мигрировали запись документов, потом публикацию событий, потом импорт из внешних систем. Полная миграция заняла девять месяцев — почти столько же, сколько провалившийся Big Bang, — но продукт всё это время продолжал развиваться, инцидентов не было, и в конце команда осталась с системой, которую понимает.</p><h2>Типичные ошибки при работе с legacy</h2><p>Первая ошибка — пытаться улучшить всё сразу. Команда одновременно меняет архитектуру, бизнес-логику, контракты и инфраструктуру. В результате становится невозможно понять, какая именно часть вызвала проблему. Правильнее сначала воспроизвести поведение, стабилизировать новую реализацию и только потом улучшать.</p><p>Вторая ошибка — недооценивать скрытые зависимости и побочные эффекты. Legacy-код часто делает больше, чем кажется. На один и тот же вызов могут быть навешаны: запись в таблицу аудита, инкремент счётчика в кэше, публикация события в очередь, обновление статуса связанной сущности, инвалидация кэша, дёрганье webhook’а во внешнюю систему. Если в новой реализации воспроизвести только явный путь, скрытые потребители молча перестанут получать данные — и узнают об этом через жалобу бизнеса, а не через ошибку в логах. Поэтому перед выносом любого модуля имеет смысл составить инвентаризацию побочных эффектов: пройтись по коду и логам и выписать каждое нелогичное действие отдельным пунктом чек-листа.</p><p>Третья ошибка — отсутствие наблюдаемости. Без логов, метрик и трассировки команда не управляет миграцией, а угадывает. Особенно опасно смотреть только на технические ошибки и игнорировать бизнес-показатели.</p><p>Четвертая ошибка — не договариваться с бизнесом. Модернизация не должна быть невидимой «инженерной активностью в стол». Её нужно встраивать в roadmap, объяснять эффект и договариваться о приоритетах. Если бизнес не понимает, зачем команда тратит время на миграцию, работа будет постоянно проигрывать новым фичам.</p><p>Пятая ошибка — не удалять старый код. Временное сосуществование старой и новой логики нормально. Вечное сосуществование — нет. Если legacy не удаляется, технический долг не уменьшается, а просто меняет форму.</p><p>Шестая ошибка — не удалять фича-флаги после миграции. Флаг, который сыграл свою роль и больше никогда не выключается, превращается в постоянное ветвление в коде. Через год команда не помнит, можно ли удалить такую ветку или там сидит важный edge-case. Через два — кода с такими «мёртвыми» флагами становится больше, чем основной логики. Поэтому каждый флаг должен заводиться с условием удаления («после полной выкатки и двух недель стабильной работы») и иметь ответственного, кто этим удалением займётся.</p><p>Отдельно стоит упомянуть организационную сторону. Закон Конвея работает и в обратную сторону: если новый и старый код владеются разными командами с разными приоритетами, миграция будет тормозиться независимо от выбранного паттерна. На время миграции имеет смысл явно проговорить, кто отвечает за переход, и не разделять старую и новую реализации между несовместимыми roadmap’ами.</p><h2>Компромиссы, к которым нужно быть готовыми</h2><p>Постепенная модернизация безопаснее Big Bang-переписывания, но она не бесплатна. Некоторое время система будет сложнее, чем раньше. В ней появятся старый и новый код, прокси-слой, фича-флаги, дублирование логики, дополнительные метрики.</p><p>Shadow testing увеличит нагрузку на инфраструктуру, потому что часть запросов будет обрабатываться дважды. Команде придется поддерживать дисциплину: документировать контракты, отслеживать флаги, удалять старую реализацию после миграции, поддерживать contract-тесты в актуальном состоянии.</p><p>Но это контролируемая сложность. Она распределена во времени и управляется инженерными практиками. В отличие от Big Bang-риска, где команда долго работает с минимальной обратной связью, а потом выкатывает один большой релиз с максимальной неопределенностью.</p><h2>Когда Strangler Fig особенно оправдан</h2><p>Постепенная миграция особенно хорошо подходит для систем, где downtime невозможен или слишком дорог. Это финтех, e-commerce, биллинг, мобильные бэкенды с большой аудиторией, высоконагруженные продукты, старые монолиты и системы с большим количеством интеграций.</p><p>Если продуктом ежедневно пользуются сотни тысяч или миллионы людей, нельзя позволить себе «переписать и посмотреть, что будет». Нужно менять архитектуру так, чтобы пользователь не замечал процесса миграции.</p><p>Этот подход также полезен там, где бизнес продолжает активно развивать продукт. Если фичи нельзя заморозить на полгода, модернизация должна идти параллельно с продуктовой разработкой.</p><h2>Когда модернизацию лучше не делать</h2><p>Постепенная миграция — мощный инструмент, но у неё тоже есть стоимость, и иногда правильный ответ — оставить систему как есть. Несколько сценариев, в которых модернизация плохо окупается.</p><p>Продукт, который уходит из эксплуатации. Если через год сервис будет выключен или заменён на покупное решение, тратить квартал на его рефакторинг бессмысленно. Достаточно стабилизировать то, что есть.</p><p>Модуль, который никто не трогает. Если код десятилетней давности продолжает работать, не падает, не требует изменений и не вызывает инцидентов, его «уродливость» — не повод его переписывать. Цель модернизации — упростить будущие изменения; если будущих изменений нет, цели тоже нет.</p><p>Регулируемые системы с тяжёлой ресертификацией. В банковских, медицинских и государственных контурах любое изменение в критичной системе может потребовать повторной сертификации, перепрохождения аудитов, обновления договорной обвязки. В таких условиях стоимость модернизации может на порядок превышать стоимость поддержки текущей реализации, и решение нужно принимать вместе с владельцем продукта и юристами, а не только инженерным составом.</p><p>Простой тест: если на вопрос «какой бизнес-сценарий мы откроем после миграции» нет внятного ответа — модернизацию имеет смысл отложить и заняться чем-то другим.</p><h2>Что получает команда</h2><p>Главный результат постепенной модернизации — управляемость. Команда начинает лучше понимать систему, контролировать изменения и снижать риск инцидентов.</p><p>Появляются понятные контракты, наблюдаемость, практика безопасных релизов, культура удаления старого кода. Разработчики перестают бояться legacy, потому что у них появляется метод, а не только желание «когда-нибудь всё переписать».</p><p>Для бизнеса это тоже выгодно. Продукт продолжает развиваться, сроки становятся более прогнозируемыми, риски крупных сбоев снижаются, а технический долг постепенно уменьшается.</p><h2>Модернизация — это процесс, а не проект</h2><p>Legacy нельзя «починить за квартал». Если система развивалась годами, она не станет простой после одного рефакторинга. Но её можно системно улучшать.</p><p>Strangler Fig Pattern, Branch by Abstraction, feature toggles, shadow testing и аккуратная миграция данных дают рабочую модель: выбрать ограниченный участок, описать контракт, реализовать новую версию, проверить её на реальном трафике, постепенно переключить пользователей и удалить старый код.</p><p>Это не самый быстрый путь. Зато он управляемый. А в зрелых продуктах управляемость важнее скорости.</p><p>Потому что цель модернизации — не написать красивую новую систему. Цель — сделать так, чтобы продукт продолжал развиваться, команда могла безопасно вносить изменения, а пользователи не становились участниками инженерного эксперимента.</p>]]></content:encoded>
    </item>
    <item>
      <title>Netflix построила Service Topology: живая карта микросервисов</title>
      <link>https://tproger.ru/articles/netflix-postroila-zhivuyu-kartu-servisov-kak-ustroena-service-top</link>
      <comments>https://tproger.ru/articles/netflix-postroila-zhivuyu-kartu-servisov-kak-ustroena-service-top?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/netflix-postroila-zhivuyu-kartu-servisov-kak-ustroena-service-top</guid>
      <description><![CDATA[<p>Как Netflix объединяет eBPF, IPC-метрики и tracing в единую карту зависимостей. Разбираем, почему статические схемы устарели и что перенести в свою систему.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/netflix-postroila-zhivuyu-kartu-servisov-kak-ustroena-service-top">Netflix построила Service Topology: живая карта микросервисов</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Архитектура ПО]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Графы]]></category>
      <category><![CDATA[Инфраструктура]]></category>
      <category><![CDATA[Архитектура приложений]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 19 Jun 2026 07:47:47 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если вы хоть раз отлаживали микросервис ночью, знаете главный вопрос: это мой сервис сломался или его уронило что-то выше по течению? В системе из тысяч сервисов ответ приходится искать по кускам — метрики, логи и трейсы показывают симптомы, но не дают единой карту зависимостей. Netflix столкнулась с этой же болью и построила инструмент под названием Service Topology, который рисует живую карту зависимостей в реальном времени.</p><p>Service Topology — это не статическая схема из вики, а динамическая карта связей между сервисами. Она обновляется по мере того, как меняется трафик, появляются новые зависимости или старые исчезают. Карта показывает не только «кто с кем говорит», но и контекст: уровень доступности, бизнес-домен, владельца и текущее состояние здоровья.</p><p>Если тема микросервисов для вас новая, начните с базового разбора <a href="https://tproger.ru/articles/chto-takoe-mikroservisy--arhitektura--plyusy-i-minusy--primery">«Что такое микросервисы»</a>, а если выбираете архитектуру для проекта — сравните варианты в материале <a href="https://tproger.ru/articles/monolit-ili-mikroservisy--kak-vybrat-arhitekturu-dlya-novogo-proekta">«Монолит или микросервисы»</a>. Авторский разбор внутреннего устройства Netflix читайте в статье <a href="https://tproger.ru/articles/razrabotchik-izuchal-sistemu-rekomendacij-netflix-mesyacami--vot-chto-skryvaetsya-vnutri">«Разработчик изучал систему рекомендаций Netflix месяцами»</a>.</p><ul><li>Netflix объединила три источника данных: eBPF-сетевые потоки, IPC-метрики и распределённые трейсы.</li><li>Каждый источник строит свой граф; общий вид получается параллельным слиянием слоёв.</li><li>Карта обновляется почти в реальном времени и отвечает на запросы быстрее секунды.</li><li>Инженеры используют её для поиска причин сбоев, оценки зоны поражения и планирования изменений.</li><li>Подход можно перенести в любую распределённую систему, где нужно понимать зависимости.</li></ul><h2>Почему обычной наблюдаемости мало</h2><p>Традиционные инструменты наблюдаемости показывают фрагменты картины. Метрики говорят, что что-то болит. Логи рассказывают, что конкретно произошло в одном сервисе. Трейсы прослеживают путь отдельного запроса. Но ни один из этих сигналов не показывает полную топологию зависимостей — ту самую основу, на которой держится распределённая архитектуры.</p><p>Инженеру в три часа ночи приходится мысленно склеивать данные из разных источников. Это медленно, чревато ошибками и добавляет стресса. Netflix проанализировала тысячи обращений в поддержку за четыре года и увидела повторяющиеся вопросы: кто мои upstream и downstream, что упадёт вместе со мной, почему сервис отображается в панели мониторинга как Unknown (неизвестный сервис). Ответы на них требовали единого представления о зависимостях.</p><h2>Три источника данных Service Topology</h2><p>Главный вывод Netflix: ни один источник не рассказывает всю историю. Поэтому система строит три независимых графа и объединяет их по запросу.</p><h3>Сетевые потоки eBPF</h3><p>На сетевом уровне Netflix собирает потоки ядра через eBPF. Это даёт полноту: сюда попадают все соединения, независимо от того, инструментирован сервис или нет. Слой показывает связи между кластерами и приложениями такими, какими они есть на самом деле. Недостаток — не хватает прикладного контекста: видно, что сервис А достучался до IP-адреса сервиса Б, но неизвестно, какой конкретно endpoint вызывался.</p><h3>IPC-метрики</h3><p>На прикладном уровне собираются метрики межпроцессного взаимодействия. Когда сервис обращается к другому через gRPC, GraphQL или REST, он фиксирует endpoint, ошибки, задержки и протокол. Этот слой даёт детали, которых нет у сетевого: какой именно путь вызывается и с какой вероятностью ошибки. Ограничение очевидно: если сервис не отправляет метрики, его вызовов здесь не будет.</p><h3>Распределённые трейсы</h3><p>Третий слой — трейсинг запросов от начала до конца. Он показывает не «может ли сервис А позвонить сервису Б», а «звонил ли он в рамках этого конкретного пользовательского запроса». Это помогает увидеть поведение во время выполнения, ветвления, фича-флаги и редкие пути. Поскольку трейсы собирают выборочно, редкие сценарии могут не попасть в агрегированный вид.</p><p>Когда инженер запрашивает общую картину, система обходит все три графа параллельно и сливает результаты. Сеть обеспечивает полноту, IPC добавляет контекст, трейсы показывают реальное поведение. Каждый источник компенсирует слабости остальных.</p><h2>Как собирают Service Topology</h2><h3>Приём и обработка потоков</h3><p>За кулисами работает конвейер, который держит миллионы событий в секунду. Потоки сетевых логов читаются из Kafka в нескольких регионах AWS. Для обработки Netflix использует Apache Pekko Streams — форк Akka, который разбивает нагрузку по группам автомасштабирования и сам управляет обратным давлением.</p><h3>Восстановление прямых связей</h3><p>Сетевой лог показывает отдельные сетевые прыжки: например, приложение → балансировщик → приложение или приложение → NAT-шлюз → приложение. Чтобы получить настоящие связи, запускается трёхступенчатая агрегация. Первая стадия забирает сырые записи, вторая распознаёт посредников и восстанавливает прямые пути между приложениями, третья финализирует агрегаты и добавляет статус здоровья. Такой градуированный подход раскидывает нагрузку и не даёт горячим узлам уронить весь конвейер.</p><p>Готовая топология хранится в графовой базе Netflix — абстракции поверх распределённого хранилища «ключ — значение». Она заточена под быстрый обход графа в несколько хопов. Поверх базы — gRPC-API с фильтрами по уровню доступности и домену, постраничным выводом больших выборок и ответом менее чем за секунду.</p><h3>Хранение и API</h3><p>Отдельно стоит возможность «путешествия во времени». Система не хранит каждый момент отдельно, а накапливает данные в скользящих окнах. Это позволяет спросить «как выглядела топология вчера в полночь» без взрыва объёмов хранения.</p><h2>Что даёт инженерам</h2><p>Интерфейс и API дают инженерам несколько рабочих сценариев — от ручного расследования до автоматических проверок.</p><ul><li>Видеть upstream и downstream для любого сервиса с фильтрами по уровню доступности и домену.</li><li>Переключаться между единым видом и отдельными слоями: только сеть, только IPC или только трейсы.</li><li>Одним кликом переходить от узла топологии к логам, трейсам и детальным метрикам.</li><li>Оценивать зону поражения перед отключением сервиса на обслуживание и понимать, кого уведомлять.</li><li>Накладывать статус здоровья на граф и быстро понимать, локальная ли это проблема или каскадный сбой.</li><li>Обращаться к топологии программно — например, чтобы автоматически проверять классификацию доступности критичных сервисов.</li><li>Смотреть историю зависимостей и находить, что изменилось перед инцидентом.</li></ul><h2>Как перенести в свою систему</h2><p>Не каждая компания работает в масштабе Netflix, но логика подхода универсальна. Если у вас десятки сервисов, уже появляется эффект «тысячи кусочков пазла». Начать можно с малого: собрать список зависимостей из существующих источников и периодически сверять его с реальным трафиком.</p><p><b>Чек-лист для первых шагов:</b><br />1. Выберите один настоящий источник связей: логи балансировщика, агент на хосте или метрики вызовов.<br />2. Не пытайтесь сразу построить идеальную модель — начните с автоматически обнаруженных рёбер.<br />3. Добавьте контекст: владельца сервиса, уровень критичности и домен.<br />4. Сделайте карту доступной программно, а не только в интерфейсе — инцидент-боты и скрипты будут благодарны.<br />5. Проверяйте актуальность: в динамичной среде карты, устаревшие на несколько часов, быстро теряют ценность.</p><p>Для иллюстрации вот минимальный скрипт, который строит рёбра графа из логов балансировщика:</p><h2>Часто задаваемые вопросы</h2><h2>Выводы</h2><p>Service Topology — не просто красивая картинка для панели мониторинга. Это операционная основа, которая ускоряет расследования, снижает риск изменений и даёт автоматическим системам общую картину инфраструктуры. Netflix называет её knowledge graph foundation — фундаментом для интеллектуальной автоматизации, в том числе для автоматического поиска первопричины сбоев.</p><blockquote>Service topology provides the knowledge graph foundation that makes this kind of intelligent automation possible.</blockquote><p>Для российских команд, где инфраструктура тоже стремительно усложняется, главный урок в другом: не ждите идеальной полноты данных. Начните с одного реального источника, добавьте контекст, сделайте карту программно доступной — и она начнёт приносить пользу раньше, чем вы построите «полноценную» систему.</p><h2>Источники</h2><ul><li><a href="https://medium.com/netflix-techblog/from-silos-to-service-topology-why-netflix-built-a-real-time-service-map-0165ba13a7bc">From Silos to Service Topology: Why Netflix Built a Real-Time Service Map</a></li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Production-safe агентный цикл: как не дать ИИ сжечь бюджет</title>
      <link>https://tproger.ru/articles/production-safe-agentnyj-cikl-kak-ne-dat-ii-szhech-byudzhet</link>
      <comments>https://tproger.ru/articles/production-safe-agentnyj-cikl-kak-ne-dat-ii-szhech-byudzhet?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/production-safe-agentnyj-cikl-kak-ne-dat-ii-szhech-byudzhet</guid>
      <description><![CDATA[<p>Как построить production-safe агентный цикл на Python, чтобы ИИ не сжигал бюджет в бесконечных итерациях. Разбираем circuit breaker, ledger и human attestation.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/production-safe-agentnyj-cikl-kak-ne-dat-ii-szhech-byudzhet">Production-safe агентный цикл: как не дать ИИ сжечь бюджет</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Машинное обучение]]></category>
      <category><![CDATA[Фреймворки и библиотеки]]></category>
      <category><![CDATA[Информационная безопасность]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 17 Jun 2026 09:45:21 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если ваш ИИ-агент работает круглосуточно и не может остановиться — это не автономность, а биллинговая авария, которая уже идёт. В июле 2025 года рекурсивный агентный цикл в Claude Code сжёг от 16 000 до 50 000 долларов за пять часов. Агенты не падают и не выдают ошибку: они делают ровно то, что им сказали, — пока кто-то не скажет остановиться.</p><p>Через четыре месяца четырёхагентный пайплайн на LangChain крутился одиннадцать дней и стоил 47 000 долларов. Никто не заметил, пока не пришёл счёт. Тот же паттерн: цикл работал корректно, но у него не было условия выхода.</p><p>Проблема не в моделях, а в отсутствии условия остановки. В этой статье разберём, как собрать минимальный, но production-ready каркас агентного цикла: спецификацию до запуска, предохранитель по токенам и ходам, неизменяемый аудит и поверхность для человеческого согласования. Полный код и 80 тестов с 100% покрытием доступны в <a href="https://github.com/dannwaneri/production-safe-agent-loop">репозитории автора оригинала</a>.</p><p>Агентные циклы сжигают бюджет не из-за плохих моделей, а из-за нечёткого условия остановки.</p><p>Спецификация должна отвечать на три вопроса: что делает, что не делает и что значит «готово» — в одном предложении.</p><p>Circuit breaker режет цикл по жёстким потолкам: число ходов и суммарные токены. Проверка — до вызова модели, а не после.</p><p>Ledger в SQLite фиксирует каждый ход: хеш входа, дельту токенов, время, результат. Это аудит, а не лог для отладки.</p><p>Review surface даёт поверхность для обязательной человеческой аттестации и формирует аудиторскую квитанцию frame_hash, которую вызывающий код может использовать как условие передачи результата в прод.</p><h2>Что такое агентный цикл и почему он уходит в бесконечность</h2><p>Агентный цикл — это конструкция вида while True, внутри которой языковая модель получает задачу, вызывает инструменты, анализирует результат и решает, продолжать или закончить. Такие циклы лежат в основе оркестраторов вроде LangGraph, CrewAI и AutoGen, а также внутри coding-агентов. Если только начинаете разбираться с LLM, полезно сначала понять, <a href="https://tproger.ru/articles/chto-takoe-llm-dlya-nachinayushhih">как устроены большие языковые модели</a>, а для практики — заглянуть в <a href="https://tproger.ru/articles/python-dlya-nachinayushhih">основы Python</a>.</p><p>Цикл уходит в бесконечность не потому, что модель «глупая», а потому, что никто не определил, что значит «готово». Модель видит неоднозначность и пытается быть полезной: перефразирует вызов инструмента, запускает верифицирующего агента, тот находит «проблему», срабатывает корректирующий агент — и так далее. На дашбордах всё выглядит активно: растёт число вызовов инструментов, completion rate держится высоким, а бюджет течёт в пустоту.</p><p><b>Почему дорожает каждая итерация:</b><br />Агент не начинает с чистого листа. Он каждый раз перечитывает всё предыдущее окно контекста — все неудачные попытки, все промежуточные выводы. Итерация 1 стоит 100 токенов, итерация 10 — уже тысячи. Вы платите за каждый провал снова и снова.</p><h2>Почему компании сначала платят за чатбота, а потом за агентный рабочий процесс</h2><p>Gartner фиксирует разрыв в потреблении токенов между пилотными чатботами и production-агентными рабочими процессами в 5–30 раз. А отчёт FinOps Foundation за 2026 год говорит, что 73% компаний превысили изначальный бюджет на ИИ. Цифры взяты из <a href="https://www.freecodecamp.org/news/how-to-build-a-production-safe-agent-loop-from-exit-conditions-to-audit-trails/">оригинального туториала</a>; полные отчёты Gartner и FinOps Foundation доступны по платным подпискам. Причина разрыва — в неправильном масштабировании: команда планировала стоимость чатбота (~0,04 USD за взаимодействие), а в прод ушёл мультиагентный оркестр (~1,20 USD за взаимодействие, до 70x на сложных задачах).</p><blockquote>A loop that runs without an exit condition isn't autonomous. It's a billing event waiting to happen.</blockquote><h2>Пять примитивов, которые ловят большинство отказов</h2><p>Автор оригинального туториала предлагает не монолитный фреймворк, а пять независимых Python-модулей, которые можно встроить в любой проект. Вместе они покрывают три уровня риска: дисциплину до запуска, принудительную остановку во время работы и доказательства после.</p><ol><li><b>Spec writer</b> — заставляет ответить на три вопроса до первого вызова модели.</li><li><b>Circuit breaker</b> — режет цикл, если превышены потолки по ходам или токенам.</li><li><b>Ledger</b> — ведёт append-only журнал каждого хода в SQLite.</li><li><b>Agent loop</b> — связывает три компонента в единый цикл.</li><li><b>Review surface</b> — собирает пятиэлементный фрейм и требует человеческой аттестации перед выдачей результата.</li></ol><h2>Фаза 1. Определить «готово» до первой строчки кода</h2><p>Самая дорогая ошибка в разработке агентов — не выбор модели, а начало кодинга до того, как команда может одним предложением описать условие завершения. «Агент проверит сайт» — не подходит. «Агент обходит целевой URL, извлекает все теги &lt;title&gt; и &lt;meta name="description"&gt;, помечает отсутствующие или слишком длинные и останавливается» — подходит.</p><p>Spec writer интерактивно запрашивает три поля, сохраняет их значения в SQLite и возвращает неизменяемый SpecResult(frozen=True). Полученный session_id связывает спецификацию, строки журнала и итоговый результат в одну трассируемую сессию.</p><p><b>Почему frozen=True:</b><br />Спецификация — это обязательство, а не черновик. frozen=True запрещает переприсваивать поля объекта SpecResult, поэтому код цикла не может «подвинуть» условие завершения посреди запуска.</p><h2>Фаза 2. Принудить «готово» на лету</h2><p>Circuit breaker задаёт два жёстких потолка: turn_limit — максимальное число обращений к модели, и token_limit — суммарное число токенов за всю сессию. Каждый потолок — «строго больше»: если лимит 5 ходов, пятый ещё разрешён, шестой выбросит исключение.</p><p>Ключевое правило: breaker.check() вызывается до запроса к модели, а не после. Постфактум проверка бессмысленна: токены уже сожжены. Исключение, а не код возврата, — чтобы нельзя было промолчать.</p><h3>Как подобрать лимиты для продакшена</h3><p>Демонстрационные значения 5 ходов / 15 000 токенов слишком жёсткие для реальных задач. Для продакшена автор предлагает настроить лимиты под свой бюджет; в туториале приведён пример breaker = CircuitBreaker(turn_limit=10, token_limit=50000). Если одна сессия должна стоить не дороже 1 USD, а средний ход — 0,10 USD, получается порядка 10 ходов. Конкретный token_limit выбирается исходя из прайсинга модели и среднего размера контекста: чем длиннее история диалога, тем раньше сработает потолок.</p><ul><li>Стартуйте с жёсткими лимитами и разрешайте рост только по метрикам, не по интуиции.</li><li>Отдельно лимитируйте retry-политику: каждый повторный запрос увеличивает и turn_count, и объём контекста.</li><li>Не смешивайте лимит токенов с лимитом выходных токенов модели; circuit breaker считает сумму input + output.</li></ul><h2>Фаза 3. Записывать всё, что нельзя подделать</h2><p>Circuit breaker защищает бюджет. Ledger защищает понимание того, что произошло. Это не лог для отладки, а журнал аудита: каждая строка — один ход, append-only, без обновлений и удалений.</p><p>Три решения стоит взять на заметку. Во-первых, вместо исходного текста сохраняется SHA-256 хеш входа: так не утекают персональные данные, а одинаковые входы разных запусков можно сравнивать. Во-вторых, pass_fail хранится как INTEGER (1/0), потому что у SQLite нет булева типа. В-третьих, временная метка — datetime.now(timezone.utc).isoformat(), так как datetime.utcnow() объявлен устаревшим в Python 3.12.</p><h2>Фаза 4. Цикл, который уважает границы</h2><p>Agent loop — единственный компонент, который обращается к языковой модели. Всё остальное работает локально: проверка потолков, запись в журнал, оценка условия выхода.</p><p>Анатомия одного хода простая и строгая: сначала breaker.check(), потом вызов модели, потом ledger.write(), потом проверка stop_reason. Если модель вернула end_turn — возвращаем результат. Если нет — добавляем сообщение continue и идём на следующий круг.</p><p>Этот вариант цикла — минимальный текстовый. Если агент использует инструменты, в Anthropic API stop_reason может быть tool_use: тогда нужно выполнить инструмент, вернуть его результат в messages и только потом решать, продолжать или завершать.</p><p>Системный промпт обязательно включает все три поля спецификации, а не только done_looks_like. Модели нужна негативная область — то, что агент делать не должен (what_it_does_not), — не меньше, чем позитивная: иначе она начнёт «добавлять ценность» за рамками задачи.</p><h2>Фаза 5. Поверхность согласования: цикл бежит к человеку</h2><p>Circuit breaker и ledger решают технические проблемы, но не отвечают на вопрос: «Соответствует ли результат тому, что обещали?» Именно здесь ошибки проходят в прод: вывод выглядит аккуратным, дашборд зелёный, ревьюер ставит галочку.</p><p>Review surface собирает пятиэлементный фрейм из SQLite и требует явной аттестации:</p><ol><li><b>Исходное обещание</b> — три поля спецификации.</li><li><b>Критерий приёмки</b> — поле done_looks_like как явный бенчмарк.</li><li><b>Diff</b> — вход первого хода, выход последнего, число ходов, токены, сработал ли breaker.</li><li><b>Доказательства</b> — все строки ledger за сессию.</li><li><b>Неразрешённые допущения</b> — строки с breach_reason и failed-ходами.</li></ol><p>После согласования ревьюер вызывает attest(). Функция собирает пятиэлементный фрейм в каноническом порядке и считает от него SHA-256 — получается frame_hash. Это аудиторская квитанция: она доказывает, что ревьюер видел именно этот фрейм, а не краткое резюме.</p><h2>Практический пример: SEO-аудит по расписанию</h2><p>Автор приводит пример SEO-аудита. SEO-аудит имеет естественный ритм: обход, выявление проблем, исправление, ожидание переиндексации. Запускать агента 24/7 бессмысленно — он будет сжигать токены в паузах между событиями. Честная архитектура — cron-задача, которая запускает цикл по расписанию.</p><p><b>Пример упрощён:</b><br />В production-варианте стоит проверять URL (допустимые схемы и хосты) и оборачивать requests.get в try/except requests.RequestException, чтобы агент не падал при недоступности сайта.</p><p>Cron-строка выглядит так:</p><p>Агент выполняет работу, записывает ходы в ledger, и если circuit breaker сработал — результат уходит на человеческую проверку, а не в прод.</p><h2>Провайдер-независимость через адаптер</h2><p>Цикл работает с любым клиентом, удовлетворяющим протоколу LLMClient. По умолчанию используется Anthropic, но через адаптер можно подключить OpenAI, Gemini, Ollama, локальные модели или собственный сервер. В репозитории автора показан иллюстративный пример адаптера для OpenAI. Главное — привести ответ к форме, которую ожидает AgentLoop: usage.input_tokens, usage.output_tokens, content[0].text, stop_reason.</p><h2>Выводы: дисциплина дороже модели</h2><p>Большинство аварий с агентными циклами предотвращаются не интеллектом модели, а чёткими границами. Спецификация до запуска, жёсткие потолки ресурсов, неизменяемый аудит и человеческое согласование — это минимальный набор примитивов, который отделяет автономного агента от неконтролируемого биллингового события.</p><p>Для российских команд это означает, что внедрять LLM-агентов без бюджетных предохранителей — всё равно что запускать бесконечный цикл с доступом к корпоративной карте. Начните с пяти модулей, описанных выше, прогоните их на тестовом дубле модели и только после этого открывайте доступ к реальным API.</p><blockquote>Define what done looks like before you start. That's the job, and always has been.</blockquote><p>Полный код и 80 тестов с 100% покрытием доступны в репозитории автора оригинала: <a href="https://github.com/dannwaneri/production-safe-agent-loop">github.com/dannwaneri/production-safe-agent-loop</a>.</p><p><b>Источник:</b> <a href="https://www.freecodecamp.org/news/how-to-build-a-production-safe-agent-loop-from-exit-conditions-to-audit-trails/">How to Build a Production-Safe Agent Loop — From Exit Conditions to Audit Trails</a>, freeCodeCamp.</p>]]></content:encoded>
    </item>
    <item>
      <title>Чистое API на Node.js: практическое руководство</title>
      <link>https://tproger.ru/articles/chistoe-api-na-node-js-prakticheskij-gajd</link>
      <comments>https://tproger.ru/articles/chistoe-api-na-node-js-prakticheskij-gajd?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/chistoe-api-na-node-js-prakticheskij-gajd</guid>
      <description><![CDATA[<p>Как построить поддерживаемое REST API на Node.js: слои, Zod, единые ошибки, версионирование и Swagger. Проверьте свою архитектуру.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/chistoe-api-na-node-js-prakticheskij-gajd">Чистое API на Node.js: практическое руководство</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Фреймворки и библиотеки]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 16 Jun 2026 11:00:21 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если ваше Node.js-приложение начиналось с одного server.js, а через полгода превратилось в лабиринт маршрутов, где бизнес-логика растворилась в обработчиках Express — эта статья для вас. Чистое API проектируется не ради красоты, а чтобы команда могла добавлять конечные точки, не боясь сломать соседние.</p><p>Разберём минимальный, но готовый к продакшену скелет: разделение слоёв, валидацию входных данных, централизованную обработку ошибок, версионирование, ограничение частоты запросов и автоматическую документацию. Все принципы применимы и к Express, и к Fastify, и к NestJS.</p><p>Чистое API — это прежде всего разделение ответственности: роутер знает маршруты, контроллер переводит HTTP в вызовы сервиса, сервис отвечает за бизнес-логику, а схема проверяет входные данные. Такой подход делает код предсказуемым при любом масштабе.</p><p>Чистое API — это, прежде всего, разделение ответственности: роутеры, контроллеры, сервисы и валидация живут в разных слоях.</p><p>Валидация с помощью Zod выполняется на границе — до того, как запрос попадёт в бизнес-логику.</p><p>Централизованный обработчик ошибок — единственное место, где исключения превращаются в HTTP-ответы.</p><p>Стоит закладывать версионирование и документацию OpenAPI с первого дня: позже это обойдётся дороже.</p><p>Fastify и NestJS дают те же архитектурные идеи из коробки, но логика слоёв от этого не меняется.</p><h2>Что мы будем строить</h2><p>Возьмём намеренно простой домен — каталог товаров. Нам важна не бизнес-логика, а структура. К концу у нас будет REST API с единым форматом ответов, валидацией, версионированием по пути /api/v1, ограничением частоты запросов и интерактивной документацией Swagger.</p><h2>Структура проекта</h2><p>Прежде чем писать код, договоримся, где что лежит. Каждая фича — отдельная папка, а не рассыпанный по проекту набор файлов.</p><ul><li>api/v1/ — все маршруты версионированы с первого дня. Добавить v2 позже можно новой папкой, а не рефакторингом.</li><li>products/ — фичевая папка владеет роутером, контроллером, сервисом и схемой.</li><li>middleware/ — сквозная функциональность: защита, логирование, лимиты.</li><li>lib/ — утилиты без привязки к фреймворку.</li></ul><h2>Разделяем ответственность</h2><p>Самая частая ошибка в Express-приложениях — бизнес-логика внутри обработчика маршрута. Там же появляется валидация, работа с базой данных и формирование ответа. При росте проекта такой файл становится опасным для изменений.</p><h3>Роутер знает только «куда идти»</h3><h3>Промежуточный обработчик валидации</h3><p>Промежуточный обработчик validateRequest проверяет body, params и query до попадания в контроллер. Если данные не проходят проверку, ошибка передаётся в централизованный обработчик.</p><h3>Контроллер переводит HTTP в вызовы сервиса</h3><p>Контроллер не знает, где хранятся товары. Его задача — извлечь параметры из запроса, вызвать сервис и вернуть ответ. Всё остальное передаётся в централизованный обработчик ошибок через next(error).</p><h3>Сервис содержит бизнес-логику</h3><p>Сервис не зависит от HTTP. Когда придёт время заменить хранилище в памяти на настоящую базу данных, потребуется поправить только этот файл.</p><h2>Валидация на границе с Zod</h2><p>Любое API, принимающее внешние данные, должно их проверять. Без валидации один некорректный запрос способен превратиться в ошибку времени выполнения, некорректную запись в базе или уязвимость.</p><p>Zod даёт две вещи сразу: проверку во время выполнения и типы TypeScript, выведенные из одной схемы. Промежуточный обработчик validateRequest проверяет body, params и query до того, как запрос попадёт в контроллер. Если данные невалидны, дальше они не идут.</p><h2>Единый обработчик ошибок</h2><p>Разбросанная обработка ошибок — один из главных источников хаоса: где-то возвращается { error: '...' }, где-то { message: '...' }, а где-то случайно отдаётся HTML-страница. Решение — один обработчик, через который проходят все исключения.</p><p>Теперь клиент всегда получает предсказуемую форму ответа, а добавление логирования или отправки ошибок в мониторинг — однострочное изменение в одном месте.</p><h2>Единый формат ответов</h2><p>Успешный ответ всегда выглядит как { success: true, data: ... }, а ошибка — как { success: false, error: { code, message, details } }. Фронтенд или сторонний интегратор знает, чего ожидать от любого эндпоинта.</p><h2>Версионирование API</h2><p>Версионировать API с первого дня стоит недорого. Добавить версию позже — значит ломать существующих клиентов или городить сложную миграцию.</p><p>Новая версия — новая папка src/api/v2/ и новый префикс. Старые клиенты продолжают работать на /api/v1.</p><h2>Ограничение частоты запросов</h2><p>Rate limiting защищает API от случайных и намеренных перегрузок. Настроить его в Express помогает пакет express-rate-limit.</p><p>Глобальный лимит распространяется на все запросы; операции, которые изменяют данные, ограничены жёстче. Ответ тоже соответствует единому формату ошибки.</p><h2>Документация OpenAPI и Swagger</h2><p>API без документации годится только для автора. С помощью swagger-jsdoc и swagger-ui-express можно получить интерактивную документацию прямо из JSDoc-комментариев в роутерах.</p><p><b>Совет:</b><br />Держите описания эндпоинтов в одном файле с маршрутами, а glob в swagger.ts настройте на файлы, доступные во время работы приложения. Лучше генерировать спецификацию на этапе сборки, чем полагаться на исходники TypeScript.</p><h2>Fastify и NestJS: альтернативы Express</h2><p>Всё, что мы разобрали, работает и в Express. Но если вы начинаете проект с нуля, стоит взглянуть на альтернативы.</p><ul><li>Fastify — быстрее Express в бенчмарках (порой в два раза), имеет встроенный логгер Pino и валидацию по схеме. Разделение слоёв остаётся на совести разработчика.</li><li>NestJS — популярен в крупных компаниях: слои модулей, контроллеров и сервисов навязаны архитектурой, что упрощает введение новых разработчиков в проект.</li><li>Express — остаётся лучшим выбором, если вы присоединяетесь к существующему проекту или команда уже знает экосистему.</li></ul><p>Архитектурные принципы — разделение слоёв, единый формат ошибок, валидация на границе — не зависят от фреймворка. Меняется только синтаксис.</p><h2>FAQ</h2><h3>Минимальный набор для старта</h3><p>Для самостоятельного запуска понадобятся базовые зависимости и алиасы путей в tsconfig.json. Объявите @/* на папку src, и примеры заработают без ручных правок импортов.</p><h2>Выводы</h2><blockquote>Чистая структура API — это не переусложнение. Это минимум, при котором бэкенд можно поддерживать нескольким людям.</blockquote><p>Мы собрали минимальный, но масштабируемый каркас: папки по фичам, разделённые слои, валидацию на границе, централизованную обработку ошибок, единый формат ответов, версионирование, лимиты и автоматическую документацию. Ни один из этих шагов сложный сам по себе. Их ценность — в сочетании и в том, чтобы сделать всё это до того, как код разрастётся.</p><p>Если начинаете новый Node.js-проект, не откладывайте структуру «на потом». А в существующем — попробуйте вынести валидацию в схему и собрать ошибки в одном обработчике. Потом всегда дороже.</p><h2>Источники</h2><p>Идеи и примеры в статье основаны на материале Gavin Cettolo «<a href="https://dev.to/gavincettolo/clean-api-design-in-nodejs-a-practical-guide-3a32">Clean API Design in Node.js: A Practical Guide</a>» (dev.to).</p>]]></content:encoded>
    </item>
    <item>
      <title>A2A Java SDK 1.0.0: стабильный релиз для агентных приложений на Java</title>
      <link>https://tproger.ru/news/a2a-java-sdk-1-0-0-stabilnyj-reliz-dlya-agentnyh-prilozhenij-na</link>
      <comments>https://tproger.ru/news/a2a-java-sdk-1-0-0-stabilnyj-reliz-dlya-agentnyh-prilozhenij-na?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/a2a-java-sdk-1-0-0-stabilnyj-reliz-dlya-agentnyh-prilozhenij-na</guid>
      <description><![CDATA[<p>Вышел A2A Java SDK 1.0.0.Final — официальная Java-реализация протокола Agent2Agent. Разбираем ключевые изменения, как подключить SDK из Maven Central и зачем это Java-разработчикам.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/a2a-java-sdk-1-0-0-stabilnyj-reliz-dlya-agentnyh-prilozhenij-na">A2A Java SDK 1.0.0: стабильный релиз для агентных приложений на Java</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Open Source]]></category>
      <category><![CDATA[Сетевые протоколы]]></category>
      <category><![CDATA[Новости]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 16 Jun 2026 09:45:59 GMT</pubDate>
      <content:encoded><![CDATA[<p>Java-разработчики получили стабильный инструмент для создания агентных систем. <b>A2A Java SDK 1.0.0</b> вышел в релиз и доступен в Maven Central с groupId org.a2aproject.sdk. Для сборки клиента можно взять артефакт a2a-java-sdk-client или импортировать a2a-java-sdk-bom. Библиотека реализует протокол <b>Agent2Agent (A2A)</b> — открытый стандарт, управляемый Linux Foundation, для взаимодействия ИИ-агентов друг с другом.</p><p><b>Agent2Agent</b> — это протокол, управляемый Linux Foundation (изначально представленный Google), который позволяет агентам на разных фреймворках и языках находить друг друга, делегировать задачи и обмениваться результатами. Для Java-экосистемы выпуск SDK версии 1.0.0 означает переход от экспериментальных сборок к инструменту, готовому к промышленной эксплуатации.</p><p>Релиз 1.0.0 появился на прошлой неделе, как сообщает InfoQ в очередном выпуске Java News Roundup. В него вошли исправления ошибок, обновление зависимостей и несколько новых возможностей: интеграционный тестовый набор на базе Quarkus для проверки совместимости разных SDK, а также расширение интерфейса A2AHttpResponse и класса A2AClientHTTPError для доступа к HTTP-заголовкам ответов.</p><ul><li>A2A Java SDK 1.0.0 вышел в GA — первая стабильная версия для Java.</li><li>Реализует протокол Agent2Agent для взаимодействия ИИ-агентов.</li><li>Появился интеграционный тестовый набор на базе Quarkus.</li><li>Доступен в Maven Central: org.a2aproject.sdk.</li><li>Параллельно вышел A2A Jakarta 1.0.0.CR1 для Jakarta EE серверов.</li></ul><h2>Что вошло в релиз A2A Java SDK 1.0.0</h2><ul><li>Новый интеграционный тестовый набор (ITK) на базе Quarkus для проверки кросс-SDK совместимости.</li><li>Возможность получать HTTP-заголовки ответов через интерфейс A2AHttpResponse и класс A2AClientHTTPError.</li><li>Исправления ошибок и обновление зависимостей.</li><li>Готовность к использованию в production вместе с A2A Protocol Specification 1.0.</li></ul><blockquote>I am pleased to announce the release of A2A Java SDK 1.0.0.Final — our first GA release. The A2A Java SDK is the official Java implementation of the Agent2Agent (A2A) Protocol, an open standard that enables AI agents to communicate and collaborate regardless of underlying framework, language, or vendor.</blockquote><p>Параллельно команда выпустила первый релиз-кандидат <b>A2A Jakarta 1.0.0.CR1</b>. Эта интеграция помогает запускать A2A-агентов внутри Jakarta EE серверов, таких как WildFly. В CR1 переименованы пакеты и артефакты, обновлён набор TCK для работы с A2A Java SDK 1.0.0 и настроен запуск CI на Windows.</p><h2>Зачем это Java-разработчикам</h2><p>SDK позволяет строить агентные приложения на Java без привязки к Python-стеку. Агенты могут общаться с агентами на Google ADK, LangGraph, CrewAI и других фреймворках через единый протокол. Это особенно важно для команд, где основная инфраструктура уже написана на Java. Рядом с A2A развивается протокол <a href="https://tproger.ru/news/anthropic-zapustila-mcp-tunneli-i-sendboksy-dlya-korporativnyh-ai">MCP</a>: если MCP соединяет агента с инструментами, то A2A — агента с агентом.</p><p>A2A Java SDK 1.0.0 делает Java полноценной платформой для агентных приложений: теперь можно подключить SDK из Maven Central и начать строить агентов, которые работают в одной экосистеме с Python- и TypeScript-решениями.</p><p><b>Источник:</b> <a href="https://www.infoq.com/news/2026/06/java-news-roundup-jun08-2026/">InfoQ — Java News Roundup: A2A Java SDK 1.0, Jakarta EE 12, JNoSQL, GraalVM, Micrometer, OpenXava, Gradle</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Представляем MDN MCP server</title>
      <link>https://tproger.ru/translations/predstavlyaem-mdn-mcp-server</link>
      <comments>https://tproger.ru/translations/predstavlyaem-mdn-mcp-server?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/predstavlyaem-mdn-mcp-server</guid>
      <description><![CDATA[<p>MDN MCP server переносит актуальную документацию и данные о совместимости браузеров прямо в редактор или AI-агента. Разбираем, как подключить и почему точнее.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/predstavlyaem-mdn-mcp-server">Представляем MDN MCP server</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Браузеры]]></category>
      <category><![CDATA[Mozilla]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 15 Jun 2026 11:30:35 GMT</pubDate>
      <content:encoded><![CDATA[<p>Перевод статьи The MDN Team из MDN Blog, оригинал: <a href="https://developer.mozilla.org/en-US/blog/introducing-mdn-mcp-server/">Introducing the MDN MCP server</a>.</p><p>Мы рады анонсировать выпуск MDN MCP server. MCP (Model Context Protocol) — открытый стандарт, который позволяет ИИ-инструментам подключаться к внешним источникам данных. MDN MCP server использует этот протокол, чтобы перенести документацию MDN и данные о совместимости браузеров прямо в вашего ИИ-агента или IDE.</p><ul><li>MDN MCP server — экспериментальный сервер по протоколу MCP.</li><li>Даёт ИИ-агентам и IDE доступ к актуальной документации MDN и данным о совместимости браузеров.</li><li>Работает с VS Code, Zed, Cursor, Claude Code, Codex CLI, Antigravity CLI и Claude Desktop.</li><li>В тестах с Claude Code Opus 4.7 MDN MCP дал гораздо точнее и надёжнее результаты о поддержке браузеров.</li><li>Ответы с MDN MCP были вдвое быстрее, чем без него.</li></ul><h2>Зачем мы создали MDN MCP</h2><p>Всё больше ИИ-инструментов интегрируется в рабочие процессы веб-разработки, но они могут выдавать устаревшую информацию о веб-платформе из-за обучающих данных и даты знания модели.</p><p>Например, LLM или агент для написания кода может не знать, что существует функция вроде @view-transition CSS at-rule, или не знать, достигла ли она статуса Widely Available в Baseline и безопасна ли для использования во всех браузерах.</p><p>MDN MCP даёт вашему агенту для написания кода доступ к точной и актуальной информации о веб-платформе. Также он упрощает доступ к последней документации, не покидая привычные инструменты.</p><p>Сервер сейчас находится в экспериментальном статусе. Подробности об обработке данных в этой фазе — в нашей <a href="https://developer.mozilla.org/en-US/mcp#privacy_and_data_retention">заметке о приватности</a>.</p><h2>Как использовать MDN MCP</h2><p>MDN MCP server работает с любым MCP-совместимым клиентом, включая:</p><ul><li><b>Редакторы</b>: VS Code, Zed и Cursor.</li><li><b>CLI-агенты</b>: Claude Code, Codex CLI и Antigravity CLI (ранее Gemini CLI).</li><li><b>Чат-приложения</b>: Claude Desktop.</li></ul><p>Ссылки в этом списке ведут к инструкциям по настройке MCP для каждого инструмента. Инструкции по установке и другие детали — на нашей странице <a href="https://developer.mozilla.org/en-US/mcp">MDN MCP server</a>.</p><p>Как быстрый пример, чтобы использовать его с Claude Code, нужно выполнить следующую команду:</p><p>Мы с нетерпением ждём, как вы интегрируете его в свой рабочий процесс веб-разработки и в каких сценариях он окажется наиболее полезен.</p><h2>Какую разницу даёт MCP</h2><p>Учитывая недетерминированную природу LLM и разнообразие доступных моделей, часто сложно сравнивать их поведение с включёнными или выключенными навыками, промптами, инструментами и MCP.</p><p>Мы протестировали Claude Code Opus 4.7 с MDN MCP и без него на нескольких функциях, недавно появившихся в Firefox 150 и 151, спрашивая, как использовать функции и какая у них поддержка браузеров. А именно:</p><ol><li>Как использовать CSS-функцию light-dark() для изображений и какие браузеры её поддерживают?</li><li>Как использовать CSS-псевдокласс :buffering и какие браузеры его поддерживают?</li><li>Как использовать атрибут shadowrootslotassignment на элементе  и какие браузеры его поддерживают?</li><li>Как использовать Web Serial API и какие браузеры его поддерживают?</li></ol><p>Мы заметили определённые закономерности в результатах. В большинстве случаев заметки по использованию от Claude Code с MDN MCP и без него были сопоставимы. Часть ответов, использовавших MCP, была структурирована лучше и полнее. Например, заметки для CSS-функции light-dark() также включали примеры с линейными градиентами, которые не были прямо упомянуты в вопросе, но тоже поддерживаются.</p><p>Когда дело дошло до информации о поддержке браузеров, победитель был очевиден: MDN MCP дал намного точнее и надёжнее результаты. Claude Code без MCP правильно определил поддержку браузеров только в одном случае — для псевдокласса :buffering.</p><p>Например, Claude Code без MCP настаивал, что декларативный атрибут shadowrootslotassignment поддерживается в Chrome 120 и Safari 18.3, возможно, путая его с опцией slotAssignment метода Element.attachShadow(). Но на самом деле Firefox 151 — первый браузер, в котором появилась поддержка этого атрибута.</p><p>Без MCP Claude Code также не дал никакой конкретной информации о поддержке браузеров для использования изображений в функции light-dark(): «поддержка менее однородна, чем вариант с цветом», тогда как с MCP он выдал полную таблицу с указанием Firefox 150 и Chrome (за флагом) как поддерживающих браузеров.</p><p>Худший результат Claude Code без MCP показал на вопросе про Web Serial API. Firefox 151 получил поддержку Web Serial API в мае 2026 года. Однако Claude Code без MCP правильно упомянул браузеры на базе Chromium как поддерживающие эту функцию, но также настаивал, что в Firefox она:</p><blockquote>Не реализовано (и не в планах — см. позицию Mozilla по стандартам: «вредно»).</blockquote><p>С включённым MCP Claude Code правильно определил, что Firefox 151 поставляет поддержку Web Serial API, согласно примечаниям к выпуску.</p><p>Кроме того, мы заметили, что в наших тестах ответы с использованием MDN MCP были вдвое быстрее. Без MCP Claude Code приходилось загружать и парсить немало HTML-страниц, чтобы найти актуальную информацию, что занимало время, но даже тогда не давало точных результатов.</p><h2>Поучаствовать</h2><p>Ваш отзыв помогает нам становиться лучше. Если вы столкнулись с проблемами, есть комментарии или предложения или хотите поделиться, как используете MDN MCP, мы будем рады услышать вас. Заходите в канал platform в нашем Discord. Если заметили проблемы, сообщайте о них в репозиторий <a href="https://github.com/mdn/mcp">mdn/mcp</a> на GitHub.</p><h2>Что дальше</h2><p>По мере того как ИИ-инструменты становятся всё большей частью рабочих процессов веб-разработки, мы стремимся сделать документацию MDN доступной там, где она вам нужна. Этот релиз — один шаг к этой цели, и мы с нетерпением ждём возможности продолжить улучшать опыт с вашей помощью.</p><p>Источник: <a href="https://developer.mozilla.org/en-US/blog/introducing-mdn-mcp-server/">Introducing the MDN MCP server — MDN Blog</a>.</p><p>Попробуйте подключить MDN MCP к своему редактору или агенту и проверьте, насколько точнее станут ответы о веб-платформе.</p>]]></content:encoded>
    </item>
    <item>
      <title>Локализация через Enum, неожиданный Дзен, быстрее только телепатия</title>
      <link>https://tproger.ru/articles/lokalizaciya-cherez-enum-neozhidannyj-dzen-bystree-tolko-telepat</link>
      <comments>https://tproger.ru/articles/lokalizaciya-cherez-enum-neozhidannyj-dzen-bystree-tolko-telepat?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Самир Гёзалов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/lokalizaciya-cherez-enum-neozhidannyj-dzen-bystree-tolko-telepat</guid>
      <description><![CDATA[<p>Надоело плодить JSON/ARB файлы при локализации Flutter-приложения? Автор делился личным опытом и показал, как элегантно настроить локализацию через Enum без внешних зависимостей, генераторов кода и боли в рантайме.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/lokalizaciya-cherez-enum-neozhidannyj-dzen-bystree-tolko-telepat">Локализация через Enum, неожиданный Дзен, быстрее только телепатия</a>»</p>]]></description>
      <category><![CDATA[Алгоритмы и структуры данных]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Массивы и строки]]></category>
      <category><![CDATA[Красивый хак]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Мобильная разработка]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Flutter]]></category>
      <category><![CDATA[Dart]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 04 Jun 2026 04:45:17 GMT</pubDate>
      <content:encoded><![CDATA[<p>Решил давеча добавить локализацию в свое приложение на Flutter. Задачка-то простая: пара кнопок, пару десятков переменных. Казалось бы, делов на пять минут. Но Flutter «из коробки» сразу попытался всучить мне какую-то дичь в виде ARB и JSON файлов. Хмм, из прошлого с такими реализациями лишь печаль, так что…</p><h2>Попытка №1. Путь в лоб: Классы и интерфейсы</h2><p>Самый очевидный способ - создать родительский класс с переменными, а языки сделать его наследниками. Но это просто… фиаско. Даже если не писать from/toJson, процесс выглядит так:</p><ol><li>Объявил переменную в родителе.</li><li>Прописал её в конструкторе.</li><li>Повторил то же самое для всех дочерних классов (всех языков).</li></ol><p>Если бы я работал на аутсорсе в Индии и мне платили за количество строк кода - это был бы идеальный вариант. Но я хотел, чтобы одной строки при объявлении было достаточно.</p><h2>Попытка №2. Стандарт (ARB/JSON)</h2><p>Я поплевался, но решил попробовать - «стандарт» всё-таки. Мало ли, может чего поменялось за годы. Вроде всё завелось, но сам процесс… это боль. Бегать по разным файлам, чтобы добавить одну строчку - так себе удовольствие.</p><p>Почему я от него окончательно отказался? Когда данных становится реально много (десятки языков, тысячи строк), ты попадаешь в ловушку: тебе нужно эту махину либо целиком держать в памяти, либо постоянно подгружать и парсить. Ради смены одного слова на кнопке заставлять девайс ворочать тяжелые JSON-ы в рантайме - так себе затея для производительности.</p><h2>Попытка №3. Таблицы и костыли</h2><p>Подумал: «Окей, почему бы не подтянуть старый добрый CSV или вообще закинуть всё в табличку?». И тут официальный пакет локализации сказал: «Извини, мужик, тут наши полномочия всё».</p><p>Ну, я тоже не пальцем деланный. Решил припахать нейросеть, чтобы она написала мне собственный генератор. Флоу получился такой:</p><ol><li>Добавляю строку в таблицу.</li><li>Запускаю генератор.</li><li>Он лепит «родительский» файл.</li><li>После Freezed генерит toJson, fromJson…</li></ol><p>Короче, весело не было. Мало того, я понимал: если языков станет много, мне придется добавлять их все разом и единовременно, иначе в рантайме всё начнет плеваться ошибками. Плюс та же проблема с памятью: таблица - это структура, которую надо парсить и хранить.</p><h2>Красный флаг для программиста</h2><p>Но главная проблема даже не в этом. Необходимость запускать генератор после добавления каждой переменной - это для любого программиста красный флаг.</p><p>Что происходит на практике? Когда ты пишешь код и тебе нужно добавить одну несчастную строку, тебе лень (читать: нехочется выходить из потока творения) запускать весь этот цикл с генерацией. Ты просто её хардкодишь в надежде «потом скопом всё добавлю одним махом». А «потом» наступает тогда, когда уже весь проект завален хардкодом, и вычищать его - то еще удовольствие. Даже нейросетки с такими запросами помогают не с первого раза, и с сомнительной эффективностью.</p><p>Нутром чуял - флоу неправильный. В итоге я пришел к тому, что называю идеальной локализацией.</p><h2>Эволюция лени: почему Enum победил интерфейсы</h2><p>Я начал мучить нейросеть разными вариантами реализации. Для меня в первую очередь был важен флоу работы: мне было тупо лень писать больше одной строки кода, чтобы добавить переменную.</p><p>Моя философия проста: строку захардкодить - моментально. Добавление даже одной строки в другом файле требует доп. действий. НО, если действий минимум, то кодер поймет, что выигрыш во времени сейчас мизерный против больших потерь в будущем, и исправно добавит строку в правильное место. Этого не произойдет, если для добавления строки нужно «отчитаться» в десяти местах.</p><h2>Попытка №4. Рекорды (Records)</h2><p>Присматривался к рекордам. С ними удобно: не нужно писать конструкторы. Но есть подвох: как только ты добавил переменную в один язык, компилятор тут же сходит с ума и требует добавить её во все остальные прямо сейчас. Никакой гибкости и возможности оставить «на потом».</p><h2>Идеальный костыль: Enum</h2><p>В итоге я пришел к самому, казалось бы, «неправильному» способу, который оказался идеальным. Enum. Само название намекает на перечисления и цифры, но оказалось, что хранить в нем буквы и целые фразы - это лучший путь для локализации.</p><p>Знаете, мне моё решение так понравилось, что я пошел к нейросетям и проверил его со всех сторон. Все модели  остались в полном восторге. Под это дело я даже подготовил монументальную «нейро-статью» на полтора часа внимательного чтения, со всеми графиками, бенчмарками и анализом производительности.</p><p>Но потом я заглянул в правила Хабра, прислушался к голосу разума и понял: никто не хочет читать полтора часа сухой статистики. Лучше я просто расскажу вам свою историю «от первого лица», как я докатился до такой жизни. Ну, а если вы совсем уж фанаты цифр - просто скормите этот текст любой нейронке, она вам перескажет всё в лучших академических тонах с графиками на любой вкус.</p><p>А здесь мы будем говорить по делу.</p><p>Ниже я выкатываю сам код. Код тут не для зубрежки, а лишь чтобы указать направление / идею. Самая большая прелесть этой системы в том, что она оставляет гигантское пространство для любого типа реализации. Это архитектурный каркас, который чертовски сложно сломать. Главное — уловить принцип.</p><h2>Реализация</h2><p>Принцип разделения:</p><ul><li>enum Strings → типизированный контракт (что существует).</li><li>translator → источник данных (откуда берётся текст).</li></ul><p>Структура файлов - минимальная. Никаких внешних зависимостей:</p><h2>Ядро - strings.dart</h2><p>Весь контракт локализации в одном enum. Два режима - хардкод switch и серверный кеш - за одним и тем же</p><p>. Даже сообщения об ошибках локализации — сами локализованы:</p><h2>Список языков - languages_enum.dart</h2><p>Каждый язык - самодостаточная единица: знает свой код, название, направление текста и как себя загрузить:</p><p>Хотите грузить с сервера? Одна строка + loader. И</p><p>- тоже одна строка, потому что</p><p>уже является registry:</p><h2>Переводчик - i18n/russian.dart</h2><p>Как это выглядит в жизни (и почему я перестал хардкодить) Я намеренно не привожу здесь код оберток виджетов или конкретных стейт-менеджеров. Всё это - чистая «вкусовщина». Для работы системы нужен лишь элементарный вещатель событий (Notifier), повешенный на метод смены языка.</p><p>Но главное - это мой ежедневный флоу. Сейчас, чтобы добавить строку в UI, я просто вызываю нужный мне ключ: Strings.someKey(). Без контекста, везде.</p><p>А если ключа еще нет? Я тупо иду в Strings и добавляю одну строчку в Enum. Всё.</p><p>Благодаря дефолтному конструктору, приложению абсолютно плевать, что у меня там еще 100 языков не переведены. Оно компилируется и работает здесь и сейчас. А дальше в дело вступают гит-хуки: при комите нейросетка сама подхватывает изменения и заполняет недостающие поля в переводчиках.</p><p>Знаете, какое самое странное чувство? Мне сейчас реально проще и быстрее завести переменную в локализации, чем хардкодить строку в коде. Кажется, это и есть признак здоровой архитектуры - когда делать «правильно» становится физически удобнее, чем делать «быстро» и криво.</p><p>Собственно если в кратце это все о чем я хотел рассказать. Если тема зайдет или кто-то сам не сможет допереть, как прикрутить это к своей архитектуре - пишите в комментариях, разберемся.</p><p>Надеюсь, мой опыт сэкономит вам пару литров нервных клеток. Всех благ и чистого кода без «магических строк»!</p>]]></content:encoded>
    </item>
    <item>
      <title>Claude Opus 4.8: рекордные бенчмарки и дешёвый fast mode</title>
      <link>https://tproger.ru/news/anthropic-vypustila-claude-opus-4-8-s-rekordnymi-benchmarkami-i-d</link>
      <comments>https://tproger.ru/news/anthropic-vypustila-claude-opus-4-8-s-rekordnymi-benchmarkami-i-d?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/anthropic-vypustila-claude-opus-4-8-s-rekordnymi-benchmarkami-i-d</guid>
      <description><![CDATA[<p>Claude Opus 4.8 работает надёжнее в агентных сценариях, честнее оценивает ошибки и предлагает fast mode втрое дешевле. Разбираем ключевые улучшения и цены.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/anthropic-vypustila-claude-opus-4-8-s-rekordnymi-benchmarkami-i-d">Claude Opus 4.8: рекордные бенчмарки и дешёвый fast mode</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Новости]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 29 May 2026 06:16:33 GMT</pubDate>
      <content:encoded><![CDATA[<p>Anthropic обновила флагманскую модель <b>Claude Opus</b> до версии 4.8. Новинка работает надёжнее в агентных сценариях, честнее оценивает собственные ошибки и при этом сохраняет прежнюю цену за токены. Для разработчиков главное новшество — режим fast mode стал втрое дешевле.</p><p>Claude Opus 4.8 — это топовая модель семейства Claude, ориентированная на сложные задачи: программирование, юридический анализ, глубокое исследование и многошаговые рабочие процессы. Версия 4.8 пришла на смену 4.7 и доступна уже сегодня через API и веб-интерфейс claude.ai.</p><p>Claude Opus 4.8 вышел 28 мая 2026 года и заменил версию 4.7 по той же цене.</p><p>Fast mode ускоряет работу в 2,5 раза и стоит втрое меньше, чем раньше.</p><p>Модель показывает рекордные результаты на бенчмарках кодирования, юридических задач и компьютерного использования.</p><p>В Claude Code появились динамические рабочие процессы с сотнями параллельных подагентов.</p><p>Opus 4.8 в 4 раза реже пропускает собственные ошибки в коде, чем предшественник.</p><h2>Что улучшилось</h2><p>По словам Anthropic, ключевое изменение — <b>надёжность в агентных задачах</b>. Ранние тестировщики отмечают, что модель задаёт правильные уточняющие вопросы, замечает неточности в планах и не пытается «продавить» заведомо слабое решение. На бенчмарке <b>Super-Agent</b> Opus 4.8 стал единственной моделью, которая завершила все тестовые сценарии от начала до конца, обойдя GPT-5.5 при равной стоимости.</p><p>В программировании прирост заметен на всех уровнях сложности: по данным <b>CursorBench</b>, вызов инструментов стал эффективнее — модель использует меньше шагов для достижения того же результата. На юридическом бенчмарке <b>Legal Agent Benchmark</b> модель впервые преодолела порог в 10% по стандарту all-pass — показатель, который ранее был недостижим для языковых моделей.</p><p>Ещё один важный аспект — <b>честность</b>. Anthropic специально обучает модели избегать необоснованных заявлений, и в 4.8 этот навык заметно усилился: по внутренним оценкам, модель в четыре раза реже пропускает ошибки в собственном коде без комментариев.</p><h2>Новые функции платформы</h2><p>Вместе с моделью Anthropic выпустила несколько обновлений инфраструктуры:</p><ul><li>Dynamic workflows в Claude Code — возможность запускать сотни параллельных подагентов в одной сессии для масштабных задач вроде миграции кодовой базы.</li><li>Effort control в claude.ai — ползунок, который позволяет выбирать между скоростью и глубиной ответа.</li><li>System entries в Messages API — разработчики теперь могут обновлять системные инструкции прямо в массиве сообщений, не прерывая кеш подсказок.</li></ul><h2>Цены и доступность</h2><p>Обычный режим стоит прежние <b>5 долларов за миллион входных токенов</b> и <b>25 долларов за миллион выходных</b>. Fast mode — <b>10 и 50 долларов</b> соответственно, что втрое ниже, чем у предыдущих версий. Модель доступна через Claude API под именем claude-opus-4-8.</p><h2>Выводы</h2><p>Основные улучшения Claude Opus 4.8 сосредоточены вокруг надёжности агентных задач и честности модели. Для разработчиков это означает, что Claude Code станет более самостоятельным инструментом, способным вести масштабные проекты с меньшим контролем со стороны человека. Снижение цен на fast mode делает флагманскую модель более доступной для задач, где важна скорость.</p><p>В ближайшие недели Anthropic планирует выпустить семейство <b>Mythos</b> — модели ещё более высокого интеллектуального уровня, чем Opus. Они уже проходят тестирование в рамках проекта Glasswing, но для массового запуска требуются дополнительные кибербезопасные меры.</p><p>Источник: <a href="https://www.anthropic.com/news/claude-opus-4-8">Anthropic — Introducing Claude Opus 4.8</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Скрытый сбой идемпотентности в финтех-системе: разбор инцидента</title>
      <link>https://tproger.ru/articles/skrytyj-sboj-idempotentnosti-v-finteh-sisteme-razbor-incidenta</link>
      <comments>https://tproger.ru/articles/skrytyj-sboj-idempotentnosti-v-finteh-sisteme-razbor-incidenta?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Дмитрий Москалюк]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/skrytyj-sboj-idempotentnosti-v-finteh-sisteme-razbor-incidenta</guid>
      <description><![CDATA[<p>Разбор реального production-инцидента в финтех-системе: почему ошибка HTTP 500 не остановила операцию создания карты и как сбой идемпотентности в API Gateway вызвал массовые дубликаты. Практический кейс о микросервисной архитектуре, distributed systems, request-id, API idempotency и техническом долге.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/skrytyj-sboj-idempotentnosti-v-finteh-sisteme-razbor-incidenta">Скрытый сбой идемпотентности в финтех-системе: разбор инцидента</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Рефакторинг]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Финтех]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[faq]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 18 May 2026 04:55:17 GMT</pubDate>
      <content:encoded><![CDATA[<h2>Как все началось</h2><p>Всё началось с безобидного, почти рутинного тикета в саппорт:</p><p><i>«У меня тут несколько одинаковых карт создалось. Я вроде один раз нажимал, а их штук пять висит в приложении». </i></p><p>Для финтеха подобная фраза — не мелкая UI-аномалия, а сигнал тревоги высшего уровня. Когда речь идёт о платёжных инструментах, дубль сущности мгновенно переходит из разряда «странностей» в категорию «полноценный инцидент».</p><p>Поначалу казалось, что это просто один случай. Но на самом деле, проблема уже какое-то время была, хоть и скрытно: люди получали дубликаты своих банковских карт, но массово на это никто не жаловался. На уровне первой линии поддержки это ошибочно классифицировали как пользовательские ошибки</p><p>Настоящий шум поднялся не внутри компании, а уже в соцсетях. Один из клиентов выложил пост. Там была фотография посылки, а в ней — примерно сотня одинаковых карт. Пост очень быстро стал популярным, и вот тогда-то и возникли проблемы с репутацией, а команда разработчиков только тогда и узнала о случившемся. И особенно тревожно это звучало на фоне того, что мы считали что таких проблем быть не может - ведь считалось, что у  нас глобальная идемпотентность на все запросы.</p><p>Мы начали разбираться. Стандартный мониторинг показывал норму: дашборды зелёные, в логах тихо, метрики CPU и памяти без отклонений. При этом в базе обнаруживались дубликаты, которых быть не должно. И только тогда, когда мы внимательно посмотрели на коммунальный API Gateway, то поняли что одно изменение от другой команды поменяло идемпотентность работы endpoint-а.</p><p>Проблема была структурно невидима для тех, кто находился ближе всего к ней. Отсутствие видимой проблемы не равно отсутствию риска — система просто ждала подходящего момента.</p><h2>Что произошло: хронология инцидента</h2><p>Архитектура была классической: Клиент → API Gateway → микросервисы,.</p><p>Сценарий развивался почти незаметно для стандартных средств наблюдения:</p><p>1. Фронтенд: Пользователь нажимает кнопку «Выпустить карту».</p><p>2. Gateway: Запрос начинает обрабатываться в API Gateway.</p><p>3. Микросервис по созданию карт: честно выполняет работу: создаёт запись в БД и возвращает `200 OK` в Gateway.</p><p>4. Новый микросервис: API Gateway вызывает новый микросервис и получает HTTP 500 в ответ от него. Исключение возникает уже после успешного вызова нашего микросервиса, и это ключевая точка разрыва: Gateway считает весь запрос неудавшимся, а ответ нашего микросервиса теряется.</p><p>5. Клиент: получает HTTP 500</p><p>6. Реакция: Пользователь видит красную плашку ошибки и логично решает: «Не сработало, пробую снова». Более того, с точки зрения протокола HTTP - запросы, в ответ на которые пришла ошибка HTTP 500, можно пытаться отправлять опять.</p><p>7. Петля: Микросервис, ничего не зная о судьбе предыдущих ответов, послушно создавал карту за картой.</p><p>Круг замкнулся. Эпидемия началась.</p><p>В компании такого уровня это не было предусмотрено. И это такая обидная ошибка.</p><h2>Как так получилось?</h2><p>Вскрылось ошибочное предположение:</p><p><i>«В API Gateway вызов микросервиса создания карт всегда идет последним». </i></p><p>Таким образом идемпотентность достигалась «формально» - ведь если создание карты завершалось с ошибкой - это точно означало что и вызов API Gateway тоже завершится с ошибкой. Сработало ложное чувство безопасности.</p><p>Ответ на вопрос “почему так было сделано?” очень простой - это было осознанное упрощение на старте. Все знали об этом, но задача на фикс потерялась в недрах бэклога на очень долгое время. Это классический пример того, как архитектурное допущение и отложенный рефакторинг годами живут в проде, пока их не вскрывает редкая последовательность отказов.-</p><h2>Что потребовалось изменить</h2><p>Пришлось в срочном порядке внедрять полноценный механизм идемпотентности по request-id, который не зависел бы от порядка вызова downstream-сервисов. И это было достаточно тяжело, потому что окно для легкого внедрения закрывается в первый день продакшена: до этого момента нет ни живых пользователей, ни накопленных данных, ни клиентов старых версий, с которыми нужно сохранять обратную совместимость. Ниже — ответы на вопросы, которые мы получили от коллег, когда разбирали этот инцидент.</p><h2>FAQ: Часто задаваемые вопросы</h2><p><b>1. Почему нельзя просто заблокировать кнопку на фронте?</b></p><p>Блокировка кнопки решает проблему только при стабильной сети. Если запрос ушёл, сервер создал сущность, но ответ потерялся — кнопка разблокируется по таймауту, и пользователь нажмёт снова. Это не устраняет корневую причину, а лишь слегка снижает вероятность дубля.</p><p><b>2. Чем идемпотентность отличается от дедупликации в БД?</b></p><p>Дедупликация через уникальные индексы защищает от дублей в хранилище, но не решает проблему сайд-эффектов: повторный запрос всё равно вызовет отправку SMS, печать банковской карты, генерацию событий в шине или списание средств. Идемпотентность гарантирует, что вся цепочка выполнится ровно один раз — включая все внешние вызовы и побочные действия.</p><p><b>3. Как долго хранить ключи идемпотентности?</b></p><p>На практике мы хранили ключи в основной базе данных без ограничения срока — затраты на хранение UUID по всем сущностям оказались небольшими. В общем случае минимальный срок зависит от конкретных сценариев использования — кому-то хватит и  часа, а кому-то нужна неделя. В любом случае, окна должно быть достаточно, чтобы покрыть сценарии, когда пользователь возвращается к повтору запроса, например, на следующий день или когда клиентское приложение автоматически перезапускает отложенные запросы после восстановления сети. Бессрочное хранение не обязательно, но слишком короткий TTL создаёт риск дублей при длительных сетевых проблемах.</p><p><b>4. Что делать со старыми клиентами, которые не шлют request_id?</b></p><p>Мы сделали несколько версий API для создания карт — под разные версии приложения. Для новых клиентов работала полноценная идемпотентность с клиентским ключом. Для старых версий приходилось принимать риски и генерировать request_id на стороне сервера. Альтернативой может быть хэширование payload запроса, но это менее надежно и сложнее: таймстемпы и случайные поля могут отличаться от вызова к вызову. Поэтому мы выбрали  подход с генерацией ключа на сервере для устаревших клиентов: риски дублей на переходный период оказались меньше, чем сложность поддержки двух схем валидации одновременно.</p><p><b>5. Обязательно ли делать идемпотентность для всех методов API?</b></p><p>Идемпотентность требуется только для методов, которые изменяют состояние системы — POST, PUT, PATCH и иногда DELETE. Методы чтения (GET, HEAD, OPTIONS) не изменяют данные, поэтому считаются идемпотентными по умолчанию.</p><p><b>6. Как понять, что в вашей системе уже есть скрытая проблема с дублями?</b></p><p>Лучший способ — ввести метрики превентивно, не дожидаясь жалоб пользователей. Отслеживайте количество повторных вызовов с одинаковым ключом идемпотентности и сравнивайте его с общим числом запросов. Если метрики уже показывают ненулевое значение — проблема есть, даже если внешне всё работает незаметно.</p><p>Если метрик ещё нет, вот три косвенных признака, которые помогут заподозрить неладное:</p><ul><li>В базе данных периодически появляются записи с одинаковым содержимым, созданные с разницей в несколько секунд.</li><li>Пользователи жалуются на дубликаты карт, заказов или платежей, но вы не можете воспроизвести проблему локально, списываете на то, что пользователи что-то делают не так</li><li>В логах API Gateway периодически всплывают HTTP 500 ошибки, но downstream-сервисы при этом отрабатывают успешно.</li></ul><p>Если заметили хотя бы один из этих симптомов — простого решения уже не будет. Однако остаётся возможность исправить ситуацию до того, как проблему заметят пользователи. В нашем случае дубли проявлялись редко и стали массовыми только при повышении нагрузки. Если отложить решение, скрытая проблема перейдет на уровень, где её последствия станут заметны снаружи и потребуют значительно больших усилий.</p><h2>Итог</h2><p>Главный урок, который мы вынесли: идемпотентность — это общая ответственность всех команд разработки, и поломать её может быть проще, чем кажется. А добавить в уже работающую систему быстро и дёшево — почти невозможно.</p><p>Метрик на всплески повторных запросов у нас не было. А зря — это самый дешёвый способ увидеть проблему до того, как она обрушит продакшен. Системы, спроектированные на 10% нагрузки, ломаются на 60% — и обычно это становится неожиданностью для команды.</p><h2>Практический чек-лист: что проверить в своей системе уже сегодня</h2><ul><li>Убедитесь, что все критические мутирующие эндпоинты поддерживают ключ идемпотентности.</li><li>Настройте алерты на аномальное количество запросов на создание сущностей от одного пользователя за короткий промежуток времени.</li><li>Проверьте, как ваш API Gateway обрабатывает ошибки — не теряет ли он ответы downstream-сервисов.</li><li>Убедитесь, что фронтенд корректно обрабатывает не только 200, но и 500, 502, 504, не провоцируя пользователя на повторные клики без необходимости.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Как построить API-интеграцию оплаты для цифровых ключей и игровых сервисов</title>
      <link>https://tproger.ru/articles/kak-postroit-api-integraciyu-oplaty-dlya-cifrovyh-klyuchej-i-igrovy</link>
      <comments>https://tproger.ru/articles/kak-postroit-api-integraciyu-oplaty-dlya-cifrovyh-klyuchej-i-igrovy?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-postroit-api-integraciyu-oplaty-dlya-cifrovyh-klyuchej-i-igrovy</guid>
      <description><![CDATA[<p>Как построить API-интеграцию оплаты для цифровых ключей и игровых сервисов. Автоматизация платежей, пополнение Steam, выбор API-партнера и масштабирование магазина.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-postroit-api-integraciyu-oplaty-dlya-cifrovyh-klyuchej-i-igrovy">Как построить API-интеграцию оплаты для цифровых ключей и игровых сервисов</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Xbox]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[PlayStation]]></category>
      <category><![CDATA[Discord]]></category>
      <category><![CDATA[Epic Games]]></category>
      <category><![CDATA[Steam]]></category>
      <category><![CDATA[Инфраструктура]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 15 May 2026 04:43:34 GMT</pubDate>
      <content:encoded><![CDATA[<p>Рынок цифровых товаров за последние несколько лет вырос в полноценную инфраструктурную индустрию. Продажа игровых ключей, внутриигровой валюты, подписок и пополнений кошельков давно перестала быть «серой нишей» и превратилась в высококонкурентный сегмент e-commerce с миллионами транзакций ежедневно. Steam, PlayStation, Xbox, Nintendo, Epic Games, Discord Nitro, Game Pass — пользователи привыкли получать цифровой продукт мгновенно, без задержек и ручной обработки.</p><p>Для владельцев маркетплейсов, игровых магазинов и сервисов автоматизация оплаты сегодня становится не преимуществом, а обязательным условием масштабирования. Именно поэтому API-интеграции для цифровых платежей и автоматического пополнения игровых сервисов стали ключевым технологическим инструментом в индустрии.</p><h2>Почему ручная обработка больше не работает</h2><p>Большинство начинающих проектов стартуют одинаково: оператор вручную проверяет оплату, подтверждает заказ и отправляет ключ или проводит пополнение аккаунта. Пока заказов немного — схема кажется рабочей. Но после роста трафика начинаются проблемы:</p><ul><li>задержки обработки;</li><li>ошибки операторов;</li><li>потеря заказов;</li><li>возвраты из-за долгого подтверждения;</li><li>невозможность работать 24/7;</li><li>высокий риск мошенничества.</li></ul><p>В сегменте цифровых товаров пользователь ожидает моментальную выдачу. Если пополнение Steam занимает не секунды, а минуты — конверсия падает. Особенно в периоды распродаж, релизов крупных игр и сезонных акций.</p><p>Именно поэтому современные площадки переходят на автоматизированную архитектуру: платежный шлюз + API поставщика цифровых услуг + система мгновенной обработки заказов.</p><h2>Почему бизнес выбирает GGPay</h2><p>На фоне растущего рынка особое внимание получают сервисы, которые совмещают удобный API, стабильную инфраструктуру и понятную финансовую модель.</p><p>Одним из таких решений сегодня является<a href="https://ggpay.gg/steam?utm_id=928fe578" rel="follow"> GGPAY</a> — сервис для пополнения Steam и других цифровых платформ с поддержкой автоматизированной обработки платежей.</p><p>Платформа ориентирована как на конечных пользователей, так и на владельцев цифровых магазинов, маркетплейсов и игровых сервисов. Среди ключевых преимуществ:</p><ul><li>стабильная работа API;</li><li>автоматическое проведение платежей;</li><li>поддержка популярных способов оплаты;</li><li>низкие комиссии;</li><li>высокая скорость зачисления;</li><li>работа 24/7;</li><li>удобная интеграция для сайтов и Telegram-проектов.</li></ul><p>Для владельцев цифровых площадок особенно важно, что подобные сервисы позволяют быстро запускать автоматизированную продажу без необходимости строить собственную сложную платежную инфраструктуру с нуля.</p><h2>Как устроена API-интеграция цифровых платежей</h2><p>С технической точки зрения система выглядит достаточно просто, хотя внутри скрывается сложная логика маршрутизации и проверки транзакций.</p><p>Типовой процесс выглядит следующим образом:</p><ol><li>Пользователь выбирает цифровой товар или пополнение.</li><li>Сайт формирует заказ.</li><li>Платежный шлюз принимает оплату.</li><li>После подтверждения транзакции сервер обращается к API поставщика.</li><li>API выполняет пополнение или выдает цифровой ключ.</li><li>Клиент получает результат автоматически.</li></ol><p>Подобная модель давно используется в международной игровой индустрии и интегрируется через REST API, callback-уведомления и защищенные webhook-системы.</p><p>Главное преимущество такой схемы — отсутствие ручной обработки. Бизнес получает возможность масштабироваться практически без увеличения штата.</p><h2>Какие задачи решает API для цифровых товаров</h2><p>Современные API-платформы позволяют автоматизировать практически весь цикл продажи:</p><ul><li>пополнение Steam;</li><li>продажу игровых ключей;</li><li>выдачу gift card;</li><li>оплату подписок;</li><li>работу с региональными балансами;</li><li>массовую обработку заказов;</li><li>автоматический возврат;</li><li>мониторинг статусов транзакций;</li><li>защиту от дублирования платежей.</li></ul><p>Для крупных площадок особенно важна возможность работать с несколькими поставщиками одновременно. Это позволяет распределять нагрузку, снижать комиссии и поддерживать стабильность даже во время пикового спроса.</p><h2>На что обращать внимание при выборе API-партнера</h2><p>Ошибка многих проектов — выбор поставщика исключительно по размеру комиссии. На практике стабильность API намного важнее разницы в 1–2%.</p><p>При выборе сервиса необходимо оценивать:</p><h3>1. Скорость обработки</h3><p>Для игровых сервисов критична мгновенная выдача. Пользователь не готов ждать 10–15 минут после оплаты.</p><h3>2. Аптайм инфраструктуры</h3><p>Если API регулярно падает во время крупных распродаж Steam — бизнес теряет деньги и репутацию.</p><h3>3. Наличие webhook и callback-систем</h3><p>Это основа автоматизации статусов платежей.</p><h3>4. Документация</h3><p>Качественная документация сокращает время интеграции в разы.</p><h3>5. Поддержка популярных способов оплаты</h3><p>СБП, банковские карты, криптовалюты, электронные кошельки — современный рынок требует гибкости.</p><h3>6. Защита от мошенничества</h3><p>Антифрод-механизмы и валидация заказов особенно важны в сегменте цифровых товаров.</p><h2>Почему рынок активно переходит на автоматические пополнения Steam</h2><p>Steam остается крупнейшей игровой платформой мира, а пополнение кошелька — одним из самых востребованных цифровых продуктов в СНГ и Восточной Европе.</p><p>После изменений в международной платежной инфраструктуре спрос на альтернативные способы пополнения вырос кратно. На этом фоне появились специализированные сервисы, работающие через API-интеграции и автоматические платежные шлюзы.</p><p>Сегодня пользователи ожидают:</p><ul><li>низкую комиссию;</li><li>мгновенное зачисление;</li><li>стабильную работу;</li><li>поддержку разных регионов;</li><li>прозрачный курс конвертации;</li><li>отсутствие ручных подтверждений.</li></ul><p>Именно поэтому автоматизированные сервисы показывают значительно более высокую конверсию по сравнению с полуавтоматическими решениями.</p><h2>Как выглядит современная архитектура цифрового магазина</h2><p>Профессиональная инфраструктура обычно включает несколько уровней:</p><ul><li>frontend магазина;</li><li>платежный шлюз;</li><li>сервер обработки заказов;</li><li>API-поставщик цифровых товаров;</li><li>систему логирования;</li><li>антифрод-модуль;</li><li>резервные каналы оплаты.</li></ul><p>Дополнительно многие проекты подключают аналитические сервисы, отслеживающие:</p><ul><li>процент успешных транзакций;</li><li>скорость выдачи;</li><li>причины отказов;</li><li>нагрузку по регионам;</li><li>эффективность платежных методов.</li></ul><p>Такой подход позволяет масштабировать платформу практически без ограничений.</p><h2>Какие технологии будут доминировать дальше</h2><p>Рынок цифровых платежей продолжит двигаться в сторону полной автоматизации. Уже сейчас активно развиваются:</p><ul><li>direct top-up через Steam ID;</li><li>мультивалютные API;</li><li>криптовалютные расчеты;</li><li>AI-антифрод;</li><li>распределенные платежные системы;</li><li>автоматические системы маршрутизации транзакций.</li></ul><p>При этом требования пользователей становятся только жестче: скорость, надежность и прозрачность превращаются в стандарт индустрии.</p><h2>Заключение</h2><p>API-интеграция оплаты для цифровых ключей и игровых сервисов — это уже не дополнительная функция, а фундамент современного digital-бизнеса. Автоматизация позволяет масштабировать продажи, снижать издержки, минимизировать ошибки и обеспечивать мгновенную выдачу цифрового товара.</p><p>Именно поэтому проекты, работающие в сегменте игровых пополнений и цифровых товаров, всё чаще выбирают готовые инфраструктурные решения вместо ручной обработки заказов.</p><p>А сервисы вроде GGPAY становятся частью новой экосистемы цифровых платежей, где скорость обработки, стабильность API и удобство пользователя напрямую влияют на рост бизнеса и удержание аудитории.</p><p><i>Реклама. Рекламодатель: ОсОО «НОВАПЭЙ», ИНН:9909710276, erid: 2SDnjf2S7a2</i></p>]]></content:encoded>
    </item>
    <item>
      <title>Что такое REST API и почему ваш — вероятно, не REST</title>
      <link>https://tproger.ru/translations/chto-takoe-rest-api-i-pochemu-vaw-veroyatno-ne-rest</link>
      <comments>https://tproger.ru/translations/chto-takoe-rest-api-i-pochemu-vaw-veroyatno-ne-rest?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/chto-takoe-rest-api-i-pochemu-vaw-veroyatno-ne-rest</guid>
      <description><![CDATA[<p>6 ограничений Филдинга и почему большинство JSON API соответствуют лишь 2–3 из них. Проверьте, сколько из них выполняет ваш API — с примерами кода.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/chto-takoe-rest-api-i-pochemu-vaw-veroyatno-ne-rest">Что такое REST API и почему ваш — вероятно, не REST</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Лучшая практика]]></category>
      <category><![CDATA[Паттерны проектирования]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 14 May 2026 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Большинство разработчиков хотя бы раз строили «REST API». Мало кто читал диссертацию, которая его определяет. Этот разрыв между популярным пониманием и оригинальной спецификацией порождает повторяющиеся архитектурные проблемы и нестабильность API.</p><p>REST API — это веб-сервис, удовлетворяющий шести архитектурным ограничениям, выведенным Роем Филдингом в докторской диссертации «Architectural Styles and the Design of Network-based Software Architectures» (UC Irvine, 2000 год). Начав с «нулевого стиля» — пустого набора без ограничений — Филдинг добавлял каждое из них последовательно, анализируя порождаемые ими свойства распределённых гипермедиа-систем (систем, где переходы между состояниями описаны прямо в ответах сервера). Результат получил название «Передача репрезентативного состояния» (Representational State Transfer).</p><p>Индустрия взяла название и проигнорировала большинство ограничений. «REST» теперь означает «любой API, который отправляет JSON по HTTP». Если вы строите публичный API или API для команд за пределами вашей организации — пропущенные ограничения начинают стоить денег.</p><p>REST — это шесть архитектурных ограничений, сформулированных Роем Филдингом в 2000 году, а не «любой JSON-over-HTTP API».</p><p>Большинство API выполняют лишь 2–3 ограничения из шести: клиент-сервер, stateless и частично слоистую систему.</p><p>Самое игнорируемое ограничение — HATEOAS: сервер передаёт клиенту список доступных действий прямо в ответе.</p><p>HATEOAS решает три дорогостоящие проблемы: пагинацию, версионирование API и обнаруживаемость ресурсов.</p><p>Для небольшой команды с одним потребителем пропуск HATEOAS оправдан. Для публичного API — нет.</p><h2>Шесть ограничений REST API: разбор по порядку</h2><h3>Ограничение 1: Клиент-сервер</h3><p>Клиент и сервер имеют разные зоны ответственности. Клиент отвечает за интерфейс, сервер — за данные и логику. Большинство API справляются с этим по умолчанию. Нарушение появляется, когда сервер начинает диктовать, как клиент должен <i>отображать</i> информацию.</p><p>Например, если API возвращает displayOrder: 3 и buttonColor: "#ff0000" для какого-либо действия — это нарушение. Порядок отображения должен следовать из позиции элементов в ответе. Цвет должен определяться семантическим свойством вроде class: ["danger"], которое каждый клиент интерпретирует самостоятельно.</p><h3>Ограничение 2: Stateless (без состояния)</h3><p>Каждый запрос содержит всю информацию, необходимую серверу для его обработки. Сервер не хранит состояние сессии между вызовами.</p><p>Если вы отправляете GET /path-1 с сессионной cookie, и сервер ищет её в памяти, чтобы получить ваш ID пользователя — это серверное состояние. Stateless-версия включает ID прямо в запрос: JWT или тело POST-запроса переносят его вместе с запросом и могут вернуть в ответе для повторного использования клиентом.</p><h3>Ограничение 3: Кэшируемость</h3><p>Ответы должны быть явно или неявно помечены как кэшируемые или некэшируемые. Клиент или промежуточный узел может повторно использовать закэшированные ответы, не обращаясь к серверу. Филдинг рассматривал кэшируемость как архитектурную задачу первого класса, повышающую эффективность и воспринимаемую производительность за счёт снижения средней задержки.</p><p>Большинство JSON API полностью игнорируют кэширование. Вы отправляете GET /articles/42, а в ответе нет ни Cache-Control, ни ETag, ни Last-Modified. Клиент обращается к серверу каждый раз, даже если статья не менялась неделями.</p><h3>Ограничение 4: Единый интерфейс (Uniform Interface)</h3><p>Это главное ограничение. Филдинг разбил его на четыре подограничения — три описываются ниже, четвёртое (HATEOAS) вынесено в отдельный раздел из-за его значимости.</p><p><b>4.1 URI идентифицируют ресурсы.</b> Единообразие здесь — это сама спецификация URI: схема, authority, путь, запрос, фрагмент. Ограничение ничего не говорит о структуре сегмента пути: /articles/42, /x?id=42 и /a/b/c — всё это валидные URI. «Используйте чистые URL-пути» — популярное соглашение и хороший SEO-инструмент, но не то, что требует Филдинг.</p><p><b>4.2 Управление ресурсами через представления.</b> Вы выполняете GET в /whatever, чтобы получить представление ресурса. Заголовок Content-Type сообщает серверу формат тела запроса. Заголовок Accept сообщает, какие медиатипы (форматы обмена данными) поддерживает клиент для ответа.</p><p><b>4.3 Самоописывающие сообщения.</b> Ответ с Content-Type: application/vnd.collection+json сообщает клиенту, как разбирать тело, без каких-либо предположений.</p><h3>Ограничение 4.4: HATEOAS — то, что пропускают почти все</h3><p>HATEOAS (Hypermedia As The Engine Of Application State) — четвёртое подограничение Uniform Interface. С первыми тремя большинство API справляются. HATEOAS — место, где останавливается почти каждый.</p><p>Разница хорошо видна на примере API для списка чтения. Без HATEOAS вы получаете просто данные, похожие на запись в базе:</p><p>Клиент ничего не знает о том, что он может сделать дальше. Чтобы отметить статью как прочитанную, клиент уже должен знать endpoint: PATCH /articles/42 с {"status": "read"}. Разработчик захардкодил эти знания, прочитав документацию. Сам API их не сообщил.</p><p>С HATEOAS сервер сообщает клиенту о доступных действиях в стандартизированном виде. Вот тот же ответ с использованием <a href="https://github.com/kevinswiber/siren">Siren</a> — одного из стандартизированных медиатипов для гипермедиа-API:</p><p>Клиент не хардкодит URL и HTTP-методы. Массив actions сообщает, что можно сделать. Навигация приходит из links. Если статья уже прочитана — сервер исключает действие mark-as-read из ответа. Кнопка исчезает в UI. Без единого условного выражения в клиентском коде.</p><p>Сервер добавляет новое действие — и каждый клиент подхватывает его при следующем запросе, без деплоя. Это принципиальное отличие: сервер управляет доступными переходами состояния.</p><h3>Ограничение 5: Слоистая система</h3><p>Клиент не может определить, общается ли он с конечным сервером или с промежуточным узлом. Балансировщики нагрузки, CDN и API-шлюзы должны быть прозрачны для вызывающей стороны. Большинство API выполняют это ограничение автоматически. Самый распространённый вид нарушения — когда сообщения об ошибках раскрывают имя хоста бэкенд-сервиса, тем самым нарушая прозрачность слоёв.</p><h3>Ограничение 6: Код по требованию (необязательное)</h3><p>Сервер может передавать исполняемый код клиенту. Думайте о JavaScript, подключаемом через тег &lt;script&gt; на веб-странице. Для API это ограничение почти не применимо. Филдинг сделал его единственным необязательным.</p><h2>Что HATEOAS решает на практике</h2><p>Филдинг разработал HATEOAS для решения тех самых проблем, с которыми API-команды сейчас борются вручную, многократно и каждый раз по-разному.</p><h3>Пагинация</h3><p>Без HATEOAS каждый API изобретает собственную схему. Один использует page и pageSize. Другой — offset и limit. Третий — токены на основе курсора. С HATEOAS сервер включает ссылку с отношением «следующая страница». Клиент следует этому отношению. Схема пагинации может измениться, не сломав ни одного клиента: клиент не знал деталей схемы и не знает формата URL.</p><h3>Версионирование</h3><p>Без HATEOAS команды версионируют API через URL-пути (/v1/, /v2/) или кастомные заголовки вроде X-API-Version. Поддержка нескольких версий занимает месяцы, клиенты привязываются к версии и ломаются при её выводе из эксплуатации. С HATEOAS сервер вводит новые действия, добавляя ссылки. Старые ссылки продолжают работать.</p><h3>Обнаруживаемость</h3><p>Без HATEOAS первый шаг разработчика — чтение Swagger-документации, второй — хардкодинг каждого endpoint в клиент. С HATEOAS корень API возвращает ссылки на все доступные ресурсы. Клиент исследует API так же, как браузер исследует веб-сайт.</p><h2>Сколько ограничений выполняет ваш API</h2><p>Итого шесть ограничений. Большинство API удовлетворяют двум-трём: клиент-сервер, слоистую систему и частичную безгосударственность. Большинство нарушают кэшируемость по умолчанию. Большинство полностью игнорируют HATEOAS.</p><ul><li><b>Клиент-сервер</b> — разделение ответственности за интерфейс и данные</li><li><b>Stateless</b> — каждый запрос самодостаточен, без серверных сессий</li><li><b>Кэшируемость</b> — явные заголовки Cache-Control, ETag, Last-Modified</li><li><b>Единый интерфейс</b> — URI, представления, самоописывающие сообщения и HATEOAS</li><li><b>Слоистая система</b> — прозрачность промежуточных узлов</li><li><b>Код по требованию</b> — опционально, для API почти не применимо</li></ul><p>Это не оценка. Это карта компромиссов, которые вы приняли — намеренно или случайно. Для небольшой команды с одним потребителем и Slack-каналом для координации пропуск HATEOAS оправдан. Публичный API с сотнями потребителей платит за каждый пропущенный раунд миграции версий. Подробнее об эволюции REST-архитектуры — в <a href="https://ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm">главе 5 диссертации Филдинга</a>.</p><h2>Выводы</h2><blockquote>Я разочарован тем, что многие не знакомы с 15-летними исследованиями в области гипермедиа, которые стоят за REST. Большинство так называемых REST API — это просто удалённые вызовы процедур через HTTP.</blockquote><p>Пройдитесь по шести ограничениям и посчитайте, сколько из них выполняет ваш API. Это даст не оценку, а карту принятых компромиссов — осознанных или случайных. Упражнение отвечает на один вопрос: ваш API — это Representational State Transfer или просто HTTP-транспорт, закрытый для расширения?</p><p>Оригинальная статья: <a href="https://fagnerbrack.com/what-is-a-rest-api-and-why-yours-probably-isnt-one-7e5fb65ece4d">Fagner Brack — What Is a REST API, and Why Yours Probably Isn't One</a>. Первоисточник: <a href="https://ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm">Глава 5 диссертации Роя Филдинга, UC Irvine</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как подключить общую память к Claude Code и Cursor за 5 минут</title>
      <link>https://tproger.ru/articles/kak-podklyuchit-obshhuyu-pamyat-k-claude-code-i-cursor-za-5-minut</link>
      <comments>https://tproger.ru/articles/kak-podklyuchit-obshhuyu-pamyat-k-claude-code-i-cursor-za-5-minut?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[C0Ally]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-podklyuchit-obshhuyu-pamyat-k-claude-code-i-cursor-za-5-minut</guid>
      <description><![CDATA[<p>Как подключить общую память к Claude Code и Cursor за 5 минут, общая shared память для ИИ-агентов. Общий контекст и экономия ресурсов. CoAlly</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-podklyuchit-obshhuyu-pamyat-k-claude-code-i-cursor-za-5-minut">Как подключить общую память к Claude Code и Cursor за 5 минут</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Рефакторинг]]></category>
      <category><![CDATA[Slack]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 09 May 2026 07:40:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Работаю с Claude Code и Cursor параллельно. Claude Code хорош для архитектурных задач и рефакторинга, Cursor - для быстрого редактирования и code review. Проблема одна: они друг про друга ничего не знают. И даже при выполнении задач в одной среде разработки через пару дней уже и не вспомнишь что решил, почему, приходится опять просить агента изучить контекст и разобраться чтобы получить нужную информацию. Это время и токены.</p><p>Сделал себе инструмент, который это решает. Потом оформил в продукт. Называется <b>CoAlly</b> - сервер, который дает агентам общую память.</p><h2>Что он делает</h2><p>Агент автоматически сохраняет контекст работы: какие решения принял, какие файлы затронул, почему сделал так, а не иначе. Когда другой агент (или тот же, но в новой сессии) берется за связанную задачу, он находит этот контекст через семантический поиск.</p><p>Запрос "проблемы с авторизацией" найдет запись про "token refresh rotation", хотя слова совершенно разные. Работает через эмбеддинги и косинусное расстояние, скоро выйдет фича с анализом смысловой корреляции при поиске.</p><h2>Подключение</h2><h2>Шаг 1: регистрация</h2><p>Заходим на <a href="https://coally.cortexally.ai">coally.cortexally.ai</a>, создаем аккаунт. Получаем API ключ.</p><h2>Шаг 2: подключение к агенту (Claude, Cursor и др.)</h2><p>Одна команда в терминале:</p><p>claude mcp add coally-nexus --transport sse https://coally.cortexally.ai/sse --header "Authorization: Bearer ВАШ_КЛЮЧ"</p><p>Перезапускаем Claude Code. В списке MCP-инструментов должен появиться coally-nexus.</p><p><b>Cursor, Windsurf, VSCode</b></p><p>Заходим в настройки Cursor -&gt; Settings -&gt; MCP -&gt; Settings (значок шестеренки) или создаем/редактируем файл `.cursor/mcp.json` в корне проекта (или в домашней директории для глобального подключения):</p><p>Файл `~/.codeium/windsurf/mcp_config.json` для Windsurf или соответствующее меню для VSCode и других его форков.</p><p>Перезапускаем IDE|Agent. Готово.</p><h2>Первая сессия</h2><p>После подключения агент при первом взаимодействии проиндексирует проект автоматически. Если нет - попросите: "<i>проиндексируй этот проект через CoAlly</i>".</p><p>Что происходит при индексации: сканируется дерево проекта, находятся конфиги, важные воспоминания, memorybanks и др., все это эмбеддится и сохраняется как контекст.</p><p>Дальше агент сам начнет сохранять контекст работы после значимых изменений. Если нужно явно сохранить что-то: "<i>сохрани контекст этой задачи в CoAlly</i>".</p><h2>Что получаем</h2><p>На вопрос "<i>что вчера делали по задаче авторизации? какой статус бага с токеном и сколько времени потребуется на доработку</i>" Агент достает из <b>CoAlly</b> записи: "<i>вчера в Cursor поправили ротацию токенов, причина была в TTL, затронули два файла. Могу сразу продолжить и на основе коммитов ... исправить точечно флоу, время на исправление — N минут.</i>"</p><p>Если работаете в команде - еще полезнее. Контекст коллеги тоже доступен. Его экспертиза и навыки также постепенно приобретают цифровую версию. Не нужно ждать стендап или писать в Slack.</p><p><b>Ограничения</b></p><p>Агенты иногда игнорируют инструкции и не сохраняют контекст. Бывает. Можно просить явно.</p><p>Семантический поиск хорош, но не идеален. Если запрос слишком общий ("что нового?"), результаты будут размытыми. Конкретные вопросы работают лучше.</p><p>Бесплатный тариф - 2 проекта. Для личного использования хватает. Для команд - тарифы Team и Enterprise.</p>]]></content:encoded>
    </item>
    <item>
      <title>Addy Osmani зашил сениор-инженерную дисциплину в скиллы для AI-агентов</title>
      <link>https://tproger.ru/news/addy-osmani-zawil-senior-inzhenernuyu-disciplinu-v-skilly-dlya-ai-a</link>
      <comments>https://tproger.ru/news/addy-osmani-zawil-senior-inzhenernuyu-disciplinu-v-skilly-dlya-ai-a?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/addy-osmani-zawil-senior-inzhenernuyu-disciplinu-v-skilly-dlya-ai-a</guid>
      <description><![CDATA[<p>Addy Osmani выложил 20 markdown-навыков, которые заставляют AI-агента писать спеки, тесты, ревью и не пропускать сениорские шаги. Разбираем пять принципов.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/addy-osmani-zawil-senior-inzhenernuyu-disciplinu-v-skilly-dlya-ai-a">Addy Osmani зашил сениор-инженерную дисциплину в скиллы для AI-агентов</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Нейронные сети]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Markdown]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 06 May 2026 09:30:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>AI-агент пишет фичу за минуту, а спецификация, тесты и ревью где-то теряются. Addy Osmani — бывший Engineering Lead Chrome Developer Experience в Google, сейчас Director в Google Cloud AI — собрал на GitHub репозиторий из 20 «навыков», которые заставляют агента не пропускать сениорские этапы работы. К моменту разбора в блоге репозиторий собрал 27 тысяч звёзд, к моменту этой публикации — уже больше 29 тысяч.</p><p>Скилл — это markdown-файл со специальной шапкой (frontmatter — служебный блок с метаданными в начале файла), который Claude Code или Anthropic Agent SDK подгружают в контекст агента по триггеру. Не справочник, а пошаговый workflow с чекпоинтами и критерием выхода: написать падающий тест, запустить, увидеть, что он падает, написать минимальный код, увидеть, что тест прошёл.</p><p>Поведение по умолчанию у любого AI-агента — кратчайший путь к «готово». Просишь функцию — он пишет функцию. Не задаёт вопросов про спеку, не пишет тест перед реализацией, не думает про границы доверия и не смотрит, как diff будет выглядеть в ревью. Скиллы прибивают сениорский каркас обратно.</p><ul><li>Addy Osmani опубликовал на GitHub набор из 20 скиллов для AI-агентов — markdown-файлов, в которых процесс встроен прямо в инструкции.</li><li>За несколько недель проект собрал 27 000 звёзд и устанавливается в Claude Code одной командой.</li><li>Скиллы покрывают шесть этапов цикла разработки: определение, планирование, сборка, верификация, ревью и выкат, плюс сквозной режим упрощения кода.</li><li>Главные принципы дизайна: процесс важнее текста, антирационализационные таблицы, обязательная верификация, прогрессивное раскрытие, дисциплина по объёму.</li><li>Формат переносится: те же markdown-файлы работают в Claude Code, Cursor, Gemini CLI, Codex, Aider, OpenCode.</li></ul><h2>Что внутри: 20 скиллов на шесть этапов разработки</h2><p>Двадцать скиллов организованы вокруг шести фаз жизненного цикла, поверх которых сидят семь slash-команд. Это та же модель, по которой работают здоровые инженерные команды, просто с другой лексикой.</p><ul><li>Define — /spec: что именно мы строим.</li><li>Plan — /plan: разбиение работы на куски.</li><li>Build — /build: реализация вертикальными слайсами.</li><li>Verify — /test: доказательство, что работает.</li><li>Review — /review: что ускользнуло от автора.</li><li>Ship — /ship: безопасный выкат.</li><li>Cross-cutting — /code-simplify: упрощение в любой фазе.</li></ul><p>Большая фича может активировать одиннадцать скиллов подряд, мелкий багфикс — три. Решает мета-роутер с именем using-agent-skills: он смотрит на запрос и подгружает только релевантные.</p><h2>Пять принципов, на которых всё держится</h2><h3>1. Процесс важнее текста</h3><p>Скилл — это последовательность шагов, а не эссе. Если положить в контекст агента двухтысячный текст «о лучших практиках тестирования», агент прочитает, сгенерирует правдоподобный ответ и тестов не напишет. Если положить workflow (пиши падающий тест → запусти → убедись, что упал → пиши код → убедись, что прошёл → рефактори), у агента есть, что делать, а у тебя — что проверять.</p><p>Это правило одинаково работает и для людей: справочник на 200 страниц никто не открывает в дедлайн, маленький workflow с чекпоинтами выполняется.</p><h3>2. Антирационализационные таблицы</h3><p>В каждом скилле есть таблица «оправданий» с заранее написанными контраргументами. Примеры:</p><ul><li>«Эта задача слишком простая для спеки» → критерии приёмки всё равно нужны. Пять строк подойдёт; ноль строк нет.</li><li>«Тесты напишу позже» → «позже» — это слово-обманка. Никакого «позже» не будет: пиши падающий тест сейчас.</li><li>«Тесты прошли — мержим» → проходящий тест — это улика, а не доказательство. Запусти приложение, проверь поведение, дай человеку посмотреть diff.</li></ul><p>LLM хорошо умеет в правдоподобную аргументацию: «именно эта задача спеки не требует, именно этот merge безопасный без ревью». Антирационализационная таблица — это заранее заготовленные ответы на отговорки, которые агент пока ещё даже не придумал. Тот же приём отлично работает в человеческих командах.</p><h3>3. Верификация — не опция</h3><p>Каждый скилл заканчивается конкретной уликой: тесты прошли, билд чистый, трейс рантайма показывает ожидаемое поведение, ревьюер подписался. «Кажется, ОК» — недостаточно никогда. Агент-генератор всегда скажет, что всё хорошо, поэтому нужен отдельный сигнал, что работа действительно сделана.</p><h3>4. Прогрессивное раскрытие</h3><p>Все 20 скиллов в контекст не загружаются. На старте сессии активен только маленький мета-навык using-agent-skills, который выбирает релевантный скилл под текущую задачу. Каждый лишний токен в контексте где-то уменьшает качество, поэтому подгружать нужно только то, что реально применимо.</p><h3>5. Дисциплина по объёму</h3><p>Мета-скилл фиксирует жёсткое правило: трогай только то, о чём попросили. Не рефактори соседние модули. Не сноси код, который не понимаешь до конца. Это самый частый параметр, по которому пулреквест агента становится немёрджибельным: где-то по пути он решил «заодно отрефакторить».</p><h2>ДНК Google в каждом скилле</h2><p>Скиллы насыщены практиками из книги <b>Software Engineering at Google</b> и публичной инженерной культуры. Это сделано осознанно: большая часть того, что заставляет работать большой код, задокументирована — и именно это агент пропускает первым делом.</p><ul><li>api-and-interface-design — закон Хайрама: любое наблюдаемое поведение API кто-то рано или поздно начнёт использовать.</li><li>test-driven-development — пирамида ~80/15/5 (unit / integration / e2e) и правило Бейонсе: «если функционал тебе нравится — обязательно прикрой его тестом». DAMP важнее DRY в тестах: тест должен читаться как спецификация, даже ценой дублирования.</li><li>code-review-and-quality — пулреквесты по 100 строк и метки Critical / Nit / Optional / FYI. Большие PR не ревьюят, их штампуют.</li><li>code-simplification — забор Честертона: не сноси, пока не понял, зачем поставили. Удалённый код имеет привычку возвращаться багом.</li><li>git-workflow-and-versioning — trunk-based development и атомарные коммиты.</li><li>ci-cd-and-automation — shift-left и feature-флаги: лови проблемы как можно раньше, выкат и релиз — разные операции.</li><li>deprecation-and-migration — код как обязательство: каждая строка живёт ровно столько, сколько её обслуживают.</li></ul><p>Любая модель видела в обучении словосочетание «закон Хайрама», но не применяет его, проектируя API в три часа ночи. Скиллы — способ сделать так, чтобы применяла.</p><h2>Три режима использования</h2><p><b>Режим 1: установка плагином в Claude Code.</b></p><p>Получаешь все slash-команды, скиллы активируются автоматически по контексту.</p><p><b>Режим 2: ручной импорт markdown в свой инструмент.</b> Скиллы — это plain-markdown, переносится куда угодно. В Cursor — в .cursor/rules/. Gemini CLI, Codex, Aider, Windsurf, OpenCode — у каждого свой путь, но workflow одинаковый.</p><p><b>Режим 3: ничего не устанавливать, читать как спеку.</b> Открыть <i>code-review-and-quality.md</i> и применить пятиосевую шкалу серьёзности замечаний (Critical / Nit / Optional / FYI плюс blocking-комментарий) к ревью своей команды. Открыть <i>test-driven-development.md</i> и закрыть следующий спор «нужно ли писать тест первым». Открыть мета-навык и взять оттуда пять non-negotiables в свой AGENTS.md.</p><h2>Выводы</h2><p>Главная идея проекта не в самих скиллах, а в подходе. AI-агент — это крайне способный джуниор без инстинкта на ту часть работы, которая не попадает в diff. Сениор-инженерные шаги — спека, размер изменений, оставленные доказательства, отказ мержить непрослеживаемое — именно то, что агент пропустит, если пропуск возможен в принципе.</p><blockquote>Задача всё чаще сводится к тому, чтобы закодировать эту дисциплину так, чтобы агент не мог уговорить себя её обойти.</blockquote><p>Репозиторий лежит на <a href="https://github.com/addyosmani/agent-skills" rel="noopener">github.com/addyosmani/agent-skills</a> под лицензией MIT, разбор подхода <a href="https://addyosmani.com/blog/agent-skills/" rel="noopener">опубликован в блоге</a> Addy Osmani. Те же markdown-файлы можно прочитать как описание того, как должна выглядеть инженерия с AI-агентами — и забрать оттуда пять non-negotiables в свой AGENTS.md без установки чего-либо.</p><p>Берите одну фазу — спеку, ревью или верификацию — и закрепляйте её в правилах своего агента. Дальше расширяйте по мере того, какие шаги команда чаще всего пропускает.</p>]]></content:encoded>
    </item>
    <item>
      <title>Сэкономили на CMS при запуске магазина — а через полгода заплатили втройне за переезд</title>
      <link>https://tproger.ru/articles/sekonomili-na-cms-pri-zapuske-magazina-a-cherez-polgoda-zaplati</link>
      <comments>https://tproger.ru/articles/sekonomili-na-cms-pri-zapuske-magazina-a-cherez-polgoda-zaplati?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Pavel Pat]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/sekonomili-na-cms-pri-zapuske-magazina-a-cherez-polgoda-zaplati</guid>
      <description><![CDATA[<p>Зачем CMS для магазина — это не «витрина», а контур продаж: каталог, 1С, промо, масштаб. Разбор Битрикса, WooCommerce, облака и самописа, плюс честно про миграцию и ошибки на старте.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/sekonomili-na-cms-pri-zapuske-magazina-a-cherez-polgoda-zaplati">Сэкономили на CMS при запуске магазина — а через полгода заплатили втройне за переезд</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[SEO]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Быстрый старт]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[WordPress]]></category>
      <category><![CDATA[Magento]]></category>
      <category><![CDATA[OpenCart]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[CMS]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 06 May 2026 08:20:34 GMT</pubDate>
      <content:encoded><![CDATA[<p>Мне часто приносят историю в таком виде: «Сделали сайт дёшево, всё летало на старте». Потом каталог раздувается до десятков тысяч SKU, поиск начинает подвисать, 1С не дружит с админкой — и вместо продаж получается проект спасения.</p><p>Один такой кейс я помню особенно болезненно. Заказчик специально ушёл от «тяжёлых» платформ ради самописного решения: быстрее сроки, ниже чек на входе. Полгода спустя каталог перевалил за 10 000 позиций. Страницы открывались по 8–12 секунд, поиск фактически умер, обмен с учёткой превратился в ручной ад. В итоге пришлось пересобирать магазин на другой системе — и суммарно это стоило примерно в три раза больше, чем если бы выбрать нормальный фундамент сразу.</p><p>Вывод простой и непопулярный: для интернет-магазина CMS — это не «движок сайта», а контур бизнеса. Если он не тянет каталог, склады, оплаты и промо — экономия на старте превращается в налог на переделку.</p><h2>Почему «красивая витрина» не спасает</h2><p>Товар и дизайн важны. Но когда речь про оборот, в игру входят другие вещи: скорость выдачи каталога под нагрузкой, связка с 1С или CRM, гибкость скидок, безопасность оплат, возможность масштабировать без ручного копания в ядре.</p><p>Я бы проверял любую платформу не по «можно ли сделать красиво», а по чек-листу: большой каталог без комы в выдаче, интеграции без лютого кастома, промо-логика без боли, понятный путь от заказа до оплаты. Всё остальное — уже вторичный дизайн.</p><h2>Где Битрикс реально оправдан</h2><p>На корпоративных и сетевых историях Битрикс заходит потому, что это не «лендинг с корзиной», а связка магазина с процессами: каталог, заказы, складские и клиентские сценарии из коробки, обмен с 1С как отдельная экосистема.</p><p>Был у нас запуск для стройсети: 80 000 товаров, несколько складов, отдельная математика скидок для B2B. На чистом PHP такое можно дописать, но это месяцы и жирный бюджет. На готовом контуре мы вышли в прод заметно быстрее — потому что решали задачу бизнеса, а не изобретали велосипед.</p><p>Цена лицензии и сервера — да, это не «бесплатный WordPress». Зато это честная модель: вы платите за то, что масштаб и интеграции уже заложены в архитектуру, а не пробиты латками.</p><h2>Kогда разумнее WooCommerce и облако</h2><p>Если у вас не миллион SKU и не десять складов, а тысяча позиций и простая воронка — связка WordPress + WooCommerce часто выигрывает по скорости запуска и по цене входа. Экосистема плагинов закрывает типовые задачи без заказной разработки на каждый чих.</p><p>Облачные SaaS вроде Shopify годятся, когда компании нужен быстрый старт без администрирования сервера и команды DevOps. Комиссии и ограничения платформы нужно закладывать в юнит-экономику заранее — но для проверки гипотезы это иногда лучший компромисс.</p><p>OpenCart и аналоги я чаще видел у проектов, где важна предсказуемость и «руки разработчика на аутсорсе»: проще найти исполнителя, меньше сюрпризов, чем на экзотике. Magento и тяжёлый enterprise-класс имеют смысл, когда команда уже сильная технически и каталог — это отдельный продукт, а не «сайт с корзиной».</p><h2>Самопис — не зло, но это отдельная ставка</h2><p>Своя CMS имеет смысл, когда продукт по сути уникален и типовые решения мешают. Во всех остальных случаях вы покупаете не «уникальность», а дорогую поддержку собственного монстра: каждый апдейт PHP, каждый новый способ оплаты — ваш головняк.</p><h2>Если уже понятно, что платформа не та</h2><p>Переезд между системами редко бывает «копипастой базы». Обычно это заново собранная карточка товара, перепроверенные атрибуты, аккуратная переездная SEO-схема и пауза в маркетинге на время технических работ. Я закладываю такие работы как отдельный проект с понятным бэклогом — иначе получится хаос и простой продаж.</p><p>На этом этапе экономить опаснее всего: «перенесём как получится» почти всегда означает битые URL, дубли в выдаче и потерянные заказы в переходный месяц. Если уж делаете миграцию — делайте её один раз и основательно.</p><h2>Что мы делаем перед выбором</h2><ul><li>Считаем не «стоимость запуска», а стоимость трёх лет жизни: лицензии, хостинг, доработки, интеграции.</li><li>Фиксируем сценарии: каталог, промо, B2B/B2C, обмен с учёткой, маркетплейсы.</li><li>Закладываем буфер на рост — если через год SKU вырастет в пять раз, платформа должна выдержать без полной переделки.</li><li>Перед подписанием уточняем у подрядчика три неудобных вещи: сколько стоит час поддержки после запуска, как закрываются интеграции «не из коробки», и что будет, если через полгода понадобится второй склад или новый тип оплаты.</li></ul><p>Ответы без конкретики («сделаем как надо») для меня красный флаг. Нормальный исполнитель называет риски и диапазоны хотя бы порядка величины.</p><p>Если очень коротко: не экономьте на фундаменте там, где сайт — канал продаж. Экономия почти всегда вернётся чеком на миграцию.</p><p>Подробнее разобрал платформы и критерии в материале на сайте: <a href="https://webfull.ru/blog/vybor-cms-dlya-internet-magazina/">как выбрать CMS для интернет-магазина — сравнение подходов</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как я написал E2EE-мессенджер на Spring Boot и WebCrypto — и почему сервер не видит сообщения</title>
      <link>https://tproger.ru/articles/kak-ya-napisal-e2ee-messendzher-na-spring-boot-i-webcrypto-i-poch</link>
      <comments>https://tproger.ru/articles/kak-ya-napisal-e2ee-messendzher-na-spring-boot-i-webcrypto-i-poch?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Василенков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-ya-napisal-e2ee-messendzher-na-spring-boot-i-webcrypto-i-poch</guid>
      <description><![CDATA[<p>Разбор архитектуры E2EE-мессенджера на Spring Boot 3, React и WebCrypto: X3DH, symmetric ratchet, AES-GCM, WebSocket, multi-device и ограничения реализации.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-ya-napisal-e2ee-messendzher-na-spring-boot-i-webcrypto-i-poch">Как я написал E2EE-мессенджер на Spring Boot и WebCrypto — и почему сервер не видит сообщения</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Stack Overflow]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Алиса]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Мессенджер]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Взлом]]></category>
      <category><![CDATA[5g]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 05 May 2026 05:35:02 GMT</pubDate>
      <content:encoded><![CDATA[<figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/240e412b-4307-49f9-b24f-bde7e0a7fd9a.webp" alt="" /></figure><p>Я Java-разработчик и в основном работаю с backend: Spring Boot, базы данных, интеграции, авторизация, WebSocket — всё то, что обычно находится за интерфейсом.</p><p>В какой-то момент я поймал себя на мысли: я каждый день пользуюсь мессенджерами, но плохо понимаю, как они устроены внутри. Окей, JWT, WebSocket, PostgreSQL, Redis — это понятно. Но что технически означает фраза "end-to-end encryption"? Как сервер доставляет сообщения, если он не должен их читать? Где живут ключи? Что хранится в базе? Что происходит, если у пользователя два устройства?</p><p>Решил разобраться через практику. Написал мессенджер с нуля. Назвал Chaos Messenger.</p><p>Сразу честно: криптографическую часть я изучал вместе с Claude и ChatGPT — читал спецификации X3DH и Double Ratchet, разбирал примеры, задавал вопросы, пока не сложилась цельная картина. Frontend тоже делался с активной помощью ChatGPT: я backend-разработчик, React для меня не основная среда. Но архитектура, backend, интеграция WebCrypto, модель конвертов, хранение сообщений и принципиальные решения — мои.</p><p>Для меня AI здесь был не заменой понимания, а инструментом — примерно как документация, Stack Overflow и ревью коллег. Без понимания threat model и архитектуры такой проект всё равно не собрать.</p><p>В статье расскажу, как работает E2EE изнутри: как устанавливается сессия через X3DH, как каждое сообщение получает отдельный ключ через Symmetric Ratchet, почему сервер хранит только зашифрованные конверты, и какие ошибки я допустил по дороге.</p><p>Стек: Spring Boot 3, React 18, WebCrypto API, PostgreSQL, Redis, WebSocket/STOMP, Prometheus, Grafana.</p><figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/4b028f37-2de1-46ea-a247-567f74fb3081.webp" alt="" /></figure><h2>Важная оговорка про web-E2EE</h2><p>Когда я говорю, что сервер не может прочитать сообщения, я имею в виду backend, базу данных, WebSocket-слой и уже сохранённые ciphertext-конверты. У них нет ключей и plaintext.</p><p>Но у web-E2EE есть отдельная проблема: frontend-код тоже приходит с сервера. Теоретически скомпрометированный сервер может отдать изменённый JavaScript, который украдёт ключи или plaintext до шифрования. Это ограничение не конкретно моего проекта, а браузерной модели в целом.</p><p>Поэтому корректная формулировка такая: backend не получает ключи и не может расшифровать уже переданные или сохранённые сообщения. Защита от подмены клиентского кода — отдельный слой безопасности: подпись сборок, независимая верификация клиента, desktop/mobile-приложения, reproducible builds.</p><h2>Почему обычный подход не работает</h2><p>Большинство "мессенджеров" на GitHub выглядят примерно так:</p><p>Сервер знает всё. Видит каждое сообщение. Если БД утекла — утекла вся переписка. Если сервер взломали — читай что хочешь. Если завтра компания решит продать данные — технически ничего не мешает.</p><p>E2EE решает это радикально: backend не получает ключи и не хранит plaintext. Сообщение шифруется на устройстве отправителя до отправки в сеть, а расшифровывается только на устройстве получателя.</p><p>Это уже не вопрос политики конфиденциальности в стиле "мы обещаем не читать". Это архитектурное ограничение: если у сервера нет ключа, он не может превратить ciphertext обратно в текст.</p><p>Звучит как магия. На самом деле — два протокола и немного WebCrypto.</p><h2>Главная идея: конверты</h2><p>Представь что Алиса хочет написать Бобу. Вместо того чтобы положить письмо на стол и надеяться что никто не прочитает — она кладёт его в запечатанный конверт. Конверт может открыть только Боб своим ключом. Сервер просто передаёт конверт не заглядывая внутрь.</p><p>Именно так это работает в коде. В базе данных у меня это выглядит так:</p><p>Когда я впервые увидел</p><p>в своей БД вместо текста — стало понятно, что модель наконец работает правильно: сервер создал сообщение, доставил его, сохранил метаданные, но так и не узнал содержимое.</p><p>А вот что сервер возвращает при запросе списка чатов через API:</p><p>Не</p><p>. Не</p><p>. Буквально</p><figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/b466ad91-20da-4e64-8b78-f6e08d2851d5.webp" alt="" /></figure><p>(DevTools → Network → ответ API с</p><p>)</p><h2>Откуда берутся ключи: X3DH</h2><p>Главный вопрос: как Алиса и Боб получают общий секрет, если они никогда раньше не общались? И как сделать это так, чтобы сервер только помог передать публичные данные, но сам не смог вычислить итоговый ключ?</p><p>Для этого используется X3DH — Extended Triple Diffie-Hellman, протокол из экосистемы Signal. Его задача — установить общий секрет между двумя устройствами, используя долгосрочные и временные ключи.</p><h2>Что хранится на сервере</h2><p>Когда пользователь регистрирует устройство, он загружает на сервер пакет публичных ключей:</p><p>На сервер уходят только публичные части. Приватные ключи сериализуются и хранятся локально в браузере — и никогда не покидают устройство в сеть.</p><p>Здесь важно сказать честно: хранение приватных ключей в</p><p>Более строгий вариант — использовать Web Crypto API с</p><p>, чтобы приватный ключ жил внутри браузерного crypto runtime и его нельзя было экспортировать в байты. Но у этого подхода есть практическая сложность: ключи нужно переживать между перезагрузками страницы, синхронизировать с IndexedDB, аккуратно восстанавливать состояние устройства и не сломать UX.</p><p>В браузерных E2EE-приложениях обычно приходится выбирать между несколькими вариантами:</p><ul><li>Сериализуемые ключи в localStorage или IndexedDB — проще реализовать, но нужно очень серьёзно относиться к XSS и целостности frontend-кода.</li><li>extractable: false + IndexedDB — безопаснее, но сложнее в реализации и восстановлении состояния.</li><li>Нативное secure storage вроде Android Keystore или iOS Secure Enclave — лучший вариант для мобильных клиентов, но он недоступен обычному web-приложению.</li></ul><p>В текущей версии Chaos Messenger используется первый вариант. Это осознанный компромисс для pet/open-source проекта и удобного запуска в браузере. Переход на non-extractable ключи и более строгую модель хранения стоит в roadmap.</p><p>Ключевой момент: backend всё равно не получает приватные ключи и не может расшифровать сохранённые ciphertext-конверты. Но защита ключей на клиенте — отдельная задача, и её нельзя честно замалчивать.</p><h2>Установка сессии</h2><p>Когда Алиса открывает переписку с Бобом впервые, происходит следующее:</p><p>В классическом X3DH четвёртая DH-операция с one-time prekey опциональна: она выполняется, если сервер выдал доступный OPK получателя. В моей реализации устройство публикует набор one-time prekeys при регистрации, поэтому первое сообщение обычно использует DH4. Если OPK закончились, сессию всё равно можно установить через остальные DH-компоненты, но это уже менее сильный вариант.</p><p>Боб, получив конверт с эфемерным публичным ключом Алисы, повторяет те же операции со своими приватными ключами и получает тот же самый</p><p>. Математика симметрична.</p><p>Сервер в этот момент видит только публичные ключи и зашифрованный конверт. Он помогает устройствам найти друг друга, но не участвует в вычислении секрета.</p><p>Получить</p><figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/e7bbacf3-4fd2-4710-863a-2c710b1f6759.webp" alt="" /></figure><h2>Как шифруется каждое сообщение: Symmetric Ratchet</h2><p>X3DH даёт нам стартовый</p><p>. Но использовать один и тот же ключ для всех сообщений — плохая идея. Если использовать один ключ для всей переписки, компрометация этого ключа сразу открывает весь поток сообщений.</p><p>Решение — симметричный ratchet. После каждого сообщения цепочка ключей продвигается вперёд:</p><p>Визуально это выглядит так:</p><p>используется для шифрования одного сообщения через AES-GCM, после чего уничтожается. Если атакующий компрометирует</p><p>— он прочитает только второе сообщение.</p><p>В рамках такой симметричной цепочки это даёт forward secrecy назад по цепочке: зная текущий или отдельный</p><figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/939a74f7-60c5-4816-85f0-05b5afdc9845.webp" alt="" /><figcaption>(диаграмма схемы chainKey → messageKey)</figcaption></figure><p>Само шифрование сообщения:</p><p>А вот что уходит на сервер — живой пример из DevTools:</p><p>Сервер получает</p><p>и</p><p>. Расшифровать без</p><figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/b5e24cda-6fd9-4b15-9f27-3eb9b4f843b0.webp" alt="" /></figure><h2>Важная оговорка: это ещё не полный Double Ratchet</h2><p>В этом проекте реализован Symmetric Ratchet — цепочка, где из</p><p>для каждого сообщения выводится отдельный</p><p>Это защищает прошлые сообщения: если атакующий узнает текущий ключ или отдельный</p><p>, он не сможет откатить HMAC назад и получить старые ключи.</p><p>Но это не полный Double Ratchet из Signal Protocol.</p><p>В полном Double Ratchet есть ещё DH ratchet step: стороны периодически выполняют новый Diffie-Hellman обмен и обновляют root key. Это даёт break-in recovery — возможность восстановить безопасность будущих сообщений после компрометации части состояния.</p><p>В моей реализации DH ratchet step пока нет. Если атакующий получит актуальное состояние сессии на устройстве и сможет продолжать его читать, он сможет расшифровывать будущие сообщения до переустановки сессии. Это честное ограничение текущей версии, и оно стоит первым пунктом в roadmap.</p><h2>Мультиустройство: один пользователь, несколько конвертов</h2><p>Первый неочевидный момент: в E2EE сообщение адресуется не просто пользователю, а конкретным устройствам пользователя.</p><p>Если у Боба два устройства — телефон и ноутбук — нужен отдельный encrypted envelope для каждого устройства. Сервер не может взять один конверт, расшифровать его и "переупаковать" для второго устройства: у него нет ключей и он не знает plaintext.</p><p>Значит при отправке сообщения нужно зашифровать его отдельно для каждого устройства каждого участника чата.</p><p>Для чата где у каждого по 2 устройства — 4 конверта на одно сообщение. Для группы из 10 человек — потенциально 20 конвертов. Это нормально, это цена безопасности.</p><h2>Сервер: хранение и доставка конвертов</h2><p>На сервере сообщение создаётся с контентом</p><p>, а конверты сохраняются отдельно:</p><p>После сохранения — fanout по WebSocket. Каждое устройство получает свой конверт и только его:</p><p>Это важное отличие от обычного WebSocket-чата. В обычном чате сервер рассылает одно и то же событие всем участникам. В E2EE-чате сервер рассылает разные события разным устройствам: payload для каждого устройства содержит свой</p><p>Топик</p><p>— строго персональный. Устройство А не получает конверт устройства Б. Никакого broadcast — только адресная доставка.</p><h2>Архитектура целиком</h2><figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/de0e3257-d893-459f-86ed-7ed8eace5d56.webp" alt="" /></figure><h2>Баг который долго не замечал</h2><p>В панели чатов показывается превью последнего сообщения. Я реализовал это через</p><p>Запускаю — в списке чатов у всех написано</p><p>.</p><p>Конечно. Сервер же не знает что там написано.</p><p>Я полчаса думал как решить это на сервере. Потом дошло: нельзя решить это на сервере — у него нет ключей. Решение только на клиенте.</p><p>После того как пользователь открыл чат и сообщения расшифровались — кешируем последнее в памяти:</p><p>Это хороший пример того, как E2EE меняет привычное мышление backend-разработчика. В обычном приложении preview — это поле в SQL-запросе. В E2EE-приложении preview — это локальное клиентское состояние, потому что только клиент видел plaintext.</p><p>Простое решение. Но чтобы к нему прийти нужно было полностью принять идею что сервер здесь просто не при делах — и перестать пытаться решить задачу на его стороне.</p><h2>Rate limiting: дыра которую легко не заметить</h2><p>Эндпоинт</p><p>отправляет SMS с кодом. Без защиты любой скрипт может дёргать его тысячи раз — это называется SMS pumping fraud, SMS стоят реальных денег.</p><p>Redis у нас уже был для хранения онлайн-статусов. Добавил rate limiting поверх него:</p><p>При превышении — HTTP 429 с заголовком</p><p>. Клиент знает через сколько секунд можно повторить.</p><p>Важный нюанс: в текущей реализации, если Redis недоступен, сервис не блокирует авторизацию полностью. Для pet-проекта это приемлемый компромисс: лучше рискнуть одним лишним SMS, чем положить вход в приложение.</p><p>В production я бы сделал строже: fallback in-memory лимит на инстанс, отдельные лимиты по IP и телефону, антифрод-логику и алерты на всплески отправки кодов.</p><h2>Авторизация WebSocket</h2><p>Отдельная история — авторизация WebSocket соединений. HTTP-эндпоинты защищены Spring Security автоматически, но WebSocket — другое дело. STOMP-соединение устанавливается один раз, и нужно проверять JWT при каждом подключении.</p><p>Отдельно важно не только проверить JWT, но и связать WebSocket-соединение с конкретным устройством. Пользователь может быть один, но устройств у него несколько, а encrypted envelope адресован именно</p><p>Поэтому при подключении я проверяю не только токен, но и</p><p>: устройство должно быть зарегистрировано и принадлежать текущему пользователю. Иначе легко случайно превратить per-device E2EE-доставку обратно в обычный broadcast по пользователю.</p><h2>Что получилось — живые скрины</h2><figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/1fdfa006-f5c6-4731-a40f-50559be8832d.webp" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/c99164a5-021c-49ac-bcc4-3e38f9cd1c31.webp" alt="" /></figure><p>Что реализовано:</p><ul><li>E2EE-модель с per-device encrypted envelopes</li><li>X3DH session setup + Symmetric Ratchet + AES-GCM</li><li>Мультиустройство</li><li>Личные и групповые чаты</li><li>Realtime доставка через WebSocket/STOMP</li><li>Статусы SENT → DELIVERED → READ</li><li>Редактирование и soft delete сообщений</li><li>Online presence, typing indicator</li><li>Фото-вложения</li><li>Поиск пользователей</li><li>Rate limiting на SMS через Redis</li><li>Prometheus метрики + Grafana дашборд</li><li>Swagger UI с JWT авторизацией</li><li>24 backend-теста на Testcontainers, 12 frontend на Vitest, E2E на Playwright</li><li>GitHub Actions CI</li></ul><p>Что ещё не сделано:</p><ul><li>Полный Double Ratchet с DH ratchet step и break-in recovery</li><li>Ротация signed prekey и аккуратное пополнение one-time prekeys</li><li>Более строгая модель хранения приватных ключей на клиенте: non-extractable CryptoKey + IndexedDB</li><li>Защита от подмены frontend-кода: подпись сборок, независимая верификация клиента, reproducible builds</li><li>Android-клиент с Android Keystore</li><li>Реальный SMS-провайдер вместо кода в backend-логах</li><li>Push-уведомления без утечки содержимого сообщений</li><li>Более строгая metadata-модель для групповых чатов</li></ul><h2>Главный инсайт</h2><p>E2EE — это архитектурное решение, а не библиотека.</p><p>Нельзя взять обычный Spring Boot чат и просто "включить шифрование". Нужно с самого начала проектировать систему так, чтобы backend не был участником доверенной зоны: он не должен получать plaintext, не должен иметь ключи и не должен уметь пересобирать сообщение из данных в базе.</p><p>Это меняет почти всё:</p><ul><li>структуру БД — вместо текста появляются encrypted envelopes</li><li>API — сервер отдаёт [encrypted], а не preview сообщения</li><li>WebSocket — доставка идёт не по пользователю, а по конкретному устройству</li><li>мультиустройство — одно сообщение превращается в несколько ciphertext-конвертов</li><li>frontend — становится полноценной криптографической частью системы, а не просто UI</li></ul><p>Второй инсайт: мессенджер — это не "чат с WebSocket". В E2EE-модели это система доставки зашифрованных конвертов с адресацией по устройствам. Как только это принимаешь, многие странные на первый взгляд решения становятся логичными.</p><h2>Репозиторий</h2><p>Код открыт: <a href="https://github.com/vaazhen/chaos-messenger">github.com/vaazhen/chaos-messenger</a></p><p>В репозитории есть README на русском и английском, диаграммы, скриншоты, security audit, Docker Compose и запуск одной командой.</p><p>Проект не претендует на уровень production-криптомессенджера вроде Signal. Это учебный и инженерный open-source прототип, цель которого — показать, как E2EE меняет архитектуру backend, frontend и realtime-доставки.</p><p>Если вы делали что-то похожее — особенно интересно сравнить подходы к ротации prekey-ов, хранению non-extractable ключей в браузере и реализации DH ratchet step. Вопросы и критика приветствуются.</p>]]></content:encoded>
    </item>
    <item>
      <title>Страница статусов снизила нагрузку на поддержку в три раза. Как мы к этому пришли</title>
      <link>https://tproger.ru/articles/stranica-statusov-snizila-nagruzku-na-podderzhku-v-tri-raza-kak</link>
      <comments>https://tproger.ru/articles/stranica-statusov-snizila-nagruzku-na-podderzhku-v-tri-raza-kak?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Алексей Симоненков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/stranica-statusov-snizila-nagruzku-na-podderzhku-v-tri-raza-kak</guid>
      <description><![CDATA[<p>Разбор кейса: как страница статусов сократила количество тикетов во время инцидентов на 67%. Что пробовали до этого, как устроен нормальный incident workflow и что важно при выборе инструмента для российского рынка.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/stranica-statusov-snizila-nagruzku-na-podderzhku-v-tri-raza-kak">Страница статусов снизила нагрузку на поддержку в три раза. Как мы к этому пришли</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Новости]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Telegram]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Системное администрирование]]></category>
      <category><![CDATA[Техподдержка]]></category>
      <category><![CDATA[Высокие нагрузки]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 28 Apr 2026 06:40:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Несколько лет назад я работал в компании, которая делала платёжный процессинг. Не скажу название - NDA жив до сих пор. Но расскажу про один конкретный вечер в пятницу, который изменил то, как я думаю об инцидентах.</p><p>Около семи вечера начали падать транзакции. Не все - примерно 15%. Команда сразу занялась разбором: логи, метрики, трейсы. Стандартный процесс. Проблему нашли и починили за 40 минут. По меркам платёжки - нормально.</p><p>Но пока мы разбирались, в поддержку пришло 300 тикетов. Три сотни «что происходит», «у нас не проходят платежи», «когда заработает». Саппорт ничего не знал - он ждал, пока инженеры выплывут из логов. Клиенты ждали саппорт. Всё это время тишина с нашей стороны читалась как безразличие.</p><p>Проблему починили за 40 минут. Разгребали тикеты три дня.</p><h2>Почему молчание хуже, чем «мы знаем о проблеме»</h2><p>Есть простая психология: человек переносит неопределённость хуже, чем плохие новости. Если транзакция не прошла и нет никакой информации - клиент начинает строить сценарии. Деньги потерялись. Сервис умер. Нас кинули. Он пишет в поддержку. Потом пишет ещё раз. Потом оставляет отзыв.</p><p>Если транзакция не прошла, но есть страница</p><p>с записью «Повышенное время отклика платёжного шлюза. Investigating. 19:12» - большинство людей закрывают вкладку и ждут. Не все. Но большинство.</p><p>Мы это проверили. После того как поставили нормальную страницу статусов, количество тикетов во время инцидентов упало примерно в три раза. Точнее - на 67% по среднему за квартал. Это не магия, это просто информация в нужный момент.</p><h2>Что мы пробовали до этого</h2><p>Расскажу честно, через что прошли, потому что это типичный путь.</p><p>Шаг первый: Telegram-канал. Завели канал «Статус сервиса». Писали туда когда что-то падало. Работало ровно до тех пор, пока кто-то не забыл написать. А потом написал через два часа когда уже всё починилось. Клиенты не понимали что происходило. Доверие к каналу упало быстро.</p><p>Шаг второй: статус в шапке сайта. Зелёный кружок когда всё хорошо. Ручной - кто-то должен был его менять. Понятно куда это ведёт: кружок всегда зелёный, потому что некогда, потому что забыли, потому что «сейчас разбираемся, потом обновим».</p><p>Шаг третий: Atlassian Statuspage. Это уже нормальный инструмент. Он решил проблему. Но у него есть два неудобства для русскоязычного рынка: оплата в долларах (что в 2022 стало практической проблемой) и серверы за пределами России (что для ряда клиентов принципиально с точки зрения регулирования).</p><h2>Как устроен нормальный incident workflow со страницей статусов</h2><p>Я говорю «нормальный» - имею в виду тот, который не требует героизма от дежурного инженера в 2 ночи.</p><p>Всё начинается с мониторинга. HTTP/TCP-проверки каждую минуту на все критичные эндпоинты: API, веб, база, очереди. Когда что-то падает - автоматическое создание инцидента и уведомление команды. Это не новость, большинство так и делают.</p><p>Новость в том, что параллельно с уведомлением команды - автоматическое обновление публичной страницы статусов. Не «кто-то должен написать туда», а именно автоматически. Клиент видит «Degraded performance» раньше, чем успевает написать в поддержку.</p><p>Дальше инженер работает по стандартному процессу: Investigating - Identified - Monitoring - Resolved. Каждый статус обновляется на странице. Клиенты, подписавшиеся на уведомления, получают апдейты в Telegram или email. Поддержка может в один клик скопировать ссылку на инцидент и отправить клиенту вместо объяснений.</p><p>После разрешения - postmortem прямо на странице. Клиенты видят что случилось, почему и что сделано чтобы не повторилось. Это, как ни странно, повышает доверие сильнее, чем если бы инцидента не было совсем.</p><h2>Что важно при выборе инструмента</h2><p>Несколько технических вещей, на которые стоит обратить внимание.</p><p>Uptime самой страницы статусов. Она должна быть на отдельной инфраструктуре. Если ваш основной сервис упал и страница статусов на той же инфраструктуре - вы получили идеальный шторм: сервис не работает и статус показать невозможно.</p><p>Собственный домен.</p><p>вместо</p><p>. Это доверие и брендинг.</p><p>Telegram-уведомления. Для российской аудитории это важнее email. Люди читают Telegram, а не почту, когда ищут статус сервиса в панике.</p><p>Локализация данных. Если работаете с персональными данными российских пользователей - вопрос где физически хранятся данные о ваших инцидентах становится юридическим, а не техническим.</p><p>Мы в Flaree делаем страницу статусов именно для таких случаев - серверы в России, Telegram из коробки, оплата в рублях. Сейчас открыт ранний доступ, первые 50 команд получают 3 месяца Pro бесплатно: <a href="https://flaree.ru/">flaree.ru</a></p><h2>Что в итоге</h2><p>Страница статусов - это не инструмент для больших команд. Это инструмент для любого сервиса, у которого есть клиенты и бывают инциденты. То есть для всех.</p><p>Настройка занимает 15 минут. Первый же инцидент, который клиенты узнают из статусной страницы раньше, чем напишут в поддержку - окупает это время с запасом.</p><p>P.S. Если у вас уже есть страница статусов - напишите в комментариях какой инструмент используете. Интересно что прижилось у разных команд.</p>]]></content:encoded>
    </item>
    <item>
      <title>Слово за ИИ: как речевая аналитика меняет телекоммуникации</title>
      <link>https://tproger.ru/articles/slovo-za-ii-kak-rechevaya-analitika-menyaet-telekommunikacii</link>
      <comments>https://tproger.ru/articles/slovo-za-ii-kak-rechevaya-analitika-menyaet-telekommunikacii?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Александр Красников]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/slovo-za-ii-kak-rechevaya-analitika-menyaet-telekommunikacii</guid>
      <description><![CDATA[<p>Рассказываем, как ИИ помогает бизнесу говорить на одном языке с клиентом в поддержке и повышать продажи.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/slovo-za-ii-kak-rechevaya-analitika-menyaet-telekommunikacii">Слово за ИИ: как речевая аналитика меняет телекоммуникации</a>»</p>]]></description>
      <category><![CDATA[Алгоритмы и структуры данных]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 23 Apr 2026 06:00:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Бизнес активно внедряет речевую аналитику, о чем говорит быстрый рост глобального рынка подобных решений. По данным <a href="https://www.datainsightsmarket.com/reports/speech-analytics-industry-14722">отчета</a> аналитической компании Data Insight, в 2025 году он оценивался на уровне 3,13 млрд долларов, а средний годовой темп его роста составит в период с 2025-го по 2033 годы 15,6%. Эта динамика во многом объясняется быстрым развитием облачных ИИ-решений, которые становятся доступны не только крупному, но  малому и среднему бизнесу.</p><p>В России также востребована речевая аналитика прежде всего банками, поставщиками страховых услуг, медицинскими и телекоммуникационными компаниями. Интерес к таким сервисам растет, потому что бизнес уделяет все больше внимания повышению качества клиентского опыта и заинтересован в получении маркетинговой информации, которую в изобилии приносит анализ всех разговоров с клиентами.</p><p>Кроме того, росту рынка способствует развитие омниканальных решений связи, в которых также очень часто задействованы сервисы для анализа коммуникаций. Российский рынок речевой аналитики, по ранее опубликованному <a href="https://telecomdaily.ru/news/2023/11/09/iaa-telecomdaily-rossiyskiy-rynok-ra-budet-rasti-v-srednem-na-15-ezhegodno">прогнозу</a> TelecomDaily, растет схожими с мировым темпами: в 2025 году он должен был увеличиться на 16% и составить 1,56 млрд руб.</p><p>Если говорить упрощенно, то речевая аналитика — это ИИ-анализ коммуникаций, то есть любых диалогов с помощью больших языковых моделей. Нейросети переводят голос в текст и, выполняя поставленные им задачи, отслеживают соответствие речи оператора или клиента заранее настроенным параметрам.</p><p>Такие сервисы умеют выделять диалоги с повышенным, отрицательным эмоциональным фоном, оценивать уровень уверенности в речи менеджера по продажам, наличие в разговоре логики, ключевых слов, соответствия скриптам. На основе этих данных алгоритмы формируют отчеты, которые дают бизнесу представление об уровне сервиса и эффективности продаж.</p><p>Разумеется, такой анализ требуется прежде всего в отделах клиентской поддержки и продаж, чтобы контролировать качество работы менеджеров, видеть узкие места, типичные ошибки в коммуникационных сценариях. На основе речевой аналитики можно принимать решения о корректировке бизнес-процессов и даже стратегические. Использование таких сервисов нельзя сравнить с ручным анализом, ведь они достигают нужной цели на порядки быстрее человека.</p><p>Если упростить: чтобы проанализировать час разговора с клиентом, порой требуется потратить тот же час. ИИ сделает это за несколько минут.</p><h2>Речевая аналитика и предубеждения</h2><p>Сегодня не приходится говорить о том, что речевая аналитика — будущее компаний. Эти технологии уже находятся на высоком уровне развития и внедряются во многих сферах. Еще больше на них возлагается надежд, связанных с тем, что они полностью изменят бизнес и сделают его радикально эффективнее, помогут исправить все недостатки в бизнес-процессах. Однако это не совсем так: ИИ в телекоммуникациях — это условие для принятия верных решений, а не инструмент для устранения проблем.</p><p>Например: речевая аналитика способна выявить ключевые маркеры эффективности менеджеров. А вот что делать с результатами анализа, как их обратить на пользу бизнесу — отдельная задача для стратегов. Анализ действительно может показать, например, что менеджеры по продажам допускают ошибки, предлагая конкретный продукт (или не предлагают его вовсе). Однако нейросети просто предоставляют отчет, суммаризируют диалоги и оценивают их результативность, и это лишь констатация факта, с которым необходимо дальше работать.</p><p>Второй предрассудок — якобы предельно высокая стоимость внедрения речевой аналитики и похожих ИИ-решений. Какое-то время назад они действительно были доступны только крупному бизнесу, а для среднего и малого оставались далеко не всегда рациональным расходованием средств. Это было связано с высокой ценой решений на этапе их выхода на рынок. Но сейчас стоимость LLM, как и оборудования, на которых они работают, снижается.</p><p>Растут конкуренция и выбор ИИ-решений, а общая их эффективность повышается, что делает их внедрение все более оправданным для компаний любого масштаба. Даже с учетом того, что затрат требуют не только оборудование и программы, но и работа квалифицированных сотрудников, которых на рынке пока не хватает ( следовательно, их зарплаты находятся на высоком уровне и растут).</p><p>Впрочем, к оценке стоимости проектов по внедрению речевой аналитики необходимо подходить не линейно: их цена должна рассматриваться в контексте повышения эффективности работы бизнеса. Если компания благодаря внедрению ИИ получает полмиллиона дополнительной прибыли, и это стоит ей 300 тысяч на ежемесячную зарплату инженеру — выбор вполне очевиден.</p><h2>LLM становятся доступнее</h2><p>Стоимость больших языковых моделей падает, так как их становится больше. Сегодня выбор ИИ-решений в области распознавания и анализа речи на рынке достаточно широк, хотя фундаментально такие технологии разрабатывают лишь несколько крупнейших ИТ-компаний. Но предложение не ограничивается проприетарными LLM: в открытом доступе присутствуют разработки open source, например от LLaMA, Qwen и других компаний.</p><p>У моделей с открытым программным кодом есть свои преимущества. Они создаются на основе совместных исследований разработчиков ИИ-решений, обычно поддерживают несколько языков, а главное — компаниям проще кастомизировать их под свои потребности, чем в случае с проприетарными LLM.</p><p>При этом стоит отметить, что у отечественных моделей тоже есть важный плюс: они изначально лучше подходят для русскоязычных пользователей, ведь обучаются на русском языке. Это отчасти обусловливает тот факт, что российские решения нередко (но не всегда) дают более качественные ответы, чем зарубежные. Выбор модели в любом случае зависит от потребностей компании в кастомизации продукта, от масштабов и бюджета бизнеса.</p><p>То же касается и решения — разворачивать ли ИИ-сервисы в собственном контуре или в облаках. Как правило, среднему и малому бизнесу экономически невыгодно локализовывать ИИ-агентов полностью в своей инфраструктуре.</p><h2>Принцип работы моделей</h2><p>Важно понимать, что на сегодняшний день в большинстве случаев нет возможности поставить модели любую задачу и получить решение на основе свободной мысли и воли искусственного интеллекта. Большинство из них формулируют ответы, используя в работе уже загруженную в них информацию, при этом они постоянно нуждаются в обучении. Их внутреннюю базу знаний приходится периодически пополнять, а также при необходимости настраивать доступ моделей к внешним источникам информации. Ими могут быть интернет либо внутренние базы знаний в компании. При этом, если модель ищет информацию в сети, то ее ответы будет сложно верифицировать. Поэтому чаще всего в чат-боты, ИИ-ассистенты, умные помощники операторов контакт-центра встроены модели, которые используют данные только из внутренних информационных систем бизнеса. Они выделяют нужное, формулируют ответы и списки источников, которыми пользовались, а человек только проверяет результаты. Но специалист пока остается последним звеном и фильтром тех решений, которые предлагает нейросеть. Потому что галлюцинации ИИ все равно неизбежны.</p><p>Как ни странно, это связано с принципиальным устройством «мышления» моделей: на самом деле у них нет задачи ответить на вопрос верно. Они просто обязаны дать любой ответ. Насколько точным он окажется, полностью зависит от качества данных, на которых обучена модель, и умения сотрудников ставить задачи для ИИ. В этом деле самое важное — понимать, что модель не умеет видеть смыслы и у нее нет обязательного для любого человека интеллектуального бэкграунда.</p><p>Проще говоря, у нее отсутствуют априорные знания о явлениях и предметах (солнце — желтое), поэтому идеальный промпт должен быть максимально подробным: не стоит опасаться перегнуть палку с формализацией при описании задач. Может показаться, что такой промпт предназначен ребенку — что же, пока ИИ, к счастью или  сожалению, и правда не дорос до уровня человеческого осознания.</p>]]></content:encoded>
    </item>
    <item>
      <title>Вышел OpenSSL 4.0 — выпилены engines, SSLv3 и ASN1_STRING</title>
      <link>https://tproger.ru/news/vywel-openssl-4-0-vypileny-engines-sslv3-i-asn1-string</link>
      <comments>https://tproger.ru/news/vywel-openssl-4-0-vypileny-engines-sslv3-i-asn1-string?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/vywel-openssl-4-0-vypileny-engines-sslv3-i-asn1-string</guid>
      <description><![CDATA[<p>OpenSSL 4.0 — первый мажор с 2021 года. Удалили engine-интерфейс (ломает gost-engine), SSLv3, сделали ASN1_STRING непрозрачным. Узнайте, как мигрировать с 3.x.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/vywel-openssl-4-0-vypileny-engines-sslv3-i-asn1-string">Вышел OpenSSL 4.0 — выпилены engines, SSLv3 и ASN1_STRING</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 15 Apr 2026 09:00:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если в вашей сборке крутится что-то линкованное с OpenSSL — посмотрите, не сломает ли вас переход на 4.0: релиз выкидывает engine-интерфейс (на нём держится gost-engine для ГОСТ-криптографии), поддержку SSLv3, скрипт c_rehash и делает непрозрачной структуру ASN1_STRING. Следом едут новые фичи — Encrypted Client Hello, гибридный постквант-обмен и FFDHE в TLS 1.2.</p><p>14 апреля 2026 года OpenSSL Project <a href="https://openssl-library.org/post/2026-04-14-openssl-4.0/">выпустил OpenSSL 4.0</a> — первый мажорный релиз со времён 3.0 (сентябрь 2021). За четыре с половиной года накопилось много удалений и чуть поменьше новых возможностей. Разбираем, что именно сломается при апгрейде и ради чего всё это затевалось.</p><ul><li>OpenSSL 4.0 — первый мажор с 2021 года. Релиз 14 апреля 2026.</li><li>Engine-интерфейс удалён полностью. Ломает gost-engine, старые PKCS#11- и TPM-адаптеры — мигрируйте на providers.</li><li>Поддержка SSLv3 вырезана из кода (выключена по умолчанию была с 2016 года).</li><li>ASN1_STRING стал непрозрачным — прямой доступ к полям через -&gt; больше не компилируется.</li><li>Появилась поддержка ECH (RFC 9849) — TLS прячет SNI от провайдера.</li><li>Добавлен гибридный постквантовый обмен SM2+ML-KEM-768 и подпись ML-DSA-MU.</li></ul><h2>Что выпилили: список для миграции</h2><p>OpenSSL 3.0 в 2021 году ввёл архитектуру providers и одновременно объявил engine-интерфейс устаревшим. Четыре года переходного периода закончились: engines больше нет в коде, опция сборки no-engine всегда включена, макрос OPENSSL_NO_ENGINE — всегда определён. Это самое болезненное для тех, кто держал кастомный крипто-плагин: GOST, аппаратные HSM, PKCS#11-токены со старым драйвером.</p><p>Из публичных API в 4.0 пропали или стали непрозрачными:</p><ul><li>Engine-интерфейс целиком — <a href="https://www.openssl.org/docs/man3.0/man7/provider.html">providers</a> теперь единственный способ подключить внешнюю криптографию.</li><li>Поддержка SSLv2 Client Hello и SSLv3. SSLv3 деприкейтнули ещё в 2015 году (<a href="https://datatracker.ietf.org/doc/html/rfc7568">RFC 7568</a>), в 1.1.0 выключили по умолчанию в 2016-м, теперь удалили из кода.</li><li>Структура ASN1_STRING стала непрозрачной. Прямой доступ к полям — через функции-аксессоры.</li><li>ERR_get_state(), ERR_remove_state(), ERR_remove_thread_state() — объект ERR_STATE теперь непрозрачный.</li><li>Кастомные методы EVP_CIPHER, EVP_MD, EVP_PKEY, EVP_PKEY_ASN1 — устаревшие API удалены.</li><li>X509_cmp_time() и семейство деприкейтнуты в пользу X509_check_certificate_times().</li><li>Скрипт c_rehash — использовать openssl rehash.</li><li>BIO_f_reliable() — был сломан с 3.0 и без жалоб прожил все эти годы.</li><li>Опция msie-hack в команде openssl ca.</li><li>Таргеты сборки darwin-i386 и darwin-ppc.</li><li>Устаревшие эллиптические кривые в TLS (<a href="https://datatracker.ietf.org/doc/html/rfc8422">RFC 8422</a>) выключены в сборке по умолчанию — включаются флагом enable-tls-deprecated-ec.</li><li>Explicit EC curves — аналогично, флаг enable-ec_explicit_curves.</li></ul><p>Отдельно изменилось поведение глобальной очистки. libcrypto больше не ставит обработчик на atexit(); OPENSSL_cleanup() теперь вызывается как глобальный деструктор при выходе процесса — значит, освобождение памяти по умолчанию происходит позже и в непредсказуемом порядке относительно других деструкторов. Если вам нужна детерминированная очистка до завершения процесса (например, чтобы выявлять утечки под valgrind), вызывайте OPENSSL_cleanup() явно.</p><h2>Что это значит для ГОСТ-криптографии</h2><p><a href="https://github.com/gost-engine/engine">gost-engine</a> — основной проект, который даёт OpenSSL понимание российских алгоритмов (ГОСТ Р 34.10-2012, ГОСТ Р 34.11-2012, «Кузнечик» и «Магма» по ГОСТ Р 34.12-2015). Как понятно из названия, он реализован именно как engine и без engine-слоя собраться и загрузиться в OpenSSL 4.0 не сможет.</p><p>Альтернатива — <a href="https://github.com/provider-corner/gostprov">gostprov</a>, провайдер от того же сообщества на новом API. На 15 апреля 2026 года gostprov покрывает базовые примитивы — ГОСТ Р 34.10-2012 (подпись), ГОСТ Р 34.11-2012 (хеш «Стрибог») и блочный шифр «Магма»/«Кузнечик» (ГОСТ Р 34.12-2015). Что ещё не закрыто по сравнению с gost-engine: часть схем шифрования CMS (ГОСТ-обёртки ключей), VKO KEK-2012 и ряд нишевых TLS-свитов. Если ваш продукт сертифицирован по требованиям ФСБ или продаётся в госсектор — апгрейд на 4.0 нужно планировать заранее, с пересертификацией.</p><p>Ветки 3.x продолжают поддерживаться: 3.5 — LTS до апреля 2030 года, 3.4/3.3 — обычные релизы с обновлениями безопасности. Если с 4.0 спешить некуда — остановитесь на 3.5 и дождитесь, пока gostprov покроет нужные вам примитивы.</p><h2>Что добавили</h2><h3>Encrypted Client Hello (ECH)</h3><p>ECH — это <a href="https://datatracker.ietf.org/doc/rfc9849/">RFC 9849</a>, принятый в марте 2026 года. В обычном <a href="https://tproger.ru/articles/tls-handshake-explained">TLS-рукопожатии</a> первый Client Hello содержит SNI — имя сайта, к которому вы подключаетесь — в открытом виде. Провайдер видит его и по нему можно фильтровать трафик или собирать метаданные. ECH делит Client Hello на две части: ClientHelloOuter с именем фронтового домена идёт в открытую, а ClientHelloInner с настоящим SNI шифруется публичным ключом, опубликованным через DNS (HTTPS-запись).</p><p>OpenSSL 4.0 — первая мажорная версия с ECH в основной ветке. Серверная и клиентская стороны поддерживают draft-final в полном объёме. Документация проекта — <a href="https://github.com/openssl/openssl/blob/master/doc/designs/ech-api.md">doc/designs/ech-api.md</a>.</p><h3>Гибридный постквант: SM2+ML-KEM-768</h3><p>OpenSSL поддерживает ML-KEM (Module-Lattice Key Encapsulation Mechanism, FIPS 203 — постквантовый обмен ключами) и гибриды с ним с версии 3.5. В 4.0 добавили ещё один гибридный обмен — curveSM2MLKEM768: китайский SM2 (<a href="https://datatracker.ietf.org/doc/rfc8998/">RFC 8998</a>) плюс ML-KEM-768 в качестве постквантовой части. Комбинация адресная — она нужна прежде всего для рынка КНР, где SM2 обязателен по национальному стандарту. Плюс новый алгоритм цифровой подписи ML-DSA-MU — вариант <a href="https://tproger.ru/news/openssh-10-3-zakryvaet-shell-injection-i-nachinaet-postkvantovuyu">ML-DSA</a> с внешним префиксом (prehash) для больших сообщений.</p><p>Для остального мира в релизе также появился <a href="https://csrc.nist.gov/pubs/sp/800/185/final">cSHAKE</a> (SP 800-185 — customizable SHAKE, версия SHAKE с доменным разделением). cSHAKE используется как строительный блок в новых стандартах NIST — именно на нём построен KMAC, а также часть постквантовых подписей. Плюс KDF для SNMP и SRTP — узкие штуки, но их в OpenSSL долго не было.</p><h3>FFDHE в TLS 1.2 и прочие мелочи</h3><p>FFDHE (finite-field Diffie-Hellman) по <a href="https://datatracker.ietf.org/doc/html/rfc7919">RFC 7919</a> — способ согласовывать группы для классического DH из фиксированного списка, а не из того, что сервер пришлёт. В TLS 1.3 это сделали сразу, в TLS 1.2 OpenSSL годами поддерживал только «пришли мне параметры». 4.0 закрыл этот пробел.</p><ul><li>FIPS self tests теперь можно откладывать до реального использования — флаг -defer_tests в openssl fipsinstall.</li><li>На Windows можно выбирать статическую или динамическую линковку VC Runtime.</li><li>Нижние границы параметров PKCS5_PBKDF2_HMAC теперь проверяются при работе в FIPS-провайдере.</li><li>Проверка AKID добавлена при установленном X509_V_FLAG_X509_STRICT.</li><li>CRL-верификация получила несколько дополнительных проверок корректности.</li></ul><h2>Как мигрировать на OpenSSL 4.0</h2><ol><li>Не обновляйтесь в лоб. Сначала прогоните вашу сборку с 3.5 и флагами -Wdeprecated-declarations и OPENSSL_NO_DEPRECATED_3_0, чтобы увидеть, где висит engine-API или структурный доступ к ASN1_STRING.</li><li>Составьте карту зависимостей: какие ваши библиотеки линкуются с OpenSSL и какие из них делают что-то нестандартное. Особое внимание — ко всему, где в коде встречается ENGINE_*.</li><li>Если используете ГОСТ — ставьте параллельно gostprov на 3.x, проверьте, что покрываются все ваши примитивы, и только после этого двигайтесь к 4.0.</li><li>Проверьте, как ваше приложение освобождает ресурсы OpenSSL. Если вы полагались на atexit()-финализацию или ранний OPENSSL_cleanup() в середине работы — добавьте явный вызов в точку, где очистка действительно нужна.</li><li>Пересоберите статические пакеты. OpenSSL 4.0 несовместим по ABI с 3.x — пакетные менеджеры дистрибутивов ближайшие месяцы будут подтягивать зависимости.</li></ol><h2>Выводы</h2><p>OpenSSL 4.0 — релиз не столько про новые фичи, сколько про дочистку хвостов. За четыре с половиной года команда вывела из эксплуатации несколько слоёв устаревшего API и зафиксировала архитектуру providers как единственный способ подключать внешнюю криптографию. Цена — несовместимость по исходникам и ABI. На 15 апреля 2026 года крупные пакеты Debian, Ubuntu, RHEL и Fedora ещё линкуются с 3.x; пересборка экосистемы займёт месяцы, а для продуктов на engines (HSM-адаптеры, gost-engine, старые PKCS#11-драйверы) — ещё дольше.</p><p>Практический совет: если у вас нет конкретной нужды в ECH или SM2+ML-KEM-768, ближайший год можно спокойно сидеть на 3.5 LTS и следить за тем, как пересобираются ваши зависимости. Когда пакетные менеджеры дистрибутивов начнут подтягивать 4.0 автоматически — это и будет момент серьёзной миграции.</p><p>Полный changelog, downloadable tarballs и ключи для проверки подписи — на странице <a href="https://github.com/openssl/openssl/releases/tag/openssl-4.0.0">релиза на GitHub</a>. Сам <a href="https://github.com/openssl/openssl/blob/openssl-4.0.0/CHANGES.md">файл CHANGES.md</a> — хорошее чтение на вечер для всех, кто хоть раз линковал с OpenSSL.</p>]]></content:encoded>
    </item>
    <item>
      <title>9 нативных API браузера вместо npm-пакетов</title>
      <link>https://tproger.ru/translations/9-nativnyh-api-brauzera-vmesto-npm-paketov</link>
      <comments>https://tproger.ru/translations/9-nativnyh-api-brauzera-vmesto-npm-paketov?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/9-nativnyh-api-brauzera-vmesto-npm-paketov</guid>
      <description><![CDATA[<p>9 встроенных API браузера вместо npm-пакетов: requestIdleCallback, :focus-within, container queries, dialog, Speech API и другие — с примерами кода.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/9-nativnyh-api-brauzera-vmesto-npm-paketov">9 нативных API браузера вместо npm-пакетов</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 10 Apr 2026 07:45:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если вы привыкли ставить npm-пакет под каждую задачу — вот девять вещей, под которые давно существует нативный API браузера. Кода меньше, багов меньше, бандл легче. Статья польской разработчицы Sylwia Łask собрала самые показательные примеры — перевели и адаптировали для русскоязычного читателя.</p><ul><li>requestIdleCallback — запустить фоновую задачу, когда браузер простаивает</li><li>:focus-within — стилизовать родителя, внутри которого есть элемент в фокусе</li><li>navigator.onLine + события offline/online — детектировать пропажу интернета</li><li>requestAnimationFrame — плавная анимация без рывков</li><li>Container queries — адаптив относительно размеров контейнера, а не viewport</li><li>crypto.getRandomValues — криптографически стойкие случайные ID без коллизий</li><li>&lt;dialog&gt; — нативный модал с доступностью из коробки</li><li>Web Speech API — распознавание речи без библиотек (только Chromium)</li><li>@supports — CSS feature detection без костылей</li></ul><h2>1. «Запустим это потом» → requestIdleCallback</h2><p>Хотите собирать аналитику, предзагружать данные или генерировать что-то в фоне, не конкурируя с рендером 200 компонентов? requestIdleCallback запускает ваш код в те моменты, когда браузер простаивает. На первый взгляд это кажется узкоспециальной фичей, но на практике кейсов много: сбор аналитики о поведении пользователя, несрочная фоновая обработка картинок, предварительная подготовка данных, которые пригодятся позже.</p><p>Поддержка: современные браузеры. В Safari исторически отсутствовал, так что fallback на setTimeout всё ещё полезен.</p><h2>2. «Почему мой input не подсвечивается?» → :focus-within</h2><p>Стилизовать элемент с фокусом — просто. А как стилизовать родителя, внутри которого какой-то элемент получил фокус, — задача, которую обычно решают сорока строками JavaScript со слушателями focus и blur. Всё это не нужно: :focus-within делает то же самое одной CSS-строкой.</p><p>Поддержка: везде, где это хоть сколько-нибудь важно.</p><h2>3. «Покажем офлайн-режим» → navigator.onLine</h2><p>Вечная боль любого PWA — что делать, когда у пользователя пропал интернет (он уехал в лес или зашёл в лифт). Можно писать сложные if-ы — а можно просто слушать события offline и online. На offline складываем данные в IndexedDB, на online отправляем на сервер.</p><p>Поддержка: широкая. Одна оговорка: «онлайн» не равно «ваш бэкенд доступен». Это проверка уровня сетевого соединения, а не доступности конкретного сервиса.</p><h2>4. «Плавная анимация, но проклятая» → requestAnimationFrame</h2><p>Хотите, чтобы анимация не дёргалась на слабых ноутбуках, а батарея садилась медленнее? Привычка «60 fps = setInterval каждые 16 мс» — плохая идея, и вот почему. Классика, которую все видели:</p><p>Интуитивно понятно, что это плохая идея. Лагает. К счастью, есть requestAnimationFrame — он синхронизирован с циклом перерисовки браузера, поэтому анимация действительно плавная.</p><p>Поддержка: везде.</p><h2>5. «Карточка должна адаптироваться, но только здесь» → container queries</h2><p>Одну и ту же карточку можно положить в узкий сайдбар, в основную ленту или в лайтбокс — и чтобы она корректно подстраивалась под каждое место без знания о том, на каком она экране. Раньше media queries были привязаны к размеру viewport, то есть «ко всей странице». Container queries позволяют применять стили в зависимости от размера конкретного контейнера. Компонент становится самодостаточным: куда положили — под то и подстроился.</p><p>Поддержка: современные браузеры. Если целитесь в старые — добавьте fallback через обычные media queries.</p><h2>6. «Случайный ID, что может пойти не так?» → crypto.getRandomValues</h2><p>Именно так рождаются баги:</p><p>Выглядит как «достаточно случайная» криптография с AliExpress — и работает, пока не перестаёт. Во-первых, всё зависит от реализации движка, мы не знаем, что происходит под капотом. Во-вторых, определённые паттерны вполне возможны, а при большом количестве ID вы фактически напрашиваетесь на коллизии.</p><p>К счастью, есть нативное решение. Не серебряная пуля, но crypto.getRandomValues заметно лучше: больше энтропии, нет странных паттернов, вероятность коллизий резко снижается. Браузер просто делает это правильно. А если вам нужен не произвольный набор байтов, а именно UUID, в современных браузерах есть ещё короче: crypto.randomUUID() выдаёт готовый UUID v4 одной строкой — тоже криптографически стойко и без ручной возни с байтами.</p><p>Поддержка: широкая.</p><h2>7. «Нам нужен модал» → dialog</h2><p>Больше не нужно ставить 12-килобайтную библиотеку ради модального окна, которое так любят пользователи. Нативный &lt;dialog&gt; даёт клавиатурную навигацию, фокус-трап и корректную работу со скринридерами прямо из коробки — всё то, что в самописных модалах обычно забывают или делают криво.</p><p>Поддержка: современные браузеры.</p><h2>8. «Голосовой ввод был бы крутой фичей» → Web Speech API</h2><p>Собирались ставить transformers.js, потому что понадобилось распознавание речи? У браузера для этого уже есть Web Speech API. Chromium-браузеры поддерживают его напрямую, Safari — через префиксную версию webkitSpeechRecognition (код ниже как раз это учитывает), в Firefox поддержки нет. Для демо и ассистивных фич — отлично, в проде лучше иметь запасной план на случай Firefox.</p><p>Поддержка: Chromium и Safari (через webkit-префикс), в Firefox до сих пор нет.</p><h2>9. «Не сломает ли это CSS?» → @supports</h2><p>Хотите выкатить backdrop-filter или :has() и при этом не сломать вёрстку в браузере, где фича ещё не поддерживается? Оборачиваем в @supports — и спокойны: браузер, который знает фичу, получит красивую версию, остальные — дефолтный fallback.</p><p>Поддержка: очень хорошая.</p><h2>Когда всё-таки нужна библиотека</h2><p>Библиотеки — это отлично, и иногда они действительно необходимы. Но иногда вы ставите зависимость на то, что браузер решил годы назад. Перед npm install полезно спросить себя (или поискать в MDN): «А браузер не умнее меня в этом вопросе?» Иногда ответ — да. И это нормально.</p><p>Источник: <a href="https://dev.to/sylwia-lask/9-things-youre-overengineering-the-browser-already-solved-them-o99">Sylwia Łask — 9 things you're overengineering: the browser already solved them</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>USB для разработчиков: как написать драйвер из пользовательского пространства</title>
      <link>https://tproger.ru/translations/usb-dlya-razrabotchikov-kak-napisat-drajver-iz-polzovatelskogo</link>
      <comments>https://tproger.ru/translations/usb-dlya-razrabotchikov-kak-napisat-drajver-iz-polzovatelskogo?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/usb-dlya-razrabotchikov-kak-napisat-drajver-iz-polzovatelskogo</guid>
      <description><![CDATA[<p>Написать USB-драйвер не сложнее, чем приложение с сокетами — без кода ядра. Endpoint как порты, 4 типа передачи, libusb API и Fastboot-клиент за 50 строк.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/usb-dlya-razrabotchikov-kak-napisat-drajver-iz-polzovatelskogo">USB для разработчиков: как написать драйвер из пользовательского пространства</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 09 Apr 2026 10:30:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Вам вручили USB-устройство и попросили написать для него драйвер. Звучит страшно? На самом деле это не сложнее, чем написать приложение с сокетами. Не нужно лезть в ядро — всё можно сделать из пользовательского пространства с помощью библиотеки <a href="https://libusb.info">libusb</a>.</p><p>Это перевод <a href="https://werwolv.net/posts/usb_for_sw_devs">статьи</a> WerWolv — введение в USB для разработчиков, которые не работали с железом. Концепции объясняются через аналогию с сетевым программированием, а практический пример — реализация протокола Android Fastboot.</p><ul><li>USB-драйвер можно написать целиком в userspace через libusb — без кода ядра</li><li>Endpoint в USB — аналог порта в TCP: устройство сообщает, какие «порты» открыты и какой протокол используют</li><li>4 типа передачи: Control (конфигурация), Bulk (большие данные), Interrupt (низкая задержка), Isochronous (аудио/видео)</li><li>USB — master-slave: хост всегда инициирует обмен, устройство только отвечает</li><li>Практический пример: полноценный Fastboot-клиент на C++ за ~50 строк кода</li></ul><h2>USB — это как сеть</h2><p>Ключевая мысль статьи: USB можно понимать через аналогию с сетевым программированием. Endpoint — это порт, на который устройство принимает данные. Дескриптор устройства — аналог DNS, который говорит, кто это и какие «сервисы» доступны. Вам не нужно быть инженером встраиваемых систем, чтобы работать с USB — как не нужно быть сетевым специалистом, чтобы работать с сокетами.</p><h2>Шаг 1: узнаём, что за устройство</h2><p>При подключении устройства хост запрашивает у него информацию — это называется enumeration. На Linux это можно увидеть через lsusb:</p><p>Здесь 18d1 — Vendor ID (Google), 4ee0 — Product ID (загрузчик Pixel). Это уникальные идентификаторы, по которым хост находит нужный драйвер. VID выдаётся организацией USB-IF компаниям за деньги, PID назначает сам производитель.</p><p>Более подробный вывод:</p><p>Driver=[none] означает, что ОС не загрузила драйвер — именно то, что нужно для написания своего.</p><h2>Шаг 2: общаемся через libusb</h2><p>Библиотека <a href="https://libusb.info">libusb</a> позволяет общаться с USB-устройствами из пользовательского пространства. Она предоставляет универсальный драйвер и API для отправки запросов — без написания кода ядра.</p><p>Пример: обнаружение устройства по VID:PID и получение дескриптора через Control endpoint:</p><p>Каждое USB-устройство имеет Control endpoint на адресе 0x00 — это стандартизированная «точка входа», через которую хост получает дескрипторы (кто устройство, какие интерфейсы, какие endpoint'ы). Аналогия: это как DNS-запрос перед подключением.</p><h2>Endpoint'ы: порты USB-устройства</h2><p>Endpoint'ы — аналог портов на сетевом устройстве. Устройство описывает в дескрипторе, какие endpoint'ы доступны и какой протокол каждый из них использует. Четыре типа:</p><ul><li><b>Control</b> — один на устройство, адрес 0x00. Для конфигурации и запроса информации. Решает проблему курицы и яйца: чтобы узнать endpoint'ы, нужен endpoint — и это он</li><li><b>Bulk</b> — большие объёмы данных, низкий приоритет. Используется в Mass Storage (флешки), CDC-ACM (Serial over USB), RNDIS (Ethernet over USB)</li><li><b>Interrupt</b> — маленькие данные, минимальная задержка. Клавиатуры и мыши опрашиваются 1000+ раз в секунду через HID. Название обманчивое: реальных прерываний нет, хост просто очень часто опрашивает</li><li><b>Isochronous</b> — потоковые данные с гарантией тайминга. Аудио и видео, где задержка означает заикание</li></ul><p><b>IN и OUT:</b> USB — master-slave протокол, устройство никогда не говорит первым. IN = хост просит данные «к себе», OUT = хост отправляет данные «от себя». Направление кодируется в старшем бите адреса endpoint'а.</p><h2>Практика: Fastboot-клиент за 50 строк</h2><p>Протокол Fastboot (<a href="https://android.googlesource.com/platform/system/core/+/master/fastboot/README.md">документация</a>) предельно прост: хост отправляет строковую команду, устройство отвечает 4-символьным статусом + данные:</p><p>Реализация через libusb — отправляем команду на OUT Bulk endpoint, читаем ответ с IN Bulk endpoint:</p><p>Это всё. Два вызова libusb — и мы общаемся с загрузчиком Android без единой строки кода ядра.</p><p>Полный текст с исходным кодом: <a href="https://werwolv.net/posts/usb_for_sw_devs">USB for Software Developers</a>, WerWolv.</p>]]></content:encoded>
    </item>
    <item>
      <title>Почему ваш канал связи — не ваш. История о том, как паранойя заставила меня написать свой мессенджер с нуля.</title>
      <link>https://tproger.ru/articles/pochemu-vaw-kanal-svyazi---ne-vaw--istoriya-o-tom--kak-paranojya-zas</link>
      <comments>https://tproger.ru/articles/pochemu-vaw-kanal-svyazi---ne-vaw--istoriya-o-tom--kak-paranojya-zas?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[igrym]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/pochemu-vaw-kanal-svyazi---ne-vaw--istoriya-o-tom--kak-paranojya-zas</guid>
      <description><![CDATA[<p>Вернул UIN-ы из нулевых и завернул всё в PWA: как я писал свой мессенджер, балансируя между ностальгией и Highload</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/pochemu-vaw-kanal-svyazi---ne-vaw--istoriya-o-tom--kak-paranojya-zas">Почему ваш канал связи — не ваш. История о том, как паранойя заставила меня написать свой мессенджер с нуля.</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Мессенджер]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Песочница]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 04 Apr 2026 14:35:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>В какой-то момент я понял неприятную вещь: если твой канал связи живет по чужому настроению, политической погоде, сбою в чужом облаке или очередной внезапной любви регулятора к кнопке «запретить» — это не твой канал связи. Это аренда с правом внезапного выселения.</p><p>Мне эта модель быстро наскучила.</p><p>Поэтому я сделал то, что обычно делают люди с нездоровой смесью инженерной паранойи, скуки и профессиональной деформации: психанул и начал писать свой мессенджер.</p><p>Сразу зафиксируем рамки, чтобы не плодить фантомные ожидания:</p><p>- это не убийца Telegram;</p><p>- это не презентация для инвестора с KPI и growth loops;</p><p>- это не проповедь о том, как всем теперь жить.</p><p>Это мой личный цифровой бункер, моя песочница, мой учебный полигон и мой инженерный аттракцион. Я строю это прежде всего для себя: как резервный канал связи, как способ не зависеть от чужих решений и как честный highload-эксперимент, в котором можно не рассуждать про real-time в теории, а ловить его за горло руками.</p><p>И вот здесь началось смешное.</p><p>Я рассчитывал на бодрую гаражную поделку. Но эта штука оказалась заметно живее, упрямее и интереснее, чем я ожидал. Поэтому я и притащил ее на TProger. Не за аплодисментами. За самым ценным, что здесь умеют делать лучше многих: находить слабое место раньше, чем автор успевает самодовольно сказать «ну вроде едет».</p><h2>Что это вообще такое</h2><p>На текущем этапе это PWA-мессенджер.</p><p>Да, PWA. Да, осознанно. Да, я знаю весь стандартный набор комментариев про ограничения платформы, кривые пуши, фоновые ограничения и то, что</p><p>«настоящие пацаны пишут только натив». Можете не разогреваться, я это всё уже сам себе рассказал.</p><p>Почему все равно PWA:</p><p>- мне нужен был короткий путь от идеи до живого клиента;</p><p>- мне нужен был быстрый цикл выката без ритуальных танцев с</p><p>магазинами приложений;</p><p>- мне нужен был клиент, который можно быстро ломать, чинить,</p><p>пересобирать и снова кидать в бой;</p><p>- мне нужно было что заработает на разных платформах;</p><p>- мне нравится, что PWA живет в браузерной песочнице, а не лезет в телефон как хозяин квартиры.</p><p>У PWA есть реальные потолки:</p><p>- нет такой свободы по платформенным API, как у нативного клиента;</p><p>- фон, пуши и некоторые сценарии мобильной жизни работают хуже, чем</p><p>хотелось бы;</p><p>- нет нормальных VoIP-пушей (звонки работают только когда приложение</p><p>открыто), нет нормальной интеграции со списком вызовов телефона;</p><p>- по голой производительности натив его обгоняет.</p><p>И, да, Service Workers иногда ведут себя как подростки в пубертате, а iOS местами режет фоновую жизнь PWA так, будто лично обиделась на идею веб-клиента. Я в курсе. Выживаем с тем, что есть.</p><p>Но для моей задачи PWA дал главное: скорость эволюции. А в экспериментальном проекте это иногда важнее, чем стерильная идеология.</p><p>И да, работает эта штука подозрительно хорошо. Лучше, чем я ожидал, если честно.</p><h2>Зачем вообще писать еще один мессенджер, когда мир и так ими забит</h2><p>Потому что «и так забит» — плохой аргумент, когда существующие варианты в любой момент могут начать вести себя как полуживые.</p><p>Потому что я люблю контролировать инфраструктуру, а не молиться на чужую.</p><p>Потому что читать статьи про очереди, ретраи, доставку, порядок сообщений и борьбу с race condition — это теория. А написать свое, увидеть, где оно течет, и потом руками это затыкать — уже ремесло.</p><p>Потому что мне скучно.</p><p>Да, это тоже важная часть правды. На обычной работе мозг периодически начинает зевать от предсказуемости. А когда ты в одиночку пытаешься собрать живой real-time-сервис, где есть сессии, доставка сообщений, поиск, синхронизация состояния, очереди и weird cases мобильной сети —</p><p>то зевота быстро заканчивается.</p><p>То есть да: это учебный проект. Но из тех учебных проектов, которые в какой-то момент говорят: «всё, детский сад закончился, теперь давай как взрослые».</p><p>Где начинаются не разговоры про highload, а настоящая инженерная жизнь</p><p>Пока не собираешь такое сам, кажется, что мессенджер — это просто чатик.</p><p>Ну текстик, ну websocket, ну кнопка «отправить», господи. А потом начинается взрослая часть спектакля.</p><h3>1. Сообщение должно не просто уйти, а дойти правильно</h3><p>Самая скучная и самая дорогая ошибка — считать, что «отправил» значит</p><p>«доставил».</p><p>Нет. В реальной жизни между клиентом, сетью, сервером и хранилищем полно мест, где всё может стать интересно:</p><p>- клиент послал пакет, но сеть моргнула;</p><p>- сервер принял, но клиент не получил подтверждение;</p><p>- клиент решил, что ничего не дошло, и отправил повторно;</p><p>- внезапно у тебя уже не просто доставка, а идемпотентность,</p><p>дедупликация, подтверждения, ретраи и очень неприятные разборки с</p><p>дублями.</p><p>И это только один кусок.</p><h3>2. Порядок сообщений — штука гораздо более капризная, чем кажется</h3><p>Пользователь хочет простой магии: чтобы сообщения были в нужном порядке, статусы не врали, а история не прыгала, как пьяный курсор.</p><p>Инженерная реальность куда веселее:</p><p>- локальный optimistic update на offline-first клиенте хочет быть</p><p>быстрым;</p><p>- серверная истина хочет быть правильной;</p><p>- база хочет жить в своей временной линии;</p><p>- несколько устройств одного пользователя могут в это время смотреть на</p><p>мир разными глазами.</p><p>Как только начинаешь совмещать низкую задержку с внятной консистентностью, выясняется, что ты не «чатик пишешь», а торгуешься с физикой и распределенными состояниями.</p><h3>3. Race condition — это когда баг уже произошел, но ты еще не знаешь, где именно тебя унизили</h3><p>Race conditions — мой любимый жанр инженерного фольклора. Это когда всё прекрасно, пока ты смотришь. И ломается ровно в тот момент, когда отвлекся налить кофе.</p><p>Условно:</p><p>- один поток думает, что пользователь в онлайне;</p><p>- второй уже считает, что он отвалился;</p><p>- третий в это время честно пишет новое состояние;</p><p>- четвертый с невинным лицом отдает клиенту вчерашнюю правду.</p><p>А потом ты сидишь и объясняешь себе, почему в 99.7% случаев всё идеально, а в оставшихся 0.3% система внезапно начинает разговаривать голосами. А когда еще и пытаешься заставить работать реалтайм систему еще в кластере, то все сложности возводятся в квадрат.</p><h4>4. Любая «маленькая фича» очень быстро приходит за твоей архитектурой с ножом</h4><p>Захотел новую механику? Например, необычную резервацию UIN еще до регистрации? На бумаге выглядит забавно. На бэкенде начинается вечеринка:</p><p>- появляется состояние для еще не существующего пользователя;</p><p>- нужно резервировать ресурс так, чтобы его не вымели любопытные и жадные боты;</p><p>- нужно думать о TTL, освобождении, гонках, повторных запросах и кривом клиентском поведении;</p><p>- нужно следить, чтобы веселая фича не превратилась в атаку на собственную логику.</p><p>И вот так почти всё. В продуктовых презентациях фича может подаваться как «геймификация входа». В серверной реальности — «еще один слой боли, зато красиво».</p><h3>5. Поиск и история сообщений сначала кажутся простыми. Потом ты взрослеешь</h3><p>Пока данных мало, Postgres прощает тебе оптимизм. Потом история растет, индексы начинают намекать, что дружба дружбой, а latency по расписанию, и любой неаккуратный запрос внезапно становится личным конфликтом с CPU.</p><p>И тут выясняется, что в реальном мессенджере мало просто «хранить сообщения». Нужно еще:</p><p>- быстро искать;</p><p>- не ломать горячий путь доставки;</p><p>- не превращать сервер в печку под нагрузкой;</p><p>- думать наперед, где потом начнется горизонтальное масштабирование, а</p><p>где сначала будет боль, потом переписывание, потом снова боль.</p><p>Чтобы это не выглядело как очередная литература про «сложности highload», вот живой пример. Это кусок поиска по групповым сообщениям в моем бекенде: с проверкой доступа, выборкой только текстовых сообщений и сортировкой по релевантности.</p><p>Под этот запрос у меня лежит не молитва, а вполне конкретная опора: partial GIN index по выражению`(content-&gt;&gt;'text') gin_trgm_ops`.Иначе такая красота очень быстро превращает сервер в отопление стойки за счет тупого перебора JSONB.</p><p>А вот так тот же самый функционал очень часто пишут новички — вроде работает, пока данных смешно мало:</p><p>Проблема тут не в эстетике. Проблема в том, что верхний вариант ищет по нужному полю, умеет нормально ранжировать результат и опирается на индекс. Нижний часто уезжает в тяжелый scan по JSONB, ищет по строковому представлению всего объекта и под нагрузкой начинает жечь CPU просто потому, что автору было лень договориться с базой по-хорошему.</p><p>На реальном объеме истории в проде разница здесь может быть уже не в процентах, а на порядок и выше. То есть это очень быстро превращается не в «чуть-чуть быстрее», а в 10x+, а дальше всё зависит от размера истории, доли текстовых сообщений, партиций и того, насколько сильно вы любите мучить PostgreSQL.</p><p>И это еще сравнительно добрый пример. В по-настоящему наивной реализации люди (да часто и нейросети в руках новичков) иногда забывают не только про индекс и ранжирование, но и про нормальную проверку членства в чате — и тогда у тебя получается не просто медленный поиск, а еще и билет в секцию «как я сам себе устроил privacy-инцидент».</p><h3>6. Очереди, ретраи и backpressure — это не украшения, а повод спать чуть спокойнее</h3><p>В сетевом сервисе нельзя жить по принципу «ну отправили и ладно». Когда клиентов много, а сеть у части из них вечно в состоянии «между EDGE и молитвой», тебе нужны механизмы, которые умеют не только гнать трафик, но и не убивать систему собственным рвением.</p><p>То есть нужны:</p><p>- очереди (Kafka, или что вы там предпочитаете);</p><p>- повторные попытки (retry-логика);</p><p>- backpressure;</p><p>- вменяемая реакция на временную деградацию (graceful degradation);</p><p>- circuit breaker чтобы какой-нибудь маленький и вроде бы некритичный сервис не мог каскадно положить бы всю инфраструктуру;</p><p>- архитектура, которая умеет признавать, что мир не идеален.</p><p>Красиво это звучит только в статьях. В коде это обычно выглядит как серия компромиссов, которые ты принимаешь с лицом человека, только что подписавшего договор с хаосом. И все это когда у тебя нет сотен высокопроизводительных серверов в кармане, которые уже лишь за счет их мощности могли бы прощать многое.</p><h2>Интерфейс я подсматривал у Telegram. И да, специально</h2><p>Я не стал устраивать дизайнерский карнавал ради уникальности. У пользователя уже есть мышечная память. Она дороже моего самолюбия.</p><p>Если человек открывает новый мессенджер, он хочет быстро разобраться и написать сообщение. Ему не нужен артхаус-квест «найди кнопку отправки, автор так видит».</p><p>Поэтому UI здесь знакомый. Не потому что я беден фантазией, а потому что я делаю инструмент связи, а не выставку интерфейсного концептуализма.</p><figure><img src="https://media.tproger.ru/user-uploads/136500/2026-03-17/d42e785c-1951-43a6-b560-bc03d1f503a2.webp" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/136500/2026-03-17/7f9a0d02-7637-41c9-8ca1-408153554887.webp" alt="" /></figure><h2>Моя любимая инженерная шалость: UIN-рулетка до регистрации</h2><p>Тут я, конечно, немного похулиганил.</p><p>Я сделал резервацию UIN еще до этапа регистрации. То есть можно зайти, поймать красивый номер, а уже потом решить, нужен тебе вообще этот зоопарк или нет.</p><p>С человеческой стороны это фан, ностальгия и немного ICQ-вайба.</p><p>С серверной стороны это пачка вопросов:</p><p>- как хранить состояние для «почти-пользователя»;</p><p>- как не раздать красивые номера слишком щедро;</p><p>- как не дать мимо проходящему ботнету выгрести пул;</p><p>- как освобождать резервы и не плодить мусор;</p><p>- как не застрелить логическую целостность ради красивой игрушки.</p><p>С практической точки зрения миру, возможно, и не нужна эта фича. С инженерной — она просто слишком вкусная, чтобы я прошел мимо.</p><h2>Про безопасность — без дешевой магии и без сказок для инвестора</h2><p>Нет, я не изобретал свою криптографию. Я вообще считаю, что желание «сейчас быстренько придумаю свой защищенный протокол» должно автоматически активировать тревожную сирену. Да, создать защищенный протокол возможно, но это сложнее и дольше чем кажется из-за необходимости учета множества edge-cases; и в реальности сделанные на коленке протоколы чаще ненадежны, и, что еще хуже, об их уязвимостях могут знать лишь немногие пронырливые и порой не самые добросовестные люди.</p><p>Поэтому мой подход скучный, взрослый и не очень годится для красивых презентаций:</p><p>- транспорт закрыт современным TLS 1.3 (который на текущий момент, март 2026, взломать прямым криптографическим методом практически невозможно);</p><p>- клиент живет как PWA в браузерной песочнице, какая уже сама по себе имеет ряд уровней защиты;</p><p>- поверх этого я стараюсь не творить откровенной дичи;</p><p>Но важная оговорка, и она принципиальна: проект развивается быстро, агрессивно и временами как лаборатория под кофеином. Некоторые части еще могут отваливаться на ходу. Какие-то углы я уже вижу. Какие-то, уверен, еще нет.</p><p>Поэтому, несмотря на базово вменяемый современный уровень безопасности приложения, я не рекомендую сейчас доверять системе особо чувствительные данные.</p><p>Если вам нужна зрелая крепость для деликатной переписки — берите зрелые решения, которым вы уже доверяете.</p><p>Если вам нужен живой инженерный эксперимент, резервный канал связи и объект для вдумчивого краш-теста — вот он.</p><h2>Почему я вообще тащу это именно на TProger</h2><p>Потому что TProger — это место, где тексту мало быть наглым. Здесь за дерзость прощают только одно: если под ней есть мясо.</p><p>А у меня как раз тот случай, когда мне интереснее не «собрать лайки», а получить нормальную техническую реакцию:</p><p>- где архитектура выглядит спорно;</p><p>- где логика доставки сообщений может начать чудить;</p><p>- где PWA упрется в реальные ограничения платформы;</p><p>- где резервация UIN создает лишнюю поверхность атаки;</p><p>- где под нагрузкой начнет хрустеть то, что в одиночных тестах ведет себя прилично;</p><p>- где в протоколе, порядке событий, ретраях или кешировании я недооценил крайний случай.</p><p>Мне не нужен хор в духе «вау, круто».</p><p>Мне нужен ваш внутренний вредный сеньор. Тот самый тип, который открывает статью, хмыкает, а потом начинает мысленно разбирать чужую систему на части.</p><p>Вот ему я и пишу.</p><h2>Что я от вас хочу</h2><p>По сути — честной драки, но умной.</p><p>- Хотите проверить, как это переживает плохую сеть — отлично.</p><p>- Хотите посмотреть, как выглядит поведение в edge-cases — вообще прекрасно.</p><p>- Хотите понять, насколько легко читается логика протокола — давайте.</p><p>- Хотите найти баг в порядке сообщений, в кеше, в подтверждениях, в резервации UIN, в клиентском поведении — тем более.</p><p>Только давайте без детского жанра «я что-то молча сломал и ушел сиять в закат». Если найдете слабое место, баг, странность, дыру, подозрительный сценарий или красивый способ заставить систему вести себя не так, как я планировал, — пишите.</p><p>Мне это полезнее, чем аплодисменты.</p><p>И да: я не заявляю, что построил новый и единственно верный мессенджер.</p><p>Я заявляю другое. Я собрал свой рабочий велосипед, уже довольно злой и живой, и мне интересно, где именно TProger попробует вставить ему отвертку в спицы, и на какой секунде этот велосипед упадет.</p><p>Что можно делать прямо сейчас</p><p>- Если вы параноик или устали от мейнстрима и навязанных решений — держите это как запасной канал связи.</p><p>- Если вы соскучились по временам красивых UIN — приходите ловить UIN-номер.</p><p>- Если вы любите sniff, разбор трафика и сетевые игры — смотрите что идет по проводу.</p><p>- Если у вас профессиональная привычка первым делом искать edge-cases — вот, собственно, ради вас всё это и принесено.</p><p>И если что-то положите, вскроете или красиво разберете — пришлите детали. Я не обидчивый. Я, строго говоря, именно ради этого и открыл двери.</p><h2>Что дальше</h2><p>Планы без корпоративной шелухи, но вполне понятные:</p><p>- дальше допиливаю PWA-версию;</p><p>- нативные Android и iOS-клиенты — в планах, но пока не в приоритете;</p><p>- клиентскую часть, вероятно, позже открою, когда там станет меньше творческого барокко;</p><p>- идея с SDK / библиотекой для кастомных клиентов мне нравится отдельно: если люди захотят писать свои оболочки, это будет уже совсем красивый уровень игры.</p><p>Исходники сейчас закрыты. Не потому что я жадничаю или прячу священный секретный соус, а потому что местами там еще такой авторский лофт из боевых решений, экспериментов, временных костылей и честной инженерной импровизации, что сначала я предпочту сам это немного причесать.</p><h2>Итог</h2><p>На сегодня это экспериментальный PWA-мессенджер, который родился из упрямства, паранойи, скуки и любви к инженерным задачам, от которых нормальные люди обычно стараются держаться подальше.</p><p>Я делал его в первую очередь для себя. Но он уже дорос до стадии, когда его интересно не только строить, но и показывать наружу.</p><p>Если будете пробовать — лучше сразу добавить его на домашний экран (PWA так устанавливается). Так приложению жить будет заметно удобнее: платформа позволит заработать пуш-уведомлениям, появится нормальное кеширование, а оффлайн-режим перестанет быть декоративной надписью.</p><p>Если хотите просто еще один канал связи — пожалуйста.</p><p>Если хотите посмотреть и проверить, насколько крепок мой цифровой эксперимент, — тем более пожалуйста.</p><p>Если хотите проверить заодно и собственные навыки на живой системе, которая не притворяется идеальной, — вот, собственно, и весь смысл этой публикации.</p><p>Добро пожаловать.</p><p>Посмотрим, кто кого утомит первым: вы — мой сервер, я — ваши попытки его удивить, или реальность — нас обоих.</p><p><b>PS:</b></p><p>Меня там можно найти по нику IGRYM или по UIN 10001. Также есть внутренняя группа для первых пользователей (Early Birds, доступна на экране списка чатов через «+» вверху экрана)</p><p>Ссылки:</p><p>- Приложение: https://beta.plumb-app.ru/</p><p>- Телеграм-канал с новостями проекта: https://t.me/plumb_channel</p><p>- Телеграм-группа обсуждения: https://t.me/plumb_group</p>]]></content:encoded>
    </item>
    <item>
      <title>LocalStack стал платным — MiniStack заменяет его бесплатно: 33 AWS-сервиса, реальный Postgres и 2 секунды на старт</title>
      <link>https://tproger.ru/news/localstack-stal-platnym---ministack-zamenyaet-ego-besplatno--33-a</link>
      <comments>https://tproger.ru/news/localstack-stal-platnym---ministack-zamenyaet-ego-besplatno--33-a?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Алексей Михайлишин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/localstack-stal-platnym---ministack-zamenyaet-ego-besplatno--33-a</guid>
      <description><![CDATA[<p>MiniStack эмулирует 33 AWS-сервиса на одном порте с реальным Postgres, Redis и Docker. Запуск за 2 секунды, 30 МБ RAM, MIT-лицензия. Полная замена платного LocalStack.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/localstack-stal-platnym---ministack-zamenyaet-ego-besplatno--33-a">LocalStack стал платным — MiniStack заменяет его бесплатно: 33 AWS-сервиса, реальный Postgres и 2 секунды на старт</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Open Source]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 01 Apr 2026 07:15:20 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://localstack.cloud/">LocalStack</a> долгое время был стандартом для локальной эмуляции AWS-сервисов — бесплатный, удобный, с поддержкой S3, SQS, DynamoDB и десятков других API. Но в начале 2026 года базовые сервисы переехали за пейволл: даже S3 и Lambda теперь требуют платной подписки от $35/мес.</p><p>Разработчик <b>Nahuel Nucera</b> решил эту проблему: <a href="https://github.com/Nahuel990/ministack">MiniStack</a> — полностью бесплатная замена LocalStack с открытым исходным кодом, которая эмулирует 33 AWS-сервиса на одном порте. И, в отличие от LocalStack, запускает <b>настоящие</b> базы данных и контейнеры вместо мок-заглушек.</p><p><b>MiniStack</b> — бесплатная open-source замена LocalStack (MIT-лицензия)</p><p>33 AWS-сервиса на одном порте — S3, SQS, DynamoDB, Lambda, IAM, RDS, ElastiCache, ECS и другие</p><p>Реальная инфраструктура: RDS поднимает настоящий Postgres, ElastiCache — настоящий Redis, ECS — Docker-контейнеры</p><p>Запуск за 2 секунды, 30 МБ RAM в простое (vs 30 секунд и 500 МБ у LocalStack)</p><p>Drop-in совместимость с boto3, AWS CLI, Terraform, CDK, Pulumi</p><h2>Почему LocalStack стал платным</h2><p>LocalStack сменил лицензию с Apache 2.0 на <b>Business Source License</b> (BSL) и перенёс ключевые сервисы — S3, SQS, Lambda, IAM, Cognito, EC2 — в платный тир. Бесплатная версия <a href="https://localstack.cloud/pricing/">LocalStack Community</a> фактически перестала покрывать базовые сценарии локальной разработки.</p><p>Для коммерческих команд LocalStack Pro стоит от $35/мес на разработчика. Для опенсорс-проектов и индивидуальных разработчиков это создало вакуум — и MiniStack его заполнил.</p><h2>Что умеет MiniStack</h2><p>MiniStack — это один Python ASGI-сервер, который эмулирует AWS API на порте 4566. Ваши существующие boto3-клиенты, Terraform-провайдеры, CDK-стеки и AWS CLI работают без изменений — достаточно указать endpoint.</p><h3>33 поддерживаемых сервиса</h3><ul><li><b>Хранилище:</b> S3 (с версионированием, Object Lock, CORS, lifecycle), EBS, EFS</li><li><b>Очереди и события:</b> SQS (FIFO + DLQ), SNS (fanout в SQS и Lambda), EventBridge, Kinesis, Firehose</li><li><b>Базы данных:</b> DynamoDB (TTL, транзакции), RDS (реальный Postgres/MySQL), ElastiCache (реальный Redis), Athena (реальный SQL через DuckDB)</li><li><b>Вычисления:</b> Lambda (реальное исполнение Python, warm pool), ECS (реальные Docker-контейнеры), Step Functions, EMR</li><li><b>Сеть и безопасность:</b> EC2 (instances, VPC, subnets, security groups), ALB/ELBv2, Route53, Cognito, IAM, STS</li><li><b>Конфигурация:</b> SSM Parameter Store, Secrets Manager, CloudFormation, Glue Catalog</li></ul><h3>Реальная инфраструктура, а не заглушки</h3><p>Главное отличие MiniStack — он поднимает <b>настоящие</b> сервисы там, где это важнее всего:</p><ul><li><b>RDS</b> — вызов CreateDBInstance с engine=postgres запускает реальный PostgreSQL-контейнер и возвращает настоящий host:port</li><li><b>ElastiCache</b> — реальный Redis-контейнер, а не in-memory имитация</li><li><b>ECS</b> — реальные Docker-контейнеры</li><li><b>Athena</b> — реальный SQL через DuckDB (при наличии)</li></ul><p>Это принципиально отличается от подхода LocalStack, который во многих случаях использует стабы — ответы «всё ОК» без реального выполнения.</p><h2>Сравнение с LocalStack</h2><p>Ключевые метрики рядом:</p><ul><li><b>Запуск:</b> MiniStack ~2 сек vs LocalStack ~15–30 сек</li><li><b>RAM в простое:</b> MiniStack ~30 МБ vs LocalStack ~500 МБ</li><li><b>Docker-образ:</b> MiniStack 150 МБ vs LocalStack ~1 ГБ</li><li><b>Лицензия:</b> MiniStack MIT vs LocalStack BSL (ограниченная) / Proprietary ($35+/мес)</li><li><b>RDS, ElastiCache, ECS:</b> MiniStack — реальные контейнеры бесплатно vs LocalStack — только в Pro</li></ul><p>При этом MiniStack совместим с тем же API: endpoint-url, boto3, Terraform, CDK — всё работает без изменения кода.</p><h2>Как начать</h2><p>Три способа установки:</p><p>Проверка работы:</p><p>Для Python-проектов:</p><h2>Выводы</h2><p>MiniStack не претендует на полное покрытие всех AWS-сервисов — это задача LocalStack Pro. Но для типичной локальной разработки (S3 + SQS + DynamoDB + Lambda + IAM + RDS) он закрывает 90% потребностей при нулевой стоимости, мгновенном запуске и MIT-лицензии.</p><p>Проект активно развивается (947 звёзд на GitHub, версия 1.0.7) и уже привлёк внимание на <a href="https://news.ycombinator.com/item?id=47593285">Hacker News</a> (227+ баллов). Если вы искали замену LocalStack после перехода на платную модель — попробуйте.</p><p>Ссылки: <a href="https://github.com/Nahuel990/ministack">GitHub</a> | <a href="https://ministack.org/">Сайт</a> | <a href="https://pypi.org/project/ministack/">PyPI</a> | <a href="https://hub.docker.com/r/nahuelnucera/ministack">Docker Hub</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>