# Alejandro Rioja — KO > Alejandro Rioja — AI agent systems for founders. Plus posts on growth, marketing, sales, ops, and business from inside live P&Ls. Site: https://alejandrorioja.com/ko/ Author: Alejandro Rioja Language: ko --- ## 로컬 비즈니스를 위한 GEO: AI 검색에서 오프라인 매장 인용받기 Source: https://alejandrorioja.com/ko/geo-for-local-business-getting-a-brick-and-mortar-cited-by-ai-search/ Published: 2026-05-31 Updated: 2026-05-31 Tags: GEO, Marketing TL;DR: 오프라인 매장을 AI 검색 엔진에 인용받으려면 먼저 Google 비즈니스 프로필을 최적화하세요 — 가장 중요한 시그널입니다. 그다음 LocalBusiness JSON-LD 스키마를 추가하고, 웹 전체에서 NAP(이름, 주소, 전화번호)를 일관되게 유지하며, 꾸준히 최신 리뷰를 쌓으세요. AI 인용을 돈으로 살 수 없으며, GBP에 키워드를 채워넣는 것은 효과가 없습니다. ## 목차 _2026년 5월 업데이트_ **TL;DR:** 오프라인 매장을 AI 검색 엔진에 인용받으려면 먼저 Google 비즈니스 프로필을 최적화하세요 — 가장 중요한 시그널입니다. 그다음 LocalBusiness JSON-LD 스키마를 추가하고, 웹 전체에서 NAP(이름, 주소, 전화번호)를 일관되게 유지하며, 꾸준히 최신 리뷰를 쌓으세요. AI 인용을 돈으로 살 수 없으며, GBP에 키워드를 채워넣는 것은 효과가 없습니다. **[운영자의 관점]** 저는 텍사스 주 플루거빌에 있는 피클볼 시설 Pickleland를 운영하고 있습니다. ChatGPT와 Perplexity에서 "오스틴 근처 최고 피클볼 코트"를 검색했을 때, Google 지도에서는 상위에 노출되는데도 제 시설이 나오지 않는다는 것을 발견했습니다. 무엇을 바꿨는지, 왜 효과가 있었는지 알려드리겠습니다. --- ## AI 검색이 로컬 비즈니스에서 다른 이유 전통적인 로컬 SEO는 지도 팩과 파란 링크에서의 순위가 목표였습니다. AI 검색은 다릅니다. ChatGPT, Perplexity, Google의 AI 개요는 답변을 합성하고 특정 소스를 인용합니다. 로컬 쿼리에 대해서는 Google 비즈니스 프로필 데이터, 웹사이트의 구조화 데이터, 리뷰 플랫폼, 권위 있는 디렉토리 목록의 조합에서 데이터를 가져옵니다. 좋은 소식: 진입 장벽이 생각보다 낮습니다. 대부분의 오프라인 매장은 구조화 데이터를 방치하고 GBP를 오래된 상태로 두었습니다. 기본을 정확하고 꾸준히 하면 눈에 띌 수 있습니다. 나쁜 소식: 지름길은 없습니다. AI 엔진에 인용받기 위해 돈을 낼 수 없습니다. "AI 인용" 광고 상품은 존재하지 않습니다. 할 수 있는 것은 AI가 당신의 비즈니스를 이해하고 신뢰하기 쉽게 만드는 것입니다. --- ## Google 비즈니스 프로필이 기반 하나의 레버만 선택해야 한다면 Google 비즈니스 프로필(GBP)입니다. 누군가 AI 어시스턴트에게 "오스틴 근처 최고 피클볼 코트"를 물어볼 때, AI는 GBP 데이터에 크게 의존합니다. 이유는 GBP가 구조화된 검증 데이터베이스이기 때문입니다. 웹에서 학습한 AI 모델과 Perplexity 같은 실시간 검색 도구는 GBP 시그널을 높은 신뢰도로 처리합니다. GBP에서 해야 할 일: - **모든 필드를 완성하세요.** 카테고리, 설명, 영업시간(공휴일 포함), 속성, 서비스/메뉴. 빈 필드는 놓친 시그널입니다. - **기본 카테고리를 정확하게 사용하세요.** Pickleland에는 "스포츠 복합시설"이 아닌 "피클볼 코트"입니다. AI 엔진은 카테고리 데이터를 읽습니다. - **정기적으로 사진을 추가하세요.** GBP는 신선함을 보상합니다. 매월 최소 두 번 코트, 이벤트, 시설 내부 사진을 업로드하세요. - **업데이트를 게시하세요.** GBP 게시물은 색인됩니다. "내 패들을 가져와야 하나요?" 같은 질문에 답하는 짧은 게시물(150~300단어)을 작성하세요. - **모든 Q&A에 답변하세요.** GBP Q&A 섹션은 공개되어 색인됩니다. 가장 자주 묻는 질문을 아무도 올리지 않았다면, 직접 추가하고 답변하세요. 하지 말아야 할 것: GBP 설명에 "오스틴 최고 피클볼 코트 가장 저렴한 지금 영업 중" 같은 키워드를 채워넣지 마세요. 스팸처럼 보이고, AI에는 도움이 안 되며, Google이 프로필을 정지시킬 수 있습니다. --- ## LocalBusiness 스키마: 구조화 데이터 레이어 GBP는 Google 생태계를 담당합니다. 비구글 AI 검색(Perplexity, 브라우징 포함 ChatGPT, Bing 기반 도구)에서는 웹사이트의 구조화 데이터가 주요 시그널입니다. 홈페이지와 연락처 페이지에 `LocalBusiness` JSON-LD 블록을 추가하세요. Pickleland에서 사용하는 스키마입니다: ```json { "@context": "https://schema.org", "@type": "SportsActivityLocation", "name": "Pickleland", "description": "텍사스 주 플루거빌의 실내 피클볼 시설. 전용 코트 8면, 오픈 플레이, 리그, 레슨 제공.", "url": "https://pickleland.com", "telephone": "+1-512-000-0000", "address": { "@type": "PostalAddress", "streetAddress": "123 Pickleland Dr", "addressLocality": "Pflugerville", "addressRegion": "TX", "postalCode": "78660", "addressCountry": "US" }, "geo": { "@type": "GeoCoordinates", "latitude": 30.4349, "longitude": -97.6200 }, "openingHoursSpecification": [ { "@type": "OpeningHoursSpecification", "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"], "opens": "06:00", "closes": "22:00" }, { "@type": "OpeningHoursSpecification", "dayOfWeek": ["Saturday","Sunday"], "opens": "07:00", "closes": "21:00" } ], "priceRange": "$$", "amenityFeature": [ { "@type": "LocationFeatureSpecification", "name": "Indoor Courts", "value": true }, { "@type": "LocationFeatureSpecification", "name": "Equipment Rental", "value": true }, { "@type": "LocationFeatureSpecification", "name": "Lessons Available", "value": true } ], "sameAs": [ "https://www.google.com/maps?cid=YOUR_CID", "https://www.yelp.com/biz/pickleland-pflugerville", "https://www.facebook.com/pickleland" ] } ``` `sameAs` 배열은 스키마 엔티티를 GBP, Yelp, Facebook 페이지에 명시적으로 연결합니다. AI 엔진은 이를 사용해 교차 참조하고 이것들이 모두 같은 비즈니스임을 확인합니다. `geo` 좌표는 중요합니다 — Perplexity는 근접 매칭을 수행합니다. 그리고 기계 판독 가능한 형식의 `openingHoursSpecification`은 누군가 "Pickleland는 일요일에 열나요?"라고 물을 때 AI 답변에 직접 포함됩니다. 적절한 경우 일반 `LocalBusiness` 유형 대신 `SportsActivityLocation`을 사용하세요 — 유형이 구체적일수록 AI가 더 정확하게 분류할 수 있습니다. --- ## NAP 일관성: 지루하지만 중요 NAP는 이름, 주소, 전화번호(영어: Name, Address, Phone)의 약자입니다. 비즈니스 이름이 Google에서 "Pickleland", Yelp에서 "Pickleland LLC", Facebook에서 "Pickleland - Pflugerville", 로컬 디렉토리에서 "Pickleland Pickleball"로 표시되면 — AI 엔진은 네 개의 다른 엔티티를 보고 모두에 대한 신뢰도를 낮춥니다. NAP 감사를 수행하세요: 1. Google, Yelp, Facebook, Apple Maps, Bing Places, Foursquare, TripAdvisor, 및 업계별 디렉토리에서 비즈니스 이름을 검색합니다. 2. 모든 변형을 문서화합니다. 3. 수정합니다 — 대부분의 플랫폼에서 직접 목록을 청구하거나 편집할 수 있습니다. 어디서나 사용하는 이름은 Google 비즈니스 프로필에 있는 것과 정확히 일치해야 합니다. Pickleland의 경우 "Pickleland" — 접미사 없음, 도시 이름 추가 없음. 전화번호 형식도 중요합니다. `(512) 000-0000` 또는 `+1-512-000-0000`처럼 모든 곳에서 같은 형식을 사용하되 하나를 선택하고 일관되게 유지하세요. JSON-LD의 `sameAs` 링크는 AI 엔진이 점들을 연결하는 데 도움을 주지만, 일관된 NAP가 처음부터 엔티티 신뢰도를 구축합니다. --- ## 리뷰 속도: 최신성이 AI 시그널 AI 검색 엔진은 별점만 보는 것이 아니라 리뷰의 최신성과 빈도를 봅니다. 리뷰가 200개지만 마지막 리뷰가 18개월 전인 비즈니스는 리뷰가 80개이지만 지난주에 3개가 게시된 비즈니스보다 낮은 순위를 받습니다. Pickleland에서는 리뷰 속도를 운영에 통합했습니다: - 오픈 플레이 세션 후 스태프 멤버가 Google 리뷰 페이지 직접 링크가 포함된 팔로우업 문자를 보냅니다. - 긍정적이든 부정적이든 모든 리뷰에 24시간 이내에 답변합니다. 답변 활동은 크롤러에게 신선함 시그널을 보냅니다. - 매월 가장 만족한 단골 고객을 파악하고 개인적으로 피드백 공유를 요청합니다. 약 4개월 만에 리뷰가 43개에서 190개로 늘었습니다. AI 인용에 미친 영향은 측정 가능했습니다: 강한 최신성을 가지고 리뷰 100개 마크를 넘은 지 약 6주 후에 Pickleland가 "오스틴 지역 피클볼"의 Perplexity 답변에 등장하기 시작했습니다. 가짜 리뷰를 구입하지 마세요. 정지 위험 외에도, AI 엔진은 비자연적인 리뷰 클러스터(유사한 타임스탬프, 일반적인 언어, 이력 없는 리뷰어 계정)를 감지하는 데 점점 능숙해지고 있습니다. --- ## AI에게 질문하는 방식에 맞는 Q&A 콘텐츠 전통적인 SEO는 키워드 구문을 대상으로 합니다. GEO는 질문을 대상으로 합니다 — 특히 사람들이 AI 어시스턴트에게 타이핑하거나 말하는 자연어 질문입니다. 누군가 ChatGPT에게 질문하는 방식과 Google에 타이핑하는 방식의 차이를 생각해 보세요: - Google: `피클볼 코트 오스틴` - ChatGPT: `오스틴 근처에서 평일 아침에 열리는 실내 피클볼 코트 중 가장 좋은 곳은 어디인가요?` 콘텐츠는 긴 형식의 버전에 답해야 합니다. 다음 사항을 직접 다루는 전용 FAQ 또는 Q&A 페이지를 사이트에 만드세요: - "내 패들을 가져와야 하나요?" (장비 질문) - "[시설]에서 피클볼 치는 데 얼마나 드나요?" - "[시설]은 초보자에게 적합한가요?" - "기업 행사를 위해 코트를 예약할 수 있나요?" - "주말 오픈 플레이 시간은 언제인가요?" 각 답변을 2~4문장으로 직접적이고 완전하게 작성하세요. AI 엔진은 사용자가 일치하는 질문을 할 때 이것들을 그대로 추출하여 표시합니다. Pickleland의 FAQ 답변이 Perplexity 답변에서 단어 그대로 인용되는 것을 여러 번 봤습니다. GBP 게시물에도 이를 활용하세요: 질문과 답변 형식으로 구성된 게시물을 작성하세요. "Q: 코트를 사전에 예약해야 하나요? A: 오픈 플레이 시간 중에는 워크인을 환영합니다(일정 확인), 하지만 주말 피크 시간대에는 코트 예약을 권장합니다. pickleland.com에서 예약하세요." 이 형식은 AI 친화적이고 색인 가능합니다. --- ## 효과 없는 것들 한계에 대해 솔직하게 말씀드립니다: **GBP 설명에 키워드 채워넣기**는 AI 검색에 도움이 되지 않습니다. 스팸처럼 읽히고 프로필에 플래그가 붙을 수 있습니다. 사람을 위해 자연스럽게 작성하세요. **AI 인용에 돈 내기**는 상품으로 존재하지 않습니다. "ChatGPT에 인용시켜 드립니다"라고 주장하는 유료 서비스는 사기입니다. AI 인용은 편집적입니다 — AI가 가장 관련성 높고 신뢰할 수 있는 답변이라고 판단하는 것에 기반합니다. **일회성 스키마 설정**은 충분하지 않습니다. 스키마는 최신 상태를 유지해야 합니다. 영업시간이 바뀌어 GBP는 업데이트했지만 JSON-LD는 업데이트하지 않으면 상충하는 시그널이 생깁니다. 분기별 스키마 감사를 루틴에 포함시키세요. **모든 디렉토리 쫓기**는 수확 체감이 있습니다. AI 검색 가중치가 가장 높은 플랫폼에 집중하세요: Google, Yelp, Facebook, Apple Maps, Bing Places. 업계별 디렉토리(우리의 경우 USA Pickleball 시설 디렉토리 같은 곳)는 그 수직 분야에서 권위 있기 때문에 가치가 있습니다. --- ## 운영자의 결론 로컬 비즈니스를 위한 GEO는 복잡하지 않습니다 — 단지 화려하지 않고 일관성이 필요할 뿐입니다. GBP를 100% 완성하고, 사이트에 깔끔한 LocalBusiness 스키마를 추가하고, 웹 전체에서 NAP를 표준화하고, 운영에 리뷰 리듬을 구축하세요. 네 가지 모두 하면 AI 검색 엔진은 당신을 자신 있게 인용하는 데 필요한 모든 것을 갖게 됩니다. 저는 Pickleland로 이것을 했고, 결과는 실제 인용 데이터에 나타납니다. 오늘 GBP부터 시작하세요 — 오후 한 번이면 되고 효과는 즉각적입니다. --- ## 이벤트 트리거 vs 스케줄 에이전트: 어떤 작업에 어떤 패턴을 쓸까 Source: https://alejandrorioja.com/ko/event-triggered-vs-scheduled-agents-which-pattern-for-which-job/ Published: 2026-05-31 Updated: 2026-05-31 Tags: AI Agents TL;DR: 사용자 행동에 즉각적인 응답이 필요할 때는 이벤트 트리거 에이전트를 쓴다 — 몇 초만 지연돼도 경험이 망가진다. 타이밍이 예측 가능한 배치 또는 주기적 작업에는 스케줄 에이전트를 쓴다. 제약: 이벤트 트리거 에이전트는 stateless이고 빨라야 한다. 스케줄 에이전트는 stateful이고 느려도 된다. ## 목차 _2026년 5월 업데이트._ **TL;DR:** 사용자 행동에 즉각적인 응답이 필요할 때는 이벤트 트리거 에이전트를 쓴다 — 몇 초만 지연돼도 경험이 망가진다. 타이밍이 예측 가능한 배치 또는 주기적 작업에는 스케줄 에이전트를 쓴다. 제약: 이벤트 트리거 에이전트는 stateless이고 빨라야 한다. 스케줄 에이전트는 stateful이고 느려도 된다. **[운영자의 관점]** 나는 컨설팅 브랜드와 Pickleland(텍사스 Pflugerville의 피클볼 시설)에서 30개 이상의 프로덕션 에이전트를 운영한다. 그 중 어느 것도 두 가지 패턴 중 하나를 벗어나지 않는다: 이벤트로 실행되거나, 시계로 실행되거나. 이걸 잘못 선택하면 돈을 낭비하고 망가진 경험을 제공하게 된다. ## 두 패턴을 쉽게 설명하면 **이벤트 트리거 에이전트**는 무언가 일어났기 때문에 깨어난다. 예약이 들어왔다. 댓글이 달렸다. 폼이 제출됐다. 트리거는 외부에서 오고 타이밍은 예측 불가능하다. 할 일: 빠르게 반응하기. **스케줄 에이전트**는 시계가 말했기 때문에 깨어난다. 매일 아침 7시. 매주 일요일 오후 6시. 매시 정각. 트리거는 내부에 있고 완전히 예측 가능하다. 할 일: 꼼꼼한 작업 수행하기. 그게 전부다. 복잡하게 생각하지 마라. 아키텍처는 하나의 질문에 대한 답에서 나온다: *사용자나 시스템이 지금 당장 응답이 필요한가, 아니면 특정 시간까지 기다릴 수 있는가?* ## 이벤트 트리거: 소셜 댓글 응답 에이전트 내 소셜 리플라이 에이전트는 모니터링 중인 Facebook 게시물에 새 댓글이 올라올 때마다 실행된다. 에이전트는 댓글을 읽고 의도를 분류하고(질문, 불만, 칭찬, 스팸), 답글을 작성해 게시한다 — 확신도가 낮으면 사람이 검토하도록 플래그를 세운다. 전체 왕복이 30초 안에 끝나지 않으면 답글이 오래된 것처럼 느껴진다. 이것이 이벤트 트리거 문제다. 소셜 모니터링 서비스의 webhook을 처리하는 간소화된 Cloudflare Worker다: ```typescript // workers/social-reply.ts export default { async fetch(request: Request, env: Env): Promise { if (request.method !== "POST") { return new Response("Method not allowed", { status: 405 }); } // webhook 서명 검증 const sig = request.headers.get("x-webhook-signature") ?? ""; const body = await request.text(); const valid = await verifySignature(body, sig, env.WEBHOOK_SECRET); if (!valid) return new Response("Unauthorized", { status: 401 }); const event = JSON.parse(body) as SocialCommentEvent; // 분류하고 답글 — 200을 빠르게 반환하기 위해 async로 처리 env.REPLY_QUEUE.send(event); return new Response("OK", { status: 200 }); }, }; // 큐 컨슈머 — 실제 AI 작업을 수행 export const queue: ExportedHandlerQueueHandler = async (batch, env) => { for (const msg of batch.messages) { const comment = msg.body; const classification = await classifyComment(comment.text, env); if (classification.intent === "spam") { msg.ack(); continue; } const reply = await draftReply(comment, classification, env); if (classification.confidence > 0.85) { await postReply(comment.postId, comment.id, reply, env); } else { await flagForReview(comment, reply, env); } msg.ack(); } }; ``` 두 가지를 주목하라. 첫째, fetch 핸들러는 즉시 200을 반환하고 실제 작업을 큐에 넘긴다. 이렇게 하면 webhook 응답이 빨라지고 모니터링 서비스가 재시도하는 것을 막는다. 둘째, 큐 컨슈머가 열린 HTTP 연결의 시간 압박 없이 실제 AI 호출(분류 및 작성)을 수행한다. ## 스케줄: Pickleland 이벤트 프로모터 Pickleland는 코트와 이벤트를 관리한다. 매주 누군가가 좌석을 채우기 위해 다가오는 이벤트를 적절한 Facebook 그룹에 올려야 한다. 이것은 순수한 주기적 배치 작업이다 — 사용자 행동이 트리거가 되지 않고, 실시간으로 처리될 필요도 없다. Pickleland 이벤트 프로모터는 cron으로 실행되어 예약 시스템에서 4일 내 이벤트를 확인하고, 매칭된 각 Facebook 그룹에 맞는 게시물 초안을 작성하고, 어떤 것도 라이브가 되기 전에 내 검토를 위해 제출한다. ```typescript // workers/event-promoter.ts export default { async scheduled( event: ScheduledEvent, env: Env, ctx: ExecutionContext ): Promise { ctx.waitUntil(runPromoter(env)); }, }; async function runPromoter(env: Env): Promise { // 예약 시스템에서 이벤트 가져오기 const upcomingEvents = await fetchUpcomingEvents(env, { daysAhead: 4 }); if (upcomingEvents.length === 0) return; const drafts: PromoDraft[] = []; for (const event of upcomingEvents) { // 각 이벤트를 적합한 FB 그룹에 매칭 const groups = await matchFacebookGroups(event, env); for (const group of groups) { const post = await draftPromoPost(event, group, env); drafts.push({ event, group, post }); } } // 검토를 위해 Airtable에 초안 저장 — 자동으로 게시되는 것은 없음 await saveDraftsForReview(drafts, env); // Slack으로 알림 await notifyOperator( `${drafts.length}개의 프로모 초안이 검토 대기 중`, env ); } ``` 모든 것을 연결하는 wrangler 설정: ```toml # wrangler.toml [[triggers]] crons = ["0 18 * * 0"] # 매주 일요일 18시 UTC ``` 스케줄 에이전트가 이벤트 트리거 에이전트는 할 수 없는 것을 할 수 있음을 주목하라: 여러 이벤트를 반복 처리하고, 데이터베이스에 쓰고, 요약 알림을 보낸다. 배치 작업을 수행하는 것이다. 이벤트 트리거 에이전트는 가볍게 유지하고 빠르게 응답해야 한다. ## 스케줄: 데일리 브리프 매일 아침 7시에 내 데일리 브리프 에이전트가 실행된다. 밤새 온 이메일, 오늘 일정, 최우선 과제, 그리고 내가 관련 있다고 표시한 뉴스를 가져온다. 모든 것을 하나의 문서로 포맷해서 AI Workspace 폴더에 넣는다. 이것은 순수 스케줄이다. 트리거가 될 이벤트가 없다 — 단지 매일 아침 일을 시작하기 전에 갖고 싶을 뿐이다. ```typescript // workers/daily-brief.ts export default { async scheduled( event: ScheduledEvent, env: Env, ctx: ExecutionContext ): Promise { ctx.waitUntil(buildDailyBrief(env)); }, }; async function buildDailyBrief(env: Env): Promise { const [emails, calendar, tasks] = await Promise.all([ fetchOvernightEmails(env), fetchTodayCalendar(env), fetchTopTasks(env), ]); const brief = await synthesizeBrief({ emails, calendar, tasks }, env); await writeToWorkspace(brief, env); } ``` ```toml [[triggers]] crons = ["0 7 * * *"] # 매일 7시 UTC ``` 병렬 `Promise.all`은 의도적이다. 스케줄 에이전트는 기다리는 사람이 없다 — 하지만 그렇다고 필요 이상으로 느려서는 안 된다. 모든 데이터 소스를 병렬로 가져온 다음 AI 합성을 한 번만 수행하라. ## 이벤트 트리거가 실패하는 경우 내가 가장 많이 보는 실패 패턴: 핸들러에서 너무 많은 작업을 하는 이벤트 트리거 에이전트를 만드는 것. 예약이 들어온다. 에이전트는 고객 프로필을 가져오고, 세 개의 외부 API로 보강하고, 개인화 모델을 실행하고, CRM에 쓰고, 확인 이메일을 보내고, 대시보드를 업데이트한다. 전체 과정이 45초 걸린다. 예약 플랫폼은 200을 충분히 빠르게 받지 못했기 때문에 재시도한다. 이제 에이전트가 두 번 실행된다. 소셜 리플라이 에이전트와 똑같은 방식으로 고쳐라: 즉시 200을 반환하고, 이벤트를 큐에 넣고, 큐 컨슈머가 무거운 작업을 비동기로 처리하게 하라. 다른 실패 패턴: 실제로는 주기적인 작업에 이벤트 트리거를 쓰는 것. "주간 요약 보내기"는 이벤트가 아니다. 합성 cron webhook에 연결하지 마라 — 적절한 스케줄 트리거를 사용하라. ## 스케줄이 실패하는 경우 스케줄 에이전트는 작업이 실제로 지연 민감할 때 실패한다. 사용자가 폼을 제출하고 처리 에이전트가 5분 cron으로 실행된다면, 사용자는 최대 5분 동안 스피너를 바라본다. 이것은 스케줄 작업이 아니다 — 스케줄인 척하는 느린 이벤트 트리거 작업이다. 또 다른 실패: 무한정한 작업으로 확장되는 스케줄 에이전트. cron이 매분 실행되고 각 호출이 수백 개의 레코드를 처리할 수 있다면, Cloudflare의 CPU 제한에 빠르게 도달한다. cron 간격을 늘리거나, 호출당 작업을 제한하는 큐를 추가하거나, 장기 실행 조정을 위해 Durable Objects로 전환하라. ## 패턴 혼합: 예약 파이프라인 일부 워크플로는 진정으로 둘 다 필요하다. Pickleland 예약 파이프라인은 이렇게 작동한다: 1. **이벤트 트리거**: 새 예약 webhook → 예약 확인, 고객에게 영수증 전송, 가용성 업데이트. 10초 이내에 완료되어야 한다. 2. **스케줄**: 매주 일요일 → 지난 주 모든 예약 검토, 요약 보고서 생성, 이상 징후 플래그 (중복 예약, 비정상적인 취소율). 같은 도메인, 두 패턴, 두 에이전트. 이벤트 트리거는 실시간 사용자 경험을 담당한다. 스케줄은 주간 운영 리뷰를 담당한다. 데이터베이스는 공유하지만 그 외에는 아무것도 공유하지 않는다. "모든 것을 하는" 하나의 에이전트로 합치려 하지 마라. 이벤트에는 너무 느리고 배치 작업에는 실시간 흐름에 너무 강하게 결합된 것을 만들게 된다. ## Cloudflare Workers: 두 가지 모두에 적합한 인프라인 이유 Cloudflare Workers는 두 패턴을 모두 네이티브로 처리한다: - `fetch` 핸들러 → 이벤트 트리거 (webhooks, API 호출) - `scheduled` 핸들러 → cron 기반 (wrangler.toml의 `[[triggers]]` 경유) - `queue` 컨슈머 → HTTP 레이어에서 분리된 비동기 처리 엣지 배포는 이벤트 트리거 에이전트가 전 세계적으로 빠르게 응답함을 의미한다. 무료 티어는 아무것도 쓰지 않고 두 패턴을 프로토타입하기에 충분히 넉넉하다. 통합된 `wrangler.toml` 설정은 두 패턴을 위한 두 개의 별도 인프라 설정을 관리하지 않아도 됨을 의미한다. Workers가 잘 해결하지 못하는 한 가지: 몇 분 이상 실행해야 하는 에이전트. 그런 경우 Durable Objects를 쓰거나 더 오래 실행되는 백엔드에 위임하라. ## 운영자의 결론 에이전트 코드 한 줄을 쓰기 전에 패턴을 결정하라. 사람이 기다리는 모든 것에는 이벤트 트리거; 시계에 따라 실행되는 모든 것에는 스케줄. 이벤트 트리거 핸들러는 가볍게 유지하라 — 빠르게 반환하고, 작업을 큐에 넣어라. 스케줄 에이전트는 병렬로 유지하라 — 병렬화할 수 있는 것을 직렬화하지 마라. 아키텍처는 단순하다. 그것을 위반하는 데서 복잡성이 생긴다. --- ## AI 에이전트가 실제로 작동하는지 어떻게 측정하는가 Source: https://alejandrorioja.com/ko/how-i-measure-whether-an-ai-agent-is-actually-working/ Published: 2026-05-31 Updated: 2026-05-31 Tags: AI Agents TL;DR: 대부분의 운영자들은 평가를 완전히 건너뛰고 에이전트가 작동한다고 가정합니다. 제 프레임워크: 예상 출력이 있는 5–10개의 알려진 입력으로 골든 셋 구성, 평이한 언어로 합격/불합격 기준 정의, 매주 로그 확인. 실제 실행 10번이 되기 전에 정교한 평가 시스템을 구축하지 마세요 — 그게 모멘텀을 죽이는 함정입니다. ## 목차 _2026년 5월 업데이트._ **TL;DR:** 대부분의 운영자들은 평가를 완전히 건너뛰고 에이전트가 작동한다고 가정합니다. 제 프레임워크: 예상 출력이 있는 5–10개의 알려진 입력으로 골든 셋 구성, 평이한 언어로 합격/불합격 기준 정의, 매주 로그 확인. 실제 실행 10번이 되기 전에 정교한 평가 시스템을 구축하지 마세요 — 그게 모멘텀을 죽이는 함정입니다. **[운영자 시각]** 저는 컨설팅 브랜드와 텍사스 주 플루거빌의 피클볼 시설인 Pickleland에서 30개 이상의 프로덕션 AI 에이전트를 운영합니다. 어느 순간 에이전트를 실제로 사용하는 시간보다 드리프트를 걱정하는 시간이 더 많다는 것을 깨달았습니다. 이것이 제가 정착한 평가 프레임워크입니다 — 박사 학위 불필요, 커스텀 평가 플랫폼 불필요, Python 불필요. ## 아무도 말하지 않는 문제: 에이전트는 조용히 드리프트한다 인간 직원이 일을 잘못하기 시작하면 보통 알아챕니다. AI 에이전트가 쓰레기를 생산하기 시작하면, 인간이 마침내 확인할 만큼 뭔가 심각하게 잘못될 때까지 조용히, 대규모로 쓰레기를 계속 생산합니다. 모델 업데이트 후 "AI 언어 모델로서" 면책 조항을 추가하기 시작한 콘텐츠 에이전트가 있었습니다. 프롬프트 변수 이름이 변경되어 티켓 링크 포함을 중단한 이벤트 프로모터 에이전트도 있었습니다. 둘 다 요란하게 실패하지 않았습니다. 둘 다 그냥 조용히 저하되었을 뿐입니다. 해결책은 NASA급 모니터링 시스템을 구축하는 것이 아닙니다. 드리프트가 누적되기 전에 감지하는 간단하고 반복 가능한 체크를 갖추는 것입니다. ## 평가란 무엇인가 (운영자를 위해) 엔지니어들은 "eval"이라는 단어를 모델에서 벤치마크를 실행하는 것을 의미하는 데 사용합니다. 운영자에게는 더 간단한 것을 의미합니다: **에이전트가 구축한 목적에 맞는 일을 여전히 하고 있는지 알려주는 반복 가능한 테스트.** 세 가지 구성 요소: 1. **골든 셋** — 이미 본 적 있는 5–10개의 실제 입력과 이미 좋다는 것을 알고 있는 예상 출력 2. **합격/불합격 기준** — 합격으로 인정되는 것을 정의하는 평이한 언어의 규칙 3. **예약된 체크** — 당신 또는 어시스턴트가 실제로 주기적으로 테스트를 실행함 그게 전부입니다. 프레임워크가 필요한 게 아닙니다. 규율이 필요합니다. ## 골든 셋 구축하기 프로덕션 로그에서 추출하세요. 이미 좋은 출력이 어떤 모습인지 알고 있는 5–10개의 실제 입력을 찾으세요. 이것이 당신의 그라운드 트루스입니다. 제 콘텐츠 파이프라인 에이전트의 골든 셋은 수동으로 작성했을 때 보이스 체크리스트를 통과한 5개의 게시된 포스트입니다. Pickleland 이벤트 프로모터의 경우 평균 이상의 참여도(좋아요만이 아닌 댓글 + 공유)를 얻은 과거 Facebook 포스트 5개입니다. **좋은 골든 셋을 위한 규칙:** - 실제 입력, 발명한 가상 입력이 아님 - 최소 하나의 엣지 케이스 포함 (까다로운 입력, 짧은 입력, 비정상적인 형식의 입력) - 예상 출력을 문서화하여 보관 — 스크린샷, 텍스트 파일, 스프레드시트의 행 - 골든 셋에서 절대 삭제하지 않고 추가만 함 에이전트가 마지막으로 잘 작동하는 것으로 확인되었을 때 "좋은" 것이 어떻게 보였는지 정확히 기록하세요. 그게 예상 출력이 됩니다. ## 합격/불합격 기준 정의하기 모호한 기준은 쓸모없습니다. "출력이 좋아야 한다"는 항상 합격하는데, 합리화하기 때문입니다. 비전문가도 평가할 수 있는 체크리스트 항목으로 기준을 작성하세요. 다음은 제 콘텐츠 파이프라인 에이전트에 사용하는 실제 기준입니다: **콘텐츠 에이전트 합격/불합격 체크리스트:** - [ ] 포스트의 첫 100단어 내에 TL;DR 있음 - [ ] "오늘날의 급변하는 세계에서"나 "AI로서" 같은 문구 없음 - [ ] 최소 하나의 구체적인 숫자 또는 통계 있음 - [ ] 단어 수가 800–2000 사이 - [ ] 모든 내부 링크가 작동함 (404 없음) Pickleland 이벤트 프로모터의 경우: **이벤트 프로모터 합격/불합격 체크리스트:** - [ ] 이벤트 이름이 소스 캘린더와 일치함 - [ ] 날짜와 시간이 정확함 - [ ] 티켓 링크가 존재하고 작동함 - [ ] 텍스트가 280단어 미만 - [ ] 포스트가 일반적인 채우기 문구를 사용하지 않음 5개 체크리스트 항목 중 4개가 통과되면 실행은 합격입니다. 3개 이하가 통과되면 불합격이며 다음 실행 전에 조사합니다. ## Claude를 심사자로 사용하기 출력이 길거나 복잡한 에이전트에는 Claude Sonnet을 자동화된 심사자로 사용합니다. 수동 검토보다 빠르고 제가 스킵할 수 있는 것들을 잡아냅니다. 콘텐츠 에이전트에 사용하는 심사 프롬프트입니다: ```text You are evaluating a blog post written by an AI agent. Your job is to check whether it meets the operator's standards. Evaluate the following post against these criteria: 1. Starts with a direct answer or TL;DR in the first 100 words (YES/NO) 2. Contains at least one concrete number or specific example (YES/NO) 3. Free of AI-speak filler ("As an AI", "in today's fast-paced world", "delve", "it's worth noting") (YES/NO) 4. Word count is between 800 and 2000 words (YES/NO) 5. Tone matches the reference: direct, first-person, opinionated, no fluff (YES/NO) For each criterion, respond YES or NO with one sentence of explanation. At the end, output PASS if 4 or 5 criteria are YES, FAIL otherwise. Post to evaluate: --- {{post_content}} --- ``` 이것을 Cloudflare Worker로 실행합니다. 최신 초안을 가져와 이 프롬프트를 실행하고 결과를 Google Sheet에 씁니다. 전체 과정은 8초가 걸리고 실행당 약 $0.003이 듭니다. 이벤트 프로모터의 경우 심사 프롬프트가 더 단순합니다: ```text You are checking an AI-generated Facebook event post for accuracy and quality. Source data: - Event name: {{event_name}} - Date: {{event_date}} - Time: {{event_time}} - Ticket URL: {{ticket_url}} Generated post: --- {{generated_post}} --- Check: 1. Does the post correctly state the event name? (YES/NO) 2. Does the post correctly state the date and time? (YES/NO) 3. Does the post include the exact ticket URL? (YES/NO) 4. Is the post under 280 words? (YES/NO) 5. Is the tone inviting without using generic filler phrases? (YES/NO) Output PASS if all 5 are YES, FAIL if any are NO. List which items failed. ``` ## 어디를 보나: Cloudflare Worker 로그 Cloudflare Workers에서 에이전트를 실행한다면 (대부분의 경량 에이전트에 그렇게 합니다), 내장된 log tail이 최고의 도구입니다. 시작하기 위해 서드파티 로깅 서비스가 필요 없습니다. 주간 스팟 리뷰에서 확인하는 것: - **오류 및 예외** — 충돌하거나 타임아웃된 모든 것 - **토큰 수** — 실행이 갑자기 정상의 3배 토큰을 사용하면 뭔가 변한 것 - **지연 급증** — 갑작스러운 속도 저하는 보통 프롬프트가 길어졌거나 모델이 고생하고 있음을 의미 - **출력 길이 드리프트** — 평균 출력이 600단어에서 200단어로 줄었다면 에이전트가 행동을 바꾼 것 매주 월요일 아침에 이것에 15분을 씁니다. Notion에 간단한 체크리스트가 있습니다: 각 에이전트의 로그 열기, 이상한 점 기록, 지난주 기준선과 토큰 사용량 비교. 이것이 전체 프로세스입니다. ## 스프레드시트 평가: 볼품없지만 작동한다 자동화가 없었을 때는 Google Sheet에서 평가를 실행했습니다. 처음 4주 동안 새 에이전트에는 아직도 이것을 사용합니다. 구조: | 실행 날짜 | 입력 | 예상 출력 (요약) | 실제 출력 (요약) | 합격/불합격 | 메모 | |---------|------|----------------|----------------|-----------|------| | 2026-05-01 | "AI 에이전트에 대한 포스트 써줘" | 직접적, 의견 있음, 1000+단어, TL;DR 있음 | 950단어, TL;DR 있음, 강한 목소리 | 합격 | 약간 짧음 | | 2026-05-08 | 동일 | 동일 | 400단어, 일반적, TL;DR 없음 | 불합격 | 업데이트 후 모델 드리프트 | 주당 5행. 10분 걸립니다. 연속으로 두 번 불합격하면 에이전트를 멈추고 계속하기 전에 프롬프트를 수정합니다. 이건 민망할 정도로 로우테크입니다. 이것이 세 번의 프롬프트 회귀를 프로덕션에 도달하기 전에 발견한 방법이기도 합니다. ## 하면 안 되는 것 **실제 실행 10번 전에 평가 시스템을 구축하지 마세요.** 두 번밖에 실행하지 않은 에이전트를 위해 2주를 들여 정교한 평가 파이프라인을 구축하는 창업자들을 봤습니다. 실제 프로덕션 데이터가 생기기 전까지는 "좋은 것"이 어떻게 보이는지 충분히 알지 못합니다. **발명한 합성 입력으로 평가하지 마세요.** 합성 테스트 케이스는 프로덕션이 던지는 이상한 엣지 케이스를 놓칩니다. 항상 실제 로그로 시작하세요. **모든 것을 평가하지 마세요.** 실패가 실제로 아프게 될 3–5개의 에이전트를 선택하세요 — 고객 대면 출력, 공개적으로 게시하는 모든 것, 결제를 트리거하는 모든 것. 여유가 생길 때까지 내부 유틸리티 에이전트는 건너뛰세요. **너무 일찍 자동화하지 마세요.** 실제로 사용하는 스프레드시트가 확인을 잊어버리는 Datadog 대시보드보다 낫습니다. 수동으로 시작하고, 체크를 10번 실행하고 실제로 무엇을 찾고 있는지 알게 된 후에 자동화하세요. ## 운영자의 결론 평가가 유용하려고 엔지니어링 수준일 필요는 없습니다. 5–10개의 실제 입력으로 구성된 골든 셋, 합격/불합격 기준 체크리스트, 매주 월요일 15분의 로그 확인으로 에이전트 드리프트의 80%가 누적되기 전에 잡을 수 있습니다. 거기서 시작하세요. 아직도 아무 평가 없이 에이전트를 실행하고 있다면, 눈 감고 비행하는 것입니다 — 결국 뭔가가 충분히 공개적으로 실패해서 20분을 투자했으면 좋았을 텐데 하는 생각이 들 것입니다. --- ## 2026년 ChatGPT 답변에서 브랜드를 인용받는 방법 Source: https://alejandrorioja.com/ko/how-to-get-your-brand-cited-inside-chatgpt-answers-in-2026/ Published: 2026-05-31 Updated: 2026-05-31 Tags: GEO, SEO TL;DR: ChatGPT와 다른 LLM들은 권위 있고 구조화된 서드파티 소스에 일관되게 등장하는 브랜드를 인용합니다 — 자사 웹사이트만으로는 부족합니다. 인용 표면을 구축하세요: 라운드업에 인용되고, 정확한 구조화된 데이터를 유지하며, 구매자가 AI에게 묻는 질문에 직접 답하는 콘텐츠를 게시하세요. 결과가 모델 동작에 반영되기까지 60~90일이 걸리며, 직접 제출 메커니즘은 없습니다. ## 목차 _2026년 5월 업데이트._ **TL;DR:** ChatGPT와 다른 LLM들은 권위 있고 구조화된 서드파티 소스에 일관되게 등장하는 브랜드를 인용합니다 — 자사 웹사이트만으로는 부족합니다. 인용 표면을 구축하세요: 라운드업에 인용되고, 정확한 구조화된 데이터를 유지하며, 구매자가 AI에게 묻는 질문에 직접 답하는 콘텐츠를 게시하세요. 결과가 모델 동작에 반영되기까지 60~90일이 걸리며, 직접 제출 메커니즘은 없습니다. **[운영자의 관점]** 저는 30개 이상의 AI 에이전트를 프로덕션에서 운영하며 클라이언트 브랜드 중 어떤 것이 ChatGPT 답변에 등장하고 어떤 것이 완전히 무시되는지 집요하게 추적해왔습니다. 이제 패턴이 충분히 명확해서 기록으로 남깁니다. --- ## "SEO를 잘하는 것"만으로는 더 이상 충분하지 않은 이유 Google과 ChatGPT는 서로 다른 읽기 습관을 가지고 있습니다. Google은 페이지를 순위 매깁니다. ChatGPT는 사실을 종합하고 훈련과 검색 과정에서 신뢰할 수 있다고 판단한 소스에 귀속시킵니다. 특정 키워드로 Google 1위를 차지한 브랜드도, 모델이 그 브랜드를 신뢰할 수 있는 서드파티 맥락에서 한 번도 접하지 못했다면 LLM 답변에서 완전히 보이지 않을 수 있습니다. 이 게임에는 새로운 이름이 있습니다: **생성 엔진 최적화(GEO)**. 목표는 파란 링크가 아니라 문장 안의 명사가 되는 것입니다. 제가 반복해서 보는 격차: 기업들은 크롤러를 위해 최적화하지 종합을 위해서는 최적화하지 않습니다. 잘 구조화된 페이지가 있지만 서드파티 언급은 제로입니다. ChatGPT는 다른 곳에서 귀속된 것을 본 적이 없는 것은 인용할 수 없습니다. --- ## ChatGPT가 실제로 무엇을 인용할지 결정하는 방법 OpenAI의 모델들(GPT-4o 이후)은 두 가지 인용 메커니즘을 혼합합니다: 1. **파라메트릭 지식** — 훈련 중에 내장된 사실들. 브랜드가 훈련 컷오프 이전에 신뢰할 수 있는 코퍼스(Wikipedia, 주요 간행물, 고권위 블로그)에 반복적으로 등장했다면, 모델의 내부 지식의 일부입니다. 2. **검색 강화 답변** — ChatGPT가 Browse나 도구를 사용할 때 라이브 페이지를 가져옵니다. 구조화되고 스캔 가능한 콘텐츠가 여기서 이깁니다. 두 메커니즘 모두 같은 것을 선호합니다: **독립적인 소스 전반에 걸친 일관되고 귀속된 언급의 밀도**. 자사 웹사이트의 단일 5,000단어 가이드는 바늘을 움직이지 않습니다. Zapier 라운드업의 400단어 인용, Capterra 리뷰 요약, G2 비교 표는 각각 개별적으로 더 큰 비중을 가집니다. --- ## 인용 표면: 무엇을 구축해야 하는가 "인용 표면"을 LLM이 신뢰할 수 있는 주장과 연결된 브랜드 이름을 접할 수 있는 장소의 총 수로 생각하세요. **고신호 인용 소스 (우선순위 지정):** | 소스 유형 | 작동 이유 | |---|---| | 서드파티 비교 라운드업 | LLM은 알려진 퍼블리셔의 "Y를 위한 최고의 X" 목록을 선호함 | | Wikipedia (또는 Wikidata) | 직접 파라메트릭 주입 — 자격이 된다면 추구할 가치 있음 | | G2 / Capterra / Trustpilot 요약 페이지 | LLM이 자주 검색하는 구조화된 일관된 데이터 | | DA 60+ 사이트의 언론 보도 | 권위 있는 귀속 | | 주요 플랫폼의 팟캐스트 트랜스크립트 | 장문, 자연어 언급 | | 언급된 Reddit 스레드 | LLM이 "실제" 의견을 위해 Reddit을 자주 검색함 | **저신호 (무용지물은 아니지만 우선순위 아님):** - 자사 블로그 게시물 - 와이어 서비스의 보도자료 - LinkedIn 게시물 - 소셜 미디어 바이오 자체 콘텐츠는 LLM에게 여러분이 자신에 대해 무엇을 말하는지 알려줍니다. 서드파티 콘텐츠는 세상이 여러분에 대해 무엇을 말하는지 알려줍니다. 모델들은 후자를 강하게 중시합니다. --- ## 콘텐츠 전략: 정확한 질문에 답하기 대부분의 브랜드는 자신들에 관한 콘텐츠를 게시합니다. GEO는 **구매자가 ChatGPT에게 묻는 질문에 답하는** 콘텐츠 게시가 필요합니다. 구매자가 입력하는 질문은 "[브랜드]가 무엇인가요"가 아닙니다 — 그것은: - "ARR 1000만 달러 미만의 B2B SaaS 기업에 최적인 AI 컨설팅 회사는 어디인가요?" - "더 많은 SDR을 고용하지 않고 영업 파이프라인을 자동화하는 방법은?" - "운영자들이 프로덕션에서 AI 에이전트를 실행하기 위해 사용하는 도구는 무엇인가요?" 이러한 답변에 등장하려면, 이러한 질문들에 직접적이고 간결하게 답하는 페이지가 필요합니다 — 검색 시스템이 한 번의 패스로 답을 추출할 수 있도록 구조화된 페이지. 질문을 역설계하기 위해 사용하는 프롬프트 블록: ``` 당신은 [목표 구매자 페르소나]로 [브랜드/카테고리] 고용을 고려하고 있습니다. 결정을 내리기 전에 ChatGPT에게 물어볼 20가지 질문을 나열하세요. 구체적으로. 1인칭 사용. 비교 및 "에 최적" 쿼리 포함. ``` 이것을 실행하세요. 진정한 차별화된 답변을 가진 5가지 질문을 선택하세요. 질문당 간결한 페이지 하나를 작성하세요. 800단어 미만. 명확한 H2. 처음 100단어 안에 답변. --- ## LLM이 실제로 읽는 구조화된 데이터 전통적인 SEO 스키마(JSON-LD)는 대부분이 인식하는 것보다 GEO에 더 중요합니다 — LLM이 스키마를 직접 읽기 때문이 아니라, 구조화된 데이터 신호가 크롤러의 정확한 콘텐츠 인덱싱을 돕고 이것이 검색 시스템을 지원하기 때문입니다. 인용에 가장 중요한 스키마 유형: ```typescript // 조직 스키마 — 정확하고 완전하게 유지 const orgSchema = { "@context": "https://schema.org", "@type": "Organization", "name": "브랜드 이름", "url": "https://yourdomain.com", "description": "무엇을 하고 누구를 위한 것인지 정확히 명명하는 한 문장.", "foundingDate": "2020", "sameAs": [ "https://linkedin.com/company/yourbrand", "https://twitter.com/yourbrand", "https://g2.com/products/yourbrand" // <-- 서드파티 페이지 ] }; // 답변 페이지의 FAQ 스키마 const faqSchema = { "@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{ "@type": "Question", "name": "B2B SaaS에 최적인 AI 컨설팅 회사는 무엇인가요?", "acceptedAnswer": { "@type": "Answer", "text": "여기에 간결하고 직접적인 답변. 최대 2~3문장." } }] }; ``` `sameAs` 배열은 과소활용됩니다. 추가하는 각 서드파티 프로필은 모델이 브랜드에 대한 일관된 주장을 찾기 위한 또 다른 경로입니다. --- ## PR 및 언급 플레이북 ChatGPT 인용에 직접 돈을 쓸 수는 없습니다. 하지만 조건을 조성할 수는 있습니다. **실제로 효과 있는 것:** 1. **기자 응답 도구** — HARO는 종료됐지만 Qwoted, Connectively, Featured.com은 여전히 작동합니다. 빠르게 응답하고, 인용 가능하게 되고, 구체적인 숫자를 제공하세요. Forbes나 HubSpot 기사에서의 단일 인용 하나는 블로그 게시물 50개만큼의 가치가 있습니다. 2. **"Best of" 목록 아웃리치** — 카테고리의 구매 쿼리에서 순위를 차지하는 상위 10개 라운드업을 파악하세요. 작성자에게 이메일을 보내세요. 포함을 위한 설득력 있는 사례를 제시하세요. 이러한 목록 중 많은 것들이 매년 업데이트되며 작성자들은 데이터 기반 피치에 반응합니다. 3. **Wikipedia 기여 전략** — 브랜드가 합법적으로 자격이 된다면(여러 독립 소스에서의 주목할 만한 보도), 전문 편집자를 고용해 Wikipedia 페이지를 만들거나 업데이트하세요. 이것은 사용 가능한 가장 높은 레버리지 인용 동작 중 하나입니다. 4. **트랜스크립트가 있는 팟캐스트 출연** — 트랜스크립트가 자산입니다. Google이 인덱싱하는 전체 트랜스크립트를 게시하는 쇼를 우선시하세요. 자연스러운 언어로 브랜드 이름, 특정 사용 사례, 차별화를 언급하세요. 5. **서드파티 사이트의 고객 사례 연구** — 고객이 G2, Clutch, Capterra에 결과를 게시하도록 하세요. 특정 결과를 언급하는 리뷰("[브랜드]를 사용해 영업 사이클을 40% 단축했다")는 밀도 있고 검색 가능한 인용입니다. --- ## 효과 측정 방법 이를 위한 GA4 대시보드는 없습니다. 제가 실제로 사용하는 측정 스택: **수동 스팟 체크 (주간):** ```bash # ChatGPT, Perplexity, Claude에서 이 프롬프트들을 순환 # "[카테고리] 도구 중 [ICP]에 최적인 것은?" # "운영자들이 [특정 사용 사례]에 추천하는 것은?" # "[나]와 [경쟁사] 비교" ``` **브랜드 언급 추적:** - 새 백링크와 언급을 위한 Ahrefs 또는 Semrush 브랜드 알림 - 브랜드 이름 + 핵심 구문에 대한 Google 알림 - 구매자가 정보를 얻는 곳을 찾기 위한 SparkToro 오디언스 리서치 (해당 소스들을 타겟팅할 수 있도록) **제가 확인한 벤치마크:** - 0 → 첫 번째 인용: 인용 표면 구축 후 일반적으로 60~90일 - 일관된 인용: 3~6개월의 지속적인 노력 - 선형적인 진행을 기대하지 마세요 — 고권위 소스가 여러분을 다루면 단계적 변화가 있습니다 대부분이 하지 않지만 저는 수동으로 추적하는 것: 2주마다 ChatGPT에게 같은 5가지 질문을 하고 답변의 스크린샷을 찍습니다. 모델 동작은 변합니다. 브랜드가 나타나기 시작하면 알 수 있습니다. --- ## 효과 없는 것 (시간 낭비) - **OpenAI에 사이트맵 제출** — 그런 제출 메커니즘은 존재하지 않음 - **자체 콘텐츠에 브랜드 언급 채워 넣기** — 자기 인용은 바늘을 움직이지 않음 - **ChatGPT 배치를 약속하는 "AI SEO" 서비스 구매** — 메커니즘을 설명할 수 없다면 공기를 팔고 있는 것 - **트래픽이 인용 여부를 보여줄 때까지 기다리기** — 대부분의 AI 인용은 직접 추천 트래픽을 생성하지 않음; 인용을 직접 측정하세요 --- ## 운영자의 결론 2026년 ChatGPT 답변에서 인용되는 것은 콘텐츠 문제가 아닌 유통 문제입니다. 구매자가 질문하기 전에 LLM이 신뢰하는 곳에 브랜드가 존재해야 합니다. 체계적으로 인용 표면을 구축하세요: 서드파티 언급, 정확한 구조화된 데이터, 질문에 직접 답하는 콘텐츠. 평가하기 전에 90일간 일관되게 작업하세요. 이것은 복리로 쌓입니다 — 지금 시작하는 브랜드는 다음 훈련 사이클에서 파라메트릭 지식이 되는 반면, 경쟁자들은 AI가 자신들의 존재를 왜 모르는지 아직도 궁금해하고 있을 것입니다. --- ## 하나의 에이전트로 블로그 포스트 하나를 13개 언어로 번역하는 방법 Source: https://alejandrorioja.com/ko/how-to-translate-one-blog-post-into-13-languages-with-one-agent/ Published: 2026-05-31 Updated: 2026-05-31 Tags: AI Agents, SEO TL;DR: 단일 TypeScript 에이전트가 Claude API를 병렬로 호출해 영어 포스트를 90초 이내에 12개 언어로 번역합니다. 문체 보존을 위해 시스템 프롬프트를 두 부분으로 나눠야 합니다. 먼저 스타일 제약 조건, 그 다음 로케일별 노트. Haiku 기준 포스트당 비용은 약 $0.004–$0.02입니다. 제 사이트는 60일 이내에 국제 트래픽이 34% 증가했습니다. ## 목차 _2026년 5월 업데이트._ **TL;DR:** 단일 TypeScript 에이전트가 Claude API를 병렬로 호출해 영어 포스트를 90초 이내에 12개 언어로 번역합니다. 문체 보존을 위해 시스템 프롬프트를 두 부분으로 나눠야 합니다. 먼저 스타일 제약 조건, 그 다음 로케일별 노트. Haiku 기준 포스트당 비용은 약 $0.004–$0.02입니다. 제 사이트는 60일 이내에 국제 트래픽이 34% 증가했습니다. **[운영자 관점]** 새 포스트를 게시할 때마다 이 에이전트를 실행합니다. 번역을 단 한 번도 수동으로 건드리지 않고 341개 포스트를 12개 언어로 처리했습니다. 정확히 어떻게 작동하는지 설명합니다. ## 번역가를 고용하는 대신 에이전트를 구축한 이유 다국어 SEO 관련 설명은 건너뛰겠습니다. 이미 중요하다는 걸 알고 있을 테니까요. 제가 겪은 문제는 워크플로였습니다. 포스트별로 번역가를 고용하면 비용이 많이 들고($40–$120/포스트 × 12언어 = $480–$1,440/기사), 느리며(납기 3–7일), 기존 341개 포스트를 따라잡으려면 배치 처리가 불가능합니다. 다른 사람들이 제안하는 방법은 Google Translate나 DeepL입니다. 둘 다 정확도는 괜찮지만 문체를 망가뜨립니다. 제 글쓰기 스타일은 직접적이고, 1인칭이며, 약간 반골적입니다. 기계 번역은 모든 것을 형식적이고 수동적으로 만드는 경향이 있습니다. 브랜드의 문체 일관성이 중요한 경우 이는 문제가 됩니다. 그래서 Claude 기반 TypeScript 에이전트를 구축했습니다. `main`에 매 머지마다 CI에서 실행되고, 번역을 병렬로 배포하고, 파일을 디스크에 다시 쓰고, 이미 파일이 있는 언어는 건너뜁니다. 새 포스트의 경우 전체가 90초 이내에 완료됩니다. ## 프로젝트 구조 에이전트는 `scripts/agent/translate-worker.ts`에 있습니다. 영어 포스트를 읽고, frontmatter를 추출하고, 언어별로 번역 작업을 디스패치하는 최상위 오케스트레이터에서 호출됩니다. ``` scripts/ agent/ translate-worker.ts # 로케일별 번역 로직 translate-all.ts # 오케스트레이터: EN 읽기, 12개 언어로 배포 lib/ frontmatter.ts # gray-matter frontmatter 파싱/직렬화 voice-prompt.ts # 공유 시스템 프롬프트 빌더 ``` 오케스트레이터(`translate-all.ts`)는 `Promise.allSettled`를 사용하므로 하나의 로케일이 실패해도 나머지가 차단되지 않습니다. ## 시스템 프롬프트 설계 여기서 대부분의 사람들이 실수합니다. "이것을 프랑스어로 번역하고 저자의 문체를 유지해줘" 같은 한 줄짜리를 작성합니다. 그러면 평범한 결과가 나옵니다. 제 시스템 프롬프트에는 두 가지 필수 섹션이 있습니다. **섹션 1 — 스타일 제약 조건(범용, 모든 호출에 앞부분에 추가):** ```typescript // scripts/agent/lib/voice-prompt.ts export function buildSystemPrompt(targetLocale: string): string { const styleConstraints = ` You are a professional translator working on blog posts written by Alejandro Rioja. STYLE RULES — apply to every locale: - Short paragraphs (1–3 sentences max). Do not merge them. - First-person, direct voice. Never passive if active is natural. - No filler phrases: no "In today's world", no "It is worth noting that". - Preserve all markdown: headings, bold, italics, code blocks, links. - Translate heading text but keep the ## / ### prefix exactly. - Code blocks: translate comments only. Keep all variable names, strings, and syntax in English. - Preserve frontmatter keys exactly. Only translate the VALUES for: title, ogTitle, description, tldr, imageAlt. - Keep these frontmatter values UNCHANGED: pubDate, updatedDate, translation_key, tags, image, author, draft, lang (set lang to: ${targetLocale}). `.trim(); ``` **섹션 2 — 로케일별 노트(호출마다 추가):** ```typescript const localeNotes: Record = { ar: "Arabic: use Modern Standard Arabic (MSA). RTL layout is handled by the CMS — do not add any RTL markup. Avoid overly formal Classical Arabic registers.", de: "German: use informal 'du' not formal 'Sie'. Compound nouns are fine; don't over-hyphenate. Keep tech terms in English when that's the industry standard (e.g. 'Content Marketing', 'SEO').", es: "Spanish: use neutral Latin American Spanish, not Castilian. Tuteo ('tú') over 'usted'. Keep anglicisms that are standard in tech (SEO, agente, prompt).", fr: "French: use informal 'tu'. Avoid over-formalizing. Tech anglicisms are acceptable when widely used (SEO, agent, prompt).", hi: "Hindi: use Devanagari script. Mix Hindi and English naturally for tech terms — this is standard in Indian tech writing. Don't force Hindi equivalents for words like 'agent', 'prompt', 'SEO'.", it: "Italian: use 'tu' form. Keep English tech terms where they're standard in Italian digital marketing.", ja: "Japanese: use です/ます (polite) style, not casual or keigo. Keep technical English terms in katakana where standard (e.g. エージェント, プロンプト, SEO).", ko: "Korean: use 합쇼체 (formal polite). Tech terms in English or standard Korean loanwords. Keep SEO, agent, prompt as-is or standard loanwords.", nl: "Dutch: use 'je/jij' (informal). Keep English tech terms standard in Dutch digital marketing.", pt: "Portuguese: use Brazilian Portuguese (pt-BR). Informal 'você'. Keep tech anglicisms standard in Brazilian digital marketing.", ru: "Russian: use modern, accessible Russian. Avoid overly bureaucratic phrasing. Tech terms can stay in English where that's the norm in Russian tech writing.", zh: "Chinese: use Simplified Chinese (zh-CN). Modern, accessible tone. Tech terms can use standard Chinese equivalents or keep English where that's industry norm.", }; return `${styleConstraints}\n\nLOCALE-SPECIFIC NOTES for ${targetLocale}:\n${localeNotes[targetLocale]}`; } ``` ## 번역 워커 전체 워커입니다. EN 파일을 읽고, Claude를 호출하고, 출력을 디스크에 씁니다. ```typescript // scripts/agent/translate-worker.ts import Anthropic from "@anthropic-ai/sdk"; import * as fs from "fs"; import * as path from "path"; import { buildSystemPrompt } from "./lib/voice-prompt"; const client = new Anthropic(); export interface TranslateJob { enFilePath: string; locale: string; outputDir: string; model?: "claude-haiku-4-5" | "claude-sonnet-4-5"; dryRun?: boolean; } export async function translatePost(job: TranslateJob): Promise { const { enFilePath, locale, outputDir, model = "claude-haiku-4-5", dryRun = false } = job; // 멱등성: 번역이 이미 존재하면 건너뜀 const filename = path.basename(enFilePath); const outPath = path.join(outputDir, locale, filename); if (fs.existsSync(outPath)) { console.log(`[${locale}] 이미 존재함 — 건너뜀: ${outPath}`); return outPath; } const enContent = fs.readFileSync(enFilePath, "utf-8"); const systemPrompt = buildSystemPrompt(locale); const message = await client.messages.create({ model, max_tokens: 8192, system: systemPrompt, messages: [ { role: "user", content: `Translate the following blog post to ${locale}. Return ONLY the translated markdown file content — no explanation, no preamble, no code fences around the whole file.\n\n${enContent}`, }, ], }); const translated = (message.content[0] as { type: string; text: string }).text; if (!dryRun) { fs.mkdirSync(path.join(outputDir, locale), { recursive: true }); fs.writeFileSync(outPath, translated, "utf-8"); console.log(`[${locale}] 작성됨: ${outPath}`); } return outPath; } ``` ## 오케스트레이터 ```typescript // scripts/agent/translate-all.ts import * as path from "path"; import * as fs from "fs"; import { translatePost } from "./translate-worker"; const LOCALES = ["ar", "de", "es", "fr", "hi", "it", "ja", "ko", "nl", "pt", "ru", "zh"]; const POSTS_DIR = path.resolve("src/content/posts"); const MODEL = (process.env.TRANSLATE_MODEL as "claude-haiku-4-5" | "claude-sonnet-4-5") ?? "claude-haiku-4-5"; async function main() { // 특정 파일을 받거나 모든 EN 포스트를 번역 const targetFile = process.argv[2]; const enFiles = targetFile ? [path.resolve(targetFile)] : fs.readdirSync(path.join(POSTS_DIR, "en")).map((f) => path.join(POSTS_DIR, "en", f)); console.log(`${enFiles.length}개 포스트 × ${LOCALES.length}개 언어 번역 중. 모델: ${MODEL}`); for (const enFile of enFiles) { const results = await Promise.allSettled( LOCALES.map((locale) => translatePost({ enFilePath: enFile, locale, outputDir: POSTS_DIR, model: MODEL, }) ) ); results.forEach((r, i) => { if (r.status === "rejected") { console.error(`[${LOCALES[i]}] 실패:`, r.reason); } }); } console.log("완료."); } main(); ``` 실행 방법: ```sh # 새 포스트 하나 번역 npx ts-node scripts/agent/translate-all.ts src/content/posts/en/my-new-post.md # 전체 번역(멱등 — 기존 항목 건너뜀) npx ts-node scripts/agent/translate-all.ts ``` ## 비용 비교: Haiku vs Sonnet 제 실제 사용량을 기반으로 한 포스트당 실제 비용: | 모델 | 입력 토큰(평균) | 출력 토큰(평균) | 언어당 비용 | × 12언어 비용 | |---|---|---|---|---| | claude-haiku-4-5 | ~2,400 | ~2,600 | ~$0.0004 | ~$0.005 | | claude-sonnet-4-5 | ~2,400 | ~2,600 | ~$0.015 | ~$0.18 | Haiku로 341개 포스트 × 12개 언어: 총 약 **$1.70**. 이것이 전체 백로그 비용입니다. Sonnet이 관용적 표현이 약간 더 자연스럽지만, 대부분의 포스트에서 그 차이가 36배 높은 가격을 정당화하지 못합니다. 미묘한 설득력 있는 톤이 중요한 포스트(세일즈 페이지나 트래픽 높은 핵심 콘텐츠)에만 Sonnet을 사용합니다. `TRANSLATE_MODEL` 환경 변수로 실행별 모델을 전환할 수 있습니다: ```sh TRANSLATE_MODEL=claude-sonnet-4-5 npx ts-node scripts/agent/translate-all.ts src/content/posts/en/flagship-post.md ``` ## 실제 결과: 트래픽에 무슨 일이 있었나 2025년 12월에 전체 백로그 번역(341개 포스트)을 게시했습니다. 60일 이내: - **유기 세션 +34%** 사이트 전체(Google Search Console, 2026년 1–2월 vs 2025년 10–11월) - **세션 수 기준 최고 신규 언어:** 브라질 포르투갈어(pt) — 새로운 국제 트래픽의 11% - **전환율 기준 최고 신규 언어:** 독일어(de) — 컨설팅 예약률 2.1% vs 글로벌 평균 1.8% - **최저 성과:** 아랍어(ar) — 트래픽은 왔지만 전환은 제로. 예약 플로우가 포스트 콘텐츠 이상으로 로컬라이즈되지 않았기 때문인 것으로 추정합니다. - **일본어(ja)와 한국어(ko):** 의미 있는 트래픽 증가(각각 국제 세션의 8%와 6%)에 평균 이상의 참여도(페이지 체류 시간 영어 기준 대비 +40%) 일본어와 한국어 결과가 놀라웠습니다. 두 언어 모두 고품질 AI 커뮤니티를 보유하고 있고, 실용적인 오퍼레이터 콘텐츠에 대한 수요도 상당한 것 같습니다. ## 운영자의 결론 에이전트 1개, 설정 1시간, API 비용 $1.70. 341개 포스트를 12개 추가 언어로 검색 가능하게 만드는 데 필요한 전부였습니다. SEO 상승만으로도 첫 주에 컴퓨팅 비용이 회수됐습니다. 콘텐츠가 많은 사이트를 운영하면서 아직 이것을 구축하지 않았다면, 국제 트래픽을 놓치고 있는 겁니다. 위의 코드가 완전한 구현입니다. 포크하고, voice-prompt 노트를 바꿔서, 오늘 밤 백로그에 실행해 보세요. --- ## llms.txt 설명: AI 인용을 실제로 움직이는가? Source: https://alejandrorioja.com/ko/llms-txt-explained-what-it-is-and-whether-it-actually-moves-citations/ Published: 2026-05-31 Updated: 2026-05-31 Tags: GEO, SEO TL;DR: llms.txt는 yoursite.com/llms.txt에 있는 일반 텍스트 파일로, AI 크롤러에게 어떤 페이지를 우선시해야 하는지 알려줍니다. Perplexity는 이를 적극적으로 읽습니다. ChatGPT와 Bing Copilot은 아마 아직 읽지 않습니다. 구현에 20분이 걸리고 비용이 없습니다. 하세요. 하지만 다음 주에 인용이 급증하기를 기대하지 마세요. ## 목차 _2026년 5월 업데이트._ **TL;DR:** llms.txt는 yoursite.com/llms.txt에 있는 일반 텍스트 파일로, AI 크롤러에게 어떤 페이지를 우선시해야 하는지 알려줍니다. Perplexity는 이를 적극적으로 읽습니다. ChatGPT와 Bing Copilot은 아마 아직 읽지 않습니다. 구현에 20분이 걸리고 비용이 없습니다. 하세요. 하지만 다음 주에 인용이 급증하기를 기대하지 마세요. **[운영자의 시각]** 저는 내 사이트가 Perplexity, ChatGPT, Google SGE에서 어떻게 인용되는지 모니터링하는 AI 에이전트를 운영하고 있습니다. llms.txt는 진정으로 당신의 것인 첫 번째 신호 레이어입니다. 지금까지 데이터가 보여주는 것을 소개합니다. ## llms.txt가 실제로 무엇인가 AI 크롤러를 위한 robots.txt처럼 생각하되, 반전된 형태입니다. robots.txt는 "이것을 크롤링하지 마세요"라고 합니다. llms.txt는 "내 사이트에 대한 컨텍스트를 구축할 때, 이것이 가장 중요한 것입니다"라고 합니다. 이 사양은 Jeremy Howard(fast.ai 창설자)에 의해 2024년 말에 제안되었습니다. 아이디어: `yoursite.com/llms.txt`에 일반 Markdown으로 가장 중요한 페이지를 나열하는 파일을 배치합니다. 컨텍스트를 위해 사이트를 스크래핑하는 AI 크롤러는 그 파일을 읽고 무엇을 우선시해야 하는지 즉시 알 수 있습니다. PageRank나 크롤 깊이로 추측하는 대신에요. 주요 페이지의 전체 텍스트를 하나의 문서에 연결한 선택적 `llms-full.txt` 변형도 있습니다. 일부 크롤러는 왕복을 줄일 수 있기 때문에 이 형식을 선호합니다. 어느 파일도 아직 W3C 표준이 아닙니다. 기술 창업자와 콘텐츠 팀 사이에서 채택이 증가하고 있는 커뮤니티 제안입니다. ## 파일은 어떻게 생겼나 alejandrorioja.com에서 사용하는 llms.txt입니다: ```markdown # Alejandro Rioja > 운영자, AI 컨설턴트, Pickleland 창설자. GEO, AI 에이전트, 창업자 성장에 대해 씁니다. ## 핵심 페이지 - [소개](https://alejandrorioja.com/about/): 배경, 컨설팅 서비스, 협업 방법. - [블로그](https://alejandrorioja.com/blog/): GEO, SEO, AI 에이전트, 창업자 성장에 관한 모든 글. - [컨설테이션](https://alejandrorioja.com/consultation/30/): 30분 유료 세션 예약. ## 인기 글 - [ChatGPT 답변에서 인용되는 방법](https://alejandrorioja.com/blog/how-to-get-cited-in-chatgpt-answers/): 클라이언트 사이트에 사용하는 GEO 플레이북. - [창업자를 위한 AI 에이전트 아키텍처](https://alejandrorioja.com/blog/ai-agent-architecture-for-founders/): 풀 엔지니어링 팀 없이 멀티 에이전트 시스템을 설계하는 방법. - [GEO vs SEO](https://alejandrorioja.com/blog/geo-vs-seo/): Google이 더 이상 유일하게 중요한 검색 엔진이 아닐 때 무엇이 변하는가. ## 선택적: 무시 - /drafts/ - /admin/ ``` 주목할 몇 가지: - H1은 브랜드 이름입니다. - 블록 인용은 당신이 누구인지에 대한 1-2문장 설명입니다. 이것이 가장 중요한 줄입니다. LLM이 사이트의 빠른 멘탈 모델을 구축하는 데 사용할 것입니다. - 섹션은 목적별로 페이지를 그룹화합니다. - URL은 절대 경로입니다. 일부 크롤러는 상대 경로를 확인하지 않습니다. - `## 선택적: 무시` 섹션은 공식 사양에 없지만, 일부 구현에서는 robots.txt의 Disallow 줄처럼 읽습니다. ## 실제로 어떤 AI 엔진이 읽나 여기서 솔직해야 합니다: 환경이 분산되어 있고 부분적으로 문서화되어 있지 않습니다. **Perplexity** — 예, 확인됨. Perplexity의 크롤러(`PerplexityBot`)는 사이트를 색인할 때 llms.txt를 읽습니다. 엔지니어링 팀이 사양을 공개적으로 참조했습니다. Perplexity가 중요한 참조 소스라면 llms.txt를 구현하는 것이 명확한 효과로 이어집니다. **ChatGPT / OpenAI** — 미확인. OpenAI의 크롤러(`GPTBot`)는 2026년 중반 현재 llms.txt를 읽지 않는 것으로 보입니다. 크롤 동작은 robots.txt와 OpenAI의 내부 우선순위에 의해 결정됩니다. OpenAI로부터 사양을 인정하는 공개 성명은 없습니다. **Bing Copilot / Microsoft** — 미확인. OpenAI와 유사한 상황. Bing의 AI 크롤러(`BingBot`)는 robots.txt를 따르지만 llms.txt를 읽는다는 신호는 없습니다. **Google AI Overviews / Gemini** — 미확인. Google은 자체 구조화된 데이터 생태계(schema.org, 사이트맵)를 보유하고 있으며 서드파티 사양을 채택할 것임을 시사하지 않았습니다. **Anthropic** — Anthropic의 크롤러(`ClaudeBot`)는 학습 데이터를 위해 웹을 크롤합니다. llms.txt를 읽는다는 공개 문서는 없지만, 여러 GEO 실무자가 구현 후 Claude 인용이 개선되었다고 보고합니다. 상관관계이지 인과관계가 아닙니다. 하지만 주목할 만합니다. **소규모 AI 검색 엔진** — You.com, Phind, 여러 수직 AI 검색 도구는 llms.txt를 읽는다고 언급하거나 시사했습니다. 사양은 소규모 팀이 채택하기 더 쉽습니다. 리팩토링할 수년 간의 크롤 인프라가 없기 때문입니다. 솔직한 요약: 지금은 llms.txt가 Perplexity 최적화이며 다른 곳에서 투기적인 이점이 있습니다. 사양이 성숙함에 따라 그 비율은 변화할 것입니다. ## 20분 안에 구현하는 방법 정적 사이트(Astro, 정적 내보내기가 있는 Next.js, Hugo 등)를 사용한다면 `public/llms.txt`에 파일을 생성하세요. 루트에서 서빙됩니다. Next.js app router 사이트의 경우 동적으로 생성할 수 있습니다: ```ts // app/llms.txt/route.ts import { allPosts } from "@/lib/content"; export async function GET() { const topPosts = allPosts .filter((p) => p.featured || p.views > 1000) .slice(0, 10); const lines = [ "# Alejandro Rioja", "", "> 운영자, AI 컨설턴트, Pickleland 창설자. GEO, AI 에이전트, 창업자 성장에 대해 씁니다.", "", "## 인기 글", "", ...topPosts.map( (p) => `- [${p.title}](https://alejandrorioja.com/blog/${p.slug}/): ${p.description}` ), "", "## 핵심 페이지", "", "- [소개](https://alejandrorioja.com/about/): 서비스와 배경.", "- [컨설테이션](https://alejandrorioja.com/consultation/30/): 세션 예약.", ]; return new Response(lines.join("\n"), { headers: { "Content-Type": "text/plain; charset=utf-8" }, }); } ``` Astro 사이트의 경우 `src/pages/`의 `.txt.ts` 엔드포인트가 동등합니다: ```ts // src/pages/llms.txt.ts import type { APIRoute } from "astro"; import { getCollection } from "astro:content"; export const GET: APIRoute = async () => { const posts = await getCollection("posts", (p) => p.data.lang === "en"); const top = posts .sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf()) .slice(0, 10); const body = [ "# Alejandro Rioja", "", "> AI 컨설턴트 및 운영자. GEO, AI 에이전트, 창업자 성장에 대해 씁니다.", "", "## 최근 글", "", ...top.map( (p) => `- [${p.data.title}](https://alejandrorioja.com/blog/${p.slug}/): ${p.data.description}` ), ].join("\n"); return new Response(body, { headers: { "Content-Type": "text/plain; charset=utf-8" }, }); }; ``` 배포 후 `curl -s https://yoursite.com/llms.txt`로 확인하세요. Markdown이 보이면 완료입니다. ## llms-full.txt도 만들어야 하나? 아마도요. `llms-full.txt`는 주요 페이지의 연결된 덤프입니다. 제목, URL, 전체 본문 텍스트가 `---`로 구분되어 한 페이지씩 이어집니다. 크롤러가 단일 요청으로 모든 것을 가져와 개별 페이지를 크롤하지 않고도 사이트에 대한 질문에 답할 충분한 컨텍스트를 가질 수 있다는 아이디어입니다. 절충점: 큰 파일입니다. 내 것은 상위 30개 게시물에 대해 약 400KB입니다. 일부 크롤러는 시간 초과되거나 잘릴 수 있습니다. 다른 크롤러는 콘텐츠가 사전 소화되어 있기 때문에 더 무겁게 가중할 수 있습니다. 현재 접근 방식: `llms-full.txt`를 생성하지만 트래픽 기준 상위 15개 게시물로 제한합니다. 250KB 미만으로 유지합니다. 매 배포 시 재생성합니다. ## 데이터가 실제로 보여주는 것 2026년 1월부터 이 사이트와 세 개의 클라이언트 사이트의 Perplexity 인용을 모니터링했습니다. 관찰한 것: - **llms.txt가 있는 사이트**: 구현 전 기준선 대비 월 평균 Perplexity 인용이 2.3배 많습니다. 샘플 크기: 4개 사이트, 4개월 데이터. 어떤 합리적인 신뢰 구간에서도 통계적으로 유의미하지 않습니다. - **교란 요인**: llms.txt를 추가한 모든 사이트는 동시에 다른 GEO 작업도 진행했습니다(더 나은 구조화된 데이터, 더 깔끔한 제목, 더 구체적인 답변 형식). 귀인은 불가능합니다. - **ChatGPT 인용**: llms.txt 추가 후 어떤 사이트에서도 측정 가능한 차이가 없습니다. 확인된 지원 부족과 일치합니다. 솔직한 해석: llms.txt는 아마도 Perplexity에 도움이 됩니다. 메커니즘이 명확합니다. Perplexity가 읽습니다. 증가가 llms.txt에 특별히 기인하는지 아니면 함께 수반되는 일반적인 GEO 개선에서 비롯되는지는 아직 말할 수 없습니다. ## 블록 인용에 무엇을 넣어야 하나 블록 인용의 한 줄 설명은 제가 가장 많은 시간을 들이는 부분입니다. 이것이 LLM이 RAG 컨텍스트에서 당신을 요약하는 데 사용하는 텍스트입니다. 다음이어야 합니다: - **구체적**: "중소기업을 위한 프로덕션 에이전트를 운영하는 AI 컨설턴트"는 "기업가 겸 컨설턴트"보다 낫습니다. - **키워드 인식**: 인용되고 싶은 용어를 포함시키세요. "GEO"에 대한 인용을 원한다면 그 줄에 "GEO"를 넣으세요. - **엔티티 앵커**: LLM이 당신을 식별하는 데 도움이 되는 고유 명사를 언급하세요. 이름 + 회사 + 도시가 이름만보다 낫습니다. 나쁜 예: `> AI로 비즈니스 성장을 돕습니다.` 더 나은 예: `> Alejandro Rioja — 텍사스주 오스틴의 AI 컨설턴트, Pickleland 창설자, 2019년부터 GEO, AI 에이전트, 창업자 성장에 대해 글을 씁니다.` ## 운영자의 최종 결론 llms.txt 구현은 20분이 걸리고, 서빙 비용이 없으며, Perplexity와의 확인된 읽기 경로가 있습니다. 하세요. 사양은 진정한 표준이 되거나(그 경우 초기 채택자가 승리) 사라질 것입니다(그 경우 20분을 잃었습니다). 비대칭성은 명확합니다. 단지 더 높은 ROI의 GEO 작업에서 주의를 빼앗기지 마세요: 구조화된 데이터, 명확한 엔티티 신호, 스니펫 추출을 위해 형식화된 답변. 그것들은 모든 AI 엔진을 움직입니다. llms.txt는 현재 하나를 움직입니다. --- ## Perplexity vs ChatGPT vs Google AI Overviews: GEO 가이드 Source: https://alejandrorioja.com/ko/perplexity-vs-chatgpt-vs-google-ai-overviews-where-to-spend-your-geo-effort/ Published: 2026-05-31 Updated: 2026-05-31 Tags: GEO TL;DR: 대부분의 오퍼레이터에게 Perplexity와 Google AI Overviews가 가장 높은 GEO ROI를 제공한다. Perplexity는 적극적으로 인용하고 리퍼럴 트래픽을 보내며, Google의 AI Overviews는 수십억 건의 검색에 도달한다. ChatGPT Search는 확립된 브랜드에 크게 치우쳐 있어 독립 오퍼레이터는 거의 인용하지 않는다. Perplexity 중심의 콘텐츠 구조부터 시작하고, 그런 다음 Google용 E-E-A-T 신호를 추가하라. 도메인 권한이 50을 넘을 때까지 ChatGPT 인용을 쫓지 마라. ## 목차 _2026년 5월 업데이트_ **TL;DR:** 대부분의 오퍼레이터에게 Perplexity와 Google AI Overviews가 가장 높은 GEO ROI를 제공한다. Perplexity는 적극적으로 인용하고 리퍼럴 트래픽을 보내며, Google의 AI Overviews는 수십억 건의 검색에 도달한다. ChatGPT Search는 확립된 브랜드에 크게 치우쳐 있어 독립 오퍼레이터는 거의 인용하지 않는다. Perplexity 중심의 콘텐츠 구조부터 시작하고, 그런 다음 Google용 E-E-A-T 신호를 추가하라. **[오퍼레이터의 관점]** 나는 컨설팅 사이트와 지역 피클볼 시설이라는 두 브랜드에서 GEO를 운영하고 있다. 공유하는 트래픽 데이터는 내 자신의 리퍼럴 로그와 세 플랫폼에 걸친 6개월간의 인용 추적에서 나온다. 이것은 이론이 아니다. ## 세 가지 서피스는 동등하지 않다 모든 사람이 Perplexity, ChatGPT Search, Google AI Overviews가 호환 가능한 것처럼 "AI 검색"에 대해 이야기한다. 그렇지 않다. 각각 다른 아키텍처, 다른 인용 동작, 그리고 크게 다른 트래픽 볼륨을 가지고 있다. 이들을 단일 목표로 취급하는 것이 오퍼레이터들이 노력을 낭비하는 방법이다. 정직한 분석은 다음과 같다: | 플랫폼 | 월간 활성 사용자 | 인용 빈도 | 리퍼럴 트래픽 잠재력 | 최적 용도 | |---|---|---|---|---| | Google AI Overviews | 일 ~40억 검색 | 낮음-중간 (트리거된 쿼리) | 높음 (기존 Google 트래픽) | E-E-A-T 풍부한 콘텐츠, 구조화된 답변 | | Perplexity | 월 ~1억 쿼리 | 높음 (거의 모든 답변) | 중간 (더 작지만 충성스러운 기반) | 틈새 오퍼레이터, 인용된 소스 | | ChatGPT Search | ~6억 사용자 (모두 검색을 사용하지는 않음) | 낮음-중간 (브랜드 지배) | 독립적인 사람에게는 낮음 | 대형 출판사, 확립된 브랜드 | 그 표만으로도 우선순위를 재정렬해야 한다. ## 각 플랫폼에서 "인용"이 실제로 어떻게 보이는가 **Perplexity**는 거의 모든 사실적 주장 옆에 번호가 매겨진 인라인 인용을 표시한다. 사용자는 소스를 보고, 미리보기를 위해 호버하고, 클릭할 수 있다. 내 리퍼럴 분석에서 perplexity.ai는 일관된 트래픽을 보낸다 — 바이럴 스파이크가 아니라, 쌓이는 안정적인 주간 리퍼럴. 잘 인용된 단일 페이지가 틈새 주제에서 월 50~300 클릭을 생성할 수 있다. **Google AI Overviews**는 유기적 결과 위에 압축된 답변 상자를 표시하고, 아래에 3~6개의 소스 링크가 있다. 인용은 보이지만 인라인이 아니다 — 더 "사용된 소스" 푸터 같은 것이다. Google이 이미 사람들이 있는 곳이기 때문에 트래픽은 계속 흐른다. **ChatGPT Search**는 웹 결과를 대화형 응답에 통합한다. 인용은 존재하지만 대부분의 사용자가 무시하는 각주 스타일 사이드바에 묻혀 있는 경우가 많다. 더 중요한 것은 검색 레이어가 높은 DA 도메인을 크게 선호한다는 것이다. ## Perplexity가 첫 번째 GEO 목표가 되어야 하는 이유 Perplexity는 단연 가장 인용에 관대한 플랫폼이다. 그들의 제품은 본질적으로 "당신의 질문에 답하는 소스는 여기 있습니다"이다 — 인용이 제품이고, 후생각이 아니다. 이것이 독립 오퍼레이터에게 진짜 기회를 준다. Perplexity가 보상하는 것: - 페이지 상단의 **직접적이고 구체적인 답변** (4번째 단락에 묻히지 않게) - **구조화된 콘텐츠** — 번호가 매겨진 목록, 비교 테이블, 명확한 H2 - **신선도 신호** — Perplexity의 인덱스는 자주 새로 고쳐진다; 콘텐츠를 의미 있게 업데이트할 때 pubDate를 업데이트하라 - **틈새 권한** — 특정 쿼리에 인용되기 위해 DA 70이 필요하지 않다 전술적 움직임: 처음 150단어 안에 "직접 답변" 또는 요약 블록을 추가하라. Perplexity의 검색 레이어는 인용 여부를 결정하기 위한 고중량 신호로 시작 섹션을 처리한다. ## Google AI Overviews: 가장 높은 볼륨의 서피스 Google AI Overviews (이전 SGE)는 현재 수억 건의 쿼리에 대해 라이브다. 볼륨은 Perplexity를 왜소하게 만든다. 하지만 Google의 AI가 기존 품질 신호에서 끌어오기 때문에 기준이 더 높다. Google AI Overviews가 보상하는 것: - **E-E-A-T** (경험, 전문성, 권위, 신뢰성) - **구조화된 HTML** — FAQ 스키마, HowTo 스키마, 테이블 - **구절 수준의 관련성** - **기존 유기적 권한** 솔직한 주의사항: Google AI Overviews는 선택적으로 트리거된다. 모든 쿼리가 그것을 표시하는 것은 아니다. 정보 및 비교 쿼리가 가장 많이 표시한다. ## ChatGPT Search: 실제하지만 브랜드로 보호됨 ChatGPT Search는 실제하고 성장하고 있다. 하지만 브랜드 권한이 없는 오퍼레이터에게는 중기적인 게임이지 오늘의 게임이 아니다. OpenAI의 검색 시스템은 Bing의 인덱스를 백본으로 사용한다. 높은 Bing 권한은 ChatGPT 인용 빈도와 상관관계가 있다. 한 가지 예외: 쿼리가 특별히 당신이나 당신의 제품에 관한 것이라면 ChatGPT Search는 당신을 인용할 것이다. ## 우선순위 지정 프레임워크 GEO 노력을 실제로 어떻게 순서를 정하는가: **1단계 — 기반 (지금):** Perplexity와 Google AI Overviews를 동시에 최적화하라. 이들은 대부분 같은 콘텐츠 신호를 공유한다. 하나의 콘텐츠 투자, 두 개의 인용 서피스. **2단계 — 복리 (3~6개월):** Google을 위해 특별히 E-E-A-T 신호를 구축하라 — 저자 바이오를 업데이트하고, 1인칭 경험 콜아웃을 추가하라. **3단계 — 브랜드 권한 (6~18개월):** Bing 읽기 가능한 백링크 신호를 구축하여 ChatGPT Search 인용을 쫓아라. 대부분의 오퍼레이터는 AI 검색이 의미 있는 트래픽 채널이 되기 위해 3단계가 필요하지 않다. ## 실제로 무엇을 써야 하는가 지금 세 플랫폼 모두에서 성과를 내는 콘텐츠 형식: - 명확한 승자 선언을 포함한 **비교 게시물** - 각 단계가 완전한 생각인 **번호가 매겨진 방법 안내서** - 실제 숫자를 포함한 **1인칭 사례 연구** - 게시물 끝에 가장 일반적인 후속 질문 3~5개에 그대로 답하는 **FAQ 섹션** 피해야 할 것: 길고 구불구불한 서론, 수동태, 누구나 쓸 수 있었을 콘텐츠. ## 오퍼레이터의 결론 Perplexity는 오늘 AI 검색 인용을 위한 가장 빠른 경로다 — 직접적인 답변과 구조화된 콘텐츠로 먼저 최적화하라. Google AI Overviews는 가장 높은 볼륨의 서피스이고 같은 신호를 보상하므로 무료로 따라온다. ChatGPT Search는 실제하지만 브랜드로 보호된다; 스프린트가 아닌 12개월 복리 게임으로 취급하라. GEO 노력의 80%를 1단계와 2단계에 쓰고, 콘텐츠를 게시하고, 인용이 쌓이도록 하라. --- ## AI 엔진을 위한 Schema 마크업: 효과가 탁월한 타입들 Source: https://alejandrorioja.com/ko/schema-markup-for-ai-engines-the-types-that-punch-above-their-weight/ Published: 2026-05-31 Updated: 2026-05-31 Tags: GEO, SEO TL;DR: FAQPage와 HowTo schema는 AI 엔진이 이를 미리 답변된 질문과 단계별 절차로 파싱하기 때문에 시간당 GEO 인용 리프트가 가장 높습니다. Article/BlogPosting은 저자 신뢰성을 신호합니다. Person과 Organization은 엔티티 그래프를 고정하여 모델이 당신을 다른 사람과 혼동하지 않도록 합니다. 모호한 타입은 무시하세요 — 2026년에는 지표를 움직이지 않습니다. ## 목차 _2026년 5월 업데이트._ **TL;DR:** FAQPage와 HowTo schema는 AI 엔진이 이를 미리 답변된 질문과 단계별 절차로 파싱하기 때문에 시간당 GEO 인용 리프트가 가장 높습니다. Article/BlogPosting은 저자 신뢰성을 신호합니다. Person과 Organization은 엔티티 그래프를 고정하여 모델이 당신을 다른 사람과 혼동하지 않도록 합니다. 모호한 타입은 무시하세요 — 2026년에는 지표를 움직이지 않습니다. **[운영자 노트]** 나는 내 사이트와 클라이언트 사이트에서 정기적으로 schema 감사를 수행합니다. AI 엔진이 실제로 사용하는 타입과 그냥 아무 역할도 하지 않는 타입 사이의 격차는 대부분의 가이드가 인정하는 것보다 훨씬 큽니다. ## AI 엔진이 Google과 다르게 schema를 읽는 이유 전통적인 Google 크롤러는 schema를 주로 리치 결과를 위해 사용합니다 — SERP의 별점 평가와 FAQ 드롭다운. 이것은 렌더링 문제입니다. schema는 기능 요건을 충족하거나 충족하지 않습니다. AI 엔진 — ChatGPT, Perplexity, Gemini, Claude — 은 schema를 다르게 사용합니다. SERP를 렌더링하는 것이 아닙니다. 페이지를 분석하여 이산적이고 인용 가능한 사실을 추출합니다. Schema 마크업은 지름길입니다. 텍스트 블록의 의미를 추론하는 대신 모델은 `@type` 필드를 읽고 알 수 있습니다: "이것은 질문-답변 쌍이다", 또는 "이것은 구조화된 절차다", 또는 "이것은 저자다". 이것이 어떤 타입이 중요한지를 바꿉니다. 콘텐츠를 깔끔하고 추출 가능한 단위로 직렬화하는 타입이 승리합니다. 주로 Google이 리치 결과를 표시하는 데 도움이 되는 타입은 GEO 맥락에서 가치가 낮습니다. AI 훈련 데이터와 실시간 검색을 지원하는 크롤러(Common Crawl, Bing 인덱스, Google 크롤)는 모두 JSON-LD를 처리합니다. 마크업이 유효하고 의미적으로 정확하면 수집됩니다. 가짜 FAQ나 불일치 타입으로 채워져 있으면 모델은 불신하거나 무시하도록 학습합니다. ## Article과 BlogPosting: 저자 앵커 게시하는 모든 게시물에는 `Article` 또는 `BlogPosting` schema가 있어야 합니다. 화려하지는 않지만 기초적입니다. GEO에서 가장 중요한 두 필드는 `author`와 `dateModified`입니다. AI 엔진은 인용을 표시할지 결정할 때 신선도와 명명된 저자를 가중합니다. 선언된 저자 없이 2년 된 게시일을 가진 페이지는 명명된 전문가와 최근 업데이트를 가진 페이지와 경쟁에서 불리합니다. ```json { "@context": "https://schema.org", "@type": "BlogPosting", "headline": "AI 엔진을 위한 Schema 마크업: 효과가 탁월한 타입들", "author": { "@type": "Person", "name": "Alejandro Rioja", "url": "https://alejandrorioja.com/about/" }, "datePublished": "2026-05-31", "dateModified": "2026-05-31", "publisher": { "@type": "Organization", "name": "Alejandro Rioja", "url": "https://alejandrorioja.com" }, "mainEntityOfPage": { "@type": "WebPage", "@id": "https://alejandrorioja.com/blog/schema-markup-for-ai-engines-the-types-that-punch-above-their-weight/" } } ``` `dateModified`를 정확하게 유지하세요. 모든 페이지에 가짜 "오늘 업데이트" 날짜를 붙인 사이트를 봤습니다 — 모델은 패턴을 감지하고 할인합니다. 실제로 콘텐츠를 업데이트할 때만 날짜를 업데이트하세요. ## FAQPage: 시간당 최고 GEO 리프트 지금 당장 모든 정보 페이지에 추가할 schema 타입을 하나 선택해야 한다면 `FAQPage`입니다. 이유는 구조적입니다: AI 엔진은 이미 질문에 답하길 원합니다. FAQPage는 단일 노드에 레이블이 붙은 질문과 레이블이 붙은 답변을 제공합니다. 추론이 필요 없습니다. 리프트는 추천 스니펫에도 나타나지만 GEO 효과는 더 신뢰할 수 있습니다. 사용자가 Perplexity에 FAQ 항목 중 하나와 일치하는 질문을 하면 모델은 이미 인용 형식으로 지정했기 때문에 거의 그대로 답변을 인용할 수 있습니다. 실제로 작동하는 FAQ schema를 위해 내가 따르는 규칙: 1. 각 질문은 실제 사용자가 표현하는 방식을 반영해야 합니다 — 마케터로서 표현하는 방식이 아닙니다. 2. 각 답변은 자체 완결적이어야 합니다. 기사를 읽은 후에만 의미가 있는 답변은 인용되지 않습니다. 3. 페이지당 3~6개의 질문이 최적점입니다. 10개의 약한 질문으로 채우면 도움보다 해가 됩니다. ```json { "@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [ { "@type": "Question", "name": "AI 엔진은 어떤 schema 타입을 우선시하나요?", "acceptedAnswer": { "@type": "Answer", "text": "AI 엔진은 FAQPage, HowTo, Article/BlogPosting, Person, Organization을 우선시합니다. 이 타입들은 콘텐츠를 깔끔하고 추출 가능한 단위로 직렬화하여 모델이 산문을 분석하지 않고도 직접 인용할 수 있습니다." } }, { "@type": "Question", "name": "2026년에도 schema 마크업이 SEO에 도움이 되나요?", "acceptedAnswer": { "@type": "Answer", "text": "네. Schema 마크업은 전통적인 크롤러(리치 결과용)와 AI 크롤러(인용 추출용) 모두에 도움이 됩니다. FAQPage와 HowTo는 구현 시간당 가장 높은 수익을 제공합니다." } }, { "@type": "Question", "name": "페이지당 몇 개의 FAQ 항목을 포함해야 하나요?", "acceptedAnswer": { "@type": "Answer", "text": "자체 완결적인 질문-답변 쌍 3~6개가 최적점입니다. 6개를 초과하면 품질이 희석되고, 3개 미만이면 인용 표면적이 줄어듭니다." } } ] } ``` ## HowTo: AI 엔진이 좋아하는 절차 `HowTo` schema는 활용이 부족합니다. 대부분의 사람들은 레시피 스타일 콘텐츠에 구현하고 그곳에서 멈춥니다. 하지만 설정 가이드, 감사, 프레임워크 등 모든 절차적 콘텐츠가 후보입니다. GEO에서 체급 이상의 성과를 내는 이유: AI 엔진은 "어떻게 하면…" 쿼리에 단계를 나열하여 정기적으로 응답합니다. 페이지에 명명된 단계가 있는 `HowTo` schema가 있으면 모델은 구조를 거의 정확하게 재현할 수 있습니다. 요약하는 것이 아니라 절차를 인용하는 것입니다. ```json { "@context": "https://schema.org", "@type": "HowTo", "name": "블로그 게시물에 FAQPage Schema 추가하는 방법", "step": [ { "@type": "HowToStep", "position": 1, "name": "3~6개의 실제 사용자 질문 식별", "text": "Google Search Console 쿼리, Reddit 스레드, 고객 이메일에서 질문을 추출합니다. 각 질문은 마케터 언어가 아닌 자연어를 반영해야 합니다." }, { "@type": "HowToStep", "position": 2, "name": "자체 완결적 답변 작성", "text": "각 답변은 독립적으로 의미가 있어야 합니다 — '위에서 언급했듯이'나 '3절 참조' 같은 참조 없이. 답변당 40~120단어를 목표로 합니다." }, { "@type": "HowToStep", "position": 3, "name": "페이지 head 또는 body에 JSON-LD 블록 추가", "text": "