Pubblicata: 14 gennaio 2025
Lo scorso anno, in occasione di Google I/O 2024, abbiamo lanciato gli approfondimenti della console, la prima funzionalità di IA in Chrome DevTools. Gli Approfondimenti della console consentono di comprendere gli errori e gli avvisi registrati nella console inviando dati di rete, codice sorgente e tracce dello stack relativi al messaggio di log a Gemini, il modello linguistico di grandi dimensioni (LLM) di Google. Approfondimenti della console invia un singolo prompt a Gemini che restituisce una singola risposta senza che gli sviluppatori abbiano la possibilità di porre domande di follow-up. Sebbene questo singolo flussi di interazione funzionino relativamente bene per spiegare i messaggi di errore, non si adattano a casi d'uso di debug più complessi in DevTools, dove non è chiaro quali dati della pagina ispezionata un'AI richiederebbe per fornire assistenza.
Un caso d'uso di questo tipo è il debug dei problemi di stile. Una singola pagina web può contenere migliaia di elementi e regole CSS, di cui solo un sottoinsieme è pertinente per il debug di uno scenario specifico. Identificare il codice corretto da eseguire il debug può essere difficile anche per le persone. Tuttavia, grazie a un prototipo creato durante un hackathon sull'IA in Google, abbiamo scoperto che gli LLM sono in realtà piuttosto bravi. Quindi, naturalmente, abbiamo voluto offrire questa funzionalità agli utenti di DevTools, creando uno strumento in grado di esaminare i problemi di stile eseguendo query interattive sulla pagina per ottenere ulteriori dati di contesto. Qualche mese dopo, abbiamo lanciato la nostra soluzione come assistenza IA per lo stile.
In questo post vogliamo mettere in luce le sfide che abbiamo dovuto affrontare durante l'introduzione dell'IA in un prodotto molto apprezzato come gli Strumenti per gli sviluppatori di Chrome, che in fondo è un'app web, e cosa puoi adattare per le tue funzionalità di IA.
Raccogliere i dati giusti
Console Insights utilizza sempre gli stessi punti dati per rispondere a un prompt predefinito. Affinché l'assistenza IA sia utile con qualsiasi prompt definito dall'utente, dobbiamo determinare dinamicamente quali dati di contesto sono importanti per la query in questione.
Pertanto, abbiamo implementato il modello ReAct (Yao et al., 2022). Questa strategia di prompt consente agli LLM di ragionare in modo autonomo e di determinare l'azione successiva in base al proprio ragionamento.
In questo modo, l'assistenza AI opera in un ciclo di pensiero, azione e osservazione fino a quando non determina una risposta adeguata alla query dell'utente, a quel punto conclude il ciclo e fornisce una risposta. Questa procedura iterativa consente all'LLM di raccogliere le informazioni precise necessarie per eseguire il debug dei problemi di stile in modo efficace.
Per raccogliere informazioni, abbiamo fornito a Gemini un solo strumento: l'esecuzione di JavaScript sulla pagina ispezionata. In questo modo, Gemini può, ad esempio,
- Accedi e analizza il DOM: attraversa la struttura ad albero DOM, ispeziona gli attributi degli elementi e comprendi le relazioni tra gli elementi.
- Recupero degli stili calcolati: accedi agli stili calcolati per qualsiasi elemento.
- Esegui calcoli e misurazioni: esegui il codice JavaScript per calcolare distanze, dimensioni e posizioni degli elementi.
In questo modo, l'assistenza AI agisce in modo interattivo solo sul codice pertinente, migliorando la qualità e il tempo di risposta e l'utilizzo delle risorse di calcolo rispetto all'invio del codice sorgente HTML e CSS completo a Gemini.
Eseguire codice generato dall'IA nello spazio utente
Potrebbe sembrare inaspettato che per il debug dei problemi di stile abbiamo utilizzato JavaScript. I motivi sono due:
- Le API web sono molto potenti e coprono intrinsecamente molti casi d'uso di debug. Sebbene per uno sviluppatore possa essere noioso utilizzare manualmente le chiamate API per esaminare il DOM o accedere agli stili calcolati per il debug, non è un problema per un LLM generare codice che le richiama.
- Sebbene sia possibile inventare nuove API da utilizzare per un agente, spesso è preferibile riutilizzare quelle pubbliche esistenti, perché sono già conosciute dagli LLM. Insegnare a un LLM una nuova API richiede molte risorse per la messa a punto e dati di addestramento specifici.
Tuttavia, l'esecuzione di codice creato con l'IA nello spazio utente comporta dei rischi. Per l'assistenza con l'IA, abbiamo dovuto minimizzare il rischio di modifiche dannose che l'agente potrebbe apportare alla pagina. Per questo, abbiamo utilizzato i controlli degli effetti collaterali esposti da V8, il motore JavaScript di Chrome tramite il protocollo Chrome DevTools. Gli stessi controlli vengono utilizzati per la funzionalità di completamento automatico nella console DevTools: viene eseguito solo il codice JavaScript, a condizione che non modifichi lo stato della pagina. I controlli vengono eseguiti mentre V8 esegue il codice e si basano su una lista consentita di elementi incorporati JavaScript che non hanno effetti collaterali.
Se i controlli rilevano che il codice generato sta modificando la pagina ispezionata, l'esecuzione viene messa in pausa e all'utente viene chiesto di esaminare il codice e confermare che è possibile eseguire il codice.
Inoltre, il codice JavaScript generato viene eseguito in un cosiddetto "mondo" isolato. È simile al modo in cui le estensioni eseguono script sandbox: il codice generato è in grado di accedere alle API DOM e web, ma non al codice o allo stato JavaScript definito dalla pagina ispezionata.
Monitoraggio delle modifiche apportate dall'agente
Oltre a esaminare i problemi e rispondere alle domande di debug sulla pagina, volevamo anche dare all'agente di assistenza AI la possibilità di correggere gli stili sulla pagina in modo che fossero tracciabili dagli sviluppatori.
Per farlo, abbiamo implementato una binding chiamata setElementStyles
che viene esposta al contesto di esecuzione dell'agente, oltre alle API web predefinite.
Per informare Gemini di questo nuovo metodo, gli diciamo di utilizzarlo nel preambulo dell'assistenza con l'IA:
If you need to set styles on an HTML element, always call the \`async setElementStyles(el: Element, styles: object)\` function.
Nonostante sia un'API progettata specificamente per l'agente, che presenta le difficoltà già menzionate, anche senza ottimizzazione Gemini la utilizza in modo abbastanza affidabile quando deve modificare gli stili di un determinato elemento.
Lato DevTools, quando setElementStyles
viene chiamato dall'agente, l'assistenza AI utilizza i fogli di stile dell'ispettore per registrare la modifica del selettore di elementi. L'annidamento CSS viene utilizzato per assegnare un nome alla modifica e aumentare la specificità del selettore dell'elemento. Una regola CSS di esempio creata dall'agente, quindi, è la seguente:
.ai-style-change-1 { /* the ID is incremented for each change*/
.element-selector { /* Element selector is computed based on the element setElementStyles was called on. */
color: blue;
}
}
Sebbene questa operazione non risolva tutti i possibili conflitti di stile che possono verificarsi nella pagina, funziona nella maggior parte dei casi.
Il vantaggio dell'utilizzo dei fogli di stile dell'ispettore rispetto agli stili in linea è che in questo modo le modifiche apportate dall'agente vengono visualizzate anche nel riquadro Modifiche, il che semplifica il monitoraggio delle modifiche apportate agli stili degli elementi e di ciò che uno sviluppatore deve trasferire al codice sorgente sottostante. L'integrazione con il riquadro Modifiche consente anche di annullare le modifiche se non sono più necessarie.
Rendere osservabili le azioni degli agenti per gli utenti
Quando aggiungi funzionalità di agenti a un prodotto, è importante rendere trasparenti le azioni degli agenti per gli utenti, in modo che abbiano la possibilità di tracciarle, comprenderle e potenzialmente intervenire.
Per l'assistenza con l'IA, quindi, insegniamo a Gemini a strutturare le risposte in un formato specifico con un'aggiunta al preambolo:
You are going to answer to the query in these steps:
* THOUGHT
* TITLE
* ACTION
* ANSWER
* SUGGESTIONS
Use THOUGHT to explain why you take the ACTION. Use TITLE to provide a short summary of the thought.
Questa struttura viene poi utilizzata per presentare le azioni e i processi mentali di Gemini come passaggi inizialmente compressi, evitando il sovraccarico di informazioni e consentendo al contempo agli utenti di esaminare i dettagli sottostanti o interrompere l'esecuzione in caso di effetti collaterali involontari.
Questo approccio non si limita a osservare l'IA, ma mira a imparare attivamente da essa. Espandendo queste sezioni, gli utenti possono analizzare i dati ritenuti pertinenti da Gemini per il debug di un problema specifico e comprendere la procedura seguita. Questa trasparenza consente agli utenti di imparare dalle strategie di debug dell'IA, in modo da poter applicare tecniche simili alle sfide future, anche quando lavorano senza l'IA.
Per migliorare ulteriormente l'esperienza utente, l'assistenza AI fornisce anche suggerimenti pertinenti dal punto di vista del contesto dopo la risposta dell'IA. Questi suggerimenti semplificano la conversazione, offrendo idee per il passaggio successivo di debug o consentendo persino agli utenti di eseguire direttamente le correzioni consigliate con un solo clic.
Inizialmente, per generare titoli e suggerimenti per i passaggi nell'assistenza AI, abbiamo pensato di utilizzare un modello più piccolo e separato specificamente per il riepilogo. Tuttavia, ci siamo resi conto che il pattern ReAct, che struttura il ragionamento di Gemini in un loop di "Pensieri" e "Azioni", può essere esteso in modo efficace. Pertanto, anziché introdurre un secondo modello, che avrebbe comportato anche una maggiore latenza, abbiamo modificato il nostro prompt per insegnare a Gemini a generare non solo i suoi "Pensieri" e "Azioni" di base, ma anche titoli concisi e suggerimenti utili nello stesso loop ReAct.
Sviluppo basato su valutazione
Lo sviluppo dell'assistenza dell'IA per lo stile è stato guidato da un processo di valutazione rigoroso. Per misurarne le prestazioni e identificare le aree di miglioramento, abbiamo selezionato una raccolta completa di esempi di debug web reali, che trattano problemi comuni di overflow, componenti web, animazioni e altro ancora. In questo modo abbiamo potuto mappare l'ampiezza dello spazio dei problemi di debug web e comprendere a fondo le sfide associate. Tuttavia, si tratta di un lavoro che non finisce mai: con l'aggiunta regolare di nuove funzionalità alla piattaforma web, dobbiamo mantenere aggiornati questi esempi in futuro.
Questi esempi vengono inseriti in una pipeline di valutazione automatica, che registra le risposte di Gemini. I dati di queste esecuzioni di test automatici vengono poi resi disponibili in uno strumento personalizzato in cui valutiamo manualmente il rendimento di Gemini per l'assistenza IA in base a rubriche predefinite, che informano i nostri sforzi di sviluppo successivi.
Questo approccio basato sulla valutazione garantisce che tutte le modifiche, che si tratti di perfezionare i comportamenti esistenti o di introdurre nuove funzionalità, vengano verificate attentamente per ottenere i miglioramenti previsti e prevenire le regressioni nelle funzionalità esistenti.
Per migliorare ulteriormente la nostra procedura di valutazione, stiamo valutando metodi di verifica automatica, tra cui:
- Verifiche per confermare la corretta applicazione delle correzioni
- Controlli basati sul codice per evitare output indesiderati da Gemini
- Utilizzo di LLM come giudici, guidati da rubriche specifiche, per semiautomatizzare e accelerare le nostre valutazioni manuali
Sebbene la verifica automatica aiuti a scalare, il feedback umano è importante. Stiamo raccogliendo feedback umani con controlli di voto sotto ogni risposta nell'assistenza con l'IA per capire quanto sono soddisfatti gli utenti. Un pulsante Segnala aggiuntivo consente agli utenti di fornire un feedback più preciso per le risposte contestabili.
Prompt injection
Una limitazione ben nota e documentata degli LLM è che sono soggetti a iniezioni di prompt. L'iniezione di prompt è la tecnica che consente di trovare un modo per sovrascrivere le istruzioni di sistema originali di un LLM, in modo che generi contenuti non previsti dagli sviluppatori.
La maggior parte dei modelli ora dispone di mitigazioni integrate per l'iniezione di prompt, come Gemini. Per quanto riguarda l'assistenza tramite l'IA, cerchiamo inoltre di mitigare questo problema nel preambulo includendo la seguente istruzione:
If the user asks a question about religion, race, politics, sexuality, gender, or other sensitive topics, answer with "Sorry, I can't answer that. I'm best at questions about debugging web pages.
Sebbene questo metodo funzioni per alcune domande esplicitamente fuori tema, non è perfetto. Un svantaggio che abbiamo notato è che le query brevi e ambigue potrebbero essere classificate come off-topic.
Creare una base solida
Quando introduci l'IA nel tuo prodotto per la prima volta, vale la pena procedere gradualmente, anziché fare un grande balzo contemporaneamente. È così che abbiamo scelto di procedere anche per l'assistenza IA. Con tutto ciò che abbiamo imparato durante la creazione dell'agente di stile, abbiamo creato una base solida per estendere in un secondo momento l'assistenza IA ad altre aree di DevTools.
Avendo già risolto la maggior parte dei problemi più grandi durante lo sviluppo dell'agente di stile, solo pochi mesi dopo siamo stati in grado di introdurre l'assistenza dell'IA per la rete, il rendimento e le origini e di concentrarci sulle singole sfide.
Implicazioni per la sicurezza quando si utilizzano le richieste di rete
L'assistenza AI per la rete consente agli utenti di discutere con Gemini di richieste di rete specifiche, utilizzando i dati della richiesta come contesto per la conversazione. Nello specifico, a Gemini vengono inviati i seguenti dati:
- Intestazioni della richiesta: un sottoinsieme di intestazioni inviate dal browser al server.
- Intestazioni di risposta: un sottoinsieme di intestazioni restituite dal server.
- Stato risposta: il codice di stato HTTP che indica la risposta del server (ad es. 200, 404).
- Tempi: informazioni dettagliate sui tempi che coprono varie fasi della richiesta, ad esempio la configurazione della connessione e il trasferimento dei dati.
- Catena iniziatore della richiesta: la sequenza di azioni e script che hanno avviato la richiesta.
Sebbene le intestazioni siano importanti per comprendere appieno la formazione di una richiesta, rappresentano un rischio per la sicurezza: potrebbero contenere credenziali come chiavi API, token di sessione o persino password non criptate. Per proteggere queste informazioni sensibili, non transmittiamo tutte le intestazioni a Gemini. Manteniamo invece un elenco consentito di intestazioni consentite. I valori delle intestazioni non presenti nella lista consentita vengono sostituiti con <redacted>
. Questo approccio garantisce che Gemini riceva il contesto necessario proteggendo al contempo i dati utente.
Adattamento a vari formati di dati
L'assistenza AI per le origini consente agli sviluppatori di porre domande su un file di origine nel riquadro Origini, ad esempio "A cosa serve questo file?".
I dati relativi al file, inclusi il nome, i contenuti e l'eventuale mappatura della sorgente, vengono inviati in un unico prompt. Questo approccio è efficace perché si tratta di testo normale. Tuttavia, i file di testo o binari di grandi dimensioni rappresentano una sfida per gli LLM. Per i file binari, abbiamo deciso di indicare che i contenuti sono binari nel prompt e di non inviare contenuti effettivi. Per i file di testo di grandi dimensioni, inviamo solo una parte minore dei contenuti presi dall'inizio del file.
Per l'assistenza AI per il rendimento, che consente agli sviluppatori di porre domande su una determinata attività da un profilo di rendimento registrato, esiste una sfida simile per creare una rappresentazione che si adatti alla finestra del contesto di Gemini e che possa anche essere interpretata per fornire approfondimenti aggiuntivi.
Per creare una presentazione di questo tipo da un profilo di rendimento, abbiamo creato un
serializzatore dedicato chiamato
AiCallTree
che formatta l'albero di chiamate per un'attività in modo che possa essere elaborato da un LLM. In futuro, esploreremo anche la strategia ReAct per ridurre al minimo la quantità di dati da inviare a Gemini in anticipo.
Assistenza dell'IA in futuro
Il risultato di tutto questo lavoro è ora disponibile a partire da Chrome 132, che include l'assistenza dell'IA per stile, rete, origini e prestazioni. Ci auguriamo che ti piaccia usarlo tanto quanto ci è piaciuto crearlo.
Per avere un'idea da dove iniziare, consulta la guida rapida all'assistenza IA completa con numerosi prompt di dimostrazione da provare sulle tue pagine e non esitare a farci sapere cosa ne pensi nel nostro bug di discussione aperto.