Skip to content
게으른 엔지니어의 기술 블로그
Go back

링크가 깨질 줄 알고 새 필드까지 설계했는데, 이미 다 되어 있었다

블로그 글이 103개까지 쌓였는데 전부 programming 폴더 하나에 들어있었다. 태그도 programming이 103개 중 103개, AI_Agents가 93개에 붙어 있었다 — 둘 다 필터링 기능을 전혀 못 하는 죽은 태그였다. 카테고리를 나누기로 했다.

카테고리는 정했는데, 폴더를 나누면 링크가 깨진다고 생각했다

실제 글 제목과 설명을 다 훑어서 Obsidian 플러그인 개발, 뉴스 검색 파이프라인, AI 에이전트 인프라 등 7개 카테고리로 나눴다. 문제는 그다음이었다 — 이 사이트는 폴더가 그대로 URL이 되는 구조라(/posts/programming/제목/), 파일을 카테고리별 폴더로 옮기면 URL이 바뀌는 것까지는 각오했는데, 글 사이 링크까지 걱정이 됐다. 본문에서 다른 글을 참조할 때 [텍스트](파일명.md) 형식을 쓰는데, 지금까지는 전부 같은 폴더 안에 있어서 문제가 없었을 뿐, 서로 다른 카테고리에 속하게 될 글끼리 연결된 링크가 이미 9개 있었다.

그래서 대안을 냈다 — 프론트매터에 category 필드를 새로 만들고, URL을 폴더가 아니라 그 필드가 결정하게 라우팅 코드를 바꾸자고. 파일은 안 옮기고 필드만 추가하면 기존 링크는 그대로 다 작동할 거라는 계산이었다.

”왜 파일을 안 옮기면 링크가 안 깨지는 거지?”

이 제안에 질문이 하나 생겼다. 파일이 그대로 있으면 그 파일이 여전히 읽히는 거니까, 결국 URL이 두 개가 되는 거 아니냐는 거였다. 대답하려고 실제 링크 처리 코드(remarkResolvePostLinks.ts)를 열어봤다.

코드는 완전히 다른 걸 하고 있었다. [텍스트](파일명.md) 링크를 만나면, 이 사이트는 그 파일이 같은 폴더에 있다고 가정하지 않고 src/content/posts/ 밑의 모든 카테고리 폴더를 다 뒤져서 파일명이 일치하는 걸 찾고, 실제로 찾은 위치를 기준으로 URL을 다시 계산하는 커스텀 remark 플러그인을 이미 갖고 있었다. 파일을 어느 폴더로 옮기든 알아서 찾아서 올바른 URL로 치환해주는 구조였다 — category 필드도, 라우팅 코드 수정도 필요 없었다. 그냥 103개 파일을 폴더로 옮기기만 하면, 이미 있는 로직이 다 처리해주는 거였다.

가정만으로 새 메커니즘을 설계할 뻔했는데, 코드를 열어보니 그 문제 자체가 이미 없었다.

그래도 실제로 돌려서 확인했다

말로 설명한 걸로 끝내지 않고 작게 실험했다. 서로 링크가 걸린 글 한 쌍을 골라서 한쪽만 실제로 새 카테고리 폴더로 옮기고 빌드해봤다. 그런데 첫 결과가 이상했다 — prev/next 네비게이션 링크는 새 경로로 정확히 나왔는데, 본문 안의 링크는 여전히 옛 경로를 가리키고 있었다.

원인은 Astro 빌드 캐시였다. .astro/dist 캐시를 지우고 클린 빌드하니 본문 링크도 새 경로로 정확히 나왔다. 로컬에서 파일을 옮긴 직후엔 캐시를 지워야 한다는 것 하나만 기억해두면 되는 문제였고, 실제 배포는 매번 새로 빌드하는 Cloudflare Pages라 이 문제와 무관했다.

이 확인 덕분에 실제 이동은 안심하고 한 번에 진행할 수 있었다. 103개 파일을 전부 카테고리 폴더로 옮기고 클린 빌드했는데, 링크 대상을 못 찾으면 빌드 자체가 실패하도록 짜여 있는 플러그인이라(오타를 조용히 넘기지 않음) 이 검증도 공짜로 따라왔다. 빌드는 한 번에 통과했다.

검색엔진 색인은 별개 문제였다

폴더를 옮기면서 URL이 바뀌는 것 자체는 각오한 일이었지만, Search Console에 이미 색인된 옛 URL들은 그대로 두면 전부 404가 된다는 걸 뒤늦게 짚었다. 이건 remark 플러그인이 해결해주는 영역이 아니라 별개로 처리해야 했다 — 이미 라이브였던 글 80개(한 번도 발행 안 된 draft 23개는 제외)에 대해 public/_redirects에 301 리다이렉트를 추가했다. 사이트 자체의 문제(링크 탐색)와 사이트 밖의 문제(검색엔진이 기억하는 옛 주소)는 서로 다른 해법이 필요했다.

태그에서도 같은 실수를 했다

카테고리 정리가 끝나고 태그 차례였다. programming/AI_Agents를 지우고 나니 태그가 하나도 없는 글이 42개나 남았다. “실제 내용 기준으로 정말 붙일 태그가 하나도 없는 거냐”는 생각에 다시 훑어보니, 아니었다. 처음 만든 태그 후보 6개에도 이미 맞는 글을 놓쳤고, 특정 시스템(Honcho, GitHub, Karpathy의 LLM Wiki 개념 등)을 가리키는 태그 자체가 아예 없었다. 다시 채우니 42개가 10개로 줄었다.

남은 10개를 다시 보다가, 처음에 지웠던 AI_Agents를 이번엔 전체가 아니라 이 10개에만 selectively 다시 붙이면 어떨지 얘기가 나왔다. 다시 읽어보니 대부분 정말 그 얘기였다 — “AI는 매번 같은 답을 안 낸다”, “AI에게 코드를 맡길 때 승인이 필요한 이유”처럼 AI 에이전트의 행동이나 실수가 그대로 핵심 주제인 글들이었다. 다만 하나(ISO 8601 주차 계산 규칙을 발견한 글)는 순수한 캘린더 로직 얘기라 안 맞았다. 그래서 9개에만 다시 붙이고, 안 맞는 1개는 억지로 채우지 않고 그냥 태그 없이 남겨뒀다 — 103개 중 102개가 태그를 갖게 됐다.

카테고리 이동 때와 같은 패턴이었다 — 처음 낸 결론(“링크가 깨진다”, “태그 붙일 게 없다”)은 둘 다 실제로 확인하기 전까지의 추측이었고, 둘 다 틀렸다.

남는 생각

문제를 풀 새 메커니즘을 설계하기 전에, 그 문제가 이미 풀려 있는지부터 코드로 확인했어야 했다. 대신 “폴더를 나누면 링크가 깨질 것이다”라는 가정 위에 바로 설계를 얹었고, 그 가정 자체가 틀렸다는 걸 질문 하나(“근데 왜 안 깨지는 거지?”)를 받고 나서야 코드를 열어보고 알았다. 태그 쪽에서도 “이 정도면 다 확인했다”는 판단이 실제 재검토 앞에서 무너졌다. 둘 다 검증을 안 한 게 아니라, 검증하기 전에 이미 결론부터 내려놓고 있었다는 게 같은 문제였다.


Share this post:

Previous Post
에이전트를 두 개 켜놨더니, 하나는 아무것도 몰랐다
Next Post
벤치마크 표를 못 믿어서, 같은 원고 63개로 두 모델을 직접 붙여봤다