Skip to content

This Post About AI-Generated Posts Was Written by AI

Posted on:November 24, 2023 at 10:49 AM

This Post About AI-Generated Posts Was Written by AI

In this academic post, we will delve into a simple explanation of some Rust code that utilizes Artificial Intelligence (AI) to generate blog posts. Our primary focus in this discussion is to explore the fundamental concepts involved and their potential applications in various fields.

Understanding Rust Programming Language

Rust is a systems programming language known for its speed, safety, and concurrency capabilities. It has gained significant traction due to its memory-safe and thread-safe features. Rust code can be executed in various environments, including web applications and command-line tools.

Harnessing AI for Post Generation

Artificial Intelligence plays a crucial role in today’s technological advancements, and its application in content generation is no exception. With the rise of Natural Language Processing (NLP) techniques and machine learning algorithms, it is now possible to generate human-like text using computer programs.

Rust AI Code for Blog Post Generation

To demonstrate how Rust can be leveraged to create AI-generated blog posts, let’s examine a simple example of Rust code that uses Ollama to send prompts to a locally running LLM. The following code is the exact code that was used to generate this blog post.

use clap::Parser;
use reqwest;
use serde_json::{json, Value};
use std::fs;
use tokio;
use chrono::Utc; // Add chrono to your Cargo.toml dependencies
use std::process::Command;

/// Blog Post Generator
#[derive(Parser, Debug)]
#[command(author = "Dax the Dev", version, about = "Generates blog posts using Ollama", long_about = None)]
struct Args {
    /// Name of the article
    #[arg(short = 'n', long)]
    name: String,

    /// Topic of the article
    #[arg(short = 't', long)]
    topic: String,

    /// Tone of the article
    #[arg(short = 'o', long)]
    tone: String,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let args = Args::parse();

    let content = generate_blog_content(&args.name, &args.topic, &args.tone).await?;
    let tags = generate_blog_tags(&content).await?;
    let description = generate_blog_description(&content).await?;

    // Get the current time
    let current_time = Utc::now().format("%Y-%m-%dT%H:%M:%SZ").to_string();

    // Format the blog post with metadata
    let formatted_post = format!(
        "---\nauthor: Dax the Dev\npubDatetime: {}\ntitle: {}\npostSlug: {}\nfeatured: true\ndraft: false\ntags:\n{}\ndescription: {}\n---\n\n{}",
        current_time,
        args.name,
        slugify(&args.name),
        tags.split(',').map(|tag| format!("  - {}", tag.trim())).collect::<Vec<String>>().join("\n"),
        description, // Replace with your actual description
        content
    );

// Save the blog post locally
let local_path = format!("./{}.md", slugify(&args.name));
fs::write(&local_path, &formatted_post)?;

// Copy the file to the Astro project directory
let destination_path = format!("/Users/dax/Code/dumpBlogs/src/content/blog/{}.md", slugify(&args.name));
Command::new("cp")
    .arg(&local_path)
    .arg(&destination_path)
    .output()?;

println!("Blog post generated and copied successfully!");

    Ok(())
}


async fn generate_blog_content(article_name: &str, topic: &str, tone: &str) -> Result<String, Box<dyn std::error::Error>> {
    let client = reqwest::Client::new();
    let prompt = format!("Create a blog post in markdown called '{}' that is all about '{}' and has a '{}' tone.\n\n###", article_name, topic, tone);
    let response = client.post("http://localhost:11434/api/generate")
        .json(&json!({
            "model": "openhermes2-mistral:latest",
            "prompt": prompt,
            "stream": false
        }))
        .send()
        .await?
        .text()
        .await?;

        let final_response = response
        .lines()
        .filter_map(|line| serde_json::from_str::<Value>(line).ok())
        .filter_map(|val| val.get("response")?.as_str().map(ToString::to_string))
        .collect::<Vec<String>>()
        .join("");

    Ok(final_response)
}


async fn generate_blog_tags(content: &str) -> Result<String, Box<dyn std::error::Error>> {
    let client = reqwest::Client::new();
    let prompt = format!("create a list of tags (3 words or less for each tag use - for each one) for the following blog post:\n\n{}", content);
    let response = client.post("http://localhost:11434/api/generate")
        .json(&json!({
            "model": "openhermes2-mistral:latest",
            "prompt": prompt,
            "stream": false
        }))
        .send()
        .await?
        .text()
        .await?;

        let final_response = response
        .lines()
        .filter_map(|line| serde_json::from_str::<Value>(line).ok())
        .filter_map(|val| val.get("response")?.as_str().map(ToString::to_string))
        .collect::<Vec<String>>()
        .join("");

    Ok(final_response)

}
async fn generate_blog_description(content: &str) -> Result<String, Box<dyn std::error::Error>> {
    let client = reqwest::Client::new();
    let prompt = format!("create a description for this blog post:\n\n{}", content);
    let response = client.post("http://localhost:11434/api/generate")
        .json(&json!({
            "model": "openhermes2-mistral:latest",
            "prompt": prompt,
            "stream": false
        }))
        .send()
        .await?
        .text()
        .await?;

        let final_response = response
        .lines()
        .filter_map(|line| serde_json::from_str::<Value>(line).ok())
        .filter_map(|val| val.get("response")?.as_str().map(ToString::to_string))
        .collect::<Vec<String>>()
        .join("");

    Ok(final_response)

}


fn slugify(title: &str) -> String {
    title.to_lowercase().replace(" ", "-")
}

This code demonstrates how Rust can be used as a platform for incorporating AI-generated content within various applications, ranging from blog posts to social media updates. While this is just a simplified example, it showcases the potential applications and benefits of leveraging Rust programming language in combination with AI technologies.

Detailed Breakdown of the Rust Code

  1. Command Line Interface with Clap:

    • The code uses clap::Parser to create a command-line interface, allowing users to input parameters like the name, topic, and tone of the article.
  2. Asynchronous Programming with Tokio:

    • The tokio crate is used for asynchronous programming, essential for handling network requests efficiently.
  3. Interacting with AI using Reqwest:

    • reqwest is used for making HTTP requests to the Ollama service, which is an AI model running locally.
  4. Generating Content, Tags, and Description:

    • Functions like generate_blog_content, generate_blog_tags, and generate_blog_description send structured prompts to Ollama and process the AI-generated responses.
  5. Formatting and File Operations:

    • The code formats the blog post with metadata and saves it locally using std::fs. It also copies the file to a specific project directory for deployment.
  6. Utility Functions:

    • The slugify function is a utility to convert titles into URL-friendly slugs.

Conclusion

In conclusion, the integration of AI and Rust code has paved the way for innovative content generation techniques. By understanding the underlying concepts and principles of this technology, we can unlock new possibilities and explore diverse applications across multiple industries. As AI continues to evolve, so too will our ability to generate human-like text, revolutionizing how we create, share, and consume information in the digital age.