Sdílet prostřednictvím


Kurz: Návrh indexu pro RAG ve službě Azure AI Search

Index obsahuje prohledávatelný text a vektorový obsah a konfigurace. V modelu RAG, který používá model chatu pro odpovědi, chcete mít index navržený kolem bloků obsahu, které je možné předat LLM v době dotazu.

V tomto kurzu se naučíte:

  • Seznamte se s charakteristikami schématu indexu sestaveného pro RAG.
  • Vytvoření indexu, který bude obsahovat vektorové a hybridní dotazy
  • Přidání vektorových profilů a konfigurací
  • Přidání strukturovaných dat
  • Přidání filtrování

Požadavky

Visual Studio Code s rozšířením Pythonu a balíčkem Jupyter Další informace najdete v pythonu v editoru Visual Studio Code.

Výstupem tohoto cvičení je definice indexu ve formátu JSON. V tomto okamžiku se nenahraje do služby Azure AI Search, takže v tomto cvičení nejsou žádné požadavky na cloudové služby ani oprávnění.

Kontrola důležitých aspektů schématu pro RAG

V konverzačním vyhledávání vytvoří LLM odpověď, kterou uživatel uvidí, ne vyhledávací web, takže nemusíte přemýšlet o tom, jaká pole se mají zobrazit ve výsledcích hledání a jestli jsou reprezentace jednotlivých vyhledávacích dokumentů koherentní pro uživatele. V závislosti na otázce může LLM vrátit doslovný obsah z indexu nebo s větší pravděpodobností znovu zabalit obsah pro lepší odpověď.

Uspořádané kolem bloků dat

Když LLM vygenerují odpověď, pracují na blocích obsahu pro vstupy zpráv a zatímco potřebují vědět, odkud blok dat pochází pro účely citace, co je nejdůležitější, je kvalita vstupů zpráv a její význam pro otázku uživatele. Ať už bloky dat pocházejí z jednoho dokumentu nebo tisíce, LLM ingestuje informace nebo podkladová data a formuluje odpověď podle pokynů uvedených v příkazovém řádku systému.

Bloky dat jsou fokusem schématu a každý blok dat je definující prvek hledaného dokumentu ve vzoru RAG. Index si můžete představit jako velkou kolekci bloků, na rozdíl od tradičních vyhledávacích dokumentů, které pravděpodobně mají větší strukturu, například pole obsahující jednotný obsah pro název, popisy, kategorie a adresy.

Vylepšené s vygenerovanými daty

V tomto kurzu se ukázková data skládají z souborů PDF a obsahu z knihy NASA Earth Book. Tento obsah je popisný a informativní, s mnoha odkazy na zeměpisné oblasti, země a oblasti po celém světě. Veškerý textový obsah je zachycen v blocích, ale opakované instance názvů míst vytvářejí příležitost pro přidání struktury do indexu. Pomocí dovedností je možné rozpoznat entity v textu a zachytit je v indexu pro použití v dotazech a filtrech. V tomto kurzu zahrneme dovednost rozpoznávání entit, která rozpoznává a extrahuje entity polohy a načítá je do prohledávatelného a filtrovatelného locations pole. Přidáním strukturovaného obsahu do indexu získáte další možnosti filtrování, lepší relevance a lépe zaměřené odpovědi.

Pole nadřazený-podřízený v jednom nebo dvou indexech?

Blokovaný obsah se obvykle odvozuje od většího dokumentu. I když je schéma uspořádané kolem bloků dat, chcete také zachytit vlastnosti a obsah na nadřazené úrovni. Příklady těchto vlastností můžou zahrnovat cestu k nadřazeným souborům, název, autory, datum publikování nebo souhrn.

Inflexní bod v návrhu schématu je to, zda mají mít dva indexy pro nadřazený a podřízený/blokovaný obsah, nebo jeden index, který opakuje nadřazené prvky pro každý blok dat.

V tomto kurzu, protože všechny bloky textu pocházejí z jednoho nadřazeného objektu (NASA Earth Book), nepotřebujete samostatný index vyhrazený na úrovni nadřazených polí. Pokud ale indexujete z více nadřazených souborů PDF, můžete chtít, aby pár indexů nadřazený-podřízený zachytával pole specifická pro danou úroveň a potom do nadřazeného indexu odesílal vyhledávací dotazy , aby tato pole načetla relevantní pro každý blok dat.

Kontrolní seznam důležitých aspektů schématu

Ve službě Azure AI Search má index, který nejlépe vyhovuje úlohám RAG, tyto vlastnosti:

  • Vrátí bloky dat, které jsou relevantní pro dotaz a čitelné pro LLM. LLM dokáže zpracovat určitou úroveň zašpiněných dat v blocích, jako jsou označení, redundance a neúplné řetězce. I když bloky dat musí být čitelné a relevantní pro danou otázku, nemusí být nedotčené.

  • Udržuje vztah nadřazený-podřízený mezi bloky dokumentu a vlastnostmi nadřazeného dokumentu, jako je název souboru, typ souboru, název, autor atd. Pokud chcete odpovědět na dotaz, můžou se bloky načíst z libovolného místa v indexu. Přidružení k nadřazeným dokumentům poskytujícím blok dat je užitečné pro kontext, citace a následné dotazy.

  • Vyhodí dotazy, které chcete vytvořit. Měli byste mít pole pro vektorový a hybridní obsah a tato pole by měla být přiřazovat, aby podporovala konkrétní chování dotazů, jako je prohledávatelné nebo filtrovatelné. Dotazovat se můžete vždy jen na jeden index (bez spojení), takže kolekce polí by měla definovat veškerý prohledávatelný obsah.

  • Schéma by mělo být buď ploché (bez složitých typů nebo struktur), nebo byste před odesláním do LLM měli formátovat výstup komplexního typu jako JSON . Tento požadavek je specifický pro model RAG ve službě Azure AI Search.

Poznámka:

Návrh schématu ovlivňuje úložiště a náklady. Toto cvičení se zaměřuje na základy schématu. V kurzu Minimalizovat úložiště a náklady se znovu seznámíte se schématy, abyste se dozvěděli, jak úzké datové typy, komprese a možnosti úložiště výrazně snižují množství úložiště používané vektory.

Vytvoření indexu pro úlohy RAG

Minimální index pro LLM je navržený tak, aby ukládaly bloky obsahu. Pokud chcete vyhledat vysoce relevantní výsledky, obvykle obsahuje vektorová pole. Obsahuje také nevectorová pole pro vstupy čitelné člověkem do LLM pro konverzační vyhledávání. Nevector blokovaný obsah ve výsledcích hledání se stane uzemněním dat odesílaných do LLM.

  1. Otevřete Visual Studio Code a vytvořte nový soubor. Pro toto cvičení nemusí být typem souboru Pythonu.

  2. Tady je minimální definice indexu pro řešení RAG, která podporují vektorové a hybridní vyhledávání. Projděte si úvod k požadovaným prvkům: název indexu, pole a oddíl konfigurace pro vektorová pole.

    {
      "name": "example-minimal-index",
      "fields": [
        { "name": "id", "type": "Edm.String", "key": true },
        { "name": "chunked_content", "type": "Edm.String", "searchable": true, "retrievable": true },
        { "name": "chunked_content_vectorized", "type": "Edm.Single", "dimensions": 1536, "vectorSearchProfile": "my-vector-profile", "searchable": true, "retrievable": false, "stored": false },
        { "name": "metadata", "type": "Edm.String", "retrievable": true, "searchable": true, "filterable": true }
      ],
      "vectorSearch": {
          "algorithms": [
              { "name": "my-algo-config", "kind": "hnsw", "hnswParameters": { }  }
          ],
          "profiles": [ 
            { "name": "my-vector-profile", "algorithm": "my-algo-config" }
          ]
      }
    }
    

    Pole musí obsahovat klíčové pole ("id" v tomto příkladu) a měly by obsahovat vektorové bloky pro vyhledávání podobnosti a bloky nevectoru pro vstupy do LLM.

    Vektorová pole jsou přidružená k algoritmům, které určují cesty hledání v době dotazu. Index má oddíl vectorSearch pro zadání více konfigurací algoritmů. Vektorová pole mají také specifické typy a další atributy pro dimenze modelu vložení. Edm.Single je datový typ, který funguje pro běžně používané LLM. Další informace o vektorovýchpolích

    Pole metadat můžou být cesta k nadřazeného souboru, datum vytvoření nebo typ obsahu a jsou užitečná pro filtry.

  3. Tady je schéma indexu pro zdrojový kód kurzu a obsah Earth Booku.

    Podobně jako základní schéma je uspořádané kolem bloků dat. Jednoznačně chunk_id identifikuje každý blok dat. Pole text_vector je vložením bloku dat. Pole bezvectoru chunk je čitelný řetězec. Mapuje title se na jedinečnou cestu úložiště metadat pro objekty blob. Toto parent_id je jediné pole na úrovni nadřazené a jedná se o verzi identifikátoru URI nadřazeného souboru s kódováním base64.

    V integrovaných vektorizačních úlohách, jako je ta, která se používá v této sérii kurzů, dimensions by vlastnost vektorových polí měla být shodná s počtem dimensions vygenerovaných dovedností vkládání, která se používá k vektorizaci dat. V této sérii používáme dovednost vkládání Azure OpenAI, která v Azure OpenAI volá model s vkládáním textu do 3 velkých modelů. Dovednost je určena v dalším kurzu. Rozměry jsme nastavili na 1024 v vektorovém poli i v definici dovednosti.

    Schéma obsahuje locations také pole pro ukládání generovaného obsahu vytvořeného kanálem indexování.

     from azure.identity import DefaultAzureCredential
     from azure.identity import get_bearer_token_provider
     from azure.search.documents.indexes import SearchIndexClient
     from azure.search.documents.indexes.models import (
         SearchField,
         SearchFieldDataType,
         VectorSearch,
         HnswAlgorithmConfiguration,
         VectorSearchProfile,
         AzureOpenAIVectorizer,
         AzureOpenAIVectorizerParameters,
         SearchIndex
     )
    
     credential = DefaultAzureCredential()
    
     # Create a search index  
     index_name = "py-rag-tutorial-idx"
     index_client = SearchIndexClient(endpoint=AZURE_SEARCH_SERVICE, credential=credential)  
     fields = [
         SearchField(name="parent_id", type=SearchFieldDataType.String),  
         SearchField(name="title", type=SearchFieldDataType.String),
         SearchField(name="locations", type=SearchFieldDataType.Collection(SearchFieldDataType.String), filterable=True),
         SearchField(name="chunk_id", type=SearchFieldDataType.String, key=True, sortable=True, filterable=True, facetable=True, analyzer_name="keyword"),  
         SearchField(name="chunk", type=SearchFieldDataType.String, sortable=False, filterable=False, facetable=False),  
         SearchField(name="text_vector", type=SearchFieldDataType.Collection(SearchFieldDataType.Single), vector_search_dimensions=1024, vector_search_profile_name="myHnswProfile")
         ]  
    
     # Configure the vector search configuration  
     vector_search = VectorSearch(  
         algorithms=[  
             HnswAlgorithmConfiguration(name="myHnsw"),
         ],  
         profiles=[  
             VectorSearchProfile(  
                 name="myHnswProfile",  
                 algorithm_configuration_name="myHnsw",  
                 vectorizer_name="myOpenAI",  
             )
         ],  
         vectorizers=[  
             AzureOpenAIVectorizer(  
                 vectorizer_name="myOpenAI",  
                 kind="azureOpenAI",  
                 parameters=AzureOpenAIVectorizerParameters(  
                     resource_url=AZURE_OPENAI_ACCOUNT,  
                     deployment_name="text-embedding-3-large",
                     model_name="text-embedding-3-large"
                 ),
             ),  
         ], 
     )  
    
     # Create the search index
     index = SearchIndex(name=index_name, fields=fields, vector_search=vector_search)  
     result = index_client.create_or_update_index(index)  
     print(f"{result.name} created")  
    
  4. Pro schéma indexu, které přesněji napodobuje strukturovaný obsah, byste měli samostatné indexy pro nadřazená a podřízená pole (blokovaná). K koordinaci indexování těchto dvou indexů současně potřebujete projekce indexů. Dotazy se provádějí s podřízeným indexem. Logika dotazu zahrnuje vyhledávací dotaz pomocí parent_idt načtení obsahu z nadřazeného indexu.

    Pole v podřízeného indexu:

    • ID
    • chunk
    • chunkVectcor
    • parent_id

    Pole v nadřazeného indexu (vše, co chcete "jedno z"):

    • parent_id
    • Pole nadřazené úrovně (název, název, kategorie)

Další krok