update
This commit is contained in:
@@ -101,11 +101,14 @@ class Welt:
|
||||
j = json.dumps
|
||||
# Board 1 / Inventar
|
||||
if "-research-" in key:
|
||||
# Bottom-up: Research liefert die ATOME flach; Board 1 gruppiert sie zu den
|
||||
# Cluster-Bausteinen. Jedes Atom gehört zu genau einem Cluster.
|
||||
zeilen = []
|
||||
n = 1
|
||||
for t, b in self.bloecke.items():
|
||||
zeilen.append(f"{n}. {t} — {b['beschreibung']}")
|
||||
n += 1
|
||||
for cl, b in self.bloecke.items():
|
||||
for atom in b["subs"]:
|
||||
zeilen.append(f"{n}. {atom} — Atom aus {cl}")
|
||||
n += 1
|
||||
return "\n".join(zeilen)
|
||||
if "-pair-" in key:
|
||||
n = prompt.count("\nA: ") or 1
|
||||
@@ -130,7 +133,19 @@ class Welt:
|
||||
if "-gruppierung-completion-" in key:
|
||||
return j({"additions": []})
|
||||
if "-gruppierung-" in key:
|
||||
return j({"umbrellas": []})
|
||||
# jedes Atom seinem Cluster zuordnen (nur die FULL ITEM LIST, 1..n eindeutig)
|
||||
seg = prompt.split("FULL ITEM LIST", 1)[-1]
|
||||
atom_cluster = {_norm(a): cl for cl, b in self.bloecke.items() for a in b["subs"]}
|
||||
umb: dict[str, list[int]] = {}
|
||||
for m in _NUM_RE.finditer(seg):
|
||||
nr, zeile = int(m.group(1)), _norm(m.group(2))
|
||||
for an, cl in atom_cluster.items():
|
||||
if zeile.startswith(an):
|
||||
umb.setdefault(cl, []).append(nr)
|
||||
break
|
||||
umbrellas = [{"title": cl, "description": self.bloecke[cl]["beschreibung"],
|
||||
"members": ms} for cl, ms in umb.items() if ms]
|
||||
return j({"umbrellas": umbrellas})
|
||||
if "-supplement-beleg" in key or "-anker-beleg-" in key:
|
||||
nums = {m.group(1) for m in _NUM_RE.finditer(prompt)}
|
||||
return j({"relevant": {k: "ja" for k in sorted(nums, key=int)} or {"1": "ja"}})
|
||||
@@ -141,6 +156,16 @@ class Welt:
|
||||
return j({"relevant": {k: "ja" for k in sorted(nums, key=int)} or {"1": "ja"}})
|
||||
|
||||
# Board 2 / Artefakte (verschmolzene Calls, block_calls.py)
|
||||
if "-sb-enrich-" in key: # Bottom-up: feste Subs (aus dem Prompt) mit Facts anreichern
|
||||
seg = prompt.split("FIXED SUBBLOCKS", 1)[-1].split("\n\n", 1)[0]
|
||||
subs = []
|
||||
for m in re.finditer(r"^\s*\d+\.\s+(.+)$", seg, re.M):
|
||||
s = m.group(1).strip()
|
||||
f = self._fakt("", s)
|
||||
subs.append({"title": s, "level": "beginner", "relevance": "relevant",
|
||||
**{k: f[k] for k in ("key_points", "prerequisites", "hurdles",
|
||||
"cited_facts", "example_idea")}})
|
||||
return j({"subs": subs})
|
||||
if "-sb-gen-" in key:
|
||||
subs = []
|
||||
for t in self._bloecke_im_prompt(prompt):
|
||||
@@ -251,13 +276,15 @@ class Welt:
|
||||
|
||||
|
||||
def standard_bloecke() -> dict:
|
||||
"""3 Blöcke; „Gemeinsamer Grundbegriff" liegt in Alpha UND Beta (Cross-Block-Fall)."""
|
||||
"""3 Themen-Cluster; die subs sind die ATOME, die Board 1 bottom-up zu genau diesem
|
||||
Cluster gruppiert. Jedes Atom liegt in genau einem Cluster (kein geteiltes Atom mehr —
|
||||
das globale Clustern in Board 1 macht Cross-Block-Dubletten unmöglich)."""
|
||||
return {
|
||||
"Alpha-Konzept": {"beschreibung": "Das erste Grundkonzept",
|
||||
"subs": ["Definition Alpha", "Alpha Eigenschaften",
|
||||
"Gemeinsamer Grundbegriff"]},
|
||||
"Beta-Verfahren": {"beschreibung": "Das zentrale Verfahren",
|
||||
"subs": ["Beta Ablauf", "Beta Grenzen", "Gemeinsamer Grundbegriff"]},
|
||||
"subs": ["Beta Ablauf", "Beta Grenzen"]},
|
||||
"Gamma-Anwendung": {"beschreibung": "Praktische Anwendung",
|
||||
"subs": ["Gamma Praxisfall", "Gamma Werkzeuge"]},
|
||||
}
|
||||
@@ -308,11 +335,18 @@ def aktivieren(welt: Welt, setattr_fn=setattr) -> None:
|
||||
|
||||
@staticmethod
|
||||
def embed(texts):
|
||||
import hashlib
|
||||
|
||||
import numpy as np
|
||||
uniq = {t: k for k, t in enumerate(dict.fromkeys(texts))}
|
||||
arr = np.zeros((len(texts), max(len(uniq), 1)))
|
||||
# FESTE Dimension (hash → One-hot): identischer Text = gleiche Spalte = cos 1.0,
|
||||
# verschiedener Text = andere Spalte = cos 0.0. Anders als eine pro-Aufruf
|
||||
# variable Breite lassen sich so Vektoren aus verschiedenen embed()-Aufrufen
|
||||
# concatenieren (Board-1-Cluster-Cache) ohne Dimensions-Mismatch.
|
||||
D = 4096
|
||||
arr = np.zeros((len(texts), D))
|
||||
for r, t in enumerate(texts):
|
||||
arr[r, uniq[t]] = 1.0
|
||||
h = int(hashlib.blake2b(t.encode("utf-8"), digest_size=8).hexdigest(), 16) % D
|
||||
arr[r, h] = 1.0
|
||||
return arr
|
||||
|
||||
@staticmethod
|
||||
@@ -320,9 +354,14 @@ def aktivieren(welt: Welt, setattr_fn=setattr) -> None:
|
||||
arr = _FakeEmb.embed(texts)
|
||||
return arr @ arr.T
|
||||
|
||||
for mod in (blocks, ba, qa):
|
||||
setattr_fn(mod, "embedding", _FakeEmb)
|
||||
# reine Matrix-/Union-Find-Helfer (modell-unabhängig) ans echte Modul delegieren
|
||||
import embedding as _real_emb
|
||||
capped_blocks = staticmethod(_real_emb.capped_blocks)
|
||||
_find = staticmethod(_real_emb._find)
|
||||
_union = staticmethod(_real_emb._union)
|
||||
|
||||
async def emb_ok(flow): # Board-1-Vektorpfade aus — Judge-Wellen reichen
|
||||
return False
|
||||
setattr_fn(bi, "_emb_ok", emb_ok)
|
||||
for mod in (blocks, ba, qa, bi):
|
||||
setattr_fn(mod, "embedding", _FakeEmb)
|
||||
# _emb_ok bleibt echt (True über _FakeEmb): Bottom-up braucht den Grouping-Stage.
|
||||
# _FakeEmb bildet nur bei identischem Text Nachbarn — verschiedene Atome erzeugen keine
|
||||
# falschen Vorab-Cluster; das eigentliche Clustern macht der TOP-Judge (Card-sort).
|
||||
|
||||
Reference in New Issue
Block a user