I Built an AI Article Generator From Scratch (& Why It Beats ChatGPT)

by | Mar 8, 2025

In today’s fast-paced digital landscape, content creation remains one of the most time-consuming aspects of maintaining an online presence.

I can’t speak for anyone else but a 1,000 word blog post takes me something like 6-8 hours to create from scratch.

That involves:

  • Digging deep to learn a new topic.
  • Sketch an outline before writing.
  • Write content worth reading.
  • Make Google love your content.
  • Formatting before publishing.

What if you could leverage AI to generate high-quality articles in minutes instead of hours?

That’s exactly what I set out to build when I was recently tasked with writing blog posts and new website pages for my local business clients.

I made a simple but powerful AI article generator that streamlines the content creation process above, so you start with a well-structured first draft that is much easier to add on top of vs. starting with a blank sheet.

✏️ Try the Free Article Generator Demo

Want to run this on your own server with no limitations? Purchase the full source code here.

The Development Journey

Creating this tool was a fascinating process that showcased how AI can dramatically accelerate software development. Let’s look at the key steps and challenges I faced while building this solution, along with the prompting techniques I used to engage effectively with the AI models.

Establishing the Foundation

First, I needed a clear vision for the article generator. The goal was simplicity: users enter a brief topic description (3-5 words), click a button, and receive a complete article.

To kick off the process, I shared my detailed requirements with an AI assistant and provided an example form integrated with the LLM APIs.

Here’s what I asked:

I want to create an article generator. Use this example form template for a workout planner (PHP file attached), and mimic the exact template code and styles to create the article generator. I will be using the exact same openai.php and anthropic.php wrappers to use AI functions to generate the article. It will be generated by a series of prompting steps shown below.

This article generator form will be dead simple where I input an article idea in a text box, which will be the seed idea with a big "generate" button (same styles from planner.css).

The output will also be the same with a notification area, and the output.txt file which contains the article content.

I then outlined the multi-step prompting process I envisioned for the first version of the article generator (which I’ve since updated a few times):

  • Generate two separate outlines using different AI models.
  • Combine these outlines into one coherent structure.
  • Think up SEO keywords relevant to the topic.
  • Produce a well-written, comprehensive article.

The exact prompt sequence I asked for was this:

SEED_IDEA - 3-5 word description input via form.

PROMPT #1 - Outline an article for the topic SEED_IDEA. I want a very concise 3-5 bullet points outline, each with a short 1-sentence description of what's included in that bullet section.

PROMPT #2 - Combine these two outlines for an article entitled SEED_IDEA, and make it ultra-concise without losing any of the core ideas: [Include OUTLINE_1 and OUTLINE_2]

PROMPT #3 - Extract and generate keywords that people likely search that are related to the article outline: [Include OUTLINE_COMBINED]

PROMPT #4 - Write an article on the topic of SEED_IDEA using the outline below. Make it as long as it needs to be to adequately cover all the topics in the outline. Consider using the SEO keywords below to enhance the article, but do not force them. [Include KEYWORD_LIST and OUTLINE_COMBINED]

The AI assistant provided a complete implementation plan, including:

  • PHP code for the backend processing.
  • HTML structure for the user interface.
  • JavaScript code for handling form submission and displaying results.
  • Detailed explanation of the workflow.

The response included a complete solution with proper error handling, AJAX calls, and a user-friendly interface—all while maintaining the same styling as my existing workout planner application.

Here is the pseudo-code of the LLM response (which is ironically summarized by an AI chat to condense the full code!):

AI ARTICLE GENERATOR

FILES:
- generate_article.php: Handles backend processing of article generation requests.
- article.php: Provides the HTML structure and user interface for the article generator.
- article.js: Manages the client-side logic and AJAX requests for article generation.
- lib/openai.php: Abstracts interactions with the OpenAI API.
- lib/anthropic.php: Abstracts interactions with the Anthropic API.
- planner.css: Contains the styling rules for the article generator's user interface.
- api.log: Stores a record of API calls and responses for debugging and monitoring.

generate_article.php (Backend Processor)

