การวัดผลกระทบของการอ้างอิงจาก AI: การวิเคราะห์, บันทึก Log, และการรวบรวมข้อมูลจากแผงคำตอบ
บทนำ
การค้นพบที่ขับเคลื่อนด้วย AI ปัจจุบันถูกแบ่งออกเป็นหลายระดับการวัดผล บุคคลอาจเห็นบริษัทถูกอ้างอิงในคำตอบของ AI คลิกที่ลิงก์ที่ไม่มีข้อมูลผู้แนะนำที่เป็นประโยชน์ เข้าชมผ่านเบราว์เซอร์ที่ตัดข้อมูลแคมเปญออก หรืออ่านคำตอบโดยไม่ได้คลิกเลย ในขณะเดียวกัน AI crawler อาจร้องขอหน้าเพจของบริษัทโดยไม่ได้แสดงถึงผู้เยี่ยมชมที่เป็นมนุษย์
ดังนั้น ระบบการวัดผลที่มีประโยชน์ต้องแยกคำถามออกเป็นสี่ข้อดังนี้:
- เว็บไซต์ถูกรวบรวมข้อมูลหรือดึงข้อมูลมาหรือไม่?
- เว็บไซต์ถูกอ้างอิงในคำตอบของ AI หรือไม่?
- มีบุคคลเข้าชมเว็บไซต์จากคำตอบนั้นหรือไม่?
- การเข้าชมนั้นก่อให้เกิดการมีส่วนร่วมหรือรายได้ที่มีความหมายหรือไม่?
ณ วันที่ 22 กันยายน 2026 การรายงานของบุคคลที่หนึ่งกำลังดีขึ้น Google Search Console มีรายงานประสิทธิภาพ Generative AI สำหรับ AI Overviews และ AI Mode ซึ่งรวมถึงการแสดงผล, หน้าเว็บ, ประเทศ, อุปกรณ์ และวันที่ รายงานนี้เปิดให้ใช้งานทั่วโลกเมื่อ วันที่ 31 สิงหาคม 2026 รายงานประสิทธิภาพ Generative AI ของ Google (support.google.com)
Microsoft ยังมีรายงาน AI Performance ใน Bing Webmaster Tools การแสดงตัวอย่างสาธารณะจะรายงานจำนวนการอ้างอิงทั้งหมด, หน้าที่ถูกอ้างอิง, คำค้นหาที่ใช้เป็นฐานข้อมูล และแนวโน้มการอ้างอิงในประสบการณ์ AI ของ Microsoft ที่รองรับ ประสิทธิภาพ AI ใน Bing Webmaster Tools (blogs.bing.com)
เครื่องมือเหล่านี้ควรถือเป็นแหล่งข้อมูลที่น่าเชื่อถือสำหรับพื้นผิวของตนเอง แต่ไม่ได้สร้างระบบการวัดผลข้ามผู้ช่วยที่สมบูรณ์ วิธีการที่แนะนำคือการรวม รายงานของบุคคลที่หนึ่ง, บันทึกเซิร์ฟเวอร์, ลิงก์ติดตามที่ควบคุมได้, การส่งออกข้อมูลวิเคราะห์ และการสังเกตแผงคำตอบตามกำหนดเวลา
1. เหตุใดการวัดผลการอ้างอิงจาก AI จึงเป็นเรื่องยาก
การวิเคราะห์เว็บแบบดั้งเดิมขึ้นอยู่กับส่วนหัว Referer และพารามิเตอร์แคมเปญอย่างมาก ซึ่งทั้งสองอย่างนี้อาจหายไปหรือไม่สมบูรณ์ได้
ส่วนหัว HTTP Referer อาจมีหน้าก่อนหน้า, เฉพาะต้นทางของเว็บไซต์ก่อนหน้า, หรือไม่มีค่าเลยก็ได้ นโยบาย Referrer ของเบราว์เซอร์สามารถจำกัดหรือลบข้อมูลนั้นออกไปโดยเจตนา เอกสาร MDN Referrer-Policy (developer.mozilla.org)
ระบบ AI สร้างความซับซ้อนเพิ่มเติมดังนี้:
- ผู้ช่วยอาจลิงก์ไปยังหน้าเว็บโดยไม่ส่งผู้แนะนำที่สามารถจดจำได้
- ผู้ช่วยอาจใช้ URL ที่เปลี่ยนเส้นทางหรือถูกเขียนใหม่
- ผู้ช่วยอาจดึงเนื้อหาจากฝั่งเซิร์ฟเวอร์ก่อนแสดงคำตอบ
- AI crawler อาจเยี่ยมชมหน้าเว็บโดยที่ไม่มีมนุษย์เห็นเลย
- คำตอบอาจอ้างอิง Canonical URL แทน URL ที่ถูกดึงมาแต่แรก
- คำตอบอาจเปลี่ยนแปลงไปขึ้นอยู่กับตำแหน่ง, อุปกรณ์, ภาษา, เวลา หรือการปรับให้เป็นส่วนตัว
ตัวอย่างเช่น OpenAI แยกความแตกต่างระหว่าง OAI-SearchBot สำหรับการค้นหา, GPTBot สำหรับการใช้งานที่เป็นไปได้ในการฝึกอบรม, และ ChatGPT-User สำหรับการกระทำที่ผู้ใช้เริ่มต้น Perplexity แยกแยะ PerplexityBot และ Perplexity-User Anthropic แยกแยะ ClaudeBot, Claude-SearchBot, และ Claude-User การร้องขอเหล่านี้ไม่ควรรวมเข้าเป็นตัวเลข "AI traffic" ทั่วไปเพียงตัวเลขเดียว เอกสารของ OpenAI crawler (openai.com) เอกสารของ Perplexity crawler (docs.perplexity.ai) เอกสารของ Anthropic crawler (support.anthropic.com)
กฎหลักคือ:
กิจกรรมของ Crawler ไม่ใช่ปริมาณการเข้าชมที่มาจากการอ้างอิง, การมองเห็นการอ้างอิงไม่ใช่ปริมาณการเข้าชม, และปริมาณการเข้าชมไม่ใช่ผลกระทบทางธุรกิจ
2. กรอบการวัดผล
ใช้การวัดผลห้าชั้น
| ชั้น | คำถามหลัก | ข้อมูลที่แนะนำ |
|---|---|---|
| การเข้าถึง | ระบบ AI ร้องขอหน้าเว็บหรือไม่? | บันทึกเซิร์ฟเวอร์เว็บ, บันทึกไฟร์วอลล์ |
| การมองเห็น | หน้าเว็บถูกแสดงหรือถูกอ้างอิงหรือไม่? | Google Search Console, Bing Webmaster Tools, การสังเกตแผงคำตอบ |
| การได้มาซึ่งผู้ใช้ | มีบุคคลเข้ามาจากพื้นผิว AI หรือไม่? | ผู้แนะนำ, พารามิเตอร์แคมเปญ, การคลิกลิงก์ย่อ, การวิเคราะห์ |
| การมีส่วนร่วม | ผู้เยี่ยมชมมีการโต้ตอบอย่างมีความหมายหรือไม่? | กิจกรรมใน Analytics, การดูหน้าเว็บ, เวลาการมีส่วนร่วม |
| มูลค่า | การเข้าชมนั้นก่อให้เกิดผลลัพธ์ที่ต้องการหรือไม่? | การลงทะเบียน, ลีด, การซื้อ, การสมัครสมาชิก |
ลำดับชั้นแหล่งข้อมูลที่น่าเชื่อถือที่แนะนำ
ใช้สัญญาณที่แข็งแกร่งที่สุดที่มีอยู่สำหรับแต่ละคำถาม:
- รายงานแพลตฟอร์มบุคคลที่หนึ่ง สำหรับการแสดงผลและการอ้างอิง
- การสังเกตแผงคำตอบ สำหรับการมองเห็นระดับคำถามและเปรียบเทียบกับคู่แข่ง
- บันทึกการเปลี่ยนเส้นทาง สำหรับการคลิกลิงก์ที่ควบคุมได้
- การวิเคราะห์เว็บ สำหรับเซสชัน, การมีส่วนร่วม, และการแปลง
- บันทึกเซิร์ฟเวอร์ สำหรับกิจกรรมของ crawler และ fetcher
- การประมาณค่าแบบจำลอง เฉพาะเมื่อไม่มีหลักฐานโดยตรง
อย่ารวมสัญญาณทั้งหมดเข้าเป็นตัวเลขเดียวโดยไม่รักษาสถานะแหล่งที่มาและระดับความเชื่อมั่น
3. แบบจำลองข้อมูลหลัก
สร้างคลังข้อมูลที่มีตารางแยกต่างหากสำหรับการสังเกตการณ์ดิบและเมตริกที่ได้มา
panel_runs
หนึ่งแถวสำหรับแต่ละคำถามและตรวจสอบพื้นผิว
text run_id observed_at surface topic prompt_id query_text locale country device pane l_present pane l_type answer_hash raw_html_path screenshot_path collector_version status
panel_citations
หนึ่งแถวสำหรับแต่ละลิงก์ที่พบในแผงคำตอบ
text run_id surface topic prompt_id cited_url cited_domain citation_position link_scope target_domain target_cited
ai_crawler_requests
ข้อมูลบันทึกเซิร์ฟเวอร์ที่รวมเข้าด้วยกัน
text date bot_name bot_role path requests successful_requests error_requests unique_ip_count
shortener_clicks
หนึ่งแถวสำหรับการร้องขอลิงก์ที่ควบคุมได้แต่ละครั้ง
text click_id occurred_at slug surface topic prompt_id asset_id referrer_host user_agent_family ip_hmac destination_path
ai_sessions
ตารางการวิเคราะห์ที่ถูกปรับรูปแบบแล้ว
text session_id date surface topic prompt_id landing_page attribution_method confidence engaged engagement_time_seconds key_event revenue
ฟิลด์ confidence มีความสำคัญ ค่าที่แนะนำคือ:
- A — โดยตรง: การคลิกลิงก์ย่อที่ควบคุมได้หรือพารามิเตอร์แคมเปญที่เชื่อถือได้
- B — แข็งแกร่ง: ผู้แนะนำผู้ช่วยที่รู้จักหรือคำขอที่ผู้ใช้ยืนยันแล้ว
- C — มีแนวโน้ม: หลักฐานจากแคมเปญหรือหน้า Landing Page โดยไม่มีผู้แนะนำที่สมบูรณ์
- D — แบบจำลอง: อนุมานจากเวลา, การสังเกตแผง, หรือการเปลี่ยนแปลงโดยรวม
รายงาน A และ B แยกต่างหากจาก C และ D
4. คำจำกัดความของเมตริก
สัดส่วนการอ้างอิงตามหัวข้อ (Citation Share by Topic)
Citation Share by Topic วัดความถี่ที่โดเมนเป้าหมายปรากฏในแหล่งข้อมูลที่สังเกตสำหรับหัวข้อนั้นๆ
\[ \text{Citation Share}_{topic}
\frac{\text{จำนวนการปรากฏของการอ้างอิงโดเมนเป้าหมาย}} {\text{จำนวนการปรากฏของการอ้างอิงทั้งหมด}} \]
ตัวอย่าง:
- มีการอ้างอิงทั้งหมด 100 ครั้งสำหรับ "ซอฟต์แวร์บริหารโครงการ"
- มีการอ้างอิง 12 ครั้งที่ชี้ไปยังโดเมนของคุณ
- Citation Share by Topic = 12%
เมตริกนี้วัด สัดส่วนแหล่งที่มา ไม่ใช่ว่าคำตอบนั้นมีเว็บไซต์ของคุณอย่างน้อยหนึ่งครั้งหรือไม่
ความครอบคลุมของการอ้างอิง (Citation Coverage)
ใช้เมตริกที่สองสำหรับการปรากฏในระดับคำตอบ:
\[ \text{Citation Coverage}_{topic}
\frac{\text{จำนวนรอบคำตอบที่มีการอ้างอิงเป้าหมาย}} {\text{จำนวนรอบคำตอบที่มีแผงคำตอบปรากฏ}} \]
Citation Coverage มักจะเข้าใจง่ายกว่าสำหรับผู้ชมที่ไม่ใช่ผู้เชี่ยวชาญ:
"เว็บไซต์ของเราปรากฏในคำตอบ AI ที่สังเกตได้ 34% สำหรับหัวข้อนี้"
ตำแหน่งการอ้างอิง (Citation Position)
บันทึกตำแหน่งของการอ้างอิงภายในคำตอบ:
1= แหล่งที่มาที่สังเกตพบครั้งแรก2= แหล่งที่มาที่สังเกตพบครั้งที่สอง3= แหล่งที่มาที่สังเกตพบครั้งที่สาม
เนื่องจากอินเทอร์เฟซ AI มักจะจัดกลุ่มหรือจัดลำดับแหล่งที่มาใหม่ ให้ถือว่าตำแหน่งเป็นข้อมูลเชิงพรรณนา ไม่ใช่การจัดอันดับที่เป็นสากล
อัตราการอ้างอิงจากผู้ช่วย (Assistant Referral Rate)
Assistant Referral Rate วัดสัดส่วนของเซสชันของผู้เยี่ยมชมที่เป็นมนุษย์ที่สามารถระบุแหล่งที่มาได้จากพื้นผิว AI
\[ \text{Assistant Referral Rate}
\frac{\text{เซสชันของผู้เยี่ยมชมที่เป็นมนุษย์ที่ระบุแหล่งที่มาได้จาก AI}} {\text{เซสชันของผู้เยี่ยมชมที่เป็นมนุษย์ทั้งหมด}} \]
รายงานอย่างน้อยสองเวอร์ชัน:
text อัตราการอ้างอิงจากผู้ช่วยที่ยืนยันแล้ว = เซสชัน AI ที่มีความเชื่อมั่นระดับ A / เซสชันของมนุษย์ทั้งหมด
อัตราการอ้างอิงจากผู้ช่วยที่ขยายแล้ว = เซสชัน AI ที่มีความเชื่อมั่นระดับ A + B + C / เซสชันของมนุษย์ทั้งหมด
เวอร์ชันที่ยืนยันแล้วจะอนุรักษ์นิยมมากกว่า ส่วนเวอร์ชันที่ขยายแล้วมีประโยชน์สำหรับการวิเคราะห์แนวโน้ม แต่ไม่ควรอ้างว่าเป็นปริมาณการเข้าชมที่ถูกสังเกตการณ์อย่างสมบูรณ์
อย่าใช้การรันแผงคำตอบเป็นการแสดงผล
หากคุณรวบรวมข้อมูลจากคำถาม 500 คำถาม นั่นไม่ได้หมายความว่ามีคน 500 คนเห็นคำตอบเหล่านั้น Scraper ของคุณวัดผลจากตัวอย่างสถานะคำตอบที่ควบคุมได้ ใช้รายงานการแสดงผลจากแพลตฟอร์มบุคคลที่หนึ่งเมื่อมีข้อมูลให้ใช้
การมีส่วนร่วมหลังการอ้างอิง (Post-Citation Engagement)
Post-Citation Engagement วัดว่าผู้ที่เข้ามาผ่านการอ้างอิง AI ได้ดำเนินการที่มีความหมายหรือไม่
\[ \text{Post-Citation Engagement}
\frac{\text{เซสชัน AI ที่มีส่วนร่วม}} {\text{เซสชันที่ระบุแหล่งที่มาได้จาก AI}} \]
สำหรับ Google Analytics 4 เซสชันที่มีส่วนร่วมคือเซสชันที่มีระยะเวลานานกว่า 10 วินาที, มีเหตุการณ์สำคัญ, หรือมีการดูหน้าเว็บหรือหน้าจออย่างน้อยสองครั้ง เอกสารอัตราการมีส่วนร่วมของ Google Analytics (support.google.com)
รายงานเพิ่มเติม:
text เวลาการมีส่วนร่วมหลังการอ้างอิง = ค่ามัธยฐานของวินาทีที่มีส่วนร่วมต่อเซสชัน AI
อัตราการเปลี่ยน (Conversion Rate) หลังการอ้างอิง = เซสชัน AI ที่มีเหตุการณ์สำคัญ / เซสชันที่ระบุแหล่งที่มาได้จาก AI
รายได้ต่อเซสชันหลังการอ้างอิง = รายได้จากเซสชัน AI / เซสชันที่ระบุแหล่งที่มาได้จาก AI
เวลาการมีส่วนร่วมเฉลี่ย (Median engagement time) มักจะเสถียรกว่าเวลาการมีส่วนร่วมเฉลี่ย (average engagement time) เนื่องจากเซสชันที่ยาวนานมากๆ จำนวนน้อยอาจทำให้ค่าเฉลี่ยผิดเพี้ยนได้
เมตริกที่เป็นประโยชน์เพิ่มเติม
อัตราความสำเร็จของ AI Crawler (AI Crawler Success Rate)
\[ \text{Crawler Success Rate}
\frac{\text{คำขอ AI crawler ที่คืนค่า 2xx หรือ 3xx}} {\text{คำขอ AI crawler ทั้งหมด}} \]
แบ่งย่อยตาม bot และ path อัตราการลดลงของการอ้างอิงที่สูงร่วมกับอัตราข้อผิดพลาดของ crawler ที่เพิ่มขึ้นอาจบ่งชี้ถึงปัญหาการโฮสต์, ไฟร์วอลล์, หรือการกำหนดค่า robots
อัตราการคลิกจากอ้างอิง (Citation-to-Click Rate)
สำหรับการสังเกตแผงคำตอบที่ควบคุมได้:
\[ \text{Observed Citation-to-Click Rate}
\frac{\text{จำนวนการคลิกลิงก์ย่อที่ยืนยันแล้ว}} {\text{จำนวนการอ้างอิงเป้าหมายที่สังเกตพบ}} \]
นี่ไม่ใช่อัตราการคลิกผ่านของผู้ใช้ที่แท้จริง เว้นแต่ตัวส่วนจะแสดงถึงการแสดงผลของผู้ใช้จริง ระบุให้ชัดเจนว่าเป็นเมตริกการดำเนินงานที่สังเกตการณ์ได้
ความสดใหม่ของการอ้างอิง (Citation Freshness)
วัดความถี่ที่ URL ที่ถูกอ้างอิงสะท้อนถึงเวอร์ชันหน้าปัจจุบัน
text ความสดใหม่ของการอ้างอิง = หน้าที่ถูกอ้างอิงที่มีแฮชเนื้อหาปัจจุบัน / หน้าที่ถูกอ้างอิงทั้งหมด
สิ่งนี้มีประโยชน์สำหรับเอกสาร, ราคา, ผลิตภัณฑ์ และหน้าเพจนโยบายที่มีการเปลี่ยนแปลงบ่อยครั้ง
5. การวิเคราะห์บันทึกเซิร์ฟเวอร์
กำหนดค่าบันทึกการเข้าถึงแบบมีโครงสร้าง
บันทึกแบบมีโครงสร้างวิเคราะห์ง่ายกว่าบันทึกแบบดั้งเดิมที่คั่นด้วยช่องว่าง
ตัวอย่างการกำหนดค่า Nginx:
nginx log_format ai_json escape=json '{' '"ts":"$time_iso8601",' '"remote_addr":"$remote_addr",' '"request":"$request",' '"status":$status,' '"bytes":$body_bytes_sent,' '"referer":"$http_referer",' '"user_agent":"$http_user_agent",' '"host":"$host"' '}';
access_log /var/log/nginx/ai-access.jsonl ai_json;
จัดเก็บไฟล์บันทึกในตำแหน่งที่จำกัด อย่าส่งที่อยู่ IP ดิบไปยังตารางการวิเคราะห์ทั่วไป เว้นแต่คุณจะมีเหตุผลในการดำเนินการที่ชัดเจน
ระบุประเภทคำขอ AI
อย่างน้อยที่สุด ให้แยกสิ่งเหล่านี้:
text OpenAI:
- OAI-SearchBot
- ChatGPT-User
- GPTBot
Anthropic:
- Claude-SearchBot
- Claude-User
- ClaudeBot
Perplexity:
- PerplexityBot
- Perplexity-User
Search engines:
- Googlebot
- Bingbot
คุณสมบัติ AI Search ของ Google โดยทั่วไปใช้การควบคุมการรวบรวมข้อมูลของ Google Search ที่มีอยู่แล้ว แทนที่จะใช้ "AI Overview bot" แยกต่างหาก Google ระบุว่า Googlebot ควบคุมการเข้าถึงสำหรับการค้นหา รวมถึงคุณสมบัติ AI คุณสมบัติ AI ของ Google และเว็บไซต์ (developers.google.com)
สตริง User-agent สามารถปลอมแปลงได้ สำหรับการตัดสินใจในการดำเนินงาน ให้รวมการจับคู่ user-agent เข้ากับช่วง IP ที่ผู้ให้บริการเผยแพร่หรือการตรวจสอบ reverse DNS ที่ยืนยันได้ (หากมี) OpenAI และ Perplexity เผยแพร่ข้อมูล IP สำหรับ crawler และ fetcher ที่เกี่ยวข้องของพวกเขา (openai.com)
ตัวสรุปบันทึกที่สามารถทำซ้ำได้
บันทึกสิ่งต่อไปนี้เป็น ai_log_summary.py
python #!/usr/bin/env python3
import csv import hashlib import hmac import json import os import re import sys from collections import Counter, defaultdict from datetime import datetime from urllib.parse import urlsplit
BOT_PATTERNS = { "OAI-SearchBot": ("openai", re.compile(r"\bOAI-SearchBot\b", re.I)), "ChatGPT-User": ("openai_user", re.compile(r"\bChatGPT-User\b", re.I)), "GPTBot": ("openai_training", re.compile(r"\bGPTBot\b", re.I)), "Claude-SearchBot": ("anthropic", re.compile(r"\bClaude-SearchBot\b", re.I)), "Claude-User": ("anthropic_user", re.compile(r"\bClaude-User\b", re.I)), "ClaudeBot": ("anthropic_training", re.compile(r"\bClaudeBot\b", re.I)), "PerplexityBot": ("perplexity", re.compile(r"\bPerplexityBot\b", re.I)), "Perplexity-User": ("perplexity_user", re.compile(r"\bPerplexity-User\b", re.I)), "Googlebot": ("google_search", re.compile(r"\bGooglebot\b", re.I)), "Bingbot": ("bing_search", re.compile(r"\bbingbot\b", re.I)), }
SECRET = os.environ.get("HMAC_SECRET", "replace-this-in-production").encode()
def hmac_ip(ip): return hmac.new(SECRET, ip.encode(), hashlib.sha256).hexdigest()[:16]
def classify_bot(user_agent): for bot_name, (role, pattern) in BOT_PATTERNS.items(): if pattern.search(user_agent or ""): return bot_name, role return None, None
def parse_path(request_line): try: parts = request_line.split() return urlsplit(parts[1]).path except Exception: return "/"
def main(input_path): totals = defaultdict(lambda: { "requests": 0, "success": 0, "errors": 0, "ips": set(), "paths": Counter(), })
with open(input_path, "r", encoding="utf-8") as source:
for line in source:
try:
record = json.loads(line)
except json.JSONDecodeError:
continue
bot_name, bot_role = classify_bot(record.get("user_agent", ""))
if not bot_name:
continue
timestamp = record.get("ts", "")
date = datetime.fromisoformat(
timestamp.replace("Z", "+00:00")
).date().isoformat()
status = int(record.get("status", 0))
path = parse_path(record.get("request", ""))
key = (date, bot_name, bot_role)
totals[key]["requests"] += 1
totals[key]["ips"].add(hmac_ip(record.get("remote_addr", "")))
totals[key]["paths"][path] += 1
if 200 <= status < 400:
totals[key]["success"] += 1
else:
totals[key]["errors"] += 1
writer = csv.writer(sys.stdout)
writer.writerow([
"date",
"bot_name",
"bot_role",
"requests",
"successful_requests",
"error_requests",
"unique_ip_count",
"top_paths",
])
for (date, bot_name, bot_role), values in sorted(totals.items()):
top_paths = values["paths"].most_common(10)
writer.writerow([
date,
bot_name,
bot_role,
values["requests"],
values["success"],
values["errors"],
len(values["ips"]),
json.dumps(top_paths),
])
if name == "main": if len(sys.argv) != 2: print("Usage: python ai_log_summary.py /path/to/access.jsonl") sys.exit(1)
main(sys.argv[1])
เรียกใช้ด้วย:
bash HMAC_SECRET='a-long-random-secret' \ python ai_log_summary.py /var/log/nginx/ai-access.jsonl \
data/ai_crawler_daily.csv
สิ่งนี้ให้หลักฐานการดำเนินงานเกี่ยวกับ กิจกรรมการดึงข้อมูล ไม่ใช่ปริมาณการเข้าชมของผู้ใช้
6. เครื่องมือย่อลิงก์แบบกำหนดเองสำหรับสรุปข้อมูลที่แสดงต่อ AI
เครื่องมือย่อลิงก์ของบุคคลที่หนึ่งเป็นจุดวัดผลที่ควบคุมได้เมื่อคุณเผยแพร่ข้อมูลสรุปหรือเอกสารอ้างอิงที่ระบบ AI อาจอ้างอิงถึง
ใช้โดเมนที่คุณควบคุม เช่น:
text https://go.example.com/ai-docs
ปลายทางควรมีพารามิเตอร์แคมเปญ เช่น:
text utm_source=perplexity utm_medium=ai_answer utm_campaign=product_documentation utm_content=pricing_summary_v3
Google แนะนำพารามิเตอร์แคมเปญสำหรับการระบุแหล่งที่มาของการเข้าชมและแคมเปญ เอกสาร URL แคมเปญของ Google Analytics (support.google.com)
ฟิลด์ลิงก์ที่แนะนำ
text surface topic prompt_id asset_id content_version destination_path
ห้ามใส่ข้อมูลส่วนตัว, ที่อยู่อีเมล หรือคำค้นหาของผู้ใช้ลงในลิงก์ ตัวระบุแคมเปญควรอธิบายถึงเนื้อหาที่เผยแพร่ ไม่ใช่การระบุตัวบุคคล
ข้อจำกัดที่สำคัญ
ลิงก์ย่อเป็น อุปกรณ์สอบเทียบ ไม่ใช่วิธีแก้ปัญหาสากล:
- ผู้ช่วยอาจเขียน URL ปลายทางใหม่
- ผู้ช่วยอาจอ้างอิง Canonical URL แทน
- ลิงก์อาจถูกแสดงแต่ไม่เคยถูกคลิก
- เบราว์เซอร์หรือเครื่องมือความเป็นส่วนตัวอาจลบผู้แนะนำออก
- บางระบบอาจดึงปลายทางจากฝั่งเซิร์ฟเวอร์
- ลิงก์ย่อไม่ได้วัดผู้ใช้ที่จดจำแบรนด์และกลับมาภายหลัง
อย่าใช้เครื่องมือย่อลิงก์เพื่อซ่อนปลายทาง, หลีกเลี่ยงระบบความปลอดภัย หรือบิดเบือนการอ้างอิง ใช้การเปลี่ยนเส้นทางที่ชัดเจนไปยังหน้า Canonical ที่เกี่ยวข้อง
เครื่องมือย่อลิงก์บุคคลที่หนึ่งแบบขั้นต่ำ
ตัวอย่างต่อไปนี้ใช้ FastAPI และ SQLite โปรดป้องกัน endpoint การสร้างลิงก์ด้วยการรับรองความถูกต้องก่อนนำไปใช้งานจริง
python
shortener.py
import hashlib import hmac import os import secrets import sqlite3 from datetime import datetime, timezone from urllib.parse import parse_qsl, urlencode, urlsplit, urlunsplit
from fastapi import FastAPI, HTTPException, Request from fastapi.responses import RedirectResponse from pydantic import BaseModel
DB_PATH = os.environ.get("SHORTENER_DB", "shortener.db") HMAC_SECRET = os.environ.get( "HMAC_SECRET", "replace-this-in-production" ).encode()
ALLOWED_HOST = "www.example.com"
app = FastAPI()
def db(): connection = sqlite3.connect(DB_PATH) connection.row_factory = sqlite3.Row return connection
def init_db(): connection = db() connection.execute(""" CREATE TABLE IF NOT EXISTS links ( slug TEXT PRIMARY KEY, destination TEXT NOT NULL, surface TEXT NOT NULL, topic TEXT, prompt_id TEXT, asset_id TEXT, created_at TEXT NOT NULL ) """) connection.execute(""" CREATE TABLE IF NOT EXISTS clicks ( id INTEGER PRIMARY KEY AUTOINCREMENT, occurred_at TEXT NOT NULL, slug TEXT NOT NULL, surface TEXT, topic TEXT, prompt_id TEXT, referrer_host TEXT, user_agent TEXT, ip_hmac TEXT ) """) connection.commit() connection.close()
def append_query(url, params): parsed = urlsplit(url) query = dict(parse_qsl(parsed.query, keep_blank_values=True)) query.update(params) return urlunsplit(( parsed.scheme, parsed.netloc, parsed.path, urlencode(query), parsed.fragment, ))
def hash_ip(ip): return hmac.new( HMAC_SECRET, (ip or "").encode(), hashlib.sha256 ).hexdigest()[:16]
class LinkRequest(BaseModel): destination_path: str surface: str topic: str | None = None prompt_id: str | None = None asset_id: str | None = None
@app.on_event("startup") def startup(): init_db()
@app.post("/links") def create_link(payload: LinkRequest): destination = f"https://{ALLOWED_HOST}{payload.destination_path}"
if not payload.destination_path.startswith("/"):
raise HTTPException(400, "destination_path must be a site-relative path")
slug = secrets.token_urlsafe(7).replace("_", "-").replace("/", "-")
target = append_query(destination, {
"utm_source": payload.surface,
"utm_medium": "ai_answer",
"utm_campaign": "citation_measurement",
"utm_content": payload.asset_id or "unspecified",
})
connection = db()
connection.execute("""
INSERT INTO links
(slug, destination, surface, topic, prompt_id, asset_id, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (
slug,
target,
payload.surface,
payload.topic,
payload.prompt_id,
payload.asset_id,
datetime.now(timezone.utc).isoformat(),
))
connection.commit()
connection.close()
return {"slug": slug, "url": f"https://go.example.com/{slug}"}
@app.get("/{slug}") def redirect(slug: str, request: Request): connection = db() row = connection.execute( "SELECT * FROM links WHERE slug = ?", (slug,) ).fetchone()
if not row:
connection.close()
raise HTTPException(404, "Unknown link")
referrer = request.headers.get("referer", "")
referrer_host = urlsplit(referrer).hostname or ""
connection.execute("""
INSERT INTO clicks
(occurred_at, slug, surface, topic, prompt_id,
referrer_host, user_agent, ip_hmac)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
""", (
datetime.now(timezone.utc).isoformat(),
slug,
row["surface"],
row["topic"],
row["prompt_id"],
referrer_host,
request.headers.get("user-agent", "")[:300],
hash_ip(request.client.host if request.client else ""),
))
connection.commit()
connection.close()
return RedirectResponse(row["destination"], status_code=302)
เรียกใช้ด้วย:
bash pip install fastapi uvicorn uvicorn shortener:app --host 0.0.0.0 --port 8080
ใช้การเปลี่ยนเส้นทาง 302 สำหรับลิงก์การวัดผล เพื่อลดโอกาสที่เบราว์เซอร์และระบบตัวกลางจะแคชการเปลี่ยนเส้นทางอย่างถาวร
7. การรวบรวมข้อมูลจากแผงคำตอบ AI ตามกำหนดเวลา
การรวบรวมข้อมูลจากแผงคำตอบมีประโยชน์สำหรับการตอบคำถามที่ข้อมูลวิเคราะห์ของบุคคลที่หนึ่งอาจไม่เปิดเผย:
- มีการอ้างอิงแหล่งที่มาคู่แข่งใดบ้าง?
- มีการอ้างอิงหน้าใดสำหรับคำถามที่เฉพาะเจาะจง?
- คำตอบมีการเปลี่ยนแปลงตามประเทศหรืออุปกรณ์หรือไม่?
- การอ้างอิงปรากฏในคำตอบ, รายการแหล่งที่มา หรือทั้งสองอย่าง?
- คำตอบมีความเสถียรเมื่อเวลาผ่านไปหรือไม่?
- ผู้ช่วยอ้างอิงลิงก์ย่อหรือ Canonical URL?
อย่างไรก็ตาม การรวบรวมข้อมูลต้องทำอย่างระมัดระวัง
กฎสำหรับการรวบรวมข้อมูลอย่างมีความรับผิดชอบ
- เลือกใช้ API อย่างเป็นทางการ, ผู้ให้บริการข้อมูลการค้นหาที่ได้รับอนุญาต หรือรายงานบุคคลที่หนึ่ง
- ตรวจสอบข้อกำหนดของผู้ให้บริการก่อนดำเนินการร้องขอแบบอัตโนมัติ
- เคารพคำสั่ง robots หากมี
- ห้ามหลีกเลี่ยง CAPTCHA, อุปสรรคการเข้าสู่ระบบ, ข้อจำกัดอัตรา, หรือการป้องกันบอท
- ใช้ชุดคำถามขนาดเล็กและคงที่
- ดำเนินการด้วยความถี่ต่ำ
- บันทึกการตอบกลับและเวลาเพื่อตรวจสอบผลลัพธ์ได้
- หยุดเมื่อผู้ให้บริการคืนค่าการท้าทายหรือการตอบกลับที่ถูกปฏิเสธการเข้าถึง
Robots Exclusion Protocol เป็นกลไกการตั้งค่าของ crawler ไม่ใช่ระบบรักษาความปลอดภัย ไม่ได้อนุญาตการเข้าถึงเนื้อหาที่ได้รับการป้องกัน RFC 9309: Robots Exclusion Protocol (rfc-editor.org)
สร้างรายการคำถาม (Prompt Manifest)
csv prompt_id,topic,query,locale,surface,target_domain pm_001,project-management,"best project management software for remote teams",en-US,google,example.com pm_001,project-management,"best project management software for remote teams",en-US,bing,example.com pm_002,analytics,"how to measure AI referral traffic",en-US,google,example.com
รักษาคำถามให้คงที่ หากคำถามเปลี่ยนแปลง การเปรียบเทียบแนวโน้มจะเชื่อถือได้น้อยลง
จัดเก็บข้อมูลเพิ่มเติมดังนี้:
- ประเทศ
- ภาษา
- ประเภทอุปกรณ์
- เวอร์ชันเบราว์เซอร์
- เวอร์ชันคำถาม
- เวอร์ชันเนื้อหา
- เวลาที่รวบรวมใน UTC
Google ระบุว่าการตอบกลับของ AI Overview และ AI Mode อาจแตกต่างกันไปเนื่องจากใช้ระบบที่แตกต่างกันและอาจใช้การค้นหาที่เกี่ยวข้องหรือ "query fan-out" เอกสารคุณสมบัติ AI ของ Google และเว็บไซต์ (developers.google.com)
สคริปต์ Playwright สำหรับการรวบรวมข้อมูล
สคริปต์ต่อไปนี้เป็นเครื่องมือวิจัยเอนกประสงค์ มันจะบันทึกหน้าเว็บที่เรนเดอร์, สกรีนช็อต, ลิงก์ในหน้า และข้อความคำตอบ โดยมีเจตนาที่จะไม่หลีกเลี่ยงการท้าทายหรือพยายามเอาชนะการควบคุมการเข้าถึง
python
scrape_panels.py
import asyncio import csv import hashlib import json import os import re from datetime import datetime, timezone from pathlib import Path from urllib.parse import quote_plus, urljoin, urlsplit
from playwright.async_api import async_playwright
DATA_DIR = Path("data/panels") DATA_DIR.mkdir(parents=True, exist_ok=True)
SURFACE_URLS = { "google": "https://www.google.com/search?q={query}&hl=en&gl=us", "bing": "https://www.bing.com/search?q={query}&setlang=en-us", }
PANEL_MARKERS = { "google": ["AI Overview", "AI Mode"], "bing": ["Copilot", "Generative search"], }
BLOCK_MARKERS = [ "captcha", "unusual traffic", "verify you are human", "access denied", ]
def clean_text(value): return re.sub(r"\s+", " ", value or "").strip()
def host_matches(url, target_domain): host = (urlsplit(url).hostname or "").lower() target = target_domain.lower().lstrip("www.") return host == target or host.endswith("." + target)
def page_hash(text): normalized = clean_text(text).encode("utf-8") return hashlib.sha256(normalized).hexdigest()
async def collect_one(page, row): surface = row["surface"] query = row["query"] target_domain = row["target_domain"]
search_url = SURFACE_URLS[surface].format(
query=quote_plus(query)
)
await page.goto(
search_url,
wait_until="domcontentloaded",
timeout=45_000,
)
await page.wait_for_timeout(2500)
text = await page.locator("body").inner_text()
lowered = text.lower()
if any(marker in lowered for marker in BLOCK_MARKERS):
return {
**row,
"observed_at": datetime.now(timezone.utc).isoformat(),
"status": "blocked_or_challenged",
"panel_present": False,
"links": [],
}
links = await page.locator("a").evaluate_all("""
anchors => anchors.map(a => ({
href: a.href || "",
text: (a.innerText || "").trim()
})).filter(x => x.href)
""")
panel_present = any(
marker.lower() in lowered
for marker in PANEL_MARKERS.get(surface, [])
)
observed_at = datetime.now(timezone.utc)
run_id = hashlib.sha256(
f"{surface}|{row['prompt_id']}|{observed_at.isoformat()}".encode()
).hexdigest()[:20]
html_path = DATA_DIR / f"{run_id}.html"
screenshot_path = DATA_DIR / f"{run_id}.png"
await page.screenshot(path=str(screenshot_path), full_page=True)
html_path.write_text(await page.content(), encoding="utf-8")
output_links = []
for position, link in enumerate(links, start=1):
output_links.append({
"href": urljoin(search_url, link["href"]),
"text": clean_text(link["text"])[:300],
"position": position,
"target_cited": host_matches(
link["href"],
target_domain
),
})
return {
**row,
"run_id": run_id,
"observed_at": observed_at.isoformat(),
"status": "ok",
"panel_present": panel_present,
"answer_hash": page_hash(text),
"answer_text": clean_text(text)[:50_000],
"html_path": str(html_path),
"screenshot_path": str(screenshot_path),
"link_scope": "page_fallback",
"links": output_links,
}
async def main(manifest_path): rows = [] with open(manifest_path, newline="", encoding="utf-8") as source: rows = list(csv.DictReader(source))
output_path = DATA_DIR / (
datetime.now(timezone.utc).strftime("%Y-%m-%d") + ".jsonl"
)
async with async_playwright() as playwright:
browser = await playwright.chromium.launch(headless=True)
context = await browser.new_context(
locale="en-US",
timezone_id="UTC",
)
page = await context.new_page()
with open(output_path, "w", encoding="utf-8") as output:
for row in rows:
try:
result = await collect_one(page, row)
except Exception as exc:
result = {
**row,
"observed_at": datetime.now(timezone.utc).isoformat(),
"status": f"error:{type(exc).__name__}",
"panel_present": False,
"links": [],
}
output.write(json.dumps(result) + "\
") output.flush()
# Keep request volume low.
await asyncio.sleep(8)
await browser.close()
if name == "main": asyncio.run(main("prompts.csv"))
ติดตั้งและรัน:
bash pip install playwright playwright install chromium python scrape_panels.py
กำหนดเวลาด้วยการล็อก เพื่อไม่ให้สองการทำงานทับซ้อนกัน:
cron 15 3 * * * flock -n /tmp/ai-panel.lock \ /usr/bin/python3 /opt/ai-measure/scrape_panels.py
ปรับปรุงความแม่นยำด้วยตัวปรับพื้นผิว
สคริปต์สำรองจะบันทึกลิงก์ระดับหน้า ซึ่งมีประโยชน์สำหรับการค้นพบ แต่อาจรวมลิงก์ผลการค้นหาปกติได้ สำหรับการใช้งานจริง:
- ใช้ API แผงคำตอบที่ได้รับอนุญาตเมื่อมี
- สร้างตัวปรับตัวเลือกแยกต่างหากสำหรับแต่ละพื้นผิว
- จัดเก็บเวอร์ชันของตัวเลือก
- จัดเก็บ HTML ดิบและสกรีนช็อต
- ทำเครื่องหมายทุกเรคคอร์ดด้วย
link_scope = "panel_selector"หรือlink_scope = "page_fallback"
คำนวณ Citation Share จากข้อมูล panel_selector เท่านั้น เมื่อคุณสามารถระบุแผงคำตอบได้อย่างน่าเชื่อถือ เก็บการสังเกตการณ์สำรองไว้ในรายงานการสำรวจแยกต่างหาก
8. การรวม Google Analytics และ BigQuery
Google Analytics 4 สามารถส่งออกข้อมูลเหตุการณ์ดิบไปยัง BigQuery ได้ การส่งออกรายวันให้ตารางที่เสถียร เช่น events_YYYYMMDD; การส่งออกแบบสตรีมมิ่งมีประโยชน์สำหรับการตรวจสอบใกล้เคียงเรียลไทม์ แต่อาจไม่สมบูรณ์จนกว่าตารางรายวันจะเสร็จสมบูรณ์ การส่งออก Google Analytics ไปยัง BigQuery (support.google.com)
การสืบค้นเซสชันแบบง่ายอาจมีลักษณะดังนี้:
sql WITH page_events AS ( SELECT event_date, user_pseudo_id,
(
SELECT value.int_value
FROM UNNEST(event_params)
WHERE key = 'ga_session_id'
) AS session_id,
(
SELECT value.string_value
FROM UNNEST(event_params)
WHERE key = 'page_location'
) AS page_location,
(
SELECT value.string_value
FROM UNNEST(event_params)
WHERE key = 'session_engaged'
) AS session_engaged,
event_name
FROM PROJECT.analytics_PROPERTY.events_*
WHERE _TABLE_SUFFIX BETWEEN '20260901' AND '20260921'
),
session_rollup AS ( SELECT event_date, user_pseudo_id, session_id,
MAX(
CASE
WHEN REGEXP_CONTAINS(
LOWER(page_location),
r'[?&]utm_medium=ai_answer'
)
THEN 1 ELSE 0
END
) AS ai_session,
MAX(
CASE
WHEN session_engaged = '1'
THEN 1 ELSE 0
END
) AS engaged_session,
MAX(
CASE
WHEN event_name IN ('purchase', 'generate_lead', 'sign_up')
THEN 1 ELSE 0
END
) AS key_event
FROM page_events GROUP BY event_date, user_pseudo_id, session_id )
SELECT event_date, COUNTIF(ai_session = 1) AS ai_sessions, COUNTIF(ai_session = 1 AND engaged_session = 1) AS engaged_ai_sessions, COUNTIF(ai_session = 1 AND key_event = 1) AS ai_key_events, SAFE_DIVIDE( COUNTIF(ai_session = 1 AND engaged_session = 1), COUNTIF(ai_session = 1) ) AS post_citation_engagement_rate FROM session_rollup GROUP BY event_date ORDER BY event_date;
สำหรับการนำไปใช้งานที่สมบูรณ์ ให้เพิ่ม surface, topic และ prompt_id ลงในโครงสร้างแคมเปญ หรือรวมเข้ากับตารางคลิกลิงก์ย่อ
อย่าสร้างมิติข้อมูลการวิเคราะห์ที่มีความละเอียดสูง (high-cardinality analytics dimension) สำหรับผู้ใช้หรือเซสชันแต่ละราย Google เตือนว่ามิติข้อมูลที่กำหนดเองที่มีความละเอียดสูงเกินไปอาจลดคุณภาพการรายงานลง มิติข้อมูลและเมตริกที่กำหนดเองของ Google Analytics (support.google.com)
9. การออกแบบแดชบอร์ด
แดชบอร์ดที่ใช้งานได้จริงควรรวมห้ามุมมอง
สรุปสำหรับผู้บริหาร
แสดง:
- Citation Share by Topic
- Citation Coverage by Topic
- Confirmed Assistant Referral Rate
- Expanded Assistant Referral Rate
- Post-Citation Engagement
- AI crawler success rate
- AI-attributed key events หรือ revenue
แนวโน้มสัดส่วนการอ้างอิง
แผนภูมิเส้น:
text วันที่ × หัวข้อ × พื้นผิว
แสดงทั้งสองอย่าง:
- จำนวนการปรากฏของการอ้างอิงโดเมนเป้าหมาย
- จำนวนการปรากฏของการอ้างอิงทั้งหมดที่สังเกตได้
ช่องทางปริมาณการเข้าชมจากผู้ช่วย
text การอ้างอิงที่สังเกตได้ ↓ การคลิกลิงก์ที่ควบคุมได้ ↓ เซสชันที่ระบุแหล่งที่มาได้จาก AI ↓ เซสชัน AI ที่มีส่วนร่วม ↓ เหตุการณ์สำคัญ
แต่ละขั้นตอนควรแสดงความเชื่อมั่นในการระบุแหล่งที่มา
สุขภาพของ Crawler
ตารางแยกตาม bot:
text bot_name requests successful_requests error_rate unique_ip_count top_paths
แจ้งเตือนเมื่อ:
- อัตราข้อผิดพลาดเกิน 2 เปอร์เซ็นต์
- บอทหายไปอย่างกะทันหัน
- ส่วนเนื้อหาที่เคยเข้าถึงได้ส่งค่า 403 หรือ 429 กลับมา
- คำขอของ crawler มุ่งเน้นไปที่เส้นทางส่วนตัวที่ไม่ตั้งใจ
ตารางโอกาสเนื้อหา
จัดอันดับหน้าและหัวข้อตาม:
text สัดส่วนการอ้างอิงสูง + อัตราการอ้างอิงต่ำ การแสดงผลสูง + ความครอบคลุมการอ้างอิงต่ำ การมีส่วนร่วมสูง + การมองเห็นการอ้างอิงต่ำ ข้อผิดพลาดของ crawler สูง + ความสำคัญทางธุรกิจสูง
การรวมกันเหล่านี้มักจะนำไปสู่การตัดสินใจที่ดีกว่าการดูเฉพาะปริมาณการเข้าชม
แดชบอร์ด Streamlit แบบขั้นต่ำ
บันทึกเป็น dashboard.py
python import glob import json from pathlib import Path
import pandas as pd import streamlit as st
st.set_page_config( page_title="AI Citation Impact", layout="wide", )
@st.cache_data(ttl=300) def load_panel_rows(): rows = []
for filename in glob.glob("data/panels/*.jsonl"):
with open(filename, encoding="utf-8") as source:
for line in source:
record = json.loads(line)
run_id = record.get("run_id")
for link in record.get("links", []):
hostname = link.get("href", "").split("/")[2]
rows.append({
"run_id": run_id,
"observed_at": record.get("observed_at"),
"surface": record.get("surface"),
"topic": record.get("topic"),
"prompt_id": record.get("prompt_id"),
"panel_present": record.get("panel_present"),
"target_domain": record.get("target_domain"),
"cited_domain": hostname,
"target_cited": link.get("target_cited", False),
"position": link.get("position"),
"link_scope": record.get("link_scope"),
})
return pd.DataFrame(rows)
panels = load_panel_rows()
st.title("AI Citation Impact Dashboard")
if panels.empty: st.warning("No panel observations found.") st.stop()
panels["date"] = pd.to_datetime( panels["observed_at"], errors="coerce" ).dt.date
citation_share = ( panels.groupby("topic") .apply( lambda group: group["target_cited"].sum() / max(len(group), 1) ) .reset_index(name="citation_share") )
coverage = ( panels.groupby(["topic", "run_id"], dropna=False) .agg( panel_present=("panel_present", "max"), target_cited=("target_cited", "max"), ) .reset_index() )
coverage = ( coverage[coverage["panel_present"] == True] .groupby("topic") .apply(lambda group: group["target_cited"].mean()) .reset_index(name="citation_coverage") )
col1, col2 = st.columns(2)
with col1: st.subheader("Citation Share by Topic") st.dataframe(citation_share, use_container_width=True) st.bar_chart( citation_share.set_index("topic")["citation_share"] )
with col2: st.subheader("Citation Coverage by Topic") st.dataframe(coverage, use_container_width=True) st.bar_chart( coverage.set_index("topic")["citation_coverage"] )
st.subheader("Citation Position") st.dataframe( panels.groupby(["topic", "surface"], dropna=False) .agg( citations=("target_cited", "sum"), median_position=("position", "median"), observations=("run_id", "nunique"), ) .reset_index(), use_container_width=True, )
st.subheader("Daily Observations") daily = ( panels.groupby(["date", "surface"], dropna=False) .agg( citations=("target_cited", "sum"), observed_links=("cited_domain", "count"), ) .reset_index() )
st.line_chart( daily.pivot( index="date", columns="surface", values="citations" ).fillna(0) )
เรียกใช้ด้วย:
bash pip install streamlit pandas streamlit run dashboard.py
สำหรับการใช้งานจริง ให้โหลดตารางที่ถูกปรับรูปแบบแล้วลงใน DuckDB, BigQuery, Snowflake หรือ PostgreSQL แทนการอ่านไฟล์ดิบโดยตรง
10. การควบคุมคุณภาพ
ระบบการวัดผลสามารถสร้างตัวเลขที่ดูแม่นยำแต่ก็อาจทำให้เข้าใจผิดได้ เพิ่มการควบคุมเหล่านี้
แยกบอทออกจากผู้ใช้
ห้ามนับ OAI-SearchBot, GPTBot, ClaudeBot, หรือ PerplexityBot เป็นเซสชันของผู้ใช้ เหล่านี้คือสัญญาณของ crawler หรือการดึงข้อมูล
รักษาหลักฐานดิบ
สำหรับทุกการรันแผงคำตอบ ให้เก็บ:
- HTML ดิบ
- สกรีนช็อต
- ข้อความคำตอบ
- เวลา
- เวอร์ชันเบราว์เซอร์และตัวรวบรวม
- คำถามและ Locale
- แฮชคำตอบ
สิ่งนี้ทำให้สามารถอธิบายได้ว่าเหตุใดเมตริกจึงเปลี่ยนแปลง
ติดตามการไม่ปรากฏของแผงคำตอบ
แผง AI ที่หายไปไม่เหมือนกับคำตอบที่ไม่มีการอ้างอิงของคุณ
ใช้:
text panel_not_present panel_present_no_target panel_present_target_cited blocked_or_challenged collection_error
ควบคุมอคติการสุ่มตัวอย่าง
การรวบรวมข้อมูลตามกำหนดเวลาได้รับผลกระทบจาก:
- ตำแหน่ง
- อุปกรณ์
- ภาษา
- เวลา
- การปรับให้เป็นส่วนตัว
- สถานะเบราว์เซอร์
- ถ้อยคำของคำถาม
ใช้ชุดคำถามหลักที่คงที่และชุดคำถามสำรวจแบบหมุนเวียน แยกสองกลุ่มนี้ออกจากกันในรายงาน
หลีกเลี่ยงความแม่นยำที่ผิดพลาด
รายงานช่วงความเชื่อมั่นหรือขนาดตัวอย่างขั้นต่ำสำหรับกลุ่มหัวข้อขนาดเล็ก หัวข้อที่มีการสังเกตสามครั้งไม่ควรถูกเปรียบเทียบโดยตรงกับหัวข้อที่มีการสังเกต 300 ครั้ง
เปรียบเทียบสิ่งเดียวกันกับสิ่งเดียวกัน
เมื่อเปรียบเทียบพื้นผิว ให้รักษาสิ่งเหล่านี้ให้คงที่:
- คำถาม
- Locale
- ประเทศ
- อุปกรณ์
- ชั่วโมงการรวบรวมข้อมูล
- กฎของโดเมนเป้าหมาย
- เวอร์ชันของตัวแยกวิเคราะห์การอ้างอิง
11. แผนการนำร่องที่แนะนำ
สัปดาห์ที่ 1: การวางโครงสร้างพื้นฐาน
- กำหนดค่าบันทึกเซิร์ฟเวอร์แบบมีโครงสร้าง
- สร้างทะเบียนบอท
- สร้างโดเมนสำหรับเครื่องมือย่อลิงก์
- เพิ่มกฎการตั้งชื่อแคมเปญ
- กำหนดอนุกรมวิธานของหัวข้อ
- เปิดใช้งานการส่งออก Google Analytics 4 ไปยัง BigQuery
สัปดาห์ที่ 2: ลิงก์ที่ควบคุมได้
- เผยแพร่ข้อมูลสรุปที่มีการติดตามห้าถึงสิบรายการ
- สร้างลิงก์สำหรับหัวข้อและเวอร์ชันเนื้อหาที่แตกต่างกัน
- ตรวจสอบบันทึกการเปลี่ยนเส้นทางเทียบกับเซสชันการวิเคราะห์
- ยืนยันว่าไม่มีข้อมูลส่วนตัวเข้าสู่ URL หรือพารามิเตอร์การวิเคราะห์
สัปดาห์ที่ 3: การสังเกตแผงคำตอบ
- สร้าง Prompt Manifest
- เริ่มต้นด้วยสองพื้นผิวและคำถามที่เสถียร 20 ถึง 50 ข้อ
- รันวันละครั้ง
- บันทึกสกรีนช็อตและ HTML
- วัดความล้มเหลวในการรวบรวมข้อมูลแยกจากการไม่มีการอ้างอิง
สัปดาห์ที่ 4: แดชบอร์ดและการกำกับดูแล
- สร้างแดชบอร์ดสำหรับหัวข้อและพื้นผิว
- เพิ่มการแจ้งเตือนสุขภาพของ crawler
- กำหนดกฎความเชื่อมั่น
- เปรียบเทียบรายงานบุคคลที่หนึ่งกับการสังเกตแผงคำตอบ
- จัดทำเอกสารนโยบายการเก็บรักษา, การเข้าถึง และการลบข้อมูล
บทสรุป
การวัดผลการอ้างอิงจาก AI ควรถูกสร้างขึ้นในฐานะ ระบบการระบุแหล่งที่มาแบบหลายสัญญาณ ไม่ใช่เป็นรายงานการอ้างอิงเดียว
กรอบการทำงานที่น่าเชื่อถือที่สุดประกอบด้วย:
- รายงานการมองเห็นของบุคคลที่หนึ่งจาก Google และ Bing
- บันทึกเซิร์ฟเวอร์สำหรับกิจกรรมของ crawler และ fetcher
- ลิงก์ย่อของบุคคลที่หนึ่งสำหรับการวัดการคลิกที่ควบคุมได้
- การสังเกตแผงคำตอบตามกำหนดเวลาและเป็นไปตามข้อกำหนด
- ข้อมูลวิเคราะห์และการแปลงสำหรับการวัดมูลค่าปลายทาง
เมตริกที่สำคัญที่สุดสามประการคือ:
- Citation Share by Topic — สัดส่วนของแหล่งข้อมูลที่สังเกตได้ว่าเป็นของโดเมนของคุณ
- Assistant Referral Rate — ปริมาณการเข้าชมของผู้ใช้ที่สามารถระบุแหล่งที่มาได้จากพื้นผิว AI
- Post-Citation Engagement — ผู้เยี่ยมชมที่มาจาก AI ดำเนินการที่มีความหมายหรือไม่
ระบบนี้จะใช้งานได้เมื่อตัวเลขทุกตัวรวมถึง พื้นผิว, ช่วงเวลา, ตัวส่วน, วิธีการระบุแหล่งที่มา, และระดับความเชื่อมั่น วินัยนี้ช่วยป้องกันไม่ให้การเข้าถึงของ crawler ถูกเข้าใจผิดว่าเป็นผู้ใช้, คำตอบที่ถูกรวบรวมข้อมูลถูกเข้าใจผิดว่าเป็นการแสดงผล, และการอ้างอิงถูกเข้าใจผิดว่าเป็นผลลัพธ์ทางธุรกิจ
Auto