5.6 Information Provenance and Multi-Source Synthesis
Information Provenance คืออะไร
Information Provenance คือการ track ว่าข้อมูลแต่ละชิ้นมาจากไหน — เมื่อ agent ใช้หลาย sources (documents, APIs, databases, web search) ต้องระบุได้ว่า claim แต่ละ claim มาจาก source ไหน verified เมื่อไหร่ และ reliable แค่ไหน ป้องกันปัญหา “agent บอกว่ารู้ แต่ไม่รู้ว่ารู้มาจากไหน”
ทำไม Provenance สำคัญ
- Hallucination detection — ถ้า claim ไม่มี source = อาจเป็น hallucination
- Conflict resolution — เมื่อ 2 sources ขัดกัน ต้องรู้ว่าไหน authoritative กว่า
- Freshness — ข้อมูลเก่า 6 เดือนอาจ outdated
- Accountability — เมื่อ output ผิด trace back ได้ว่า source ไหนให้ข้อมูลผิด
Source Tracking Pattern
from dataclasses import dataclass
from datetime import datetime
from enum import Enum
class SourceType(Enum):
DOCUMENT = "document"
API = "api"
DATABASE = "database"
WEB = "web"
HUMAN_INPUT = "human_input"
MODEL_GENERATION = "model_generation" # Claude generated — no external source
@dataclass
class SourceCitation:
source_type: SourceType
location: str # URL, file path, or API endpoint
retrieved_at: datetime
reliability: float # 0-1 confidence in source
excerpt: str # The actual text cited
@dataclass
class Claim:
statement: str
sources: list[SourceCitation]
confidence: float
@property
def is_grounded(self):
"""A claim is grounded if it has at least one non-model source"""
return any(s.source_type != SourceType.MODEL_GENERATION for s in self.sources)
Multi-Source Synthesis
เมื่อ Sources เห็นตรงกัน (Agreement)
def synthesize_agreement(claims_from_sources):
"""Multiple sources agree — high confidence"""
common_claims = find_common(claims_from_sources)
for claim in common_claims:
claim.confidence = min(1.0, 0.5 + 0.2 * len(claim.sources))
# More sources agree = higher confidence
return common_claims
เมื่อ Sources ขัดกัน (Conflict)
def resolve_conflict(claim_a, claim_b):
"""Two sources disagree — need resolution strategy"""
strategies = {
"recency": lambda a, b: a if a.retrieved_at > b.retrieved_at else b,
"authority": lambda a, b: a if a.source_reliability > b.source_reliability else b,
"specificity": lambda a, b: a if a.is_more_specific else b,
}
# Apply hierarchy: official docs > API response > web > model generation
authority_rank = {
SourceType.DOCUMENT: 4, # Official docs
SourceType.API: 3, # Live API data
SourceType.DATABASE: 3, # Internal data
SourceType.WEB: 2, # Web search
SourceType.HUMAN_INPUT: 2, # User said
SourceType.MODEL_GENERATION: 1, # Claude generated
}
a_rank = max(authority_rank[s.source_type] for s in claim_a.sources)
b_rank = max(authority_rank[s.source_type] for s in claim_b.sources)
if a_rank != b_rank:
winner = claim_a if a_rank > b_rank else claim_b
return {
"resolved": winner,
"conflict_note": f"Conflict between sources. Chose {winner.sources[0].location} (higher authority)",
"discarded": claim_b if a_rank > b_rank else claim_a
}
# Same authority — flag for human review
return {
"resolved": None,
"conflict_note": "Equal authority sources disagree — human review needed",
"options": [claim_a, claim_b]
}
Provenance in Practice
Annotated Output
def generate_report_with_provenance(topic, sources):
"""Generate a report where every claim has a citation"""
report = client.messages.create(
system="""Generate a report. For EVERY factual claim, add a citation
in [Source N] format. At the end, list all sources with their details.
If you are not sure about a claim, mark it as [UNVERIFIED].""",
messages=[{"role": "user", "content": f"""
Topic: {topic}
Available sources:
{format_sources(sources)}
Write a report with citations for every claim.
"""}]
)
# Verify citations actually exist in sources
claims = extract_claims_with_citations(report)
for claim in claims:
if not verify_citation_exists(claim.citation, sources):
claim.flag = "CITATION_NOT_FOUND" # Possible hallucination
return report, claims
Source Freshness Check
def check_freshness(source: SourceCitation, max_age_days=30):
age = (datetime.now() - source.retrieved_at).days
if age > max_age_days:
return {
"fresh": False,
"age_days": age,
"recommendation": "Re-fetch this source — data may be outdated"
}
return {"fresh": True, "age_days": age}
Key Concepts
- Grounded vs Ungrounded claims — grounded = มี external source; ungrounded = Claude generated (potential hallucination)
- Source authority hierarchy — official docs > API > database > web > model generation
- Freshness — ข้อมูลเก่าอาจ outdated; ต้อง re-verify periodically
- Conflict resolution — เมื่อ sources ขัดกัน ใช้ authority + recency + specificity
- Citation verification — ตรวจว่า citation ที่ Claude ใส่มา match กับ source จริง
Exam Tips
- ข้อสอบจะถาม: เมื่อ 2 sources ขัดกัน ทำอย่างไร — ตอบ: ดู authority hierarchy, recency, escalate ถ้า equal
- Hallucination detection = claim ที่ไม่มี source citation = suspect
- Model-generated content มี reliability ต่ำสุด — ต้อง verify กับ external source เสมอ
- ข้อสอบอาจให้ scenario ที่ Claude assert ข้อมูลผิด — ถามว่าป้องกันอย่างไร → citation + verification
- Source freshness check สำคัญ: ข้อมูลเทค 6 เดือนอาจ outdated (เช่น API versions, pricing)
- Multi-source synthesis ≠ เอาทุก source มา merge — ต้อง detect conflicts และ resolve