Prompt
I'm building an internal tool to monitor AI citations by topic, what data model should I use?
Latest observation
A good data model for monitoring AI citations by topic should separate:
- the source content being cited,
- the extracted citation events,
- the topic taxonomy you want to analyze,
- the AI system / prompt / model context that produced the citation.
That gives you flexibility to answer questions like:
- “Which topics get cited most?”
- “Which models cite which sources?”
- “Are citations increasing or decreasing over time?”
- “What sources are most reused across topics?”
Recommended core entities
1) Document
Represents an underlying source or reference.
Fields
document_id(PK)titleurlpublisherauthorpublished_atretrieved_atcontent_hashdocument_type(article, paper, webpage, internal doc, etc.)metadata(JSON)
2) Topic
Represents a controlled taxonomy.
Fields
topic_id(PK)nameslugparent_topic_id(nullable, for hierarchy)descriptionstatus(active, deprecated)
If you need many-to-many topic tagging, keep it separate from documents and citations.
3) Citation
Represents a single citation event in an AI output.
Fields
citation_id(PK)document_id(FK to Document)topic_id(FK to Topic, or use join table if multiple topics per citation)ai_response_id(FK to AIResponse)citation_text(the quoted or referenced text)citation_type(direct quote, paraphrase, link, attribution, inferred)confidence_scorestart_offsetend_offsetcreated_at
4) AIResponse
Represents the generated output containing the citation.
Fields
ai_response_id(PK)request_id/prompt_idmodel_namemodel_versionproviderresponse_textgenerated_atlatency_mstokens_inputtokens_output
5) Prompt
Useful if you want to analyze citation behavior by prompt structure.
Fields
prompt_id(PK)prompt_textprompt_template_idtopic_id(nullable)created_at
Better design: use a join table for topics
A citation may relate to multiple topics, and a document may belong to multiple topics. In that case, avoid a single topic_id on Citation.
CitationTopic
citation_id(FK)topic_id(FK)assignment_method(manual, classifier, LLM, rule-based)confidence_score
DocumentTopic
document_id(FK)topic_id(FK)assignment_methodconfidence_score
This is usually the most practical approach.
Suggested relational schema
Tables
documentstopicsdocument_topicsai_responsescitationscitation_topicspromptsoptionalprompt_runsorrequestsoptional
Key relationships
- One
AIResponsehas manyCitations - One
Documentcan appear in manyCitations - Many
Citations can map to manyTopics - Many
Documents can map to manyTopics
If you want analytics-friendly reporting
Consider a star schema in addition to normalized storage:
Fact table
fact_citations
citation_iddocument_idai_response_idtopic_iddate_idmodel_idprovider_idcitation_type_idconfidence_scorecount= 1
Dimensions
dim_datedim_topicdim_documentdim_modeldim_providerdim_citation_type
This makes dashboards and BI queries much faster.
Important fields to add for monitoring
If your goal is monitoring rather than just cataloging, add:
ingestion_sourcedetected_atreview_status(pending, approved, rejected)reviewed_byreviewed_atrisk_levelorpolicy_flagduplicate_of_citation_idfor deduplicationembedding_vectoror vector ID if you do semantic clustering
Example simplified schema
documents (
document_id UUID PK,
title TEXT,
url TEXT,
publisher TEXT,
published_at TIMESTAMP,
content_hash TEXT
);
topics (
topic_id UUID PK,
name TEXT,
parent_topic_id UUID NULL
);
ai_responses (
ai_response_id UUID PK,
model_name TEXT,
model_version TEXT,
prompt_text TEXT,
response_text TEXT,
generated_at TIMESTAMP
);
citations (
citation_id UUID PK,
ai_response_id UUID FK,
document_id UUID FK,
citation_text TEXT,
citation_type TEXT,
confidence_score FLOAT,
created_at TIMESTAMP
);
citation_topics (
citation_id UUID FK,
topic_id UUID FK,
assignment_method TEXT,
confidence_score FLOAT,
PRIMARY KEY (citation_id, topic_id)
);
Practical recommendation
If you’re starting from scratch, I’d use:
- PostgreSQL for the main system of record
- JSONB for flexible metadata
- Join tables for all many-to-many relationships
- Optional warehouse/star schema later for analytics
- Optional vector store if you’ll cluster or classify citations semantically
Best default choice
If you want one clean answer:
Use a normalized relational model with Document, Topic, AIResponse, and Citation as core tables, plus join tables like CitationTopic and DocumentTopic.
If you want, I can also give you:
- a full ER diagram,
- a PostgreSQL DDL script, or
- a version optimized for analytics dashboards.
Brands