社区新闻

如何用 WordPress AI 客户端构建图片生成插件

WordPress 7.0 内置 AI 客户端:一个 PHP API,允许插件向 AI 服务提供者发送提示并接收结果。还有什么比用它构建真实的API更好的方式来理解这个新API的工作方式呢?在本文中,你将学习如何使用AI客户端,通过构建一个插件直接在媒体库中生成图像。

插件设计得很小。它可以向AI提供商发送文本提示,接收生成的图片,然后你可以将其保存到WordPress媒体库中。在此过程中,你会看到使 AI 驱动功能在 WordPress 中可靠运行的模式——所有这些都依赖于全新的内置 AI 客户端。

AI客户端的工作原理

提供者与模式无关性

WordPress AI 客户端背后最重要的理念是,你的插件绝不会直接与 AI 提供商通信。你描述你需要什么——文本、图片、特定的输出格式——以及你需要它的方式——图片的宽高比、文本生成的温度等等。基于这些信息,WordPress会将请求路由到网站所有者配置的供应商的合适型号。

这与以下几个原因相关:

  • 网站所有者保持控制权。他们选择自己的提供商(Anthropic、Google、OpenAI 或其他任何支持的服务),并通过设置>连接器界面管理 API 密钥——这是一个用于管理服务连接的集中管理界面。你的插件不需要自己的API凭证设置页面。
  • 插件是可移植的。一个插件能和一个供应商合作,就适用于所有供应商。没有专门针对提供者的代码路径需要维护。
  • 生态系统会扩展。随着新供应商和新型号的推出,现有插件会自动获得支持——无需插件更新。

这意味着你绝不应该编写假设某个特定供应商或模型的代码。相反,你描述了你的需求,AI客户端会找到合适的匹配。

切入点:wp_ai_client_prompt()

每次与 AI 客户端的交互都从一个函数调用开始:

$builder = wp_ai_client_prompt();

这返回了一个WP_AI_Client_Prompt_Builder实例——一个流畅构建器,遵循WordPress命名规范(snake_case方法),同时包裹底层的php-ai-client库。

然后,你用方法来描述你的提示词。例如,生成文本:

$builder = wp_ai_client_prompt()
    ->with_text( 'Summarize the benefits of caching in WordPress' )
    ->using_temperature( 0.7 );

with_text()提供了提示。 是控制输出随机性的可选配置参数。准备好后,调用生成方法:using_temperature()

$result = $builder->generate_text_result();

该 是$resultGenerativeAiResult对象——一个可序列化的数据传输对象,包含生成内容以及关于哪个提供者和型号处理请求的元数据。你可以直接传给rest_ensure_response()这使得通过REST API直接展示AI功能变得简单。

同样的构建模式适用于图像生成,这也是本文的重点。你将在下面的章节中看到如何配置图片构建器——包括输出文件类型、宽高比等。

模型偏好,而非需求

由于你的插件无法控制每个 WordPress 网站上可用的供应商或型号,AI 客户端采用偏好系统而非硬性要求。

你可以用一个或多个模型的笔条来指示哪些型号最适合你的使用场景。AI客户端按顺序尝试——如果第一个有,就用它;否则它会退回到下一个,依此类推。如果没有任何偏好型号可用,则会退回到支持该请求功能的任意模型。你的插件无论如何都能正常工作。using_model_preference()

$builder = wp_ai_client_prompt()
    ->with_text( 'Summarize the benefits of caching in WordPress' )
    ->using_temperature( 0.7 )
    ->using_model_preference( 'gpt-5.4', 'gemini-3.1-pro-preview', 'claude-opus-4.6' );

这只是偏好,不是强制要求。围绕特定模型构建会强制插件用户使用厂商锁定,或者阻止他们使用插件——这会违背抽象的初衷。当某个模型特别适合你的使用场景时,使用模型偏好,但设计插件时要避免它们。

支持检查:限制你的AI功能

