#import "@preview/cetz:0.4.2"
#import "@preview/cetz-plot:0.1.3": plot

#heading(level: 2)[Large Language Models im Software Engineering]

#heading(level: 3)[Künstliche Intelligenz, Machine Learning und Einordnung von LLMs]

Die Einordnung von Large Language Models folgt einer hierarchischen Begriffsstruktur, die sich in vier Ebenen gliedern lässt (vgl. @abb_hierarchie_ki):

*Künstliche Intelligenz (KI)* ist der Oberbegriff für Verfahren, die Aufgaben bearbeiten, welche in der Praxis typischerweise kognitive Fähigkeiten erfordern (z. B. Klassifikation, Planung, Sprachverarbeitung) @bishop2006prml.

*Machine Learning (ML)* ist ein Teilgebiet der KI, das Modelle aus Daten lernt, anstatt Regeln vollständig manuell zu spezifizieren (sogennante Expertensysteme). in der Praxis wird zwischen Systemen mit überwachtem Lernen (mit Zielwerten), unüberwachtem Lernen (ohne Zielwerte, System erkennt selbst eine Struktur) und Reinforcement Learning (Lernen über Rückmeldung, z.B. Ergebnis Richtig / Falsch) unterschieden @bishop2006prml @goodfellow2016dl. In der heutigen Welt sind Neuronale Netze die dominierende ML-Architektur, insbesondere für unstrukturierte Daten wie Text und Code.

*Deep Learning* ist wiederum ein Teilbereich von ML, der neuronale Netze mit vielen Parametern und vielen (tiefen) Verarbeitungsebenen nutzt, um geeignete Repräsentationen aus Rohdaten zu lernen. Charakteristisch ist, dass Merkmalsextraktion und Modellanpassung gemeinsam über Optimierung (typischerweise Gradientenverfahren) erfolgen. 

*Large Language Models (LLMs)* sind eine spezielle Ausprägung von Neuronalen Netzen, die auf sehr großen Text- und Codemengen vortrainiert werden. Zudem verfügen sie über sehr große Mengen (>Milliarden) von Eingabeparametern (Tokens) und viele Schichten (>100). In der aktuellen Modellgeneration dominiert die Transformer-Architektur @vaswani2017attention, deren Funktionsweise in den folgenden Abschnitten erläutert wird.

#figure(
  cetz.canvas({
    import cetz.draw: *

    rect((-6, -2.8), (6, 2.8), stroke: black + 0.6pt, fill: luma(242))
    content((0, 2.35), text(size: 9pt, weight: "bold")[Künstliche Intelligenz (KI)])

    rect((-5.4, -2.2), (5.4, 1.9), stroke: black + 0.6pt, fill: luma(228))
    content((0, 1.45), text(size: 9pt, weight: "bold")[Machine Learning (ML)])

    rect((-4.8, -1.6), (4.8, 1.0), stroke: black + 0.6pt, fill: luma(214))
    content((0, 0.55), text(size: 9pt, weight: "bold")[Deep Learning])

    rect((-4.2, -1.0), (4.2, 0.1), stroke: black + 0.6pt, fill: luma(200))
    content((0, -0.45), text(size: 9pt, weight: "bold")[Large Language Models (LLMs)])
  }),
  caption: [Hierarchische Einordnung: KI ⊃ ML ⊃ Deep Learning ⊃ LLMs.],
) <abb_hierarchie_ki>
#pagebreak()
*Neuronale Netze* lassen sich vereinfacht als parametrisierte Funktionsketten aus Schichten (Layern) beschreiben. Dabei geben die Schichten die Eingaben in zunehmend abstrakte Repräsentationen jeweils in die nächste Schicht weiter. Das Training erfolgt über eine Zielfunktion  und Gradientenberechnung. In der Praxis geschieht dies meist über Backpropagation und Varianten des Gradientenabstiegs @goodfellow2016dl.

