🎫

AIにチケット作成を任せて、私たちは開発に集中する ─ Claude Code × Linear MCP の実践

に公開

はじめに

開発中にふと気づく、ちょっとしたリファクタリングや改善点。
「あとでチケットにしておこう」と思ったのに、結局忘れて放置──そんな経験はありませんか?

これらの小さな改善こそ、積み重なると大きな品質低下につながります。
👉 だからこそ、AIに任せて確実にチケット化してしまいましょう。

本記事では Claude Code × Linear MCP を使って、タスクを自動でチケット化する方法を紹介します。

理想のチケット自動化フロー

  1. コード書いてて「あ、ここ直したい」と思う
  2. Claude Codeに「この関数を修正するタスクを作って」と一言
  3. AIが自動でコード解析し、Linearにチケットを作成
  4. 自分は目の前の実装に集中継続

たったこれだけで、リファクタタスクが確実に処理されるようになります。
では、具体的にどんなタスクをAIに任せられるのか見ていきましょう。

どんなタスクをAIに任せられるか

AIによる自動チケット化が最も効果を発揮するのは、コードを見れば明確な改善点がわかるケースです。
例として、以下のようなコードを見てみましょう:

// このコードには2つの典型的な問題があります
package main

import (
	"fmt"
	"strings"
)

/*
# ユーザーの新規登録を行う
# 問題点
1. **長大メソッド**
   - バリデーションと登録処理が1つの関数に詰め込まれている。
2. **重複ロジック**
   - 同じような入力チェックが繰り返されている(名前・メール)。
*/
type User struct {
	Name  string
	Email string
}

func RegisterUser(users *[]User, name, email string) {
	// 名前チェック
	if name == "" {
		fmt.Println("名前は必須です")
		return
	}
	if strings.TrimSpace(name) == "" {
		fmt.Println("名前が空です")
		return
	}

	// メールチェック
	if !strings.Contains(email, "@") {
		fmt.Println("メールアドレスが不正です")
		return
	}
	if !strings.Contains(email, ".") {
		fmt.Println("メールアドレスが不正です(ドメインなし)")
		return
	}

	// 重複確認
	for _, u := range *users {
		if u.Email == email {
			fmt.Println("このメールアドレスは既に登録済みです")
			return
		}
	}

	// 登録
	*users = append(*users, User{Name: name, Email: email})
	fmt.Printf("ユーザー %s を登録しました!\n", name)
}

func main() {
	users := []User{}
	RegisterUser(&users, "Taro", "taro@example.com")
	RegisterUser(&users, "Hanako", "hanakoexample.com") // エラー例
}

プロンプトでチケット作成

では実際にプロンプトを使ってチケットを作成してみましょう。

  1. 長大なメソッドを分割したいとき

    プロンプト
    この関数が長すぎるので適切なサイズに分割するタスクを作成してください。
    背景 => ゴール => 受け入れ基準 => 詳細コード箇所 の形式でLinearでチケットを作成してください。
    
    出力例

    RegisterUser関数の長大メソッドを適切なサイズに分割

    背景

    main.go:26RegisterUser関数が長大メソッドとなっており、以下の問題を抱えています:

    • バリデーションと登録処理が1つの関数に混在
    • 名前とメールの入力チェックで重複ロジックが存在
    • テストしにくい構造
    • 単一責任原則に違反

    ゴール

    RegisterUser関数を適切なサイズの複数の関数に分割し、保守性とテスト容易性を向上させる

    受け入れ基準

    • バリデーション関数の分離
      • validateName(name string) error 関数を作成
      • validateEmail(email string) error 関数を作成
    • 重複確認関数の分離
      • checkDuplicateEmail(users []User, email string) error 関数を作成
    • メイン登録関数の簡素化
      • RegisterUserは各バリデーション関数を呼び出すだけの構造にする
    • エラーハンドリングの統一
      • 全ての関数でerrorを返すように統一
    • 既存の動作を維持
      • 分割後も同じ入出力とエラーメッセージを保持

    詳細コード箇所

    • 対象ファイル: main.go
    • 対象関数: RegisterUser (line 26-58)
    • 分割対象の処理:
      • 名前バリデーション (line 27-35)
      • メールバリデーション (line 37-45)
      • 重複確認 (line 47-53)
      • ユーザー登録 (line 55-57)
  2. ロジック内の重複処理を整理したいとき

    プロンプト
    この関数で重複している処理を整理し、タスクを作成してください。
    背景 => ゴール => 受け入れ基準 => 詳細コード箇所 の形式でLinearでチケットを作成してください。
    
    出力例

    RegisterUser関数の重複処理リファクタリング

    背景

    現在のRegisterUser関数(main.go:18-53)では、バリデーション処理で同じような処理が重複している。具体的には:

    1. 名前のバリデーションで類似処理が2回実行
      • 空文字チェック(L22-25)
      • 空白文字のみチェック(L26-29)
    2. メールのバリデーションで類似処理が2回実行
      • @マークの存在チェック(L32-35)
      • ドット(.)の存在チェック(L36-39)

    この重複により、コードの保守性と可読性が低下している。

    ゴール

    RegisterUser関数を以下の観点でリファクタリングする:

    • 重複しているバリデーション処理を統合・分離
    • 単一責任の原則に従った関数分割
    • テスタブルな構造への変更

    受け入れ基準

    • 名前バリデーション処理を1つの関数に統合
    • メールバリデーション処理を1つの関数に統合
    • RegisterUser関数から独立したバリデーション関数を作成
    • 既存の機能・エラーメッセージが正常に動作
    • main関数での実行結果が変更前と同一

    詳細コード箇所

    重複箇所1: 名前バリデーション

    // main.go:22-29
    if name == "" {
        fmt.Println("名前は必須です")
        return
    }
    if strings.TrimSpace(name) == "" {
        fmt.Println("名前が空です")
        return
    }
    

    重複箇所2: メールバリデーション

    // main.go:32-39
    if !strings.Contains(email, "@") {
        fmt.Println("メールアドレスが不正です")
        return
    }
    if !strings.Contains(email, ".") {
        fmt.Println("メールアドレスが不正です(ドメインなし)")
        return
    }
    

    提案されるリファクタリング構造

    1. validateName(name string) error 関数の作成
    2. validateEmail(email string) error 関数の作成
    3. checkDuplicateEmail(users []User, email string) error 関数の作成
    4. RegisterUser関数の簡素化

さらに効率化:カスタムスラッシュコマンドでワンフレーズ実行

毎回プロンプトを手で書くのは少し面倒ですよね。
そこで カスタムスラッシュコマンド を導入すると、ワンフレーズでチケット作成の依頼をすることができます。

以下のファイルを配置することで、/create-task この関数が長すぎるので適切なサイズに分割したいで実行できるようになります。

{project}/.claude/commands/create-task.md
    # Linear Task Creation
    
    `/create-task [要件]`で簡潔にLinearチケットを作成します。
    
    ## 使用例
    ```
    /create-task この関数が長すぎるので適切なサイズに分割したい
    /create-task この関数で重複している処理を整理したい
    ```
    
    以下、`$ARGUMENTS`から該当するコードを分析し、具体的なタイトル・背景・ゴール・受入基準を推定してチケットを自動生成し、確認後にLinear MCPでチケットを作成します。
    
    **コードベース分析開始**
    
    要件: "$ARGUMENTS"
    
    *コードベース分析中...*
    
    1. 該当する関数・ファイルの特定
    2. 問題箇所の詳細分析
    3. 具体的なリファクタリング提案の生成
    
    **分析結果**
    
    # [具体的な関数名]の[問題内容]リファクタリング
    
    ## 背景
    
    現在の[ファイル名]の[関数名]関数([ファイル名]:[行番号]-[行番号])では、以下の問題が発生している:
    
    1. **[具体的問題1]**
       - [詳細説明とコード箇所]
    2. **[具体的問題2]**
       - [詳細説明とコード箇所]
    
    この問題により、コードの保守性・可読性・テスタビリティが低下している。
    
    ## ゴール
    
    [関数名]関数を以下の観点でリファクタリングする:
    - [具体的な改善目標1]
    - [具体的な改善目標2]
    - [具体的な改善目標3]
    
    ## 受入基準
    
    - [ ] [具体的な実装完了条件1]
    - [ ] [具体的な実装完了条件2]
    - [ ] [具体的な実装完了条件3]
    - [ ] 既存の機能・エラーメッセージが正常に動作
    - [ ] [テスト・ビルドの動作確認]
    
    ## 詳細コード箇所
    
    ### 問題箇所1: [問題名]
    
    ```[言語]
    // [ファイル名]:[行番号]-[行番号]
    [該当するコード抜粋]
    ```
    
    ### 問題箇所2: [問題名]
    
    ```[言語]
    // [ファイル名]:[行番号]-[行番号]
    [該当するコード抜粋]
    ```
    
    この内容でLinearチケットを作成しますか?確認後、MCPでチケットを作成します。
出力例

RegisterUser関数のリファクタリング

背景

現在の main.go の RegisterUser 関数(main.go:26-58)では、以下の問題が発生している:

  1. 長大メソッド問題

    • バリデーション、重複チェック、登録処理が1つの関数に混在している(32行の関数)
    • 単一責任の原則に違反している
  2. 重複ロジック

    • 名前チェックが2回(空文字チェックとトリム後の空文字チェック)
    • メールチェックが2回(@の有無と.の有無で同様のエラーメッセージ)
  3. テスタビリティの低下

    • バリデーション、重複確認、登録処理が分離されていないため個別テストが困難

この問題により、コードの保守性・可読性・テスタビリティが低下している。

ゴール

RegisterUser関数を以下の観点でリファクタリングする:

  • バリデーション処理を独立した関数に分離
  • 重複確認処理を独立した関数に分離
  • 登録処理をシンプルで明確な責任範囲に限定
  • 各処理が個別にテスト可能な構造に改善

受入基準

  • validateUserInput 関数を新規作成(名前・メールのバリデーション統合)
  • checkUserExists 関数を新規作成(重複チェック処理の分離)
  • RegisterUser 関数を簡潔にリファクタリング(3つの関数を呼び出すのみ)
  • 既存の機能・エラーメッセージが正常に動作
  • go run main.go で動作確認が完了

詳細コード箇所

問題箇所1: 重複したバリデーションロジック

// main.go:27-35
if name == "" {
    fmt.Println("名前は必須です")
    return
}
if strings.TrimSpace(name) == "" {
    fmt.Println("名前が空です")
    return
}

問題箇所2: 重複したメールチェック

// main.go:37-45
if !strings.Contains(email, "@") {
    fmt.Println("メールアドレスが不正です")
    return
}
if !strings.Contains(email, ".") {
    fmt.Println("メールアドレスが不正です(ドメインなし)")
    return
}

問題箇所3: 混在した責任範囲

// main.go:26-58 全体
// バリデーション + 重複チェック + 登録処理が1つの関数に混在

ユースケース集

特に効果的な場面

  1. コードレビューで指摘された細かい改善

    • 「ここの命名微妙」「この処理分割した方が」のような指摘を即チケット化。
  2. 実装中の「あ、これも直したい」

    • 本来のタスクじゃないけど気になる箇所を見つけた時。

👉 リファクタや"ついで対応"なら、該当コードを示すだけでAIが8-9割対応。人間の作業は2〜3分の確認で済みます。

あまり効果的でない場面

  1. プロジェクト全体の要件整理が必要な内容

    • 「新サービスの立ち上げ」「大規模機能の設計」など、まだ頭の中にしか情報がないものはAIだけでは整理しきれません。
  2. 人間の判断が必要なタスク

    • コードの良し悪しではなく、プロダクトの方向性に関わる変更。
    • 他チームとの調整が必要なインターフェース変更。

👉 これらはAIにチケット化させても、結局人間が詳細を詰める必要があります。

おわりに

開発における生成AI活用というと「どれだけ早くコードを書けるか?」「どれだけ早くリリースできるか?」に目が行きがちかもしれません。しかし私たちは、AIを単なるスピードアップの道具としてではなく、開発フロー全体を進化させるツールとして捉えています。

小さな改善や気づきをAIでチケット化し、さらにClaudeCodeに読み込ませて対応まで任せる。こうした一連の流れを整えることで放置されがちなタスクも確実に処理され、チームはより本質的な開発に集中できます。


J-CATでは、こうしたAI駆動開発を通じて観光業界に新しい価値を届けています。
この開発スタイルにワクワクする方、ぜひ一緒に観光業界を盛り上げませんか?

J-CATテックブログ

Discussion