PROBLEM / S01 01
CRITICAL
AI 코딩 도구를 팀에 도입해서
구현 속도는 올랐습니다.
그런데 기획부터 테스트까지,
전체 워크플로우 속도는
거의 그대로였습니다.
INTRO / S02 02
RESOLVER

안준헌

이커머스센터 / 이커머스사업그룹
인천공항 스마트 식음 구축
PM DA BE
인천공항 스마트 면세 운영
DA BE
경복궁 온라인 면세점 운영
DA BE

AI Agent Team 협업 기반 소프트웨어 개발 자동화

PROBLEM / S03 03
CRITICAL
OA 도구
AI 도구
OA 도구

AI에게 설계 → GUI 도구로 옮기면 컨텍스트 유실

도구 A→B→C 넘길 때마다 유실

OA 도구 거쳐도, AI 도구끼리 넘겨도 끊김

컨텍스트가 유지되지 않는 작업 환경

DIAGNOSIS / S04 04
WARNING

병목 ① 산출물 컨텍스트가 AI에게 전달 안 됨

컨텍스트 어디에 있나 왜 AI가 못 읽나
DB 설계 의도 · 히스토리 GUI Modeling tool (DA#) 그림 형태 — AI가 읽고 쓸 수 없음
기획 의도 · 논리 구조 PPT 기획서 레이아웃 형태 — AI가 해석 불가
DIAGNOSIS / S05 05
INVESTIGATING

병목 ② 업무 규칙 컨텍스트가 AI에게 전달 안 됨

컨텍스트 어디에 있나 왜 AI가 못 읽나
산출물 스타일 · 패턴 담당자 머릿속 명문화되지 않음
프로젝트 규칙 사내 Wiki 산재 비구조화, AI 접근 불가
역할별 권한 구두 합의 기록 자체가 없음
SOLUTION / S06 06
RESOLVING

AI가 읽고 쓸 수 있는 형태로 전환

BEFORE

GUI 모델링 도구

그림 — AI가 읽을 수 없음

암묵지 · 산재 문서

머릿속, Wiki — 비구조화

AFTER

JSON 스키마

코드 — AI가 읽고 쓰는 형태

하네스 구조화

CLAUDE.md · agents · skills · hooks

DIAGNOSIS / S07 07
BEFORE GUI Modeling Tool
GUI 모델링 도구 화면

그림 형태 — AI가 읽고 쓸 수 없음

SOLUTION / S08 08
AFTER JSON Schema
{
  "schema": "fnb_order",
  "migrationDir": "developer/migration",
  "defaultSince": { "table": "M3_005", "relation": "M8_004" },
  "groups": [
    {
      "name": "미분류",
      "description": "자동 생성 — 후처리에서 논리 그룹으로 재분류 필요",
      "tables": [ "tb_claim", "tb_claim_target", "tb_fulfillment", "tb_order",
                  "tb_order_amount", "tb_order_item", "tb_order_product",
                  "tb_order_product_option", "tb_order_state_log",
                  "tb_order_state_projection", "tb_order_state_source",
                  "tb_payment", "tb_payment_unit", "tb_payment_unit_merchant",
                  "tb_payment_unit_point", "tb_refund", "tb_refund_unit",
                  "tb_refund_unit_merchant", "tb_refund_unit_point" ]
    },
    { "name": "장바구니", "description": "장바구니 관리",
      "tables": [ "tb_cart", "tb_cart_product", "tb_cart_product_option" ] }
  ],
  "tables": {
    "tb_claim": {
      "comment": "클레임", "entityType": "master",
      "columns": {
        "claim_key":   { "type": "bigint", "pk": true, "identity": true, "notNull": true, "comment": "클레임 Key" },
        "order_key":   { "type": "bigint", "notNull": true, "comment": "주문 Key" },
        "claim_ckey":  { "type": "integer", "notNull": true, "comment": "클레임 구분 코드 Key",
          "codeIds": { "ORDER": { "CLAIM": { "CLAIM_TYPE": {
            "CUSTOMER_CANCEL": {}, "STORE_CANCEL": {}, "RETURN": {} } } } } },
        "claim_mid":   { "type": "varchar(50)", "comment": "입점사 클레임 식별자" },
        "last_state_lkey": { "type": "bigint", "notNull": true, "default": "0", "comment": "최종 상태 이력 Key" },
        "last_success_refund_key": { "type": "bigint", "notNull": true, "default": "0", "comment": "최종 성공 환불 Key" }
      }, "audit": true, "since": "M3_005"
    },
    "tb_claim_target": {
      "comment": "클레임 대상", "entityType": "master",
      "columns": {
        "claim_target_key": { "type": "bigint", "pk": true, "identity": true, "notNull": true, "comment": "클레임 대상 Key" },
        "claim_key":  { "type": "bigint", "notNull": true, "comment": "클레임 Key" },
        "target_ckey": { "type": "integer", "notNull": true, "default": "0", "comment": "대상 코드 Key",
          "codeIds": { "ORDER": { "ENTITY": { "TARGET_TYPE": {
            "ORDER": {}, "FULFILLMENT": {}, "ORDER_PRODUCT": {}, "PAYMENT": {},
            "PAYMENT_UNIT": {}, "CLAIM": {}, "REFUND": {}, "REFUND_UNIT": {} } } } } },
        "target_key": { "type": "bigint", "notNull": true, "comment": "대상 Key" }
      }, "audit": true, "since": "M3_005"
    },
    "tb_fulfillment": {
      "comment": "이행",
      "description": "픽업주문과 예약주문 공용. 픽업주문은 queue_no/est_wait_min/queue_req_dttm으로 대기열을 관리하고, 예약주문의 방문 정보(인원·일시)는 tb_order_product.prod_qty와 타임슬롯 옵션으로 표현한다.",
      "entityType": "master",
      "columns": {
        "fulf_key":      { "type": "bigint", "pk": true, "identity": true, "notNull": true, "comment": "이행 Key" },
        "order_key":     { "type": "bigint", "notNull": true, "comment": "주문 Key" },
        "store_key":     { "type": "integer", "notNull": true },
        "fulf_verif_id": { "type": "varchar(512)", "notNull": true },
        "fulf_mid":      { "type": "varchar(50)", "comment": "입점사 이행 식별자" },
        "last_state_lkey": { "type": "bigint", "notNull": true, "default": "0", "comment": "최종 상태 이력 Key" },
        "queue_no":      { "type": "integer", "comment": "대기열 번호" },
        "est_wait_min":  { "type": "integer", "comment": "예상 대기 시간(분)" },
        "queue_req_dttm": { "type": "timestamp", "comment": "대기열 요청 시간" }
      }, "audit": true, "since": "M3_005"
    },
    "tb_order": {
      "comment": "주문", "entityType": "master",
      "columns": {
        "order_key":  { "type": "bigint", "pk": true, "identity": true, "notNull": true, "comment": "주문 Key" },
        "order_mid":  { "type": "varchar(50)", "notNull": true, "comment": "주문 입점사 ID" },
        "member_key": { "type": "integer", "notNull": true, "comment": "회원 Key" },
        "sales_unit_info_snap_lkey": { "type": "bigint", "notNull": true, "comment": "매출 단위 정보 스냅샷 이력 Key" },
        "order_type_ckey": { "type": "integer", "notNull": true, "default": "0", "comment": "주문 유형 코드 Key",
          "codeIds": { "ORDER": { "ENTITY": { "ORDER_TYPE": { "PICKUP": {}, "RESERVATION": {} } } } } },
        "order_ch_ckey": { "type": "integer", "notNull": true, "default": "0", "comment": "주문 채널 코드 Key",
          "codeIds": { "COMMON": { "CHANNEL": { "WEB_PC": {}, "WEB_MOBILE": {}, "APP_IOS": {}, "APP_AOS": {} } } } },
        "prod_qty":   { "type": "integer", "notNull": true, "comment": "주문 상품 수" },
        "last_success_pay_key": { "type": "bigint", "notNull": true, "default": "0", "comment": "최종 성공 결제 Key" }
      }, "audit": true, "since": "M3_005"
    },
    "tb_order_amount": {
      "comment": "주문 금액", "entityType": "master",
      "columns": {
        "amt_key":    { "type": "bigint", "pk": true, "identity": true, "notNull": true, "comment": "금액 Key" },
        "target_ckey": { "type": "integer", "notNull": true, "default": "0", "comment": "대상 구분 코드 Key" },
        "target_key": { "type": "bigint", "notNull": true, "comment": "대상 Key" },
        "amt_ckey":   { "type": "integer", "notNull": true, "default": "0", "comment": "금액 구분 코드 Key" },
        "currency_cd": { "type": "char(3)", "notNull": true, "comment": "통화 코드" },
        "amount":     { "type": "numeric(18,2)", "notNull": true, "comment": "금액" }
      }, "audit": true, "since": "M3_005"
    },
    "tb_order_state_log": {
      "comment": "거래 상태 이력",
      "description": "모든 주문 엔티티(주문·이행·결제·클레임·환불)의 상태 변경을 target_ckey 다형성으로 기록하는 감사(audit) 이력. Event Sourcing 원본.",
      "entityType": "history",
      "columns": {
        "log_key":     { "type": "bigint", "pk": true, "identity": true, "notNull": true, "comment": "이력 Key" },
        "target_ckey": { "type": "integer", "notNull": true, "default": "0", "comment": "대상 코드 Key" },
        "target_key":  { "type": "bigint", "notNull": true, "comment": "대상 Key" },
        "state_group_ckey": { "type": "integer", "notNull": true, "default": "0", "comment": "상태 그룹 코드 Key" },
        "state_ckey":  { "type": "integer", "notNull": true, "default": "0", "comment": "상태 코드 Key" },
        "cause_group_ckey": { "type": "integer", "notNull": true, "default": "0", "comment": "변경원인 그룹 코드 Key" },
        "cause_ckey":  { "type": "integer", "notNull": true, "default": "0", "comment": "변경원인 코드 Key" },
        "change_reason": { "type": "varchar(500)", "notNull": true, "comment": "변경 이유" },
        "operator_key": { "type": "integer", "notNull": true, "comment": "작업자 Key" },
        "change_dttm": { "type": "timestamp", "notNull": true, "comment": "변경 일시" }
      }, "audit": true, "since": "M3_005"
    },
    "tb_order_state_projection": {
      "comment": "주문 상태 반영",
      "description": "주문 자체에는 상태가 없으나, 고객 페이싱(FO)에서는 이행·결제·클레임 상태를 분리해서 보여줄 수 없으므로 이행 단위별 대표 상태가 필요하다.",
      "entityType": "master",
      "columns": {
        "proj_key":   { "type": "bigint", "pk": true, "identity": true, "notNull": true, "comment": "반영 Key" },
        "target_ckey": { "type": "integer", "notNull": true, "default": "0", "comment": "대상 코드 Key" },
        "target_key": { "type": "bigint", "notNull": true, "comment": "대상 Key" },
        "src_target_ckey": { "type": "integer", "notNull": true, "default": "0", "comment": "소스 대상 코드 Key" },
        "src_target_total_cnt": { "type": "integer", "notNull": true, "comment": "소스 대상 총 갯수" }
      }, "audit": true, "since": "M3_005"
    },
    "tb_order_state_source": {
      "comment": "주문 상태 소스",
      "description": "projection의 하위 엔티티별 상태 카운트 캐시. cnt == src_target_total_cnt이면 모든 하위 엔티티가 동일 상태에 도달.",
      "entityType": "master",
      "columns": {
        "src_key":    { "type": "bigint", "pk": true, "identity": true, "notNull": true, "comment": "소스 Key" },
        "proj_key":   { "type": "bigint", "notNull": true, "comment": "반영 Key" },
        "state_group_ckey": { "type": "integer", "notNull": true, "default": "0", "comment": "상태 그룹 코드 Key" },
        "state_ckey": { "type": "integer", "notNull": true, "default": "0", "comment": "상태 코드 Key" },
        "cnt":        { "type": "integer", "notNull": true, "comment": "갯수" }
      }, "audit": true, "since": "M3_005"
    },
    "tb_payment": {
      "comment": "결제", "entityType": "master",
      "columns": {
        "pay_key":    { "type": "bigint", "pk": true, "identity": true, "notNull": true, "comment": "결제 Key" },
        "order_key":  { "type": "bigint", "notNull": true, "comment": "주문 Key" },
        "last_state_lkey": { "type": "bigint", "notNull": true, "default": "0", "comment": "최종 상태 이력 Key" }
      }, "audit": true, "since": "M3_005"
    },
    "tb_payment_unit": {
      "comment": "결제 단위", "entityType": "master",
      "columns": {
        "pay_unit_key": { "type": "bigint", "pk": true, "identity": true, "notNull": true, "comment": "결제 단위 Key" },
        "pay_key":    { "type": "bigint", "notNull": true, "comment": "결제 Key" },
        "method_ckey": { "type": "integer", "notNull": true, "default": "0", "comment": "결제수단 코드 Key" },
        "last_state_lkey": { "type": "bigint", "notNull": true, "default": "0", "comment": "최종 상태 이력 Key" }
      }, "audit": true, "since": "M3_005"
    },
    "tb_refund": {
      "comment": "환불", "entityType": "master",
      "columns": {
        "refund_key": { "type": "bigint", "pk": true, "identity": true, "notNull": true, "comment": "환불 Key" },
        "claim_key":  { "type": "bigint", "notNull": true, "comment": "클레임 Key" },
        "pay_key":    { "type": "bigint", "notNull": true, "comment": "결제 Key" },
        "last_state_lkey": { "type": "bigint", "notNull": true, "default": "0", "comment": "최종 상태 이력 Key" }
      }, "audit": true, "since": "M3_005"
    },
    "tb_refund_unit": {
      "comment": "환불 단위", "entityType": "master",
      "columns": {
        "refund_unit_key": { "type": "bigint", "pk": true, "identity": true, "notNull": true, "comment": "환불 단위 Key" },
        "refund_key": { "type": "bigint", "notNull": true, "comment": "환불 Key" },
        "pay_unit_key": { "type": "bigint", "notNull": true, "comment": "결제 단위 Key" },
        "last_state_lkey": { "type": "bigint", "notNull": true, "default": "0", "comment": "최종 상태 이력 Key" }
      }, "audit": true, "since": "M3_005"
    },
    "tb_cart": {
      "comment": "장바구니", "entityType": "master",
      "columns": {
        "cart_key":   { "type": "bigint", "pk": true, "identity": true, "notNull": true, "comment": "장바구니 Key" },
        "member_key": { "type": "integer", "notNull": true, "comment": "회원 Key" },
        "sales_unit_key": { "type": "integer", "notNull": true, "comment": "매출 단위 Key" }
      }, "audit": true, "since": "M3_018"
    },
    "tb_cart_product": {
      "comment": "장바구니 상품", "entityType": "master",
      "columns": {
        "cart_prod_key": { "type": "bigint", "pk": true, "identity": true, "notNull": true, "comment": "장바구니 상품 Key" },
        "cart_key":   { "type": "bigint", "notNull": true, "comment": "장바구니 Key" },
        "store_prod_key": { "type": "bigint", "notNull": true, "comment": "가게 상품 Key" },
        "options_hash": { "type": "varchar(64)", "notNull": true, "comment": "옵션 해시" },
        "prod_qty":   { "type": "integer", "notNull": true, "comment": "상품 수량" }
      }, "audit": true, "since": "M3_018"
    }
  },
  "relations": [
    { "name": "tb_claim_fk_01", "from": { "table": "tb_claim", "column": "last_success_refund_key" }, "to": { "table": "tb_refund", "column": "refund_key" }, "type": "1:1" },
    { "name": "tb_claim_fk_02", "from": { "table": "tb_claim", "column": "order_key" }, "to": { "table": "tb_order", "column": "order_key" }, "type": "N:1" },
    { "name": "tb_fulfillment_fk_01", "from": { "table": "tb_fulfillment", "column": "order_key" }, "to": { "table": "tb_order", "column": "order_key" }, "type": "N:1" },
    { "name": "tb_order_fk_01", "from": { "table": "tb_order", "column": "member_key" }, "to": { "table": "tb_member", "column": "member_key", "schema": "fnb_member" }, "type": "N:1" },
    { "name": "tb_order_product_fk_01", "from": { "table": "tb_order_product", "column": "order_key" }, "to": { "table": "tb_order", "column": "order_key" }, "type": "N:1" },
    { "name": "tb_payment_fk_02", "from": { "table": "tb_payment", "column": "order_key" }, "to": { "table": "tb_order", "column": "order_key" }, "type": "N:1" },
    { "name": "tb_payment_unit_fk_01", "from": { "table": "tb_payment_unit", "column": "pay_key" }, "to": { "table": "tb_payment", "column": "pay_key" }, "type": "N:1" },
    { "name": "tb_refund_fk_01", "from": { "table": "tb_refund", "column": "pay_key" }, "to": { "table": "tb_payment", "column": "pay_key" }, "type": "N:1" },
    { "name": "tb_refund_fk_02", "from": { "table": "tb_refund", "column": "claim_key" }, "to": { "table": "tb_claim", "column": "claim_key" }, "type": "N:1" },
    { "name": "tb_cart_fk01", "from": { "table": "tb_cart", "column": "member_key" }, "to": { "table": "tb_member", "column": "member_key", "schema": "fnb_member" }, "type": "N:1" },
    { "name": "tb_cart_product_fk01", "from": { "table": "tb_cart_product", "column": "cart_key" }, "to": { "table": "tb_cart", "column": "cart_key" }, "type": "N:1" }
  ],
  "logicalRelations": [
    { "name": "상태 이력 대상 참조 (주문)", "table": "tb_order_state_log", "discriminator": "target_ckey", "key": "target_key", "target": "tb_order" },
    { "name": "상태 이력 대상 참조 (이행)", "table": "tb_order_state_log", "discriminator": "target_ckey", "key": "target_key", "target": "tb_fulfillment" },
    { "name": "상태 이력 대상 참조 (결제)", "table": "tb_order_state_log", "discriminator": "target_ckey", "key": "target_key", "target": "tb_payment" },
    { "name": "상태 반영 대상 참조", "table": "tb_order_state_projection", "discriminator": "target_ckey", "key": "target_key", "target": "tb_order" },
    { "name": "상태 소스 → 반영", "table": "tb_order_state_source", "key": "proj_key", "target": "tb_order_state_projection" }
  ]
}

AI가 직접 읽고 쓰는 형태

generate.mjs
SOLUTION / S09 09
GENERATED JSON generate.mjs ERD
ERD 시각화 결과

사람이 리뷰할 땐 JSON에서 자동 생성된 ERD로 — 외부 도구 불필요

SOLUTION / S10 10

도구 체인

JSON 하나로 DB 산출물 전체를 파생

JSON

Single Source of Truth

generate.mjs

DDL

CREATE TABLE 스크립트

ERD 시각화

SVG 렌더링 · ELK.js

reverse.mjs DDL → JSON 역변환도 가능

7

도메인 ERD

9

단계 마이그레이션

Git

버전 관리 용이

Diff

공유 · 리뷰 원활

SOLUTION / S11 11

시간 단축 효과

DB DESIGN
0
~4시간 → ~30분
ARTIFACT SYNC
0
수동 동기화 필요 건수
DEVELOPER HANDOFF
0
~2시간 → 10~20분

기존 (GUI 툴) vs 전환 후 (JSON + AI)

SOLUTION / S12 12

하네스

마구(馬具) — AI의 힘을 원하는 방향으로 쓰게 하는 장치

.claude/

CLAUDE.md
settings.json
agents/
├─ pm.md
├─ developer.md
└─ reviewer.md
skills/
└─ code-review/
└─ SKILL.md
hooks/
└─ pre-commit.sh
CLAUDE.md

핵심 지침 — 프로젝트 규칙서. 모든 에이전트가 읽는 기본 문서

settings.json

환경 설정 — 모델·권한·MCP 서버·hooks(이벤트 트리거) 구성

agents/

역할 부여 — AI 에이전트별 책임·권한·도구 정의

skills/

업무 도구 — 에이전트가 사용하는 전문 스킬 정의

hooks/ custom

커스텀 디렉토리 — 프로젝트별 가드레일 스크립트 모음

DIAGNOSIS / S13 13
INVESTIGATING

주문 기능을 만들려면?

order
+
db-schema
+
planning
+
...
각 레포를 따로 열면
AI가 다른 레포를 참조 못함
사람이 컨텍스트를 수동 복사
도메인 간 컨텍스트 단절
하나로 합치면
컨텍스트 윈도우 초과
도메인 규칙이 뒤섞임
관련 없는 코드가 노이즈

따로 열어도, 합쳐도 문제 — 어떻게 해야 하나?

SOLUTION / S14 14
RESOLVING

AI-Legible Workspace

workspace/
CLAUDE.md
harness-plugins/
├─ agents/
├─ skills/
└─ hooks/
order/
└─ CLAUDE.md
db-schema/
└─ CLAUDE.md
planning/
└─ CLAUDE.md
fe-fo/
└─ CLAUDE.md
fe-bo/
└─ CLAUDE.md
...
루트가 오케스트레이션

CLAUDE.md가 어떤 레포를 언제 참조할지 지시

필요한 하위 레포만 선택적으로 조합

각 레포는 셀프 컨테인드

자기만의 CLAUDE.md + 하네스를 플러그인으로 설치 가능

harness-plugins

공통 규칙 및 개별 규칙을 한 곳에서 관리, 각 레포에 동기화

비개발 직군도 사용 중

기획자도 코드 에디터 + Git 작업 환경에서 AI와 협업

송금아 이사님 · 이종석 과장님 · 박소미 과장님

러닝커브 1주일 내 해소 · 개발자와의 산출물 공유 원활

RESULT / S15 15

하네스 워크플로우

하네스 완성도에 따라 워크플로우가 어떻게 달라지는지 비교합니다

하네스 완성도 20% → 80%로 보강되는 과정을 보겠습니다

RESULT / S1616
DIAGNOSIS / S17 17

하네스 없이 AI에게 프롬프트만

규칙 없음 · 가드레일 없음 · 일관성 없음

01
지시
02
AI 생성
03
수동 검토
사용자
프롬프트 작성
컨텍스트
매번 처음부터 설명
규칙
없음 — AI 임의 판단
AI
코드 생성
스타일
매번 다름
패턴
기존 코드 무시
사용자
수동 리뷰
체크
사람이 전부 확인
결과
수정에 수정 반복
AI 이득 → 0 수렴

리뷰에서 하나둘 고치다 보면 결국 수작업 — AI를 쓰는 이득이 0에 수렴

SOLUTION / S18 18

CLAUDE.md만 있을 때 하네스 시작

프로젝트 규칙서만 존재 · 에이전트/스킬/훅 없음

01
지시
02
AI 생성
03
수동 검토
04
완료
사용자
프롬프트 작성
CLAUDE.md
규칙 자동 적용
AI
코드 생성
스타일
규칙 범위 내 일관
패턴
자동 분석 없음
사용자
수동 리뷰
체크
사람이 직접 확인
교정 루프
없음 — 수동 재지시
COMMIT
완료
기본 품질

CLAUDE.md 규칙은 적용되지만, 분석·검증·교정은 모두 사람 몫

RESULT / S19 19

워크플로우 하네스 ~20%

W13 · 에이전트 4명 · ~30건 체크 · 단순 pass/fail

01
지시
02
구현
03
검증
04
완료
사용자
한 줄 지시
PM Agent
Jira 자동 생성
Analyzer-BE
코드 패턴 분석 (기본)
참조 파일 전달
구조화 안 됨
Developer-BE
구현
./gradlew build
성공?
↓ 실패 시 재시도
Reviewer-BE
빌드 + 테스트
코드 리뷰
~30건 체크 (5개 영역)
BLOCKER 8 · WARN 15 · NIT 7
빌드+테스트 통과?
단순 pass/fail
↓ BLOCKER
사용자에게 보고
수동 판단 · 수동 재지시
COMMIT
완료
RESULT / S20 20

풀 워크플로우 — Track A 하네스 ~80%

W14 · 에이전트 6명 · 113건 체크 · 6차원 ICL 자동 교정

01
지시
02
설계
03
구현
04
검증
05
ICL ↻ MAX 5
06
완료
사용자
한 줄 지시
PM Agent
Jira 자동 생성
Track 판단
(6+ files, 신규 도메인)
A:설계 B:분석 C:직접
Dev-Lead
설계 Spec 작성
(기능/아키텍처/API/DB)
사용자 Spec 승인?
Y → 진행 / N → 반려
Analyzer-BE
코드 패턴 분석
Handoff Envelope
참조 파일 + 패턴 체크리스트
Developer-BE
구현
DB 스키마 변경?
↓ Yes
jOOQ Gen
(dev DB 기준)
DSL + CommonCodeConstant
+ Multilingual + Partner
신규 CommonCode?
↓ Yes
Common Code Seeding
1. API로 dev DB 등록
2. code_key 재조회 (필수)
3. M6_data SQL 생성
./gradlew build
PM
Reviewer 스폰 (필수)
Reviewer-BE
1. jOOQ gen clean + build
2. 전체 테스트
(VerifiedDocumentation)
3. 코드 리뷰
총 113건 체크
BLOCKER 20 · WARNING 76 · NIT 6
코드 리뷰 13개 영역
/query-auditN+1, 재조회
/code-quality복잡도, 길이
DDD 감사E13·CVO7·VO5·Exc2·P7
DTO 감사Req6·Q6·Res5·KC3
Infra 감사Repo8·Asm4
Svc/CtrlSvc7·Ctrl6
다국어·기타다국어4·크로스3·API2·테스트6
/icl-score 산출
6차원 점수 계산
D1: Build (0/100)
D2: Test (pass/total)
D3: DDD 준수
D4: Query 품질
D5: ADR 준수
D6: 설계 정합
복합 점수
= 0.20×D1 + 0.20×D2
+ 0.20×D3 + 0.15×D4
+ 0.15×D5 + 0.10×D6
점수 ≥ 90?
↓ No
Fix Directive 생성
(BLOCKER 우선 + 영향도 순)
→ Developer ↻
↓ delta<0
사용자 에스컬레이션
↓ Yes
PASS
COMMIT
[AI Generated] JIRA-KEY
type(scope): subject
벌크 테스트 데이터?
↓ Yes
Seeder-BE
/seed-script-build
Controller→DTO 분석
인증 모드 결정
(Partner SSO / BO Login)
--dry-run
구조 검증
Canary (1건)
성공?
400/422→retry 500→esc
↓ 200
--count=N Main
벌크 실행
--verify
SELECT COUNT SQL
완료

* ICL = Iterative Correction Loop — 품질 미달 시 Fix Directive를 생성하여 구현→검증을 반복하는 자동 교정 루프

RESULT / S21 21

병렬 워크플로우 실행

이슈가 시간차로 동시 진행 — 사용자는 Spec 승인과 에스컬레이션만 개입

JIRA-101
01
지시
02
설계
03
구현
04
검증
05
ICL
06
완료
사용자
한 줄 지시
PM Agent
Jira 생성
Track 판단
A/B/C
Dev-Lead
Spec 작성
승인?
Analyzer
패턴 분석
Developer
구현
jOOQ Gen
build
Reviewer
113건
코드 리뷰
13개 영역
ICL
6차원 점수
≥90?
Fix Directive
COMMIT
Seeder
완료
JIRA-102
01
지시
02
설계
03
구현
04
검증
05
ICL
06
완료
사용자
한 줄 지시
PM Agent
Jira 생성
Track 판단
A/B/C
Dev-Lead
Spec 작성
승인?
Analyzer
패턴 분석
Developer
구현
jOOQ Gen
build
Reviewer
113건
코드 리뷰
13개 영역
ICL
6차원 점수
≥90?
Fix Directive
COMMIT
Seeder
완료
JIRA-103
01
지시
02
설계
03
구현
04
검증
05
ICL
06
완료
사용자
한 줄 지시
PM Agent
Jira 생성
Track 판단
A/B/C
Dev-Lead
Spec 작성
승인?
Analyzer
패턴 분석
Developer
구현
jOOQ Gen
build
Reviewer
113건
코드 리뷰
13개 영역
ICL
6차원 점수
≥90?
Fix Directive
COMMIT
Seeder
완료
JIRA-104
01
지시
02
설계
03
구현
04
검증
05
ICL
06
완료
사용자
한 줄 지시
PM Agent
Jira 생성
Track 판단
A/B/C
Dev-Lead
Spec 작성
승인?
Analyzer
패턴 분석
Developer
구현
jOOQ Gen
build
Reviewer
113건
코드 리뷰
13개 영역
ICL
6차원 점수
≥90?
Fix Directive
COMMIT
Seeder
완료
JIRA-105
01
지시
02
설계
03
구현
04
검증
05
ICL
06
완료
사용자
한 줄 지시
PM Agent
Jira 생성
Track 판단
A/B/C
Dev-Lead
Spec 작성
승인?
Analyzer
패턴 분석
Developer
구현
jOOQ Gen
build
Reviewer
113건
코드 리뷰
13개 영역
ICL
6차원 점수
≥90?
Fix Directive
COMMIT
Seeder
완료
JIRA-106
01
지시
02
설계
03
구현
04
검증
05
ICL
06
완료
사용자
한 줄 지시
PM Agent
Jira 생성
Track 판단
A/B/C
Dev-Lead
Spec 작성
승인?
Analyzer
패턴 분석
Developer
구현
jOOQ Gen
build
Reviewer
113건
코드 리뷰
13개 영역
ICL
6차원 점수
≥90?
Fix Directive
COMMIT
Seeder
완료
JIRA-107
01
지시
02
설계
03
구현
04
검증
05
ICL
06
완료
사용자
한 줄 지시
PM Agent
Jira 생성
Track 판단
A/B/C
Dev-Lead
Spec 작성
승인?
Analyzer
패턴 분석
Developer
구현
jOOQ Gen
build
Reviewer
113건
코드 리뷰
13개 영역
ICL
6차원 점수
≥90?
Fix Directive
COMMIT
Seeder
완료
JIRA-108
01
지시
02
설계
03
구현
04
검증
05
ICL
06
완료
사용자
한 줄 지시
PM Agent
Jira 생성
Track 판단
A/B/C
Dev-Lead
Spec 작성
승인?
Analyzer
패턴 분석
Developer
구현
jOOQ Gen
build
Reviewer
113건
코드 리뷰
13개 영역
ICL
6차원 점수
≥90?
Fix Directive
COMMIT
Seeder
완료
JIRA-109
01
지시
02
설계
03
구현
04
검증
05
ICL
06
완료
사용자
한 줄 지시
PM Agent
Jira 생성
Track 판단
A/B/C
Dev-Lead
Spec 작성
승인?
Analyzer
패턴 분석
Developer
구현
jOOQ Gen
build
Reviewer
113건
코드 리뷰
13개 영역
ICL
6차원 점수
≥90?
Fix Directive
COMMIT
Seeder
완료

W14 기준 일 평균 ~20건 병렬 처리 · 한 줄 지시 → 전체 자동

SOLUTION / S22 22
CAVEAT 1 / 3

규칙이 레포를 넘지 못한다

agents · skills · hooks — 선언한 레포 안에서만 동작

BEFORE

order/
.claude/ 복붙
catalog/
.claude/ 복붙
member/
.claude/ 복붙
하나 고치면 나머지는 옛날 버전
상위/하위 레포 간 전파 불가

AFTER

harness-plugins
중앙 레포
fnb-common fnb-be fnb-fe fnb-infra
규칙 수정 → 버전 업 → 전체 동기화
레포별 필요한 조합만 설치
SOLUTION / S23 23
CAVEAT 2 / 3

지시서가 길면 AI가 잊는다

매뉴얼 200페이지를 한꺼번에 읽으면 앞부분을 까먹는 것과 같음

CONTEXT WINDOW OVERFLOW
CLAUDE.md 비대화 에이전트 간 규칙 중복 규칙 누락
슬림화

CLAUDE.md에는 핵심 원칙만

상세 절차 → agents · skills로 위임

중복 제거

같은 규칙이 여러 파일에 반복되면

한 곳에 정의하고 참조

텍스트 → 프로그램

글로 쓴 규칙을 프로그램으로 강제

CLI 명령어 · JS 스크립트 등

SOLUTION / S24 24
CAVEAT 3 / 3

Git은 의미 충돌을 못 잡는다

하네스 파일도 git에 올라감 — 라인 충돌 ≠ 의미 충돌

GIT MERGE

// A: developer-be.md
+ Entity에 @Builder 사용
// B: reviewer-be.md
+ Entity에 @Builder 금지
충돌 없음 — 다른 파일이니 자동 머지

HARNESS-KEEPER

// 의미적 충돌 분석
BLOCKER: 모순 발견
  developer ↔ reviewer
  "@Builder 사용" vs "@Builder 금지"
의미 모순 탐지 → PM에게 리포트
모순 BLOCKER 중복 WARNING 범위 침범 WARNING 부작용 NIT
RESULT / S25 25
REVIEW CYCLE

코드 리뷰 소요 시간

Bitbucket PR 생성 → 머지 시각 기준 측정

BEFORE

90

분 (최대)

−94%

AFTER

5

분 (최대)

AI Reviewer가 113건 체크리스트를 자동 수행

사람은 BLOCKER 요약만 확인 → 승인/반려

RESULT / S26 26
OPTIMAL

도입 효과

BE git log 기준 · 인·월당 기능 수 · order + catalog + member 합산

하네스 없음 하네스 ~20% 하네스 ~80% 40 32 24 16 8 0 인·월당 기능 수 W02–W08 (7주) W09–W12 (4주) W13–W14 (2주) 1월–2월 3월 전반 3월 후반–4월 ~5 ~11 ~37 ×2 ×7 29건 66건 220건
315

총 이슈 (3개 도메인)

×7

증가율

13주

측정 기간

1건 = git 커밋의 고유 Jira 이슈 번호 · order(114) + catalog(287) + member(83) · 진행 중

RESULT / S27 27
OPTIMAL

이전 프로젝트와의 비교

주문 도메인, 도메인 API 기준

경복궁 프로젝트
엔드포인트 90개
집중 개발 ~6개월
개발자 3명
엔드포인트/인·월 ~5개
인천공항 프로젝트
엔드포인트 43개 (진행 중)
집중 개발 ~2개월
개발자 1명
엔드포인트/인·월 ~20개

AI가 읽을 수 있는 구조를 먼저 만들었기 때문입니다.

인천공항은 진행 중이라 최종 수치는 달라질 수 있음

CLOSING / S28 28

다음 단계

직무 경계 재설정

AI 워크플로우 기준으로 역할 분담을 다시 그림

메타 하네스

하네스 자체를 AI가 생성·보강하는 구조

CLOSING / S29 29

참고 출처

기술 근거

W3C Data on the Web Best Practices
OASIS DITA v1.2 Specification
NTIA AI Accountability Policy Report (2024)
Microsoft RAG in Azure AI Search

컨퍼런스

DevMento Agentic Workflow 2026 — AI 에이전트 주도 개발 실전 컨퍼런스

안준헌 · 이커머스사업그룹 · 2026.04.25

감사합니다

01 / 24
← → · SPACE