Download Game! Currently 101 players. Last logged in:MorkzarStylusJosimToudi

Blitzer's Blog >> 72659

Back to blogs index
Posted: 21 Sep 2026 10:08 [ permalink ]
Tuo nC$yttC$C$ huomattavasti kliinisemmC$ltC$! Oikeat elementit  kuten
syC6ttC6kentC$t, chatin viestikuplat ja yksittC$iset ikonit  ovat nyt
selkeC$sti eristettyinC$ ilman sitC$ aiempaa C$C$riviivojen sekamelskaa.

Kuvassa nC$kyvC$ chatin automaatioloki on muuten todella mielenkiintoinen. Se
paljastaa, ettC$ HAUKI_GEM-agenttisi osaa dynaamisesti vaihtaa strategiaa
lennosta: kun perinteinen `template_match` ei lC6ydC$ dokumentti-ikonia
polusta, jC$rjestelmC$ ei kaadu, vaan siirtyy sujuvasti `semantic_agent`-reitit
ykseen ja hakee lokaalista semanttisesta kartasta oikean ikonin ID:n (132).
Tuollainen dynaaminen resilienssi on tC$smC$lleen sitC$, mitC$ vaaditaan, kun
rakennetaan luotettavaa RPA-putkea Metan jatkuvasti muuttuviin "hostile"
kC$yttC6liittymiin. Tuo tekee tulevista WhatsApp-automaatioiden monistamisista
varmasti paljon vakaampia.

Nyt kun DOM on saatu taltutettua ja visuaalinen syC6te LLM:lle on
huomattavasti puhtaampi, graafinen tunnistus on hyvC$llC$ mallilla.

TC$mC$ on tunnettu ja erittC$in tehokas tekniikka nimeltC$ **Set-of-Mark
(SoM)**. Kun LLM saa kuvan, jossa jokainen interaktiivinen elementti on
numeroitu, se hallusinoi huomattavasti vC$hemmC$n ja pystyy suoraan vastaamaan
esimerkiksi: `[42]`.

Helpoin tapa toteuttaa tC$mC$ rikkomatta alkuperC$istC$ layoutia on luoda
JavaScriptillC$ jokaisen valitun elementin pC$C$lle erillinen, absoluuttisesti
asemoitu kelluva numerolappu (badge). Samalla injektoimme itse elementtiin
`data-som-id`-attribuutin, jotta Playwright lC6ytC$C$ elementin heti, kun LLM
palauttaa numeron.

Korvaa aiempi `valittu_sivu.evaluate(...)` tC$llC$ koodilla:

```python
        valittu_sivu.evaluate("""
            let idCounter = 1;
            
            document.querySelectorAll('*').forEach(el => {
                // HylC$tC$C$n rakenteelliset ja ei-visuaaliset elementit
                if (['SCRIPT', 'STYLE', 'SVG', 'PATH', 'NOSCRIPT'].includes(el.
tagName)) return;
                
                // Varmistetaan, ettC$ elementti on oikeasti nC$kyvissC$
                const rect = el.getBoundingClientRect();
                if (rect.width === 0 || rect.height === 0) return;
                
                let hasDirectText = Array.from(el.childNodes).some(node => 
                    node.nodeType === Node.TEXT_NODE && node.nodeValue.trim().l
ength > 0
                );
                
                // Valitaan interaktiiviset elementit ja tekstiC$
sisC$ltC$vC$t solmut
                if (hasDirectText || el.tagName === 'BUTTON' || el.tagName ===
'INPUT' || el.getAttribute('role') === 'button') {
                    
                    // 1. PiirretC$C$n magentan vC$rinen C$C$riviiva
                    el.style.outline = '2px solid magenta';
                    el.style.outlineOffset = '-2px';
                    
                    // TCRKECC: Tallennetaan ID elementtiin Playwrightia
varten
                    el.setAttribute('data-som-id', idCounter);
                    
                    // 2. Luodaan kelluva numerolappu
                    const label = document.createElement('div');
                    label.textContent = idCounter;
                    
                    // Asemoidaan lappu elementin vasempaan ylC$kulmaan
                    label.style.position = 'absolute';
                    label.style.top = (rect.top + window.scrollY) + 'px';
                    label.style.left = (rect.left + window.scrollX) + 'px';
                    
                    // TyylitellC$C$n lappu konenC$C6lle selkeC$ksi
                    label.style.backgroundColor = 'magenta';
                    label.style.color = 'white';
                    label.style.fontSize = '12px';
                    label.style.fontWeight = 'bold';
                    label.style.padding = '1px 3px';
                    label.style.zIndex = '2147483647'; // Pakotetaan
pC$C$llimmC$iseksi
                    label.style.pointerEvents = 'none'; // EstetC$C$n
klikkausten blokkautuminen
                    label.style.boxShadow = '1px 1px 2px rgba(0,0,0,0.5)'; //
Pieni varjo parantaa luettavuutta
                    
                    document.body.appendChild(label);
                    
                    idCounter++;
                }
            });
        """)

```

### Miten hyC6dynnC$t tC$tC$ automaatiossa

Kun olet syC6ttC$nyt tC$mC$n injektion jC$lkeen otetun kuvan mallille ja
pyytC$nyt sitC$ palauttamaan klikattavan elementin numeron (esim. se vastaa
`132`), Playwrightin jatkotoimenpide on C$C$rimmC$isen yksinkertainen:

```python
# Oletetaan, ettC$ LLM palautti numeron 132
kohde_id = "132"

# Playwright etsii injektoidun attribuutin perusteella
elementti = valittu_sivu.locator(f'[data-som-id="{kohde_id}"]')

if elementti.is_visible():
    # Playwright osaa laskea koordinaatit ja klikata suoraan keskelle!
    elementti.click()

```

TC$mC$ ratkaisee X/Y-koordinaattien arvaamisen tuoman epC$varmuuden kokonaan
ja kytkee visuaalisen analyysin saumattomasti fyysiseen suoritukseen.