← Retour aux projets

Smart Expansion History

Une extension Chrome, History Chat, qui retrouve une page que vous avez visitée quand vous vous souvenez seulement de son sujet, pas de son titre ni de son URL. Je l'ai construite avec React et Vite pendant mon stage chez DevFortress : la recherche se fait dans l'historique local de Chrome, et l'API Gemini de Google ne sert que si vous ajoutez votre propre clé.

Architecture

Fenêtre de l'extension (React)Historique ChromeGemini (facultatif)
Gemini n'est appelé que si l'utilisateur ajoute une clé, pour transformer la question en mots-clés et classer jusqu'à 100 candidats locaux.

L'extension est une fenêtre Manifest V3 construite avec React, sans serveur propre et sans script de contenu. Sans clé, le texte saisi va directement à chrome.history.search sur la période choisie par l'utilisateur, des dernières 24 heures aux 3 derniers mois, et les résultats sont nettoyés et affichés sur-le-champ. Avec une clé, Gemini 2.5 Flash transforme d'abord la question en mots-clés classés par pertinence, la fenêtre cherche dans l'historique local un mot-clé à la fois jusqu'à avoir 100 candidats nettoyés ou épuiser la liste, puis Gemini en choisit jusqu'à 5 avec une courte raison. Les paramètres, y compris la clé Gemini, sont gardés dans le stockage synchronisé de Chrome, et le journal de conversation dans le stockage local.

Décisions clés

Quatre profondeurs de recherche, au choix

Je laisse l'utilisateur choisir jusqu'où l'IA élargit une question : Superficial demande 5 mots-clés à Gemini, Regular (par défaut) 20, Exhaustive 50 et Sheerlock jusqu'à 100. Le prompt demande des mots seuls, sans doublons, classés du plus pertinent au moins pertinent, et dit au modèle de ne pas allonger la liste pour la remplir. Une recherche rapide reste petite, et le mode profond est là pour les pages difficiles à retrouver.

Un budget fixe de 100 candidats

Peu importe la profondeur, au plus 100 pages sont envoyées à Gemini pour être classées. Les 10 premiers mots-clés ont droit à 10 places chacun au maximum, les 20 suivants à 5, les autres à 2, et une deuxième passe remplit les places libres avec les restes, toujours dans l'ordre des mots-clés. Avec cette récupération progressive, l'extension a trouvé plus de bonnes pages en utilisant environ 40 % de jetons Gemini en moins.

Nettoyer la liste avant que le modèle la voie

Je normalise chaque URL candidate : je retire la partie après le # et les paramètres de suivi comme utm_source, gclid et fbclid, puis je trie le reste. Les doublons se fondent ensuite en une seule entrée, et les pages de recherche Google, les pages chrome:// et les fichiers locaux sont exclus. Ainsi, aucune place du budget ne va deux fois à la même page ni à du bruit de recherche.

Le point difficile

Quand le JSON du modèle n'est pas du JSON valide

Les deux appels à Gemini attendent du JSON brut, et les deux prompts le demandent, mais je retire quand même les délimiteurs de bloc de code markdown avant l'analyse et j'extrais le tableau entre crochets de la réponse des mots-clés. Si les mots-clés restent illisibles, ou si l'appel échoue, l'extension se rabat sur les mots de la question de plus de trois caractères et cherche avec ceux-là. Si le classement est illisible, l'utilisateur voit quand même les 5 premiers candidats au lieu d'une erreur.

Sécurité et performance

  • Sans clé d'API, l'extension ne fait aucun appel réseau : la recherche passe par l'API d'historique de Chrome. Avec une clé Gemini, la question ainsi que le titre, l'URL et l'heure de dernière visite d'au plus 100 pages candidates sont envoyés à l'API Gemini de Google, mais jamais l'historique complet.
  • En dehors de l'accès aux hôtes des API d'IA, le manifeste ne demande que les permissions history et storage, et rien n'est injecté dans les pages visitées. Le journal de conversation, résultats passés compris, reste dans le stockage local de l'extension, et les messages plus vieux que la durée de conservation choisie sont supprimés à l'ouverture de la fenêtre.

Stack

ReactViteTailwind CSSChrome Manifest V3Gemini API

Liens