Nástroj azure OpenAI Assistants pro vyhledávání souborů (Preview)

Vyhledávání souborů rozšiřuje asistenta o znalosti mimo jeho model, jako jsou informace o vlastním produktu nebo dokumenty poskytované vašimi uživateli. OpenAI automaticky parsuje a ukládá dokumenty, vytváří a ukládá vložené položky a pomocí vektoru a vyhledávání klíčových slov načítá relevantní obsah pro odpovědi na dotazy uživatelů.

Důležité

  • Vyhledávání souborů má další poplatky nad rámec poplatků založených na tokenech za využití Azure OpenAI.

Poznámka:

  • Hledání souborů může ingestovat až 10 000 souborů na asistenta – 500krát více než dříve. Je to rychlý způsob, podporuje paralelní dotazy prostřednictvím vícevláknového vyhledávání a vylepšeného řazení a přepisování dotazů.
    • Vektorové úložiště je nový objekt v rozhraní API. Jakmile se soubor přidá do úložiště vektorů, automaticky se parsuje, zachytá a vloží a připraví k hledání. Vektorová úložiště se dají používat napříč asistenty a vlákny, což zjednodušuje správu souborů a fakturaci.
  • Přidali jsme podporu parametru tool_choice , který se dá použít k vynucení použití konkrétního nástroje (například vyhledávání souborů, interpret kódu nebo funkce) v určitém spuštění.

Podpora vyhledávání souborů

Podporované oblasti

Hledání souborů je dostupné v oblastech , které podporují asistenty.

Verze rozhraní API

  • 2024-05-01-preview

Podporované typy souborů

Poznámka:

U typů text/MIME musí být kódování buď utf-8, utf-16 nebo ASCII.

File format Typ MIME
c. text/x-c
.cs text/x-csharp
.Cpp text/x-c++
.doc application/msword
.docx application/vnd.openxmlformats-officedocument.wordprocessingml.document
.html, text/html
.java text/x-java
.json application/json
.md text/markdown
.pdf aplikace/pdf
.php text/x-php
.pptx application/vnd.openxmlformats-officedocument.presentationml.presentation
.py text/x-python
.py text/x-script.python
.rubidium text/x-ruby
.Tex text/x-tex
.txt text/plain
.Css text/css
.js text/javascript
.pst application/x-sh
.Ts application/typescript
from openai import AzureOpenAI
    
client = AzureOpenAI(
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),  
    api_version="2024-05-01-preview",
    azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
    )

assistant = client.beta.assistants.create(
  name="Financial Analyst Assistant",
  instructions="You are an expert financial analyst. Use your knowledge base to answer questions about audited financial statements.",
  model="gpt-4-turbo",
  tools=[{"type": "file_search"}],
)

Pro přístup k souborům používá nástroj pro vyhledávání souborů objekt úložiště vektorů. Nahrajte soubory a vytvořte vektorové úložiště, které je bude obsahovat. Po vytvoření vektorového úložiště byste se měli dotazovat na jeho stav, dokud nebudou in_progress všechny soubory mimo stav, aby se zajistilo, že zpracování veškerého obsahu bylo dokončeno. Sada SDK poskytuje pomocné rutiny pro nahrávání a dotazování.

from openai import AzureOpenAI
    
client = AzureOpenAI(
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),  
    api_version="2024-05-01-preview",
    azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
    )

# Create a vector store called "Financial Statements"
vector_store = client.beta.vector_stores.create(name="Financial Statements")
 
# Ready the files for upload to OpenAI
file_paths = ["mydirectory/myfile1.pdf", "mydirectory/myfile2.txt"]
file_streams = [open(path, "rb") for path in file_paths]
 
# Use the upload and poll SDK helper to upload the files, add them to the vector store,
# and poll the status of the file batch for completion.
file_batch = client.beta.vector_stores.file_batches.upload_and_poll(
  vector_store_id=vector_store.id, files=file_streams
)
 
# You can print the status and the file counts of the batch to see the result of this operation.
print(file_batch.status)
print(file_batch.file_counts)

Aktualizujte asistenta tak, aby používal nové úložiště vektorů.

Pokud chcete, aby byly soubory přístupné vašemu asistentovi, aktualizujte ho tool_resources novým vector_store ID.

assistant = client.beta.assistants.update(
  assistant_id=assistant.id,
  tool_resources={"file_search": {"vector_store_ids": [vector_store.id]}},
)

Vytvoření vlákna

Soubory můžete také připojit jako přílohy zprávy ve vlákně. Tím vytvoříte další vector_store přidružené vlákno, nebo pokud už je k tomuto vláknu připojeno vektorové úložiště, připojte nové soubory k existujícímu úložišti vektorů vláken. Když vytvoříte spustit v tomto vlákně, nástroj pro vyhledávání souborů se dotazuje jak vector_store z vašeho asistenta, tak z vector_store vlákna.

# Upload the user provided file to OpenAI
message_file = client.files.create(
  file=open("mydirectory/myfile.pdf", "rb"), purpose="assistants"
)
 
# Create a thread and attach the file to the message
thread = client.beta.threads.create(
  messages=[
    {
      "role": "user",
      "content": "How many company shares were outstanding last quarter?",
      # Attach the new file to the message.
      "attachments": [
        { "file_id": message_file.id, "tools": [{"type": "file_search"}] }
      ],
    }
  ]
)
 
# The thread now has a vector store with that file in its tool resources.
print(thread.tool_resources.file_search)

Vektorové úložiště se vytvářejí pomocí příloh zpráv, které mají výchozí zásadu vypršení platnosti 7 dnů po jejich poslední aktivní (definováno jako poslední, kdy bylo úložiště vektorů součástí spuštění). Toto výchozí nastavení vám pomůže se správou nákladů na úložiště vektorů. Tyto zásady vypršení platnosti můžete kdykoli přepsat.

Vytvoření spuštění a kontrola výstupu

Vytvořte spuštění a všimněte si, že model používá nástroj pro vyhledávání souborů k poskytnutí odpovědi na otázku uživatele.

from typing_extensions import override
from openai import AssistantEventHandler, OpenAI
 
client = OpenAI()
 
class EventHandler(AssistantEventHandler):
    @override
    def on_text_created(self, text) -> None:
        print(f"\nassistant > ", end="", flush=True)

    @override
    def on_tool_call_created(self, tool_call):
        print(f"\nassistant > {tool_call.type}\n", flush=True)

    @override
    def on_message_done(self, message) -> None:
        # print a citation to the file searched
        message_content = message.content[0].text
        annotations = message_content.annotations
        citations = []
        for index, annotation in enumerate(annotations):
            message_content.value = message_content.value.replace(
                annotation.text, f"[{index}]"
            )
            if file_citation := getattr(annotation, "file_citation", None):
                cited_file = client.files.retrieve(file_citation.file_id)
                citations.append(f"[{index}] {cited_file.filename}")

        print(message_content.value)
        print("\n".join(citations))


# Then, we use the stream SDK helper
# with the EventHandler class to create the Run
# and stream the response.

with client.beta.threads.runs.stream(
    thread_id=thread.id,
    assistant_id=assistant.id,
    instructions="Please address the user as Jane Doe. The user has a premium account.",
    event_handler=EventHandler(),
) as stream:
    stream.until_done()

Jak to funguje

Nástroj pro vyhledávání souborů implementuje několik osvědčených postupů načítání, které vám pomůžou extrahovat správná data ze souborů a rozšířit odpovědi modelu. Nástroj file_search:

  • Přepíše dotazy uživatelů, aby je optimalizoval pro vyhledávání.
  • Rozdělí složité dotazy uživatelů do několika vyhledávání, které může běžet paralelně.
  • Spouští klíčová i sémantická hledání v úložištích vektorů asistentů i vláken.
  • Výsledky hledání se před vygenerováním konečné odpovědi znovu seřadí a vyberou ty nejrelevavantnější.
  • Ve výchozím nastavení nástroj pro vyhledávání souborů používá následující nastavení:
    • Velikost bloku: 800 tokenů
    • Překrývající se blok dat: 400 tokenů
    • Model vkládání: text-embedding-3-large s 256 rozměry
    • Maximální počet bloků dat přidaných do kontextu: 20

Vektorová úložiště

Objekty vektorového úložiště poskytují nástroji pro vyhledávání souborů možnost prohledávat soubory. Přidání souboru do vektorového úložiště automaticky parsuje, bloky dat, vkládání a ukládá soubor do vektorové databáze, která dokáže klíčové slovo i sémantické vyhledávání. Každé úložiště vektorů může obsahovat až 10 000 souborů. Vektorové úložiště lze připojit ke asistentům i vláknům. V současné době můžete k asistentovi připojit maximálně jedno vektorové úložiště a k vláknu maximálně jedno úložiště vektorů.

Vytváření vektorových úložišť a přidávání souborů

Můžete vytvořit vektorové úložiště a přidat do něj soubory v jednom volání rozhraní API:

vector_store = client.beta.vector_stores.create(
  name="Product Documentation",
  file_ids=['file_1', 'file_2', 'file_3', 'file_4', 'file_5']
)

Přidání souborů do vektorových úložišť je asynchronní operace. Abyste měli jistotu, že je operace dokončená, doporučujeme použít pomocné rutiny pro vytváření a hlasování v našich oficiálních sadách SDK. Pokud sady SDK nepoužíváte, můžete načíst vector_store objekt a monitorovat jeho file_counts vlastnost, abyste viděli výsledek operace příjmu souborů.

Soubory lze také přidat do vektorového úložiště po vytvoření vytvořením souborů vektorového úložiště.

file = client.beta.vector_stores.files.create_and_poll(
  vector_store_id="vs_abc123",
  file_id="file-abc123"
)

Alternativně můžete do úložiště vektorů přidat několik souborů vytvořením dávek až 500 souborů.

batch = client.beta.vector_stores.file_batches.create_and_poll(
  vector_store_id="vs_abc123",
  file_ids=['file_1', 'file_2', 'file_3', 'file_4', 'file_5']
)

Podobně lze tyto soubory z úložiště vektorů odebrat buď:

  • Odstraněním objektu souboru úložiště vektorů nebo
  • Odstraněním základního objektu souboru (který odebere soubor ze všech konfigurací vector_store a code_interpreterve všech asistentech a vláknech ve vaší organizaci)

Maximální velikost souboru je 512 MB. Každý soubor by měl obsahovat maximálně 5 000 000 tokenů na soubor (při připojení souboru se počítá automaticky).

Připojení úložišť vektorů

Vektorové úložiště můžete připojit ke svému asistentovi nebo vláknu pomocí parametru tool_resources.

assistant = client.beta.assistants.create(
  instructions="You are a helpful product support assistant and you answer questions based on the files provided to you.",
  model="gpt-4-turbo",
  tools=[{"type": "file_search"}],
  tool_resources={
    "file_search": {
      "vector_store_ids": ["vs_1"]
    }
  }
)

thread = client.beta.threads.create(
  messages=[ { "role": "user", "content": "How do I cancel my subscription?"} ],
  tool_resources={
    "file_search": {
      "vector_store_ids": ["vs_2"]
    }
  }
)

Vektorové úložiště můžete také připojit ke vláknům nebo asistentům po jejich vytvoření tak, že je aktualizujete pravým tool_resourcestlačítkem .

Zajištění připravenosti úložiště vektorů před vytvořením spuštění

Důrazně doporučujeme, abyste před vytvořením spuštění zajistili, že všechny soubory v vector_store budou plně zpracovány. Tím zajistíte, že všechna data ve vašem vektorovém úložišti budou prohledávatelná. Připravenost úložiště vektorů můžete zkontrolovat pomocí pomocných rutin dotazování v sadách SDK nebo ručním dotazováním objektu vector_store , aby se zajistilo dokončení stavu.

Jako záložní úložiště existuje 60sekundový maximální čekání v objektu spuštění, když úložiště vektorů vlákna obsahuje soubory, které se stále zpracovávají. To zajistí, aby všechny soubory, které uživatelé nahrají do vlákna, plně prohledávatelné před zahájením spuštění. Toto náhradní čekání se nevztahuje na úložiště vektorů asistenta.

Správa nákladů pomocí zásad vypršení platnosti

Nástroj file_search použije vector_stores objekt jako prostředek a bude vám účtován na základě velikosti vytvořených objektů vector_store. Velikost objektu úložiště vektorů je součet všech parsovaných bloků dat z vašich souborů a jejich odpovídajících vložených objektů.

Abychom vám pomohli se správou nákladů spojených s těmito vector_store objekty, přidali jsme podporu zásad vypršení platnosti objektu vector_store . Tyto zásady můžete nastavit při vytváření nebo aktualizaci objektu vector_store .

vector_store = client.beta.vector_stores.create_and_poll(
  name="Product Documentation",
  file_ids=['file_1', 'file_2', 'file_3', 'file_4', 'file_5'],
  expires_after={
	  "anchor": "last_active_at",
	  "days": 7
  }
)

Úložiště vektorů vláken mají výchozí zásady vypršení platnosti.

Vektorová úložiště vytvořená pomocí pomocných rutin vláken (například tool_resources.file_search.vector_stores ve vláknech nebo message.attachments ve zprávách) mají výchozí zásadu vypršení platnosti sedm dnů po jejich poslední aktivní (definováno jako poslední, kdy bylo úložiště vektorů součástí spuštění).

Když vyprší platnost úložiště vektorů, spuštění v daném vlákně selže. Pokud chcete tento problém vyřešit, můžete znovu vytvořit nový vector_store se stejnými soubory a znovu ho připojit k vláknu.

all_files = list(client.beta.vector_stores.files.list("vs_expired"))

vector_store = client.beta.vector_stores.create(name="rag-store")
client.beta.threads.update(
    "thread_abc123",
    tool_resources={"file_search": {"vector_store_ids": [vector_store.id]}},
)

for file_batch in chunked(all_files, 100):
    client.beta.vector_stores.file_batches.create_and_poll(
        vector_store_id=vector_store.id, file_ids=[file.id for file in file_batch]
    )