<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[Han Xiang Choong - Elasticsearch Labs]]></title>
    <description><![CDATA[Articles and tutorials from the Search team at Elastic]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[Han Xiang Choong - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/de/search-labs/author/han-xiang-choong</link>
    </image>
    <link>https://www.elastic.co/de/search-labs/author/han-xiang-choong</link>
    <atom:link href="https://www.elastic.co/de/search-labs/rss/author/han-xiang-choong.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[de]]></language>
    <lastBuildDate>Mon, 28 Sep 2026 12:55:12 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Fortgeschrittene RAG-Techniken Teil 2: Abfragen und Testen]]></title>
    <description><![CDATA[Diskussion und Umsetzung von Techniken zur Steigerung der RAG-Leistung. Teil 2 von 2, mit Schwerpunkt auf Abfragen und Tests einer erweiterten RAG-Pipeline.]]></description>
    <content:encoded><![CDATA[<p><em>Der gesamte Code ist </em><a href="https://github.com/elastic/elasticsearch-labs/tree/advanced-rag-techniques/supporting-blog-content/advanced-rag-techniques"><em>im Searchlabs-Repository im Branch advanced-rag-techniques zu</em></a><em> finden.</em></p><p>Willkommen zu Teil 2 unseres Artikels über fortgeschrittene RAG-Techniken! Im <a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1">ersten Teil dieser Serie</a> haben wir die Datenverarbeitungskomponenten der erweiterten RAG-Pipeline eingerichtet, besprochen und implementiert:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9a4691874a19d8da/6a170b3f47d49c99f22d8a24/72b51ba2ae5e5977b56e5b915674753d6cfd0e56-1440x840.jpg" alt="Fortschrittliche RAG-Pipeline" /><p>In diesem Teil werden wir mit dem Abfragen und Testen unserer Implementierung fortfahren. Kommen wir gleich zur Sache!</p><h3>Inhaltsverzeichnis</h3><ul><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#searching-and-retrieving,-generating-answers">Suchen und Abrufen, Generieren von Antworten</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#enriching-queries-with-synonyms">Anreicherung von Suchanfragen mit Synonymen</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#hyde-hypothetical-document-embedding">HyDE (Hypothetische Dokumenteneinbettung)</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#hybrid-search">Hybrid Search</a></p></li></ul></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#experiments">Experimente</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#summary-of-results">Zusammenfassung der Ergebnisse</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#test-1-who-audits-elastic">Test 1: Wer prüft Elastic?</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#advancedrag">AdvancedRAG</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#simplerag">SimpleRAG</a></p></li></ul></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#test-2--total-revenue-2023">Test 2: Gesamtumsatz 2023</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#advancedrag-1">AdvancedRAG</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#simplerag-1">SimpleRAG</a></p></li></ul></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#test-3-what-product-does-growth-primarily-depend-on-how-much">Test 3: Von welchem Produkt hängt das Wachstum primär ab? Wie viel?</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#advancedrag-2">AdvancedRAG</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#simplerag-2">SimpleRAG</a></p></li></ul></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#test-4-describe-employee-benefit-plan">Test 4: Beschreiben Sie den Mitarbeitervergütungsplan</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#advancedrag-3">AdvancedRAG</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#simplerag-3">SimpleRAG</a></p></li></ul></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#test-5-which-companies-did-elastic-acquire">Test 5: Welche Unternehmen hat Elastic übernommen?</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#advancedrag-4">AdvancedRAG</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#simplerag-4">SimpleRAG</a></p></li></ul></li></ul></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#conclusion">Fazit</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#appendix">Anhang</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#prompts">Eingabeaufforderungen</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#rag-question-answering-prompt">RAG-Frage-Antwort-Aufforderung</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#elastic-query-generator-prompt">Eingabeaufforderung für den Elastic-Abfragegenerator</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#potential-questions-generator-prompt">Mögliche Fragen zur Generierung von Anregungen</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#hyde-generator-prompt">HyDE-Generator-Eingabeaufforderung</a></p></li></ul></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#sample-hybrid-search-query">Beispiel einer hybriden Suchanfrage</a></p></li></ul></li></ul><h2>Suchen und Abrufen, Generieren von Antworten</h2><p>Beginnen wir mit unserer ersten Frage, idealerweise einer Information, die hauptsächlich im Jahresbericht zu finden ist. Wie wäre es mit:</p>Who audits Elastic?"
<p>Nun wenden wir einige unserer Techniken an, um die Abfrage zu verbessern.</p><h3>Anreicherung von Suchanfragen mit Synonymen</h3><p>Zunächst sollten wir die Vielfalt der Abfrageformulierungen erhöhen und sie in eine Form bringen, die sich leicht in eine Elasticsearch-Abfrage verarbeiten lässt. Wir werden GPT-4o zur Hilfe nehmen, um die Abfrage in eine Liste von OR-Klauseln umzuwandeln. Schreiben wir diese Aufgabenstellung auf:</p>
ELASTIC_SEARCH_QUERY_GENERATOR_PROMPT = '''
You are an AI assistant specialized in generating Elasticsearch query strings. Your task is to create the most effective query string for the given user question. This query string will be used to search for relevant documents in an Elasticsearch index.

Guidelines:
1. Analyze the user's question carefully.
2. Generate ONLY a query string suitable for Elasticsearch's match query.
3. Focus on key terms and concepts from the question.
4. Include synonyms or related terms that might be in relevant documents.
5. Use simple Elasticsearch query string syntax if helpful (e.g., OR, AND).
6. Do not use advanced Elasticsearch features or syntax.
7. Do not include any explanations, comments, or additional text.
8. Provide only the query string, nothing else.

For the question "What is Clickthrough Data?", we would expect a response like:
clickthrough data OR click-through data OR click through rate OR CTR OR user clicks OR ad clicks OR search engine results OR web analytics

AND operator is not allowed. Use only OR.

User Question:
[The user's question will be inserted here]

Generate the Elasticsearch query string:
'''
<p>Bei Anwendung auf unsere Anfrage generiert GPT-4o Synonyme der Basisanfrage und verwandtes Vokabular.</p>'audits elastic OR 
elasticsearch audits OR 
elastic auditor OR 
elasticsearch auditor OR 
elastic audit firm OR 
elastic audit company OR 
elastic audit organization OR 
elastic audit service'
<p>In der Klasse <code>ESQueryMaker</code> habe ich eine Funktion definiert, um die Abfrage aufzuteilen:</p>def parse_or_query(self, query_text: str) -&gt; List[str]:
    # Split the query by 'OR' and strip whitespace from each term
    # This converts a string like "term1 OR term2 OR term3" into a list ["term1", "term2", "term3"]
    return [term.strip() for term in query_text.split(' OR ')]
<p>Seine Aufgabe besteht darin, diese Kette von ODER-Klauseln in eine Liste von Begriffen aufzuteilen, um uns eine Mehrfachübereinstimmung unserer wichtigsten Dokumentfelder zu ermöglichen:</p>["original_text", 'keyphrases', 'potential_questions', 'entities']
<p>Schließlich komme ich zu folgender Anfrage:</p> 'query': {
    'bool': {
        'must': [
            {
                'multi_match': {
                'query': 'audits Elastic Elastic auditing Elastic audit process Elastic compliance Elastic security audit Elasticsearch auditing Elasticsearch compliance Elasticsearch security audit',
                'fields': [
                    'original_text',
                'keyphrases',
                'potential_questions',
                'entities'
                ],
                'type': 'best_fields',
                'operator': 'or'
                }
            }
      ]
<p>Dies deckt wesentlich mehr Aspekte ab als die ursprüngliche Anfrage und verringert hoffentlich das Risiko, ein Suchergebnis zu verpassen, weil wir ein Synonym vergessen haben. Aber wir können mehr tun.</p><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#table-of-contents">Zurück nach oben</a></p><h3>HyDE (Hypothetische Dokumenteneinbettung)</h3><p>Lassen Sie uns GPT-4o erneut einsetzen, diesmal zur Implementierung <a href="https://arxiv.org/abs/2212.10496">von HyDE</a>.</p><p>Die Grundidee von HyDE besteht darin, ein hypothetisches Dokument zu generieren – also ein Dokument, das wahrscheinlich die Antwort auf die ursprüngliche Anfrage enthält. Die sachliche Richtigkeit oder Genauigkeit des Dokuments ist nicht von Belang. Vor diesem Hintergrund formulieren wir nun die folgende Aufgabenstellung:</p>HYDE_DOCUMENT_GENERATOR_PROMPT = '''
You are an AI assistant specialized in generating hypothetical documents based on user queries. Your task is to create a detailed, factual document that would likely contain the answer to the user's question. This hypothetical document will be used to enhance the retrieval process in a Retrieval-Augmented Generation (RAG) system.

Guidelines:
1. Carefully analyze the user's query to understand the topic and the type of information being sought.
2. Generate a hypothetical document that:
   a. Is directly relevant to the query
   b. Contains factual information that would answer the query
   c. Includes additional context and related information
   d. Uses a formal, informative tone similar to an encyclopedia or textbook entry
3. Structure the document with clear paragraphs, covering different aspects of the topic.
4. Include specific details, examples, or data points that would be relevant to the query.
5. Aim for a document length of 200-300 words.
6. Do not use citations or references, as this is a hypothetical document.
7. Avoid using phrases like "In this document" or "This text discusses" - write as if it's a real, standalone document.
8. Do not mention or refer to the original query in the generated document.
9. Ensure the content is factual and objective, avoiding opinions or speculative information.
10. Output only the generated document, without any additional explanations or meta-text.

User Question:
[The user's question will be inserted here]

Generate a hypothetical document that would likely contain the answer to this query:
'''
<p>Da die Vektorsuche typischerweise mit der Kosinusvektorähnlichkeit arbeitet, besteht die Prämisse von HyDE darin, dass wir bessere Ergebnisse erzielen können, indem wir Dokumente mit Dokumenten abgleichen, anstatt Anfragen mit Dokumenten abzugleichen.</p><p>Uns geht es um Struktur, Ablauf und Terminologie. Nicht so sehr die Fakten. GPT-4o erzeugt ein HyDE-Dokument wie dieses:</p>'Elastic N.V., the parent company of Elastic, the organization known for developing Elasticsearch, is subject to audits to ensure financial accuracy, 
regulatory compliance, and the integrity of its financial statements. The auditing of Elastic N.V. is typically conducted by an external, 
independent auditing firm. This is common practice for publicly traded companies to provide stakeholders with assurance regarding the company\'s 
financial position and operations.\n\nThe primary external auditor for Elastic is the audit firm Ernst &amp; Young LLP (EY). Ernst &amp; Young is one of the 
four largest professional services networks in the world, commonly referred to as the "Big Four" audit firms. These firms handle a substantial number 
of audits for major corporations around the globe, ensuring adherence to generally accepted accounting principles (GAAP) and international financial 
reporting standards (IFRS).\n\nThe audit process conducted by EY involves several steps. Initially, the auditors perform a risk assessment to identify 
areas where misstatements due to error or fraud could occur. They then design audit procedures to test the accuracy and completeness of financial statements,
 which include examining financial transactions, assessing internal controls, and reviewing compliance with relevant laws and regulations. Upon completion of 
 the audit, Ernst &amp; Young issues an audit report, which includes the auditor’s opinion on whether the financial statements are free from material misstatement 
 and are presented fairly in accordance with the applicable financial reporting framework.\n\nIn addition to external audits by firms like Ernst &amp; Young, 
 Elastic may also be subject to internal audits. Internal audits are performed by the company’s own internal auditors to evaluate the effectiveness of internal 
 controls, risk management, and governance processes.\n\nOverall, the auditing process plays a crucial role in maintaining the transparency and reliability of 
 Elastic\'s financial information, providing confidence to investors, regulators, and other stakeholders.'
<p>Es sieht ziemlich glaubwürdig aus, wie der ideale Kandidat für die Art von Dokumenten, die wir indexieren möchten. Wir werden dies einbetten und für die hybride Suche verwenden.</p><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#table-of-contents">Zurück nach oben</a></p><h3>Hybrid Search</h3><p>Dies ist der Kern unserer Suchlogik. Unsere lexikalische Suchkomponente besteht aus den generierten OR-Klauselzeichenketten. Unsere dichte Vektorkomponente wird das eingebettete HyDE-Dokument (auch Suchvektor genannt) sein. Wir verwenden KNN, um effizient mehrere Kandidatendokumente zu identifizieren, die unserem Suchvektor am nächsten liegen. Unsere lexikalische Suchkomponente nennen wir standardmäßig <em>Scoring mit TF-IDF und BM25</em> . Schließlich werden die lexikalischen und dichten Vektorwerte unter Verwendung des von <a href="https://arxiv.org/abs/2407.01219">Wang et al</a>. empfohlenen Verhältnisses von 30/70 kombiniert.</p>def hybrid_vector_search(self, index_name: str, query_text: str, query_vector: List[float], 
                         text_fields: List[str], vector_field: str, 
                         num_candidates: int = 100, num_results: int = 10) -&gt; Dict:
    """
    Perform a hybrid search combining text-based and vector-based similarity.

    Args:
        index_name (str): The name of the Elasticsearch index to search.
        query_text (str): The text query string, which may contain 'OR' separated terms.
        query_vector (List[float]): The query vector for semantic similarity search.
        text_fields (List[str]): List of text fields to search in the index.
        vector_field (str): The name of the field containing document vectors.
        num_candidates (int): Number of candidates to consider in the initial KNN search.
        num_results (int): Number of final results to return.

    Returns:
        Dict: A tuple containing the Elasticsearch response and the search body used.
    """
    try:
        # Parse the query_text into a list of individual search terms
        # This splits terms separated by 'OR' and removes any leading/trailing whitespace
        query_terms = self.parse_or_query(query_text)

        # Construct the search body for Elasticsearch
        search_body = {
            # KNN search component for vector similarity
            "knn": {
                "field": vector_field,  # The field containing document vectors
                "query_vector": query_vector,  # The query vector to compare against
                "k": num_candidates,  # Number of nearest neighbors to retrieve
                "num_candidates": num_candidates  # Number of candidates to consider in the KNN search
            },
            "query": {
                "bool": {
                    # The 'must' clause ensures that matching documents must satisfy this condition
                    # Documents that don't match this clause are excluded from the results
                    "must": [
                        {
                            # Multi-match query to search across multiple text fields
                            "multi_match": {
                                "query": " ".join(query_terms),  # Join all query terms into a single space-separated string
                                "fields": text_fields,  # List of fields to search in
                                "type": "best_fields",  # Use the best matching field for scoring
                                "operator": "or"  # Match any of the terms (equivalent to the original OR query)
                            }
                        }
                    ],
                    # The 'should' clause boosts relevance but doesn't exclude documents
                    # It's used here to combine vector similarity with text relevance
                    "should": [
                        {
                            # Custom scoring using a script to combine vector and text scores
                            "script_score": {
                                "query": {"match_all": {}},  # Apply this scoring to all documents that matched the 'must' clause
                                "script": {
                                    # Script to combine vector similarity and text relevance
                                    "source": """
                                    # Calculate vector similarity (cosine similarity + 1)
                                    # Adding 1 ensures the score is always positive
                                    double vector_score = cosineSimilarity(params.query_vector, params.vector_field) + 1.0;
                                    # Get the text-based relevance score from the multi_match query
                                    double text_score = _score;
                                    # Combine scores: 70% vector similarity, 30% text relevance
                                    # This weighting can be adjusted based on the importance of semantic vs keyword matching
                                    return 0.7 * vector_score + 0.3 * text_score;
                                    """,
                                    # Parameters passed to the script
                                    "params": {
                                        "query_vector": query_vector,  # Query vector for similarity calculation
                                        "vector_field": vector_field  # Field containing document vectors
                                    }
                                }
                            }
                        }
                    ]
                }
            }
        }

        # Execute the search request against the Elasticsearch index
        response = self.conn.search(index=index_name, body=search_body, size=num_results)
        # Log the successful execution of the search for monitoring and debugging
        logger.info(f"Hybrid search executed on index: {index_name} with text query: {query_text}")
        # Return both the response and the search body (useful for debugging and result analysis)
        return response, search_body
    except Exception as e:
        # Log any errors that occur during the search process
        logger.error(f"Error executing hybrid search on index: {index_name}. Error: {e}")
        # Re-raise the exception for further handling in the calling code
        raise e
<p>Schließlich können wir eine RAG-Funktion zusammensetzen. Unser Ampelsystem, von der Anfrage bis zur Antwort, folgt diesem Ablauf:</p><ol><li><p>Konvertiere die Abfrage in OR-Klauseln.</p></li><li><p>Generieren Sie ein HyDE-Dokument und betten Sie es ein.</p></li><li><p>Übergeben Sie beide Werte als Eingaben an die Hybridsuche.</p></li><li><p>Die Top-n-Ergebnisse abrufen und umkehren, sodass die relevanteste Bewertung im Kontextspeicher des LLM als „aktuellste“ angezeigt wird (Reverse Packing). Beispiel für Reverse Packing: Anfrage: „Elasticsearch-Abfrageoptimierungstechniken“. Abgerufene Dokumente (sortiert nach Relevanz): Umgekehrte Reihenfolge für den LLM-Kontext: Durch die Umkehrung der Reihenfolge erscheint die relevanteste Information (1) zuletzt im Kontext und erhält potenziell mehr Aufmerksamkeit vom LLM bei der Antwortgenerierung.</p><ol><li><p>„Verwenden Sie Boolesche Abfragen, um mehrere Suchkriterien effizient zu kombinieren.“</p></li><li><p>„Implementieren Sie Caching-Strategien, um die Antwortzeiten von Abfragen zu verbessern.“</p></li><li><p>„Indexzuordnungen für schnellere Suchleistung optimieren.“</p></li><li><p>„Indexzuordnungen für schnellere Suchleistung optimieren.“</p></li><li><p>„Implementieren Sie Caching-Strategien, um die Antwortzeiten von Abfragen zu verbessern.“</p></li><li><p>„Verwenden Sie Boolesche Abfragen, um mehrere Suchkriterien effizient zu kombinieren.“</p></li></ol></li><li><p>Übergeben Sie den Kontext zur Generierung an das LLM.</p></li></ol>def get_context(index_name, 
                match_query, 
                text_query, 
                fields, 
                num_candidates=100, 
                num_results=20, 
                text_fields=["original_text", 'keyphrases', 'potential_questions', 'entities'], 
                embedding_field="primary_embedding"):

    embedding=embedder.get_embeddings_from_text(text_query)

    results, search_body = es_query_maker.hybrid_vector_search(
        index_name=index_name,
        query_text=match_query,
        query_vector=embedding[0][0],
        text_fields=text_fields,
        vector_field=embedding_field,
        num_candidates=num_candidates,
        num_results=num_results
    )

    # Concatenates the text in each 'field' key of the search result objects into a single block of text.
    context_docs=['\n\n'.join([field+":\n\n"+j['_source'][field] for field in fields]) for j in results['hits']['hits']]

    # Reverse Packing to ensure that the highest ranking document is seen first by the LLM.
    context_docs.reverse()
    return context_docs, search_body

def retrieval_augmented_generation(query_text):
    match_query= gpt4o.generate_query(query_text)
    fields=['original_text']

    hyde_document=gpt4o.generate_HyDE(query_text)

    context, search_body=get_context(index_name, match_query, hyde_document, fields)

    answer= gpt4o.basic_qa(query=query_text, context=context)
    return answer, match_query, hyde_document, context, search_body

<p>Führen wir unsere Abfrage aus und erhalten wir die Antwort:</p>According to the context, Elastic N.V. is audited by an independent registered public accounting firm, PricewaterhouseCoopers (PwC). 
This information is found in the section titled "report of independent registered public accounting firm," which states:

"We have audited the accompanying consolidated balance sheets of Elastic N.V. [...] / s / pricewaterhouseco."
<p>Hübsch. Das ist richtig.</p><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#table-of-contents">Zurück nach oben</a></p><h2>Experimente</h2><p>Jetzt gilt es, eine wichtige Frage zu beantworten. Was hat uns der immense Aufwand und die zusätzliche Komplexität dieser Implementierungen gebracht?</p><p>Lasst uns einen kleinen Vergleich anstellen. Die von uns implementierte RAG-Pipeline im Vergleich zur hybriden Basissuche, ohne die von uns vorgenommenen Verbesserungen. Wir werden eine kleine Testreihe durchführen und sehen, ob wir wesentliche Unterschiede feststellen. Wir werden das soeben implementierte RAG-Schema als AdvancedRAG und die Basispipeline als SimpleRAG bezeichnen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf605c8246989df32/6a1711178b73cbc61d18a11d/8da40067835ab8b4dc12fe52a51a6c26858ad32f-1440x1095.jpg" alt="Einfache RAG-Pipeline" /><h4>Zusammenfassung der Ergebnisse</h4><p>Diese Tabelle fasst die Ergebnisse von fünf Tests beider RAG-Pipelines zusammen. Ich habe die relative Überlegenheit der einzelnen Methoden anhand der Detailtiefe und Qualität der Antworten beurteilt, aber dies ist eine rein subjektive Einschätzung. Die tatsächlichen Antworten sind unterhalb dieser Tabelle zu Ihrer Information aufgeführt. Nach dieser Vorrede schauen wir uns nun an, wie sie abgeschnitten haben!</p><p>SimpleRAG konnte die Fragen 1 und 5 nicht beantworten. AdvancedRAG ging bei den Fragen 2, 3 und 4 wesentlich detaillierter vor. Aufgrund der detaillierteren Antworten beurteilte ich die Qualität der Antworten von AdvancedRAG als besser.</p><p>Prüfen</p><p>Frage</p><p>AdvancedRAG-Leistung</p><p>SimpleRAG Performance</p><p>Erweiterte RAG-Latenz</p><p>SimpleRAG-Latenz</p><p>Gewinner</p><p>1</p><p>Wer prüft Elastic?</p><p>PwC wurde korrekt als Wirtschaftsprüfer identifiziert.</p><p>Der Prüfer konnte nicht identifiziert werden.</p><p>11,6 Sekunden</p><p>4,4 Sekunden</p><p>AdvancedRAG</p><p>2</p><p>Wie hoch waren die Gesamteinnahmen im Jahr 2023?</p><p>Die korrekte Umsatzzahl wurde angegeben. Zusätzliche Kontextinformationen wurden mit Umsatzzahlen aus den Vorjahren hinzugefügt.</p><p>Die korrekte Umsatzzahl wurde angegeben.</p><p>13,3 Sekunden</p><p>2,8 Sekunden</p><p>AdvancedRAG</p><p>3</p><p>Von welchem Produkt hängt das Wachstum primär ab? Wie viel?</p><p>Elastic Cloud wurde korrekt als Haupttreiber identifiziert. Beinhaltete den Gesamtkontext der Einnahmen und detailliertere Informationen.</p><p>Elastic Cloud wurde korrekt als Haupttreiber identifiziert.</p><p>14,1 Sekunden</p><p>12,8 Sekunden</p><p>AdvancedRAG</p><p>4</p><p>Beschreibung des Mitarbeitervergütungsprogramms</p><p>Gab eine umfassende Beschreibung der Altersvorsorgepläne, Gesundheitsprogramme und sonstigen Leistungen. Enthält spezifische Beitragsbeträge für verschiedene Jahre.</p><p>Es wurde ein guter Überblick über die Leistungen gegeben, einschließlich Vergütung, Altersvorsorgepläne, Arbeitsumfeld und das Elastic Cares-Programm.</p><p>26,6 Sekunden</p><p>11,6 Sekunden</p><p>AdvancedRAG</p><p>5</p><p>Welche Unternehmen hat Elastic übernommen?</p><p>Die im Bericht erwähnten kürzlich erfolgten Akquisitionen (CmdWatch, Build Security, Optimyze) wurden korrekt aufgeführt. Es wurden einige Anschaffungsdaten und Kaufpreise angegeben.</p><p>Es konnten keine relevanten Informationen aus dem bereitgestellten Kontext abgerufen werden.</p><p>11,9 Sekunden</p><p>2,7 Sekunden</p><p>AdvancedRAG</p><h4>Test 1: Wer prüft Elastic?</h4><p>AdvancedRAG</p>According to the context, Elastic N.V. is audited by an independent 
registered public accounting firm, PricewaterhouseCoopers (PwC). 
This information is found in the section titled "report of 
independent registered public accounting firm," which states:
"We have audited the accompanying consolidated balance sheets 
of Elastic N.V. [...] / s / pricewaterhouseco."
<p>SimpleRAG</p>According to the provided context, no specific auditing firm 
or company is mentioned as the auditor for Elastic. 
The context provided talks about various features, strengths, 
deployment options, and other details related to Elastic and 
its operations but does not specify which auditing firm is 
responsible for auditing Elastic's financial statements or 
internal controls.
<p><strong>Zusammenfassung</strong>: SimpleRAG hat PwC nicht als Wirtschaftsprüfer identifiziert.</p><p>Okay, das ist tatsächlich ziemlich überraschend. Das sieht nach einem Suchfehler seitens SimpleRAG aus. Es wurden keine Dokumente im Zusammenhang mit der Wirtschaftsprüfung gefunden. Lasst uns den Schwierigkeitsgrad beim nächsten Test etwas reduzieren.</p><h4>Test 2: Gesamtumsatz 2023</h4><p>AdvancedRAG</p>### Total Revenue for 2023

According to the provided context, the total revenue for the 
year ended April 30, 2023, was **$1,068,989,000**. This 
information can be found several times in the provided text. 
Specifically, one part states:

"The following table sets forth our results of operations 
for the periods presented in dollars and as a percentage of 
our total revenue. ... year ended April 30, 2023, ... 
total revenue 1,068,989".

Additionally, it is mentioned here as well:

"For the years ended April 30, 2023, 2022, and 2021, 
representing year-over-year growth of 24% for the year 
ended April 30, 2023... total revenue $1,068,989".

Therefore, the total revenue for 2023 is $1.069 billion.
<p>SimpleRAG</p>According to the context provided, the total revenue for the fiscal year ended April 30, 2023, is:

$1,068,989,000 (or approximately $1.1 billion).
<p><strong>Zusammenfassung</strong>: Beide RAGs haben die richtige Antwort gegeben: 1.068.989.000 US-Dollar Gesamtumsatz im Jahr 2023</p><p>Beide waren genau hier. Es scheint, als ob AdvancedRAG ein breiteres Spektrum an Dokumenten erworben hat. Die Antwort ist sicherlich detaillierter und berücksichtigt auch Informationen aus den Vorjahren. Das war angesichts der von uns vorgenommenen Verbesserungen zu erwarten, aber es ist viel zu früh, um das zu beurteilen.</p><p>Erhöhen wir den Schwierigkeitsgrad.</p><h4>Test 3: Von welchem Produkt hängt das Wachstum primär ab? Wie viel?</h4><p>AdvancedRAG</p>### Product Growth Primarily Depends On:
According to the context, "our revenue is derived primarily from 
subscriptions of search, observability and security built into 
the elastic stack." The document mentions various strategies and 
factors contributing to the company’s growth which include investment 
in "elastic cloud," "elastic stack," and the conversion of free 
users to paid subscribers.

### Quantitative Data:
- **Revenue**: The document states, "Our total revenue was $1.1 billion, 
$862.4 million, and $608.5 million for the years ended April 30, 2023, 
2022, and 2021, respectively."
- **Subscription Revenue**: "Subscriptions accounted for 92%, 93%, 
and 93% of our total revenue for the years ended April 30, 2023, 
2022, and 2021, respectively."
- **Elastic Cloud Contribution**: "For the years ended April 30, 2023, 
2022, and 2021, Elastic Cloud contributed 40%, 35%, and 27% of our 
total revenue, respectively."
- **Customer Growth**: The number of customers increased from 
"over 15,000 as of April 30, 2021," to "approximately 20,200 as of 
April 30, 2023."

### Summary:
Product growth for the company primarily depends on the "Elastic Stack" 
(which includes search, observability, and security solutions) and 
particularly the "Elastic Cloud." The Elastic Cloud's growing contribution 
to revenue highlights its significance, which grew from 27% in 2021 to 40% in 2023.
<p>SimpleRAG</p>According to the provided context, growth primarily depends on **Elastic Cloud**, 
which is described as the company's "family of cloud-based offerings." 
The context also emphasizes the significance of Elastic Cloud in achieving 
the company's long-term growth potential and its role in increasing subscription revenue.

From the context:

- "Increasing adoption of Elastic Cloud... is an important growth opportunity 
for our business. Organizations are increasingly looking for hosted 
deployment alternatives with reduced administrative burdens."
- "We believe that offering Elastic Cloud is important for achieving 
our long-term growth potential, and we expect Elastic Cloud’s contribution 
to our subscription revenue to continue to increase."

In terms of the contribution to total revenue, here are the specific figures provided:

- Elastic Cloud contributed 40% of the total revenue for the year ended April 30, 2023.
- Elastic Cloud contributed 35% of the total revenue for the year ended April 30, 2022.
- Elastic Cloud contributed 27% of the total revenue for the year ended April 30, 2021.

This progression shows a clear upward trend in the importance and 
contribution of Elastic Cloud to the company's overall revenue.
<p><strong>Zusammenfassung</strong>: Beide RAG-Modelle haben Elastic Cloud korrekt als wichtigsten Wachstumstreiber identifiziert. AdvancedRAG hingegen enthält mehr Details, berücksichtigt Abonnementumsätze und Kundenwachstum und erwähnt explizit andere Elastic-Angebote.</p><h4>Test 4: Beschreiben Sie den Mitarbeitervergütungsplan</h4><p>AdvancedRAG</p>### Employee Benefit Plan Overview

The provided context outlines various elements of the employee benefit plan at 
Elastic, often referred to as "Elasticians." Here are the key components 
described in the texts:

1. **401(k) Plan**:
   - **Coverage**: The 401(k) plan is available to substantially all U.S. 
   employees who meet minimum age and service requirements.
   - **Contributions**: Elastic makes contributions to the 401(k) plan up to 
   6% of the participating employee’s W-2 earnings and wages.
   - **Expenses**: For the fiscal years ended April 30, Elastic recorded 
   expenses of $17.9 million (2023), $15.2 million (2022), and $11.4 million (2021) 
   related to the 401(k) plan.
   - **Defined-Contribution Plans in Other Countries**: Elastic has 
   defined-contribution plans in various other countries and recorded respective 
   expenses of $9.4 million (2023), $7.2 million (2022), and $5.1 million (2021).

2. **Stock-Based Compensation**:
   - **Types of Awards**: Stock options, restricted stock units (RSUs), 
   and shares under the Employee Stock Purchase Plan (ESPP).
   - **Fair Value Measurement**: Fair value of these stock awards is 
   measured using models like Black-Scholes.
   - **Employee Stock Purchase Plan (2022 ESPP)**: 
     - Started in 2022, it allows employees to acquire ordinary 
     shares at a discount (85% of the market value at the beginning 
     or end of the offering period).
     - Offering periods are approximately six months long.

3. **Total Rewards Compensation**:
   - **Components**: Includes cash compensation as well as equity awards, 
   reflecting a comprehensive interest in the well-being of the employees.
   - **Programs**: Market competitive medical and dental programs, 
   mental health, and holistic well-being programs.
   - **Paid Time Off**: Features 16 weeks of paid leave for new 
   parents and life-planning benefits.

4. **Retirement and Income Protection Plans**:
   - **401(k) Match**: Elastic provides a dollar-for-dollar 
   match up to 6% of eligible earnings up to a plan-limit 
   maximum for U.S.-based employees.
   - **Similar Plans Outside the U.S.**: Competitive retirement 
   plans available for employees based outside the United States.

5. **Flexible Work Environment**: 
   - **Distributed Workforce**: Elastic operates with a global 
   distributed workforce model, allowing employees to work remotely 
   and providing a broad candidate pool.
   
6. **Learning and Development**:
   - **Programs**: Access to on-demand video-based learning, 
   leadership development programs, and other specific training 
   to develop managers and leaders.

7. **Employee Engagement and Surveys**:
   - **Mechanisms**: Annual employee engagement survey and 
   mid-year pulse survey.
   - **Objectives**: To monitor morale, develop action plans, 
   and maintain high engagement scores.

8. **Onboarding Program**:
   - **X-School**: An extensive new-hire orientation program to 
   help new employees meet peers and learn about the company's 
   products and solutions.

In summary, Elastic's employee benefit plan encompasses a broad 
spectrum of financial, health, well-being, and professional development 
benefits designed to support and enhance the lives of its employees. 
The plan is both competitive and comprehensive, aiming to attract,
retain, and engage its global workforce.
<p>SimpleRAG</p>The employee benefit plan at the Company includes several key 
components aimed at enhancing the overall well-being and 
professional development of employees, referred to as "Elasticians." 

1. **Compensation and Benefits:**
   - The Company provides market-competitive compensation 
   packages which typically include cash compensation and equity awards.
   - Comprehensive medical and dental programs are offered, 
   emphasizing mental health and holistic well-being.
   - Paid time off programs feature:
     - 16 weeks of paid leave for new parents.
     - Life-planning benefits.
     - Travel reimbursements for certain healthcare services.

2. **Retirement and Income Protection Plans:**
   - In the United States, employees are eligible for a 401k 
   plan with a dollar-for-dollar match by the Company up to 6% 
   of eligible earnings, subject to a plan limit.
   - Similar competitive retirement and income protection plans 
   are available for employees outside the United States.

3. **Work Environment:**
   - The Company offers a flexible work environment, allowing most 
   employees to work from anywhere as often as they would like.
   - Physical offices around the world are available for employees 
   who prefer to work on-site or need a space for face-to-face interactions.

4. **Community Involvement:**
   - The Elastic Cares Program supports charitable organizations 
   that matter to employees on both local and global levels.
   - The program includes:
     - Donation matching.
     - Providing the Company's technology for free to certain 
     nonprofit organizations.
     - Volunteer time off initiative.
<p><strong>Zusammenfassung</strong>: AdvancedRAG geht wesentlich tiefer und detaillierter darauf ein und erwähnt den 401K-Plan für in den USA ansässige Mitarbeiter sowie die Beitragspläne außerhalb der USA. Es werden auch Gesundheits- und Wohlbefindenspläne erwähnt, das Programm Elastic Cares, das SimpleRAG erwähnt, wird jedoch nicht aufgeführt.</p><h4>Test 5: Welche Unternehmen hat Elastic übernommen?</h4><p>AdvancedRAG</p>Elastic acquired several companies over the years to enhance its 
technology and market presence. According to the provided context, 
the specific acquisitions include:

1. **CmdWatch Security Inc.**: Acquired on September 17, 2021. 
The total purchase consideration was $77.8 million.
2. **Build Security Ltd.**: Acquired on September 2, 2021. The 
combined purchase price for Build Security Ltd. and another acquisition was $57.2 million.
3. **Optimyze Cloud Inc.**: Acquired on November 1, 2021. Part 
of the combined purchase price mentioned above with Build Security Ltd.
4. **Endgame, Inc.**: Although the context mentions an amended 
and restated stock incentive plan, it indicates that Endgame, Inc. was 
associated with Elastic, suggesting it could have been acquired at some point.

These acquisitions are part of Elastic's strategy to 
enhance the technology underlying its security and 
observability offerings.
<p>SimpleRAG</p>The provided context does not specify any companies that Elastic has acquired. 
Therefore, based on the context, there is no information available about the companies acquired by Elastic.
<p><strong>Zusammenfassung</strong>: SimpleRAG liefert keine relevanten Informationen zu Akquisitionen, was zu einer fehlerhaften Antwort führt. AdvancedRAG listet CmdWatch, Build Security und Optimyze korrekt auf; dies waren die im Bericht genannten wichtigsten Akquisitionen.</p><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#table-of-contents">Zurück nach oben</a></p><h2>Fazit</h2><p>Unsere Tests ergaben, dass unsere fortschrittlichen Techniken den Umfang und die Tiefe der präsentierten Informationen erhöhen und dadurch potenziell die Qualität der RAG-Antworten verbessern.</p><p>Darüber hinaus könnten Verbesserungen bei der Zuverlässigkeit erzielt werden, da mehrdeutig formulierte Fragen wie <code>Which companies did Elastic acquire?</code> und <code>Who audits Elastic</code> von AdvancedRAG korrekt beantwortet wurden, nicht aber von SimpleRAG.</p><p>Allerdings sollte man bedenken, dass in 3 von 5 Fällen die grundlegende RAG-Pipeline, die die Hybridsuche, aber keine anderen Techniken einbezog, Antworten lieferte, die den Großteil der wichtigsten Informationen erfassten.</p><p>Es ist zu beachten, dass die Latenz von AdvancedRAG aufgrund der Einbeziehung von LLMs in den Phasen der Datenaufbereitung und -abfrage im Allgemeinen 2- bis 5-mal größer ist als die von SimpleRAG. Dies stellt einen erheblichen Kostenfaktor dar, der AdvancedRAG möglicherweise nur für Situationen geeignet macht, in denen die Antwortqualität Vorrang vor der Latenz hat.</p><p>Die erheblichen Latenzkosten können durch den Einsatz eines kleineren und kostengünstigeren LLM wie Claude Haiku oder GPT-4o-mini in der Datenaufbereitungsphase verringert werden. Die fortgeschrittenen Modelle werden für die Antwortgenerierung verwendet.</p><p>Dies steht im Einklang mit den Ergebnissen von Wang et al. Wie ihre Ergebnisse zeigen, sind alle erzielten Verbesserungen relativ geringfügig. Kurz gesagt, mit einer einfachen RAG-Basislinie kommt man schon fast zu einem brauchbaren Endprodukt und ist dabei auch noch günstiger und schneller. Für mich ist das ein interessantes Ergebnis. Für Anwendungsfälle, in denen Geschwindigkeit und Effizienz im Vordergrund stehen, ist SimpleRAG die vernünftige Wahl. Für Anwendungsfälle, in denen jedes letzte Quäntchen Leistung herausgeholt werden muss, könnten die in AdvancedRAG integrierten Techniken einen vielversprechenden Ansatz bieten.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt56b7067a9d41d5a8/6a171119acf0886fb4be9c45/ea811706b6adc4731d90b925a9fefa0ac15901b4-1440x1060.jpg" alt="Wang-Pipeline" /><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2#table-of-contents">Zurück nach oben</a></p><h2>Anhang</h2><h3>Eingabeaufforderungen</h3><h4>RAG-Frage-Antwort-Aufforderung</h4><p>Aufforderung an das LLM, Antworten basierend auf Anfrage und Kontext zu generieren.</p>BASIC_RAG_PROMPT = '''
You are an AI assistant tasked with answering questions based primarily on the provided context, while also drawing on your own knowledge when appropriate. Your role is to accurately and comprehensively respond to queries, prioritizing the information given in the context but supplementing it with your own understanding when beneficial. Follow these guidelines:

1. Carefully read and analyze the entire context provided.
2. Primarily focus on the information present in the context to formulate your answer.
3. If the context doesn't contain sufficient information to fully answer the query, state this clearly and then supplement with your own knowledge if possible.
4. Use your own knowledge to provide additional context, explanations, or examples that enhance the answer.
5. Clearly distinguish between information from the provided context and your own knowledge. Use phrases like "According to the context..." or "The provided information states..." for context-based information, and "Based on my knowledge..." or "Drawing from my understanding..." for your own knowledge.
6. Provide comprehensive answers that address the query specifically, balancing conciseness with thoroughness.
7. When using information from the context, cite or quote relevant parts using quotation marks.
8. Maintain objectivity and clearly identify any opinions or interpretations as such.
9. If the context contains conflicting information, acknowledge this and use your knowledge to provide clarity if possible.
10. Make reasonable inferences based on the context and your knowledge, but clearly identify these as inferences.
11. If asked about the source of information, distinguish between the provided context and your own knowledge base.
12. If the query is ambiguous, ask for clarification before attempting to answer.
13. Use your judgment to determine when additional information from your knowledge base would be helpful or necessary to provide a complete and accurate answer.

Remember, your goal is to provide accurate, context-based responses, supplemented by your own knowledge when it adds value to the answer. Always prioritize the provided context, but don't hesitate to enhance it with your broader understanding when appropriate. Clearly differentiate between the two sources of information in your response.

Context:
[The concatenated documents will be inserted here]

Query:
[The user's question will be inserted here]

Please provide your answer based on the above guidelines, the given context, and your own knowledge where appropriate, clearly distinguishing between the two:
'''
<h4>Eingabeaufforderung für den Elastic-Abfragegenerator</h4><p>Aufforderung zur Anreicherung von Abfragen mit Synonymen und deren Umwandlung in das OR-Format.</p>ELASTIC_SEARCH_QUERY_GENERATOR_PROMPT = '''
You are an AI assistant specialized in generating Elasticsearch query strings. Your task is to create the most effective query string for the given user question. This query string will be used to search for relevant documents in an Elasticsearch index.

Guidelines:
1. Analyze the user's question carefully.
2. Generate ONLY a query string suitable for Elasticsearch's match query.
3. Focus on key terms and concepts from the question.
4. Include synonyms or related terms that might be in relevant documents.
5. Use simple Elasticsearch query string syntax if helpful (e.g., OR, AND).
6. Do not use advanced Elasticsearch features or syntax.
7. Do not include any explanations, comments, or additional text.
8. Provide only the query string, nothing else.

For the question "What is Clickthrough Data?", we would expect a response like:
clickthrough data OR click-through data OR click through rate OR CTR OR user clicks OR ad clicks OR search engine results OR web analytics

AND operator is not allowed. Use only OR.

User Question:
[The user's question will be inserted here]

Generate the Elasticsearch query string:
'''
<h4>Mögliche Fragen zur Generierung von Anregungen</h4><p>Anregung zur Generierung potenzieller Fragen, Anreicherung der Dokumentmetadaten.</p>RAG_QUESTION_GENERATOR_PROMPT = '''
You are an AI assistant specialized in generating questions for Retrieval-Augmented Generation (RAG) systems. Your task is to analyze a given document and create 10 diverse questions that would effectively test a RAG system's ability to retrieve and synthesize information from this document.

Guidelines:
1. Thoroughly analyze the entire document.
2. Generate exactly 10 questions that cover various aspects and levels of complexity within the document's content.
3. Create questions that specifically target:
   a. Key facts and information
   b. Main concepts and ideas
   c. Relationships between different parts of the content
   d. Potential applications or implications of the information
   e. Comparisons or contrasts within the document
4. Ensure questions require answers of varying lengths and complexity, from simple retrieval to more complex synthesis.
5. Include questions that might require combining information from different parts of the document.
6. Frame questions to test both literal comprehension and inferential understanding.
7. Avoid yes/no questions; focus on open-ended questions that promote comprehensive answers.
8. Consider including questions that might require additional context or knowledge to fully answer, to test the RAG system's ability to combine retrieved information with broader knowledge.
9. Number the questions from 1 to 10.
10. Output only the ten questions, without any additional text, explanations, or answers.

Document:
[The document content will be inserted here]

Generate 10 questions optimized for testing a RAG system based on this document:
'''
<h4>HyDE-Generator-Eingabeaufforderung</h4><p>Aufforderung zur Generierung hypothetischer Dokumente mit HyDE</p>HYDE_DOCUMENT_GENERATOR_PROMPT = '''
You are an AI assistant specialized in generating hypothetical documents based on user queries. Your task is to create a detailed, factual document that would likely contain the answer to the user's question. This hypothetical document will be used to enhance the retrieval process in a Retrieval-Augmented Generation (RAG) system.

Guidelines:
1. Carefully analyze the user's query to understand the topic and the type of information being sought.
2. Generate a hypothetical document that:
   a. Is directly relevant to the query
   b. Contains factual information that would answer the query
   c. Includes additional context and related information
   d. Uses a formal, informative tone similar to an encyclopedia or textbook entry
3. Structure the document with clear paragraphs, covering different aspects of the topic.
4. Include specific details, examples, or data points that would be relevant to the query.
5. Aim for a document length of 200-300 words.
6. Do not use citations or references, as this is a hypothetical document.
7. Avoid using phrases like "In this document" or "This text discusses" - write as if it's a real, standalone document.
8. Do not mention or refer to the original query in the generated document.
9. Ensure the content is factual and objective, avoiding opinions or speculative information.
10. Output only the generated document, without any additional explanations or meta-text.

User Question:
[The user's question will be inserted here]

Generate a hypothetical document that would likely contain the answer to this query:
'''
<h3>Beispiel einer hybriden Suchanfrage</h3>{'knn': {'field': 'primary_embedding',
  'query_vector': [0.4265527129173279,
   -0.1712949573993683,
   -0.042020395398139954,
   ...],
  'k': 100,
  'num_candidates': 100},
 'query': {'bool': {'must': [{'multi_match': {'query': 'audits Elastic Elastic auditing Elastic audit process Elastic compliance Elastic security audit Elasticsearch auditing Elasticsearch compliance Elasticsearch security audit',
      'fields': ['original_text',
       'keyphrases',
       'potential_questions',
       'entities'],
      'type': 'best_fields',
      'operator': 'or'}}],
   'should': [{'script_score': {'query': {'match_all': {}},
      'script': {'source': '\n                                        double vector_score = cosineSimilarity(params.query_vector, params.vector_field) + 1.0;\n                                        double text_score = _score;\n                                        return 0.7 * vector_score + 0.3 * text_score;\n                                        ',
       'params': {'query_vector': [0.4265527129173279,
         -0.1712949573993683,
         -0.042020395398139954,
        ...],
        'vector_field': 'primary_embedding'}}}}]}},
 'size': 10}
]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2</guid>
    <category><![CDATA[Vektordatenbank]]></category>
    <category><![CDATA[KI]]></category>
    <dc:creator><![CDATA[Han Xiang Choong]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf605c8246989df32/6a1711178b73cbc61d18a11d/8da40067835ab8b4dc12fe52a51a6c26858ad32f-1440x1095.jpg" length="0" type="image/jpeg"/>
    <pubDate>Thu, 15 Aug 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Erweiterte RAG-Techniken Teil 1: Datenverarbeitung]]></title>
    <description><![CDATA[Diskussion und Umsetzung von Techniken zur Steigerung der RAG-Leistung. Teil 1 von 2, der sich auf die Datenverarbeitungs- und Aufnahmekomponente einer fortschrittlichen RAG-Pipeline konzentriert.]]></description>
    <content:encoded><![CDATA[<p><em>Dies ist Teil 1 unserer Erkundung fortgeschrittener RAG-Techniken. </em><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2"><em>Klicken Sie hier für Teil 2!</em></a></p><p>Die kürzlich erschienene Arbeit <a href="https://arxiv.org/abs/2407.01219">„Searching for Best Practices in Retrieval-Augmented Generation“</a> bewertet empirisch die Wirksamkeit verschiedener RAG-Verbesserungstechniken mit dem Ziel, eine Reihe von Best Practices für RAG zu ermitteln.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt671704ff06a4011d/6a170b3ea929cf2d19ae09d8/dafa7250e7c4ead4d9b4aed7c407509131929749-1440x572.png" alt="Die von Wang empfohlene RAG-Pipeline" /><p>Wir werden einige dieser vorgeschlagenen Best Practices umsetzen, nämlich diejenigen, die darauf abzielen, die Qualität der Suche zu verbessern <strong>(Sentence Chunking, HyDE, Reverse Packing)</strong>.</p><p>Aus Gründen der Kürze lassen wir die Techniken zur Effizienzsteigerung <strong>(Abfrageklassifizierung und Zusammenfassung)</strong> aus.</p><p>Wir werden auch einige Techniken anwenden, die nicht behandelt wurden, die ich persönlich aber für nützlich und interessant halte <strong>(Metadateneinbindung, zusammengesetzte Multi-Field-Einbettungen, Abfrageanreicherung)</strong>.</p><p>Zum Schluss führen wir einen kurzen Test durch, um zu sehen, ob sich die Qualität unserer Suchergebnisse und generierten Antworten im Vergleich zur Ausgangslage verbessert hat. Los geht's!</p><h2>RAG-Übersicht</h2><p>RAG zielt darauf ab, LLMs zu verbessern, indem Informationen aus externen Wissensdatenbanken abgerufen werden, um die generierten Antworten anzureichern. Durch die Bereitstellung domänenspezifischer Informationen können LLMs schnell an Anwendungsfälle außerhalb des Umfangs ihrer Trainingsdaten angepasst werden; dies ist wesentlich kostengünstiger als eine Feinabstimmung und einfacher, sie auf dem neuesten Stand zu halten.</p><p>Maßnahmen zur Verbesserung der Qualität von Ampelbewertungen konzentrieren sich typischerweise auf zwei Bereiche:</p><ol><li><p>Verbesserung der Qualität und Klarheit der Wissensbasis.</p></li><li><p>Verbesserung der Abdeckung und Spezifität von Suchanfragen.</p></li></ol><p>Diese beiden Maßnahmen sollen das Ziel erreichen, die Wahrscheinlichkeit zu erhöhen, dass der LLM Zugang zu relevanten Fakten und Informationen hat und somit weniger wahrscheinlich Halluzinationen hat oder auf sein eigenes Wissen zurückgreift, das möglicherweise veraltet oder irrelevant ist.</p><p>Die Vielfalt der Methoden lässt sich in wenigen Sätzen nur schwer verdeutlichen. Um die Dinge verständlicher zu machen, gehen wir direkt zur Umsetzung über.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9a4691874a19d8da/6a170b3f47d49c99f22d8a24/72b51ba2ae5e5977b56e5b915674753d6cfd0e56-1440x840.jpg" alt="Fortschrittliche RAG-Pipeline" /><h3>Inhaltsverzeichnis</h3><ul><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#overview">Überblick</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#table-of-contents">Inhaltsverzeichnis</a></p></li></ul></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#set-up">Aufstellen</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#ingesting-processing-and-embedding-documents">Einlesen, Verarbeiten und Einbetten von Dokumenten</a>  </p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#data-ingestion">Dateningestion</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#sentence-level-token-wise-chunking">Chunking auf Satzebene, tokenweise</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#metadata-inclusion-and-generation">Metadateneinbindung und -generierung</a> </p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#keyphrases-extracted-by-textrank">Von TextRank extrahierte Schlüsselphrasen</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#potential-questions-generated-by-gpt-4o">Mögliche Fragen, die von GPT-4o generiert wurden</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#entities-extracted-by-spacy">Von Spacy extrahierte Entitäten</a></p></li></ul></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#composite-multi-field-embeddings">Zusammengesetzte Mehrfeldeinbettungen</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#indexing-to-elastic">Indexierung zu Elastic</a></p></li></ul></li></ul></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#cat-break">Katzenbruch</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#appendix">Anhang</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#definitions">Definitionen</a></p></li></ul></li></ul><h2>Aufstellen</h2><p><em>Der gesamte Code ist </em><a href="https://github.com/elastic/elasticsearch-labs/tree/advanced-rag-techniques/supporting-blog-content/advanced-rag-techniques"><em>im Searchlabs-Repository zu</em></a><em> finden.</em></p><p>Das Wichtigste zuerst. Sie benötigen Folgendes:</p><ol><li><p>Eine elastische Cloud-Bereitstellung</p></li><li><p>Eine LLM-API – In diesem Notebook verwenden wir eine GPT-4o-Bereitstellung auf Azure OpenAI.</p></li><li><p>Python Version 3.12.4 oder höher</p></li></ol><p>Wir werden den gesamten Code aus <a href="https://github.com/elastic/elasticsearch-labs/blob/advanced-rag-techniques/supporting-blog-content/advanced-rag-techniques/main.ipynb">dem main.ipynb-Notebook ausführen.</a></p><p>Klonen Sie nun das Repository mit git, navigieren Sie zu supporting-blog-content/advanced-rag-techniques und führen Sie anschließend die folgenden Befehle aus:</p># Create a new virtual environment named 'rag_env'
python -m venv rag_env

# Activate the virtual environment (for Unix-based systems)
source rag_env/bin/activate

# (For Windows)
.\rag_env\Scripts\activate

# Install packages listed in requirements.txt
pip install -r requirements.txt
<p>Sobald das erledigt ist, erstellen Sie eine <em>.env-Datei.</em> Datei öffnen und die folgenden Felder ausfüllen (Referenz in <a href="https://github.com/elastic/elasticsearch-labs/blob/advanced-rag-techniques/supporting-blog-content/advanced-rag-techniques/.env.example"><em>.env.example</em></a>). Ein Dank geht an meinen Co-Autor Claude-3.5 für die hilfreichen Kommentare.</p># Elastic Cloud: Found in the 'Deployment' page of your Elastic Cloud 
# console
ELASTIC_CLOUD_ENDPOINT=""
ELASTIC_CLOUD_ID=""

# Elastic Cloud: Created during deployment setup or in 'Security' 
# settings
ELASTIC_USERNAME=""
ELASTIC_PASSWORD=""

# Elastic Cloud: The name of the index you created in Kibana or via API
ELASTIC_INDEX_NAME=""

# Azure AI Studio: Found in 'Keys and Endpoint' section of your Azure 
# OpenAI resource
AZURE_OPENAI_KEY_1=""
AZURE_OPENAI_KEY_2=""
AZURE_OPENAI_REGION=""
AZURE_OPENAI_ENDPOINT=""

# Azure AI Studio: Found in 'Deployments' section of your Azure OpenAI 
# resource
AZURE_OPENAI_DEPLOYMENT_NAME=""

# Using BAAI/bge-small-en-v1.5 because I think it is a good balance of 
# resource efficiency and performance. 
HUGGINGFACE_EMBEDDING_MODEL="BAAI/bge-small-en-v1.5"
<p>Als Nächstes wählen wir das zu importierende Dokument aus und legen es im Dokumentenordner ab. Für diesen Artikel verwenden wir den <a href="https://s201.q4cdn.com/217177842/files/doc_downloads/OtherDocuments/2023/AnnualMeeting/Annual-Report-Fiscal-Year-2023.pdf">Elastic NV Jahresbericht 2023</a>. Es handelt sich um ein ziemlich anspruchsvolles und komplexes Dokument, perfekt geeignet, um unsere RAG-Techniken einem Stresstest zu unterziehen.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte292dc6030d496cc/6a170b40dc55de9b03e00dfc/e513b9d67adac43da794c25a5969b893127bbbe3-1440x395.jpg" alt="Elastic-Jahresbericht 2023" /><p>Jetzt sind wir bereit, lasst uns mit der Einnahme beginnen. Öffnen Sie <em>main.ipynb</em> und führen Sie die ersten beiden Zellen aus, um alle Pakete zu importieren und alle Dienste zu initialisieren.</p><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#table-of-contents">Zurück nach oben</a></p><h2>Einlesen, Verarbeiten und Einbetten von Dokumenten</h2><h3>Dateningestion</h3><ul><li><p><em>Persönliche Anmerkung: Ich bin von der Benutzerfreundlichkeit von LlamaIndex begeistert. In den alten Zeiten vor LLMs und LlamaIndex war das Einlesen von Dokumenten in verschiedenen Formaten ein mühsamer Prozess, bei dem man esoterische Pakete aus allen möglichen Quellen zusammentragen musste. Jetzt ist es auf einen einzigen Funktionsaufruf reduziert. Wild.</em></p></li></ul><p>Die <code>SimpleDirectoryReader</code> lädt alle Dokumente in den <code>directory_path.</code> -Dateien. Für <code>.pdf</code> -Dateien gibt sie eine Liste von Dokumentobjekten zurück, die ich in Python-Dictionaries umwandle, da ich diese einfacher zu handhaben finde.</p># llamaindex_processor.py
from llama_index.core import SimpleDirectoryReader

class LlamaIndexProcessor:
   def __init__(self):
       pass 
   
   def load_documents(self, directory_path):
       ''' 
       Load all documents in directory
       '''
       reader = SimpleDirectoryReader(input_dir=directory_path)
       return reader.load_data()

# main.ipynb
llamaindex_processor=LlamaIndexProcessor()
documents=llamaindex_processor.load_documents('./documents/')
documents=[dict(doc_obj) for doc_obj in documents]
<p>Jedes Wörterbuch enthält den Schlüsselinhalt im Feld <code>text</code> . Es enthält außerdem nützliche Metadaten wie Seitenzahl, Dateiname, Dateigröße und Dateityp.</p>{
  'id_': '5f76f0b3-22d8-49a8-9942-c2bbab14f63f',
  'metadata': {'page_label': '5',
   'file_name': 'Elastic_NV_Annual-Report-Fiscal-Year-2023.pdf',
   'file_path': '/Users/han/Desktop/Projects/truckasaurus/documents/Elastic_NV_Annual-Report-Fiscal-Year-2023.pdf',
   'file_type': 'application/pdf',
   'file_size': 3724426,
   'creation_date': '2024-07-27',
   'last_modified_date': '2024-07-27'},
   'text': 'Table of Contents\nPage\nPART I\nItem 1. Business 3\n15 Item 1A. Risk Factors\nItem 1B. Unresolved Staff Comments 48\nItem 2. Properties 48\nItem 3. Legal Proceedings 48\nItem 4. Mine Safety Disclosures 48\nPART II\nItem 5. Market for Registrant's Common Equity, Related Stockholder Matters and Issuer Purchases of \nEquity Securities49\nItem 6. [Reserved] 49\nItem 7. Management's Discussion and Analysis of Financial Condition and Results of Operations 50\nItem 7A. Quantitative and Qualitative Disclosures About Market Risk 64\nItem 8. Financial Statements and Supplementary Data 66\nItem 9. Changes in and Disagreements With Accountants on Accounting and Financial Disclosure 100\n100\n101Item 9A. Controls and Procedures\nItem 9B. Other Information\nItem 9C. Disclosure Regarding Foreign Jurisdictions That Prevent Inspections 101\nPART III\n102\n102\n102\n102Item 10. Directors, Executive Officers and Corporate Governance\nItem 11. Executive Compensation\nItem 12. Security Ownership of Certain Beneficial Owners and Management, and Related Stockholder Matters  \nItem 13. Certain Relationships and Related Transactions, and Director Independence\nItem 14. Principal Accountant Fees and Services 102\nPART IV\n103\n105Item 15. Exhibits and Financial Statement Schedules  \nItem 16. Form 10-K Summary\nSignatures 106\ni',
   ...
}
<p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#table-of-contents">Zurück nach oben</a></p><h3>Chunking auf Satzebene, tokenweise</h3><p>Als Erstes sollten wir unsere Dokumente in Abschnitte von einheitlicher Länge unterteilen (um Konsistenz und Verwaltbarkeit zu gewährleisten). Einbettungsmodelle haben individuelle Token-Limits (maximale Eingabegröße, die sie verarbeiten können). Tokens sind die grundlegenden Einheiten des Textes, die Prozesse modellieren. Um Informationsverluste (Abschneidung oder Auslassung von Inhalten) zu vermeiden, sollten wir Texte bereitstellen, die diese Grenzen nicht überschreiten (indem wir längere Texte in kleinere Abschnitte aufteilen).</p><p>Das Chunking hat einen erheblichen Einfluss auf die Leistung. Im Idealfall stellt jeder Abschnitt eine in sich abgeschlossene Informationseinheit dar, die Kontextinformationen zu einem einzelnen Thema erfasst. Zu den Chunking-Methoden gehören das Chunking auf Wortebene, bei dem Dokumente anhand der Wortanzahl aufgeteilt werden, und das semantische Chunking, das ein LLM verwendet, um logische Trennpunkte zu identifizieren.</p><p>Die Segmentierung auf Wortebene ist zwar günstig, schnell und einfach, birgt aber das Risiko, Sätze zu trennen und dadurch den Kontext zu zerstören. Die semantische Segmentierung wird langsam und teuer, insbesondere bei Dokumenten wie dem 116-seitigen Elastic Annual Report.</p><p>Lasst uns einen Mittelweg wählen. Die Segmentierung auf Satzebene ist zwar immer noch einfach, kann aber den Kontext besser erhalten als die Segmentierung auf Wortebene und ist dabei deutlich günstiger und schneller. Zusätzlich werden wir ein gleitendes Fenster implementieren, um einen Teil des umgebenden Kontextes zu erfassen und die Auswirkungen der Absatzteilung zu verringern.</p># chunker.py 

import uuid
import re


class Chunker: 
    def __init__(self, tokenizer):
        self.tokenizer = tokenizer 
    
    def split_into_sentences(self, text):
        """Split text into sentences."""
        return re.split(r'(?&lt;=[.!?])\s+', text)
 
    def sentence_wise_tokenized_chunk_documents(self, documents, chunk_size=512, overlap=20, min_chunk_size=50):
        '''
        1. Split text into sentences.
        2. Tokenize using the provided tokenizer method.
        3. Build chunks up to the chunk_size limit.
        4. Create an overlap based on tokens - to preserve context.
        5. Only keep chunks that meet the minimum token size requirement.
        '''
        chunked_documents = []

        for doc in documents:
            sentences = self.split_into_sentences(doc['text'])
            tokens = []
            sentence_boundaries = [0]

            # Tokenize all sentences and keep track of sentence boundaries
            for sentence in sentences:
                sentence_tokens = self.tokenizer.encode(sentence, add_special_tokens=True)
                tokens.extend(sentence_tokens)
                sentence_boundaries.append(len(tokens))

            # Create chunks
            chunk_start = 0
            while chunk_start &lt; len(tokens):
                chunk_end = chunk_start + chunk_size

                # Find the last complete sentence that fits in the chunk
                sentence_end = next((i for i in sentence_boundaries if i &gt; chunk_end), len(tokens))
                chunk_end = min(chunk_end, sentence_end)

                # Create the chunk
                chunk_tokens = tokens[chunk_start:chunk_end]

                # Check if the chunk meets the minimum size requirement
                if len(chunk_tokens) &gt;= min_chunk_size:
                    # Create a new document object for this chunk
                    chunk_doc = {
                        'id_': str(uuid.uuid4()),
                        'chunk': chunk_tokens,
                        'original_text': self.tokenizer.decode(chunk_tokens),
                        'chunk_index': len(chunked_documents),
                        'parent_id': doc['id_'],
                        'chunk_token_count': len(chunk_tokens)
                    }

                    # Copy all other fields from the original document
                    for key, value in doc.items():
                        if key != 'text' and key not in chunk_doc:
                            chunk_doc[key] = value

                    chunked_documents.append(chunk_doc)

                # Move to the next chunk start, considering overlap
                chunk_start = max(chunk_start + chunk_size - overlap, chunk_end - overlap)

        return chunked_documents

# main.ipynb 
# Initialize Embedding Model
HUGGINGFACE_EMBEDDING_MODEL = os.environ.get('HUGGINGFACE_EMBEDDING_MODEL')
embedder=EmbeddingModel(model_name=HUGGINGFACE_EMBEDDING_MODEL)

# Initialize Chunker
chunker=Chunker(embedder.tokenizer)
<p>Die Klasse <code>Chunker</code> verwendet den Tokenizer des Einbettungsmodells zum Kodieren und Dekodieren von Text. Wir werden nun Blöcke von jeweils 512 Token erstellen, mit einer Überlappung von 20 Token. Dazu teilen wir den Text in Sätze auf, tokenisieren diese Sätze und fügen die tokenisierten Sätze dann unserem aktuellen Chunk hinzu, bis wir keine weiteren mehr hinzufügen können, ohne unser Token-Limit zu überschreiten.</p><p>Zum Schluss werden die Sätze wieder in den Originaltext dekodiert, um sie einzubetten. Dieser wird in einem Feld namens <code>original_text</code> gespeichert. Die Chunks werden in einem Feld namens <code>chunk</code> gespeichert. Um unnötige Dokumente (auch: überflüssige Dokumente) zu reduzieren, werden wir alle Dokumente verwerfen, die kürzer als 50 Token sind.</p><p>Lassen Sie uns das anhand unserer Dokumente prüfen:</p>chunked_documents=chunker.sentence_wise_tokenized_chunk_documents(documents, chunk_size=512)
<p>Und Sie erhalten Textabschnitte zurück, die etwa so aussehen:</p>print(chunked_documents[4]['original_text'])

[CLS] the aggregate market value of the ordinary shares held by non - affiliates of the registrant, 
based on the closing price of the shares of ordinary shares on the new york stock exchange on 
october 31, 2022 ( the last business day of the registrant 's second fiscal quarter ), was 
approximately $ 6. 1 billion. [SEP] [CLS] as of may 31, 2023, the registrant had 97, 390, 886 
ordinary shares, par value €0. 01 per share, outstanding. [SEP] [CLS] documents incorporated by 
reference portions of the registrant 's definitive proxy statement relating to the registrant 's 2
023 annual general meeting of shareholders are incorporated by reference into part iii of this annual 
...
...
<p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#table-of-contents">Zurück nach oben</a></p><h3>Metadateneinbindung und -generierung</h3><p>Wir haben unsere Dokumente in Abschnitte unterteilt. Nun ist es an der Zeit, die Daten anzureichern. Ich möchte zusätzliche Metadaten generieren oder extrahieren. Diese zusätzlichen Metadaten können genutzt werden, um die Suchleistung zu beeinflussen und zu verbessern.</p><p>Wir definieren eine <code>DocumentEnricher</code> -Klasse, deren Aufgabe es ist, eine Liste von Dokumenten (Python-Dictionaries) und eine Liste von Prozessorfunktionen entgegenzunehmen. Diese Funktionen werden auf die Spalte <code>original_text</code> der Dokumente angewendet und ihre Ergebnisse in neuen Feldern gespeichert.</p><p>Zuerst extrahieren wir mithilfe von <a href="https://github.com/elastic/elasticsearch-labs/blob/advanced-rag-techniques/supporting-blog-content/advanced-rag-techniques/nltk_processor.py">TextRank</a> Schlüsselphrasen. TextRank ist ein graphenbasierter Algorithmus, der Schlüsselphrasen und -sätze aus Texten extrahiert, indem er ihre Wichtigkeit anhand der Beziehungen zwischen den Wörtern ordnet.</p><p>Als nächstes <a href="https://github.com/elastic/elasticsearch-labs/blob/advanced-rag-techniques/supporting-blog-content/advanced-rag-techniques/llm.py">generieren wir potenzielle_Fragen mithilfe von GPT-4o</a>.</p><p>Zum Schluss <a href="https://github.com/elastic/elasticsearch-labs/blob/advanced-rag-techniques/supporting-blog-content/advanced-rag-techniques/entity_extractor.py">extrahieren wir Entitäten</a> mithilfe von <a href="https://spacy.io/">Spacy</a>.</p><p>Da der Code für jeden dieser Punkte recht umfangreich und komplex ist, verzichte ich darauf, ihn hier wiederzugeben. Bei Interesse sind die Dateien in den unten stehenden Codebeispielen gekennzeichnet.</p><p>Starten wir die Datenanreicherung:</p># documentenricher.py
from tqdm import tqdm

class DocumentEnricher:

    def __init__(self):
        pass 

    def enrich_document(self, documents, processors, text_col='text'):
        for doc in tqdm(documents, desc="Enriching documents using processors: "+str(processors)): 
            for (processor, field) in processors: 
                metadata=processor(doc[text_col])
                if isinstance(metadata, list):
                    metadata='\n'.join(metadata)
                doc.update({field: metadata})
 
# main.ipynb
# Initialize processor classes 
nltkprocessor=NLTKProcessor() // nltk_processor.py
entity_extractor=EntityExtractor() // entity_extractor.py
gpt4o = LLMProcessor(model='gpt-4o') // llm.py

# Initialize LLM
documentenricher=DocumentEnricher()

# Create new fields in the documents - These are the outputs of the processor functions.
processors=[
    (nltkprocessor.textrank_phrases, "keyphrases"),
    (gpt4o.generate_questions, "potential_questions"),
    (entity_extractor.extract_entities, "entities")
    ]

# .enrich_document() will modify chunked_docs in place. 
# To view the results, we'll print chunked_docs in the next few cells!
documentenricher.enrich_document(chunked_docs, text_col='original_text', processors=processors)
<p>Und sehen Sie sich die Ergebnisse an:</p><h4>Von TextRank extrahierte Schlüsselphrasen</h4><p>Diese Schlüsselbegriffe stehen stellvertretend für die Kernthemen des jeweiligen Abschnitts. Wenn eine Anfrage mit Cybersicherheit zu tun hat, wird die Punktzahl dieses Abschnitts erhöht.</p>print(chunked_documents[25]['keyphrases'])

'elastic agent stop', 'agent stop malware', 
'stop malware ransomware', 'malware ransomware environment', 
'ransomware environment wide', 'environment wide visibility', 
'wide visibility threat', 'visibility threat detection', 
'sep cl key', 'cl key feature'
<h4>Mögliche Fragen, die von GPT-4o generiert wurden</h4><p>Diese potenziellen Fragen könnten direkt mit den Suchanfragen der Nutzer übereinstimmen und so zu einer Verbesserung der Punktzahl führen. Wir fordern GPT-4o auf, Fragen zu generieren, die mithilfe der im aktuellen Chunk enthaltenen Informationen beantwortet werden können.</p>print(chunked_documents[25]['potential_questions'])

1. What are the primary functions that Elastic Agent provides in terms of cybersecurity?
2. Describe how Logstash contributes to data management within an IT environment.
3. List and explain any key features of Logstash mentioned in the document.
4. How does Elastic Agent enhance environment-wide visibility in threat detection?
5. What capabilities does Logstash offer for handling data beyond simple collection?
6. In what ways does the document suggest that Elastic Agent stops malware and ransomware?
7. Can you identify any relationships between the functionalities of Elastic Agent and Logstash in an integrated environment?
8. What implications might the advanced threat detection capabilities of Elastic Agent have for organizational security policies?
9. Compare and contrast the roles of Elastic Agent and Logstash based on their described functions.
10. How might the centralized collection ability of Logstash support the threat detection capabilities of Elastic Agent?
<h4>Von Spacy extrahierte Entitäten</h4><p>Diese Entitäten dienen einem ähnlichen Zweck wie die Schlüsselphrasen, erfassen aber die Namen von Organisationen und Einzelpersonen, die bei der Extraktion von Schlüsselphrasen möglicherweise nicht erfasst werden.</p>print(chunked_documents[29]['entities'])

'appdynamics', 'apm data', 'azure sentinel', 
'microsoft', 'mcafee', 'broadcom', 'cisco', 
'dynatrace', 'coveo', 'lucidworks'
<p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#table-of-contents">Zurück nach oben</a></p><h3>Zusammengesetzte Mehrfeldeinbettungen</h3><p>Nachdem wir unsere Dokumente nun mit zusätzlichen Metadaten angereichert haben, können wir diese Informationen nutzen, um robustere und kontextsensitive Einbettungen zu erstellen.</p><p>Lassen Sie uns den aktuellen Stand des Prozesses noch einmal betrachten. Wir haben in jedem Dokument vier Interessensgebiete.</p>{
    "chunk": "...",
    "keyphrases": "...", 
    "potential_questions": "...", 
    "entities": "..." 
}
<p>Jedes Feld repräsentiert eine andere Perspektive auf den Kontext des Dokuments und hebt möglicherweise einen wichtigen Bereich hervor, auf den sich das LLM konzentrieren sollte.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt84cb328fce6aae23/6a170b42964cea3e4408bbc4/aea1f513009a0c7c8545a79fad8f072a5bcae24c-1440x1067.jpg" alt="Metadatenanreicherungspipeline in RAG" /><p>Der Plan besteht darin, jedes dieser Felder einzubetten und dann eine gewichtete Summe der Einbettungen zu erstellen, die als zusammengesetzte Einbettung bezeichnet wird.</p><p>Mit etwas Glück wird dieses Composite Embedding dem System ermöglichen, kontextsensitiver zu werden, und zusätzlich einen weiteren einstellbaren Hyperparameter zur Steuerung des Suchverhaltens einführen.</p><p>Zunächst betten wir jedes Feld ein und aktualisieren jedes Dokument direkt, indem wir unser lokal definiertes Einbettungsmodell verwenden, das wir zu Beginn des Notebooks main.ipynb importiert haben.</p># EmbeddingModel defined in embedding_model.py
embedder=EmbeddingModel(model_name=HUGGINGFACE_EMBEDDING_MODEL)

cols_to_embed=['keyphrases', 'potential_questions', 'entities']

embedding_cols=[]
for col in cols_to_embed:
    # Works on text input
    embedding_col=embedder.embed_documents_text_wise(chunked_documents, text_field=col)
    embedding_cols.append(embedding_col)
# Works on token input
embedding_col=embedder.embed_documents_token_wise(chunked_documents, token_field="chunk")
embedding_cols.append(embedding_col)
<p>Jede Einbettungsfunktion gibt das Feld der Einbettung zurück, welches einfach das ursprüngliche Eingabefeld mit einem Suffix <code>_embedding</code> ist.</p><p>Definieren wir nun die Gewichtungen unserer zusammengesetzten Einbettung:</p>embedding_cols=[
                'keyphrases_embedding',
                'potential_questions_embedding',
                'entities_embedding',
                'chunk_embedding']
combination_weights=[
                    0.1,
                    0.15,
                    0.05,
                    0.7
                ]
<p>Mithilfe der Gewichtungen können Sie den einzelnen Komponenten Prioritäten zuweisen, basierend auf Ihrem Anwendungsfall und der Qualität Ihrer Daten. Intuitiv betrachtet hängt die Größe dieser Gewichtungen vom semantischen Wert jeder Komponente ab. Da der Chunk-Text selbst mit Abstand den größten Informationsgehalt aufweist, weise ich ihm eine Gewichtung von 70 % zu. Da es sich bei den Entitäten um die kleinsten handelt, nämlich lediglich um eine Liste von Organisations- oder Personennamen, weise ich ihnen eine Gewichtung von 5 % zu. Die genaue Festlegung dieser Werte muss empirisch, also für jeden Anwendungsfall einzeln, erfolgen.</p><p>Zum Schluss schreiben wir eine Funktion, um die Gewichtungen anzuwenden und unser zusammengesetztes Embedding zu erstellen. Um Speicherplatz zu sparen, löschen wir auch alle Komponenteneinbettungen.</p>from tqdm import tqdm 
def combine_embeddings(objects, embedding_cols, combination_weights, primary_embedding='primary_embedding'):
    # Ensure the number of weights matches the number of embedding columns
    assert len(embedding_cols) == len(combination_weights), "Number of embedding columns must match number of weights"
    
    # Normalize weights to sum to 1
    weights = np.array(combination_weights) / np.sum(combination_weights)
    
    for obj in tqdm(objects, desc="Combining embeddings"):
        # Initialize the combined embedding
        combined = np.zeros_like(obj[embedding_cols[0]])
        
        # Compute the weighted sum
        for col, weight in zip(embedding_cols, weights):
            combined += weight * np.array(obj[col])
        
        # Add the new combined embedding to the object
        obj.update({primary_embedding:combined.tolist()})
        
        # Remove the original embedding columns
        for col in embedding_cols:
            obj.pop(col, None)

combine_embeddings(chunked_documents, embedding_cols, combination_weights)
<p>Hiermit ist unsere Dokumentenbearbeitung abgeschlossen. Wir haben nun eine Liste von Dokumentobjekten, die folgendermaßen aussehen:</p>{ 'id_': '7fe71686-5cd0-4831-9e79-998c6dbeae0c', 'chunk': [2312, 14613, ...], 'original_text': 'if an emerging growth company, indicate by check mark if the registrant has elected not to use the extended ...', 'chunk_index': 3, 'chunk_token_count': 399, 'metadata': {'page_label': '3', 'file_name': 'Elastic_NV_Annual-Report-Fiscal-Year-2023.pdf', ... 'keyphrases': 'sep cl unk\ncheck mark registrant\ncl unk indicate\nunk indicate check\nindicate check mark\nprincipal executive office\naccelerate filer unk\ncompany unk emerge\nunk emerge growth\nemerge growth company', 'potential_questions': '1. What are the different types of registrant statuses mentioned in the document?\n2. Under what section of the Sarbanes-Oxley Act must registrants file a report on the effectiveness of their internal ...', 'entities': 'the effe ctiveness of\nsection 13\nSEP\nUNK\nsection 21e\n1934\n1933\nu. s. c.\nsection 404\nsection 12\nal', 'primary_embedding': [-0.3946287803351879, -0.17586839850991964, ...] }
<h4>Indexierung zu Elastic</h4><p>Lasst uns unsere Dokumente per Massen-Upload in Elastic Search hochladen. Zu diesem Zweck habe ich vor langer Zeit eine Reihe von Elastic-Helper-Funktionen in <a href="https://github.com/elastic/elasticsearch-labs/blob/advanced-rag-techniques/supporting-blog-content/advanced-rag-techniques/elastic_helpers.py"><code>elastic_helpers.py</code></a> definiert. Es handelt sich um einen sehr langen Codeabschnitt, daher konzentrieren wir uns auf die Funktionsaufrufe.</p><p><code>es_bulk_indexer.bulk_upload_documents</code> Funktioniert mit beliebigen Listen von Wörterbuchobjekten und nutzt dabei die praktischen dynamischen Zuordnungen von Elasticsearch.</p># Initialize Elasticsearch
ELASTIC_CLOUD_ID = os.environ.get('ELASTIC_CLOUD_ID')
ELASTIC_USERNAME = os.environ.get('ELASTIC_USERNAME')
ELASTIC_PASSWORD = os.environ.get('ELASTIC_PASSWORD')
ELASTIC_CLOUD_AUTH = (ELASTIC_USERNAME, ELASTIC_PASSWORD)
es_bulk_indexer = ESBulkIndexer(cloud_id=ELASTIC_CLOUD_ID, credentials=ELASTIC_CLOUD_AUTH)
es_query_maker = ESQueryMaker(cloud_id=ELASTIC_CLOUD_ID, credentials=ELASTIC_CLOUD_AUTH)

# Define Index Name
index_name=os.environ.get('ELASTIC_INDEX_NAME')


# Create index and bulk upload 
index_exists = es_bulk_indexer.check_index_existence(index_name=index_name)
if not index_exists:
    logger.info(f"Creating new index: {index_name}")
    es_bulk_indexer.create_es_index(es_configuration=BASIC_CONFIG, index_name=index_name)

success_count = es_bulk_indexer.bulk_upload_documents(
    index_name=index_name, 
    documents=chunked_documents, 
    id_col='id_',
    batch_size=32
)
<p>Gehe zu Kibana und überprüfe, ob alle Dokumente indexiert wurden. Es sollten 224 sein. Nicht schlecht für ein so umfangreiches Dokument!</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8efeface6effe01d/6a170b447d8d67652870e72a/1b3b07f6b98ceb65f6594ce4be83c5b0ed7e7cf9-1440x1380.jpg" alt="Index Kibana" /><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#table-of-contents">Zurück nach oben</a></p><h2>Katzenbruch</h2><p>Lasst uns eine Pause machen, der Artikel ist etwas anspruchsvoll, ich weiß. Schaut euch meine Katze an:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc1db5595f71c12ff/6a170b450e2e49940241a0fe/baca4eb52b801b21ced97352cc55462f0a12d6b0-969x996.jpg" alt="Han-Pipeline" /><p>Liebenswert. Der Hut ist verschwunden und ich vermute fast, dass sie ihn gestohlen und irgendwo versteckt hat :(</p><p>Herzlichen Glückwunsch, dass du es so weit geschafft hast :)</p><p>Seien Sie in <a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2">Teil 2</a> wieder dabei, wenn wir unsere RAG-Pipeline testen und bewerten!</p><h2>Anhang</h2><h3>Definitionen</h3><p><strong>1. Satzgliederung</strong></p><ul><li><p>Eine Vorverarbeitungstechnik, die in RAG-Systemen verwendet wird, um Text in kleinere, sinnvolle Einheiten zu unterteilen.</p></li><li><p><em>Prozess:</em> </p><ol><li><p>Eingabe: Großer Textblock (z. B. Dokument, Absatz)</p></li><li><p>Ausgabe: Kleinere Textsegmente (typischerweise Sätze oder kleine Satzgruppen)</p></li></ol></li><li><p><em>Zweck:</em> </p><ul><li><p>Erzeugt detaillierte, kontextspezifische Textsegmente</p></li><li><p>Ermöglicht eine präzisere Indizierung und einen schnelleren Abruf.</p></li><li><p>Verbessert die Relevanz der abgerufenen Informationen in RAG-Systemen</p></li></ul></li><li><p><em>Eigenschaften:</em> </p><ul><li><p>Segmente sind semantisch aussagekräftig.</p></li><li><p>Kann unabhängig indexiert und abgerufen werden.</p></li><li><p>Oft wird etwas Kontext beibehalten, um die Verständlichkeit für sich allein zu gewährleisten.</p></li></ul></li><li><p><em>Vorteile:</em> </p><ul><li><p>Verbessert die Abrufgenauigkeit</p></li><li><p>Ermöglicht eine gezieltere Erweiterung in RAG-Pipelines.</p></li></ul></li></ul><p><strong>2. HyDE (Hypothetisches Dokumenteneinbetten)</strong></p><ul><li><p>Eine Technik, die ein LLM verwendet, um ein hypothetisches Dokument zur Abfrageerweiterung in RAG-Systemen zu generieren.</p></li><li><p><em>Prozess:</em>  </p><ol><li><p>Eingabeanfrage an einen LLM</p></li><li><p>LLM generiert ein hypothetisches Dokument, das die Anfrage beantwortet.</p></li><li><p>Das generierte Dokument einbetten</p></li><li><p>Verwenden Sie die Einbettung für die Vektorsuche</p></li></ol></li><li><p><em>Hauptunterschied:</em> </p><ul><li><p>Traditionelles RAG: Gleicht Suchanfragen mit Dokumenten ab</p></li><li><p>HyDE: Ordnet Dokumente einander zu</p></li></ul></li><li><p><em>Zweck:</em> </p><ul><li><p>Verbesserung der Abfrageleistung, insbesondere bei komplexen oder mehrdeutigen Anfragen</p></li><li><p>Erfasst einen reichhaltigeren semantischen Kontext als eine kurze Anfrage</p></li></ul></li><li><p><em>Vorteile:</em> </p><ul><li><p>Nutzt das Wissen des LLM, um Anfragen zu erweitern</p></li><li><p>Kann potenziell die Relevanz der abgerufenen Dokumente verbessern</p></li></ul></li><li><p><em>Herausforderungen:</em> </p><ul><li><p>Erfordert zusätzliche LLM-Inferenz, was die Latenz und die Kosten erhöht.</p></li><li><p>Die Leistung hängt von der Qualität des generierten hypothetischen Dokuments ab.</p></li></ul></li></ul><p><strong>3. Rückwärtsverpackung</strong></p><ul><li><p>Eine in RAG-Systemen verwendete Technik, um Suchergebnisse neu zu ordnen, bevor sie an den LLM weitergeleitet werden.</p></li><li><p><em>Prozess:</em> </p><ol><li><p>Die Suchmaschine (z. B. Elasticsearch) gibt Dokumente in absteigender Reihenfolge ihrer Relevanz zurück.</p></li><li><p>Die Reihenfolge ist umgekehrt, das wichtigste Dokument steht nun an letzter Stelle.</p></li></ol></li><li><p><em>Zweck:</em> </p><ul><li><p>Nutzt den Aktualitätsbias von LLMs aus, die sich tendenziell stärker auf die neuesten Informationen in ihrem Kontext konzentrieren.</p></li><li><p>Gewährleistet, dass im Kontextfenster des LLM die relevantesten Informationen stets aktuell sind.</p></li></ul></li><li><p><em>Beispiel:</em> Ursprüngliche Reihenfolge: [Relevantester, Zweitwichtigster, Drittwichtigster, ...] Umgekehrte Reihenfolge: [..., Drittwichtigster, Zweitwichtigster, Relevantester]</p></li></ul><p><strong>4. Abfrageklassifizierung</strong></p><ul><li><p>Eine Technik zur Optimierung der Effizienz von RAG-Systemen durch die Bestimmung, ob eine Anfrage RAG erfordert oder direkt vom LLM beantwortet werden kann.</p></li><li><p><em>Prozess:</em> </p><ol><li><p>Entwickeln Sie einen benutzerdefinierten Datensatz, der speziell auf den verwendeten LLM zugeschnitten ist.</p></li><li><p>Trainieren Sie ein spezialisiertes Klassifizierungsmodell</p></li><li><p>Nutzen Sie das Modell, um eingehende Anfragen zu kategorisieren.</p></li></ol></li><li><p><em>Zweck:</em> </p><ul><li><p>Verbessern Sie die Systemeffizienz, indem Sie unnötige RAG-Verarbeitung vermeiden.</p></li><li><p>Direkte Anfragen an den am besten geeigneten Antwortmechanismus</p></li></ul></li><li><p><em>Anforderungen:</em> </p><ul><li><p>LLM-spezifischer Datensatz und Modell</p></li><li><p>Kontinuierliche Optimierung zur Aufrechterhaltung der Genauigkeit</p></li></ul></li><li><p><em>Vorteile:</em> </p><ul><li><p>Reduziert den Rechenaufwand für einfache Abfragen</p></li><li><p>Verbessert möglicherweise die Antwortzeit für Nicht-RAG-Anfragen</p></li></ul></li></ul><p><strong>5. Zusammenfassung</strong></p><ul><li><p>Eine Technik zur Komprimierung abgerufener Dokumente in RAG-Systemen.</p></li><li><p><em>Prozess:</em> </p><ol><li><p>Relevante Dokumente abrufen</p></li><li><p>Erstellen Sie prägnante Zusammenfassungen jedes Dokuments.</p></li><li><p>Verwenden Sie in der RAG-Pipeline Zusammenfassungen anstelle vollständiger Dokumente.</p></li></ol></li><li><p><em>Zweck:</em> </p><ul><li><p>Verbessern Sie die RAG-Performance, indem Sie sich auf wesentliche Informationen konzentrieren.</p></li><li><p>Rauschen und Störungen durch weniger relevante Inhalte reduzieren</p></li></ul></li><li><p><em>Vorteile:</em> </p><ul><li><p>Verbessert möglicherweise die Relevanz der LLM-Antworten</p></li><li><p>Ermöglicht die Einbeziehung weiterer Dokumente innerhalb der Kontextgrenzen.</p></li></ul></li><li><p><em>Herausforderungen:</em> </p><ul><li><p>Gefahr, wichtige Details in der Zusammenfassung zu verlieren</p></li><li><p>Zusätzlicher Rechenaufwand für die Zusammenfassungserstellung</p></li></ul></li></ul><p><strong>6. Einbeziehung von Metadaten</strong></p><ul><li><p>Eine Technik zur Anreicherung von Dokumenten mit zusätzlichen Kontextinformationen.</p></li><li><p><em>Metadatentypen:</em>  </p><ul><li><p>Schlüsselwörter</p></li><li><p>Titel</p></li><li><p>Termine</p></li><li><p>Angaben zur Autorschaft</p></li><li><p>Klappentexte</p></li></ul></li><li><p><em>Zweck:</em> </p><ul><li><p>Erweitern Sie die dem Ampelsystem zur Verfügung stehenden Kontextinformationen.</p></li><li><p>LLM-Studierenden ein klareres Verständnis des Dokumentinhalts und dessen Relevanz vermitteln</p></li></ul></li><li><p><em>Vorteile:</em> </p><ul><li><p>Verbessert möglicherweise die Abrufgenauigkeit</p></li><li><p>Verbessert die Fähigkeit des LLM-Programms, den Nutzen von Dokumenten zu beurteilen</p></li></ul></li><li><p><em>Durchführung:</em> </p><ul><li><p>Kann während der Dokumentenvorverarbeitung erfolgen.</p></li><li><p>Möglicherweise sind zusätzliche Datenextraktions- oder -generierungsschritte erforderlich.</p></li></ul></li></ul><p><strong>7. Zusammengesetzte Mehrfeld-Einbettungen</strong></p><ul><li><p>Eine fortschrittliche Einbettungstechnik für RAG-Systeme, die separate Einbettungen für verschiedene Dokumentkomponenten erstellt.</p></li><li><p><em>Prozess:</em> </p><ol><li><p>Relevante Felder identifizieren (z. B. Titel, Schlüsselwörter, Klappentext, Hauptinhalt)</p></li><li><p>Erzeugen Sie separate Einbettungen für jedes Feld.</p></li><li><p>Diese Einbettungen können kombiniert oder gespeichert werden, um sie beim Abruf zu verwenden.</p></li></ol></li><li><p><em>Unterschied zum Standardverfahren:</em> </p><ul><li><p>Traditionell: Einmaliges Einbetten für das gesamte Dokument</p></li><li><p>Komposit: Mehrere Einbettungen für verschiedene Dokumentaspekte</p></li></ul></li><li><p><em>Zweck:</em> </p><ul><li><p>Erstellen Sie differenziertere und kontextbezogene Dokumentendarstellungen</p></li><li><p>Informationen aus einer größeren Vielfalt von Quellen innerhalb eines Dokuments erfassen</p></li></ul></li><li><p><em>Vorteile:</em> </p><ul><li><p>Verbessert möglicherweise die Leistung bei mehrdeutigen oder vielschichtigen Anfragen.</p></li><li><p>Ermöglicht eine flexiblere Gewichtung verschiedener Dokumentaspekte bei der Recherche.</p></li></ul></li><li><p><em>Herausforderungen:</em> </p><ul><li><p>Erhöhte Komplexität bei der Einbettung von Speicher- und Abrufprozessen</p></li><li><p>Möglicherweise sind komplexere Matching-Algorithmen erforderlich.</p></li></ul></li></ul><p><strong>8. Abfrageanreicherung</strong></p><ul><li><p>Eine Technik zur Erweiterung der ursprünglichen Suchanfrage um verwandte Begriffe, um die Suchabdeckung zu verbessern.</p></li><li><p><em>Prozess:</em> </p><ol><li><p>Analysieren Sie die ursprüngliche Anfrage</p></li><li><p>Generieren Sie Synonyme und semantisch verwandte Phrasen</p></li><li><p>Erweitern Sie die Abfrage um diese zusätzlichen Begriffe</p></li></ol></li><li><p><em>Zweck:</em> </p><ul><li><p>Erhöhen Sie den Bereich potenzieller Übereinstimmungen im Dokumentenkorpus.</p></li><li><p>Verbesserung der Abfrageleistung für Anfragen mit spezifischer oder technischer Sprache</p></li></ul></li><li><p><em>Vorteile:</em> </p><ul><li><p>Ruft möglicherweise relevante Dokumente ab, die nicht exakt den ursprünglichen Suchbegriffen entsprechen.</p></li><li><p>Kann dazu beitragen, Vokabeldiskrepanz zwischen Anfragen und Dokumenten zu überwinden.</p></li></ul></li><li><p><em>Herausforderungen:</em> </p><ul><li><p>Gefahr der Abfrageabweichung bei unsachgemäßer Implementierung</p></li><li><p>Kann den Rechenaufwand im Abrufprozess erhöhen</p></li></ul></li></ul><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1#table-of-contents">Zurück nach oben</a></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1</guid>
    <category><![CDATA[Vektordatenbank]]></category>
    <category><![CDATA[KI]]></category>
    <dc:creator><![CDATA[Han Xiang Choong]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9a4691874a19d8da/6a170b3f47d49c99f22d8a24/72b51ba2ae5e5977b56e5b915674753d6cfd0e56-1440x840.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 14 Aug 2024 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>