Mert Özen Her Satırda Daha İleri
Yapay Zeka Claude Code — #05

Claude Code'da Skills ve Slash Command'lar: Tekrar Eden İşleri Paketlemek

Mert Özen 15 Kas 2026 11 dk 3 görüntülenme
Claude Code'da Skills ve Slash Command'lar: Tekrar Eden İşleri Paketlemek

Claude Code'da tekrar eden bir prosedürün yeri CLAUDE.md değil skill'dir: session başında yalnız açıklaması listelenir, içeriği çağrılınca yüklenir; yan etkili işlerde disable-model-invocation ile yalnız senin çağırmana izin verilir. Bundled skill'ler, custom command'ların skill'lerle birleşmesi, konumlar ve öncelik, allowed-tools'un kısıt değil izin olması, Bookstore için /add-migration ve angular-component skill'leri.

Sürüm notu: Bu yazı Claude Code 2.1.325'i (13 Kasım 2026) anlatır; skill konumları, frontmatter alanları ve bundled skill listesi 15 Kasım 2026'da code.claude.com/docs'taki Extend Claude with skills ve Commands sayfalarından kontrol edilmiştir. Bu yazıda resmî belgelerden yararlanılmıştır. Örnek SKILL.md dosyalarının frontmatter'ı yerelde ayrıştırılıp doğrulanmıştır.

Önce Tahmin Et

Emre, sitedeki serilerin ortak örnek uygulaması Bookstore'da (bir online kitapçı) migration eklemenin adımlarını her seferinde yazmaktan yoruldu ve bir skill yazdı. Açıklamaya "Helps with database stuff" yazdı, onay sorularından kurtulmak için de allowed-tools: Bash(*) ekledi. Sonuç karışık oldu: "Book tablosuna kolon ekle" dediğinde skill devreye girmedi, ertesi gün bir SQL sorgusunun neden yavaş olduğunu sorduğunda ise Claude skill'i yükleyip istenmemiş bir migration oluşturdu.

Tahminin ne? Skill neden istenen yerde değil de istenmeyen yerde tetiklendi? Ve allowed-tools: Bash(*) satırı tam olarak ne yapıyor: skill'in kullanabileceği tool'ları mı sınırlıyor, yoksa başka bir şey mi? Birinci cevap context maliyeti bölümünde, ikincisi /add-migration bölümünde.

Skill'lerin Copilot'taki karşılığını GitHub Copilot serisinin altıncı yazısında, kod için yazılan prompt'ların doğrulanabilir hâle getirilmesini de Prompt Engineering Uygulamada serisinin altıncı yazısında anlatmıştık. Burada Claude Code'un skill sistemine odaklanıyoruz: nerede durur, ne zaman yüklenir, ne kadar context harcar ve Bookstore'da hangi tekrarları paketler.

Built-in Command'lar ve Bundled Skill'ler

Prompt'a / yazdığında açılan menüde iki tür şey var. Bir kısmı Claude Code'un kendi komutları: /clear, /compact, /permissions, /memory, /model gibi. Commands sayfasında bir kısmının yanında ise "Skill" etiketi var; bunlar Claude Code'la birlikte gelen bundled skill'ler:

  • /code-review (takma adı /review): mevcut diff'i, bir pull request'i ya da bir branch'i doğruluk hataları açısından inceler; --fix ile bulguları uygular.
  • /simplify: değişen kodu tekrar kullanım, sadeleştirme ve verimlilik açısından dört paralel agent'la inceler ve düzeltmeleri uygular; doğruluk hatası aramaz.
  • /batch: büyük bir değişikliği 5 ile 30 arası bağımsız birime böler, plan sunar ve onaydan sonra her birim için izole bir worktree'de arka plan subagent'ı başlatır.
  • /debug, /doctor: session için debug log'u açıp okur / kurulum, ayar ve CLAUDE.md sorunlarını tarar.
  • /run, /verify: uygulamayı başlatıp değişikliği çalışırken görür / build edip çalıştırarak değişikliğin istenen şeyi yaptığını doğrular.
  • /loop, /claude-api: bir prompt'u session açıkken aralıklarla tekrarlar / Claude API ve Managed Agents referansını yükler.

