Skip to content

Choosing models

Every model the pipeline uses is your choice, with its effort level and any further request options. There are three roles:

Role Default Python argument Server setting
Page reader Claude Haiku 5.5, high effort model=, effort=, model_options= READANYDOC_READER
Handwritten pages (engine only) Claude Sonnet 5.5 handwriting_model=, handwriting_effort=, handwriting_options= READANYDOC_HANDWRITING_READER
Extraction (fills your schema) the page reader's model extract_model=, extract_effort=, extract_options= READANYDOC_TASK_LLM

What is benchmarked

The published numbers use Claude Haiku 5.5 (Sonnet 5.5 for handwriting). Other models work; their accuracy has not been measured here.

Providers

You write Provider Key
claude-haiku-5-5, claude-sonnet-5-5, any claude-* Anthropic API ANTHROPIC_API_KEY
gpt-5, any gpt-*, o3, o4-* OpenAI API OPENAI_API_KEY (and OPENAI_BASE_URL for a proxy or gateway)
openai_compatible:<model>@<base_url> Any OpenAI-compatible server: vLLM, SGLang, Ollama, LM Studio, a hosted gateway none, or set by the server
<adapter>:<model> Explicit adapter, see Model specs as above

Examples

import readanydoc

# a stronger page reader
readanydoc.parse("scan.pdf", model="claude-sonnet-5-5", effort="high")

# extra request fields, sent to the provider as given
readanydoc.parse("long.pdf", model_options={"max_tokens": 32000})

# handwriting read like any other page
readanydoc.parse("form.pdf", handwriting_model=None)

# a cheap reader, a strong extractor
readanydoc.extract("contract.pdf", schema=Terms,
                   model="claude-haiku-5-5",
                   extract_model="claude-sonnet-5-5", extract_effort="high")

# OpenAI
readanydoc.parse("doc.pdf", model="gpt-5", effort="medium")

# your own model server, nothing leaves your network
readanydoc.parse("doc.pdf", mode="model-only",
                 model="openai_compatible:Qwen/Qwen2.5-VL-7B-Instruct@http://localhost:8001/v1")

On the server, use the same specs in environment variables:

READANYDOC_READER="anthropic_api:claude-sonnet-5-5#high" \
READANYDOC_TASK_LLM="openai:gpt-5#medium" \
readanydoc serve

Effort

effort is passed to providers that support it: Anthropic's effort setting and OpenAI's reasoning_effort. Higher effort is slower and costs more output tokens. On our measurements high effort was worth it for page reading; lower effort was tried and dropped. For openai_compatible servers effort is ignored.

Request options

model_options, handwriting_options and extract_options are added to the provider's request body as given, so every provider setting is available (for example max_tokens, temperature where the model allows it, inference_geo, service_tier). The fields ReadAnyDoc itself owns are refused with an error, because the pipeline could not read the reply otherwise: model, messages, system, stream, tools, tool_choice, prompt, input.