前編では、Redmineの要求をAI Agentへ渡し、実装・CI・Pull RequestまでつなぐAIコーディング基盤の全体設計を整理しました。
この設計で重要なのは、単純な
Redmine
↓
ChatGPT
↓
Git
↓
AI Agent
ではなく、AI Agentへ渡す前に人間によるBriefの確認と承認を必須にすることです。
全体像は次のようになります。
Redmine
│
▼
人間がChatGPT Skillを起動
│
▼
Agent Brief生成
│
▼
人間がレビュー・承認
│
▼
Git Writer MCP
│
▼
承認済みAgent Brief
│
▼
Brief Ready
│
▼
Handlerによる検証
│
▼
Ready for Agent
│
▼
Agent Controller
│
▼
GCE Agent Worker
│
▼
Codex / Claude Code
│
▼
Application Git
│
▼
CircleCI
│
▼
Pull Request
ここで重要なのは、ChatGPT Skillは自動実行パイプラインの一部ではないという点です。
ChatGPT Skillは人間が起動し、Redmineの要求をAgent Briefへ変換するために使います。
一方、
Ready for Agent
↓
Agent
↓
Git
↓
CI
という実行ループはAgent Controller側で完結させます。
今回の実装編では、この設計を実際に動かすための最小構成を考えます。
最初からKubernetesや大規模なジョブ管理基盤を導入するのではなく、まずGoogle Compute Engine上に1台のAgent Runnerを構築します。
1. 今回構築するMVP
最初に作る構成は次の通りです。
Redmine
│
│ Issue
▼
Human Operator
│
▼
ChatGPT Skill
│
Brief Draft
│
▼
Human Review
│
Approve
│
▼
Git Writer MCP
│
▼
Agent Taskリポジトリ
Approved Brief
│
▼
Brief Ready
│
▼
Handler
│
▼
Ready for Agent
│
▼
Agent Controller
│
▼
GCE Agent Worker
│
┌───────────┴───────────┐
▼ ▼
Codex Claude Code
│ │
└───────────┬───────────┘
▼
Applicationリポジトリ
│
git push
│
▼
CircleCI
│
▼
Pull Request
この段階では、
- Agent ControllerとWorkerは同一VM
- Workerは1台
- 実行状態の正本はRedmine
- Agent BriefはGitで管理
- Workerの排他制御はControllerのローカルロック
- WorkspaceはDockerまたはディレクトリ分離
- CIはCircleCI
- AgentはCodexを優先
- Claude Codeは後からAdapterとして追加
とします。
ここでは、
queue/
↓
running/
↓
completed/
というGit上のファイル移動による状態管理は行いません。
Gitは、
Agentへ渡した指示内容を保存する場所
として使います。
実行状態はRedmineとControllerで管理します。
2. コンポーネント構成
GCE VM上には、次のコンポーネントを配置します。
ai-agent-runner-01
/opt/ai-agent/
├── controller/
├── adapters/
│ ├── codex/
│ └── claude/
├── scripts/
├── workspaces/
├── logs/
├── locks/
└── config/
それぞれの役割は次の通りです。
controller
Redmine上で
Ready for Agent
になったIssueを取得し、Agent Workerへ渡します。
状態遷移、CI監視、Retry制御もControllerが担当します。
adapters
CodexやClaude CodeのCLI差異を吸収します。
例えば、
run_agent(task)
という共通インターフェースを用意します。
workspaces
Issue単位の作業ディレクトリです。
workspaces/
├── 5320/
├── 5321/
└── 5322/
logs
AgentやControllerの実行ログを保存します。
locks
単一WorkerのMVPで二重起動を防止するためのロックを置きます。
例えば、
locks/5320.lock
です。
このロックはGitへコミットしません。
3. Agent Taskリポジトリを作る
まず、Agentへの指示書専用リポジトリを作ります。
例えば、
ai-agent-tasks
です。
構成は次のようにします。
ai-agent-tasks/
├── briefs/
│ └── approved/
├── templates/
└── README.md
Issue #5320の承認済みAgent Briefであれば、
briefs/approved/5320.md
とします。
重要なのは、ここに
queue/
running/
completed/
failed/
を作らないことです。
Agent Briefの保存場所とTaskの実行状態を二重表現しないようにします。
TaskファイルはMarkdownで管理します。
例えば、
---
issue: 5320
repository: mcp-redmine
repository_url: git@github.com:example/mcp-redmine.git
branch: agent/5320
agent: codex
brief_version: 1
requirements_fingerprint: sha256:0123456789abcdef...
source_updated_on: 2026-09-01T10:00:00Z
---
# Task
Context Budget Report / CI Integrationを実装する。
# Goal
CI上でコンテキスト使用量を計測し、確認可能にする。
# Requirements
- CI上で計測できること
- レポートを確認できること
- 既存CIを壊さないこと
# Acceptance Criteria
- 関連テストが成功する
- lintが成功する
- CircleCIが成功する
requirements_fingerprintは、Agent Briefがどの要求から生成・承認されたかを検証するために使います。
一方、
source_updated_on:
は監査や調査のための参考情報です。
Redmineのupdated_onは、Agent実装とは無関係な変更でも更新される可能性があるため、
approved updated_on
==
current updated_on
のような単純比較をAgent Briefの有効性判定には使いません。
実行状態についても、
status: ready
のような値は持たせません。
実行状態の正本はRedmineです。
4. ChatGPTからAgent Briefを作る
ChatGPTはAgent Controllerから自動的に呼び出すのではなく、人間が操作する要求変換ツールとして使います。
例えば、人間が、
Redmine #5320を取得してAgent Briefのドラフトを作成してください。
まだGitには保存しないでください。
と指示します。
処理は、
Human
↓
ChatGPT Skill
↓
Redmine MCP
↓
Issue取得
↓
Agent Brief Draft
となります。
人間は生成されたBriefを確認します。
必要であれば修正し、問題なければ、
このBriefを承認します。
Agent Taskリポジトリへ保存してください。
と指示します。
その時点で初めて、
ChatGPT
↓
Git Writer MCP
↓
briefs/approved/5320.md
へ保存します。
このように、
生成と承認を分離する
ことが重要です。
5. Git Writer MCPの権限を限定する
Git Writer MCPは汎用Gitクライアントにする必要はありません。
むしろ、
write_agent_brief(issue_id, content)
のような用途限定APIにします。
書き込み先も、
briefs/approved/<issue-id>.md
へ固定できます。
さらに、
- Applicationリポジトリには書き込めない
- 任意ファイルを削除できない
- mainブランチを変更できない
- Agent Brief専用リポジトリだけ操作できる
ようにします。
これにより、ChatGPTが誤ってアプリケーションコードを変更するリスクを減らせます。
6. Brief承認ゲートを設ける
Agent BriefをGitへ保存しただけでは、まだAgentを起動しません。
人間によるレビューが完了し、Handlerへ検証を要求する段階でRedmineを、
Brief Ready
へ変更します。
ここでのBrief Readyは、
人間によるBriefのレビューと承認が完了し、Handlerによる検証を要求した状態
と定義します。
つまり、
Human Review
↓
Human Approval
↓
Brief保存
↓
Brief Ready
↓
Handler検証
です。
Brief Readyは、Handlerによる検証が完了した状態ではありません。
非同期でHandlerが動く以上、人間による状態変更とHandlerの検証完了の間には時間差があります。
その時間差を状態モデルへ正しく反映します。
Handlerは、
- 承認済みBriefが存在するか
- BriefとRedmine Issueの対応が正しいか
- requirements fingerprintが一致しているか
- 承認メタデータを保存できるか
- 同じ承認イベントが二重処理されていないか
などを検証します。
成功した場合、MVPではHandler自身が、
Ready for Agent
へ自動遷移させます。
したがって、
Brief Ready
↓
Handler Validation
↓
Ready for Agent
となります。
ここでは、
Briefの承認 = Agent実行許可
として扱います。
承認済みのBriefを通常はそのまま実行するため、MVPでは別途人間がReady for Agentへ変更するゲートを設けません。
将来、
- 実行時間帯を制御したい
- 高コストTaskだけ別承認したい
- リリース凍結期間を設けたい
- Taskの優先順位を人間が調整したい
といった要件が出た場合には、
Brief Approved
↓
Execution Approval
↓
Ready for Agent
のように、Brief承認と実行許可を別ゲートへ分離できます。
最初からその複雑さを持ち込む必要はありません。
7. Briefの陳腐化を検出する
Agent Brief生成後にRedmineの要求が変更される可能性があります。
例えば、
10:00 Brief生成
10:10 RedmineのAcceptance Criteria変更
10:20 Agent開始
となった場合、Agentは古い要求を実装してしまいます。
そのため、Brief生成時または承認時の要求からfingerprintを作ります。
概念的には、
SHA256(
normalized_subject
+ normalized_description
+ normalized_acceptance_criteria
+ normalized_relevant_custom_fields
)
です。
承認時には、
Brief Requirements Fingerprint
Brief Approved At
Brief Approved By
Brief Git SHA
などをRedmineのカスタムフィールドへ保存します。
Agent起動前に現在のRedmine情報からfingerprintを再計算し、
approved fingerprint
!=
current fingerprint
であればAgentを起動しません。
その場合は、
Brief Draft
へ戻し、再生成または再承認を要求します。
ここでもupdated_onの単純比較は使いません。
コメント追加や担当者変更など、Agentへ渡す要求そのものと関係しない変更でもupdated_onが変わる可能性があるためです。
MVPの最初の段階ではfingerprint検証を自動化しなくても構いません。
ただし、
Agent起動前に人間がRedmineとBriefの差分を確認する
という運用上のゲートは残します。
fingerprintによる検証は後のPhaseで自動化します。
8. GCE VMを用意する
最初のWorkerは通常のCompute Engine VMで十分です。
例えば、
Machine type:
e2-standard-4
(4 vCPU / 16GB)
OS:
Ubuntu LTS
Disk:
50〜100GB
程度から始められます。
AI Agentは、
- Git
- Node.js
- Python
- Docker
- build tools
などを同時に利用する可能性があります。
そのため、最初から極端に小さなVMへ詰め込むより、ある程度余裕を持たせた方が運用しやすくなります。
9. VMに必要なソフトウェア
例えば、
sudo apt update
sudo apt install -y \
git \
curl \
jq \
build-essential \
docker.io
をインストールします。
Node.jsやPythonについては対象リポジトリに合わせます。
Agent自身の環境とアプリケーション依存環境を可能な限り分離するため、アプリケーションのビルドやテストをDocker内で実行する構成も有効です。
10. Codex CLIを導入する
Agent Workerでは対話UIではなく、スクリプトから実行できるCLIを利用します。
概念的には、
codex exec \
"Read TASK.md and AGENTS.md. Implement the task and run relevant tests."
のように実行します。
Promptそのものは極力短くします。
例えば、
Read TASK.md.
Follow AGENTS.md.
Implement the requested change.
Run relevant tests before finishing.
程度です。
実際の要求はTASK.md側から読み取らせます。
これもPull Contextの考え方です。
11. Codex Adapterを作る
ControllerからCodex固有のCLIを直接扱うのではなく、Adapterを挟みます。
例えば、
adapters/
└── codex/
└── run.sh
とします。
概念的には、
#!/bin/bash
set -e
WORKSPACE="$1"
cd "$WORKSPACE/repo"
codex exec \
"Read ../TASK.md and AGENTS.md. Implement the task, run relevant tests, and report the result."
です。
将来Claude Codeを追加する場合も、
adapters/
├── codex/run.sh
└── claude/run.sh
とできます。
Controllerからは、
run_agent("codex", workspace)
のような共通インターフェースだけを呼びます。
12. Taskの状態はRedmineで管理する
この設計ではGit上のファイル移動によってTask状態を管理しません。
状態の正本はRedmineです。
例えば、
Brief Draft
↓
Brief Ready
↓
Ready for Agent
↓
Agent Running
↓
Review
という状態を持ちます。
異常時には、
Needs Human
へ遷移します。
Gitには、
briefs/approved/5320.md
がそのまま残ります。
Agentが実行中だから、
running/5320.md
へ移動することはありません。
これにより、
Redmine status
Git directory
frontmatter status
という三重管理を避けられます。
13. 単一Workerではロックファイルを使う
Redmineを状態の正本にしても、Controllerの二重起動などによって同じTaskが同時処理される可能性はあります。
ただし今回のMVPはControllerもWorkerも1台です。
そのため最初は、
/opt/ai-agent/locks/5320.lock
のような単純な排他制御で十分です。
例えば、
Ready for Agent取得
↓
lock取得
↓
RedmineをAgent Runningへ変更
↓
Agent実行
↓
lock解放
とします。
Workerを複数台へ増やす段階では、このローカルロックを分散LeaseやController DBへ置き換えます。
14. Workspaceを作成する
Task #5320を処理する場合、
/opt/ai-agent/workspaces/5320/
を作ります。
その中で対象リポジトリをcloneします。
例えば、
git clone git@github.com:example/mcp-redmine.git \
/opt/ai-agent/workspaces/5320/repo
その後、
cd /opt/ai-agent/workspaces/5320/repo
git checkout -b agent/5320
とします。
Agent Briefは、
TASK.md
としてWorkspaceへコピーします。
構成は、
workspaces/5320/
├── TASK.md
└── repo/
となります。
AgentにはGit上のBriefを直接編集させず、実行時にWorkspaceへコピーしたものを参照させます。
Task終了後は、成功・失敗に関係なくWorkspaceを破棄します。
Workspaceは永続的な状態保存先ではありません。
15. AgentにGit認証を直接持たせすぎない
Agent WorkerにはGitへの書き込み権限が必要ですが、可能な限り権限を限定します。
例えばGitHub Appを使う場合、
- 対象リポジトリ限定
- Contents write
- Pull Requests write
- Administrationなし
とします。
長期間有効なPersonal Access TokenをVMへ直接配置するより、短命CredentialやGitHub Appを使う方が管理しやすくなります。
CredentialはGoogle Secret Managerなどへ保存します。
Agent Brief内にCredentialを書いてはいけません。
16. Controllerの基本処理
Agent Controllerは単純な処理から始められます。
MVPではWorkerが1台なので、1Taskずつ直列に処理する設計とします。
概念的には次のようになります。
while true:
issue = find_redmine_issue(
status = "Ready for Agent"
)
if issue does not exist:
sleep()
continue
if not acquire_lock(issue):
continue
workspace = null
try:
brief = load_approved_brief(issue)
if brief does not exist:
update_redmine(issue, "Brief Draft")
add_redmine_comment(
issue,
"Approved Brief was not found."
)
continue
if approval_validation_enabled:
validation = validate_approval_metadata(
issue,
brief
)
if validation failed:
update_redmine(issue, "Brief Draft")
add_redmine_comment(
issue,
validation.reason
)
continue
fingerprint = validate_fingerprint(
issue,
brief
)
if fingerprint mismatched:
update_redmine(issue, "Brief Draft")
add_redmine_comment(
issue,
"Requirements changed after Brief approval."
)
continue
update_redmine(
issue,
"Agent Running"
)
workspace = create_workspace(issue)
clone_repository(
issue.repository,
workspace
)
copy_brief_to_workspace(
brief,
workspace
)
run_agent(
issue.agent,
workspace
)
run_local_validation(
workspace
)
commit_changes(
workspace
)
push_branch(
workspace
)
retry = 0
while true:
ci_result = wait_for_ci()
if ci_result == success:
create_pull_request(issue)
update_redmine(
issue,
"Review"
)
break
retry += 1
if retry > max_ci_retries:
update_redmine(
issue,
"Needs Human"
)
add_redmine_comment(
issue,
"CI retry limit exceeded."
)
break
collect_ci_failure(
issue,
workspace
)
run_agent_retry(
issue.agent,
workspace
)
run_local_validation(
workspace
)
commit_changes(
workspace
)
push_branch(
workspace
)
except unexpected_error:
update_redmine(
issue,
"Needs Human"
)
record_error(
issue,
unexpected_error
)
finally:
if workspace exists:
cleanup_workspace(
workspace
)
release_lock(
issue
)
ここで重要なのは、承認情報やfingerprintの検証に失敗した場合、
Agent Running
へ進めないことです。
例えばRedmineの要求がBrief承認後に変更されていれば、
Ready for Agent
↓
検証失敗
↓
Brief Draft
へ戻します。
人間が内容を確認し、必要に応じてBriefを再生成・再承認します。
また、wait_for_ci()はブロックします。
これは意図的です。
今回のMVPでは、
Worker = 1
同時実行Task = 1
としているためです。
Taskが成功しても失敗しても、
cleanup_workspace()
と
release_lock()
は必ず実行します。
並列処理が必要になった段階でControllerとWorkerを分離します。
17. ローカル検証を実行する
Agentは変更後、まずWorkspace内部で高速な検証を行います。
例えば、
formatter
lint
typecheck
targeted unit test
です。
全テストを毎回Agent側で実行する必要はありません。
Agent側では、
失敗を早く検出できるチェック
を優先します。
包括的な検証はCircleCIへ任せます。
18. GitへPushする
ローカル検証が成功したら、
git add .
git commit -m "feat: implement Redmine #5320"
git push origin agent/5320
します。
ここでCircleCIが通常通り起動します。
Agent ControllerがCircleCIを特別な方法で起動する必要はありません。
git push
↓
通常のCI
という既存の開発フローをそのまま利用します。
19. CircleCIを独立Validatorとして使う
CircleCIは、
AI Agent
↓
Git
↓
CircleCI
の外部Validatorとして扱います。
Agent自身の、
テストは通りました
という自己申告だけで成功判定をしてはいけません。
Controllerは、
agent/5320
↓
CircleCI Pipeline
↓
Workflow
↓
Job
↓
status
を確認します。
CIが成功して初めて、実装成功と判定します。
20. CIが失敗したら必要な情報だけAgentへ渡す
CircleCIが失敗した場合、ログ全体をCodexへ渡す必要はありません。
Controller側で、
Pipeline
↓
Failed Workflow
↓
Failed Job
↓
Failed Step
↓
必要部分のログ
まで絞ります。
その内容を、
CI_FAILURE.md
としてWorkspaceへ保存します。
例えば、
workspaces/5320/
├── TASK.md
├── CI_FAILURE.md
└── repo/
とします。
そしてCodexへ、
Read CI_FAILURE.md.
Fix the failure without changing unrelated behavior.
Run relevant tests before finishing.
と指示します。
大量のCIログをPromptへ直接貼り付けないのがポイントです。
21. CI Retryには上限を設ける
AI Agentに無限修正を許可してはいけません。
例えば、
max_ci_retries: 3
とします。
流れは、
git push
↓
CircleCI失敗
↓
CI_FAILURE.md生成
↓
Agent修正
↓
ローカル検証
↓
再push
↓
CircleCI再実行
です。
これを上限まで繰り返します。
3回失敗した場合、
Needs Human
へ遷移します。
この状態もRedmineで管理するため、
needs-human/
のようなGitディレクトリを追加する必要はありません。
自律Agentでは、
自動化することより、どこで自動化を止めるかを決めること
の方が重要です。
22. CI APIの権限はRead中心にする
Agent Controllerには、
CI Status Read
CI Workflow Read
CI Job Read
CI Logs Read
を中心に与えます。
最初は、
rerun
cancel
config change
などの操作権限をAgentへ与えない方が安全です。
CIの実行そのものはGit pushで発生します。
Controllerは基本的に、
結果を読む側
に限定します。
23. PRを作成する
CircleCIが成功したらPull Requestを作成します。
例えば、
agent/5320
↓
main
です。
PR本文には、
Redmine: #5320
Agent: Codex
Agent Brief:
briefs/approved/5320.md
Requirements fingerprint:
sha256:0123456789abcdef...
Local validation:
- lint: passed
- unit test: passed
CircleCI:
- passed
CI retries:
1
Files changed:
- ...
などを記録します。
これによりReviewerは、
- どの要求から作られたか
- どのBriefをAgentへ渡したか
- どのAgentが実装したか
- どの要求fingerprintを基準にしたか
- ローカル検証結果
- CI結果
- Retry回数
を確認できます。
24. Redmineへ結果を戻す
PR作成後、Redmineを、
Review
へ変更します。
コメントには、
Agent implementation completed.
Branch:
agent/5320
Pull Request:
#123
CI:
Passed
CI retries:
1
Agent:
Codex
などを記録します。
Redmineが、
要求と実行状態の正本
になります。
詳細な実行ログまでRedmineへ保存する必要はありません。
25. ChatGPTを実行ループに入れすぎない
この構成で特に重要な点です。
ChatGPTは、
Human
↓
Redmine
↓
Agent Brief生成
↓
Human Approval
↓
Git
までを担当します。
その後の、
Brief Ready
↓
Handler
↓
Ready for Agent
↓
Agent Runner
↓
Git
↓
CI
↓
PR
は自動実行基盤側で完結させます。
例えばCI失敗時に、
Controller
↓
ChatGPT Skill
↓
次に何をするか判断
とはしません。
ChatGPT SkillはControllerから自動的に呼び出す実行APIとして設計しないためです。
役割は、
ChatGPT
= 要求変換
Human
= Briefレビューと承認
Handler
= 承認検証とReady for Agentへの遷移
Agent Controller
= 実行状態遷移
Codex / Claude Code
= 実装
CircleCI
= 独立検証
と分離します。
26. Agent Controller APIを用意する
後からSlackやWeb UIを追加できるように、Controllerには小さなAPIを持たせます。
例えば、
GET /tasks/5320
POST /tasks/5320/cancel
POST /tasks/5320/retry
です。
管理用途として、
POST /tasks/5320/start
を用意しても構いません。
ただし通常運用では、
Ready for Agent
をControllerが取得して自動実行するため、手動startを必須にはしません。
ステータス取得例は、
{
"issue": 5320,
"status": "ci_running",
"agent": "codex",
"branch": "agent/5320",
"ci_retry": 1
}
です。
Slackなどの外部UIは、このAPIを呼ぶだけにします。
Agent実行ロジックをSlack側へ持たせません。
27. ログを残す
最低限、次のログを保存します。
logs/
└── 5320/
├── controller.log
├── agent.log
├── local-test.log
└── ci.log
Redmineには、
成功
失敗
PR
CI結果
Retry回数
などの要約だけを保存します。
詳細ログはCloud Loggingなどへ送ります。
これによりRedmineのIssueが巨大なAgentログで埋まるのを防げます。
WorkspaceはTask終了後に削除しますが、必要な実行ログはWorkspace外へ保存しておきます。
28. Secret ManagerとSandboxを使う
GCE上には、
- GitHub Credential
- CircleCI Token
- OpenAI Credential
- Redmine Credential
などが必要になります。
これらを、
.env
へ長期間保存するのではなく、Secret Managerから取得する構成にします。
また、AgentへVM全体へのアクセス権限を与えないことも重要です。
Agentが操作できる場所を、
/opt/ai-agent/workspaces/5320/
へ限定します。
例えば、
/etc
/home
/opt/ai-agent/controller
/opt/ai-agent/config
などをAgentから自由に変更できないようにします。
もう一段分離する場合は、1Taskを1Containerで実行します。
GCE
Agent Controller
│
├─ Docker agent-5320
├─ Docker agent-5321
└─ Docker agent-5322
Containerには、
TASK.md
Applicationリポジトリ
Agent CLI
必要なBuild Tools
だけを渡します。
Task終了後はContainerごと削除します。
29. 複数Workerへ拡張する
最初はVM1台・Worker 1台ですが、Task数が増えたらWorkerを増やします。
Agent Controller
│
┌─────────┼─────────┐
▼ ▼ ▼
Worker-01 Worker-02 Worker-03
Google Compute EngineのManaged Instance Groupなどを利用すれば、同じ構成のVM群をまとめて管理できます。
ただし、Workerを複数台へ増やした時点で、
ローカルlockファイル
では排他制御できません。
その段階では、
Controller DB
Cloud Tasks
Pub/Sub
Redis
Database
などを使って、
Task取得
Lease
Retry
Timeout
Worker Assignment
を中央管理します。
ここでもGitを実行Queueとして使わないことが重要です。
Gitは引き続き、
承認済みAgent Briefの保存と監査
を担当します。
30. MVP構築の順番
最初から全部実装する必要はありません。
段階的に作ります。
Phase 1
Approved Brief
↓
Ready for Agent
↓
GCE
↓
Codex
↓
Application Git
まずは、
briefs/approved/5320.md
を人間が手動で作成し、
Ready for Agent
にすると、Codexが実装してpushできるところまで作ります。
この段階ではHandlerによる承認検証をまだ自動化せず、人間がBriefを確認したうえでReady for Agentへ変更しても構いません。
Phase 2
CircleCI連携を追加します。
git push
↓
CircleCI
↓
Controllerが結果確認
↓
失敗時Agent Retry
まで作ります。
Phase 3
ChatGPTとGit Writer MCPを追加します。
Redmine
↓
人間がChatGPT Skillを起動
↓
Agent Brief Draft
↓
Human Review
↓
Git Writer MCP
↓
Approved Brief
とします。
ここでもChatGPT Skillを自動起動しません。
Phase 4
Brief承認処理とRedmine状態遷移を自動化します。
Human Review
↓
Human Approval
↓
Brief Ready
↓
Handler
↓
承認メタデータ保存
↓
fingerprint検証
↓
Ready for Agent
を実装します。
このPhase以降は、Handlerが検証成功後に自動的にReady for Agentへ遷移させます。
またAgent起動前にもfingerprintを確認し、Brief承認後にRedmineの要求が変化していれば自動実行を止めます。
Phase 5
Workerを複数台へ増やします。
この段階で、
ローカルlock
から、
Controller DB
Cloud Tasks
Pub/Sub
などの中央Queue / Lease方式へ移行します。
この順番なら、最初から大規模基盤を作らず、
1 Worker
↓
CI連携
↓
Brief生成
↓
承認自動化
↓
複数Worker
と段階的に育てられます。
31. 完成後の流れ
最終形では、人間がまずRedmineのIssueを作成・更新します。
例えば、
Redmine #5320
です。
その後、
Human
↓
ChatGPT Skillを起動
↓
Redmine #5320取得
↓
Agent Brief Draft生成
↓
Human Review
↓
必要なら修正
↓
Human Approval
↓
Git Writer MCP
↓
briefs/approved/5320.md
↓
Redmine = Brief Ready
↓
Handler
↓
Brief / Redmine整合性検証
↓
requirements fingerprint検証
↓
承認メタデータ保存
↓
Ready for Agent
↓
Agent Controller
↓
GCE Worker
↓
git clone
↓
Codex
↓
Local Test
↓
git push
↓
CircleCI
となります。
CircleCIが失敗した場合は、
CircleCI失敗
↓
Controllerが失敗Job取得
↓
必要なログだけ抽出
↓
CI_FAILURE.md
↓
Codex修正
↓
Local Test
↓
git push
↓
CircleCI再実行
となります。
成功すれば、
CircleCI成功
↓
Pull Request
↓
Redmine Review
↓
Human Review
です。
Taskが成功しても失敗しても、最後に、
Workspace削除
↓
lock解放
を実行します。
全体を一枚で表すと、
Human
│
▼
Redmine
│
▼
ChatGPT Skill
(人間が起動する)
│
▼
Brief Draft
│
▼
Human Review
│
Approve
│
▼
Git Writer MCP
│
▼
Approved Brief
│
▼
Brief Ready
│
▼
Handler
│
┌─────────┴─────────┐
│ │
Validation NG Validation OK
│ │
▼ ▼
Brief Draft Ready for Agent
│ │
▼ ▼
Human Agent Controller
│
▼
GCE Worker
│
Codex / Claude
│
▼
Application Git
│
git push
│
▼
CircleCI
│
┌─────────────┴─────────────┐
│ │
Failed Passed
│ │
▼ ▼
CI Failure Context Pull Request
│ │
▼ ▼
Agent Retry Redmine Review
│
▼
Human Review
この構成で守る設計原則
この実装で最も重要なのは、各コンポーネントへ責任を持たせすぎないことです。
役割は次のように分けます。
Redmine
= 要求と業務状態の正本
ChatGPT Skill
= 要求をAgent Briefへ変換
人間が起動する
Human
= Briefレビューと承認
最終レビュー
Git Writer MCP
= 承認済みBriefを安全に保存
Agent Taskリポジトリ
= Briefの履歴・監査ログ
Handler
= Brief承認情報と陳腐化の検証
Ready for Agentへの遷移
Agent Controller
= Agent実行
状態遷移
Retry
CI監視
Worker制御
Codex / Claude Code
= コード実装
Application Git
= 開発履歴
CircleCI
= 独立した検証
Pull Request
= 人間とのレビュー境界
この境界を守ることで、例えばCodexをClaude Codeへ変更しても、要求管理やCI構成まで作り直す必要がありません。
同様に、将来WorkerをGCEからKubernetesへ移しても、RedmineやAgent Briefの仕組みはそのまま利用できます。
まとめ
最初のAIコーディング基盤は、意外と小さく作れます。
MVPで必要なのは、
GCE 1台
Gitリポジトリ 2つ
Agent Controller
Codex CLI
CircleCI API
Redmine
程度です。
大規模なAIプラットフォームから始める必要はありません。
まず確立するのは、
Approved Brief
↓
Ready for Agent
↓
Agent
↓
Git
↓
CI
という最小ループです。
その後、
Redmine
↓
ChatGPT Skill
↓
Human Approval
を前段へ追加します。
さらに、
Brief Ready
↓
Handler
↓
承認メタデータ
↓
requirements fingerprint
↓
Ready for Agent
を追加すれば、古くなったBriefがそのまま実行されることを防げます。
MVPでは、
人間によるBrief承認をAgent実行許可とみなし、Handlerの検証成功後に自動的にReady for Agentへ進める
設計とします。
将来、優先度制御や実行タイミング管理が必要になれば、
Brief Approval
↓
Execution Approval
↓
Ready for Agent
とゲートを分離できます。
開発者やTaskが増えたら、
1 Worker
↓
Multiple Workers
↓
Central Queue / Lease
↓
Managed Instance Group
へ拡張します。
ここで重要なのは、GitをWorker間のQueueや状態データベースとして使わないことです。
Gitには、
何をAgentへ依頼したのか
を残します。
Redmineには、
現在どの状態なのか
を残します。
Handlerには、
そのBriefを実行してよい状態か
を検証させます。
Controllerには、
承認済みTaskをどう実行するか
を管理させます。
この責務分離によって、
Redmine
↓
Human
↓
Approved Agent Brief
↓
AI Development Platform
↓
Pull Request
という開発フローを安定して構築できます。
この設計の本質は、AIを特別なチャットツールとして扱わないことです。
CI Runnerがコードを検証するように、
Agent Runnerが承認済みの開発作業を実行する
という共通基盤として扱います。
そして人間は、Promptを何度もコピーしてAIへ指示するのではなく、
要求を書くこと
Agentへ渡す要求を承認すること
成果物をレビューすること
に集中します。
実装順としては、まずPhase 1の
Approved Brief
↓
Ready for Agent
↓
GCE
↓
Codex
↓
Git Push
だけを実際に作るのが最短です。
ここが動けば、CircleCI、ChatGPT Skill、Git Writer MCP、Brief承認Handler、陳腐化検知、複数Worker化はすべて後から段階的に追加できます。