fix(maria): mesajul si captura sunt acelasi lucru, iar cosinusul singur nu mai e dovada
Doua greseli din grupul "Maria Test", 2026-09-01, pe care 27409fb le-a atenuat dar
nu le-a rezolvat.
1. La o reclamatie vaga Maria cauta, in loc sa intrebe. "Buna . Am si eu o factura
pe luna august cu eroare in spv la trimitere AUTO SULE" nu spune CE eroare e —
n-are ce cauta in documente si n-are ce trimite la suport, fiindca programatorul
ar pune exact aceeasi intrebare. Gardul (triaj.prea_vag) exista, dar cerea text
sub 12 cuvinte; mesajul are 14. Gresea si invers: "nu pot incarca factura in SPV,
imi da eroare de certificat" are 9 cuvinte si ARE raspuns in documente, si era
oprita degeaba. Lungimea nu masoara cat de precis e mesajul.
-> gardul nu mai numara cuvinte si se aplica DUPA cautare, doar cand nu exista
acoperire. O singura data pe fir: daca nici intrebat omul nu spune mai mult,
mesajul pleaca la suport.
2. Textul si captura, trimise una dupa alta, erau tratate ca doua probleme fara
legatura. `este_continuare` rupea firul la ORICE imagine — dar cazul frecvent e
tocmai omul care scrie problema si trimite captura imediat dupa, sau care
raspunde la "trimite-mi o captura". Textul se pierdea, captura se cauta doar pe
OCR-ul ei, se deschideau doua fire si se puteau deschide doua escaladari pentru
aceeasi problema.
-> o captura in primele FIR_IMAGINE_MIN (5) minute continua firul: textul citit
din ea intra in ancora (cu tot cu coduri), cautarea se face pe mesaj +
captura, iar pe o escaladare deschisa pleaca la aceeasi referinta — cu
imaginea, nu doar cu textul citit din ea (_notifica_suport ia si media).
Si, ca urmare a lui (2): RANK_STRONG_COSINE dispare. Interogarea pe un fir e ancora
plus mesajul nou, deci cosinusul urca la fiecare replica fara sa apara vreo dovada
noua — aceeasi captura da 0,778 singura si 0,836 cu mesajul de dinainte, adica peste
0,80 pus ieri. Orice prag fix de sus e trecut de o discutie destul de lunga. Acoperirea
ramane pe dovada lexicala (termenii distinctivi ai intrebarii chiar in chunk-uri),
care e stabila la lungime. Niciun caz cu raspuns in documente nu avea nevoie de
scurtatura.
ops/calibrate-rank.py: 26/26, cu interogarea combinata adaugata la set. Teste: 102 pass.
Verificat end-to-end pe scenariul real (mesaj, apoi captura la 10 secunde): intrebare
de detalii, apoi o singura escaladare care poarta si textul si captura.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q4uzvgm7AyJch5WH8QHRhY
This commit is contained in:
@@ -353,24 +353,28 @@ Fuziunea da mereu un clasament, si la o intrebare complet straina. De aceea deci
|
||||
|
||||
0. **intrebarea contine un cod de eroare** (`ORA-…`, `PLS-…`, `D406`) → decide
|
||||
doar prezenta lui in chunk-uri, indiferent de cosinus;
|
||||
1. cosinus ≥ `RANK_STRONG_COSINE` → raspundem;
|
||||
2. cosinus < `RANK_WEAK_COSINE` → escaladam direct;
|
||||
3. intre ele → raspundem doar daca cel putin `RANK_MIN_RARE_RATIO` din termenii
|
||||
1. cosinus < `RANK_WEAK_COSINE` → escaladam direct;
|
||||
2. peste → raspundem doar daca cel putin `RANK_MIN_RARE_RATIO` din termenii
|
||||
distinctivi ai intrebarii (coduri, cuvinte rare in corpus) apar chiar in
|
||||
chunk-urile gasite.
|
||||
|
||||
Fractiunea din pasul 3 nu e cosmetica: cu un singur termen gasit, „cum imi resetez
|
||||
Fractiunea din pasul 2 nu e cosmetica: cu un singur termen gasit, „cum imi resetez
|
||||
parola de la Windows" trecea drept acoperita fiindca „parola" apare in documente.
|
||||
|
||||
`RANK_STRONG_COSINE` a fost 0,70 si a lasat sa treaca doua raspunsuri inventate
|
||||
**Nu exista prag „cosinus destul de mare ca sa nu mai verificam".** A existat
|
||||
(`RANK_STRONG_COSINE`, 0,70) si a lasat sa treaca doua raspunsuri inventate
|
||||
(2026-09-01, grupul „Maria Test"): „am o factura pe luna august cu eroare in SPV"
|
||||
(0,768 — nu spune ce eroare e) si o captura cu `errorMessage="CUI cumparator
|
||||
incorect"` (0,778 — eroarea nu exista in documente). **Toate chunk-urile eFactura
|
||||
seamana intre ele**, deci pe 0,7x cosinusul nu mai distinge „e in documente" de „e
|
||||
despre eFactura"; e acelasi tip de greseala ca la codurile Oracle de mai sus, doar
|
||||
ca fara cod pe care sa te sprijini. La **0,80** trec doar potrivirile aproape
|
||||
textuale, iar restul cad pe dovada lexicala de la pasul 3. `ops/calibrate-rank.py`:
|
||||
25/25, cu ambele cazuri adaugate la set.
|
||||
incorect"` (0,778 — eroarea nu exista in documente). Toate chunk-urile eFactura
|
||||
seamana intre ele, deci pe 0,7x cosinusul nu mai distinge „e in documente" de „e
|
||||
despre eFactura".
|
||||
|
||||
L-am scos, nu urcat, fiindca **cosinusul creste cu lungimea interogarii**: pe un fir
|
||||
de discutie se cauta dupa ancora plus mesajul nou, deci scorul urca la fiecare
|
||||
replica fara sa apara vreo dovada in plus. Aceeasi captura: 0,778 singura, 0,836
|
||||
impreuna cu mesajul de dinainte. Orice prag fix de sus e trecut de o discutie destul
|
||||
de lunga. `ops/calibrate-rank.py`: 26/26, si niciunul dintre cazurile cu raspuns in
|
||||
documente nu avea nevoie de scurtatura — toate trec pe dovada lexicala.
|
||||
|
||||
Modelul primeste `temperature=0` (`LLM_TEMPERATURE`). Fara ea, llama.cpp raspunde
|
||||
cu 0,8 — creativitate exact acolo unde vrem sa se rezume la context.
|
||||
@@ -393,9 +397,18 @@ Nu orice mesaj e o intrebare, si nu orice raspuns e util. `rag/triaj.py` ia trei
|
||||
decizii inaintea modelului:
|
||||
|
||||
**Mesaj prea vag.** „Am o eroare" nu spune nimic. Maria cere operatiunea, ecranul si
|
||||
textul erorii (sau o captura) — nu ghiceste si nu deranjeaza suportul cu atat. Regula
|
||||
e ingusta deliberat: doar text scurt, fara captura si fara cod de eroare, in care apar
|
||||
cuvinte de acuza („nu merge", „imi da"). „Cum trimit D406" trece nestingherit.
|
||||
textul erorii (sau o captura) — nu ghiceste si nu deranjeaza suportul cu atat, fiindca
|
||||
programatorul ar pune exact aceeasi intrebare.
|
||||
|
||||
Decizia se ia **dupa cautare, si numai cand nu exista acoperire in documente**. Inainte
|
||||
se lua inaintea cautarii, dupa lungime: text scurt (sub 12 cuvinte), fara captura si
|
||||
fara cod, cu cuvinte de acuza („nu merge", „imi da"). Gardul gresea in ambele sensuri
|
||||
— „Buna . Am si eu o factura pe luna august cu eroare in spv la trimitere AUTO SULE"
|
||||
are 14 cuvinte si tot nu zice CE eroare e (a trecut, si a primit un raspuns inventat),
|
||||
iar „nu pot incarca factura in SPV, imi da eroare de certificat" are 9 si e in
|
||||
documente (era oprita degeaba). Lungimea nu masoara cat de precis e mesajul;
|
||||
acoperirea in documente da. Se cere o singura data pe fir: daca nici dupa ce a fost
|
||||
intrebat omul nu spune mai mult, mesajul pleaca la suport.
|
||||
|
||||
**Erori care oricum ajung la programatori.** Dictionarul de erori Oracle are pe fiecare
|
||||
intrare campul `cand suni suportul`. Noua incep cu „Intotdeauna" sau „Imediat" — nu se
|
||||
@@ -437,10 +450,20 @@ La o continuare: cautarea se face pe **ancora + mesajul nou**, modelul primeste
|
||||
istoricul, mesajul se adauga la escaladarea deschisa (`completari`, de cate ori e
|
||||
nevoie), iar „mesaj prea vag" nu se mai aplica — detaliile au fost deja cerute.
|
||||
|
||||
**Ce rupe firul, necontestat:** o captura noua sau un cod de eroare diferit. Sunt
|
||||
singurele semne sigure ca omul a trecut la altceva. Schimbarea subiectului in cuvinte
|
||||
NU rupe firul: e prea usor de confundat cu o continuare, iar greseala aia produce
|
||||
exact tabelul de mai sus. In rest, firul expira dupa `FIR_TTL_MIN` (120 min).
|
||||
**Ce rupe firul:** un cod de eroare pe care firul nu-l are, sau o captura venita la
|
||||
mai mult de `FIR_IMAGINE_MIN` (5 min) dupa ultimul mesaj. Schimbarea subiectului in
|
||||
cuvinte NU rupe firul: e prea usor de confundat cu o continuare, iar greseala aia
|
||||
produce exact tabelul de mai sus. In rest, firul expira dupa `FIR_TTL_MIN` (120 min).
|
||||
|
||||
Orice captura a rupt firul pana pe 2026-09-01, si era gresit exact in cazul cel mai
|
||||
frecvent: **omul scrie problema si trimite captura imediat dupa** (sau Maria tocmai
|
||||
i-a cerut-o). WhatsApp le livreaza ca doua mesaje, dar e un singur lucru. Tratate
|
||||
separat, textul se pierdea si captura se cauta doar pe OCR-ul ei; se deschideau doua
|
||||
fire, se puteau deschide doua escaladari pentru aceeasi problema, iar suportul primea
|
||||
doua mesaje fara legatura. Acum captura din fereastra de 5 minute continua firul:
|
||||
textul citit din ea intra in ancora (cu tot cu codurile lui), cautarea se face pe
|
||||
mesaj + captura, iar daca firul are deja o escaladare deschisa captura pleaca la
|
||||
aceeasi referinta — cu imaginea, nu doar cu textul citit din ea.
|
||||
|
||||
### Completarile: trei feluri, trei raspunsuri
|
||||
|
||||
|
||||
Reference in New Issue
Block a user