Skip to main content

How Prompt Composability Works

Create base prompt components

Create prompts that serve as reusable components. These are regular ABV prompts containing shared content like system instructions, examples, or guidelines.
from abvdev import ABV

abv = ABV(api_key="sk-abv-...")

# Create a reusable safety guidelines component
abv.create_prompt(
    name="safety-guidelines",
    type="text",
    prompt="Never provide medical, legal, or financial advice. If asked, direct users to licensed professionals.",
    labels=["production"]
)

# Create reusable company voice component
abv.create_prompt(
    name="company-voice",
    type="text",
    prompt="Speak in a friendly, professional tone. Use 'we' and 'our' when referring to the company. Keep responses concise.",
    labels=["production"]
)
These components can be versioned, labeled, and managed like any other prompt.

Reference components in parent prompts

In parent prompts, reference base components using the special @@@abvdevPrompt syntax. You can reference by specific version or by label for dynamic resolution.Reference by label (recommended for production):
You are a customer support agent for Acme Corp.

@@@abvdevPrompt:name=company-voice|label=production@@@

@@@abvdevPrompt:name=safety-guidelines|label=production@@@

Answer the customer's question: {{question}}
Reference by specific version (for testing):
You are a customer support agent for Acme Corp.

@@@abvdevPrompt:name=company-voice|version=3@@@

Answer the customer's question: {{question}}
The syntax works in both text and chat prompts (in chat, insert references within message content).

ABV resolves references at fetch time

When you fetch a prompt via SDK or API, ABV automatically resolves all prompt references, replacing them with the actual content from the referenced prompts.
# Fetch parent prompt
prompt = abv.get_prompt("customer-support-agent")

# ABV resolves references automatically:
# - Fetches "company-voice" (production label)
# - Fetches "safety-guidelines" (production label)
# - Injects their content into the parent prompt
# - Returns the fully composed prompt

compiled = prompt.compile(question="How do I reset my password?")
print(compiled)
# Output includes the composed content:
# "You are a customer support agent for Acme Corp.
#  Speak in a friendly, professional tone. Use 'we' and 'our'...
#  Never provide medical, legal, or financial advice...
#  Answer the customer's question: How do I reset my password?"
Resolution happens transparently—you work with the composed prompt as if it were a single, flat prompt.

Update base prompts to propagate changes

When you update a base prompt component and assign the production label to the new version, all parent prompts that reference it via label=production automatically use the updated content on their next fetch.
# Update safety guidelines (create new version)
abv.create_prompt(
    name="safety-guidelines",
    type="text",
    prompt="Never provide medical, legal, or financial advice. If asked, direct users to licensed professionals. Additionally, do not provide tax preparation advice.",
    labels=["production"]  # Assign to production
)

# All parent prompts referencing safety-guidelines via production label
# now use the updated version on next fetch—no code changes required
This enables centralized updates across your entire prompt library.

Use Cases and Patterns

Maintain consistent persona and behavior across multiple prompts by defining system instructions once.Base Component:
abv.create_prompt(
    name="customer-support-persona",
    type="text",
    prompt="You are a helpful, empathetic customer support agent for Acme Corp. Always acknowledge the customer's concern before providing solutions. If you don't know an answer, say so honestly and offer to escalate to a human agent.",
    labels=["production"]
)
Parent Prompts (multiple use cases):
# Billing support prompt
@@@abvdevPrompt:name=customer-support-persona|label=production@@@

Help the customer with their billing question: {{question}}
# Technical support prompt
@@@abvdevPrompt:name=customer-support-persona|label=production@@@

Help the customer troubleshoot their technical issue: {{issue}}
# Returns/refunds prompt
@@@abvdevPrompt:name=customer-support-persona|label=production@@@

Process the customer's return or refund request: {{request}}
All three prompts share the same persona and behavioral guidelines. Update the persona once to change all three.
Share few-shot examples across related prompts to maintain consistent performance patterns.Base Component (examples):
abv.create_prompt(
    name="sentiment-analysis-examples",
    type="text",
    prompt="""Example 1:
Input: "The product exceeded my expectations!"
Output: Positive

Example 2:
Input: "Shipping was delayed and customer service was unhelpful."
Output: Negative

Example 3:
Input: "The item works as described."
Output: Neutral""",
    labels=["production"]
)
Parent Prompts (different domains, same task):
# Product review sentiment
Classify the sentiment of the following product review.

@@@abvdevPrompt:name=sentiment-analysis-examples|label=production@@@

Review: {{review_text}}
Sentiment:
# Support ticket sentiment
Classify the sentiment of the following support ticket.

@@@abvdevPrompt:name=sentiment-analysis-examples|label=production@@@

Ticket: {{ticket_text}}
Sentiment:
Both prompts use the same examples. Refine examples once, improve both prompts.
Enforce organizational policies (safety, compliance, brand voice) consistently across all LLM applications.Base Components:
# Safety policy
abv.create_prompt(
    name="safety-policy",
    type="text",
    prompt="Never generate content that is harmful, illegal, discriminatory, or violates user privacy.",
    labels=["production"]
)

# Brand voice
abv.create_prompt(
    name="brand-voice",
    type="text",
    prompt="Acme Corp's voice is: Professional yet approachable, concise but not terse, confident without arrogance. Avoid jargon and acronyms unless industry-standard.",
    labels=["production"]
)

# Data privacy policy
abv.create_prompt(
    name="data-privacy-policy",
    type="text",
    prompt="Never ask for or store personally identifiable information (PII) such as Social Security numbers, credit card numbers, or passwords in conversation logs.",
    labels=["production"]
)
Every Prompt in Your Organization:
[Prompt-specific instructions]

@@@abvdevPrompt:name=brand-voice|label=production@@@
@@@abvdevPrompt:name=safety-policy|label=production@@@
@@@abvdevPrompt:name=data-privacy-policy|label=production@@@

[Rest of prompt]
When your legal team updates the data privacy policy, one change in ABV updates every LLM application company-wide.
Build language-specific components and compose them dynamically based on user locale.Base Components (per language):
# English instructions
abv.create_prompt(
    name="instructions-en",
    type="text",
    prompt="Please provide detailed, step-by-step instructions.",
    labels=["production"]
)

# Spanish instructions
abv.create_prompt(
    name="instructions-es",
    type="text",
    prompt="Por favor, proporcione instrucciones detalladas, paso a paso.",
    labels=["production"]
)

# French instructions
abv.create_prompt(
    name="instructions-fr",
    type="text",
    prompt="Veuillez fournir des instructions détaillées, étape par étape.",
    labels=["production"]
)
Runtime Language Selection:
# Determine user's language
user_language = get_user_language()  # "en", "es", "fr"

# Fetch language-specific instructions
instructions = abv.get_prompt(f"instructions-{user_language}")

# Use in parent prompt
parent_prompt = abv.get_prompt("help-wizard")
compiled = parent_prompt.compile(
    language_instructions=instructions.prompt,
    task=user_task
)
Alternatively, maintain separate parent prompts per language, each referencing the appropriate language component.
Test new component versions in parent prompts without affecting production.Workflow:
# Current production component (v1)
abv.create_prompt(
    name="response-format",
    type="text",
    prompt="Provide your answer in 2-3 sentences.",
    labels=["production"]
)

# Create experimental version (v2)
abv.create_prompt(
    name="response-format",
    type="text",
    prompt="Provide your answer in a numbered list with 3-5 key points.",
    labels=["staging"]
)

# Parent prompt references by label
# Production: uses v1 via label=production
# Staging: uses v2 via label=staging
parent_prompt = """
Answer the user's question about {{topic}}.

@@@abvdevPrompt:name=response-format|label=production@@@

Question: {{question}}
"""

# Test in staging by changing label reference to staging
# Deploy to production by reassigning production label from v1 to v2
This enables safe A/B testing of component changes before rolling them out.
Create hierarchies of reusable components where components themselves reference other components.Multi-Level Component Structure:
# Level 1: Fundamental policies
abv.create_prompt(name="safety-core", type="text",
                  prompt="Do not generate harmful content.", labels=["production"])

abv.create_prompt(name="privacy-core", type="text",
                  prompt="Do not request PII.", labels=["production"])

# Level 2: Department-specific guidelines (reference Level 1)
abv.create_prompt(
    name="support-guidelines",
    type="text",
    prompt="""@@@abvdevPrompt:name=safety-core|label=production@@@
@@@abvdevPrompt:name=privacy-core|label=production@@@

Always verify customer identity before accessing account details.""",
    labels=["production"]
)

# Level 3: Specific use cases (reference Level 2)
abv.create_prompt(
    name="billing-support",
    type="text",
    prompt="""@@@abvdevPrompt:name=support-guidelines|label=production@@@

Help customers with billing questions, refunds, and payment issues.

Question: {{question}}""",
    labels=["production"]
)
ABV recursively resolves all nested references, giving you the fully composed prompt.

