共用方式為


Azure OpenAI Assistants 檔案搜尋工具 (預覽)

檔案搜尋會增強小幫手及其模型外部的知識,例如使用者提供的專屬產品資訊或檔。 OpenAI 會自動剖析和區塊檔、建立及儲存內嵌,並使用向量和關鍵詞搜尋來擷取相關內容來回應用戶查詢。

注意

檔案搜尋目前不會計費。

注意

  • 檔案搜尋 可以擷取每個助理最多 10,000 個檔案 - 比之前多 500 倍。 其速度很快,可透過多線程搜尋支援平行查詢,以及增強重新撰寫和查詢重寫的功能。
    • 向量存放區是 API 中的新物件。 一旦檔案新增至向量存放區,它就會自動剖析、區塊化和內嵌,準備好進行搜尋。 向量存放區可以跨助理和線程使用,簡化檔案管理和計費。
  • 我們已新增參數的支援 tool_choice ,可用來強制在特定執行中使用特定工具(例如檔案搜尋、程式代碼解釋器或函式)。

檔案搜尋支援

支援的區域

支援小幫手的區域提供檔案搜尋。

API 版本

  • 2024-05-01-preview

支援的檔案類型

注意

針對 text/MIME 類型,編碼必須是 utf-8、utf-16 或 ASCII。

File format 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 應用程式/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"}],
)

若要存取您的檔案,檔案搜尋工具會使用向量存放區物件。 上傳您的檔案,並建立向量存放區以包含它們。 建立向量存放區之後,您應該輪詢其狀態,直到所有檔案都脫離 in_progress 狀態,以確保所有內容都已完成處理。 SDK 提供上傳和輪詢的協助程式。

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)

更新小幫手以使用新的向量存放區

若要讓助理存取檔案,請使用新的vector_store識別碼更新助理的 tool_resources

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

建立執行緒

您也可以將檔案附加為線程上的訊息附件。 這樣做會建立與線程相關聯的另一個 vector_store ,或者,如果已經連結至這個線程的向量存放區,請將新檔案附加至現有的線程向量存放區。 當您在此執行時,檔案搜尋工具會同時從助理和vector_store線程上的 查詢 vector_store

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

向量存放區是使用訊息附件來建立的,其預設到期原則是在上次作用中后七天(定義為最後一次執行向量存放區的時間)。 此預設值可協助您管理向量儲存成本。 您可以隨時覆寫這些到期原則。

建立執行並檢查輸出

建立執行並觀察模型使用檔案搜尋工具來提供用戶問題的回應。

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

運作方式

檔案搜尋工具會立即實作數個擷取最佳做法,以協助您從檔案擷取正確的數據,並增強模型的回應。 file_search工具:

  • 重寫用戶查詢以將其優化以進行搜尋。
  • 將複雜的使用者查詢細分為可以平行執行的多個搜尋。
  • 跨助理和線程向量存放區執行關鍵詞和語意搜尋。
  • 在產生最終回應之前,重新調整搜尋結果以挑選最相關的搜尋結果。
  • 根據預設,檔案搜尋工具會使用下列設定:
    • 區塊大小:800 個令牌
    • 區塊重迭:400 個令牌
    • 內嵌模型:256 個維度的 text-embedding-3-large
    • 新增至內容的最大區塊數目:20

向量存放區

向量存放區物件可讓檔案搜尋工具搜尋您的檔案。 將檔案新增至向量存放區時,會自動剖析、區塊、內嵌檔案,並將檔案儲存在能夠同時進行關鍵詞和語意搜尋的向量資料庫中。 每個向量存放區最多可以保存10,000個檔案。 向量存放區可以附加至 Assistants 和 Threads。 您目前最多可以將一個向量存放區附加至助理,最多可以將一個向量存放區附加至線程。

建立向量存放區及新增檔案

您可以在單一 API 呼叫中建立向量存放區,並將檔案新增至其中:

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

將檔案新增至向量存放區是異步作業。 為了確保作業已完成,我們建議您在正式 SDK 中使用「建立和輪詢」協助程式。 如果您未使用 SDK,您可以擷取 vector_store 物件並監視其 file_counts 屬性,以查看檔案擷取作業的結果。

建立向量存放區檔案之後,也可以將檔案新增至向量存放區。

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

或者,您可以建立最多 500 個檔案的批次,將數個檔案新增至向量存放區。

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

同樣地,這些檔案也可以透過下列其中一項從向量存放區移除:

  • 刪除向量存放區檔案物件,或
  • 藉由刪除基礎檔案物件(這會從組織中所有助理和線程的所有vector_store中移除該檔案,並code_interpreter組態)

檔案大小上限為 512 MB。 每個檔案應包含每個檔案不超過 5,000,000 個令牌(當您附加檔案時自動計算)。

附加向量存放區

您可以使用 tool_resources 參數,將向量存放區附加至 Assistant 或 Thread。

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

您也可以將向量存放區附加至線程或小幫手,方法是使用正確的 tool_resources更新它們。

在建立執行之前確保向量存放區整備

強烈建議您在建立執行之前,先確定vector_store中的所有檔案都已完整處理。 這可確保可搜尋向量存放區中的所有數據。 您可以使用 SDK 中的輪詢協助程式,或手動輪詢 vector_store 對象以確保狀態已完成,來檢查向量存放區整備程度。

作為後援,當線程的向量存放區包含仍在處理的檔案時,Run 物件中會有 60 秒的最大等候時間。 這是為了確保您的用戶上傳的任何檔案在線程中,在繼續執行之前,可完全搜尋。 此後援等候不適用於助理的向量存放區。

使用到期原則管理成本

此工具 file_search 會使用 vector_stores 對象作為其資源,而您會根據所建立vector_store物件的大小來計費。 向量存放區物件的大小是檔案中所有剖析區塊的總和,以及其對應的內嵌。

為了協助您管理與這些vector_store對象相關聯的成本,我們已在物件中 vector_store 新增到期原則的支援。 您可以在建立或更新 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
  }
)

線程向量存放區有預設到期原則

使用線程協助程式建立的向量存放區(例如 tool_resources.file_search.vector_stores 在線程或 message.attachments 訊息中),其預設到期原則會在上次使用中后七天(定義為最後一次執行向量存放區的時間)。

當向量存放區過期時,在該線程上執行將會失敗。 若要修正此問題,您可以使用相同的檔案重新建立新的vector_store,並將其重新附加至線程。

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