gwoe-antragspruefer/app/templates/methodik.html
Dotty Dotter 07507de24a #96 Methodik-/Transparenz-Seite unter /methodik
Neue Seite für Endnutzer-Transparenz über die Bewertungsmethodik:

- GWÖ-Matrix 2.0 Erklärung mit interaktivem 5×5-Grid
- Analyse-Pipeline als 5-Schritt-Visualisierung (Download → Embedding
  → LLM → Verifikation → Darstellung)
- Wahlprogramm-Vergleich: Erklärung des Retrieval + Top-K + Verifikation
- Qualitätssicherung: Sub-D Property-Tests, server-seitige Quellen-
  Rekonstruktion, automatische Neu-Analyse
- Einschränkungen: KI-Bias, keine juristische Bewertung, nur indexierte
  Programme, kein Abstimmungsverhalten
- Datenquellen: dynamische Tabelle aller angebundenen Parlamente aus
  ADAPTERS + bundeslaender.py
- Technische Details aufklappbar (details/summary) für Interessierte,
  Haupttext verständlich für Nicht-Techniker
- Links zu Quellen-Seite, Adapter-Matrix, ADRs

In Hauptnavigation verlinkt (neben Quellen + Auswertungen).
Template-Variablen: adapter_count, model_name, programme_count,
chunk_count, bundeslaender — alles dynamisch aus dem Backend.

Tests: 194/194 grün.

Refs: #96
2026-04-10 16:14:38 +02:00

