I have a vector store containing a list of doc files. I want the best way to get a general table of contents of all the files: a list of JSON objects with the title of each chapter, a short description of the chapter, and the order of the final results.
try:
response = client.responses.create(
model=AIModelChoices.GPT_4O_MINI,
max_tool_calls=1,
parallel_tool_calls=False,
# --- 1. STRICT OUTPUT CONFIG ---
text=ResponseTextConfigParam(
format=ResponseFormatTextJSONSchemaConfigParam(
type="json_schema",
name="curriculum_schema",
schema=schema_dict,
strict=True,
)
),
max_output_tokens= 1000000,
# --- 2. IMPROVED PROMPT ---
instructions=(
"You are an expert curriculum designer.\n"
f"CONTEXT: Existing chapters: {context_str}\n"
f"CONSTRAINT: {density_instruction}\n"
"TASK:\n"
"1. Use file_search to scan the beginning of the document for a Table of Contents.\n"
"2. If no TOC is found, infer chapters from the section headers you see.\n" # <--- FALLBACK
"3. Extract titles and short descriptions.\n"
"4. Merge with existing chapters and re-order.\n"
"5. YOU MUST OUTPUT JSON. Do not return empty text."
),
input="Generate the chapter list.",
tools=[
FileSearchToolParam(
type="file_search",
vector_store_ids=vector_store_ids,
max_num_results=5,
)
]
)
logger.info(f"📦 Response Status: {getattr(response, 'status', 'unknown')}")
# --- 3. EXTRACT AND VALIDATE ---
# Use the helper property to get the aggregated text
response_text = response.output_text
logger.info("=============== RAW JSON START ===============")
logger.info('output_text'+response.output_text)
logger.info(f'text {response.text}')
logger.info(f'output {response.output}')
logger.info(f'queries {response.output[-1].queries}')
logger.info(f'model_dump_json {response.model_dump_json()}')
logger.info("================ RAW JSON END ================")
except Exception as e:
logger.error(f"❌ OpenAI API Error: {e}", exc_info=True)
return []
This code will always rerun the output text as empty
Here’s the skinny:
Vector stores extracts document text, and then chunks it. All documents are combined into one vector store of chunks, with the embeddings allowing semantic search retrieval of top-ranked chunks by a query string.
This text is not exposed to you, nor is it exposed as a complete document to the AI, either. You get placement of ranked chunks of 800 tokens, for the AI to ferret out snippets of knowledge.
An AI using a vector store cannot “summarize this PDF”, nor separate out the ranked results it gets from running a query.
If you want to independently get the per-document “table of contents” you describe generated by AI, the best way would be to use the “input_file” method to send a PDF (and only PDF) as a content part in a user message. This places the whole document into AI context, along with images of each page. Then you can ask the AI to produce single document output product based on its observations.