Skip to content

What Are Agent Skills and How Do They Differ from Global Instructions

Problem

My context window was getting polluted. I had a CLAUDE.md file with 500+ lines of instructions covering React patterns, TypeScript conventions, testing requirements, security rules, and database schemas. Every time I started a session, all of it loaded.

The problem? I wasn’t always working on React. Sometimes I was writing Python scripts. Sometimes I was documenting APIs. Sometimes I was reviewing SQL queries. But my context always contained those React instructions, consuming tokens whether I needed them or not.

Here’s what my bloated CLAUDE.md looked like:

CLAUDE.md (BEFORE)
# Project Instructions
## React + TypeScript
- Use functional components with hooks
- Prefer named exports
- One component per file
- Props interface before component definition
- Use Zod for runtime validation
... (100 more lines)
## Testing Requirements
- Minimum 80% coverage
- TDD workflow mandatory
- Jest for unit tests
- Playwright for E2E
... (50 more lines)
## Security Guidelines
- No hardcoded secrets
- Validate all inputs
- Parameterized queries only
... (80 more lines)
## Database Conventions
- Use SQLAlchemy ORM
- Repository pattern required
- Migration scripts in alembic/
... (70 more lines)

I was burning tokens on irrelevant instructions. When I asked Claude to write a simple Python script, it had to process all those React rules first. I needed a way to load instructions only when they were relevant.

What Happened?

I searched for solutions and discovered agent skills. The key insight: skills load on-demand, global instructions load automatically.

Here’s the difference:

Global Instructions (CLAUDE.md/AGENTS.md)
┌─────────────────────────────────────────────────────────────────────┐
│ Session Start │
│ │ │
│ ▼ │
│ [CLAUDE.md loads automatically] │
│ │ │
│ ▼ │
│ Context contains ALL instructions │
│ (whether you need them or not) │
└─────────────────────────────────────────────────────────────────────┘
Agent Skills
┌─────────────────────────────────────────────────────────────────────┐
│ Session Start │
│ │ │
│ ▼ │
│ [Only CLAUDE.md loads] │
│ │ │
│ ▼ │
│ User mentions "React component" │
│ │ │
│ ▼ │
│ [React skill loads on-demand] │
│ │ │
│ ▼ │
│ Context contains only relevant instructions │
└─────────────────────────────────────────────────────────────────────┘

This matters for token economics. Smaller instruction files mean fewer tokens consumed. Context efficiency directly impacts response quality and cost.

How I Fixed It

I split my instructions into two tiers: global conventions and specialized skills.

Tier 1: Global Instructions (CLAUDE.md)

I kept only project-wide conventions in my global CLAUDE.md:

~/.claude/CLAUDE.md
# Working Relationship
- Be matter-of-fact, straightforward, and clear
- Challenge my assumptions when appropriate
- Don't be lazy. Do things the right way
# Project Conventions
- Use TypeScript strict mode
- Prefer functional patterns over classes
- Follow immutability patterns
- Handle errors comprehensively
- Validate user inputs
# Git Workflow
- Write descriptive commit messages
- Create branches for features
- Run tests before committing

This stays small (under 50 lines). It loads every session because these rules apply to everything I do.

Tier 2: Specialized Skills

I moved framework-specific instructions into separate skill files:

~/.claude/skills/typescript-react/SKILL.md
---
name: typescript-react
description: |
Use when working with React + TypeScript:
- Component patterns and best practices
- Type definitions for props and state
- Hook usage conventions
---
# React + TypeScript Guidelines
## Component Structure
- One component per file
- Named exports preferred
- Props interface before component
```typescript title="ComponentTemplate.tsx"
interface ButtonProps {
label: string
onClick: () => void
variant?: 'primary' | 'secondary'
}
export function Button({ label, onClick, variant = 'primary' }: ButtonProps) {
return (
<button className={`btn btn-${variant}`} onClick={onClick}>
{label}
</button>
)
}

Hook Patterns

  • Use custom hooks for reusable logic
  • Keep hooks focused on single responsibility
  • Return objects for multiple values, primitives for single values
```markdown title="~/.claude/skills/testing/SKILL.md"
---
name: testing
description: |
Use when writing tests:
- Unit test patterns
- Integration test setup
- E2E test conventions
---
# Testing Guidelines
## Unit Tests
- Follow AAA pattern: Arrange, Act, Assert
- One assertion per test when practical
- Use descriptive test names
```typescript title="example.test.ts"
describe('Button', () => {
it('should render with correct label', () => {
// Arrange
const label = 'Click me'
// Act
render(<Button label={label} onClick={() => {}} />)
// Assert
expect(screen.getByText(label)).toBeInTheDocument()
})
})
```markdown title="~/.claude/skills/security/SKILL.md"
---
name: security
description: |
Use when handling:
- User input validation
- Authentication flows
- Data sanitization
---
# Security Requirements
## Input Validation
- Validate ALL user inputs
- Use Zod schemas for runtime validation
- Never trust client-side data
```typescript title="validation.ts"
import { z } from 'zod'
const UserSchema = z.object({
email: z.string().email(),
age: z.number().int().min(0).max(150),
name: z.string().min(1).max(100)
})
type User = z.infer<typeof UserSchema>
function validateUser(input: unknown): User {
return UserSchema.parse(input)
}
## Why This Works
The front matter in each skill file is key. Claude transforms the `description` field into a tool definition:
```yaml
---
name: typescript-react
description: |
Use when working with React + TypeScript:
- Component patterns and best practices
- Type definitions for props and state
- Hook usage conventions
---

