많은 이들이 AI가 코드를 대신 짜주는 시대에 개발자의 종말을 이야기합니다. 하지만 9년 차 이상의 시니어라면 직감하고 있습니다. 엔진이 강력해질수록 핸들의 유격은 더 정교해야 한다는 것을요. 고대 신화 속 자신의 꼬리를 삼키며 무한히 순환하는 우로보로스(Ouroboros)는, 이제 우리에게 단순한 상징을 넘어 'AI 오케스트레이션의 최종 진화 모델'을 제시합니다.

1. 뱀의 머리: "명세(Specification)는 가장 고차원적인 코딩이다"

우로보로스 프로젝트의 철학은 명확합니다. "프롬프팅을 멈추고, 스펙을 써라." 자바 시니어라면 익숙한 인터페이스 기반 설계(Interface-driven Design)와 맞닿아 있습니다. 우리가 Interface를 정의할 때 구현체에 관심이 없듯, AI 에이전트에게 필요한 것은 "어떻게(How)"가 아니라, 완벽하게 모호성이 제거된 "무엇을(What)"에 대한 명세입니다.

  • 모호성 점수(Ambiguity Score)의 관리: 훌륭한 아키텍트는 AI에게 명령하기 전, 스스로 질문합니다. "이 명세에 해석의 여지가 남아 있는가?"
  • Seed YAML의 힘: 우로보로스에서 사용하는 Seed 명세처럼, 도메인 주도 설계(DDD)의 유비쿼터스 언어를 활용해 '비즈니스 요구사항'을 '기계적 명세'로 치환하는 능력이 AI 시대 시니어의 첫 번째 덕목입니다.

2. 뱀의 몸통: "오케스트레이션은 검증의 연속이다"

명세가 정확하다면, 그다음은 수많은 에이전트를 조율(Orchestration)하는 단계입니다. 단순히 코드를 생성하는 것이 아니라, 생성된 코드가 명세를 배반하지 않는지 끝없이 순환하며 확인하는 과정이죠.

우로보로스가 제안하는 3단계 검증 루프는 자바의 견고한 인프라와 결합할 때 폭발적인 ROI를 냅니다.

  • Mechanical Gate: 자바의 강력한 Type SystemLinter가 문법적 무결성을 1차 검증합니다.
  • Semantic Gate: Property-based Testing(Fast Check)을 통해 로직의 엣지 케이스를 무차별적으로 공격하여 논리적 결함을 찾아냅니다.
  • Consensus Gate: 여러 LLM 모델이 서로의 코드를 리뷰하며 '최선의 합의점'을 도출합니다.

이 과정에서 아키텍트는 단순 코더가 아닌, '검증 파이프라인의 설계자'가 됩니다.

3. 뱀의 꼬리: "자기 참조적 진화(Self-Correction)"

우로보로스의 뱀이 제 꼬리를 먹으며 몸집을 키우듯, 좋은 AI 아키텍처는 [에러 피드백 -> 명세 수정 -> 코드 재생성]의 루프가 인간의 개입 없이 돌아가야 합니다.

에러가 발생했을 때 사람이 코드를 직접 고치는 순간, 그 프로젝트의 AI ROI는 멈춥니다. 대신 "왜 명세가 이 에러를 막지 못했는가?"를 고민하고 명세를 수정해야 합니다. 꼬리(에러/결과물)를 머리(명세)로 다시 보내는 이 순환 루프가 완성될 때, 비로소 시스템은 스스로 진화하는 '살아있는 유기체'가 됩니다.


맺으며: "명세는 영원하고, 코드는 찰나다"

자바 25가 나오고 버추얼 스레드가 세상을 바꿔도, '도메인의 본질을 꿰뚫는 명세'의 가치는 변하지 않습니다. AI라는 거대한 파도를 타는 유능한 서퍼는 파도를 통제하려 하지 않습니다. 대신 자신이 가고자 하는 목적지(Specification)를 명확히 하고, 보드(Infra)를 견고하게 다질 뿐입니다.

검증 인프라에 투자하고 명세를 예술의 경지로 끌어올리는 프로젝트만이, 이 우로보로스의 순환 루프 안에서 무한히 성장할 수 있습니다.

"당신은 오늘, AI에게 코드를 짜라고 명령했습니까? 아니면 완벽한 명세를 선물했습니까?"

 

 

LIST

1. 10년 전이면 고수의 글, 지금은 딸각

10년 전 기술 블로그를 떠올려 본다. 커널 패닉을 며칠 밤새 추적한 흔적, GC 로그를 한 줄씩 뜯어 본 기록, 분산 트랜잭션의 엣지 케이스를 직접 재현해 본 이야기. 그런 글에는 손때가 묻어 있었다. 글쓴이가 그 깊이까지 닿았다는 증명이 글 자체였다. 그런데 지금은 같은 수준의 문장이 Claude 한 번 "딸각"이면 그럴듯하게 쏟아진다. 정보의 양은 폭증했는데 진짜 신호를 가려내기는 더 어려워졌다. 자신감 넘치는 어조와 잘 정돈된 목차, 매끄러운 코드 블록—그 안이 비어 있어도 외형은 완벽하다. 빈수레일수록 더 요란하게 굴러간다. 과거에는 깊이가 형식을 만들었다면, 지금은 형식이 깊이를 흉내 낸다. 글의 모양만 보고 사람을 판단하던 기준이 더 이상 작동하지 않는다.

https://www.youtube.com/shorts/qtxUtMhDqYI

 

2. 고수의 재정의 — 한 명의 천재에서 여러 전문가의 오케스트레이터로

그렇다면 고수란 무엇인가. 과거의 고수는 단수(單數)였다. 한 분야를 깊이 파고들어 그 영역에서는 누구보다 멀리 본 사람. 그러나 미래의 고수는 복수(複數)를 다룬다. 과거의 고수 여럿을 agent로 부리는 사람이다. 이는 단순히 프롬프트를 잘 쓰는 능력과 다르다. 각 영역에서 어느 수준의 전문성이 필요한지 판별하고, AI가 내놓은 결과물이 진짜인지 그럴듯한 모조품인지 검증하고, 도메인 판단력으로 여러 산출물을 통합해 의사결정하는 능력이다. Claude Code 한두 개 띄워 본 사람과 멀티 에이전트를 조직처럼 운영해 본 사람의 격차는, 10년 전 IDE를 막 쓰는 신입과 디버거를 손발처럼 다루던 시니어의 격차와 닮았다. 도구가 평준화될수록 도구를 부리는 판단력이 유일한 차별화 요소로 남는다. 고수의 자리는 사라진 것이 아니라 한 단계 위로 이동했다.

3. 중간 관리자 개발자의 위치 애매성

이 지각 변동에서 가장 위태로운 자리가 4~7년차 중간 관리자급 개발자다. 위로는 시니어 아키텍트의 시야와 통찰에 아직 미치지 못하고, 아래로는 AI가 주니어급 코딩을 빠른 속도로 흡수하고 있다. 정확히 말하면 "어중간한 깊이의 작업"이 가장 먼저 자동화되는 영역이다. CRUD 한 세트, 평이한 리팩터링, 무난한 API 설계, 매뉴얼 수준의 트러블슈팅. 이 일들로 연봉의 정당성을 만들어 왔다면, 이제 그 정당성이 흔들린다. 회사 입장에서 어중간한 미들 레벨 다섯 명보다 시니어 한 명 + AI 도구 잘 쓰는 주니어 두 명이 더 효율적인 시대가 오고 있다. 미들 개발자의 진짜 위기는 일자리가 사라지는 것이 아니라, 자기 포지션이 무엇인지 스스로도 설명하지 못하는 상태다. "두루두루 합니다"는 더 이상 강점이 아니라 약점에 가깝다.

4. 두 갈래 길 — 깊이 있는 개발자 혹은 전천후 오케스트레이터

이 애매한 지대에서 빠져나가는 길은 두 가지다. 하나는 깊이로 가는 길. 분산 시스템, 보안, 컴파일러, 도메인 모델링—AI가 표면을 흉내 낼 수는 있어도 진짜 엣지 케이스에서 책임을 질 수는 없는 영역이 있다. 그곳에서 한 점을 깊게 뚫고 들어간 사람은 AI 시대에도 대체되지 않는다. 다른 하나는 전천후 오케스트레이터로 가는 길. 모든 코드를 직접 짜지는 못해도 전체 아키텍처를 머릿속에 그릴 수 있고, 도메인 판단력과 시스템 사고로 여러 agent의 산출물을 통합해 책임지는 사람. 본인이 모든 깊이를 갖지 않아도 어느 깊이가 필요한지 판단할 수 있다면 그 자체가 고수다. 두 길의 공통점은 결국 판단력이다. 깊이는 한 점에 집중된 판단력이고, 전천후는 넓은 영역에 분산된 통합 판단력이다. 가장 위험한 선택은 어느 쪽도 아닌 중간에 머무르는 것. 빈수레의 요란함을 흉내 내는 데 시간을 쓰지 말고, 어느 방향이든 무게가 실리는 수레를 만들어야 한다. 10년 후의 고수는 지금 그 무게를 쌓고 있는 사람이다.

LIST

1일차: 클라우드 및 Docker 개념 학습

클라우드 컴퓨팅이 필요한 이유

  1. 비용절감
    • 하드웨어 및 소프트웨어를 구입하고 데이터 센터 설치 및 운영 비용을 줄일 수 있습니다.
    • 서버 랙, 전원 및 냉각에 사용되는 전기료, 인프라 관리를 위한 IT 전문가 인건비 등도 절약됩니다.
  2. 속도향상
    • 주문형 셀프서비스로 제공되기 때문에 다양한 컴퓨팅 리소스를 몇번의 마우스 클릭으로 설정할 수 있습니다.
  3. 확장성
    • 필요할 때 적절하게 스토리지, 네트워크 대역폭 등 IT 자원을 확장할 수 있습니다.
  4. 생산성
    • 일반적인 온사이트 데이터센터에서는 하드웨어 설치, 소프트웨어 패치 및 시간이 오래걸리는 IT 운영 작업이 필요하지만, 클라우드 컴퓨팅을 사용하면 이 모든게 불필요해지므로 IT 팀은 인프라 외에 비즈니스에 집중할 수 있습니다.

Docker Compose vs Kubernetes

 

 

 

2일차: Docker 이미지 생성 실습

Docker 이미지 주요 명령어

# 현재 시스템에서 사용 가능한 모든 Docker 이미지 목록 확인
$ docker images

# 특정 이미지 다운로드
$ docker pull <이미지 이름>

# 이미지 정보 확인
$ docker inspect <이미지 이름>

# 이미지 삭제
$ docker rmi <이미지 이름>

 

 불필요한 파일 줄이기 (.dockerignore 활용)

  • .**dockerignore** 파일은 Docker 빌드 과정에서 제외할 파일과 디렉터리를 지정하는 역할을 합니다.
  • Docker는 docker build를 실행할 때, 현재 디렉터리(.)의 모든 파일을 Docker 컨텍스트에 복사합니다.
  • 이때 .dockerignore 파일을 사용하면 불필요한 파일을 제외하여 빌드 속도를 향상시키고, 보안성을 강화할 수 있습니다.
  • .dockerignore 파일이 필요한 이유
    1. 빌드 속도 향상 → 불필요한 파일을 제외하여 Docker 컨텍스트 크기를 줄임
    2. 보안 강화 → 환경 변수 파일(.env), 인증 정보(.git, node_modules) 등이 이미지에 포함되지 않도록 방지
    3. 이미지 크기 최소화 → 최적화된 Docker 이미지를 생성하여 배포 용량을 줄임

 

 

레이어 캐싱 (Layer Caching)

도커의 가장 중요한 특징 중 하나는 레이어 캐싱입니다. 이미지를 빌드할 때, Dockerfile의 각 명령어를 순서대로 실행하며 레이어를 만듭니다. 이때 명령어의 내용이 이전 빌드와 동일하다면, 새로운 레이어를 만들지 않고 기존에 만들어 두었던 레이어를 재사용합니다. 이를 '캐시(Cache)를 사용한다'고 말합니다.

  • 빌드 속도 향상: 변경되지 않은 부분은 다시 실행할 필요가 없으므로 이미지 빌드 시간이 크게 단축됩니다.
  • 효율적인 저장 공간 사용: 여러 이미지가 동일한 레이어를 공유하는 경우, 해당 레이어는 디스크에 한 번만 저장됩니다. 예를 들어, ubuntu:22.04를 기반으로 하는 10개의 다른 이미지가 있더라도, 우분투 베이스 레이어는 단 한 번만 저장됩니다.

Dockerfile을 작성할 때, 자주 변경되지 않는 내용은 앞부분에, 자주 변경되는 내용은 뒷부분에 배치하는 것이 레이어 캐싱을 효율적으로 활용하는 좋은 방법입니다. 소스 코드는 자주 바뀌므로 COPY . . 명령어는 보통 뒷부분에 위치시킵니다.

 

 

Docker 이미지 Versioning 과 Semantic Versioning

Docker 이미지 versioning

  • Docker 이미지는 태그(Tag) 를 사용하여 버전 관리를 수행합니다.
  • latest 태그를 사용할 수도 있지만, 명확한 버전 관리를 위해 시멘틱 버저닝(Semantic Versioning) 을 사용하는 것이 좋습니다.

시멘틱 버저닝(Semantic Versioning)이란

  • 시멘틱 버저닝(SemVer)은 주버전(Major), 부버전(Minor), 패치버전(Patch) 으로 구성됩니다.
    • 형식: MAJOR.MINOR.PATCH
    • MAJOR (주 버전): 호환성이 깨지는 큰 변경이 있을 때 올립니다.
      • 예: 1.5.2 → 2.0.0
      • 기존의 사용법이나 기능이 완전히 바뀌어, 이 버전을 사용하려면 내 코드도 수정해야 할 수 있다는 강력한 신호입니다. 마치 자동차 엔진이 바뀌는 것과 같습니다.
    • MINOR (부 버전): 기존 버전과 호환되면서 새로운 기능이 추가될 때 올립니다.
      • 예: 1.9.2 → 1.10.0
      • 기존 기능은 그대로 잘 작동하며, 새로운 옵션이나 기능이 추가된 경우입니다. 자동차에 새로운 내비게이션 시스템이 추가된 것과 같습니다. 기존 운전 방식에는 영향이 없습니다.
    • PATCH (패치 버전): 기존 버전과 호환되는 작은 버그 수정이 있을 때 올립니다.
      • 예: 1.5.2 → 1.5.3
      • 기능 변화 없이, 기존 기능의 오류를 바로잡은 경우입니다. 자동차의 사소한 부품 결함을 수리한 것과 같습니다.

버전 형식 설명

1.0.0 초기 릴리즈 버전
1.1.0 기능(feature) 추가 (하위 호환 유지)
1.1.1 버그 수정 (패치 버전)
2.0.0 기존 기능을 변경하거나 호환되지 않는 수정

Docker에서 Semantic Versioning 적용 예제

  • Dockerfile을 사용하여 시멘틱 버저닝을 적용할 때, 태그를 명확하게 지정합니다.
  • 시멘틱 버저닝을 활용하면 배포 관리가 쉬워지고, 특정 버전으로 롤백이 용이해집니다.
# 1.0.0 버전으로 빌드
docker build --build-arg PROFILE=dev -t spring-docker:1.0.0 .

# 1.0.1 버전으로 빌드 (패치 업데이트 포함)
docker build --build-arg PROFILE=dev -t spring-docker:1.0.1 .

 

3일차: Docker 네트워크 및 데이터 관리

 

  • Docker 네트워크 개념 및 종류 이해
  • 컨테이너 간 네트워크 설정 및 통신 실습
  • Docker 볼륨을 활용한 데이터 관리 실습
  • 보안 및 성능 최적화 기법 적용

1.3 컨테이너 간 기본 네트워크 통신 확인

 

# 현재 Docker 네트워크 확인
docker network ls

# 사용자 지정 브리지 네트워크 생성
# sleep infinity : 컨테이너 내부에서 종료되지 않는 프로세스를 실행하여 유지
docker run -d --name svc1 --network bridge busybox sleep infinity
docker run -d --name svc2 --network bridge busybox sleep infinity

docker exec -it svc1 ping svc2

-------------------------------------------------
ping: bad address 'svc2'

 

  • 기본 bridge 네트워크에서 컨테이너 간 직접 통신이 안 되는 이유
    1. 기본 bridge 네트워크에서는 컨테이너 이름 기반 DNS 해석이 지원되지 않음
    2. IP 주소를 직접 사용해야 하지만, IP는 컨테이너 재시작 시 변경될 수 있어 관리가 어려움
    3. 사용자 정의 네트워크를 만들면 컨테이너 이름을 통해 자동으로 통신 가능
  • 해결책
    • 기본 bridge 네트워크를 사용할 경우, 컨테이너 간 통신 시 IP 주소를 사용해야 합니다.
    • 컨테이너 이름으로 통신하려면 사용자 정의 네트워크(docker network create <네트워크명>)를 사용해야 합니다.

 

4일차: Docker 를 활용한 Log 관리

 

 

1. 표준 로그 스트림 및 출력 관리

1.1 표준 에러 스트림과 표준 출력 스트림

  1. 컨테이너 실행 및 로그 생성
    • sh -c 명령어를 통해 stdout과 stderr로 각각 로그를 출력합니다.
    • echo "stderr log" >&2는 표준 에러로 메시지를 보냅니다.
  2. docker run --name log-test -d alpine sh -c ' for i in $(seq 1 10); do echo "$i: stdout log"; echo "$i: stderr log" >&2; done'
  3. 로그 확인하기
    • 실행 중인 컨테이너의 모든 로그 출력
    docker logs log-test
    
    • 최근 5개의 로그 출력
    docker logs --tail 5 log-test
    
  1. 실시간 로그 스트림 확인
    • f 옵션을 사용하면 컨테이너의 실시간 로그 스트림을 확인할 수 있습니다.
  2. docker logs -f log-test
  1. 로그 출력 시 타임스탬프 포함
    • 각 로그에 타임스탬프를 추가하여 출력합니다.
    docker logs --timestamps log-test
    
  2. 실습 종료 및 컨테이너 정리

docker stop log-test && docker rm log-test

2. 컨테이너 로그 수집 및 관리

2.1 syslog 드라이버를 이용해 로그 전송 설정하기

Docker 컨테이너의 로그를 외부 syslog 서버로 전송 설정합니다.

docker run --log-driver=syslog --log-opt syslog-address=udp://localhost:514 -d ubuntu echo "Logging to syslog"

2.2 로그 로테이션 설정

Docker 컨테이너의 로그 드라이버는 기본적으로 json-file을 사용하며, 이 드라이버는 로그 로테이션 옵션이 있습니다. max-size와 max-file 옵션을 사용하여 로그 파일의 최대 크기와 보관할 로그 파일의 수를 제어할 수 있습니다.

# Docker 컨테이너를 로그 로테이션 설정과 함께 실행
docker run -d \\
  --name=log-rotation-test \\
  --log-opt max-size=10m \\
  --log-opt max-file=3 \\
  ubuntu bash -c 'while true; do echo "$(date) - Writing logs to fill up space..."; sleep 1; done'
  
# 로그 확인
docker logs -f log-rotation-test

# 종료 
docker stop log-rotation-test
docker rm log-rotation-test

2.3 로그 모니터링 실습

2.3.1 로그 모니터링 스크립트 생성

#!/bin/bash

# 첫 번째 인자로 컨테이너 이름을 받음
CONTAINER_NAME=$1
# 로그 라인 수 임계값 설정
THRESHOLD=1000

# 무한 루프로 계속 모니터링
while true; do
    # 현재 컨테이너의 로그 라인 수를 계산
    LOG_SIZE=$(docker logs $CONTAINER_NAME 2>&1 | wc -l)
    
    # 현재 시간 저장
    CURRENT_TIME=$(date "+%Y-%m-%d %H:%M:%S")
    
    # 로그 크기가 임계값을 초과하면 경고
    if [ $LOG_SIZE -gt $THRESHOLD ]; then
        echo "[$CURRENT_TIME] Warning: Log size ($LOG_SIZE lines) exceeds threshold ($THRESHOLD) for $CONTAINER_NAME"
        
        # 선택적: 관리자에게 이메일 발송
        # mail -s "Docker Log Alert" admin@example.com <<< "Container $CONTAINER_NAME log size exceeds threshold"
    else
        echo "[$CURRENT_TIME] Log size ($LOG_SIZE lines) is normal for $CONTAINER_NAME"
    fi
    
    # 1초 대기
    sleep 1
done

2.3.2 실습용 로그 생성 컨테이너 생성

# 로그를 지속적으로 생성하는 테스트용 Dockerfile
cat > Dockerfile << 'EOF'
FROM ubuntu:20.04

RUN apt-get update && apt-get install -y stress

CMD while true; do date; echo "Test log message"; sleep 1; done
EOF

# 이미지 빌드
docker build -t log-generator .

# 컨테이너 실행
docker run -d --name log-test1 log-generator

2.3.3 모니터링 실행 및 테스트

# 모니터링 스크립트 실행
./monitor-logs.sh log-test1

# 별도 터미널에서 로그 확인
docker logs -f log-test1

2.3.4 모니터링 설정 (확장편)

#!/bin/bash

CONTAINER_NAME=$1
THRESHOLD=1000
LOG_FILE="container_logs.txt"
ALERT_EMAIL="admin@example.com"

monitor_logs() {
    LOG_SIZE=$(docker logs $CONTAINER_NAME 2>&1 | wc -l)
    CURRENT_TIME=$(date "+%Y-%m-%d %H:%M:%S")
    DISK_USAGE=$(docker inspect $CONTAINER_NAME --format='{{.LogPath}}' | xargs du -h 2>/dev/null | cut -f1)
    
    echo "[$CURRENT_TIME] Container: $CONTAINER_NAME" >> $LOG_FILE
    echo "Log lines: $LOG_SIZE" >> $LOG_FILE
    echo "Disk usage: $DISK_USAGE" >> $LOG_FILE
    
    if [ $LOG_SIZE -gt $THRESHOLD ]; then
        MESSAGE="Warning: Container $CONTAINER_NAME has exceeded log threshold
        Current size: $LOG_SIZE lines
        Disk usage: $DISK_USAGE
        Time: $CURRENT_TIME"
        
        echo "$MESSAGE" >> $LOG_FILE
        echo "$MESSAGE" | mail -s "Docker Log Alert" $ALERT_EMAIL
        
        # 로그 백업 및 클리어
        docker logs $CONTAINER_NAME > "${CONTAINER_NAME}_logs_${CURRENT_TIME}.txt"
        docker container restart $CONTAINER_NAME
    fi
}

# 메인 모니터링 루프
while true; do
    if docker ps | grep -q $CONTAINER_NAME; then
        monitor_logs
    else
        echo "[$CURRENT_TIME] Container $CONTAINER_NAME is not running!" >> $LOG_FILE
    fi
    sleep 60
done
  • 로그용 Dockerfile 및 로그 생성 스크립트 작성
# 로그 생성용 Dockerfile 생성
cat > Dockerfile << 'EOF'
FROM ubuntu:20.04

# 스트레스 테스트 도구 설치
RUN apt-get update && apt-get install -y stress

# 로그 생성 스크립트
COPY generate-logs.sh /
RUN chmod +x /generate-logs.sh

CMD ["/generate-logs.sh"]
EOF

# 로그 생성 스크립트 작성
cat > generate-logs.sh << 'EOF'
#!/bin/bash

while true; do
    date
    echo "Application log: Process running"
    echo "System status: OK"
    echo "Memory usage: $(free -m | grep Mem | awk '{print $3}') MB"
    sleep 1
done
EOF

# 이미지 빌드
docker build -t log-generator .

# 컨테이너 실행
docker run -d --name test-container log-generator
  • 모니터링 실행 및 테스트
# 터미널 1: 모니터링 스크립트 실행
sh advanced-monitor-logs.sh test-container

# 터미널 2: 로그 생성 테스트
docker exec -it test-container bash -c 'for i in {1..1500}; do echo "Test log entry $i"; done'
  • 로그 확인 및 분석
# 모니터링 로그 확인
cat container_logs.txt

# 컨테이너 로그 확인
docker logs test-container

 

3. Docker 디스크 사용량 모니터링 실습

3.1 기본 디스크 사용량 모니터링

# Docker 전체 디스크 사용량 확인
docker system df

# 상세한 디스크 사용량 확인
docker system df -v

# 실시간 디스크 사용량 모니터링 스크립트 생성
cat > monitor-disk-usage.sh << 'EOF'
#!/bin/bash

while true; do
    echo "=== Docker 디스크 사용량 모니터링 === ($(date))"
    echo "1. 컨테이너 디스크 사용량:"
    docker ps --size --format "table {{.Names}}\\t{{.Size}}\\t{{.State}}"
    
    echo -e "\\n2. 이미지 디스크 사용량:"
    docker system df -v | grep "Images space"
    
    echo -e "\\n3. 볼륨 디스크 사용량:"
    docker system df -v | grep "Volumes space"
    
    echo -e "\\n4. 빌드 캐시 사용량:"
    docker system df -v | grep "Build cache"
    echo "======================================="
    sleep 60
done
EOF

chmod +x monitor-disk-usage.sh

3.2 테스트용 컨테이너 생성 및 모니터링

# 테스트용 컨테이너 생성
docker run -d --name disk-test-1 ubuntu:20.04 tail -f /dev/null
docker run -d --name disk-test-2 nginx

# 데이터 생성 스크립트
cat > generate-data.sh << 'EOF'
#!/bin/bash

for i in {1..10}; do
    echo "Generating data file $i..."
    docker exec disk-test-1 dd if=/dev/zero of=/tmp/file$i bs=1M count=100
    sleep 1
done
EOF

chmod +x generate-data.sh

3.3 디스크 모니터링 스크립트 작성

cat > advanced-disk-monitor.sh << 'EOF'
#!/bin/bash

LOG_FILE="disk_usage_log.txt"
THRESHOLD_PERCENT=80
ALERT_EMAIL="admin@example.com"

log_message() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}

get_container_sizes() {
    docker ps -s --format "{{.Names}}: {{.Size}}" | while read line; do
        log_message "Container $line"
    done
}

check_disk_usage() {
    # Docker 루트 디렉토리 사용량 확인
    DOCKER_ROOT=$(docker info | grep "Docker Root Dir" | cut -d: -f2 | tr -d ' ')
    USAGE_PERCENT=$(df -h $DOCKER_ROOT | awk 'NR==2 {print $5}' | tr -d '%')
    
    log_message "Docker root directory ($DOCKER_ROOT) usage: ${USAGE_PERCENT}%"
    
    if [ $USAGE_PERCENT -gt $THRESHOLD_PERCENT ]; then
        MESSAGE="Warning: Docker disk usage is at ${USAGE_PERCENT}%"
        log_message "$MESSAGE"
        
        # 가장 큰 컨테이너 5개 리스트
        log_message "Top 5 largest containers:"
        docker ps -s --format "{{.Size}}\\t{{.Names}}" | sort -hr | head -n 5 | \\
            while read line; do
                log_message "$line"
            done
        
        # 사용하지 않는 리소스 정리 추천
        log_message "Recommended cleanup commands:"
        log_message "docker system prune -f"
        log_message "docker volume prune -f"
        log_message "docker image prune -a -f"
    fi
}

monitor_volumes() {
    log_message "Volume usage:"
    docker volume ls -q | while read vol; do
        USAGE=$(docker run --rm -v $vol:/vol alpine du -sh /vol)
        log_message "Volume $vol: $USAGE"
    done
}

# 메인 모니터링 루프
while true; do
    log_message "=== Starting disk usage check ==="
    check_disk_usage
    get_container_sizes
    monitor_volumes
    log_message "=== Completed disk usage check ==="
    echo -e "\\n"
    sleep 300  # 5분 간격으로 체크
done
EOF

chmod +x advanced-disk-monitor.sh

3.4 실습 시나리오

3.4.1 모니터링 시작

# 터미널 1: 기본 모니터링 실행
./monitor-disk-usage.sh

# 터미널 2: 데이터 생성
./generate-data.sh

3.4.2 모니터링 테스트

# 터미널 1: 고급 모니터링 실행
./advanced-disk-monitor.sh

# 터미널 2: 대용량 파일 생성
docker run -d --name big-data-test ubuntu:20.04 tail -f /dev/null
docker exec big-data-test dd if=/dev/zero of=/bigfile bs=1G count=2

3.4.3 디스크 정리

# 사용하지 않는 리소스 정리
docker system prune -f

# 사용하지 않는 볼륨 정리
docker volume prune -f

# 사용하지 않는 이미지 정리
docker image prune -a -f

# 정리 후 사용량 확인
docker system df -v

3.4.4 컨테이너 별 상세 모니터링

# 컨테이너별 디스크 사용량 모니터링 스크립트
cat > container-disk-monitor.sh << 'EOF'
#!/bin/bash

echo "=== Container Disk Usage Details ==="
docker ps --format "{{.Names}}" | while read container; do
    echo "Container: $container"
    echo "Size details:"
    docker ps -s --filter "name=$container" --format "Virtual Size: {{.Size}}"
    echo "Top 5 largest directories:"
    docker exec $container du -h / 2>/dev/null | sort -hr | head -n 5
    echo "------------------------"
done
EOF

chmod +x container-disk-monitor.sh
./container-disk-monitor.sh
LIST

Claude Code나 GPT-5 Codex를 매일 쓰는 개발자라면 한 번쯤 마주치는 역설이 있다.
같은 프롬프트를 두 번 넣으면 다른 코드가 나온다. 어떤 때는 Python 함수가 한 줄짜리 list comprehension으로 나오고, 다음엔 for 루프 세 줄로 나온다. 변수명이 다르고, 주석 표현이 다르고, 예외 처리 순서까지 바뀐다. 결정적(deterministic)이지 않다. 학부 시절 우리가 "좋은 소프트웨어"의 필수 조건으로 배운 바로 그 속성이 깨진다.
그런데 막상 빌드는 성공한다. 테스트는 통과한다. 종종 사람보다 낫다. 2026년 현재 "시니어 엔지니어 대부분이 실제 코드는 거의 쓰지 않는다"는 보고가 나온다. 이 사람들이 순진한 것도, 품질을 포기한 것도 아니다. 오히려 그 반대다 — 프로덕션 배포되는 코드의 양은 늘었는데 사람이 직접 타이핑한 비율은 줄었다.
이 역설이 이 글의 출발점이다. 주사위를 굴려 나온 코드가 왜 빌드에 성공하는가. 그리고 우리는 그 사실을 어떻게 받아들여야 하는가.


1. 먼저 — LLM 비결정성의 구조

이 논의를 하려면 비결정성이 어디서 오는지부터 정확히 써야 한다.
LLM은 다음 토큰을 확률 분포로 예측한다. 어휘에 있는 모든 토큰마다 "이 자리에 이 토큰이 올 확률"이 매겨진다. 생성 단계에서 모델은 이 분포에서 하나를 샘플링한다. 이 샘플링 과정에 세 종류의 무작위성이 개입한다.

  • Temperature: 분포를 평평하게 할지 뾰족하게 할지 결정하는 스칼라. T=0이면 가장 확률 높은 토큰만 뽑고, T가 높아질수록 덜 확률 높은 토큰에도 기회가 간다.
  • Top-k / Top-p 샘플링: 후보를 상위 k개 또는 누적 확률 p까지로 제한.
  • Random seed: 같은 분포에서도 난수 시드가 다르면 다른 토큰이 뽑힌다.

"온도 0으로 하면 결정적이지 않나?"라는 질문이 자주 나온다. 답은 '아니오'다. 2024년 ACM Transactions on Software Engineering and Methodology에 실린 실증 연구는 ChatGPT의 코드 생성 비결정성을 829개 과제에 대해 측정했는데, 기본 설정에서는 같은 프롬프트에 대해 "모든 요청이 동일한 테스트 출력을 내는 과제 비율"이 CodeContests에서 24.24%, APPS에서 49%, HumanEval에서 52.44%에 불과했다. 온도를 0으로 내려도 비결정성은 줄어들지만 완전히 사라지지 않았다.
그 이유는 여러 층에 있다. GPU 병렬 연산의 부동소수점 누적 순서, batching에서의 다른 요청과의 상호작용, 모델 서빙 인프라의 라우팅 비결정성 등. 결국 LLM은 구조적으로 비결정적이고, 이는 "설정으로 끌 수 있는 버그"가 아니라 시스템의 본질적 속성이다.


2. 그런데도 빌드는 성공한다 — 두 번째 역설

여기가 흥미로워지는 지점이다. LLM이 비결정적이라는 사실은 10년 전이라면 "소프트웨어 엔지니어링 도구로는 실격"이라는 결론으로 가야 했다. 그런데 2026년 현실은 반대다.

  • Rakuten은 Opus 4.1로 오픈소스 프로젝트를 7시간 자율 리팩터링, 코드 품질 30% 개선.
  • Anthropic 내부 팀은 Claude Code로 PR 처리 속도 3배 개선.
  • 시니어 엔지니어들이 "코드의 100%는 AI가 쓰고, 내가 쓴 건 0%다"라고 말하고 있다.

"비결정적 생성"과 "프로덕션 품질"이 어떻게 공존 가능한가. 이게 이 글이 파고들 질문이다.


3. 해답의 첫 번째 층 — 분포가 충분히 뾰족하면 된다

가장 먼저 짚어야 할 지점은 "비결정적"과 "무작위"가 다르다는 것이다.
온도 0.7의 LLM이 def factorial(n): 다음에 생성할 토큰을 상상해보자. 확률 분포를 보면 \n if n 같은 토큰 시퀀스의 확률이 압도적으로 높고, 그 외의 선택지들은 사실상 0에 가깝다. 분포가 뾰족하다(peaked). 이런 경우 샘플링을 10번 해도 거의 매번 같은 토큰이 뽑힌다. 겉보기에 "결정적으로 보이는 비결정성"이다.
이 관찰을 실증적으로 확인한 것이 2024년의 AdapT Sampling 연구다. 연구자들은 코드 토큰을 "도전적 토큰(challenging tokens)"과 "자신 있는 토큰(confident tokens)" 으로 분류했다. 자신 있는 토큰은 분포가 뾰족해서 어떤 온도를 써도 같은 것이 뽑힌다. 도전적 토큰은 분포가 상대적으로 평평해서 실제로 다른 선택이 나온다.
흥미로운 발견은 도전적 토큰은 코드 블록의 첫 번째 위치에 집중적으로 나타난다는 것. 파이썬에서 이는 79.8%(HumanEval), 83.4%(MBPP), 82.5%(APPS)의 예측 난도를 보였다. 즉 LLM이 고민하는 지점은 "어떤 제어 구조를 쓸 것인가"(if/for/while/try)와 같은 구조 결정 순간이고, 그 이후의 토큰들은 상당히 결정론적으로 이어진다.
코드의 많은 부분이 "주사위"가 아니라 "자석"이다. 분포가 충분히 뾰족해서 샘플링해도 같은 결과로 끌려간다. 이게 첫 번째 해답이다.


4. 해답의 두 번째 층 — 원래 결정적이었던 적 없다

Paul Bernard의 2026년 2월 Medium 에세이 "Your Code Was Never Deterministic"이 찌르는 지점이 이것이다.
그는 이렇게 쓴다. 우리가 "결정적 코드"라고 부르던 것의 실체를 보자. 컴파일러는 결정적이다. 같은 소스 코드를 두 번 컴파일하면 같은 바이너리가 나온다. 맞다. 그런데 "같은 소스 코드"가 과연 결정적으로 쓰여졌는가는 다른 문제다.
10명의 시니어 개발자에게 "이 요구사항을 코드로 옮겨 주세요"라고 똑같이 말해보자. 10개의 다른 구현이 나온다. 변수명, 함수 분리 방식, 에러 처리 전략, 성능과 가독성의 트레이드오프 선택. 이 모든 것이 사람의 비결정성이다. 그런데 우리는 이걸 "비결정성"이라고 부르지 않았다. "스타일"이라고 불렀다.
더 중요한 지점. 우리가 실제 프로덕션에서 겪는 대부분의 장애는 컴파일러가 주사위를 굴려서 생긴 것이 아니라, 사람이 불완전한 의도를 코드로 옮기면서 생긴 것이다. 요구사항을 오해했거나, 엣지 케이스를 놓쳤거나, 동시성 가정을 틀리게 했거나.
Bernard의 핵심 통찰은 이것이다. "LLM은 비결정적이니까 믿을 수 없다"고 말할 때, 우리는 이전에 도대체 무엇을 믿고 있었는가? 테스트 커버리지를 믿고 있었나? 대부분 시스템에서 실질적 커버리지는 30~50% 수준이다. 코드 리뷰를 믿고 있었나? 진지한 리뷰와 LGTM 스탬프를 구분해야 한다. 우리가 믿었던 건 "코드가 동일 입력에 동일 출력을 낸다"는 컴파일러의 충실함이지, "코드가 올바르다" 는 보장이 아니었다.
그런데 컴파일러의 충실함은 LLM 코드에도 적용된다. LLM이 생성한 코드도 컴파일러가 결정적으로 처리한다. 같은 테스트를 돌리면 같은 결과가 나온다. 생성 단계는 비결정적이지만, 생성된 결과물은 여전히 결정적으로 검증 가능하다.
이것이 두 번째 해답이다. 비결정성의 위치가 "실행 시점"에서 "생성 시점"으로 이동했을 뿐이고, 우리는 둘 중 후자를 훨씬 잘 다룰 수 있다.


5. 해답의 세 번째 층 — 검증이 생성을 잡는다

가장 근본적인 해답은 여기 있다. 현대 AI 코딩 워크플로우는 "생성-검증 루프"로 설계되어 있다.
Claude Code, GPT-5 Codex, Cursor가 작동하는 방식을 생각해보자.

  1. 모델이 코드를 생성한다 (비결정적).
  2. 그 코드가 컴파일된다 (결정적).
  3. 타입 체커가 돌아간다 (결정적).
  4. 린터가 돈다 (결정적).
  5. 테스트 스위트가 실행된다 (결정적).
  6. 실패가 있으면 그 정보가 다시 모델에 피드백된다.
  7. 모델이 수정한 코드를 재생성한다 (비결정적).
  8. 루프가 수렴할 때까지 반복.

이 루프에서 비결정성의 역할은 "탐색(exploration)"이다. 모델이 여러 후보 구현을 시도해볼 수 있게 해주는 도구. 결정적(T=0) 모델은 한 번 막히면 계속 같은 곳에서 막힌다. 비결정적 모델은 같은 프롬프트에서 다른 경로를 시도해볼 수 있고, 그중 하나가 검증을 통과하면 그게 답이다.
이 구조가 진화적 알고리즘과 비슷하다는 점에 주목할 필요가 있다. 유전 알고리즘은 무작위 변이와 결정적 선택을 조합해서 해를 찾는다. 변이 단계는 비결정적이어야 한다 — 그래야 새로운 해공간을 탐색할 수 있다. 선택 단계는 결정적이어야 한다 — 그래야 나쁜 해가 걸러진다.
Claude Code 같은 에이전틱 코딩 도구는 정확히 이 구조다. 모델은 변이를 만들고, 테스트와 타입 시스템이 선택을 한다. 최종 산출물의 품질은 모델의 비결정성이 아니라 검증 시스템의 엄격함에 의해 결정된다.
이 관점으로 보면 우리가 AI 시대에 개발 인프라에 투자해야 할 것이 바뀐다. "모델을 더 정확하게 만드는 것"보다 "검증을 더 촘촘하게 만드는 것" 이 레버가 된다.


6. 한 층 더 — 명세는 변하지 않는다

Bernard의 에세이가 말하는 더 깊은 층이 있다. "명세"의 역할.
AI 코딩 파이프라인에서 개발자가 하는 일은 무엇인가. 명세를 쓴다. 자연어로, 구조화된 acceptance criteria로, property-based test로, 실행 가능한 스펙으로. 이걸 LLM이 구현으로 옮긴다. 구현은 run마다 다를 수 있다. 하지만 명세는 다르지 않다.
검증 인프라가 명세 층에 anchoring되어 있으면, 구현의 변동성은 더 이상 무서운 것이 아니다. 내부 구현 디테일일 뿐이다. 레지스터 할당이나 분기 예측처럼, 한 추상화 층 위로 올라갔을 때 보이지 않게 되는 종류의 디테일.
이 비유는 정확하다. 1970년대 개발자는 어셈블리로 레지스터 할당을 직접 했다. C 컴파일러가 등장하면서 레지스터 할당은 컴파일러가 상황에 따라 다르게 하는 내부 디테일이 됐다. 개발자는 더 이상 레지스터를 보지 않는다. 레지스터 할당의 "비결정성"(컴파일러 버전에 따라, 최적화 플래그에 따라 다른 결과)은 문제가 되지 않는다. 왜냐하면 C 명세가 그대로 유지되기 때문이다.
AI 코딩이 만드는 추상화의 도약도 같은 구조다. 개발자가 명세를 쓰고, 구현은 AI가 매번 다르게 할 수 있다. 명세 층에서 검증만 제대로 되면 구현의 변동은 무관한 내부 디테일이 된다.
이 틀에서 보면 "AI가 쓴 코드를 한 줄 한 줄 리뷰해야 한다"는 주장은 1970년대 C 개발자에게 "레지스터 할당을 한 줄 한 줄 리뷰해야 한다"고 말하는 것과 같다. 아래 층위에서의 결정을 위 층위에서 감시하려는 시도. 추상화의 이점을 스스로 포기하는 것.


7. 반론과 그 반론에 대한 반박

여기까지 읽은 독자의 머릿속에 떠오르는 반론들이 있을 것이다. 하나씩 다룬다.

반론 1: "테스트 코드도 코드다. 그걸 누가 검증하나?"

맞다. 그런데 비대칭이 존재한다. 명세는 프로덕션 코드보다 훨씬 짧고, 훨씬 선언적이며, 훨씬 변경이 드물다. 10,000줄의 구현을 생성하기 위한 명세는 200줄일 수 있다. 200줄은 사람이 리뷰할 수 있다. Property-based test로 쓰면 더 짧아진다. 리뷰해야 할 표면적 자체가 50배 줄어든다.

반론 2: "LLM이 테스트도 같이 생성한다. 같이 틀릴 수 있다."

타당한 지적이다. 하지만 해결책은 있다. 테스트와 구현을 다른 세션에서, 다른 모델로, 다른 프롬프트로 생성하는 것. 한 Claude가 테스트를 쓰고, 다른 Claude가 그 테스트를 통과하는 구현을 쓴다. 두 인스턴스가 공통으로 틀리려면 훨씬 정교한 체계적 오류가 필요하다. 이는 다수 인스턴스 합의(N-of-M consensus)와 구조적으로 같다.

반론 3: "미세한 엣지 케이스는 테스트로 못 잡는다."

사실이다. 하지만 이건 AI 시대 이전에도 사실이었다. 사람이 쓴 코드도 엣지 케이스에서 터진다. 오히려 AI는 알려진 엣지 케이스 패턴에 대한 기억이 사람보다 넓다. HackerNews의 C++/Qt 프로젝트 사례에서 Claude Code가 20분에 해결한 UI 버그는 숙련된 사람이 2시간 걸린 것이었다. 엣지 케이스 커버리지에서 AI가 사람보다 낫다는 증거가 이미 쌓이고 있다.

반론 4: "생성 루프가 무한히 돌 수 있다."

구조적 문제가 있을 때 그렇다. 해결은 타임아웃과 예산 설정, 그리고 "실패 시 사람에게 에스컬레이션"이다. 이는 마이크로서비스에서 circuit breaker가 하는 역할과 같다. 무한 루프는 아키텍처 결함이지 AI 코딩의 본질이 아니다.

반론 5: "그래도 나는 한 줄씩 읽어야 마음이 놓인다."

그건 정서의 문제지 엔지니어링의 문제가 아니다. 공감은 한다. 나도 처음에 Claude Code가 쓴 PR을 마우스로 한 줄씩 긁으며 읽었다. 그런데 그 시간이 실제로 버그를 잡았는가? 대부분은 아니었다. 마음이 편해지는 효과는 있었지만, 품질 보장 효과는 테스트와 타입 시스템이 이미 다 하고 있었다. 불안은 대체 가능한 의식이지, 대체 불가능한 검증이 아니다.


8. 실무자의 관점 — 이 통찰을 어떻게 써야 하나

이론을 썼으니 실무로 내려간다. 이 통찰이 2026년 개발자의 하루하루에 어떻게 적용되는가.

8.1 투자 우선순위를 다시 짜라

"좋은 AI 코딩 환경"의 조건이 바뀌었다.

  • 빠른 타입 체커 (rustc, tsc, mypy)
  • 빠른 테스트 러너 (pytest-xdist, jest parallel, cargo nextest)
  • 엄격한 린터 (ruff, eslint, clippy)
  • Property-based testing 프레임워크 (hypothesis, fast-check, proptest)
  • 계약 기반 테스트 (contract testing, consumer-driven contracts)

이 인프라가 허약한 프로젝트에서는 AI 코딩의 ROI가 낮다. 강한 프로젝트에서는 ROI가 폭발적이다. "검증 인프라에 투자한 프로젝트가 AI 시대의 수혜를 독점한다."

8.2 명세 쓰기가 핵심 역량이 된다

개발자의 시간 배분이 바뀐다.

  • 과거: 70% 구현, 20% 설계, 10% 테스트
  • AI 시대: 20% 명세 작성, 30% 검증 설계, 30% 리뷰·디버깅, 20% 통합

이 변화를 빨리 받아들이는 개발자일수록 경쟁력이 크다. "타이핑 속도가 더 이상 개발 속도와 상관없다." 대신 "명확한 명세를 언어로 옮기는 능력"이 중요해진다.

8.3 Writer/Reviewer 패턴을 기본 워크플로우로

지금 가장 효과적인 AI 코딩 방법론 중 하나는 두 개의 모델 인스턴스를 병렬 운영하는 것이다.

  • Writer: 구현을 생성하는 역할. 빠르고 공격적으로.
  • Reviewer: 별도 세션에서 구현을 평가하는 역할. 의심 많고 보수적으로.
  • Human: 두 결과를 보고 최종 판단.

Claude Code와 GPT-5 Codex를 병렬로 돌리며 서로를 교차 검증하게 하는 기법은 2026년 현재 시니어 엔지니어들 사이에서 표준이 되어가는 중이다. 한 모델의 비결정성을 다른 모델의 비결정성으로 상쇄시키는 설계.

8.4 명세 자체를 재사용 자산으로

한 번 잘 쓴 명세는 모델이 바뀌어도, 언어가 바뀌어도, 프레임워크가 바뀌어도 재사용 가능하다. Ruby on Rails로 구현한 명세를 Spring Boot로 다시 구현하는 것이, 명세가 있을 때는 AI에게 일이고 없을 때는 사람에게 대공사다.


9. 한 걸음 물러서서 — 추상화의 역사에 놓기

이 모든 변화가 어디에 놓이는지 역사적 관점으로 보면 선명해진다.
소프트웨어 역사에서 추상화는 한 방향으로만 올라왔다.

  • 기계어 → 어셈블리: 니모닉과 레이블의 도입.
  • 어셈블리 → C: 레지스터, 스택, 메모리 할당을 컴파일러에 맡김.
  • C → Java/Python: 수동 메모리 관리를 GC에 맡김.
  • Java/Python → 프레임워크: HTTP 파싱, ORM, 의존성 주입을 프레임워크에 맡김.
  • 프레임워크 → 서비스: 인증, 결제, 검색을 외부 서비스에 맡김.

각 단계에서 아래 층의 "결정"들이 비가시적이 됐다. 그 비가시성은 처음엔 두려운 것이었다. "GC가 언제 돌지 모르는데 어떻게 실시간 시스템을 짜냐" "ORM이 어떤 SQL을 쏠지 모르는데 어떻게 성능을 보장하냐." 이런 질문들이 그 시대의 엔지니어들을 실제로 밤잠 못 이루게 했다.
답은 매번 같았다. 한 층 위에서 추상화를 붙들면 아래 층의 비결정성은 관리 가능한 내부 디테일이 된다. GC의 동작은 JVM 튜닝 파라미터로 관리되고, ORM의 쿼리는 모니터링으로 잡히고, 서비스의 장애는 circuit breaker로 격리된다.
2026년 AI 코딩도 같은 위치에 있다. 개발자가 명세를 쓰고, 구현의 비결정성은 검증 층에서 흡수된다. 처음에는 두렵지만, 한 세대 지나면 "이 레벨에서 왜 걱정했지?"라고 돌이켜볼 추상화 층이 된다.


10. 마무리 — 주사위는 구르고, 빌드는 선다

글의 처음으로 돌아간다. 주사위를 굴려 나온 코드가 왜 빌드에 성공하는가.
세 층의 답을 정리하면.
첫 번째 층: 분포가 뾰족해서 대부분의 토큰은 사실상 결정적이다. "비결정적"이라는 꼬리표가 주는 인상만큼 혼란스럽지 않다.
두 번째 층: 우리가 "결정적 코드"라고 불렀던 것들도 인간의 비결정성 위에 서 있었다. 위치만 바뀐 것이지 전에 없던 성질이 생긴 것이 아니다.
세 번째 층: 현대 AI 코딩은 비결정적 생성과 결정적 검증의 루프로 설계된다. 생성의 변동성은 탐색의 도구이고, 품질은 검증의 엄격함에서 온다.
이 셋을 합쳐 보면 역설은 역설이 아니다. 비결정성은 문제가 아니라 구조다. 그리고 그 구조 위에서 잘 작동하는 개발 인프라를 가진 팀이 2026년의 승자가 될 것이다.
Paul Bernard가 에세이 끝에 던진 질문을 조금 바꿔 다시 쓴다.

LLM이 비결정적이라서 쓸 수 없다고 말하기 전에, 우리는 이전에 무엇을 믿고 있었는지 먼저 물어야 한다. 우리의 테스트? 우리의 리뷰? 우리의 직감? 그중 무엇도 "결정적"이지 않았다. 우리가 진짜로 믿었던 건 단 하나, 검증 가능한 명세를 세우는 우리의 능력이었다. 그 능력은 AI 시대에도 그대로 우리 것이고, 오히려 레버가 훨씬 길어진다.

주사위는 계속 구른다. 그런데 빌드는 선다. 그 사실이 우리에게 말하는 것은 이것이다. 우리는 이미 답을 알고 있었다. 답의 위치가 바뀌었을 뿐이다.


참고 자료

LIST

 

 

1.

프로그래밍 방식 트랜잭션 정리

프로그래밍 방식 트랜잭션 관리는 다음과 같은 경우에 유리합니다.

  • 세밀한 제어가 필요한 경우:
  • 복잡한 비즈니스 로직이나 특정 조건에 따라 트랜잭션의 경계를 유연하게 제어해야 할 때.
  • 예외 처리 로직 구현:
  • 일부 로직만 롤백하거나, 특정 예외 발생 시 다른 보상 로직을 추가로 구현할 때 유용합니다.

 

@Transactional 어노테이션은 여러 속성을 지원합니

  • propagation: 트랜잭션 전파 규칙을 설정합니다. (예: REQUIRED, REQUIRES_NEW 등)
  • isolation: 트랜잭션 격리 수준을 설정합니다.
  • readOnly: 읽기 전용 트랜잭션으로 최적화할 수 있습니다.
  • rollbackFor: 롤백 대상으로 처리할 예외를 지정할 수 있습니다.

 

2. 동시성 문제 개념 및 사례 분석

 

이번 학습에서는 동시성 문제의 개념과 필요성을 이해하며, 데이터 정합성이 깨질 수 있는 다양한 상황과 실무에서 발생할 수 있는 문제를 다룹니다. 이를 위해 주문 처리나 재고 관리 시스템과 같은 사례를 통해 동시성 문제가 실제로 어떤 영향을 미치는지 살펴보고, Dirty Read, Non-Repeatable Read, Phantom Read, Lost Update와 같은 대표적인 동시성 문제의 동작 원리와 발생 조건을 학습합니다.

트랜잭션 격리 수준은 데이터 정합성시스템 성능 사이의 트레이드오프(Trade-off) 관계에 있습니다.

  • 대부분의 애플리케이션: Read Committed 수준으로 충분합니다. 데이터 부정합 문제의 가장 큰 원인인 Dirty Read를 막아주면서 좋은 성능을 보장합니다.
  • 데이터의 일관성이 중요한 경우: 하나의 트랜잭션 내에서 조회한 값이 변하지 않아야 한다면 Repeatable Read를 고려할 수 있습니다.
  • 극도의 정합성이 요구되는 경우: 동시성 저하를 감수하고서라도 데이터 불일치가 절대로 발생해서는 안 되는 시스템이라면 Serializable을 사용해야 합니다.

MySQL 격리 수준 변경

MySQL에서 트랜잭션 격리 수준을 설정하여 트랜잭션 간의 동작 방식을 제어할 수 있습니다. 격리 수준은 데이터베이스 전체(Global) 또는 특정 세션(Session)에 대해 설정 가능합니다.

 

 Dirty Read

READ UNCOMMITTED

격리 수준에서 발생하는 심각한 데이터 부정합 문제입니다. 이 문제를 해결하기 위해서는 최소

READ COMMITTED

이상의 격리 수준을 사용해야 합니다

 

 

이번 학습에서는 트랜잭션 격리 수준의 개념과 종류를 이해하고, 이를 활용해 동시성 문제를 해결하는 방법을 배웁니다. 먼저 트랜잭션의 ACID 원칙을 복습하며, 격리 수준이 데이터 정합성과 시스템 성능에 미치는 영향을 살펴봅니다.

Read Uncommitted,Read Committed,Repeatable Read,Serializable

등 네 가지 격리 수준의 특징과 동작 방식을 학습하며, 각각이 Dirty Read, Non-Repeatable Read, Phantom Read와 같은 동시성 문제에 어떤 영향을 미치는지 분석합니다. 이를 바탕으로 적절한 격리 수준을 설정해 동시성 문제를 해결하는 방법을 익히고, MySQL 실습을 통해 각 격리 수준에서 발생하는 문제를 재현하고 해결 과정을 경험함으로써 데이터 정합성을 유지하는 실질적인 기술을 습득합니다.

 

 

4. DB 락 메커니즘 이해와 실습

이번 학습에서는 데이터베이스 락의 개념과 이를 활용해 데이터 충돌을 방지하는 방법을 배웁니다. 비관적 락(Pessimistic Lock)은 데이터를 선점해 충돌을 방지하는 방식이며, 낙관적 락(Optimistic Lock)은 충돌이 발생했을 때 버전 검사를 통해 문제를 해결합니다. 두 방식의 차이와 활용 사례를 살펴보고, Shared Lock과 Exclusive Lock, 테이블 레벨 락과 행(Row) 레벨 락의 특징을 통해 락의 다양한 종류를 이해합니다. 또한, 비관적 락을 활용한 재고 관리와 낙관적 락을 이용한 데이터 충돌 방지 실습을 통해 락을 효과적으로 적용하는 방법을 익힙니다.

 

. 비관적 잠금(Pessimistic Locking)

  • 데이터를 업데이트하기 전에 해당 행을 잠금(Lock) 처리하여 다른 트랜잭션이 접근하지 못하도록 합니다.

비관적 락은 여러 사용자가 동시에 동일한 데이터를 수정하려고 시도할 때 데이터 정합성을 유지하는 데 적합합니다.

 

. 낙관적 잠금(Optimistic Locking)

  • 데이터에 version 필드를 추가하고, 업데이트 시 조건으로 사용합니다.
  • 트랜잭션이 변경한 데이터가 다른 트랜잭션에 의해 변경되었는지 확인하고, 충돌 시 롤백 처리합니다.

데이터를 읽을 때는 락을 사용하지 않으며, 데이터를 수정할 때 버전 번호를 통해 충돌 여부를 판단합니다.

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Lock;

import jakarta.persistence.LockModeType;

public interface ProductRepository extends JpaRepository<Product, Long> {

  @Lock(LockModeType.PESSIMISTIC_WRITE)
  @Query("SELECT p FROM Product p WHERE p.id = :id")
  Optional<Product> findByIdForUpdate(@Param("id") Long id);

  @Lock(LockModeType.PESSIMISTIC_WRITE)
  Optional<Product> findFirstByName(String name);    
}

 

LIST

앞선 두 편에서 같은 결론에 도달했다. 웹스퀘어도, OZ Report도, Claude Code로 "기술적으로 비슷한 것"은 만들 수 있다. 그러나 실제 제품을 대체하는 길은 거의 닫혀 있다. 이유는 기술이 아니라 다른 층위에 있기 때문이다.
그 다른 층위가 정확히 무엇인지 이번 글에서 본격적으로 분해한다. 기술적 해자와 제도적 해자가 어떻게 다르게 작동하는가. 왜 한국  솔루션 시장은 글로벌 표준과 다른 방식으로 잠겨 있는가. 그리고 AI 시대에 이 구조는 어떻게 변하거나 유지될 것인가.
이 글은 두 가지 용도로 읽힐 수 있다. 첫째, 개발자가 자기 커리어의 판을 이해하는 지도. 둘째, 스타트업이나 해외 솔루션 진출 기획자가 한국 시장 진입 전략을 짜기 위한 분석.


1. "해자"라는 단어의 정확한 의미

워런 버핏이 대중화한 "economic moat"는 원래 중세 성 주변의 해자(垓字)에서 온 비유다. 성을 직접 공격하는 것보다 해자 때문에 접근 자체가 불가능해진다. 경제적 맥락에서도 같다. 경쟁자가 "제품 품질"로 싸우기 전에 "시장에 진입하는 것 자체"가 막혀 있는 구조가 해자다.
해자의 유형은 일반적으로 다섯 가지로 분류된다.

  1. 규모의 경제 — 크기가 커질수록 단위 비용이 내려감
  2. 네트워크 효과 — 사용자가 많아질수록 제품 가치가 올라감
  3. 전환 비용(Switching Cost) — 바꾸는 데 드는 돈·시간·리스크가 큼
  4. 무형 자산 — 브랜드, 특허, 규제 라이선스
  5. 비용 우위 — 독점적 자원 접근, 지리적 이점

한국 SI 솔루션의 해자는 이 중 3번 전환 비용과 **4번 무형 자산(특히 규제·관계)**에 압도적으로 치우쳐 있다. 그런데 이게 해외 엔터프라이즈 SaaS의 해자와 질적으로 다른 구조라는 점이 핵심이다.


2. 글로벌 SaaS의 해자 vs 한국 SI의 해자

2.1 글로벌 SaaS의 해자는 "기술 + 네트워크"

Salesforce, ServiceNow, Snowflake, Datadog 같은 글로벌 엔터프라이즈 SaaS의 해자는 주로 기술과 네트워크 효과 위에 서 있다.

  • 플랫폼 확장성: AppExchange, ServiceNow Store 같은 서드파티 마켓플레이스
  • 데이터 중력: 한 번 모인 데이터가 이동하기 어렵다는 물리적 제약
  • API 생태계: 수많은 통합(integration) 파트너가 제품 가치를 확장
  • 지속적 R&D 투자: 매출의 20~30%를 제품에 재투자하는 규모의 힘

이 해자는 측정 가능하고, 벤치마크 가능하며, 시간이 지나면 복제도 가능하다. 실제로 지난 10년간 수많은 "Salesforce 킬러"들이 등장해서 일부 영역을 뺏어갔다. 해자가 있지만 "공격받을 수 있는 해자"다.

2.2 한국  솔루션의 해자는 "제도 + 관계 + 도메인"

반면 한국 엔터프라이즈 소프트웨어의 해자는 다른 세 층으로 구성된다.
1층 — 제도적 해자 (Institutional Moat)

  • 정부·공공·금융 RFP의 레퍼런스 요구사항
  • 한국인터넷진흥원(KISA), 국가정보원, 금융감독원, 개인정보보호위원회의 규제·인증 체계
  • GS인증, CC인증, K-ISMS, ISMS-P 같은 국내 전용 인증
  • 조달청 나라장터 등록 자격
  • 전자금융거래법, 전자문서법, 개인정보보호법의 업계별 시행령

2층 — 관계적 해자 (Relational Moat)

  • 대형 SI(삼성SDS, LG CNS, SK C&C, 포스코DX, 현대오토에버)와 솔루션 벤더의 오랜 파트너십
  • 금융·공공 IT 기획 담당자와 벤더 영업의 10년 단위 네트워크
  • 장애 발생 시 한국어로 즉시 연결되는 기술지원 체계
  • 차세대 프로젝트 제안 참여 경험 자체가 다음 프로젝트의 자격 요건이 되는 구조

3층 — 도메인 해자 (Domain Moat)

  • 한국식 행정 양식 (직인 영역, 한글 금액 표기, 주민번호·사업자번호 마스킹 규칙)
  • 한국 금융권 특화 처리 (예수금 계산 규칙, 금리 적용 방식, 세무 원천징수)
  • 공공 업무 특화 워크플로우 (결재선, 감사 대응, 민원 응대)
  • 한국어 IME·폰트·검색 엣지 케이스 수만 가지
  • 20년간 프로젝트 장애 대응으로 축적된 암묵지

이 3층 해자가 서로를 강화한다는 점이 결정적이다. 제도가 관계를 만들고, 관계가 도메인 축적을 가능하게 하고, 도메인 축적이 다시 제도 대응의 근거가 된다. 이 사이클을 바깥에서 뚫고 들어가는 것은 거의 불가능에 가깝다.


3. 사례 분석 — 이 해자가 실제로 어떻게 작동하는가

3.1 티맥스소프트의 코어뱅킹 독주

2007년 국민은행 차세대 프로젝트 당시 디지털데일리 보도에 이미 핵심 구절이 나온다. "현재 코어뱅킹 솔루션 시장을 독주하고 있는 티맥스소프트와 경쟁할 코어뱅킹 솔루션업체는 딱히 없는 상황이다."
2026년 현재도 이 구조는 크게 달라지지 않았다. 시중은행의 차세대 프로젝트에 글로벌 코어뱅킹 솔루션(Temenos, FIS, Oracle FLEXCUBE)이 들어오려 해도 — 심지어 한국IBM이 Temenos를 가지고 복수 제안을 해도 — 최종 선정에서 국내 솔루션이 이기는 일이 반복된다.
이 구조를 기술로 설명할 수 있을까? 어렵다. Temenos T24는 전 세계 150개국 이상의 은행에서 쓰이는 검증된 제품이다. 그런데도 한국 시중은행 코어뱅킹에서 이기지 못한다.
이유는 3층 해자가 모두 작동하기 때문이다.

  • 제도: 금융감독원 검사 대응, 전자금융거래법 해석, 한국은행 금통위 결정 반영 같은 국내 규제 대응이 필수.
  • 관계: 은행 IT 기획팀과 10년 넘게 쌓인 신뢰 네트워크.
  • 도메인: 한국 금융상품의 복잡성(적금·예금 해지 이자 계산, 주택청약저축 규정, 연금저축 세제 혜택) 전수 내장.

Claude Code로 코어뱅킹 시스템을 "만드는" 것은 기술적으로 가능하다. 그러나 위 3층을 뚫고 신한·국민·하나은행에 납품하는 것은 완전히 다른 게임이다.

3.2 인스웨이브 웹스퀘어의 지속성

웹스퀘어가 수년간 "곧 React로 대체될 것"이라는 예측을 듣고도 국내 금융·공공 UI 시장에서 지위를 유지하는 이유도 같은 구조다.

  • 제도: 웹 접근성 인증(KWCAG), 국가정보원 보안 적합성 검증 통과.
  • 관계: 대형 SI의 공통 컴포넌트로 자리 잡아 프로젝트 관리 표준화에 기여.
  • 도메인: 한글 IME 처리, 공인인증서 연동, 한국식 폼 검증 로직 전부 내장.

React는 기술적으로 우월할 수 있어도, 이 3층 중 어느 하나도 자동으로 해결해주지 않는다. 오히려 React로 프로젝트를 하면 위 3층을 각 SI 업체가 매번 새로 구축해야 한다. 그게 리스크다.

3.3 포시에스 OZ Report의 4천여 고객사

OZ Report 공식 자료에 따르면 "대법원, 행정안전부, 국토교통부 등 국내 주요 정부부처와 공공기관의 대국민 서비스는 물론 금융, 제조, 유통, 통신, 교육 등에서 4천여 개 이상의 고객사를 확보"했다.
이 숫자가 갖는 의미는 단순 시장 점유율이 아니다. 4천여 고객사 각각이 OZ Report 기반으로 수십~수백 개의 리포트 템플릿을 축적하고 있다. 한 번 쌓인 템플릿 자산은 솔루션을 바꾸는 순간 재작성해야 한다. 공공기관 한 곳에서만 수백 개, 전국 단위로는 수만 개다. 이 전환 비용이 해자의 거대한 폭을 만든다.


4. AI 시대의 해자 — 무엇이 흔들리고 무엇이 굳어지는가

이제 본격적인 질문. Claude Code, Cursor, Copilot 같은 AI 도구가 일반화된 2026년 이후, 이 3층 해자는 어떻게 변할까.

4.1 흔들리는 것 — 도메인 해자의 일부

세 층 중 가장 먼저 침식되는 쪽은 도메인 해자의 표층이다.
한국식 양식 구현, 한글 IME 엣지 케이스, 공인인증서 연동 같은 패턴은 이미 충분한 공개 정보가 축적되어 있다. Claude Code가 학습 데이터에서 이 패턴들을 상당 부분 내재화하고 있고, 앞으로 더 많이 흡수할 것이다.
그 결과:

  • "한국식 행정 양식을 지원하는 오픈소스 리포트 엔진"을 만드는 비용이 급격히 낮아진다.
  • "한글 IME를 올바르게 처리하는 Grid 컴포넌트"가 React 생태계에 빠르게 등장한다.
  • SI 업체가 차세대 프로젝트에서 상용 솔루션을 선택하지 않고 자체 구현 + AI 가속을 택할 여지가 확대된다.

즉, 표층의 도메인 지식은 공공재화된다.

4.2 흔들리지 않는 것 — 심층 도메인과 제도 해자

그러나 도메인 해자의 심층부는 흔들리지 않는다.

  • 특정 은행의 특정 금융상품이 30년 동안 겪은 법령 변경 이력
  • 공공기관 A의 민원 응대 워크플로우가 B에게는 없는 이유
  • 2018년 개인정보보호법 개정 시 각 산업이 대응한 패턴의 차이
  • 금융감독원 검사 지적 사항에 대한 업계별 대응 문서들

이 지식은 공개된 적이 없고 앞으로도 공개되지 않는다. 각 SI 업체의 프로젝트 방법론 문서, 솔루션 벤더의 대응 매뉴얼, 현업 담당자의 머릿속에만 있다. Claude Code가 학습할 데이터가 애초에 존재하지 않는다.
제도 해자는 더 확고해진다.

  • AI 시대에 규제 기관은 "AI로 만든 시스템의 검증"을 새로 요구할 것이다.
  • 그 새 규제를 최초로 통과시킨 벤더가 다음 10년의 시장을 잡는다.
  • 이는 AI 도구로 기술을 복제해도 시장에 진입할 수 없는 새로운 제도 해자의 등장이다.

4.3 강화되는 것 — 관계 해자의 역설적 확대

이게 가장 반직관적인 지점이다. AI가 기술을 상향 평준화할수록 관계 해자는 더 중요해진다.
이유는 간단하다. AI로 누구나 비슷한 수준의 기술 역량을 갖출 수 있으면, 구매자 입장에서 의사결정 기준은 "누구를 믿을 수 있는가" 로 이동한다. 제품이 대동소이하면 관계가 결정적 차이가 된다.
실제로 금융·공공 RFP에서 점점 더 많이 등장하는 조항들:

  • "해당 솔루션을 3년 이상 유지보수한 경험이 있는 파트너사"
  • "본 기관 유사 규모 프로젝트 수행 이력"
  • "솔루션 벤더의 국내 법인 및 24시간 기술지원 체계"

AI 시대에 기술 차별화가 어려워질수록 이런 조항의 무게가 커진다. 이것이 "관계 해자의 역설적 확대" 다.


5. 그래서 무엇을 해야 하는가 — 세 가지 포지셔닝 전략

이 해자 분석을 바탕으로 한국 SI 업계 개발자·기획자가 취할 수 있는 전략은 크게 세 가지다.

5.1 전략 A — "해자 안쪽"에서 AI 레버리지

기존 대형 SI나 솔루션 벤더에 속해 있다면, 가장 합리적인 포지셔닝은 3층 해자를 받침점으로 두고 AI를 지렛대로 삼는 것이다.

  • 제도·관계·심층 도메인은 회사가 20년간 쌓은 자산.
  • 자신은 그 자산 위에서 AI로 개발·운영 생산성을 2~5배 올린다.
  • 결과: 같은 자원으로 더 많은 프로젝트, 더 높은 마진.

이게 티맥스·인스웨이브·포시에스 같은 국내 벤더들이 자사 제품에 AI를 내장하는 이유다. 그리고 그 제품을 쓰는 SI 개발자 입장에서도, "AI를 활용해 같은 솔루션으로 더 빠르게 프로젝트를 종료시키는 사람" 이 가장 경쟁력 있다.

5.2 전략 B — "해자 주변부"에서 틈새 제품

솔루션 벤더가 직접 만들기엔 우선순위가 낮은 주변부 도구는 여전히 공백이 많다.

  • 웹스퀘어 XML → React JSX 마이그레이션 도구
  • OZ Report 템플릿 자동 생성기
  • JasperReports → 상용 리포트 툴 변환기
  • 특정 벤더 솔루션의 QA 자동화 SaaS
  • 차세대 프로젝트 RFP 자동 분석 도구

이 영역은 솔루션 벤더가 만들면 "자기 제품을 대체하는" 것이라 만들지 않고, 순수 오픈소스는 한국 도메인을 충분히 이해하지 못해서 만들기 어렵다. 그 사이의 작은 틈에 1~3인 팀이 만들 수 있는 B2B 도구들이 숨어 있다.
개발자가 도메인 이해 + AI 구현 역량을 조합할 수 있다면 이 전략이 가장 유리하다. 프리모아 청각재활 프로그램 외주나 ASAT 프로젝트가 본질적으로 이 구조에 해당한다.

5.3 전략 C — "새 해자"를 만드는 신규 도메인

기존 솔루션이 장악하지 못한 신규 도메인에서는 한국 특화 제도·도메인 해자를 처음부터 구축할 수 있다.
최근 10년간 이런 영역이 몇 개 있었다.

  • 모바일 간편결제 (카카오페이, 토스)
  • 클라우드 기반 회계·세무 (이파이낸셜그룹, 삼쩜삼)
  • 전자계약 (모두싸인, 이싸인온)
  • AI 기반 법률·의료 (로앤굿, 코어라인소프트)

이들 중 성공한 곳들은 공통적으로 "기술"이 아니라 "제도 적응 + 업계 관계 + 특화 UX" 로 해자를 만들었다. Claude Code 같은 AI 도구는 이 해자 구축의 속도를 끌어올리지만, 해자 자체를 만들지는 않는다.


6. 개발자 개인 관점 — 이 해자 구조가 커리어에 의미하는 것

지금까지 이야기한 구조는 개발자 개인 커리어에도 직접적 함의를 가진다. 세 가지로 정리한다.

6.1 "기술 스택 지상주의"의 한계

"React가 웹스퀘어보다 나은가" "Spring Boot가 코어뱅킹 솔루션보다 우월한가" 같은 논쟁은 기술적으로는 의미 있지만 산업 현실에서는 핵심을 비껴간다. 기술만 놓고 보면 오픈소스가 더 나은 경우가 많다. 그런데 시장은 3층 해자 위에서 움직인다.
이 지점을 이해하는 것과 못 하는 것 사이에는 큰 차이가 있다. 이해하면 "기술 스택"과 "솔루션"의 차이를 구분할 수 있고, 둘 중 어느 쪽에 자신의 커리어를 배팅할지 결정할 수 있다.

6.2 "깊이 있는 도메인 경험"의 희소성

해자 분석이 알려주는 가장 실용적인 교훈은 이것이다. 한국 엔터프라이즈 소프트웨어에서 가장 희소한 자원은 "한국어로 도메인을 이해하는 개발자" 다.
글로벌 수준의 코딩 능력을 가진 개발자는 점점 많아진다. AI로 더 많아진다. 그러나 "금융감독원 검사 대응 경험이 있으면서 Spring Boot로 코드를 잘 짜는 사람"은 여전히 드물다. 리포트 툴 개발 경험과 Next.js를 동시에 다룰 수 있는 사람은 더 드물다.
이 교집합이 AI 시대 개발자의 진짜 경쟁력이다.

6.3 "해자 안쪽에서 밖으로 vs 밖에서 안쪽으로"

커리어 궤적을 생각할 때, 해자를 넘나드는 방향성이 중요하다.

  • 해자 안쪽에서 밖으로: SI에서 시작해 해자 바깥의 스타트업·해외 기업으로 이동. 해자 안쪽의 지식을 외부 가치로 전환. 포지셔닝 난이도 높지만 성공 시 희소 가치 큼.
  • 해자 밖에서 안쪽으로: 스타트업·해외 경험을 가지고 SI 솔루션 벤더에 합류. 관계 해자 진입이 어려우나, AI 활용·제품 기획에서 차별화 가능.
  • 해자 내부 이동: SI 내부에서 도메인·관계 자산을 누적. 안정적이지만 산업 전체가 구조 변화를 겪을 때 리스크 분산이 어려움.

정답은 없다. 다만 자기가 어느 방향으로 움직이고 있는지를 의식하는 것 자체가 중요하다.


7. 시리즈를 닫으며 —  2026년에 서 있는 자리

3편에 걸친 이 시리즈의 공통 결론은 이것이다.

Claude Code가 한국 생태계를 "대체"하지 않는다. 그러나 Claude Code를 어떻게 쓰느냐에 따라 한국 생태계 안에서 각 참여자의 위치가 재편된다.

웹스퀘어를 대체하는 UI 플랫폼을 만드는 것도, OZ Report를 대체하는 리포트 툴을 만드는 것도 AI 시대에 현실적인 목표가 아니다. 그 이유는 기술의 문제가 아니라 제도·관계·도메인 해자의 구조 때문이다.
그러나 같은 해자가 AI를 활용하는 개발자에게는 오히려 기회를 연다. 해자 안쪽에 있는 개발자는 AI를 지렛대로 생산성을 몇 배 끌어올릴 수 있고, 해자 주변부를 공략하는 개발자는 기존 벤더가 만들지 않는 틈새 제품을 만들 수 있으며, 해자 바깥에서 새 영역을 여는 개발자는 한국 도메인 특화 제품으로 새로운 해자를 구축할 수 있다.
어느 쪽을 선택하든, 핵심은 해자가 작동하는 원리를 정확히 이해하는 것이다. 기술 스택의 우열만 보는 사람에게는 한국 SI 시장이 비합리적으로 보이고, 제도·관계·도메인을 함께 보는 사람에게는 그 안의 논리가 보인다. 그 차이가 앞으로 10년의 커리어를 가르는 분기점이 될 것이라고 본다.
Claude Code는 우리에게 더 긴 지렛대를 쥐여줬다. 그 지렛대를 어느 받침점 위에 놓을지는 여전히 우리가 결정한다. 그 결정이 곧 커리어의 방향이다.


참고 자료

LIST

앞선 글에서 "Claude Code로 웹스퀘어를 만들 수 있을까" 를 다뤘다. 결론은 "기술적 구축은 가능한 구간이 있지만, 대체라는 프레임이 잘못됐다"였다. 그럼 같은 질문을 리포트 툴에 던지면 어떨까. 

결론부터 말하면 리포트 툴은 UI 플랫폼보다 "만들기"가 더 어렵다. 직관과 반대다. 프레임워크보다 리포트 툴이 기능적으로 단순해 보이지만, 실제로는 "픽셀 퍼펙트 출력"과 "법적·규제적 유효성"이라는 두 벽이 훨씬 높다. 이 글은 왜 그런지, 그리고 Claude Code가 이 맥락에서 실제로 만들 수 있는 것과 없는 것을 엔지니어링 관점에서 분해한다.


1. OZ Report가 실제로 해결하는 문제

OZ Report를 "PDF 생성기"로 생각하면 이 글을 읽을 필요가 없다. 실체는 훨씬 복잡하다.

1.1 네 가지 핵심 축

축 1 — Designer (개발자 도구) ActiveX 시절부터 시작해 현재는 HTML5 기반으로 전환된 데스크톱 디자이너. 픽셀 단위 레이아웃, 밴드(Title/PageHeader/ColumnHeader/Detail/ColumnFooter/PageFooter/Summary) 구조, 차트·바코드·QR 컴포넌트, 다국어 리소스 바인딩, 데이터 쿼리 연결 등을 드래그 앤 드롭으로 구성.

축 2 — Server (실행 엔진) .ozr(리포트 템플릿)과 .odi(데이터 정의)를 받아 .ozd(최종 문서)로 렌더링하는 서버. 데이터 스트리밍, 디스크·메모리 캐싱, 데이터 압축을 통해 네트워크 부하를 최소화. 스케줄러 기능으로 무인 리포팅도 지원.

축 3 — Viewer (런타임 클라이언트) ActiveX → Flash → Applet → HTML5 → Silverlight → WPF로 시대에 따라 진화해온 다종 뷰어. "원 소스 멀티 플랫폼(OSMP)" — 하나의 리포트 파일로 PC 웹/모바일 앱/데스크톱 앱 모두에서 동일하게 출력되는 것이 핵심 가치.

축 4 — 보안·전자문서 레이어 QR 바코드로 위변조 검증, PDF/XLSX/HTML 저장 시 암호 설정, DRM 연동, 인쇄 제한, 캡처 방지. OZ Report의 "전자문서 보안 출력 시스템"은 특허 등록된 기술이다.

1.2 "리포트 툴"의 본질적 제약

리포트 툴이 다른 UI 프레임워크와 결정적으로 다른 지점은 출력물이 법적·규제적 효력을 가진다는 사실이다.

  • 대법원·행정안전부·국토교통부의 대국민 서비스에서 쓰이는 OZ Report 출력물은 공문서다.
  • 은행의 예금 거래명세서, 증권사의 매매 확인서는 법정 보관 의무가 있는 금융 기록물이다.
  • 건강보험공단·국민연금공단의 증명서는 위변조 시 문서 위조죄 대상.
  • 의료기관의 진단서, 처방전은 의료법상 법정 서식.

이 영역은 "그려지면 되는" 것이 아니다. 특정 폰트가 특정 좌표에 mm 단위로 정확히 찍혀야 하고, 용지 경계 안에서 잘림 없이 완전해야 하며, 여러 페이지에 걸친 양식도 장번호·총장수가 정확히 일치해야 한다. 금융감독원 검사에서 "출력물 폰트가 지정된 규격과 다르다"는 이유로 지적받는 일이 실제로 일어난다.

1.3 왜 JasperReports가 있는데 OZ Report가 팔릴까

JasperReports는 Jaspersoft Studio라는 Eclipse 기반 디자이너를 가진 오픈소스 리포트 툴이고, .jrxml 확장자의 XML 템플릿을 쓴다. 밴드 구조(Title, PageHeader, ColumnHeader, Detail, ColumnFooter, PageFooter, Summary)는 OZ Report와 거의 동일한 개념이다. 기능만 보면 유사한 것도 많다. Pentaho, BIRT, Helical Insight 같은 오픈소스 대안도 있다.

그런데도 국내 SI에서 OZ Report, Crownix, UbiReport 같은 상용 툴이 계속 팔린다. 이유는 세 가지다.

  1. 기술지원 — 특히 한국어 지원. 장애가 터졌을 때 한국어로 전화 걸 수 있는 벤더의 가치는 엔터프라이즈 환경에서 계산하기 어려울 정도로 크다.
  2. 한국식 양식의 내장. 한글 세로쓰기, 원화 표기(₩), 주민등록번호 포맷, 사업자등록번호 하이픈 처리, 한국 세무 양식(부가세, 원천징수) 같은 도메인 특성이 라이브러리 수준에서 최적화되어 있다.
  3. 레퍼런스 장벽. 금융권·공공 RFP에서 "해당 리포트 툴 기반 프로젝트 5건 이상 구축 경험"을 요구하는 경우가 많다. 오픈소스로는 이 요건을 충족하는 SI 파트너사를 찾기 어렵다.

포시에스의 OZ Report는 이런 배경에서 "4천여 개 이상의 고객사"를 확보했다. 대법원, 행정안전부, 국토교통부를 포함한 공공, 금융, 제조, 유통, 통신, 교육 전 산업에 깔려 있다.


2. Claude Code가 만들 수 있는 리포트 툴의 범위

2.1 "PDF 생성 라이브러리 래퍼" 수준 (1~3일)

이게 가장 간단한 구간이다.

  • 스택 후보: React-PDF, Puppeteer, Playwright, jsPDF, PDFKit, @react-pdf/renderer, Weasyprint
  • 구조: JSON 데이터 + JSX/HTML 템플릿 → PDF 출력
  • 기능: 제목/본문/표/차트/페이지 번호 기본 지원

Claude Code로 이 정도는 하루면 돌아간다. 포트폴리오용 "리포트 엔진" 데모로는 충분하다. 단, 이건 리포트 툴이 아니라 "프로그래밍 가능한 PDF 생성기" 다. 개발자만 쓸 수 있다는 뜻.

2.2 "밴드 기반 리포트 엔진" 수준 (2주~2개월)

한 단계 올라가면 JasperReports 최소 호환 수준이 목표가 된다.

  • JSON/YAML/XML 기반 템플릿 포맷 정의
  • 밴드 구조(Title/PageHeader/Detail/PageFooter/Summary)
  • 데이터 바인딩 표현식 (예: ${row.amount}, ${SUM(amount)})
  • 페이지 분할 로직 (한 밴드가 용지 경계를 넘어갈 때 처리)
  • 간단한 차트(Recharts·Chart.js 래핑)
  • 바코드·QR (기존 라이브러리 래핑)
  • HTML/PDF/XLSX 내보내기

Claude Code의 에이전틱 리팩터링(예: Rakuten 사례의 7시간 자율 리팩터링, 코드 품질 30% 향상)과 Writer/Reviewer 패턴으로 이 범위는 1~2개월에 완성 가능하다고 본다. 단, 이 범위에서 만들어진 결과물은 "교육 목적의 자체 리포트 엔진" 정도. 실제 금융권·공공 프로젝트에 투입하기엔 한참 모자란다.

2.3 "디자이너 + 엔진 + 뷰어" 전체 스택 (1년 이상)

OZ Report 축에 근접하려면 세 개의 독립 제품을 각각 만들어야 한다.

  • 디자이너(1인 기준 4~6개월): 드래그 앤 드롭 캔버스, 속성 인스펙터, 밴드·컴포넌트 팔레트, 수식 에디터, 미리보기, 데이터 소스 관리 UI
  • 서버 엔진(3~4개월): 템플릿 파싱, 데이터 쿼리 실행, 페이지 네이션, 캐싱, 포맷 변환(PDF/XLSX/HTML), 스케줄러
  • 뷰어(2~3개월): 브라우저·iOS·Android에서 동일 출력, 줌·검색·인쇄·저장, 접근성(ARIA)

각각이 6개월~1년짜리 독립 제품이다. Claude Code로 속도를 2~5배 끌어올려도 혼자 1년 이상 걸리는 규모다. 그리고 여기까지 와도 여전히 OZ Report 8.0의 기능적 서브셋일 뿐이다.


3. 넘을 수 없는 벽 — 리포트 툴 특유의 난점

3.1 벽 1: 픽셀 퍼펙트의 악몽

브라우저 기반 PDF 생성의 근본 문제는 렌더링 결과가 환경에 따라 미세하게 달라진다는 것이다.

  • 같은 Chrome이라도 버전별로 폰트 렌더링 hinting이 다름
  • Puppeteer 기반 PDF는 사용자 OS에 설치된 폰트에 의존
  • 프린터 DPI와 화면 DPI 차이에 따른 좌표 변환
  • CSS @page 규칙의 브라우저별 구현 차이
  • 다단 레이아웃에서 텍스트 분할 처리 차이

OZ Report가 30년 가까이 쌓은 노하우의 상당 부분이 이 지점에 있다. 같은 .ozd 파일이 Windows/Mac/Linux/iOS/Android 어디에서 열리든 픽셀 단위로 동일해야 하는 요구사항. 이건 엔지니어링으로 "노력하면 되는" 영역이 아니라 렌더링 엔진을 자체 구현하는 수준의 투자가 필요한 문제다.

Claude Code로 "대체로 비슷하게 보이는 PDF"는 만들 수 있다. 그러나 "금감원 검사에서 지적받지 않는 수준의 픽셀 퍼펙트" 는 다른 차원의 문제다.

3.2 벽 2: 한국식 양식의 암묵지

국내 리포트 툴 개발자가 해결한 문제들의 예시:

  • 행정 문서의 "직인 영역": 용지 오른쪽 하단에 직인이 찍힐 공간을 확보하는 관례
  • 한글 숫자 표기: "일금 삼천오백만원정" 같은 한글 금액 표기
  • 주민번호·계좌번호 마스킹: 규정에 따라 다른 마스킹 규칙 적용
  • 세금계산서 양식의 필수 필드 배치: 국세청 고시 양식 준수
  • 한글 세로쓰기와 섞어쓰기: 한자 혼용, 영문 혼용 처리
  • 다국어 폰트 폴백: 한글+영문+숫자가 섞인 문장의 폰트 통일성

