На прошлой неделе я имел честь представить одно из них на TheJam.dev . Это была моя первая презентация о генеративном искусственном интеллекте, и мне удалось поделиться, по моему мнению, интересным вариантом использования — помощь в процессе написания.
Теперь, чтобы внести ясность, я не имею в виду использование GenAI для написания сообщений в блогах, это было бы ужасной идеей. (ИМО!) Вместо этого я посмотрел, как это может помочь в некоторых этапах процесса. Позвольте мне немного вернуться назад и рассказать немного предыстории.
Я уже много лет являюсь поклонником Джона Бирмингема . Он автор, пишущий в жанре военной/научно-фантастической/и т. д. и у него есть довольно интересные идеи. Впервые я познакомился с ним через его трилогию «Ось времени», в которой речь шла об идее отправки современного международного военно-морского флота в прошлое, в 1942 год.
Это само по себе круто, однако мне понравилось, что он не просто сосредоточился на военном аспекте, но и потратил много времени на разговоры о культурном столкновении между «аптаймерами» (людьми из будущего) и современниками.
Полагаю, можно было бы сказать, что это немного похоже на Тома Клэнси, но не просто сосредоточено на действии. Я бы порекомендовал любую из его книг, и если вы уже читали его, дайте мне знать в комментариях ниже.
Как последователь его творчества, я подписался на его Patreon, и это было действительно интересно. Он делится черновиками глав из будущих работ, но, что более важно, он также довольно много рассказывает о своем процессе. Мне, как писателю, это действительно интересно.
Недавно он говорил о своем собственном использовании GenAI и обсудил, как он использует его с точки зрения «фреймворка». То есть, как в нужный момент использовать мотив персонажа и как расставить точки сюжета. Это еще «творческая» работа, но больше… не знаю. Руководство работой?
Однако, как я уже сказал, мне это показалось действительно интересным, и это заставило меня задуматься. Как я могу использовать GenAI в своем блоге, чтобы помочь в процессе написания? Вот что я придумал.
Вкратце: все, что я обсуждаю ниже, использует Google Gemini API и Eleventy , но, безусловно, будет полезно в другом месте.
Первая демо-версия, которую я создал, заключалась в том, чтобы помочь мне придумать заголовки для сообщений в блоге. Обычно у меня с этим проблем нет, но мне было любопытно, сможет ли GenAI предложить альтернативы лучшим играм.
Я начал с проверки подсказки:
близнецы
Учитывая следующий заголовок сообщения в блоге, поделитесь тремя предложениями, которые могут улучшить заголовок и привлечь трафик к сообщению: «НЕКОТОРОЙ НАЗВАНИЕ». Представьте свой ответ в форме JSON. Ключом верхнего уровня результата JSON должен быть «предложения», и каждое предложение должно использовать ключ «заголовок» для предлагаемого заголовка и «обоснование» для обоснования.
Вы заметите, что я специально прошу дать три предложения и говорю, что хочу помочь привлечь больше трафика. Теперь я буду честен. Это кажется немного грубым и спамом. Мне не обязательно нужны кликбейтные заголовки. При этом я хотел увидеть другие идеи для своих названий.
Эта подсказка, похоже, хорошо сработала при нескольких тестах в AI Studio , поэтому я приступил к кодированию. Я взял код, экспортированный Google, а затем написал немного кода:
Вот весь сценарий:
#!/usr/bin/env node /* Given an input MD file, grab the title, and ask Google's AI APIs to offer suggestions. */ const fs = require('fs'); const fm = require('front-matter'); require('dotenv').config({path:__dirname + '/.env'}); const { GoogleGenerativeAI, HarmCategory, HarmBlockThreshold, } = require("@google/generative-ai"); const MODEL_NAME = "gemini-pro"; const API_KEY = process.env.GOOGLE_AI_KEY; async function runGenerate(title) { const genAI = new GoogleGenerativeAI(API_KEY); const model = genAI.getGenerativeModel({ model: MODEL_NAME }); const generationConfig = { temperature: 0.9, topK: 1, topP: 1, maxOutputTokens: 2048, }; const safetySettings = [ { category: HarmCategory.HARM_CATEGORY_HARASSMENT, threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, }, { category: HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, }, { category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, }, { category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, }, ]; const parts = [ {text: `Given the following title for a blog post, share three suggestions that may improve the title and drive traffic to the post: \"${title}\". Present your answer in JSON form. The top level key of the JSON result should be "suggestions" and each suggestion should use the key "title" for the suggested title and "reasoning" for the reasoning. The returned JSON should look like the following sample: [ { title: "First suggested title", reasoning: "This is the reason for the suggestion." } ] `}, ]; const result = await model.generateContent({ contents: [{ role: "user", parts }], generationConfig, safetySettings, }); const response = result.response; // remove backticks and parse. I'm seeing ```json sometimes too // console.log('DEBUG', response.text()); return JSON.parse(response.text().replace(/```/mg, '').replace(/```json/mg,'')); } (async () => { if(process.argv.length === 2) { console.log('Usage: titlesuggestions.js <<path to md>>'); process.exit(1); } const mdPath = process.argv[2]; if(!fs.existsSync(mdPath)) { console.log(`Unable to find ${mdPath}.`); process.exit(1); } const contents = fs.readFileSync(mdPath,'utf-8'); let title = fm(contents).attributes.title; console.log(`\nGenerating suggestions for: ${title}`); console.log('------------------------------------------------------------------------'); let suggestions = (await runGenerate(title)).suggestions; //console.log(suggestions); suggestions.forEach(s => { console.log(`Suggested Title: ${s['title']}\n\nReasoning: ${s['reasoning']}\n`); console.log('------------------------------------------------------------------------'); }); })();
И как это работает? Эта запись в блоге называется: «Использование генеративного искусственного интеллекта в качестве помощника по контенту».
Вот что предложили Близнецы:
Suggested Title: The Power of Generative AI: Your New Content Assistant Reasoning: This title emphasizes the strength and potential of generative AI as a content creation tool, capturing the reader's attention and making them curious about the possibilities it offers. ------------------------------------------------------------------------ Suggested Title: Unlock Your Content Creation Potential with Generative AI Reasoning: This title suggests that generative AI can unlock new levels of productivity and creativity in content creation, attracting readers who are looking for ways to enhance their content strategy. ------------------------------------------------------------------------ Suggested Title: Revolutionize Your Content Creation: Meet Your Generative AI Assistant Reasoning: This title highlights the transformative potential of generative AI in content creation, appealing to readers who are eager to adopt cutting-edge technologies to streamline their workflow.
Да... Я думаю, это очень круто. Однако ни один из них на самом деле не похож на «мой» голос. Я определенно вижу в этих предложениях определенные достоинства, и это дает мне повод задуматься, но, очевидно, я оставил исходное название как есть.
В своей следующей демонстрации я рассмотрел ту часть своего писательского процесса, которая мне действительно не нравится, — написание значения description
из одного предложения, используемого в моем вступительном слове. Эта строка попадает в мой тег <meta name="description">
и больше нигде не используется.
Я подумал, что это будет отличное использование функции обобщения GenAI. Я начал с такой подсказки:
Учитывая следующую публикацию в блоге, напишите краткое изложение в одно предложение, которое будет использоваться в качестве описания.
А потом задумался, какой контент прислать. В моих сообщениях в блоге обычно много примеров кода, и я решил, что в конечном итоге это будет шум. Итак, моя логика стала такой:
По большей части это всего лишь модифицированная версия первого примера, но давайте взглянем на аспект очистки:
function cleanup(str) { str = str.replace(/```(.*?)```/sg, ''); str = str.replace(/---(.*?)---/sg, ''); str = str.replace(/\n{3,}/g, '\n'); return str.trim(); }
Здесь передается все содержимое сообщения блога, поэтому я удалил вступительную часть и примеры кода. Затем я также заменил несколько пустых строк. Вот весь сценарий:
#!/usr/bin/env node /* Given an input MD file, grab the text, scrub code, and ask for a summary. */ const fs = require('fs'); const fm = require('front-matter'); require('dotenv').config({path:__dirname + '/.env'}); const { GoogleGenerativeAI, HarmCategory, HarmBlockThreshold, } = require("@google/generative-ai"); const MODEL_NAME = "gemini-pro"; const API_KEY = process.env.GOOGLE_AI_KEY; async function runGenerate(text) { const genAI = new GoogleGenerativeAI(API_KEY); const model = genAI.getGenerativeModel({ model: MODEL_NAME }); const generationConfig = { temperature: 0.9, topK: 1, topP: 1, maxOutputTokens: 2048, }; const safetySettings = [ { category: HarmCategory.HARM_CATEGORY_HARASSMENT, threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, }, { category: HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, }, { category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, }, { category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, }, ]; const parts = [ {text: `Given the following blog post, write a one sentence summary to use as the description:\n${text} `}, ]; const result = await model.generateContent({ contents: [{ role: "user", parts }], generationConfig, safetySettings, }); return result.response.candidates[0].content.parts[0].text; } /* I'm responsible for 'cleaning' up the text before sending to Google. For now, I'll just remove code blocks, but in the future I may remove images too. Also remove double blank lines. Oh, also remove FM. */ function cleanup(str) { str = str.replace(/```(.*?)```/sg, ''); str = str.replace(/---(.*?)---/sg, ''); str = str.replace(/\n{3,}/g, '\n'); return str.trim(); } (async () => { if(process.argv.length === 2) { console.log('Usage: summarysuggestions.j <<path to md>>'); process.exit(1); } const mdPath = process.argv[2]; if(!fs.existsSync(mdPath)) { console.log(`Unable to find ${mdPath}.`); process.exit(1); } let contents = fs.readFileSync(mdPath,'utf-8'); let title = fm(contents).attributes.title; // Make it nicer! contents = cleanup(contents); console.log(`\nGenerating summary suggestion for: ${title}`); console.log('------------------------------------------------------------------------'); let suggestion = (await runGenerate(title)); console.log(suggestion); })();
А вот что показано в сообщении, опубликованном несколько дней назад, «Использование генеративного искусственного интеллекта для улучшения имен файлов изображений» :
This post explores how Generative AI can be used to enhance image filenames, making them more descriptive, accurate, and consistent.
Должен сказать, это очень точно! И меня не так уж беспокоит «голос». Я использовал его для этого поста (после того, как закончил) и получил (и использовал) — это:
Улучшите процесс создания контента, используя генеративный искусственный интеллект в качестве виртуального помощника по написанию текстов.
Если это вас интересует, но вам бы хотелось, чтобы я болтал, глядя на Звезду Смерти LEGO, вы можете посмотреть презентацию ниже:
Оба моих сценария, показанные выше, находятся в моем репозитории, и их можно найти в каталоге сценариев здесь: https://github.com/cfjedimaster/raymondcamden2023/tree/main/scripts .
Дайте мне знать, что вы думаете в комментарии ниже!