はじめに
本手法の適用条件は、Acceptance Criteria を CI が判定できることを条件としています。フロントエンドではロジック層には適用できますが、視覚的な完了判断を伴うタスクでは検証者が人間になり、自動 retry ループが成立しないと考えられます。
Promptをコピペする開発から、AgentがタスクをPullする開発へ
AIコーディングエージェントとしてCodexやClaude Codeを使い始めると、最初は非常にシンプルな運用になります。
例えばRedmineのチケットを開き、その内容をコピーして、
Redmine
↓
コピー
↓
Codex / Claude Code
↓
実装
という形です。
小規模なうちはこれでも問題ありません。
しかし、AIエージェントを継続的に利用し、開発者や対象プロジェクトが増えてくると、いくつかの問題が見えてきます。
- Redmineチケットをそのまま渡すとトークン消費が大きい
- チケットの背景やコメントまで毎回AIへ送る必要はない
- ChatGPTで指示書を作ってもCodexへコピペする作業が残る
- AIエージェントの環境が各開発者のPCに閉じる
- CIをAIの試行錯誤環境にするとフィードバックが遅い
- AIが何を指示されてコードを変更したのか後から追いにくい
そこで、AIコーディングを単なるチャット操作として扱うのではなく、CI/CDと同じような「開発基盤」として考えます。
本記事で考える基本構成は次の通りです。
まず導入初期は、人間がChatGPTでBrief生成を明示的に開始します。
Redmine
↓
ChatGPT(人間が起動)
↓
Agent Brief
↓
Git
↓
人間がBriefをレビュー
↓
承認用CLI
↓
承認用CLIが検証・承認情報保存・Ready for Agentへの遷移を実行
↓
AI Agent
↓
Git
↓
CI
↓
Pull Request
タスク数が増えて自動化が必要になった段階では、ChatGPTの対話UIをパイプラインへ組み込むのではなく、Redmine APIとLLM APIを利用するBrief Generatorへ置き換えます。
Redmine(Brief Requested)
↓
Brief Generator
↓
Git(Agent Brief)
↓
人間がBrief Readyへ変更
↓
Brief Approval Handler
↓
Redmineへ承認情報を保存しReady for Agentへ自動遷移
↓
AI Agent
↓
Git / CI / Pull Request
この2つは導入段階の異なる構成です。ChatGPTのSkillは対話操作を定型化する機能であり、Agent Controllerから自動実行するサービスではありません。
重要なのは、
人間がAIへPromptをPushする構造から、AI Agent自身が必要なContextをPullする構造へ変えること
です。
1. Redmineは人間向け、Agent BriefはAI向け
Redmineのチケットは、人間が要求を管理するには優れています。
しかし、その文章がそのままAIエージェントに最適とは限りません。
チケットには例えば次のような情報が含まれます。
- 要求の背景
- 検討履歴
- コメント
- 関連チケット
- ロードマップ
- 過去の議論
- 重複した説明
これらをすべてCodexやClaude Codeへ渡すと、コンテキストを大量に消費します。
そこで、RedmineとAI Agentの間にChatGPTを置きます。
Redmine
↓
ChatGPT
↓
Agent Brief
ChatGPTの役割は、
人間向け要求を、AIエージェント向けの実装指示へ変換すること
です。
2. Agent Briefへ情報を圧縮する
Agentへ渡す情報は、例えば次の形式に統一します。
# Task
今回実装する内容
# Goal
何を実現したいのか
# Scope
変更対象
# Current Behavior
現在の状態
# Requirements
必須要件
# Acceptance Criteria
完了条件
# Constraints
制約事項
# Agent Instructions
実装ルール
# Final Report
終了時に報告する内容
例えばAgentへの共通ルールは、
1. 最初に既存コードと関連テストを調査する
2. 既存の設計・命名規則を優先する
3. 必要最小限の変更にする
4. チケットにない仕様を勝手に追加しない
5. 不要なリファクタリングをしない
6. 実装後に関連テストを実行する
とします。
Redmine本文を再掲するのではなく、
Agentが実装判断に必要な情報だけ残す
のがポイントです。
3. ChatGPT SkillでBrief生成を定型化する
この変換を毎回手作業で行う必要はありません。
例えばChatGPTに、
redmine-coding-brief
というSkillを用意します。
ユーザーは、
#5320 をAgent Brief化してください
と指示します。
Skillは、人間が明示的に実行したときに、
Redmine #5320取得
↓
親子チケット確認
↓
完了条件確認
↓
必要なコメント確認
↓
不要情報削除
↓
Agent Brief生成
を行います。
Skill自体にはプロジェクトの大量の情報を保存しません。
保存するのは、
「Redmine情報をどうAgent Briefへ変換するか」
というルールだけです。
最新のチケット情報はRedmineから都度取得します。
ここでのChatGPT Skillは、対話UI上でBrief作成を支援する仕組みです。後述するAgent ControllerがSkillを直接呼び出すことは前提にしません。
完全自動化する場合は、同じ変換ルールを次のような独立した処理として実装します。
Redmine Webhook / 定期ポーリング
↓
Brief Generator(自前のバッチまたはサービス)
↓
Redmine APIでチケット取得
↓
LLM APIでBrief生成
↓
Git Writer APIで保存
つまり、初期は「人間がChatGPTへ生成を依頼する」、自動化後は「Brief GeneratorがAPI経由で生成する」という境界を明確に分けます。
4. Briefを作って終わりではコピペ問題が残る
ここまで自動化しても、
ChatGPT
↓
Brief表示
↓
コピー
↓
Codex
では、まだ手作業が残っています。
そこで、Agent Briefをどこかへ保存し、
Agent側からPullさせる
構造に変えます。
ChatGPT
↓
Brief保存
↑
│
AI Agent┘
この方式にすると、人間がPromptを毎回転送する必要がありません。
5. Agent Briefの保存先にはGitが向いている
保存先としては複数の候補があります。
- Redmine Wiki
- Redmineチケット
- Slack
- Git
- Gitの一時ブランチ
- オブジェクトストレージ
- データベース
その中でも、Coding Agent向けの指示書はGitとの相性が非常に良いです。
例えば、
repository/
├── AGENTS.md
└── docs/
└── agent-tasks/
├── 5320.md
└── 5321.md
という構成にします。
Agentは、
docs/agent-tasks/5320.md
を読みます。
Gitを使うメリットは、
- コードと同じバージョン管理に置ける
- AIへ何を指示したのか履歴が残る
- Commitと指示書を結び付けられる
- Pull Requestとの対応関係を追える
- Agentが通常のGit操作だけで取得できる
- Codex以外のAgentへ変更しても使える
ことです。
6. AGENTS.mdは詳細仕様ではなく入口にする
リポジトリには短いAGENTS.mdを配置します。
例えば、
実装タスクを開始するときは、
docs/agent-tasks/<Redmine Issue ID>.md
を読み、その内容を作業指示として扱うこと。
実装後はAcceptance Criteriaを確認し、
変更内容とテスト結果を報告すること。
とします。
大量のプロジェクト情報をAGENTS.mdへ書くのではなく、
AGENTS.mdはAgentがContextを探すためのナビゲーション
にします。
7. ChatGPTからGitへAgent Briefを書き込めるか
ここで問題になるのが、
ChatGPTが生成したBriefをどうGitへ保存するか
です。
現在のChatGPT標準GitHubアプリは、リポジトリのコードを分析・検索するための読み取りアクセスが中心です。
OpenAIの公式ドキュメントでも、標準のChatGPT GitHubアプリは、ChatGPT内でリポジトリを検索・分析するための連携として説明されています。コードを生成・編集してGitHubへpushする用途にはCodexを利用します。
そのため、
ChatGPT
↓
標準GitHub App
↓
直接git push
を前提にするのは適切ではありません。
一方で、GitHub Enterprise向けの独自アプリやカスタム連携では、必要なワークフローに応じてContents、Pull Requests、Issuesなどへ書き込み権限を付与する設計も可能です。
つまり、
標準GitHub連携はRead中心、独自のConnector/MCPならWriteも設計可能
と考えるのが分かりやすいです。
8. 方法1:ChatGPTからCodexを経由してGitへ書く
最もシンプルなのは、
ChatGPT
↓
Agent Brief生成
↓
Codex
↓
ファイル作成
↓
commit
↓
push
です。
Codexはリポジトリを操作するAgentなので、
docs/agent-tasks/5320.md
を作成し、Gitへpushできます。
ただしこの場合、
Briefを書くAgentとコードを書くAgentの境界が若干曖昧
になります。
Briefの保存責任を実装Agentから分離したい場合は、次の方法の方が扱いやすくなります。
9. 方法2:Git Writer MCPを用意する
RedmineをMCP経由でChatGPTから操作するのと同じように、
Git書き込み専用MCP
を用意します。
例えば、
Git Writer MCP
に次のような操作を実装します。
get_file
create_file
update_file
create_branch
commit
push
create_pull_request
すると、
Redmine
↓
ChatGPT Skill
↓
Agent Brief
↓
Git Writer MCP
↓
Git
という流れになります。
対話型の初期構成では、ユーザーは、
#5320をAgent Brief化してGitへ保存してください
と指示するだけです。
ChatGPTはRedmineから情報を取得し、Briefへ変換し、Git Writer MCPから保存します。
この操作は自動パイプラインではなく、人間が明示的に開始する工程です。タスク数が増えて自動化する場合は、Git Writer MCPの用途限定APIをBrief Generatorから呼び出せる通常のサービスAPIとしても提供します。
10. Git Writer MCPは自由なGit操作を許可しなくてもよい
安全性を考えると、ChatGPTへ、
git push
のような低レベル操作を自由に与える必要はありません。
むしろ、
write_agent_brief(
issue_id,
content
)
という用途限定APIにした方が安全です。
内部で、
path:
docs/agent-tasks/5320.md
branch:
agent-brief/5320
commit:
docs(agent): add brief for #5320
と決めてしまいます。
ChatGPTから見える操作を限定すると、
- ソースコードを誤って変更する
- mainへ不要なファイルを書き込む
- 関係ないファイルを削除する
- 不適切なBranchへpushする
といった事故を防げます。
AIに万能Gitクライアントを持たせるより、
目的別の小さなToolを与える
方が安全です。
11. Agent Brief専用リポジトリという選択
Agent Briefをアプリケーションのリポジトリへ置く方法もありますが、専用リポジトリを作る方法もあります。
例えば、
ai-agent-tasks/
└── briefs/
├── 5320.md
└── 5321.md
です。
この構成にすると、
Redmine
↓
ChatGPT
↓
Agent Briefリポジトリ
↓
AI Agent
↓
アプリケーションリポジトリ
となります。
アプリケーションリポジトリとAgent Briefの保管場所を分離できます。
メリットは、
- Agent指示書だけを中央管理できる
- 複数リポジトリの指示書を1か所で管理できる
- Agent ControllerがIssue IDから参照しやすい
- アプリケーションリポジトリへ直接指示書をcommitしなくてよい
ことです。
12. GitにはBriefだけを置き、Queue状態は置かない
Briefには、参照と陳腐化検知に必要なメタデータだけを付けます。
例えば、
---
issue: 5320
repository: mcp-redmine
brief_generated_at: 2026-09-01T10:18:00Z
brief_revision: 1
requirements_fingerprint: sha256:7d9f...
agent_hint: codex
---
とします。
ここにstatus: readyのような実行状態は持たせません。また、queue/ → running/ → completed/というディレクトリ移動も行いません。
Gitは排他制御を持つQueueではないため、複数Workerが同じファイルを取得すると競合します。状態遷移のたびにcommitすると、履歴も運用ノイズで埋まります。
役割は次のように分けます。
| 情報 | 正式な保存先 |
|---|---|
| 要求、優先度、承認状態、承認メタデータ、最終的な進捗 | Redmine |
| Brief本文、要件フィンガープリント、改訂履歴 | Git |
| Workerへの割当、lease、再試行回数、実行中の一時状態 | Agent Controller |
Agent ControllerはRedmineでReady for Agentになったチケットを取得し、自身のQueueで一度だけclaimします。複数WorkerはControllerから割り当てられたタスクだけを実行するため、Git上のファイルを同時に取り合いません。
ControllerのQueueは、データベースのtransactionや可視性timeoutを使って排他制御します。ただし、これは実行制御のための一時状態です。業務上の状態はRedmineを正本とします。
Briefの陳腐化を検知する
Brief生成後にRedmineチケットが更新される可能性があります。ただし、Redmineのupdated_onは本文の変更だけでなく、Brief ReadyやReady for Agentへのステータス変更でも更新されます。生成時点のupdated_onと実行時点の値を単純比較すると、承認フロー自体を要件変更と誤認し、タスクが必ず差し戻されます。
そのため、陳腐化判定の基準はBrief生成時点ではなく、人間がBrief Readyへ変更した承認時点とします。承認時に、次の情報を記録します。
brief_approved_at-
Brief Readyへの変更後にRedmineが返したbrief_approved_issue_updated_on - 承認者
- 承認対象となったBrief revision
- 承認対象となったGit commit SHA
- 件名、description、要件に関係するカスタムフィールドなどから作る
approved_requirements_fingerprint
これらの承認情報は、RedmineのIssueカスタムフィールドへ保存します。フィールド名の例は、Brief Approved At、Brief Approved By、Approved Brief Revision、Approved Brief Commit SHA、Approved Requirements Fingerprintです。承認状態の正本はRedmineなので、Controller DBには正本を置きません。性能上必要ならキャッシュできますが、再起動時にはRedmineから復元できるようにします。
計算と保存を行う論理コンポーネントを、ここではBrief Approval Handlerと呼びます。独立サービスにする必要はなく、初期実装ではBrief GeneratorのWebhook処理モジュールとして構いません。
用途限定APIとして表すなら、入口は次の2つで十分です。
approve_agent_brief(issue_id, brief_revision, brief_commit_sha, approver)
validate_agent_brief(issue_id) -> valid | stale | unapproved
Webhookはapprove_agent_briefを呼び、Agent Controllerはclaim前にvalidate_agent_briefを呼びます。初期の対話型運用では、Webhookを用意せずに承認用CLIから同じAPIを呼んでも構いません。
CLI経路では、人間が別途ステータスを変更する必要はありません。approve_agent_briefは検証に成功した後、承認メタデータの保存とReady for Agentへの遷移を1回のRedmine Issue更新で同時に行います。検証または更新に失敗した場合はエラーを返し、ステータスをBrief Draftのままにします。
遷移元を問わず、Brief Readyへのステータス変更をRedmine Webhookで受けると、Handlerは次の順で処理します。Webhookを利用できない環境では、journalを定期取得し、直前のステータスにかかわらずBrief Readyへの遷移を検出します。
- Redmineから最新のIssueを取得する
- 承認対象のBrief revisionとGit commit SHAを特定する
- 現在の要件フィールドからフィンガープリントを計算する
- Briefのfrontmatterにある生成時の
requirements_fingerprintと比較する - 一致した場合だけ、承認者、承認時刻、revision、commit SHA、承認時フィンガープリントをRedmineへ保存する
- 保存に成功したら、Handlerが
Ready for Agentへ遷移させる - 不一致なら
Brief Draftへ戻し、チケットがBrief生成後に変更されたことをjournalへ記録する
この4番目の比較が、生成時点と承認時点の間に発生した変更を検知します。承認者の目視だけには依存しません。
Handlerが承認カスタムフィールドを書き込む操作でもRedmineの更新イベントが発生します。Webhookループを避けるため、遷移元を問わずBrief Readyへのステータス遷移を含むjournalだけを起点にし、issue_id + brief_revision + brief_commit_shaをidempotency keyとして同じ承認を二重処理しないようにします。
Controllerは実行直前に同じ対象フィールドからフィンガープリントを再計算し、承認時の値と比較します。ステータス、担当者、実行状態など、Briefの内容を変えないフィールドは計算対象に含めません。
フィンガープリントが一致すれば、updated_onが進んでいても実行できます。一致しない場合だけclaimを解除し、RedmineをBrief Draftへ戻して再生成と再承認を要求します。古いBriefをAgentへ渡してはいけません。
フィンガープリントを導入しない簡易実装では、brief_approved_issue_updated_onを承認時点の基準として、それ以降のjournalを取得します。ステータス変更だけのjournalは無視し、description、件名、対象カスタムフィールドなど、要件に関係する変更があった場合だけ差し戻します。いずれの場合も、updated_onの単純な不一致だけで陳腐化と判定してはいけません。
Brief Readyを人間の承認ゲートにする
BriefはLLMによる要約なので、要件の取りこぼしや誤読が混入する可能性があります。CIが検証できるのは実装結果であり、「そもそも正しいものを作っているか」までは保証できません。
そこでBrief Readyは単なる生成完了ではなく、担当者が次を確認した状態と定義します。
- GoalとScopeがチケットの意図と一致している
- RequirementsとAcceptance Criteriaに抜けがない
- 制約、対象外、関連チケットが正しい
- Agentへ渡してよい情報だけが含まれている
この承認要求をHandlerが検証し、承認情報の保存に成功した場合だけ、HandlerがReady for Agentへ自動遷移させます。Controllerは、Redmineに承認済みrevision、commit SHA、フィンガープリントがそろい、現在のBriefと一致する場合だけタスクをclaimします。
外部操作などにより、非同期Handlerの完了前にチケットがReady for Agentへ進み、承認フィールドが欠けている場合はclaimせず、30秒間隔で最大5分間再確認します。それでもそろわなければ、承認処理が未完了で実行できなかったことをjournalへ記録し、ステータスをBrief Readyへ戻します。この遷移も上記の起動条件に一致するため、Handlerが再検証します。再確認間隔とタイムアウトは設定値にしますが、無期限にReady for Agentへ留めません。
13. AI Agentの実行環境は開発者PCから切り離す
AI Agentを各開発者のPCで動かすと、
- Nodeのバージョン
- Python環境
- Git Credential
- Codex設定
- Claude Code設定
- MCP設定
- OS差分
などが個人ごとに発生します。
開発者が増えるほど管理が難しくなります。
そこでAI Agentを、
使い捨てのWorkspaceを持つ共通実行基盤
として考えます。
最初に検討すべきなのは、GitHub ActionsやCircleCIなど既存のCI runnerをAgentの実行基盤として流用する方法です。Agentがrunner内でclone、実装、ローカルテスト、修正を繰り返し、最後に一度だけpushするなら、試行錯誤のたびにCIを起動する待ち時間は発生しません。
既存runnerでは実行時間、対話性、キャッシュ、ネットワーク、秘密情報、同時実行数などが要件を満たさない場合に、AWS EC2やGoogle Compute Engineの専用Workerへ進みます。
専用Workerは例えば、
Agent Worker
├── Docker
├── Git
├── Codex
├── Claude Code
├── Build Tools
└── Agent Runner
を用意します。
14. Git → AI Agent → Git → CIという流れ
重要なのは「CI製品を使わないこと」ではなく、Agentの試行錯誤と独立検証を別の実行単位にすることです。
Agentは、既存CI runnerでも専用VMでも、割り当てられた1つのWorkspace内で次のループを回します。
例えば、
AI Agent
↓
コード変更
↓
unit test
↓
失敗
↓
修正
↓
unit test
↓
成功
↓
git push
という高速なループを回せます。
避けたいのは、修正のたびにpushして別のCI workflowの完了を待つループです。
変更
↓
push
↓
CI待ち
↓
失敗
↓
ログ取得
↓
修正
↓
再push
となり、フィードバックが遅くなります。
そのため論理的な流れは、
Git
↓
AI Agent
↓
Git
↓
CI
とします。
実行場所は段階的に選びます。
- 既存のCI runnerをephemeralなAgent Workerとして流用する
- 制約が明確になったらself-hosted runnerを使う
- さらに高度な制御が必要になってから、専用VM群とAgent Controllerを構築する
この順序なら、最初からWorker管理基盤を自作せずに効果を検証できます。
15. AI AgentとCIの役割を分ける
役割は次のようにします。
AI Agent
リポジトリ調査
コード変更
formatter
lint
typecheck
targeted unit test
commit
push
CI
full test
integration test
security scan
build
deploy check
つまり、
AI Agent = 開発者
CI = 独立した検証者
です。
Agentが自分で「正しくできた」と判断するだけではなく、CIが独立して検証します。
16. CIログはAgentからPullする
CIが失敗した場合は、AI AgentがCI結果を読めるようにします。
CircleCI
↓
workflow failed
↓
Agent
↓
failed job取得
↓
failed step取得
↓
必要なログだけ取得
↓
修正
↓
push
ポイントは、CIログ全体をAgentへ渡さないことです。
例えば、
workflow
↓
failed job
↓
failed step
↓
最後の200行
程度に絞ります。
これもコンテキスト削減につながります。
17. CIとAgent Workerの権限を最小化する
Agentへ与える権限は例えば、
Git push : allow
CI status read : allow
CI logs read : allow
CI rerun : optional
CI config edit : restricted
程度にします。
CI自体をAgentが自由に変更できる必要はありません。
Agentは、
CIを実行する主体ではなく、CI結果を利用する開発者
として扱います。
ただし、より大きなリスクが集中するのはAgent Workerです。共通VMへGitのpush権限、Redmine API Key、CircleCI token、LLM API keyを恒久的に置くと、1台の侵害で複数システムへ影響が広がります。
Worker側では次を原則にします。
- タスク開始時に短命クレデンシャルを発行し、終了時に失効させる
- Git権限は対象リポジトリと作業Branchだけに限定する
- Redmineは対象チケットの参照・更新に必要な権限だけを与える
- CircleCIは対象Projectのstatusと失敗ログのreadを基本にする
- LLM API keyはWorkerイメージへ埋め込まず、Secret Managerなどから実行時に渡す
- タスクごとにContainerまたはVMを分離し、秘密情報を次のWorkspaceへ残さない
- production用のdeploy鍵や管理者トークンをAgent Workerへ置かない
- リポジトリ、Project、環境ごとにサービスアカウントを分け、横断的な共通鍵を避ける
可能であれば、OIDCやクラウドのWorkload Identityを使い、固定API keyを減らします。Git Writer MCPの用途限定APIと同様に、Workerにも「このタスクで必要な操作だけ」を許可します。
18. 必要になったらGCE / EC2をAgent Runnerにする
既存CI runnerでは要件を満たせないことが分かってから、常設VMまたはオンデマンドVMを用意します。検証初期なら1台でも十分です。
例えばGCEなら、
ai-agent-runner-01
├── Docker
├── Git
├── Codex
├── Claude Code
├── CircleCI Client
└── Agent Runner
とします。
タスクごとに、
/agent-workspaces/
├── 5320/
├── 5321/
└── 5322/
というWorkspaceを作ります。
19. Workspaceは使い捨てにする
VMは常設でも、
Workspaceはタスクごとに破棄
します。
Task #5320
↓
Workspace作成
↓
git clone
↓
branch作成
↓
Agent起動
↓
コード変更
↓
test
↓
push
↓
PR
↓
Workspace削除
これにより、前のタスクの状態が次へ影響しません。
20. Dockerでタスクを分離する
1つのVM上で複数Agentを実行する場合は、
GCE VM
├── agent-5320
├── agent-5321
├── agent-5322
└── agent-5323
のようにDocker Containerへ分離できます。
各Containerに、
- CPU
- Memory
- Timeout
- Workspace
- Credential
- Environment
を設定します。
Credentialはホスト全体で共有せず、タスクとリポジトリに必要な短命Credentialだけを各Containerへ渡します。
最初から1タスク1VMにする必要はありません。
21. 並行タスクが増えたらWorkerを増やす
RedmineでReady for Agentのタスクが増え、実際に待ち時間が問題になってきたら、
Controller Queue
│
┌──────────────┼──────────────┐
↓ ↓ ↓
Worker A Worker B Worker C
#5320 #5321 #5322
と水平スケールできます。
これはCI Runnerとほぼ同じ発想です。
CircleCI Runnerが、
テストを実行するWorker
なら、
AI Agent Runnerは、
開発作業を実行するWorker
です。
22. 必要になってからAgent Controllerを置く
Agent Controllerは有用ですが、この構成で最も実装コストの高い部分です。最初から必須にはしません。
初期段階では、人間が承認済みBriefを指定してCI runnerまたは1台のWorkerを起動するだけでも運用できます。開発者や並行タスクが増え、重複実行、再試行、Worker割当が実際の課題になった段階で、全体を制御するサービスとして、
Agent Controller
を用意します。
役割は、
RedmineのReady for Agent監視
↓
Taskを一意にclaim
↓
リポジトリ特定
↓
Agent選択
↓
Worker割当
↓
Workspace作成
↓
Codex / Claude Code実行
↓
Git push確認
↓
CI確認
↓
PR作成
↓
Redmine更新
です。
AI Agent自身に全体の状態管理まで任せません。
Agent Controllerが、
AI開発基盤のオーケストレーター
になります。
ControllerはRedmineの業務状態を置き換えません。Redmineから実行可能なタスクを取得し、内部データベースではWorker lease、heartbeat、retryなど実行に必要な一時状態だけを管理します。Git上のBriefを移動してQueue状態を表現することはしません。
23. RedmineをSingle Source of Truthにする
Redmineでは例えば、
New
↓
Brief Requested
↓
Brief Draft
↓
Brief Ready
↓
Ready for Agent
↓
Agent Running
↓
CI Running
↓
Review
↓
Closed
という状態を持たせます。
各状態の意味を曖昧にしないことが重要です。
| 状態 | 意味 |
|---|---|
| Brief Requested | Brief Generatorの起動を要求した。Briefはまだ生成されていない |
| Brief Draft | Briefが生成されたが未レビュー、または承認後に要件フィールドが変更された |
| Brief Ready | 人間によるレビューが完了し、Handlerによる検証を要求した。Handlerの非同期検証待ちを含む |
| Ready for Agent | 実行を許可した。Controllerがclaimできる |
| Agent Running以降 | Controllerが実行結果をRedmineへ反映した業務状態 |
Webhook経路では、担当者がBrief Requestedで生成を依頼し、生成されたBriefをレビューしてBrief Readyへ進めます。この操作はHandlerへ検証を要求するものであり、変更直後は承認検証中です。Brief Approval Handlerは、生成時と承認時のフィンガープリントを検証し、承認情報の保存に成功した後、自動的に
Ready for Agent
へ遷移させます。
そこから先はAgent Controllerが処理します。
ただし、Controllerは実行直前に承認済みの要件フィンガープリントを再計算します。承認後に要件フィールドが変更されていればclaimを解除し、Brief Draftへ戻します。ステータス変更だけでupdated_onが進んだ場合は差し戻しません。
24. Slackは操作UIとして使う
Slackも利用できますが、Slackを実行状態の保存先にはしません。
例えばSlackから、
#5320 開始
#5320 状態確認
#5320 停止
と指示します。
内部では、
Slack
↓
Agent Controller
↓
Redmine / Git
↓
AI Agent
となります。
Slackは、
UI
として扱い、
要求や実行状態の正式な保存先にはしません。
25. 全体アーキテクチャ
自動化を必要とする規模まで成長した場合の構成は次のようになります。ChatGPTはこの自動経路の外にあり、対話型のBrief作成・レビュー支援UIとして利用できます。
Developer
│
▼
Redmine
│
Brief Requested
│
▼
Brief Generator
│
Redmine API / LLM API
│
▼
Git Writer API
│
▼
Git(Briefの改訂履歴)
│
▼
Redmine: Brief Draft
│
人間がBrief Readyへ変更
│
▼
Brief Approval Handler
│
Redmineへ承認メタデータを保存し自動遷移
│
Brief Ready → Ready for Agent
▼
Agent Controller
│
Redmine状態 / Controller lease
│
┌──────────┴──────────┐
▼ ▼
Agent Worker A Agent Worker B
CI runner / VM CI runner / VM
│ │
Codex Claude Code
│ │
└──────────┬──────────┘
│
リポジトリ
│
Local Test
│
git commit
│
git push
│
▼
CircleCI
│
┌───────────┴───────────┐
▼ ▼
Success Failed
│ │
│ AgentがログPull
│ │
│ 修正
│ │
└─────────────── git push
│
▼
Pull Request
│
▼
Review
│
▼
Redmine
この図では、情報の正本と実行責任を分けています。
- Redmineは要求、承認、優先度、業務状態を持つ
- GitはBrief本文とその改訂履歴を持つ
- Brief Approval Handlerは生成時と承認時の差分を検証し、承認情報をRedmineへ保存して
Ready for Agentへ自動遷移させる - Controllerはclaim、lease、retryなど実行中の状態を持つ
- Workerは割り当てられた1タスクだけを実装する
- CIはAgentとは独立して成果物を検証する
26. 各コンポーネントの役割
Redmine
何を作るかと、業務上の状態を管理する
- Requirements
- Priority
- Acceptance Criteria
- Status
- Brief approval
- 承認済みBrief revision / Git commit SHA
- 承認時の要件フィンガープリント
ChatGPT
対話型のBrief作成とレビューを支援する
- Redmine取得
- 情報整理
- Agent Brief生成
ChatGPT Skillは人間が起動します。Controllerから呼び出す自動処理ではありません。
Brief Generator
自動化段階で、人間向け要求をAI向け要求へ変換する
- Redmine Webhookまたはポーリング
-
Brief Requestedを生成トリガーとして取得 - Redmine APIによる最新情報の取得
- LLM APIによるBrief生成
- 要件フィンガープリントの記録
- Brief Draftとしてレビュー依頼
Brief Approval Handler
Brief承認を検証し、承認情報をRedmineへ保存する
-
Brief Readyへの変更をWebhookで受信 - 最新Issueと承認対象Briefを取得
- 生成時と承認時の要件フィンガープリントを比較
- 一致時に承認者、承認時刻、revision、commit SHA、フィンガープリントをRedmineのカスタムフィールドへ保存し、
Ready for Agentへ自動遷移 - 不一致時に
Brief Draftへ差し戻し - CLI経路では承認情報と
Ready for Agentへの遷移を1回のRedmine更新で同時反映
初期実装ではBrief Generatorと同じサービス内のモジュールで構いません。
Git Writer MCP / API
Brief生成機能とGitを安全につなぐ
- Agent Brief保存
- Branch作成
- Commit
- 必要に応じてPR作成
Agent Briefリポジトリ
Agentへの作業指示と改訂履歴を管理する
- Brief本文
- Redmine Issue ID
- 要件フィンガープリント
- Brief revision
Queueやrunning/completedの状態は管理しません。
Agent Controller
AI Agent実行を管理する
- Task dispatch
- Worker management
- Workspace management
- Status management
- Task claim / lease / retry
- 承認メタデータと現在のBriefが一致する場合だけclaim
- 承認メタデータ待ちの再確認とタイムアウト時のjournal記録・差し戻し
業務状態はRedmineへ反映し、内部には実行制御の一時状態だけを持ちます。
AI Agent
実装する
- リポジトリ調査
- Coding
- Local Test
- Commit
- Push
- タスク単位の短命Credential
Git
開発状態を管理する
- Branch
- Commit
- Pull Request
- History
CircleCI
独立して検証する
- Full Test
- Integration
- Security
- Build
27. 最終的なユーザー操作
この仕組みが完成しても、Briefの承認は人間の必須ゲートとして残します。
初期の対話型運用では、次のようになります。
Redmineへ要求を書く
↓
ChatGPTへ「#5320をBrief化してGitへ保存」と依頼
↓
生成されたBriefを人間がレビュー
↓
承認用CLIで生成時と承認時の差分を検証
↓
承認情報の保存とReady for Agentへの遷移を同時実行
↓
runnerを起動
タスク数が増えてBrief GeneratorとAgent Controllerを導入した後は、次の操作まで減らせます。
例えば、
Redmine #5320
Status:
Brief Requested
へ変更するとBrief Generatorが起動し、生成結果をGitへ保存してRedmineをBrief Draftへ進めます。担当者が内容を確認してBrief Readyへ変更すると、Brief Approval Handlerが生成時と承認時の要件を検証し、承認情報をRedmineへ保存したうえでReady for Agentへ自動遷移させます。この遷移を契機に実装パイプラインが開始されます。
すると、
Redmine: Brief Requested
↓
Brief Generator
↓
Gitへ保存
↓
Redmine: Brief Draft
↓
人間がBrief Readyへ変更
↓
Brief Approval Handler
↓
Redmineへ承認情報を保存
↓
HandlerがReady for Agentへ自動遷移
↓
Agent Controllerがclaim
↓
CI runner / 専用Agent Worker
↓
Codex / Claude Code
↓
実装
↓
Local Test
↓
Git Push
↓
CircleCI
↓
必要ならAIが修正
↓
Pull Request
↓
Review
まで進みます。
人間の仕事は最終的に、
要求を書く
↓
Briefをレビューして承認
↓
Pull Requestをレビュー
という形になります。
Brief承認後にRedmineの要件フィールドが変更された場合は、自動的にBrief Draftへ戻し、再生成・再承認します。ステータス変更だけの場合はそのまま実行できます。これにより、承認フローを妨げずに古いBriefによる実装を防ぎます。
28. 導入は3段階に分ける
この構成を最初からすべて作る必要はありません。費用対効果の高い順に導入します。
Phase 1:Briefのフォーマット統一とGit保存
最初に行うのはここです。
- Briefテンプレートを決める
- ChatGPTで人間が明示的に生成する
- 人間が内容をレビューする
- Gitへ保存して、指示と実装の履歴を結び付ける
- Redmineへ承認メタデータ用のカスタムフィールドを追加する
- 承認用CLIから
approve_agent_briefを呼び、差分検証、承認情報保存、Ready for Agentへの遷移をまとめて行う - 承認後に要件フィールドが変わった場合の再生成ルールを決める
この段階ではAgent Controllerも専用VMも不要です。「AIへ何を指示したか」が履歴に残るだけでも大きな効果があります。
Phase 2:Agent実行環境の共通化
次に、個人PC依存を減らします。
- まず既存CI runnerをephemeral Agent Workerとして試す
- タスクごとにWorkspaceを作成・破棄する
- Agent内で実装とtargeted testのループを回す
- push後は独立したCI workflowでfull testを行う
- 短命かつリポジトリ単位のCredentialを使う
既存runnerの制約が問題になった場合だけ、self-hosted runnerやGCE / EC2へ移行します。
Phase 3:Brief GeneratorとAgent Controller
並行タスクや開発者が増え、手動起動がボトルネックになってから導入します。
- Brief GeneratorによるAPIベースの生成
- Brief Approval Handlerによる生成時・承認時の差分検証
- 承認メタデータのRedmineカスタムフィールドへの保存
- Redmineを起点にしたtask claim
- Controller DBによるlease、heartbeat、retry
- 複数Workerへの割当
- CI失敗ログの限定取得と再実行制御
Agent Controllerは最も重いコンポーネントです。重複実行やWorker割当が実際の課題になるまで、後回しにして問題ありません。
まとめ
AIエージェントを本格的に開発へ導入する場合、重要なのはAIモデルそのものだけではありません。
重要なのは、
AIにどう仕事を渡し、どう実行し、どう検証し、どう履歴を残すか
です。
初期構成では、
Redmine
↓
ChatGPT(人間が起動)
↓
Briefを人間が承認
↓
Gitへ保存
↓
AI Agent
↓
CI
という役割分離を行います。
さらに、
Prompt Push
から、
Context Pull
へ変更します。
人間が毎回CodexへチケットやPromptをコピペするのではありません。
人間がChatGPTでAgent Briefを生成・承認してGitへ保存し、Agent自身がそれをPullします。自動化段階ではChatGPTをパイプライン部品として扱わず、Redmine APIとLLM APIを使うBrief Generatorへ置き換えます。
AI Agentの実行環境は、まず既存CI runnerの流用から始めます。要件を満たせない場合にself-hosted runnerやGCE / EC2上の専用Workerへ進みます。
Agentは同一Workspace内で実装とローカルテストのループを回し、CIはpushされた成果物を独立して検証するValidatorとして残します。
状態管理も一元化します。
- Redmine:要求、承認、優先度、業務状態の正本
- Git:Brief本文と改訂履歴
- Agent Controller:claim、lease、retryなど実行中の一時状態
Git上でqueue/ → running/ → completed/とファイルを移動する方式は採用しません。
最終的には、
Developer
↓
Redmine
↓
Ready for Agent
↓
AI Development Platform
↓
Pull Request
というユーザー体験を目指します。
ただし、Ready for Agentの前には人間によるBrief承認を必須とし、Redmineが更新されたBriefは陳腐化したものとして再生成します。
これは単に「AIにコードを書かせる仕組み」ではありません。
AIによる開発作業そのものを、CI/CDと同様の共通インフラとして運用する
という考え方です。
AI Agentが増え、開発者が増え、複数リポジトリを扱うようになった段階では、Agent ControllerとRunnerを追加して水平にスケールできます。
そしてCodex、Claude Code、将来登場する別のCoding Agentも、
Task
↓
Agent Adapter
↓
Git
という共通インターフェースの中で交換できるようになります。
AIコーディングの次の段階は、Promptをうまく書くことではなく、
AIエージェントが仕事を受け取り、実装し、検証し、成果物を返す仕組みそのものを設計すること
だと考えられます。