Урок 11: Інтеграція AI у робочі процеси — звіти, шаблони, візуалізації

Навігація курсу: Хаб: Уроки

Курс: AI для OSINT 2026
Рівень: Середній / Продвинутий
Тривалість: ~2 академічних години
Попередній урок: Урок-10-Моніторинг-реального-часу | Наступний: Урок-12-Кластеризація-телеграм-груп-та-візуалізація-графів

Інструменти уроку:
Claude Code · Obsidian · Python · Plotly · Jinja2 · QGIS · Kepler.gl


Цілі навчання

Після цього уроку ви зможете:

  • Структурувати OSINT-звіт за стандартами розвідувального аналізу (BLUF, 7 секцій, рівні впевненості)
  • Будувати ефективні аналітичні промпти за фреймворком R.O.C.E. і застосовувати ACH з допомогою AI
  • Організовувати знання розслідування в Obsidian із YAML-шаблонами і Dataview-дашбордом
  • Автоматизувати генерацію звітів через Python + Jinja2 + Plotly
  • Вибрати та налаштувати геопросторову візуалізацію (QGIS, Kepler.gl та ін.) під конкретну задачу звіту
  • Запускати Claude Code як агента для багатокрокових OSINT-задач

Вступ: де аналітик витрачає час — і де його бере AI

Більшість OSINT-аналітиків витрачають на реальний аналіз лише близько 12% робочого часу. Решта йде на механічну роботу:

Збір даних                  ████████████████  35%
Переклад / нормалізація     ████████          18%
Написання звіту             ████████████      25%
Пошук по нотатках           ████              10%
Реальний аналіз             ████              12%

AI здатний забрати на себе більшу частину цієї механічної роботи — але тільки якщо аналітик розуміє, що саме він делегує і чому. Цей урок — про те, як збудувати такий процес.

Де AI бере на себе тягар:

  • Переклад і перефразовування → LLM
  • Структурування чернеток звіту → LLM
  • Генерація коду для скрейпінгу/парсингу → LLM
  • Автоматичні графіки з даних → Python + LLM
  • Пошук по накопичених нотатках → векторна БД + RAG

Де AI не замінює аналітика:

  • Оцінка достовірності джерела
  • Атрибуція: хто стоїть за операцією
  • Ключові судження з юридичними або оперативними наслідками
  • Рішення під невизначеністю на основі досвіду

Принцип уроку: AI підвищує якість роботи аналітика — але лише якщо аналітик розуміє, що саме він делегує і чому.


Частина І — Розвідувальний звіт: стандарти та AI

Більшість OSINT-аналітиків вміють збирати інформацію. Набагато менше вміють перетворювати її на аналітичний продукт, що реально допомагає приймати рішення. У цій частині — стандарти, без яких звіт залишається лише набором фактів.

Планування перед написанням

«Справжня цінність — не в тому, що ви знайшли, а в тому, як ви це інтерпретували.»
(Dutch OSINT Guy)

Перш ніж відкривати редактор, дайте відповідь на три питання:

1. Яка мета продукту?

  • Попередити про загрозу → Flash report
  • Підтвердити або спростувати гіпотезу → Assessment
  • Надати фактологічну базу для рішення → Strategic estimate
  • Задокументувати знахідку для юридичних цілей → Forensic report

2. Хто аудиторія?

АудиторіяЩо їм потрібно
Технічний фахівецьДеталі методології, сирі метрики, відтворюваність
Керівник / замовникКлючові висновки, ризики, рекомендовані дії
Юрист / судЛанцюжок доказів, цитування джерел, нейтральна мова
Медіа / громадськістьДоступна мова, без жаргону, наочні візуалізації

3. Яке рішення буде прийнято на основі цього звіту?

Якщо відповідь незрозуміла — уточніть у замовника перед початком роботи. Звіт без зрозумілого замовника не має аналітичної цінності.

Промпт для Claude (допомога з плануванням):
«Я пишу OSINT-звіт для [тип аудиторії] з метою [ціль]. Яка структура найбільш підходить? Які деталі включити, які опустити? Які терміни потребують пояснення для цієї аудиторії?»

Анатомія розвідувального звіту

Розвідувальний продукт (Intelligence Product) — структурований документ, що перетворює сирі дані на знання, придатне для прийняття рішень.

Повна структура (7 секцій):

┌─────────────────────────────────────────────┐
│  1. ТИТУЛЬНА СТОРІНКА                       │
│     Назва · Організація · Дата · Гриф ·     │
│     Номер кейсу                             │
├─────────────────────────────────────────────┤
│  2. BLUF (Bottom Line Up Front)             │  ← 1–3 речення
│     Ключове судження + рівень впевненості   │
├─────────────────────────────────────────────┤
│  3. ВСТУП                                   │
│     Цілі · Обсяг · Дослідницькі питання ·  │
│     Значущість для замовника                │
├─────────────────────────────────────────────┤
│  4. МЕТОДОЛОГІЯ                             │  ← прозорість
│     Інструменти · Джерела · Обмеження ·    │
│     Процес верифікації                      │
├─────────────────────────────────────────────┤
│  5. ЗНАХІДКИ (Findings)                     │
│     Хронологічно або тематично              │
│     Факти відокремлені від оцінок           │
├─────────────────────────────────────────────┤
│  6. АНАЛІЗ                                  │
│     Key Judgements + рівні впевненості ·   │
│     Патерни · Альтернативні сценарії ·     │
│     Прогалини в інформації                  │
├─────────────────────────────────────────────┤
│  7. ВИСНОВКИ ТА РЕКОМЕНДАЦІЇ               │
│     Конкретні · Дієві · Пріоритизовані     │
└─────────────────────────────────────────────┘

Типи розвідувальних продуктів:

