Chaînes
Des chaînes pré-construites pour les patterns LLM courants : question-réponse sur documents, récupération conversationnelle avec mémoire, et résumé multi-stratégie. Chaque chaîne orchestre la récupération, la construction de contexte et la génération en un seul appel.
Pourquoi des Chaînes ?
Construire un pipeline RAG from scratch nécessite plusieurs étapes : récupérer les documents, construire le contexte, formater les prompts, appeler le LLM et gérer les erreurs. Les chaînes encapsulent ces patterns dans des composants réutilisables et testés avec une observabilité intégrée via les étapes intermédiaires.
RetrievalQA
Synchro Sans État"Flux direct requête-réponse pour bases de connaissances."
Conversational
Gestion du Contexte"Maintient l'état du dialogue via un historique persistant."
Summarization
Optimiseur de Tokens"Traite de gros volumes via logique Stuff ou Map-Reduce."
QA Chain
Logique Avancée"Prompts personnalisés et stratégies de retrieval multi-étapes."
# RetrievalQAChain
La chaîne la plus simple pour le question-réponse sur documents. Elle récupère les documents pertinents, construit une fenêtre de contexte et génère une réponse en un seul appel. Parfaite pour les requêtes simples sur une base de connaissances.
import { RetrievalQAChain, VectorRetriever } from '@orka-js/tools';import { OpenAIAdapter } from '@orka-js/openai'; const llm = new OpenAIAdapter({ apiKey: process.env.OPENAI_API_KEY! }); const retriever = new VectorRetriever({ llm, vectorDB: myVectorDB, topK: 5}); const chain = new RetrievalQAChain({ llm, retriever, collection: 'documentation', returnSources: true, // Inclut les documents sources dans le résultat maxSourceTokens: 3000, // Max de tokens pour la fenêtre de contexte systemPrompt: 'Tu es un assistant utile. Réponds uniquement sur la base du contexte fourni.'}); const result = await chain.call('How do I configure authentication?'); console.log(result.answer);// "Pour configurer l'authentification, vous devez..." console.log(result.sources);// [{ id: 'doc-1', score: 0.92, content: '...' }, ...] console.log(result.intermediateSteps);// [// { name: 'retrieve', input: '...', output: 'Found 5 relevant documents', latencyMs: 120 },// { name: 'generate', input: '...', output: '...', latencyMs: 850 }// ] console.log(result.usage);// { promptTokens: 1200, completionTokens: 350, totalTokens: 1550 }
Étapes Intermédiaires
Chaque chaîne retourne intermediateSteps avec le nom, l'entrée, la sortie et la latence de chaque étape. Cela vous donne une observabilité complète de l'exécution de la chaîne — utile pour le débogage, le monitoring et l'optimisation.
# ConversationalRetrievalChain
Étend RetrievalQA avec la mémoire conversationnelle. Elle condense automatiquement les questions de suivi en utilisant l'historique du chat, pour que le retriever reçoive une requête autonome même quand l'utilisateur demande "Et le deuxième ?" ou "Peux-tu expliquer plus ?". La chaîne maintient son propre historique de chat en interne.
import { ConversationalRetrievalChain } from '@orka-js/tools'; const chain = new ConversationalRetrievalChain({ llm, retriever, collection: 'documentation', returnSources: true, maxHistoryLength: 10, // Garde les 10 derniers messages en contexte // Optionnel: personnalisez la condensation des questions de suivi condenseQuestionPrompt: `Given the following conversation and a follow-up question,rephrase the follow-up as a standalone question. Chat History:{{history}} Follow-up: {{question}} Standalone Question:`}); // Première question — récupération normaleconst result1 = await chain.call('What authentication methods are supported?');console.log(result1.answer);// "Orka JS supporte JWT, OAuth2 et API key authentication..." // Suivi — automatiquement condensé avec l'historiqueconst result2 = await chain.call('How do I configure the second one?');// Internally condensed to: "How do I configure OAuth2 authentication?"console.log(result2.answer);// "Pour configurer OAuth2, vous devez configurer..." // Un autre suiviconst result3 = await chain.call('What are the required scopes?');// Condensed to: "What are the required OAuth2 scopes?"console.log(result3.answer);// "Les scopes requis sont: openid, profile, email..." // Vérifiez les étapes intermédiaires pour voir la question condenséeconsole.log(result2.intermediateSteps);// [// { name: 'condense_question', input: 'How do I configure the second one?',// output: 'How do I configure OAuth2 authentication?' },// { name: 'retrieve', ... },// { name: 'generate', ... }// ] // Gérer l'historiqueconsole.log(chain.getChatHistory());// [{ role: 'user', content: '...' }, { role: 'assistant', content: '...' }, ...] // Réinitialiser la conversationchain.clearHistory();Requête Contextuelle
L'utilisateur pose une question de suivi (ex: 'Et le deuxième ?') qui dépend des échanges précédents.
Step 1: InputAmbiguous User InputCondensation Sémantique
Le LLM analyse l'historique pour réécrire la requête en version autonome : 'Comment configurer OAuth2 ?'
Step 2: CondenseLLM Pre-processingRecherche de Connaissances
Le retriever utilise la question autonome condensée pour récupérer les documents les plus pertinents.
Step 3: RetrievalVector LookupGénération Finale
Le LLM synthétise le contexte récupéré et l'historique complet pour fournir une réponse précise.
Step 4: ResponseContextual Answer# SummarizationChain
Résume un ou plusieurs documents en utilisant trois stratégies différentes, chacune avec des compromis différents pour la qualité, la vitesse et le coût.
Stuffing 
Regroupe tous les chunks dans un seul contexte. Exécution instantanée mais se heurte aux limites de tokens.
Map-Reduce 
Résume les chunks en parallèle, puis les distille. Idéal pour les datasets massifs et l'extensibilité infinie.
Refine 
Parcourt les chunks pour affiner le résultat. Meilleure rétention des nuances mais plus lent (séquentiel).
- Stratégie Stuff
import { SummarizationChain } from '@orka-js/tools'; // Stuff: tous les documents dans une seule promptconst stuffChain = new SummarizationChain({ llm, strategy: 'stuff', systemPrompt: 'Provide a clear and concise summary.'}); const result = await stuffChain.call([ 'Document 1 content here...', 'Document 2 content here...', 'Document 3 content here...']); console.log(result.answer); // Résumé combinéconsole.log(result.usage); // Utilisation des tokens (1 appel LLM)- Stratégie Map-Reduce
// Map-Reduce: résume les chunks indépendamment, puis combineconst mapReduceChain = new SummarizationChain({ llm, strategy: 'map-reduce', maxChunkSize: 3000, // Divise les gros documents en chunks de 3000 caractères combinePrompt: Combine les résumés suivants en un résumé cohérent:\n\n{{summaries}}\n\nRésumé Combiné:}); const result = await mapReduceChain.call([ veryLongDocument1, // 50 000 caractères veryLongDocument2 // 30 000 caractères]); console.log(result.answer);// Résumé combiné finalconsole.log(result.intermediateSteps);// [// { name: 'map_chunk_0', ... }, // Résumé du chunk 1// { name: 'map_chunk_1', ... }, // Résumé du chunk 2// ...// { name: 'reduce_combine', ... } // Final combined summary// ]- Stratégie Refine
// Refine: améliore itérativement le résumé avec chaque chunkconst refineChain = new SummarizationChain({ llm, strategy: 'refine', maxChunkSize: 3000, refinePrompt: `Voici un résumé existant:{{existingSummary}} Affine ce résumé avec le contexte supplémentaire suivant:{{context}} Résumé Affiné:`}); const result = await refineChain.call([longDocument]); console.log(result.answer);// Résumé final affinéconsole.log(result.intermediateSteps);// [// { name: 'initial_summary', ... }, // Résumé du premier chunk// { name: 'refine_1', ... }, // Affiné avec le chunk 2// { name: 'refine_2', ... }, // Affiné avec le chunk 3// ...// ]# QAChain — Question-Réponse Avancé
QAChain combine la récupération avec le question-réponse multi-stratégie. Contrairement à RetrievalQAChain qui utilise toujours l'approche "stuff", QAChain supporte les stratégies stuff, map-reduce et refine pour répondre aux questions sur de grands ensembles de documents.
import { QAChain } from '@orka-js/tools'; // Stratégie Stuff (par défaut) — rapide, pour petits ensembles de documentsconst stuffQA = new QAChain({ llm, retriever, collection: 'docs', strategy: 'stuff', returnSources: true}); const result1 = await stuffQA.call(Quel est le taux de limitation?); // Stratégie Map-Reduce — pour de nombreux documents récupérésconst mapReduceQA = new QAChain({ llm, retriever, collection: 'docs', strategy: 'map-reduce', returnSources: true, systemPrompt: Réponds précisément basé sur les documents. Cite les sources quand c'est possible.}); const result2 = await mapReduceQA.call(Compare toutes les méthodes d'authentification);// Map : extrait les informations pertinentes de chaque document// Reduce : combine en une réponse complète // Stratégie Refine — meilleure qualité pour questions complexesconst refineQA = new QAChain({ llm, retriever, collection: 'docs', strategy: 'refine', returnSources: true}); const result3 = await refineQA.call(Explique le processus de déploiement complet étape par étape);// Commence avec la réponse du premier doc, affine avec chaque doc supplémentaireExemple Complet — Pipeline RAG Production
import { createOrka } from '@orka-js/core';import { OpenAIAdapter } from '@orka-js/openai';import { EnsembleRetriever, VectorRetriever, BM25Retriever, ConversationalRetrievalChain, SummarizationChain} from '@orka-js/tools';import { MemoryCache, CachedLLM } from '@orka-js/cache'; // Configuration avec mise en cacheconst baseLLM = new OpenAIAdapter({ apiKey: process.env.OPENAI_API_KEY! });const llm = new CachedLLM(baseLLM, new MemoryCache({ maxSize: 500 })); const orka = createOrka({ llm, vectorDB: myVectorDB }); // Récupérateur hybride (BM25 + Vector)const hybrid = new EnsembleRetriever({ retrievers: [ new BM25Retriever({ documents: myDocs, topK: 10 }), new VectorRetriever({ llm, vectorDB: myVectorDB, topK: 10 }) ], weights: [0.3, 0.7], topK: 5}); // Chaîne conversationnelle avec récupérateur hybrideconst chatChain = new ConversationalRetrievalChain({ llm, retriever: hybrid, collection: 'documentation', returnSources: true, maxHistoryLength: 10}); // Gérer la conversation utilisateurasync function handleMessage(userMessage: string) { const result = await chatChain.call(userMessage); return { answer: result.answer, sources: result.sources?.map(s => ({ id: s.id, score: s.score, preview: s.content?.slice(0, 100) })), steps: result.intermediateSteps };} // Résumer de longs documentsconst summarizer = new SummarizationChain({ llm, strategy: 'map-reduce', maxChunkSize: 3000}); async function summarizeDocuments(texts: string[]) { const result = await summarizer.call(texts); return result.answer;}Comparaison
| Moteur de Chaine | Usage Cible | État / Mémoire | Logiques Disponibles |
|---|---|---|---|
RetrievalQA | Q&R unitaire sur documents | Stateless | stuff |
Conversational | Agents de support contextuels | Stateful | stuff |
Summarization | Distillation de contenus massifs | Stateless | stuffmap-reducerefine |
QAChain | Analyse haute-fidélité | Stateless | stuffmap-reducerefine |
Comparaison des Stratégies de Résumé
| Stratégie d'Agrégation | Coût de Calcul | Fidélité de Sortie | Capacité |
|---|---|---|---|
Stuffing | 1LLM Calls | Baseline | Lié au contexte |
Map-Reduce | N + 1LLM Calls | Parallelized | Unlimited |
Refine | N (Sequential)LLM Calls | State-of-the-Art | Unlimited |
💡 Bonnes Pratiques
1. Commencez avec RetrievalQA
Pour la plupart des cas d'usage, RetrievalQAChain suffit. Passez à ConversationalRetrievalChain uniquement quand vous avez besoin de conversations multi-tours.
2. Utilisez la Récupération Hybride
Combinez BM25 + VectorRetriever dans un EnsembleRetriever pour les meilleurs résultats. La correspondance de mots-clés capture les termes exacts que la recherche sémantique pourrait manquer.
3. Surveillez les Étapes Intermédiaires
Utilisez intermediateSteps pour déboguer la qualité de récupération, identifier les étapes lentes et optimiser votre pipeline.
4. Choisissez la Bonne Stratégie de Résumé
Utilisez 'stuff' pour les documents courts (<4K tokens), 'map-reduce' pour le traitement parallèle de gros docs, et 'refine' quand la qualité du résumé est critique.
Imports Tree-shakeable
// ✅ Importez uniquement ce dont vous avez besoinimport { RetrievalQAChain } from '@orka-js/tools';import { ConversationalRetrievalChain } from '@orka-js/tools';import { SummarizationChain } from '@orka-js/tools';import { QAChain } from '@orka-js/tools'; // ✅ Ou importez depuis l'indeximport { RetrievalQAChain, ConversationalRetrievalChain, SummarizationChain, QAChain } from '@orka-js/tools';