并非每个WordPress网站都会配置AI提供商,也不是每个供应商都支持所有功能或配置选项。在向用户展示AI功能之前,先确认它是否真的能起作用。例如:

$is_available = wp_ai_client_prompt()
    ->with_text( 'test' )
    ->is_supported_for_image_generation();

is_supported_for_image_generation()只有当网站有支持图像生成的配置提供商时才会返回为真。其他功能如文本生成也有类似的方法。

此检查不进行API调用或进行任何推理。提示文本本身不会被用于支持检查。该方法采用纯确定性逻辑,将构建者的配置(请求的能力、输出选项等)与可用模型声明的能力进行匹配。打电话没有任何费用。

这个检查非常重要。用它来有条件加载你的UI,在该功能不可用时显示有用的通知,或者完全跳过注册UI项目。不要仅仅因为安装了 WordPress 7.0 就认为 AI 功能就会开放——网站所有者仍然需要设置一个服务提供商。

实现插件

该插件在媒体库中添加了“生成图像文件”按钮。点击它会打开一个对话框,用户输入文本提示。该插件将提示发送给 AI 客户端,将生成的图片作为预览显示,并允许用户将其保存为新的媒体附件。

打开“生成图片”模式的WordPress媒体库截图,显示一个带有“生成图片”按钮的提示文本输入字段,生成的骑士查理王小猎犬图片,以及一个用于上传图片到媒体库的独立界面
这是本文中插件添加的图像生成模态截图

完整源代码可在GitHub上的wptrainingteam/ai-client-imagegen获取。

注:本文中部分代码片段与插件中的代码略有删减,以便更好地聚焦最相关的更改。

前提条件

要跟进,你需要:

  • 安装并运行的是 WordPress 7.0(或更高版本)。
  • 一个配置支持图像生成的AI提供商。在WordPress管理层的>“连接器设置”里,添加OpenAI或Google AI等服务的连接。确保配置好的供应商提供一个或多个能够生成图像的模型。
  • Node.js(版本20或更高版本)用于构建前端资产。
  • 对WordPress插件开发、REST API和PHP有基本了解。

插件文件结构

该插件使用一个简单的结构:

ai-client-imagegen/
├── plugin.php
├── includes/
│   ├── prompt.php
│   ├── rest-api.php
│   └── admin.php
├── src/
│   └── index.ts
├── build/
│   ├── index.js
│   └── index.asset.php
├── package.json
└── composer.json
  • plugin.php——主入口。加载所有东西,注册钩子。
  • includes/prompt.php— 可重用函数构建AI客户端提示。
  • includes/rest-api.php— REST API 端点,用于生成图像并保存到媒体库。
  • includes/admin.php—— 媒体库界面上的剧本注册和排队。
  • src/index.ts— 前端:对话界面和API调用。
  • build/— 由WordPress/脚本生成的编译JavaScript输出。

主插件文件

档案非常简约。它声明插件头部,对 AI 客户端是否可用进行门控,加载包含文件,并注册钩子:plugin.php