When I start a session, Claude sees available skills as tools. When I say “Create a React component for user login,” Claude recognizes the trigger and loads the typescript-react skill.

Here’s how the loading works:

Before (Bloated Context):
┌────────────────────────────────────────┐
│ Session Context: 500 lines │
│ - React rules (100 lines) │
│ - Testing rules (50 lines) │
│ - Security rules (80 lines) │
│ - Database rules (70 lines) │
│ - Python rules (50 lines) │
│ - General conventions (150 lines) │
└────────────────────────────────────────┘
Tokens consumed: ~8,000
After (Efficient Context):
┌────────────────────────────────────────┐
│ Session Context: 50 lines │
│ - General conventions (50 lines) │
└────────────────────────────────────────┘
Tokens consumed: ~800
When React work requested:
┌────────────────────────────────────────┐
│ Session Context: 150 lines │
│ - General conventions (50 lines) │
│ - React skill (100 lines) │
└────────────────────────────────────────┘
Tokens consumed: ~2,400

The difference is substantial. I reduced my baseline context from 8,000 tokens to 800 tokens. When I need specialized knowledge, it loads automatically.

Common Mistakes I Made

Mistake 1: Putting everything in CLAUDE.md

This was my original problem. I treated CLAUDE.md as a dumping ground for all project knowledge. The result was context pollution.

# BAD: Everything in one file
CLAUDE.md (500 lines)
├── React conventions
├── Python conventions
├── Testing requirements
├── Security rules
├── Database schemas
└── Git workflows
# GOOD: Split by scope
CLAUDE.md (50 lines)
├── Working relationship
├── General conventions
└── Git workflows
skills/
├── typescript-react/SKILL.md
├── testing/SKILL.md
├── security/SKILL.md
└── database/SKILL.md

Mistake 2: Vague skill descriptions

My first skill descriptions were too generic:

# BAD: Vague
description: "React skill"
# GOOD: Specific triggers
description: |
Use when working with React + TypeScript:
- Component patterns and best practices
- Type definitions for props and state
- Hook usage conventions

The description tells Claude when to load the skill. Be specific about triggers.

Mistake 3: Assuming all assistants handle skills identically

I tested this with both Claude Code and GitHub Copilot. They handle instruction files similarly but skills differently:

Feature | Claude Code | GitHub Copilot
---------------------|-------------|---------------
Global instructions | CLAUDE.md | .github/copilot-instructions.md
Skills support | Yes | Limited (prompts only)
Auto-triggering | Yes | Manual

Claude transforms SKILL.md front matter into tools with auto-triggering. Copilot’s equivalent (prompts) requires manual selection.

Organizing Skills

I found this structure works well:

~/.claude/
├── CLAUDE.md # Global instructions (50 lines max)
├── rules/ # Shared rule files
│ ├── coding-style.md
│ ├── testing.md
│ ├── security.md
│ └── git-workflow.md
├── agents/ # Agent definitions
│ ├── planner/
│ ├── tdd-guide/
│ └── code-reviewer/
└── skills/ # On-demand skills
├── typescript-react/
│ └── SKILL.md
├── testing/
│ └── SKILL.md
├── security/
│ └── SKILL.md
└── database/
└── SKILL.md

Each skill folder contains a SKILL.md file with:

  1. Front matter (name, description)
  2. Specific guidelines
  3. Code examples

Summary

In this post, I showed how agent skills differ from global instructions. Skills load on-demand when triggered, while global instructions load automatically every session. The key point is using a two-tier approach: global instructions for baseline conventions, skills for specialized knowledge.

I reduced my baseline context from 500 lines to 50 lines by extracting framework-specific rules into skills. This saves tokens and improves response quality because Claude focuses on relevant instructions.

To implement this:

  1. Audit your current CLAUDE.md for bloat
  2. Identify instructions that only apply to specific tasks
  3. Create skill files with descriptive front matter
  4. Keep global CLAUDE.md under 50 lines

The result is a more efficient context window that loads specialized knowledge only when you need it.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments