Maison > développement back-end > Tutoriel Python > Maîtriser la réponse aux requêtes avec RAG : surmonter les principaux défis liés aux données de réunion à grande échelle

Maîtriser la réponse aux requêtes avec RAG : surmonter les principaux défis liés aux données de réunion à grande échelle

DDD
Libérer: 2024-11-27 03:25:11
original
245 Les gens l'ont consulté

À l’ère numérique de la surcharge d’informations, extraire des informations exploitables à partir de grands ensembles de données est plus crucial que jamais. Récemment, je me suis lancé dans une aventure visant à tirer parti de la génération augmentée par récupération (RAG) pour relever un défi majeur : fournir des réponses précises à partir d'une vaste collection de notes de réunion. Ce blog explore les obstacles, les solutions et les réalisations qui ont transformé mon système de réponse aux requêtes basé sur RAG en un outil robuste pour extraire des informations à partir de données de réunion non structurées.

Énoncé du problème : défis liés à la réponse aux requêtes avec RAG
L’un des principaux défis consistait à créer un système capable de traiter des requêtes complexes et spécifiques à une intention au sein d’un vaste référentiel de notes de réunion. Les modèles de réponse aux requêtes RAG traditionnels renvoyaient fréquemment des informations non pertinentes ou incomplètes, ne parvenant pas à capturer l'intention de l'utilisateur. La nature non structurée des données de réunion combinée à divers types de requêtes a nécessité une solution plus raffinée.

Approche initiale : jeter les bases d'une réponse efficace aux requêtes
J'ai commencé avec un modèle RAG fondamental conçu pour combiner la récupération et la génération de réponses. Les deux techniques initiales utilisées étaient :

  1. Chunking : diviser les documents volumineux en segments plus petits selon les limites des phrases a amélioré la récupération en réduisant la portée de la recherche.

  2. Intégration et stockage vectoriel : Après le découpage, chaque segment a été intégré et stocké dans une base de données vectorielles, permettant des recherches efficaces.

Cependant, cette configuration avait des limites. L'approche de segmentation initiale conduisait souvent à la récupération d'informations non pertinentes, et les réponses générées manquaient de précision et d'alignement avec l'intention de chaque requête.

Défis liés à la réponse aux requêtes RAG à grande échelle

  • Gestion des requêtes complexes : certaines questions complexes nécessitaient une compréhension sémantique plus approfondie au-delà de la recherche sémantique de base.
  • Inadéquations contextuelles : les morceaux récupérés étaient souvent contextuellement similaires mais pas suffisamment précis pour satisfaire les exigences de la requête.
  • Limitations de la précision de la récupération : la récupération d'un petit ensemble de documents (par exemple, cinq à dix) aboutissait souvent à des résultats limités et manquant de pertinence.

Ces défis ont souligné la nécessité d'une approche plus avancée pour améliorer la précision des réponses aux requêtes RAG.

Techniques RAG avancées pour une précision améliorée des requêtes (solution)
Pour résoudre ces problèmes, j'ai appliqué plusieurs méthodologies avancées, affinant le système de manière itérative :
Chunking sémantique
Contrairement au chunking traditionnel, le Semantic Chunking donne la priorité au sens de chaque segment, améliorant ainsi la pertinence en alignant les informations récupérées sur l'intention de la requête.

Mastering Query Answering with RAG: Overcoming Key Challenges in Large-Scale Meeting Data

from langchain_experimental.text_splitter import SemanticChunker
from langchain_openai.embeddings import OpenAIEmbeddings
from langchain.schema import Document

# Initialize OpenAI Embeddings with API key
openai_api_key = ""
embedder = OpenAIEmbeddings(openai_api_key=openai_api_key)
text_splitter = SemanticChunker(embedder)

def prepare_docs_for_indexing(videos):
    all_docs = []

    for video in videos:
        video_id = video.get('video_id')
        title = video.get('video_name')
        transcript_info = video.get('details', {}).get('transcript_info', {})
        summary = video.get('details', {}).get('summary')
        created_at = transcript_info.get('created_at')  # Getting the created_at timestamp

        # Get the full transcription text
        transcription_text = transcript_info.get('transcription_text', '')

        # Create documents using semantic chunking
        docs = text_splitter.create_documents([transcription_text])

        for doc in docs:
            # Add metadata to each document
            doc.metadata = {
                "created_at": created_at,
                "title": title,
                "video_id": video_id,
                "summary": summary
            }
            all_docs.append(doc)

    return all_docs


docs = prepare_docs_for_indexing(videos)

# Output the created documents
for doc in docs:
    print("____________")
    print(doc.page_content)
Copier après la connexion

Récupération de la marge maximale
Cette méthode a amélioré la précision de la récupération en différenciant les données pertinentes et non pertinentes, garantissant que seuls les blocs de données les mieux adaptés ont été récupérés.

Score Lambda
Grâce au Lambda Scoring, j'ai pu classer les résultats en fonction de leur pertinence, en donnant la priorité aux réponses qui correspondaient plus étroitement à l'intention de la requête pour une meilleure qualité de réponse.

from langchain_community.vectorstores import OpenSearchVectorSearch
from langchain_openai import OpenAIEmbeddings

