Data publikacji: 14 stycznia 2025 r.
W zeszłym roku na konferencji Google I/O 2024 wprowadziliśmy statystyki konsoli, czyli pierwszą funkcję AI w Narzędziach deweloperskich Chrome. Statystyki konsoli pomagają zrozumieć błędy i ostrzeżenia zalogowane w konsoli. Polega to na wysyłaniu danych sieciowych, kodu źródłowego i zrzutów stosu powiązanych z komunikatem logowania do Gemini, czyli dużego modelu językowego (LLM) Google. Statystyki w Konsoli wysyłają do Gemini pojedynczy prompt, który zwraca jedną odpowiedź bez możliwości zadawania przez deweloperów dodatkowych pytań. Chociaż ten pojedynczy przepływ interakcji sprawdza się w przypadku wyjaśniania komunikatów o błędach, nie można go zastosować w bardziej złożonych przypadkach debugowania w Narzędziach deweloperskich, ponieważ nie jest jasne, jakich danych z przeglądanej strony potrzebuje AI, aby pomóc.
Jednym z takich zastosowań jest debugowanie problemów ze stylami. Pojedyncza strona internetowa może zawierać tysiące elementów i reguł CSS, z których tylko część jest istotna w przypadku debugowania konkretnego scenariusza. Wyznaczenie odpowiedniego kodu do debugowania może być trudne nawet dla ludzi. Jednak dzięki prototypowi stworzonemu podczas hackathonu AI w Google dowiedzieliśmy się, że LLM-e radzą sobie z tym całkiem nieźle. Dlatego postanowiliśmy udostępnić tę funkcję użytkownikom DevTools, tworząc narzędzie, które może badać problemy ze stylami, wysyłając interaktywne zapytania do strony w celu uzyskania dodatkowych danych kontekstowych. Kilka miesięcy później udostępniliśmy pomoc AI w stylizacji.
W tym artykule chcemy przybliżyć Ci wyzwania, z którymi mieliśmy do czynienia podczas wprowadzania AI do popularnej usługi, takiej jak Narzędzia programistyczne w Chrome, która jest w istocie aplikacją internetową. Dowiesz się też, jak możesz dostosować własne funkcje AI.
Zbieranie odpowiednich danych
Statystyki w konsoli zawsze używają tych samych punktów danych do odpowiedzi na wstępnie zdefiniowany prompt. Aby AI assistance mogła być przydatna w przypadku dowolnego promptu zdefiniowanego przez użytkownika, musimy dynamicznie określić, jakie dane kontekstowe są ważne dla danego zapytania.
Dlatego wdrożyliśmy metodę ReAct (Yao i in., 2022) strategii. Ta strategia promptów umożliwia LLM samodzielne wnioskowanie i określanie dalszych działań na podstawie tych wniosków.
W ten sposób asystent AI działa w cyklu myślenia, działania i obserwacji, aż do momentu, gdy znajdzie odpowiednią odpowiedź na zapytanie użytkownika. Następnie kończy cykl i podaje odpowiedź. Ten iteracyjny proces pozwala LLM zbierać dokładne informacje potrzebne do skutecznego debugowania problemów ze stylami.
Aby zebrać informacje, Gemini otrzymało tylko jedno narzędzie: uruchamianie skryptu JavaScript na stronie, którą sprawdzamy. Dzięki temu Gemini może za pomocą AI:
- Dostęp do DOM i analizowanie go: przechodzenie po drzewie DOM, sprawdzanie atrybutów elementów i poznawanie relacji między elementami.
- Pobierz style wynikowe: uzyskaj dostęp do stylów wynikowych dowolnego elementu.
- Wykonywanie obliczeń i pomiary: wykonuj kod JavaScript, aby obliczać odległości, rozmiary i pozycje elementów.
Dzięki temu asystent AI może interaktywnie działać tylko na odpowiednim kodzie, co poprawia jakość odpowiedzi, czas odpowiedzi i wykorzystanie zasobów obliczeniowych w porównaniu z wysyłaniem do Gemini pełnego kodu źródłowego HTML i CSS.
Uruchamianie kodu wygenerowanego przez AI w przestrzeni użytkownika
Może się wydawać, że użycie JavaScriptu do debugowania problemów ze stylami jest nieoczekiwane. Dzieje się tak z 2 przyczyn:
- Interfejsy API sieciowe są bardzo wydajne i obejmują wiele przypadków użycia związanych z debugowaniem. Korzystanie z ręcznych wywołań interfejsu API do przeglądania DOM lub dostępu do obliczonych stylów na potrzeby debugowania może być dla dewelopera żmudne, ale dla LLM wygenerowanie kodu wywołującego te elementy nie stanowi problemu.
- Chociaż można tworzyć nowe interfejsy API do użycia przez agenta, często lepszym rozwiązaniem jest ponowne użycie istniejących, publicznych interfejsów API, ponieważ są one już znane LLM. Nauczanie LLM nowego interfejsu API wymaga wielu zasobów na dostosowanie i specyficzne dane treningowe.
Jednak uruchamianie kodu wygenerowanego przez AI w przestrzeni użytkownika wiąże się z pewnymi zagrożeniami. W przypadku pomocy AI musieliśmy zminimalizować ryzyko wprowadzenia przez agenta zmian, które mogłyby zniszczyć stronę. W tym celu wykorzystaliśmy mechanizmy sprawdzania efektów ubocznych, które V8, czyli mechanizm JavaScriptu w Chrome, udostępnia za pomocą protokołu Chrome DevTools. W przypadku funkcji autouzupełniania w Konsoli Narzędzi deweloperskich są stosowane te same mechanizmy weryfikacji: kod JavaScriptu jest wykonywany tylko wtedy, gdy nie zmienia stanu żadnej strony. Sprawdzanie odbywa się podczas wykonywania kodu przez V8 i opiera się na liście dozwolonych wbudowanych funkcji JavaScript, o których wiadomo, że nie mają efektów ubocznych.
Jeśli podczas sprawdzania zostanie wykryte, że wygenerowany kod modyfikuje sprawdzaną stronę, wykonanie zostanie wstrzymane, a użytkownik zostanie poproszony o sprawdzenie kodu i potwierdzenie, że można go uruchomić.
Dodatkowo wygenerowany kod JavaScript jest uruchamiany w tak zwanym odizolowanym „świecie”. Działa to podobnie jak uruchamianie skryptów w piaskownicy przez rozszerzenia: wygenerowany kod może uzyskiwać dostęp do DOM i interfejsów API sieci, ale nie może uzyskiwać dostępu do kodu JavaScript ani stanu zdefiniowanego przez skanowaną stronę.
Śledzenie zmian wprowadzonych przez pracownika obsługi klienta
Oprócz badania problemów i odpowiedzi na pytania dotyczące debugowania strony chcieliśmy też umożliwić agentowi pomocy opartym na AI poprawianie stylów na stronie w sposób możliwy do śledzenia przez deweloperów.
Aby to osiągnąć, wprowadziliśmy ograniczenie o nazwie setElementStyles
, które oprócz domyślnych interfejsów API dla sieci udostępniamy kontekstowi wykonania agenta.
Aby Gemini wiedziało o tej nowej metodzie, przekazujemy mu instrukcje dotyczące jej używania w preambule pomocy AI:
If you need to set styles on an HTML element, always call the \`async setElementStyles(el: Element, styles: object)\` function.
Mimo że jest to interfejs API zaprojektowany specjalnie dla agenta, co wiąże się z wymienionymi wcześniej problemami, nawet bez dokładnego dostosowania Gemini dość niezawodnie używa go, gdy musi zmienić styl danego elementu.
Gdy setElementStyles
jest wywoływany przez agenta, AI assistance używa szablonów stylów w Inspektorze do rejestrowania zmian w selektorze elementów. Zagnieżdżanie w CSS służy do nadawania nazw zmianom i zwiększania specyficzności selektora elementu. Przykładowa reguła CSS utworzona przez agenta wygląda tak:
.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;
}
}
Chociaż nie rozwiązuje to wszystkich możliwych konfliktów stylów, które mogą wystąpić na stronie, w większości przypadków działa to dobrze.
Zaletą korzystania z arkuszy stylów w narzędzie inspekcji w porównaniu ze stylami wstawianymi jest to, że zmiany wprowadzone przez agenta są też widoczne w panelu Zmiany, co ułatwia śledzenie zmian w stylach elementów i to, co deweloper musi przenieść do kodu źródłowego. Integracja z panelem Zmiany umożliwia też wycofanie zmian, jeśli nie są już potrzebne.
Udostępnianie działań agenta użytkownikom
Dodając do produktu funkcje agenta, należy zadbać o to, aby działania agenta były przejrzyste dla użytkowników, aby mogli oni śledzić, rozumieć i potencjalnie interweniować w sytuacjach, gdy to konieczne.
W przypadku pomocy AI instruujemy Gemini, aby sformatowała odpowiedzi w określonym formacie z dodatkiem wstępu:
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.
Ta struktura jest następnie wykorzystywana do przedstawiania procesów myślowych i działań Gemini jako początkowo złożonych kroków, co zapobiega przeładowaniu informacjami, a jednocześnie umożliwia użytkownikom zapoznanie się z podstawowymi szczegółami lub zatrzymanie wykonania w przypadku niezamierzonych skutków ubocznych.
To podejście nie polega tylko na obserwowaniu AI, ale na aktywnym uczeniu się od niej. Po rozwinięciu tych sekcji użytkownicy mogą analizować dane, które Gemini uzna za istotne do debugowania konkretnego problemu, i rozumieć proces, który doprowadził do jego wystąpienia. Ta przejrzystość pozwala użytkownikom uczyć się na podstawie strategii debugowania AI, dzięki czemu mogą stosować podobne techniki w przyszłości, nawet bez AI.
Aby jeszcze bardziej zwiększyć wygodę użytkowników, AI Assistant podaje też trafne sugestie kontekstowe po odpowiedzi AI. Te sugestie usprawniają rozmowę, podając pomysły na kolejny krok debugowania, a nawet pozwalają użytkownikom bezpośrednio stosować zalecane poprawki jednym kliknięciem.
Początkowo rozważaliśmy użycie mniejszego, osobnego modelu do generowania tytułów kroków i sugestii w ramach pomocy AI. Zdaliśmy sobie jednak sprawę, że wzór ReAct, który strukturyzuje wnioskowanie Gemini w pętli „Myśli” i „Działania”, można skutecznie rozszerzyć. Zamiast wprowadzać drugi model, który również wiązałby się z dodatkowym opóźnieniem, zmodyfikowaliśmy prompt, aby Gemini generował nie tylko podstawowe „Myśli” i „Działania”, ale też zwięzłe tytuły i przydatne sugestie w ramach tego samego cyklu ReAct.
Ocena rozwoju
Prace nad sztuczną inteligencją do pomocy w stylizacji były prowadzone zgodnie ze ścisłym procesem oceny. Aby zmierzyć wydajność i wyznaczyć obszary wymagające poprawy, przygotowaliśmy obszerną kolekcję przykładów debugowania stron internetowych, w której omówiliśmy m.in. typowe problemy z przepełnieniem, komponenty internetowe i animację. Dzięki temu mogliśmy zbadać szeroki zakres problemów związanych z debugowaniem stron internetowych i dokładnie poznać związane z nimi wyzwania. To jednak nie koniec pracy: nowe funkcje są regularnie dodawane do platformy internetowej, więc musimy na bieżąco aktualizować te przykłady.
Przykłady te są przekazywane do automatycznego procesu oceny, który rejestruje odpowiedzi Gemini. Dane z tych automatycznych testów są następnie dostępne w specjalnym narzędziu, w którym ręcznie oceniamy skuteczność Gemini w zakresie wspomagania przez AI na podstawie zdefiniowanych wcześniej kryteriów. Wyniki te są wykorzystywane w dalszych pracach rozwojowych.
Dzięki temu podejściu wszystkie zmiany, niezależnie od tego, czy polegają na udoskonaleniu dotychczasowych zachowań czy wprowadzaniu nowych funkcji, są dokładnie sprawdzane, aby osiągnąć zamierzone ulepszenia i zapobiec regresji dotychczasowej funkcjonalności.
Aby jeszcze bardziej usprawnić proces oceny, badamy automatyczne metody weryfikacji, takie jak:
- Zarzuty potwierdzające prawidłowe zastosowanie poprawek
- Sprawdzanie kodu w celu zapobiegania niepożądanym wynikom z Gemini
- Wykorzystanie modeli LLM jako sędziów, kierowanych przez konkretne kryteria, do częściowej automatyzacji i przyspieszenia naszych ręcznych ocen
Chociaż weryfikacja automatyczna pomaga zwiększać skalę, opinia człowieka jest ważna. Zbieramy opinie użytkowników za pomocą przycisków głosowania pod każdą odpowiedzią w asystencie AI, aby dowiedzieć się, jak zadowoleni są użytkownicy. Dodatkowy przycisk zgłaszania pozwala użytkownikom dokładniej oceniać odpowiedzi, co do których mają wątpliwości.
Wstrzyknięcia promptów
Znane i udokumentowane ograniczenie modeli LLM polega na tym, że są one podatne na wstrzykiwanie promptów. Wstrzyknięcie promptu to technika polegająca na znalezieniu sposobu na zastąpienie oryginalnych instrukcji systemu dużego modelu językowego (LLM), aby generował on treści nieprzewidziane przez programistów.
Większość modeli ma obecnie wbudowane środki zaradcze na wypadek wstrzyknięcia promptu, podobnie jak Gemini. W przypadku pomocy AI staramy się też ograniczyć ten problem, dodając w wstępie instrukcję:
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.
Ta metoda sprawdza się w przypadku niektórych wyraźnie nie na temat, ale nie jest idealna. Jednym z zauważonych przez nas problemów jest to, że krótkie i niejednoznaczne zapytania mogą zostać zaklasyfikowane jako nie na temat.
Budowanie na solidnych podstawach
Gdy po raz pierwszy wprowadzasz AI do swojego produktu, warto postępować krok po kroku, zamiast robić duży skok. W ten sam sposób podeszliśmy do stworzenia asystenta AI. Dzięki temu, czego nauczyliśmy się podczas tworzenia agenta stylizacji, stworzyliśmy solidne podstawy, które pozwolą nam w przyszłości udostępnić pomoc AI w innych obszarach DevTools.
Po rozwiązaniu większości większych problemów związanych z działaniem agenta stylizacji w ciągu zaledwie kilku miesięcy mogliśmy wprowadzić pomoc AI w zakresie sieci, wydajności i źródeł, a także skupić się na poszczególnych problemach.
Konsekwencje bezpieczeństwa związane z pracą z żądaniami sieciowymi
Asystent AI dla sieci umożliwia użytkownikom omawianie konkretnych próśb dotyczących sieci z Gemini, przy użyciu danych z prośby jako kontekstu rozmowy. Do Gemini wysyłane są te dane:
- Nagłówki żądania: podzbiór nagłówków wysyłanych przez przeglądarkę do serwera.
- Nagłówki odpowiedzi: podzbiór nagłówków zwróconych przez serwer.
- Stan odpowiedzi: kod stanu HTTP wskazujący odpowiedź serwera (np. 200, 404).
- Czas: szczegółowe informacje o czasie trwania poszczególnych faz żądania, takie jak konfiguracja połączenia i przesyłanie danych.
- Łańcuch inicjatora żądania: sekwencja działań i skryptów, które zainicjowały żądanie.
Nagłówki są ważne, ponieważ pozwalają w pełni zrozumieć, jak powstaje żądanie, ale stanowią też zagrożenie dla bezpieczeństwa: mogą zawierać dane logowania, takie jak klucze API, tokeny sesji, a nawet hasła. Aby chronić takie informacje poufne, nie przekazujemy wszystkich nagłówków do Gemini. Zamiast tego utrzymujemy listę dozwolonych nagłówków. Wartości nagłówków, które nie znajdują się na liście dozwolonych, są zastępowane wartością <redacted>
. Dzięki temu Gemini otrzymuje niezbędny kontekst, a jednocześnie chroni dane użytkowników.
dostosowywanie się do różnych formatów danych,
Pomoc AI dla źródeł umożliwia programistom zadawanie pytań dotyczących pliku źródłowego w panelu źródeł, na przykład „Do czego służy ten plik?”.
Dane o pliku, w tym nazwa pliku, zawartość pliku i to, czy jest on powiązany ze źródłem, są wysyłane w jednym promptzie. To działa, ponieważ jest to zwykły tekst. Duże pliki tekstowe lub pliki binarne stanowią jednak wyzwanie dla dużych modeli językowych. W przypadku plików binarnych zdecydowaliśmy się wskazać w promptach, że są to pliki binarne, i nie wysyłać żadnych rzeczywistych treści. W przypadku dużych plików tekstowych wysyłamy tylko mniejszą część treści z początku pliku.
W przypadku pomocy AI dotyczącej wydajności, która pozwala deweloperom zadawać pytania dotyczące konkretnego zadania na podstawie zarejestrowanego profilu wydajności, pojawia się podobny problem polegający na utworzeniu reprezentacji, która pasuje do okna kontekstowego Gemini i może też zostać zinterpretowana w celu uzyskania dodatkowych informacji.
Aby utworzyć taką prezentację na podstawie profilu wydajności, utworzyliśmy specjalny sejrator o nazwie AiCallTree
, który formatuje drzewo wywołań dla zadania w sposób, który może przetworzyć LLM. W przyszłości będziemy też wykorzystywać strategię ReAct, aby zminimalizować ilość danych, które należy przesłać do Gemini z wyprzedzeniem.
Pomoc AI w przyszłości
Efekt tych prac jest dostępny od wersji 132 Chrome, która zawiera pomoc AI w zakresie stylizacji, sieci, źródeł i wydajności. Mamy nadzieję, że będziesz z niego zadowolony/a tak samo jak my z jego tworzenia.
Aby dowiedzieć się, od czego zacząć, przeczytaj obszerny przewodnik po pomocy AI, w którym znajdziesz wiele instrukcji demonstracyjnych do wypróbowania na własnych stronach. Podziel się z nami swoją opinią w otwartym buzierze.