Fundamentals

Few-Shot Prompting Patterns

⏱ 14 min

Lesson 1 covered instructions, telling a model what to do in words. This lesson covers showing it instead, giving the model two or three worked examples of exactly the kind of input and output you want, before it ever sees the real one. That’s few-shot prompting, and for tasks with a specific, repeatable output style, meta descriptions, excerpt formatting, tag naming conventions, it’s often more reliable than any amount of extra wording in a system instruction. with_history() is the builder method that makes this possible, and this lesson builds a real few-shot setup for generating consistent SEO meta descriptions.

What you'll learn in this lesson
What few-shot prompting is
Showing example input/output pairs instead of only describing the rules.
with_history()
How it prepends prior conversation turns before your current prompt.
Building a few-shot set for meta descriptions
Two or three consistent examples, then the real post.
Combining few-shot with a system instruction
Why the two work best stacked together, not as alternatives.
Prerequisites

Lesson 1’s system instruction patterns, and a working wp_ai_client_prompt() setup from Course 1 or Course 5. This lesson assumes you’re comfortable calling generate_text() and reading its output.

Step 1: Why examples work when instructions alone don’t

A system instruction can describe a rule, “keep it under 155 characters, active voice, no clickbait phrasing,” but “active voice” and “no clickbait phrasing” are judgment calls, and a model asked to follow a judgment call in words alone will interpret it inconsistently across different inputs. Showing two or three examples of input content paired with the exact output style you want removes most of that ambiguity, the model now has a concrete pattern to match rather than a description to interpret.

Step 2: How with_history() actually works

with_history() takes a list of prior messages and prepends them to the conversation, before the current prompt you build with with_text(). Each message has a role, either a user turn or a model turn, and the pattern for few-shot prompting is straightforward: alternate a user message showing sample input with a model message showing the exact output you want for it, repeated for each example, then your real input follows as the final, un-answered turn.

// File: my-plugin/class-meta-description-generator.php
use WordPress\AiClient\Messages\DTO\MessagePart;
use WordPress\AiClient\Messages\DTO\UserMessage;
use WordPress\AiClient\Messages\DTO\ModelMessage;

$few_shot_history = array(
	new UserMessage( array( new MessagePart(
		'Post title: How to Prune Tomatoes for a Bigger Harvest. ' .
		'Content summary: step-by-step pruning technique for indeterminate tomato ' .
		'plants, covers suckers, timing, and tools.'
	) ) ),
	new ModelMessage( array( new MessagePart(
		'Learn the exact pruning technique that increases tomato yield, ' .
		'covering suckers, timing, and the right tools.'
	) ) ),

	new UserMessage( array( new MessagePart(
		'Post title: WordPress 7.0 Block Editor Changes. ' .
		'Content summary: overview of new block editor features shipping in ' .
		'WordPress 7.0, aimed at theme developers.'
	) ) ),
	new ModelMessage( array( new MessagePart(
		'A theme developer\'s overview of the block editor changes shipping in ' .
		'WordPress 7.0.'
	) ) ),
);

Step 3: Running the real input through the same shape

The final call adds the real post as the current prompt, after the example history, and keeps the system instruction from Lesson 1’s pattern for the parts examples can’t cover on their own, the hard character limit in particular:

// File: my-plugin/class-meta-description-generator.php
$response = wp_ai_client_prompt()
	->using_system_instruction(
		'Write a single SEO meta description, 150 to 155 characters, active voice, ' .
		'no clickbait, no quotation marks around the result.'
	)
	->with_history( ...$few_shot_history )
	->with_text(
		'Post title: Setting Up a Staging Site With WP-CLI. ' .
		'Content summary: creating an isolated staging copy of a WordPress site ' .
		'using wp-cli commands, for testing plugin updates safely.'
	)
	->using_temperature( 0.3 )
	->generate_text();

Notice the system instruction still carries the one rule examples handle poorly, an exact character count, since counting characters isn’t a pattern a model reliably infers from two examples alone. Few-shot examples and a system instruction aren’t competing techniques, they cover different kinds of constraints and work best stacked together, exactly as they are here.

Keep examples in the same domain as production input

Two or three examples that closely resemble the real inputs your feature will actually see teach the pattern far better than generic, unrelated examples. If this generator mostly runs on how-to and tutorial posts, write your examples from how-to and tutorial posts, not from news posts or product pages.

Step 4: How many examples is enough

Two or three well-chosen examples cover most WordPress content-generation tasks. Each example adds tokens to every single call, which is real, recurring cost, not a one-time setup cost, so more examples isn’t automatically better. If two examples aren’t producing consistent output, the more likely fix is that the examples themselves are inconsistent with each other, not that a third or fourth example will resolve it.

Contradictory examples confuse the model more than none at all

If your few-shot examples don’t actually follow the same style consistently, one meta description in active voice, the next in passive voice, one 150 characters, the next 90, you’re teaching the model that inconsistency is the pattern. Review your own examples for consistency with each other before assuming the technique isn’t working.

Test it: run the meta description generator

wp-env run cli wp eval '
$title = "Setting Up a Staging Site With WP-CLI";
$summary = "Creating an isolated staging copy of a WordPress site using wp-cli commands, for testing plugin updates safely.";

echo wp_ai_client_prompt()
	->using_system_instruction(
		"Write a single SEO meta description, 150 to 155 characters, active voice, " .
		"no clickbait, no quotation marks around the result."
	)
	->with_text( "Post title: $title. Content summary: $summary." )
	->using_temperature( 0.3 )
	->generate_text();
'

Run it once with only the system instruction, then add the with_history() few-shot set from Step 2 and run it again. You should see the few-shot version land more consistently in the 150 to 155 character range and match the tone of the two examples more closely than the instruction-only version does.

Recap

Few-shot prompting works by showing a model examples instead of only describing rules, and with_history() is the builder method that prepends those example turns before your real prompt. Build history as alternating user and model messages using UserMessage, ModelMessage, and MessagePart, keep examples consistent with each other and representative of real production input, and stack few-shot history with a system instruction rather than treating them as alternatives, since each covers constraints the other handles poorly.

Resources & further reading

← System Prompts and Instructions in the PHP AI Client SDK Getting Reliable JSON Back From the Model →