Use built-in chat() to ask questions about your documents with your preferred LLM.
- Set up the PageIndex client — choose your index mode and LLM.
- Send a query — prepare messages and select documents.
- Customize the response — enable streaming and citations.
Set up the PageIndex client
Both sides need configuring: index decides where documents are processed and stored, chat is the model that searches the tree and writes the answer.
Cloud
import os
from pageindex import PageIndexClient
os.environ["PAGEINDEX_API_KEY"] = "your-pageindex-key"
os.environ["OPENAI_API_KEY"] = "your-openai-key"
client = PageIndexClient(
index="cloud", # index and store in PageIndex Cloud
chat="gpt-5.6-sol", # your own model answers
)Client instructions
Pass instructions= when creating the client to customize the answering agent across questions. These instructions are appended after PageIndex’s default system prompt.
client = PageIndexClient(
index="cloud",
chat="gpt-5.6-sol",
instructions="You are ACME's support assistant. Answer in the user's language.",
)Use an existing document ID from client.list_documents(), or submit a new document. wait=True blocks until it is ready:
doc_id = client.submit_document("./2023-annual-report.pdf", wait=True)["doc_id"]The examples above use OpenAI. Any provider works — see Use different LLMs.
Send a query
Start with a question string or a list of conversation messages.
Single message
messages = "What are the key findings in this document?"Then choose the documents or folder and send messages:
Document
answer = client.chat(messages, doc_id=doc_id)Streaming
Streamed answers show the agent’s process by default — thinking and tool calls woven into the text as it runs:
for chunk in client.chat("Summarize this document", doc_id=doc_id, stream=True):
print(chunk, end="", flush=True)[thinking] I should read the report's key sections first.
[tool_call] get_document_structure {"doc_name": "report.pdf"}
[tool_result] get_document_structure: {"success": true, ... (+304 chars)
The report finds that ...Use show_process=False to stream only the answer.
To customize the process output, pass a dict to show_process:
| Key | Description | Default |
|---|---|---|
thinking | Show the model’s thinking when available. | True |
tool_call | Show tool calls. | True |
tool_result | Show tool results. | True |
max_chars | Character limit per process summary line. | 200 |
client.chat("...", doc_id=doc_id, stream=True, show_process={"thinking": False})Citations
Pass citations=True to request source citations. Citations use <cite doc="…" page="…"/> tags, with block="…" where the cloud document has block-level data:
answer = client.chat("Summarize the document.", doc_id=doc_id, citations=True)Revenue increased during the reporting period. <cite doc="report.pdf" page="12"/>With your own chat model, choose a citation format using client.citation_prompt(format=...):
| Format | Output |
|---|---|
"cite" (default) | <cite doc="report.pdf" page="12"/> tags, with block when available. |
"markdown" | Bracketed references such as [report.pdf, p. 12]. Useful when your app does not render custom tags. |
"footnote" | Numbered footnote markers with source definitions. |
Pass the returned prompt as instructions=:
answer = client.chat(
"Summarize the document.",
doc_id=doc_id,
instructions=client.citation_prompt(format="markdown"),
)API protocols
Use protocol= to return a protocol’s native response format. With stream=True, the response is its native event stream.
Chat Completions
response = client.chat(
"Summarize this document",
doc_id=doc_id,
protocol="chat_completions",
)
print(response["choices"])Returns the Chat Completions envelope with choices and usage. This protocol also works with managed cloud chat, without your own chat model. chat_completions() remains available for existing code.
show_process does not apply when protocol is set. Pass provider-specific fields such as thinking and top_k through extra_body.
chat() parameters
The following parameters apply to client.chat().
Parameters
| Name | Type | Required | Description | Default |
|---|---|---|---|---|
| messages | string or List[Dict] | yes | A question string, or role/content conversation history. | - |
| doc_id | string or List[string] | no | Document ID(s) to scope the conversation. | None |
| folder_id | string | no | Cloud-only — steer discovery toward this folder’s documents; "root" is the whole library. | None |
| stream | boolean | no | Yield the answer as text chunks as it is produced; with a protocol, that protocol’s native event stream. | False |
| show_process | boolean or Dict | no | Streamed chat: weave the run into the text. False for the bare answer; dict keys thinking / tool_call / tool_result / max_chars. | on |
| model | string | no | Backend model name; defaults to the client’s chat_model (protocol="messages" requires it). | None |
| reasoning_effort | string | no | "low" / "medium" / "high", sent in each lane’s native spelling. | None |
| protocol | string | no | "chat_completions", "responses" or "messages": drive that wire natively, with its own input/output shapes. The managed cloud chat serves "chat_completions" too. | None |
| instructions | string or List[Dict] | no | Guidance for this call, appended after the managed system prompt and the client’s own instructions (Messages system blocks with protocol="messages"). | None |
| citations | boolean | no | Request source citations with <cite doc= page=/> tags (block= where the cloud document has blocks); on the managed cloud chat, the endpoint’s own citations. | False |
| max_turns | int | no | Cap on agent turns per call. | None |
| backend | Dict | no | Per-call connection overrides, merged over the client’s chat_backend. | None |
| extra_headers | Dict | no | Extra HTTP headers on each backend request. | None |
| extra_body | Dict | no | The provider’s own request fields beyond these parameters, merged last. | None |
model, reasoning_effort, max_turns, backend, extra_headers and the responses / messages protocols apply to own-model chat (a configured chat_model); the managed cloud chat selects its own model and rejects them. instructions, citations, extra_body and protocol="chat_completions" work on both.