Redmine AI Helperプラグインを公開しました
新しいRedmineのプラグインを作りました。
また、2025/05/10に実施された第28回Redmine.tokyo勉強会で発表させていただきました。
発表内容を簡単にまとめておきます。
資料
資料はこちらです。
プラグインの概要
Redmine AI Helperというプラグインを作りました。RedmineのサイドバーにAIのチャットボットを表示するものです。
商用で提供されている多くのプロジェクト管理ツールはAI機能を搭載し始めています。OSSのRedmineでもAI機能を搭載して、プロジェクト管理の効率化を図ることができるようにしたいと思い作成しました。
基本機能
チケットやWikiの内容を要約することができます。よくあるやつですね。英語のチケットも日本語で要約してくれます。
ちなみにAI Helperプラグインはユーザーの言語設定を見て話す言葉を決めています。例えば言語設定が中国語だったら中国語で答えます。
チケットの回答案を作ってくれます。回答の要点だけ伝えれば、シチュエーションに合った文章を作ってくれます。内容が良ければ実際にチケットに書き込むこともできます。
リポジトリに登録されているソースコードの解説ができます。差分表示からの解説にも対応しています。
ベクター検索
チケットのベクター検索ができます。ベクター検索を使用するためには別途Qdrantを準備する必要があります。
設定
LLMやモデルを複数登録して切り替えることができます。回答の品質、性能、コストなどを比較して最適なものを選べます。
ただし現状ではOpenAI以外はあまり評価できていません。
ちなみに、チケットに回答を書き込む前には必ずユーザーに内容の確認をするよう内部で指示をしていますが、あまり頭が良くないモデルを使うと指示を無視して勝手に書き込んでしまうことがあります。この辺りは注意が必要です。
LLMに対するインストラクションを追加できます。プロジェクト独自のルールなどを記載しておくとそれを踏まえて回答してくれます。
AI Helper Pluginを拡張する
AI Helper Plugin自体に手を入れなくても機能追加をする方法を2つ用意しています。
- MCPServerを使用する方法
- 独自にコードを追加する方法
MCP Serverを使用する方法
説明するまでもないやつですね。
SlackのMCP Serverを組み込んだ例。AI Helper Plugin本体の機能でチケットを要約した後、MCP Serverの機能でその内容をSlackに送っています。
独自にコードを追加する方法
独自にコードを書いて機能を追加する方法。かなり簡単に機能追加できるようにしたつもり。
マルチエージェントモデル
このプラグインでは、マルチエージェントモデルを採用しています。個別の役割を持った複数のエージェントが自然言語で会話しながら協力してタスクを解決します。
具体的には以下のよう流れです。
- ユーザーからのリクエストをリーダーエージェントが受け取る。
- リーダーエージェントは過去の会話も含めてリクエストの内容を解析し、最終的なゴールを定義する。
- リーダーエージェントはチャットルームを作成し、ゴール達成に必要なエージェントを選定して招待する。
- リーダーエージェントはチャットルームで各エージェントに作業を指示する。その際、チャットルーム内のすべての会話は全エージェントに共有される。
- 各エージェントは他のエージェントの会話の内容も参考にしながらリーダーエージェントからの指示を実行し、チャットルームに結果を報告する。
- リーダーエージェントは各エージェントの報告をもとに、最終的な回答を作成し、ユーザーに返す。
このエージェントを独自の作成して追加することで、機能追加ができます。
langchainrb
なお、今回のエージェントの実装は、langchainrbのassistantという仕組みをベースに構築しています。
占いエージェント
独自に「占いエージェント」を作成して組み込んだ例です。このサンプルコードはプラグインに同梱しています。
エージェントを追加するためには以下の2つのコードを作る必要があります。
- エージェントのクラス
- エージェント本体。RedmineAiHelper::BaseAgentを継承して作成する。
- 実装するメソッドはbackstory, available_tool_povidersの2つ。
- backstoryにはエージェントの役割を文章で記載する。
- available_tool_providersにはエージェントが使用するツールを記載する。
- ツールクラス
- ツールの実装。RedmineAiHelper::BaseToolsを継承して作成する。
- ツールクラス内に実装するtool分だけdefine_functionとtoolの実態のペアを書く。
今回の占いエージェントでは単に大吉、中吉などの文字列をランダムに返しているだけです。
これら2つのコードを実装したら、エージェントクラスをinit.rb等の適当な場所からロードしてください。これで完了です。
上のスライドの例では、ツール側は単に「末吉」という文字列を返しているだけですが、それを受け取った占いエージェントが
・運勢:末吉
・少しずつ良い方向に向かいますが、油断せずに過ごすことが大切です。
・小さな幸運を見逃さないようにしましょう。
という文を勝手に生成してくれています。これはエージェントの役割を定義したbackstoryに従ってこのエージェントが自律的に判断してくれた結果です。
このように、ツール側は単純な処理を実装するだけで、エージェント側で色々なことを考えてくれます。
今後やりたいこと
今回ファーストリリースをしましたが、AIエージェントとしてはまだまだ未熟です。
Redmineを使用してプロジェクトを運営する上で、AI Helperプラグインがチームメンバーの一人として活躍できるくらいにしていけたら良いと思っています。
また、Agent2Agentプロトコルを実装して他のAIエージェントと連携できるようにします。これは近々対応予定。
もし使っていただけたらフィードバックをいただけると幸いです。
作ってみて思ったこと
AIエージェント構築は育成ゲームの如し
プロンプトをチューニングしながらAIエージェントを育てていくのは、まるで育成ゲームのようでした。色々言い聞かせていくとちょっとずつ賢くなっていきます。
しかし、新しく実装した機能を動かすためにプロンプトを変えているうちに、前にできていたことがいつの間にかできなくなったり苦労します。
LLMのAPIは普通のAPIと違って、返ってくる値が予想できないところが難しいところでもあり面白いところです。
AIエージェント間連系の可能性
将来的には1つのエージェントでどんなタスクもこなせる汎用エージェントが登場するかもしれません。
しかし現状はある特定のドメインに特化したエージェントを作るのが現実的です。
Agent2Agentプロトコルのような仕組みを使って独立したエージェント同士が協力できるようなネットワークがメッシュ上に出来上がると、それが仮想的な汎用エージェントとして機能するようになるかもしれません。
最後に
7月にはこちらでもお話させていただく予定です。興味があったら来てください。
追記: 機能追加に関する記事を書きました。
Discussion