この記事は CyberAgent Developers Advent Calendar 2025 8日目の記事です。
1. はじめに
こんにちは!
CIU(CyberAgent group Infrastructure Unit) Computing & Web Serviceセクション の近藤です。普段の業務では、CyberAgent のプライベートクラウドである “Cycloud” の IaaS 基盤の開発・運用を担当しています。
IaaS 基盤と言うと、インフラ運用が中心でモダンなソフトウェア開発とは距離がある、というイメージを持たれる方もいるかもしれません。しかし Cycloud ではインフラ基盤自体も Kubernetes / OpenStack といった大規模OSSを利用して構築されていたり、独自のシステムや周辺ツールを Go / Python 等を用いて開発することも多々あり、ソフトウェア開発も盛んに行われています。
さらに最近では組織全体として AI Coding Agent (以下 AI) の利用も推進され、部分的なコード実装だけでなく、テストや Lint、レビューといった一連の開発フローを AI に任せる動きも増えており、開発スピードと品質の両立が図られています。
そこで本記事では、私が個人的に取り組んでいる 「AI を単なる “補助ツール” ではなく、一連の開発フローを任せられる “部下” として扱うための開発環境づくり」 をテーマとして、
- AI Coding Agent を用いた開発フロー
- それを支える開発環境をどう作っているか
について、具体例を交えて紹介していきます。
主な開発ツール一覧
- Claude Code
- git-worktree-runner
- Zsh
- Neovim
- tmux
- dotfiles
2. Claude Code を「AI専用コンソール」として使う
2-1. CLI ベースの開発スタイル
私は AI Coding Agent として主に Claude Code を利用しており、ターミナル上の CLI で 「AI専用コンソール」 として立ち上げています。 世の中には GUI のエディタ組み込みの AI 製品もいくつか存在しますが、私が CLI ベースの AI を好む主な理由としては:
- ターミナル上のみへの開発環境の集約
- 様々な環境で同じ開発体験を実現
- ベンダーロックインの低減
といったあたりです。
私は普段の開発に tmux / Neovim を使用しており、CLI ベースの AI との親和性が高いです。GUI ベースの AI 組み込みのエディタも試してみたのですが、自分の使い方ではエディタ自体の使い勝手が合わず、生産性が落ちてしまうのを体感し、ターミナル上で完結する CLI ベースの AI と Neovim を併用するスタイルに落ち着きました。
また、ターミナル上で完結するスタイルの恩恵として、新しい PC やリモート環境でローカルと同じ開発環境をサクッと立てられることや、CLI ベースであれば他の AI とも比較的容易に切り替えできて、ベンダーロックインをある程度低減できるといったメリットも感じています。
2-2. tmux + Neovim + Claude Code
普段の開発は tmux を用いてプロジェクトごとのセッション、タスクごとのウィンドウを管理し、Neovim と Claude Code を画面分割して表示するスタイルでやっています。
tmux では以下のようなキーバインドの設定をし、vim 上のバッファー移動と同じ感覚で エディタと AIコンソールを手癖で移動できるようにしています。
tmux 側のキーバインド設定 (抜粋):
# prefix キーを C-q に変更
set -g prefix C-q
# Vim 風ペイン移動
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
環境によっては画面分割するとスペースが足りなくて見辛かったり、人間側で細部の修正をする際にエディタだけに集中したいようなこともあります。そのような時は tmux の Ctrl-z のキーバインドを使うことで一時的に選択したペインを全画面表示にすることができて便利なため多用しています。
3. AI に長時間タスクを任せる
ここからは、実際に AI を開発の中でどのように利用しているかや、その中で実践している生産性向上のための工夫について紹介していきます。
3-1.「頻繁すぎる AI のアウトプットレビュー地獄」からの脱却
AI に限ったことではないですが、他人のアウトプットを確認もせずにそのまま信用してはいけません。必ず別の人間が責任を持ってレビューを行うプロセスが必要になります。 とはいえ、AI が出してくる頻繁かつ大量のアウトプットを人間が全て確認したり、毎回テストを実行して実行時のログを眺め、AI にフィードバックを書いて修正させ… ということをしていては生産性は上がらず、人間が他の作業に集中して取り組むこともできません。
人間が他の作業をできず AI のレビューにつきっきりになってしまっては、むしろ最初から自分で書いた方が早かった、という経験をした方も多いと思います。
そこで私は以下のような工夫をして、AI に時間をかけてでも品質の高いアウトプットを出力させ、人間が AI のアウトプットをレビューする頻度と量を削減しています。
- Lint / Test / レビュー を自動で AI に実行させる
- 何らかのエラーが出たらその原因特定と修正まで自動でやらせる
- 上記をエラーが出なくなるまで繰り返させる
3-2. Makefile で「最低限の品質チェック」をコマンド化
Makefile ではなくても構いませんが、プロジェクトごとに「最低限これが通っていればレビューに出してよい」というコマンドを用意します。
Makefileの例:
.PHONY: lint
lint: ## Run linters (golangci-lint and staticcheck).
golangci-lint run
staticcheck ./...
.PHONY: test
test: ## Run all tests.
go test -cover ./...
これらのコマンド をコードの編集後には必ず実行するように指示しておくことで、AI が最終的に提出するアウトプットが予め定めた最低限の基準を満たすことを保証できます。
AGENTS.mdでの指示例 (抜粋):
## Coding Style
### Go Code Style
...
**Formatting & Linting**: After every Go code change, run the following commands.
```bash
make fmt # Format Go code with gofmt and goimports.
make lint # Run linters (golangci-lint and staticcheck).
```
## Testing Guidelines
Every change must pass `make test`. ```bash make test # Run all tests. ```
3-3. Claude Code の permissions 設定
AI が自分でフィードバックループを回せるようにするためには、人間と同様に必要なツールを自動で使えるようにする必要があります。AI がツールを使うたびにいちいち手動で承認をしていては生産性など上がりません。
しかし、当然ながら任意のコマンドを AI に許可などしてはいけません。特に削除系の操作や外部システムに対して操作をする CLI ツールの使用には注意が必要です。
この課題を解決するために、Claude Code では設定ファイル (.claude/settings.json) で、承認なしで実行してよいコマンドや絶対に実行してはいけないコマンドを明示的に制御できます。
参考:CLI 設定のドキュメント
https://code.claude.com/docs/en/settings
プロジェクトによらず実行しても良い read 系の操作は ~/.claude/settings.json で許可し、make コマンド等のプロジェクトごとに設定したいコマンドを <PROJECT_ROOT>/.claude/settings.json で許可するようにしています。
グローバル設定 (抜粋):
{
"permissions": {
"allow": [
"Bash(mkdir:*)",
"Bash(ls:*)",
"Bash(tree:*)",
"Bash(grep:*)",
"Bash(sort:*)",
...
"Bash(git status:*)",
"Bash(git diff:*)",
...
"Bash(gh repo list:*)",
"Bash(gh repo view:*)",
...
"mcp__context7",
"mcp__serena"
],
"deny": [
"Bash(sudo:*)",
"Bash(rm -rf:*)",
...
],
...
}
}
プロジェクト設定 (抜粋):
{
"permissions": {
"allow": [
"Bash(make help)",
"Bash(make fmt)",
"Bash(make lint)",
"Bash(make build)",
"Bash(make test)",
"Bash(make proto)",
"Bash(make proto-fmt)",
"Bash(make proto-lint)",
"Bash(make sql-generate)",
"Bash(make sql-fmt)",
"Bash(make sql-lint)"
],
...
}
}
これにより、AI が基本的なコードリーディングや編集だけでなく、自動で実行するように指示した Lint / Test といった一連の作業も人間の介入なく実行でき、AI による長時間の自律的な開発とアウトプットの品質向上を実現できます。
4. hooks とデスクトップ通知による割り込み処理
Claude Code には hooks という機能があり、セッションの状態に応じて任意のコマンドを実行できます。
参考:Claude Code Hooks reference
https://code.claude.com/docs/en/hooks
設定例(settings.json より抜粋):
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash -c \\\\"~/bin/claude_notify.sh Notification\\\\""
}
]
}
],
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash -c \\\\"~/bin/claude_notify.sh Stop\\\\""
}
]
}
]
}
}
ここでは、AI が人間に対して何らかの指示や承認を仰いだり (Notification)、タスクが完了したタイミング (Stop) でスクリプトを呼び出しています。
実際に実行しているスクリプトは以下のようなものです:
#!/bin/bash
# ~/bin/claude_notify.sh
TYPE="$1"
INPUT="$(cat -)"
# 作業ディレクトリ
WORKDIR=$(echo "$INPUT" | jq -r '.cwd')
# transcript から最後の assistant メッセージを取得
TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path')
MSG=""
if [[ -n "$TRANSCRIPT_PATH" && "$TRANSCRIPT_PATH" != "null" ]]; then
JSON="$(tac "$TRANSCRIPT_PATH" | jq -rn '
inputs
| select(.message?.role? == "assistant")
| select(.message?.content?[0]?.text != null)
| (., halt)
')"
if [[ -n "$JSON" && "$JSON" != "null" ]]; then
MSG="$(echo "$JSON" | jq -r '.message.content[0].text')"
fi
fi
osascript -e "display notification \\\\"$MSG\\\\" \\\\
with title \\\\"Claude Code ($TYPE)\\\\" subtitle \\\\"$WORKDIR\\\\""
hooks で定義した command には session のメタデータを含む json 形式の文字列が標準入力で渡されます:
{
"session_id": "abc123",
"transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "Notification",
"message": "Claude needs your permission to use Bash",
"notification_type": "permission_prompt"
}
参考:Claude Code Hooks reference
https://code.claude.com/docs/en/hooks#notification-input
この中から session の詳細情報を含むファイルパスが格納されている transcript_path を抽出します。そのファイルの中身もまた複数の json 文字列になっているため、中身をこねくり回してプロジェクトのパスや最後のメッセージを取り出し、デスクトップ通知として表示させます (ちなみに音も鳴ります)。

