Agent tools

Give your LLM agent tools over your documents: it lists your collections and documents, finds the ones that answer, and searches or reads their pages, then cites them. For an agent you write; for an MCP client, see MCP.

Set up an agent

Make the tools with client.tools() and give them to your agent. They see all your documents: name a collection or document in the question, or keep the agent to some of them (see Choose the documents).

# pip install "pageindex-search[agents]"
from agents import Agent, Runner
from pageindex_search import PageSearch

tools = PageSearch().tools()  # all your documents; collection= or filter= keeps the agent to some

agent = Agent(
    name="Filings",
    model="gpt-6.1-terra",
    instructions="Answer from the documents and cite the file and page numbers.",
    tools=tools.openai_agents(),
)
result = Runner.run_sync(agent, "What was NVIDIA's revenue in fiscal 2025?", max_turns=30)
print(result.final_output)

What the agent does, in a collection of 40 annual reports:

list_documents    {"filter": {"$and": [{"ticker": "NVDA"}, {"year": 2025}]}}
                  → NVDA_2025_10K.pdf, 130 pages
search_pages      {"questions": ["…"], "document_id": "doc_458c6d87306949ac8184cbdd", "top_k": "auto"}
                  → pages 38, 52, 78, …, each with its text

NVIDIA's fiscal 2025 revenue was $130.497 billion. (NVDA_2025_10K.pdf, pp. 38, 52)

Show where the answer is

Add CITATIONS to the agent's instructions, and it cites as it answers: a tag after each sentence, with the page. Add CITATIONS_WITH_BOXES instead for the part of the page too: the agent then looks at each page it cites, for a few seconds more.

Revenue was $215.9 billion. <cite doc="NVDA_2026_10K.pdf" page="51"/>
Data Center made most of it. <cite doc="NVDA_2026_10K.pdf" page="77" box="0.08,0.31,0.92,0.52"/>

client.citations(answer) finds the tags, each with its document's id. Open the page at the answer, outline its box on it, or show only that part with page_image. Each citation also says where its tag is in the answer, to put a link in its place.

from pageindex_search import CITATIONS_WITH_BOXES, PageSearch

client = PageSearch()
instructions = "Answer only from the documents. " + CITATIONS_WITH_BOXES  # give these to your agent

# ... run the agent with client.tools(), as above; answer is what it wrote ...

for c in client.citations(answer):
    print(c.document, c.page, c.box)  # box: (x0, y0, x1, y1), fractions of the page, or None
    png = client.documents.page_image(c.document_id, c.page, box=c.box)  # the page, or that part of it

The examples and the console's Agent work so: an answer's citations open its pages, with the part outlined.

Tips

  • Scope the tools only to limit them. Made for all your documents, the tools let the agent find the collection or documents a question names. Give them a collection, or a filter, to keep the agent to those documents, whatever it asks for.
  • Leave top_k on auto. The tools ask for the documents and pages likely to help; a number brings back many pages of text, and many more tokens. When those pages do not answer, the agent reads the next most relevant, which come with them, for free, instead of searching again.
  • Ask several questions at once. Both searches take up to 10 questions; each after the first costs less than a search of its own, so the tools ask the agent to put together the questions it has of the same documents.
  • Let it call tools in parallel. For a question across several companies, an agent that searches each at once answers in a few turns.
  • Make the tools again when documents change. The metadata in their descriptions is read when they are made.
  • Give documents metadata. With metadata, the agent finds the documents a question names by listing them, for free, and searches documents only when it cannot.
  • Listing and reading cost nothing. Searches are priced as in Pricing; listing documents, the text and pictures of pages, and zooming in on them, are free.

Tools

client.tools() gives seven tools:

ToolWhat it does
list_collectionsLists your collections, each with its id, name and how many documents it holds. Free. The agent uses it when the question names a collection, then passes its id to list_documents or search_documents.
list_documentsLists the documents whose metadata meets a filter, a page at a time. Free. Its description lists your metadata's keys, types and values, so the agent can write the filter. The agent uses it when the question says which documents it is about.
search_documentsFinds which documents likely answer a question, if any, with the next most relevant. The agent uses it when a filter cannot pick the documents out, and narrows it with a filter where it can.
search_pagesFinds the pages of one document that help answer a question, each with its relevance, its text, and how it is best read, and the next most relevant pages, to read if those do not answer. The agent calls it for each document it picked, at the same time.
read_pagesReads pages: their text, with a picture of any page whose read is "image", such as a scan or a chart. Up to 20 pages, 5 of them pictures, at a time.
view_pagesShows pages as pictures, with their text, where how a page looks matters, such as a table's layout. Up to 5 at a time.
zoom_pageShows part of a page, sharper, where small print or a dense table's figures are hard to read in its picture. The agent looks at the whole page first, then zooms on the part it needs.

tools.definitions are the tools for Claude, tools.openai for OpenAI, and, in Python, tools.openai_agents() for the OpenAI Agents SDK, and tools.mcp() an MCP server. tools.run(name, input) calls one: its .text is JSON for the model and its .images the pictures of pages, and .anthropic() makes both into Claude's tool result. An error, such as a filter written wrong, comes back as {"error": …} for the agent to correct.

The metadata lines the agent sees in list_documents, for a collection of 40 annual reports:

Metadata keys of the 40 documents:
- ticker: string, on 40 documents; values: "AAPL" (5), "BA" (5), "BRK" (5), "JPM" (5), "NVDA" (5), …
- year: number, on 40 documents; 2021 to 2026

The tools call the API, documented in the API reference. To search yourself, see Search pages. Try the tools in the console's Agent playground, which shows each step and what it cost.