Skip to content
Skill Authoring
Skill

/writing-prompts

How to write LLM system prompts: role, structured output, injection resistance.

BOOST
From plugin
nlpm
15317 skills8 agents15 commands1 hook
Install
$ npx -y skills add xiaolai/nlpm --skill writing-prompts --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/writing-prompts

Context preview

The summary Claude sees to decide when to auto-load this skill.

How to write LLM system prompts: role, structured output, injection resistance.

SKILL.md

writing-prompts.SKILL.md
name: writing-prompts
description: "How to write LLM system prompts: role, structured output, injection resistance."
version: 0.1.0
user-invocable: false

Writing Prompts

> Scope: covers universal prompt engineering for any LLM. For Claude Code agent prompts specifically, see [[writing-agents]]. For Claude Code rules, see [[writing-rules]].

1. The Five Layers

Every effective prompt has five layers, in order. Missing a layer degrades output quality predictably.

1. Role       → WHO the AI is
2. Context    → WHAT it's working with
3. Task       → WHAT to do
4. Constraints → WHAT NOT to do
5. Output     → HOW to format the result

Layer Impact on Output Quality

| Layers present | Typical output quality | Common failure mode | |---------------|----------------------|---------------------| | Task only | 30% -- wildly variable | Different format every time, scope creep | | Role + Task | 55% -- decent but inconsistent | Right expertise, wrong format | | Role + Task + Output | 75% -- consistent format | Scope creep, over-generation | | Role + Task + Constraints + Output | 88% -- reliable | Missing edge case handling | | All five layers | 95% -- production-grade | Rare failures on adversarial input |

Layer 1: Role

Define expertise and perspective, not personality.

**Bad**: `"You are a helpful, friendly AI assistant."` **Good**: `"You are a senior security auditor specializing in OWASP Top 10 vulnerabilities in Python web applications."`

Role specificity ladder:

Generic:    "You are an AI assistant"                          → 0 signal
Domain:     "You are a security expert"                        → weak signal
Specific:   "You are a security auditor specializing in OWASP" → strong signal
Grounded:   "You are a security auditor at a fintech company   → strongest signal
             reviewing Django applications for PCI compliance"

Layer 2: Context

Tell the AI what it will receive and what domain it's operating in.

You will receive pull request diffs from a Django 4.2 application
that handles financial transactions. The application uses PostgreSQL,
Celery for async tasks, and Redis for caching.

Layer 3: Task

Specify what to do. Use numbered steps for multi-step tasks.

1. Identify all SQL queries that use string concatenation or f-strings
2. Check every endpoint for authentication decorators
3. Verify all user input is validated before database insertion
4. Flag any hardcoded secrets or API keys

Layer 4: Constraints

Boundaries prevent scope creep and hallucination.

- Do NOT suggest code fixes; only identify issues
- Do NOT report style issues (formatting, naming)
- Limit findings to 10 most critical issues
- If unsure whether something is a vulnerability, include it with severity "uncertain"

Layer 5: Output Format

Specify the exact structure. See section 3 below.

2. Specificity Ladder

Every instruction can be made more specific. More specific = more consistent output.

Three Levels

| Level | Instruction | Output consistency | |-------|------------|-------------------| | Vague | "Review the code" | 20% -- does something different each time | | Specific | "Check for SQL injection, XSS, and auth bypass" | 70% -- covers the right areas | | Measurable | "Check every string concatenation in SQL queries, every unescaped user input in templates, every endpoint without `@login_required`" | 95% -- reproducible results |

Converting Vague to Measurable

| Vague instruction | Specific | Measurable | |-------------------|----------|-----------| | "Summarize this" | "Write a 3-paragraph summary" | "Write exactly 3 paragraphs: (1) main thesis, (2) key evidence, (3) implications. Each paragraph 2-4 sentences." | | "Clean up this code" | "Refactor for readability" | "Extract functions > 30 lines, rename single-letter variables, add JSDoc to exported functions" | | "Check for errors" | "Find bugs and issues" | "Check for: null dereferences, unclosed resources, race conditions, integer overflow" |

3. Structured Output

When you need parseable output, specify the **exact** format. Leave nothing to interpretation.

JSON Output

Return ONLY a JSON object with this exact schema:
{
  "findings": [
    {
      "severity": "critical|high|medium|low",
      "file": "string — relative path",
      "line": "number",
      "description": "string — one sentence"
    }
  ],
  "summary": "string — one paragraph overview",
  "pass": "boolean — true if no critical/high findings"
}

Do not include markdown formatting, code fences, or commentary outside the JSON.
Do not add fields not listed above.

Markdown Table Output

Return a markdown table with exactly these columns:

| File | Line | Finding | Severity | Fix |
|------|------|-------|----------|-----|

One row per finding. Severity must be one of: critical, high, medium, low.
After the table, add a one-line summary: "Found {N} issues: {X} critical, {Y} high, {Z} medium, {W} low"

Enum Enforcement

When a field has fixed values, list them explicitly:

severity must be exactly one of: "critical", "high", "medium", "low"
status must be exactly one of: "pass", "warn", "fail"
type must be exactly one of: "bug", "security", "performance", "style"

4. Few-Shot Examples

For complex tasks, 2-3 input/output examples eliminate ambiguity better than paragraphs of instructions.

When to Use Few-Shot

| Situation | Few-shot needed? | |-----------|-----------------| | Simple extraction (names, dates) | No -- instructions suffice | | Format-sensitive output (specific JSON shape) | Yes -- 1 example | | Judgment calls (severity classification) | Yes -- 2-3 examples showing different severities | | Style matching (writing in a specific voice) | Yes -- 2-3 examples of the target style | | Edge case handling | Yes -- 1 example of the edge case |

Example Structure

## Examples

### Example 1 — Critical severity
Input:
` ` `python
query = "
Read more
Ships withnlpm

Natural-Language Programming Manager — score, check, fix, and test NL artifacts across Claude Code, Codex CLI, and Antigravity. Tier-aware scoring with per-tool overlays. Part of the xiaolai plugin marketplace.

Get the whole plugin

Other skills on nlpm.