Key Takeaways
WordPress 7.0 introduces the standardized AI Client API, eliminating vendor lock-in by routing prompts through `wp_ai_client_prompt()` instead of coupling blocks to specific provider SDKs.
The architecture separates deterministic core functions from generative AI, using the Interactivity API and WordPress 6.9 Abilities API to handle block states, analytics, and UI logic reliably.
Tutorial-aware context improves relevance by feeding surrounding lesson content into the model, shifting the assistant from generic code explanations to targeted educational guidance.
Pre-generating content during authoring reduces unnecessary API calls, cutting token consumption and improving page speed by using AI to draft explanations and quizzes before publication.
Robust security safeguards prevent misuse of public-facing AI endpoints by enforcing server-side input validation, published article verification, rate limits, and relevance checks.
Review the Interactivity API documentation to start building interactive block components.
Explore how the AI connectors and Interactivity API in WordPress transform static code snippets into interactive, inline learning tools for site visitors.
As a Developer Advocate, part of my work involves experimenting, testing, and building. In the latest phase of our team’s Developer Relations Experimentation (DRX) initiative, I set out to explore the intersection of WordPress®1 and AI.
As a former educator, I know firsthand how critical accessible learning materials are and how technical tutorials routinely lose readers at the exact same friction point: a copied code snippet that breaks silently in a local setup, sending frustrated developers to external LLMs for answers.
For technical publishers, keeping developers focused through to execution directly lowers bounce rates and yields actionable engagement data, turning static articles into active learning environments.
To solve this, I set out to explore how WordPress 7.0 fundamentally changes this dynamic. Using ChatGPT as a code partner, I paired the Interactivity API with Core AI capabilities to transform a standard content block into an inline learning assistant, one that explains syntax, answers questions, and keeps execution directly on the page. While this isn’t the only way to tackle the problem, hitting early development hurdles pushed me to iterate, ultimately arriving at a far more robust solution than I originally envisioned.
AI as a WordPress capability
WordPress 7.0 introduced the AI Client, giving developers a standardized Core API for generative AI that eliminates vendor lock-in. Instead of coupling custom blocks to a specific provider’s SDK, interactions begin with wp_ai_client_prompt(), which returns a WP_AI_Client_Prompt_Builder:
$result = wp_ai_client_prompt( $prompt )->generate_text();
The generate_text() method requests a textual response from whichever model is configured at the site level (with parallel methods like generate_image() handling other modalities). By serving as a clean abstraction layer, the AI Client allows your block to focus purely on the capability it requires, leaving model selection and credentials entirely to WordPress Core.
Architecture flow:
Your Block → Prompt/Config → WordPress AI Client → Configured Provider/Model → Response → Block UI
From AI Requests to WordPress Abilities
The second foundation of this architecture arrived previously in WordPress 6.9 with the Abilities API. This provided a standardized way to register discrete capabilities with defined inputs, outputs, permissions, and execution logic.
An ability describes what WordPress can do. This distinction is critical: our features are not “AI features” by definition, but application capabilities whose execution happens to leverage the AI Client. For instance, we register intelligent-code-assistant/explain-code with explicit schema constraints and permission callbacks, which then delegates the generative work to the AI Client.
End-to-end execution flow:
Reader → Interactivity API → Block UI → Explain Code Ability → Execution Callback → WP AI Client → AI Model → Response → Block UI
Building the Intelligent Code Assistant
A reader reviewing a complex snippet often needs a quick explanation. This first feature addresses this by allowing readers to click a single “Explain” action and view an inline breakdown directly beneath the block.
To implement this, abilities are registered using a wp_abilities_api_init hook:
add_action( 'wp_abilities_api_init', function() {
wp_register_ability(
'intelligent-code-assistant/explain-code',
array(
'label' => __( 'Explain Code', 'textdomain' ),
'description' => __( 'Generates a concise breakdown of a code snippet.', 'textdomain' ),
'category' => 'developer-tools',
'input_schema' => array( /* ... */ ),
'output_schema' => array( /* ... */ ),
'permission_callback' => '__return_true',
'execute_callback' => function( $input ) {
return wp_ai_client_prompt( $input['prompt'] )->generate_text();
},
)
);
} );
The Interactivity API connects this backend capability to the frontend and manages the button click, loading state, and the inline render without the need for a full page reload.
One AI architecture, multiple capabilities
While experimenting with this block, it became clear that the key pattern wasn’t just piling on AI features, but creating a unified architecture that could power several distinct capabilities.
export function buildAIContext(context, extras = {}) {
return {
code: context.rawCodeText || context.activeCodeText || '',
language: context.codeLanguage || 'php',
filename: context.filename || '',
title: context.title || '',
...extras
};
}
export function buildAIContext(context, extras = {}) {
return {
code: context.rawCodeText || context.activeCodeText || '',
language: context.codeLanguage || 'php',
filename: context.filename || '',
title: context.title || '',
...extras
};
}
Now, buildAIContext() constructs the baseline environment, requestAICapability() manages communication with WordPress, and individual features simply pass their specific requirements through extras.
Pre-defined intent vs. reader-defined intent
One-click features such as Explain Code and Explain Line reduce friction by anticipating common needs. The intent is pre-defined, so the reader gets immediate assistance without formulating a prompt.
More complex tutorials, however, must also support open-ended questions. In a typical external LLM workflow, a reader manually crafts the input:
I’m reading a WordPress tutorial containing this function: [paste snippet]. Why does it use wp_unslash()?
With this embedded assistant solution, the tutorial itself acts as the implicit context. Because the block already knows the code snippet, language, and scope, the reader simply asks: “Why do we use wp_unslash() here?“. The block then appends the necessary background automatically.
AI creates, deterministic code runs
The final feature I wanted to implement showcased more structured responses within a capability. We can ask the AI Client for structured data by passing a JSON schema into as_json_response() before requesting text generation:
$result = wp_ai_client_prompt( $prompt )
->as_json_response( $quiz_schema )
->generate_text();
This allowed me to include a Knowledge Check feature, providing a formative assessment opportunity and allowing readers to get instant feedback on their understanding.
Generative AI constructs the question, multiple-choice options, and explanations. However, native Interactivity API logic governs what happens when the reader selects an answer, evaluating correctness and updating UI state deterministically.
Quality over quantity
More context is not always better context. Effective contextual AI relies on deciding what the model needs to know, not simply how much data you can pass.
As the block became more capable, code context alone wasn’t enough. I wanted its responses to reflect what the reader was actually learning at that specific point, as a technically correct explanation was not necessarily the most useful explanation for someone following a tutorial.
I introduced tutorial awareness: the build context function receives the active code example together with relevant nearby tutorial content. That moves it from giving generic code explanations towards providing help grounded in the lesson.
Consider a snippet filtering active tasks:
tasks.filter(task => !task.completed);
If the surrounding text explains, “Now we’ll use array methods to let users toggle between all, pending, and completed tasks” that editorial context changes everything. By making our block tutorial-aware, the AI connects the code directly to the underlying lesson.
This elevates every capability: Explain Code grounds its breakdown in the lesson plan, Explain This Line bridges syntax with theory, and Knowledge Check tests what the reader was actually taught and whether they understand it.
AI controls, metadata generation and detected tutorial context are exposed within each individual Code Assistant block.
Rethinking the reader experience
Improving context was only half the challenge. The other was reconsidering how readers interacted with the assistant.
Initially, much of the functionality was organised around individual Code Assistant blocks. Each block exposed its own AI features, while the editor provided controls for enabling those features, generating metadata and inspecting the tutorial context associated with the snippet.
However, I wanted to avoid making every code example feel like a separate AI application embedded within the article. The solution was to introduce a unified, page-level Code Assistant interface.
The redesigned experience moves assistance into a shared interface, allowing the application to identify the active code example and provide the relevant tools without duplicating controls across the page.
Closing the content loop
Building intelligent blocks isn’t just about embedding AI into the front end. It’s about creating a workflow where WordPress and AI each handle what they do best. While reader-facing features drive engagement, those interactions also generate valuable editorial signals, and consolidate the concept identified in the introduction that articles can be turned into active learning environments.
However, I didn’t want to use AI to guess where readers might be struggling. I wanted WordPress to record what readers were actually doing first, then use AI to help interpret that evidence.
To achieve this I introduced analytics to record specific interactions with the Code Assistant.
The plugin tracks six key events:
- explain_code – When a reader requests an explanation of a code example.
- explain_line – When a reader requests an explanation of a particular line, including the line number.
- ask_question – When a reader submits a question about the code, retaining the question text as a record of their intent.
- knowledge_check – When a reader attempts a knowledge check, including information about their accuracy.
- mark_complete – When a reader marks a code example as completed.
- copy_code – When a reader copies a snippet.
These events are deterministic. WordPress records that an interaction happened, together with the associated information, without requiring AI to interpret it at the point of collection.
Once WordPress was collecting these interaction events, aggregating them into meaningful analytics unlocked a second, author-facing layer of AI. Rather than generating live responses for readers, Editorial AI evaluates aggregated usage data to help authors locate reader friction.
The analytics might reveal that:
- A specific line triggers a spike in explanation requests.
- Readers repeatedly ask similar unscripted questions about a concept.
- Knowledge-check results show a clear pattern of incorrect attempts.
- Code is frequently copied, but rarely marked as completed.
While each signal is useful, raw data doesn’t explain why readers struggle. By feeding these metrics alongside tutorial context into the WP AI Client, Editorial AI interprets the friction and returns structured recommendations:
{
"summary": "...",
"frictionPoints": [],
"recommendations": [],
"suggestedFaqs": []
}
Rather than making automated editorial changes, the model acts as an advisor. The author reviews the AI’s diagnostic suggestions against raw metrics, retaining full control over how to refine the tutorial.
The editorial feedback loop
This established a continuous process for improving technical content:
- Author creates tutorial: WordPress stores the post and code examples.
- Reader interacts: Readers request explanations, ask questions, and complete quizzes.
- WordPress records signals: The plugin logs deterministic, ground-truth interactions.
- Analytics aggregate: Interaction events compile into actionable author reports.
- AI interprets evidence: Editorial AI suggests specific friction points and revisions.
- Author refines content: The author applies editorial updates based on evidence.
A new architectural challenge
Introducing analytics gave me a new perspective on the block’s architecture.
Until this point, identifying an individual block within an article had been sufficient for delivering the reader experience. But once I started recording interactions, I needed to consider what those events actually belonged to.
If the same code example appeared in several tutorials, should its interactions be treated as entirely separate, or should I be able to recognise that they are related to the same underlying snippet?
That question exposed a limitation in the way the plugin identified its code examples.
From block instances to canonical code entities
Tracking events revealed a structural limitation: isolated block IDs (blockId) treated identical code snippets across different tutorials as unrelated instances. To make analytics semantically meaningful, we introduced a codeExampleId backed by a dedicated Custom Post Type (CPT).
Decoupling code into a canonical CPT ensures a single source of truth for code, language, and settings across multiple articles. More importantly, it gives the AI complete contextual awareness:
- What snippet is this? (Canonical identity and language)
- Where is it used? (Tutorial scope and surrounding teaching goals)
- How are readers performing? (Aggregated interaction and completion data)
The same article level analytics could now be applied to individual code snippets.
The final piece of the puzzle was giving authors the exact same Code Assistant experience inside the Block Editor that they get from the admin dashboard. Reusable content should be created right at the point of need, even when its source entity lives elsewhere.
Allowing authors to create and edit Code Snippet post types directly inline, eliminates context-switching. Managing both the article copy and the underlying code entity within a single editing flow seamlessly ties the entire architecture together.
Problems
Having reached a point in development where I thought the block was complete, it became increasingly clear that there were some additional improvements that could be made. On the surface, the block was doing everything I wanted it to do: providing readers with tools to understand what they were learning and, ultimately, encouraging them to stay on the page. However, there were two particularly important issues that I wanted to address.
Using AI to add value
The majority of the reader-facing features are fundamentally similar: they provide predictable output. Explain This Code, Explain This Line and Knowledge Check all provide information that can be generated from content already known to the author. Ask About This Code, however, responds to an unpredictable question introduced by the reader.
This made me consider whether I was using WordPress’ AI capabilities in the most appropriate way. It wasn’t a question of whether AI should be used for these features, but rather when it should be used.
Ask About This Code requires a live AI request because the reader can ask something that wasn’t anticipated during authoring. The other features, however, can be generated from the existing code and tutorial content. Why not generate those responses when the author creates the article, rather than every time a reader interacts with the block?
This provides several advantages:
- Fewer AI requests and reduced token consumption.
- Faster reader interactions.
- Less reliance on publicly accessible AI endpoints.
- Better reliability if the AI provider or connector becomes unavailable.
- Consistent explanations for every reader, with editorial control over the generated teaching content.
Implementing this architecture led me to an important principle:
Use AI at the point where it adds value, rather than making every interaction an AI request.
I now had three distinct uses for AI:
- Authoring AI: Generates code explanations, line-by-line explanations and knowledge checks while the content is being created. The author can review and edit these before publication.
- Reader AI: Powers Ask About This Code, where the reader introduces a question that could not necessarily have been anticipated.
- Editorial AI: Powers Reader and Code Snippet Insights, interpreting collected analytics to help the author understand reader behaviour.
Security
The architectural changes also highlighted another concern: How do I prevent readers from misusing the public-facing AI functionality?
Ask About This Code is different from the other features because it accepts an unpredictable question from the reader. Although the intention is to help someone understand a particular code example, there is nothing inherently stopping them from entering an unrelated question, such as “Write me a poem” or “Give me a recipe for brownies.”
This creates two potential problems:
- Unrelated questions could consume the site’s AI allowance without providing any educational value.
- The feature could effectively become a general-purpose AI chatbot rather than a focused learning tool.
I wanted to retain the flexibility of allowing readers to ask their own questions without leaving the article, but I also needed to introduce safeguards to control how the functionality could be used.
Safeguards implemented
Rather than relying on a single restriction, I introduced several layers of protection, each addressing a different aspect of the problem.
1. Server-side input validation
The first safeguard validates the request before it reaches the AI provider.
The plugin rejects empty questions and enforces a maximum question length of 1,000 characters. This prevents unnecessarily large questions from being submitted and places an initial boundary around the amount of user-generated text accepted by the feature.
Although this does not determine whether a question is relevant, it prevents certain invalid requests from consuming AI credits.
2. Published article and code verification
The next safeguard ensures that questions are associated with genuine content published on the website.
When WordPress renders an Intelligent Code Assistant block, the plugin includes the current article’s post ID in its context. When a reader submits a question, this ID is sent to the server alongside the code and question.
The server then verifies that:
- The article exists and is published.
- The article’s post type is publicly viewable.
- The submitted code matches a Code Assistant block associated with that article.
- Where the block references a separate Code Example, the linked record is also published.
This prevents someone from simply submitting arbitrary code to the public endpoint and using the site’s AI connection to ask questions about it.
Importantly, the server does not trust the article ID or code supplied by the browser without checking it against the content stored in WordPress.
These checks are applied before the public request reaches the AI provider.
3. Request limits
Even with article verification in place, someone could repeatedly ask questions about legitimate published code. To reduce this risk, I introduced configurable request limits.
The current default limits are:
- 10 requests per visitor per hour.
- 250 requests across the entire website per day.
Once either limit is reached, further requests are rejected before reaching the AI provider. The counters are updated using a database lock, helping prevent simultaneous requests from bypassing the limits.
These restrictions help control usage, but they are not an absolute guarantee against abuse. For example, a visitor could potentially use different IP addresses to avoid an individual limit, and the number of tokens consumed can vary between requests.
Nevertheless, the site-wide limit provides an additional boundary that applies regardless of which visitor submits the questions.
4. AI relevance validation
The final safeguard addresses the content of the question itself. Even when a request comes from a genuine article and falls within the permitted limits, the question might have nothing to do with the code being studied. To address this, I introduced a relevance check within the AI capability.
The AI is instructed to act as a narrowly scoped code-learning assistant. It should only answer questions relating to the supplied code, programming concepts needed to understand that code, or the surrounding tutorial.
Rather than returning unrestricted text, the AI is asked to produce a structured response containing a relevance flag and an answer.
For example, an unrelated question should produce a response equivalent to:
{
"relevant": false,
"answer": ""
}
A relevant question should produce:
{
"relevant": true,
"answer": "An explanation relating to the supplied code."
}
This checks the relevance flag before returning the answer to the reader. If the AI identifies the question as unrelated, the reader receives a controlled message:
This assistant can only answer questions about this code example or the surrounding tutorial.
This helps keep the assistant focused on its intended educational purpose rather than allowing it to operate as a general-purpose chatbot. However, there is an important limitation. The relevance check is performed by the AI itself, meaning the request has already reached the provider and may have consumed tokens, even when the question is rejected.
The classification is also dependent on the model’s response, so it cannot guarantee that every unrelated question will be rejected. This is where the other safeguards become particularly important. Article verification and request limits restrict what can reach the AI, while relevance validation controls what the assistant is intended to return.
Further safeguards to consider
Although these measures provide several layers of protection, I recognise that no public-facing, open-ended AI feature can be guaranteed to be completely immune to misuse.
There are additional improvements I could introduce to strengthen the implementation further:
Caching previously answered questions
One potential improvement is to cache questions and their answers. If several readers ask the same question about the same code example, the plugin could return the previously generated answer rather than making another AI request.
For example, if ten readers ask “What does this function return?”, the first request could generate the explanation, while subsequent identical requests retrieve the stored response.
This could reduce token consumption, improve response times and make the feature less dependent on the availability of the AI provider.
The limitation is that caching is most effective for repeated questions. Slightly different wording could still trigger separate AI requests. Cached responses would also need to be invalidated when the underlying code or tutorial changes.
Pre-AI misuse detection
Another possibility is to introduce a lightweight relevance filter before contacting the AI provider. For example, the server could identify certain obvious prompt-injection attempts, repetitive submissions or known patterns of unrelated questions. This could reject some requests without consuming AI credits.
However, the difficulty is distinguishing genuinely unrelated questions from legitimate programming questions.
A reader might ask about building a recipe application or implementing a shopping basket. Rejecting every question containing words such as “recipe” or “shopping” would incorrectly block valid learning opportunities. Any preliminary filter would therefore need to be conservative. It could reduce obvious misuse, but it would not replace the AI relevance check.
Provider-level spending limits
The existing request limits restrict how frequently the public functionality can be used, but they do not guarantee a fixed financial cost.
Different questions can consume different numbers of tokens, and AI providers may charge different amounts depending on the model being used.
A further safeguard would be to configure a hard spending limit with the AI provider, where supported.
This would provide a financial backstop independently of the plugin’s own request restrictions.
The trade-off is that once the provider limit is reached, live AI questions would become unavailable until the allowance is restored. The pre-generated explanations and knowledge checks, however, could continue functioning without additional AI requests.
Per-article control over live AI
I could also introduce an option allowing authors to disable Ask About This Code for individual articles.
This would be particularly useful for articles where live questions are unlikely to add significant value, or where the author wants to restrict AI usage.
The pre-generated explanations, line-by-line guidance and knowledge checks could remain available even when live AI questions are disabled.
This would give authors greater control over where AI credits are spent without removing the other educational features.
Finding the balance
The objective was never to eliminate every possible misuse scenario. With an anonymous, open-ended question feature, that would be difficult to guarantee without fundamentally changing how it works. Instead, I wanted to establish a sensible balance between accessibility, educational value, security and cost.
The safeguards already implemented provide several layers of protection: validating requests, verifying published content, limiting usage and restricting the scope of AI-generated answers. The additional measures could further reduce unnecessary requests, improve performance and give site owners greater control over their AI expenditure.
The underlying principle is the same one that guided the architectural changes: AI should be used deliberately, with appropriate controls around when it is invoked and what it is permitted to do.
Conclusion: Reimagining intelligent site operations
This project started with a simple question: How can AI make technical content genuinely more useful to the reader?
What began as a way to explain code snippets evolved into a comprehensive framework—spanning granular breakdowns, open-ended questions, tutorial-aware assistance, and AI-driven editorial analytics. Yet the most valuable lesson came from looking beyond what AI can generate and focusing on how it should integrate into the application architecture.
Throughout development, one principle proved paramount: AI shouldn’t replace core WordPress functionality; it becomes transformative when working alongside it.
WordPress excels at what it has always done best:
- Structuring & owning content and its surrounding context.
- Recording deterministic reader interactions and managing canonical assets.
- Aggregating analytics that authors can evaluate independently.
Generative AI is then introduced only where it adds distinct value:
- Generating contextual explanations and quizzes during the authoring phase.
- Answering unpredictable, live reader questions inline.
- Interpreting aggregate friction patterns to recommend editorial refinements.
Moving static explanations into the authoring workflow drastically reduced unnecessary API requests, boosted site responsiveness, and gave authors total editorial governance over educational content. Live AI was preserved for its true purpose: handling dynamic queries that couldn’t be anticipated during drafting.
The content improvement loop
- Author creates structured content: WordPress manages the article and canonical code entities. AI assists with explanations and quizzes, which authors review prior to publication.
- Reader engages: Users interact with pre-generated learning tools and ask inline questions as needed.
- WordPress records interactions: Core tracks deterministic signals without relying on LLMs to interpret every raw event in real time.
- Analytics reveal patterns: Authors examine aggregate interaction metrics to pinpoint drop-off points.
- AI interprets friction: Editorial AI provides structured insights, highlighting friction points and suggesting revisions.
- Author Refines Content: Authors apply data-backed updates, continuously elevating tutorial quality.
Ultimately, meaningful AI integration isn’t about making every feature AI-powered. It’s about combining WordPress’s native strengths with its new Core AI APIs—using appropriate security safeguards to build richer, execution-ready learning environments. The real innovation isn’t just that WordPress can use AI. It’s knowing when it should.
- WP Engine is a proud member and supporter of the community of WordPress® users. The WordPress® trademarks are the intellectual property of the WordPress Foundation, and the Woo® and WooCommerce® trademarks are the intellectual property of WooCommerce, Inc. Uses of the WordPress®, Woo®, and WooCommerce® names in this website are for identification purposes only and do not imply an endorsement by WordPress Foundation or WooCommerce, Inc. WP Engine is not endorsed or owned by, or affiliated with, the WordPress Foundation or WooCommerce, Inc. ↩︎


