Verifikasi Sumber dan Sitasi
Membandingkan klaim di berbagai sumber dan melampirkan URL sumber pada fakta.
Verifikasi Sumber dan Sitasi adalah pelajaran AI Agents gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Agents, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Agents mencakup 4 pelajaran total.
Mengapa Verifikasi Sumber Penting
Agen dapat mengambil klaim yang salah dari sumber berkualitas rendah dan menyajikannya sebagai fakta. Tanpa verifikasi, agen riset hanyalah mesin pencari canggih tanpa penyaring kualitas.
Verifikasi menambahkan lapisan yang memeriksa apakah klaim didukung oleh beberapa sumber independen.
Aturan Dua Sumber
Sebuah klaim dianggap terverifikasi jika muncul dalam setidaknya dua sumber independen. 'Independen' berarti berasal dari domain yang berbeda — menemukan klaim yang sama di dua situs yang sama-sama mengutip artikel asli yang sama tidak dihitung.
from urllib.parse import urlparse
def extract_domain(url: str) -> str:
return urlparse(url).netloc.replace('www.', '')
def is_verified(fact: str, all_facts: list[dict]) -> bool:
matching_domains = set()
for f in all_facts:
if fact.lower() in f['fact'].lower() or f['fact'].lower() in fact.lower():
matching_domains.add(extract_domain(f['source']))
return len(matching_domains) >= 2
# Example
facts = [
{'fact': 'Inflation peaked at 9.1% in June 2022', 'source': 'https://bls.gov/cpi'},
{'fact': 'US inflation hit 9.1% peak in mid-2022', 'source': 'https://reuters.com/article/a'}
]
print(is_verified('inflation peaked at 9.1%', facts)) # TruePencocokan Semantik Berbasis LLM
Pencocokan string tidak dapat menangkap klaim yang diparafrasekan. Gunakan LLM untuk menilai apakah dua fakta setara secara semantik sebelum menghitungnya sebagai sumber yang saling menguatkan.
import openai, json
client = openai.OpenAI(api_key='YOUR_OPENAI_KEY')
def claims_are_equivalent(claim_a: str, claim_b: str) -> bool:
prompt = (
f'Are these two statements making the same factual claim?\n'
f'A: "{claim_a}"\n'
f'B: "{claim_b}"\n'
f'Answer JSON: {{"equivalent": true/false}}'
)
resp = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}],
response_format={'type': 'json_object'}
)
return json.loads(resp.choices[0].message.content).get('equivalent', False)
print(claims_are_equivalent(
'CPI hit 9.1% in June 2022',
'US consumer prices rose 9.1 percent year-over-year in June 2022'
)) # TruePenilaian Kualitas Sumber
Tidak semua sumber memiliki kualitas yang sama. Nilai setiap sumber berdasarkan jenis domain, tanggal publikasi, dan tingkat keandalan yang diketahui. Sumber Tingkat 1 (statistik pemerintah, jurnal yang ditelaah sejawat) seharusnya memiliki bobot lebih besar daripada blog atau media sosial.
from datetime import datetime, timezone
HIGH_AUTHORITY_DOMAINS = [
'gov', 'edu', 'nature.com', 'science.org', 'pubmed.ncbi.nlm.nih.gov',
'reuters.com', 'bbc.com', 'apnews.com', 'who.int'
]
def score_source(url: str, publication_date: str | None) -> float:
score = 0.5 # baseline
domain = extract_domain(url)
tld = domain.split('.')[-1]
# Domain authority
if any(ha in domain for ha in HIGH_AUTHORITY_DOMAINS):
score += 0.3
elif tld in ('gov', 'edu', 'org'):
score += 0.1
# Recency
if publication_date:
try:
pub = datetime.fromisoformat(publication_date)
days_old = (datetime.now(timezone.utc) - pub.replace(tzinfo=timezone.utc)).days
if days_old < 365:
score += 0.1
elif days_old > 1825: # 5 years
score -= 0.1
except ValueError:
pass
return min(1.0, max(0.0, score))Mencocokkan Silang Klaim dengan Sumber
Untuk setiap klaim yang ingin disertakan agen dalam laporan akhir, cocokkan silang klaim tersebut dengan semua dokumen yang diambil untuk menemukan sumber pendukung terbaik.
def cross_reference(claim: str, all_facts: list[dict]) -> list[dict]:
supporting = []
seen_domains = set()
for fact in all_facts:
if claims_are_equivalent(claim, fact['fact']):
domain = extract_domain(fact['source'])
if domain not in seen_domains: # only one per domain
seen_domains.add(domain)
supporting.append({
'source': fact['source'],
'domain': domain,
'fact': fact['fact'],
'score': score_source(fact['source'], fact.get('publication_date'))
})
return sorted(supporting, key=lambda x: x['score'], reverse=True)Pemeriksaan Kredensial Penulis
Untuk klaim ilmiah atau medis, kredensial penulis penting. Studi dengan penulis yang disebutkan namanya dari institusi terakreditasi memiliki bobot lebih besar daripada tulisan blog anonim. Ekstrak informasi penulis dan tandai klaim dari sumber anonim.
def assess_authorship(url: str, page_text: str) -> dict:
prompt = (
f'From this webpage text, extract:\n'
f'1. Author name(s) (or null)\n'
f'2. Author affiliation/credentials (or null)\n'
f'3. Publication name (or null)\n'
f'Return JSON: {{"authors": [], "affiliation": null, "publication": null}}\n\n'
f'TEXT:\n{page_text[:2000]}'
)
resp = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}],
response_format={'type': 'json_object'}
)
return json.loads(resp.choices[0].message.content)Menandai Klaim yang Belum Terverifikasi
Klaim yang tidak dapat dicocokkan silang dengan dua sumber independen harus ditandai sebagai belum terverifikasi dalam keluaran. Bergantung pada tingkat risiko laporan, klaim yang belum terverifikasi dapat dikecualikan atau disajikan dengan penafian.
def classify_claims(claims: list[str], all_facts: list[dict]) -> list[dict]:
classified = []
for claim in claims:
support = cross_reference(claim, all_facts)
classified.append({
'claim': claim,
'verified': len(support) >= 2,
'sources': support[:3], # top 3 supporting sources
'confidence': 'high' if len(support) >= 3 else
'medium' if len(support) == 2 else
'low'
})
return classifiedFormat Sitasi: Daftar Dalam Teks dan Referensi
Laporan harus menyertakan sitasi dalam teks (superskrip bernomor) dan daftar referensi di bagian akhir. Hasilkan keduanya dari metadata sumber yang telah diverifikasi.
def format_citations(classified_claims: list[dict]) -> tuple[list[str], list[str]]:
ref_list = []
ref_map = {} # url -> citation number
inline_claims = []
for item in classified_claims:
nums = []
for src in item['sources']:
url = src['source']
if url not in ref_map:
ref_map[url] = len(ref_list) + 1
ref_list.append(f'[{ref_map[url]}] {url}')
nums.append(f'[{ref_map[url]}]')
citation_str = ''.join(nums)
prefix = '' if item['verified'] else '[UNVERIFIED] '
inline_claims.append(f'{prefix}{item["claim"]} {citation_str}')
return inline_claims, ref_list
if __name__ == '__main__':
demo_claims = [
{'claim': 'Revenue grew 12% year over year', 'verified': True, 'sources': [{'source': 'https://example.com/report'}]},
{'claim': 'The CEO plans to step down', 'verified': False, 'sources': [{'source': 'https://example.com/rumor'}]},
]
inline, refs = format_citations(demo_claims)
for line in inline:
print(line)
print('References:')
for r in refs:
print(' ', r)
Mendeteksi Kontradiksi Antar-Sumber
Terkadang dua sumber tepercaya saling bertentangan. Deteksi kontradiksi dan sajikan kedua sisi, alih-alih memilih salah satunya secara diam-diam. Hal ini sangat penting terutama untuk klaim empiris yang masih diperdebatkan.
def find_contradictions(claim: str, all_facts: list[dict]) -> list[dict]:
contradictions = []
for fact in all_facts:
if extract_domain(fact['source']) == extract_domain(claim):
continue
prompt = (
f'Does fact B contradict fact A?\n'
f'A: "{claim}"\nB: "{fact["fact"]}"\n'
f'JSON: {{"contradicts": true/false}}'
)
resp = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}],
response_format={'type': 'json_object'}
)
result = json.loads(resp.choices[0].message.content)
if result.get('contradicts'):
contradictions.append(fact)
return contradictionsKartu Ringkasan Verifikasi
Sebelum menghasilkan laporan akhir, buat ringkasan verifikasi: jumlah klaim yang terverifikasi, jumlah klaim yang belum terverifikasi, sumber utama berdasarkan skor otoritas, serta kontradiksi yang terdeteksi.
def verification_report_card(classified: list[dict]) -> dict:
total = len(classified)
verified = sum(1 for c in classified if c['verified'])
all_sources = [
src for c in classified for src in c['sources']
]
top_domains = sorted(
set(s['domain'] for s in all_sources),
key=lambda d: max(s['score'] for s in all_sources if s['domain'] == d),
reverse=True
)[:5]
return {
'total_claims': total,
'verified': verified,
'unverified': total - verified,
'verification_rate': f'{verified/max(total,1)*100:.0f}%',
'top_sources': top_domains
}
if __name__ == '__main__':
demo_classified = [
{'verified': True, 'sources': [{'domain': 'docs.python.org', 'score': 1.3}]},
{'verified': False, 'sources': [{'domain': 'quora.com', 'score': 0.5}]},
]
card = verification_report_card(demo_classified)
for k, v in card.items():
print(f'{k}: {v}')
Keluaran Berbasis Ambang Keyakinan
Tetapkan ambang verifikasi minimum sebelum menerbitkan laporan. Jika kurang dari 70% klaim terverifikasi, minta siklus riset menjalankan iterasi lain yang secara khusus menargetkan klaim yang belum terverifikasi.
MIN_VERIFICATION_RATE = 0.70
def should_run_more_research(classified: list[dict]) -> list[str]:
unverified = [c for c in classified if not c['verified']]
total = len(classified)
if total == 0:
return []
rate = (total - len(unverified)) / total
if rate >= MIN_VERIFICATION_RATE:
return [] # Sufficient confidence — stop
# Return search queries to verify remaining claims
return [f'verify: {c["claim"]}' for c in unverified[:3]]
if __name__ == '__main__':
demo_classified = [
{'claim': 'A', 'verified': True},
{'claim': 'B', 'verified': False},
{'claim': 'C', 'verified': False},
]
followups = should_run_more_research(demo_classified)
print('Follow-up queries needed:', followups)
Apa yang menentukan dua sumber 'independen' dalam aturan verifikasi dua sumber?
Kriteria independensi mencegah verifikasi ruang gema ketika klaim yang sama ditelusuri kembali ke satu sumber asli yang dikutip oleh banyak penerbit.
Ringkasan Verifikasi Sumber
Riset yang terverifikasi memerlukan: penguatan oleh dua sumber dari domain yang berbeda, pencocokan semantik LLM untuk mendeteksi padanan yang diparafrasekan, penilaian kualitas sumber (otoritas domain + kemutakhiran), deteksi kontradiksi, dan keluaran berbasis ambang keyakinan yang memicu riset tambahan jika tingkat verifikasi terlalu rendah.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Verifikasi Sumber dan Sitasi” gratis?
Ya — teks lengkap “Verifikasi Sumber dan Sitasi” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Agents, upgrade ke CoddyKit PRO. Kursus AI Agents mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Verifikasi Sumber dan Sitasi”?
Membandingkan klaim di berbagai sumber dan melampirkan URL sumber pada fakta. Kamu berlatih AI Agents dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai AI Agents?
Tidak diperlukan pengalaman sebelumnya. AI Agents di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Verifikasi Sumber dan Sitasi” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Agents ini?
Ya. Setiap pelajaran AI Agents menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Desain Putaran Riset Multi-Langkah
- Verifikasi Sumber dan Sitasi
- Pembuatan Laporan Terstruktur
- Pemeriksaan Fakta dan Pencegahan Halusinasi