fix(maria): codul de eroare decide acoperirea, nu cosinusul

O captura cu ORA-06550 / PLS-00906 primea raspunsul despre ORA-12541 (TNS no
listener) si nu pleca la suport. Cauza: doua erori Oracle diferite se scriu
aproape la fel ("[Oracle][ODBC][Ora]ORA-..."), asa ca chunk-ul gresit a iesit la
cosinus 0,736 — peste RANK_STRONG_COSINE, care scurtcircuita orice alta dovada.
Chunk-ul corect din dictionar exista, dar statea pe pozitia 4, in afara TOP_K:
OCR-ul unei ferestre intregi aduce zeci de tokeni de zgomot, iar BM25 ineca tocmai
codul.

- `rank.codes()` scoate codurile de oriunde din text, nu doar ca token intreg —
  OCR-ul le lipeste de ce e langa ("OraJORA-06550").
- `rank.by_codes()` e un al treilea clasament in fuziune: chunk-ul care poarta
  codul cerut urca peste cele care doar seamana. Acum iese primul.
- `rank.assess()`: cand intrebarea are coduri, decid doar ele. Niciun cod gasit =
  escaladare la suport, oricat de mare ar fi cosinusul.
- `consumer.search()` judeca acoperirea pe cosinusul chunk-urilor date chiar
  modelului, nu pe cel mai bun din tot indexul.

Calibrare 21/21 (cele 19 cazuri + captura reala + ORA-00600, cod care nu e in
documente si trebuie sa plece la suport). Teste: 79 pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q4uzvgm7AyJch5WH8QHRhY
This commit is contained in:
Claude Agent
2026-08-31 22:25:45 +00:00
parent 44763869ce
commit b7d75f05ee
5 changed files with 143 additions and 10 deletions

View File

@@ -49,6 +49,12 @@ CAZURI: list[tuple[str, bool]] = [
("imi da ORA-12154 cand deschid programul", True),
("ORA-00001 unique constraint violated", True),
("eroare ORA-28000 the account is locked", True),
# captura reala (OCR), 2026-08-31: raspundea cu ORA-03113/ORA-12541, alta eroare
("[Oracle][ODBC][OraJORA-06550: line 1, column 7\n"
"PLS-00906: object VADECO PACK PARTENERI is invalid\n"
"ORA-06550: line 1, column 7:", True),
# cod Oracle real, dar care NU e in dictionar: trebuie sa plece la suport
("ORA-00600 internal error code arguments", False),
("care e capitala Frantei", False),
("cat costa un bilet de avion la Paris", False),
("imi da eroare la imprimanta HP LaserJet, nu trage hartia", False),
@@ -84,11 +90,13 @@ def pregateste(cazuri: list[tuple[str, bool]]) -> tuple[consumer.Index, list[dic
nou += 1
cos = [consumer.cosine(vec, e["embedding"]) for e in index.entries]
bm = index.bm25.scores(intrebare)
ordine = rank.rank(cos, bm)[: config.get_int("TOP_K", 3)]
ordine = rank.rank(cos, bm, rank.by_codes(intrebare, index.texts))[
: config.get_int("TOP_K", 3)]
date.append({
"intrebare": intrebare,
"asteptat": asteptat,
"best": max(cos),
# ca in consumer.search: cosinusul chunk-urilor date modelului
"best": max((cos[i] for i in ordine), default=0.0),
"top_texts": [index.texts[i] for i in ordine],
"top_surse": [index.sources[i] for i in ordine],
})