embeddings = OpenAIEmbeddings()

docsearch = OpenSearchVectorSearch.from_documents(
    docs, embeddings, opensearch_url="http://localhost:9200"
)

query = "your query"
docs = docsearch.max_marginal_relevance_search(query, k=2, fetch_k=10, lambda_param=0.25)
Copier après la connexion

Multi-requêtes et fusion RAG
Pour les questions complexes, le système génère plusieurs sous-requêtes. RAG Fusion intègre ensuite diverses réponses en une réponse unique et cohérente, améliorant ainsi la qualité des réponses et réduisant les erreurs.

def generate_multi_queries(question: str):
    # Template to generate multiple queries
    template = """You are an AI language model assistant. Your task is to generate five 
    different versions of the given user question to retrieve relevant documents from a vector 
    database. By generating multiple perspectives on the user question, your goal is to help
    the user overcome some of the limitations of the distance-based similarity search. 
    Provide these alternative questions separated by newlines. Original question: {question}"""

    # Creating a prompt template for query generation
    prompt_perspectives = ChatPromptTemplate.from_template(template)

    # Generate the queries using ChatOpenAI and output parser
    generate_queries = (
        prompt_perspectives 
        | ChatOpenAI(temperature=0, openai_api_key=openai_api_key) 
        | StrOutputParser() 
        | (lambda x: x.split("\n"))
    )

    # Invoke the chain to generate queries
    multi_queries = generate_queries.invoke({"question": question})

    return multi_queries
Copier après la connexion
def reciprocal_rank_fusion(results: list[list], k=60):
    """Applies Reciprocal Rank Fusion (RRF) to fuse ranked document lists."""
    fused_scores = {}
    for docs in results:
        for rank, doc in enumerate(docs):
            doc_str = dumps(doc)  # Convert to a serializable format
            if doc_str not in fused_scores:
                fused_scores[doc_str] = 0
            fused_scores[doc_str] += 1 / (rank + k)  # RRF formula

    # Sort documents by the fused score
    reranked_results = [
        (loads(doc), score)
        for doc, score in sorted(fused_scores.items(), key=lambda x: x[1], reverse=True)
    ]
    return reranked_result
Copier après la connexion

Mastering Query Answering with RAG: Overcoming Key Challenges in Large-Scale Meeting Data

Indexation améliorée et recherche de vecteurs optimisée
L'amélioration du mécanisme d'indexation et l'affinement des paramètres de recherche vectorielle ont rendu la récupération plus rapide et plus précise, en particulier pour les grands ensembles de données.

Résultats : principales réalisations dans la réponse aux requêtes RAG
La mise en œuvre de ces techniques a conduit à des améliorations significatives :

  • Précision de récupération accrue : des techniques telles que le regroupement sémantique et la récupération de marge maximale ont affiné la récupération des données, garantissant que seuls les fragments les plus pertinents ont été renvoyés.
  • Pertinence améliorée : Lambda Scoring a efficacement hiérarchisé les résultats pertinents, en alignant étroitement les réponses sur l'intention de la requête.
  • Gestion améliorée des requêtes complexes : la génération de requêtes multiples et RAG Fusion ont permis au système de gérer des questions complexes, fournissant des réponses complètes.
  • Une plus grande robustesse du système : ces améliorations ont élevé le système d'un modèle de base à un outil de réponse aux requêtes sophistiqué et fiable pour les données de réunion non structurées à grande échelle.

Principaux points à retenir et leçons apprises
Au cours de ce voyage, j'ai identifié plusieurs idées fondamentales :

  1. L'adaptabilité est la clé : des solutions efficaces émergent rarement du premier coup ; l'amélioration itérative et la flexibilité sont essentielles.
  2. Les méthodologies en couches améliorent la robustesse : l'intégration de plusieurs approches (Semantic Chunking, Maximum Margin Retrieval, Lambda Scoring) a créé un système plus solide et plus efficace.
  3. Gestion approfondie des requêtes : la génération multi-requêtes et RAG Fusion ont souligné l'importance de répondre aux questions sous plusieurs angles.
  4. Se concentrer sur la sémantique : mettre l'accent sur la signification des données plutôt que sur la structure seule a considérablement amélioré la précision de la récupération.

Conclusion : perspectives d'avenir pour les systèmes basés sur RAG
L'amélioration des modèles RAG avec des techniques avancées a transformé un système de récupération simple en un outil puissant pour répondre à des requêtes complexes et nuancées. Pour l’avenir, mon objectif est d’incorporer des capacités d’apprentissage en temps réel, permettant au système de s’adapter dynamiquement aux nouvelles données. Cette expérience a approfondi mes compétences techniques et mis en évidence l'importance de la flexibilité, de la concentration sémantique et de l'amélioration itérative dans les systèmes de récupération de données.

Réflexions finales : Un guide pour la mise en œuvre de systèmes RAG avancés
En partageant mon expérience dans la résolution des défis RAG, j'espère offrir un guide pour la mise en œuvre de solutions similaires. Les techniques stratégiques, combinées à un raffinement itératif, ont non seulement résolu des problèmes immédiats, mais ont également jeté une base solide pour les progrès futurs des systèmes de réponse aux requêtes.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal