Skip to content
AI Field Notes

Part IV · Tools & Infrastructure

14

Agents and Skills

How reusable skill files encode domain knowledge beyond a single session

Every session, the same instructions. "Use our Button component from @/components/ui, not a custom one." "Spacing uses Tailwind's scale, no arbitrary values." "New components get a Storybook story."

It works fine. But you're typing it every time, and the model forgets the moment the session ends. Repeat this across a team and you've got the same conventions being re-explained in every chat, differently each time.

Skills are a different approach: encode the instructions once in a markdown file. The agent reads the relevant skill when it's working in that domain and applies the knowledge — without you re-explaining. Write it once, use it everywhere. Update it once, everyone benefits.

The concept is simple. The difference it makes in a team context is not small.

The building blocks

Three concepts, so the rest of this chapter makes sense.

An agent is an AI that doesn't just answer questions — it takes actions. It reads files, writes code, runs commands, and makes decisions in a loop until the task is done. You give it a goal; it figures out the steps. Think of it as the AI actually doing the work, not just describing how.

A skill is a markdown file that teaches an agent how to handle something specific. It's a set of instructions the agent reads at the right moment: "when working with our design system, follow these conventions." You write it once; every session gets the benefit. Update it once; everyone benefits.

A subagent is an agent running inside another agent. When a task gets complex, the main agent can spin up a specialized worker — "handle the CMS data fetching" or "verify this component against the design tokens" — and delegate. The subagent works in its own context, with its own tools and constraints, then hands back the result.

That's the whole model. An agent does the work. Skills tell it how. Subagents let it split up complicated jobs.

What skills actually are

A skill is a markdown file (or set of files) that contains instructions, context, and conventions for a specific domain. When an agent is working on a task in that domain, it reads the relevant skill and applies the knowledge.

The difference from a system prompt: skills are composable and domain-specific. You might have a skill for Next.js best practices, a skill for your team's coding conventions, and a skill for your company's API patterns. The agent applies whichever skills are relevant to the current task.

vercel-labs/next-skills

A strong public example of this pattern: vercel-labs/next-skills. It's a collection of skills for Next.js development:

next-best-practices is a background skill — it's automatically applied whenever you're working on a Next.js project. It covers:

  • File conventions and project structure
  • Server/Client component boundaries (the most common source of Next.js bugs)
  • Data fetching and mutation patterns
  • Next.js 15+ async APIs
  • Hydration error debugging

next-upgrade is an on-demand skill — you invoke it with /next-upgrade when you need to upgrade between Next.js versions. It applies the official migration guide automatically.

next-cache-components covers the new Cache Components API in Next.js 16 — 'use cache', cache profiles, cacheLife(), cacheTag().

Install them with:

npx skills add vercel-labs/next-skills --skill next-best-practices

A useful second-pass skill: code-simplifier

One pattern I like a lot: let the model implement first, then run a simplification pass before you accept the diff.

That's exactly what Anthropic's official code-simplifier plugin is for. The goal isn't "shorter code at all costs." It's preserving behavior while making recently changed code easier to read and maintain: less nesting, fewer unnecessary abstractions, clearer naming, and less dense conditional logic. The source is public in Anthropic's claude-plugins-official repository.

The use case is straightforward:

  • After a feature that works but feels overbuilt
  • After a bug fix that added too many defensive branches
  • After a refactor that became harder to read than the original

The prompt shapes are simple too:

  • "Simplify this component without changing behavior."
  • "Refine the recently changed functions for clarity."
  • "Preserve the public API, reduce nesting, and remove unnecessary abstractions."

If you use Claude Code, install the official code-simplifier plugin from Claude's plugin marketplace, then use it as a cleanup pass after implementation rather than as your first move. That's the important habit: generation first, simplification second.

Writing your own skills

