Le probleme : un RAG qui ne suivait pas
Les bases de connaissances ne sont utiles que si la recherche est rapide. Lorsque nous avons lance le support RAG dans JieGou, le pipeline fonctionnait — les documents etaient decoupes, les embeddings generes et injectes dans les prompts. Mais les performances racontaient une autre histoire.
Une base de connaissances contenant 705 documents necessitait ~160 secondes pour recuperer le contexte pertinent. Cela signifiait que chaque execution de recipe, chaque etape de workflow et chaque conversation d’agent touchant une base de connaissances payait un cout de plusieurs minutes avant meme que le LLM ne commence a generer.
Pour les cas d’usage interactifs — un agent de support cherchant une politique, un commercial consultant des specifications produit en pleine conversation — 160 secondes est redhibitoire.
Nous devions ramener la recherche a moins d’une seconde sans ajouter de complexite d’infrastructure.
Phase 1 : Recherche vectorielle native Firestore
L’approche de recherche initiale chargeait tous les embeddings depuis Firestore, calculait la similarite cosinus dans le code applicatif et retournait les top-k resultats. C’etait simple et correct, mais cela scalait lineairement avec le nombre de documents.
La premiere optimisation a consiste a deplacer la recherche de similarite dans Firestore lui-meme en utilisant Firestore Vector Search (base sur l’indexation ScaNN). Au lieu de charger les 705 embeddings en memoire et de calculer les distances, nous avons laisse Firestore gerer la recherche des plus proches voisins de maniere native.
Ce qui a change
- Avant : Recuperer tous les embeddings → calculer la similarite cosinus en Node.js → trier → prendre les top-k
- Apres : Une seule requete Firestore avec
findNearest()→ retourne les top-k directement
Cela a elimine le transfert de donnees et le calcul O(n). L’index vectoriel de Firestore utilise la recherche approximative des plus proches voisins, echangeant une quantite negligeable de recall contre des gains de vitesse massifs sur les grandes collections.
Resultats
La requete a froid sur 705 documents est passee de ~160s a ~10s. Une amelioration de 16x — mais encore trop lente pour les workflows interactifs.
Phase 2 : Recherche hybride avec fallback
Toutes les requetes ne beneficient pas de la recherche vectorielle de la meme maniere. Certaines bases de connaissances sont suffisamment petites pour que la force brute soit plus rapide que le cout d’une requete d’index vectoriel. D’autres ont des documents qui ne s’embedent pas bien (tableaux, extraits de code, donnees structurees).
Nous avons implemente une strategie de recherche hybride :
- Essayer la recherche vectorielle d’abord — Si un index vectoriel Firestore existe et que la base de connaissances a des embeddings, utiliser
findNearest() - Se rabattre sur la force brute — Si la recherche vectorielle echoue, n’est pas disponible ou retourne trop peu de resultats, charger les embeddings et calculer la similarite dans le code applicatif
- Fusionner et dedupliquer — Combiner les resultats des deux chemins, dedupliquer par ID de document, re-classer par score de similarite
L’approche hybride signifie que la recherche n’echoue jamais. Si les index vectoriels Firestore n’ont pas encore ete crees (par exemple, dans un environnement nouvellement provisionne), le systeme se degrade elegamment vers le chemin de force brute d’origine.
Le flag usedVectorSearch
Chaque operation de recherche inclut desormais un booleen usedVectorSearch dans son span de trace. Cela nous permet de surveiller quelles requetes empruntent le chemin rapide et lesquelles utilisent le fallback, et d’identifier les bases de connaissances qui necessitent la creation d’index ou un re-embedding.
Phase 3 : Cache Redis pour les requetes frequentes
La derniere optimisation cible les requetes repetees — la meme question posee a la meme base de connaissances dans une courte fenetre de temps. Cela arrive constamment en production :
- Plusieurs etapes de workflow interrogeant la meme base de connaissances FAQ
- Des conversations d’agent qui re-recuperent le contexte a chaque tour
- Des executions batch ou 50 elements interrogent des documents de reference identiques
Nous avons ajoute un cache Redis par document avec un TTL de 10 minutes :
- Avant d’executer la recherche de similarite, verifier Redis pour des resultats caches avec la cle
(knowledgeBaseId, queryEmbeddingHash) - En cas de cache hit, retourner immediatement — aucune requete Firestore du tout
- En cas de cache miss, executer le pipeline de recherche hybride et cacher les resultats
Resultats
| Scenario | Avant | Apres |
|---|---|---|
| Requete a froid, 705 docs | ~160s | ~10s |
| Requete frequente (Redis hit) | ~160s | <1s |
| Petite KB (<50 docs) | ~5s | ~2s |
| Batch de 50 elements, meme KB | ~8 000s au total | ~10s + 49x <1s |
Le scenario batch est celui ou le cache apporte le plus grand gain. Le premier element paie le cout de la requete a froid ; les 49 elements restants touchent Redis et retournent en millisecondes.
Architecture : zero dependance externe
Une contrainte de conception cle etait pas d’infrastructure supplementaire. De nombreuses plateformes RAG necessitent de provisionner et gerer une base de donnees vectorielle dediee — Pinecone, Weaviate, Qdrant, Milvus. Chacune ajoute :
- Un service de plus a deployer et surveiller
- Un ensemble de credentials supplementaire a gerer
- Une dimension de facturation fournisseur en plus
- Un mode de defaillance supplementaire dans votre pipeline
L’approche de JieGou n’utilise que l’infrastructure que vous possedez deja :
| Composant | Objectif | Deja existant ? |
|---|---|---|
| Firestore | Index vectoriel + stockage de documents | ✅ Votre base de donnees principale |
| Redis | Cache des resultats de requete | ✅ Utilise pour le rate limiting et les sessions |
| Code applicatif | Fallback force brute | ✅ S’execute dans vos pods existants |
Pas de Pinecone. Pas de Weaviate. Aucune nouvelle infrastructure a provisionner, securiser ou payer.
Ce que cela signifie pour vos workflows
Execution de recipes plus rapide
Chaque recipe utilisant une base de connaissances recupere desormais le contexte en moins d’une seconde pour les requetes frequentes. Le spinner “reflexion en cours…” avant la generation a disparu pour les cas d’usage repetitifs.
Traitement batch pratique
Les executions batch traitant des centaines d’elements contre la meme base de connaissances sont desormais viables. Le premier element rechauffe le cache ; le reste passe a toute vitesse.
Des conversations d’agent qui semblent instantanees
Les agents conversationnels re-interrogent les bases de connaissances a chaque tour. Avec le cache Redis, les tours 2 a N recuperent le contexte en millisecondes au lieu de re-executer la recherche de similarite.
Recherche observable
Le flag de trace usedVectorSearch signifie que vous pouvez voir exactement quel chemin de recherche a ete utilise pour chaque execution. Si une base de connaissances se rabat systematiquement sur la force brute, vous savez qu’elle necessite une attention.
Essayez-le aujourd’hui
Si vous utilisez deja les bases de connaissances JieGou, ces optimisations sont actives — aucune modification de configuration requise. Vos bases de connaissances existantes beneficient automatiquement de la recherche vectorielle Firestore et du cache Redis.
Si vous n’avez pas encore configure de base de connaissances :
- Allez dans Knowledge Bases dans la console JieGou
- Telechargez des documents ou importez depuis une URL
- Attachez la base de connaissances a n’importe quel recipe ou workflow
- Observez la recherche s’effectuer en moins d’une seconde
La combinaison de la recherche vectorielle native Firestore, de la recherche hybride et du cache Redis signifie que vos automatisations AI obtiennent un contexte specifique a votre entreprise sans la penalite de latence — et sans gerer une seule piece d’infrastructure supplementaire.