Freigeben über


Dateisuchtool in Azure OpenAI Assistants (Vorschau)

Die Dateisuche erweitert den Assistenten um Kenntnisse, die nicht im Modell enthalten sind, z. B. proprietäre Produktinformationen oder Dokumente, die von Ihren Benutzern bereitgestellt werden. OpenAI parst und gruppiert Ihre Dokumente automatisch, erstellt und speichert die Einbettungen und verwendet sowohl die Vektor- als auch die Schlüsselwortsuche, um relevante Inhalte abzurufen und Benutzerfragen zu beantworten.

Hinweis

Die Dateisuche wird derzeit nicht in Rechnung gestellt.

Hinweis

  • Die Dateisuche kann bis zu 10.000 Dateien pro Assistent erfassen – 500 mal mehr als bisher. Sie ist schnell, unterstützt parallele Abfragen durch Multithreadsuchvorgänge und beinhaltet verbesserte Funktionen für Neusortierung und das Umschreiben von Abfragen.
    • Der Vektorspeicher ist ein neues Objekt in der API. Sobald eine Datei einem Vektorspeicher hinzugefügt wurde, wird sie automatisch geparst, aufgeteilt und eingebettet, damit sie durchsucht werden kann. Vektorspeicher können über Assistenten und Threads hinweg verwendet werden und vereinfachen so die Dateiverwaltung und Abrechnung.
  • Wir haben Unterstützung für den Parameter tool_choice hinzugefügt. Dieser kann verwendet werden, um die Nutzung eines bestimmten Tools (z. B. Dateisuche, Codeinterpreter oder eine Funktion) in einer bestimmten Ausführung zu erzwingen.

Unterstützung der Dateisuche

Unterstützte Regionen

Die Dateisuche ist in Regionen verfügbar, die Assistenten unterstützen.

API-Version

  • 2024-05-01-preview

Unterstützte Dateitypen

Hinweis

Bei Text-/MIME-Typen muss die Codierung entweder utf-8, utf-16 oder ASCII sein.

Dateiformat MIME-Typ
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 application/pdf
.php text/x-php
.pptx application/vnd.openxmlformats-officedocument.presentationml.presentation
.py text/x-python
.py text/x-script.python
.rb text/x-ruby
.tex text/x-tex
.txt text/plain
.css text/css
.js text/javascript
.sh 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"}],
)

Um auf Ihre Dateien zuzugreifen, verwendet das Dateisuchtool das Vektorspeicherobjekt. Laden Sie Ihre Dateien hoch, und erstellen Sie einen Vektorspeicher für sie. Nachdem der Vektorspeicher erstellt wurde, sollten Sie den Status abfragen, bis alle Dateien nicht mehr im in_progress-Zustand sind. So wird sichergestellt, dass die Verarbeitung für alle Inhalte abgeschlossen wurde. Das SDK stellt Hilfsprogramme zum Hochladen und Abrufen bereit.

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)

Aktualisieren des Assistenten für die Verwendung des neuen Vektorspeichers

Um die Dateien für Ihren Assistenten zugänglich zu machen, aktualisieren Sie die tool_resources des Assistenten mit der neuen vector_store-ID.

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

Erstellen eines Threads

Sie können Dateien auch als Nachrichtenanlagen in Ihrem Thread anfügen. Dadurch wird ein weiterer vector_store erstellt, der dem Thread zugeordnet ist. Wenn bereits ein Vektorspeicher an diesen Thread angefügt ist, werden die neuen Dateien an den vorhandenen Threadvektorspeicher angefügt. Wenn Sie eine Ausführung in diesem Thread erstellen, fragt das Dateisuchtool sowohl den vector_store aus Ihrem Assistenten als auch den vector_store im Thread ab.

# 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)

Vektorspeicher werden mithilfe von Nachrichtenanlagen erstellt, die eine Standardablaufrichtlinie von sieben Tagen nach der letzten Aktivität aufweisen (definiert als der Zeitpunkt, an dem der Vektorspeicher das letzte Mal Teil einer Ausführung war). Diese Standardeinstellung ist vorhanden, um Ihre Vektorspeicherkosten zu verwalten. Sie können diese Ablaufrichtlinien jederzeit überschreiben.

Erstellen einer Ausführung und Überprüfen der Ausgabe

Wenn Sie eine Ausführung erstellen, können Sie beobachten, dass das Modell das Dateisuchtool verwendet, um eine Antwort auf die Frage des Benutzers bereitzustellen.

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()

Funktionsweise

Das Dateisuchtool implementiert standardmäßig mehrere bewährte Methoden für den Abruf, um die richtigen Daten aus Ihren Dateien zu extrahieren und die Antworten des Modells zu erweitern. Das file_search-Tool:

  • Schreibt Benutzerabfragen um, um sie für die Suche zu optimieren.
  • Unterteilt komplexe Benutzerabfragen in mehrere Suchvorgänge, die parallel ausgeführt werden können.
  • Führt Schlüsselwort- und semantische Suchen sowohl in Assistenten- als auch in Threadvektorspeichern aus.
  • Sortiert Suchergebnisse neu, um die relevantesten auszuwählen, bevor die endgültige Antwort generiert wird.
  • Standardmäßig verwendet das Dateisuchtool die folgenden Einstellungen:
    • Blockgröße: 800 Token
    • Blocküberlappung: 400 Token
    • Einbettungsmodell: text-embedding-3-large mit 256 Dimensionen
    • Maximale Anzahl von Blöcken, die dem Kontext hinzugefügt werden: 20

Vektorspeicher

Vektorspeicherobjekte bieten dem Dateisuchtool die Möglichkeit, Ihre Dateien zu durchsuchen. Durch das Hinzufügen einer Datei zu einem Vektorspeicher wird sie automatisch geparst, unterteilt und in eine Vektordatenbank eingebettet, die sowohl für die Schlüsselwort- als auch für die semantische Suche geeignet ist. Jeder Vektorspeicher kann bis zu 10.000 Dateien enthalten. Vektorspeicher können an Assistenten und Threads angefügt werden. Derzeit können Sie höchstens einen Vektorspeicher an einen Assistenten und höchstens einen Vektorspeicher an einen Thread anfügen.

Erstellen von Vektorspeichern und Hinzufügen von Dateien

Sie können in einem einzigen API-Aufruf einen Vektorspeicher erstellen und Dateien hinzufügen:

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

Das Hinzufügen von Dateien zu Vektorspeichern ist ein asynchroner Vorgang. Um sicherzustellen, dass der Vorgang abgeschlossen ist, empfehlen wir Ihnen, die Hilfsprogramme „Erstellen und Abfragen“ in unseren offiziellen SDKs zu verwenden. Wenn Sie die SDKs nicht verwenden, können Sie das vector_store-Objekt abrufen und dessen file_counts-Eigenschaft überwachen, um das Ergebnis des Dateierfassungsvorgangs anzuzeigen.

Dateien können auch zu einem Vektorspeicher hinzugefügt werden, nachdem er erstellt wurde, indem Sie Vektorspeicherdateien erstellen.

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

Alternativ können Sie einem Vektorspeicher mehrere Dateien hinzufügen, indem Sie Batches mit bis zu 500 Dateien erstellen.

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']
)

Ebenso können diese Dateien aus einem Vektorspeicher entfernt werden. Dazu haben Sie folgende Möglichkeiten:

  • Löschen des Vektorspeicherdateiobjekts oder
  • Löschen des zugrunde liegenden Dateiobjekts (wodurch die Datei aus allen vector_store- und code_interpreter-Konfigurationen in allen Assistenten und Threads in Ihrer Organisation entfernt wird)

Die maximale Dateigröße beträgt 512 MB. Jede Datei sollte nicht mehr als 5.000.000 Token pro Datei enthalten (wird automatisch berechnet, wenn Sie eine Datei anfügen).

Anfügen von Vektorspeichern

Sie können Vektorspeicher mithilfe des tool_resources-Parameters an Ihren Assistenten oder Thread anfügen.

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"]
    }
  }
)

Sie können einen Vektorspeicher auch an Threads oder Assistenten anfügen, nachdem sie erstellt wurden, indem Sie sie mit den richtigen tool_resources aktualisieren.

Sicherstellen der Bereitschaft des Vektorspeichers vor dem Erstellen von Ausführungen

Es wird dringend empfohlen, sicherzustellen, dass alle Dateien in einem vector_store vollständig verarbeitet wurden, bevor Sie eine Ausführung erstellen. Dadurch wird sichergestellt, dass alle Daten in Ihrem Vektorspeicher durchsuchbar sind. Sie können die Bereitschaft des Vektorspeichers überprüfen, indem Sie die Abrufhilfsprogramme in den SDKs verwenden oder das vector_store-Objekt manuell abfragen, um sicherzustellen, dass der Status „abgeschlossen“ ist.

Als Fallback gibt es eine maximale Wartezeit von 60 Sekunden im Ausführungsobjekt, wenn der Vektorspeicher des Threads Dateien enthält, die noch verarbeitet werden. Dadurch wird sichergestellt, dass alle Dateien, die Ihre Benutzer in einen Thread hochladen, vollständig durchsuchbar sind, bevor die Ausführung fortgesetzt wird. Diese Fallback-Wartezeit gilt nicht für den Vektorspeicher des Assistenten.

Verwalten von Kosten mit Ablaufrichtlinien

Das file_search-Tool verwendet das vector_stores-Objekt als Ressource, und die Abrechnung erfolgt basierend auf der Größe der erstellten vector_store-Objekte. Die Größe des Vektorspeicherobjekts ist die Summe aller geparsten Blöcke aus Ihren Dateien und der entsprechenden Einbettungen.

Um Ihnen bei der Verwaltung der Kosten für diese vector_store-Objekte zu helfen, haben wir Unterstützung für Ablaufrichtlinien im vector_store-Objekt hinzugefügt. Sie können diese Richtlinien beim Erstellen oder Aktualisieren des vector_store-Objekts festlegen.

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
  }
)

Standardablaufrichtlinien für Threadvektorspeicher

Vektorspeicher, die mithilfe von Threadhilfsprogrammen (wie tool_resources.file_search.vector_stores in Threads oder message.attachments in Nachrichten) erstellt wurden, haben eine Standardablaufrichtlinie von sieben Tagen nach der letzten Aktivität (definiert als der Zeitpunkt, an dem der Vektorspeicher das letzte Mal Teil einer Ausführung war).

Wenn ein Vektorspeicher abläuft, schlagen Ausführungen in diesem Thread fehl. Um dies zu beheben, können Sie einen neuen vector_store mit denselben Dateien neu erstellen und an den Thread anfügen.

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]
    )