- BrainTools - https://www.braintools.ru -
Делали SEO-блог под SAT-направление для школьников из СНГ. Нужно было SEO сразу на трёх языках: RU, KK, EN.
Написали 28 уникальных статей. Каждая переведена на три языка, итого 84 файла контента и 90 URL в sitemap. От первой строки до индексации в Google и Яндексе ушло три календарных дня.
Пайплайн на Claude API, Next.js 16 и GitHub CI/CD. Без CMS, без Markdown, без headless платформ. Статьи хранятся как TypeScript-файлы.
Соотношение AI / ручная работа у нас получилось примерно 70/30. Остальные 30% (вычитка фактов, локализация идиом, финальные правки) — человек. Без этой части статьи быстро уходят в low-quality индекс.
В robots.txt запрещены AI-краулеры (GPTBot, ChatGPT-User, Google-Extended, anthropic-ai и другие). Так делают многие крупные медиа. В паре с AI-генерируемым блогом это создаёт этическую неоднозначность, про неё — ниже.

В апреле 2026 мы запустили русскоязычную SAT-платформу для школьников из Казахстана, России и Узбекистана. SAT — экзамен для поступления в американские вузы, русскоязычного аналога Khan Academy для него не существует.
Сразу стало понятно: без органического трафика платформа умрёт через месяц. Платная реклама в нашей нише неадекватно дорогая (аудитория узкая, аукцион перегрет), остаётся SEO. А у нас три языка одновременно: русский, казахский, английский. Это три разных хаба ключевиков, три блога, три версии каждой статьи.
Нанять под это в штат двух копирайтеров и переводчика — убить бюджет до запуска. Решение напросилось: автоматизировать генерацию и публикацию через Claude API.
Стандартно SEO-блоги делают на Markdown, MDX, Contentlayer или headless CMS типа Sanity. У нас каждая статья лежит в .ts файле и экспортирует типизированный объект BlogArticle.
import type { BlogArticle } from '../../types';
export const satGrammarRules: BlogArticle = {
slug: 'sat-grammar-rules',
locale: 'ru',
title: 'SAT Grammar Rules — полный список правил',
description: 'Все правила грамматики для секции Reading & Writing...',
keywords: ['SAT grammar', 'SAT правила грамматики', /* ... */],
excerpt: 'Краткое описание для карточки...',
heroImage: '/landing/blog/grammar.png',
heroAlt: 'SAT Grammar Rules — список правил',
publishedAt: '2026-03-20',
readingTime: 12,
author: 'yanina',
alternates: {
en: 'sat-grammar-rules-complete-list',
kk: 'sat-grammatika-erezheleri',
},
content: `
## Первый заголовок H2
Текст параграфа. Markdown формат.
...
`,
};
Почему так:
Типобезопасность. Забыл поле readingTime или опечатался в locale. TypeScript ругается в IDE, до билда дело не доходит. С Markdown frontmatter такое ловится в рантайме, часто уже в проде.
hreflang из коробки. Поле alternates напрямую маппится в <link rel="alternate" hreflang="..."> в <head>. Никакой отдельной базы соответствий.
Нет CMS — нет зависимости. Contentful падает, блог падает. GitHub падает — ну, такое.
Diff-able review. Изменение статьи — это PR с понятным diff. Можно посмотреть blame, прогнать CI-проверки на обновлённый контент.
Минус один: авторам-нетехнарям нужен хотя бы VSCode и минимальное понимание git. В нашем случае автор один, и трейд-офф приемлем.
Типовая ошибка [1] AI-пайплайнов: короткий промпт «напиши SEO-статью про X». Claude пишет гладко, получается универсальный контент, который Google давно научился отсеивать в low-quality.
Наш промпт лежит в файле seo/ARTICLE-GUIDE.md [2] на 361 строку. Передаётся целиком как system prompt. Что в нём:
Структура TypeScript-файла с примером корректного объекта BlogArticle
Требования к контенту: 3-8 секций H2, обязательные H3 внутри, таблицы где уместно, списки, итоговый CTA
Список существующих статей блога с URL — Claude видит и обязан проставить 2-3 internal-ссылки
Стилистические гайдлайны: избегать общих фраз типа «в современном мире», приводить конкретные цифры, использовать прямую речь
Чеклист перед выдачей: все поля заполнены, keywords не пустые, alternates содержит slug для всех трёх языков
Главное, что я вынес за два месяца экспериментов: качество AI-контента на 70% определяется не моделью, а детальностью системного промпта. Разница между 50-строчным и 350-строчным промптом на одной и той же модели — это разница между «сойдёт» и «реально ранжируется».
Internal linking — отдельная боль [3]. Без явного списка существующих статей в промпте Claude сочиняет ссылки типа /blog/how-to-pass-sat, которых у нас нет. На выходе 404. С явным списком ставит только реальные URL, и каждая новая статья усиливает перелинковку старых.
Про это честно скажу отдельно. Добавить статью — не одно действие, а шесть. Claude выдал .ts файл контента, дальше руками (или через скрипт-обёртку) регистрируем статью в frontend/src/lib/i18n/blog/articles.ts:
// 1. ID
ARTICLE_IDS.push('sat-grammar-rules');
// 2. URL slug на каждом языке
SLUG_MAP['sat-grammar-rules'] = {
ru: 'sat-grammar-rules',
en: 'sat-grammar-rules-complete-list',
kk: 'sat-grammatika-erezheleri',
};
// 3. Категория
CATEGORY_MAP['sat-grammar-rules'] = 'writing';
// 4. Автор
AUTHOR_MAP['sat-grammar-rules'] = 'yanina';
// 5. Даты
DATES_MAP['sat-grammar-rules'] = {
publishedAt: '2026-03-20',
updatedAt: '2026-03-20',
};
// 6. Рейтинг (для Review schema)
RATING_MAP['sat-grammar-rules'] = { value: 4.8, count: 12 };
// + loader в getArticle() для каждого языка
Зачем так, если можно было просто прочитать папку с файлами? Ради статической сборки Next.js. generateStaticParams и generateMetadata работают с этими мапами без обращения к файловой системе. На выходе быстрая сборка (1-2 минуты на 84 статьи) и стабильный SSG.
Честный минус: для массовой генерации это добавляет скрипт на 30 строк. Скрипт парсит выдачу Claude и автодополняет мапы. Один раз написал, забыл.
На старте мы пробовали генерировать три версии независимо. Получили три разных фактологических варианта одной статьи. Три пруф-чека, три SEO-оптимизации, тройная нагрузка на вычитку. Отказались. Сейчас схема такая:
Claude пишет полную русскую версию с максимальной детализацией.
Отдельным вызовом с другим промптом Claude переводит и адаптирует на английский и казахский. Промпт явно говорит: не просто переводи, локализуй с учётом SAT-контекста местной аудитории.
Slug на каждом языке свой (не транслит), прописывается в alternates.
Next.js через generateMetadata автоматически ставит <link rel="alternate" hreflang="ru|kk|en|x-default"> на все три версии. x-default направили на RU, это основная аудитория.
Для каждой статьи нужно уникальное превью 1200×630. Влияет и на SEO, и на CTR в соцсетях. 84 картинки руками в Figma — отдельная катастрофа.
Написали гибридный пайплайн в файле generate-blog-covers.py [4]:
Через Gemini 2.5 Flash Image API генерируем тематический фон 1200×630 по теме статьи (например, «SAT Math formulas pattern» или «abstract reading background»).
Через PIL на этот фон композитим вырезанное фото автора статьи (у нас три автора: два эксперта плюс обобщённая марка проекта). Вырезание белого фона, мягкая тень, лёгкое свечение.
На выходе PNG, который идёт в heroImage статьи и в OG-метатеги.
Почему два разных AI в пайплайне вместо одного. Для связного текста Claude объективно лучше, но на генерации картинок он пока отстаёт. Gemini Flash Image — это быстро (секунды на картинку), дёшево и заточено под нашу задачу: осмысленный тематический фон, а не фотореалистичное изображение. Текст и лица генерировать ему не доверяем, поэтому фото авторов всегда настоящие, аккуратно вырезанные.
Работает минуту на всю серию. Получаем уникальные карточки для Telegram, VK, Facebook, Twitter. При шаринге статьи выглядят как у полноценного медиа.
Sitemap мы собираем прямо из articles.ts в файле frontend/src/app/sitemap.ts — стандартный Next.js 16 способ. На выходе 90 URL: 3 лендинга + 3 блог-индекса + 84 статьи. lastModified динамический, берётся из DATES_MAP.updatedAt.
С robots.txt мы сделали то же, что в 2025–2026 делают многие крупные медиа (NYT, Reuters, BBC, CNN): явно запретили AI-краулеры.
User-Agent: GPTBot
Disallow: /
User-Agent: ChatGPT-User
Disallow: /
User-Agent: CCBot
Disallow: /
User-Agent: Google-Extended
Disallow: /
User-Agent: Bytespider
Disallow: /
User-Agent: anthropic-ai
Disallow: /
В нашем случае это создаёт этическую неоднозначность: сами генерируем контент через Claude, но другим моделям на нём обучаться не даём. Наша позиция: мы заплатили за генерацию (API-токены), несём репутационную ответственность за факты в статьях (вычитка, правки, пруф). Отдавать этот контент бесплатно на обучение [5] моделей, которые через полгода будут конкурировать с нашим трафиком, резона не видим. Поисковые боты (Googlebot, YandexBot) пускаем, AI-боты нет.
Понятно, что это не останавливает всех. Скрейперы, которые игнорируют robots.txt, существуют. Но на официальных краулерах крупных лабораторий работает.
Что получили за три дня:
28 уникальных статей × 3 языка = 84 файла контента, ~75 000 слов
90 URL в sitemap, отправлены в GSC и Яндекс.Вебмастер
Все статьи с уникальными OG-превью, hreflang, JSON-LD Article schema
Индексация пошла в обеих системах, трафик начал расти через 2 недели после публикации
По экономике сравнение грубое и зависит от рынка. Руками 84 текста на трёх языках при средних ставках копирайтера и переводчика — это десятки тысяч долларов и 6-8 недель работы команды. У нас вся серия вписалась в несколько сотен долларов на API и инфраструктуру плюс три дня одного человека с прочими задачами параллельно. Соотношение по деньгам — порядок (десятки раз), по времени — на порядок-два. При этом 30% работы (вычитка фактов, проверка KK-локализации носителем) всё равно делал человек, и без этих 30% статьи быстро уходят в low-quality индекс.
Где AI косячит и где ручная работа неизбежна. Те самые 30% человеческой работы распределены примерно так:
Цифры и даты. Claude регулярно придумывает статистику типа «по данным College Board 85% студентов…» с несуществующей ссылкой. Мы ввели правило: любая статистика либо реальная с пруфом, либо её нет в тексте. Ловится только ручной вычиткой.
Обновление статей. SAT меняется, даты плавают, College Board обновляет формат. Автоматически Claude это не отслеживает, нужен отдельный процесс аудита раз в квартал.
Уникальные инсайты. AI пишет корректно, но не даёт того, что даёт эксперт после пяти лет в теме. Самые сильные статьи у нас те, где Claude написал черновик, а человек добавил свой опыт [6] и конкретные случаи.
Если у вас есть Next.js проект и хочется закрыть SEO-блог без найма копирайтера, примерный путь такой:
Определите 20-30 ключевых запросов в своей нише через GSC (если уже есть сайт) или Ahrefs/Similarweb/Serpstat. Каждый запрос — это будущая статья.
Составьте типовую структуру статьи под свой домен: какие H2 нужны, какие поля метаданных, какие internal-ссылки. Это ваш будущий BlogArticle тип в TypeScript.
Напишите большой system prompt с этой структурой, примерами, стилевыми гайдлайнами («избегай общих фраз», «приводи цифры», «ссылайся только на реальные URL из списка»). Начните со 200 строк, доращивайте до 400+ по мере ошибок.
Пишите через Claude API (или GPT/Gemini) итеративно. Каждая статья — отдельный вызов с одним и тем же system prompt и новыми параметрами темы. Claude Sonnet для такого достаточно, Opus излишен.
Сохраняйте как TypeScript, коммитьте в GitHub. Настройте CI/CD на автодеплой в Vercel или AWS App Runner. Sitemap генерируется Next.js автоматически из вашего реестра статей.
Обязательно вручную: факт-чек цифр, финальная вычитка на калькированные обороты, если есть локализация — проверка носителем. Это те 30%, без которых статьи уходят в low-quality.
В robots.txt решите позицию по AI-краулерам. Можете пускать, можете блокировать. Главное, чтобы Googlebot и YandexBot были открыты.
Время на первый запуск (20-30 статей на одном языке): 2-3 дня работы одного человека с нормальной занятостью по основным задачам. На три языка плюс вычитка носителем — неделя.
Автоматизировать обновление статей: скрипт, который раз в месяц проверяет даты SAT-экзаменов на College Board и обновляет соответствующие поля в нужных статьях.
Интеграция с Google Indexing API и IndexNow для мгновенного пинга поисковиков после публикации (сейчас индексация идёт органически, через 7-14 дней).
A/B тест заголовков на основе данных GSC: статьи с высокими impressions и низким CTR автоматически получают 2-3 альтернативных заголовка для теста.
Выход на четвёртый язык (узбекский) — но только после стабилизации KK-версий.
Готов отвечать на вопросы в комментариях. Если зайдёт то напишу продолжение про техническую часть AI-тьютора (RAG + Claude tool use) и про процессы квартального аудита и обновления статей.
Автор: LevAvdoshin
Источник [7]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/29779
URLs in this post:
[1] ошибка: http://www.braintools.ru/article/4192
[2] ARTICLE-GUIDE.md: http://ARTICLE-GUIDE.md
[3] боль: http://www.braintools.ru/article/9901
[4] generate-blog-covers.py: http://generate-blog-covers.py
[5] обучение: http://www.braintools.ru/article/5125
[6] опыт: http://www.braintools.ru/article/6952
[7] Источник: https://habr.com/ru/articles/1031082/?utm_campaign=1031082&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.