Cum a construit Kimi K3 pe cont propriu o tușă digitală de stilou
Voiam stiloul direcțional din Freeform în Lulucat Notes. Specificația era o captură de ecran cu scris de mână. Două modele, o întrebare de departajare și o peniță eliptică mai târziu, pixul cu apă scrie așa cum trebuie. Cercetarea, codul și validarea au fost făcute de Kimi K3 pe Fireworks.

Randat de pipeline-ul Metal al Lulucat Notes despre care este vorba în această postare.
Lulucat Notes are un stilou simplu și un evidențiator. Următorul instrument din plan era un pix cu apă — stiloul direcțional pe care îl știți din Apple Notes și Freeform, unde tușele verticale ies groase, iar cele orizontale subțiri. Specificația acestui instrument nu era un document. Era o captură de ecran: trei rânduri de scris de mână, cuvintele “pencilkit”, “无边记” și “这种有方向的水笔能力” — această capacitate direcțională a pixului cu apă.
La fel ca în cazul pipeline-ului Metal de dinainte, munca a fost făcută de Kimi K3, modelul open-source al Moonshot care rulează pe Fireworks: măsurarea, modelarea, codul și validarea. Omul a furnizat captura de ecran, a răspuns la o întrebare și a evaluat senzația pe un iPad real.
Specificația este o captură de ecran
O imagine statică nu îți poate spune de ce o tușă este subțire. Îți poate spune doar cât de subțire este și unde. Așa că primul pas a fost măsurarea. Am scanat captura de ecran rând cu rând și coloană cu coloană, urmărind deplasarea liniei centrale a fiecărei tușe pentru a-i obține direcția, apoi am transformat lățimea scanată în lățime adevărată folosind sinusul acelui unghi:
| Tușă | Direcție | Lățime adevărată |
|---|---|---|
| Tija ascendentă a literei “l”, “pencilkit” | ≈ 78° | 27.3 px |
| Tija lui “k”, “pencilkit” | ≈ 90° | 28 px |
| Mișcarea descendentă spre stânga din 力 | ≈ 66° | 25.7 px |
| Legături cursive | ≈ 8° | 11 px |
| Orizontale chinezești (横) | ≈ 0° | 6–11 px |
Raportul gros-subțire este ≈ 2.5. Potrivirea
Versiunea unu: lățime din direcție
Primul model a fost cel evident. Calculează o direcție pentru fiecare punct de intrare, mapează direcția la lățime prin curba ajustată și fixează rezultatul în raza punctului la momentul capturii. Direcția era estimată cauzal — o medie ponderată cu decădere exponențială peste ultimele câteva puncte ale arcului, calculată în spațiul unghiului dublat, astfel încât o inversare a deplasării să nu anuleze estimarea. Sunt folosite doar punctele anterioare, deci tușa live și tușa confirmată coincid byte cu byte.
Builderul a trecut verificarea unitară: trasee sintetice orizontale, verticale, la 45° și cu inversare au fixat toate lățimile teoretice — 0.99, 2.52, 2.00 și 0.99 puncte. Randarea nu a avut nevoie de niciun cod nou: o tușă cu raza fixată este doar un lanț de ștampile rotunde, iar pipeline-ul nostru de point sprites le desena deja.
Pe iPad, omul a respins-o în aproximativ zece secunde: “ăsta este un stilou artistic, nu pixul cu apă”.
Două povești se potrivesc unei singure imagini
De ce se simțea greșit? Existau două explicații posibile, iar captura de ecran nu le putea deosebi:
- Blocare pe direcție. Geometria peniței forțează orizontalele să fie subțiri și verticalele groase, indiferent ce face mâna. Asta a implementat versiunea unu.
- Presiune și viteză. Stiloul este controlat de presiune, iar modelul din mostră este doar dinamica scrisului de mână: tușele descendente sunt apăsate în mod natural, iar legăturile sunt în mod natural rapide și ușoare.
Ambele produc o captură cu orizontale subțiri și verticale groase. Diferența este ce se întâmplă când apeși tare pe o tușă orizontală. Versiunea unu o păstrează subțire. Un stilou controlat de presiune o îngroașă. Așa că l-am întrebat pe om un singur lucru: o tușă orizontală apăsată tare ar trebui să devină mai groasă?
“Nu. Orizontalele rămân subțiri.”
Blocarea pe direcție a fost confirmată. Dar ceva tot nu era în regulă, pentru că și versiunea unu era blocată pe direcție.
Răspunsul se afla la capetele tușelor
Următorul indiciu era în vârful ascendentelor. O mărire a tijelor literelor “l” și “k” din mostră a arătat două lucruri: o tușă dreaptă păstrează aceeași lățime de la început până la sfârșit, iar capetele tușelor sunt tăieturi diagonale plate — forma unei penițe tip daltă care se ridică de pe hârtie. Nu puncte rotunde. Nu subțieri de la presiune.

