AI 3인이 내 블로그를 진단했다 — 그리고 내가 무시한 것들

시리즈: AI 팀과 함께 기술블로그 만들기 | Episode 2


이전 에피소드에서 Claude Code Agent Teams로 3인 AI 팀을 꾸렸습니다. UI/UX 담당, 기술 아키텍처 담당, 코드 리뷰 담당. 각자 독립적으로 블로그를 분석하고 보고서를 제출했습니다.

이번 글에서는 3명이 각각 무엇을 발견했는지, 그리고 그 결과를 실제로 적용하면서 내가 따른 것과 무시한 것을 솔직하게 기록합니다.

결론부터 말하면, AI의 기술적 분석은 놀라울 정도로 정확했지만 모든 권장 사항을 그대로 따르면 안 됩니다. 왜 그런지 구체적으로 보여드리겠습니다.

보고서 스펙

3명의 에이전트가 제출한 보고서의 규모부터 보겠습니다.

에이전트보고서 분량주요 섹션비교 분석
UI/UX 담당~1,000줄8개 섹션테마 4종, 플러그인 4종, 폰트 6종
아키텍처 담당~1,430줄8개 섹션docker-compose 전체 재설계, CI/CD 파이프라인
코드 리뷰 담당~760줄9개 섹션22개 이슈 (Critical 7, Warning 9, Info 6)

총 3,190줄, 25개 섹션. 한 사람이 이 정도 조사를 하려면 최소 2~3일은 걸렸을 겁니다.

UI/UX 담당: “기술블로그에 최적화된 UX를 설계해줘”

테마 전략: TT5 자식 테마를 강력 권장

UI/UX 에이전트는 기존 테마인 Twenty Twenty-Five(TT5)의 theme.json을 분석했습니다. 그리고 꽤 흥미로운 발견을 했습니다.

“TT5는 이미 Fira Code를 코드 블록 전용 폰트로 번들링하고 있으며, core/code 블록에 대한 스타일이 theme.json에 사전 정의되어 있다. 이것은 기술블로그에 상당히 유리한 출발점이다.”

4가지 옵션을 비교한 끝에 TT5 자식 테마를 최종 권장했습니다. Fira Code가 이미 번들되어 추가 로드 불필요하고, FSE(Full Site Editing) 지원으로 theme.json 상속만으로 커스터마이징이 가능하며, 8개 스타일 변형을 다크 모드 기반으로 활용할 수 있다는 이유였습니다.

그런데 나는 이 권장 사항을 따르지 않았습니다.

내가 GeneratePress를 선택한 이유

TT5 자식 테마 대신 GeneratePress FREE를 선택했습니다. AI의 분석이 틀린 건 아닙니다. 기술적으로 TT5 자식 테마는 훌륭한 선택입니다. 하지만 실제 구축 과정에서 우선순위가 달라졌습니다.

기준TT5 자식 테마GeneratePress
초기 설정 시간자식 테마 생성, theme.json, functions.php 필요Customizer에서 클릭 몇 번
코드 블록Fira Code 번들됨CSS에서 CDN 로드
커스터마이징theme.json + PHPCustomizer + Additional CSS
유지보수TT5 업데이트 시 호환성 확인 필요독립적

핵심은 시간이었습니다. 블로그는 글을 쓸 때 가치가 있지, 테마를 만드는 데 시간을 쓸 때가 아닙니다.

교훈 1: AI는 “기술적으로 가장 우아한 솔루션”을 권장하지만, 실제로는 “가장 빨리 동작하는 솔루션”이 더 나을 때가 있다.

타이포그래피: 거의 100% 채택

반면 타이포그래피 권장 사항은 거의 그대로 따랐습니다. Pretendard(본문) + Fira Code(코드) 조합은 toss.tech, velog 등 국내 기술블로그에서 이미 검증된 조합이라 신뢰도가 높았습니다.

항목AI 권장실제 적용채택
본문 폰트PretendardPretendard Variable (CDN)O
코드 폰트Fira CodeFira Code (CDN)O
본문 행간1.81.8O
콘텐츠 폭720px720px (max-width)O
코드 블록 배경#1e1e2e (항상 다크)#1e1e2eO

한 가지 인상적이었던 것은 “코드 블록은 라이트 모드에서도 항상 다크 배경”이라는 원칙입니다. VS Code, GitHub, Stack Overflow에서 개발자들이 이미 익숙한 패턴을 따르자는 것인데, 이건 혼자서는 명시적으로 정리하지 못했을 통찰이었습니다.


아키텍처 담당: “Docker 구성을 최적화해줘”

docker-compose.yml 전면 재설계

항목BeforeAfter
WordPress 이미지wordpress:latestwordpress:6.9-php8.3-apache
Health check없음모든 서비스에 추가
Resource limits없음메모리 제한 설정
PostgreSQL실행 중 (미사용)제거
Redis설정 없음128MB, LRU, AOF
로깅무제한max-size 10m, 3파일

이 부분은 거의 100% 채택했습니다. 인프라 구성은 “빠르게 대충”이 아니라 “제대로 한 번”이 맞기 때문입니다.

Redis 캐시 전략: 3단계 레이어

[사용자] → [Caddy (정적 캐시)] → [WordPress + PHP]
                                       ↓
                              [Redis Object Cache]
                                       ↓
                                  [MariaDB]

실제 적용한 Redis 설정:

redis:
  image: redis:7-alpine
  command: >
    redis-server
    --requirepass ${REDIS_PASSWORD}
    --maxmemory 128mb
    --maxmemory-policy allkeys-lru
    --appendonly yes
    --appendfsync everysec

단순히 redis:alpine으로 띄우던 것에서, 메모리 제한(128MB), LRU 정책(메모리 가득 차면 가장 오래된 키 삭제), AOF 영속성(데이터 유실 방지)까지 설정한 것입니다.

내가 따르지 않은 것: Caddy HTTPS 자동화

아키텍처 에이전트와 코드 리뷰 에이전트 모두 “Caddy 레이블에서 http:// 프리픽스를 제거해야 자동 HTTPS가 활성화된다”고 권장했습니다.

# AI 권장
labels:
  caddy: "yndl.dev"        # http:// 없음 → 자동 HTTPS

# 실제 적용
labels:
  caddy: "http://yndl.dev"  # http:// 있음 → HTTP만 서빙

AI 권장 대로 http://를 제거했을 때 벌어진 일:

  1. Caddy가 auto-HTTPS를 활성화
  2. Let’s Encrypt에 인증서 발급 요청
  3. DNS-01 챌린지 시도 → Cloudflare 프록시 뒤에 있어서 실패
  4. 사이트 전체 다운 (308 무한 리다이렉트)

Cloudflare가 SSL을 처리하므로 Caddy는 HTTP만 서빙하면 됩니다. AI는 인프라의 전체 그림(Cloudflare → Caddy → WordPress)을 모른 채 Caddy만 보고 판단한 것입니다.

교훈 2: AI는 개별 컴포넌트의 Best Practice는 정확히 아는 반면, 컴포넌트 간의 상호작용(Cloudflare + Caddy + WordPress 체인)은 놓칠 수 있다. 인프라의 전체 그림은 사람이 판단해야 한다.


코드 리뷰 담당: “보안 취약점을 찾아줘”

코드 리뷰 에이전트는 가장 실용적인 결과를 냈습니다. 총 22개 이슈를 발견했는데, Critical 7개 중 대부분이 실제로 위험한 것들이었습니다.

Critical-01: PostgreSQL 포트가 인터넷에 노출

# 발견된 문제
postgres:
  ports:
    - "5432:5432"  # 0.0.0.0:5432에 바인딩