これにより、AI に長時間のタスクを任せている間は別の作業をしておき、通知が来たタイミングで AI のセッションに戻る、という人間側の負荷が少ない開発フローを実現できます。
5. git worktree × Claude Code で並列タスクを回す
5-1. git worktree を用いた開発スタイル
同じリポジトリで複数のタスクを並列に進めたい場面は多いです。
- 0 → 1 の開発で設計書を元に複数コンポーネントを同時に開発させる
- 機能追加をしながらリファクタリングも行う
このような場合、同じブランチで複数の作業を進めてしまうと PR の粒度が大きくなってしまってレビュー負荷が高くなったり、AI が把握するコンテキストが汚れてアウトプットの品質が低下するといったデメリットがあります。
そのため私は git worktree を用いてタスクごとにブランチ・ディレクトリを分割し、複数タスクを並列で AI に実行させる開発フローをとっています。
git worktree を使うことで、
- ブランチごとに独立したディレクトリを作成
- 各 worktree で独立した Claude Code セッションを起動
のような形にタスク単位で AIセッション を分離することができます。
5-2. git-worktree-runner の活用
git worktree は標準機能だけで使うこともできるのですが、worktree 用のディレクトリの管理や AIセッション へのシームレスな移動の手間が大きいです。
そこで私は CIU の AI推進チーム の方に教えてもらった git-worktree-runner を活用しています。
主な機能:
- worktree の作成・削除
- worktree 用のディレクトリ管理
- worktree 上での AI Agent 実行
参考:git-worktree-runner
https://github.com/coderabbitai/git-worktree-runner
これをを導入することで、
git gtr new <branch>で worktree 作成git gtr ai <branch>でその worktree に対応した Claude Code セッション起動
といった操作が一コマンドで実行できるようになり、タスク・worktree・AIセッション 間の紐付けを手軽に実行することができます。
5-3. シェル関数によるラッパー
git-worktree-runner 単体でも十分に便利なのですが、いちいち複数のサブコマンドを打ったりするのは正直ちょっと面倒です。
そのため、 よくあるユースケースをラッパーのシェルの関数として定義して簡単に実行できるようにしています。
# worktree 一覧
function gls {
local branch="$1"
git gtr list "$branch"
}
# worktree に移動
function gcd {
local branch="$1"
if [[ "$branch" == main || "$branch" == "" ]]; then
cd "$(git worktree list | grep -E '\\[main\\]$' | awk '{print $1}')"
else
cd "$(git gtr go "$branch" 2>&1 | tail -n1)"
fi
}
# worktree 作成+ Claude Code 起動
function gai {
local branch="$1"
if [[ "$branch" == "main" ]]; then
echo "Cannot use 'main' as worktree branch. Specify a feature branch." >&2
return 1
fi
if ! git gtr list | grep -Eq "^$branch"; then
echo "Worktree '$branch' does not exist. Creating new worktree." >&2
git gtr new "$branch"
fi
git gtr ai "$branch"
}
例えば gai feature/new-api のように打つだけで、
- worktree 作成
- 対応する Claude Code セッション起動
まで一気に実行したり、gcd feature/new-api で作成した worktree に移動したり、gcd main で大元の main ブランチに簡単に移動することができます。
gai コマンドの利用例:

6. dotfiles による 設定の一元管理とセットアップ
これまで様々な設定やスクリプトを紹介してきましたが、新しい PC やリモートサーバー環境でこれら全ての設定を毎回一から構築するのは正直かなりの手間です。それだけで日が暮れてしまいます。
そのため、”dotfiles” を使うことでそれらの管理とセットアップを行なっています。
参考:ようこそdotfilesの世界へ
https://qiita.com/yutkat/items/c6c7584d9795799ee164
dotfiles 構成 (抜粋):
.
├── bin
│ ├── claude_notify.sh # デスクトップ通知スクリプト
│ ├── git-gtr # git-worktree-runner
├── claude
│ ├── agents # subagents管理
│ ├── assets # AI用のリファレンス等
│ ├── commands # custom slash command
│ ├── skills # skill管理
│ ├── CLAUDE.md # グローバルのインストラクション
│ └── settings.json # グローバル設定
├── tmux # tmux 設定
└── setup.sh # 環境セットアップスクリプト
新しい環境でも、dotfiles のリポジトリを clone してきてセットアップスクリプトを実行するだけでサクッと普段と同様の開発環境を実現できます。下記は各設定ファイルやスクリプトを環境で使えるようにするためのシンボリックリンクを貼る処理の例です。
~/dotfiles/setup.sh (抜粋):
#!/bin/bash
PAIRS=(
"$PWD/bin:$HOME/bin"
"$PWD/claude/settings.json:$HOME/.claude/settings.json"
"$PWD/claude/CLAUDE.md:$HOME/.claude/CLAUDE.md"
"$PWD/claude/commands:$HOME/.claude/commands"
"$PWD/claude/agents:$HOME/.claude/agents"
"$PWD/claude/skills:$HOME/.claude/skills"
"$PWD/zsh/.zshrc:$HOME/.zshrc"
"$PWD/zsh/.zsh_aliases:$HOME/.zsh_aliases"
"$PWD/zsh/.zsh_functions:$HOME/.zsh_functions"
"$PWD/tmux/.tmux.conf:$HOME/.tmux.conf"
)
for PAIR in "${PAIRS[@]}"; do
SOURCE_PATH="${PAIR%%:*}"
TARGET_PATH="${PAIR##*:}"
if [ -e "$TARGET_PATH" ]; then
echo "'$TARGET_PATH' already exists. Skip."
continue
fi
TARGET_DIR="$(dirname "$TARGET_PATH")"
mkdir -p "$TARGET_DIR"
ln -s "$SOURCE_PATH" "$TARGET_PATH"
echo "Created symbolic link: $TARGET_PATH -> $SOURCE_PATH"
done
このように、開発環境に関わる設定やスクリプトをすべて dotfiles に集約しておくことで、どのマシンでも短時間で同じ開発体験を再現でき、AI Coding Agent を含めた「自分仕様の開発フロー」を再現性高く持ち運べるようにしています。
7. まとめ
この記事では、AI Coding Agent を単なる “補助ツール” ではなく、長時間のタスクを任せられる “部下” として扱うことを目指した開発環境や、生産性向上のための工夫を紹介しました。
- 「Lint・Test・CI チェックのループ」を AI に自動実行 させることで、AI による低品質のアウトプットの抑制と、人間が頻繁にレビューをする手間を削減。
- hooks 機能によるデスクトップ通知の仕組みを整え、AI の長時間タスクの完了や入力待ちを人間がポーリングするのではなく割り込みで検知。
- git-worktree-runner や シェル関数 を組み合わせて、AI によるシームレスな複数タスクの並列実行を実現。
- これらの設定やスクリプトを dotfiles に集約し、新しいマシンやリモート環境でも同じ開発体験を素早く再現。
様々な工夫を紹介してきましたが、重要なポイントは AI を 一定の品質基準と開発フローを自律的にこなしてくれる“部下” として扱えるよう、常に開発環境をブラッシュアップし続けていくことです。各個人にとっての理想の環境は一朝一夕で作れるものではありません。継続的に育てていくという意識が重要です。
今後は個人での開発環境の継続的な整備はもちろん、組織としての AI 開発フローの基盤作りや、運用への AI の導入 (いわゆる AIOps) も引き続き進めていきたいと思います。
本記事の内容が、読者の AI Coding Agent を用いた開発への第一歩になれば幸いです。最後まで読んでいただきありがとうございました。


