Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Example template for project-specific skill files covering architecture, patterns, testing, and deployment.
.claude/skills/project-guidelines-example/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | 48% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 41% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 74% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 138% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 91% | 0% |
This is an example of a project-specific skill. Use this as a template for your own projects.
Based on a real production application: Zenith - AI-powered customer discovery platform.
Reference this skill when working on the specific project it's designed for. Project skills contain:
Tech Stack:
Services:
┌─────────────────────────────────────────────────────────────┐
│ Frontend │
│ Next.js 15 + TypeScript + TailwindCSS │
│ Deployed: Vercel / Cloud Run │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Backend │
│ FastAPI + Python 3.11 + Pydantic │
│ Deployed: Cloud Run │
└─────────────────────────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Supabase │ │ Claude │ │ Redis │
│ Database │ │ API │ │ Cache │
└──────────┘ └──────────┘ └──────────┘project/
├── frontend/
│ └── src/
│ ├── app/ # Next.js app router pages
│ │ ├── api/ # API routes
│ │ ├── (auth)/ # Auth-protected routes
│ │ └── workspace/ # Main app workspace
│ ├── components/ # React components
│ │ ├── ui/ # Base UI components
│ │ ├── forms/ # Form components
│ │ └── layouts/ # Layout components
│ ├── hooks/ # Custom React hooks
│ ├── lib/ # Utilities
│ ├── types/ # TypeScript definitions
│ └── config/ # Configuration
│
├── backend/
│ ├── routers/ # FastAPI route handlers
│ ├── models.py # Pydantic models
│ ├── main.py # FastAPI app entry
│ ├── auth_system.py # Authentication
│ ├── database.py # Database operations
│ ├── services/ # Business logic
│ └── tests/ # pytest tests
│
├── deploy/ # Deployment configs
├── docs/ # Documentation
└── scripts/ # Utility scriptspythonfrom pydantic import BaseModel from typing import Generic, TypeVar, Optional T = TypeVar('T') class ApiResponse(BaseModel, Generic[T]): success: bool data: Optional[T] = None error: Optional[str] = None @classmethod def ok(cls, data: T) -> "ApiResponse[T]": return cls(success=True, data=data) @classmethod def fail(cls, error: str) -> "ApiResponse[T]": return cls(success=False, error=error)
typescriptinterface ApiResponse<T> { success: boolean data?: T error?: string } async function fetchApi<T>( endpoint: string, options?: RequestInit ): Promise<ApiResponse<T>> { try { const response = await fetch(`/api${endpoint}`, { ...options, headers: { 'Content-Type': 'application/json', ...options?.headers, }, }) if (!response.ok) { return { success: false, error: `HTTP ${response.status}` } } return await response.json() } catch (error) { return { success: false, error: String(error) } } }
pythonfrom anthropic import Anthropic from pydantic import BaseModel class AnalysisResult(BaseModel): summary: str key_points: list[str] confidence: float async def analyze_with_claude(content: str) -> AnalysisResult: client = Anthropic() response = client.messages.create( model="claude-sonnet-4-5-20250514", max_tokens=1024, messages=[{"role": "user", "content": content}], tools=[{ "name": "provide_analysis", "description": "Provide structured analysis", "input_schema": AnalysisResult.model_json_schema() }], tool_choice={"type": "tool", "name": "provide_analysis"} ) # Extract tool use result tool_use = next( block for block in response.content if block.type == "tool_use" ) return AnalysisResult(**tool_use.input)
typescriptimport { useState, useCallback } from 'react' interface UseApiState<T> { data: T | null loading: boolean error: string | null } export function useApi<T>( fetchFn: () => Promise<ApiResponse<T>> ) { const [state, setState] = useState<UseApiState<T>>({ data: null, loading: false, error: null, }) const execute = useCallback(async () => { setState(prev => ({ ...prev, loading: true, error: null })) const result = await fetchFn() if (result.success) { setState({ data: result.data!, loading: false, error: null }) } else { setState({ data: null, loading: false, error: result.error! }) } }, [fetchFn]) return { ...state, execute } }
bash# Run all tests poetry run pytest tests/ # Run with coverage poetry run pytest tests/ --cov=. --cov-report=html # Run specific test file poetry run pytest tests/test_auth.py -v
Test structure:
pythonimport pytest from httpx import AsyncClient from main import app @pytest.fixture async def client(): async with AsyncClient(app=app, base_url="http://test") as ac: yield ac @pytest.mark.asyncio async def test_health_check(client: AsyncClient): response = await client.get("/health") assert response.status_code == 200 assert response.json()["status"] == "healthy"
bash# Run tests npm run test # Run with coverage npm run test -- --coverage # Run E2E tests npm run test:e2e
Test structure:
typescriptimport { render, screen, fireEvent } from '@testing-library/react' import { WorkspacePanel } from './WorkspacePanel' describe('WorkspacePanel', () => { it('renders workspace correctly', () => { render(<WorkspacePanel />) expect(screen.getByRole('main')).toBeInTheDocument() }) it('handles session creation', async () => { render(<WorkspacePanel />) fireEvent.click(screen.getByText('New Session')) expect(await screen.findByText('Session created')).toBeInTheDocument() }) })
npm run build succeeds (frontend)poetry run pytest passes (backend)bash# Build and deploy frontend cd frontend && npm run build gcloud run deploy frontend --source . # Build and deploy backend cd backend gcloud run deploy backend --source .
bash# Frontend (.env.local) NEXT_PUBLIC_API_URL=https://api.example.com NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ... # Backend (.env) DATABASE_URL=postgresql://... ANTHROPIC_API_KEY=sk-ant-... SUPABASE_URL=https://xxx.supabase.co SUPABASE_KEY=eyJ...
coding-standards.md - General coding best practicesbackend-patterns.md - API and database patternsfrontend-patterns.md - React and Next.js patternstdd-workflow/ - Test-driven development methodology| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-05 | fail→pass | 18,597 | 10,414 | -44% | 1 | 1 | 0% | 3,096 | 4,586 | +48% | 0 | 0 | — |
case-01 | fail→pass | 14,832 | 9,720 | -34% | 1 | 1 | 0% | 3,221 | 4,548 | +41% | 0 | 0 | — |
case-02 | fail→pass | 14,208 | 12,417 | -13% | 1 | 1 | 0% | 3,001 | 5,236 | +74% | 0 | 0 | — |
case-03 | fail→pass | 11,123 | 14,457 | +30% | 1 | 1 | 0% | 2,380 | 5,674 | +138% | 0 | 0 | — |
case-04 | fail→pass | 9,352 | 6,247 | -33% | 1 | 1 | 0% | 1,931 | 3,689 | +91% | 0 | 0 | — |
case-06 | fail→pass | 11,799 | 5,716 | -52% | 1 | 1 | 0% | 2,686 | 3,464 | +29% | 0 | 0 | — |
case-07 | fail→pass | 7,909 | 2,468 | -69% | 1 | 1 | 0% | 1,538 | 2,717 | +77% | 0 | 0 | — |
case-08 | fail→pass | 8,703 | 4,366 | -50% | 1 | 1 | 0% | 1,829 | 3,128 | +71% | 0 | 0 | — |
case-09 | fail→pass | 11,653 | 5,690 | -51% | 1 | 1 | 0% | 2,200 | 3,462 | +57% | 0 | 0 | — |
case-10 | pass→pass | 4,627 | 2,928 | -37% | 1 | 1 | 0% | 791 | 2,777 | +251% | 0 | 0 | — |
case-11 | pass→pass | 4,036 | 1,455 | -64% | 1 | 1 | 0% | 661 | 2,452 | +271% | 0 | 0 | — |
case-12 | fail→pass | 8,995 | 1,947 | -78% | 1 | 1 | 0% | 1,477 | 2,507 | +70% | 0 | 0 | — |
case-13 | pass→pass | 12,551 | 8,381 | -33% | 1 | 1 | 0% | 2,115 | 3,941 | +86% | 0 | 0 | — |
case-14 | fail→pass | 10,250 | 2,555 | -75% | 1 | 1 | 0% | 1,890 | 2,655 | +40% | 0 | 0 | — |
case-15 | fail→pass | 3,000 | 1,341 | -55% | 1 | 1 | 0% | 463 | 2,434 | +426% | 0 | 0 | — |
case-16 | fail→pass | 11,657 | 3,116 | -73% | 1 | 1 | 0% | 2,019 | 2,769 | +37% | 0 | 0 | — |
case-17 | pass→pass | 3,537 | 2,347 | -34% | 1 | 1 | 0% | 618 | 2,483 | +302% | 0 | 0 | — |
case-18 | fail→pass | 2,246 | 1,320 | -41% | 1 | 1 | 0% | 317 | 2,429 | +666% | 0 | 0 | — |
case-19 | pass→pass | 7,293 | 5,559 | -24% | 1 | 1 | 0% | 1,479 | 3,115 | +111% | 0 | 0 | — |
case-20 | pass→pass | 14,610 | 14,455 | -1% | 1 | 1 | 0% | 2,703 | 4,770 | +76% | 0 | 0 | — |
case-21 | pass→pass | 11,909 | 7,833 | -34% | 1 | 1 | 0% | 2,511 | 3,964 | +58% | 0 | 0 | — |
case-22 | pass→pass | 14,651 | 9,699 | -34% | 1 | 1 | 0% | 2,806 | 4,087 | +46% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +64 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 7/29/2026 | +59% |
Other measured skills in the registry, with their headline benchmark lift.