The real power is writing skills for your specific project. A custom skill for your codebase might include:

  • Your naming conventions (how you name files, functions, components)
  • Your patterns (how you handle auth, how you structure API routes, how you write tests)
  • Your guardrails (what not to do, what to ask before doing)
  • Context about the codebase (what's legacy, what's being migrated, what's in flux)

Skills compose with CLAUDE.md, AGENTS.md, and .cursorrules. Think of them as layers: the skill provides domain knowledge, the project config provides project-specific context, and the task prompt provides the specific request.

Subagents: skills with autonomy

Skills tell an agent what to do. Subagents are agents that do it — they run as specialized workers within a larger task, with their own context, tools, and scope. Think of them as team members you spin up for specific jobs.

Claude Code supports this through AGENTS.md — a file where you define subagents with their own instructions, tool access, and constraints. When the main agent encounters a task that matches a subagent's domain, it delegates.

Example: a Prepr integration agent

Agent for Prepr CMS integration on a Next.js monorepo, invoked automatically when working with CMS data:

---
name: prepr-integration
description: Expert in Prepr CMS integration for this codebase. Handles
  GraphQL queries, fragments, codegen, Apollo client setup, data fetching
  patterns, and preview mode. Use proactively when working with CMS data,
  creating new content types, or connecting frontend pages to Prepr.
---
 
## Architecture Overview
 
- Prepr CMS: GraphQL API at https://graphql.prepr.io/{token}
- Apollo Client: with Next.js App Router via @apollo/client-integration-nextjs
- GraphQL Codegen: generates typed operations from .graphql files
- Fragment Masking: for type-safe fragment data extraction
 
## Key Locations
 
packages/prepr-sdk/
├── src/queries/*.graphql         # GraphQL query documents
├── src/fragments/*.graphql       # Reusable fragments
└── src/generated/                # Auto-generated types + documents
 
## When Creating a New Content Type
 
1. Create the query in packages/prepr-sdk/src/queries/{name}.graphql
2. Use existing fragments from packages/prepr-sdk/src/fragments/
3. Run codegen: pnpm --filter @repo/prepr-sdk codegen
4. Cache the query with React's cache() for request deduplication
5. Add cache tags in fetchOptions.next.tags for on-demand revalidation
6. Include <meta property="prepr:id" content={_id} /> for analytics
 
## Data Fetching Pattern
 
const getResult = cache(async (slug: string) => {
  return getClient().query<GetContentBySlugQuery>({
    query: GetContentBySlugDocument,
    variables: { slug },
    context: { fetchOptions: { next: { tags: ['content', slug] } } },
  });
});
 
## Constraints
 
- Never hardcode the GraphQL URL — use helpers from @repo/prepr-sdk/api
- Always use getFragmentData() to extract typed fragment data
- Always organize imports: external → repo (@repo/) → local (@/)

The description field tells the main agent when to delegate.

Example: a design system expert

Figma-to-code agent with token architecture context and Figma MCP access:

---
name: design-expert
description: Design system expert that verifies Figma designs match
  implementation using design tokens. Use proactively when implementing
  UI from Figma, reviewing components for design compliance, or checking
  that colors/typography/spacing use correct tokens.
---
 
## Figma MCP Tools
 
- get_design_context: generate UI code for a node (always set
  clientLanguages: "typescript,css", clientFrameworks: "react,next")
- get_variable_defs: get Figma variables used in the design
- get_screenshot: visual reference
- get_code_connect_suggestions: link Figma components to code
 
## 4-Layer Token Architecture
 
Layer 1: Primitives   → packages/design-system/colors.css, typography.css
Layer 2: Semantic     → packages/ui/src/globals.css (generates Tailwind utilities)
Layer 3: Component    → packages/ui/src/{atoms|molecules|organisms}/*.css.ts
Layer 4: React        → packages/ui/src/{atoms|molecules|organisms}/*.tsx
 
Rules:
✅ Components use semantic tokens from globals.css
✅ Semantic tokens reference primitives from design-system
❌ NEVER use primitives directly in components
❌ NEVER use arbitrary values (no text-[36px], no #hexvalue)
 
## Workflow
 
1. get_screenshot for visual reference
2. get_design_context for structure
3. get_variable_defs to see Figma tokens
4. Read packages/design-system/colors.css and globals.css for current values
5. Map every Figma variable to an existing token — flag gaps, never invent
6. Check get_code_connect_map for existing component links
7. Report findings with token mapping table and layer compliance checklist
 
## Anti-Patterns to Flag
 
❌ className="text-[36px]"           → text-heading-1 leading-heading-1
❌ className="text-[#hexvalue]"      → text-spinach-500
❌ className="text-2xl md:text-4xl"  → text-heading-1 (responsive via tokens)
❌ className="p-4 mb-8"             → p-component-inner mb-component-outer

It stays current by reading source token files before each review instead of relying on cached knowledge.

Skills as team knowledge

Encode your team's conventions as skills so everyone benefits: update once when conventions change, onboard new developers with accumulated knowledge, and add new patterns as you discover them.

Config Generator

coming soon

Generate .cursorrules, CLAUDE.md, or AGENTS.md for your project

Answer a few questions about your project (framework, team size, AI tools, coding conventions) and get a generated config file ready to copy into your repo. Encodes your conventions so agents follow them automatically — no more repeating yourself in every prompt.

FrameworkNext.js 15 (App Router)
AI toolsCursor + Claude Code
OutputCLAUDE.md
# CLAUDE.md
You are working in a Next.js 15 App Router project.

## Conventions
- Use server components by default
- Client components only when needed (interactivity, hooks)
- Co-locate tests with components
- Use Tailwind for all styling

## Guardrails
- Never delete files without confirmation
- Stay in scope — don't refactor adjacent code
- Ask before changing shared utilities

This tool is being built based on real usage patterns. Check back as the blog evolves.

Workflow Recipe

Copy-pasteable flows and guided workflow finder

Pick a workflow

Prompt

I need to build [feature]. Here’s the spec: inputs, outputs, edge cases, constraints. Produce a plan before writing any code.

Steps

1

Spec

Write a developer spec with inputs, outputs, edge cases, and constraints.

2

Plan

Ask the model to produce a plan — files to create/modify, key decisions. Review before coding.

3

Code

Implement against the plan. One feature, one PR. Pull the model back if it goes out of scope.

4

Review

Ask the model to review its own code: "What edge cases might this miss? What would break this?"

5

Tests

Generate tests from the review’s edge cases: "Write tests for the edge cases you identified."

6

PR description

Generate the PR description from the spec and the diff. Full context produces clear descriptions.

Tools

CursorClaude CodeGitHub Actions

Guardrails

  • One feature, one PR — keep scope tight
  • Review the plan before writing code
  • Don’t let the model touch files outside scope
  • Ask before refactoring adjacent code

Expected output

Working PR with passing CI, clear description, and tests covering the identified edge cases.

Paste into CLAUDE.md, .cursorrules, or your workflow docs

Scenario Lab

Real tasks, real model outputs — see which model wins and why

Paste a stack trace and get a plain-English explanation with a fix suggestion.

~0.8k in~0.5k outsignal: speed

Fast models handle this as well as expensive ones. The answer is either right or obviously wrong — no back-and-forth needed.

🌸
Claude Haiku 4.5Best pickrecommended

Fast, correct, no fluff

What it produced

The error occurs because `user` can be `undefined` when the component first renders. Add a null check: `if (!user) return null;` before accessing `user.name`.

What went right

  • Identified root cause immediately
  • Gave a one-line fix
  • No unnecessary explanation

Cost note

Negligible at any volume

token cost

$0.0033/run

💎
Gemini 3 FlashGood fit

Correct but slightly verbose

Claude Sonnet 4.6Use with care

Correct, but added unrequested refactor suggestions

🧠
Claude Opus 4.6Avoid

Thorough but massively over-engineered for this task

Bottom line

Haiku is fast, cheap, and more than capable for error explanation. Paying for Sonnet or Opus here is waste.

Outputs are curated from real usage. Prices from official API docs, verified 2026-03-20. Anthropic · OpenAI · Google · DeepSeek · Cursor