블로그 글을 마크다운으로도 내주면 AI 에이전트가 읽기 쉬워진다
정적 블로그를 운영하는 개발자가 사이트를 사람뿐 아니라 AI 에이전트에게도 읽기 좋은 형태로 손본 사례를 공개했다. 대상은 nginx가 서빙하는 정적 사이트 'Deallocated Objects'로, 프레임워크나 별도 서버 없이 빌드 시점에 생성되는 파일과 nginx 설정 몇 줄만으로 작업을 끝냈다. Claude, ChatGPT, Perplexity 같은 도구가 사용자 질문에 답하려고 페이지를 가져오는 상황을 전제로 한 정리다.
가장 기본이 되는 조치는 모든 글에 마크다운 원문을 함께 두는 것이다. 글 URL 뒤에 .md를 붙이면 마크다운 파일이 나오고, 파일 앞에는 제목·정규 URL·저자·날짜·짧은 설명을 담은 YAML 프런트매터가 붙는다. 원래 마크다운으로 작성됐던 과거 글은 빌드 과정에서 정리하고 이미지 경로를 자체 호스팅 사본으로 바꿔 같은 형식으로 맞췄다.
더 눈에 띄는 부분은 콘텐츠 협상이다. 클라이언트가 Accept 헤더에 마크다운을 요청하면 .md를 붙이지 않은 평소 URL에서도 마크다운이 반환된다. nginx에서는 map 블록과 location별 한 줄로 처리한다. 이때 모든 응답에 Vary: Accept를 실어 중간 캐시가 브라우저에 마크다운을, 에이전트에 HTML을 잘못 넘기는 상황을 막는다. 마크다운 응답에는 원본 HTML 페이지를 가리키는 Link rel="canonical" 헤더와 X-Robots-Tag: noindex를 함께 보내 검색엔진이 이를 중복 문서로 취급하지 않게 했다.
사이트 루트에는 /llms.txt를 두었다. 블로그 한 줄 소개, 마크다운을 얻는 방법, 피드 위치, 인용 방식에 대한 희망, 그리고 전체 글 목록과 각 글의 마크다운 링크·한 줄 요약을 담는다. 전체 글 본문을 한 파일로 합친 /llms-full.txt는 약 225KB이며, 홈페이지를 마크다운으로 표현한 /index.md도 제공한다. 모든 응답에는 llms.txt를 가리키는 Link 헤더가 붙어 에이전트가 경로를 추측하지 않아도 된다.
robots.txt는 침묵 대신 명시적 허용을 택했다. 모든 크롤러를 허용한 뒤 GPTBot, ClaudeBot, PerplexityBot, Google-Extended 등 십여 개를 이름으로 나열하고 Content-Signal: search=yes, ai-input=yes, ai-train=yes 한 줄을 추가했다. 인용되고 싶은 블로그에는 맞는 선택이지만 제품 사이트라면 다르게 판단할 수 있다는 단서도 붙였다.
피드도 손봤다. 기존 Atom 피드는 그대로 유지하면서 각 항목에 요약과 text/markdown 대체 링크를 넣었고, JSON Feed를 새로 추가해 항목마다 밑줄로 시작하는 사용자 정의 키 _markdown_url을 실었다.
검색·공유용 메타데이터는 사실상 전면 재작성에 가까웠다. 모든 페이지에 실제 메타 설명, 정규 URL, 로봇 태그, lang 속성을 넣고 Open Graph와 Twitter 카드 태그에 article:published_time과 modified_time을 더했다. JSON-LD로는 글마다 BlogPosting과 브레드크럼을, 인덱스 페이지에는 WebSite·Blog·Person을 넣었다. 설명문은 옛 데이터베이스에 저장된 값을 그대로 쓸 수 없었다. 문단이 붙어버린 데다 일부는 <img> HTML이 섞여 있었기 때문에, 렌더링된 본문 텍스트에서 요약을 새로 생성하도록 바꿨다.
2014년 마크업에서 남은 문제도 정리했다. viewport 태그의 maximum-scale=1을 제거해 모바일에서 손가락으로 확대하는 동작을 되살렸고, og:image가 없어 공유 시 페이지 첫 이미지가 대표 이미지로 잡히던 문제는 글마다 1200x630 미리보기 카드를 두는 방식으로 해결했다.
발행 알림도 자동화했다. IndexNow 키와 스크립트를 두고 글이 올라올 때마다 Bing 등에 핑을 보낸다. 구글은 이 방식에 참여하지 않지만 Bing 인덱스가 여러 AI 검색 도구에 쓰이기 때문에 30줄짜리 스크립트를 둘 가치가 있다는 판단이다.
개발자 입장에서 이 사례의 핵심은 대부분의 작업이 코드가 아니라 파일과 설정이라는 점이다. 정적 사이트라면 llms.txt와 글별 .md 버전을 만드는 것부터 시작할 수 있고, 콘텐츠 협상과 캐시 헤더는 nginx 설정 몇 줄로 얹을 수 있다. 다만 이 구성은 빌드 시점에 파일을 생성하는 정적 사이트와 nginx를 전제로 하므로, 동적 렌더링이나 다른 웹서버를 쓰는 환경에서는 같은 효과를 내는 별도 구현이 필요하다.