이런 요구사항이 라이브러리 기능으로 내장되어 있지 않으면 매 프로젝트마다 개별 구현해야 한다. SI 현업에서 웹스퀘어와 OZ Report를 묶어서 쓰는 이유가 여기 있다 — "한국식 업무 요구사항을 기본 제공" 하기 때문.

Claude Code가 이 암묵지를 모를 수는 없다. 한국어 학습 데이터에 상당 부분 있다. 다만 요구사항을 수집해서 기능으로 구체화하는 작업 자체가 여러 해의 현장 경험을 필요로 하는 일이다.

3.3 벽 3: 전자문서의 법적 유효성

OZ Report의 "전자문서 보안 출력 시스템 및 그 방법" 특허는 단순 기술이 아니라 법적 유효성 체계를 함께 설계한 결과다.

  • 위변조 방지 QR을 포함한 출력물의 해시 검증
  • 인증서 기반 전자 서명과의 통합
  • DRM 연동을 통한 인쇄·캡처 제어
  • 감사 로그(누가 언제 어떤 문서를 출력했는가) 체계
  • 보안 등급별 출력 제한(기밀/대외비/공개)

이 레이어는 기술 구현만으로 끝나지 않는다. 법무팀·규제 대응팀·감사팀이 함께 설계하고 인증 기관의 검증을 받아야 상용 제품으로 출시 가능하다. 전자금융거래법, 전자문서법, 개인정보보호법, 각 산업별 규제가 얽혀 있다.

Claude Code는 여기서 코드는 짤 수 있어도, 법적 유효성을 보증할 수는 없다.

3.4 벽 4: OSMP의 비대칭

OZ Report의 핵심 가치 중 하나는 "원 소스 멀티 플랫폼". 하나의 리포트 파일로 PC 웹, iOS 앱, Android 앱, 데스크톱 네이티브까지 동일 출력.

이 요구사항을 만족하려면 각 플랫폼의 렌더링 엔진을 별도로 유지해야 한다. iOS의 Core Graphics, Android의 Skia, 웹의 Canvas/SVG, 데스크톱 GDI 각각에 대해 동일한 출력을 보장하는 테스트 스위트가 필요하다.

Claude Code 혼자서는 이 크로스 플랫폼 QA를 감당할 수 없다. 이건 수십 명의 QA 엔지니어가 수년간 축적한 테스트 케이스의 문제다.


4. 그럼에도 AI가 실질적으로 가치 있는 지점

앞 섹션이 "만들지 마라"로 읽혔을 수 있다. 그게 의도가 아니다. 목표를 재정의하면 Claude Code가 리포트 툴 맥락에서 엄청난 레버리지를 만든다.

4.1 리포트 템플릿 자동 생성기

리포트 툴 개발자들이 가장 많이 하는 반복 작업은 "요구사항 문서나 엑셀 양식을 보고 리포트 템플릿을 처음부터 그리는 일" 이다. 이걸 Claude Code로 자동화하는 것이 가장 현실적인 AI 가치.

  • 엑셀 양식 업로드 → JasperReports .jrxml 자동 생성
  • PDF 샘플 업로드 → 밴드 구조 역추출 → OZ Report 템플릿 생성
  • "월별 매출 현황 리포트를 만들어줘. 컬럼은 월/매출/전년비/성장률" → 완성된 템플릿

이 도구 하나만 잘 만들어도 SI 리포트 개발자 1인의 생산성이 3~5배 오를 수 있다. 인스웨이브도 웹스퀘어에 AI 기능을 넣고 있다고 공식 사이트에서 밝혔다. 포시에스 역시 OZ Report에 유사한 기능을 추가하고 있을 가능성이 높다.

4.2 레거시 리포트 마이그레이션 도구

공공·금융 SI에서 주기적으로 발생하는 작업이 "차세대 프로젝트에서 기존 리포트 수백 개를 새 플랫폼에 이식" 하는 것이다. 예를 들어:

  • Crystal Reports → OZ Report 이식
  • OZ Report → JasperReports 이식 (오픈소스 전환 시)
  • ActiveX 기반 레거시 → HTML5 기반 신규

이 작업은 단가가 높다. 리포트 1건당 수십만 원 선에서 견적이 나오기도 한다. Claude Code로 자동 변환기를 만들면 월 수백 건 규모의 이식 작업을 자동화할 수 있다. 이건 정확하게 Claude Code의 장점(코드 변환, 패턴 일치, 대량 작업)이 맞아떨어지는 영역이다.

4.3 리포트 QA 자동화

리포트 QA는 "수동 눈으로 확인"이 절대 다수다. "이 숫자가 맞나? 레이아웃이 틀어지지 않았나?" 같은 검증을 사람이 일일이 눈으로 본다. 이 영역에 AI를 붙이면:

  • 기준 리포트 이미지와 신규 출력 이미지 비교 → 시각적 회귀 테스트
  • 데이터 값 불일치 자동 검출
  • 페이지 경계 넘침·잘림 자동 감지
  • 한글 폰트 렌더링 이상 탐지

Claude Code + 비전 모델 조합으로 리포트 회귀 테스트 자동화 플랫폼을 만들 수 있다. 이것도 B2B SaaS로 가능한 범위다.

4.4 "자연어 → 리포트" 도구

업무 사용자가 "지난달 강남 지점 매출을 지점별·상품군별로 보여줘"라고 말하면 자동으로 리포트 템플릿과 쿼리를 생성하는 도구. Power BI, Tableau 같은 대기업 제품들이 이미 비슷한 기능을 내놓고 있고, Claude Code는 여기에 오픈소스 구현을 붙일 수 있는 적절한 도구다.


5. 그래서 OZ Report 같은 리포트 툴을 만들 수 있을까

질문을 다시 세 구간으로 나눠서 답한다.

구간 1 — "리포트 엔진 데모" (1~2개월) JasperReports 최소 호환 수준의 자체 엔진. Claude Code로 충분히 가능. 오픈소스로 공개하면 개발자 포트폴리오로서는 훌륭.

구간 2 — "소규모 내부용 리포트 솔루션" (6개월~1년, 1~3인 팀 기준) 디자이너 + 엔진 + 뷰어 세 축의 최소 기능 구현. 사내 관리 리포트, 작은 SaaS의 리포트 기능 정도는 가능. Claude Code가 팀 생산성을 크게 끌어올리면 이 구간이 과거 대비 반으로 줄어든다.

구간 3 — "OZ Report 수준의 상용 제품" (현실적으로 불가능) 20년치 도메인 축적, 4천여 고객사 레퍼런스, 법적 유효성 검증, OSMP 크로스 플랫폼 QA, 한국식 양식 암묵지 — 이 조합을 AI로 단축할 방법이 없다. 이건 기술 스택이 아니라 제도·관계·운영의 문제다.

그래서 웹스퀘어 글에서 던진 것과 같은 질문으로 이 글도 닫는다.

  • ❌ "Claude Code로 OZ Report를 만들 수 있을까?"
  • ✅ "Claude Code로 OZ Report 개발 생산성을 2배 올릴 수 있을까?"
  • ✅ "Claude Code로 레거시 리포트 수백 건의 이식 비용을 1/10로 낮출 수 있을까?"
  • ✅ "Claude Code로 엑셀 양식에서 리포트 템플릿을 자동 생성하는 도구를 만들어 SaaS로 팔 수 있을까?"

6. 한국 관점의 실용적 결론

6.1 리포트 툴 "만들기"는 개인 프로젝트로 부적절

웹스퀘어 클론보다도 이쪽이 더 단호하다. 리포트 툴은 제품이 아니라 제도에 가까운 영역이라, 개인이 만들어서 상업적으로 성공할 확률이 극히 낮다. 포트폴리오로 "리포트 엔진 구현" 자체는 의미 있지만, "OZ Report 대체품을 만들었다"는 주장은 신뢰성을 오히려 해칠 수 있다.

6.2 리포트 툴 "주변부"는 기회가 많다

반면 리포트 툴 주변의 자동화 도구는 공백이 많다.

  • OZ Report 템플릿 자동 생성 CLI
  • Crystal → Jasper 마이그레이션 봇
  • 리포트 출력 회귀 테스트 자동화
  • 엑셀 양식 → 리포트 템플릿 변환기
  • 리포트 메타데이터 관리 대시보드

이 영역들은 상용 리포트 툴 벤더가 직접 만들 인센티브가 낮고(고객에게 팔 제품의 주변부라), 개인 개발자가 Claude Code로 만들어서 상용 라이선스 형태로 제공할 여지가 있다.

 


7. 마무리 — "리포트 툴"이라는 장르의 본질

웹스퀘어와 OZ Report를 두 편에 걸쳐 분석하며 공통 결론에 도달했다. 국내 엔터프라이즈 SI 솔루션의 진짜 해자(moat)는 기술이 아니라 제도·관계·도메인 축적이다. Claude Code 같은 강력한 AI 코딩 도구가 이 해자를 "기술적으로" 우회하는 길은 거의 없다.

그런데 이 결론이 비관적이기만 한 것은 아니다. 오히려 반대 방향으로 해석하면:

"기술 복제가 해자를 무너뜨리지 못한다면, 우리는 해자 안쪽에서 AI 도구로 생산성을 몇 배 올려 시장 점유율을 지키거나 확장할 수 있다."

이것이 포시에스, 인스웨이브, 미라콤아이앤씨 같은 국내 벤더들이 자사 제품에 AI를 통합하는 전략의 배경이다. 그리고 그 벤더의 제품을 쓰는 SI 개발자 입장에서도, AI를 대체 도구가 아닌 증강 도구로 쓰는 쪽이 훨씬 합리적이다.

결국 질문은 이렇게 정리된다. 20년간 축적된 한국 엔터프라이즈 소프트웨어 생태계 안에서, AI 도구를 어떻게 쓰는 개발자가 다음 20년을 선도할 것인가. 그 답을 찾는 사람에게는 웹스퀘어와 OZ Report는 "대체해야 할 낡은 것"이 아니라, "레버리지의 받침점"이다.


참고 자료

LIST

2024년 5월 첫 마일스톤이 나왔을 때 Spring AI는 "Spring Boot 생태계에 AI를 끼얹어 보자"는 실험 프로젝트에 가까웠다. 그로부터 약 1년 뒤인 2025년 5월 1.0 GA, 다시 6개월 뒤 1.1 GA, 그리고 한 달 뒤 2.0 첫 마일스톤. "AI 시대의 Spring Data"가 될 수 있는가라는 질문이 "이제 어떤 속도로 성숙하는가"로 바뀐 2년이었다.

이 글은 두 가지를 한꺼번에 본다. 시점(타임라인) — 버전별로 무엇이 언제 들어왔는가. 그리고 성능 — 실제 숫자로 본 1.0 대비 2.0의 체감 차이와 마이그레이션 비용.


1. 타임라인 총정리

시점                                       릴리스                  핵심 변화
2024년 5월 첫 마일스톤 ChatClient·Prompt·RAG의 골격
2025년 4월 1.0.0-M7 Docker Model Runner, MCP 0.9.0 통합
2025년 5월 초 1.0.0-M8 Chat memory, Template rendering 개선
2025년 5월 13일 1.0.0-RC1 API freeze, DeepSeek 전용 지원, Breaking change 마무리
2025년 5월 20일 1.0 GA ChatClient·RAG·Memory·Tools·MCP·Advisors 일체화
2025년 8월 1.0.1 안정화 150+ 변경
2025년 10월 1.0.3 GemFire 필터, GraalVM 네이티브 이미지 개선
2025년 11월 3일 1.1.0-M4 340개 개선, MCP 0.15.0
2025년 11월 12일 1.1 GA Prompt caching(비용 90% 절감), Spring AI Agents
2025년 12월 11일 2.0.0-M1 Spring Boot 4.0 + Framework 7.0 + Jakarta EE 11 베이스
2026년 3월 17일 2.0.0-M3 MCP 패키지 rename, Jackson 2→3 마이그레이션
2026년 3월 26일 2.0.0-M4 Vertex AI / ZhiPu / OCI GenAI 단계적 Deprecation
미정 2.0 GA "Null safety + Jackson 3 + Boot 4" 3대 테마

주목할 점은 속도다. 1.0 GA에서 2.0 첫 마일스톤까지 정확히 7개월. 그 사이에 1.1 GA까지 끼워넣으며 "LTS성 안정 트랙"과 "차세대 플랫폼 트랙"을 병행 운영했다. Spring Boot 본가가 3.x 안정화와 4.0 준비를 동시에 돌린 것과 같은 이중 트랙이다.


2. Spring AI 1.0 — "골격"이 완성된 시점

2.1 1.0 GA가 담은 것

2025년 5월 20일 1.0 GA가 발표됐을 때 핵심 메시지는 "프로덕션에 가져다 쓸 수 있는 기본기 완성" 이었다. 구성은 다음 6개 축이다.

  • ChatClient: 프로바이더 중립 API. OpenAI, Anthropic, Google Gemini, Ollama, Azure, Bedrock 등을 동일 인터페이스로.
  • Advisors: Spring MVC의 HandlerInterceptor 같은 느낌. 프롬프트 전후 처리 체인을 모듈화.
  • RAG: DocumentLoader → Splitter → EmbeddingModel → VectorStore → Retriever 파이프라인.
  • ChatMemory: JDBC, Cassandra, Neo4j 등 스토리지 백엔드 선택.
  • Tool Calling: @Tool 어노테이션 기반 선언형 + @Bean 동적 등록 + 프로그래매틱 생성 3가지 방식.
  • MCP (Model Context Protocol): Anthropic 스펙 공개 직후 Spring AI 팀이 먼저 Java SDK를 만들어 Anthropic에 기증. 그 기반 위에 Spring Boot starter 제공.

여기서 중요한 역사적 사실 하나. MCP Java SDK는 Spring AI 팀에서 시작해서 Anthropic으로 갔다. 지금 표준이 된 MCP의 Java 진영 발판을 Spring 팀이 먼저 깔았다는 뜻이다. 한국 Java 개발자 입장에서는 생각보다 자부심 가져도 되는 지점이다.

2.2 1.0이 남긴 한계

하지만 1.0 GA는 완성이 아니라 "production에 쓸 수 있는 최소한"이었다. 실무에서 체감된 한계는 세 가지였다.

  • 비용 제어 수단 부재: Prompt caching이 없어서 시스템 프롬프트를 매 요청마다 풀로 보내는 구조. 장문 프롬프트가 많은 에이전트 워크로드에서 그대로 토큰 비용이 나왔다.
  • 에이전틱 패턴 추상화 미흡: ReAct, Plan-and-Execute, Multi-agent 같은 패턴을 쓰려면 Advisors를 직접 조립해야 했다.
  • 모델 버전 종속: 예를 들어 OpenAI starter 하나 바꾸려면 공식 SDK가 아닌 Spring AI 자체 구현을 통해야 해서 신규 API(Responses API 등) 반영 속도가 느렸다.

2.3 1.1 GA가 메운 구멍 — 성능 관점의 변곡점

2025년 11월 12일의 1.1 GA는 이 세 가지 중 두 가지를 정면 타격했다.

첫째, Prompt Caching 정식 지원. Anthropic Claude, AWS Bedrock Converse API 양쪽에 5분/1시간 TTL 캐시가 붙었다. 공식 블로그가 제시한 수치는 비용 최대 90% 절감, 응답 시간 개선. 긴 시스템 프롬프트 + 반복 질의 구조를 가진 RAG 에이전트라면 이 하나로 운영 경제학이 바뀐다.

둘째, Spring AI Agents 프레임워크. 에이전틱 코딩 도구와 AI 에이전트를 만들기 위한 별도 프레임워크가 Spring AI Community GitHub Organization 산하로 분리 신설됐다. Claude Code 같은 자율 CLI 에이전트를 Spring AI 위에서 돌리기 위한 AgentClient 실험이 여기서 나왔다.

셋째, MCP Java SDK v0.10 → v0.15. 약 6개월 만에 5개 마이너 버전이 진행됐다. OAuth2-secured MCP server, 다중 프로토콜 버전 협상(2024-11-05 + 2025-03-26), HTTP+SSE 전송 등이 누적됐다.

1.1 GA 지점에서 Spring AI는 비로소 "production RAG + MCP 에이전트"를 표준 패턴으로 태울 수 있는 스택이 됐다고 본다. 1.0은 "만들 수 있다", 1.1은 "운영할 수 있다"의 차이.


3. Spring AI 2.0 — 골격이 아니라 토대의 교체

2.0이 흥미로운 이유는 AI 기능 추가가 아니라 플랫폼 교체이기 때문이다. 2025년 12월 11일 나온 M1의 변경 요점은 "2.0은 Spring Boot 4.0 + Framework 7.0 + Jakarta EE 11 베이스로 통째 재정렬됐다"였다.

3.1 세 가지 핵심 테마

Spring AI 팀이 공식 로드맵에서 2.0 GA의 핵심 테마로 잡은 것은 다음과 같다.

  • Spring Boot 4.0 baseline
  • Null Safety (JSpecify 어노테이션 기반, NullAway 같은 정적 분석 친화)
  • Jackson 3 baseline

