Dela via


Filsökningsverktyg för Azure OpenAI Assistants (förhandsversion)

Filsökning utökar assistenten med kunskap utanför modellen, till exempel produktinformation eller dokument som tillhandahålls av dina användare. OpenAI parsar och segmenterar automatiskt dina dokument, skapar och lagrar inbäddningarna och använder både vektor- och nyckelordssökning för att hämta relevant innehåll för att besvara användarfrågor.

Viktigt!

  • Filsökning har ytterligare avgifter utöver de tokenbaserade avgifterna för Azure OpenAI-användning.

Kommentar

  • Filsökning kan mata in upp till 10 000 filer per assistent – 500 gånger mer än tidigare. Den är snabb, stöder parallella frågor via sökningar med flera trådar och funktioner för förbättrad omrankning och omskrivning av frågor.
    • Vector Store är ett nytt objekt i API:et. När en fil har lagts till i ett vektorlager parsas den automatiskt, segmenteras och bäddas in och görs redo att sökas igenom. Vektorlager kan användas mellan assistenter och trådar, vilket förenklar filhantering och fakturering.
  • Vi har lagt till stöd för parametern tool_choice som kan användas för att tvinga fram användningen av ett specifikt verktyg (till exempel filsökning, kodtolkare eller en funktion) i en viss körning.

Stöd för filsökning

Regioner som stöds

Filsökning är tillgängligt i regioner som stöder assistenter.

API-version

  • Förhandsversion 2024-05-01

Filtyper som stöds

Kommentar

För text-/MIME-typer måste kodningen vara antingen utf-8, utf-16 eller ASCII.

File format 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 program/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"}],
)

För att komma åt dina filer använder filsökningsverktyget vektorlagringsobjektet. Ladda upp dina filer och skapa ett vektorarkiv som innehåller dem. När vektorarkivet har skapats bör du avsöka dess status tills alla filer inte är i tillstånd för att säkerställa att allt innehåll har slutfört bearbetningen in_progress . SDK:t tillhandahåller hjälp för uppladdning och avsökning.

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)

Uppdatera assistenten så att den använder det nya vektorarkivet

Om du vill göra filerna tillgängliga för din assistent uppdaterar du assistentens tool_resources med det nya vector_store ID:t.

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

Skapa en tråd

Du kan också bifoga filer som bifogade filer i tråden. Om du gör det skapas en annan vector_store som är associerad med tråden, eller om det redan finns ett vektorlager kopplat till den här tråden, bifogar du de nya filerna till det befintliga trådvektorarkivet. När du skapar en Kör på den här tråden frågar filsökningsverktyget både från assistenten vector_store vector_store och i tråden.

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

Vektorlager skapas med hjälp av meddelandebilagor som har en standardprincip för förfallotid på sju dagar efter att de senast var aktiva (definieras som den senaste gången vektorarkivet var en del av en körning). Det här standardvärdet finns för att hjälpa dig att hantera dina kostnader för vektorlagring. Du kan när som helst åsidosätta dessa förfalloprinciper.

Skapa en körning och kontrollera utdata

Skapa en Kör och observera att modellen använder filsökningsverktyget för att ge ett svar på användarens fråga.

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

Hur det fungerar

Filsökningsverktyget implementerar flera metodtips för hämtning direkt för att hjälpa dig att extrahera rätt data från dina filer och utöka modellens svar. Verktyget file_search:

  • Skriver om användarfrågor för att optimera dem för sökning.
  • Delar upp komplexa användarfrågor i flera sökningar som kan köras parallellt.
  • Kör både nyckelords- och semantiska sökningar i både assistent- och trådvektorlager.
  • Reranks sökresultat för att välja de mest relevanta innan du genererar det slutliga svaret.
  • Som standard använder filsökningsverktyget följande inställningar:
    • Segmentstorlek: 800 token
    • Segment överlappning: 400 token
    • Inbäddningsmodell: textinbäddning-3-stor vid 256 dimensioner
    • Maximalt antal segment som lagts till i kontexten: 20

Vektorlager

Vektorlagringsobjekt ger filsökningsverktyget möjlighet att söka i dina filer. Genom att lägga till en fil i ett vektorlager parsas, segment, bäddas in och lagras filen i en vektordatabas som kan både nyckelords- och semantisk sökning. Varje vektorlager kan innehålla upp till 10 000 filer. Vektorlager kan kopplas till både assistenter och trådar. För närvarande kan du koppla högst ett vektorlager till en assistent och högst ett vektorlager till en tråd.

Skapa vektorlager och lägga till filer

Du kan skapa ett vektorlager och lägga till filer i det i ett enda API-anrop:

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

Att lägga till filer i vektorlager är en asynkron åtgärd. För att säkerställa att åtgärden är klar rekommenderar vi att du använder hjälparna "skapa och avsöka" i våra officiella SDK:er. Om du inte använder SDK:erna kan du hämta vector_store objektet och övervaka dess file_counts egenskap för att se resultatet av filinmatningsåtgärden.

Filer kan också läggas till i ett vektorlager när det har skapats genom att skapa filer för vektorlagring.

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

Du kan också lägga till flera filer i ett vektorlager genom att skapa batchar med upp till 500 filer.

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

På samma sätt kan dessa filer tas bort från ett vektorlager genom att antingen:

  • Ta bort vektorlagringsfilobjektet eller,
  • Genom att ta bort det underliggande filobjektet (som tar bort filen från alla vector_store och code_interpreter konfigurationer i alla assistenter och trådar i din organisation)

Den maximala filstorleken är 512 MB. Varje fil får inte innehålla fler än 5 000 000 token per fil (beräknas automatiskt när du bifogar en fil).

Koppla vektorlager

Du kan koppla vektorlager till assistenten eller tråden med hjälp av parametern 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"]
    }
  }
)

Du kan också koppla ett vektorlager till trådar eller assistenter när de har skapats genom att uppdatera dem med rätt tool_resources.

Säkerställa beredskap för vektorlager innan du skapar körningar

Vi rekommenderar starkt att du ser till att alla filer i en vector_store bearbetas fullständigt innan du skapar en körning. Detta säkerställer att alla data i vektorlagret är sökbara. Du kan söka efter beredskap för vektorlager med hjälp av avsökningshjälparna i SDK:erna eller genom att manuellt avsöka vector_store objektet för att säkerställa att statusen har slutförts.

Som reserv finns det en maximal väntetid på 60 sekunder i körningsobjektet när trådens vektorarkiv innehåller filer som fortfarande bearbetas. Detta är för att säkerställa att alla filer som användarna laddar upp i en tråd är helt sökbara innan körningen fortsätter. Den här reservväntningen gäller inte för assistentens vektorarkiv.

Hantera kostnader med förfalloprinciper

Verktyget file_search använder objektet vector_stores som resurs och du debiteras baserat på storleken på de vector_store objekt som skapas. Storleken på vektorlagringsobjektet är summan av alla parsade segment från dina filer och deras motsvarande inbäddningar.

För att hjälpa dig att hantera kostnaderna för dessa vector_store objekt har vi lagt till stöd för förfalloprinciper i vector_store objektet. Du kan ange dessa principer när du skapar eller uppdaterar objektet 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
  }
)

Trådvektorlager har standardprinciper för förfallodatum

Vektorlager som skapats med hjälp av trådhjälpare (till exempel tool_resources.file_search.vector_stores i Trådar eller message.attachments i Meddelanden) har en standardprincip för förfallotid på sju dagar efter att de senast var aktiva (definieras som den senaste gången vektorarkivet var en del av en körning).

När ett vektorlager upphör att gälla misslyckas körningen på den tråden. Du kan åtgärda detta genom att återskapa en ny vector_store med samma filer och koppla den till tråden igen.

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