Last month a client came to us wanting to build AI deeply into their high-traffic WordPress site. They had already tried a few off-the-shelf AI plugins. Those were fine for a quick proof of concept, but the client hit a wall on custom models, scaling, and staying compatible with their existing tech stack. A classic case of quick fix now, big headache later. The core problem was not the AI itself, it was the underlying WordPress AI architecture.
My first thought, I will admit, was to extend one of those existing plugins. For about five minutes it looked like that might work. But once we dug into the details, custom data pipelines, their own training models, real error handling, it became clear. A generic plugin was going to turn into a spaghetti code monster. We needed a foundation, not another band-aid.
Core WordPress developers are debating this too. The Core AI meeting summary from August 21st, 2025 covers it (full notes are at make.wordpress.org/ai). One thread was about MCP Adapter Distribution, and the question was whether it should ship as a canonical plugin or a Composer library. That is the exact architectural crossroads many developers hit with WordPress AI integration.
When you are building something other components will depend on, a Composer library has real advantages: proper dependency management, versioning, and cleaner separation of concerns. A canonical plugin looks simpler to distribute, but it tends toward tightly coupled dependencies that make later updates or extensions painful. Avoiding technical debt upfront is almost always cheaper than refactoring later.
Building a solid WordPress AI architecture
Distribution is one question; responsible AI is another. The documentation team proposed a “Responsible AI workflow for creating new documentation for WordPress 6.9.” The goal was to teach AI the “language of WordPress,” telling apart WP.com, WP.org, and the software itself. That goes beyond code. It means systems that understand context, and that needs a solid, extensible architecture.
So what does this look like in practice? Instead of dumping everything into one plugin, keep core AI services as independent Composer packages and wire them in with WordPress hooks. Here is a small example that hooks into an AI service to process content while staying extendable and manageable:
<?php
/**
* Plugin Name: Bbioon AI Content Processor
* Description: Integrates a modular AI content processing service.
* Version: 1.0.0
* Author: Ahmad Wael
* Text Domain: bbioon-ai-content
*/
// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
die;
}
/**
* Main class for the Bbioon AI Content Processor.
*/
class Bbioon_AI_Content_Processor {
public function __construct() {
add_filter( 'bbioon_preprocess_content_for_ai', [ $this, 'bbioon_run_ai_processing' ], 10, 2 );
add_action( 'save_post', [ $this, 'bbioon_trigger_ai_on_post_save' ], 10, 3 );
}
/**
* Placeholder for running actual AI processing.
*
* @param string $content The content to process.
* @param int $post_id The ID of the post.
* @return string The processed content.
*/
public function bbioon_run_ai_processing( $content, $post_id ) {
// In a real scenario, this would interact with an AI service,
// likely loaded via Composer and configured.
if ( apply_filters( 'bbioon_should_process_ai_for_post', true, $post_id ) ) {
// Example: Append a small AI-generated summary.
$ai_summary = Bbioon_AI_Service_Adapter::get_instance()->summarize( $content );
return $content . '<!-- AI Summary -->' . $ai_summary;
}
return $content;
}
/**
* Triggers AI processing when a post is saved.
*
* @param int $post_id The post ID.
* @param WP_Post $post The post object.
* @param bool $update Whether this is an update or a new post.
*/
public function bbioon_trigger_ai_on_post_save( $post_id, $post, $update ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
if ( 'post' !== $post->post_type && 'page' !== $post->post_type ) {
return;
}
$processed_content = apply_filters( 'bbioon_preprocess_content_for_ai', $post->post_content, $post_id );
// Update post with AI-processed content if different.
if ( $processed_content !== $post->post_content ) {
remove_action( 'save_post', [ $this, 'bbioon_trigger_ai_on_post_save' ] ); // Prevent infinite loop.
wp_update_post( [
'ID' => $post_id,
'post_content' => $processed_content,
] );
add_action( 'save_post', [ $this, 'bbioon_trigger_ai_on_post_save' ], 10, 3 ); // Re-add action.
}
}
}
new Bbioon_AI_Content_Processor();
The example uses a hook (bbioon_preprocess_content_for_ai) and an action (save_post) to inject AI processing cleanly. The AI service itself (say, Bbioon_AI_Service_Adapter) would be a Composer-managed library, so your core plugin stays lean and handles integration rather than implementation. That is where the flexibility comes from: you can swap AI models, update libraries, or extend features without tearing the whole site apart. You are building for stability and scalability from day one.
Choosing an architecture that lasts
The lesson is simple. Whether it is a new AI feature or any large integration, rushing the architecture decision bites you later. For foundational pieces like a Core AI adapter, the canonical plugin versus Composer library debate is not academic. It sets the maintainability, performance, and future flexibility of your whole WordPress build. Deciding carefully upfront saves you costly headaches later.
This stuff gets complicated fast. If you are tired of debugging someone else’s mess and just want your site to work, drop my team a line. We have probably seen it before.