Prompt Template¶
Overview¶
The Prompt Template policy enables dynamic prompt transformation by replacing template:// URI patterns in JSON payloads with predefined templates. Template placeholders are resolved using parameters passed in the URI query string, allowing you to standardize and reuse prompts across different API calls. This is particularly useful for AI/LLM APIs where consistent prompt formatting improves response quality and maintainability.
Features¶
- Pattern-based template matching using
template://URI format - Parameter substitution with
[[parameter-name]]placeholder syntax - Multiple templates per policy configuration
- JSON-safe string replacement and escaping
- Processes entire JSON payload as string to find and replace patterns
Configuration¶
Parameters¶
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
promptTemplateConfig |
string | Yes | - | JSON string containing an array of template objects. Each template must have a name and prompt field. Example: [{"name": "translate", "prompt": "Translate from [[from]] to [[to]]: [[text]]"}] |
Template Configuration Format¶
The promptTemplateConfig must be a JSON array of template objects:
Each template object contains:
- name: Unique identifier for the template (used in template:// URIs)
- prompt: The template string with [[parameter-name]] placeholders that will be replaced
Template Syntax¶
Template URI Format¶
Templates are referenced in JSON payloads using the following URI format:
Example:
Placeholder Syntax¶
Within template prompts, use double square brackets to define placeholders:
During resolution, placeholders are replaced with values from the URI query parameters. Parameter names are case-sensitive and must match exactly between the placeholder and the URI parameter.
Example template:
When called with template://translate?from=english&to=spanish&text=Hello, the resolved prompt would be:
Examples¶
Example 1: Translation Template¶
Deploy an LLM provider with a translation prompt template:
For local or development environments only, the default credentials may be admin:admin encoded as YWRtaW46YWRtaW4=.
curl -X POST http://localhost:9090/llm-providers \
-H "Content-Type: application/yaml" \
-H "Authorization: Basic <BASE64_CREDENTIAL>" \
--data-binary @- <<'EOF'
apiVersion: gateway.api-platform.wso2.com/v1alpha1
kind: LlmProvider
metadata:
name: translation-provider
spec:
displayName: Translation Provider
version: v1.0
template: openai
vhost: openai
upstream:
url: "https://api.openai.com/v1"
auth:
type: api-key
header: Authorization
value: Bearer <openai-apikey>
accessControl:
mode: deny_all
exceptions:
- path: /chat/completions
methods: [POST]
policies:
- name: prompt-template
version: v1
paths:
- path: /chat/completions
methods: [POST]
params:
promptTemplateConfig: '[{"name": "translate", "prompt": "Translate the following text from [[from]] to [[to]]: [[text]]"}]'
EOF
Test the template:
Note: Ensure that "openai" is mapped to the appropriate IP address (e.g., 127.0.0.1) in your /etc/hosts file, or remove the vhost from the LLM provider configuration and use localhost to invoke.
curl -X POST http://openai:8080/chat/completions \
-H "Content-Type: application/json" \
-H "Host: openai" \
-d '{
"model": "gpt-4",
"messages": [
{
"role": "user",
"content": "template://translate?from=english&to=spanish&text=Hello world"
}
]
}'
The policy will transform the request to:
{
"model": "gpt-4",
"messages": [
{
"role": "user",
"content": "Translate the following text from english to spanish: Hello world"
}
]
}
Example 2: Summarization Template¶
Create a template for summarizing content with configurable length:
curl -X POST http://localhost:9090/llm-providers \
-H "Content-Type: application/yaml" \
-H "Authorization: Basic <BASE64_CREDENTIAL>" \
--data-binary @- <<'EOF'
apiVersion: gateway.api-platform.wso2.com/v1alpha1
kind: LlmProvider
metadata:
name: summarization-provider
spec:
displayName: Summarization Provider
version: v1.0
template: openai
vhost: openai
upstream:
url: "https://api.openai.com/v1"
auth:
type: api-key
header: Authorization
value: Bearer <openai-apikey>
accessControl:
mode: deny_all
exceptions:
- path: /chat/completions
methods: [POST]
policies:
- name: prompt-template
version: v1
paths:
- path: /chat/completions
methods: [POST]
params:
promptTemplateConfig: '[{"name": "summarize", "prompt": "Summarize the following content in [[length]] words: [[content]]"}]'
EOF
Test with template:
curl -X POST http://openai:8080/chat/completions \
-H "Content-Type: application/json" \
-H "Host: openai" \
-d '{
"model": "gpt-4",
"messages": [
{
"role": "user",
"content": "template://summarize?length=50&content=Artificial intelligence is a branch of computer science that aims to create intelligent machines capable of performing tasks that typically require human intelligence."
}
]
}'
Example 3: Multiple Templates¶
Configure multiple templates in a single policy:
policies:
- name: prompt-template
version: v1
paths:
- path: /chat/completions
methods: [POST]
params:
promptTemplateConfig: |
[
{
"name": "translate",
"prompt": "Translate from [[from]] to [[to]]: [[text]]"
},
{
"name": "summarize",
"prompt": "Summarize in [[length]] words: [[content]]"
},
{
"name": "explain",
"prompt": "Explain [[topic]] to a [[audience]] audience: [[question]]"
}
]
Use Cases¶
-
Standardized Prompts: Ensure consistent prompt formatting across different API consumers by centralizing prompt definitions.
-
Reusable Templates: Create library of common prompts (translation, summarization, explanation) that can be reused across multiple APIs.
-
Parameterized Prompts: Allow dynamic content insertion while maintaining consistent prompt structure and quality.
-
Multi-language Support: Use templates with language parameters to standardize prompts for different locales.
-
Prompt Versioning: Update prompt templates centrally without requiring changes to client applications.
Template Pattern Matching¶
The policy uses regex pattern matching to find template:// URIs in the JSON payload:
- Pattern:
template://[a-zA-Z0-9_-]+\?[^\s"']* - Location: Searches the entire JSON payload as a string
- Replacement: Each matched pattern is replaced with the resolved template string (JSON-escaped)
Pattern Details¶
- Template names can contain letters, numbers, underscores, and hyphens
- Query parameters can contain any characters except spaces, quotes, or single quotes
- Multiple template:// patterns can exist in a single payload
- Each pattern is resolved independently
Error Handling¶
If a template:// pattern references a template name that doesn't exist in the configuration, the pattern is left unchanged (no replacement occurs). This allows for graceful handling of missing templates.
When template resolution fails (e.g., invalid JSON escaping), the specific pattern is skipped and other patterns continue to be processed.
Notes¶
- Template names are case-sensitive and must match exactly between the URI reference and the configuration.
- Parameter names in placeholders
[[param]]are case-sensitive and must match query parameter names exactly. - Query parameter values are URL-decoded before being inserted into templates.
- The resolved template string is JSON-escaped (special characters like quotes, newlines are escaped) before replacement.
- The policy processes the entire JSON payload as a string, so templates can be used anywhere in the JSON structure.
- Multiple
template://patterns can appear in a single payload and will all be processed.