1.  Receives a seed idea from the user via a POST request.
2.  Validates and sanitizes the input.
3.  Uses the OpenAI and Anthropic APIs to generate two article outlines.
4.  Combines the generated outlines into a single, refined outline.
5.  Generates SEO keywords related to the combined outline.
6.  Uses an AI model to write the full article based on the outline and keywords.
7.  Returns the generated article as a JSON response.
8.  Handles errors and logs API interactions.

article.php (Frontend HTML)

1.  Presents a form for the user to input an article seed idea.
2.  Provides a "Generate Article" button to trigger the article generation process.
3.  Includes a loading indicator to show when the process is running.
4.  Displays the generated article and a download option in a designated area.

article.js (Frontend JavaScript)

1.  Captures the form submission event.
2.  Sends an AJAX request to generate_article.php with the user's seed idea.
3.  Displays a loading indicator while waiting for the response.
4.  Handles the JSON response from the backend.
5.  Displays the generated article and a download button to the user.
6.  Handles and displays any errors that occur during the process.

lib/openai.php (OpenAI API Wrapper)

1.  Encapsulates the logic for interacting with the OpenAI API.
2.  Takes a prompt as input and returns the API's response.

lib/anthropic.php (Anthropic API Wrapper)

1.  Encapsulates the logic for interacting with the Anthropic API.
2.  Takes a prompt as input and returns the API's response.

planner.css (CSS Styling)

1.  Defines the visual presentation and layout of the article generator's user interface.

api.log (API Logging)

1.  Stores a record of API requests and responses for debugging and monitoring purposes.

This foundation gave me everything needed to build out the powerful article generation tool that leverages multiple AI models in sequence to create high-quality content from a simple topic idea.

It’s not always smooth sailing and error free, though.

You will likely get some issues that you must debug… or let AI debug for you!

Just continue to test, ask questions, grab any errors you receive and feed them back into the chat to find solutions.

Building the User Interface

I prioritized a clean, intuitive interface with a single input text box and a big “Generate” button:

<form id="articleForm" class="mb-4">
    <div class="mb-4">
        <label for="seedIdea" class="form-label">Article Topic/Idea</label>
        <input type="text" class="form-control" id="seedIdea" required placeholder="Enter 3-5 words describing your article topic">
    </div>

    <button type="submit" class="btn btn-primary">
        <i class="fas fa-sync-alt me-2"></i>Generate Article
    </button>

    <div id="loading" style="display:none">
        <i class="fas fa-spinner spinner"></i> Generating your article...
    </div>
</form>

Bootstrap and Font Awesome make form design effortless in this code snippet.

The form uses Bootstrap’s margin classes (i.e. mb-4) to create proper spacing between elements without writing custom CSS.

Font Awesome icons (fas fa-sync-alt and fas fa-spinner) add visual polish to the submit button and loading indicator.

These libraries work together to create a professional-looking article generator interface with minimal coding effort – perfect for developers who want clean, responsive designs without extensive CSS knowledge.

From there if we need to add custom CSS, we can.

The Power of Chain Prompting

The most fascinating aspect of this project was implementing “chain prompting” – a technique where multiple AI operations are strung together sequentially, with each step building upon the previous one. This approach dramatically improves output quality compared to generating an entire article in a single prompt.

Chain prompting proves effective by decomposing complex tasks into specialized sub-tasks that allow each step to concentrate exclusively on its specific area of expertise. This creates a powerful refinement pipeline where outputs from one prompt are fed as the input to the next prompt, effectively creating a progressive enhancement process at each stage.

The approach leverages the unique strengths of different AI models, combining their capabilities to deliver superior results than any single model or prompt could achieve alone.

Here’s how the chain prompting logic works in the article generator:

try {
    // Step 1: Generate outlines from both AIs
    $prompt1 = [
        ['role' => 'system', 'content' => 'You are an expert article outliner.'],
        ['role' => 'user', 'content' => "PROMPT_1"]
    ];
    
    $outline1 = anthropicAi($prompt1); // Use Claude Sonnet model
    $outline2 = openAi($prompt1); // Use ChatGPT model
    
    // Step 2: Combine outlines
    $prompt2 = [
        ['role' => 'system', 'content' => 'You are an expert at synthesizing article outlines.'],
        ['role' => 'user', 'content' => "PROMPT_2"]
    ];
    
    $outlineCombined = openAi($prompt2); // Use ChatGPT model
    
    // Step 3: Generate SEO keywords
    $prompt3 = [
        ['role' => 'system', 'content' => 'You are an SEO expert.'],
        ['role' => 'user', 'content' => "PROMPT_3"]
    ];
    
    $keywords = anthropicAi($prompt3); // Use Claude Sonnet model
    
    // Step 4: Write article
    $prompt4 = [
        ['role' => 'system', 'content' => 'You are a professional article writer.'],
        ['role' => 'user', 'content' => "PROMPT_4"]
    ];
    
    $article = anthropicAi($prompt4); // Use Claude Sonnet model
    
    // Return final article
    echo json_encode(['article' => $article]);
    exit;

} catch (Exception $e) {
    http_response_code(500);
    echo json_encode(['error' => 'Error generating article: ' . $e->getMessage()]);
    exit;
}

Notice how each output from previous steps becomes input for this final prompt. The AI isn’t starting from scratch – it’s building upon layers of previous work.

System prompts are foundational to unlocking the full potential of large language models, acting as invisible instruction sets that guide the AI behavior throughout conversations. They establish the AI’s role, expertise, and operational parameters.

In a small app like this article generator, extensive system prompts will create guardrails that ensure consistency and quality across every output stage—from outlining and keyword research to final composition.

While the simplified example code above shows basic system prompts like “You are an expert article outliner,” to get the most out of your AI models, you want to employ elaborate prompts with detailed guidelines for tone, formatting, and expert knowledge.

Some system prompts can be as long as 1,000 words. In effect, you are molding the perfect assistant for one specific task.

This behind-the-scenes engineering explains why the same question to different AI implementations produces vastly different results, as the system prompt essentially programs the AI’s personality and capabilities for each task.

Combining well-written system prompts with chain prompting produces dramatically better results than asking for an entire article in one step.

It’s like the difference between having four specialists collaborate on a project versus asking one generalist to handle everything.

The error handling wraps the entire process, ensuring any failures in the chain are gracefully reported back to the user – an essential consideration when working with multiple API calls that could each potentially fail.

Troubleshooting Issues

When working with AI-generated code, you’ll typically receive functional code that works 90% of the time. However, being a first version, it often lacks logistical elements like proper logging and error checking that make future debugging easier.

For example, the first code it gave me included a function logApi() which existed in my example code that I provided in my prompt from a previously created workout planner form (generate_plan.php).

However, the AI didn’t place this function anywhere to be used.

I had to ask a follow-up question about where to place this function call within the generated code, and I also requested that each AI response be saved in a text file so I could easily reference specific steps like the outline or brainstorming later.

tell me where to add logApi within generate_article.php. I want to log each prompt and response exactly like I did in generate_plan.php. Only tell me where to add the logApi function calls, do not give me full code.

You’ll notice patterns in how AI occasionally omits certain parts of code.

For instance, I encountered a recurring issue with my wrapper files for OpenAI and Anthropic. I used PHP echo statements to log details of each step to an API log file, but this caused errors when running the code from the browser because it was interpreting these log statements as part of the AI response and breaking the “handshake” code between the frontend JS and backend PHP.

The solution was to implement the PHP ob_get_clean() function, which effectively clears these extra log statements and returns only the pure AI response.

can you then implement the same error checking and validation before echo'ing the response back via JSON. I specifically need generate_article.php to implement the ob_get_clean() section of the code to clear the buffer since the wrapper files echo other things. include the JSON_THROW_ON_ERROR, too. Do not give me any of the function code, just provide this additional code that you omitted.

The nice thing is that since I encountered this error before, the prompt above was hyper-specific instead of something vague like, “Not working, no idea what’s going on.”

I also encountered authentication issues where the system was retrying hundreds of times rather than gracefully quitting. When testing the original code, I discovered that I needed to build in more validation around these errors as they occurred. This prompted me to request error checking that would terminate the script if authentication failed on any of the API function calls.

I'm realizing that it's working but there is no refresh icon indicating that it's running. Include an icon in the button text to the left of the wording with a font awesome spinning refresh icon. I'm also receiving an authentication error. For instance here's what I see in api.log:

Array
(
    [error_type] => authentication_error
    [error_message] => x-api-key header is required
)

