Let Anthropic API decide chunk relevance instead of local prefilter
Updated both structure_batch and reformulate_batch prompts to return null for chunks without actionable requirements (definitions, TOCs, scope-only). Explicit instruction to always process annexes/appendices as they often contain concrete technical requirements. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1102,12 +1102,15 @@ Gib JSON zurück mit diesen Feldern:
|
|||||||
Du DARFST den Originaltext verwenden (Quellen sind jeweils angegeben).
|
Du DARFST den Originaltext verwenden (Quellen sind jeweils angegeben).
|
||||||
{doc_context}
|
{doc_context}
|
||||||
WICHTIG:
|
WICHTIG:
|
||||||
- Erstelle fuer JEDEN Chunk ein separates Control mit verstaendlicher, praxisorientierter Formulierung.
|
- Pruefe JEDEN Chunk: Enthaelt er eine konkrete Pflicht, Anforderung oder Massnahme?
|
||||||
|
- Wenn JA: Erstelle ein vollstaendiges, eigenstaendiges Control mit praxisorientierter Formulierung.
|
||||||
|
- Wenn NEIN (reines Inhaltsverzeichnis, Begriffsbestimmung ohne Pflicht, Geltungsbereich ohne Anforderung, reine Verweiskette): Gib null fuer diesen Chunk zurueck.
|
||||||
|
- BEACHTE: Anhaenge/Annexe enthalten oft KONKRETE technische Anforderungen — diese MUESSEN als Control erfasst werden!
|
||||||
- Jedes Control muss eigenstaendig und vollstaendig sein — nicht auf andere Controls verweisen.
|
- Jedes Control muss eigenstaendig und vollstaendig sein — nicht auf andere Controls verweisen.
|
||||||
- Qualitaet ist wichtiger als Geschwindigkeit. Jedes Control muss die gleiche Qualitaet haben wie ein einzeln erstelltes.
|
- Qualitaet ist wichtiger als Geschwindigkeit.
|
||||||
- Antworte IMMER auf Deutsch.
|
- Antworte IMMER auf Deutsch.
|
||||||
|
|
||||||
Gib ein JSON-Array zurueck mit GENAU {len(chunks)} Objekten. Jedes Objekt hat diese Felder:
|
Gib ein JSON-Array zurueck mit GENAU {len(chunks)} Elementen. Fuer Chunks ohne Anforderung gib null zurueck. Fuer Chunks mit Anforderung ein Objekt mit diesen Feldern:
|
||||||
- chunk_index: 1-basierter Index des Chunks (1, 2, 3, ...)
|
- chunk_index: 1-basierter Index des Chunks (1, 2, 3, ...)
|
||||||
- title: Kurzer praegnanter Titel auf Deutsch (max 100 Zeichen)
|
- title: Kurzer praegnanter Titel auf Deutsch (max 100 Zeichen)
|
||||||
- objective: Was soll erreicht werden? (1-3 Saetze, Deutsch)
|
- objective: Was soll erreicht werden? (1-3 Saetze, Deutsch)
|
||||||
@@ -1131,7 +1134,12 @@ Gib ein JSON-Array zurueck mit GENAU {len(chunks)} Objekten. Jedes Objekt hat di
|
|||||||
|
|
||||||
# Map results back to chunks by chunk_index (or by position if no index)
|
# Map results back to chunks by chunk_index (or by position if no index)
|
||||||
controls: list[Optional[GeneratedControl]] = [None] * len(chunks)
|
controls: list[Optional[GeneratedControl]] = [None] * len(chunks)
|
||||||
|
skipped_by_api = 0
|
||||||
for pos, data in enumerate(results):
|
for pos, data in enumerate(results):
|
||||||
|
# API returns null for chunks without actionable requirements
|
||||||
|
if data is None:
|
||||||
|
skipped_by_api += 1
|
||||||
|
continue
|
||||||
# Try chunk_index first, fall back to position
|
# Try chunk_index first, fall back to position
|
||||||
idx = data.get("chunk_index")
|
idx = data.get("chunk_index")
|
||||||
if idx is not None:
|
if idx is not None:
|
||||||
@@ -1195,15 +1203,19 @@ Gib ein JSON-Array zurueck mit GENAU {len(chunks)} Objekten. Jedes Objekt hat di
|
|||||||
f"Text (nur zur Analyse, NICHT kopieren, NICHT referenzieren):\n{chunk.text[:1500]}"
|
f"Text (nur zur Analyse, NICHT kopieren, NICHT referenzieren):\n{chunk.text[:1500]}"
|
||||||
)
|
)
|
||||||
joined = "\n\n".join(chunk_entries)
|
joined = "\n\n".join(chunk_entries)
|
||||||
prompt = f"""Analysiere die folgenden {len(chunks)} Pruefaspekte und formuliere fuer JEDEN ein EIGENSTAENDIGES Security Control.
|
prompt = f"""Analysiere die folgenden {len(chunks)} Pruefaspekte und formuliere fuer JEDEN mit konkreter Anforderung ein EIGENSTAENDIGES Security Control.
|
||||||
KOPIERE KEINE Saetze. Verwende eigene Begriffe und Struktur.
|
KOPIERE KEINE Saetze. Verwende eigene Begriffe und Struktur.
|
||||||
NENNE NICHT die Quellen. Keine proprietaeren Bezeichner (kein O.Auth_*, TR-03161, BSI-TR etc.).
|
NENNE NICHT die Quellen. Keine proprietaeren Bezeichner (kein O.Auth_*, TR-03161, BSI-TR etc.).
|
||||||
|
|
||||||
WICHTIG:
|
WICHTIG:
|
||||||
|
- Pruefe JEDEN Aspekt: Enthaelt er eine konkrete Pflicht, Anforderung oder Massnahme?
|
||||||
|
- Wenn JA: Erstelle ein vollstaendiges, eigenstaendiges Control.
|
||||||
|
- Wenn NEIN (reines Inhaltsverzeichnis, Begriffsbestimmung ohne Pflicht, Geltungsbereich ohne Anforderung): Gib null fuer diesen Aspekt zurueck.
|
||||||
|
- BEACHTE: Anhaenge/Annexe enthalten oft KONKRETE technische Anforderungen — diese MUESSEN erfasst werden!
|
||||||
- Jedes Control muss eigenstaendig und vollstaendig sein — nicht auf andere Controls verweisen.
|
- Jedes Control muss eigenstaendig und vollstaendig sein — nicht auf andere Controls verweisen.
|
||||||
- Qualitaet ist wichtiger als Geschwindigkeit. Jedes Control muss die gleiche Qualitaet haben wie ein einzeln erstelltes.
|
- Qualitaet ist wichtiger als Geschwindigkeit.
|
||||||
|
|
||||||
Gib ein JSON-Array zurueck mit GENAU {len(chunks)} Objekten. Jedes Objekt hat diese Felder:
|
Gib ein JSON-Array zurueck mit GENAU {len(chunks)} Elementen. Fuer Aspekte ohne Anforderung gib null zurueck. Fuer Aspekte mit Anforderung ein Objekt mit diesen Feldern:
|
||||||
- chunk_index: 1-basierter Index des Aspekts (1, 2, 3, ...)
|
- chunk_index: 1-basierter Index des Aspekts (1, 2, 3, ...)
|
||||||
- title: Kurzer eigenstaendiger Titel (max 100 Zeichen)
|
- title: Kurzer eigenstaendiger Titel (max 100 Zeichen)
|
||||||
- objective: Eigenstaendige Formulierung des Ziels (1-3 Saetze)
|
- objective: Eigenstaendige Formulierung des Ziels (1-3 Saetze)
|
||||||
@@ -1225,6 +1237,8 @@ Gib ein JSON-Array zurueck mit GENAU {len(chunks)} Objekten. Jedes Objekt hat di
|
|||||||
|
|
||||||
controls: list[Optional[GeneratedControl]] = [None] * len(chunks)
|
controls: list[Optional[GeneratedControl]] = [None] * len(chunks)
|
||||||
for pos, data in enumerate(results):
|
for pos, data in enumerate(results):
|
||||||
|
if data is None:
|
||||||
|
continue
|
||||||
idx = data.get("chunk_index")
|
idx = data.get("chunk_index")
|
||||||
if idx is not None:
|
if idx is not None:
|
||||||
idx = int(idx) - 1
|
idx = int(idx) - 1
|
||||||
|
|||||||
Reference in New Issue
Block a user