Quellenangabe mit Zitaten
Überblick
Jede belegte Behauptung trägt ihren Beweis inline: die wörtliche Passage, ein Link, der zu dieser Passage springt und sie hervorhebt, und optional ein Screenshot. Leser prüfen nach, ohne zu klicken; ein Klick landet exakt auf dem Text. Funktioniert für Markdown-Dateien und für Antworten im Chat.
Jedes Zitat MUSS aus der Ausgabe von snap.mjs stammen, niemals aus dem Gedächtnis, einer Suchergebnis-Zusammenfassung oder einem zusammenfassenden Fetch-Tool. Suchzusammenfassungen und WebFetch-artige Tools paraphrasieren Seiten; nur das Skript prüft den gerenderten Text wörtlich.
Prüfe Behauptungen, nicht nur Zitate. Ein passendes Zitat beweist, dass die Seite das sagt. Es beweist nichts darüber, was die Seite nicht sagt. Zwei Arten von Behauptungen durchlaufen das Skript immer als eigene Batch-Einträge, auch wenn du nur einen Entwurf „verifizierst“:
- Abwesenheit: Bevor du schreibst, dass eine Seite etwas nicht sagt, erwähnt oder erfordert, füge den Satz hinzu, der dort stünde, wenn sie es täte (z. B. „Responses with the 429 status code MUST NOT be stored by a cache.“). Nur
match: nonebelegt die Abwesenheit, und schreibe dann „nicht gefunden auf “, niemals „die Spezifikation sagt nichts zu X“. - Widerspruch: Wenn Gedächtnis, eine Suchzusammenfassung, ein bereits geschriebener Entwurf oder Beispiele dieser Skill widersprüchliche Angaben darüber machen, was eine Seite sagt, füge den strittigen Satz hinzu. Das Ergebnis des Skripts klärt es, egal welche Seite es begünstigt. (Jedes Zitat in den Beispielen dieser Skill wurde mit dem Skript verifiziert.)
Einrichtung (einmal pro Maschine)
npm install --prefix <skill-verz>/scripts && npx --prefix <skill-verz>/scripts playwright install chromium
<skill-verz> ist das Verzeichnis, das diese SKILL.md enthält.
Das Skript
Erstelle zuerst das Dokument oder die Antwort, sammle alle Zitate, verifiziere sie dann alle in einem Batch-Aufruf:
node <skill-verz>/scripts/snap.mjs --batch - <<'EOF'
[
{"url": "https://www.rfc-editor.org/rfc/rfc6585.html", "quote": "Responses with the 429 status code MUST NOT be stored by a cache."},
{"url": "https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Retry-After", "quote": "A non-negative decimal integer", "out": "/abs/pfad/docs/refs/delay.png"}
]
EOF
Ein Browser für den Batch; Zitate auf derselben URL teilen sich einen Seitenaufruf. Verwende absolute Pfade für out. Die Eingabe kann auch {"defaults": {...}, "cites": [...]} sein, um Screenshot-Optionen auf jeden Eintrag anzuwenden. Die Batch-Ausgabe ist ein JSON-Array in Eingabereihenfolge (Einzelmodus, snap.mjs "<url>" --quote "...", gibt ein Objekt aus). Jeder Eintrag:
| Feld | Verwendung |
|---|---|
ok / match | exact/loose = wörtlich. fuzzy = dein Zitat war falsch; verwende stattdessen quote_on_page und überprüfe erneut, ob die Behauptung noch Bestand hat. none = nicht auf der Seite. |
quote_on_page | Der Text, der in das Blockzitat gesetzt werden soll. Niemals dein ursprüngliches --quote. |
fragment_url | Der zu verwendende Link (hat #:~:text=, hebt in Chrome/Safari/Firefox hervor). |
excerpt | Umgebender Absatz, zur Überprüfung des Kontexts (Negationen, Einschränkungen, „außer wenn …“). Willst du mehr davon zitieren? Führe den Vorgang mit dieser längeren Passage als --quote erneut aus, damit Link und Screenshot übereinstimmen. |
title, section, retrieved | Die Quellenangabe: [<title> — <section>](fragment_url) · abgerufen am <Datum>, oder [<title>](fragment_url) wenn section fehlt. Verwende diese Felder; füge keine Abschnittsnummern aus dem Gedächtnis hinzu. |
occurrences / occurrence | Vorhanden, wenn das Zitat mehrfach vorkommt. Überprüfe, ob excerpt das gemeinte ist; falls nicht, führe den Vorgang mit prefix/suffix (den Wörtern unmittelbar davor/danach auf der Seite) erneut aus. |
hidden | Zitat befindet sich in Inhalten, die die Seite verbirgt (z. B. ein inaktiver Tab): verifiziert, aber kein Screenshot. |
note | Alles andere Wissenswerte (unscharfe Übereinstimmung, aufgeklappter Bereich, Fallback auf Frame). Lies es. |
internal | Die Seite befindet sich in einem internen Netzwerk. Ihr Inhalt kann vertraulich sein; zitiere nicht mehr, als die Behauptung benötigt. |
Exit 0 = alle gefunden, 1 = einige nicht gefunden, 2 = einige fehlgeschlagen (PDF, 4xx, Login-Wall, Bot-Erkennung, Timeout). Rechne mit einem Folge-Batch: Fasse alle Einträge, die einen weiteren Durchlauf benötigen (fehlgeschlagen, unscharf, falsches Vorkommen oder eine längere Passage gewünscht), darin zusammen.
Screenshot-Optionen
Optionale Felder für jeden Eintrag (oder in defaults). Ordne die Formulierung des Benutzers zu; bei keiner Formulierung lasse sie weg.
| Benutzer sagt | Feld |
|---|---|
| „enge Screenshots“, „nur das Zitat“ | "frame": "quote" (Standard paragraph) |
| „den ganzen Abschnitt zeigen“ | "frame": "section" (Höhenbegrenzung steigt automatisch auf 1200) |
| „Vollbild“, „die Seite darum herum zeigen“ | "frame": "viewport" |
| „ein paar Zeilen darum herum“ | "context": 2 (ganze Textzeilen darüber und darunter) |
| „mobilgroß“ | "width": 390 (Standard 1100) |
| „kurz halten“ | "max_height": 150 (Standard 500; Zuschnitt zentriert auf das Zitat) |
| „gelb hervorheben“, „keine Hervorhebung“ | "highlight": "#fff3a0" / "none" |
| „dunkler Modus“ | "theme": "dark" (nur Seiten mit einem dunklen Design; note sagt andernfalls) |
| „kleinere Bilder“ | "scale": 1 (Standard 2) |
Diese formen nur Screenshots. Kontext, der im Text selbst gewünscht wird (oder ohne Screenshots) → zitiere eine längere Passage, die aus excerpt entnommen wurde, führe sie im Folge-Batch erneut aus. Zitate in Tabellenzellen rahmen automatisch die Zeile plus die Kopfzeile ein. Jede Option mit ihrem Screenshot ist im examples/README.md des Repos.
Ausgabeformat
Wähle das Format danach, wohin der Text geht.
Markdown-Datei: Behauptung im Fließtext, Fußnote mit dem Beleg:
Clients should not cache rate-limit responses.[^429-cache]
[^429-cache]: > Responses with the 429 status code MUST NOT be stored by a cache.
>
> — [Additional HTTP Status Codes — 4. 429 Too Many Requests](https://www.rfc-editor.org/rfc/rfc6585.html#:~:text=Responses%20with%20the%20429%20status%20code%20MUST%20NOT%20be%20stored%20by%20a%20cache.) · retrieved 2026-11-08
>
> 
- Fußnoten-IDs sind kurze, beschreibende Slugs, keine Nummern. Verwende dieselbe
[^id]wieder, wenn dieselbe Passage zwei Behauptungen stützt. - Speichere Screenshots in
refs/neben der Markdown-Datei; Dateiname = Fußnoten-Slug. Lösche PNGs für Zitate, die du fallen gelassen hast.
Chat-Antwort: Keine Fußnoten (Terminals zeigen sie als Rohtext). Setze den Beleg direkt unter die Behauptung, die er stützt:
Clients should not cache rate-limit responses:
> Responses with the 429 status code MUST NOT be stored by a cache.
> — [Additional HTTP Status Codes — 4. 429 Too Many Requests](https://www.rfc-editor.org/rfc/rfc6585.html#:~:text=Responses%20with%20the%20429%20status%20code%20MUST%20NOT%20be%20stored%20by%20a%20cache.)
- Kein
retrieved-Datum (die Antwort ist der Abruf). - Speichere Chat-Screenshots im temporären Systemverzeichnis (z. B.
$TMPDIR/receipts/<slug>.png), niemals im Projekt des Benutzers. Wenn dein Host ein Werkzeug zum Anzeigen einer Datei oder eines Bildes hat, zeige jeden Screenshot damit an; andernfalls gib den vollständigen absoluten Pfad jedes Bildes in einer eigenen Zeile nach dem Zitat an. - Keine Screenshots angefordert → beende die Antwort mit einem einzeiligen Angebot, z. B. „Screenshots dieser Passagen gewünscht?“
Beide:
- Deine eigene Argumentation oder Empfehlung erhält kein Zitat; sage, dass es deine (oder die des Teams) Argumentation ist, nicht die der Quelle. Eine sachliche Behauptung über die Außenwelt (wie Bibliotheken, Browser oder Standards sich verhalten) benötigt eine Quellenangabe oder muss als Erwartung formuliert werden.
- Screenshots sind optional: Sie sind günstig (etwa eine halbe Sekunde pro Seite), fügen aber Bilddateien hinzu, die der Benutzer behalten oder löschen muss. Füge
"out"nur hinzu, wenn der Benutzer Screenshots anfordert, oder, in einer Markdown-Datei, der Beleg visuell ist (eine Tabelle, Abbildung, Code-Layout), bei dem der Text allein die Bedeutung verliert. Füge ein Bild oder einen Pfad nur für Einträge mitscreenshotim Ergebnis ein. - Zitiere die kürzeste Passage, die die Behauptung vollständig stützt (ein Satz ist typisch).
Wenn das Skript fehlschlägt
| Ergebnis | Handlung |
|---|---|
match: fuzzy | Verwende quote_on_page (der Screenshot hebt es bereits hervor). Wenn es deine Behauptung nicht mehr stützt, ändere die Behauptung. |
match: none | Durchsuche die Seite auf andere Weise (andere Passage, andere Abschnitts-URL). Immer noch nichts → lasse die Behauptung fallen oder kennzeichne sie mit **UNVERIFIED:** und einem einfachen Link. Präsentiere niemals ein unverifiziertes Zitat als Blockzitat. |
ok: false + Fehler (PDF, Login-Wall, Bot-Erkennung, 403) | Einfacher Link + `**UNVERIFIED (could not load: )****. Erfinde das Zitat nicht aus dem Gedächtnis oder aus WebFetch. |
occurrences > 1 und excerpt ist das falsche | Führe mit "prefix" oder "suffix" erneut aus, gesetzt auf die benachbarten Wörter des gemeinten. |
Häufige Fehler
- Zitieren, was die Seite „im Grunde sagt“ → Blockzitate sind nur wörtlich; Paraphrasierung gehört in den Fließtext.
- Verwenden eines Abschnittsanbinds (
#section-4) anstelle vonfragment_url→ der Leser muss immer noch jagen. - Zitieren einer Passage, deren
excerptder Behauptung widerspricht (z. B. der nächste Satz sagt „dies gilt nicht für …“). - Ausführen von WebFetch zum „Verifizieren“ → es fasst zusammen; es kann wörtlichen Text nicht bestätigen. Verwende das Skript.
- Vertrauen der Zusammenfassung eines Suchtools darüber, was eine Seite sagt oder auslässt → es paraphrasiert wie WebFetch und platziert oft falsch, welcher Abschnitt was sagt. Setze den strittigen Satz durch das Skript.
- „Verifizieren“ eines Entwurfs, indem nur die darin bereits enthaltenen Zitate überprüft werden → seine Abwesenheitsbehauptungen und strittigen Behauptungen bleiben ungeprüft, sodass eine falsche Antwort vollständig verifiziert aussieht.
