Урок 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 report | 1 абзац | Термінове попередження, до 2 годин |
| Spot report | 1 сторінка | Подія або знахідка |
| Assessment | 2–5 сторінок | Поглиблений аналіз теми |
| Strategic estimate | 10–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 Pro | Historical 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, whoisRead/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 українською мовою:
- BLUF (1–2 речення, ключовий висновок, рівень впевненості)
- Key Judgements (3–5 пунктів із явними рівнями впевненості)
- Коротке тіло аналізу (факти + зв’язки)
- Прогалини (що невідомо і що потрібно перевірити)
- Оцінка джерел (яке джерело, наскільки надійне)
Мінімум: 400 слів. Один AI-інструмент (Claude/GPT) — задокументуйте, як саме ви його використали (який промпт, що редагували).
Частина Б — Obsidian шаблон:
- Встановіть Obsidian + плагіни Dataview та Templater
- Створіть 3 нотатки у форматі з YAML frontmatter: 2 суб’єкти + 1 подія
- Напишіть Dataview-запит, що виводить усі суб’єкти зі статусом «ймовірно» у вигляді таблиці
- Скріншот результату
Рівень 2 — Розширений
Python автоматизація:
- Напишіть (або згенеруйте через AI) Python-скрипт, що:
- Читає CSV файл із подіями або повідомленнями
- Рахує мінімум 2 агрегати (наприклад: повідомлень на день, унікальних акторів на тиждень)
- Генерує мінімум 2 графіки (Plotly або matplotlib)
- Зберігає результат у Markdown-файл через Jinja2-шаблон
- У звіті задокументуйте: які промпти ви використали для генерації коду і скільки ітерацій знадобилось
ACH матриця:
- Для свого кейсу побудуйте ACH матрицю з мінімум 3 гіпотезами і 5 доказами
- Використайте промпт для Claude з розділу «Analysis of Competing Hypotheses»
- Відредагуйте результат — що AI пропустив або неправильно оцінив?
Геопросторова візуалізація (бонус, +10 балів):
- Виберіть мінімум 5 подій із вашого кейсу, що мають прив’язку до локації
- Підготуйте CSV із полями
lat,lon,event_type,date,source - Завантажте у QGIS (або Kepler.gl) — додайте супутникову підложку, стилізуйте точки
- Створіть публікаційну карту: масштабна лінійка, Північ, легенда, джерело
- Вставте карту у ваш spot report як окремий розділ «Геопросторовий аналіз»
- Напишіть 2–3 речення, що описують просторовий патерн
Рівень 3 — Дослідницький
Агентний воркфлоу:
- Сформулюйте OSINT-задачу (аналіз домену, акаунту або мережі каналів)
- Запустіть Claude Code як агента: напишіть один вхідний промпт і дозвольте агенту самостійно виконати кілька кроків із реальними інструментами (bash, web search, файли)
- Збережіть трейс — лог усіх кроків агента
- Оцініть: де агент діяв правильно, де помилився, що потребувало ручного втручання?
- Напишіть фінальний 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
- Anthropic Prompt Engineering Guide: https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/overview
- DAIR.AI Prompt Engineering Guide: https://www.promptingguide.ai/ — найповніша публічна база прийомів
Python та автоматизація
- Jinja2 документація: https://jinja.palletsprojects.com/
- Plotly Python: https://plotly.com/python/ — галерея з кодом для кожного типу графіку
- Pandas документація: https://pandas.pydata.org/docs/
Obsidian
- Dataview документація: https://blacksmithgu.github.io/obsidian-dataview/
- Templater документація: https://silentvoid13.github.io/Templater/
Геопросторові інструменти
- QGIS навчання: https://www.qgistutorials.com/
- Kepler.gl документація: https://docs.kepler.gl/
- bearhunt38 — QGIS for OSINT: https://bearhunt38.medium.com/qgis-for-osint-use-e53cfd0dfba8
- Datawrapper Academy: https://academy.datawrapper.de/ — швидкий старт для карт і графіків у публікаціях
Кінець Уроку 11. Матеріали до наступного заняття: Урок-12-Кластеризація-телеграм-груп-та-візуалізація-графів