WordPress가 사용하지도 않는 PostgreSQL이 인터넷에 포트가 열려 있었습니다. 방화벽이 없으면 누구든 DB에 직접 접속을 시도할 수 있는 상태였습니다.

Critical-04: DB 비밀번호 불일치 + Docker $ 보간 문제

.env 파일에서 MARIADB_PASSWORD와 WORDPRESS_DB_PASSWORD가 다른 값으로 설정되어 있었습니다. 게다가 비밀번호에 $와 @ 같은 특수문자가 있었는데, Docker의 환경변수 보간에서 $M이 변수로 해석되어 비밀번호가 깨지는 문제도 있었습니다.

# Before (위험 — $가 Docker 변수로 해석됨)
MARIADB_PASSWORD=d&a9X5McNt7s2PX^@$M^

# After (안전 — hex-only)
MARIADB_PASSWORD=a36e81299c2218db0be92434155a2b87

교훈: .env의 비밀번호는 hex-only (openssl rand -hex 16)로 생성하면 Docker $ 보간 문제를 완전히 피할 수 있습니다.

채택률: 22개 중 19개 (86%)

등급발견채택비율
Critical (7)77100%
Warning (9)9889%
Info (6)6467%
합계221986%

3명이 동의한 것, 그리고 겹친 것

Agent Teams의 가장 가치 있는 순간은 독립적 수렴이 일어날 때입니다.

주제UI/UX아키텍처코드 리뷰
Prismatic 채택290+ 언어, 경량Prism.js 업계 표준–
Rank Math 채택무료로 Schema 지원한국어 UI, 경량–
PostgreSQL 제거–불필요한 리소스포트 노출 위험
이미지 버전 고정–재현 가능한 배포latest 태그 위험

같은 결론인데 도달 경로가 다릅니다. 아키텍처 담당은 PostgreSQL을 “불필요한 리소스 소모”로 봤고, 코드 리뷰 담당은 “보안 위험(포트 노출)”으로 봤습니다. 두 관점이 합쳐지면 제거의 근거가 한층 단단해집니다.

관점이 보완된 경우: Redis

아키텍처 담당은 Redis의 기능적 최적화(메모리 정책, 영속성, 성능)를 설계했고, 코드 리뷰 담당은 같은 Redis에서 보안 이슈(비밀번호 미설정)를 발견했습니다. 두 관점을 합치면 “기능적으로 최적화된 + 보안이 강화된” Redis 설정이 완성됩니다. 이것이 Agent Teams의 진짜 가치입니다.


AI 권장 vs 실제 결정: 최종 대조표

항목AI 권장실제 결정채택이유
테마TT5 자식 테마GeneratePress FREEX속도 우선
본문 폰트PretendardPretendardO검증된 조합
코드 하이라이팅PrismaticPrismaticO만장일치
SEORank MathRank MathO만장일치
Caddy HTTPSauto-HTTPSHTTP 모드XCloudflare 환경
Docker 이미지버전 고정버전 고정O
PostgreSQL제거제거O만장일치
Redis 인증추가추가O
콘텐츠 폭720px720pxO

채택률: 86% — AI 권장을 따르지 않은 2건 모두 “AI가 틀렸기” 때문이 아니라 “AI가 모르는 컨텍스트가 있었기” 때문입니다.


보고서에서 가장 인상 깊었던 것 3가지

1. 한국어 기술 콘텐츠의 타이포그래피 과제

“한국어 기술블로그는 세 가지 글자 체계가 혼재한다: 한글 본문(설명, 개념 서술), 영문 기술 용어(API, JavaScript, Docker), 코드 블록(순수 영문 + 기호). 이 세 가지가 자연스럽게 어우러지려면 폰트 선택이 매우 중요하다.”

이 문제를 명시적으로 정리한 적이 없었는데, AI가 대신 정리해 주니 이후 모든 타이포 결정이 쉬워졌습니다. 문제가 정의되면 해결책은 따라옵니다.