Eski Claude Code sürümlerinde kendi slash command'larını .claude/commands/ altına Markdown dosyası olarak yazıyordun. Belgelere göre custom command'lar artık skill'lerle birleşti: .claude/commands/add-migration.md çalışmaya devam ediyor ve .claude/skills/add-migration/SKILL.md ile aynı /add-migration komutunu üretiyor. İkisi aynı adla varsa skill kazanıyor. Yeni iş için skill öneriliyor, çünkü yalnız skill'ler yanında referans dosyası ve script taşıyabiliyor.

Skill Nedir, Nerede Durur?

Skill, içinde bir SKILL.md dosyası olan bir klasör. Dosyanın başında YAML (girintiyle yazılan bir configuration formatı) frontmatter'ı, altında Markdown talimatlar var. Claude skill'i ilgili gördüğünde kendisi yükleyebiliyor ya da sen /skill-name ile çağırıyorsun. Konumlar ve aynı ad çakışmasında hangisinin kazandığı:

KonumYolKapsam
EnterpriseManaged settings klasöründe .claude/skills/<name>/SKILL.mdOrganizasyonun dağıttığı makineler; en yüksek öncelik
Personal~/.claude/skills/<name>/SKILL.mdBu makinedeki bütün projelerin; project'in önünde
Project.claude/skills/<name>/SKILL.mdBu repo'daki session'lar
Nested<folder>/.claude/skills/<name>/SKILL.mdClaude o klasörde bir dosya okuyunca ya da düzenleyince yüklenir
Plugin<plugin>/skills/<name>/SKILL.md/plugin-name:skill-name olarak, çakışmadan

Öncelik sırasının pratik sonucu önemli: Emre'nin ~/.claude/skills/add-migration diye kişisel bir kopyası varsa, ekibin repo'daki /add-migration'ı onun session'larında hiç çalışmaz. Ekip skill'lerinin kişisel kopyalarını tutma. Proje skill'leri, Claude Code'u başlattığın dizinden repo köküne kadar her üst dizinden yükleniyor; bu yüzden web/bookstore-web içinde başlatılan bir session da kökteki skill'leri görüyor. Skill klasörlerindeki değişiklikler session'ı yeniden başlatmadan algılanıyor. claude.ai hesabında açık olan skill'ler de terminal session'larına ~/.claude/skills/synced/ altına iniyor.

Context Maliyeti: Neden CLAUDE.md'den Skill'e?

İkinci yazıda çok adımlı prosedürleri CLAUDE.md'den çıkarmayı önermiştik; nedeni yüklenme biçimi. CLAUDE.md her session'da tamamıyla context'te. Skill'lerde ise session başında yalnız açıklamalar listeleniyor; tam içerik ancak skill çağrıldığında yükleniyor. Claude açıklamaya bakarak skill'in o işe uyup uymadığına karar veriyor, bu yüzden açıklama hem tetikleyici hem de context maliyeti.

Tahmindeki ilk sorunun cevabı burada. "Helps with database stuff" hem çok geniş hem de çok belirsiz bir açıklama: Claude yavaş bir SQL sorgusunu "database stuff" sayabilir, "Book tablosuna kolon ekle" isteğini ise bu cümleyle eşleştirmeyebilir. Belgelerin önerisi, açıklamaya skill'in ne yaptığını ve ne zaman kullanılacağını yazmak ve en önemli kullanım durumunu başa koymak; description ve when_to_use alanları listede birlikte 1.536 karakterde kesiliyor. Asıl kesin çözüm ise migration gibi yan etkisi olan işlerde modelin skill'i kendi kendine çağırmasını tamamen kapatmak: disable-model-invocation: true olan bir skill'in açıklaması context'e hiç girmiyor ve skill yalnız sen /add-migration yazınca çalışıyor.

Çağrıldıktan sonra ne oluyor? Belgelere göre işlenmiş SKILL.md içeriği konuşmaya tek bir mesaj olarak giriyor ve sonraki turlarda orada kalıyor; Claude Code dosyayı her turda yeniden okumuyor. Compaction olduğunda her skill'in en son çağrısı özetin arkasına yeniden ekleniyor, ama her biri için ilk 5.000 token ve hepsi için toplam 25.000 token sınırıyla. Çok sayıda skill çağrılan uzun bir session'da eskiler düşebiliyor. /skills listesinde t tuşu skill'leri token sayısına göre sıralıyor; hangisinin pahalı olduğunu buradan görürsün.

Bookstore: /add-migration

Bookstore'da her migration aynı adımları istiyor: adı kontrol et, build al, migration'ı oluştur, SQL'i üret ve oku, veri kaybı riskini raporla, geri dönüş notunu yaz. Bu bir prosedür, yani tam bir skill işi. .claude/skills/add-migration/SKILL.md:

---
name: add-migration
description: Create a new EF Core migration in Bookstore.Api, review the generated SQL and write rollback notes. Run only when the user invokes /add-migration.
argument-hint: "[MigrationName]"
arguments: [name]
disable-model-invocation: true
allowed-tools:
  - Bash(dotnet build Bookstore.slnx)
  - Bash(dotnet ef migrations list *)
  - Bash(dotnet ef migrations add *)
  - Bash(dotnet ef migrations script *)
  - PowerShell(dotnet build Bookstore.slnx)
  - PowerShell(dotnet ef migrations list *)
  - PowerShell(dotnet ef migrations add *)
  - PowerShell(dotnet ef migrations script *)
---

# Add an EF Core migration

Migration name: $name

1. If the name is empty or not PascalCase (for example `AddLowStockAlerts`), ask for a name and stop.
2. Build the solution: `dotnet build Bookstore.slnx`. Stop and report if the build fails.
3. Find the latest existing migration: `dotnet ef migrations list --project src/Bookstore.Api`.
4. Create the migration:
   `dotnet ef migrations add $name --project src/Bookstore.Api --output-dir Data/Migrations`
5. Generate the SQL from the previous migration to the new one:
   `dotnet ef migrations script <Previous> $name --project src/Bookstore.Api --output artifacts/migrations/$name.sql`
6. Read the migration and the SQL, then report:
   - tables and columns that are added, changed or dropped
   - anything that can lose data: dropped columns, narrowed types, NOT NULL without a default
   - indexes the new queries need that the migration does not create
7. Write `artifacts/migrations/$name.rollback.md` with the previous migration name and the command
   `dotnet ef database update <Previous> --project src/Bookstore.Api`.

Never apply the migration to a database and never edit an existing migration.

Alanları tek tek okuyalım. arguments: [name] ilk argümanı $name olarak içeriğe yerleştiriyor; /add-migration AddLowStockAlerts yazınca her $name o değere dönüşüyor. İçerikte hiç yer tutucu olmasaydı Claude Code yazdığını ARGUMENTS: <value> olarak içeriğin sonuna ekleyecekti. argument-hint yalnız otomatik tamamlamada görünen ipucu. disable-model-invocation: true skill'i yalnız senin çağırabileceğin bir komuta çeviriyor.

Tahmindeki ikinci sorunun cevabı allowed-tools'ta. Belgelere göre bu alan tool'ları sınırlamıyor; skill'i çağıran turda listedeki tool'ların sana sormadan kullanılmasına izin veriyor ve bu izin bir sonraki mesajını gönderdiğinde siliniyor. Diğer bütün tool'lar çağrılabilir kalıyor ve permission ayarların onlar için geçerli olmaya devam ediyor. Yani Emre'nin Bash(*) satırı, skill'in çalıştığı turda her shell komutunu sorgusuz onaylamak demekti. Tool'ları gerçekten kısıtlamak istiyorsan ayrı bir alan var: disallowed-tools. Bizim listemizde yalnız build ve dört dotnet ef alt komutu var, her biri Bash ve PowerShell için; veritabanını değiştiren dotnet ef database update bilerek yok, üçüncü yazıdaki ask kuralı onun için yine soru sorduruyor.

Bookstore: angular-component

İkinci skill bir prosedür değil, bir template: proje kurallarına uygun bir Angular component'i oluşturmak. Bunu Claude'un kendi kendine kullanmasını istiyoruz, ama yalnız Angular tarafında çalışırken. .claude/skills/angular-component/SKILL.md:

---
name: angular-component
description: Scaffold a standalone Angular component in web/bookstore-web that follows the project conventions (signals, OnPush, spec file). Use when creating a new component, page or dialog in the Angular client.
paths:
  - "web/bookstore-web/src/**"
---

# Angular component for bookstore-web

Create the component the user asked for. Before writing files, read the folder layout and naming rules in [reference.md](reference.md).

1. Put the files in the feature folder `web/bookstore-web/src/app/<feature>/`: `<name>.ts`, `<name>.html` and `<name>.spec.ts`.
2. The component is standalone, uses `ChangeDetectionStrategy.OnPush`, keeps its state in signals and gets data from a service in `src/app/core`.
3. Use the `input()` and `output()` functions, not decorators.
4. Write at least one test that renders the component with test data.
5. Run `npm test` in `web/bookstore-web` and show the test summary.

Aynı klasördeki reference.md, skill çağrılmadan context'e girmiyor; SKILL.md ondan bir bağlantıyla söz ettiği için Claude gerektiğinde açıp okuyor. Belgeler SKILL.md'yi 500 satırın altında tutmayı ve ayrıntılı referansı bu tür dosyalara taşımayı öneriyor:

# bookstore-web layout

- `src/app/core/`: API services (`CatalogApi`, `OrdersApi`), interceptors and models shared by features
- `src/app/catalog/`, `src/app/cart/`, `src/app/checkout/`, `src/app/orders/`, `src/app/admin/`: one folder per feature
- Each feature exports its routes from `<feature>.routes.ts`; `app.routes.ts` lazy-loads them
- File names are kebab-case without a `.component` suffix: `low-stock-list.ts` holds the class `LowStockList`
- Shared test data lives in `src/testing/` (books: Dune, Emma, The Hobbit)

paths alanı, skill'in yalnız eşleşen dosyalarla çalışılırken otomatik yüklenmesini sağlıyor; pattern'ler Claude'un çalışma dizinine göre. Backend üzerinde çalışan bir session'da Claude bu skill'i kendiliğinden yüklemiyor, ama sen /angular-component yazarak her zaman çağırabiliyorsun. Bu skill ikinci yazıdaki Angular kural dosyasının yerine geçmiyor: kural dosyası her .ts düzenlemesinde geçerli olan kısa kuralları taşıyor, skill ise yeni bir component oluşturmanın adımlarını.

Frontmatter'ın Geri Kalanı

context: fork skill'i ayrı bir subagent'ta çalıştırıyor; agent alanı hangi subagent türünün kullanılacağını seçiyor (örneğin keşif için Explore). Fork edilen subagent konuşma geçmişini görmüyor, skill içeriğini görev olarak alıyor; bu yüzden talimatların kendi başına anlaşılır olması gerekiyor. background yalnız fork ile anlam taşıyor ve varsayılan true; sonucu aynı turda beklemek için false yapılıyor. Subagent'ları altıncı yazıda ayrıntılı göreceğiz.

model ve effort o turun geri kalanı için modeli ve effort seviyesini değiştiriyor, ayarlara kaydedilmiyor; basit bir template işi için küçük bir model seçmek maliyeti düşürür. Skill içeriğine ! ve backtick'le yazılan bir komut, Claude skill'i görmeden önce çalıştırılıp çıktısı içeriğe yerleştiriliyor; örneğin güncel git diff'i skill'e eklemek için. Bu komutların hangi shell'de çalışacağını shell alanı belirliyor: varsayılan bash, Git for Windows'u olmayan bir ekip için powershell.

Erişimi Yönetmek ve Taşınabilirlik

Skill'ler de permission sistemine bağlı. Skill deny kuralı bütün skill'leri, Skill(add-migration) ya da Skill(deploy *) gibi kurallar tek tek skill'leri hedefliyor. Ayarlardaki skillOverrides bir skill'i "on", "name-only", "user-invocable-only" ya da "off" yapabiliyor; kendi yazmadığın bir plugin skill'inin açıklamasının context'e girmesini istemiyorsan işe yarıyor. Bundled skill'lerin hepsini disableBundledSkills kapatıyor; ama ikinci yazıdaki /doctor prompt-audit bundled /claude-api skill'ini kullandığı için o da kapanıyor.

Claude Code skill'leri açık Agent Skills standardını izliyor. Ama taşınabilirliğin bir sınırı var: claude.ai'a yüklenen ya da Skills API ile kullanılan bir skill'de yalnız name, description, license, compatibility, metadata ve allowed-tools alanları kabul ediliyor; argument-hint gibi Claude Code'a özgü bir alan yükleme hatası veriyor, ! ile komut çalıştırma da orada çalışmıyor. Ekip skill'lerini Claude uygulamalarında da kullanmayı düşünüyorsan, Claude ile Çalışmak serisindeki skill yazısında anlatılan biçime uygun ayrı bir sürüm tut.

Üretimde Dikkat

Skill'leri kod gibi review et. Bir skill, çağrıldığı turda tool izni verebiliyor ve ! ile komut çalıştırabiliyor; repo'ya eklenen bir skill ekipteki herkesin session'ında çalışan bir talimat seti demek. Belgelere göre proje skill'lerinin allowed-tools ve hook'ları, klasör güvenilir olarak işaretlenmeden de kullanılabiliyor; güvenmediğin bir repo'da claude -p çalıştırmadan önce bunu hesaba kat.

Yan etkisi olan her skill'e disable-model-invocation: true koy: migration, deploy, commit, dış servise mesaj. Claude'un kendi kararıyla çalıştırması gereken skill'ler bilgi ve template skill'leri olsun.

Context bütçesini izle. Her yeni skill'in açıklaması her session'da yer kaplıyor; /skills listesinde token sayısına göre sıralayıp az kullanılanları kapat ya da name-only yap.

Sık Düşülen Tuzaklar

Belirsiz açıklama. "Helps with database stuff" ya hiç tetiklenmez ya da her yerde tetiklenir. Ne yaptığını, ne zaman kullanılacağını ve en önemli durumu ilk cümlede yaz.

allowed-tools'u bir kısıt sanmak. Bu alan izin verir, sınırlamaz. Geniş bir liste, skill çağrıldığında sorgusuz çalışan geniş bir komut ailesi demek. Kısıt için disallowed-tools.

İş akışlarını CLAUDE.md'de bırakmak. Her session'da gereksiz yere yüklenen bir prosedür, hem context'i hem uyumu harcıyor. Prosedür skill'e, kısa kural CLAUDE.md'ye.

Kişisel kopya tutmak. Personal skill project skill'inin önüne geçtiği için ekibin güncellediği skill senin session'ında hiç çalışmaz.

Fork edilen skill'e konuşmaya dayanan talimat yazmak. context: fork konuşma geçmişini görmez; "yukarıda konuştuğumuz endpoint" ona bir şey ifade etmez.

Küçük Bir Deneme

★☆☆ /skills listesini aç, t ile token sayısına göre sırala ve en pahalı üç skill'in açıklamasını oku. Hangisi gerçekten her session'da listelenmeye değer?

★★☆ Kendi projende tekrar eden bir prosedürü disable-model-invocation: true olan bir skill'e çevir ve CLAUDE.md'den çıkar. Bir hafta boyunca /context çıktısında memory dosyalarının kapladığı yerin nasıl değiştiğini not et.

★★★ Aynı skill'i iki açıklamayla dene: biri belirsiz, biri "ne yapar + ne zaman" yapısında. Beş farklı istek yaz (ikisi skill'e uygun, üçü değil) ve her açıklamayla Claude'un skill'i hangi isteklerde yüklediğini kaydet.

Skill'ler talimatı paketliyor ama işi yine ana konuşmanın context'inde yaptırıyor. Uzun test çıktısının kısa bir raporunu çıkaran, yalnız okuma yetkisiyle EF (Entity Framework; .NET'in veritabanı erişim library'si) Core sorgularını inceleyen ya da kendi context window'unda paralel çalışan yardımcılar için bir sonraki adım subagent'lar. Altıncı yazıda .claude/agents/ ile Bookstore'a üç subagent ekleyeceğiz.