<?php
/**
 * Plugin Name: AI Client ImageGen
 * Plugin URI: https://github.com/wptrainingteam/ai-client-imagegen
 * Description: Generates images in the WordPress Media Library using the built-in AI Client.
 * Requires at least: 7.0
 * Requires PHP: 7.4
 * Version: 1.0.0
 * Author: Your Name
 * License: GPL-2.0-or-later
 * Text Domain: ai-client-imagegen
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

if ( ! function_exists( 'wp_ai_client_prompt' ) ) {
    return;
}

require_once __DIR__ . '/includes/prompt.php';
require_once __DIR__ . '/includes/rest-api.php';
require_once __DIR__ . '/includes/admin.php';

add_action( 'rest_api_init', 'aicig_register_rest_routes' );
add_action( 'init', 'aicig_register_assets' );
add_action( 'admin_enqueue_scripts', 'aicig_enqueue_media_assets' );

在插件头部设置可以确保WordPress在旧版本中不会激活该插件。该检查作为运行时的安全网——如果 AI 客户端功能因任何原因不可用,插件会提前退出。Requires at least: 7.0function_exists( 'wp_ai_client_prompt' )

这三个调用连接了REST API路由、资产注册和条件脚本队列。每个回调都定义在自己的文件中。add_action()

构建提示词

这是AI客户端集成的核心。该文件定义了一个可复用函数,用于配置用于生成图像的提示构建器:includes/prompt.php

<?php
use WordPress\AiClient\Files\Enums\FileTypeEnum;
use WordPress\AiClient\Files\Enums\MediaOrientationEnum;

function aicig_get_image_generation_prompt( string $prompt, string $orientation = '' ): WP_AI_Client_Prompt_Builder {
    $builder = wp_ai_client_prompt()
        ->with_text( $prompt )
        ->as_output_file_type( FileTypeEnum::inline() );

    if ( $orientation ) {
        $builder->as_output_media_orientation( MediaOrientationEnum::from( $orientation ) );
    }

    return $builder;
}

有几点需要注意:

  • 函数返回的是构建者,而不是结果。这是一个刻意的设计选择。调用者决定何时执行提示符(通过 ),并可添加更多配置。它还让构建器可用于支持检查——同样的功能被用来调用 ,正如你在后面管理集成中会看到的。generate_image_result()is_supported_for_image_generation()
  • FileTypeEnum::inline()在响应中请求 base64 编码的图像数据。这对于需要在浏览器中显示图片再保存的插件来说非常方便。
  • MediaOrientationEnum是可选的。如果提供,则提示所需的宽高比 — , , 或 。该方法将字符串转换为枚举值。squarelandscapeportraitMediaOrientationEnum::from()
  • 没有具体说明提供者或型号。AI客户端负责路由。提示描述了所需的内容;WordPress决定如何实现它。该功能适用于任何支持图像生成的服务商。

将提示配置包装成独立函数可以保持其可重复使用性。REST API 调用它生成图像,管理代码调用它来检查是否支持图像生成。

The REST API

该插件在命名空间下暴露了两个 REST 端点:一个用于生成图像,另一个用于上传生成图像到媒体库。或者,单一端点可以生成图像并一次性保存到媒体库。不过,用户理想情况下应该在承诺前先审查生成的图片,因此将两者分开处理更合理。ai-client-imagegen/v1

生成图像

生成路径需要文本和可选的 。其回调可以在文件中定义,使用可重用的提示函数,调用 ,并直接返回结果:promptorientationincludes/rest-api.phpincludes/prompt.phpgenerate_image_result()

function aicig_register_rest_routes(): void {
    register_rest_route(
        'ai-client-imagegen/v1',
        '/generate-image',
        array(
            'methods'             => WP_REST_Server::CREATABLE,
            'callback'            => 'aicig_rest_generate_image',
            'permission_callback' => static function () {
                return current_user_can( 'upload_files' );
            },
            'args'                => array(
                'prompt'      => array(
                    'type'     => 'string',
                    'required' => true,
                ),
                'orientation' => array(
                    'type'     => 'string',
                    'required' => false,
                    'enum'     => array( 'square', 'landscape', 'portrait' ),
                ),
            ),
        )
    );
}

function aicig_rest_generate_image( WP_REST_Request $request ) {
    $prompt      = $request->get_param( 'prompt' );
    $orientation = $request->get_param( 'orientation' );

    $builder = aicig_get_image_generation_prompt(
        $prompt,
        $orientation ?? ''
    );

    return rest_ensure_response(
        $builder->generate_image_result()
    );
}

因为返回的对象是可序列化的,直接转换成 JSON 响应。响应包括生成的图像数据,以及关于哪个提供者和模型处理请求的元数据——前端可以显示为归因信息。GenerativeAiResultgenerate_image_result()rest_ensure_response()

同样,如果在此过程中发生错误,返回一个 ,也可以直接作为 REST 响应处理——无需条件处理。generate_image_result()WP_Error

上传至媒体库

一旦用户对生成的图像满意,前端就会将其发送到第二个端点。该路由获取base64编码的图像数据、文件名和MIME类型。回调解码数据,写入磁盘,并创建 WordPress 附件:

function aicig_register_rest_routes(): void {
    // Other REST route registration for generating an image.
    register_rest_route(
        'ai-client-imagegen/v1',
        '/upload-image',
        array(
            'methods'             => WP_REST_Server::CREATABLE,
            'callback'            => 'aicig_rest_upload_image',
            'permission_callback' => static function () {
                return current_user_can( 'upload_files' );
            },
            'args'                => array(
                'image_base64' => array(
                    'type'     => 'string',
                    'required' => true,
                ),
                'file_name'    => array(
                    'type'              => 'string',
                    'required'          => true,
                    'sanitize_callback' => 'sanitize_file_name',
                ),
                'mime_type'    => array(
                    'type'              => 'string',
                    'required'          => false,
                    'default'           => 'image/png',
                    'sanitize_callback' => 'sanitize_mime_type',
                ),

            ),
        )
    );
}

function aicig_rest_upload_image( WP_REST_Request $request ) {
    $image_base64 = $request->get_param( 'image_base64' );
    $file_name    = $request->get_param( 'file_name' );
    $mime_type    = $request->get_param( 'mime_type' );

    $decoded = base64_decode( $image_base64, true );
    if ( false === $decoded ) {
        return new WP_Error(
            'invalid_image_data',
            __( 'The provided image data is not valid base64.', 'ai-client-imagegen' ),
            array( 'status' => 400 )
        );
    }

    $upload = wp_upload_bits( $file_name, null, $decoded );
    if ( ! empty( $upload['error'] ) ) {
        return new WP_Error(
            'upload_failed',
            $upload['error'],
            array( 'status' => 500 )
        );
    }

    $attachment_data = array(
        'post_mime_type' => $mime_type,
        'post_title'     => sanitize_file_name(
            pathinfo( $file_name, PATHINFO_FILENAME )
        ),
        'post_status'    => 'inherit',
    );

    $attachment_id = wp_insert_attachment(
        $attachment_data,
        $upload['file']
    );

    if ( is_wp_error( $attachment_id ) ) {
        return $attachment_id;
    }

    require_once ABSPATH . 'wp-admin/includes/image.php';

    $metadata = wp_generate_attachment_metadata(
        $attachment_id,
        $upload['file']
    );

    wp_update_attachment_metadata( $attachment_id, $metadata );

    return rest_ensure_response(
        array(
            'id'  => $attachment_id,
            'url' => wp_get_attachment_url( $attachment_id ),
        )
    );
}

这就是标准的WordPress媒体处理——写入文件、创建数据库记录,以及创建缩略图和图片元数据。这里没有任何针对人工智能的特有内容。wp_upload_bits()wp_insert_attachment()wp_generate_attachment_metadata()

到此为止,我们完成了该功能的服务器端基础。接下来我们来关注前端和用户界面。

管理集成

我们唯一需要 PHP 的前端功能是管理渲染动态界面和处理交互的脚本。该文件处理三件事:注册脚本、在媒体库界面有条件地排队,以及在不支持图像生成时显示通知。includes/admin.php

注册脚本

function aicig_register_assets(): void {
    $asset_file = plugin_dir_path( __DIR__ ) . 'build/index.asset.php';

    if ( file_exists( $asset_file ) ) {
        $asset = require $asset_file;
    } else {
        $asset = array(
            'dependencies' => array(),
            'version'      => '1.0.0',
        );
    }

    wp_register_script(
        'aicig-imagegen',
        plugins_url( 'build/index.js', __DIR__ ),
        $asset['dependencies'],
        $asset['version'],
        array( 'strategy' => 'defer' )
    );
}

该文件在构建步骤中自动生成。它声明脚本的依赖关系和基于内容的版本哈希。这是 WordPress 捆绑脚本的标准模式build/index.asset.php@wordpress/scripts

带支持检查的条件队列

为了让脚本真正加载到前端,我们还需要对它进行队列。不过,这正是我们需要先应用支持检查的地方,这样脚本只有在实际支持基于AI的功能时才会被加载:

function aicig_enqueue_media_assets( string $hook_suffix ): void {
    if ( 'upload.php' !== $hook_suffix ) {
        return;
    }

    if ( ! current_user_can( 'upload_files' ) ) {
        return;
    }

    if ( ! aicig_get_image_generation_prompt( 'test' )->is_supported_for_image_generation() ) {
        // Show an admin notice, or handle the unsupported case in another way.
        return;
    }

    wp_enqueue_script( 'aicig-imagegen' );
}

三次检定依次进行:

  1. 屏幕检查——仅在(媒体库)上运行。upload.php
  2. 能力检查——仅限能够上传文件的用户。这里使用与REST API端点相同的能力非常重要,因此我们基于相同的标准对UI进行门控。否则,你可能会渲染一些实际上无法正常工作的界面。
  3. 支持检查——呼叫提示生成器,确认配置好的供应商是否能处理图像生成。如果没有,建议提前退出——你可能想向网站所有者展示一个指向连接器设置的通知。is_supported_for_image_generation()

注意这里重复使用了相同的函数。通过“test”作为提示文本就足够了——该方法只检查提供者和模型的能力,而非提示内容。这也是为什么我们没有让它返回提示结果,这样它也可以用来检查支持。aicig_get_image_generation_prompt()includes/prompt.php

只有当这三种条件都通过时,脚本才会被列入队列。这意味着“生成图片文件”按钮只有在实际生效时才会出现。

前端

前端TypeScript文件包含~590行原版DOM操作。它创建模态对话框,通过 处理表单提交,显示生成的图片预览并显示提供者/模型归属,并处理保存到媒体库。@wordpress/api-fetch

详细解释这段代码超出本文的目的。这些都是很标准的原版JavaScript功能,如果你感兴趣,建议你单独学习。所以这里不用详细讲前端代码,你可以直接从GitHub仓库复制下来:把代码放到你的本地文件里。一旦构建完成,它会显示为 ,即我们在 PHP 中注册的相同脚本路径。src/index.tssrc/index.tsbuild/index.js

关于客户端代码的简要说明:代码使用原版JavaScript(也就是TypeScript编译成JavaScript),除了和之外没有框架依赖。这是一个刻意的选择——对于一个自成一体的对话来说,原版DOM操作轻量且性能优良。现代编码代理在编写这种直接命令式UI代码方面也特别擅长。对于更复杂的插件界面,使用 WordPress 自带的 React 版本可能更合适。@wordpress/api-fetch@wordpress/i18n

构建与测试

插件需要在根目录中构建前端代码并允许在捆绑的WordPress开发环境中测试插件。

注:你需要在系统里安装Node.js才能使用这些工具。要使用基于 的内置开发环境,你还需要安装 Docker。或者,也可以选择你选择的其他开发环境。@wordpress/env

首先,是一个声明构建工具和运行时依赖的package.json

{
    "name": "ai-client-imagegen",
    "private": true,
    "license": "GPL-2.0-or-later",
    "dependencies": {
        "@wordpress/api-fetch": "^7.41.0",
        "@wordpress/i18n": "^6.14.0"
    },
    "devDependencies": {
        "@wordpress/env": "^10.27.0",
        "@wordpress/scripts": "^31.0.0",
        "typescript": "^5.8.2"
    },
    "scripts": {
        "build": "wp-scripts build",
        "wp-env": "wp-env"
    }
}

第二,一个文件,这样你就可以启动一个本地的WordPress 7.0环境,插件已经激活了.wp-env.jsonwp-env:

{
    "core": "https://wordpress.org/wordpress-7.0.zip",
    "plugins": [ "." ]
}

有了这些文件,安装依赖并构建:

npm install
npm run build

运行 ,编译并生成依赖清单。PHP 端不需要构建步骤——AI 客户端是 WordPress Core 的一部分。@wordpress/scriptssrc/index.tsbuild/index.jsbuild/index.asset.php

要测试插件,启动本地环境:

npm run wp-env start

这样会启动一个基于 Docker 的 WordPress 网站(默认凭证:admin / password),插件已经激活。接着:http://localhost:8888

  1. 进入连接器>设置,配置支持图像生成的AI提供商。
  2. 前往媒体>图书馆
  3. 点击“生成图片文件”按钮,输入提示,生成图片。
  4. 当你对一张图片满意后,点击“保存到媒体库”按钮。可选地,可以自定义文件名以用于图片。

如果你看到的是通知而不是按钮,说明你配置的服务商不支持图片生成——请查看连接器设置。

收尾

回头看,AI集成度很小

如果你查看插件代码,可能会惊讶于其中其实很少涉及人工智能。提示构建器功能大约有10行。调用的REST回调则更多。其余部分是标准的WordPress开发——REST API注册、媒体处理、脚本队列、权限检查。includes/prompt.phpgenerate_image_result()

这正是重点。WordPress AI 客户端负责提供商通信、认证、模型选择和响应规范化的复杂性。你的插件专注于它自身的目的,而 AI 部分只是另一个 API 调用。

更进一步

本文涉及图像生成,但这只是一个基础起点。例如,你也可以允许用AI编辑现有图片,比如用户请求对生成图像进行进一步修改。这个提示函数看起来几乎和生成图片的类似,只不过你还要把现有的图片文件传递给它:

use WordPress\AiClient\Files\DTO\File;
use WordPress\AiClient\Files\Enums\FileTypeEnum;
use WordPress\AiClient\Files\Enums\MediaOrientationEnum;

function aicig_get_image_editing_prompt( string $prompt, File $image_file, string $orientation = '' ): WP_AI_Client_Prompt_Builder {
    $builder = wp_ai_client_prompt()
        ->with_text( $prompt )
        ->with_file( $image_file )
        ->as_output_file_type( FileTypeEnum::inline() );

    if ( $orientation ) {
        $builder->as_output_media_orientation( MediaOrientationEnum::from( $orientation ) );
    }

    return $builder;
}

调用将源图像作为DTO传递。AI客户端负责将该路由到支持图像编辑的提供商和模型。with_file()File

我鼓励你进一步应用这个插件:也许可以添加上述提示函数,并将其集成到图像生成的 REST 端点中(你只需要添加一个可选参数来传递已有的图像并有条件调用上述函数)。然后探索如何调整前端界面,使这个用例更直观。aicig_get_image_editing_prompt()

即使是这个看似简单的功能,也有许多更多想法值得探索。以下是一些值得探索的点子:

  • 你可以考虑扩展图片生成(或编辑)行为,让它为用户提示生成多种图片变体,用户可以选择最喜欢的。
  • 你可能注意到上传图片到媒体库前有一个文件名输入字段。目前,这个文件名字段是程序生成的,导致文件名不太实用。你可以利用AI客户端的文本生成功能,根据图片实际显示的内容生成更具描述性的文件名。
  • 你可以与媒体库中的现有图片集成,比如显示提示文本字段和一个按钮让AI编辑现有图片。

如果你对基于新WordPress客户端的专业端到端插件感兴趣,它提供类似AI驱动功能的插件,我建议你看看官方的WordPress AI插件

你看,AI的能力是无穷无尽的。虽然像我们这里做的这样简单的图像生成示例很酷,但它只是冰山一角。我们可以利用人工智能真正将用户体验提升到另一个层次。

但通过这篇文章,你希望现在对如何使用WordPress AI客户端所提供的一切有了更清晰的启示。你可以在GitHub上查看插件源代码:wptrainingteam/ai-client-imagegen