It looks like it retried hundreds of times, so please build in some type of error checking to just quit the script if authentication fails on any of the API function calls.

This prompt led the AI to create a function handleApiError() which was supposed to quit the app if it encounters this authentication error.

// Add this function near the top with other function definitions
function handleApiError($response) {
    if (is_array($response) && isset($response['error_type'])) {
        if ($response['error_type'] === 'authentication_error') {
            http_response_code(401);
            echo json_encode([
                'error' => 'API Authentication failed. Please check API credentials.',
                'details' => $response['error_message'] ?? 'Unknown authentication error'
            ]);
            exit;
        }
    }
    return $response;
}

However that didn’t work!

I had to go back and forth for about 10 minutes trying to spot where the issue was actually occurring, and it turned out to be within my wrapper file, anthropic.php.

Here were some of my prompts:

This is giving me authorization errors. I tried to fix this by exiting the script upon ONE single authentication error but it's still trying far too many times. This is what's appearing on the console log after the script runs for several minutes (it should quit immediately after the first anthropicAi() if the authentication doesn't work). I also don't understand why the authentication isn't working. I'm setting environment variables in my .htaccess file and using the getenv() in PHP. this works perfectly using the exact same openai.php and anthropic.php files on another project, hosted on the same server just with a different domain. The only difference is one project is on the root domain and the other is in a subfolder. Please fix these problems or give me ideas for what's going on if you are unsure of a solution. Only provide the changed code, no unchanged working code.
why are you convinced it's the JS? I think it's PHP.
this is the error in my api.log. use your smartness and figure it out:

API Error (HTTP 401): authentication_error - x-api-key header is requiredFull response: Array
(
    [type] => error
    [error] => Array
        (
            [type] => authentication_error
            [message] => x-api-key header is required
        )

)
this makes sense, but what i still don't understand is why maxRetries is set to 3 yet I'm getting 500+ errors in my api.log. am i misunderstanding that use?
when are errors passed along via httpcode 200 and when it that httpcode different. im so confused.

Handling such issues is the typical life of a software developer, and it doesn’t come without frustration.

But now you have the ultimate assistant to help you.

Over time, you build your own infrastructure of code and functions to address the various scenarios you encounter. You also want to use these issues as an opportunity to elaborate on your system prompts to avoid it responding similarly with less than ideal answers in the future.

With AI assistance, you can now simply copy and paste error messages and your codebase into a chat, and it will solve the problem 80% of the time. For the remaining 20%, you’ll need to engage in follow-up conversations to diagnose and resolve the issue.

Also remember that AI is only creating a first pass on the user interface, so you’ll likely need to provide more detailed instructions to achieve your desired appearance. For instance, I had to follow up specifically to get the correct spinner icon which visually indicates that the backend processing is working after pressing the button.

You don’t need to be a coding expert, but when you obtain working code examples based on ideas you clearly articulate, you’ll learn code much faster.

Once you grasp the fundamentals, you can ask more technical questions about function names, variables, and the general jargon surrounding programming, producing even higher-quality AI responses.

The Age of AI-Accelerated Development

What’s most remarkable about this project is how quickly it came together. Traditional development would have required:

  • Days of planning the article generation logic.
  • Extensive testing of different prompt strategies.
  • Complex error handling for multiple API endpoints.
  • Custom UI design and implementation.

By leveraging AI throughout the development process, I was able to compress this timeline dramatically.

The AI not only powers the article generator tool itself but also assisted in developing the code, troubleshooting issues, and refining the implementation.

Key Takeaways

  • API Integration Complexity: Working with multiple AI APIs requires careful error handling and retry logic.
  • Prompt Engineering Matters: The quality of results depends heavily on how prompts are structured.
  • Multi-Step Processes Work Better: Breaking complex tasks into sequential steps produces better results.
  • Error Handling Is Critical: Especially when dealing with rate-limited external services.
  • User Experience Simplicity: A focused, single-purpose tool is often more valuable than a complex multi-feature application.

Try the Free Article Generator

The AI Article Generator showcases how modern development can leverage artificial intelligence not just as a feature but as the core functionality of an application.

See the article generator in action! 👇

Try the free version to generate basic articles, or purchase the source code to run the more powerful version on your own server without limitations and the ability to customize however you’d like.

Categories

×