fix: Gegenprobe der Abbildungen je Datenzeile; Standardmodell ~deepseek/deepseek-flash-latest
- check_figure_readings vergleicht Zahlentupel je Datenzeile statt aller Zahlen des Freitexts (Fehlalarm im ersten echten Lauf: zusätzliche Knotenaufzählung); fängt falsch zugeordnete Bewertungen und vertauschte Pfeilrichtungen - feste Form 'Start → Ziel: Bewertung' in Verstehen- und Abbildungs-Prompt; abweichende Lesungen stehen im Log - Standardmodell ist der Alias ~deepseek/deepseek-flash-latest (derzeit V4.1 Flash); Benchmarks weiter mit festen IDs Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
b07dd16143
commit
101d55b713
9 changed files with 55 additions and 28 deletions
|
|
@ -325,7 +325,7 @@ Was dabei passiert:
|
||||||
|
|
||||||
Voraussetzungen und Grenzen:
|
Voraussetzungen und Grenzen:
|
||||||
|
|
||||||
- Das Modell der Verstehensstufe muss Bilder lesen können. `deepseek/deepseek-v4.1-flash` kann das; sonst ein Bildmodell über `LLM_MODEL_UNDERSTANDING` wählen (z. B. `qwen/qwen3.8-flash`).
|
- Das Modell der Verstehensstufe muss Bilder lesen können. Das Standardmodell `~deepseek/deepseek-flash-latest` (derzeit DeepSeek V4.1 Flash) kann das; sonst ein Bildmodell über `LLM_MODEL_UNDERSTANDING` wählen (z. B. `qwen/qwen3.8-flash`).
|
||||||
- Höchstens 6 Abbildungen, je 5 MB.
|
- Höchstens 6 Abbildungen, je 5 MB.
|
||||||
- Mehrkosten: ein bis zwei zusätzliche kleine Aufrufe für die Gegenprobe.
|
- Mehrkosten: ein bis zwei zusätzliche kleine Aufrufe für die Gegenprobe.
|
||||||
- Verweise auf Webadressen werden nicht geladen (das Programm lädt nichts aus dem Internet).
|
- Verweise auf Webadressen werden nicht geladen (das Programm lädt nichts aus dem Internet).
|
||||||
|
|
@ -401,7 +401,7 @@ Wo das Geld hingeht: rund zwei Drittel der Kosten sind **erzeugter Output**, dav
|
||||||
|
|
||||||
**Prompt-Cache:** Alle Aufrufe eines Laufs gehen an denselben OpenRouter-Anbieter, damit dessen Cache wiederholt gelesene Prompt-Teile billiger abrechnen kann. Der Cache-Anteil steht in der Abschlusszeile.
|
**Prompt-Cache:** Alle Aufrufe eines Laufs gehen an denselben OpenRouter-Anbieter, damit dessen Cache wiederholt gelesene Prompt-Teile billiger abrechnen kann. Der Cache-Anteil steht in der Abschlusszeile.
|
||||||
|
|
||||||
**Feste Modellnamen verwenden** (z. B. `deepseek/deepseek-v4.1-flash`), keine `…-latest`-Aliase – sonst ändern sich Ergebnisse unbemerkt.
|
**Standardmodell ist der Alias `~deepseek/deepseek-flash-latest`** – er zeigt immer auf das neueste DeepSeek-Flash-Modell (September 2026: V4.1 Flash). Das hält die Pipeline aktuell, kann Ergebnisse aber unbemerkt verändern, sobald DeepSeek ein neues Flash-Modell veröffentlicht. **Für Benchmarks und Vergleiche feste Modellnamen verwenden** (z. B. `--models deepseek/deepseek-v4.1-flash`).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -429,7 +429,7 @@ Wo das Geld hingeht: rund zwei Drittel der Kosten sind **erzeugter Output**, dav
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `OPENROUTER_API_KEY` | Schlüssel für OpenRouter | – |
|
| `OPENROUTER_API_KEY` | Schlüssel für OpenRouter | – |
|
||||||
| `GEMINI_API_KEY` | Schlüssel für Gemini | – |
|
| `GEMINI_API_KEY` | Schlüssel für Gemini | – |
|
||||||
| `LLM_MODEL` | Modell, falls `--model` fehlt | `deepseek/deepseek-v4.1-flash` |
|
| `LLM_MODEL` | Modell, falls `--model` fehlt | `~deepseek/deepseek-flash-latest` |
|
||||||
| `LLM_MODEL_UNDERSTANDING` | Modell für Verstehen und Abbildungs-Gegenprobe (muss bei Abbildungen Bilder lesen können) | Session-Modell |
|
| `LLM_MODEL_UNDERSTANDING` | Modell für Verstehen und Abbildungs-Gegenprobe (muss bei Abbildungen Bilder lesen können) | Session-Modell |
|
||||||
| `LLM_MODEL_EXTRACTION` | Modell nur für die Extraktion | Session-Modell |
|
| `LLM_MODEL_EXTRACTION` | Modell nur für die Extraktion | Session-Modell |
|
||||||
| `LLM_MODEL_REVIEW` | Modell nur für die Prüfung | Session-Modell |
|
| `LLM_MODEL_REVIEW` | Modell nur für die Prüfung | Session-Modell |
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ Exit-Codes: `0` Ergebnis zuverlässig, `2` Ergebnis vorhanden, aber unzuverläss
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `--report DATEI` | Report als `.md` (z. B. VS Code-Vorschau: Strg+Umschalt+V) oder `.html` (Browser, Formeln via MathJax) | – |
|
| `--report DATEI` | Report als `.md` (z. B. VS Code-Vorschau: Strg+Umschalt+V) oder `.html` (Browser, Formeln via MathJax) | – |
|
||||||
| `--code DATEI` | Solver-Programm als eigenständiges, dokumentiertes Python-Skript speichern | – |
|
| `--code DATEI` | Solver-Programm als eigenständiges, dokumentiertes Python-Skript speichern | – |
|
||||||
| `--model` / `LLM_MODEL` | LLM-Modell | `deepseek/deepseek-v4.1-flash` |
|
| `--model` / `LLM_MODEL` | LLM-Modell | `~deepseek/deepseek-flash-latest` (Alias, derzeit V4.1 Flash) |
|
||||||
| `--daten DATEI …` | beigelegte CSV-/Excel-Dateien; ihr Profil (Zeilen, Spalten, Spannweiten, Lücken) geht in die Prompts, die Dateien ins Arbeitsverzeichnis des Programms | – |
|
| `--daten DATEI …` | beigelegte CSV-/Excel-Dateien; ihr Profil (Zeilen, Spalten, Spannweiten, Lücken) geht in die Prompts, die Dateien ins Arbeitsverzeichnis des Programms | – |
|
||||||
| `--von STUFE ERGEBNIS.JSON` | gespeichertes Ergebnis fortsetzen statt alles zu wiederholen: `solver` (nur Solver-Code neu) oder `pruefung` (ab Prüfung/Korrektur) | – |
|
| `--von STUFE ERGEBNIS.JSON` | gespeichertes Ergebnis fortsetzen statt alles zu wiederholen: `solver` (nur Solver-Code neu) oder `pruefung` (ab Prüfung/Korrektur) | – |
|
||||||
| `--max-revisions` / `MAX_REVISIONS` | Korrekturrunden | 2 |
|
| `--max-revisions` / `MAX_REVISIONS` | Korrekturrunden | 2 |
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,9 @@ def _checked_figure_readings(session, task: str, figures, first, label: str) ->
|
||||||
if not befunde:
|
if not befunde:
|
||||||
return first, []
|
return first, []
|
||||||
log(f"[{label}] Abbildungen uneinheitlich gelesen – dritte Lesung: " + "; ".join(i.message for i in befunde)[:300])
|
log(f"[{label}] Abbildungen uneinheitlich gelesen – dritte Lesung: " + "; ".join(i.message for i in befunde)[:300])
|
||||||
|
for nummer, lesung in ((1, first), (2, zweite)):
|
||||||
|
for f in lesung:
|
||||||
|
log(f" Lesung {nummer}, {f.id}: " + f.transcription.replace("\n", " | ")[:300])
|
||||||
dritte = read_figures(session, task, figures).figures
|
dritte = read_figures(session, task, figures).figures
|
||||||
if not check_figure_readings(first, dritte):
|
if not check_figure_readings(first, dritte):
|
||||||
return first, []
|
return first, []
|
||||||
|
|
|
||||||
|
|
@ -206,23 +206,35 @@ def check_understanding(understanding, task: str) -> List[CheckIssue]:
|
||||||
return issues
|
return issues
|
||||||
|
|
||||||
|
|
||||||
def _numbers_multiset(text: str) -> Counter:
|
def _number_rows(text: str) -> Counter:
|
||||||
"""Zahlen eines Textes mit Häufigkeit – eine Kante mit Bewertung 3 zweimal ist nicht dasselbe wie einmal."""
|
"""Je Datenzeile das Tupel ihrer Zahlen: „Pfeil 1 → 2: 3“ und „(1,2): 3“ ergeben beide (1, 2, 3).
|
||||||
zaehler = Counter()
|
|
||||||
for roh in NUMBER_PATTERN.findall(text or ""):
|
Zeilen trennt der Zeilenumbruch oder ein Semikolon; Zeilen ohne Zahl zählen nicht. So ist der Vergleich
|
||||||
try:
|
unabhängig von der Schreibweise, bemerkt aber eine Bewertung am falschen Pfeil.
|
||||||
zaehler[normalize_number(roh)] += 1
|
"""
|
||||||
except ValueError:
|
zeilen = Counter()
|
||||||
continue
|
# „(1,2)“ ist ein Pfeil, keine Dezimalzahl 1,2 – ganzzahlige Paare in Klammern vorher trennen
|
||||||
return zaehler
|
text = re.sub(r"\((\d+)\s*,\s*(\d+)\)", r"(\1 \2)", text or "")
|
||||||
|
for zeile in re.split(r"[\n;]", text):
|
||||||
|
tupel = []
|
||||||
|
for roh in NUMBER_PATTERN.findall(zeile):
|
||||||
|
try:
|
||||||
|
tupel.append(normalize_number(roh))
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
if tupel:
|
||||||
|
zeilen[tuple(tupel)] += 1
|
||||||
|
return zeilen
|
||||||
|
|
||||||
|
|
||||||
def check_figure_readings(first, second) -> List[CheckIssue]:
|
def check_figure_readings(first, second) -> List[CheckIssue]:
|
||||||
"""Zwei unabhängige Übertragungen derselben Abbildungen vergleichen – Zahl für Zahl, ohne LLM.
|
"""Zwei unabhängige Übertragungen derselben Abbildungen vergleichen – Zahl für Zahl, ohne LLM.
|
||||||
|
|
||||||
Ein Bildmodell kann eine Pfeilbewertung dem falschen Pfeil zuordnen oder eine Ziffer verlesen; eine einzige
|
Ein Bildmodell kann eine Pfeilbewertung dem falschen Pfeil zuordnen oder eine Ziffer verlesen; eine einzige
|
||||||
Lesung wäre dann ungeprüft die Datengrundlage jeder weiteren Stufe. Verglichen werden die Zahlen je Abbildung
|
Lesung wäre dann ungeprüft die Datengrundlage jeder weiteren Stufe. Verglichen werden die Datenzeilen als
|
||||||
samt Häufigkeit. Richtungsfehler bei gleichen Zahlen fängt das nicht – dafür steht das Original im Report.
|
Zahlentupel (`_number_rows`). Erster Ansatz – alle Zahlen des Freitexts – schlug im ersten echten Lauf
|
||||||
|
fälschlich an: eine Lesung zählte zusätzlich „Knoten: 1, 2, 3, 4“ auf (test_Image.md, 17.09.2026).
|
||||||
|
Eine vertauschte Pfeilrichtung (2 → 3 statt 3 → 2) fällt auf; eine in BEIDEN Lesungen gleich falsche nicht.
|
||||||
"""
|
"""
|
||||||
issues = []
|
issues = []
|
||||||
erste = {f.id: f for f in first}
|
erste = {f.id: f for f in first}
|
||||||
|
|
@ -232,15 +244,14 @@ def check_figure_readings(first, second) -> List[CheckIssue]:
|
||||||
issues.append(CheckIssue(severity=CheckSeverity.ERROR, code="FIGURE_READINGS_DIFFER",
|
issues.append(CheckIssue(severity=CheckSeverity.ERROR, code="FIGURE_READINGS_DIFFER",
|
||||||
message=f"{kennung} wurde nur in einer von zwei Lesungen übertragen."))
|
message=f"{kennung} wurde nur in einer von zwei Lesungen übertragen."))
|
||||||
continue
|
continue
|
||||||
a = _numbers_multiset(erste[kennung].transcription)
|
a = _number_rows(erste[kennung].transcription)
|
||||||
b = _numbers_multiset(zweite[kennung].transcription)
|
b = _number_rows(zweite[kennung].transcription)
|
||||||
if a != b:
|
if a != b:
|
||||||
nur_a = sorted((a - b).elements(), key=float)
|
zeilen = lambda z: ", ".join("(" + " ".join(t) + ")" for t in sorted(z.elements())) or "–"
|
||||||
nur_b = sorted((b - a).elements(), key=float)
|
|
||||||
issues.append(CheckIssue(
|
issues.append(CheckIssue(
|
||||||
severity=CheckSeverity.ERROR, code="FIGURE_READINGS_DIFFER",
|
severity=CheckSeverity.ERROR, code="FIGURE_READINGS_DIFFER",
|
||||||
message=f"{kennung} uneinheitlich gelesen – nur in Lesung 1: {', '.join(nur_a) or '–'}; "
|
message=f"{kennung} uneinheitlich gelesen – Datenzeilen nur in Lesung 1: {zeilen(a - b)}; "
|
||||||
f"nur in Lesung 2: {', '.join(nur_b) or '–'}."))
|
f"nur in Lesung 2: {zeilen(b - a)}."))
|
||||||
return issues
|
return issues
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,9 @@ import instructor
|
||||||
|
|
||||||
from core.model_schema import CallRecord, LLMUsage
|
from core.model_schema import CallRecord, LLMUsage
|
||||||
|
|
||||||
DEFAULT_MODEL = os.environ.get("LLM_MODEL", "deepseek/deepseek-v4.1-flash")
|
# Alias auf das jeweils neueste DeepSeek-Flash-Modell (September 2026: V4.1 Flash, nimmt auch Bilder an).
|
||||||
|
# Für vergleichbare Benchmarks ein festes Modell mit --models angeben.
|
||||||
|
DEFAULT_MODEL = os.environ.get("LLM_MODEL", "~deepseek/deepseek-flash-latest")
|
||||||
# Modell je Pipeline-Stufe: ein starkes Modell für Extraktion/Prüfung, ein schnelles für den Solver-Code
|
# Modell je Pipeline-Stufe: ein starkes Modell für Extraktion/Prüfung, ein schnelles für den Solver-Code
|
||||||
# (oder umgekehrt, je nach Messung). Leer = das Modell der Session (LLM_MODEL bzw. --model).
|
# (oder umgekehrt, je nach Messung). Leer = das Modell der Session (LLM_MODEL bzw. --model).
|
||||||
STEP_MODEL_ENV = {
|
STEP_MODEL_ENV = {
|
||||||
|
|
|
||||||
|
|
@ -132,8 +132,8 @@ class FigureTranscription(BaseModel):
|
||||||
id: str = Field(description="Kennung wie im Text, z. B. 'Abbildung 1'")
|
id: str = Field(description="Kennung wie im Text, z. B. 'Abbildung 1'")
|
||||||
shows: str = Field(description="Was die Abbildung zeigt, in einem Satz (z. B. 'gerichteter Graph mit 4 Knoten')")
|
shows: str = Field(description="Was die Abbildung zeigt, in einem Satz (z. B. 'gerichteter Graph mit 4 Knoten')")
|
||||||
transcription: str = Field(
|
transcription: str = Field(
|
||||||
description="Vollständige Übertragung ALLER Inhalte: jede Zahl, jede Beschriftung, jede Pfeilrichtung, "
|
description="Nur die Daten, eine Zeile je Datenpunkt, jede Zahl genau einmal (Graph: '1 → 2: 3' je Pfeil; "
|
||||||
"am besten als Tabelle oder Liste (z. B. 'Pfeil 1→2: 3'). Nichts ergänzen, was nicht zu sehen ist.")
|
"Tabelle: 'Zeile / Spalte: Wert'). Keine Knotenaufzählung, keine Lagebeschreibung – das gehört nach shows.")
|
||||||
uncertain: List[str] = Field(
|
uncertain: List[str] = Field(
|
||||||
default_factory=list,
|
default_factory=list,
|
||||||
description="Stellen, die nicht sicher lesbar sind (verdeckt, unscharf, mehrdeutig); leer = alles sicher gelesen")
|
description="Stellen, die nicht sicher lesbar sind (verdeckt, unscharf, mehrdeutig); leer = alles sicher gelesen")
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ def test_identical_readings_have_no_finding():
|
||||||
def test_misread_value_is_found_with_both_numbers():
|
def test_misread_value_is_found_with_both_numbers():
|
||||||
befunde = check_figure_readings([GRAPH], [VERLESEN])
|
befunde = check_figure_readings([GRAPH], [VERLESEN])
|
||||||
assert len(befunde) == 1 and befunde[0].code == "FIGURE_READINGS_DIFFER"
|
assert len(befunde) == 1 and befunde[0].code == "FIGURE_READINGS_DIFFER"
|
||||||
assert "nur in Lesung 1: 3" in befunde[0].message and "nur in Lesung 2: 5" in befunde[0].message
|
assert "nur in Lesung 1: (2 4 3)" in befunde[0].message and "nur in Lesung 2: (2 4 5)" in befunde[0].message
|
||||||
|
|
||||||
|
|
||||||
def test_figure_missing_in_one_reading_is_found():
|
def test_figure_missing_in_one_reading_is_found():
|
||||||
|
|
@ -139,3 +139,14 @@ def test_report_shows_original_and_transcription():
|
||||||
assert f'<img src="data:image/png;base64,{PNG}"' in html
|
assert f'<img src="data:image/png;base64,{PNG}"' in html
|
||||||
assert "Pfeil 1 → 3: 1" in html and "unsicher gelesen" in html
|
assert "Pfeil 1 → 3: 1" in html and "unsicher gelesen" in html
|
||||||
assert f"" in to_markdown(build_document(result))
|
assert f"" in to_markdown(build_document(result))
|
||||||
|
|
||||||
|
|
||||||
|
def test_reading_comparison_ignores_wording_but_not_assignment():
|
||||||
|
# erster echter Lauf: Knotenaufzählung und doppelte Pfeilbeschreibung lösten einen Fehlalarm aus
|
||||||
|
anders_formuliert = GRAPH.model_copy(update={"transcription": "(1,2): 3; (1,3): 1; (3,2): 1; (2,4): 3; (3,4): 5"})
|
||||||
|
assert check_figure_readings([GRAPH], [anders_formuliert]) == []
|
||||||
|
vertauscht = GRAPH.model_copy(update={"transcription": GRAPH.transcription.replace("1 → 2: 3", "1 → 2: 1")
|
||||||
|
.replace("1 → 3: 1", "1 → 3: 3")}) # gleiche Zahlen, falsche Pfeile
|
||||||
|
assert check_figure_readings([GRAPH], [vertauscht])
|
||||||
|
richtung = GRAPH.model_copy(update={"transcription": GRAPH.transcription.replace("3 → 2: 1", "2 → 3: 1")})
|
||||||
|
assert check_figure_readings([GRAPH], [richtung])
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ Deine Übertragung wird ohne LLM mit einer zweiten, unabhängigen Übertragung d
|
||||||
|
|
||||||
Für jede Abbildung, in der Reihenfolge ihrer Kennung („Abbildung 1“, „Abbildung 2“, …), ein Eintrag in figures:
|
Für jede Abbildung, in der Reihenfolge ihrer Kennung („Abbildung 1“, „Abbildung 2“, …), ein Eintrag in figures:
|
||||||
- id: die Kennung genau wie angegeben.
|
- id: die Kennung genau wie angegeben.
|
||||||
- shows: was die Abbildung zeigt, in einem Satz (z. B. „gerichteter Graph mit 4 Knoten und 5 bewerteten Pfeilen“).
|
- shows: was die Abbildung zeigt, in einem Satz (z. B. „gerichteter Graph mit 4 Knoten und 5 bewerteten Pfeilen“); hier ist Platz für Lage und Aufbau.
|
||||||
- transcription: ALLE Inhalte – jede Zahl, jede Beschriftung, bei Graphen jeden Pfeil mit Start, Ziel und Bewertung (eine Zeile je Pfeil, z. B. „Pfeil 1 → 2: 3“), bei Tabellen jede Zelle, bei Diagrammen Achsen, Einheiten und abgelesene Werte. Achte bei Pfeilen genau auf die Richtung (wo sitzt die Spitze?).
|
- transcription: NUR die Daten, eine Zeile je Datenpunkt, jede Zahl genau einmal – bei Graphen je Pfeil „Start → Ziel: Bewertung“ (z. B. „1 → 2: 3“), bei Tabellen je Zelle „Zeile / Spalte: Wert“, bei Diagrammen je Punkt „x: y“. Keine Aufzählung von Knoten, keine Lagebeschreibung, keine Wiederholung – das gehört nach shows. Achte bei Pfeilen genau auf die Richtung (wo sitzt die Spitze?).
|
||||||
- uncertain: jede Stelle, die du nicht sicher lesen kannst (verdeckt, unscharf, mehrdeutige Richtung oder Zuordnung einer Zahl zu einem Pfeil). Leer nur, wenn alles eindeutig ist.
|
- uncertain: jede Stelle, die du nicht sicher lesen kannst (verdeckt, unscharf, mehrdeutige Richtung oder Zuordnung einer Zahl zu einem Pfeil). Leer nur, wenn alles eindeutig ist.
|
||||||
|
|
||||||
Ergänze nichts, was nicht zu sehen ist, und rechne nichts aus.
|
Ergänze nichts, was nicht zu sehen ist, und rechne nichts aus.
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,6 @@ GEMEINSAMER RAHMEN (gilt für alle vier Stufen dieser Pipeline: Verstehen, Model
|
||||||
- ignored_numbers ist für Aufgabennummern („3.8“), Zahlen in Einheiten („in 1000 Stunden“), Jahreszahlen, Seitenzahlen, Nummern von Sätzen. Immer mit Grund.
|
- ignored_numbers ist für Aufgabennummern („3.8“), Zahlen in Einheiten („in 1000 Stunden“), Jahreszahlen, Seitenzahlen, Nummern von Sätzen. Immer mit Grund.
|
||||||
Eine Zahl, die weder im einen noch im anderen steht, gilt als übersehen. [→ UNCAPTURED_NUMBERS]
|
Eine Zahl, die weder im einen noch im anderen steht, gilt als übersehen. [→ UNCAPTURED_NUMBERS]
|
||||||
|
|
||||||
4. ABBILDUNGEN: Liegen der Aufgabe Abbildungen bei (im Text als „[Abbildung N]“, die Bilder folgen der Nachricht), trage je Abbildung einen Eintrag in figures ein: id genau wie im Text, shows in einem Satz, transcription mit ALLEN Inhalten (jede Zahl, jede Beschriftung, bei Graphen jeder Pfeil mit Start, Ziel und Bewertung – achte auf die Richtung der Pfeilspitze; bei Tabellen jede Zelle), uncertain für alles, was nicht sicher lesbar ist. Die Zahlen der Abbildung gehören außerdem in facts, mit quote „Abbildung N: …“. Eine zweite, unabhängige Übertragung wird Zahl für Zahl mit deiner verglichen. [→ check_figure_readings]
|
4. ABBILDUNGEN: Liegen der Aufgabe Abbildungen bei (im Text als „[Abbildung N]“, die Bilder folgen der Nachricht), trage je Abbildung einen Eintrag in figures ein: id genau wie im Text, shows in einem Satz, transcription mit ALLEN Daten, NUR die Daten, eine Zeile je Datenpunkt, jede Zahl genau einmal – bei Graphen je Pfeil „Start → Ziel: Bewertung“ (z. B. „1 → 2: 3“), bei Tabellen je Zelle „Zeile / Spalte: Wert“, bei Diagrammen je Punkt „x: y“. Keine Aufzählung von Knoten, keine Lagebeschreibung, keine Wiederholung – das gehört nach shows. Achte auf die Richtung der Pfeilspitze., uncertain für alles, was nicht sicher lesbar ist. Die Zahlen der Abbildung gehören außerdem in facts, mit quote „Abbildung N: …“. Eine zweite, unabhängige Übertragung wird Zahl für Zahl mit deiner verglichen. [→ check_figure_readings]
|
||||||
|
|
||||||
5. Erfinde nichts. Was der Text nicht sagt, gehört nicht in facts – fehlende Angaben werden später als Annahme ausgewiesen, nicht hier geraten.
|
5. Erfinde nichts. Was der Text nicht sagt, gehört nicht in facts – fehlende Angaben werden später als Annahme ausgewiesen, nicht hier geraten.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue