AI가 빨라진 게 아니라, 기록이 빨라졌다

AI가 빨라진 게 아니라 기록이 빨라졌다. TASK 문서, Git 히스토리, PR, 검증 로그가 컨텍스트로 쌓이면서 goodtek-web의 개발 속도는 10~20분 단위로 빨라졌다. 이번 TASK-025에서는 AdSense 승인 준비를 위해 robots.txt, sitemap.xml, Contact, Privacy, Start Here, Projects, 허브 SEO를 정리하며 기초가 속도가 되는 과정을 기록했다.

Share
AI가 빨라진 게 아니라, 기록이 빨라졌다
AdSense 승인 준비와 허브 SEO 강화

웹사이트 개발을 더 진행하기 전에 슬슬 애드센스 승인에 대한 부분을 고민하지 않을 수 없어서 “Privacy에 광고 문구 추가하고, Contact 페이지 만들고, sitemap 하나 넣으면 되겠지.”

이런 가벼운 마음으로 goodtek-web을 열었습니다.
그리고 바로 깨달았습니다.

아, 이건 광고 준비가 아니라 사이트의 기초 체력을 검사하는 작업이구나.

작업 전 상태를 보니 결과가 꽤 솔직했습니다.
홈, About, Privacy는 있었습니다. 그런데 robots.txt는 404였고, sitemap.xml도 404였습니다. Contact는 mailto에만 기대고 있었고, Privacy에는 AdSense 관련 고지가 없었습니다.

Start Here나 Projects처럼 goodtek이 어떤 흐름으로 운영되는지 설명하는 고유 페이지도 부족했습니다.

기능을 더 얹기 전에, 사이트가 먼저 자기소개를 제대로 해야 하는 상황이었습니다.

그리고 이번 작업을 하면서 다시 느꼈습니다.

개발 속도는 코드를 빨리 치는 데서만 나오지 않습니다. 다시 시작할 때 덜 헤매는 데서 나옵니다.

요즘 goodtek 작업 속도가 확실히 달라졌습니다.
예전에는 기능 하나 만들려고 하면 먼저 기억을 복구해야 했습니다.

“이거 왜 이렇게 만들었더라?”
“이 파일은 어디랑 연결되어 있었지?”
“지난번에 어디까지 했지?”
“이건 AI가 만든 건가, 내가 의도해서 바꾼 건가?”

이런 질문으로 시간을 쓰다 보면, 막상 개발은 시작도 못 했는데 이미 에너지가 줄어듭니다.

그런데 이제는 TASK 문서, Git 히스토리, PR, 커밋 메시지, 검증 로그가 모두 컨텍스트로 남습니다.
AI와 바이브코딩을 해도 블랙박스처럼 흘러가지 않습니다.

무엇을 왜 바꿨는지, 어디까지 검증했는지, 다음에 무엇을 확인해야 하는지가 기록으로 이어집니다.

AI가 빨라진 게 아니라, 기록이 빨라졌습니다. 그리고 기록이 빨라지니 개발도 같이 빨라졌습니다.

10~20분 만에 기능 하나가 붙는 이유

요즘은 작은 기능 하나를 10~20분 단위로 구현하는 일이 늘었습니다.

처음에는 단순히 AI 도구에 익숙해진 덕분이라고 생각했습니다.
프롬프트를 더 잘 쓰게 됐고, Cursor 작업 흐름에도 익숙해졌고, 반복되는 패턴도 손에 붙었습니다.

그런데 이번 TASK-025를 하면서 생각이 조금 바뀌었습니다.

속도가 빨라진 진짜 이유는 AI가 갑자기 모든 걸 알아서 해결해줘서가 아니었습니다.
AI에게 넘겨주는 컨텍스트가 점점 정리되고 있었기 때문이었습니다.

예전에는 이런 식이었습니다.

“이거 SEO 좀 해줘.”
“AdSense 준비도 같이 해줘.”
“아, 그런데 blog는 외부고 notes도 따로 있어.”
“login은 색인되면 안 되고, sitemap에는 이건 넣지 말고…”

말하다 보면 저도 헷갈립니다.
AI도 당연히 헷갈립니다.

그런데 지금은 다릅니다.
TASK 문서에 목표, 범위, 제외 항목, 검증 결과가 남습니다. Git에는 변경 히스토리가 남고, PR에는 왜 이 작업이 필요한지 남습니다.

예전 방식지금 방식
머릿속 기억에 의존TASK 문서로 작업 기준 정리
AI에게 매번 배경 설명Git 히스토리와 PR이 컨텍스트 역할
구현 후 “된 것 같음”lint, build, smoke로 확인
끊기면 다시 처음부터 설명어디서든 이어서 작업 가능

이 차이가 생각보다 큽니다.

바이브코딩이 위험해지는 순간은 AI가 코드를 많이 만들 때가 아닙니다.
기준 없이 빨라질 때입니다.

반대로 기준이 있으면, AI가 빠르게 만들어도 사람이 흔들리지 않습니다.
“이 페이지는 색인 대상인가?”
“이 URL은 sitemap에 들어가야 하나?”
“이건 AdSense 승인 전에 필요한가, 승인 후에 해도 되는가?”

이런 판단을 붙잡을 수 있습니다.

이번 TASK-025는 그 기준이 꽤 잘 작동한 작업이었습니다.

광고를 붙이기 전에 안내판부터 세우기

작업 전 prod 상태를 먼저 확인했습니다.

좋았던 부분도 있었습니다.
https://goodtek.xyz/ko에는 홈 teaser, About, Privacy가 있었습니다. 완전히 비어 있는 사이트는 아니었습니다.

그런데 AdSense나 검색엔진 관점에서 보면 빠진 부분이 선명했습니다.

점검 항목상태판단
robots.txt404검색엔진 기본 안내 없음
sitemap.xml404색인 경로 제출 어려움
Contactmailto 중심독립 문의 페이지 부족
Privacy광고 고지 없음AdSense 준비 부족
고유 페이지start-here/projects 없음허브 설명 신호 부족

여기서 방향이 정해졌습니다.

광고 스크립트를 먼저 붙이는 게 아니라, 사이트가 신뢰 가능한 허브처럼 읽히도록 기본 구조를 먼저 정리하는 것.

이번 선택은 “수익화 기능 추가”가 아니라 “승인 받을 수 있는 사이트 상태 만들기”였습니다.

생각해보면 당연합니다.

사람도 처음 만났을 때 자기소개가 어색하면 신뢰하기 어렵습니다.
사이트도 비슷합니다.

검색엔진에게는 robots.txt와 sitemap.xml이 기본 안내판입니다.
방문자에게는 Contact, Privacy, Start Here, Projects가 자기소개입니다.
AdSense에게는 이 사이트가 실제로 운영되고 있고, 정책과 문의 경로가 준비되어 있다는 신호가 필요합니다.

그러니까 이번 작업은 광고를 다는 작업이라기보다, goodtek.xyz가 “저는 이런 사이트입니다”라고 말할 수 있게 만드는 작업이었습니다.

SITE_URL 하나가 기준이 되는 순간

처음에는 robots.txt와 sitemap.xml만 만들면 끝날 줄 알았습니다.
그런데 메타데이터를 정리하려고 보니 기준 URL이 필요했습니다.

운영 도메인은 https://goodtek.xyz입니다.
하지만 개발 환경이나 dev 환경에서는 달라질 수 있습니다.

그래서 사이트 URL을 한 곳에서 가져오도록 정리했습니다.

export function getSiteUrl(): string {
  const fromEnv = process.env.SITE_URL?.replace(/\/$/, "");
  return fromEnv || "https://goodtek.xyz";
}

코드는 짧습니다.
하지만 이런 작은 코드가 생각보다 큰 역할을 합니다.

canonical, openGraph URL, sitemap URL, robots.txt의 Sitemap 위치까지 모두 같은 기준을 바라보게 됩니다. 나중에 환경이 바뀌어도 여기저기 흩어진 문자열을 뒤질 필요가 줄어듭니다.

이런 작업은 겉으로 티가 잘 안 납니다.
누가 사이트를 봐도 “와, SITE_URL 함수가 정말 멋지네요”라고 말하지는 않습니다.

하지만 운영하는 사람은 압니다.
기준이 한 곳에 있으면, 다음 작업이 훨씬 편해집니다.

AI도 덜 헤매고, 저도 덜 의심합니다.

robots.txt와 sitemap.xml은 기본 중의 기본

이번에 새로 만든 robots.txt는 단순합니다.

User-Agent: *
Allow: /
Disallow: /ko/login
Disallow: /ko/signup
Disallow: /en/login
Disallow: /en/signup
Sitemap: https://goodtek.xyz/sitemap.xml

핵심은 두 가지였습니다.

첫째, 공개 페이지는 허용합니다.
둘째, login/signup 같은 얇은 페이지는 검색 대상에서 제외합니다.

sitemap.xml에는 6개 경로 × 2개 언어, 총 12개 URL을 넣었습니다.

goodtek.xyz
├─ /ko, /en
├─ /about
├─ /privacy
├─ /contact
├─ /start-here
└─ /projects

여기서 중요한 건 “넣은 것”만이 아닙니다.
넣지 않은 것도 중요했습니다.

login/signup은 sitemap에 넣지 않았습니다.
blog, notes, community 같은 외부 채널 URL도 goodtek.xyz sitemap에 넣지 않았습니다.

goodtek.xyz는 허브입니다.
본문은 blog, notes, community에 있습니다.
그러면 sitemap도 그 역할을 흐리지 않는 게 맞다고 봤습니다.

이 기준을 남겨두면 나중에 도움이 됩니다.

몇 달 뒤에 다시 보면 분명히 이런 생각을 할 수 있습니다.

“왜 외부 채널 URL은 sitemap에 안 넣었지?”
“왜 login/signup은 빠졌지?”

그때 TASK 문서와 PR이 답을 해줍니다.

좋은 기록은 미래의 내가 다시 질문하지 않게 만드는 장치입니다.

Contact 페이지는 생각보다 강한 신뢰 신호

작업 전에는 Header와 Footer의 Contact가 mailto 중심이었습니다.
빠르긴 합니다. 클릭하면 바로 이메일 앱이 열립니다.

그런데 사이트 관점에서는 조금 아쉬웠습니다.

문의 페이지가 따로 없으면, 사이트가 아직 덜 완성된 느낌을 줍니다.
특히 AdSense 승인 준비를 생각하면 더 그렇습니다.

그래서 /contact 페이지를 새로 만들었습니다.

운영자, 이메일, 답변 범위, 광고·제휴, 생태계 문의를 정리했습니다.
과하게 꾸미지는 않았습니다. 대신 방문자가 “여기는 실제로 운영되고 있구나”라고 느낄 수 있도록 구성했습니다.

Header, Footer, footer columns의 Contact 링크도 모두 내부 페이지로 바꿨습니다.
이메일 주소는 Contact 페이지 안에서 자연스럽게 연결되도록 했습니다.

작은 변화입니다.
하지만 이런 작은 변화들이 쌓이면 사이트의 인상이 바뀝니다.

기능은 많은데 설명이 없는 사이트보다,
기능은 아직 작아도 기준과 안내가 있는 사이트가 더 신뢰를 줍니다.

이번 작업에서 그 차이를 꽤 크게 느꼈습니다.

Privacy는 그냥 문서가 아니었다

Privacy 페이지도 보강했습니다.

이번에는 특히 AdSense를 염두에 두고 광고 관련 섹션을 추가했습니다.
Google의 제3자 리마케팅 쿠키, Google과 파트너의 맞춤 광고, 광고 설정 opt-out, Google 광고 기술 정책 링크를 포함했습니다.

시행일도 2026-06-09로 정리했습니다.

여기서 중요한 건 문구를 추가하는 것 자체가 아니었습니다.
goodtek.xyz의 역할을 Privacy 안에서도 일관되게 설명하는 것이었습니다.

goodtek.xyz는 본문 전체를 재게시하는 블로그가 아닙니다.
blog, notes, community를 연결하는 퍼블리셔 허브입니다.

그래서 Privacy의 설명도 그 구조를 반영해야 했습니다.

허브는 허브답게. 본문 채널은 본문 채널답게.

이 기준은 JSON-LD 작업에서도 이어졌습니다.

홈에는 WebSiteItemList 구조화 데이터를 넣었습니다.
blog latest, notes, community 항목은 각각 외부 채널 URL로 연결했습니다.

반대로 goodtek.xyz에 BlogPosting은 넣지 않았습니다.
본문 원본이 다른 채널에 있는데 허브 도메인에서 BlogPosting을 주장하면 중복 canonical 문제가 생길 수 있기 때문입니다.

이런 판단은 코드보다 기준에 가깝습니다.

AI가 코드를 만들 수는 있지만,
어떤 도메인이 어떤 역할을 가져야 하는지는 사람이 정해야 합니다.

Start Here와 Projects가 필요했던 이유

AdSense 승인 준비를 하다 보면 자연스럽게 이런 질문을 하게 됩니다.

“이 사이트는 충분히 설명되고 있는가?”
“처음 온 사람이 goodtek이 뭘 하는 곳인지 알 수 있는가?”
“각 채널은 왜 나뉘어 있고, 어디로 가야 하는가?”