364 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Methodik — {{ app_name }}</title>
<style>
:root {
--color-darkgray: #5a5a5a;
--color-green: #889e33;
--color-blue: #009da5;
--color-lightgray: #bfbfbf;
--color-bg: #f5f5f5;
--color-amber: #ffc107;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: 'Avenir', 'Segoe UI', sans-serif;
color: var(--color-darkgray);
line-height: 1.6;
background: var(--color-bg);
}
.header {
background: white;
padding: 1rem 2rem;
border-bottom: 1px solid var(--color-lightgray);
display: flex;
align-items: center;
gap: 1rem;
}
.header h1 { color: var(--color-blue); font-size: 1.5rem; }
.header a { color: var(--color-blue); text-decoration: none; }
.container { max-width: 900px; margin: 2rem auto; padding: 0 2rem; }
h2 {
color: var(--color-blue);
margin: 2rem 0 1rem;
padding-bottom: 0.5rem;
border-bottom: 2px solid var(--color-blue);
}
h3 { color: var(--color-green); margin: 1.5rem 0 0.5rem; }
.card {
background: white;
padding: 1.5rem;
border-radius: 8px;
margin-bottom: 1.5rem;
box-shadow: 0 1px 3px rgba(0,0,0,.08);
}
.matrix-grid {
display: grid;
grid-template-columns: auto repeat(5, 1fr);
gap: 2px;
font-size: 0.8rem;
margin: 1rem 0;
}
.matrix-grid .cell {
padding: 0.4rem;
text-align: center;
background: #f8f9fa;
border: 1px solid #e0e0e0;
}
.matrix-grid .header-cell {
background: var(--color-blue);
color: white;
font-weight: bold;
}
.matrix-grid .row-header {
background: var(--color-green);
color: white;
font-weight: bold;
text-align: left;
}
details { margin: 0.5rem 0; }
details summary {
cursor: pointer;
color: var(--color-blue);
font-weight: 600;
padding: 0.3rem 0;
}
details summary:hover { text-decoration: underline; }
.pipeline-step {
display: flex;
align-items: flex-start;
gap: 1rem;
margin: 0.75rem 0;
padding: 0.75rem;
background: #f8f9fa;
border-radius: 6px;
border-left: 3px solid var(--color-blue);
}
.step-num {
background: var(--color-blue);
color: white;
width: 28px; height: 28px;
border-radius: 50%;
display: flex; align-items: center; justify-content: center;
font-weight: bold;
font-size: 0.85rem;
flex-shrink: 0;
}
.note {
background: #fff3cd;
border-left: 3px solid var(--color-amber);
padding: 0.75rem 1rem;
margin: 1rem 0;
border-radius: 4px;
font-size: 0.9rem;
}
table { border-collapse: collapse; width: 100%; margin: 0.5rem 0; }
th, td { padding: 0.5rem; border: 1px solid #e0e0e0; text-align: left; font-size: 0.9rem; }
th { background: #f0f0f0; }
a { color: var(--color-blue); }
.footer { text-align: center; padding: 2rem; color: #999; font-size: 0.85rem; }
</style>
</head>
<body>
<div class="header">
<h1>{{ app_name }}</h1>
<a href="/">Bewertungen</a>
<a href="/auswertungen">Auswertungen</a>
<a href="/quellen">Quellen</a>
<strong>Methodik</strong>
</div>
<div class="container">
<h2>Wie funktioniert der GWÖ-Antragsprüfer?</h2>
<div class="card">
<p>
Der GWÖ-Antragsprüfer bewertet Parlamentsanträge automatisch nach der
<strong>Gemeinwohl-Ökonomie Matrix 2.0 für Gemeinden</strong>. Jede Bewertung
analysiert drei Dimensionen: GWÖ-Treue, Übereinstimmung mit Wahlprogrammen
und Übereinstimmung mit Grundsatzprogrammen der Parteien.
</p>
<p style="margin-top: 0.5rem;">
Alle Bewertungen werden durch ein KI-Sprachmodell erzeugt und anschließend
<strong>automatisch verifiziert</strong> — Zitate werden gegen die Originaltexte
der Wahlprogramme geprüft, nicht-verifizierbare Zitate werden verworfen.
</p>
</div>
<h2>Die GWÖ-Matrix 2.0</h2>
<div class="card">
<p>Die Matrix besteht aus <strong>5 Berührungsgruppen</strong> (Zeilen) und
<strong>5 Werten</strong> (Spalten) = 25 Themenfelder:</p>
<div class="matrix-grid">
<div class="cell"></div>
<div class="header-cell">Menschen&shy;würde</div>
<div class="header-cell">Solidarität</div>
<div class="header-cell">Ökologische Nachhaltig&shy;keit</div>
<div class="header-cell">Soziale Gerechtig&shy;keit</div>
<div class="header-cell">Transparenz & Demokratie</div>
<div class="row-header">A · Lieferanten</div>
<div class="cell">A1</div><div class="cell">A2</div><div class="cell">A3</div><div class="cell">A4</div><div class="cell">A5</div>
<div class="row-header">B · Finanzen</div>
<div class="cell">B1</div><div class="cell">B2</div><div class="cell">B3</div><div class="cell">B4</div><div class="cell">B5</div>
<div class="row-header">C · Verwaltung</div>
<div class="cell">C1</div><div class="cell">C2</div><div class="cell">C3</div><div class="cell">C4</div><div class="cell">C5</div>
<div class="row-header">D · Bürger</div>
<div class="cell">D1</div><div class="cell">D2</div><div class="cell">D3</div><div class="cell">D4</div><div class="cell">D5</div>
<div class="row-header">E · Gesellschaft</div>
<div class="cell">E1</div><div class="cell">E2</div><div class="cell">E3</div><div class="cell">E4</div><div class="cell">E5</div>
</div>
<p>Jedes Feld wird auf einer Skala von <strong>-5</strong> (fundamental widersprechend)
bis <strong>+5</strong> (stark fördernd) bewertet. Der Gesamtscore (0-10) gewichtet
die Matrix-Bewertungen und berücksichtigt Ausschlusskriterien:</p>
<table>
<tr><th>Symbol</th><th>Rating</th><th>Bedeutung</th></tr>
<tr><td>++</td><td>+4 bis +5</td><td>Stark fördernd, vorbildlich</td></tr>
<tr><td>+</td><td>+1 bis +3</td><td>Fördernd</td></tr>
<tr><td></td><td>0</td><td>Neutral / nicht berührt</td></tr>
<tr><td></td><td>-1 bis -3</td><td>Widersprechend</td></tr>
<tr><td></td><td>-4 bis -5</td><td>Stark widersprechend</td></tr>
</table>
<details>
<summary>Mehr zur GWÖ-Matrix</summary>
<p style="margin-top: 0.5rem;">
Die Matrix basiert auf dem
<a href="https://econgood.org" target="_blank">Arbeitsbuch der Gemeinwohl-Ökonomie</a>.
Die Adaption für Gemeinden fokussiert auf kommunale Handlungsfelder:
Beschaffung, Haushalt, Verwaltung, Daseinsvorsorge und überregionale Wirkung.
</p>
</details>
</div>
<h2>Analyse-Pipeline</h2>
<div class="card">
<p>Jede Bewertung durchläuft fünf Schritte:</p>
<div class="pipeline-step">
<div class="step-num">1</div>
<div>
<strong>Antrags-Text herunterladen</strong><br>
Der Volltext wird automatisch aus dem jeweiligen Landtags-Portal geholt
({{ adapter_count }} Parlamente angebunden). Der PDF-Text wird via PyMuPDF extrahiert.
</div>
</div>
<div class="pipeline-step">
<div class="step-num">2</div>
<div>
<strong>Relevante Wahlprogramm-Passagen suchen</strong><br>
Für <strong>alle Fraktionen der Wahlperiode</strong> werden per Embedding-Suche
(Qwen text-embedding-v3) die thematisch relevantesten Passagen aus Wahl- und
Grundsatzprogrammen gesucht (Top-5 pro Partei, Cosinus-Ähnlichkeit ≥ 0.45).
</div>
</div>
<div class="pipeline-step">
<div class="step-num">3</div>
<div>
<strong>KI-Bewertung</strong><br>
Ein Sprachmodell ({{ model_name }}) bewertet den Antrag anhand der GWÖ-Matrix
und vergleicht ihn mit den gefundenen Programm-Passagen. Der Prompt enthält
strikte Regeln für die Quellenangabe (nur wörtliche Zitate aus den vorgelegten Passagen).
</div>
</div>
<div class="pipeline-step">
<div class="step-num">4</div>
<div>
<strong>Zitat-Verifikation</strong><br>
Jedes vom Modell genannte Zitat wird <strong>server-seitig verifiziert</strong>:
Der zitierte Text muss als Substring (oder 5-Wort-Sequenz) in einem der
vorgelegten Chunks auffindbar sein. Nicht-verifizierbare Zitate werden
verworfen — Quellenangabe und Seitenzahl werden aus dem echten Treffer
rekonstruiert, nicht aus der Modell-Ausgabe übernommen.
</div>
</div>
<div class="pipeline-step">
<div class="step-num">5</div>
<div>
<strong>Persistierung & Darstellung</strong><br>
Die verifizierte Bewertung wird gespeichert. Klick auf ein Zitat öffnet
das Original-Wahlprogramm-PDF mit <strong>gelb markierter Fundstelle</strong>.
</div>
</div>
<details>
<summary>Technische Details zum Sprachmodell</summary>
<div style="margin-top: 0.5rem;">
<table>
<tr><th>Eigenschaft</th><th>Wert</th></tr>
<tr><td>Modell</td><td>{{ model_name }}</td></tr>
<tr><td>Anbieter</td><td>DashScope (Alibaba Cloud)</td></tr>
<tr><td>Retry bei Parse-Fehlern</td><td>3 Versuche mit steigender Temperatur</td></tr>
<tr><td>Embedding-Modell</td><td>text-embedding-v3 (1024 Dimensionen)</td></tr>
<tr><td>Chunk-Größe</td><td>400 Wörter, 50 Wörter Overlap</td></tr>
</table>
</div>
</details>
</div>
<h2>Wahlprogramm-Vergleich</h2>
<div class="card">
<p>
Für jede Fraktion der aktuellen Wahlperiode wird die <strong>Passung</strong>
des Antrags zu zwei Programmen bewertet:
</p>
<ul style="margin: 0.5rem 0 0.5rem 1.5rem;">
<li><strong>Wahlprogramm</strong> — das Landtags-Wahlprogramm der jeweiligen Legislaturperiode</li>
<li><strong>Grundsatzprogramm</strong> — das aktuelle Bundespartei-Grundsatzprogramm</li>
</ul>
<p>
Aktuell sind <strong>{{ programme_count }} Programme</strong> indexiert
({{ chunk_count }} Textabschnitte). Die vollständige Liste ist auf der
<a href="/quellen">Quellen-Seite</a> einsehbar.
</p>
<div class="note">
<strong>Wichtig:</strong> Wenn für eine Fraktion kein Programm im Index vorhanden ist,
wird kein Score vergeben — stattdessen erscheint ein Hinweis. Bewertungen
basieren ausschließlich auf verifizierbaren Quellen, nicht auf dem Trainingswissen
des Sprachmodells.
</div>
</div>
<h2>Qualitätssicherung</h2>
<div class="card">
<h3>Zitat-Verifikation (Sub-D)</h3>
<p>
Ein automatisierter Property-Test prüft für jedes in der Datenbank gespeicherte
Zitat, ob der zitierte Text tatsächlich auf der angegebenen Seite des
Wahlprogramm-PDFs vorkommt (Substring- oder 5-Wort-Anker-Match). Dieses
Verfahren hat im April 2026 drei halluzinierte Zitate aufgedeckt und zur
Implementierung der server-seitigen Verifikation geführt.
</p>
<h3>Server-seitige Quellen-Rekonstruktion</h3>
<p>
Das Sprachmodell darf keine Quellenangaben (Programmname, Seitenzahl) frei
erfinden. Nach jeder Analyse wird jedes Zitat gegen die tatsächlich vorgelegten
Textabschnitte abgeglichen. Quellenangabe und URL werden aus dem gefundenen
Treffer <strong>server-seitig konstruiert</strong> — die Modell-Ausgabe für
diese Felder wird verworfen.
</p>
<h3>Automatische Neu-Analyse</h3>
<p>
Wenn ein Nutzer auf ein Zitat klickt und die Textstelle im PDF nicht auffindbar
ist (z.B. bei älteren Bewertungen vor der Verifikations-Einführung), wird der
Antrag automatisch mit der aktuellen Pipeline neu analysiert.
</p>
</div>
<h2>Einschränkungen</h2>
<div class="card">
<ul style="margin-left: 1.5rem;">
<li><strong>Keine juristische Bewertung</strong> — die GWÖ-Analyse ist eine
wertebasierte Einordnung, keine Rechtsprüfung.</li>
<li><strong>KI-Bias</strong> — Sprachmodelle können systematische Verzerrungen
aufweisen. Die Bewertungen sollten als Orientierung verstanden werden,
nicht als objektive Wahrheit.</li>
<li><strong>Nur indexierte Programme</strong> — Parteien ohne hinterlegtes
Programm können nicht zuverlässig bewertet werden.</li>
<li><strong>Keine Analyse des Abstimmungsverhaltens</strong> — bewertet wird
der Antragstext, nicht ob oder wie darüber abgestimmt wurde.</li>
<li><strong>Aktualität</strong> — Wahlprogramme werden einmalig zur Wahl
indexiert und nicht automatisch aktualisiert.</li>
</ul>
</div>
<h2>Datenquellen</h2>
<div class="card">
<p><strong>{{ adapter_count }} Parlamente</strong> sind angebunden:</p>
<table>
<tr><th>Parlament</th><th>Doku-System</th></tr>
{% for bl in bundeslaender %}
<tr>
<td>{{ bl.name }} ({{ bl.code }})</td>
<td>{{ bl.doku_system }}</td>
</tr>
{% endfor %}
</table>
<p style="margin-top: 1rem;">
<a href="/quellen">Vollständige Programm-Liste</a> ·
<a href="https://docs.toppyr.de/gwoe-antragspruefer/reference/adapter-capabilities/" target="_blank">Technische Adapter-Vergleichsmatrix</a> ·
<a href="https://docs.toppyr.de/gwoe-antragspruefer/adr/" target="_blank">Architektur-Entscheidungen (ADRs)</a>
</p>
</div>
</div>
<div class="footer">
{{ app_name }} · <a href="https://econgood.org" target="_blank">Gemeinwohl-Ökonomie</a> ·
<a href="https://repo.toppyr.de/tobias/gwoe-antragspruefer" target="_blank">Quellcode</a>
</div>
</body>
</html>