Beyond chat models, Cobble hosts the pieces you need to make documents searchable and answerable: four OCR models and five embedding models. Both are billed from your wallet at per-page and per-token rates — they don't touch your plan window.
OCR: documents in, text out
Four models, one decision — accuracy versus cost:
| Model | Batch size | Price | Pick it when |
|---|---|---|---|
| GLM-OCR | 200 pages | $0.08/1K pages | Default for clean printed documents |
| DeepSeek OCR2 | 250 pages | $0.08/1K pages | Mixed layouts, tables |
| Nemotron OCR v2 | 300 pages | $0.08/1K pages | Large batches, throughput-first |
| Chandra OCR | 500 pages | $4/1K pages | Hard documents: handwriting, degraded scans, complex layouts |
Start with a $0.08 model; escalate pages that come back garbled to Chandra rather than running everything through it.
<!-- TODO before publishing: sync request example with the real OCR endpoint shape (see api-reference.md TODO). -->Embeddings: text in, vectors out
| Model | Context | Price | Pick it when |
|---|---|---|---|
nomic/nomic-embed-1.5 | 8K | $0.01/1M | Default — strong general retrieval, cheap |
qwen/qwen3-embedding-0.6b | 32K | $0.01/1M | Long chunks, multilingual |
qwen/qwen3-embedding-8b | 32K | $0.01/1M | Highest retrieval quality |
ibm/granite-embedding-97m | 8K | $0.09/1M | Latency-critical lookups |
ibm/granite-embedding-311m | 8K | $0.1/1M | Enterprise/compliance-flavored stacks |
One rule that outranks model choice: embed your documents and your queries with the same model. Vectors from different models live in different spaces; mixing them silently breaks retrieval.
vectors = client.embeddings.create(
model="nomic/nomic-embed-1.5",
input=chunks, # list of strings
).dataRecipe: PDF → searchable knowledge base
The full pipeline, using only Cobble endpoints plus a vector store of your choice:
# 1. OCR the document (wallet, per page)
text = cobble_ocr("contract.pdf", model="glm/glm-ocr")
# 2. Chunk — start simple: ~800 tokens per chunk, 100 overlap
chunks = chunk(text, size=800, overlap=100)
# 3. Embed the chunks (wallet, $0.01/1M tokens)
vectors = client.embeddings.create(model="nomic/nomic-embed-1.5", input=chunks)
# 4. Store in your vector DB (pgvector, Qdrant, Chroma...)
db.upsert(zip(chunks, vectors))
# 5. At question time: embed the query, retrieve, generate (plan window)
hits = db.search(embed(question), top_k=8)
answer = client.chat.completions.create(
model="qwen/qwen3.5-122b-a10b",
messages=[
{"role": "system", "content": "Answer from the provided context. Cite which excerpt supports each claim."},
{"role": "user", "content": f"Context:\n{format(hits)}\n\nQuestion: {question}"},
],
)Cost intuition for a 1,000-page archive: ~$0.08 to OCR, roughly a cent to embed, and question-answering runs inside your plan window. The expensive part of RAG isn't the pipeline — it's doing it somewhere that meters every step.
Coming soon: a hosted reranker to slot between retrieval and generation, and managed knowledge endpoints that run this whole pipeline for you. The recipe above future-proofs cleanly — the reranker drops in between steps 5's retrieve and generate.
