La semaine dernière, j'ai eu l'honneur d'en présenter un sur TheJam.dev . C'était ma première présentation sur l'IA générative, et j'ai pu partager ce que je pensais être un cas d'utilisation intéressant : aider au processus d'écriture.
Maintenant, pour être clair, je ne parle pas d'utiliser GenAI pour écrire des articles de blog, ce serait une horrible idée. (OMI !) Au lieu de cela, j'ai regardé comment cela pourrait aider dans une partie du processus. Permettez-moi de revenir un peu en arrière et de vous donner un peu de contexte.
Je suis fan de John Birmingham depuis de nombreuses années maintenant. C'est un auteur qui écrit dans le genre militaire/science-fiction/etc et qui a des idées assez fascinantes. Je l'ai d'abord découvert via sa trilogie "Axis of Time" qui traitait de l'idée d'une flotte navale internationale moderne renvoyée dans le temps jusqu'en 1942.
Maintenant, c'est cool en soi, cependant, j'ai adoré qu'il ne se concentre pas uniquement sur l'aspect militaire mais passe beaucoup de temps à parler du choc culturel entre les "uptimers" (les gens du futur) et les contemporains.
Je suppose qu'on pourrait dire que c'était un peu comme Tom Clancy mais pas seulement axé sur l'action. Je recommanderais n'importe lequel de ses livres, et si vous l'avez déjà lu, faites-le moi savoir dans un commentaire ci-dessous.
En tant que adepte de son travail, je me suis abonné à son Patreon, et ça a été vraiment intéressant. Il partage des ébauches de chapitres d'œuvres à venir, mais plus important encore, il parle également beaucoup de son processus. En tant qu'écrivain moi-même, je trouve cela vraiment fascinant.
Récemment, il a parlé de sa propre utilisation de GenAI et a expliqué comment il l'utilise d'un point de vue davantage « framework ». C'est-à-dire, comment introduire les motivations d'un personnage au bon moment et comment définir les points de l'intrigue. Il s'agit toujours d'un travail de « création », mais plus encore... je ne sais pas. Gestion des travaux ?
Mais comme je l'ai dit, j'ai trouvé cela vraiment intéressant et cela m'a fait réfléchir. Comment puis-je utiliser GenAI sur mon blog pour faciliter le processus d'écriture ? Voici ce que j'ai trouvé.
En passant, tout ce dont je discute ci-dessous utilise l'API Gemini et Eleventy de Google, mais serait certainement utile ailleurs.
La première démo que j'ai construite consistait à m'aider à trouver des titres pour les articles de blog. Maintenant, je n'ai généralement pas de difficulté avec cela, mais j'étais curieux de savoir si GenAI pouvait peut-être suggérer des alternatives pour de meilleurs titres.
J'ai commencé par tester une invite :
Gémi
Étant donné le titre suivant pour un article de blog, partagez trois suggestions qui peuvent améliorer le titre et générer du trafic vers l'article : « QUELQUE TITRE ». Présentez votre réponse sous forme JSON. La clé de niveau supérieur du résultat JSON doit être « suggestions » et chaque suggestion doit utiliser la clé « titre » pour le titre suggéré et « raisonnement » pour le raisonnement.
Vous remarquerez que je demande spécifiquement trois suggestions et dis que je souhaite contribuer à générer plus de trafic. Maintenant, je vais être honnête. Cela semble un peu dégoûtant et spammé. Je ne veux pas nécessairement de titres clickbait. Cela étant dit, je voulais voir d'autres idées pour mes titres.
Cette invite a semblé bien fonctionner avec quelques tests dans AI Studio , alors je me suis lancé dans le code. J'ai pris le code exporté par Google, puis j'ai écrit un peu de code pour :
Voici l'intégralité du script :
#!/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('------------------------------------------------------------------------'); }); })();
Et comment ça marche ? Cet article de blog s'intitule : "Utiliser l'IA générative comme assistant de contenu"
Voici ce que Gemini a suggéré :
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.
Ouais... je pense que c'est plutôt cool. Cependant, aucun d’entre eux ne ressemble vraiment à « ma » voix ici. Je vois absolument du mérite dans les suggestions, et cela me donne matière à réflexion, mais évidemment, j'ai laissé le titre original tel quel.
Pour ma prochaine démo, j'ai examiné une partie de mon processus d'écriture que je n'apprécie pas vraiment, à savoir l'écriture de la valeur description
en une phrase utilisée dans mon exposé. Cette chaîne finit par aller dans ma balise <meta name="description">
et n'est utilisée nulle part ailleurs.
J'ai pensé que ce serait une excellente utilisation de la fonction de résumé de GenAI. J'ai commencé avec une invite comme celle-ci :
À partir du billet de blog suivant, rédigez un résumé d'une phrase à utiliser comme description.
Et puis j'ai réfléchi au contenu que j'enverrais. Mes articles de blog contiennent généralement de nombreux exemples de code, et j'ai pensé que cela finirait par être du bruit. Ma logique est donc devenue :
La plupart de ceci n'est qu'une version modifiée du premier exemple, mais jetons un coup d'œil à l'aspect nettoyage :
function cleanup(str) { str = str.replace(/```(.*?)```/sg, ''); str = str.replace(/---(.*?)---/sg, ''); str = str.replace(/\n{3,}/g, '\n'); return str.trim(); }
L’intégralité du contenu de l’article de blog est transmis, j’ai donc supprimé les éléments préliminaires et les exemples de code. J'ai ensuite remplacé plusieurs lignes vides. Voici l'intégralité du script :
#!/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); })();
Et voici ce que cela montre pour un article d'il y a quelques jours, "Utiliser l'IA générative pour améliorer les noms de fichiers d'images" :
This post explores how Generative AI can be used to enhance image filenames, making them more descriptive, accurate, and consistent.
Je dois dire que c'est plutôt parfait ! Et je ne suis pas si inquiet de la « voix » pour cela. Je suis allé de l'avant et je l'ai utilisé pour ce post (après avoir terminé), et j'ai obtenu (et utilisé) - ceci :
Améliorez votre processus de création de contenu en utilisant l'IA générative comme assistant d'écriture virtuel.
Si cela vous intéresse mais que vous aimeriez me voir divaguer en regardant une Etoile de la Mort LEGO, vous pouvez regarder la présentation ci-dessous :
Mes deux scripts présentés ci-dessus se trouvent dans mon dépôt et peuvent être trouvés dans le répertoire des scripts ici : https://github.com/cfjedimaster/raymondcamden2023/tree/main/scripts
Dites-moi ce que vous en pensez dans un commentaire ci-dessous !