이 질문에 답하기 위해 /start-here/projects를 추가했습니다.

페이지역할
Start Here처음 온 사람이 goodtek의 방향을 이해하는 입구
Projectsblog, notes, community, SaaS 실험의 관계를 설명하는 지도
About운영자와 브랜드 방향성
Privacy정책과 데이터 처리 기준
Contact문의와 협업 경로

이렇게 놓고 보니 goodtek.xyz의 역할이 더 선명해졌습니다.

이전에는 홈이 여러 채널을 살짝 보여주는 teaser에 가까웠습니다.
이제는 최소한의 허브 골격이 생겼습니다.

방문자는 처음 온 사람용 입구를 볼 수 있고,
검색엔진은 sitemap과 metadata를 볼 수 있고,
AdSense는 정책과 문의 경로를 확인할 수 있습니다.

기능을 많이 붙인 건 아닙니다.
하지만 사이트가 훨씬 덜 임시처럼 보이기 시작했습니다.

AI에게 맡길 것과 사람이 잡아야 할 것

이번 작업도 AI와 함께 빠르게 진행했습니다.
하지만 모든 걸 AI에게 맡기지는 않았습니다.

오히려 이번 작업을 하면서 “사람이 잡아야 하는 부분”이 더 선명해졌습니다.

영역AI가 잘한 것사람이 정한 것
코드 작성페이지·컴포넌트 생성어떤 페이지가 필요한지
SEO 구현metadata, sitemap 구조화색인 대상과 제외 대상
i18nko/en 메시지 확장문서 톤과 정책 범위
검증반복 확인 흐름 보조배포 후 체크 기준
범위 관리구현 속도이번에 하지 않을 일

이 구분이 없으면 바이브코딩은 금방 흐려집니다.

AI는 빠르게 만듭니다.
정말 빠르게 만듭니다.

그래서 더 조심해야 합니다.

빠르게 만드는 능력은 좋은데, 방향이 틀리면 빠르게 멀어집니다.
작은 기능 하나가 아니라, 잘못된 구조를 빠르게 쌓을 수도 있습니다.

이번 TASK-025에서 사람이 붙잡은 기준은 분명했습니다.

  • goodtek.xyz는 AdSense 신청·퍼블리셔 허브다.
  • 본문 전체는 blog, notes, community가 담당한다.
  • login/signup은 색인 대상이 아니다.
  • 외부 채널 URL은 goodtek.xyz sitemap에 넣지 않는다.
  • 승인 전 작업과 승인 후 작업을 섞지 않는다.
  • 광고 스크립트보다 정책·문의·색인 구조를 먼저 정리한다.

이 기준이 있으니 AI와 함께 움직여도 작업이 흩어지지 않았습니다.

기록이 컨텍스트가 되는 구조

이번 작업에서 가장 만족스러웠던 부분은 결과물보다 흐름이었습니다.

TASK 문서가 있고, 브랜치가 있고, PR이 있고, 커밋이 있고, 검증 로그가 있습니다.

TASK-025
├─ 목표
│  ├─ AdSense 승인 준비
│  └─ 허브 SEO 강화
├─ 구현
│  ├─ metadata
│  ├─ robots.txt
│  ├─ sitemap.xml
│  ├─ Contact
│  ├─ Privacy
│  ├─ Start Here
│  └─ Projects
├─ 검증
│  ├─ lint
│  ├─ build
│  └─ local smoke
└─ 배포 후 체크
   ├─ prod robots 확인
   ├─ prod sitemap 확인
   ├─ GSC sitemap 제출
   └─ AdSense 사이트 신청

이렇게 남겨두면 작업이 끊겨도 괜찮습니다.

노트북을 닫아도 괜찮고, 다른 장소에서 다시 열어도 괜찮습니다.
심지어 다른 AI 세션에서 이어가도 훨씬 덜 불안합니다.

왜냐하면 컨텍스트가 대화창 안에만 있는 게 아니라, 저장소 안에 남아 있기 때문입니다.

이게 요즘 제가 느끼는 가장 큰 변화입니다.

예전에는 AI와 대화하면서 만든 흐름이 세션 안에 갇히는 느낌이 있었습니다.
지금은 그 흐름을 Git과 문서로 빼내고 있습니다.

그러면 AI는 단순한 코드 생성기가 아니라, 기록을 읽고 이어서 움직일 수 있는 개발 파트너에 가까워집니다.

기록이 컨텍스트가 되고 컨텍스트가 개발 속도가 되는 흐름

검증이 끝나야 속도라고 부를 수 있다

작업 후에는 lint와 build를 돌렸습니다.

결과는 둘 다 통과였습니다.

pnpm lint  → exit 0
pnpm build → exit 0

빌드 결과에는 새로 추가한 라우트가 보였습니다.

/[locale]/contact
/[locale]/projects
/[locale]/start-here
/robots.txt
/sitemap.xml

로컬 smoke도 확인했습니다.

robots.txt에는 login/signup 제외 규칙이 들어갔고,
sitemap.xml에는 12개 URL이 들어갔고,
Privacy 페이지에는 advertising 섹션과 관련 링크가 포함됐습니다.

여기까지 확인하고 나서야 작업을 닫을 수 있었습니다.

빠르게 만든다고 해서 검증을 생략하면 안 됩니다.
오히려 빠르게 만들수록 체크리스트가 더 중요해집니다.

이번 배포 후 human 체크리스트는 이렇게 남겼습니다.

  • https://goodtek.xyz/robots.txt 200 확인
  • https://goodtek.xyz/sitemap.xml 12 URLs 확인
  • /ko/contact, /ko/start-here, /ko/projects, /ko/privacy 확인
  • Header/Footer Contact가 /contact로 가는지 확인
  • Google Search Console에 sitemap 제출
  • AdSense 사이트 URL을 https://goodtek.xyz로 신청
  • 승인 후 ads.txt, ad script, CMP 진행

여기서도 일부러 승인 후 작업을 분리했습니다.

ads.txt, 광고 스크립트, CMP는 이번 범위가 아닙니다.
범위를 넘기 시작하면 빠른 개발은 금방 산만한 개발이 됩니다.

그래서 이번에는 여기서 멈췄습니다.

멈출 줄 아는 것도 개발 속도에 포함된다는 걸 요즘 자주 느낍니다.

이번 작업이 남긴 것

TASK-025는 겉으로 보면 AdSense 승인 준비와 SEO 강화 작업입니다.

하지만 제게는 조금 다르게 남았습니다.

기초가 정리되면 속도는 자연스럽게 올라간다.

그리고 그 속도는 단순히 AI가 코드를 빨리 써줘서 생기는 게 아닙니다.

기록이 쌓이고,
Git 히스토리가 컨텍스트가 되고,
TASK 문서가 다음 판단의 기준이 되고,
검증 로그가 작업의 마침표가 될 때 속도가 납니다.

예전에는 작업이 끊기면 다시 머릿속을 복구해야 했습니다.
지금은 기록을 열면 됩니다.

예전에는 AI에게 매번 처음부터 설명해야 했습니다.
지금은 PR, 커밋, TASK 문서를 기준으로 이어가면 됩니다.

예전에는 “이게 맞나?”를 감으로 판단했습니다.
지금은 lint, build, smoke, 배포 후 체크리스트로 닫습니다.

그래서 이번 작업은 애드센스 승인 준비이기도 하지만, goodtek의 작업 방식이 한 단계 더 안정된 순간이기도 합니다.

다음에는 승인 이후 단계가 기다리고 있을 겁니다.
ads.txt, 광고 스크립트, CMP, 그리고 실제 운영 데이터까지.

그때도 방향은 같을 것 같습니다.

빨리 만들되, 흘려보내지 않기.
AI와 함께 만들되, 기준은 사람이 남기기.

여러분은 AI와 함께 개발할 때 어떤 기록을 먼저 남기시나요?
저는 요즘 이 질문이 점점 더 중요해지고 있습니다.

Read more

바이브코딩이 꼬이는 순간, 문제는 코드가 아니라 사이클이었다

바이브코딩이 꼬이는 순간, 문제는 코드가 아니라 사이클이었다

처음에는 단순한 문제처럼 보였습니다. goodtek website를 만들면서 VibeOps를 붙여 쓰고 있었고, 흐름도 그럴듯했습니다. TASK를 만들고, 브랜치를 따고, Cursor로 구현하고, 커밋하고, 푸시하고, MR을 만들고, 머지하면 끝. 그런데 이상하게도 끝난 것 같은데 끝나지 않았습니다. task done을 실행했는데 git status는 여전히 dirty였습니다. MR은 올라갔는데 로컬 TASK 문서는 또 바뀌어 있었습니다. 머지한 뒤에 develop을

By ● goodtek