Prompt Templates
Overview¶
As your applications grow in complexity, your prompts may become large and complex, with multiple variables and metadata. Managing these prompts can become a challenge, especially when you need to reuse them across different parts of your application. Large prompts are also hard to maintain if they are part of your codebase.
Prompt
addon provides a powerful and flexible way to manage your prompts. It supports
multiple template engines (Twig, Blade), prompt metadata, variable injection, and validation.
What are Prompts¶
Prompts in Instructor are based on structured text templates that can be rendered to text or series of chat messages. As many of your prompts will be dynamically generated based on input data, you can use syntax of one of the supported template engines (Twig, Blade) to define your prompts.
This document will be using Twig syntax for prompt templates for simplicity and consistency, but you can use Blade syntax in your prompts if you prefer it.
- For more information on Twig syntax see Twig documentation.
- For more information on Blade syntax see Blade documentation.
Basic Prompt Template¶
Example prompt template in Twig:
Prompt Template with Variables¶
You can define variables in your prompt templates and inject values when rendering the prompt.
Chat Messages¶
You can define chat messages in your prompts, which can be used to generate a sequence of messages for LLM chat APIs.
<chat>
<message role="system">You are a helpful assistant.</message>
<message role="user">What is the capital of {{ country }}?</message>
</chat>
Prompt Template Metadata¶
We recommend to preface each prompt with front matter - a block of metadata that describes the prompt and its variables. This metadata can be used for validation, documentation, and schema generation.
{#---
description: Capital finder template
variables:
country:
description: Country name
type: string
default: France
schema:
name: capital
properties:
name:
description: Capital city name
type: string
required: [name]
---#}
<chat>
<message role="system">You are a helpful assistant.</message>
<message role="user">What is the capital of {{ country }}?</message>
</chat>
Template Libraries¶
Instructor allows you to define multiple template libraries
in your app. Library is just a collection of
prompt templates which is stored under a specific directory. Library can have a nested structure, which allows
you to organize your prompts in a way that makes sense for your application.
Library properties are specified in config/prompt.php
configuration file.
where you can define:
- templateEngine
- template engine used for prompts in this library,
- resourcePath
- path to prompt templates,
- cachePath
- path to compiled templates,
- extension
- file extension for prompt templates,
- frontMatterTags
- start and end tags for front matter,
- frontMatterFormat
- format of front matter (yaml, json, toml),
- metadata
- engine-specific configuration.
Instructor comes with 3 default prompt libraries:
- system
- prompt templates used by Instructor itself,
- demo-twig
- demo prompt templates using Twig template engine,
- demo-blade
- demo prompt templates using Blade template engine.
Instructor's does not specify how you should organize or manage your prompt templates, but it provides a flexible way to do it in a way that suits your application.
Using Prompt Templates¶
Rendering a Simple Prompt¶
To get started, you can create and render a simple prompt defined in the bundled library using the Prompt::using
or Prompt::make
methods. Here's how you can use them:
<?php
use Cognesy\Template\Template;
// Basic example using "using->get->with" syntax
$prompt = Template::using('demo-twig')->get('hello')->with(['name' => 'World']);
echo $prompt->toText(); // Outputs: "Hello, World!"
?>
make()
syntax:
<?php
$prompt = Template::make('demo-twig:hello')->with(['name' => 'World']);
echo $prompt->toText(); // Outputs: "Hello, World!"
?>
Rendering a Chat Template¶
The Prompt class can also render prompts directly as chat-style messages:
<?php
$messages = Template::messages('demo-twig:hello', ['name' => 'World']);
print_r($messages->toArray());
// Outputs:
// [
// ['role' => 'user', 'content' => 'Hello, World!']
// ]
?>
Custom Configuration and Template Content¶
If you need to customize the configuration or set the template content directly, you can do so with additional methods:
<?php
use Cognesy\Template\Config\TemplateEngineConfig;use Cognesy\Template\Enums\TemplateEngineType;
// Setting custom configuration
$config = new TemplateEngineConfig(
templateEngine: TemplateEngineType::Twig,
resourcePath: '',
cachePath: '/tmp/cache',
extension: '.twig',
);
$prompt = new Template();
$prompt->withConfig($config)
->withTemplateContent('Hello, {{ name }}!')
->withValues(['name' => 'World']);
echo $prompt->toText(); // Outputs: "Hello, World!"
?>
In Memory Templates¶
If you need to create an inline prompt (without saving it to a file), you can use following syntax:
<?php
$prompt = Template::twig() // or Template::blade() for Blade syntax
->withTemplateContent('Hello, {{ name }}!')
->withValues(['name' => 'World'])
->toText();
?>
There's shorter syntax for creating in-memory prompts:
<?php
$prompt = Template::twig() // or Template::blade() for Blade syntax
->from('Hello, {{ name }}!')
->with(['name' => 'World'])
->toText();
?>
Handling Template Variables¶
To check which variables are available in a prompt template:
<?php
$prompt = Template::using('demo-twig')
->withTemplateContent('Hello, {{ name }}!')
->withValues(['name' => 'World']);
$variables = $prompt->variables();
print_r($variables); // Outputs: ['name']
?>
Loading Templates by Name and Using DSNs¶
For more flexible template loading, you can load templates by name or use a 'DSN-like' (Data Source Name) syntax:
<?php
// Load a template by name using specified library 'demo-blade'
$prompt = Template::using('demo-blade')->withTemplate('hello');
echo $prompt->template();
// Load a template from specified library using DSN syntax
$prompt = Template::fromDsn('demo-blade:hello')->with(['name' => 'World']);
echo $prompt->toText(); // Outputs: "Hello, World!"
?>
Converting to Messages with Markup¶
The Prompt class also supports converting templates containing chat-specific markup into structured messages:
Here is an example XML that can be used to generate a sequence of chat messages:
<chat>
<message role="system">You are a helpful assistant.</message>
<message role="user">Hello, {{ name }}</message>
</chat>
And here is how you use Prompt
class to convert XML template into a sequence of messages:
<?php
$prompt = Template::using('demo-blade')
->withTemplateContent('<chat><message role="system">You are a helpful assistant.</message><message role="user">Hello, {{ $name }}</message></chat>')
->withValues(['name' => 'assistant']);
$messages = $prompt->toMessages();
echo $messages->toArray();
// Outputs:
// [
// ['role' => 'system', 'content' => 'You are a helpful assistant.'],
// ['role' => 'user', 'content' => 'Hello, assistant']
// ]
?>