{"id":50978576,"url":"https://github.com/stupidcucumber/creative-analyzer-agent","last_synced_at":"2026-06-19T11:32:24.773Z","repository":{"id":359140566,"uuid":"1236539285","full_name":"stupidcucumber/creative-analyzer-agent","owner":"stupidcucumber","description":"Multi-agent ChatBOT that analyses performance of various creatives.","archived":false,"fork":false,"pushed_at":"2026-05-20T14:41:38.000Z","size":532,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-20T19:43:40.541Z","etag":null,"topics":["gemini-api","langchain","langgraph","marketing","sqlite"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stupidcucumber.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-12T10:43:48.000Z","updated_at":"2026-05-15T15:35:43.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/stupidcucumber/creative-analyzer-agent","commit_stats":null,"previous_names":["stupidcucumber/creative-analyzer-agent"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/stupidcucumber/creative-analyzer-agent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stupidcucumber%2Fcreative-analyzer-agent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stupidcucumber%2Fcreative-analyzer-agent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stupidcucumber%2Fcreative-analyzer-agent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stupidcucumber%2Fcreative-analyzer-agent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stupidcucumber","download_url":"https://codeload.github.com/stupidcucumber/creative-analyzer-agent/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stupidcucumber%2Fcreative-analyzer-agent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34530300,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gemini-api","langchain","langgraph","marketing","sqlite"],"created_at":"2026-06-19T11:32:23.951Z","updated_at":"2026-06-19T11:32:24.761Z","avatar_url":"https://github.com/stupidcucumber.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Як запустити?\n\n1. Треба створити `.env` за наступними API ключами: GOOGLE_API_KEY, TELEGRAM_BOT_API_TOKEN.\n2. Зробити `uv sync` (встановити `uv` якщо ще немає [тут](https://docs.astral.sh/uv/getting-started/installation/))\n3. Запустити через `uv run agent.py`.\n\n# Характеристики креативів\n\n## Характеристики відео/зображень (AgentOutputContentCharacteristics)\nЦя група полів аналізує структуру та психологічні тригери самого відео або зобреження.\n\n1. Хук\n\n`content_hook (Текст/концепція зачіпки)`: Перший елемент, що змушує користувача зупинити гортання стрічки (scroll-stopper). Зазвичай апелює до конкретної проблеми (наприклад, «соматичні вправи проти жиру на животі») або створює інтригу.\n\n`content_hook_length_seconds (Тривалість зачіпки)`: Точний хронометраж початкового хука. Для утримання уваги це зазвичай короткий інтервал від 1 до 5 секунд, де чітко артикулюється головна цінність.\n\n`content_hook_visual_format (Візуальний формат)`: Естетична подача хука. Визначає, що саме використовується: порівняння на розділеному екрані (split-screen), «живі» UGC-кадри (контент від звичайних користувачів) чи графічні інформаційні шари (overlays).\n\n`content_hook_type (Тип хука)`: Психологічний механізм початку відео. Це може бути діагностичне питання про тіло користувача, парадоксальний/шокуючий факт або демонстрація швидкої трансформації «до/після».\n\n`content_hook_emotional_valence (Емоційне забарвлення)`: Початковий емоційний настрій відео. Визначає, чи починається ролик з нагнітання проблеми («Біль/Роздратування»), чи одразу пропонує натхненне рішення («Прагнення до полегшення»).\n\n\n2. Ціннісна пропозиція (Value)\n\n`content_product_value_type (Тип цінності продукту)`: Головна обіцянка реклами («навіщо це мені?»). Фокусується на кінцевому результаті (трансформація) або на зручності стилю життя (наприклад, легкість виконання вправ без спортзалу).\n\n`content_body_logic_type (Логіка викладу)`: Риторична стратегія для побудови довіри та подолання скепсису. Може використовувати освітній розбір (пояснення науки про кортизол/соматику) або соціальний доказ (результати реальних користувачів).\n\n3. Заклик до дії (CTA)\n\n`content_cta (Текст заклику до дії)`: Фінальна пряма вказівка чи команда наприкінці відео. Базується на терміновості або цікавості, наприклад: «Пройди тест», «Забери свій план на 28 днів» чи «Почни пробний період за $1».\n\n`content_cta_type (Тип заклику до дії)`: Стратегічна класифікація цілі конверсії: переспрямування користувача на інтерактивну діагностику (квіз) чи на миттєве оформлення підписки/тріалу.\n\n4. Загальні параметри\n\n`pacing (Темп/Динаміка)`: Швидкість, з якою відео взаємодіє з користувачем і подає інформацію.\n\n## Характеристики тексту публікації (AgentOutputPostTextCharacteristics)\nЦя група аналізує копірайтинг — текст (caption), який супроводжує відео у публікації. Структура дублює логіку відео, але націлена на текстове сприйняття.\n\n1. Текстовий хук (Post Hook)\n\n`post_hook (Перший рядок)`: Текст-зачіпка на початку опису. Зазвичай це смілива заява або опис знайомої користувачу проблеми (наприклад, «Досить боротися зі своїм тілом»), мета якої — змусити натиснути кнопку «Читати далі» (See More).\n\n`post_hook_type (Тип текстового хука)`: Риторична структура початку тексту. Наприклад, шокуючий факт про метаболізм або запитання, таргетоване на конкретний архетип (наприклад, «Для зайнятих професіоналів»).\n\n`post_hook_emotional_valence (Емоційне забарвлення тексту)`: Точка емоційного входу. Часто починається з емпатичного опису болю чи втоми, щоб вибудувати зв'язок із читачем перед пропозицією рішення.\n\n2. Цінність у тексті (Post Value)\n\n`post_product_value_type (Тип цінності в тексті)`: Обіцянка, закладена в тілі тексту (наприклад, акцент на трансформації або на тому, що вправи можна робити «прямо в піжамі»).\n\n`post_body_logic_type (Логіка текстового викладу)`: Аргументація та докази в тексті. Часто реалізується через списки (bullet points), що пояснюють фізіологічні чи психологічні переваги застосунку (наприклад, регуляція кортизолу).\n\n4. Текстовий заклик до дії (Post CTA)\n\n`post_cta (Текст фінальної інструкції)`: Фінальний заклик у тексті, часто підсилений емодзі та дедлайном, наприклад: «Тисни нижче, щоб дізнатися свій метаболічний вік ⬇️».\n\n`post_cta_type (Тип текстового CTA)`: Категорія конверсії для тексту — перехід на проходження тесту (квізу) чи пряма конверсія на обмежену в часі пропозицію.\n\n## Алгоритмічні метадані (AlgorithmicMetadata)\nТехнічні та статистичні параметри публікації, необхідні для системної аналітики та збереження в БД:\n\n`published (Статус публікації)`: Чи було оголошення опубліковано (True/False).\n\n`content_id (Ідентифікатор контенту)`: Унікальний числовий ID креативу.\n\n`content_type (Тип контенту)`: Категорія контенту за внутрішньою класифікацією.\n\n`content_format (Формат контенту)`: Опис формату (наприклад, розміри, співвідношення сторін або платформа).\n\n`product (Продукт)`: Назва продукту або застосунку, який рекламується.\n\n`date_published (Дата публікації)`: Дата, коли креатив став активним.\n\n`reach (Охоплення)`: Кількість унікальних користувачів, які побачили цю рекламу.\n\n`post_text (Повний текст)`: Весь текст публікації (копілефт) в оригінальному вигляді.\n\n# Яку модель було обрано і чому?\nДля цього демо я обрав Google (а не OpenAI, чи Claude) за його невисоку собівартість, а також різноманіття моделей, з якими можна попрацювати.\n\nЯ протестував декілька моделей від Google:\n\n1. **Gemma 4 31B**. Повільний API, контексту як раз вистачає на промпт + зображення або промпт + відео, але не вистачає складності моделі для побудови закономірностей між заданими характеристиками та креативами. В результаті модель часто брала не ті частини тексту з посту, чи неправильно записувала, що було сказано у відео.\n2. **Gemini 2.5 Flash Lite**. Швидка, багато контексту, що дозволяє аналізувати відео довжиною більше ніж 60 секунд. Має достатню складність для аналізу закономірностей між характеристиками та креативами. Модель себе гарно показала, працювала швидко, але були проблеми з Content Value Type, та розумінням коли і де треба поставити null.\n3. **Gemini 2.5 Flash**. Все те саме, що і flash lite, але вона може будувати складніші логічні зв'язки. Показала себе найкраще, бо тепер є мінімальні проблеми з Content Value Type, а також модель на достатньо гарному рівні розуміє куди поставити null.\n\nОтже я обрав `Gemini 2.5 Flash` за швидкодію, вартість та точність.\n\n# Prompts для отримання характеристик креативів\n\n## З чого складається промпт?\n\nПромпт складається з двох головних частин:\n1. Преамбула. Містить в собі загальні інструкції, як, наприклад, структура відповіді, роль, рекомендації по аналізу.\n2. Функціональна частина. Вона дуже тісно пов'язана з самою структурою даних, яку ми записуємо в базу даних. Тут описується, що кожна колонка в таблиці означає, які значення вона може приймати і, що кожне з цих значень у свою чергу означає.\n\nЧому так? Ця структура дозволяє бути гнучкою в інструкціях ЯК обробляти даних, але в той самий час вона строго описує те, ЩО ми хочемо отримати від моделі, чітко описуючи значення та приклади.  \n\n## Як відбувалось покращення промтів?\n\nЯ відібрав 10 рандомних креативів (3 зображення та 7 відео), і запускав на кожному промпті LLM для аналізу. Далі я вручну перевіряв те, наскільки гарні були відповіді та будував гіпотези, далі я робив покращення та перевіряв, чи не стало краще.\n\n### Відбір тестового датасету\n\nБуло відібрано 10% усього датасету як \"тренування\". Важливо було врахувати співвідношення зображень до відео, бо відео у нас набагато більше, тож треба і приділяти більше уваги. В результаті отримано 3 зображення та 7 відео.\n\n### Версіонування промптів\n\nВерсіювання промптів відбувається за допомогою `prompt_{prompt_version}_{commit_hash}`. При цьому створюється окрема папка з назвою \"prompts\". \n\nЧому включати в це хеш коміту? Річ у тім, що функціональна частина промпту є частиною коду, що в даному випадку забезпечує `inheritent versioning` та дозволяє не хвилюватись, що десь лежить якийсь txt файл.\n\n### Тестування промптів\n\nЯ спочатку думав, що передивлюсь вручну всі 10 відео, але після декількох ітерацій я зрозумів, що без експертної думки моя оцінка така ж сама, що й в LLM.\n\nЯкщо коротко, то я:\n1. Проганяв модель на 10 рандомних креативах\n2. Дивився де, як я думав вона помилилась\n3. Будував гіпотези, чому так вийшло\n4. Перевіряв гіпотезу, змінюючи щось\n\nГоловні частини викладені в папці [prompts](./prompts/). Майже в кожній підпапці є `ANALYSIS.md`, в якому я описую певні проблеми, покращення та інколи гарні сторони.\n\n## Підсумування промптів\n\n### Гарні сторони\n\n1. Агент правильно ідентифікує CTA та Value в постах. Гарно витягує текст (Hook) з контенту.\n2. Агент розуміє емоційне спрямування поста\n\n### Негативні сторони\n\n1. Агент іноді помиляється при визначенні довжини хуку. Мабуть це те, як всередині воно працює, LLM просто важко визначати довжину чогось.\n2. Іноді агент неправильно визначає `pacing`. Наприклад відео '870873419302426.mp4' та '1433361945187888.mp4' мають одну і ту саму основну частину, але при цьому мають `repetitive_rhythmic` та `calm_mindful` відповідно. Мені здається, що проблема в промпті, і що можна замінити на якісь інші категорії, чи підтюнити скрипт.\n\n## Приклади аналізу\n\n### Нульовий приклад\n\n```json\n{\n    \"post_cta\": \"Tap today.\",\n    \"post_cta_type\": \"direct_conversion\",\n    \"post_product_value_type\": \"frictionless_ease\",\n    \"post_body_logic_type\": \"objection_handling\",\n    \"post_hook\": \"⏳ I kept waiting for the “right moment” — more time, more energy, maybe a gym. It never came.\",\n    \"post_hook_type\": \"transformation\",\n    \"post_hook_emotional_valence\": \"pain_agitation\",\n    \"content_cta\": \"Tap now to start your transformation\",\n    \"content_cta_type\": \"direct_conversion\",\n    \"content_product_value_type\": \"transformation_outcome\",\n    \"content_body_logic_type\": \"demonstration\",\n    \"content_hook\": \"THE EASIEST WAY TO SHOCK EVERYONE WHO HASN'T SEEN YOU IN MONTHS.\",\n    \"content_hook_length_seconds\": 3,\n    \"content_hook_visual_format\": \"ugc\",\n    \"content_hook_type\": \"transformation\",\n    \"content_hook_emotional_valence\": \"aspirational_relief\",\n    \"pacing\": \"high_energy_fast\",\n    \"published\": true,\n    \"content_id\": 951064930588755,\n    \"content_type\": \"video\",\n    \"content_format\": \"9:16\",\n    \"product\": \"BetterMe\",\n    \"date_published\": \"2026-03-07\",\n    \"reach\": 538897,\n    \"post_text\": \"⏳ I kept waiting for the “right moment” — more time, more energy, maybe a gym. It never came. \\nWhat worked was BetterMe Calisthenics 👣 \\n15 min I could actually keep up with 👉 \\nBig change starts small 🚀 Tap today.\"\n}\n```\n\nВсе ідеально ідентифіковано.\n\n\n### Перший приклад\n\n```json\n{\n    \"post_cta\": \"Rozwiąż 1-minutowy quiz 📊\",\n    \"post_cta_type\": \"assessment_entry\",\n    \"post_product_value_type\": \"hyper_personalization\",\n    \"post_body_logic_type\": \"educational_teardown\",\n    \"post_hook\": \"Osiągnij cele związane z mięśniami💪\",\n    \"post_hook_type\": \"transformation\",\n    \"post_hook_emotional_valence\": \"aspirational_relief\",\n    \"content_cta\": \"KLIKNIJ EKRAN, ABY DOŁĄCZYĆ!\",\n    \"content_cta_type\": \"'direct_conversion'\",\n    \"content_product_value_type\": \"transformation_outcome\",\n    \"content_body_logic_type\": \"objection_handling\",\n    \"content_hook\": \"SZUKAMY DZIEWCZYN KTÓRE NIE ĆWICZYŁY REGULARNIE i chcą osiągnąć wymarzoną sylwetkę w 2026 roku\",\n    \"content_hook_length_seconds\": null,\n    \"content_hook_visual_format\": null,\n    \"content_hook_type\": \"transformation\",\n    \"content_hook_emotional_valence\": \"aspirational_relief\",\n    \"pacing\": null,\n    \"published\": true,\n    \"content_id\": 2099857124146357,\n    \"content_type\": \"image\",\n    \"content_format\": \"9:16\",\n    \"product\": \"BetterMe\",\n    \"date_published\": \"2026-03-06\",\n    \"reach\": 734709,\n    \"post_text\": \"\\\"Osiągnij cele związane z mięśniami💪 \\nTrzymaj się tego prostego planu, aby odnieść sukces: \\n1. Rozwiąż 1-minutowy quiz 📊 \\n2. Uzyskaj plan ćwiczeń i posiłków oparty na wadze, wzroście, wieku, codziennej aktywności i kondycji fizycznej📲 \\n3. Postępuj zgodnie z programem 😎\\\"\"\n}\n```\n\nТут правильно було ідентифіковано все. \n1. Агент правильно проаналізував текст посту, ідентифікував `Rozwiąż 1-minutowy quiz 📊` як `assessment_entry` тип CTA.\n2. Агент правильно визначив CTA контенту: `KLIKNIJ EKRAN, ABY DOŁĄCZYĆ!` та `direct_conversion` тип.\n3. Агент правильно ідентифікував Hook `SZUKAMY DZIEWCZYN KTÓRE NIE ĆWICZYŁY REGULARNIE i chcą osiągnąć wymarzoną sylwetkę w 2026 roku` та тип хуку `transformation`.\n4. Агент неправильно ідентифікував `content_hook_visual_format`. На мою думку воно має бути `cinematic`, бо це найближче серед усіх типів. Мабуть би я додав ще тип `photorealistic`. \n\n### Другий приклад\n\n```json\n{\n    \"post_cta\": null,\n    \"post_cta_type\": null,\n    \"post_product_value_type\": \"transformation_outcome\",\n    \"post_body_logic_type\": \"educational_teardown\",\n    \"post_hook\": \"Your body can become the equipment. Try Calisthenics.\",\n    \"post_hook_type\": \"call_to_action\",\n    \"post_hook_emotional_valence\": \"diagnostic_authority\",\n    \"content_cta\": \"TAP THE SCREEN TO JOIN US\",\n    \"content_cta_type\": \"direct_conversion\",\n    \"content_product_value_type\": \"transformation_outcome\",\n    \"content_body_logic_type\": \"demonstration\",\n    \"content_hook\": \"IF YOU START CALISTHENICS ON MARCH 16TH YOU'LL BE UNRECOGNIZABLE BY MAY\",\n    \"content_hook_length_seconds\": 3,\n    \"content_hook_visual_format\": \"ugc\",\n    \"content_hook_type\": \"transformation\",\n    \"content_hook_emotional_valence\": \"aspirational_relief\",\n    \"pacing\": \"high_energy_fast\",\n    \"published\": true,\n    \"content_id\": 1888741965847477,\n    \"content_type\": \"video\",\n    \"content_format\": \"9:16\",\n    \"product\": \"BetterMe\",\n    \"date_published\": \"2026-03-16\",\n    \"reach\": 1107501,\n    \"post_text\": \"Your body can become the equipment. Try Calisthenics.\\n\\nInstead of machines and weights, this 28-day plan teaches your body to move, hold, and build strength using its own resistance.\\nYou’ll develop:\\n💪 Stronger arms and shoulders\\n🔥 A tight, active core\\n🦵 Powerful legs and glutes\\n⚡ Better balance and control\\n\\nYour 28-Day Calisthenics Plan\\n🟢 Week 1: Learn foundational bodyweight moves\\n🟢 Week 2: Build control and core stability\\n🟢 Week 3: Increase strength and endurance\\n🟢 Week 4: Move with power and confidence\\n\\n🏠 No equipment needed\\n⏱ Short daily sessions\\n💪 Strength built with your own body\\n\\n✨ When your body becomes the resistance, strength feels different.\"\n}\n```\n\n1. Правильно ідентифіковано `ugc`, `pacing`, `content_product_value_type`, `content_body_logic_type`, `content_cta`, `content_cta_type` etc.\n2. Є деяка проблема з `content_hook_length_seconds`, так як Агент сказав, що воно протягом 3 seconds, однак насправді вого протягом 5 seconds.\n\n### Третій приклад\n\n```json\n{\n    \"post_cta\": \"Inizia la trasformazione ora!\",\n    \"post_cta_type\": \"assessment_entry\",\n    \"post_product_value_type\": \"hyper_personalization\",\n    \"post_body_logic_type\": \"demonstration\",\n    \"post_hook\": \"Raggiungi i tuoi obiettivi facilmente 💪\",\n    \"post_hook_type\": \"transformation\",\n    \"post_hook_emotional_valence\": \"aspirational_relief\",\n    \"content_cta\": \"TOCCA PER PARTECIPARE\",\n    \"content_cta_type\": \"direct_conversion\",\n    \"content_product_value_type\": \"transformation_outcome\",\n    \"content_body_logic_type\": \"objection_handling\",\n    \"content_hook\": \"CERCHIAMO UOMINI che non si allenano da anni e vogliono diventare irriconoscibili nel 2026\",\n    \"content_hook_length_seconds\": null,\n    \"content_hook_visual_format\": \"cinematic\",\n    \"content_hook_type\": \"transformation\",\n    \"content_hook_emotional_valence\": \"aspirational_relief\",\n    \"pacing\": null,\n    \"published\": true,\n    \"content_id\": 1612214663311424,\n    \"content_type\": \"image\",\n    \"content_format\": \"9:16\",\n    \"product\": \"BetterMe\",\n    \"date_published\": \"2026-03-06\",\n    \"reach\": 661560,\n    \"post_text\": \"Raggiungi i tuoi obiettivi facilmente 💪\\n\\n1️⃣ Fai un quiz di 1 minuto\\n2️⃣ Ottieni un programma personalizzato\\n3️⃣ Traccia i progressi e tieniti motivato\\n4️⃣  Vedi risultati visibili in 4 settimane!\\nInizia la trasformazione ora!\"\n}\n```\n\n1. Правильно ідентифіковано `content_hook_emotional_valence`, `content_hook_visual_format`, CTA, Value.\n\n# Chat-bot Agent\n\n## З чого складається?\n\nЧат бот є `Multi-agent Directed Graph`, з наступними етапами:\n\n0. Отримання питання від користувача через Телеграм (aiogram).\n1. Аналіз поставленої задачі та генерація SQL.\n2. Виконання SQL для отримання даних з БД.\n3. Аналіз отриманих даних та співставлення з питанням користувача, та формування відповіді.\n4. Відповідь через Телеграм (aiogram).\n\nДля побудови агента було використано:\n\n1. `LangChain` та `LangGraph`. Побудова графу та виклик `LLM`.\n2. `aiogram`. Зручна бібліотека для написання інтерфейсу з телеграмом. \n\n## Приклади відповідей на обов'язкові питання\n\n### «Сформуй список найкращих хуків за останній тиждень» — топ хуки за reach серед креативів, завантажених за останні 7 днів.\n\nНа жаль, агент правильно виконує завдання, тому натрапляє на таку помилку:\n\n```md\n### Аналіз найкращих хуків за останній тиждень\n\n**Теза:** Наданих даних недостатньо для формування списку найкращих хуків.\n\n**Ключові факти:** SQL-результат є порожнім (`[]`), що унеможливлює проведення аналізу за метрикою `reach` або будь-якими іншими показниками ефективності креативів за останній тиждень (168 годин).\n\n**Рекомендація:** Будь ласка, надайте актуальні дані SQL-запиту, що містять метрики ефективності рекламних креативів (`reach`, `date_published`, `post_hook`, `content_hook` тощо), для виконання запиту. Після отримання даних я зможу визначити креативи, завантажені за останні 7 днів, відсортувати їх за `reach` та виділити конкретні гачки, які забезпечили максимальне охоплення.\n```\n\nБо сьогодні вже 14 травня, а в базі даних останній пост був 3 квітня, тож повертаються порожні рядки.\n\nЯкщо ми трохи змінимо формулюванна на «Сформуй список найкращих хуків за останній тиждень (починай відлік від найближчої дати в базі даних)», то матимемо:\n\n```md\n### Аналіз найкращих хуків за останній тиждень\n\n**Теза:** За останній тиждень (відлік від 2026-04-03), найвище охоплення продемонстрували креативи, що базуються на обіцянці швидкої трансформації до конкретної дати, а також таргетовані повідомлення для специфічної аудиторії.\n\n**Ключові цифри та факти:**\n\nНайкращі хуки за охопленням (Reach) за період 2026-03-27 – 2026-04-03:\n\n1.  **Reach: 2,089,609** (Опубліковано: 2026-03-27)\n    *   **Post Hook:** `Erreiche deine Ziele! 💪`\n    *   **Content Hook:** `WENN DU AM 30. MÄRZ MIT CALISTHENICS ANFÄNGST, WIRST DU BIS MAI KAUM WIEDERZUERKENNEN SEIN.`\n    *   *Мова: Німецька. Тема: Трансформація, конкретна дата початку/кінця.*\n2.  **Reach: 1,307,411** (Опубліковано: 2026-03-27)\n    *   **Post Hook:** `Raggiungi gli obiettivi! 💪`\n    *   **Content Hook:** `SE INIZI IL CALISTHENICS IL 30 MARZO, SARAI IRRICONOSCIBILE ENTRO UN MAGGIO.`\n    *   *Мова: Італійська. Тема: Трансформація, конкретна дата початку/кінця.*\n3.  **Reach: 1,233,841** (Опубліковано: 2026-03-27)\n    *   **Post Hook:** `¡Alcanza los objetivos! 💪`\n    *   **Content Hook:** `SI EMPIEZAS CALISTENIA EL 30 DE MARZO, ESTARÁS IRRECONOCIBLE PARA MAYO.`\n    *   *Мова: Іспанська. Тема: Трансформація, конкретна дата початку/кінця.*\n4.  **Reach: 729,555** (Опубліковано: 2026-03-27)\n    *   **Post Hook:** `Erreiche deine Ziele! 💪`\n    *   **Content Hook:** `WIR SUCHEN MÄDELS DIE UNREGELMÄSSIG TRAINIERT HABEN und 2026 ihren Traumkörper erreichen wollen`\n    *   *Мова: Німецька. Тема: Таргетинг на специфічну групу (\"дівчата, які нерегулярно тренувалися\"), обіцянка майбутнього результату.*\n\n**Виявлені патерни:**\n\n*   **Обіцянка швидкої трансформації з чіткими часовими рамками:** Три з чотирьох топових хуків використовують формулу \"Якщо почнеш X до (дата), будеш Y до (дата)\". Це створює відчуття терміновості та конкретного, досяжного результату. Фрази на кшталт \"будеш невпізнанним\" (irreconocible/kaum wiederzuerkennen) є потужними тригерами.\n*   **Універсальність концепції:** Одна й та сама ідея \"трансформації за термін\" ефективно працює в різних мовах (німецька, італійська, іспанська).\n*   **Заклик до дії в Post Hook:** Повторюваний `post_hook` (\"Erreiche deine Ziele! 💪\" / \"¡Alcanza los objetivos! 💪\" / \"Raggiungi gli obiettivi! 💪\") є прямим, мотивуючим і універсальним.\n*   **Таргетинг за болем/станом:** Хук з охопленням 729,555 успішно таргетує аудиторію за їхнім минулим досвідом (\"нерегулярно тренувалися\"), що демонструє ефективність персоналізованих звернень.\n\n**Рекомендація:**\n\nМедіабаїнг-командам варто масштабувати креативи, що містять чіткі обіцянки трансформації з фіксованими датами, адаптуючи їх під різні гео та мови. Контент-командам рекомендується розробляти нові варіації \"трансформаційних\" хуків, експериментуючи з різними датами початку/кінця та більш специфічними результатами (наприклад, \"мінус X кг до літа\", \"енергія на весь день за 28 днів\"). Також слід посилити фокус на таргетованих хуках, які звертаються до конкретних проблемних точок або груп користувачів.\n```\n\n### «Сформуй список нових хуків за останній тиждень, яких не було до цього» — хуки, які вперше з'явились у нових креативах і не зустрічались раніше.\n\nЗнову ж таки, 'останній тиждень' буде порожнім:\n```md\nЗрозумів запит щодо нових хуків за останній тиждень, яких не було раніше.\n\n**Недостатньо даних:** Наданий SQL-результат є порожнім `[]`.\n\nДля виконання цього аналізу мені необхідні фактичні дані, що містять:\n1.  **`post_hook` та `content_hook`:** Тексти хуків.\n2.  **`date_published`:** Дата публікації кожного креативу для фільтрації за останні 7 днів та історичними даними.\n\n**Рекомендація:** Будь ласка, надайте SQL-результат з відповідними метриками та атрибутами. Після отримання даних я зможу виявити унікальні хуки, які були запущені вперше за останній тиждень, і, за наявності `reach`, оцінити їхню початкову ефективність.\n```\n\nАле якщо трохи змінити питання на 'Сформуй список нових хуків за останній тиждень, яких не було до цього (починай відлік від найпізнішої дати в базі даних)', то матимемо:\n\n```md\n**Теза:** За останній тиждень, відраховуючи від найпізнішої дати в наданих даних (3 квітня 2026 року), було запущено три нових унікальних хуки, сфокусованих на швидкій фізичній трансформації через калістеніку.\n\n**Ключові факти:**\n*   **Період аналізу (останній тиждень):** 28 березня 2026 року – 3 квітня 2026 року.\n*   **Виявлені нові `content_hook`:**\n    1.  `'SI TU COMMENCES LA CALLISTHÉNIE LE 6 AVRIL, PERSONNE NE TE RECONNAÎTRA EN MAI.'` (Опубліковано: 2026-04-03)\n    2.  `'If you start Calisthenics on April 6th'` (Опубліковано: 2026-04-03)\n    3.  `\"IF YOU START CALISTHENICS ON MARCH 30TH YOU'LL BE UNRECOGNIZABLE BY MAY\"` (Опубліковано: 2026-03-29)\n\n**Обмеження:**\nНадані дані не містять метрик ефективності (таких як `reach`, `CTR`), тому неможливо оцінити \"перший політ\" цих нових хуків та їхню початкову ефективність. Для повноцінного аналізу необхідні додаткові дані про продуктивність.\n```\n\n### «Сформуй ідеальний креатив на основі даних» — агент аналізує кореляцію між атрибутами та reach і генерує опис найефективнішого можливого креативу.\n\n```md\n### Ідеальний креатив на основі даних: Синтез \"переможних\" атрибутів\n\n**Теза:** На основі наданих даних, ідеальний креатив повинен акцентувати увагу на трансформаційних результатах з аспіраційним емоційним забарвленням, використовувати динамічну анімацію для залучення та ефективно відпрацьовувати заперечення, ведучи до двоступеневої конверсії (оцінка -\u003e пряма покупка).\n\n**Ключові атрибути та факти (на базі креативу з охопленням 1,848,940):**\n\n*   **Охоплення (Reach):** 1,848,940 (даний креатив показав високе охоплення).\n*   **Основна цінність (Product Value Type):** \"Transformation Outcome\" як у тексті (post), так і у відео (content). Це свідчить про ефективність фокусу на \"майбутньому Я\" користувача та обіцянці відчутних змін (фізичних, ментальних).\n*   **Емоційний гачок (Emotional Valence):** \"Aspirational Relief\" для обох гачків (post \u0026 content). Креатив починається з обіцянки полегшення та прагнення до бажаного стану.\n*   **Формат візуального гачка (Content Hook Visual Format):** \"Motion Graphics\". Використання стилізованої цифрової анімації та типографіки є ключовим для привернення уваги.\n*   **Тип гачка у відео (Content Hook Type):** \"Transformation\". Відео має одразу демонструвати контраст \"до/після\".\n*   **Логіка тіла відео (Content Body Logic Type):** \"Objection Handling\". Відео ефективно працює із запереченнями користувачів (час, вартість, зусилля).\n*   **Тип заклику до дії у відео (Content CTA Type):** \"Direct Conversion\". Відео CTA веде до негайної підписки або пробного періоду.\n*   **Тип заклику до дії у тексті (Post CTA Type):** \"Assessment Entry\". Текстовий CTA заохочує пройти діагностичний тест/квіз.\n*   **Логіка тіла тексту (Post Body Logic Type):** \"Demonstration\". Текст має показувати продукт у дії.\n*   **Тип гачка у тексті (Post Hook Type):** \"Call to Action\". Текстовий гачок одразу містить пряму інструкцію.\n\n**Рекомендація: ТЗ для \"Ідеального Креативу\"**\n\n**Назва:** \"Трансформація за 28 днів: Відчуй легкість!\"\n\n**Ціль:** Залучити користувачів, обіцяючи швидку та помітну трансформацію, та конвертувати їх через квіз з подальшою пропозицією прямої покупки.\n\n**Візуальна частина (Video Content):**\n\n1.  **Гачок (0-5 сек) - Motion Graphics, Transformation, Aspirational Relief:**\n    *   **Сцена:** Динамічна, яскрава анімація. Швидка зміна візуальних елементів, що контрастують стан \"до\" (сірі, втомлені образи, питання типу \"Вигорів? Немає енергії?\") та \"після\" (яскраві, енергійні образи, щасливі люди, що легко виконують рутини).\n    *   **Текст (на екрані):** Великий, жирний шрифт: \"Мрієш про енергію та впевненість?\" -\u003e \"Це реально за 28 днів!\"\n    *   **Звук:** Оптимістична, мотивуюча музика.\n2.  **Основна частина (5-20 сек) - Objection Handling:**\n    *   **Сцена:** Короткі, анімовані сцени або текстові накладки, що візуально відпрацьовують типові заперечення.\n        *   \"Немає часу?\" -\u003e Анімація, що показує 10-хвилинні тренування без обладнання.\n        *   \"Занадто складно?\" -\u003e Анімація простого інтерфейсу додатку.\n        *   \"Дорого?\" -\u003e Порівняння з вартістю спортзалу/тренера, підкреслюючи доступність.\n    *   **Текст (на екрані):** Чіткі, короткі тези, що відповідають на заперечення.\n3.  **Заклик до дії (20-25 сек) - Direct Conversion:**\n    *   **Сцена:** Енергійна анімація, що фокусується на пропозиції.\n    *   **Текст (на екрані):** Великий, імперативний: \"Забери свій план трансформації на 28 днів лише за $1!\" або \"Почни свій шлях до нового себе зараз!\"\n\n**Текстова частина (Post Copy):**\n\n1.  **Гачок (Post Hook) - Call to Action, Aspirational Relief:**\n    *   \"Готові до відчуття легкості та впевненості у своєму тілі? Дізнайтеся, як змінити своє життя за 28 днів!\"\n    *   \"Набридла втома та стрес? Розкрий свій потенціал із персоналізованим планом!\"\n2.  **Основна частина (Post Body) - Demonstration, Transformation Outcome:**\n    *   \"Наш унікальний квіз допоможе визначити ваш 'метаболічний вік' та створить індивідуальний план тренувань та харчування. Дивіться, як легко це працює: [короткий опис або gif-демонстрація вибору плану в додатку].\"\n    *   \"Тисячі жінок вже відчули трансформацію: від 'завжди втомленої' до 'повної енергії'!\"\n3.  **Заклик до дії (Post CTA) - Assessment Entry:**\n    *   \"Пройдіть наш 1-хвилинний квіз, щоб отримати персоналізований план трансформації! ⬇️\"\n    *   \"Натисніть тут, щоб почати свій шлях до здорового та щасливого 'Я'!\"\n\n**Обмеження даних:** Даний висновок базується на аналізі одного креативу з високим охопленням. Для підтвердження статистичної кореляції та виявлення інших \"переможних\" комбінацій атрибутів, необхідний більший обсяг даних з різними метриками ефективності (CTR, CVR) та їх історичними показниками. Відсутність даних про `pacing` та `content_hook_length_seconds` також обмежує можливість оптимізації цих параметрів\n```\n\n### «Які формати показують найкращий reach цього місяця?» — порівняння відео vs зображення, 9:16 vs 1:1 тощо.\n\n```md\n**Аналіз форматів за Reach (Квітень 2026)**\n\n**Теза:** На основі наявних даних, формат 9:16 демонструє значне охоплення у квітні 2026 року. Однак, для порівняльної оцінки ефективності форматів недостатньо даних.\n\n**Ключові цифри/факти:**\n*   **Найпізніший місяць даних:** Квітень 2026 року.\n*   **Виявлені формати:** Лише один формат, '9:16', представлений у наданих даних.\n*   **Total Reach для 9:16:** 605,194.\n\n**Рекомендація:** Для відповіді на питання щодо найкращих форматів та порівняння їхньої ефективності (наприклад, 9:16 проти 1:1, або Video проти Image), необхідно отримати агреговані дані для *всіх* релевантних форматів за вказаний період. Без порівняльних метрик (наприклад, медіанний reach для інших форматів), неможливо зробити обґрунтований висновок про \"найкращий\" формат або відсоткову різницю в ефективності.\n```\n\n### «Покажи тренди: що змінилось у підходах за останні 2 тижні порівняно з попередніми?»\n\n```md\n### Аналіз трендів ефективності креативів (останні 2 тижні до 2026-04-03)\n\n**Загальний висновок:** За останній період спостерігається чітка динаміка перерозподілу уваги користувачів. Найбільш ефективними стають прямі заклики до дії у заголовках та контент, що активно працює з запереченнями та демонструє продукт. Натомість, підходи, що раніше базувалися на діагностичному авторитеті, шокуючих фактах та окремих типах CTA, показують значне вигорання або повну втрату охоплення.\n\n---\n\n**Що стрімко набирає популярність (Зростання Reach):**\n\n*   **Post Hook Type: Call to Action**\n    *   **Ключові цифри:** Зростання на **40.51%** (середній Reach поточного періоду: 1.02M).\n    *   **Інсайт:** Прямі, активні заклики до дії вже в першому рядку тексту (caption) є надзвичайно ефективними для привернення уваги. Приклад: \"Пройди тест за 1 хвилину, щоб дізнатися свій метаболічний вік.\"\n*   **Post Body Logic Type: Objection Handling**\n    *   **Ключові цифри:** Зростання на **29.85%** (середній Reach поточного періоду: 805.9K).\n    *   **Інсайт:** Текстовий контент, що активно працює з потенційними запереченнями користувачів (наприклад, брак часу, дороговизна), значно покращує охоплення. Приклад: \"Немає часу на спортзал? Ці 10-хвилинні рутини можна робити в піжамі.\"\n*   **Pacing: High Energy Fast**\n    *   **Ключові цифри:** Зростання на **15.83%** (середній Reach поточного періоду: 803.6K).\n    *   **Інсайт:** Швидкий, енергійний темп відео з динамічним монтажем продовжує демонструвати позитивну динаміку.\n*   **Content CTA Type: Community Engagement**\n    *   **Ключові цифри:** Зростання на **16.38%** (середній Reach поточного періоду: 575.5K).\n    *   **Інсайт:** Заклики до взаємодії з контентом або приєднання до спільноти у відео ефективно залучають аудиторію.\n\n---\n\n**Що демонструє вигорання або втрачає ефективність (Падіння Reach):**\n\n*   **Повне вигорання (-100% падіння Reach):**\n    *   **Post CTA Type:** `learn_more`, `direct_conversion`\n    *   **Post Hook Emotional Valence:** `pain_agitation`\n    *   **Post Hook Type:** `question`\n    *   **Content Product Value Type:** `hyper_personalization`\n    *   **Content Hook Emotional Valence:** `diagnostic_authority`\n    *   **Content Hook Type:** `shocking_fact`\n    *   **Інсайт:** Ці підходи повністю втратили охоплення в поточному періоді, що свідчить про їх повне вигорання або стратегічне припинення використання.\n*   **Значне падіння Reach (не -100%):**\n    *   **Post Hook Emotional Valence: Diagnostic Authority**\n        *   **Ключові цифри:** Падіння на **-35.42%** (середній Reach поточного періоду: 452.0K).\n        *   **Інсайт:** Авторитетний, факт-орієнтований тон у заголовках (caption hooks) більше не приваблює аудиторію так само ефективно.\n    *   **Post Product Value Type: Frictionless Ease**\n        *   **Ключові цифри:** Падіння на **-33.19%** (середній Reach поточного періоду: 386.9K).\n        *   **Інсайт:** Акцент на \"легкості без зусиль\" у текстовому описі продукту втрачає свою привабливість.\n    *   **Pacing: Repetitive Rhythmic**\n        *   **Ключові цифри:** Падіння на **-24.77%** (середній Reach поточного періоду: 483.2K).\n        *   **Інсайт:** Повторюваний, ритмічний темп відео, схоже, викликає втому у аудиторії.\n    *   **Post Body Logic Type: Educational Teardown**\n        *   **Ключові цифри:** Падіння на **-26.27%** (середній Reach поточного періоду: 478.8K).\n        *   **Інсайт:** Детальні освітні пояснення в тексті caption стають менш ефективними для охоплення.\n\n---\n\n**Рекомендації:**\n\n*   **Для медіабаїнгу:**\n    *   **Збільшити інвестиції:** В креативи з `post_hook_type: call_to_action`, `post_body_logic_type: objection_handling`, а також `pacing: high_energy_fast`.\n    *   **Переглянути/Призупинити:** Кампанії, що використовують `post_cta_type: learn_more` та `direct_conversion`, `post_hook_emotional_valence: diagnostic_authority` та `pain_agitation`, `pacing: repetitive_rhythmic`, оскільки вони демонструють значне вигорання або повну неефективність.\n    *   **A/B тестування:** Провести тестування різних формулювань `call_to_action` у заголовках, щоб знайти оптимальні варіанти.\n*   **Для контент-команд:**\n    *   **Створювати більше контенту:** З акцентом на **прямі заклики до дії** в заголовках. Розробляти текстові частини креативів, що активно **працюють із запереченнями** користувачів.\n    *   **Пріоритизувати:** **Високоенергійний, швидкий темп** відео та заклики до **залучення спільноти** у відео-CTA.\n    *   **Уникати або переосмислити:** Підходи з `post_hook_emotional_valence: diagnostic_authority` та `post_product_value_type: frictionless_ease` у текстових описах, а також відео з `repetitive_rhythmic` темпом. Дослідити причини вигорання `educational_teardown` у текстовому форматі — можливо, їх слід інтегрувати у відео-формат.\n    *   **Аналіз причин вигорання:** Для підходів, що показали -100% падіння, необхідно провести глибокий аналіз, чи це пов'язано з повною втратою релевантності, або ж зі зміною стратегії та припиненням їх використання.\n```\n\n## Приклади відповідей на додаткові питання\n\n### «Які емоції отримали найвищий reach за останні 2 тижні?»\n\n```md\nЗа останні 2 тижні, відлік яких починається з 3 квітня 2026 року, найвище охоплення отримала емоційна валентність **\"aspirational_relief\"**.\n\n**Ключові факти:**\n*   **Aspirational Relief:** Сумарне охоплення становить **30,719,600**. Це включає як post-hook (16,122,300), так і content-hook (14,597,300) валентності.\n*   **Pain Agitation:** Охоплення складає **1,977,048** (content-hook).\n*   **Diagnostic Authority:** Охоплення складає **452,048** (post-hook).\n\n**Рекомендація:**\nЗ огляду на значну перевагу, варто продовжувати фокусуватися на креативах, що викликають **\"aspirational_relief\"**. Необхідно проаналізувати конкретні елементи цих креативів (візуал, текст, CTA), щоб виявити спільні патерни успіху та масштабувати їх. Це може бути основою для гіпотези, що користувачі активно реагують на контент, який обіцяє відчуття легкості, впевненості та трансформації.\n```\n\n### «Який CTA показав себе найкраще за весь час?»\n\n```md\nЗгідно з наданими даними, ми маємо лише один запис з високим охопленням (`total_reach`: 3,270,980). На основі цієї єдиної точки даних неможливо зробити обґрунтований висновок про те, який CTA показав себе найкраще за весь час, оскільки відсутні історичні та порівняльні дані для інших CTA.\n\n**Ключові факти з поточного запису:**\n*   **Post CTA:** \"Fai un quiz di 1 minuto\" (тип: `assessment_entry`)\n*   **Content CTA:** \"PROVA ORA!, PROVA ORA! Tocca lo schermo per partecipare., TOCCA PER PARTECIPARE\" (тип: `direct_conversion`)\n\n**Рекомендація:**\nДля відповіді на питання \"який CTA показав себе найкраще за весь час\" необхідно агрегувати дані по всім креативам за весь період, групуючи їх за `post_cta_type` та `content_cta_type` та розраховуючи середній або медіанний `reach` (та/або CTR, якщо доступно). Без ширшого набору даних будь-які висновки будуть необґрунтованими.\n```\n\n### «Яка цінність зацікавила користувачів найбільше?»\n\n```md\nСтаном на 3 квітня 2026 року, **цінність \"Transformation Outcome\" зацікавила користувачів найбільше**.\n\n**Ключові цифри/факти:**\n*   **Transformation Outcome:** Загальне охоплення склало **80.95 млн**, із середнім охопленням **722.8 тис.** на одиницю контенту (112 одиниць).\n*   **Hyper Personalization:** Загальне охоплення – **13.78 млн**, середнє – **626.5 тис.** на одиницю контенту (22 одиниці).\n*   **Frictionless Ease:** Загальне охоплення – **8.45 млн**, середнє – **528.3 тис.** на одиницю контенту (16 одиниць).\n\n**Рекомендація:**\nМедіабаїнгу та контент-командам слід продовжувати активно використовувати наративи та візуали, що фокусуються на **конкретних результатах та змінах (\"Future Self\")**, які користувач може досягти. Це є найефективнішим підходом для залучення аудиторії, забезпечуючи як найвище загальне охоплення, так і ефективність кожного креативу\n```\n\n## Опис реалізації агента: архітектура, модулі, використані моделі, промти, ліміти та ризики.\n\n### Архітектура\n\nПоточна архітектура:\n\n![Current Agentic Architecture](./assets/current_agentic_architecture.png)\n\n### Промпти\n\nПромпт для `Data Engineer Agent`:\n\n```md\n### Role\nТи — експерт із Data Engineering та SQL Optimization. Твоє завдання: згенерувати точний та ефективний SQL-запит до бази даних SQLite на основі текстового запиту маркетолога.\n\n### Schema Context\nОсь опис таблиць та колонок у базі даних (основна таблиця `marketing`):\n{column_description}\n\n### Constraints \u0026 Business Logic\n1. ВИКОРИСТОВУЙ ТІЛЬКИ СИНТАКСИС SQLite! Ніяких `INTERVAL`, `DATEADD` чи `CURRENT_DATE`.\n2. Обов'язкова фільтрація дат: Завжди додавай умову `date_published IS NOT NULL`, якщо в запиті є хоч якась прив'язка до часу чи дат. \n3. Обов'язковий вивід дати: Якщо запит пов'язаний з часом, результуючий `SELECT` повинен включати колонку `date_published` (або агрегацію по ній).\n4. Використовуй CTE (Common Table Expressions) `WITH ... AS (...)` для складних запитів (порівняння періодів, пошук нових сутностей), щоб запит був читабельним.\n5. Повертай ТІЛЬКИ валідний SQL-код без маркдаун-форматування (або строго в блоці ```sql), без додаткових пояснень.\n6. Результат виконання SQL запиту буде аналізувати ще один агент, тож додай в запит якомога більше колонок. В запиті обов'язково має бути присутня `date_published`, якщо треба агрегуй як максимальна дата в групі.\n\n### Date \u0026 Time Handling in SQLite\nДля роботи з часом використовуй виключно функцію `date('now', '\u003cmodifier\u003e')`. \nШпаргалка модифікаторів для цього завдання:\n- \"сьогодні\" -\u003e `date('now')`\n- \"останній тиждень\" / \"останні 7 днів\" -\u003e `\u003e= date('now', '-7 days')`\n- \"попередній тиждень\" (для порівняння) -\u003e `BETWEEN date('now', '-14 days') AND date('now', '-7 days')`\n- \"останні 2 тижні\" -\u003e `\u003e= date('now', '-14 days')`\n- \"попередні 2 тижні до того\" -\u003e `BETWEEN date('now', '-28 days') AND date('now', '-14 days')`\n- \"цього місяця\" -\u003e `\u003e= date('now', 'start of month')`\n- \"минулого місяця\" -\u003e `BETWEEN date('now', 'start of month', '-1 month') AND date('now', 'start of month')`\n\n### Task Cases \u0026 SQL Patterns\nЗастосовуй ці підходи для відповідних типів питань:\n- **Top Hooks (Найкращі хуки за час X):** \n  Фільтр `date_published \u003e= ...` + `ORDER BY reach DESC`.\n- **New Hooks (Нові хуки за час X, яких не було раніше):** \n  Використовуй підзапит. Знайти хуки, де `date_published \u003e= [Current Period]`, і `hook NOT IN (SELECT hook FROM marketing WHERE date_published \u003c [Current Period])`.\n- **Trends (Порівняння поточного періоду з попереднім):** \n  Використовуй 2 CTE: `current_period` та `previous_period`. Зроби `FULL OUTER JOIN` або `LEFT JOIN` за ключовим атрибутом (наприклад, hook або format) і порахуй різницю (`reach_current - reach_previous`) або зміну у відсотках.\n- **Ideal Creative (Ідеальний креатив):** \n  Використовуй агрегацію (наприклад, `AVG(reach)`) для різних атрибутів (формат, тривалість, хук). Знайди комбінацію атрибутів, яка історично дає найвищий середній `reach`. Згрупуй за цими атрибутами `GROUP BY ... ORDER BY AVG(reach) DESC LIMIT 1`.\n- **Best Formats (Найкращі формати за час X):**\n  Згрупуй за форматом (`GROUP BY format`), порахуй `AVG(reach)` або `SUM(reach)`, додай фільтр часу `WHERE date_published \u003e= ...`.\n\n### Input Question\nКористувач запитує: \"{question}\"\n\n{error_context}\n```\n\nПромпт для `Marketing Analyst Agent`:\n\n```md\n### Role\nТи — провідний Marketing Data Analyst в AI-агентстві. Твоя спеціалізація — перетворення сирих SQL-даних у стратегічні інсайти для медіабаїнгу та контент-команд.\n\n### Context\nТобі надано результати SQL-запиту, що містять метрики ефективності рекламних креативів (Reach, CTR, Hooks, Formats тощо).\n- **SQL Result:** {sql_result}\n- **Database Schema \u0026 Metadata:** {column_description}\n\n### Task\nСформулюй коротку, професійну та аналітично обґрунтовану відповідь на питання: \"{question}\".\n\n### Analysis Guidelines\n\nЗалежно від типу питання, використовуй наступну логіку:\n\n1. **Топ хуки (за 7 днів):** Визнач креативи, завантажені за останні 168 годин. Відсортуй їх за `reach` та виділи конкретні гачки (hooks), які забезпечили максимальне охоплення.\n2. **Нові хуки (Incremental Innovation):** Знайди унікальні значення в колонці hooks, які присутні в останніх завантаженнях, але відсутні в історичних даних. Оціни їхній \"перший політ\" (initial performance).\n3. **Ідеальний креатив (Synthesis):** Проаналізуй статистичну кореляцію між атрибутами (колір, формат, тривалість, CTA) та високим `reach`. Сформуй ТЗ на основі \"переможних\" комбінацій.\n4. **Формати (Efficiency):** Порівняй агреговані дані: Video vs Image, Aspect Ratios (9:16 vs 1:1). Вкажи не просто \"хто краще\", а на скільки % різниться медіанний reach.\n5. **Тренди (Dynamic Change):** Порівняй метрики поточного двотижневого періоду з попереднім. Виділи аномалії: що \"вигорає\", а що стрімко набирає популярність.\n\n### Custom Capabilities (Added Values):\n6. **Аналіз \"Втомленості\" (Creative Fatigue):** Визнач хуки, чий reach або CTR почав динамічно падати після піку. Дай рекомендацію щодо ротації.\n7. **Кореляція \"Візуал-Текст\":** Оціни, які текстові заголовки найкраще працюють з конкретними візуальними форматами (наприклад, чи правда, що 9:16 потребує коротших хуків).\n\n### Output Requirements\n- **Стиль:** Лаконічний, без води, мова цифр та гіпотез.\n- **Структура:** Коротка теза -\u003e Ключові цифри/факти -\u003e Рекомендація.\n- **Обмеження:** Якщо даних недостатньо для впевненого висновку, вкажи на це прямо.\n- **Креативність:** Якщо просять сформувати креатив, то наповни його конкретним прикладом хуку/логіки, описом сцен і т.д, як би він реально виглядав.\n```\n\n### Ліміти та ризики\n\n1. Головний ліміт це те, що у `Marketing Analyst Agent` немає вибору над якими даними працювати. Він може тільки працювати з тими, що прийшли від `Data Engineer Agent`. В реальному світі все навпаки.\n2. Чат-бот діє синхронно. Це означає, що якщо дві чи більше особи використовуватимуть його, то одому з користувачів доведеться зачекати.\n3. Ризиків немає, я додав `max_retries`, щоб не було такого, що `Data Engineer Agent` в нескінченному циклі буде намагатись відремонтувати свій SQL-запит. Також я додав `Monthly Usage Cap`, щоб контролювати фінансові витрати, і не влетіти на кругленьку суму. Також я додатково перевіряю згенерований SQL скрипт на наявність `DELETE`, `UPDATE`, `ALTER`, `INSERT`, щоб унеможливити якісь дії поза `SELECT`. \n\n## Як можна оцінити чат бот?\n\nЯ би оцінив його на етапі POC. Я з ним порозмовляв і його подальша розробка має сенс. Інколи він давав доволі гарні інсайти. З точки зору бізнесу я б фокусувався на:\n\n1. Вартість вирішення запиту. На даний момент кожен запит коштує менше \u003c= 0.005$. За весь час я використав ~2-4$ (аналітика просто ще не пройшла). Використання більших та точніших моделей? запит може бути і 0.05$, а може і більше. Це не виглядає як щось страшне, але протягом місяця може набігати непогана така сума.\n2. Задоволеність користувачів. Чи задоволені маркетологи/продуктові аналітики/маркетингові аналітики/продакт менеджери тим як цей бот працює і який результат він дає. Це можна перевірити лише дивлячись на метрики з використанням боту, та без використання боту.\n\nНа даний момент:\n1. Вартість невелика, що навіть я зміг заплатити.\n2. Я задоволений. Хоч я і не кінцевий користувач, і цей бот має трохи покращити перед продакшеном, але він дає інсайти, аналізує, і мені здається з гарною інтеграцією має цілком стати у нагоді всім. Ти продакт менеджер? Замість того, щоб смикати аналітиків просто написав боту і дізнався як там справи з рекламою. Ти аналітик, і тобі треба просто швидко перевірити який `CTA` дав найкращу конверсію в дію? Просто запитав у бота. \n\n## Наступні кроки для доведення агента до production-версії\n\n1. Додати `Agent Orchestrator`. Цей агент має управляти двома іншими агентами. Це дозволить маркетологу казати, що йому треба, а не робити те, що дав `Data Engineer Agent`.\n2. Додати паттерн `Chain of Resposibility`, щоб мати змогу швидко змінити модель у випадку, якщо у провайдера якісь проблеми. Поки я тестував бота, то постійно була проблема з `Server Error 503`.\n3. Додати функціонал для тестування промптів для агентів.\n4. Зробити все через `async` (доступ до SQLite теж).\n5. І останнє це деплоймент через `LangSmith`. Він надає обсервабіліті, можна моніторити різні промпти, дивитись на вартість. \n\nОновлена архітектура може бути:\n\n![Updated Agentic Architecture](./assets/updated_agentic_architecture.png)\n\n# Які покращення можна зробити?\n\n## Golden Set для автоматизованого тестування промпту\n\nЯк завжди відбувається в продукті, а це по-суті внутрішній продукт, де наші користувачі – маркетологи та аналітики, треба слухати кінцевого користувача. Найкраща порада так це витратити певний час, щоб зрозуміти:\n\n1. Яка структура креативу? (Для розкриття моєї думки, я буду вважати, що будь-який креатив має \"Хук\", \"Цінність\", та \"Заклик до дії\").\n2. Що може описувати \"Хук\"? Чи є якісь чіткі категорії, на які можна поділити \"Хуки\"?\n3. Чи є якісь характеристики креативу, які не можна поділити на категорії?\n4. Які питання найбільш поширені?\n\nЯ намагався відповісти на ці питання самотужки, запитуючи в Gemini та читаючи маркетингові пости, але як на мене у мене вийшли не такі гарні описи категорій, та їхніх значень. Однак маючи відповіді на ці питання від експертів ми можемо побудувати гарну функціональну частину нашого промпту. \n\nДалі треба продивитись мевні креативи та вручну розмітити їх за допомогою експертної оцінки. В подальшому цю розмітку можна використовувати як для дотренування якоїсь `SLM` (маленької Language Model), так і для тестування преамбули як `golden set`.\n\nНамагатись підлаштувати преамбулу, щоб воно якомога краще відповідало `golden set`.\n\n## Dagster для обробки та збереження даних\n\nЯ витратив час на побудову пайплайну для витягування метаданих та обробку відео. Я би для цього рекомендував використовувати `Dagster`, чи щось подібне. Використовуючи цей оркестратор можна буде розбити обробку, збереження та аналіз даних на окремі кроки, і повноцінно автоматизувати весь процес ще більше:\n\n1. Завантаження креативу на `Google Drive` чи `Google S3`. Сенсор буде слідкувати, як тільки сенсор бачить, що було додано новий креатив, то ми його скачуємо на якийсь `Compute Service`.\n2. На цьому Compute Service ми робимо аналіз креативу.\n3. Аналіз креативу записуємо в `Elastic Search`, чи `BigQuery`.\n\nКод стає простіше, обробка даних прозоріша, одразу можна побачити де і що іде не так.\n\n## Logical Guardrails\n\nЗазвичай промпт не є якимось законом для моделі, а скоріше він є \"наставленням\". Модель не зобов'язана його слухати і робить як заманеться. Поки я покращував промпти, то у мене ідея: додати якісь правила вже на структуровану відповідь, які ми називатимемо `logical guardrails`.\n\nНаприклад, часто модель каже, що `post_cta=none`, водночас каже `post_cta_type=\"assessment_entry\"`. Якщо вкінці ми додамо правило:\n```py\nanalysis_object = llm.analyze(post)\n\nif analysis_object.post_cta = None:\n    analysis_object.post_cta_type = None\n```\n\nТо це забезпечуватиме 100% того, що у нас CTA буде всюди Null, тож дані будуть \"чистіше\".\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstupidcucumber%2Fcreative-analyzer-agent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstupidcucumber%2Fcreative-analyzer-agent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstupidcucumber%2Fcreative-analyzer-agent/lists"}