0Pricing
AI Agents · Lektion

Quellenprüfung und Zitierung

Aussagen quellenübergreifend abgleichen und Fakten mit den URLs ihrer Quellen versehen.

Quellenprüfung und Zitierung ist eine kostenlose AI Agents-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des AI Agents-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der AI Agents-Kurs umfasst insgesamt 4 Lektionen.

Warum Quellenüberprüfung wichtig ist

Ein Agent kann eine falsche Behauptung aus einer minderwertigen Quelle abrufen und als Tatsache präsentieren. Ohne Überprüfung ist der Recherche-Agent lediglich eine ausgefeilte Suchmaschine ohne Qualitätsfilter.

Die Überprüfung ergänzt eine Ebene, die kontrolliert, ob Behauptungen durch mehrere unabhängige Quellen bestätigt werden.

Die Zwei-Quellen-Regel

Eine Behauptung gilt als überprüft, wenn sie in mindestens zwei unabhängigen Quellen vorkommt. „Unabhängig“ bedeutet unterschiedliche Domains – dieselbe Behauptung auf zwei Websites zu finden, die beide denselben Originalartikel zitieren, zählt nicht.

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

Semantischer Abgleich auf LLM-Basis

Ein Zeichenkettenvergleich erkennt umformulierte Behauptungen nicht. Verwenden Sie ein LLM, um zu beurteilen, ob zwei Fakten semantisch gleichwertig sind, bevor Sie sie als bestätigende Quellen zählen.

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

Quellenqualität bewerten

Nicht alle Quellen sind gleichwertig. Bewerten Sie jede Quelle anhand des Domain-Typs, des Veröffentlichungsdatums und ihrer bekannten Zuverlässigkeit. Quellen der Stufe 1 (amtliche Statistiken, von Fachleuten begutachtete Fachzeitschriften) sollten stärker gewichtet werden als Blogs oder soziale Medien.

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))

Behauptungen mit Quellen abgleichen

Gleichen Sie jede Behauptung, die der Agent in den Abschlussbericht aufnehmen möchte, mit allen abgerufenen Dokumenten ab, um die am besten bestätigenden Quellen zu finden.

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)

Qualifikationen der Autoren prüfen

Bei wissenschaftlichen oder medizinischen Behauptungen sind die Qualifikationen der Autoren wichtig. Eine Studie mit namentlich genannten Autoren an akkreditierten Einrichtungen ist höher zu gewichten als ein anonymer Blogbeitrag. Extrahieren Sie die Autoreninformationen und markieren Sie Behauptungen aus anonymen Quellen.

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)

Nicht überprüfte Behauptungen markieren

Behauptungen, die nicht durch zwei unabhängige Quellen abgeglichen werden können, sollten in der Ausgabe als nicht überprüft markiert werden. Je nach Risikostufe des Berichts können nicht überprüfte Behauptungen ausgeschlossen oder mit einem Haftungsausschluss versehen werden.

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

Zitierformat: Inline-Zitate und Literaturverzeichnis

Berichte sollten Inline-Zitate (nummerierte hochgestellte Ziffern) und am Ende ein Literaturverzeichnis enthalten. Erzeugen Sie beides aus den Metadaten der überprüften Quellen.

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)

Widersprüche zwischen Quellen erkennen

Manchmal widersprechen sich zwei glaubwürdige Quellen. Erkennen Sie Widersprüche und stellen Sie beide Seiten dar, anstatt stillschweigend eine davon auszuwählen. Das ist besonders bei umstrittenen empirischen Behauptungen wichtig.

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

Übersicht der Überprüfungsergebnisse

Erstellen Sie vor der Generierung des Abschlussberichts eine Zusammenfassung der Überprüfung: Wie viele Behauptungen wurden überprüft, wie viele nicht überprüft, welche Quellen haben die höchsten Autoritätsbewertungen und welche Widersprüche wurden erkannt?

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}')

Ausgabe mit Vertrauensschwelle

Legen Sie vor der Veröffentlichung einen Mindestschwellenwert für die Überprüfung fest. Wenn weniger als 70 % der Behauptungen überprüft sind, fordern Sie die Recherche-Schleife auf, eine weitere Iteration durchzuführen, die gezielt auf die nicht überprüften Behauptungen eingeht.

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)

Was definiert bei der Zwei-Quellen-Regel zwei „unabhängige“ Quellen?

Das Kriterium der Unabhängigkeit verhindert eine Echokammer-Überprüfung, bei der dieselbe Behauptung auf eine einzige Originalquelle zurückgeht, die von vielen Anbietern zitiert wird.

Zusammenfassung der Quellenüberprüfung

Überprüfte Recherche erfordert: Bestätigung durch zwei Quellen aus unterschiedlichen Domains, semantischen Abgleich auf LLM-Basis zum Erkennen umformulierter Entsprechungen, Bewertung der Quellenqualität (Domain-Autorität + Aktualität), Erkennung von Widersprüchen und eine Ausgabe mit Vertrauensschwelle, die bei einer zu niedrigen Überprüfungsquote weitere Recherche auslöst.

Häufig gestellte Fragen

Ist die Lektion „Quellenprüfung und Zitierung“ kostenlos?

Ja — der vollständige Text von „Quellenprüfung und Zitierung“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des AI Agents-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der AI Agents-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Quellenprüfung und Zitierung“?

Aussagen quellenübergreifend abgleichen und Fakten mit den URLs ihrer Quellen versehen. Du übst AI Agents mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um AI Agents zu starten?

Keine Vorkenntnisse erforderlich. AI Agents auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „Quellenprüfung und Zitierung“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser AI Agents-Lektion Code schreiben und ausführen?

Ja. Jede AI Agents-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Entwurf mehrstufiger Recherche-Schleifen
  2. Quellenprüfung und Zitierung
  3. Strukturierte Berichte generieren
  4. Faktenprüfung und Vermeidung von Halluzinationen
← Zurück zu AI Agents