AIエージェントをチームに統合するとき、最初に直面するのは「どのツールをハブにするか」という問いです。
私たちが最初に試みたのはSlackでした。エージェントにSlack botを持たせて、チャンネルにメッセージを投稿させる形です。直感的に「会話できる」感じがして良さそうに思えましたが、実際に動かしてみると問題が出てきました。
Slackをハブにしたときの失敗
Slackのスレッドは状態を持ちません。ボットがメッセージを投稿しても、「このタスクが完了したのか、まだ処理中なのか」を別の仕組みで管理する必要が生まれる。結局、Slackの隣にタスク管理のスプレッドシートを置くことになって、二重管理が始まりました。
GitHub Issuesも検討しました。APIが整備されていてエージェントとの相性は良い。でも既存チームはGitHub Issuesを使っておらず、人間のタスクはRedmineで管理されている。「AIのタスクだけGitHub」という分断が生まれると、人間がどこを見ればよいか分からなくなると考えました。
結局、既存のRedmineをそのまま使うことにしました。
ステータス遷移をAIとのプロトコルとして使う
Redmineの強みはステータス遷移が明示的に定義できる点です。私たちはAI専用のステータスを追加しました。
| ステータス | 意味 |
|---|---|
| AI処理待ち | エージェントが拾うキュー |
| AI処理中 | エージェントが処理中 |
| AIハンドオーバー | セッション切れで次のエージェントへ |
| AI処理完了 | エージェントの処理が終わった |
| AIレビュー待ち | 人間の判断が必要 |
エージェントはRedmine APIでチケットを取得し、処理を開始するときに「AI処理中」へ更新、完了したら「AI処理完了」へ更新します。人間は「AI処理完了」のチケット一覧を確認するだけでよい。
これはメッセージキューのプロデューサー・コンシューマーパターンと同じです。人間がチケットを作成(エンキュー)し、エージェントが取得して処理(デキュー)する。Redmineのステータス遷移がキューの状態管理を担っています。
# エージェントがキューからタスクを取得する例
# 改善の余地あり: エラー時のリトライとバックオフが未実装
def fetch_next_task(redmine_client):
issues = redmine_client.issue.filter(
assigned_to_id="me",
status_id=STATUS_AI_WAITING,
sort="priority:desc,id:asc",
limit=1
)
return issues[0] if issues else None
チケット履歴が監査ログになる
予想外に重宝しているのが、チケットのジャーナル(コメント履歴)です。エージェントは作業の各ステップでRedmineにコメントを残すようにしています。
### 作業記録: 手順2 完了
- 結果: src/content/news/ に記事ファイルを作成
- 変更点: 2026-04-28-ai-employee-redmine-queue.mdx を新規作成
- コミット: abc1234
- 次の手順への申し送り: GitHub PRの作成に進む
「AIが何をしたか」が後から追跡できる。これが運用を考えると非常に重要です。何か問題が起きたとき、Slackのログを遡るよりもチケット履歴を確認する方がはるかに速い。タスクの依頼から完了まで、人間とAIのやりとりが1つのチケットに集約されます。
既存チームのワークフローを変えずに追加できた本当の理由
正直なところ、これが一番大きかったと考えています。
人間のチームはRedmineを使い続けながら、AIエージェントを「AI処理待ち担当」として追加するだけで済みます。既存のチケット作成フローを変える必要がない。「AIに任せたいタスクは担当者をAIにして、ステータスをAI処理待ちにする」というルールだけ覚えれば動き始めます。
新しいツールの学習コストも、移行コストも発生しません。RedmineとAIエージェントが同じ言語(チケットとステータス)で会話している、というイメージです。
# エージェントが完了時にステータスを更新する処理
def complete_task(redmine_client, issue_id, completion_notes):
redmine_client.issue.update(
issue_id,
status_id=STATUS_AI_COMPLETE,
notes=completion_notes
)
落とし穴とSlack通知を後から追加した経緯
ただ、完全に問題がなかったわけではありません。最初の設計では「AI処理完了になったチケットをRedmineで確認する」という運用を想定していたのですが、人間がRedmineを常時監視するのは現実的ではなかった。
処理が完了してもしばらく誰も気づかない、という状況が続きました。結果として、「AI処理完了」に遷移したタイミングでWebhookを使ってSlack通知を飛ばす仕組みを後から追加しています。確認のきっかけはSlack、詳細はRedmineで確認——という役割分担に落ち着きました。
ここは設計時に見落としていた点で、今思えば最初から入れておくべきでした。ドキュメントにはこう書いてあるけど、という話ではなく、単純に「人間がどう動くか」の想定が甘かったというだけです。
振り返って
Redmineをメッセージキューとして使うという発想は、最初は「既存ツールの流用」という妥協の産物でした。でも実際に動かしてみると、ステータス遷移による状態管理と、チケット履歴による監査ログが、AIエージェントとの統合に思いのほかフィットしていると感じています。
今後は、AIエージェントが処理できないと判断したタスクの自動エスカレーションや、複数エージェントが並列でタスクを処理するときの競合防止など、もう少し込み入った使い方も試していきたいと考えています。完成した設計ではありませんが、現時点での判断として公開します。