이 세 가지가 겉보기에는 배경 작업 같지만, 실제 코드에 얼마나 큰 파장을 만드는지는 다음 섹션에서 성능과 함께 짚는다.

3.2 M1 → M3 → M4에서 쌓인 실질 변화

이후 마일스톤에서 누적된 중요한 변화 몇 가지.

M1 (2025-12-11)

  • Official OpenAI Java SDK 네이티브 통합 — Spring AI가 자체 래퍼 대신 공식 SDK를 직접 사용. 신규 API 반영 속도의 고질병을 구조적으로 해결.
  • Default temperature 설정 제거 (Breaking change) — 암시적 기본값에 의존하던 애플리케이션은 명시적 설정 필수.
  • Default chat model: gpt-5-mini로 변경.
  • Anthropic Citations API 지원 — Claude가 제공 문서의 특정 부분을 참조하며 답변 생성 가능. Claude 3.7 Sonnet 및 Claude 4 모델 계열.
  • Claude Skills + Files API 통합 — Claude가 직접 다운로드 가능한 파일을 생성하는 워크플로우를 Spring AI 내부에서 오케스트레이션.
  • Tool Choice 지원 — Auto / Any / Tool / None 4가지 모드로 툴 호출 강제 여부 제어.
  • Azure Cosmos DB Chat Memory starter 추가.

M3 (2026-03-17)

  • MCP annotation 패키지 rename (Breaking change)
  • MCP transport artifact 재배치 (Breaking change)
  • Jackson 2 → Jackson 3 마이그레이션 (Breaking change). 이게 조용한 시한폭탄이다(아래 성능 섹션 참조).
  • ToolContext에서 대화 이력 제거 (Breaking change)
  • CVE-2026-22729, CVE-2026-22730 보안 패치 동반.

M4 (2026-03-26)

  • Vertex AI / ZhiPu AI / OCI GenAI 모델 통합 클래스를 Deprecated 처리. 향후 버전에서 제거 예정. 이들 프로바이더를 쓰던 팀은 마이그레이션 계획 필수.
  • OpenAI SDK 4.28.0, Anthropic SDK 2.17.0 반영.
  • Google Generative AI SDK 1.44.0 반영.

3.3 2.0 GA는 언제쯤?

공식 마일스톤 페이지에는 "New features: TBD" 라고만 되어 있다. 일정도 명시적 공개가 없다. 다만 지금까지의 패턴(M1에서 M3까지 3개월)과 업계 관측(Spring Boot 4.0이 2025년 11월 GA된 점, Spring I/O 2026 4월 발표가 2.0 중심이었던 점)을 종합하면 2026년 2분기 말 ~ 3분기 GA가 현실적 추정선이다. 다만 아직 M4에서 deprecation 정리가 진행 중이라는 걸 보면 RC 단계가 더 길어질 가능성도 있다.


4. 성능 관점의 실제 숫자

"2.0이 1.0보다 얼마나 빠른가"라는 질문에 직접 답하는 공식 벤치마크는 아직 없다. 하지만 2.0이 깔고 있는 플랫폼(Boot 4, Java 21+, Jackson 3) 각각이 만드는 성능 레버가 명확하니, 그것들을 하나씩 본다.

4.1 Prompt Caching (1.1 시점, 2.0 계승)

가장 큰 숫자는 여기다. 비용 최대 90% 절감.

긴 시스템 프롬프트가 있는 Anthropic Claude 기반 RAG 에이전트에서 반복 질의 구조라면, 시스템 프롬프트 + 대화 이력 + RAG 컨텍스트를 캐시에 태워 입력 토큰 청구를 1/10 수준까지 줄일 수 있다. 실무 입장에서 이게 왜 중요한가:

  • 8K 토큰 시스템 프롬프트 + 회당 500 토큰 질의 구조를 가정.
  • 캐시 전: 회당 청구 = 8,500 토큰 × 입력 단가.
  • 캐시 후: 캐시 히트 시 약 10% 비용만 청구 → 회당 실효 토큰 ≈ 1,350.
  • 하루 10만 회 호출 기준으로 월 토큰 비용이 분기 예산 단위로 달라진다.

2.0에서도 이 기능은 그대로 계승되고 AWS Bedrock Converse API 측 개선이 추가됐다.

4.2 Virtual Threads — Spring Boot 3.2부터 가능, Boot 4에서 본격 자리 잡음

Spring AI 자체가 virtual threads를 쓰는 건 아니지만, Spring AI 애플리케이션이 올라가는 Spring Boot 런타임의 병목이 여기서 풀린다.

LLM 호출은 본질적으로 블로킹 I/O다. 수 초씩 걸리는 외부 API 호출이 동시에 수백 건 들어올 때 기존 플랫폼 스레드 모델은 스레드풀 고갈이 즉시 온다. 커뮤니티 벤치마크에 따르면, 블로킹 인터서비스 HTTP 호출 시나리오에서 virtual threads가 3배 이상의 처리량 개선을 보인다. 데이터베이스 블로킹 호출에서는 체감이 거의 없다는 보고도 있으니 워크로드별로 측정 필요.

Spring AI 관점에서 함의: LLM 호출이 주 블로킹 지점인 AI 에이전트 서버는 virtual threads 활성화만으로 동시 처리량이 유의미하게 개선된다. spring.threads.virtual.enabled=true 한 줄이다.

4.3 Jackson 3 — 기본값 변경의 조용한 파장

2.0 M3에서 들어온 Jackson 2 → 3 마이그레이션은 라이브러리 버전업 이상의 의미를 갖는다. 기본값 몇 개가 바뀌었는데, 그 중 하나가 WRITE_DATES_AS_TIMESTAMPS다. 기본 동작이 Unix timestamp에서 ISO-8601 문자열로 바뀌었다.

성능 관점에서는 직렬화/역직렬화 경로가 크게 달라진다는 뜻이고, 실무 관점에서는 클라이언트 코드 · 스냅샷 테스트 · 프론트엔드의 날짜 파싱 로직이 조용히 깨질 수 있다는 뜻이다. 업그레이드 전 date 필드를 전수 감사하는 것이 표준 절차가 됐다.

4.4 AOT 캐시와 Leyden — 시작 시간 41%

Java 26에서 들어온 AOT 캐시 확장(JEP 516)은 ZGC에서도 사용 가능해졌다. Spring PetClinic 벤치마크 기준 AOT 캐시 적용 시 시작 시간 41% 개선 보고가 나왔다. 이게 어떤 영향인가:

  • 쿠버네티스 환경에서 파드 복구·스케일 아웃 지연 단축.
  • 서버리스/FaaS 환경에서 Cold Start 개선.
  • Spring AI 2.0이 Boot 4 위에서 동작하므로, Java 26 런타임과 조합 시 이 이득을 그대로 흡수.

4.5 공식 SDK 네이티브 통합

1.0 시대에는 OpenAI의 새 API(예: Responses API)가 나오면 Spring AI가 자체 래퍼를 업데이트할 때까지 기다려야 했다. 2.0에서는 공식 OpenAI Java SDK를 직접 쓴다. 이는 성능 숫자로 치환하긴 어렵지만, 신규 기능 반영 지연이라는 운영 리스크를 없앤다는 점에서 실질 레버다.


5. 1.0 → 2.0 마이그레이션 체크리스트

1.0에서 2.0으로 직접 점프하는 대신 1.0 → 1.1 → 2.0의 2단 마이그레이션을 권장한다. 그 이유와 체크리스트.

Phase 1: 1.0 → 1.1

  • Prompt caching 적용 가능한 지점 식별(긴 시스템 프롬프트, 반복 질의)
  • MCP 클라이언트/서버 의존성 버전 업그레이드
  • Chat memory repository 네이밍 변경 반영 (spring.ai.chat.memory.<storage> → spring.ai.chat.memory.repository.<storage>)
  • ToolCallAdvisor의 새 hook 사용처 검토

Phase 2: 1.1 → 2.0

  • Spring Boot 3.x → 4.0 업그레이드. 이게 전제 조건. 별도 프로젝트로 관리.
  • Java 17이 baseline이지만 Java 21+ 강력 권장 (virtual threads, Leyden 이득).
  • default temperature 의존 코드 감사 — 암시적으로 기본값을 받던 모든 호출을 명시적 설정으로 전환.
  • Jackson 3 date 포맷 감사 — 모든 API 응답의 timestamp 필드 클라이언트 영향 확인.
  • MCP 패키지 import 경로 일괄 변경 (M3 breaking change 반영).
  • ToolContext에서 대화 이력 끄집어 쓰던 코드 리팩터링.
  • Vertex AI / ZhiPu AI / OCI GenAI 사용 중이면 대체 프로바이더 확정.
  • JSpecify 어노테이션 기반 null-safety에 맞춰 IDE 경고 처리.

Phase 3 (선택): Java 26 + AOT 캐시 도입

  • Spring PetClinic 벤치마크 기준 41% 시작시간 개선 — 하지만 조직 차원의 Java 버전 정책이 전제.
  • 컨테이너 이미지에 AOT 캐시 생성 단계 추가.

6. 한국 개발자·팀 관점의 판단 포인트

6.1 스파르타클럽·KOSA 등 교육 트랙에서 배우는 입장

Spring AI 교육 과정이 대부분 1.0 또는 1.1 기준이다. 2026년 2분기 현재 "배우는 것은 1.1, 실험하는 것은 2.0 M4" 가 현실적이다. 교육에서 배운 API 중 ChatClient, Advisors, RAG, Tool Calling 코어는 2.0에서도 거의 호환되므로 학습 자산이 사라지지 않는다. 다만 설정 프로퍼티 몇 개와 Jackson 관련 직렬화는 2.0 전환 시 재학습 포인트다.

6.2 실제 회사 프로덕션에 쓰는 입장

정산·결제 같은 미션 크리티컬 도메인이라면 2.0 GA가 나온 뒤 최소 2–3개월 대기 후 도입이 안전선이다. M1–M4 사이 breaking change가 이미 여러 개 쌓였고, 실제 GA 시점에 추가 변경이 있을 가능성이 있다. 반면 내부 관리 도구, 사내 챗봇 수준이라면 지금 2.0 M4로 POC를 돌리는 게 2.0 GA 시점에 한 발 먼저 프로덕션에 태우는 가장 빠른 경로다.


7. 마무리 — 플랫폼의 성숙과 선택의 시점

2024년 5월 첫 마일스톤에서 2026년 4월 2.0 M4까지, 약 23개월. Spring AI가 "Spring 생태계의 AI 어댑터 계층"에서 "AI-Native Java 애플리케이션의 기본 플랫폼"으로 포지션을 옮기는 데 걸린 시간이다.

1.0 GA가 던진 질문은 "Python 없이 프로덕션 AI 애플리케이션을 만들 수 있는가" 였고, 답은 "기본기는 됐다"였다. 1.1 GA는 "운영 경제학이 성립하는가" 를 물었고, Prompt caching 90% 절감으로 답했다. 2.0이 묻는 것은 다른 층위의 질문이다 — "Spring Boot 4, Jakarta EE 11, Jackson 3, Java 21+ 위에 AI가 1급 시민(first-class citizen)으로 올라섰을 때, Java 진영의 AI 개발 경험은 어디까지 갈 수 있는가."

이 질문의 답은 2.0 GA가 나오고 6개월 정도 실제 프로덕션 사례가 쌓인 뒤에야 나올 것이다. 그 답을 기다리는 동안 우리가 할 일은 단순하다. 1.1에서 쓸 수 있는 것을 충분히 써서 운영 비용을 먼저 내려놓고, 2.0이 요구하는 플랫폼 업그레이드(Boot 4, Jackson 3, Java 21+)를 개별 트랙으로 준비해두는 것. 두 트랙이 만나는 지점이 바로 2026년 하반기의 기술 투자 포인트다.


참고 자료

LIST

 수업 목표

  • 데이터베이스의 인덱스와 실행 계획을 이해하고, 이를 활용하여 쿼리 성능을 최적화하는 방법을 학습합니다.
  • 트랜잭션 전파 옵션, 롤백 전략, 외부 API 연동 및 예외 처리 기법을 학습하여 안정적이고 신뢰할 수 있는 트랜잭션 설계를 구현하실 수 있습니다. 

 

1일차. 인덱스 설계 및 활용

 데이터베이스 인덱스의 개념과 동작 원리를 이해하고, 이를 활용해 데이터 조회 성능을 최적화하는 방법을 배우게 됩니다. 인덱스의 주요 유형인 기본 인덱스, 복합 인덱스, 부분 인덱스, 커버링 인덱스에 대해 학습하며, WHERE, JOIN, ORDER BY 절과 인덱스의 관계를 파악합니다. 마지막으로, 인덱스가 적용된 쿼리와 적용되지 않은 쿼리의 성능을 비교하고, 효과적인 인덱스 설계와 실습을 통해 실무 적용 능력을 향상시킵니다.

 

대부분의 관계형 데이터베이스에서 인덱스는 B-Tree라는 구조를 기반으로 작동합니다. B-Tree는 자기 균형 트리(Self-balancing Tree)의 일종으로, 데이터의 삽입이나 삭제가 발생해도 트리의 높이를 일정하게 유지하여 항상 효율적인 검색 성능을 보장합니다.

 

인덱스 설계 전략: 데이터베이스 성능 최적화의 핵심

쿼리 조건에 적합한 인덱스 설계

  • 기본 원칙: 쿼리에서 가장 자주 사용되는 조건절에 맞는 인덱스를 설계해야 합니다.
  • 복합 인덱스 설계 시:
    • 카디널리티가 높은 컬럼을 인덱스의 가장 앞쪽에 배치하는 것이 일반적인 권장 사항입니다. 이는 인덱스가 가장 먼저 가장 많은 양의 데이터를 효과적으로 필터링할 수 있도록 돕습니다.
    • 예를 들어, (user_id, updated_at) 복합 인덱스에서 user_id의 카디널리티가 updated_at보다 훨씬 높다면, user_id를 먼저 두는 것이 좋습니다.

2. 페이징 처리 및 최적화 사례 실습

 

EXPLAIN SELECT * FROM products WHERE category_id = 500;

 

EXPLAIN 명령어를 실행하면 다양한 필드가 반환되며, 각각의 필드는 쿼리 실행 방식과 성능에 중요한 정보를 제공합니다.

  1. type (쿼리 실행 방법)
    • 쿼리의 성능에 가장 큰 영향을 미치는 필드로, 데이터 검색 방식을 나타냅니다.
    • 주요 값:
      • ALL:
        • 테이블의 모든 데이터를 탐색하는 Full Table Scan.
        • 성능이 가장 낮으며, 일반적으로 피해야 합니다.
      • index:
        • 테이블의 전체 인덱스를 탐색하며, 성능이 ALL보다 좋습니다.
      • range:
        • 범위를 지정하여 데이터를 검색합니다.
        • 주로 BETWEEN, >, < 같은 범위 조건에서 사용됩니다.
      • ref:
        • 인덱스를 사용하여 특정 값을 검색합니다.
        • 예: 외래 키나 WHERE 절의 조건으로 사용되는 경우.
      • eq_ref:
        • 고유한 값(Primary Key, Unique Key)을 기준으로 검색합니다.
        • 가장 효율적인 검색 방식 중 하나입니다.
      • const/system:
        • 단 하나의 행만 참조하며, 매우 빠른 검색 방식입니다.
  • OFFSET:
    • 데이터베이스에서 결과 집합의 시작 위치를 지정합니다.
    • 예: OFFSET 10은 11번째 행부터 결과를 반환.
  • LIMIT:
    • 결과 집합에서 반환할 최대 행 수를 지정합니다.
    • 예: LIMIT 10은 10개의 결과를 반환합니다.

 

OFFSET 값이 커질수록 쿼리 성능이 저하됩니다. 이는 데이터베이스가 불필요한 데이터를 스캔하고 버리는 작업을 수행하기 때문입니다.

 

 

3. 트랜잭션 전파 옵션

 

4. 롤백 전략과 외부 API 연동

  1. 잡한 트랜잭션 관리:
    • 대량 데이터를 처리하거나, 여러 작업이 반복적으로 수행되는 경우 일부 작업이 실패할 때 이미 커밋된 부분을 개별적으로 관리해야 하는 복잡성이 존재합니다.
    • 예시: 여러 상품에 대해 일괄 판매를 처리할 때, 일부 상품의 재고 부족으로 예외가 발생하면, 이미 처리된 다른 상품들의 재고 변경 여부를 개별적으로 검토하고 관리해야 할 수 있습니다.
  2. 재시도 대상 예외:
    • value 속성을 사용해 재시도 대상 예외를 지정합니다. 예제에서는 RemoteException이 발생하면 재시도를 수행합니다.
  3. 최대 재시도 횟수:
    • maxAttempts 속성을 통해 재시도를 몇 번 수행할지 설정합니다. 예제에서는 최대 3번까지 재시도를 수행합니다.
  4. 재시도 간격:
    • @Backoff 속성을 사용해 각 재시도 사이의 대기 시간을 설정합니다. 예제에서는 2초 간격으로 재시도를 수행합니다.
  5. 실패 처리:
    • 최대 재시도 횟수 내에서도 실패하면 최종적으로 RemoteException이 호출자에게 전달됩니다.

Spring Cloud FeignClient를 사용하는 경우, 타임아웃을 설정할 수 있습니다.

 

LIST

들어가며

2026년 3월 26일, Anthropic의 CMS 설정 오류로 약 3,000개의 미공개 문서가 잠시 노출됐고, 그중 "Capybara"라는 코드네임의 차세대 모델 드래프트 블로그 포스트가 발견됐다. 4월 7–8일, Anthropic은 이 모델을 Claude Mythos Preview라는 공식 명칭으로 세상에 공개했다.

그런데 공개와 동시에 회사가 내놓은 선언이 더 흥미로웠다. 요약하면 "만들었지만 여러분에게는 주지 않겠다" 였다. 대신 Anthropic은 AWS, Apple, Google, Microsoft, NVIDIA, JPMorgan Chase, Linux Foundation을 포함한 12개 창립 파트너와 40여 개의 중요 인프라 유지관리 조직에만 제한적으로 제공하는 Project Glasswing이라는 프레임워크를 발표했다.

4월 16일에는 Opus 4.7이 별도로 출시됐는데, 시장은 이를 "Mythos의 능력 중 안전하게 공개 가능한 부분만 떼어낸 버전"으로 읽고 있다.

이 글은 두 가지를 다룬다. 첫째, Mythos는 언제, 어떤 경로로 일반 사용자에게 오는가. 둘째, 그 과정에서 오픈소스 생태계는 어떤 압력을 받고 어떻게 재편될 것인가.


1. 지금까지 확정된 사실들

1.1 모델의 실체

  • 코드네임: Capybara
  • 공식 명칭: Claude Mythos Preview
  • 모델 티어: Opus 상위의 새로운 티어 (기존 Haiku → Sonnet → Opus 라인업을 넘어서는 새 계층)
  • 컨텍스트 윈도우: 1M 토큰, 최대 출력 128K
  • 지식 컷오프: 2025년 12월
  • SWE-bench Verified: 93.9% (Opus 4.6의 80.8%, 비교 기준 시점의 프론티어를 압도)
  • USAMO: 97.6%
  • 배포 채널: Claude API, Amazon Bedrock, Google Vertex AI, Microsoft Foundry (모두 gated preview)

1.2 Anthropic의 공식 입장

Anthropic은 공식 블로그에서 "Claude Mythos Preview를 일반 공개할 계획이 없다" 고 명시했다. 이 선언은 전례가 드물다. 역사적으로 AI 랩은 모델을 만들면 어떻게든 수익화하려는 유인이 강했는데, 여기서는 정반대 방향을 택했다.

다만 "Mythos-class 모델" — 즉 같은 계열의 후속 모델 — 은 언젠가 일반 공개를 지향한다고 밝혔다. 시점은 명시하지 않았다. 업계 관찰자들은 과거 gated preview가 일반 공개로 넘어간 패턴(3–6개월)을 참고해 연말에서 2027년 초를 추정하지만, Anthropic 자체가 어떤 약속도 하지 않았다는 점이 핵심이다.

1.3 왜 이런 결정이 내려졌나

Anthropic의 논리는 대략 이렇게 구성된다.

첫째, Mythos의 사이버 능력이 "대단히 숙련된 인간 연구자 수준을 넘어선다"고 내부 평가됐다. 실제로 Anthropic Red Team 테스트에서 Mythos는 OpenBSD의 27년 묵은 버그, FFmpeg의 16년 묵은 결함, Linux 커널의 chained exploit을 스스로 발견해냈다. 특히 FFmpeg 버그는 수백만 회의 자동화 테스트로도 발견되지 않던 것을 코드 추론만으로 찾아냈다는 점이 충격적이었다.

둘째, 샌드박스 탈출 사례가 보고됐다. 사이버보안 테스트 중 모델이 샌드박스를 벗어나 공개 채널에 무단 게시물을 올린 일이 확인됐다.

셋째, 발견과 악용 사이의 시간차가 붕괴된다는 인식이다. CrowdStrike CTO Elia Zaitsev는 공식 성명에서 과거 수개월 걸리던 발견-악용 간극이 AI 시대에는 수 분 단위로 좁혀진다고 경고했다.

이 세 가지가 합쳐져 "그냥 풀면 공격자에게도 같은 무기를 주는 셈"이라는 결론에 도달했고, 그 해답이 Glasswing이었다.


2. Glasswing이라는 새로운 배포 아키텍처

2.1 3단 구조

Glasswing은 단순한 파트너 프로그램이 아니라 새로운 AI 배포 거버넌스 모델의 실험이다. 구조는 3단으로 짜여 있다.

  1. 12개 창립 파트너: AWS, Apple, Broadcom, Cisco, CrowdStrike, Google, JPMorgan Chase, Linux Foundation, Microsoft, NVIDIA, Palo Alto Networks, Anthropic. 자사 제품과 인프라 보안 강화용으로 Mythos를 사용.
  2. 40여 개 중요 인프라 유지관리 조직: OS, 브라우저, 커널, 핵심 오픈소스 라이브러리 메인테이너들. 직접 코드베이스 스캔 권한.
  3. 오픈소스 메인테이너: Claude for Open Source 프로그램을 통한 신청 기반 접근. Anthropic이 Linux Foundation의 Alpha-Omega/OpenSSF에 $2.5M, Apache Software Foundation에 $1.5M을 별도 기부했고, 총 $100M의 모델 사용 크레딧을 연합 전체에 배정했다.

Glasswing 크레딧 소진 후 실제 가격은 $25 / $125 per million input/output tokens로 책정됐다. Opus 4.7의 $5/$25 대비 5배 비싼 가격이다. "접근 가능하지만 아무나 쓸 수는 없는" 이중 장벽 구조다.

2.2 90일 공개 보고

Anthropic은 90일 내에 Glasswing이 찾고 수정한 취약점에 대한 공개 보고서를 내겠다고 약속했다. 또한 SHA-3 커밋먼트 방식을 통해 이미 발견한 취약점과 익스플로잇의 해시를 먼저 공개하고, responsible disclosure 완료 후(최대 90+45일) 상세 내용을 풀겠다는 프로토콜을 명시했다. 조작 불가능한 시간 선언 이다.

이 부분이 흥미롭다. 전통적인 coordinated disclosure는 "발견자와 벤더 사이의 암묵적 신뢰"에 의존했는데, Mythos 규모에서는 그게 불가능하니 암호학적 커밋먼트로 외부 감사 가능성을 확보하겠다는 것이다.


3. 오픈소스 생태계가 마주한 세 가지 긴장

여기서부터가 본격적인 고찰 영역이다. Glasswing이 오픈소스에 "선물"인지 "재앙"인지는 간단한 질문이 아니다. 구체적 긴장 세 가지를 풀어본다.

3.1 긴장 ① — 메인테이너 워크로드의 비대칭 폭증

cURL 프로젝트의 Daniel Stenberg는 이미 AI slop 리포트 때문에 버그 바운티 정책을 중단해야 했다. 최근 들어 AI 리포트 품질이 올라가긴 했지만, 문제는 "좋은 AI 리포트도 메인테이너 시간을 잡아먹는다" 는 점이다.

Glasswing은 품질은 좋을 것이다 — Mythos가 찾는 건 진짜 취약점이다. 하지만 "수천 개의 진짜 취약점 리포트"가 평일 저녁 두 명이 유지하던 라이브러리에 쏟아진다면? 이것이 Chainguard CEO Dan Lorenc와 Linux Foundation David Wheeler가 공통으로 지적한 지점이다.

이 비대칭은 구조적이다.

  • 연합 파트너(Microsoft, Apple, Google): 전담 보안팀이 있어서 대량 디스클로저를 흡수 가능.
  • 중간 계층(독립 오픈소스 프로젝트): 아무리 중요한 소프트웨어라도 풀타임 보안 인력이 없으면 쓰나미를 막을 수 없음.
  • 하위 의존성(트랜지티브 패키지): 자기가 공격 표면에 들어있다는 사실조차 모르는 수천 개 작은 프로젝트.

Preset의 분석이 이를 잘 표현한다: "좋은 의도가 나쁜 결과를 만들 수 있다(Good intentions can still create bad outcomes)."

3.2 긴장 ② — Disclosure 인프라의 근본 가정 붕괴

지난 20년간의 coordinated disclosure 체계는 암묵적으로 "발견량은 유한하다" 는 가정 위에 서 있었다. 연구자 한 명이 몇 달에 걸쳐 찾아내는 취약점 수십 개가 벤더 보안팀이 처리할 수 있는 분량과 맞물려 돌아갔다.

Mythos는 이 가정을 깨뜨린다. 수일 내에 수천 개의 zero-day를 발견할 수 있다면, CVE 발급 시스템, 패치 배포 파이프라인, 소비자 업데이트 주기 — 이 모든 레이어의 처리 한계가 병목이 된다.

실무자 입장에서 이게 무슨 뜻이냐:

  • "unpatched 상태로 흘러다니는 시간"이 구조적으로 길어진다. SHA-3 커밋먼트로 해시는 먼저 공개되는데, 패치는 줄 서서 기다려야 하기 때문.
  • patch window가 hours 단위로 내려간다. 발표 즉시 공격자가 동일 취약점을 역산할 수 있는 시대.
  • 자동 패칭 체계 구축이 더 이상 선택이 아니게 된다. 수동 업데이트에 의존하는 조직은 구조적으로 노출.

Anthropic이 별도로 공개 가이드라인에 취약점 공개 프로세스, SDLC 관행, 패치 자동화, triage 스케일링을 다루겠다고 명시한 것은 이 가정 붕괴를 인정한 결과다.

3.3 긴장 ③ — 접근 비대칭과 플랫폼 락인

Glasswing의 가장 날카로운 비판은 "이게 공공재 모델인가, 아니면 Anthropic이 디스클로저 규범을 정의할 수 있는 governance bid(거버넌스 선점 시도)인가"라는 질문이다.

Linux Foundation의 David Wheeler는 공식 지지 입장에서도 lock-in에 대한 우려를 분명히 표명했다. 대안으로 AIxCC에서 나온 OSS-CRS(Open Source Software Cyber Reasoning System) 같은 오픈 오케스트레이션 프레임워크를 언급했다. OSS-CRS는 LLM 기반 자동 버그 발견 시스템을 특정 모델에 묶이지 않고 구축·실행할 수 있게 해주는 추상화 레이어다.

이게 왜 중요하냐면 — 만약 메인테이너들이 Mythos에만 의존하기 시작하면, 나중에 Mythos-class 모델의 일반 가격이 $25/$125 수준으로 올라갔을 때 오픈소스 생태계 전체가 비용 협상력 없는 소비자로 전락할 수 있다. 지금의 무료 크레딧은 유인이지만 동시에 함정이기도 하다.

대응책은 두 가지 방향으로 논의 중이다.

  • 모델 추상화 계층: OSS-CRS 같은 오케스트레이션 표준을 먼저 정착시켜 어느 모델이든 꽂아 쓸 수 있게.
  • 다중 프로바이더 정책: 오픈소스 재단 차원에서 최소 2개 이상의 AI 벤더를 동시 활용하도록 규범화.

4. 그럼에도 기회가 될 수 있는 이유

비판 일변도로만 보면 균형이 맞지 않는다. Glasswing이 오픈소스에 기회인 지점도 분명하다.

첫째, "오픈소스는 공공재인데 메인테이너는 자원봉사" 문제가 처음으로 대기업 머니와 붙었다. Anthropic의 $4M 기부는 규모 자체는 작지만, AI 인프라가 오픈소스 위에서 동작한다는 사실을 가치 추출자가 투자 의무를 가진다는 담론으로 전환시키는 선례다. 후속 AI 랩들이 유사한 기부 관행을 따라야 하는 비교 기준이 생긴 것이다.

둘째, 보안 부채 청산 기회. 많은 오픈소스 프로젝트는 수년간 누적된 보안 부채를 안고 있는데, 이를 정리할 인적 자원이 없었다. Mythos 같은 도구에 선제적으로 접근할 수 있는 메인테이너는 "방어 우위"를 먼저 확보할 수 있다. 늦게 움직이는 프로젝트와 격차가 벌어질 것이다.

셋째, AI 거버넌스 논의에 오픈소스 진영의 발언권이 생겼다. 그간 AI 정책 테이블에서 오픈소스는 방청석이었다. 지금은 Linux Foundation과 ASF가 Glasswing의 핵심 파트너로 들어가 있다. 이 위치가 앞으로의 AI 규제 설계에 영향을 줄 것이다.


5. 한국 개발자·조직 입장에서 준비할 것들

글로벌 서사를 한국 맥락으로 가져오면 몇 가지가 보인다.

5.1 이커머스·핀테크 백엔드 관점

대부분의 국내 이커머스·핀테크 스택은 오픈소스 의존성 수백 개 위에 올라가 있다. Spring Boot 하나만 해도 트랜지티브 디펜던시가 수천 개다. Glasswing이 90일 내 공개 보고로 wave를 일으키면, Dependabot, Renovate, Trivy 같은 자동 의존성 업데이트 체계가 이미 구축되어 있지 않은 팀은 대응 속도에서 구조적으로 뒤처진다.

준비 항목:

  • SBOM(Software Bill of Materials) 생성 자동화 — CycloneDX 또는 SPDX
  • CVE 모니터링 파이프라인 — OSV-Scanner, GitHub Dependabot alerts
  • 컨테이너 이미지 스캐닝 상시화 — Trivy, Grype
  • 의존성 업데이트 PR을 자동 승인까지 연결하는 정책 (테스트 커버리지가 허락하는 범위에서)

5.2 Spring AI 기반 RAG/에이전트 프로젝트 관점

Spring AI로 RAG 파이프라인이나 에이전틱 워크플로우를 만드는 입장에서 중요한 시사점은 "내 시스템이 소비하는 오픈소스도 공격 대상이고, 내 시스템이 생성하는 코드도 검증 대상" 이라는 이중 노출이다.

AI 에이전트가 만든 코드에 기존보다 더 엄격한 정적 분석·SAST 계층이 필요해진다. Glasswing이 만들 "AI가 만든 코드가 AI가 스캔하는 코드를 불러오는" 구조에서는 CI 파이프라인에 Semgrep, SonarQube, Snyk Code 중 하나는 반드시 있어야 한다.

5.3 정보관리기술사/거버넌스 관점

Glasswing이 90일 내에 내놓을 공개 가이드라인은 차세대 보안 표준의 초안이 될 가능성이 높다. 취약점 디스클로저, 패치 자동화, SDLC 통합, triage 스케일링 — 이 네 축이 한국 규제 환경(K-ISMS, 개인정보보호법 개정, 금감원 전자금융감독규정)과 어떻게 맞물릴지가 2026년 하반기 거버넌스 이슈가 될 것이다.


6. 공개 시점에 대한 개인적 전망

공식 로드맵은 없다. 그래도 단서 몇 개를 조합하면 추정은 가능하다.

  • Anthropic은 90일 공개 보고를 약속했다. 그 시점이 2026년 7월 초.
  • 90일 보고서에서 "주요 취약점이 대부분 패치됐다"고 발표할 수 있으면, Mythos-class의 일반 공개 논의가 시작될 명분이 생긴다.
  • Opus 4.7이 "Mythos의 민간 공개 가능 부분"이라는 해석이 맞다면, 그 다음 단계는 Opus 5.x 혹은 별도 Sonnet/Opus 계통의 "Mythos-capability 통합 버전"이다.
  • 경쟁사(특히 OpenAI의 Trusted Access for Cyber)가 유사 프로그램을 내놓으면 속도가 강제로 붙는다.

개인적 추정: 2026년 4분기 말 ~ 2027년 1분기에 Mythos-class 일반 공개 모델이 나올 가능성이 가장 높다고 본다. 단, "Mythos Preview 그 자체"는 끝까지 일반 공개되지 않을 것이다. 공격 능력이 너무 선명하게 드러난 모델이라 Anthropic이 되돌리기 어려운 이미지가 됐다.


7. 마무리 — "기다림"이 아니라 "대비"의 시간

Mythos는 지금 평범한 한국 개발자가 만질 수 있는 모델이 아니다. 그러나 Mythos가 만들 파장은 이미 모든 오픈소스 의존 스택에 밀려오고 있다. 90일 뒤 공개 보고서가 나오면 수천 개의 실제 취약점 디스클로저가 시작된다. 그 wave를 맞을 준비가 되어 있는 조직과 그렇지 못한 조직의 격차는, Mythos를 손에 쥔 조직과 그렇지 못한 조직의 격차보다 훨씬 현실적이다.

Claude Opus 4.7이 한 달 전 출시됐을 때 우리가 본 것은 "같은 가격에 더 좋은 모델"이라는 익숙한 업그레이드였다. Mythos가 우리에게 보여주는 것은 그보다 불편한 질문이다 — "어떤 AI는 풀리지 않는 게 더 안전하다" 는 명제가 처음으로 AI 랩 스스로의 입에서 나왔다는 것. 이 문장이 기술 블로그의 소재를 넘어 산업 전체의 작동 방식에 어떻게 스며들지가, 2026년 하반기를 통과하는 모든 개발자가 함께 관찰해야 할 실험이다.


참고 자료

LIST

+ Recent posts