# Living CI Document: конкурентная разведка, которая обновляет себя сама

> Архитектура самообновляющегося CI-документа конкурентной разведки: n8n/Make + AI, промпты для обновления секций, мониторинг изменений конкурентов.
> Author: Roman Belov · Published: 2026-07-20 · Source: https://futurecraft.pro/ru/blog/living-ci-document/

CI-документ устаревает сразу после создания. Конкурент меняет цены, запускает фичу, переписывает позиционирование. Документ остаётся прежним. Команда принимает решения на основе данных месячной давности.

Проблема не в качестве анализа. Проблема в модели: ручной документ по определению статичен. Обновление требует времени аналитика, мотивации и дисциплины. На практике обновление происходит перед стратегическими сессиями — раз в квартал, если повезёт.

Эта статья описывает архитектуру CI-документа, который обновляет себя автоматически. Мониторинг источников, AI-анализ изменений, обновление секций, уведомления команды. Без ручного труда после первичной настройки.

## Архитектура self-updating CI document

Система состоит из четырёх слоёв. Каждый решает одну задачу.

```
Источники данных
    │
    │  RSS, webhooks, скрапинг, API
    ▼
┌──────────────────┐
│  Оркестратор     │  n8n / Make
│  (автоматизация) │  Расписание + триггеры
└──────────────────┘
    │
    │  Сырые данные
    ▼
┌──────────────────┐
│  AI-процессор    │  LLM: анализ, сравнение,
│  (анализ)        │  генерация обновлений
└──────────────────┘
    │
    │  Структурированные обновления
    ▼
┌──────────────────┐
│  Документ        │  Notion / Google Docs /
│  (хранилище)     │  Markdown в репо
└──────────────────┘
    │
    │  Дайджест изменений
    ▼
Slack / Email / Telegram
```

**Оркестратор** управляет расписанием и потоком данных. n8n (self-hosted) или Make (облако) подходят одинаково. Выбор зависит от инфраструктуры: n8n даёт полный контроль и не тарифицирует по операциям, Make проще в настройке.

**AI-процессор** получает сырые данные и текущее состояние секции документа. Возвращает обновлённый текст секции и changelog изменений. Работает через API любого LLM-провайдера.

**Документ** хранит структурированную информацию о конкурентах. Каждая секция имеет метаданные: дату последнего обновления, источник, уровень уверенности.

## Структура CI-документа: секции и метаданные

Документ делится на секции. Каждая секция обновляется независимо, со своей частотой и своими источниками.

Минимальный набор секций:

| Секция | Частота обновления | Источники |
|--------|-------------------|-----------|
| Pricing & Plans | Еженедельно | Страницы pricing, API |
| Product Features | Еженедельно | Changelog, блог, release notes |
| Positioning & Messaging | 2 раза в месяц | Главная страница, landing pages |
| Team & Hiring | Ежемесячно | LinkedIn, карьерные страницы |
| Funding & Financials | Ежемесячно | Crunchbase, пресс-релизы |
| Tech Stack | Ежемесячно | Вакансии, BuiltWith, Wappalyzer |
| Content & SEO | Еженедельно | Блог, social media, Ahrefs API |
| Customer Reviews | 2 раза в месяц | G2, Capterra, Product Hunt |

Каждая секция хранит метаданные:

```json
{
  "section": "pricing",
  "competitor": "CompetitorX",
  "last_updated": "2026-03-27T10:00:00Z",
  "update_source": "https://competitorx.com/pricing",
  "confidence": "high",
  "change_detected": true,
  "previous_hash": "a3f2b1c...",
  "changelog": [
    {
      "date": "2026-03-27",
      "change": "Pro plan price increased from $49 to $59/mo",
      "significance": "high"
    }
  ]
}
```

Поле `previous_hash` хранит хеш предыдущей версии страницы-источника. Сравнение хешей позволяет определить, изменилось ли что-то, до вызова LLM. Это экономит API-вызовы при отсутствии изменений.

## Настройка мониторинга источников в n8n

n8n выбран для примеров, потому что запускается локально и не ограничивает количество операций. Адаптация для Make требует замены нод, логика остаётся прежней.

### Workflow 1: мониторинг страницы pricing

```
[Cron: каждый понедельник 09:00]
    │
    ▼
[HTTP Request: GET competitor.com/pricing]
    │
    ▼
[Code: извлечь текст, вычислить hash]
    │
    ▼
[IF: hash ≠ previous_hash]
    │         │
    YES       NO → [Stop]
    │
    ▼
[OpenAI / Anthropic: анализ изменений]
    │
    ▼
[Notion API: обновить секцию документа]
    │
    ▼
[Slack: уведомление об изменении]
```

Ключевой узел — Code node для извлечения текста и хеширования:

```javascript
const crypto = require('crypto');

// Входные данные: HTML страницы
const html = $input.first().json.data;

// Очистка от тегов, скриптов, стилей
const text = html
  .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
  .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
  .replace(/<[^>]+>/g, ' ')
  .replace(/\s+/g, ' ')
  .trim();

// Хеш для сравнения
const hash = crypto
  .createHash('md5')
  .update(text)
  .digest('hex');

return [{
  json: {
    text,
    hash,
    url: $input.first().json.url,
    timestamp: new Date().toISOString()
  }
}];
```

Хеш сравнивается с сохранённым значением из предыдущего запуска. Если совпадает — workflow останавливается. Если отличается — данные передаются в AI-процессор.

### Workflow 2: мониторинг changelog и блога через RSS

RSS проще скрапинга. Большинство SaaS-компаний публикуют changelog и блог через RSS.

```
[RSS Feed Trigger: competitor.com/blog/rss]
    │
    ▼
[Filter: новые записи за последние 7 дней]
    │
    ▼
[HTTP Request: получить полный текст каждой записи]
    │
    ▼
[AI: классифицировать — product update / marketing / hiring / other]
    │
    ▼
[Switch: по типу контента]
    │         │          │
  Product   Marketing   Other → [Skip]
    │         │
    ▼         ▼
[Обновить    [Обновить
 секцию       секцию
 Features]    Positioning]
```

Классификация контента перед обновлением документа критична. Без неё маркетинговые посты попадают в секцию продуктовых обновлений, размывая полезность документа.

## Промпты для AI-обновления секций

Плохой промпт генерирует пересказ. Хороший — выделяет значимые изменения и обновляет секцию документа, сохраняя контекст предыдущих обновлений.

### Промпт: обновление секции Pricing

```
Ты — аналитик конкурентной разведки. Задача: обновить секцию Pricing
в CI-документе на основе новых данных.

ТЕКУЩАЯ СЕКЦИЯ ДОКУМЕНТА:
---
{current_section_content}
---

НОВЫЕ ДАННЫЕ (текст страницы pricing):
---
{new_pricing_page_text}
---

ИНСТРУКЦИИ:
1. Сравни новые данные с текущей секцией
2. Определи конкретные изменения (цены, планы, лимиты, условия)
3. Обнови секцию, сохранив формат и историю предыдущих изменений
4. Добавь запись в changelog с датой и описанием изменения
5. Оцени значимость: high (изменение цен >10%, новый/удалённый план),
   medium (изменение лимитов, условий), low (косметические правки)

ФОРМАТ ОТВЕТА (строго JSON):
{
  "updated_section": "...",
  "changes": [
    {
      "change": "описание изменения",
      "significance": "high|medium|low",
      "implication": "что это значит для нас"
    }
  ],
  "has_significant_changes": true/false
}
```

### Промпт: обновление секции Product Features

