Using Prompts Inside Skills: Tips and Techniques

Clawpedia · For Humans

Optimize the prompts within your OpenClaw skills for consistent, high-quality agent responses.

Overview

Prompts are the bridge between your skill's logic and the AI model's intelligence. A well-crafted prompt inside a skill transforms raw data into natural, helpful responses. This guide covers prompt design patterns, template variables, dynamic context injection, and advanced techniques for getting the best results from any model.

Why Skills Need Prompts

Skills often fetch raw data — API responses, database records, calculations. A prompt tells the AI how to present that data to the user:


Without prompt:  {"temp": 18, "condition": "cloudy", "wind": 12}
With prompt:     "It's 18°C and cloudy in Berlin today, with a light breeze at 12 km/h. You might want a light jacket."

Prompt Architecture in Skills

Skills use prompts at two points:

1. System Prompt (Persistent Context)

Defined in the manifest, sets the skill's personality:


# manifest.yaml
prompt:
  system: |
    You are a weather assistant. Present weather data clearly and concisely.
    Always include practical advice (what to wear, whether to carry an umbrella).
    Use Celsius for temperature unless the user asks for Fahrenheit.
    Keep responses under 100 words.

2. Execution Prompt (Dynamic per Request)

Generated in code, includes the actual data:


export default class WeatherSkill extends Skill {
  async execute(context: SkillContext): Promise<SkillResult> {
    const weatherData = await this.fetchWeather(context.extractParam("city"));

    // Build the prompt with actual data
    const prompt = `
      The user asked about the weather in ${weatherData.city}.
      
      Current conditions:
      - Temperature: ${weatherData.temp}°C
      - Feels like: ${weatherData.feelsLike}°C
      - Condition: ${weatherData.condition}
      - Humidity: ${weatherData.humidity}%
      - Wind: ${weatherData.windSpeed} km/h ${weatherData.windDirection}
      - UV Index: ${weatherData.uvIndex}
      
      Forecast for tomorrow:
      - High: ${weatherData.tomorrow.high}°C
      - Low: ${weatherData.tomorrow.low}°C
      - Condition: ${weatherData.tomorrow.condition}
      
      Present this information naturally. Include practical advice.
    `;

    return this.respond(prompt);
  }
}

Template Variables

OpenClaw supports template variables in skill prompts:


prompt:
  system: |
    You are helping {{user_name}}.
    Current date: {{date}}
    User timezone: {{timezone}}
    User language: {{language}}

Available Variables

VariableDescriptionExample
{{user_name}}Display name of the user"Alice"
{{user_id}}User identifier"tg:123456789"
{{platform}}Current platform"telegram"
{{date}}Current date"2024-01-15"
{{time}}Current time"14:30"
{{timezone}}User's timezone"Europe/Berlin"
{{language}}User's language"en"
{{memory_context}}Relevant memory entries"User prefers metric units"

Prompt Patterns for Skills

Pattern 1: Data Presentation

{{conversation_history}}Recent messagesLast 5 messages

Transform raw data into natural language:


const prompt = `
  Present these stock prices to the user:
  ${stocks.map(s => `- ${s.symbol}: $${s.price} (${s.change > 0 ? '+' : ''}${s.change}%)`).join('\n')}
  
  Highlight any stocks with >5% change. Keep it concise.
`;

Pattern 2: Decision Making

Let the AI make recommendations based on data:


const prompt = `
  The user wants to plan outdoor activities this week.
  
  Weather forecast:
  ${forecast.map(day => `- ${day.date}: ${day.condition}, ${day.high}°C`).join('\n')}
  
  Recommend the best days for outdoor activities.
  Consider rain probability and temperature.
  Suggest specific activities appropriate for each day's weather.
`;

Pattern 3: Summarization

Condense large amounts of information:


const prompt = `
  Summarize these ${emails.length} unread emails:
  
  ${emails.map(e => `From: ${e.from}\nSubject: ${e.subject}\nPreview: ${e.preview}`).join('\n---\n')}
  
  Group by priority (urgent, normal, low).
  For each email, provide a one-line summary and suggested action.
`;

Pattern 4: Formatting Control

Enforce specific output formats:


const prompt = `
  Convert this task data into a formatted task list:
  ${JSON.stringify(tasks)}
  
  Format:
  ✅ Completed tasks (strikethrough)
  🔲 Pending tasks
  ⚡ High priority tasks (bold)
  
  Group by project. Add a progress bar at the top showing completion %.
`;

Pattern 5: Conditional Responses

Adapt the response based on context:


const prompt = `
  ${context.platform === 'slack' 
    ? 'Format the response using Slack mrkdwn syntax (bold with *text*, code with \`text\`).' 
    : 'Format the response using standard Markdown.'}
  
  ${context.isFirstInteraction 
    ? 'This is the user\'s first time using this skill. Include a brief explanation of what it does.' 
    : 'The user is familiar with this skill. Be concise.'}
  
  Data: ${JSON.stringify(data)}
`;

Advanced Techniques

Chain of Thought in Skills

For complex analysis, ask the model to reason step by step:


const prompt = `
  Analyze this code for security vulnerabilities:
  
  \`\`\`${language}
  ${code}
  \`\`\`
  
  Think step by step:
  1. Check for input validation issues
  2. Look for injection vulnerabilities (SQL, XSS, command)
  3. Check for authentication/authorization flaws
  4. Identify any data exposure risks
  5. Check for cryptographic issues
  
  For each finding, provide:
  - Severity: [CRITICAL] [HIGH] [MEDIUM] [LOW]
  - Line number(s)
  - Description
  - Recommended fix with code example
`;

Few-Shot Examples in Skill Prompts


const prompt = `
  Categorize this support ticket:
  
  Examples:
  - "My password doesn't work" → Category: Authentication, Priority: High
  - "Can you add dark mode?" → Category: Feature Request, Priority: Low
  - "App crashes when I upload files" → Category: Bug, Priority: Critical
  
  Now categorize:
  "${ticket.subject}: ${ticket.body}"
  
  Respond in JSON: {"category": "...", "priority": "...", "summary": "..."}
`;

Prompt Chaining

Break complex tasks into multiple prompts:


async execute(context: SkillContext): Promise<SkillResult> {
  // Step 1: Extract entities
  const entities = await this.ask(`
    Extract all named entities from this text:
    "${context.message}"
    Return as JSON: {"people": [], "places": [], "dates": []}
  `);

  // Step 2: Research each entity
  const research = await this.fetchData(entities);

  // Step 3: Generate final response
  return this.respond(`
    Based on this research data:
    ${JSON.stringify(research)}
    
    Write a comprehensive briefing about the entities mentioned.
    Focus on recent developments and connections between them.
  `);
}

Model Selection per Skill

Different skills benefit from different models:


# manifest.yaml
runtime:
  model: anthropic/claude-3-5-sonnet    # Override the agent's default model
  model_fallback: openai/gpt-4o-mini    # Fallback if primary is unavailable

Or dynamically in code:


async execute(context: SkillContext): Promise<SkillResult> {
  // Use a fast model for simple lookups
  if (this.isSimpleQuery(context)) {
    return this.respond(prompt, { model: "openai/gpt-4o-mini" });
  }
  // Use a powerful model for complex analysis
  return this.respond(prompt, { model: "anthropic/claude-3-5-sonnet" });
}

Prompt Testing

Test your prompts systematically:


describe("Prompt quality", () => {
  it("produces concise weather responses", async () => {
    const result = await skill.execute(mockContext);
    expect(result.data.length).toBeLessThan(500);
    expect(result.data).toContain("°C");
  });

  it("includes practical advice", async () => {
    const result = await skill.execute(mockContext);
    const hasAdvice = /umbrella|jacket|sunscreen|hat/i.test(result.data);
    expect(hasAdvice).toBe(true);
  });
});

Troubleshooting

Responses Are Too Long

Add explicit length constraints to your prompt:


const prompt = `${data}\n\nRespond in 2-3 sentences maximum.`;

Model Ignores Skill Prompt

The agent's system prompt may override the skill prompt. Set priority:


prompt:
  priority: high    # Ensures skill prompt takes precedence

Inconsistent Output Format

Use few-shot examples and explicit format instructions. For JSON output, add:


Respond ONLY with valid JSON. No explanation, no markdown, just the JSON object.

Next Steps

Related Articles