RAG Foundations

Turning Site Content Into Embeddings

⏱ 15 min

Retrieval needs something to search over that isn’t plain text. This lesson generates the actual vectors, the numeric representation of meaning, that the rest of this course chunks, stores, and searches. Course 5 introduced embeddings briefly. Here we confirm the exact, current method names on the SDK, since embeddings were only added to wordpress/php-ai-client in version 1.4.0, released July 15, 2026, and get precise about a detail that trips people up immediately: the result is not a bare array.

What you'll learn in this lesson
The confirmed embedding entry point
AiClient::input()->generateEmbedding(), on the standalone package, as of 1.4.0.
Why the result isn't a plain array
The embedding object's getValues() accessor, and why forgetting it breaks silently.
Controlling vector size with usingDimensions()
Trading storage size and search speed against representational precision.
Batch generation with generateEmbeddings()
Indexing many pieces of content in one call, the entry point this course's pipeline actually uses.
Prerequisites

Course 5’s Setting Up the PHP AI Client SDK and a Composer-installed wordpress/php-ai-client at version 1.4.0 or later. Embeddings did not exist in earlier versions of this package, check your installed version before continuing.

Step 1: Confirm your installed version

composer show wordpress/php-ai-client | grep versions

If this reports anything older than 1.4.0, update before continuing, embeddings simply aren’t available in earlier releases:

composer require wordpress/php-ai-client:^1.4

Step 2: The confirmed entry point

Embeddings are exposed through the standalone package’s fluent AiClient class, using input() rather than prompt(), since you’re feeding it content to represent, not instructions to follow:

// File: my-plugin/class-content-index.php
use WordPress\AiClient\AiClient;

$result = AiClient::input( 'WordPress is open source publishing software.' )
	->generateEmbedding();

That’s the confirmed, current method name: generateEmbedding(), singular, camelCase, on AiClient::input(). This lesson uses the standalone package throughout, since as of this writing that’s the path the SDK’s own documentation confirms embeddings on.

Core function vs standalone package for embeddings specifically

Course 5 established wp_ai_client_prompt() as the WordPress-core-integrated entry point for text generation, and it’s still the right call for that. For embeddings specifically, confirm which entry point your installed SDK version actually documents before shipping: at the time this course was written, the embedding methods are documented on the standalone AiClient class, not as a snake_case equivalent on wp_ai_client_prompt(). If a later SDK release adds a core-integrated embedding method, the concepts in this lesson, generating a vector, extracting it, controlling its size, carry over unchanged, only the entry point call would differ.

Step 3: Getting the actual array out with getValues()

This is the detail that silently breaks code copied from older, simpler examples: the result of generateEmbedding() is not a plain PHP array. It’s an object, and you must call getValues() on it to get the actual float array:

// File: my-plugin/class-content-index.php
$result = AiClient::input( $chunk_text )->generateEmbedding();

$vector = $result->getValues(); // array of floats, e.g. [0.0123, -0.0456, ...]

echo count( $vector ); // dimension count, e.g. 1536

Treat the returned object as a wrapper, not the data itself. Everything you store, compare, or serialize downstream in this course is $result->getValues(), the array, never $result on its own.

Step 4: Controlling vector size with usingDimensions()

Some embedding models support generating shorter vectors than their default, trading some representational precision for smaller storage and faster comparison math. The SDK exposes this as usingDimensions(), chained before the terminal call:

// File: my-plugin/class-content-index.php
$result = AiClient::input( $chunk_text )
	->usingDimensions( 512 )
	->generateEmbedding();

$vector = $result->getValues(); // now 512 floats instead of the model's default

Smaller vectors mean less storage per chunk and faster cosine similarity math at retrieval time, since you’re doing less multiplication per comparison. For most WordPress sites in the hundreds to low thousands of posts, the default dimension count is fine and this option isn’t worth reaching for until you’ve actually measured a storage or performance problem.

Step 5: Batch generation for indexing a whole site

Generating one embedding per HTTP request works for a single chunk, but indexing an entire site one request at a time is slow and expensive. generateEmbeddings(), plural, accepts an array of strings and returns an array of embedding result objects in the same order:

// File: my-plugin/class-content-index.php
use WordPress\AiClient\AiClient;

$chunks = array(
	'WordPress is open source publishing software.',
	'Plugins extend WordPress with additional functionality.',
	'Themes control how a WordPress site looks.',
);

$results = AiClient::input( $chunks )->generateEmbeddings();

foreach ( $results as $i => $result ) {
	$vector = $result->getValues();
	echo "Chunk {$i}: " . count( $vector ) . " dimensions\n";
}

This is the entry point the rest of this course’s indexing pipeline (Lesson 5) actually uses, one batch call per reindexing pass instead of one call per chunk.

Test it: generate and inspect a real embedding

wp-env run cli wp eval '
require "vendor/autoload.php";
$result = WordPress\AiClient\AiClient::input( "WordPress is open source publishing software." )->generateEmbedding();
$vector = $result->getValues();
echo "Dimensions: " . count( $vector ) . "\n";
echo "First 5 values: " . implode( ", ", array_slice( $vector, 0, 5 ) ) . "\n";
'

You should see a real dimension count and five genuine floating-point numbers, not an error and not a fatal call to a method on an array.

Calling array functions directly on the result

Calling count() or array_slice() directly on $result instead of $result->getValues() throws a fatal error, since $result is an object, not an array. This is the single most common mistake when embeddings are new to a codebase: code written against an imagined “returns an array” API fails immediately against the real one. Always extract getValues() first, then treat that extracted variable as your array.

Recap

As of wordpress/php-ai-client 1.4.0, embeddings are generated through the standalone AiClient::input()->generateEmbedding() for one chunk or generateEmbeddings() for many, usingDimensions() controls vector size, and critically, the result is an object, not an array, extract the real vector with getValues() before storing or comparing it. The next lesson uses these building blocks to decide how to split real WordPress content into chunks worth embedding in the first place.

Resources & further reading

← What RAG Actually Solves Chunking Strategies for WordPress Content →