AI 마케팅 에이전트 팀 구축기 — Claude Code로 블로그 파이프라인 만들기

배경

사내 보안 솔루션의 마케팅을 체계적으로 운영하기 위해, AI 에이전트 기반 마케팅 팀을 구축하고 블로그 콘텐츠 파이프라인을 만드는 작업을 진행했다. 목표는 SEO 최적화된 블로그 글을 AI가 작성하고, CMS에 등록하고, 배포까지 자동으로 이어지는 구조를 만드는 것이었다.

AI 마케팅 에이전트 설계

Claude Code의 서브에이전트 기능을 활용해 5개의 전문 에이전트를 정의했다.

에이전트역할
CMO (총괄)주간 계획 기반으로 다른 에이전트에 작업 위임
Content Writer블로그 글 작성, SEO 최적화
SEO Analyst키워드 리서치, 경쟁사 분석
Social MediaLinkedIn, Twitter 콘텐츠 배포
Performance Reviewer활동 분석, 인사이트 생성

각 에이전트는 .claude/agents/ 디렉토리에 마크다운으로 정의된다. 브랜드 포지셔닝, 보이스 가이드, 콘텐츠 캘린더 등의 전략 문서를 참조하도록 설정해서, 일관된 톤과 메시지를 유지하게 했다.

블로그 기술 스택

블로그는 Next.js 16 (App Router) + Sanity CMS 조합으로 구성했다.

marketing/
├── blog/                # Next.js 블로그
│   ├── src/app/         # App Router 페이지
│   ├── scripts/         # Sanity 콘텐츠 조작 스크립트
│   └── public/          # 정적 파일 (파비콘, 로고)
├── schemaTypes/         # Sanity 스키마
└── docs/                # 마케팅 전략 문서
    ├── brand/           # 포지셔닝, 보이스 가이드
    ├── strategy/        # 캘린더, 키워드
    └── posts/           # 블로그 글 마크다운 (정본)

주요 기능:

  • 인포그래픽 자동 생성next/og(satori)를 활용한 OG 이미지 생성 API. cards, stats, process, comparison, table 5종 템플릿 지원
  • TOC 사이드바 — IntersectionObserver로 스크롤 위치를 추적하는 목차. h2/h3 기반
  • TL;DR 카드 — 글 상단에 3줄 요약 표시. Sanity body에서 tldr- 접두사 키를 분리해 별도 렌더링
  • RSS 피드, sitemap, robots.txt — SEO 기본 인프라

인포그래픽 생성 파이프라인

블로그 글에 삽입되는 인포그래픽 이미지는 수동으로 만들지 않는다. Next.js의 next/og API를 활용해 JSON 데이터를 받으면 이미지를 생성하는 엔드포인트를 만들었다.

// scripts/infographic.mjs 실행 흐름
1. JSON으로 인포그래픽 데이터 정의 (제목, 항목, 수치 등)
2. /api/og?data=... 엔드포인트 호출 → PNG 이미지 생성
3. Sanity에 이미지 업로드
4. 블로그 포스트 body에 이미지 블록 삽입
5. 문서 publish

폰트 크기는 최소 20px을 기준으로 설정했다. satori로 생성하는 이미지 특성상 작은 텍스트가 뭉개지기 쉬워서, 가독성 확보를 위해 모든 템플릿의 본문 텍스트를 20px 이상으로 통일했다.

콘텐츠 품질 문제와 교훈

AI가 작성한 첫 번째 블로그 글에서 여러 품질 문제가 발견됐다. Sanity의 Portable Text body를 직접 수정하는 스크립트를 10개 가까이 작성해서 고쳤다.

발견된 문제들

  1. 문장 쪼개기 — "AI 모델이" / "스마트폰의 형태, 각도를 분석" 처럼 한 문장을 여러 bullet으로 분리. 읽기 매우 불편
  2. 제목 중복 — 페이지 제목과 본문 첫 heading이 동일하게 반복
  3. 번호 리스트 1,1,1 — Portable Text에서 numbered list가 중간에 끊기면 번호가 리셋됨
  4. 용어 오류 — "블랭킹"(blanking) 같은 부적절한 용어 사용
  5. raw markdown 노출**텍스트**가 그대로 렌더링

에이전트에 규칙으로 기록

이 문제들을 content-writer 에이전트의 "글쓰기 품질 규칙" 섹션에 기록해서 재발을 방지했다.

## 글쓰기 품질 규칙 (필수)

### 문장 쪼개기 금지
- 한 문장이 되어야 할 내용을 여러 bullet으로 쪼개지 말 것
- 주어+서술어가 분리되거나, 문장 중간에서 끊기면 안 됨

### 문단 구성 원칙
- 설명형 내용은 자연스러운 문단으로 작성 (bullet 남용 금지)
- bullet/리스트는 3개 이상의 독립 항목을 나열할 때만 사용

AI 에이전트의 품질 관리는 "문제 발견 → 규칙 추가 → 다음 작업에 적용" 사이클로 점진적으로 개선해야 한다는 걸 체감했다.

Sanity ↔ Markdown 동기화 문제

작업 중 발견한 구조적 문제가 하나 있었다. content-writer가 처음 글을 마크다운으로 작성하면 docs/posts/에 저장되고, 이걸 Sanity에 업로드한 뒤 Sanity에서 직접 수정(문장 병합, 이미지 삽입, TL;DR 추가 등)을 진행했다. 그 결과 마크다운 파일이 최종본과 달라지는 문제가 생겼다.

이 글을 다른 채널(LinkedIn, 뉴스레터 등)에서도 재활용하려면 정본(Single Source of Truth)이 필요했다. 두 가지 방향을 검토했다:

  • A. Sanity를 정본으로 — Sanity에서 최종본을 md로 역변환
  • B. Markdown을 정본으로 — md를 먼저 완성한 후 Sanity에 업로드만

우선 A 방식으로 Sanity의 Portable Text를 GROQ로 조회한 뒤 마크다운으로 역변환하는 작업을 수행했다. 이미지는 Sanity CDN URL을 그대로 참조하도록 했다.

배포

블로그는 Vercel에 배포하고, 커스텀 도메인을 연결했다. DNS에 CNAME 레코드를 추가하는 것으로 완료.

배포 과정에서 ISR 캐시 문제를 만났는데, Sanity에서 콘텐츠를 수정해도 페이지에 반영되지 않아서 .next 디렉토리를 삭제하고 서버를 재시작해야 했다. 프로덕션에서는 Sanity webhook → revalidate API로 해결할 수 있다.

결과 및 회고

하루 만에 AI 마케팅 팀 구조 설계부터 블로그 첫 글 발행까지 완료했다. 결과물:

  • AI 에이전트 5종 정의 (CMO, Content Writer, SEO, Social Media, Performance)
  • Next.js + Sanity 블로그 구축 및 프로덕션 배포
  • 인포그래픽 자동 생성 파이프라인
  • 첫 번째 블로그 글 발행 (인포그래픽 4종 포함)
  • 콘텐츠 품질 규칙 체계화

느낀 점:

  • AI가 글을 쓰는 건 빠르지만, 품질 검수가 병목이다. 문장 쪼개기, 용어 오류 같은 문제를 잡으려면 사람이 한 번은 봐야 한다
  • 에이전트에 규칙을 누적해서 점진적으로 품질을 올리는 방식이 현실적이다. 처음부터 완벽한 프롬프트는 없다
  • Sanity와 마크다운의 정본 문제는 초기에 결정해야 한다. 나중에 동기화하려면 비용이 크다
  • 인포그래픽 자동 생성은 예상보다 효과적이었다. satori의 제약(flexbox만, 일부 CSS 미지원) 안에서 충분히 쓸 만한 결과물이 나온다

Read more

사내 보안 솔루션에 SIEM/Syslog 연동 기능 구현하기

배경 사내 직원 모니터링/보안 솔루션을 개발하고 있다. 의심 활동, 디바이스 제어, 파일 전송, 스크린샷 등 다양한 보안 이벤트를 생성하는데, 엔터프라이즈 고객들은 이 이벤트를 자사 SIEM(Splunk, QRadar, Microsoft Sentinel 등)으로 수집해 통합 보안 관제를 하고 싶어한다. Organization 단위로 SIEM 서버 연동 설정을 관리하고, 보안 이벤트를 업계 표준 포맷(

By Park Chisu

[잡설] DNS에 대해 ,, 이런저런 ,,

DNS는 Domain Name System. 도메인 주소 (parkchisu.com) 을 넣으면 거기에 맞는 IP(32.132.12.123)를 리턴하는 시스템이다. 당연히 이런 기초정보를 공부하기 위해 쓰는 건 아니고.. 이번에 작업하면서 약간 헷갈렸던 부분이 있어 관련 내용을 공유한다. 회사의 내부망에서도 자체 DNS 서버를 운영할 일이 생긴다. 예를 들어 사내망에서만 접속할 수

By Park Chisu
k8s pod 자원 배분에 대해 ..

k8s pod 자원 배분에 대해 ..

k8s는 안다고 생각했는데 알고보니 몰랐던 것들이 계속 나온다 .. 이번엔 가장 기본적인 파드 자원 분배에 관한 이런 저런 얘기를 써놓을 예정 .. 계속 추가 예정 ,, 일단 기본적인 개념은 Request, Limit 일 것이다. * Request : 파드가 노드 안에서 "나는 이만큼 노드의 자원을 쓸 것이다" 라고 선언해두는 값. CPU의 경우 100m 이런식으로 정의할

By Park Chisu
[문제 해결] Docker compose 환경에서 keycloak 연결 이슈

[문제 해결] Docker compose 환경에서 keycloak 연결 이슈

문제 상황 도커 컴포즈로 keycloak 컨테이너와 그 컨테이너에 연결할 내 앱 서버를 작성했는데, 이상하게 처음 startup할 때 keycloak 연결 에러가 났다. 사실 연결 오류로 실패할 경우 자동으로 재시작하면 문제없이 동작하기에 그냥 넘어가도 됐지만… 계속 신경이 쓰여서 해당 에러를 제거하고자 했다. 서버 시작할 때마다 에러 메시지 뜨면 괜히 신경쓰이니 … keycloak.exceptions.

By Park Chisu