## TL;DR

Set the ranker and a score\_threshold between 0.0 and 1.0. The pipeline has a fixed sequence. Keep one file per document so you can set per-file attributes later. Add attributes to each file (for example category, language, version).

## When to use

You are seeing this: Agents usually get RAG wrong by wiring the pieces in the wrong order or skipping the ranking pass. Use this skill when you run into "OpenAI RAG pipeline end to end: files, vector store, file_search tool, then tune ranking".

## When not to use

If your error message or symptom does not match what is described above, this is probably not your fix. Search for your exact error text instead of forcing this one to fit.

## Versions

No specific versions are mentioned in the source material, so treat the fix as generally applicable and check the examples against whatever you have installed.

## RAG over vector stores, in the order that works

Agents usually get RAG wrong by wiring the pieces in the wrong order or skipping the ranking pass. The pipeline has a fixed sequence.

## The steps

1. Upload source files with the Files API. Keep one file per document so you can set per-file attributes later.
2. Create a vector store and attach the files to it. Do not put a store id into a request before its files show as indexed; queries against a half-indexed store silently return thin results.
3. Pick a chunking strategy up front. The default auto chunking is fine for prose. For code, tables, or dense reference docs, set an explicit `chunking_strategy` with smaller chunks and overlap so one logical unit does not get split across chunks.
4. Add `attributes` to each file (for example category, language, version). Attribute filters let the model search a slice of the corpus instead of everything, which beats a bigger store with no filters.
5. Call the Responses API with the `file_search` tool and your `vector_store_ids`. Put stable instructions in the developer message telling the model when to search versus answer from its own knowledge.
6. Tune `ranking_options` on the tool. Set the `ranker` and a `score_threshold` between 0.0 and 1.0. Start at a low threshold, look at what gets retrieved on real queries, and raise it until the junk drops out. A threshold that is too high is the classic cause of "the answer is in the docs but the model says it cannot find it."

## The trap

Treating file search as fire-and-forget. A RAG pipeline needs a small eval loop: a dozen real questions with known answers, run after every change to chunking, attributes, or threshold. Without that, every tweak is a guess.

## Checklist

- Files show indexed before the first query runs.
- Chunking is explicit for non-prose content.
- Attributes exist for the filters your queries need.
- `score_threshold` was chosen from measured retrieval, not left at default.
- The model cites which retrieved chunks it used, so misses are debuggable.
