사람과 AI 에이전트를 동시에 대응하는 사이트를 위한 6가지 실전, 복사해 쓸 수 있는 체크리스트 포함
지난 4일 동안, Claude Code와 함께 smarts.md를 "사람이 읽는 스마트 계약 문서 사이트"에서 "AI 에이전트가 사용하는 스마트 계약 문서 사이트"로 바꿨습니다.
같은 일처럼 들리지만 실제로는 꽤 다릅니다. 사람을 위한 사이트는 가독성, 검색성, 로딩 속도를 최적화합니다. AI 에이전트를 위한 사이트는 다른 질문에 답해야 합니다.
robots.txt가 차단하고 있지는 않은가)Claude에게 만들게 한 6가지 장치를 소개합니다. 모두 독립적으로 당신의 사이트에 옮길 수 있습니다.
robots.txt로 AI 크롤러를 명시적으로 환영하기대부분 사이트의 robots.txt는 오래된 템플릿에서 복사된 것이고, 모르는 User-Agent는 암묵적으로 차단합니다. 하지만 2025년 이후 많은 AI 크롤러는 새로 생긴 User-Agent입니다 — GPTBot, ClaudeBot, PerplexityBot, Applebot-Extended, Google-Extended, CCBot, meta-externalagent 등. 이들에게 열어두려면 명시적으로 Allow를 해야 합니다.
smarts의 robots.txt는 첫머리에 정책 선언을 하고, 이어서 User-agent + Allow: /를 12개 나열해 OpenAI, Anthropic, Perplexity, Google Gemini, Apple, Common Crawl, Meta, Cohere를 커버합니다. 태도는 단순 명료합니다 — 이 사이트는 AI에게 읽히기 위해 존재합니다.
llms.txt — LLM을 위한 메뉴llms.txt는 llmstxt.org가 제안한 관습입니다. 사이트 루트에 간결한 Markdown을 놓고, LLM에게 "이 사이트는 무엇인지, 어떻게 사용하는지, 주요 진입점은 어디인지"를 알려줍니다. 사이트의 엘리베이터 피치 같은 겁니다.
smarts의 llms.txt는 약 60줄이고, 이런 내용을 담습니다.
/{chain}/{address} vs 짧은 slug)핵심 통찰: LLM은 문서를 토큰으로 읽기 때문에 사이트 전체를 크롤하지 않습니다. 증류된 인덱스를 건네주면 적중률이 확 올라갑니다.
.well-known/mcp.json — 미리 베팅MCP 프로토콜은 아직 /.well-known/openid-configuration 같은 자동 발견 관습을 확립하지 못했습니다. 오늘 고정된 경로를 크롤하는 공개 클라이언트는 없습니다.
그래도 매니페스트를 공개하는 건 30줄짜리 일입니다.
def well_known_mcp
response.set_header("Cache-Control", "public, max-age=3600")
response.set_header("Access-Control-Allow-Origin", "*")
render json: {
name: "smarts",
version: "0.1.0",
description: "...",
protocol_version: "2024-11-05",
transports: [{ type: "sse", endpoint: "https://smarts.md/mcp/sse" }],
capabilities: { tools: true, resources: false, prompts: false },
tools: MCP_TOOLS.map { |t| { name: t[:name], description: t[:blurb] } }
}
end
어떤 발견 관습이 확립되는 순간 한 줄도 바꾸지 않고 합류할 수 있습니다. 동시에 이 매니페스트는 개발자 대상 자기 문서화이기도 합니다 — MCP가 어떻게 생겼는지 궁금한 사람은 curl smarts.md/.well-known/mcp.json이면 충분합니다.
핵심은 tools 배열이 MCP_TOOLS 상수에서 파생된다는 것, 단일 진실 소스입니다. 기존 구조 테스트가 모든 app/tools/*_tool.rb가 그 상수에 나타나도록 강제하므로, 매니페스트는 "새 도구를 빠뜨리지 않는다"는 보장을 공짜로 상속받습니다.
.md 변형: 모든 페이지에 WebFetch 친화적 증류판이게 제일 만족스러운 부분입니다. Claude Code의 WebFetch 도구는 HTML을 받고 나서 스스로 정리하고 내용을 뽑아내야 하는데, 토큰 소비가 많고 불안정합니다. 그런데 처음부터 .md를 제공하면 어떨까요?
Rails의 respond_to가 기본 지원합니다.
# config/routes.rb
get ":slug(.:format)", to: "contracts#show",
constraints: { slug: ContractSlugs::ROUTE_PATTERN, format: /html|md/ }
https://smarts.md/usdc-eth는 HTML을 반환하고, https://smarts.md/usdc-eth.md는 40줄짜리 Markdown을 반환합니다 — 주소, 체인, 분류, MCP 엔드포인트, AI 에이전트로 질의하는 법, 원본 링크.
# USD Coin on Ethereum
- **Address:** `0xa0b8...`
- **Chain:** Ethereum
- **Classification:** ERC-20 Token
## Query via AI agent
- **MCP endpoint:** `https://smarts.md/mcp/sse`
- **Reference:** `usdc-eth`
- **Sample prompt:** "Tell me the current state of usdc-eth"
AI 에이전트가 .md를 한 번 가져오면 원하는 구조화 정보가 전부 들어 있고 DOM 파서도 필요 없습니다. 이건 Claude가 빨리 해냈습니다 — controller 하나, .md.erb 템플릿 두 개, routes에 (.:format) 추가, 그게 전부.
이건 역방향의 발견입니다. 제 사이트 방문자 중 이미 Claude Code / Cursor / Windsurf를 쓰는 사람들이 일정 비율 있습니다. 계약 페이지를 보고 나면 대개 "내 AI한테 이거 한번 물어보자"가 다음 행동입니다.
그래서 각 계약 페이지에 카드를 렌더링합니다.
usdc-eth) 또는 chain/address, 옆에 복사 버튼mcp.smarts.md 링크 (한 줄 설정)"이 계약을 보고 있다"에서 "내 AI에게 묻고 있다"까지 클릭 한 번의 마찰. 카드는 DaisyUI 카드와 범용 Stimulus copy 컨트롤러로 erb 50줄, 거기에 회귀 테스트가 data-copy-text-value 속성을 고정해 미래의 refactor가 사용자 클립보드에 잘못된 문자열을 조용히 붙이지 못하게 합니다.
OpenGraph, Twitter Card, JSON-LD — 전통 검색과 소셜 카드용 레이어지만, 할 가치가 있습니다. AI 크롤러도 여기를 읽으니까요.
흥미로운 선택은 JSON-LD가 스마트 계약을 어떻게 기술해야 하는가입니다. Claude는 WebPage가 SoftwareApplication을 감싸는 형태를 택했습니다.
{
"@type": "WebPage",
"about": {
"@type": "SoftwareApplication",
"name": "USD Coin",
"applicationCategory": "SmartContract",
"operatingSystem": "Ethereum",
"identifier": "0xa0b8..."
}
}
operatingSystem엔 체인 이름, identifier엔 주소, additionalType엔 분류 (예: "Uniswap V3 Pool"). schema.org에는 전용 SmartContract 타입이 없지만, SoftwareApplication + 이 필드들이면 LLM이 "Ethereum에서 돌아가는, 주소로 식별되는 계약"이라고 이해하기에 충분합니다.
OG 이미지는 1200×630 summary_large_image, Twitter Card, 브레드크럼, softwareVersion, license 필드도 같이 채웠습니다.
위 6개 항목은 4일 동안 7개의 PR에 들어갔습니다.
| PR | 파일 수 | 크기 |
|---|---|---|
feat/ai-crawler-discovery |
2 | ~126줄 |
feat/well-known-mcp-manifest |
4 | ~129줄 |
feat/markdown-contract-pages |
6 | ~298줄 |
feat/contract-mcp-card |
3 | ~126줄 |
feat/seo-meta-tags |
8 | ~292줄 |
feat/seo-enrichments |
8 | ~189줄 |
feat/og-card |
— | — |
각각이 독립된 PR, 독립된 테스트, 독립된 커밋 메시지입니다. 이 잘게 나누는 리듬이 Claude와 협업하는 데서 가장 가치 있는 부분입니다 — 각 PR은 한눈에 diff를 훑을 수 있는 크기를 유지하면서, 쌓아놓고 보면 사이트에 완전한 AI 대응 면이 생겨 있습니다.
콘텐츠형 사이트를 AI 친화적으로 만들고 싶다면 이 순서로 하세요.
robots.txt에서 주요 AI 크롤러를 명시적으로 Allow/llms.txt를 작성 (증류된 메뉴).md 변형 추가/.well-known/mcp.json 공개앞의 5개는 대부분의 SEO 엔지니어가 말해주지 않습니다 — 전통 SEO 플레이북에 없기 때문입니다. 하지만 제 4일치 데이터를 보면 AI 트래픽 곡선과 사람 트래픽 곡선은 완전히 독립된 두 선입니다. 둘 다 돌봐야 합니다.