This commit is contained in:
team3
2026-07-04 12:21:45 +02:00
parent 2f5d5b9ca1
commit 8d8f6c8e51
43 changed files with 1920 additions and 236 deletions

View File

@@ -75,6 +75,9 @@ SEED_COVER_COS = 0.80
# (Markdown: 50 pairs in the band, 4 above) — below every auto-merge threshold, so an LLM
# judge decides. Candidates only; a merge still needs judge unanimity.
SUB_DUP_KANDIDAT_COS = 0.75
# Cross-block judge pairs per call: ONE call over all pairs scaled its timeout to 54 min
# and a hung call blocked the barrier that long (aak: 196 pairs) — chunks cap it at ~15 min.
CROSS_CHUNK_PAARE = 40
# Umbrella grouping (block granularity level 2, step "Blocks-Gruppierung", AFTER the filter):
# collapse sibling DEFINITIONS that are components of ONE umbrella concept (TM model:
@@ -144,12 +147,56 @@ QUELLE_RELEVANZ_SNIPPET = 800 # body characters per page in the prompt (URL i
QA_GATE_NOTE = 9.5 # 0 = gate off; quota-based, so the tolerated finding count scales with topic size
QA_GATE_LLM = True # include the LLM samples (Echtheit/Dubletten) in the gate run
# Guide section length per relevant sub (ausführlich part) — QA detector AND the
# deterministic readability-stage trigger share these bounds (writers overshot 2.74.1×).
GUIDE_LAENGE_MIN = 150
GUIDE_LAENGE_MAX = 1200
# Inline evidence for judge agents: corpus excerpts go INTO the prompt instead of letting
# every judge re-search the source folder (measured: ~10 tool turns/judge, 82 % of the
# run's tokens were cache reads from those loops).
EVIDENCE_BUDGET_CHARS = 48_000 # max excerpt characters per judge prompt
EVIDENCE_CTX_LINES = 15 # context lines around a cited source position (facts check)
# ── Pipeline tuning (zentral, tunebar via CREATOR_PARAMS — siehe Override-Hook am Datei-Ende;
# Registry mit Suchraum: backend/train_params.py). QA-/Detektor-Konstanten bleiben bewusst in
# qa.py/guide_qa.py — die Messlatte darf nie Teil des Suchraums sein. ─────────────────────────
SUBBLOCK_CHUNK = 10 # subblock finder: 1 agent per ~10 blocks, capped
SUBBLOCK_MAX = 40 # chunk cap
LEVEL_CHUNK = 100 # classifying is cheap → large packages
RESEARCH_BATCH = 20 # crawl pages per batch
RESEARCH_READERS = 2 # reader agents per batch/section (consensus ≥2)
RESEARCH_THEMA_AGENTS = 5 # web mode (source "thema")
RESEARCH_SECTION_CHARS = 12000 # uni/projekt section size (lost-in-the-middle guard)
RESEARCH_RUNTIME = 900 # one research agent, one round (tail ingests live)
SUBBLOCK_CAP = 900 # subblock find loop per chunk (seconds)
SUBBLOCK_MIN = 5 # below this consensus count → focused catch-up rounds
SUBBLOCK_EXTRA_ROUNDS = 2 # max catch-up rounds
SUBBLOCK_MAX_ROUNDS = 3 # hard round cap (rounds 45 burned 29 % of finders for ~0 gain)
CONSOLIDATION_CHUNK = 600 # up to here ONE global judge (fallback path)
DEDUP_PAIR_FLOOR = 0.6 # min cosine for a candidate pair
DEDUP_PAIRS_CHUNK = 40 # pairs per judge package
DEDUP_TITLE_AUTO = 0.95 # near-identical TITLE cosine → merge without judge
DEDUP_GLOBAL_FLOOR = 0.65 # global post-naming dedup candidate floor
FILTER_CHUNK = 35 # blocks per judge in the degrade pass
QUESTION_CHUNK_SUBS = 25 # target relevant subs per question chunk (LPT)
QUESTION_MAX_ROUNDS = 3 # catch-up rounds for subs without a pattern
FACTS_CHUNK_SUBS = 10 # facts extraction chunk (chunk count = parallelism)
ARTEFACT_CHUNK_SUBS = 25 # flashcards/examples bulk chunk
FACTS_CHECK_PANEL = 3 # judges per facts-check chunk (majority)
CONSOLIDATION_PANEL = 3 # mapping judges per chunk
SUBBLOCK_PANEL = 3 # judges in the subblock clarification
FILTER_RECHECK_PANEL = 3 # judges in the survivor-recheck
MAX_WRITER_ROUNDS = 2 # guide coverage→writer loop cap
GATE_FIX_MIN = 3 # fact-gate: unbelegt-claims below this → log only (falsch fixt immer)
WRITER_SPLIT_SUBS = 30 # guide writer splits sections above this sub count
KANBAN_BATCH = 5 # cards a worker pulls per micro-batch
MAX_CARD_RETRIES = 3 # failures per card → dead-letter
RETRY_BACKOFF = 30.0 # base seconds; backoff = base · 2^(retries-1)
MAX_RESTARTS = 2 # agent restart cap per race slot
JUDGE_CHUNK = 40 # repair: findings per judge call
EVIDENCE_PER_BLOCK = 6000 # repair: excerpt chars per fremd candidate
# Timeouts per agent step: (base seconds, seconds per block/section).
# Applies equally to all providers — whoever is too slow gets restarted or overtaken.
TIMEOUTS = {
@@ -160,17 +207,18 @@ TIMEOUTS = {
"plan": (300, 5),
"plan_judge": (600, 5), # judge reads up to 5 outlines, n = sections
"content": (450, 30), # facts find/erg/fix — p95 measured 241 s (was 600+90n)
"content_check": (300, 10), # content exam per block in the package
# Judge caps tightened 2026-07-04: judge p50 is 672 s; a stalled call burns the whole
# cap and its retry heals in seconds — the old 300 s base tripled the stall cost.
"content_check": (150, 8), # content exam per block in the package
"subblock": (400, 15), # finder round — p95 measured 124 s (was 900+45n)
"subblock_check": (300, 15), # judge decides contested subblocks in the chunk
"konsolidierung": (600, 25), # consolidation judge sees ALL subs with key points — 585 s
# (subblock_check at n=19) produced 15 % timeouts
"subblock_check": (150, 10), # judge decides contested subblocks in the chunk
"konsolidierung": (300, 20), # consolidation judge sees ALL subs with key points
"level": (300, 10), # classify subblocks per chunk
"level_check": (300, 10), # judge decides contested levels in the chunk
"level_check": (150, 8), # judge decides contested levels in the chunk
"relevance": (300, 10), # subblocks relevant/peripheral per chunk
"relevance_check": (300, 10), # judge decides contested relevance in the chunk
"relevance_check": (150, 8), # judge decides contested relevance in the chunk
"question_pattern": (300, 15), # question patterns per block (subblocks × types)
"question_pattern_check": (300, 10), # critic cleans up the pattern table per block
"question_pattern_check": (150, 8), # critic cleans up the pattern table per block
"writer": (450, 60), # per section — split keeps sections ≤30 subs
"lese_check": (300, 10), # per section in the package
# guide board (per card = one block)
@@ -209,7 +257,8 @@ PROVIDERS = {
"cli": "opencode",
"guide": "minimax/MiniMax-M3",
"fast": "minimax-kalt/MiniMax-M2.7-highspeed",
"judge": "minimax-kalt/MiniMax-M3",
"judge": "minimax/MiniMax-M3", # native route — the kalt endpoint stalled 20 % of
# judge calls to the timeout cap (516/2590, 2026-07-04)
"quick": "minimax/MiniMax-M2.7-highspeed",
"env_key": "MINIMAX_API_KEY",
},
@@ -246,3 +295,33 @@ def resolve_role(run_provider: str, role: str) -> tuple[str, str]:
if not model:
model = PROVIDERS.get(provider, {}).get(role, "")
return provider, model
# ── Trainings-Override: CREATOR_PARAMS (JSON-Dict im ENV) überschreibt gleichnamige
# Tuning-Konstanten oben — pro Prozess-Start (der Trainer startet je Trial einen Subprozess;
# Module binden die Werte beim Import). TIMEOUTS-Einträge via "TIMEOUT_<step>_base"/"_per".
def _apply_param_overrides() -> None:
raw = os.getenv("CREATOR_PARAMS")
if not raw:
return
import json as _json
try:
overrides = _json.loads(raw)
except ValueError:
raise SystemExit(f"CREATOR_PARAMS ist kein gültiges JSON: {raw[:80]}")
g = globals()
for key, val in overrides.items():
if key.startswith("TIMEOUT_"):
rest = key[len("TIMEOUT_"):]
step, _, part = rest.rpartition("_")
if step in TIMEOUTS and part in ("base", "per"):
base, per = TIMEOUTS[step]
TIMEOUTS[step] = (val, per) if part == "base" else (base, val)
continue
raise SystemExit(f"CREATOR_PARAMS: unbekannter Timeout-Schlüssel {key}")
if key not in g or not isinstance(g[key], (int, float)) or isinstance(g[key], bool):
raise SystemExit(f"CREATOR_PARAMS: unbekannter/nicht-numerischer Parameter {key}")
g[key] = type(g[key])(val)
_apply_param_overrides()