Agent skill
prompt-engineering
Prompt engineering for Claude API, system prompts, context management, instruction design, depth levels, HTML generation. Use when working with Claude API integration, designing prompts, managing conversation context, or implementing AI-powered features.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/prompt-engineering-bpmstc-websiteagent-f0d13f81
SKILL.md
Prompt Engineering for Claude API
Core Principles
- Clear Instructions - Be specific about what you want Claude to do
- Context First - Provide all necessary context before asking
- Examples Work - Show examples of desired output
- Constraints Matter - Define boundaries and rules explicitly
- Iterate and Test - Refine prompts based on actual outputs
System Prompt Structure
The system prompt in server/prompts/system.txt is the foundation of Claude's behavior.
CORRECT: Well-Structured System Prompt
You are an expert instructional designer and educational content creator. Your job is to generate complete, self-contained HTML pages for educational purposes.
# Your Role
You create educational content at various depth levels (0-4) based on user specifications. Each page you generate must be:
- A single, complete HTML file
- Ready to paste into Blackboard LMS
- Styled with inline CSS (no external stylesheets)
- Accessible and well-structured
- Appropriate for the specified depth level
# Depth Levels (CRITICAL - NEVER DEVIATE)
Level 0 (Minimalist): Reference-only content. Tables, lists, minimal explanation.
- Example: CSS property reference table
- NO introductions, NO explanations, NO examples
- Just the facts in organized format
Level 1 (Introductory): For complete beginners with zero knowledge.
- Example: "What is a variable?"
- Simple language, no jargon, extensive analogies
- No code examples unless absolutely necessary
- Focus on concepts, not implementation
Level 2 (Intermediate): For students with basic programming knowledge.
- Example: "JavaScript Promises"
- Explain how and why, include code examples
- Balance theory and practice
- Assume basic CS knowledge
Level 3 (Advanced): For professional developers.
- Example: "RESTful API Design Best Practices"
- Production-ready patterns, edge cases, performance
- Assume strong programming background
- Include real-world considerations
Level 4 (Graduate): Academic and theoretical depth.
- Example: "Complexity Theory and P vs NP"
- Formal notation, proofs, academic rigor
- Citations and references
- Theoretical foundations
**CRITICAL RULE**: You MUST stay within the selected depth level. Do not mix levels.
# Style Flags
When the user enables style flags, incorporate these elements:
- **Accessibility**: WCAG 2.1 AA compliant, ARIA labels, screen reader friendly, high contrast
- **Visual-heavy**: Diagrams, charts, color coding, visual hierarchy, infographics
- **Technical**: Code snippets, terminal commands, technical terminology, implementation details
- **Conversational**: Friendly tone, direct address, casual language, analogies
- **Humor**: Appropriate jokes, light-hearted examples, playful language (never crude)
# HTML Template Structure
Always use this structure:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>[Topic Title]</title>
<style>
/* Inline CSS here */
body {
max-width: 900px;
margin: 0 auto;
padding: 20px;
font-family: system-ui, -apple-system, sans-serif;
line-height: 1.6;
color: #333;
}
/* More styles */
</style>
</head>
<body>
<!-- Content here -->
</body>
</html>
Image Handling
When images are provided:
- Use external URLs (from Cloudinary)
- Include alt text for accessibility
- Ensure images enhance understanding
- Add captions where appropriate
Example:
<figure>
<img src="https://res.cloudinary.com/..." alt="Diagram showing..." />
<figcaption>Figure 1: Description of diagram</figcaption>
</figure>
Iteration and Refinement
When the user requests changes:
- Read the conversation history to understand context
- Apply changes to the ENTIRE page (regenerate fully)
- Maintain consistency with original depth level
- Preserve style flags unless asked to change
Output Format
Your response must include:
- A brief message to the user (1-2 sentences)
- The complete HTML (wrapped in ```html code block)
Example response format:
I've created an intermediate-level page about JavaScript Promises with code examples and explanations.
```html
<!DOCTYPE html>
...complete HTML...
</html>
# Constraints
- NO external dependencies (CSS frameworks, JavaScript libraries)
- ALL styles must be inline in <style> tag
- ALL scripts must be inline in <script> tag
- Images must use external URLs only (Cloudinary)
- File size: Keep under 500KB when possible
- Must work in Blackboard's content editor
WRONG: Vague System Prompt
You are a helpful assistant that creates educational content. Generate HTML pages based on user requests. Make them look nice.
Issues:
- No specific role definition
- No output format specified
- No depth level guidance
- No constraints defined
- No examples
User Prompt Construction
Building the Initial Generation Prompt
// server/routes/generate.js
const buildInitialPrompt = (config) => {
const { topic, depthLevel, styleFlags = [] } = config;
let prompt = `Create an educational page about: ${topic}\n\n`;
prompt += `Depth Level: ${depthLevel}\n`;
if (styleFlags.length > 0) {
prompt += `Style Flags: ${styleFlags.join(', ')}\n`;
}
return prompt;
};
// Example output:
// "Create an educational page about: JavaScript Async/Await
//
// Depth Level: 2
// Style Flags: visual-heavy, technical"
Building Iteration Prompts
const buildIterationPrompt = (userMessage, previousHtml, config) => {
let prompt = userMessage + '\n\n';
prompt += `Make this change to the existing page.\n`;
prompt += `Maintain Depth Level: ${config.depthLevel}\n`;
// Don't send full HTML back, Claude has it in conversation history
// Just reference it
prompt += `The current page HTML is in the conversation history above.`;
return prompt;
};
Conversation Context Management
CORRECT: Maintaining Context
// server/routes/generate.js
import Anthropic from '@anthropic-ai/sdk';
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY
});
export const generatePage = async (config, userMessage, conversationHistory) => {
// Build messages array with full history
const messages = [
// Include all previous messages for context
...conversationHistory.map(msg => ({
role: msg.role,
content: msg.content
})),
// Add new user message
{
role: 'user',
content: buildPrompt(config, userMessage)
}
];
try {
const response = await anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 8192, // Enough for full HTML page
system: systemPrompt, // From server/prompts/system.txt
messages: messages,
temperature: 1.0 // Default creativity
});
return {
message: extractMessage(response.content[0].text),
html: extractHTML(response.content[0].text)
};
} catch (error) {
throw new Error(`Claude API error: ${error.message}`);
}
};
Extracting HTML from Response
const extractHTML = (responseText) => {
// Claude wraps HTML in ```html code blocks
const htmlMatch = responseText.match(/```html\n([\s\S]*?)\n```/);
if (htmlMatch) {
return htmlMatch[1].trim();
}
// Fallback: look for <!DOCTYPE html>
const doctypeMatch = responseText.match(/<!DOCTYPE html>[\s\S]*/i);
if (doctypeMatch) {
return doctypeMatch[0].trim();
}
throw new Error('Could not extract HTML from response');
};
const extractMessage = (responseText) => {
// Get text before the ```html code block
const parts = responseText.split('```html');
return parts[0].trim();
};
Streaming Responses Pattern
For better UX with long generations:
export const generatePageStream = async (config, userMessage, history, onChunk) => {
const messages = [
...history.map(msg => ({ role: msg.role, content: msg.content })),
{ role: 'user', content: buildPrompt(config, userMessage) }
];
const stream = await anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 8192,
system: systemPrompt,
messages: messages,
stream: true // Enable streaming
});
let fullText = '';
for await (const chunk of stream) {
if (chunk.type === 'content_block_delta' && chunk.delta.type === 'text_delta') {
const text = chunk.delta.text;
fullText += text;
// Send incremental updates
onChunk({
type: 'text',
content: text,
fullText: fullText
});
} else if (chunk.type === 'message_stop') {
onChunk({
type: 'done',
message: extractMessage(fullText),
html: extractHTML(fullText)
});
}
}
};
Depth Level Enforcement
The system prompt defines depth levels, but you can add safeguards:
const validateDepthLevel = (config, generatedHtml) => {
const { depthLevel } = config;
// Simple heuristics (not foolproof, but helpful)
const codeBlocks = (generatedHtml.match(/<code>/g) || []).length;
const wordCount = generatedHtml.split(/\s+/).length;
const warnings = [];
if (depthLevel === 0 && wordCount > 200) {
warnings.push('Level 0 should be more concise');
}
if (depthLevel === 1 && codeBlocks > 2) {
warnings.push('Level 1 should avoid code examples');
}
if (depthLevel === 4 && !generatedHtml.includes('theorem') && !generatedHtml.includes('proof')) {
warnings.push('Level 4 should include formal academic content');
}
return warnings;
};
Image Integration Prompts
Requesting Image Generation
// When user says "generate a diagram of X"
const imageGenerationPrompt = `
The user has requested an image: "${userRequest}"
I will now generate this image using DALL-E and provide the URL. Once you have the URL, incorporate it into the page with:
- Appropriate placement in the content flow
- Descriptive alt text for accessibility
- A caption explaining the image
- Styling that fits the page design
`;
Adding User-Provided Images
const addImagePrompt = (imageUrl, description) => `
Add this image to the page:
URL: ${imageUrl}
Description: ${description || 'User-provided image'}
Place it where it makes most sense in the content and add appropriate styling.
`;
Error Handling in Prompts
Handling Generation Failures
const handleGenerationError = async (error, config, userMessage, history) => {
if (error.message.includes('max_tokens')) {
// Response too long - ask Claude to shorten
const retryPrompt = `${userMessage}\n\nNote: Please make the content more concise to fit within token limits.`;
return generatePage(config, retryPrompt, history);
}
if (error.message.includes('rate_limit')) {
// Rate limited - wait and retry
await new Promise(resolve => setTimeout(resolve, 2000));
return generatePage(config, userMessage, history);
}
throw error;
};
Testing Prompts
Always test prompts with various inputs:
// Test depth levels
const testDepthLevels = async () => {
const topic = 'JavaScript Promises';
for (let level = 0; level <= 4; level++) {
const result = await generatePage(
{ topic, depthLevel: level, styleFlags: [] },
`Create a page about ${topic}`,
[]
);
console.log(`Level ${level}:`, {
wordCount: result.html.split(/\s+/).length,
hasCode: result.html.includes('<code>'),
hasExamples: result.html.toLowerCase().includes('example')
});
}
};
// Test style flags
const testStyleFlags = async () => {
const combinations = [
['accessibility'],
['visual-heavy'],
['technical', 'conversational'],
['humor', 'visual-heavy']
];
for (const flags of combinations) {
const result = await generatePage(
{ topic: 'CSS Grid', depthLevel: 2, styleFlags: flags },
'Create a page about CSS Grid',
[]
);
console.log(`Flags ${flags.join(', ')}:`, {
hasAriaLabels: result.html.includes('aria-'),
hasVisuals: result.html.includes('<svg>') || result.html.includes('style='),
hasCode: result.html.includes('<code>'),
hasHumor: /😄|🎉|funny|joke/i.test(result.html)
});
}
};
Checklist
Before Implementing Prompt
- Clear role and purpose defined
- Output format specified
- Constraints explicitly stated
- Examples provided where helpful
- Edge cases considered
After Implementing Prompt
- Tested with various inputs
- Depth levels enforced correctly
- Style flags working as expected
- HTML extraction reliable
- Error cases handled
- Conversation context maintained
- Token usage reasonable
Integration with Other Skills
- express-api-patterns: Implementing prompt endpoints
- api-client-patterns: Calling Claude API from client
- systematic-debugging: Debugging prompt issues
- react-component-patterns: Displaying generated content
Common Mistakes to Avoid
- ❌ Vague instructions in system prompt
- ❌ Not maintaining conversation history
- ❌ Missing output format specification
- ❌ No examples in system prompt
- ❌ Forgetting to extract HTML from response
- ❌ Not handling streaming properly
- ❌ Ignoring token limits
- ❌ Not testing with edge cases
- ❌ Missing error handling for API failures
- ❌ Not enforcing depth level constraints
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?