Разбор
ИИ-агент строит карту внутренней перелинковки сайта: SEO-возможности которые ты не видишь
Блог с 80 статьями — 34 пары страниц без единой ссылки между собой при высокой тематической связи. ИИ-агент сканирует каждую страницу и за 30 минут строит полную карту: кто на кого должен ссылаться и через какой анкор.
У контентного блога с 80 статьями было 34 пары страниц с высокой тематической связью и ни одной ссылкой между ними. Не потому что редактор забыл — просто невозможно удержать в голове 6 320 потенциальных комбинаций страниц и понять которые из них стоит связать.
Хаотичная перелинковка — это не проблема дизайна
Поисковый робот Яндекса ходит по сайту как по карте метро. Чем больше путей ведёт к станции — тем чаще он туда приезжает и тем выше ценит эту страницу. Это внутренний PageRank: ссылочный вес от главной и популярных страниц перетекает на те, на которые ссылаются.
У большинства сайтов с 100+ страницами эта система работает случайно. Главная ссылается на 8 разделов. Разделы ссылаются на 10–15 статей. Статьи между собой — почти никак. Написал новый материал — поставил ссылку на 2–3 похожих которые вспомнил. Через год у тебя 80 статей и паутина из 200 хаотичных ссылок.
При этом Яндекс смотрит не только на количество ссылок, но и на анкоры. Если статья про «контент-маркетинг для B2B» получает входящую ссылку с анкором «стратегия контента», это усиливает её по этому запросу. Хаотичные перелинковки дают хаотичные анкоры — сигнал нечёткий, позиции ниже.
70 статей из 80 получают в среднем 3% от веса главной. Не потому что они плохие — просто никто не провёл линии между ними.
Что агент собирает и как решает что связывать
Полный текстовый анализ 80 страниц — это слишком дорого. Claude прочитает каждую и ответит вам счётом за API на 2 000 рублей. Агент работает хирургически: берёт только то что нужно для тематической классификации.
С каждой страницы собирается четыре элемента:
<title>— что поисковик и автор считают главной темой страницы<h1>— заголовок статьиmeta description— краткое резюме- Первые 500 символов текста — вступление, где обычно сформулирована суть
Этого достаточно чтобы Claude понял: страница про retention-маркетинг для e-commerce или про стратегию email-рассылок? Они близки, но не одно и то же. Агент разберётся.
Дальше Claude получает эти мини-профили всех страниц одним батчем и делает три вещи:
Первое — определяет тематические кластеры. Группирует страницы по смысловой близости, не по рубрикам сайта. Часто статьи из разных разделов оказываются тематически ближе, чем соседи по рубрике.
Второе — ищет недостающие связи. Внутри каждого кластера и между смежными кластерами — какие пары существуют без ссылок, хотя читатель после первой страницы логично пошёл бы на вторую.
Третье — генерирует рекомендации. Для каждой пары: страница-источник, страница-цель, предлагаемый анкор, одно предложение почему.
Схема работы агента
Весь пайплайн — локально. Никаких внешних сервисов кроме Claude API. Запустил, подождал 20–30 минут, получил CSV.
Код агента
Устанавливаем зависимости: pip install requests beautifulsoup4 anthropic
import requests
import xml.etree.ElementTree as ET
from bs4 import BeautifulSoup
import anthropic
import json
import csv
import time
SITE_URL = "https://example.com" # ваш сайт
SITEMAP_URL = f"{SITE_URL}/sitemap.xml" # путь к sitemap
CLAUDE_API_KEY = "YOUR_CLAUDE_KEY" # ключ Anthropic API
OUTPUT_CSV = "link_recommendations.csv" # куда сохранить
MAX_PAGES = 100 # лимит страниц для анализа
BATCH_SIZE = 25 # страниц на один запрос к Claude
def parse_sitemap(sitemap_url: str) -> list[str]:
"""Получаем список URL из sitemap.xml."""
resp = requests.get(sitemap_url, timeout=15)
resp.raise_for_status()
root = ET.fromstring(resp.content)
ns = {'sm': 'http://www.sitemaps.org/schemas/sitemap/0.9'}
urls = [loc.text for loc in root.findall('.//sm:loc', ns)]
# Фильтруем служебные страницы
skip = ['/tag/', '/category/', '/page/', '/author/', '/feed']
return [u for u in urls if not any(s in u for s in skip)][:MAX_PAGES]
def scrape_page_meta(url: str) -> dict | None:
"""Собираем заголовок, h1, description и первый абзац."""
try:
resp = requests.get(url, timeout=10, headers={
'User-Agent': 'Mozilla/5.0 (SEO-audit-bot)'
})
if resp.status_code != 200:
return None
soup = BeautifulSoup(resp.text, 'html.parser')
title = soup.find('title')
h1 = soup.find('h1')
desc = soup.find('meta', attrs={'name': 'description'})
# Первый непустой абзац из основного контента
paragraphs = soup.find_all('p')
first_para = next(
(p.get_text(strip=True) for p in paragraphs if len(p.get_text(strip=True)) > 80),
''
)
return {
'url': url,
'title': title.get_text(strip=True) if title else '',
'h1': h1.get_text(strip=True) if h1 else '',
'description': desc.get('content', '') if desc else '',
'intro': first_para[:500],
}
except Exception:
return None
def analyze_batch_with_claude(pages: list[dict], client: anthropic.Anthropic) -> list[dict]:
"""Анализируем батч страниц — Claude находит пары для перелинковки."""
pages_json = json.dumps(pages, ensure_ascii=False, indent=2)
prompt = f"""Ты SEO-специалист. Проанализируй список страниц сайта и найди пары для внутренней перелинковки.
Страницы для анализа:
{pages_json}
Задача: найти пары (страница А → страница Б) где:
1. Тематическая связь сильная — читатель который прочёл А, вероятно заинтересован в Б
2. Ссылка улучшит пользовательский путь и поможет роботу понять структуру сайта
3. Предлагаемый анкор — конкретные 2-5 слов из темы страницы Б
Верни JSON-массив объектов. Каждый объект:
{{
"source_url": "URL страницы А",
"source_title": "Заголовок страницы А",
"target_url": "URL страницы Б",
"target_title": "Заголовок страницы Б",
"anchor": "предлагаемый анкор",
"reason": "почему эта связь важна (1 предложение)",
"priority": "high|medium|low"
}}
Найди 10-20 пар из этого батча. Возвращай только JSON, без пояснений."""
message = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=4096,
messages=[{"role": "user", "content": prompt}]
)
text = message.content[0].text.strip()
# Извлекаем JSON если Claude обернул в markdown
if text.startswith("```"):
text = text.split("```")[1]
if text.startswith("json"):
text = text[4:]
try:
return json.loads(text)
except json.JSONDecodeError:
return []
def save_to_csv(recommendations: list[dict], output_path: str):
"""Сохраняем рекомендации в CSV для контент-менеджера."""
if not recommendations:
print("Рекомендаций нет — нечего сохранять.")
return
fields = ['source_url', 'source_title', 'target_url', 'target_title',
'anchor', 'reason', 'priority']
with open(output_path, 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=fields)
writer.writeheader()
writer.writerows(recommendations)
print(f"Сохранено {len(recommendations)} рекомендаций → {output_path}")
if __name__ == "__main__":
client = anthropic.Anthropic(api_key=CLAUDE_API_KEY)
print("Парсим sitemap...")
urls = parse_sitemap(SITEMAP_URL)
print(f"Найдено URL: {len(urls)}")
print("Собираем мета-данные страниц...")
pages = []
for i, url in enumerate(urls):
meta = scrape_page_meta(url)
if meta:
pages.append(meta)
if (i + 1) % 10 == 0:
print(f" {i+1}/{len(urls)} страниц обработано")
time.sleep(0.3) # вежливый краулер не спешит
print(f"Собрано страниц: {len(pages)}")
print("Анализируем через Claude...")
all_recommendations = []
for i in range(0, len(pages), BATCH_SIZE):
batch = pages[i:i + BATCH_SIZE]
print(f" Батч {i//BATCH_SIZE + 1}: страницы {i+1}–{i+len(batch)}")
recs = analyze_batch_with_claude(batch, client)
all_recommendations.extend(recs)
time.sleep(2) # пауза между запросами к API
# Сортируем: high priority вверх
priority_order = {'high': 0, 'medium': 1, 'low': 2}
all_recommendations.sort(key=lambda x: priority_order.get(x.get('priority', 'low'), 2))
save_to_csv(all_recommendations, OUTPUT_CSV)
print(f"Готово. Итого рекомендаций: {len(all_recommendations)}")Несколько вещей которые нужно знать перед запуском.
Пауза time.sleep(0.3) между запросами к сайту — не для красоты. Некоторые хостинги блокируют краулеры при более чем 2–3 запросах в секунду. Если сайт на shared-хостинге или за Cloudflare — увеличь до 0.8–1.0.
claude-sonnet-4-5 в коде — можно заменить на claude-haiku-3-5 если нужна экономия. Haiku справляется с тематическим анализом текстов примерно так же, стоит в 8 раз дешевле. На 80 страницах разница — около 15 рублей против 2 рублей.
Батч из 25 страниц — это максимум который помещается в разумный контекст без потери качества. Если делать батч 50+ страниц, Claude начинает находить более слабые связи просто чтобы выдать достаточное количество рекомендаций.
Есть вопрос по теме?
Пришлю шаблон контент-стратегии и примеры кейсов с цифрами
Что получается на выходе: реальный пример
Блог с 80 статьями про digital-маркетинг. Агент отработал за 28 минут, отдал 47 рекомендаций. Вот 8 из них с разными уровнями приоритета:
| Страница-источник | Страница-цель | Анкор | Приоритет |
|---|---|---|---|
| Как писать email-цепочки для e-commerce | Сегментация базы по RFM: пошаговый гайд | сегментации базы | высокий |
| Контент-план для B2B: шаблон и примеры | Как измерить ROI контент-маркетинга | измерить эффективность контента | высокий |
| SEO для интернет-магазина: с чего начать | Внутренняя перелинковка категорий каталога | перелинковки категорий | высокий |
| Как снизить CPA в Яндекс.Директ | Ретаргетинг: 7 стратегий для возврата клиентов | ретаргетинг для снижения CPA | высокий |
| Автоворонки в мессенджерах: инструкция | Чат-бот для лидогенерации: кейс | чат-бота для сбора лидов | средний |
| UX-копирайтинг: как писать CTA | A/B-тестирование заголовков: методология | A/B-тестирование текстов кнопок | средний |
| Продвижение в Telegram: органический рост | Как монетизировать Telegram-канал | монетизации канала | средний |
| Аналитика для малого бизнеса: базовый стек | Яндекс.Метрика: полное руководство 2025 | настройки Яндекс.Метрики | низкий |
34 из 47 рекомендаций прошли ручную проверку — у редактора не было возражений по тематической связи. 9 пар оказались слишком слабыми и были отброшены. 4 — дублировали уже существующие ссылки которые агент не нашёл через парсинг (они были в JavaScript-рендере).
Важный момент: агент не проверяет существующие ссылки на странице. Он анализирует тематику и предлагает связи — но не знает что ссылка уже стоит. Перед внедрением нужно быстро глазами пробежаться по каждой рекомендации. 2–3 минуты на пару.
Проверь свой сайт: квиз
Насколько хаотична перелинковка на вашем сайте?
4 вопроса — поймём нужен ли вам агент
Как внедрять: от таблицы к ссылкам
Агент отдал CSV. Дальше — три шага.
Открываем рекомендации с пометкой «высокий приоритет» — обычно это 15–20 пар. Для каждой: открываем страницу-источник и проверяем есть ли там уже ссылка на цель. Если нет — смотрим есть ли в тексте абзац где упоминается тема целевой страницы. Это займёт 30–40 минут.
Контент-менеджер берёт первые 20 пар по приоритету — это один рабочий день. Каждую правку сохраняем. Не нужно добавлять все 50 пар за раз — поисковик увидит резкий прирост внутренних ссылок и это выглядит неестественно. Растягивайте на 3–4 недели.
Запускаем Screaming Frog или аналог — смотрим что изменилось в распределении внутренних ссылок. Отслеживаем позиции страниц которые получили новые входящие ссылки. Заметный эффект обычно виден через 4–8 недель после индексации.
Одна вещь которую нужно сделать до старта: снять снапшот текущего состояния. Screaming Frog (бесплатно до 500 URL) выгрузит отчёт по внутренним ссылкам. Сохраните его — потом будет с чем сравнивать.
Где агент ошибается
Три типичных промаха из практики.
Агент иногда рекомендует связи между страницами с похожими словами в заголовках, но разным смыслом. «Контент-маркетинг для стартапов» и «Контент для Instagram» — оба про контент, но аудитории и цели разные. Проверка руками отловит такое за секунды.
Агент не знает о пользовательском пути на конкретном сайте. Он анализирует тематику, но не данные о том откуда реально приходят пользователи и куда уходят. Если у вас есть данные Метрики по поведенческим паттернам — дополните промпт этим контекстом.
Агент не учитывает коммерческий контекст. Иногда выгоднее вести с информационной статьи на коммерческую страницу, а не на другую статью — даже если тематически они дальше. Такие пары нужно добавлять вручную.
80 статей, 34 незамеченных связи, 28 минут работы агента. Это не магия — это просто то что человек не может держать в голове, а скрипт может. Контент уже написан, деньги на него потрачены. Осталось провести между ними правильные линии.
Есть вопрос по теме?
Пришлю шаблон контент-стратегии и примеры кейсов с цифрами
Источники
AI-агенты · Персональная карта
4 часа потратил — не работает?
Покажу где ты пошёл не туда и как сделать правильно за 2 недели
Получить разбор бесплатно →AI-агенты · 10 мест
Ты работаешь до полуночи — AI-агент будет работать вместо тебя
Покажу какой агент закроет твою главную операционную боль
Узнать свой маршрут →Есть вопрос по теме?
Пришлю шаблон контент-стратегии и примеры кейсов с цифрами
Источники
Читайте также
Часто задаваемые вопросы
- Что такое внутренняя перелинковка и зачем её оптимизировать?
- Внутренняя перелинковка — это система ссылок между страницами одного сайта. Поисковый робот обходит сайт по этим ссылкам: чем больше ссылок ведёт на страницу, тем выше её внутренний PageRank и тем выше она ранжируется. Без оптимизации ссылочный вес распределяется случайно — важные страницы получают меньше веса, чем второстепенные.
- Сколько страниц нужно для того, чтобы перелинковка стала проблемой?
- Уже с 50–60 страниц ручной контроль перестаёт быть реалистичным: одному редактору невозможно держать в голове все тематические связи. На практике у большинства контентных сайтов с 100+ страницами 30–40% возможных тематических связей не реализованы — страницы существуют изолированно, хотя должны усиливать друг друга.
- Как ИИ-агент определяет, какие страницы должны ссылаться друг на друга?
- Агент собирает H1, title, мета-описание и первые 500 символов текста каждой страницы. Claude анализирует тематическую близость: совпадение сущностей, вопросов которые отвечают страницы, и логику читательского пути. Рекомендует пару только если тематическая связь сильная и в тексте страницы-источника есть естественное место для вставки ссылки.
- Какой код нужен для запуска агента перелинковки?
- Python с тремя библиотеками: requests и BeautifulSoup для сканирования сайта, anthropic для анализа через Claude. Скрипт читает sitemap.xml или обходит страницы рекурсивно, собирает мета-данные и первый абзац, отправляет в Claude батчами по 20–30 страниц. Итого ~150 строк кода. Полный пример — в статье.
- Сколько стоит прогнать агент по сайту с 80 страницами?
- Один полный прогон по сайту с 80 страницами — около 15–25 рублей через Claude API (claude-sonnet-4-5 или claude-haiku-3-5 для экономии). Если запускать раз в квартал при обновлении контента — расходы практически нулевые. Для сравнения: ручной SEO-аудит перелинковки в агентстве стоит 20 000–50 000 рублей.
- Как внедрять рекомендации агента по перелинковке?
- Агент выдаёт таблицу: страница-источник, страница-цель, предлагаемый анкор, обоснование. Контент-менеджер открывает страницу-источник, находит абзац где упоминается тема целевой страницы, добавляет ссылку. Обычно правка занимает 2–3 минуты на пару. 50 пар — это полный рабочий день. После — переобход краулером чтобы убедиться что все ссылки проставлены.
Канал «Лёха Маркетолог»
Практика без воды: кейсы, инсайты, разборы. 1–2 поста в неделю.
Пока без комментариев. Будьте первым.