```
Ты — аналитик конкурентной разведки. Задача: обновить секцию Product Features
на основе нового контента (changelog, release notes, блог-пост).

ТЕКУЩАЯ СЕКЦИЯ:
---
{current_section_content}
---

НОВЫЙ КОНТЕНТ:
---
{new_content}
---

ТИП КОНТЕНТА: {content_type} (changelog / release_notes / blog_post)

ИНСТРУКЦИИ:
1. Извлеки конкретные продуктовые изменения (новые фичи, улучшения, deprecations)
2. Игнорируй маркетинговый язык — только факты
3. Категоризируй: new_feature / improvement / deprecation / integration / api_change
4. Обнови feature matrix в секции
5. Отметь фичи, которые конкурент добавил, а у нас нет (gap analysis)

ФОРМАТ ОТВЕТА (строго JSON):
{
  "updated_section": "...",
  "new_features": [
    {
      "feature": "название",
      "category": "new_feature|improvement|deprecation|integration|api_change",
      "description": "краткое описание",
      "we_have_equivalent": true/false,
      "competitive_impact": "high|medium|low"
    }
  ]
}
```

### Промпт: обновление секции Positioning & Messaging

```
Ты — аналитик конкурентной разведки. Задача: отследить изменения
в позиционировании конкурента.

ПРЕДЫДУЩАЯ ВЕРСИЯ ГЛАВНОЙ СТРАНИЦЫ:
---
{previous_homepage_text}
---

ТЕКУЩАЯ ВЕРСИЯ:
---
{current_homepage_text}
---

ТЕКУЩАЯ СЕКЦИЯ ДОКУМЕНТА:
---
{current_section_content}
---

ИНСТРУКЦИИ:
1. Сравни тексты. Выдели изменения в:
   - Headline и value proposition
   - Целевая аудитория (кого называют, к кому обращаются)
   - Ключевые benefits и selling points
   - Social proof (клиенты, метрики, testimonials)
   - Call-to-action (текст, расположение)
2. Оцени: это косметика или стратегический сдвиг в позиционировании
3. Обнови секцию документа

ФОРМАТ ОТВЕТА (строго JSON):
{
  "updated_section": "...",
  "positioning_changes": [
    {
      "element": "headline|audience|benefits|social_proof|cta",
      "previous": "что было",
      "current": "что стало",
      "interpretation": "что это означает"
    }
  ],
  "strategic_shift": true/false,
  "shift_description": "описание сдвига, если есть"
}
```

Все три промпта следуют одному паттерну: текущее состояние секции + новые данные + чёткие инструкции + структурированный формат ответа. Этот паттерн описан подробнее в [руководстве по context engineering](/ru/blog/context-engineering-guide/).

## Автоматическое обновление документа через API

Документ может жить в Notion, Google Docs или как Markdown-файл в git-репозитории. Каждый вариант имеет свой API для программного обновления.

### Notion: обновление блока

```javascript
// n8n Code node: обновление секции в Notion
const notionApiKey = $env.NOTION_API_KEY;
const pageId = 'YOUR_PAGE_ID';
const blockId = 'PRICING_SECTION_BLOCK_ID';

const aiResponse = JSON.parse($input.first().json.ai_response);

// Обновить содержимое блока
await $http.request({
  method: 'PATCH',
  url: `https://api.notion.com/v1/blocks/${blockId}/children`,
  headers: {
    'Authorization': `Bearer ${notionApiKey}`,
    'Notion-Version': '2025-09-03'
  },
  body: {
    children: [
      {
        type: 'paragraph',
        paragraph: {
          rich_text: [{
            type: 'text',
            text: { content: aiResponse.updated_section }
          }]
        }
      }
    ]
  }
});

// Обновить метаданные (last_updated, source)
await $http.request({
  method: 'PATCH',
  url: `https://api.notion.com/v1/pages/${pageId}`,
  headers: {
    'Authorization': `Bearer ${notionApiKey}`,
    'Notion-Version': '2025-09-03'
  },
  body: {
    properties: {
      'Last Updated': {
        date: { start: new Date().toISOString() }
      }
    }
  }
});

return [{ json: { status: 'updated', changes: aiResponse.changes } }];
```

### Git-репозиторий: коммит через API

Для команд, предпочитающих Markdown и version control:

```javascript
// n8n Code node: обновление Markdown в GitHub
const token = $env.GITHUB_TOKEN;
const owner = 'your-org';
const repo = 'competitive-intel';
const path = `competitors/${competitor}/pricing.md`;

