WHITEPLUS TechBlog

株式会社ホワイトプラスのエンジニアによる開発ブログです。

モノレポでClaude Codeのスキルをチームごとに出し分けたい ― direnvと環境変数で30行で解決した話

こんにちは、ホワイトプラスでエンジニアリングマネージャーをしている仲見川です。

今回は、Claude Codeのスキルをチーム別に管理・配布する仕組みを構築した話を紹介します。

Claude Codeのスキルとは

スキルは、Claude Codeの能力を拡張する仕組みです。SKILL.md ファイルに指示を記述すると、Claudeがそれを自身のツールキットに追加します。Claudeは会話の内容に応じてスキルを自動的に利用するほか、/skill-name で直接呼び出すこともできます。

たとえば「DDD構成要素の実装規約」「テストコードのパターン」といったプロジェクト固有のルールをスキルとして定義しておくと、Claude Codeがコード実装時に自動でそのルールに従って動作してくれます。

スキルは .claude/skills/ 配下にディレクトリを作り、その中にエントリーポイントとなる SKILL.md と、必要に応じてサポートファイル(詳細なリファレンスやテンプレート等)を配置します。

my-skill/
├── SKILL.md           # メインの指示(必須)
├── scripts/           # 実行可能なコード(Python/Bash等, オプション)
├── reference.md       # 詳細なリファレンス(オプション)
├── assets/            # テンプレート、フォント等の出力用素材(オプション)
└── examples/
    └── sample.md      # 出力例(オプション)

SKILL.md のフロントマター(ファイル先頭に --- で囲んで記述するYAML形式のメタデータ)に namedescription を定義すると、Claudeが「このスキルをいつ使うべきか」を判断できるようになります。フルのスキルコンテンツは呼び出し時にのみロードされるため、大量のスキルがあっても普段のコンテキストを圧迫しません。

背景・課題

この仕組みを構築するきっかけになったのはコアシステムチームのメンバーの社内チャットでのつぶやきでした。

ゆるぼ:Claude CodeのSkills使ってる方

個人用で使うskillsをどこで管理しているか
lenetリポジトリの.claude配下におくとgit管理されて全員に適用されちゃうので
個人用skillsを作りたいというモチベがある。ホームディレクトリで管理してる?

つぶやきにある「ホームディレクトリで管理してる?」はClaude CodeのPersonalスキル(~/.claude/skills/)を指しています。Personalスキルは全プロジェクトで利用でき、個人用の置き場所としては手軽です。ただし、このやりとりを見ていて、課題は「個人用スキルの置き場所」だけではないと感じました。Personalスキルだけでは以下の点が解決できないからです。

  • チーム固有のスキルを特定のメンバーにだけ配布する手段がない
  • 個人のホームディレクトリに閉じるため、チームへの展開や共有がしづらい
  • プロジェクト固有のルール(アーキテクチャ規約等)をPersonalに置くと、他プロジェクトでもロードされてしまう

個人で気軽に試す → チームに展開する → 全体に展開する、というスキルの成長パスを作れれば、チームとしてのナレッジ蓄積がもっとスムーズになるのではないかと考え、個人・チーム・全体の3レイヤーで管理する仕組みの構築に着手しました。

「チーム」というレイヤーを設けたのは、弊社の開発体制に理由があります。弊社のプロダクトはほぼモノレポの形をとっており、複数の開発チームが同じリポジトリ上で開発しています。コアシステムチームやCX開発チームといったサーバーサイドのチームはPHP/LaravelでDDD・クリーンアーキテクチャを採用しています。ただし、このチーム間でもDDDの設計を実装に落とし込むルールは異なります。さらにフロントエンドチームにまでサーバーサイド向けのスキルを適用してしまうと、Claudeのコンテキストにノイズが入り逆効果になります。

整理すると、解決すべき課題は以下の3点でした。

  • スキルの適用範囲を制御したい : 全チーム共通のスキルもあれば、特定チームだけが使うスキルもある。関係のないスキルはコンテキストのノイズになるため避けたい
  • 個人用のスキルも気軽に試したい : 試作中のスキルや個人のワークフローに特化したスキルを、チームに影響を与えずに使いたい
  • .claude/skills/ を直接Git管理すると競合する : モノレポ上でチームの異なるメンバーが同じディレクトリにコミットすると収拾がつかなくなる

解決策 : レイヤー別のスキル管理 + direnvによる自動配布

これらの課題に対して、スキルのソースをレイヤー別に分離し、direnvでプロジェクトディレクトリに入ったときに自動的に .claude/skills/ へコピーするという仕組みを導入しました。

ディレクトリ構成

リポジトリのルートに agent-skills/ ディレクトリを設け、3つのレイヤーでスキルを管理します。

agent-skills/
├── all/skills/           # 全チーム共通スキル(Git管理)
├── cx-dev/skills/        # CX開発チーム用スキル(Git管理)
├── coresys/skills/       # コアシステムチーム用スキル(Git管理)
└── local/skills/         # 個人用スキル(Git管理外)

ポイントは以下の3つです。

  • all/ : 全員が使う共通スキルを配置。Git管理される
  • {team}/ : チーム固有のスキルを配置。Git管理される
  • local/ : 個人用スキルを配置。.gitignore で管理外にしている

読み込み順序と上書きルール

スキルは allteamlocal の順でコピーされます。同名のスキルがある場合は後勝ちで上書きされるため、共通スキルをチームやローカルでカスタマイズすることが可能です。

all(共通) → team(チーム固有) → local(個人用)
                                      ↑ 後勝ちで上書き

.envrcの実装

既存の .envrcsetup_claude_skills 関数を追加しました。当プロジェクトではもともとdirenvを利用しており、ディレクトリに入ると .envrc が自動実行されます。この仕組みに乗せる形でスキルの配布を組み込みました。

# Claude Code Skills Setup (Team-based)
setup_claude_skills() {
    local skills_dir=".claude/skills"
    local team="${TEAM:-}"

    # スキルディレクトリを作成
    mkdir -p "$skills_dir"

    # 共通スキル(all)をコピー
    if [ -d "agent-skills/all/skills" ]; then
        cp -r agent-skills/all/skills/* "$skills_dir/" 2>/dev/null || true
        echo "Claude skills loaded: all"
    fi

    # チーム固有スキルをコピー(TEAM未設定ならスキップ)
    if [ -n "$team" ] && [ -d "agent-skills/${team}/skills" ]; then
        cp -r "agent-skills/${team}/skills/"* "$skills_dir/" 2>/dev/null || true
        echo "Claude skills loaded: team=${team}"
    fi

    # ローカルスキルをコピー(後勝ちで上書き可能)
    if [ -d "agent-skills/local/skills" ]; then
        cp -r agent-skills/local/skills/* "$skills_dir/" 2>/dev/null || true
        echo "Claude skills loaded: local"
    fi
}

setup_claude_skills

処理はシンプルで、各レイヤーのディレクトリが存在すれば cp -r でコピーするだけです。2>/dev/null || true としているのは、ディレクトリが空などでエラーになり得るためです。

なお、コピー前に .claude/skills/ を初期化(削除)していない点は意図的な設計です。ファーストリリースの時点では、既存で利用中のスキルが不用意に消えてしまうリスクを避けることを優先しました。そのため、スキルのディレクトリ名が変更された場合に旧名のディレクトリが残り続けるという課題はありますが、まずは安全に導入できることを重視しています。

チーム設定

各開発者は .env_profile(Git管理外の個人設定ファイル)に自分の所属チームを設定します。

# .env_profile
TEAM=coresys   # cx-dev / coresys / cx-front / app / infra など選択

.envrc の冒頭で .env_profilesource しているため、TEAM 環境変数が setup_claude_skills 関数内で参照できます。

.gitignoreの設定

# コピー先はGit管理外(自動生成されるため)
.claude/skills/

# 個人用スキルのソースもGit管理外
agent-skills/local/skills/*/

.claude/skills/ はdirenvで自動生成される一時的なディレクトリなので、Git管理から除外しています。直接ここにファイルを置いても、次回のdirenv実行時に上書きされる点に注意が必要です。

実際のスキル定義の例

この仕組みを導入したところ、きっかけとなったコアシステムチームが早速チーム固有のスキルを作成してくれました。DDD実装規約をスキルとして定義した例を紹介します。

agent-skills/coresys/skills/implementing-php/
├── SKILL.md              # エントリーポイント
├── common.md             # 共通実装ルール
├── usecase.md            # UseCase層の規約
├── entity.md             # エンティティの規約
├── value-object.md       # ValueObjectの規約
├── repository.md         # リポジトリの規約
├── testing.md            # テストコードの規約
└── ...                   # その他DDD構成要素別の規約

SKILL.md のフロントマターで、スキルのメタ情報を定義しています。

---
name: implementing-php
description: "PHP実装時のルールリファレンス。DDD構成要素(UseCase, Entity, ValueObject等)やテストコードの実装規約・パターンを参照する。PHPコードの新規作成・修正について言及された場合に使用してください。"
---

description はClaudeがスキルを自動的にロードするかどうかの判断材料になります。これにより、Claude CodeがPHPコードの実装やテスト作成時に自動でこのスキルを参照し、チームの規約に沿ったコードを生成してくれます。

セットアップ手順

開発者が行う作業は2ステップだけです。

1. .env_profile に所属チームを設定する

TEAM=coresys

弊社環境では.env_profileの内容を.envrc側で読み込み、環境変数に反映しているためexportはしていません。類似の構成にする場合は、.envrc側でsourceするなどしてTEAMが環境変数として参照できる状態にしてください(環境変数に入っていればOKです)。

2. direnv allow を実行する(通常はディレクトリに入ると自動実行)

これだけでチーム用・共通スキルが .claude/skills/ に展開され、Claude Codeから利用可能になります。

まとめ

今回の仕組みのポイントを整理します。

観点 内容
管理単位 全チーム共通 / チーム固有 / 個人用の3レイヤー
配布方法 direnvによる自動コピー(既存の仕組みに相乗り)
上書きルール all → team → local の後勝ち
Git管理 共通・チーム固有はGit管理、個人用とコピー先は管理外
セットアップコスト .env_profile にTEAMを設定するだけ

シェルスクリプト約30行の追加で、チーム別のスキル管理を実現できました。direnvを既に導入しているプロジェクトであれば、同様のアプローチで手軽にスキル配布の仕組みを構築できると思います。

今後は、個人用スキルもGit管理しつつ気軽に編集できる仕組みを考えています。さらに、他のメンバーがどんなスキルを使っているかを可視化して、ナレッジを共有できる仕組みへ発展させていきたいと考えています。「個人で試す → チームに展開 → 全体に展開」という成長パスを、より自然に回せるようにしていくのが次のステップです。


ホワイトプラスでは一緒に働いてくれるエンジニアを募集しています。興味を持っていただけたら、ぜひ採用ページやエントランスブックをご覧ください。