2. 보안 이슈의 연쇄 발견

비밀번호에 $가 포함 → Docker 변수 보간으로 깨짐
→ MariaDB와 WordPress 비밀번호 불일치
→ DB 인증 실패
→ WordPress 설치 불가

이 연쇄를 한 번에 파악하고 “hex-only 비밀번호를 사용하라”는 근본 해결책을 제시한 것은 코드 리뷰 에이전트의 가장 큰 공헌이었습니다.

3. CI/CD 파이프라인 청사진

아키텍처 에이전트는 GitHub Actions 기반 배포 파이프라인을 완전히 설계해 왔습니다. 마크다운 파일을 Git에 push하면 WordPress REST API로 자동 발행하는 구조까지요. 아직 구현하지 않았지만, 구현할 때 시간이 크게 절약될 것입니다.


세 에이전트의 한계

한계 1: 외부 서비스와의 상호작용을 모른다

에이전트들은 프로젝트 디렉토리 안의 파일만 볼 수 있습니다. Cloudflare 설정, DNS 구성, 서버 방화벽 같은 외부 컨텍스트는 알 수 없습니다. 그래서 “Caddy에서 auto-HTTPS를 켜라”는 권장이 나온 것입니다.

한계 2: “기술적 우아함”을 과대평가한다

TT5 자식 테마 vs GeneratePress 결정이 대표적입니다. AI는 1주 후의 품질을 최적화하고, 사람은 오늘의 속도를 최적화합니다. 둘 다 합리적인 판단이지만, 이 블로그는 사람의 판단이 맞았습니다.

한계 3: 비용 의식이 없다

에이전트들이 제안한 플러그인 스택을 전부 설치하면 10개가 넘습니다. 플러그인이 많으면 충돌 위험, 업데이트 부담, 성능 저하가 따라옵니다. 현재 설치한 플러그인: Redis Object Cache, Prismatic, Rank Math. 딱 3개.


이 과정에서 배운 것

  1. AI 보고서는 “의사 결정 프레임워크”로 가장 유용하다. “실행 매뉴얼”이 아니라 “어떤 옵션이 있고 각각의 장단점이 뭔지”를 파악하는 도구.
  2. 교차 검증의 가치는 생각보다 크다. 세 에이전트가 독립적으로 같은 결론에 도달하면 의심 없이 채택할 수 있다.
  3. Critical 이슈는 무조건 따라라. 보안과 안정성에 관한 문제는 “나중에”가 없다.
  4. 보고서의 수명은 짧다. AI 보고서는 “지금 결정을 내리기 위한 도구”이지 “영구 참고 문서”가 아니다.

다음 에피소드 예고

보고서 분석은 여기까지. 다음 에피소드에서는 이 결정들을 실제로 구현하면서 마주친 문제들을 다룹니다. 특히 Caddy 리버스 프록시에서 발생한 3가지 장애와 그 해결 과정은 꽤 드라마틱합니다.

예고: Episode 3 — Caddy와 싸운 하루: 308 루프, 로그인 무한 리다이렉트, 사이트 블록 증발


시리즈 안내: AI 팀과 함께 기술블로그 만들기

회차제목상태
1Agent Teams란? 3인 AI 팀 구성기발행
2AI 3인이 내 블로그를 진단했다현재 글
3Caddy와 싸운 하루: 리다이렉트 루프 3연전발행
4Docker + WordPress + Redis: AI가 설계한 인프라 적용기발행
5기술블로그 UX: 코드가 읽히는 블로그발행
6AI 코드 리뷰어가 찾아낸 22개 이슈발행
7마크다운으로 글 쓰고 자동 발행하기예정
8AI 팀 vs 혼자 코딩: 비용 대비 효과 분석예정

이 글은 Claude Code Agent Teams (Research Preview)를 사용하여 작성되었습니다.
프로젝트: yndl.dev

댓글 남기기