const aiResponse = JSON.parse($input.first().json.ai_response);

// Получить текущий файл (нужен sha для обновления)
const current = await $http.request({
  method: 'GET',
  url: `https://api.github.com/repos/${owner}/${repo}/contents/${path}`,
  headers: { 'Authorization': `Bearer ${token}` }
});

// Обновить файл
await $http.request({
  method: 'PUT',
  url: `https://api.github.com/repos/${owner}/${repo}/contents/${path}`,
  headers: { 'Authorization': `Bearer ${token}` },
  body: {
    message: `ci: update ${competitor} pricing — ${aiResponse.changes[0]?.change || 'routine update'}`,
    content: Buffer.from(aiResponse.updated_section).toString('base64'),
    sha: current.sha
  }
});
```

Git-подход даёт бесплатную историю изменений, diff между версиями и возможность ревью через pull requests.

## Обработка ошибок и валидация данных

Автоматическая система без обработки ошибок генерирует мусор. Три уровня защиты.

**Уровень 1: валидация источника.** Перед отправкой данных в AI проверить, что источник вернул ожидаемый контент. Пустая страница, 404, CAPTCHA, paywall — всё это ловится до вызова LLM.

```javascript
// Валидация перед AI-обработкой
const text = $input.first().json.text;
const url = $input.first().json.url;

// Проверка на пустой или слишком короткий контент
if (!text || text.length < 100) {
  return [{ json: { skip: true, reason: 'empty_or_too_short' } }];
}

// Проверка на CAPTCHA / блокировку
const blockedIndicators = ['captcha', 'access denied', 'please verify'];
const isBlocked = blockedIndicators.some(
  indicator => text.toLowerCase().includes(indicator)
);
if (isBlocked) {
  return [{ json: { skip: true, reason: 'blocked', url } }];
}

return $input.all();
```

**Уровень 2: валидация AI-ответа.** LLM может вернуть невалидный JSON, галлюцинацию или пустой ответ. Парсинг JSON, проверка обязательных полей, проверка на разумность (изменение цены на 1000% — вероятно ошибка).

**Уровень 3: human review для high-significance изменений.** Стратегические сдвиги в позиционировании, кратные изменения цен, запуск принципиально нового продукта — всё это отправляется на ревью перед записью в документ.

```
[AI: анализ изменений]
    │
    ▼
[Switch: significance]
    │              │
  high            medium/low
    │              │
    ▼              ▼
[Slack:           [Автоматическое
 запросить         обновление
 подтверждение]    документа]
    │
    ▼
[Wait for
 approval]
    │
    ▼
[Обновить документ]
```

## Дайджест изменений и уведомления

Поток уведомлений без приоритизации превращается в шум. Два формата доставки решают проблему.

**Мгновенные алерты** — только для high-significance изменений. Конкурент снизил цену на 30%. Конкурент запустил прямой аналог ключевой фичи. Конкурент поднял раунд финансирования.

**Еженедельный дайджест** — сводка всех изменений за неделю, сгруппированная по конкурентам и секциям.

Промпт для генерации дайджеста:

```
Сгенерируй еженедельный дайджест конкурентной разведки.

ИЗМЕНЕНИЯ ЗА НЕДЕЛЮ:
---
{all_changes_json}
---

ИНСТРУКЦИИ:
1. Сгруппируй по конкурентам
2. Внутри каждого конкурента — по значимости (high → low)
3. Для high-significance добавь рекомендацию: что команда должна сделать
4. В начало — executive summary (3-5 предложений, главное за неделю)
5. В конец — "Без изменений" для конкурентов, где ничего не произошло