ТипОбсягПризначення
Flash report1 абзацТермінове попередження, до 2 годин
Spot report1 сторінкаПодія або знахідка
Assessment2–5 сторінокПоглиблений аналіз теми
Strategic estimate10–20+ сторінокДовгостроковий прогноз

BLUF: як писати перший абзац

BLUF (Bottom Line Up Front) — ключовий принцип розвідувального письма. Найважливіший висновок — першою фразою. Завжди.

Чому BLUF важливий:

  • Керівник читає перший абзац і вирішує, чи потрібно читати далі
  • Якщо висновок похований у кінці — він може бути пропущений
  • Якщо не можеш написати BLUF — аналіз ще не завершений

Структура BLUF:

[Ключовий висновок] + [Рівень впевненості] + [Найважливіший факт-обґрунтування]

Погано (Bottom Line at the Bottom):

«Ми проаналізували активність 47 Telegram-каналів за 6 місяців. Загальна кількість повідомлень склала 1.2 мільйони. Серед них виявлено повторюваний контент. Час публікацій корелює між каналами. З урахуванням усього вищезазначеного, вважаємо за можливе припустити наявність координації.»

Добре (BLUF):

«З високою впевненістю оцінюємо, що 10 із 47 досліджуваних Telegram-каналів діють як координована мережа — публікують ідентичний контент у вікні ±5 хвилин із синхронізацією учасницької бази 78–91%.»

Підказка від AI: Після написання чернетки попросіть Claude:

«Перепиши перший абзац цього звіту у форматі BLUF: ключове судження першою фразою, рівень впевненості явно вказаний, жодної передісторії до ключового висновку.»

Рівні впевненості та мова оцінок

Рівні впевненості — стандартизована шкала, що дозволяє читачу розуміти, наскільки аналітик впевнений у судженні. Відсутність явного рівня впевненості — це аналітична помилка, а не нейтральність.

Три рівні (стандарт розвідувального аналізу):

РівеньФормулюванняКоли застосовувати
Висока впевненість«з високою впевненістю оцінюємо»Чисельні докази, кілька незалежних джерел, логічно несуперечлива картина
Помірна впевненість«оцінюємо», «вважаємо ймовірним»Деякі докази, але є прогалини або альтернативні пояснення
Низька впевненість«допускаємо», «не можемо виключити»Мало даних, одне джерело, значна невизначеність

Мова ймовірності:

СловоЙмовірність
Майже напевно / практично безсумнівно> 95%
Очевидно / з великою ймовірністю75–95%
Ймовірно / схоже55–75%
Приблизно рівна ймовірність45–55%
Малоймовірно25–45%
Дуже малоймовірно5–25%
Майже виключено< 5%

Промпт для Claude: «У цьому тексті знайди всі судження та оціни, до якого рівня впевненості (висока/помірна/низька) вони відносяться. Якщо рівень не вказаний явно — запропонуй формулювання.»

Методологія та оцінка джерел

Секція «Методологія» — частина звіту, яку аналітики найчастіше пропускають. Це помилка.

Навіщо документувати методологію:

  • Читач розуміє, звідки взялись висновки і наскільки їм довіряти
  • Забезпечує відтворюваність — інший аналітик може повторити аналіз
  • Юридична захищеність: суд або замовник можуть перевірити ланцюжок доказів
  • Виявляє власні прогалини: «я не перевірив X» стає явним

Що включати в секцію методології:

Інструменти: [перелік із поясненням, як використовувався кожен]
Джерела: [типи джерел, часовий діапазон збору]
Процес верифікації: [як підтверджувалась інформація]
Обмеження: [що НЕ могло бути досліджено і чому]

Правило мінімум трьох джерел:
Ключовий факт вважається встановленим лише якщо підтверджений трьома незалежними джерелами. Незалежними = не посилаються одне на одного, різного типу (первинне + вторинне + верифікуюче).

Оцінка джерел — матриця надійності:

ПервиннеВториннеНепідтверджено
Перевірене✅ Висока впевненість⚠️ Помірна❓ Низька
Непідтверджена ідентичність⚠️ Помірна❓ Низька❌ Не використовувати

Цитування — стандарти для OSINT:

  • Завжди вказуйте дату доступу (онлайн-контент змінюється і видаляється)
  • Зберігайте архівну копію (archive.org, локальний скріншот із timestamp)
  • Для кожного твердження — посилання на конкретне джерело, а не загальний сайт
  • AI-generated контент не є джерелом; це інструмент синтезу вже наявних джерел

Промпт для документування методології: «На основі цього переліку інструментів і дій напиши секцію “Методологія” для OSINT-звіту: що використовувалось, як верифікувалась інформація, які обмеження дослідження.»

Що і як делегувати AI у написанні звіту

Делегувати AI (безпечно):

ЗадачаПромпт
Чернетка за нотатками«На основі цих нотаток напиши чернетку spot report у форматі BLUF + Key Judgements»
Переклад з інших мов«Переклади цей текст українською, збережи технічну термінологію»
Нормалізація мови«Перепиши цей абзац у нейтральному аналітичному стилі без емоційних оцінок»
Список альтернатив«Перелічи 5 альтернативних пояснень для цього патерну поведінки»
Виявлення прогалин«Які питання залишаються без відповіді після цього аналізу?»
Резюме для керівника«Напиши executive summary у 3 реченнях для нетехнічної аудиторії»

Не делегувати AI (завжди аналітику):

  • Фінальна атрибуція — «хто це зробив»
  • Оцінка надійності джерела (знаєш лише ти)
  • Ключові судження з юридичними або оперативними наслідками
  • Підпис і відповідальність за продукт

Практичний патерн:

