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:
# 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:
# 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 committingThis 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:
---name: typescript-reactdescription: | 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: testingdescription: | 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: securitydescription: | 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-reactdescription: | 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,400The 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 fileCLAUDE.md (500 lines)├── React conventions├── Python conventions├── Testing requirements├── Security rules├── Database schemas└── Git workflows
# GOOD: Split by scopeCLAUDE.md (50 lines)├── Working relationship├── General conventions└── Git workflows
skills/├── typescript-react/SKILL.md├── testing/SKILL.md├── security/SKILL.md└── database/SKILL.mdMistake 2: Vague skill descriptions
My first skill descriptions were too generic:
# BAD: Vaguedescription: "React skill"
# GOOD: Specific triggersdescription: | Use when working with React + TypeScript: - Component patterns and best practices - Type definitions for props and state - Hook usage conventionsThe 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.mdSkills support | Yes | Limited (prompts only)Auto-triggering | Yes | ManualClaude 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.mdEach skill folder contains a SKILL.md file with:
- Front matter (name, description)
- Specific guidelines
- 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:
- Audit your current CLAUDE.md for bloat
- Identify instructions that only apply to specific tasks
- Create skill files with descriptive front matter
- 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