การตรวจสอบแหล่งที่มาและการอ้างอิง
เปรียบเทียบข้อกล่าวอ้างจากหลายแหล่งและแนบ URL ของแหล่งที่มากับข้อเท็จจริง
การตรวจสอบแหล่งที่มาและการอ้างอิง เป็นบทเรียน AI Agents ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Agents และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดการตรวจสอบแหล่งข้อมูลจึงสำคัญ
เอเจนต์อาจดึงข้อกล่าวอ้างที่ไม่เป็นจริงจากแหล่งข้อมูลคุณภาพต่ำ แล้วนำเสนอราวกับเป็นข้อเท็จจริง หากไม่มีการตรวจสอบ เอเจนต์วิจัยก็เป็นเพียงเครื่องมือค้นหาที่ซับซ้อนและไม่มีตัวกรองคุณภาพ
การตรวจสอบจะเพิ่มชั้นการทำงานที่ตรวจว่าข้อกล่าวอ้างได้รับการยืนยันสนับสนุนจากแหล่งข้อมูลอิสระหลายแห่งหรือไม่
กฎสองแหล่งข้อมูล
ข้อกล่าวอ้างจะถือว่าได้รับการตรวจสอบยืนยันเมื่อปรากฏใน แหล่งข้อมูลอิสระอย่างน้อยสองแห่ง คำว่า 'อิสระ' หมายถึงมาจากโดเมนต่างกัน การพบข้อกล่าวอ้างเดียวกันบนเว็บไซต์สองแห่งที่ต่างก็อ้างอิงบทความต้นฉบับเดียวกันยังไม่นับ
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)) # Trueการจับคู่ความหมายด้วย LLM
การจับคู่สตริงไม่สามารถตรวจพบข้อกล่าวอ้างที่เขียนใหม่ด้วยถ้อยคำต่างกันได้ ใช้ LLM ตัดสินว่าข้อเท็จจริงสองข้อมีความหมายเทียบเท่ากันหรือไม่ ก่อนนับว่าเป็นแหล่งข้อมูลที่ช่วยยืนยันกัน
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'
)) # Trueการให้คะแนนคุณภาพแหล่งข้อมูล
แหล่งข้อมูลไม่ได้มีคุณภาพเท่ากันทั้งหมด ให้คะแนนแต่ละแหล่งตามประเภทโดเมน วันที่เผยแพร่ และความน่าเชื่อถือที่ทราบ แหล่งข้อมูลระดับ 1 เช่น สถิติจากรัฐบาลและวารสารที่ผ่านการประเมินโดยผู้ทรงคุณวุฒิ ควรมีน้ำหนักมากกว่าบล็อกหรือสื่อสังคมออนไลน์
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))การตรวจสอบข้อกล่าวอ้างข้ามแหล่งข้อมูล
สำหรับข้อกล่าวอ้างแต่ละข้อที่เอเจนต์ตั้งใจจะใส่ในรายงานฉบับสุดท้าย ให้ตรวจสอบกับเอกสารที่ดึงมาทั้งหมด เพื่อหาแหล่งข้อมูลที่ช่วยยืนยันได้ดีที่สุด
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)การตรวจสอบคุณวุฒิของผู้เขียน
สำหรับข้อกล่าวอ้างทางวิทยาศาสตร์หรือการแพทย์ คุณวุฒิของผู้เขียนมีความสำคัญ งานศึกษาที่ระบุชื่อผู้เขียนจากสถาบันที่ได้รับการรับรองย่อมมีน้ำหนักมากกว่าบทความในบล็อกที่ไม่ระบุชื่อผู้เขียน ให้ดึงข้อมูลผู้เขียนและติดแฟล็กข้อกล่าวอ้างจากแหล่งข้อมูลนิรนาม
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)การติดแฟล็กข้อกล่าวอ้างที่ยังไม่ได้ตรวจสอบ
ข้อกล่าวอ้างที่ไม่สามารถตรวจสอบข้ามแหล่งข้อมูลอิสระสองแห่งได้ ควรติดแฟล็กว่า ยังไม่ได้ตรวจสอบ ในผลลัพธ์ รายงานอาจตัดข้อกล่าวอ้างเหล่านี้ออกหรือนำเสนอพร้อมคำปฏิเสธความรับผิดชอบ ทั้งนี้ขึ้นอยู่กับระดับความเสี่ยงของรายงาน
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 classifiedรูปแบบการอ้างอิง: การอ้างอิงในเนื้อหาและรายการอ้างอิง
รายงานควรมีการอ้างอิงในเนื้อหา เช่น เลขยกกำลัง และมีรายการอ้างอิงอยู่ท้ายรายงาน ให้สร้างทั้งสองส่วนจากข้อมูลเมตาของแหล่งข้อมูลที่ผ่านการตรวจสอบยืนยัน
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)
การตรวจจับความขัดแย้งระหว่างแหล่งข้อมูล
บางครั้งแหล่งข้อมูลที่น่าเชื่อถือสองแห่งอาจขัดแย้งกัน ให้ตรวจจับความขัดแย้งและนำเสนอทั้งสองมุมมอง แทนที่จะเลือกฝ่ายใดฝ่ายหนึ่งโดยไม่แจ้งให้ทราบ เรื่องนี้สำคัญเป็นพิเศษสำหรับข้อกล่าวอ้างเชิงประจักษ์ที่ยังเป็นประเด็นโต้แย้ง
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 contradictionsบัตรสรุปผลการตรวจสอบยืนยัน
ก่อนสร้างรายงานฉบับสุดท้าย ให้จัดทำสรุปการตรวจสอบยืนยัน โดยระบุจำนวนข้อกล่าวอ้างที่ตรวจสอบยืนยันแล้ว จำนวนที่ยังไม่ได้ตรวจสอบ แหล่งข้อมูลชั้นนำตามคะแนนอำนาจความน่าเชื่อถือ และความขัดแย้งที่ตรวจพบ (ถ้ามี)
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}')
ผลลัพธ์ที่ควบคุมด้วยระดับความมั่นใจ
กำหนดเกณฑ์ขั้นต่ำของการตรวจสอบยืนยันก่อนเผยแพร่ หากข้อกล่าวอ้างที่ตรวจสอบยืนยันแล้วมีน้อยกว่า 70% ให้สั่งลูปการวิจัยทำซ้ำอีกครั้ง โดยมุ่งตรวจสอบข้อกล่าวอ้างที่ยังไม่ได้รับการยืนยันโดยเฉพาะ
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)
อะไรเป็นตัวกำหนดว่าแหล่งข้อมูลสองแห่งเป็น 'อิสระ' ตามกฎการตรวจสอบจากสองแหล่งข้อมูล
เกณฑ์ความเป็นอิสระช่วยป้องกันการตรวจสอบแบบห้องสะท้อนเสียง ซึ่งข้อกล่าวอ้างเดียวกันถูกสืบย้อนกลับไปยังแหล่งข้อมูลต้นฉบับเพียงแห่งเดียวที่สื่อหลายแห่งอ้างถึง
สรุปการตรวจสอบแหล่งข้อมูล
งานวิจัยที่ผ่านการตรวจสอบยืนยันต้องประกอบด้วย: การยืนยันจากสองแหล่งข้อมูล ที่มาจากโดเมนต่างกัน การจับคู่ความหมายด้วย LLM เพื่อตรวจจับข้อความที่เขียนใหม่แต่มีความหมายเทียบเท่า การให้คะแนนคุณภาพแหล่งข้อมูล (อำนาจความน่าเชื่อถือของโดเมนและความใหม่ของข้อมูล) การตรวจจับความขัดแย้ง และ ผลลัพธ์ที่ควบคุมด้วยระดับความมั่นใจ ซึ่งจะเรียกใช้การวิจัยเพิ่มเติมหากอัตราการตรวจสอบยืนยันต่ำเกินไป
คำถามที่พบบ่อย
บทเรียน “การตรวจสอบแหล่งที่มาและการอ้างอิง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การตรวจสอบแหล่งที่มาและการอ้างอิง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Agents ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การตรวจสอบแหล่งที่มาและการอ้างอิง”
เปรียบเทียบข้อกล่าวอ้างจากหลายแหล่งและแนบ URL ของแหล่งที่มากับข้อเท็จจริง คุณปฏิบัติ AI Agents ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Agents หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Agents บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การตรวจสอบแหล่งที่มาและการอ้างอิง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน AI Agents นี้ได้ไหม
ได้ บทเรียน AI Agents ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การออกแบบวงจรการวิจัยหลายขั้นตอน
- การตรวจสอบแหล่งที่มาและการอ้างอิง
- การสร้างรายงานแบบมีโครงสร้าง
- การตรวจสอบข้อเท็จจริงและการป้องกันการหลอน