1. Аналітик збирає факти і нотатки (raw intelligence)
2. AI структурує → чернетка звіту
3. Аналітик редагує: додає атрибуції, виправляє судження
4. AI полірує: стиль, граматика, послідовність
5. Аналітик: фінальна перевірка та підпис

Частина ІІ — Prompt Engineering для аналітика

Вміння писати промпти — це не «маніпуляція ChatGPT». Це структурна навичка, аналогічна вмінню формулювати технічне завдання. Погано сформульований промпт → погана відповідь, незалежно від якості моделі.

Архітектура ефективного промпту

Промпт для аналітичної роботи — це не запитання. Це технічне завдання з чітко визначеними параметрами.

Анатомія сильного аналітичного промпту:

[РОЛЬ]          Ти — досвідчений OSINT-аналітик зі спеціалізацією в...
[КОНТЕКСТ]      Ми розслідуємо... Наразі встановлено, що...
[ЗАВДАННЯ]      Твоє завдання — ...
[ФОРМАТ]        Відповідь у форматі: 1) ... 2) ... 3) ...
[ОБМЕЖЕННЯ]     Не роби припущень без доказів. Якщо даних недостатньо — скажи явно.
[ВХІДНІ ДАНІ]   <текст/дані для аналізу>

Чому кожен елемент важливий:

  • Без ролі → LLM відповідає як загальний помічник, а не аналітик
  • Без контексту → втрачає специфіку розслідування
  • Без формату → відповідь непридатна для звіту
  • Без обмежень → LLM галюцинує «зручні» відповіді

Слабкий промпт: «Проаналізуй цей Telegram-канал»

Сильний промпт:

«Ти — OSINT-аналітик, що спеціалізується на виявленні операцій впливу. Нижче — 50 повідомлень з Telegram-каналу за останній тиждень. Встанови: 1) домінуючий наратив; 2) ознаки координованого поширення (синхронізація, ідентичний контент); 3) цільова аудиторія за мовою та темами. Для кожного висновку вкажи рівень впевненості і наведи конкретний приклад з тексту. Де даних недостатньо — скажи явно.»

Фреймворк R.O.C.E.

R.O.C.E. — структурований підхід до промптів для розвідувальних задач.

R — Role        (Роль)
O — Objective   (Ціль)
C — Context     (Контекст)
E — Evidence    (Докази/дані)

Приклад застосування для аналізу персони:

R: Ти — досвідчений аналітик відкритих джерел зі знанням
   цифрових слідів і атрибуції акаунтів.

O: Проведи аналіз цифрового сліду підозрюваного акаунту
   і визнач ймовірне місце базування оператора.

C: Акаунт @example_ua існує з 2019 року, активний переважно
   о 9–18:00 UTC+2. Публікує проросійський контент,
   іноді помиляється між українською і російською в одному повідомленні.
   Відомо, що акаунт раніше був пов'язаний з іншим (@old_handle).

E: [вставити останні 30 повідомлень у форматі timestamp + текст]

Завдання: Встанови мову оригіналу, ймовірний часовий пояс,
тематичні патерни, зв'язок між @example_ua і @old_handle.
Висновки з рівнем впевненості.

Чому R.O.C.E. кращий за вільний промпт:

  • Role активує правильну «режимну модель» в LLM
  • Context усуває двозначності без зайвих пояснень
  • Evidence структурує вхідні дані → LLM не придумує факти
  • Objective виключає відповіді не по темі

Промпти для конкретних аналітичних задач

Синтез із кількох джерел:

Нижче — 5 статей про [тему] з різних джерел і дат.
Синтезуй їх у єдиний аналіз:
1. Факти, про які повідомляють усі/більшість джерел (консенсус)
2. Суперечності між джерелами (що саме і між ким)
3. Унікальна інформація, яка є лише в одному джерелі (і оцінка її надійності)
4. Хронологічна лінія подій
Не додавай власних оцінок. Лише синтез фактів із джерел.

Виявлення наративних маніпуляцій:

Нижче — 20 публікацій про [подію]. Визнач:
1. Які факти включені/виключені порівняно з офіційними джерелами?
2. Яке емоційне забарвлення? (нейтральне / страх / обурення / іронія)
3. Які ключові слова повторюються і можуть бути частиною наративного фреймінгу?
4. Чи є ознаки синхронізованого поширення (однакові фрази, однаковий час)?
Для кожного пункту: цитата-приклад + рівень впевненості.

Складання хронології:

На основі цих даних побудуй хронологію подій у форматі:
YYYY-MM-DD HH:MM | Подія | Джерело | Рівень достовірності (підтверджено/вірогідно/непідтверджено)
Де час невідомий — використай [приблизно]. Виділи розриви в хронології.

Gap analysis:

Ось що нам відомо про [суб'єкт]: [перелік фактів]
Визнач: які ключові питання залишаються без відповіді?
Для кожної прогалини вкажи: чому це важливо для аналізу і яке джерело могло б заповнити прогалину.

Analysis of Competing Hypotheses (ACH) з AI

ACH — структурована аналітична техніка для боротьби з confirmation bias. Розроблена в ЦРУ Річардсом Хьором.

Принцип: Ми не шукаємо докази на підтримку гіпотези — ми відкидаємо гіпотези через суперечливі докази.

ACH матриця:

ДоказиH1: Координована операціяH2: Органічний рухH3: Комерційний накрут
Синхронізація ±5 хв++− −+
78–91% overlap учасників++−++
Ідентичний текст дослівно++− −−
Різноманітні IP-адреси авторів−+−
Монетизації немає+++− −

Позначки: ++ підтримує, + слабко підтримує, − суперечить, −− сильно суперечить, ? невідомо.

Висновок: H1 має найменше суперечностей → найімовірніша.

Промпт для Claude — побудова ACH матриці:

Побудуй ACH матрицю для наступної ситуації.
Сформулюй 3–5 конкуруючих гіпотез, що пояснюють [явище].
Для кожного доказу зі списку нижче постав оцінку:
++ (сильно підтримує), + (підтримує), ? (нейтрально), - (суперечить), -- (сильно суперечить).
Виведи у вигляді таблиці Markdown.
В кінці: яка гіпотеза має найменшу кількість суперечностей?

Докази: [список фактів]

Частина ІІІ — Шаблони та Obsidian

Хаотичні нотатки в різних місцях — одна з найбільших проблем OSINT-аналітика. Obsidian вирішує її за рахунок структурованих шаблонів і автоматичних запитів.

Obsidian як OSINT knowledge base

Obsidian — локальний Markdown-редактор із граф-зв’язками між нотатками. Без хмари, без підписки, без витоків даних розслідування.

Чому Obsidian для OSINT:

  • Усі нотатки — звичайні .md файли → версіонування через git
  • Двонаправлені посилання [[назва]] → автоматичний граф зв’язків
  • YAML frontmatter → структуровані метадані для Dataview
  • Canvas → візуальна карта розслідування (аналог Maltego, але локально)
  • Плагіни: Dataview, Templater, QuickAdd, Graph Analysis

Структура vault для OSINT-розслідування:

Investigation-Vault/
├── 00-Дашборд.md              ← Dataview-огляд усього розслідування
├── 01-Суб'єкти/
│   ├── Person-Іванов.md
│   ├── Organization-TechUA.md
│   └── Account-@ivan_ua.md
├── 02-Події/
│   ├── 2026-01-15-Подія-X.md
│   └── 2026-02-03-Подія-Y.md
├── 03-Докази/
│   ├── Screenshot-001.md
│   └── Article-2026-01-15.md
├── 04-Джерела/
│   └── Source-TelegramChannel.md
└── 05-Звіти/
    └── Draft-Assessment.md

Граф зв’язків будується автоматично з [[посилань]] — без жодного додаткового налаштування.

Шаблони Obsidian: YAML frontmatter

YAML frontmatter — метадані на початку кожної нотатки. Dataview читає їх як базу даних.

Шаблон: Суб’єкт (Person)

---
тип: особа
ім'я: Іванов Іван Іванович
псевдоніми:
  - "@ivan_ua"
  - "IvanUA"
  - "ivan.petrenko90@gmail.com"
статус: підтверджено          # підтверджено / ймовірно / відкинуто
впевненість: висока
теги: [фігурант, оператор-впливу, Telegram]
пов'язані_організації:
  - "[[Organization-TechUA]]"
джерела:
  - "[[Source-TelegramChannel]]"
  - "[[Article-2026-01-15]]"
дата_додавання: 2026-05-26
дата_оновлення: 2026-05-26
---
 
## Відомі факти
...
 
## Встановлені зв'язки
...
 
## Прогалини
...

Шаблон: Подія

---
тип: подія
назва: Публікація координованого контенту
дата: 2026-01-15
час: "14:22"
місце: Telegram / онлайн
учасники:
  - "[[Account-@channel_a]]"
  - "[[Account-@channel_b]]"
докази:
  - "[[Screenshot-001]]"
статус: підтверджено
теги: [CIB, координація, вибори]
---

Templater плагін — заповнює {{date}}, {{title}} та будь-які змінні автоматично при створенні нотатки.

Dataview: живий дашборд розслідування

Dataview — плагін Obsidian, що виконує SQL-подібні запити до YAML frontmatter усіх нотаток у реальному часі.

Приклад 1 — Всі непідтверджені суб’єкти:

```dataview
TABLE ім'я, впевненість, теги, дата_оновлення
FROM "01-Суб'єкти"
WHERE статус = "ймовірно"
SORT дата_оновлення DESC
```

Приклад 2 — Таймлайн подій:

```dataview
TABLE назва, час, учасники, статус
FROM "02-Події"
SORT дата ASC
```

Приклад 3 — Суб’єкти без встановлених зв’язків (прогалини):

```dataview
TABLE ім'я, дата_додавання
FROM "01-Суб'єкти"
WHERE !пов'язані_організації
SORT дата_додавання ASC
```

Приклад 4 — Дашборд: загальна статистика розслідування:

```dataviewjs
const subjects = dv.pages('"01-Суб\'єкти"');
const events   = dv.pages('"02-Події"');
const sources  = dv.pages('"04-Джерела"');

dv.paragraph(`
**Фігурантів:** ${subjects.length} (підтверджено: ${subjects.filter(p=>p.статус==="підтверджено").length})
**Подій:** ${events.length}
**Джерел:** ${sources.length}
**Останнє оновлення:** ${dv.current().file.mtime.toFormat("dd.MM.yyyy HH:mm")}
`);
```

Частина IV — Python: автоматизація звітів та візуалізацій

Якщо ви регулярно робите одні й ті ж кроки — збираєте дані, рахуєте агрегати, малюєте графіки, вставляєте в шаблон — автоматизуйте це один раз і забудьте. Python + Jinja2 + Plotly дозволяють зробити це за кілька годин.

Python pipeline: від сирих даних до звіту

Архітектура автоматизованого OSINT-звіту:

Сирі дані (CSV/JSON/DB)
        ↓
   pandas — очищення, нормалізація, агрегація
        ↓
   matplotlib / plotly — автоматичні графіки
        ↓
   Jinja2 — підстановка даних у HTML/Markdown-шаблон
        ↓
   weasyprint / pandoc — конвертація в PDF
        ↓
   Готовий звіт (PDF + JSON)

Мінімальний робочий приклад:

import pandas as pd
import plotly.express as px
from jinja2 import Environment, FileSystemLoader
import json
 
# 1. Завантаження і агрегація
df = pd.read_csv("telegram_events.csv", parse_dates=["timestamp"])
df["date"] = df["timestamp"].dt.date
 
daily = df.groupby("date").agg(
    messages=("message_id", "count"),
    unique_channels=("channel_id", "nunique")
).reset_index()
 
# 2. Автоматичний графік
fig = px.line(daily, x="date", y="messages",
              title="Активність мережі каналів по днях",
              labels={"messages": "Кількість повідомлень", "date": "Дата"})
fig.write_image("activity_chart.png", width=1200, height=500)
 
# 3. Ключові метрики для звіту
stats = {
    "total_messages": int(df.shape[0]),
    "total_channels": int(df["channel_id"].nunique()),
    "peak_day": str(daily.loc[daily["messages"].idxmax(), "date"]),
    "peak_count": int(daily["messages"].max()),
    "date_from": str(df["timestamp"].min().date()),
    "date_to": str(df["timestamp"].max().date()),
}
 
# 4. Генерація звіту через Jinja2
env = Environment(loader=FileSystemLoader("."))
template = env.get_template("report_template.md")
report = template.render(**stats)
 
with open("report_output.md", "w", encoding="utf-8") as f:
    f.write(report)

Jinja2: шаблон звіту

Jinja2 — мова шаблонів, що підставляє змінні і виконує умовну логіку в будь-якому текстовому форматі (Markdown, HTML, LaTeX).

report_template.md:

# SPOT REPORT — Аналіз мережі Telegram-каналів
 
**Дата:** {{ now }}
**Класифікація:** INTERNAL / FOR OFFICIAL USE ONLY
**Аналітик:** [підпис]
 
---
 
## BLUF
 
Аналіз мережі з **{{ total_channels }} каналів** за період {{ date_from }} — {{ date_to }}
виявив ознаки координованої активності. Пікове навантаження: **{{ peak_count }} повідомлень**
за {{ peak_day }}.
 
## Ключові судження
 
1. (Висока впевненість) Мережа демонструє синхронізацію публікацій у вікні ±5 хвилин...
2. (Помірна впевненість) Перекриття аудиторії між кластерами свідчить про спільне управління...
 
## Динаміка активності
 
*Очікуваний результат: графік активності, який генерує код вище (`activity_chart.png`).*
 
{% if peak_count > 5000 %}
> **Увага:** Пікова активність перевищує аномальний поріг (5 000 повідомлень/день).
{% endif %}
 
## Статистика
 
| Метрика | Значення |
|---------|---------|
| Повідомлень всього | {{ total_messages }} |
| Унікальних каналів | {{ total_channels }} |
| Пікова дата | {{ peak_day }} |
| Пік (повідомлень) | {{ peak_count }} |
 
## Прогалини
 
- [ ] Встановити адміністраторів каналів Кластеру 3
- [ ] Верифікувати фізичну локацію ≥3 операторів
 
## Джерела
 
[автоматично додаються зі списку]

Автоматичні візуалізації: Plotly для OSINT

Plotly — інтерактивні графіки в Python. На відміну від matplotlib, легко зберегти в HTML для інтерактивних звітів.

1. Heatmap активності по годинах і днях тижня (пошук часового патерну):

import plotly.graph_objects as go
 
pivot = df.pivot_table(
    index=df["timestamp"].dt.dayofweek,
    columns=df["timestamp"].dt.hour,
    values="message_id", aggfunc="count"
).fillna(0)
 
fig = go.Figure(data=go.Heatmap(
    z=pivot.values,
    x=[f"{h:02d}:00" for h in range(24)],
    y=["Пн","Вт","Ср","Чт","Пт","Сб","Нд"],
    colorscale="Reds",
    colorbar=dict(title="Повідомлень")
))
fig.update_layout(title="Патерн активності по годинах та днях тижня")
fig.write_html("heatmap_activity.html")

2. Scatter — порівняння метрик центральності:

fig = px.scatter(
    node_df,
    x="betweenness", y="pagerank",
    size="degree", color="community",
    hover_name="label",
    title="Betweenness vs PageRank (розмір = degree, колір = спільнота)"
)
fig.write_html("centrality_scatter.html")

3. Bar race — топ-канали по тижнях:

df["week"] = df["timestamp"].dt.to_period("W").astype(str)
weekly_top = df.groupby(["week","channel_name"])["message_id"].count().reset_index()
fig = px.bar(weekly_top, x="message_id", y="channel_name",
             animation_frame="week", orientation="h",
             title="Топ-10 каналів по тижнях")
fig.write_html("bar_race.html")

AI-генерація коду для OSINT-скриптів

Практичний паттерн: Описати задачу Claude → отримати готовий Python-скрипт → перевірити → запустити.

Промпт для генерації коду:

Напиши Python скрипт для наступного завдання:

Вхідні дані: CSV файл telegram_messages.csv з колонками:
timestamp (ISO8601), channel_id (str), channel_name (str),
message_id (int), text (str), views (int), forwards (int)

Задача:
1. Знайди всі канали, які публікували ідентичний текст (cosine similarity > 0.9)
   протягом 10-хвилинного вікна
2. Виведи: пари каналів + кількість таких збігів + приклад тексту
3. Збережи результат у coincident_posts.csv

Бібліотеки: pandas, sklearn (TfidfVectorizer, cosine_similarity)
Коментарі: мінімальні, лише де неочевидно

Що перевірити перед запуском:

  • Чи читає файл з правильним кодуванням (encoding='utf-8')
  • Чи немає hardcoded шляхів
  • Чи обробляє порожні значення (dropna або явна перевірка)
  • Чи є обмеження на розмір вибірки (на великих датасетах косинус-матриця може OOM)

Ітеративний рефайнинг:

[Отримав скрипт] → Запустив → Помилка: "KeyError: 'channel_name'"
→ Claude: «Скрипт падає з KeyError: 'channel_name'.
  Ось перші 3 рядки CSV: [вставити]. Виправ.»
→ [Виправлений скрипт]

Середня кількість ітерацій до робочого скрипту для стандартної задачі — 2–4 кроки.


Частина ІVб — Геопросторові візуалізації в звіті

Карта в звіті — це не ілюстрація. Це доказовий матеріал із власними вимогами до оформлення. Ця частина про те, коли карта підсилює звіт, а коли лише додає шум, і як обрати правильний інструмент.

Карта в OSINT-звіті: коли і як

Коли карта додає цінності:

  • Подія або об’єкт прив’язані до конкретної локації (геолокована фотографія, маршрут техніки)
  • Потрібно показати просторовий патерн (кластеризація публікацій за регіонами)
  • Верифікація: «де заявлено» vs «де це фізично»
  • Рух або маршрут є частиною знахідки

Коли карта зайва:

  • «Маємо дані з Telegram — покажемо на карті України» без просторового змісту
  • Якщо точність геолокації <30 км — крапка на карті вводить в оману
  • Якщо карта лише дублює таблицю з координатами без додаткового сенсу

Стандарти публікаційної карти (обов’язково для звіту):

ЕлементНавіщо
Масштабна лінійка + ПівнічЧитач розуміє відстані та орієнтацію
Легенда для кожного шаруСимвол без пояснення — не доказ
Джерело підложки + дата знімкуВідтворюваність; знімки змінюються
Координатна сітка або bboxДозволяє незалежно перевірити локацію
CRS / проєкціяОбов’язково якщо є вимірювання відстаней

Промпт для AI — описати просторову знахідку словами:

Я маю координати 12 подій з атрибутами [тип, дата, джерело].
Опиши просторовий патерн для секції Findings звіту:
чи є кластеризація, яка відстань між групами, який регіон охоплюють?
Не роби оцінювальних суджень — лише опис просторових характеристик.

QGIS: від даних до звітної карти

QGIS — безкоштовна крос-платформна GIS із відкритим кодом. Print Layout — саме та функція, що дає публікаційний результат із масштабною лінійкою, легендою і підписом джерела.

Звітний pipeline в QGIS:

CSV / GeoJSON (lat, lon + атрибути)
        ↓  Layer → Add Delimited Text Layer
Точковий шар на полотні
        ↓  QuickMapServices → Google Satellite Hybrid
Аналітика (за потребою)
        ↓  Processing → Heatmap / Buffer / Spatial Join
Стилізація
        ↓  Layer Properties → Symbology → колір/розмір за атрибутом
Print Layout
        ↓  Project → New Print Layout
Експорт
        ↓  Export as Image (PNG 300 dpi) або Export as PDF

Print Layout — обов’язкові елементи:

  • Add Item → Map — вставити вид карти в макет
  • Add Item → Scale Bar — масштабна лінійка
  • Add Item → North Arrow — Північ
  • Add Item → Legend — авто-легенда зі стилів шарів
  • Add Item → Label — підпис: джерело підложки, CRS, дата

Ключові QGIS-плагіни для OSINT-репортингу:

  • QuickMapServices — супутникові підложки Google/Bing/ESRI одним кліком
  • QuickOSM — витягти інфраструктуру OSM за тегами прямо в QGIS (amenity=hospital, military=base тощо)
  • Streetview — перехід до Google Street View для геолокаційної верифікації

Підготовка даних у Python перед QGIS:

df_map = df[["lat", "lon", "event_type", "date", "source"]].dropna(subset=["lat", "lon"])
df_map.to_csv("events_for_map.csv", index=False, encoding="utf-8")
# Обов'язково: окремі поля lat і lon у десятковому форматі (50.4501, а не 50°27'N)

Альтернативи QGIS: вибір інструменту під задачу

ІнструментСильна сторонаОбмеженняКоли обирати
QGISПовний GIS-аналіз, OSM-запити, PDF-друкКрива навчанняПросторовий аналіз, звіт для друку
Kepler.glМільйони точок, Trip-анімація, HTML-звітНемає spatial join, тільки браузерВеликий датасет, веб-публікація
Google Earth ProHistorical Imagery, KMZ/KML overlay, безкоштовноЗакритий, не аналітичнийШвидка геолокаційна верифікація
Felt (felt.com)Сучасний колаборативний веб-редакторХмарний — не для чутливих кейсівКомандна робота, швидка публікація
uMap (umap.openstreetmap.fr)Open source, self-hostableОбмежені шари, нема аналітикиПублічні мапи, self-hosted для чутливих
DatawrapperХороплет-карти для публікацій за 5 хвЛише агреговані дані, без точокChoropleth по країнах/регіонах

Правило вибору:

  • Чутливий кейс → QGIS (локально) або self-hosted uMap
  • Багато точок → Kepler.gl
  • Порівняння зі супутниковим знімком → Google Earth Pro
  • Карта для публічного звіту або медіа → Datawrapper або Felt
  • Просторовий аналіз (buffer, join, overlay) → тільки QGIS

Kepler.gl у Python — карта прямо зі звіту:

from keplergl import KeplerGl
 
map_1 = KeplerGl(height=600)
map_1.add_data(data=df_map, name="events")
map_1.save_to_html(file_name="report_map.html")
# → самодостатній HTML-файл, вбудовується в будь-який веб-звіт

Частина V — Агентні воркфлоу

AI найпотужніший не як «відповідальник на одне запитання», а як агент, що самостійно розбиває задачу на кроки, викликає інструменти і адаптує план при несподіваних результатах.

Від одного промпту до мульти-кроку

Одноразовий промпт — один запит → одна відповідь. Підходить для простих задач.

Агентний воркфлоу — LLM самостійно розбиває задачу на кроки, викликає інструменти, оцінює результати і продовжує до виконання мети.

ReAct паттерн (Reason + Act):

Ціль: «Знайди всю публічно доступну інформацію про домен malicious-site.com»

Крок 1:
  THINK: Спочатку перевірю WHOIS для реєстрації і власника
  ACT:   whois_lookup("malicious-site.com")
  OBS:   Реєстратор: Namecheap, дата: 2025-11-03, email: admin@fastmail.com

Крок 2:
  THINK: Email admin@fastmail.com — перевірю витоки баз
  ACT:   haveibeenpwned_check("admin@fastmail.com")
  OBS:   Знайдено в 2 витоках (LinkedIn 2021, Canva 2019)

Крок 3:
  THINK: Перевірю пасивний DNS для пов'язаних доменів
  ACT:   passive_dns("malicious-site.com")
  OBS:   IP 185.220.101.x — також хостить evil-news.net, fake-media.org

Крок 4:
  THINK: Достатньо для spot report. Формую висновки.
  ACT:   generate_report(findings)

Інструменти, які Claude Code може викликати:

  • WebSearch → пошук у відкритих джерелах
  • Bash → запуск Python скриптів, curl, whois
  • Read/Write → читання і запис файлів
  • MCP-сервери → Gephi, ArkhamMirror, Neo4j, зовнішні API

Claude як OSINT-агент: практичний приклад

Задача: Зібрати цифровий профіль домену і скласти короткий технічний бриф.

Промпт:

Проведи OSINT-аналіз домену [target.example.com].
Використовуй доступні інструменти послідовно:
1. WHOIS (реєстрація, власник, дата)
2. DNS записи (A, MX, TXT, NS)
3. Пошук у відкритих джерелах (новини, форуми)
4. SSL-сертифікат (CN, організація, дата)

Після кожного кроку — коротко зафіксуй знахідки.
Фінальний звіт: BLUF + ключові факти + рівень загрози (low/medium/high) з обґрунтуванням.
Де даних недостатньо — скажи явно.

Що відбувається всередині:

bash("whois target.example.com")
bash("dig target.example.com ANY +short")
web_search("target.example.com site:pastebin.com OR site:github.com")
bash("openssl s_client -connect target.example.com:443 </dev/null 2>/dev/null | openssl x509 -noout -text")
# → Синтезує результати → Пише звіт у Markdown
write("domain_brief.md", report_content)

Переваги агентного підходу:

  • Аналітик описує ціль, а не кроки
  • Агент адаптує план при неочікуваних результатах
  • Кожен крок задокументований (трейс)
  • Повторюваний: однаковий промпт = однакова методологія для всіх кейсів

Повний OSINT-воркфлоу з AI: кейс

Сценарій: Розслідування координованої дезінформаційної кампанії. Від отримання задачі до готового звіту — 4 години замість 2 днів.

КРОК 1 — Збір [30 хв]
  Groupint → 47 Telegram-каналів → Neo4j
  Claude (агент): автоматичний WHOIS всіх доменів зі статей

КРОК 2 — Мережевий аналіз [20 хв]
  gephi-ai + Claude → modularity, betweenness, PageRank
  → автоматичний граф PNG + GEXF

КРОК 3 — Контент-аналіз [25 хв]
  Python скрипт (Claude-generated) → cosine similarity матриця
  → 11 каналів з ідентичним контентом ±3 хв → CSV

КРОК 4 — Синтез [15 хв]
  Промпт Claude (R.O.C.E.): синтез знахідок з кроків 2–3
  → ACH матриця: 3 гіпотези → H1 (координована операція) найімовірніша

КРОК 5 — Звіт [30 хв]
  Jinja2 шаблон + pandas stats → автоматична чернетка Markdown
  Claude: відполірувати стиль, перевірити рівні впевненості
  Аналітик: додати атрибуцію, підпис, фінальна вичитка
  → PDF звіт

ЗАГАЛЬНИЙ ЧАС: ~2 год (ручна робота аналітика: ~45 хв)
БЕЗ AI: 2–3 робочі дні

Де AI помиляється в аналітичній роботі

Знати обмеження AI — так само важливо, як знати його можливості.

1. Галюцинації фактів
LLM може «вигадати» цитату, дату, ім’я або URL, якого не існує. Правило: ніколи не включати факт у звіт, якщо він не верифікований незалежним джерелом. Промпт-обережність: «Якщо ти не впевнений у факті — скажи ‘невідомо’, не вигадуй»

2. Підтвердження упередженості через формулювання
Якщо запитати «Доведи, що це координована операція» — LLM знайде докази. Якщо запитати «Які аргументи проти гіпотези про координацію?» — знайде інші. Рішення: завжди запитувати обидві сторони, використовувати ACH.

3. Переоцінка форми
Гладко написаний абзац від LLM звучить переконливо — незалежно від якості доказів. Форма не є доказом змісту.

4. Витік чутливих даних
Не вставляти у комерційні LLM API дані, що ідентифікують суб’єктів розслідування (PII). Для чутливих кейсів → локальні моделі (Ollama + Gemma/Llama).

5. Залежність від AI
Аналітик, що перестає перевіряти AI-висновки, перестає бути аналітиком.

Ключові принципи: підсумок уроку

Стандарти звіту:

  • BLUF: ключовий висновок — першою фразою, завжди
  • Рівні впевненості: висока / помірна / низька — явно для кожного судження
  • ACH: відкидати гіпотези через суперечності, не підтверджувати через збіги

Prompt Engineering:

  • Фреймворк R.O.C.E.: роль + ціль + контекст + докази
  • Конкретні задачі = конкретні промпти (не «проаналізуй», а «знайди X у форматі Y»)
  • Ітеративний рефайнинг — нормально і ефективно

Автоматизація та візуалізація:

  • Obsidian + Dataview → живий дашборд розслідування
  • Python + Jinja2 → автоматичні звіти зі стандартного шаблону
  • Plotly → аналітичні часові та мережеві візуалізації
  • QGIS Print Layout → публікаційна карта з легендою і масштабом
  • Kepler.gl / Datawrapper → карти для веб-звітів і великих датасетів

Агентний воркфлоу:

  • Агентний Claude Code → багатокрокові OSINT-задачі
  • ReAct: THINK → ACT → OBSERVE; кожен крок задокументований

Золоте правило: AI прискорює процес — аналітик несе відповідальність за висновки. Підпис під звітом завжди людський.


Домашнє завдання — ДЗ 11

Назва: «AI-асистований аналітичний продукт»

Рівень 1 — Базовий (обов’язковий)

Частина А — Структурований звіт:

На основі будь-якого публічного OSINT-кейсу (новини, твіти, Telegram-канали) напишіть Spot Report українською мовою:

  1. BLUF (1–2 речення, ключовий висновок, рівень впевненості)
  2. Key Judgements (3–5 пунктів із явними рівнями впевненості)
  3. Коротке тіло аналізу (факти + зв’язки)
  4. Прогалини (що невідомо і що потрібно перевірити)
  5. Оцінка джерел (яке джерело, наскільки надійне)

Мінімум: 400 слів. Один AI-інструмент (Claude/GPT) — задокументуйте, як саме ви його використали (який промпт, що редагували).

Частина Б — Obsidian шаблон:

  1. Встановіть Obsidian + плагіни Dataview та Templater
  2. Створіть 3 нотатки у форматі з YAML frontmatter: 2 суб’єкти + 1 подія
  3. Напишіть Dataview-запит, що виводить усі суб’єкти зі статусом «ймовірно» у вигляді таблиці
  4. Скріншот результату

Рівень 2 — Розширений

Python автоматизація:

  1. Напишіть (або згенеруйте через AI) Python-скрипт, що:
    • Читає CSV файл із подіями або повідомленнями
    • Рахує мінімум 2 агрегати (наприклад: повідомлень на день, унікальних акторів на тиждень)
    • Генерує мінімум 2 графіки (Plotly або matplotlib)
    • Зберігає результат у Markdown-файл через Jinja2-шаблон
  2. У звіті задокументуйте: які промпти ви використали для генерації коду і скільки ітерацій знадобилось

ACH матриця:

  1. Для свого кейсу побудуйте ACH матрицю з мінімум 3 гіпотезами і 5 доказами
  2. Використайте промпт для Claude з розділу «Analysis of Competing Hypotheses»
  3. Відредагуйте результат — що AI пропустив або неправильно оцінив?

Геопросторова візуалізація (бонус, +10 балів):

  1. Виберіть мінімум 5 подій із вашого кейсу, що мають прив’язку до локації
  2. Підготуйте CSV із полями lat, lon, event_type, date, source
  3. Завантажте у QGIS (або Kepler.gl) — додайте супутникову підложку, стилізуйте точки
  4. Створіть публікаційну карту: масштабна лінійка, Північ, легенда, джерело
  5. Вставте карту у ваш spot report як окремий розділ «Геопросторовий аналіз»
  6. Напишіть 2–3 речення, що описують просторовий патерн

Рівень 3 — Дослідницький

Агентний воркфлоу:

  1. Сформулюйте OSINT-задачу (аналіз домену, акаунту або мережі каналів)
  2. Запустіть Claude Code як агента: напишіть один вхідний промпт і дозвольте агенту самостійно виконати кілька кроків із реальними інструментами (bash, web search, файли)
  3. Збережіть трейс — лог усіх кроків агента
  4. Оцініть: де агент діяв правильно, де помилився, що потребувало ручного втручання?
  5. Напишіть фінальний spot report на основі результатів агента (з вашою редакцією)

Формат здачі

  • Звіт: ДЗ11_Прізвище_report.md (структурований за BLUF + KJ)
  • Obsidian: скріншот Dataview-запиту
  • Код (Рівень 2+): ДЗ11_Прізвище_script.py + ДЗ11_Прізвище_output.md
  • Трейс агента (Рівень 3): ДЗ11_Прізвище_agent_trace.md
  • Дедлайн: до наступного заняття
  • Захист: 5–7 хвилин — показати звіт, пояснити як використовували AI і де редагували

Критерії оцінювання

КритерійРівень 1Рівень 2Рівень 3
Структура звіту (BLUF, KJ, рівні впевненості)35%25%20%
Якість аналітичного змісту30%25%25%
Obsidian / автоматизація20%25%20%
Рефлексія: що AI зробив, що ви виправили15%15%15%
Агентний воркфлоу + трейс——20%

Ресурси та додаткове читання

Звітні стандарти

  • Dutch OSINT Guy — Intelligence Report Writing: https://www.dutchosintguy.com/post/osint-analysis-intelligence-report-writing — практичний посібник із структури OSINT-звіту, BLUF, аудиторії та методології
  • Richards Heuer — Psychology of Intelligence Analysis (CIA, безкоштовно онлайн) — першоджерело по ACH та аналітичним упередженням
  • NATO OSINT Handbook — офіційні стандарти для тих, хто працює з державними замовниками

Prompt Engineering

Python та автоматизація

Obsidian

Геопросторові інструменти


Кінець Уроку 11. Матеріали до наступного заняття: Урок-12-Кластеризація-телеграм-груп-та-візуалізація-графів