ФОРМАТ: Markdown, подходящий для Slack-сообщения.
Максимум 500 слов.
```

## Масштабирование: от 3 до 30 конкурентов

Система для 3 конкурентов и система для 30 конкурентов отличаются архитектурно.

**До 5 конкурентов.** Один workflow на секцию. Конкуренты перечислены в массиве внутри workflow. LLM-вызовы выполняются последовательно. Достаточно бесплатного тарифа Make или одного инстанса n8n.

**5-15 конкурентов.** Конфигурация выносится в отдельное хранилище (Notion database, Airtable, JSON в S3). Workflow читает конфигурацию и итерирует по конкурентам. Параллельные вызовы LLM. Rate limiting на уровне оркестратора.

**15+ конкурентов.** Приоритизация. Не все конкуренты одинаково важны. Tier 1 (прямые конкуренты) мониторятся еженедельно. Tier 2 (косвенные) — раз в две недели. Tier 3 (потенциальные) — ежемесячно. Конфигурация хранит tier каждого конкурента, workflow фильтрует по расписанию.

Конфигурация конкурента:

```json
{
  "name": "CompetitorX",
  "tier": 1,
  "sources": {
    "pricing_url": "https://competitorx.com/pricing",
    "blog_rss": "https://competitorx.com/blog/rss.xml",
    "changelog_url": "https://competitorx.com/changelog",
    "careers_url": "https://competitorx.com/careers",
    "linkedin": "https://linkedin.com/company/competitorx",
    "g2_url": "https://g2.com/products/competitorx/reviews"
  },
  "sections": ["pricing", "features", "positioning", "hiring", "reviews"],
  "notification_channel": "#competitive-intel"
}
```

## Стоимость и ROI автоматизации

Прозрачный расчёт для системы на 5 конкурентов, 8 секций, еженедельное обновление.

**Вызовы LLM за месяц:**
- 5 конкурентов * 8 секций * 4 недели = 160 вызовов
- Средний объём: ~2000 входных токенов + ~500 выходных
- При использовании Claude Sonnet 4.6: 160 * (2000 * ~$3 + 500 * ~$15) / 1M = ~$2.16/месяц
- При использовании GPT-5.5: 160 * (2000 * ~$5 + 500 * ~$30) / 1M = ~$4.00/месяц

**Инфраструктура:**
- n8n self-hosted: $0 (Docker на существующем сервере)
- Make: ~$9/месяц (Core план, 10 000 операций)

**Итого: ~$2-13/месяц** в зависимости от провайдера LLM и оркестратора.

**Сравнение с ручным обновлением:**
- Аналитик тратит ~2 часа на полное обновление CI-документа для 5 конкурентов
- При еженедельном обновлении: 8 часов/месяц
- При ставке аналитика $50/час: ~$400/месяц ручной работы

ROI автоматизации: **$400 / $13 ≈ 31x**. Это без учёта того, что автоматическая система не пропускает обновления и работает стабильно независимо от загрузки команды.

## Ограничения и что не автоматизируется

Автоматизация закрывает большую часть рутинного мониторинга — по опыту, порядка 70-80%. Остальное требует человека.

**Не автоматизируется:**
- Анализ стратегических намерений (конкурент нанял VP of Enterprise — это сигнал выхода в enterprise-сегмент, но LLM не сделает этот вывод надёжно)
- Информация из закрытых источников (конференции, нетворкинг, инсайды от клиентов)
- Качественная оценка продукта (UX, производительность, стабильность требуют ручного тестирования)
- Формирование стратегических рекомендаций (AI генерирует данные, стратегию определяет команда)

**Технические ограничения:**
- Сайты с client-side rendering требуют headless browser вместо простого HTTP-запроса
- Anti-bot защита блокирует автоматический скрапинг (решается через прокси или API-сервисы вроде ScrapingBee)
- Изменения в структуре HTML ломают парсинг (решается хешированием текста, а не DOM)

## Первый запуск за 2 часа

Минимальный жизнеспособный CI-документ собирается за одну сессию.

**Час 1: структура и контент.**
1. Выбрать 3 ключевых конкурента
2. Создать документ с секциями: Pricing, Features, Positioning
3. Заполнить секции вручную (первичный baseline)
4. Для каждого конкурента записать URL-источники

**Час 2: автоматизация.**
1. Развернуть n8n (Docker: `docker run -d --name n8n -p 5678:5678 n8nio/n8n`) или создать аккаунт в Make
2. Создать workflow для мониторинга pricing (самая простая секция)
3. Настроить AI-ноду с промптом из этой статьи
4. Подключить запись в документ (Notion API или GitHub API)
5. Настроить уведомление в Slack

После первого workflow остальные секции добавляются по шаблону. Одна секция — 15-20 минут настройки.

Подробнее о построении production-ready MCP серверов для подобных интеграций — в [статье о custom MCP серверах](/ru/blog/mcp-production-custom-servers/).

## Чеклист: готовность CI-системы к запуску

- [ ] Определены конкуренты (минимум 3) и их tier
- [ ] Для каждого конкурента собраны URL-источники по секциям
- [ ] Документ создан и заполнен первичными данными (baseline)
- [ ] Настроен хотя бы один workflow с полным циклом: источник → AI → документ → уведомление
- [ ] Валидация источника: пустые ответы, CAPTCHA, 404 не проходят дальше
- [ ] Валидация AI-ответа: JSON парсится, обязательные поля присутствуют
- [ ] High-significance изменения отправляются на human review
- [ ] Еженедельный дайджест настроен и приходит в канал команды
- [ ] Хеши страниц сохраняются между запусками (нет лишних LLM-вызовов)
- [ ] Error-уведомления настроены (workflow упал — команда узнаёт)

Живой CI-документ забирает на себя рутину мониторинга: конкурент изменил цены в понедельник — команда узнаёт во вторник утром, а не через квартал на стратегической сессии. Что делать с этим сигналом, по-прежнему решает команда.

---

*Нужна помощь с автоматизацией конкурентной разведки? Я помогаю стартапам внедрять AI-решения и строить продукты — [belov.works](https://belov.works).*

## FAQ

**Как предотвратить перегрузку команды низкокачественными уведомлениями и усталость от алертов?**

Трёхуровневая фильтрация решает эту проблему. Во-первых, хеш-сравнение на уровне источника гарантирует, что уведомление не срабатывает, пока страница реально не изменилась. Во-вторых, оценка значимости в промпте AI-процессора (high/medium/low) направляет medium и low изменения в еженедельный дайджест, а не в мгновенные алерты. В-третьих, промпт для дайджеста группирует изменения по конкурентам, сортирует по значимости и ограничивает объём 500 словами. Результат — одно еженедельное сообщение по всем конкурентам вместо потока отдельных уведомлений. Команды, которые пропускают формат дайджеста и отправляют каждое изменение как алерт, обычно отказываются от системы уже через несколько недель.

**Как поступать, когда сайт конкурента использует тяжёлый JavaScript-рендеринг, ломающий простой HTTP-скрапинг?**

Разверните headless browser на уровне оркестратора, используя Puppeteer или Playwright в отдельном Docker-контейнере. Workflow направляет URL в headless browser сервис вместо прямого HTTP-запроса; сервис полностью рендерит страницу и возвращает текстовое содержимое. Это добавляет 3-5 секунд на проверку страницы, но обрабатывает практически любой современный SaaS-сайт. Как альтернатива — управляемые сервисы вроде ScrapingBee или Browserless, берущие на себя браузерные инстансы в облаке. Применяйте только для Tier 1 конкурентов — дополнительная сложность и стоимость не оправданы для квартального мониторинга Tier 3.

**Как обрабатывать ситуацию, когда конкурент проводит масштабный ребрендинг или реструктуризацию сайта, меняющую все URL и структуры страниц?**

Рассматривайте как событие для ручного обновления, а не автоматического. Когда обнаружено крупное структурное изменение (хеш-сравнение сигнализирует об изменении страницы, но AI-процессор возвращает вывод с низкой уверенностью или ошибку), направьте задачу аналитику на 20-минутный ручной ревью. Обновите URL источников в конфигурации конкурента, обновите базовый контент затронутых секций, добавьте запись в changelog с датой и масштабом ребрендинга. Масштабные ребрендинги — стратегические события, заслуживающие ручного чтения: они представляют сдвиг в позиционировании, требующий интерпретации за пределами автоматического сравнения.