Asta însemna, de fapt, „senzația de stilou artistic”. Versiunea unu a modelat aspectul mostrei — lățimea ca funcție a direcției estimate — dar nu și stiloul. Un estimator de direcție este un senzor: tremură la intrare zgomotoasă, rămâne în urmă la colțuri și rotunjește fiecare capăt de tușă într-un cerc. O peniță adevărată nu are niciuna dintre aceste probleme, pentru că nu calculează nimic. Lățimea este geometrie.
Versiunea doi: o peniță eliptică
Modelul final nu are niciun estimator de direcție. Penița este o elipsă orientată: axa lungă este orizontală, axa scurtă este fixă. Ștampilele acestei elipse sunt așezate dens de-a lungul traseului tușei, iar tot restul rezultă din geometrie:
-
O tușă orizontală merge de-a lungul marginii deschise, așa că are întotdeauna lățimea
— o linie subțire constantă, indiferent de presiune. Exact specificația confirmată. -
O tușă verticală traversează întreaga axă lungă:
, capătul gros. -
O tușă diagonală ia lățimea coardei elipsei perpendiculară pe direcția de deplasare,
-
Capetele tușelor sunt tăieturi eliptice — capetele plate în forma peniței din mostră, fără niciun efort în plus.
-
Presiunea scalează doar axa lungă,
, așa că presiunea crește volumul de cerneală pe tușele descendente și nu poate îngroșa niciodată o orizontală.
Din măsurătorile mostrei am păstrat
Randarea a necesitat un fragment shader nou și nimic altceva. Formatul vertexului — poziție, diametru, culoare — avea deja tot ce trebuia: diametrul este axa lungă, iar axa scurtă este un uniform per trecere. Shaderul evaluează un SDF de elipsă cu aceeași rampă de acoperire de jumătate de pixel ca ștampilele noastre rotunde, ceea ce îl face comparabil pixel cu pixel cu implementarea de referință Core Graphics (fillEllipse per stamp). Validarea a trecut prin poarta obișnuită: un corpus sintetic cu două tușe de stilou, randate în ambele moduri și comparate pixel cu pixel — zero diferențe structurale, iar o tușă orizontală verificată punctual a măsurat 12 px în ambele randere.

Versiunea unu este în stânga, versiunea doi în dreapta. Același input scris de mână, același pipeline. Capetele spun povestea.
Pe iPad, stiloul nou a trecut imediat: “好,很好” — bine. Foarte bine.
Păstrăm modelul ratat
Versiunea unu nu a ajuns la gunoi. Este o pensulă interesantă — pur și simplu nu este un pix cu apă. Așa că a fost lansată ca prima intrare într-un nou meniu de pensule experimentale, sub numele pe care i l-a dat omul: 漏水的圆珠笔, pixul cu bilă care curge. Bara de instrumente a primit un buton în formă de balon care deschide o listă text de experimente; adăugarea următorului costă o linie într-un registru. Un model respins nu este muncă irosită dacă poate fi lansat ca un experiment etichetat clar.
O seară de bucle
Arcul complet — măsurare, modelare, construire, dispozitiv, întrebare, remodelare, reconstruire, validare — a durat o seară. Kimi K3 pe Fireworks a gestionat toată partea tehnică a buclei: a conceput scanările de măsurare, a propus întrebarea de departajare în loc să ghicească a doua oară, și-a șters estimatorul de direcție când dovezile au schimbat direcția și a extins pixel-diff harness înainte să atingă aplicația. Viteza de inferență a Fireworks a păstrat bucla interactivă — diff-uri lungi pentru Metal și Swift, scripturi de analiză a pixelilor și instrumente pentru corpus ajungeau suficient de repede încât blocajul să rămână acolo unde trebuie: judecata umană.
Tiparul de colaborare a fost același ca în postarea despre pipeline-ul Metal și a funcționat din nou: modelul este rapid și precis; omul deține gustul și verificarea end-to-end. O singură frază de feedback bazat pe senzație — “stilou artistic, nu pix cu apă” — a fost suficientă pentru ca modelul să localizeze eroarea exactă de modelare și să o înlocuiască printr-un design mai simplu.
Modelul corect s-a dovedit mai mic decât cel greșit. Versiunea doi a ajuns cu mai puține piese în mișcare decât versiunea unu — fără estimator, fără fereastră de netezire, fără exponent ajustat. Penița nu calculează lățimea. Penița este lățimea.