Gemini で Redmine の過去知見をフル活用!チケット対応の自動化に使える RAG の実践例

こんにちは。コミュニケーション&アプリケーションサービス部で業務支援システムの開発をしている山中です。 先日、自社の Google Cloud 環境で利用できる Gemini API を活用し、Redmine で管理している過去のチケットの内容に基づいて、新規のアラートや問い合わせチケットに対する自動アシストを行う仕組みを構築しました。 その具体的な方法と、実際に導入して感じた効果や感想をご紹介します。

Redmine によるチケット管理の現場のリアル

私たちの現場では、障害アラートや問い合わせ対応の管理に長年 Redmine を使い続けています。

蓄積された過去のチケット数は約5,000件。膨大なナレッジが眠っているのですが、現場ではそれを有効に活用しきれておらず、いくつかの解決したい課題を抱えていました。

  • 経験の浅いメンバーによる調査の難しさ
    • システムが複雑で提供機能も多いため、過去に類似事象があっても、経験の浅いメンバーでは関連する過去チケットに辿り着きづらい
  • Redmine の検索仕様による限界
    • 私たちが使用しているバージョンでは検索の表記揺れなどに弱く、目当ての情報にたどり着くための適切な検索ワードを思いつくのが難しい
  • 既存資産の多さによる移行の困難さ
    • モダンなツールへ移行したくても、長年の情報蓄積や依存している業務が多すぎてハードルが非常に高い
    • 壊れたときのインパクトが大きいため、本体のバージョンアップやプラグインの追加すら慎重にならざるを得ない

世間では「AI によってこれまで積み重ねてきた過去のナレッジを活かす」といった事例が数多く出ていますが、「うちの歴史ある Redmine 環境じゃ難しいか……」と半分諦めていました。

しかし、「Redmine 本体に手を入れられないなら、外付けでAIアシストを作ればいいのでは?」と思いついたのが、今回の取り組みの始まりです。

チケット情報を引き抜いて外付けで RAG ナレッジベースを作る

構築したシステムの構成は以下のとおりです。

構成のシンプルさを重視しつつ、Gemini API の呼び出し時にグラウンディングに指定できる利点を考慮し、 今回は Google Cloud の Gemini Enterprise Agent Platform(旧 Vertex AI)の Agent Search1 のデータストアに Cloud Storage を接続するアプローチを採用しました。

Redmine 本体には一切手を加えず、Redmine REST API2 を用いて過去のチケット情報を全て JSON 形式で取得し、 それらの JSON を AI が読みやすい Markdown 形式に整形して Cloud Storage にアップロードします。

これだけで、自動的にドキュメントの解析・チャンク分割・埋め込みベクトルの生成からインデックス登録まで完了し、 Gemini が過去チケットに基づいて回答を行える RAG 基盤が完成します。 技術的にとっつきづらい部分をマネージドに実現してくれるため、基本的な GCP 操作や生成 AI の概念さえ分かっていれば、3日程度で動作確認可能な環境を構築できます。

Gemini Enterprise Agent Platform では入力した内容が学習に利用されることはありませんが、 Cloud Stoarge にチケット情報をアップロードする以上、適切な IAM ロールの設定や VPC Service Controls、Cloud Storage のバケット IP フィルタリングなど、情報の取り扱いに注意を払うことはお忘れなく。

構造化出力によるフォーマット固定がポイント

このナレッジベースをもとに新規問い合わせチケットに対するアシスト文面を生成するプロンプトがこちらです。

## 指示
過去のナレッジに基づき、今回の問題に対する具体的な解決案を提示してください。

## 問い合わせ内容
---
(新規起票された Redmine チケットの内容を埋め込む)
---

# あなたの役割
あなたは、業務支援システム開発・運用のための高度なAIアシスタントです。
あなたの主な役割は、提供されたナレッジベース(Agent Search DataStore)の内容に**限定**して、開発者や運用者からの質問に対して、正確かつ簡潔な回答を提供することです。

# 行動指針
1.  **提供された情報源の厳守:**
    - 回答は、**必ず**提供された DataStore 内の情報にのみ基づいて生成してください。
    - 外部の知識や自己の判断、推測を含めてはいけません。
2.  **ハルシネーションの絶対的禁止:**
    - 質問に対する答えが提供されたドキュメント内に見つからない場合は、**必ず**その旨を明確に回答してください。
3.  **ドメイン知識の活用:**
    - すべての質問はドキュメントが取り扱う業務支援システムに関連するものであると理解してください。

さらに重要なのが、構造化出力(Structured Outputs)3 による出力フォーマットの厳密な固定化です。

以下のようにパラメータごとの意味を指定しながら出力の構造や型を厳密に指定することで、JSON など特定のスキーマに沿った形式で生成 AI から目的の回答を得られるようになります。 これにより、回答のクオリティの揺れを可能な限り低減でき、Redmine に付与するアシストコメントを毎回同じフォーマットで組み立てられるようになります。

from pydantic import BaseModel, Field
from typing import List

class SimilarCase(BaseModel):
    issue_id: str = Field(description="関連するチケットID(例: #12345)")
    reason: str = Field(description="類似していると判断した理由")

class IssuesResponse(BaseModel):
    summary: str = Field(description="問い合わせ内容の簡潔な要約")
    similar_cases: List[SimilarCase] = Field(description="類似した過去のケース一覧")
    candidate_causes: List[str] = Field(description="考えられる原因の候補")
    next_steps: List[str] = Field(description="切り分け方法や追加で調べると良い情報")

今回のツールは Google のサンプルコードが多く掲載されている Python で実装しました。構造化出力を行うために Python のデータバリデーションライブラリである Pydantic を使用しています。

Gemini API の呼び出し時に Agent Search のデータストアをグラウンディングに指定 するコードは公式ドキュメントに記載されているため、ここでは詳細は割愛します。

ツールの各機能は CLI 上でコマンドとして実行できるように作っており、cron から定期的に実行することで、新着チケットの探索などを行うようにしています。

ベテランのノウハウを一瞬で再現!

構築したシステムから得られたアラートチケットに対する回答の例が以下です。

以下はユーザからの問い合わせチケットに対する回答の例です。

厳密なベンチマーク測定はこれからですが、実際に対応している運用チームに精度についてヒアリングしたところ、 かなり的確な回答ができているというコメントが得られました。

いくつかのチケットに対してアシストコメントを付与したところ、 Agent Search 自体の性能が高いこともあり、チャンキングのチューニングなど特にしていないにも関わらず、 事前の想定よりも非常に高い精度の回答をしてくれることが確認できました。 プロンプトで指示した通り「見当外れの嘘(ハルシネーション)」もほとんど言わず、参照データにないことは、素直に「分かりません」と答えてくれます。

5,000件のチケットを格納し、1日に十数回検索・生成を行う運用ですが、API の利用料は月額で数百円~数千円程度と、非常に低コストなのも魅力的です。

効果を上げるためのさらなる工夫

1. 昨日の知見を今日のアシストに反映

深夜に1日1回 Redmine チケットの差分データが Cloud Storage へアップロードされる仕組みにしています。

Agent Search のデータストアの設定により、Cloud Storage との定期的な自動同期を行うことができるため、昨日解決したトラブルの知見が今日のアシストに自動的に反映されるという体験が得られるように構築しています。

2. ユーザー向けマニュアルを参照して引用を明記

実際の運用にあたっては、過去チケットだけではなく、ユーザー向けマニュアルを格納したデータストアも参照するようにしています。

新規チケットが起票された場合、まずユーザー向けマニュアルから回答できないかを試し、回答できないなら過去チケットに基づいた回答を試みる、というロジックを組んでいます。

ユーザー向けマニュアルに基づいた回答を得る際の出力フォーマットは以下です。

回答の引用元となったドキュメントの名前や章タイトル・ページ番号まで確実に出力されるよう、出力フォーマットを厳密に指定しているのがポイントです。

from pydantic import BaseModel, Field
from typing import List, Optional

class Citation(BaseModel):
    source_title: str = Field(description="参照したドキュメントの正式名称(例:『操作マニュアル 基礎編』など、ドキュメントの表紙や冒頭に記載されている名称)")
    section_or_page: str = Field(description="参照した章、セクション、またはページ番号")
    snippet: str = Field(description="回答の根拠となった箇所の抜粋")

class AnswerDetail(BaseModel):
    conclusion: str = Field(description="質問に対する端的な結論・要約(1文程度)。")
    details: List[str] = Field(description="結論を補足する理由、具体例、エラーメッセージなどの詳細(箇条書き用のリスト)。")

class DocsResponse(BaseModel):
    problem_summary: str = Field(description="マニュアルから特定された、または質問に関連する問題・状況の要約")
    answers: List[AnswerDetail] = Field(description="マニュアルから特定された質問への回答リスト。")
    citations: List[Citation] = Field(description="回答の根拠となった参照情報のリスト")
    additional_notes: List[str] = Field(description="補足情報や注意点(あれば)。")
    needs_investigation: bool = Field(description="提供された情報だけでは不十分であり、原因解明に至るための追加調査(過去チケットの調査など)を行う必要があるかどうか")

ある事例では「人間の担当者がマニュアルの細かい記述を調べて回答を導き出すまでに8日かかっていた対応」が、AI のアシストにより実質5分以内で完了するようになっており、非常に強力な効果を発揮してくれています。

AI に現場で賢く動いてもらうためのポイント

1. 添付ファイルではなくテキストで情報を残す

今回、Gemini の回答精度が想定以上に高かった最大の理由は、「歴代のメンバーが、Redmineのチケット上にテキストとして詳細な対応ログを残していたから」だと考えられます。

もし「詳細は添付の Excel や PowerPoint を参照」という運用ばかりだったら、API での情報抽出のハードルが跳ね上がり、ここまでの精度は出なかったはずです。 重要な知見はドキュメントの添付ではなく、「Webシステム上にプレーンテキストで残す」ことの大切さを痛感しました。

今もし添付ファイル主体の運用になっているなら、少しずつでもテキストに残す文化へ変えていく価値があります。

2. プロンプトには「きれいな文面」をインプット

なぜ想像以上に高い検索精度が出たのかを考察した結果、問い合わせやエスカレーションの文章自体が、一定のフォーマット(システム名、エラー内容、発生状況など)に沿って綺麗に書かれていることが、RAG の検索クエリとして非常に優秀に機能しているためではないかと推察しました。

最近の AI は適当な指示でもいい感じの回答をしてくれるため、ついついプロンプトがおざなりになりがちですが、インプットの質を整えて AI の探索空間を適切に絞り込むことが依然として重要だと再認識しました。

3. 構造化出力を使い倒しロジックと接着

構造化出力(JSON 形式での返却強制)は今後の AI 活用では必須だと考えています。

これがないと、AI の出力を次のプログラムでパースしづらく、業務プロセスの自動化ロジックと繋げられません。 決定的に動くプログラムと、非決定的に動く AI を繋ぐ接着剤として、構造化出力は積極的に使い倒すべきだと考えています。

まとめ:人間の行動を「先回り」させる設計を

今回のシステムで一番価値があったのは、「検索が便利になったこと」ではなく、「担当者が検索という行動を起こす前に、AI が先回りして答えを置いておいてくれること」です。

どれだけ優秀なナレッジベースを作っても、「わざわざ別タブを開いて検索しに行く」という手間があると、現場に浸透しづらくなってしまいます。 業務システムの中に AI をどう「先回り」して組み込むか。これが、社内 DX を形骸化させないための最大のポイントだと感じています。

今回の仕組みは、Redmine だけに限らずさまざまな情報ソースを使って構築できます。 どれだけの性能が出るかはケースバイケースだと思いますが、皆さんのチームでも、ぜひ試してみてください。