This commit is contained in:
team3
2026-06-29 01:46:34 +02:00
parent bf7ebe045b
commit 753b95b689
2 changed files with 34 additions and 1 deletions

View File

@@ -23,7 +23,7 @@ from pathlib import Path
import database as db
import embedding
from agents import kill_process, cancel_scope, clear_scope, run_agent
from config import KONSENS_GRACE, RECHERCHE_GRACE, KONSENS_MAX_RUNDEN, DEFAULT_PROVIDER, CRAWL_KEEP_PATTERNS, CRAWL_NOISE_PATTERNS, CRAWL_MIN_CHARS, QUELLE_RELEVANZ_CHUNK, QUELLE_RELEVANZ_SNIPPET, EMBEDDING_AKTIV
from config import KONSENS_GRACE, RECHERCHE_GRACE, KONSENS_MAX_RUNDEN, DEFAULT_PROVIDER, CRAWL_KEEP_PATTERNS, CRAWL_NOISE_PATTERNS, CRAWL_MIN_CHARS, QUELLE_RELEVANZ_CHUNK, QUELLE_RELEVANZ_SNIPPET, EMBEDDING_AKTIV, EMBEDDING_SUB_DUP
from fsutil import atomic_write_text, atomic_write_json
from jsonio import read_json_file as _json_datei
from paths import arbeit_dir, bausteine_path, frage_muster_path, project_dir, subbausteine_path, quelle_path, quelle_crawl_dir, safe_ordner
@@ -845,12 +845,41 @@ async def _subbausteine_block(ctx: GenContext, set_p, files: dict, entries: dict
if sn and sn not in have:
await db.upsert_subbaustein(topic, norm_by_num[num], sn, titel, s)
await db.set_subbaustein_felder(topic, norm_by_num[num], sn, status="konsens")
await _dedup_subbausteine(topic, roh) # Near-Dup-Filter je Baustein (deterministisch, kein LLM)
if not roh:
_bausteine_errors[topic] = "Keine Subbausteine ermittelt"
return None
return roh
async def _dedup_subbausteine(topic: str, roh: dict[str, list[str]]) -> None:
"""Deterministischer Near-Duplicate-Filter pro Baustein: Subbausteine mit Cosine ≥
EMBEDDING_SUB_DUP sind dieselbe Aussage (im engen Baustein-Kontext zuverlässig — kein LLM
nötig). Behält je Dublett-Gruppe den informativsten (längsten); Rest → DB verworfen + aus `roh`.
Modell fehlt → still überspringen (wie der übrige Embedding-Fallback)."""
if not EMBEDDING_AKTIV or not await asyncio.to_thread(embedding.verfuegbar):
return
for titel, subs in list(roh.items()):
if len(subs) < 2:
continue
sims = await asyncio.to_thread(embedding.embed_sims, subs)
if sims is None:
return
behalten: list[int] = []
verworfen: list[int] = []
for i in sorted(range(len(subs)), key=lambda x: (-len(subs[x]), x)): # informativster zuerst
if any(float(sims[i][j]) >= EMBEDDING_SUB_DUP for j in behalten):
verworfen.append(i)
else:
behalten.append(i)
if not verworfen:
continue
bnorm = _norm_titel(titel)
for i in verworfen:
await db.set_subbaustein_felder(topic, bnorm, _norm_titel(subs[i]), status="verworfen")
roh[titel] = [subs[i] for i in sorted(behalten)] # Original-Reihenfolge der Behaltenen
async def _stufen_block(ctx: GenContext, set_p, files: dict, roh: dict, instructions: str) -> dict | None:
"""Block C: drei Phasen mit Barriere — Finden (einstufen), Wählen (Vote), Klären.
Lokale IDs 1..n pro Paket, hinterher auf globale gid gemappt.