0

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:

  1. Observation unit là gì?
  2. Numerator là gì?
  3. Denominator là gì?
  4. 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

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

Viblo
Let's register a Viblo Account to get more interesting posts.