Як за допомогою АІ генерувати сотні SEO-сторінок щоденно і не збожеволіти
Привіт! Мене звати Микола, і я вже понад п’ять років працюю в продуктовому ІТ. Більше року я займався технічним SEO як Front-end Developer в Universe Group — українській ІТ-компанії, що запускає глобальні продукти, якими користуються понад 85 млн користувачів.
Я належу до покоління розробників третьої хвилі, яке відзначається відкритістю до нових технологій і нестандартних рішень. Люблю експериментувати та знаходити креативні підходи до розробки. Дехто може назвати це «безумством», але дозвольте пояснити, що я маю на увазі.
Моє становлення як розробника збіглося з епохою ChatGPT-3 та AI, і я з радістю прийняв цю хвилю інновацій. У матеріалі розповім, як за один день створити сотні SEO-сторінок з унікальним контентом за допомогою штучного інтелекту.
Ця стаття буде корисна розробникам, SEO-спеціалістам, контент-райтерам і технічним командам, які прагнуть швидко масштабуватись та потрапляти в ТОП видачі Google.
Важливо
За приклад для статті взята автоматизація, створена на той момент, коли найкращим рішенням була модель GPT 4o-mini. Тож якщо зараз, коли ви читаєте матеріал, є краща та оптимальна за витратами модель — беріть її.
Виклик: сотні воронок з мінімальними витратами
Перед нашою SEO-командою постав виклик: створити сотні нових воронок з однаковою структурою з мінімальними витратами часу та ресурсів. Ми розуміли, що написання якісного контенту людиною зайняло б понад один день на сторінку і потребувало б додаткового бюджету, тож вирішили використати ChatGPT. У процесі виникло три основні виклики:
- згенерувати якісний і правдивий контент за допомогою АІ, що відповідає вимогам SEO;
- автоматично інтегрувати контент у CMS (Content Management System);
- налагодити роботу з Google Sheet для управління процесом.
Пошук рішення, нетворкінг
Перед початком роботи ми вирішили провести нетворкінг із колегами з двох проєктів екосистеми Genesis, адже в них уже був відповідний досвід. В обох випадках мене запевнили, що технічно це не складно, але головні ризики — валідація згенерованого контенту та порушення структури даних. Що це означає?
При роботі з ChatGPT важливо задати чітку структуру чи формат даних, які ми очікуємо отримати. Розгляньмо приклад: потрібно створити текст для невеликої сторінки нашого сайту. Для цього попросимо стандартну версію ChatGPT зробити наступне:
На перший погляд, людям, які не працюють із контентом на рівні програмування, може здатись, що відповідь ChatGPT виглядає досить структурованою та зручною для подальшої розробки. Проте коли обсяги даних зростають, у цьому тексті важко чітко відокремити різні частини контенту.
Під час парсингу тексту складно визначити, де закінчується один блок (наприклад, meta title) і починається інший (наприклад, meta description). А якщо ChatGPT зробить друкарську помилку в назві ідентифікатора, це може призвести до некоректного завантаження даних або повної зупинки роботи програми.
Інша справа, якщо це улюблений у розробників JSON-формат:
У цьому підході можна легко отримати потрібне id без ризику зайвих даних. Однак і тут є нюанси, до яких ми повернемося пізніше.
Для зручної роботи з великими обсягами контенту потрібен оптимізований підхід. Генерувати сотні сторінок викликами ChatGPT вручну і переносити дані вручну — нераціонально. Розгляньмо, як можна організувати цей процес у Google Sheet.
Покровий гайд із під’єднання ChatGPT до Google Sheet
- Зайдіть в Extensions/Apps Script:
- Додайте необхідний для роботи ChatGPT у Google Sheet JavaScript-код. Базовий приклад є на офіційному сайті OpenAI. Проте ми завдяки колегам із проєктів екосистеми використали більш кастомну та покращену версію, якою я радий поділитися з вами:
- Зареєструйтесь на сайті, згенеруйте свій API-ключ і поповніть рахунок.
- Введіть скопійований API-ключ у код вашої функції та збережіть проєкт:
- Перевірте, чи працює потрібна функція:
- Переконавшись, що контент успішно генерується, оптимізуйте параметри функції під потреби вашого запиту.
- Додайте чіткий контекст: деталізуйте опис англійською мовою у змінну з аналогічною назвою. Це допоможе ChatGPT зрозуміти, який саме контент потрібен, як виглядає ваш сайт і яка функціональність на ньому є, якщо це важливо для запиту.
- Протестуйте та зафіксуйте так званий параметр відповіді «температури вигаданості». Він контролює рандомність і креативність відповідей чату. Температура 0 забезпечить точність і сталість відповідей, тоді як температура 1 дозволить генерувати більш варіативний контент.
- Оберіть відповідну роль ChatGPT для вашого запиту: system, assistant чи user.
- System — говорить мовній моделі, як саме ви збираєтесь з нею «спілкуватися» і кого вона має симулювати. Наприклад: «Ти талановитий SEO-writer, тексти якого чудово сприймаються як Google, так і людиною». У нашому експерименті ми обрали саме цю роль, адже вона дає можливість задати ChatGPT, хто він такий в бажаному контексті :)
- Assistant — це роль моделі, яка відповідає на запити користувача, спираючись на контекст, встановлений роллю system;
- User — ця роль представляє людського користувача в розмові. Введення від користувача керують розмовою і викликають відповіді від assistant.
- Покращуйте та редагуйте промт доти, доки він вас повністю не задовільнить. І задайте очікувану структуру відповіді (наприклад: «Strict Response Requirements: ...»). Чат готовий до роботи!
function runOpenAI(prompt, cell) { // Define your OpenAI API key const API_KEY = "YOUR_API_KEY"; // Define the context to guide the model's response const context ="You are a SEO content writer with 10 years of experience. You help us to write content for our website. Your replies include only the requested content part and no extra additional information or trailing quotes."; // Specify the model to use model = "gpt-4o-mini"; // Note: The model name may need to be updated based on available models // Construct the full prompt by combining the context, prompt, and cell information full_prompt = `${context}${prompt}${cell}:`; // Set the temperature parameter for the response (controls creativity) temperature = 0.7; try { // Define the request body with model, messages, temperature, and max tokens const requestBody = { model: model, messages: [{ role: "system", content: full_prompt }], temperature: temperature, max_tokens: maxTokens, // Ensure `maxTokens` is defined elsewhere in your code }; // Define the request options for the HTTP request const requestOptions = { method: "POST", headers: { "Content-Type": "application/json", Authorization: "Bearer " + API_KEY, }, payload: JSON.stringify(requestBody), }; // Send the request to the GPT-3 API endpoint for completions const response = UrlFetchApp.fetch( "https://api.openai.com/v1/chat/completions", requestOptions ); // Get the response body as a JSON object const responseBody = JSON.parse(response.getContentText()); // Extract the answer from the response let answer = responseBody.choices[0].message.content; return answer; } catch (error) { // Log the error message if an exception occurs console.log(error.message); } }
![](https://s.dou.ua/storage-files/image_65647677941736160216557.png)
![](https://s.dou.ua/storage-files/blobid0_LhXp5Ud.png)
=runOpenAI("Is Developer of the Third Wave just a joke?")
![](https://s.dou.ua/storage-files/image_21039038671736160216652.png)
Організація структури Google Sheet файлу
Тепер у Google Sheets у вас є справжній контент-спринтер. Щоб забіги були якісними й результативними, налаштуємо структуру для зручного запуску. Уявімо, що потрібно згенерувати для одного сайту три сторінки з різним контентом про домашніх улюбленців. Структуруйте таблицю так, щоб ChatGPT міг швидко генерувати тексти про котиків, собачок і рибок, враховуючи інтереси різних читачів.
Ось чотири можливих варіанти структури Google Sheet:
Унікальні id і розбивка на елементи
Записуємо унікальні id контенту, який ми хочемо, щоб згенерував ChatGPT в перший рядок файлу. Далі розбиваємо контент на дрібніші ввідні дані: унікальний id сторінки, метазаголовок (meta Title), метаопис (meta Description), заголовок першого рівня (h1) та параграф тексту (paragraph).
Цей підхід чудово підійде для генерації окремих одиниць контенту та подальшої технічної роботи, оскільки легко відстежувати й редагувати конкретний елемент контент-райтером.
Недоліки:
- робота ускладнюється через горизонтальне розташування даних;
- велика вкладеність файлу;
- збільшення витрат через більшу кількість викликів ChatGPT.
Унікальні id у першій колонці
Фіксуємо унікальні id контенту в першій колонці файлу та розбиваємо його на дрібні ввідні дані.
Це рішення може виявитися більш гнучким для менеджерів контенту, оскільки дані краще сприймаються візуально, що підтвердив наш спеціаліст із генерації та редагування контенту.
Можливі недоліки:
- деякі технічні рішення можуть складно працювати з контентом у форматі першої колонки;
- реалізація може бути складнішою для технічної обробки, якщо система не підтримує такий формат id.
Контент у JSON-форматі в одній колонці
У цьому підході зберігаємо id у першому рядку, а весь згенерований текст для сторінки — у колонці з id content. Така імплементація була б, мабуть, найкращим рішенням для технічного спеціаліста: весь контент для сторінки зберігається в одній клітинці, що спрощує подальшу обробку. Формат JSON дозволяє чітко структурувати дані та легко визначати, де який елемент контенту. Такі id як metaTitle, metaDescription, h1 та paragraph можна було б зібрати в одній клітинці.
Та в цьому підході є низка негативних аспектів:
- Редагування. Ускладнення роботи для редактора контенту.
- Валідація структури даних. Існує ризик того, що ChatGPT згенерує невірну структуру JSON, де навіть один пропущений символ може збити процес подальшої технічної реалізації;
- Якість контенту. Створення ChatGPT великої кількості даних за один раз може відобразитись на якості контенту.
Цей варіант має таку ж логіку, як і минулий, проте контент буде розміщений не вертикально, а горизонтально.
У нашому випадку перший варіант виявився оптимальним, оскільки він забезпечує якість контенту, зручність редагування для контент-райтера та мінімізує ризики під час технічної реалізації завдяки розділенню контенту на менші частини.
Ми передаємо до функції додатковий до збереженого основного контексту запит із необхідними параметрами з id:
Google Sheet дає нам можливість протягнути функцію вниз за колонкою та швидко згенерувати контент для dogs та fish, де функція використається ще раз та динамічно передається id уже наступних рядків: A3, A4 і так далі. І такий підхід застосовуємо і для metaDescription, h1, paragrap та решти одиниць необхідного контенту.
СhatGPT і JSON: як подружити
Для підходів із прикладів 3 і 4 весь контент сторінки потрібно отримати одним запитом та зберегти в одній клітинці. Це можна зробити за допомогою промпту, що генерує дані у форматі JSON:
=runOpenAI("Generate content in the form of JSON where keys are id of content and values are content itself. The list of keys are: metaTitle, metaDescription, h1, paragraph. metaTitle: SEO meta title. Max length is 65 characters. The page talks about the life of " & A2 & "; metaDescription: SEO meta description. Max length is 200 characters. Content of the page is the life of " & A2 & "; h1: H1 for this page" & "; paragraph: write the eye-catching content about the life of" & A2 & ".")
На виході отримуємо ось такий результат:
Також, якщо ваша мета більше підлаштувати сайт під SEO, можна розглядати опцію використання певних ключових слів, розкиданих по всьому тексту. Додайте до кастомних промптів таку фразу як, наприклад «Add 3 following keywords through the whole content: `pet`, `home`, `buy`». Таким чином ви зможете додатково природно наповнити текст бажаними словами.
Виглядає чудово, варто просто протягнути та застосувати цю функцію вниз, і ми маємо готовий контент для всіх наших сторінок.
На перший погляд, може здатись, що все просто супер, однак контент для fish виглядає не так, як очікувалося. Чат додав «json» на початок та " " на кінець відповіді. Це означає, що наша структура зламалась для подальшої технічної реалізації. Нам потрібно врахувати та прибрати зайві лапки та слово «json» на початку. А що як наступного разу ChatGPT згенерує зайву дужку чи щось не візьме у лапки? Все знову зламається...
Найчастіші помилки під час генерації JSON-контенту з ChatGPT:
- можуть бути пропущені фігурні {} або квадратні дужки [];
- назви ключів або значення можуть генеруватися без подвійних лапок " " ;
- відсутність ком між елементами;
- дублювання ключів;
- вставка спеціальних символів (наприклад, зворотних лапок ` `).
Як це можна виправити? Шляхом додавання до ваших конфігураційних налаштувань функції чату наступних параметрів:
response_format: { type: "json_object"}
Це забезпечить правильний формат JSON і мінімізує ризики «зламаної» структури даних.
Після генерації контенту раджу зберегти його просто як значення, а не як результат виклику функції runOpenAI. Google Sheet поводиться як абʼюзивний партнер у стосунках — будь-яка зміна в файлі чи його відкриття тригерить повторний виклик функцій і перегенерацію контенту. Це може призвести до втрати валідованого контенту, який вас влаштовував. А якщо у вас кілька сотень або тисяч викликів, це може дорого коштувати, оскільки API ChatGPT не є безплатним.
Заплати ще за нього!
Якщо ви плануєте спрогнозувати бюджет, який піде на генерацію контенту, раджу скористатись таким токанайзером від OpenAI.
Використаймо цей підхід, щоб оцінити вартість генерації контенту для однієї сторінки, порівнюючи підхід з декомпозицією контенту на частини та підхід із JSON на основі наших промптів.
У першому випадку нам потрібно взяти контекст із функції та контекст промпту із metaTitle й порахувати кількість токенів за допомогою токанайзера:
«You are a SEO content writer with 10 years of experience. You help us to write content for our website. Your replies include only the requested content part and nothing extra additional information. Your reply does not include trailing quotes»
Плюс:
«Write a SEO meta title. Max length is 65 characters. The page talks about the life of cats»
67 токенів
Далі знову беремо контекст із функції + metaDescription і так перевіряємо всі одиниці контенту (h1, paragraph...). У сумі при такому підході в мене вийшло:
270 токенів
У другому випадку, використовуючи підхід із JSON, ми отримуємо весь контент одним запитом. До контексту функції додаємо один запит, який просить ChatGPT згенерувати весь контент за раз:
«You are a SEO content writer with 10 years of experience. You help us to write content for our website. Your replies include only the requested content part and nothing extra additional information. Your reply does not include trailing quotes»
Плюс:
«Generate content in form of JSON where keys are ids of content and values are content itself. The list of keys are: metaTitle, metaDescription, h1, paragraph. metaTitle: SEO meta title. Max length is 65 characters. The page talks about the life of cats; metaDescription: SEO meta description; Max length is 200 characters; Content of the page is the life of cats; h1: H1 for this page; paragraph: write the eye-catching content about the life of cats»
При такій реалізації вийшло:
150 токенів
При такому підході нам потрібно лише один раз додати контекст функції до нашого промпту, оскільки просимо ChatGPT згенерувати весь контент для однієї сторінки в одному запиті. Це дозволяє знизити витрати токенів у порівнянні з попереднім підходом, де кожну одиницю контенту запитуємо окремо.
Один мільйон токенів, які ми передаємо до моделі GPT, коштує $0.150. У першому випадку для генерації контенту однієї статті ми витратили б $0,0000405, а в другому — $0,0000225. Якщо ж контекст функції буде значно більшим, а кількість одиниць контенту — 10, 20 чи більше, оптимізація на великих масштабах буде значно відчутнішою.
Також важливо враховувати, що ви будете платити не тільки за токени, які передаєте в запиті, але й за токени, які генерує ChatGPT у відповідь. І зазвичай тариф на токени в відповіді вищий.
Рекомендації щодо вибору моделі
Моделі GPT-4o Mini:
- Дешевші у
2-3 рази порівняно з GPT-3.5 Turbo. - Показують кращі результати за даними OpenAI.
Для досягнення оптимальних результатів варто використовувати GPT-4o Mini, щоб знизити витрати та підвищити ефективність.
Технічна реалізація
І ось уже всі тексти згенеровані, бюджети оптимізовані, райтери втомлені, девелопери підготовлені. Що далі? Наступний крок — спарсити (розшифрувати чи «розібрати на молекули») збережений контент із Google Sheet файлу в форматі .csv та розкласти весь контент по полицях.
Для парсингу рекомендую використати бібліотеку csv-parser. Її особливість у тому, що:
- перший рядок файлу сприймається як набір унікальних id;
- створюється JavaScript-об’єкт, який перевикористовує ці ключі для кожного запису (наприклад, для cats, dogs, fish тощо).
Для цього створюємо простий pets.js-файл і додаємо туди цей код:
const csv = require('csv-parser') const fs = require('fs') const results = []; fs.createReadStream("pets.csv") .pipe(csv()) .on("data", (data) => { for (const pet of [data]) { results.push({ id: pet.id, ...JSON.parse(data.content) }); } }) .on("end", () => { console.log(results); // [ // { // id: 'cats', // metaTitle: 'The Fascinating Life of Cats: A Deep Dive', // metaDescription: 'Explore the intriguing world of cats…', // h1: 'Discover the Enigmatic Life of Cats', // paragraph: 'Cats are more than just pets...' // }, // { // id: 'dogs', // metaTitle: 'The Joyful Life of Dogs: A Heartwarming Journey', // metaDescription: 'Discover the beautiful life of dogs, their loyalty...', // h1: 'The Wonderful Life of Dogs', // paragraph: 'Dogs are more than just pets...' // }, // { // id: 'fish', // metaTitle: 'Discover the Fascinating Life of Fish', // metaDescription: 'Explore the diverse and captivating world of fish, their habitats...', // h1: 'The Intriguing Life of Fish', // paragraph: 'Fish are some of the most diverse and fascinating ...' // } // ] });
Щоб запустити його, можемо виконати команду node pets.js.
У нашому випадку на кожен із cats, dogs і fish відправляємо HTTP POST запит у Strapi CMS, де в нас зберігаються дані та доставляємо йому згенерований контент.
Тепер весь контент зібрано, підготовлено, і проєкт готовий до запуску! 🚀
Висновки
Використання ChatGPT для автоматизації генерації контенту, на мій погляд, має значний потенціал для швидкого масштабування та зниження витрат на ресурси при написанні тексту. Зокрема, цей підхід дозволяє швидко генерувати якісний контент, враховуючи SEO-вимоги, що є важливим для просування сайтів у пошукових системах.
Однак важливо враховувати виклики, пов’язані з форматом даних. Дрібні помилки можуть спричинити серйозні проблеми в подальшій автоматизації та інтеграції контенту. Для уникнення цих проблем необхідно впроваджувати додаткові механізми валідації даних, як-от коректну конфігурацію налаштувань API та валідацію згенерованих даних. А саме автоматичне завантаження контенту csv-файлу може зекономити години мануальної роботи при перенесенні контенту в місце, де він зберігається.
Сподіваюсь, наш досвід стане корисним і ви зможете оптимізувати процеси та пришвидшити темпи розвитку. Можливо, це саме те рішення, яке очікує від вас команда чи роботодавець.
58 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів