Paper · PDF · 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:2608.10928},
year = {2026},
url = {https://arxiv.org/abs/2608.10928}
}
License
MIT
Release files for thinkretrieve 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| thinkretrieve-0.1.2.tar.gz | 719.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| thinkretrieve-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 741.6 kB
Release files / thinkretrieve-0.1.2.tar.gz
| Download URL | thinkretrieve-0.1.2.tar.gz |
|---|---|
| Size | 719.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
afcaabb27d84d334a9d8db5637e9ec04dd0687a92313222657b24fc720101d6e
|
|
BLAKE2b-256 checksum How to use checksums |
f4df1680f13c58a894fbc2cbfbce285090e3ddedb66cf7106ee15f6147667e7b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.8
|
Release files / thinkretrieve-0.1.2-py3-none-any.whl
| Download URL | thinkretrieve-0.1.2-py3-none-any.whl |
|---|---|
| Size | 21.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f1f456f36129ab8997c9b050287781a51385c087a6bcc29fc9370d48a8a2124e
|
|
BLAKE2b-256 checksum How to use checksums |
a914fbb71c85db30644c03deecf4f8b74e75a66167aca86a3eeb99ed2e37f216
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.8
|