Azure OpenAI Assistants のファイル検索ツール (プレビュー)
ファイル検索は、財産的価値のある製品情報やユーザーから提供されたドキュメントなど、モデルの外部からの知識でアシスタントを強化します。 OpenAI は、ドキュメントの解析とチャンク化、埋め込みの作成と保存を自動的に行い、ベクトル検索とキーワード検索の両方を使用して関連コンテンツを取得し、ユーザーのクエリに回答します。
重要
- ファイル検索では、Azure OpenAI の使用に対するトークン ベースの料金の他に、追加料金が発生します。
Note
- ファイル検索では、アシスタントあたり最大 10,000 個のファイルを取り込むことができます。これは以前の 500 倍以上の量です。 これは高速で、マルチスレッド検索を通して並列クエリをサポートしており、強化された再ランク付けとクエリの書き換えを特徴としています。
- ベクトル ストアは、API 内の新しいオブジェクトです。 ファイルがベクトル ストアに追加されると、自動的にそのファイルの解析、チャンク、埋め込みが行われ、検索の準備が整います。 ベクトル ストアは、複数のアシスタントとスレッドにわたって使用できるため、ファイル管理と課金が単純化されます。
- 特定の実行で特定のツール (ファイル検索、コード インタープリター、関数など) の使用を強制するために使用できる
tool_choice
パラメーターのサポートが追加されました。
ファイル検索のサポート
サポートされているリージョン
ファイル検索は、Assistants をサポートしているリージョンで使用できます。
API バージョン
- 2024-05-01-preview
サポートされるファイルの種類
Note
テキストまたは MIME の種類の場合、エンコードは utf-8、utf-16、または ASCII のいずれかである必要があります。
ファイル形式 | 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 |
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"}],
)
ファイル検索用のファイルをアップロードする
ファイルにアクセスするために、ファイル検索ツールではベクトル ストア オブジェクトを使用します。 ファイルをアップロードし、それらを格納するベクトル ストアを作成します。 ベクトル ストアが作成されたら、すべてのファイルが 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)
新しいベクトル ストアを使用するようにアシスタントを更新する
アシスタントがファイルにアクセスできるようにするには、アシスタントの tool_resources
を新しい vector_store
ID で更新します。
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)
ベクトル ストアは、メッセージ添付ファイルを使用して作成され、既定では最後にアクティブになった後 (ベクトル ストアが実行の一部であった最後の時刻として定義されます) 7 日間という有効期限ポリシーがあります。 この既定値は、ベクトル ストレージ コストを管理しやすくするために設定されています。 これらの有効期限ポリシーはいつでもオーバーライドできます。
実行を作成して出力を確認する
実行を作成し、モデルがファイル検索ツールを使用してユーザーの質問に応答することを確認します。
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 個のファイルを保持できます。 ベクトル ストアは、アシスタントとスレッドの両方にアタッチできます。 現在、アシスタントには最大で 1 つのベクトル ストアをアタッチでき、スレッドには最大で 1 つのベクトル ストアをアタッチできます。
ベクトル ストアの作成とファイルの追加
1 回の 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 = 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
など) を使用して作成されたベクトル ストアには、既定では最後にアクティブになった後 (ベクトル ストアが実行の一部であった最後の時刻として定義されます) 7 日間という有効期限ポリシーがあります。
ベクトル ストアの有効期限が切れると、そのスレッドでの実行は失敗します。 これを修正するには、同じファイルを含む新しい 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]
)