Your First Prompt

In this hands-on tutorial, you'll build a real prompt from scratch - an educational assistant that explains concepts at different difficulty levels.

1. Project Setup

First, create a folder for your project and set up the directory structure:

my-prompt-project/
├── prompts/
   └── explainer.prompt
├── docker-compose.yml
└── src/
    └── index.ts

Create a docker-compose.yml file in your project root (see the Getting Started guide for the full configuration), then start the server:

docker compose up -d

The API will be available at http://localhost:4000.

2. Create Your First Prompt

Create a new file called explainer.prompt in the prompts/ folder:

init do
  @major: 1
  @version: 1.0.0

  def:
    mode: educational
    description: Explains concepts at different difficulty levels

  params:
    @topic: str -> The topic to explain
    @level: enum[beginner, intermediate, advanced] = beginner

end init

You are a friendly teacher helping someone learn about @topic.

case @level do
  beginner:
    Explain @topic in simple terms, using everyday examples and analogies.
    Avoid technical jargon. Use short sentences.
    
  intermediate:
    Explain @topic with some technical details, but still accessible.
    Use some terminology but define key terms.
    
  advanced:
    Explain @topic in full technical detail.
    Use precise terminology and mention edge cases.
end @level

After your explanation, ask the learner if they'd like more details on any specific aspect.

What's happening here?

  • @topic - A string parameter for the subject to explain
  • @level - An enum parameter with three possible values
  • case @level do - Conditional branching based on the level

3. Test Your Prompt

Let's test all three difficulty levels. First, the beginner level:

curl -X POST http://localhost:4000/api/render \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "explainer",
    "runtime": {
      "topic": "photosynthesis",
      "level": "beginner"
    }
  }'

You should get a simple explanation like:

"You are a friendly teacher helping someone learn about photosynthesis. Explain photosynthesis in simple terms, using everyday examples and analogies. Avoid technical jargon. Use short sentences. After your explanation, ask the learner if they'd like more details on any specific aspect."

Intermediate Level

curl -X POST http://localhost:4000/api/render \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "explainer",
    "runtime": {
      "topic": "photosynthesis",
      "level": "intermediate"
    }
  }'

Advanced Level

curl -X POST http://localhost:4000/api/render \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "explainer",
    "runtime": {
      "topic": "photosynthesis",
      "level": "advanced"
    }
  }'

4. Integrate with a Client

Now let's use the TypeScript client to call our prompt from code:

import { DotPromptClient } from '@dotprompt/client';

const client = new DotPromptClient({
  baseUrl: 'http://localhost:4000'
});

async function explainTopic(topic: string, level: 'beginner' | 'intermediate' | 'advanced') {
  const result = await client.render('explainer', {
    topic,
    level
  });
  
  console.log(result.prompt);
  return result.prompt;
}

// Example usage
await explainTopic('black holes', 'beginner');

Install the client with: npm install @dotprompt/client

5. Enhance the Prompt

Let's add more features to our prompt. First, add a temperature parameter for tone:

init do
  @major: 1
  @version: 1.0.1

  def:
    mode: educational
    description: Explains concepts at different difficulty levels

  params:
    @topic: str -> The topic to explain
    @level: enum[beginner, intermediate, advanced] = beginner
    @temperature: float -> How technical/enthusiastic the explanation should be (0.0 to 1.0) = 0.5

end init

You are a friendly teacher helping someone learn about @topic.

case @level do
  beginner:
    Explain @topic in simple terms, using everyday examples and analogies.
    Avoid technical jargon. Use short sentences.
    
  intermediate:
    Explain @topic with some technical details, but still accessible.
    Use some terminology but define key terms.
    
  advanced:
    Explain @topic in full technical detail.
    Use precise terminology and mention edge cases.
end @level

vary @temperature do
  low: Keep your tone neutral and factual.
  medium: Add some enthusiasm and encouragement.
  high: Be very enthusiastic and use expressive language!
end @temperature

After your explanation, ask the learner if they'd like more details on any specific aspect.

Notice how we use the vary block - it selects content based on numeric ranges.

6. Add a Response Contract

Define the expected structure of the LLM's response:

init do
  @major: 1
  @version: 1.1.0

  def:
    mode: educational
    description: Explains concepts at different difficulty levels
    response:
      type: object
      required:
        - explanation
        - key_terms
        - next_steps
      properties:
        explanation:
          type: string
          description: The main explanation text
        key_terms:
          type: array
          items:
            type: object
            properties:
              term: string
              definition: string
        next_steps:
          type: array
          items:
            type: string

  params:
    @topic: str -> The topic to explain
    @level: enum[beginner, intermediate, advanced] = beginner

end init

// ... prompt content ...

This tells the LLM to respond with JSON containing explanation, key_terms, and next_steps. You can then validate the response using the client.

What's Next?

You've built your first prompt! Here's what to explore next: