It is the quickest way to answer questions from your own documents without running a search system yourself.
File search is OpenAI's hosted version of retrieval-augmented generation: you hand over documents once, and the model searches them while answering.
The documents live in a vector store, an OpenAI-managed index that splits your files into chunks, embeds them and supports both meaning-based and keyword search. Setting one up takes four steps:
- Upload a file with
client.files.create(file=..., purpose="assistants"). - Create a store with
client.vector_stores.create(name=...). - Attach the file with
client.vector_stores.files.create(vector_store_id=..., file_id=...). - Wait until its status is
completed; indexing takes a moment.
Then add {"type": "file_search", "vector_store_ids": [store.id]} to tools. The response contains a file_search_call item and a message whose text has file_citation annotations pointing at the source files.
Useful options: max_num_results (fewer results means fewer tokens and faster answers, sometimes lower quality), filters on file metadata (for example only documents for one customer), and include=["file_search_call.results"] to see the retrieved chunks, which is invaluable when an answer looks wrong.
Supported files include PDF, DOCX, PPTX, Markdown, HTML, JSON and plain text. Vector stores and their storage are billed, so delete stores you no longer need. For full control over chunking and ranking, build your own pipeline with embeddings instead.
Example
import time
from openai import OpenAI
client = OpenAI()
store = client.vector_stores.create(name="handbook")
with open("handbook.pdf", "rb") as f:
up = client.files.create(file=f, purpose="assistants")
client.vector_stores.files.create(vector_store_id=store.id, file_id=up.id)
while any(f.status != "completed"
for f in client.vector_stores.files.list(vector_store_id=store.id)):
time.sleep(2) # wait for indexing
r = client.responses.create(
model="gpt-6-astra",
input="How many vacation days do new employees get?",
tools=[{"type": "file_search", "vector_store_ids": [store.id],
"max_num_results": 5}],
include=["file_search_call.results"],
)
print(r.output_text)Remember
- Files -> vector store -> file_search tool with vector_store_ids
- Wait for indexing to complete before querying
- Use include=["file_search_call.results"] to debug retrieval
Watch out for
- Querying immediately after upload, before the file has finished indexing.