Source trace ≠ Citation ≠ Mention ≠ Recommendation: thiết kế data model thế nào để không đếm nhầm AI Visibility?
Khi bắt đầu đo AI Visibility, cách đơn giản nhất thường là một bảng kiểu:
prompt
answer
source_url
brand_found
Sau vài chục run, schema này vẫn có vẻ đủ dùng.
Nhưng khi bắt đầu cần trả lời những câu hỏi như:
- URL này chỉ được retrieve hay thật sự được citation?
- Brand được nhắc nhưng không được recommendation thì tính thế nào?
- Run lỗi API có được tính là brand không xuất hiện?
- Cùng một prompt chạy tiếng Việt và tiếng Anh có còn là cùng cohort?
- Khi so tháng này với tháng trước, prompt set đã thay đổi thì trend còn hợp lệ không?
thì một boolean brand_found=true/false bắt đầu không đủ.
Vấn đề không nằm ở dashboard.
Vấn đề nằm ở data model.
Một anti-pattern dễ gặp
Ví dụ:
visibility = source_found ? 1 : 0
Logic này trông hợp lý nếu mục tiêu duy nhất là biết “có source hay không”.
Nhưng nếu sau đó dashboard dùng cùng giá trị này cho:
- citation rate;
- brand mention rate;
- recommendation rate;
- AI visibility score;
thì hệ thống đã trộn bốn observation khác nhau thành một metric.
Một URL xuất hiện trong source trace không đồng nghĩa URL đó được citation.
Một citation không đồng nghĩa thương hiệu được mention.
Một mention không đồng nghĩa thương hiệu được recommendation.
Và recommendation không đồng nghĩa có traffic hay lead.
Một data model hợp lý hơn
Tôi thích nghĩ measurement pipeline theo hierarchy:
Project
↓
Prompt
↓
Run
↓
Answer
├── SourceExposure
├── Citation
├── BrandMention
├── CompetitorMention
└── Recommendation
Điểm quan trọng là:
Run là observation unit.
Các event phía dưới là những observation khác nhau của cùng một run.
Không nên ép chúng thành một field.
1. Bảng Run phải chứa context của phép đo
Ví dụ:
run
---
run_id
project_id
prompt_id
prompt_version
engine
model
interface
language
market
started_at
completed_at
status
error_code
Tại sao cần nhiều field như vậy?
Vì:
ChatGPT UI
!= OpenAI API
!= ChatGPT Search
!= another provider
Ngay cả cùng một vendor, interface khác nhau cũng có thể dẫn đến data path khác nhau.
Nếu report không lưu engine/model/interface, vài tháng sau rất khó biết hai kỳ có thật sự comparable hay không.
2. Prompt phải có version
Một anti-pattern khác:
prompt
---
prompt_id
text
Sau đó user sửa text của prompt nhưng vẫn giữ cùng prompt_id.
Kết quả:
- tháng 9: “công cụ GEO nào phù hợp?”
- tháng 10: “công cụ AI Visibility nào phù hợp cho agency?”
Dashboard vẫn vẽ một trend line liên tục.
Nhưng đây thực tế là hai measurement instruments khác nhau.
Tốt hơn:
prompt
---
prompt_id
current_version
prompt_version
---
prompt_id
version
text
intent_group
language
market
valid_from
valid_to
Trend chỉ nên so những observation thuộc compatible prompt cohort.
3. Source exposure và citation cần bảng riêng
Ví dụ:
source_exposure
---
run_id
url
normalized_domain
source_class
exposed
retrieval_position
và:
citation
---
run_id
url
normalized_domain
citation_type
cited
Tại sao không dùng một bảng?
Vì một URL có thể:
source_exposure = true
citation = false
Đây không phải tình huống lý thuyết.
Ahrefs Brand Radar công khai tách metric Found in khỏi Citation.
Trong các study R39-A/B/C của Ghim AI, chúng tôi cũng dùng source trace như một observation riêng và không nâng nó thành final-answer citation bằng suy luận.
Nếu gộp hai layer này, citation rate sẽ bị inflate.
4. Brand mention cần tách khỏi recommendation
Ví dụ:
brand_observation
---
run_id
brand_id
mentioned
mention_count
recommended
recommendation_position
sentiment
Một answer có thể viết:
“Ghim AI là một công cụ theo dõi AI Visibility…”
Đây là mention.
Nhưng nếu prompt là:
“Nên dùng công cụ nào để theo dõi AI Visibility cho agency?”
và answer liệt kê ba công cụ khác mà chỉ nhắc Ghim AI trong phần giải thích chung, thì chưa chắc đó là recommendation slot.
Nếu hệ thống chỉ có:
brand_found = true
thì không phân biệt được hai trường hợp.
5. Competitor observation cũng nên là entity riêng
competitor_observation
---
run_id
competitor_id
mentioned
recommended
position
Lý do đơn giản:
AI Visibility không chỉ là “brand có xuất hiện hay không”.
Với agency, câu hỏi thực tế thường là:
Khi brand không xuất hiện thì ai đang xuất hiện?
Nếu competitor data được parse từ text mỗi lần render report, rất khó audit lại.
Tốt hơn là lưu observation đã chuẩn hóa cùng provenance.
6. Denominator phải được tính từ run state, không phải total rows
Ví dụ Mention Rate:
valid_runs_with_brand_mention
/
valid_runs_in_scope
Nhưng thế nào là valid_runs_in_scope?
Một run có:
status = provider_error
không nên tự động trở thành:
mentioned = false
Nếu làm vậy, outage hoặc API error sẽ kéo AI Visibility xuống.
Do đó nên tách:
type RunStatus =
| "valid"
| "provider_error"
| "timeout"
| "blocked"
| "no_answer"
| "unsupported";
Sau đó metric query chỉ lấy denominator phù hợp.
Ví dụ:
SELECT
SUM(CASE WHEN mentioned THEN 1 ELSE 0 END)::float
/ COUNT(*) AS mention_rate
FROM brand_observation bo
JOIN run r USING (run_id)
WHERE r.status = 'valid'
AND r.project_id = ?
AND r.prompt_version IN (...);
Điểm quan trọng:
missing/error ≠ 0% visibility.
7. Citation denominator có thể khác mention denominator
Giả sử một engine không hỗ trợ citation observable trong mode đang dùng.
Nếu vẫn tính:
citation_rate =
cited_runs / all_valid_runs
thì denominator có thể sai.
Một số methodology công khai hiện nay chỉ tính citation trong những context có citation observable.
Vì vậy một implementation an toàn hơn là:
citation_rate =
runs_with_official_domain_citation
/
valid_runs_where_citation_is_observable
Tức là mỗi metric có denominator contract riêng.
8. Đừng gọi mọi thứ là Share of Voice
SOV là một trong những metric dễ bị hiểu khác nhau nhất.
Có thể là:
brand_mentions
/
all_brand_mentions
hoặc:
brand_recommendation_slots
/
all_recommendation_slots
hoặc còn được weighted theo prompt volume.
Vì vậy schema nên lưu raw observation trước.
Metric được tính sau.
Ví dụ:
metric_definition
---
metric_id
name
version
numerator_rule
denominator_rule
weighting_rule
scope_rule
Khi formula thay đổi, report lịch sử vẫn có thể trace về metric version.
9. Language và market nên nằm trong observation, không phải chỉ ở UI filter
Trong R39-C, Ghim AI chạy 12 cặp prompt Việt/Anh tương đương semantic.
24 observations.
Mean source-domain Jaccard là 0,081.
6/12 cặp không có domain overlap.
Đây không chứng minh language là causal variable duy nhất.
Nhưng nếu hệ thống chỉ lưu:
prompt_text
mà không lưu:
language
market
thì sau này rất khó audit việc score thay đổi vì language context hay vì brand visibility.
Vì vậy language/market nên là measurement dimension.
10. Repeatability nên là metadata của methodology
R39-B của Ghim AI:
- 10 prompt;
- 5 repeats;
- 50 source-trace observations;
- mean prompt-level source-domain Jaccard 0,954;
- 5/10 prompt giữ nguyên exact domain set trong 5 run.
Điều này không chứng minh “hai run luôn đủ”.
Nhưng nó cho thấy repeatability có thể được đo.
Một hệ thống có thể lưu:
measurement_batch
---
batch_id
prompt_set_version
engine
model
language
market
repeat_count
started_at
completed_at
Từ đó mới biết trend đang so:
batch A
vs
batch B
hay đang vô tình so hai phép đo có design khác nhau.
11. Raw evidence phải tồn tại song song với aggregate metric
Một dashboard tốt vẫn cần drilldown.
Tối thiểu nên truy ngược được:
metric
→ run
→ answer
→ source/citation
→ brand observation
Nếu một agency nhìn thấy:
Mention Rate = 38%
họ phải mở được các run tạo ra 38% đó.
Nếu không, metric rất khó được dùng để tư vấn khách hàng.
12. Visibility và business outcome nên nằm ở hai subsystem khác nhau
Đừng lưu:
recommended = true
converted = true
trong cùng measurement table chỉ vì muốn dashboard tiện hơn.
AI visibility data và business outcome data có nguồn khác nhau.
Ví dụ:
AI measurement
→ prompt/run/answer/citation
và:
Business analytics
→ session/lead/customer/revenue
Chúng có thể join qua campaign/session/project/time window khi có data hợp lệ.
Nhưng không nên suy:
recommendation ↑
=> lead ↑
chỉ từ AI measurement.
Một schema tổng quát
project
brand
competitor
prompt
prompt_version
prompt_set
measurement_batch
run
answer
source_exposure
citation
brand_observation
competitor_observation
recommendation_observation
metric_definition
metric_snapshot
business_event
Đây không phải universal schema.
Nhưng separation of concerns giúp tránh một lỗi khá phổ biến:
dashboard có nhiều số nhưng không biết mỗi số được sinh ra từ observation nào.
Một rule đơn giản tôi đang dùng
Trước khi thêm một metric mới, trả lời bốn câu hỏi:
- Observation unit là gì?
- Numerator là gì?
- Denominator là gì?
- Missing/error được xử lý thế nào?
Nếu chưa trả lời được cả bốn, metric chưa nên xuất hiện trên dashboard.
Kết luận
AI Visibility không khó ở chỗ tính phần trăm.
Khó ở chỗ đảm bảo phần trăm đó đại diện đúng observation mình muốn đo.
Nếu data model ngay từ đầu đã trộn:
source exposure
citation
mention
recommendation
thì mọi báo cáo phía trên đều khó sửa.
Trước khi tối ưu AI Visibility, có lẽ nên chắc rằng hệ thống đang đo đúng thứ mình gọi là Visibility.
Research foundation cho bài này:
Ghim AI — AI Visibility methodology benchmark 2026
https://ghimai.com/research/ai-visibility-methodology-benchmark-2026
Nguồn tham khảo methodology
- Semrush AI Visibility Index methodology: https://ai-visibility-index.semrush.com/methodology
- Semrush Visibility Overview Report: https://www.semrush.com/kb/1596-visibility-overview-report
- SEOmonitor AI Visibility methodology: https://www.seomonitor.com/ai-visibility/methodology
- Ahrefs AI Visibility Metrics: https://help.ahrefs.com/en/articles/15501968-ai-visibility-metrics
- Ahrefs Brand Radar methodology: https://ahrefs.com/blog/brand-radar-methodology/
- OtterlyAI research methodology: https://otterly.ai/blog/ai-search-research-methodology/
Các methodology trên được dùng để đối chiếu cách định nghĩa/đo, không phải endorsement của các nền tảng đối với Ghim AI.
Ghim AI là công cụ đo và phân tích AI Visibility cho agency và người làm SEO/GEO.
All Rights Reserved