Implementation Examples

  1. Navigate to Prompt Management in ABV dashboard
  2. Create or edit a prompt
  3. Position your cursor where you want to insert a component reference
  4. Click Add prompt reference button
  5. Select the component prompt from the dropdown
  6. Choose reference type:
    • Label (recommended): Select a label like production or staging
    • Version: Select a specific version number
  7. Save the prompt
The reference appears as a special token in your prompt: @@@abvdevPrompt:name=ComponentName|label=production@@@When you fetch this prompt via SDK or API, ABV automatically resolves the reference.
Install ABV SDK:
pip install abvdev
Create base components:
from abvdev import ABV

abv = ABV(
    api_key="sk-abv-...",
    host="https://app.abv.dev"
)

# Create reusable safety component
abv.create_prompt(
    name="safety-guidelines",
    type="text",
    prompt="Never provide medical, legal, or financial advice.",
    labels=["production"]
)

# Create reusable voice component
abv.create_prompt(
    name="company-voice",
    type="text",
    prompt="Speak professionally and concisely.",
    labels=["production"]
)
Create parent prompt that references components:
abv.create_prompt(
    name="customer-support",
    type="text",
    prompt="""You are a customer support agent for Acme Corp.

@@@abvdevPrompt:name=company-voice|label=production@@@

@@@abvdevPrompt:name=safety-guidelines|label=production@@@

Answer the customer's question: {{question}}""",
    labels=["production"]
)
Fetch and use composed prompt:
# Fetch parent prompt (references are resolved automatically)
prompt = abv.get_prompt("customer-support")

# Compile with variables
compiled = prompt.compile(question="How do I reset my password?")

print(compiled)
# Output:
# You are a customer support agent for Acme Corp.
# Speak professionally and concisely.
# Never provide medical, legal, or financial advice.
# Answer the customer's question: How do I reset my password?
Install ABV SDK:
npm install @abvdev/client
Set up environment:
import { ABVClient } from "@abvdev/client";
import dotenv from "dotenv";
dotenv.config();

const abv = new ABVClient({
    apiKey: process.env.ABV_API_KEY,
    baseUrl: "https://app.abv.dev"
});
Create base components:
async function createComponents() {
    // Safety guidelines component
    await abv.prompt.create({
        name: "safety-guidelines",
        type: "text",
        prompt: "Never provide medical, legal, or financial advice.",
        labels: ["production"]
    });

    // Company voice component
    await abv.prompt.create({
        name: "company-voice",
        type: "text",
        prompt: "Speak professionally and concisely.",
        labels: ["production"]
    });
}
Create parent prompt with references:
async function createParentPrompt() {
    await abv.prompt.create({
        name: "customer-support",
        type: "text",
        prompt: `You are a customer support agent for Acme Corp.

@@@abvdevPrompt:name=company-voice|label=production@@@

@@@abvdevPrompt:name=safety-guidelines|label=production@@@

Answer the customer's question: {{question}}`,
        labels: ["production"]
    });
}
Fetch and use composed prompt:
async function useComposedPrompt() {
    const prompt = await abv.prompt.get("customer-support", { type: "text" });

    const compiled = prompt.compile({
        question: "How do I reset my password?"
    });

    console.log(compiled);
    // You are a customer support agent for Acme Corp.
    // Speak professionally and concisely.
    // Never provide medical, legal, or financial advice.
    // Answer the customer's question: How do I reset my password?
}

useComposedPrompt();
When testing a new version of a component, reference it by specific version number instead of label.Python Example:
# Create v1 (production)
abv.create_prompt(
    name="output-instructions",
    type="text",
    prompt="Provide concise answers in 2-3 sentences.",
    labels=["production"]
)

# Create v2 (testing)
abv.create_prompt(
    name="output-instructions",
    type="text",
    prompt="Provide detailed answers with examples and citations.",
    labels=["staging"]
)

# Parent prompt for testing v2 specifically
abv.create_prompt(
    name="qa-assistant-test",
    type="text",
    prompt="""Answer the following question.

@@@abvdevPrompt:name=output-instructions|version=2@@@

Question: {{question}}""",
    labels=["testing"]
)

# Test the v2 component without affecting production
test_prompt = abv.get_prompt("qa-assistant-test")
compiled = test_prompt.compile(question="What is prompt composability?")
Once testing is successful, update the parent prompt to use label=production and reassign the production label from v1 to v2.

Next Steps