エアークローゼット cortex — AIハーネス6部作(総論〜最終章)¶
作成日: 2026-07-07 出典 / きっかけ: 辻亮佑(エアークローゼットCTO)Zenn 連載「AIハーネス」全6回 - Part 1 総論「AIのハーネスを徹底的に整えたら、レビューもシステム運用も自動化され、非エンジニアも開発に参加できるようになった話」(2026-05-12) - Part 2「AIハーネスの心臓部 ── AIのAIによるAIのためのナレッジグラフ」(2026-05-19) - Part 3「AIが書いたコードはAIが見る ── レビューが詰まらず、品質はむしろ上がる」(2026-05-26) - Part 4「気づく前に直り、直すたびに強くなる ── Self-Healingと再発防止の仕組み」(2026-06-02) - Part 5「非エンジニアが本番にPRを出し、ハーネスが品質を担保する ── 改修フェーズの民主化」(2026-06-09) - Part 6「AIは信用するものではなく設計するもの ── 連載総括・最終章」(2026-06-16) 関連: エアークローゼット_46リポジトリ知識グラフとllm_observability_整理 / エアークローゼット_agentic_graph_rag_と社内mcp基盤_整理 / エアークローゼット_非エンジニア内製化_sandbox_mcpと議事録rag_整理 / 社内mcp共通基盤_認証認可ログ_整理 / ミラティブ_ashura_分析民主化aiエージェント基盤_整理
0. 要点(3行)¶
- 「AIを信用しない。だからハーネス(踏み外せないレール)で決定論に寄せる」 が一貫した設計思想。AIに推論させず、事実をコンテキストとして供給し、出力を予測可能な範囲に閉じ込める。
- 社内AI開発プラットフォーム cortex で、PRは無人でマージされ、障害は気づく前に直っている。中核は ①Product Graph ②品質ゲート ③Auto Review ④Self-Healing の4要素フライホイール(Guides=事前制御 / Sensors=事後制御)。
- 約5ヶ月で 123アプリ・約63万行・マージ済PR約790本(1ヶ月で約22倍増)、AIレビュー関与率100%・人レビューほぼ0%。非エンジニアが本番に+1,742行のPRを人間レビュー0で通す ところまで到達した。
1. なぜハーネスなのか — 業界文脈と2つのシーン¶
1-1. 起点の2つのシーン¶
- シーン1「PRは無人でマージされる」:エンジニアがPRを出す → AIレビュアーが重複コード・ドキュメント不整備を指摘 → AI対応エージェントが git worktree で修正コミット → 自動 squash merge → 変更スタック検出で自動デプロイ。人間ノータッチで完了。
- シーン2「障害は気づく前に直っている」:Grafana アラート(BigQuery パイプライン失敗) → AI が Loki からエラーログ取得 → Product Graph で根本原因特定 → 修正PR作成・マージ・自動再デプロイ。朝出社したら既に修復済み。
1-2. 「ハーネスエンジニアリング」という潮流¶
2026年前半に固まった業界文脈を筆者は次のように整理する。
- 2026-02 OpenAI が「ハーネスエンジニアリング」を公開(Codex 主導で5ヶ月に100万行)
- Mitchell Hashimoto:「Agent = Model + Harness」
- 2026-04 Martin Fowler(ThoughtWorks)が 「Guides(事前制御)/ Sensors(事後制御)」 の分類を確立
- 業界の合言葉:"2025 was the year of agents. 2026 is the year of harnesses."
モデルの賢さではなく、モデルを取り囲む足場(ハーネス)の作り込みが競争軸になった、という時代認識。
2. cortex の全体像 — 4要素のフライホイール¶
cortex は社内向けAI開発プラットフォーム。品質を全レイヤーでAIと自動化に委譲するハーネスがコア。4要素が相互補強するフライホイールを成す。
┌─────────────── Guides(事前制御:踏み外せないレール) ───────────────┐
│ ① Product Graph(cpg) ② Lint / Quality Gates │
│ コード/docs/DB/infraを eslint-disable禁止・: any制限・ │
│ 1グラフに統合しMCPで検索 テストcov 90%+ をCIで強制 │
└───────────────────────────┬───────────────────────────────────┘
│ (AIはこのレール上でしか動けない)
┌───────────────────────────┴─── Sensors(事後制御:異常を捕まえる) ──┐
│ ③ Auto Review ④ Self-Healing │
│ 9観点をAIが順次チェックし 本番異常を検知→AIが調査→修正PR→ │
│ APPROVE/REQUEST_CHANGES 自動マージ→再デプロイ→再発防止lint追加 │
└───────────────────────────────────────────────────────────────┘
①②③④が回るほど、④が生む再発防止ルールが①②を厚くする=フライホイール
| 要素 | 分類 | 役割 |
|---|---|---|
| ① Product Graph(cpg) | Guides | コード・docs・DBスキーマ・infra定義を1グラフに統合、MCPでセマンティック検索 |
| ② Lint / Quality Gates | Guides | 逃げ道を物理的に塞ぐ(eslint-disable禁止、: any制限、cov 90%+) |
| ③ Auto Review | Sensors | Product Graph で影響範囲を踏まえた9観点レビュー |
| ④ Self-Healing | Sensors | 本番異常→自動修正PR→再発防止ルール自動追加 |
2-1. 規模感(執筆時点=2026年5月)¶
| 指標 | 値 |
|---|---|
| 開発期間 | 約5ヶ月(本格開発約4ヶ月) |
| アプリケーション | 123個 |
| パッケージ | 66個 |
| MCPサーバー | 19個 |
| Pulumi スタック | 110個 |
| 実装コード(TS) | 約63万行 |
| テストコード | 約56万行(実装:テスト ≒ 1.13:1) |
| ドキュメント | 約11万行 / 389ファイル |
| マージ済PR | 約790本(3月23本 → 4月518本、約22倍) |
| 著者コミット比率 | 91%(他メンバー9%、非エンジニア含む) |
2-2. 前提となる技術基盤¶
- フルTypeScriptモノレポ:
apps/(アプリ)/packages/(共有ライブラリ)/infra/(Pulumi)/worker/(Cloudflare Workers)すべてTS。言語境界で文脈が分断されないのがAIには重要。 - Composable Architecture:
packages/に再利用パッケージ、apps/は組み合わせのみ。apps/ 間の直接 import は禁止。 - 統合グラフ:infra定義 → Cloud Run サービス → Hono ルートまで1グラフで繋がる。
- tsgo(TypeScript の Go 移植版、tsc 比 約10倍高速)、Turborepo + pnpm workspaces、GitHub Actions(変更スタック検出で並列 Pulumi 適用)、Hono / TanStack Router / Vite。
3. Part 2 — 心臓部 Product Graph(cpg):静的解析を捨て JSDoc を SSoT に¶
3-1. 静的解析だけの code-graph が届かなかった3点¶
- コンテキストがない(ノードに「意味」がない)
- 進入点がない(ファイル名・関数名を既に知らないと検索できない)
- 数ホップでノードが指数爆発する
一方、DB graph は成功していた。理由は各ノードにビジネスコンテキストが付いていたから。→ この観察が転換点。
3-2. 設計判断:JSDoc を SSoT(Single Source of Truth)に¶
「コードからの推論」を捨て、全宣言に専用 JSDoc タグを付ける方針へ。
| タグ | 意味 |
|---|---|
@graph-stack |
属する infra スタック名 |
@graph-domain |
ビジネスドメイン |
@graph-business |
その宣言が何をするかの説明(Embedding 入力の本体) |
@graph-connects |
接続先(複数可、via: でパラメータレベル追跡) |
@graph-node |
ノード種別(省略時は Function) |
- 書き漏らしを物理的に禁止:ESLint プラグイン5本 + 自動PRレビュー。AIがコードを書く前提だからこそタグ必須化が成立する。
- ハルシネーションの発生時刻をずらす:LLM 生成は「JSDoc 記述フェーズ(write-time)」に限定。graph の構築・参照フェーズは決定論的(AST解析 + BigQuery MERGE)にして、参照時(read-time)のハルシネーションを排除。
3-3. ビルドとストレージ¶
- パイプライン:ts-morph で AST 解析 → JSDoc タグ抽出 → Vertex AI
gemini-embedding-2で Embedding → BigQuery MERGE。 - 差分 Embedding:BQ 既存ノードの
textForEmbeddingと新テキストを比較し、変更ノードだけ Vertex AI に投げる。通常 push では変更数十ノード、コスト $0.001 以下。 - ストレージに BigQuery を選んだ理由(Neo4j 等の専用グラフDBを採らず):
| 利点 | 詳細 |
|---|---|
| コスト | クラスタ常時起動より安い(オンデマンド課金) |
| 統合検索 | VECTOR_SEARCH + ML.DISTANCE + SQL が同一クエリで動く |
| 将来性 | BigQuery の Graph GA で標準 GQL へ移行可能 |
2テーブル:cortex.product_graph_nodes / cortex.product_graph_edges。
3-4. 4レイヤーを1グラフに¶
| ノード種別 | 出所 |
|---|---|
| Function / Class / Method | コード(JSDoc) |
| BigQueryTable / Column | Pulumi スキーマから自動抽出 |
| Document | docs/ ディレクトリ規約で自動ノード化 |
| CronSchedule / PubSubTopic | infra/ の JSDoc |
エッジ例:documented_by(stack一致で自動)、calls/queries/reads_from/writes_to(@graph-connects由来)、shares_topic(同トピックの境界ノード間)。
3-5. MCPツールと Runbook パターン¶
- 3層ツール:
search_product_graph_nodes(vector+name検索)→get_product_graph_node_detail(ID指定)→trace_product_graph_connections(BFS走査、via_filterでパラメータ追跡)。補助にread_file/query_product_graph_bq/read_firestore/write_firestore。 - Runbook パターン:各ツールの返却値に「次のアクション候補」を同梱し、AIがコピペで次を呼べる。
usecaseパラメータで戦略を切替(code-review=影響先追跡+business違反検知 /bug=direction=both・max_depth=5 で上下流深掘り /design=Documentノード優先・浅いtrace)。 - CLAUDE.md 規約:「常に cpg を最優先、落ちていたら即停止」を強制し、grep へのフォールバックを禁止。
- 手前の抽出部を
graph-jsdoc-extractor(500行弱) として公開({kind:"node"}/{kind:"edge"}の ndjson を吐く)。
設計思想は エアークローゼット_agentic_graph_rag_と社内mcp基盤_整理 の「Agentic Graph RAG」と地続き。検索は決定的、判断だけAI。
4. Part 3 — Auto Review:AIが書いたコードはAIが見る¶
4-1. 直近30日の実績(2026-04-21〜05-21)¶
| 指標 | 値 |
|---|---|
| マージPR | 769本 |
| AIレビュアー関与率 | 100% |
| 平均レビュー回数/PR | 10.8回(最大56回) |
| マージ時間中央値 | 31分(10分以内20% / 30分以内49%) |
| 個別PRへの人レビュー | ほぼ0% |
例:embeddingモデル移行PRは起票→マージ1.5時間・6イテレーション・初回指摘 Critical3件+Minor2件。
4-2. 「AIが書くとレビューが詰まる」を構造で防ぐ¶
- 9観点を1セッションで順次チェック:Graph / Architecture / Security / Test / Doc / Impact / Observability / AI-Antipattern / Recurrence。何をチェックするかは推論させず固定(観点=ハーネス側固定、評価=AI)。
- 実装:
claude -pを spawn、gh pr reviewで投稿、ファイルサイズ制限 500行/ファイル。 - Severity 4段階:Critical(セキュリティ/データ破壊/本番障害/
@graph-*欠落)/ Major(仕様逸脱/Composable違反/テスト欠如)/ Minor(命名・保守性)/ Nit(スタイル)。 - 降格禁止:「既存も違反しているから」で基準を下げるのを許さない。判定は APPROVE / REQUEST_CHANGES の2択に統一。品質基準の緩和提案そのものを Critical 扱い。
- モード分離:reviewer モード(常時起動PC)と author モード(PR作者PC)。
4-3. ガイドラインを育てる(human-on-the-loop)¶
AIが間違えた瞬間を捕まえてルール側を直す運用:①降格を許した→降格禁止ルール追加、②判定が3択で混乱→2択化、③判定がぶれる→全項目を severity/scope の表形式化、④AI特有の罠未検出→ai-antipattern.md 新設、⑤基準を緩める提案→緩和を Critical 化。人は個別PRでなく「ルール」を見る。
5. Part 4 — Self-Healing:気づく前に直り、直すたびに強くなる¶
5-1. 直近30日:115本の Self-Healing PR がマージ・デプロイ完了¶
内訳は約54本が Deploy Failed 系、61本が本番ランタイム系。人の対応は「AIが手を出せないケースだけ」で月数件レベル。
5-2. 「観測 → 修復 → 強化」の3層¶
観測層 OTel SDK / Loki / Mimir / Tempo / Faro / Grafana
Pino構造化ログに trace_id 自動付与、ログレベルをビジネスインパクト軸で規約化
│ Grafanaアラート
▼
修復層 イベントリレー → SSEプッシュ → Self-Healingモード起動
git worktreeで修正ブランチ → claude -p(Product Graph MCP + Grafana MCP)
で根本原因特定 → 修正コミット → PR → 自動レビュー → 自動マージ → 再デプロイ
(中央値 30分〜1時間で本番復旧)
│ 同じPR内で
▼
強化層 [Recurrence]観点の必須チェック → 再発防止を機械化
ESLint custom 26本 / CI guard 13本 / oxlint(error)183本 / TS strict 9個
- 修正AIと審査AIは完全に独立(別プロセス・別セッション)。Self-Healing が雑なPRを起票しても、独立した Auto Review が弾く。
- 具体例「Meet Subscription 409エラー」:Loki でログ特定 → Product Graph で
renewSubscriptions → createMeetSubscriptionの経路を辿る → 逆方向(404)の既存 fallback を発見し対称性欠落と判定 → idempotent化 + 409自己修復 + テスト3件 + 同PRで lint/型ゲート追加。 - deferral 禁止:「将来対応」「warn で導入」を許さない。lint 追加なら同PRで既存違反も0にして
errorで入れる。同じ罠を2回踏んだら機械化必須。 - 限界:Observability が網羅できないもの(UIエラー・静かなデータ破損・体感劣化)は対応不可。「検知できる異常 + 影響範囲が見える + ガードレールが厚い」の3条件が揃って初めて本番修正を任せられる。
6. Part 5 — 非エンジニアPRの民主化¶
6-1. 実際にマージされた非エンジニアPR¶
- PR #1557:+1,742行 / 41ファイルの PL ダッシュボード v2(部門マネージャーが自部門案件を絞って閲覧)。レビュー往復4回・人間レビュアー介入ゼロ。Auto-review が権限スコープの fall-through を検出し修正要求。
- PR #1573:+348 / -177 / 7ファイルのバグ修正。非エンジニアが集計クエリのテーブル参照の非対称性を特定・修正し、共通リスト切り出しで構造レベルで塞いだ。
6-2. 線引きの原則¶
| 非エンジニアが触れる | エンジニアが担う |
|---|---|
| 既存 stack の上への追加(新ページ・新エンドポイント・新entity)、既存集計の条件変更、UI修正 | stack の立ち上げ(インフラ・IaC・クラウド構成・認証設計・セキュリティ体系)、ハーネス自体の設計・拡張、外部API接続・Secure情報 |
「その人だから書けた」ではなく 「cortex の上だから書ける」 が設計根幹。従来「業務要件→テキスト化→エンジニア依頼→優先順位待ちで数日〜1週間」が、「Claude Code で直接実装→AIレビュー4往復→本番反映で数時間」 に短縮(=翻訳レイヤーが消える)。分析民主化の別事例は ミラティブ_ashura_分析民主化aiエージェント基盤_整理。
7. Part 6 — 総括:AIは信用するものではなく設計するもの¶
7-1. 素直な2アプローチはなぜ失敗するか¶
- コンテキストウィンドウ拡大の限界:全情報をプロンプトに乗せる案は物理破綻。"lost in the middle"(長い入力の中央の情報が事実上無視される)で、構造化なしに大きさだけ増やす問題は原理的に解けない。
- 学習戦略の破綻:ファインチューニングは本番運用に遠く、machine unlearning / catastrophic forgetting で「古い知識の削除」と「新知識の習得」が同時に壊れる。
→ 抜け道が GraphRAG + MCP:「必要なタイミングで、必要なコンテキストだけ供給する」。AIが自分で取りに行ける構造にする。
7-2. 「AIを信用しない」の再定義¶
- 「渡されていないコンテキストのことは知らない」「何も言わなくても理想状態を作るとは考えない」。
- 結論:「AIを使いこなすとは、AIに自由を与えることではなく、AIの出力を予測可能な範囲に閉じ込めること」。
- ハルシネーション管理=推論の発生時刻をずらす。write-time(一度だけ・検証済み=グラフ作成時)に寄せ、read-time(未検証・毎回)を避ける。グラフは「凍結され検証済みの推論」。
7-3. 捨てた3つ(試行錯誤の教訓)¶
- 静的解析ベースの code-graph を2ヶ月かけて捨てた:構造は取れるが意図・ビジネス文脈で辿れない。本当に欲しかったのは「コード + DBスキーマ + docs + インフラの統合」だと気づいた(→ cpg へ)。
- Coverage 90% 目標の陥穽:数値目標単独で実装が歪む(デフォルト値多用・エラー握り潰し・早期return)。cov は「最低限の床」とし、他観点と組み合わせる lint(
no-silent-catch、vitest-strong-matchers)で補う。 - 並列 sub-agent を廃止:各 sub-agent が独立にコンテキストをロードするため 「9倍ではなく4倍弱」のトークンを食い、時間・コスト・精度すべて低下。順次評価に切り替えたら速度・コスト・精度が同時改善。
7-4. エンジニアの仕事の分化¶
ハーネス整備が進むほど、エンジニアの役割は2方向へ:①業務設計方向(何を作るかを定義する力。コード作成は非エンジニアに開放)、②基盤設計方向(安全で迅速な実行環境の維持=ハーネスの構築・進化)。
8. 正直な限界(筆者が明記している範囲)¶
- コード品質と仕様の正しさは別物:実装が綺麗でも仕様解釈が誤っていればバグる。仕様が根本的に間違っていれば AI レビューはすり抜ける。
- 社内基盤だからこそ成立:トラブル時の巻き戻しが容易。toC 製品や WMS など停止が Critical なシステムでは同レベルは難しい。
- 非エンジニアの領域は「改修フェーズ」中心で、新規パイプライン・Secure 情報はエンジニア担当。
9. まとめ — いつ効くか(早見表)¶
| 状況 | この連載から借りる打ち手 |
|---|---|
| AIにコードベース全体を正しく理解させたい | 全情報を渡さず Product Graph(cpg)+ MCP で必要分だけ供給 |
| ノードの「意味」で検索したい/進入点がない | JSDoc を SSoT にし、@graph-business を Embedding して意味検索 |
| 参照時のハルシネーションを消したい | 推論を write-time(グラフ作成時)に寄せ、参照は決定論(AST + BQ MERGE) |
| AIが書いてレビューが詰まる | Auto Review を9観点固定・2択判定・降格禁止にし、人はルールを育てる |
| 障害対応を自動化したい | 観測→修復→強化の3層。修正AIと審査AIを分離し、再発は同PRで lint 化 |
| 数値目標でテストが形骸化する | cov は床。no-silent-catch 等の lint と組み合わせ評価 |
| 非エンジニアに本番改修を開きたい | 既存stack上の追加に限定し、品質はハーネスが担保 |
| 並列サブエージェントが遅い・高い | 順次評価を検討(独立ロードでトークンが膨らむ) |
一言でいえば 「AIを信じて自由を与える」のではなく「AIが踏み外せないレールを設計して、その上で自由に走らせる」。ハルシネーションを消すのではなく、起きても大丈夫な場所(write-time・境界)に閉じ込める、という発想の実装記録。
参考リンク¶
- Part 1 総論: https://zenn.dev/aircloset/articles/d416342f46f16b
- Part 2 Product Graph: https://zenn.dev/aircloset/articles/f6c990989e60d4
- Part 3 Auto Review: https://zenn.dev/aircloset/articles/91824e55b7fc9c
- Part 4 Self-Healing: https://zenn.dev/aircloset/articles/74c7dfab13cea2
- Part 5 非エンジニアPR: https://zenn.dev/aircloset/articles/07e276eeb77c3e
- Part 6 総括・最終章: https://zenn.dev/aircloset/articles/ea7e0cf2190436
- ハーネス分類の原典: Martin Fowler — LLM系記事(Guides/Sensors)
- Model Context Protocol(Anthropic 公式)
作成: 2026-07-07 / 最終更新: 2026-07-07