Paper · Project page · Code
ThinkRetrieve makes a reasoning model recall worked examples mid-thought. Instead of only "thinking longer" (which drifts and compounds errors), it pauses at each reasoning step, retrieves the most similar solved example from a bank, and injects it into the thinking trace — guidance on how to reason, not just what facts to use.
It works over any chat API (OpenAI-compatible, Anthropic, Amazon Bedrock, or a local model via Ollama / LM Studio / MLX / llama.cpp) — no GPU or vLLM required.
pip install "thinkretrieve[faiss]"
Quickstart
from thinkretrieve import ThinkRetrieve, FaissRetriever, OpenAICompatBackend
# 1. A bank of solved (question, worked-solution) pairs — a dataset, your docs, past tickets…
bank = FaissRetriever.from_examples([
("A jacket costs $120 and is discounted 25%. Final price?",
"Discount = 0.25*120 = 30. Final = 120-30 = 90. Answer: $90"),
("What is 15% of 80?", "0.15*80 = 12. Answer: 12"),
])
# 2. Any chat model — local (shown) or hosted.
backend = OpenAICompatBackend(model="qwen3:4b", base_url="http://localhost:11434/v1")
# 3. Reason with mid-thought retrieval.
result = ThinkRetrieve(backend, bank).run(
"A phone costs $250 after a 20% discount. What was the original price?")
print(result.answer) # the final answer
print(result.think_trace) # full reasoning, with injected examples visible
print(result.retrievals) # what was retrieved, when, and why
How it works
At each reasoning boundary the model elicits an interim answer, retrieves the most
similar solved example (E5 + FAISS by default), injects it into the trace, and
continues — repeating until the thinking budget is spent. Passing
retriever=None gives you the plain "think longer" baseline for A/B comparison.
Results
Across 5 reasoning models × 4 benchmarks (paper), ThinkRetrieve beats standard thinking, sequential test-time scaling (TTS), static in-context ICL, and random per-step retrieval on every cell — and, because injected tokens count against the budget but aren't generated, it produces fewer model tokens than TTS at the same budget (~6% wall-clock overhead).
Sequential TTS degrades or plateaus as the budget grows; ThinkRetrieve keeps improving — most dramatically on the hardest benchmark:
| Best accuracy (%) | GSM-8K | MATH-500 | AIME 2025 |
|---|---|---|---|
| TTS / Ours | TTS / Ours | TTS / Ours | |
| Qwen3-1.7B | 90.3 / 92.1 | 91.0 / 92.5 | 22.2 / 35.6 |
| Qwen3-4B | 95.1 / 96.8 | 93.7 / 96.1 | 64.4 / 66.7 |
| Qwen3-8B | 96.4 / 97.2 | 94.0 / 94.8 | 68.9 / 71.1 |
Use cases
1 · Reason over a dataset (math, science QA, …)
Index any dataset with worked solutions and go. See
examples/sciq_example.py for a full SciQ run
(build bank from the train split → answer test questions → score):
python examples/sciq_example.py --limit 30
Ready-made banks: NuminaMath, MetaMathQA, GSM8K, MATH, SciQ — anything with
(question, step-by-step solution) pairs.
2 · Procedural memory for agents
Most agent memory stores facts. A ThinkRetrieve bank stores procedures —
solved tasks — and recalls them mid-reasoning. The bank grows as the agent
works (examples/agent_memory.py):
result = agent.run(task)
if verified(result): # tests pass / human approves
memory.add(task, result.answer) # the agent now remembers HOW
memory.save("agent_memory")
3 · Upgrade an existing RAG stack
Prompt-level RAG is ~neutral on reasoning tasks; injecting the same content
inside the trace is what wins (paper §5). Keep your index — wrap it in a 5-line
retriever (examples/rag_integration.py):
from thinkretrieve.types import Example
class MyStore: # pgvector / Pinecone / Chroma / …
def retrieve(self, question, interim_answer="", k=1, exclude_ids=frozenset()):
hits = my_index.search(f"{question}\n{interim_answer}", k + len(exclude_ids))
return [Example(id=h.id, question=h.q, solution=h.body)
for h in hits if h.id not in exclude_ids][:k]
ThinkRetrieve(backend, MyStore()).run(question)
Compare it yourself (one command)
python examples/compare_tts_vs_thinkretrieve.py --backend openai --model qwen3:4b
Runs plain / RAG / long-thinking / ThinkRetrieve at the same budget and prints
the table. Add --backend bedrock --model qwen.qwen3-32b-v1:0 for Amazon Bedrock.
Backends
| Backend | Import | Use for |
|---|---|---|
| OpenAI-compatible | OpenAICompatBackend |
Ollama, LM Studio, MLX, llama.cpp, vLLM, OpenAI, Together, Groq, DeepSeek, OpenRouter |
| Anthropic | AnthropicBackend |
Claude models (pip install "thinkretrieve[anthropic]") |
| Amazon Bedrock | BedrockConverseBackend |
Bedrock models (pip install "thinkretrieve[bedrock]") |
Or subclass ChatTranscriptBackend and implement one _chat() method.
Install options
pip install "thinkretrieve[faiss]" # core + FAISS retrieval (recommended)
pip install "thinkretrieve[faiss,anthropic]" # + Anthropic
pip install "thinkretrieve[all]" # everything
No GPU needed: retrieval runs on CPU / Apple Silicon; generation runs wherever your model lives. Full walkthrough in TUTORIAL.md.
Citation
@article{thinkretrieve2026,
title = {ThinkRetrieve: Retrieval-Augmented Reasoning Traces for Test-Time Scaling},
author = {Singh, Vaibhav and Ghosal, Soumya Sourav and Gharat, Sarvesh and
Pal, Soumyabrata and Narayanam, Ramasuri and Manocha, Dinesh},
journal = {arXiv preprint arXiv:XXXX.XXXXX},
year = {2026}
}
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file thinkretrieve-0.1.1.tar.gz.
File metadata
- Download URL: thinkretrieve-0.1.1.tar.gz
- Upload date:
- Size: 719.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fc8ade271142026146f253ff729f5235189fde12b2bd9396e4bee9d24bdcb2dc
|
|
| MD5 |
1a7b2dda468016c7465cbe3b56218907
|
|
| BLAKE2b-256 |
64bdf7d6b720f3a3578ff508640b218474465d3de15c57fbe2411cccf5d8d5de
|
File details
Details for the file thinkretrieve-0.1.1-py3-none-any.whl.
File metadata
- Download URL: thinkretrieve-0.1.1-py3-none-any.whl
- Upload date:
- Size: 21.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bf7b54534b908e662c9f6366a3a1efbad0f5734fe90b05ec64262718b1198be9
|
|
| MD5 |
950a59fa51b9fd55993ab8e2c3cbcf56
|
|
| BLAKE2b-256 |
18fa564d434804f0db32a0c238218b6b0aa44b4d255f4c982de4890ab8849d1b
|