#figure(
  cetz.canvas({
    import cetz.draw: *

    let r = 0.35
    let lx = 3.0
    let ny = 1.5

    let ys-3 = (ny, 0, -ny)
    let ys-2 = (ny / 2, -ny / 2)

    let layers = (
      (x: 0,      ys: ys-3, labels: ($x_1$, $x_2$, $x_3$)),
      (x: lx,     ys: ys-3, labels: ($h_1$, $h_2$, $h_3$)),
      (x: 2 * lx, ys: ys-2, labels: ($y_1$, $y_2$)),
    )

    // Kanten (zuerst zeichnen, damit Knoten darüber liegen)
    for li in range(layers.len() - 1) {
      let l1 = layers.at(li)
      let l2 = layers.at(li + 1)
      for y1 in l1.ys {
        for y2 in l2.ys {
          line(
            (l1.x, y1), (l2.x, y2),
            stroke: luma(160) + 0.4pt,
          )
        }
      }
    }

    // Knoten
    for layer in layers {
      for (i, y) in layer.ys.enumerate() {
        circle((layer.x, y), radius: r, stroke: black + 0.6pt, fill: white)
        content((layer.x, y), layer.labels.at(i))
      }
    }

    // Schichtbeschriftungen
    let label-y = ny + 0.9
    content((0, label-y), text(size: 9pt)[Eingabe])
    content((lx, label-y), text(size: 9pt)[Verdeckte Schicht])
    content((2 * lx, label-y), text(size: 9pt)[Ausgabe])
  }),
  caption: [Schematische Darstellung eines vollständig verbundenen Feedforward-Netzes.]
)

Ein einzelnes Neuron lässt sich als  Transformation mit nachgeschalteter Aktivierungsfunktion formulieren:

$
z = sum_(i=1)^d w_i x_i + b, #h(1em) a = phi (z)
$

Typische Aktivierungsfunktionen ($a = phi (z)$) sind die Sigmoid-Funktion, der hyperbolische Tangens und ReLU #cite(<goodfellow2016dl>):

#grid(
  columns: (1fr, 1fr, 1fr),
  align: center,
  column-gutter: 0.8em,
  row-gutter: 0.4em,
  text(weight: "bold")[Sigmoid],
  text(weight: "bold")[tanh],
  text(weight: "bold")[ReLU],
  $ sigma(z) = frac(1, 1 + e^(-z)) $,
  $ tanh(z) = frac(e^z - e^(-z), e^z + e^(-z)) $,
  $ op("ReLU")(z) = max(0, z) $,
)

#figure(
  cetz.canvas({
    import cetz.draw: *

    plot.plot(
      size: (12, 7),
      x-tick-step: 2,
      y-tick-step: 1,
      x-min: -6, x-max: 6,
      y-min: -1.5, y-max: 6.5,
      x-label: $x$,
      y-label: $phi(x)$,
      legend: "north-west",
      {
        plot.add(
          style: (stroke: blue + 1.2pt),
          domain: (-6, 6),
          samples: 200,
          label: [$sigma(x)$ (Sigmoid)],
          x => 1 / (1 + calc.exp(-x)),
        )
        plot.add(
          style: (stroke: orange + 1.2pt),
          domain: (-6, 6),
          samples: 200,
          label: [$tanh(x)$],
          x => {
            let e2x = calc.exp(2 * x)
            (e2x - 1) / (e2x + 1)
          },
        )
        plot.add(
          style: (stroke: green.darken(20%) + 1.2pt),
          domain: (-6, 6),
          samples: 200,
          label: [ReLU $max(0, x)$],
          x => calc.max(0, x),
        )
      },
    )
  }),
  caption: [Beispielhafte Aktivierungsfunktionen (Sigmoid, tanh, ReLU).]
)

Die Optimierung erfolgt üblicherweise iterativ. Für Gradientenabstieg gilt in kompakter Form:

$
theta^(t+1) = theta^(t) - eta nabla_theta cal(L) (theta^(t))
$


LLMs unterscheiden sich von klassischen neuronalen Netzen nicht nur durch ihre Modellgröße, sondern vor allem durch ihre Zielsetzung: Sie sind Sprachmodelle -- Systeme, die Wahrscheinlichkeiten über Tokenfolgen schätzen und dadurch Texte fortsetzen, bewerten oder erzeugen können. Der Verarbeitungsablauf folgt dabei einem wiederkehrenden Muster.
Zunächst wird die Texteingabe in Token zerlegt. Token sind die kleinsten Verarbeitungseinheiten des Modells. je nach Tokenisierungsverfahren können dies Wörter, Wortteile oder einzelne Zeichen sein. Der Satz „Das System prüft den Status" wird beispielsweise in die Folge [„Das", „System", „prüft", „den", „Status"] überführt. Für Quellcode gilt dasselbe Prinzip: Identifier, Schlüsselwörter und Operatoren werden in Einheiten aufgeteilt @goodfellow2016dl.

Die resultierende Tokenfolge bildet den Kontext des Modells. Der Kontext umfasst alle Token, die das Modell in einem Verarbeitungsschritt gleichzeitig berücksichtigt. Aktuelle Modelle besitzen Kontextfenster von mehreren tausend bis über eine Million Token. Eingaben, die dieses Fenster überschreiten, müssen segmentiert oder komprimiert werden.

Auf Basis des Kontexts berechnet das Modell eine Wahrscheinlichkeitsverteilung über alle möglichen nächsten Token. Das gewählte Token wird an die bisherige Folge angefügt, und die erweiterte Folge dient als Eingabe für den nächsten Berechnungsschritt. Dieser Prozess wiederholt sich, bis ein Abbruchkriterium erreicht ist (z. B. ein Stopptoken oder eine maximale Ausgabelänge). Da das Modell jedes Token statistisch aus dem bisherigen Kontext ableitet, können Ausgaben sprachlich konsistent wirken, ohne dass fachliche Korrektheit gewährleistet ist. Formal lässt sich das Trainingsziel als Maximierung der bedingten Log-Likelihood beschreiben:

$
max_(theta) sum_(t=1)^T log p_(theta) (x_t mid x_(<t))
$

Hierbei bezeichnet $x_(<t)$ die bisherige Tokenfolge und $p_(theta)(x_t mid x_(<t))$ die vom Modell geschätzte Wahrscheinlichkeit für das nächste Token $x_t$.

In der aktuellen Modellgeneration dominiert die Transformer-Architektur @vaswani2017attention, deren Kernmechanismus die Self-Attention ist. Self-Attention ermöglicht es dem Modell, bei der Verarbeitung jedes Tokens die Beziehungen zu allen anderen Token im Kontext zu gewichten. Formal wird dies als gewichtete Kombination von Value-Vektoren beschrieben, wobei die Gewichte aus Query-Key-Ähnlichkeiten berechnet werden #cite(<vaswani2017attention>):

$
op("Attention") (Q, K, V) = op("softmax") ((Q K^T) / sqrt(d_k)) V
$
/*
#figure(
  image("../../Abbildungen/abb_2_3_attention_heatmap.png", width: 85%),
  caption: [Schematisches Beispiel einer Attention-Gewichtsmatrix (illustrativ).]
)
*/

LLMs werden daher im Software Engineering eingesetzt, weil sie sowohl Artefakte in Prosa (z. B. Anforderungen, Kommentare) als auch Codeartefakte (z. B. Klassen, Funktionen, DB Schemata) verarbeiten können. Verscheidene Arbeiten  versuchen daher LLM-Anwendungen nach Aufgabenklassen wie Codegenerierung, Codezusammenfassung, Fehlersuche, Testgenerierung oder Dokumentation zu ordnen @fan2023llmse @salem2024surveyllmse @llm4se2024slr @llm4se2024survey

_Aus den folgenden Eigenschaften der LLMs ergeben sich daher für diese Arbeit Konsequenzen:_

_- *Kontextfenster:* Modelle verarbeiten Eingaben nur bis zu einer maximalen Tokenanzahl. Längere Artefakte müssen segmentiert oder komprimiert werden._\
_- *Tokenisierung:* Quellcode und Fachsprache werden in Token zerlegt. Dies beeinflusst, wie gut Identifier, Struktur und Domänenterminologie repräsentiert werden._\
_- *Generativer Charakter:* Ausgaben sind nicht deterministisch. Temperatur, Sampling-Strategien und Promptform beeinflussen Reproduzierbarkeit._



#heading(level: 3)[LLM Training und Prompting]

LLMs werden typischerweise in mehreren Phasen entwickelt. In einer Vortrainingsphase lernen Modelle aus großen Text- und Codekorpora statistische Regularitäten. Für den Einsatz als Assistenzsysteme werden Modelle häufig zusätzlich auf Anweisungen und Dialogformate ausgerichtet („instruction tuning"). Der GPT-4 Technical Report beschreibt diese Ausrichtung auf Systemebene und diskutiert Safety- und Evaluationsaspekte, ohne die vollständige Trainingspipeline offen zu legen @openai2023gpt4.

Im Engineering-Kontext ist der Prompt damit nicht nur Eingabe, sondern auch ein Steuerungsinstrument.\ Für diese Arbeit sind vor allem folgende Hebel relevant:

- *Aufgabe:* Ziel, gewünschtes Artefaktformat, Definition von Begriffen und Abgrenzung (z. B. „Requirement" vs. „Designentscheidung").
- *Kontextwahl:* Welche Code- und Textartefakte werden bereitgestellt, und welche Teile werden bewusst ausgeblendet, um Überinterpretation zu begrenzen?
- *KI Leitplanken:* Belegpflicht, Kennzeichnung unsicherer Aussagen, feste Templates, DOs and DONTs.

Da LLMs ein begrenztes Kontextfenster besitzen, wird in Forschung und Praxis häufig Retrieval-Augmented Generation (RAG) eingesetzt: Relevante Textstellen werden zunächst über Suche/Retrieval ausgewählt und anschließend als Kontext in die Generierung eingebracht. #cite(<lewis2020rag>, form: "prose") beschreiben dieses Grundprinzip für wissensintensive Aufgaben. Für Requirements-Extraktion aus Legacy-Code ist RAG naheliegend, weil relevante Regeln, Konfigurationen und UI-Strings über große Repositories verteilt sind und eine „Alles in den Prompt"-Strategie nicht skaliert.

Prompting-Strategien wie Chain-of-Thought können die Qualität komplexer Ableitungen verbessern, bergen im Requirements-Kontext jedoch ein Risiko: Längere Begründungen können plausibel wirken und dadurch Fehlannahmen stabilisieren. #cite(<wei2022cot>, form: "prose") zeigen Chain-of-Thought als wirksame Prompttechnik.\ \ _Für diese Arbeit folgt daraus vor allem, dass Begründungen stets mit Artefaktbelegen gekoppelt werden müssen und nicht als eigenständige Evidenz gelten._
/*
#heading(level: 3)[LLMs für Code: Spezialisierung, Stärken und Grenzen]

Neben allgemeinen Modellen existieren code-spezialisierte LLMs, die auf Codekorpora vortrainiert oder nachtrainiert wurden. Ein prominentes Beispiel ist Code Llama, dessen Technical Report Training und Evaluationsaufbau beschreibt und die Ausrichtung auf Codeaufgaben explizit macht @roziere2023codellama. Aus praktischer Sicht sind bei code-spezifischen Modellen typischerweise drei Stärken zu beobachten:

- **Syntaxnahe Mustererkennung:** Wiederkehrende Idiome, Framework-Patterns und typische Kontrollstrukturen werden zuverlässig erkannt.
- **Semantische Zusammenfassung:** Funktionen und Module lassen sich in natürliche Sprache übertragen, inklusive grober Zweckbeschreibung.
- **Transformation und Vorschläge:** Refactorings, Testideen oder API-Skizzen können generiert und iterativ verfeinert werden.

Den Stärken stehen systematische Grenzen gegenüber. LLMs „verstehen" Code nicht im Sinne einer formalen Semantik. Sie approximieren Bedeutung über Muster aus Trainingsdaten und aus dem gegebenen Kontext. Insbesondere in Legacy-Systemen mit proprietären Frameworks, kundenspezifischen Erweiterungen und historisch gewachsenen Konventionen ist die Wahrscheinlichkeit hoch, dass Modelle plausible, aber falsche Erklärungen liefern. Genau diese Plausibilität ist im Requirements-Kontext kritisch, weil Text als Spezifikation eine höhere Autorität erhält als eine rein technische Zusammenfassung.
*/
#heading(level: 3)[Qualitätsrisko Halluzinationen]

Halluzinationen bezeichnen Ausgaben, die syntaktisch korrekt und plausibel wirken, aber nicht durch Eingabedaten oder Weltwissen gedeckt sind. #cite(<ji2023hallucination>, form: "prose") liefern die Begrifflichkeit und diskutieren Detektions- und Lösungsansätze. Für Requirements ist die Gefahr besonders kritisch, weil falsche Requirements nicht als „Bug" auffallen, sondern als scheinbar saubere Spezifikation in Architektur- und Funktionsentscheidungen einfließen können.

Zusätzlich zu Halluzinationen sind zwei weitere Verlässlichkeitsthemen relevant:

- *Daten- und Domänenbias:* Modelle spiegeln Verteilungen und Annahmen aus Trainingsdaten wider @bender2021stochastic. Taucht eine falsche Aussage in Trainingsdaten häufig auf, wird sie vom Modell übernommen und als Wahrheit ausgegeben.
- *Reproduzierbarkeit:* Kleine Promptänderungen oder Parameterunterschiede können zu unterschiedlichen Ergebnissen führen. Für einen engineeringfähigen Prozess sind daher Leitplanken (z. B. feste Templates, deterministische Einstellungen, versionierte Prompts) notwendig.

_Für diese Arbeit folgt daraus, dass LLM-Ausgaben im Requirements-Kontext nicht als Wahrheit", sondern als Vorschlag zu behandeln sind. Erst durch Traceability (Belege) und Validierung (Expertenreview, Laufzeitchecks) wird aus einer Hypothese eine belastbare Anforderung._

#heading(level: 3)[LLMs im Requirements Engineering: Stand der Forschung]

Aktuelle Arbeiten untersuchen, wie LLMs artefaktnahe Texte erzeugen, umformulieren und strukturieren können, und verschieben den Schwerpunkt damit gegenüber klassischen NLP/IR-Ansätzen mit begrenzten Ausgaben (Labels, Links, Hinweise). Dieser Übergang ist aber Problembehaftet: Einerseits entsteht ein enormes Produktivitätspotential,andererseits steigt das Risiko, dass sprachlich "gute" Texte als Spezifikation akzeptiert werden, obwohl die fachliche Basis unzureichend oder fehlerhaft ist (siehe Haluzinationen) @ji2023hallucination @hemmat2025directions.

Eine systematische Übersicht ordnet die LLM-Nutzung im RE dabei entlang klassischer Prozessschritte ein und nennt als wiederkehrende Problemfelder _Qualitätssicherung, Nachvollziehbarkeit und Domänenabhängigkeit_ @hemmat2025directions. Ein weiteres Review zum ChatGPT-Einsatz im Requirements Engineering diskutiert den Einsatz entlang typischer RE-Aktivitäten (Analyse, Spezifikation, Validierung) und hebt als zentrale Herausforderungen inkonsistente Ergebnisse und begrenztes Domänenwissen hervor @marques2024chatgptre.

Dabei lassen sich aktuelle LLM-Arbeiten grob nach Anwendungsfeldern bündeln:

- *Strukturierung und (Re-)Formulierung von Requirements:* Untersucht wird, wie LLMs naturalsprachliche Anforderungen in strukturiertere Formen überführen können @norheim2024structuring, sowie die automatische Umstrukturierung von Software Requirements Specifications mit dem Ziel, Standardkonformität zu erhöhen @okamoto2025restructuring.
- *Qualitätsunterstützung und Defektanalyse:* ChatGPT wurde für die Inkonsistenzdetektion in naturalsprachlichen Requirements evaluiert @fantechi2023inconsistency; weitere Arbeiten untersuchen LLM-gestützte Assistenz zur Verbesserung der Requirements-Vollständigkeit @luitel2024completeness.
- *Elicitation und Stakeholder-Perspektiven:* LLMs können zur Generierung wertorientierter User Stories als "Inspirationsimpulse" eingesetzt werden @marczak2023humanvalue. Diese Richtung ist für Reverse Requirements Engineering indirekt relevant, weil sie zeigt, wie LLMs fehlende Stakeholder-Sichten ergänzen können, ohne den Code als Primärbeleg zu ersetzen.
- *Domänenspezifische Requirements (Safety/Compliance):* Betrachtet werden LLMs bei der Engineering-Unterstützung von Safety Requirements im Kontext autonomen Fahrens @nouri2024safety sowie für rechtliche Compliance- und Regulationsanalyse @hassani2024legal. Solche Arbeiten verdeutlichen, dass LLMs nicht nur Text umformulieren, sondern auch Wissensstrukturen (Normen, Regeln) operationalisieren sollen; zugleich erhöhen sich die Anforderungen an Belegbarkeit und Haftung.

Über die einzelnen Studien hinaus ist der Evidenzstand derzeit heterogen. Viele Arbeiten sind als Workshopbeiträge oder "preliminary evaluations" angelegt, nutzen begrenzte Datensätze und kombinieren automatische Metriken mit Expertenurteilen. Zudem sind Prompting-Strategien, Modellversionen und Kontexteinstellungen häufig nicht vollständig standardisiert, was die Reproduzierbarkeit erschwert @fan2023llmse @hemmat2025directions. Aus Sicht dieser Arbeit folgt daraus eine klare Konsequenz: LLMs sind im Requirements Engineering am stärksten als Assistenzsysteme in einem kontrollierten Prozess, in dem (1) Aussagen mit Belegen verknüpft werden, (2) Unsicherheit explizit markiert wird und (3) fachliche Validierung als definierter Kontrollpunkt erfolgt.

Für Reverse Requirements Engineering lässt sich der Nutzen damit präzisieren: LLMs können Kandidaten-Requirements aus großen Artefaktmengen (Code, Kommentare, UI-Strings, Konfiguration) verdichten und in eine konsistente Spezifikationsform überführen. Die fachliche Belastbarkeit entsteht jedoch erst durch Traceability zu Codebelegen und die Validierung durch Experten, insbesondere bei Safety-, Compliance- und Abrechnungslogik.

#heading(level: 3)[Absicherung: Human-in-the-loop, Belege und Prozesskontrollen]

Die Literatur legt nahe, dass LLMs im Software Engineering dann robust eingesetzt werden können, wenn sie in einen Prozess eingebettet sind, der Fehler systematisch begrenzt @fan2023llmse @hemmat2025directions. Für die Requirements-Extraktion aus Legacy-Code sind folgende Kontrollen praxisnah:

- *Belegpflicht (Evidence-First):* Jedes generierte Requirement erhält mindestens einen konkreten Beleg (Datei/Komponente/Query/GUI-String) sowie eine kurze Begründung, warum der Beleg die Aussage trägt.
- *Trennung von Fakt und Interpretation:* Technische Fakten (z. B. „Status = 'Closed' verhindert Update") werden getrennt von fachlicher Interpretation (z. B. „Abgeschlossene Aufträge sind schreibgeschützt") dokumentiert.
- *Mehrstufige Validierung:* Automatische Checks (z. B. Linting auf Verbformen, Konsistenzregeln) werden mit Expertenreview kombiniert.
- *Reproduzierbarkeit:* Versionierung von Promptvorlagen, Modellversionen und Kontextzuschnitten, um Ergebnisse vergleichbar zu machen.

Diese Kontrollen adressieren nicht alle Risiken, reduzieren aber die typischen Fehlerklassen (Halluzination, Überinterpretation, fehlende Konsistenz) und schaffen die Grundlage für eine belastbare Evaluation in Kapitel 6.

#heading(level: 3)[Qualitätsbewertung und Messgrößen im Requirements-Kontext]

Die Qualität von LLM-Ergebnissen wird in vielen Arbeiten über allgemeine Textmetriken oder Task-spezifische Benchmarks bewertet. Für Requirements-Extraktion aus Code sind solche Metriken nur begrenzt aussagekräftig, weil der zentrale Anspruch nicht „sprachliche Ähnlichkeit", sondern fachliche Korrektheit, Prüfbarkeit und Nachvollziehbarkeit ist @hemmat2025directions @marques2024chatgptre. Eine zweckmäßige Qualitätsbewertung sollte daher an RE-Kriterien anschließen und explizit zwischen drei Ebenen unterscheiden:

- *Statement-Qualität:* Ist ein Requirement eindeutig, vollständig im Satzbau, frei von nicht belegten Annahmen und mit Akzeptanzkriterium bzw. Prüfidee versehen?
- *Set-Qualität:* Ist die Menge der Requirements konsistent, nicht redundant und deckt die relevanten Prozesse und Varianten ab, ohne sich in Detailfällen zu verlieren?
- *Traceability-Qualität:* Sind Belege reproduzierbar auffindbar (z. B. Dateipfad, Methode, SQL-Query), und lässt sich die Ableitung von „Beleg → Requirement" nachvollziehen?

Für Legacy-Migrationen ist zudem die Fehlerkostenperspektive entscheidend. Ein fehlendes Requirement kann zu Funktionsverlust führen, ein falsches Requirement kann zu fehlerhaften Designentscheidungen führen, und ein unpräzises Requirement verursacht Review- und Nacharbeit. Daraus folgt eine pragmatische Bewertung: Requirements mit hoher Migrationskritikalität (z. B. Sicherheitsregeln, Abrechnungslogik, Berechtigungen) sollten strengere Evidenzanforderungen und intensivere Reviews erhalten als periphere Funktionen. Dieses Prinzip ist kompatibel mit der risikobasierten Priorisierung von Qualitätsanforderungen @glinz2008quality und lässt sich auf Funktionsanforderungen übertragen.
/*
#heading(level: 3)[Zwischenfazit zu 2.2]

LLMs liefern im Software Engineering eine leistungsfähige Assistenz für Analyse, Zusammenfassung und Textproduktion, sind jedoch nicht verlässlich im Sinne formaler Korrektheit @fan2023llmse @ji2023hallucination. Für Requirements ist der entscheidende Punkt, dass die Qualität nicht an der sprachlichen Glätte, sondern an Nachvollziehbarkeit und Prüfbarkeit hängt. Daraus folgt für diese Arbeit ein designierter "Sicherheitsgurt": Evidence-First, Traceability und Human-in-the-loop sind keine Zusatzoptionen, sondern Kernelemente des Vorgehens.
*/