hacomono TECH BLOG

フィットネスクラブやスクールなどの顧客管理・予約・決済を行う、業界特化型SaaS「hacomono」を提供する会社のテックブログです!

AIにコードを調査させてみた



こんにちは。運用保守部のnacchiです。

今回は運用保守部の主な業務の一つである問い合わせ対応について、どうにかAIを活用して効率化を図れないかを検証してみた結果を書かせていただきます。

運用保守部では幅広い業務を行なっており、顧客からの問い合わせ対応や運用業務の仕組み化、システム改善・改修などを行なっています。
中でも顧客からの問い合わせ対応はウェイトが大きく、また時間的負担も大きい業務になっています。
問い合わせ件数はhacomono利用店舗の拡大に伴い増えており、運用保守部に来る問い合わせ件数は直近2ヶ月は毎月200件近くの問い合わせが来ています。
限られた人数・限られた業務時間でこの件数を対応するには1件に当てる時間を短くしていく必要があり、そういった面でAI活用による調査時間の短縮が期待されています。

とはいえ今回行うのはそこまで厳密な検証ではなく、自分が現在使用できるAIにプロンプトを投げてみて、どれが一番求める回答に近い内容を返してくれるかを見ていきます。
夏休みの自由研究だと思ってください。

AIにコードを調査させてみる

下記の実際にあった問い合わせについて、「何故このエラーが発生したのか」をAIに調査させてみます。

問い合わせ内容

レッスンを予約しようとしたら「[RSV_000015] このレッスンの予約に使用できるチケットがありません。」というエラーが出て予約できなかった。
なぜ予約できないのか教えて欲しい。

運用保守が受ける問い合わせでもよく見られるタイプの問い合わせです。
基本的には対象のレッスンやチケットの設定に原因があるというパターンが多く、人間が調査する際はまずはそれらの設定を確認し、そこからコードの調査に入ることが多いです。
人によってはまずコードからどういった設定の場合にこのエラーが出るのかを見ることもあるかもしれません。

先に答えを言うと、このケースでは「レッスンがトライアルレッスンになっていたが、このレッスンを予約可能なチケットに通常予約チケットしか設定されていなかった」というオチでした。
hacomonoではトライアルレッスン(お試し価格レッスン)はトライアル用チケットでしか予約できないという制約があるため、対応としてはレッスンをトライアル設定ではなく通常レッスンに変更するか、予約可能なチケットにトライアル用チケットを追加するかすれば予約が出来るようになります。

今回はこの問い合わせに対して、異なるAIモデルに下記のプロンプトを投げてどういった回答が返ってくるかを試してみます。

欲しい答えとしては、対象レッスンを予約可能なチケットを取得するロジックの中に、そのものずばり「レッスンがトライアルレッスンか」、「チケットがトライアルチケットか」という判定をしています。
この判定をエラーが発生するパターンとして挙げてくれるか、ヒントになる回答をしてくれると嬉しいですね。

今回試すAIは下記です。
自分の使用できるツールの都合上検証と呼ぶにはパターンが少ないのはご了承ください。
CopilotやDevinなども試したかったのですが、時間の都合上今回は見送りました。興味がある方は各自で検証してください。
日常的に使用しているツールで試したのですが、意外と面白い回答をしてくれました。

  • Cursor
    • claude-4-sonnet
    • gemini-2.5-pro
    • gpt-4.1
  • Claude Code


プロンプトを投げてみる

プロンプトは下記で試します。

[RSV_000015] このレッスンの予約に使用できるチケットがありません。
このエラーがなぜ出るかを教えて。

あえて雑なプロンプトでどこまで調べてくれるかを見たいため、このようなプロンプトにしています。
AIの回答内容については機密の関係で隠す必要がある部分は削除や置換をしています。

Cursor - claude-4-sonnet
## RSV_000015エラーが発生する原因

このエラーは以下の複数の条件で発生します:

### 1. **基本的なチケット不足**
- チケット予約を選択したが、使用可能なチケットが全くない場合
- 所持しているチケットの枚数が0枚の場合

### 2. **ユーザー認証の問題**
- 未ログイン状態でスクールクラスの予約を試行した場合

### 3. **チケットタイプの不一致**
- **スクール体験レッスン**の場合:スクールチケット(`SCHOOL`タイプ)以外のチケットを使用しようとした場合
- **一回完結レッスン**の場合:予約チケット(`RESERVE`タイプ)以外のチケットを使用しようとした場合

### 4. **アクセス制限による制約**
- **プラン契約者限定設定**:システム設定でプラン契約者のみにスケジュール表示を制限している場合で、有効なプランを契約していない
- **体験未受講者制限**:「体験未受講者には体験のみ表示」設定が有効で、以下のいずれも受講していない場合:
  - トライアルレッスン
  - 無料体験
  - スクール体験

### 5. **チケット購入・利用制限**
- チケットケースは存在するが、購入可能な商品がなく、かつ使用可能な所持チケットが全て0枚の場合(管理者でプラン予約以外の場合)

## 解決方法
1. **適切なタイプのチケット**を購入・所持する
2. **ログイン状態**を確認する  
3. **プラン契約**や**体験レッスンの受講**など、アクセス制限の条件を満たす
4. **チケット残枚数**を確認する

このエラーは主にチケット関連の制約や認証状態、アクセス権限に関する問題で発生するため、上記の条件を確認することで解決できます。

欲しい回答と近いものとしては 1. 基本的なチケット不足3. チケットタイプの不一致 が近いでしょうか。
実際のコードでの実装では 1. 基本的なチケット不足 の、使用可能なチケットを取得するロジックに答えがあるのですが、そこまでは回答してくれていません。
この回答から調査を進める場合は、2〜5が当てはまらないことを確認したのち、1のチケット不足の詳細について見ていく形になると思われます。
エラーが出る条件は提示されているため、今回のケースが明確に当てはまらないものを除外していくことでアタリを付けることは出来そうです。
これらのロジックを短時間でまとめてくれるので、これだけで回答は得られませんが時短に役立ちます。
でも一回完結レッスンというレッスンは初めて聞きました。そんなレッスンあったっけ…
たまに謎の造語を出してくるのは面白いですね。

Cursor - gemini-2.5-pro
エラーが発生する主な条件は以下の通りです。

1.  **チケット予約が必要だが、利用可能なチケットがない場合:**
    *   メソッド内の判定で、チケットが必要と設定されているにもかかわらず、利用可能なチケットのリストが空の場合。

2.  **スクールクラス予約で、条件に合うチケットがない場合:**
    *   メソッド内で、
        *   ログインしていない
        *   体験レッスン (`EXPERIENCE`) または都度利用 (`ONETIME`) の予約で、それぞれに対応する種類のチケット(`SCHOOL` または `RESERVE`)がない。
        *   都度利用 (`ONETIME`) の予約で、予約スケジュールの表示制限によっては、有効な料金プランを契約していない。
        *   都度利用 (`ONETIME`) の予約で、予約スケジュールの表示制限によっては、トライアルや体験レッスンをまだ受けていない。

3.  **チケットの種別が違う場合:**
    *   渡されたチケットのチケットタイプが期待される種別(スクールレッスンか、通常の予約か)と異なるときもエラーになります。

**結論として、エラー `[RSV_000015] このレッスンの予約に使用できるチケットがありません。` が発生する理由は、以下のいずれかである可能性が高いです。**

*   **ユーザーが、予約に必要な種類のチケット(回数券やプランなど)を所持していない。**
*   **予約しようとしているレッスン(通常レッスン、スクールレッスン、体験レッスンなど)と、ユーザーが持っているチケットの種類が一致していない。**
*   **システムの予約設定(例えば「プラン契約者のみ予約可能」など)により、ユーザーが予約対象外となっている。**
*   **そもそもログインしていない状態で予約しようとしている。**

より詳細な原因を特定するには、このエラーが発生したときの具体的な状況(どのユーザーが、どのレッスンを予約しようとしたか、そのユーザーがどのチケットやプランを保持していたかなど)の情報が必要になります。

ご不明な点があれば、さらに詳しく調査しますのでお知らせください。

意外とclaude-4-sonnetと近い回答になっています。
チケットの不足という回答は得られますがその先の詳細な判定部分までは回答してくれていません。
ただ、「メソッド内の判定で、チケットが必要と設定されているにもかかわらず、利用可能なチケットのリストが空の場合。」という文言はclaude-4-sonnetと比べると答えに近づいている印象です。
また上記では削除しているのですが、どのメソッドのどの判定かというような細かい部分も回答に含まれていたので、コードを読み解く際のヒントにもなりそうです。
claude-4-sonnetと比べると言語的な印象です。
余談ですがclaude-4-sonnetで出てきた一回完結レッスンはおそらくタイプがONETIMEの予約を解釈したものだということがこの回答から推測できます。
あと面白かったのが解析中のメッセージで

では、エラーの具体的な発生条件を理解するために `**********(ファイル名)` の内容を確認します。

申し訳ありません、引数を間違えました。ファイル全体を読み込みます。

`**********(ファイル名)` を確認しました。
このファイルには `RSV_000015` エラーを発生させるロジックがいくつか含まれています。

間違えてる…

Cursor - gpt-4.1
[RSV_000015]「このレッスンの予約に使用できるチケットがありません。」というエラーが出る理由について説明します。

---

### エラー発生の主な条件

このエラーは、**レッスン予約時に「使用できるチケットが1枚もない」場合**に発生します。  
具体的には、以下のような流れ・条件で発生します。

#### 1. 予約ポジションが「チケット予約」の場合
- 予約処理の中で `**********(メソッド名)` というメソッドが呼ばれます。
- ここで「利用可能なチケット」が空(blank)の場合、`RSV_000015` エラーがセットされます。

#### 2. クラスやチケットの制限設定による影響
- チケットやクラスに「このクラスで使えるチケットの制限」や「このチケットはこのクラスで使えない」などの設定がされている場合、  
  その制限により「使えるチケットが0枚」になるとこのエラーが出ます。
- 例:  
  - チケットマスタでクラス制限がON、かつクラスマスタで通常チケット制限がON、かつ予約チケットがクラス使用対象外
  - チケットマスタでクラス制限がOFFでも、クラスマスタで通常チケット制限がONで、予約チケットが対象外
  - など、**「このレッスンで使えるチケットが1枚もない」状態**

#### 3. テストコードからの具体例
- テストでは、上記のような制限設定をした場合に `RSV_000015` エラーが発生することが確認されています。

---

### まとめ

**「このレッスンの予約に使用できるチケットがありません。」エラーは、  
「予約しようとしているレッスンに対して、使えるチケットが1枚もない」場合に発生します。**

- チケットやクラスの制限設定を見直し、「本当に使えるチケットがないか」を確認してください。
- もし本来使えるはずのチケットがあるのにこのエラーが出る場合は、チケットやクラスの設定(制限)が正しいかを再度ご確認ください。

---

もし、特定のケースでこのエラーが出て困っている場合は、  
「どのチケット」「どのクラス」「どんな制限設定」かを教えていただければ、さらに詳しく調査できます。

先の2つに比べるとコード自体の具体例などはほとんど回答に含まれていませんでした。
ただ内容自体は先の2つと同様、「利用可能なチケットがない」というところまでは回答してくれています。
テストコードから具体例を出しているところも賢い。私より賢いです。
個人的な感想ですがまとめ文としてはgemini-2.5-proより読みやすい印象です。
ただ先の2つは解析中のメッセージが残っていたのに対し、こちらは解析中のメッセージは残っていませんでした。
gemini-2.5-proで間違いが発生していたように、意外と解析中のメッセージも面白いのでそこは残念です。

Claude Code
⏺ このエラーメッセージを調査するために、コードベースを検索してエラーの原因を特定します。

⏺ Update Todos
  ⎿  ☐ RSV_000015エラーコードをコードベースで検索
     ☐ チケット予約関連のロジックを調査
     ☐ エラーが発生する条件を特定

⏺ RSV_000015エラーは、以下の条件で発生します:

  主な発生条件

  1. チケットが必要だが使用可能なチケットがない場合
  - **********(ファイル名):12 - チケット予約時に利用可能なチケットが空

  2. 未ログインユーザーがスクールクラス予約を試みた場合
  - **********(ファイル名):114 - ユーザーが空の場合

  3. チケット種別が要求される種別と一致しない場合
  - スクール体験予約時にSCHOOLタイプ以外のチケット使用時
  - ワンタイム予約時にRESERVEタイプ以外のチケット使用時

  4. プラン契約者のみ表示設定でプラン未契約の場合
  - **********(ファイル名):142 - 予約スケジュールの表示制限がプラン契約者のみで有効プラン未契約

  5. 体験未受講者には体験のみ表示設定で体験未受講の場合
  - **********(ファイル名):152 - トライアル・無料体験・スクール体験をすべて未受講

  このエラーは予約に必要なチケットの条件が満たされていない時に発生する汎用的なバリデーションエラーです。

今回特に時間は計っていないので体感ですが、少し目を離した隙に出力されていたのでだいぶ早かったように思います。
他と同様、やはり「使用可能なチケットがない」という判定ロジックまでは言及されていません。
ここまでが今回のプロンプトで出力される限界なのだと思います。
試した中では最も簡潔かつ対象ファイルの該当行までまとめられていて、わかりやすい回答だと思います。
モデルはclaude-sonnet-4-20250514だったのですが、Cursorの回答とはだいぶフォーマットが違いますね。


感想

1度の簡素なプロンプトで得られる回答では求めていた回答まで辿り着くことはできませんでした。
突き詰めていくとキリがないので今回はこれで終わりにしますが、コンテキストの指定やプロンプトの工夫でだいぶ結果は変わりそうです。
ただこのレベルの指示でこのレベルの回答を得られれば、調査のフックとしては充分だと思います。

今回、「使用可能なチケットがない」と判定される条件までは出力されなかったのは、この判定ロジックがhelperで実装されていたためかと思われます。
そこを出力するにはプロンプトで詳細な指示をするか、cursorrulesなどで「どのレベルまで解析内容を出力するか」を明記しておくなどのアプローチが必要になります。
安定した出力を得るには「どのレベルの指示でどのレベルの回答が出力されるか」というのを検証し、ルールを整えていくことになりそうです。

ほぼ思いつきに近い検証だったのですが、回答内容に意外と特色が出たように思います。
コーディング能力ではclaudeがgeminiやgptに比べると高いという認識でしたが、解析能力自体は今回のレベルだとそれほど差は出ませんでしたね。
非エンジニアがコード解析に使う場合はかえってclaudeよりgeminiやgptの方が扱いやすいかもしれません。

以上となります。
夏休みの自由研究にお付き合いいただきありがとうございました。



💁 関連記事