Retrieval-Augmented Self-Recall — Part 6: The Fine-Tune That Did Nothing, and Shipping It as an MCP Server

Retrieval-Augmented Self-Recall — Part 6: The Fine-Tune That Did Nothing, and Shipping It as an MCP Server

Part 6 (finale) of Retrieval-Augmented Self-Recall. Code: RE-call. Part 5: the gap threshold that didn't transfer. I fine-tuned the embedder on my own domain expecting a win. I measured it properly, on held-out queries. The improvement was exactly zero. Δ+0.00 MRR. Δ+0.00 nDCG@10. Not "small". Not "within noise". Zero. It's also the result I wanted, which takes some explaining. That's the first half of this post. The second half is how the whole engine ships, so an agent can actually use it. The fine-tune that did nothing After Part 5, the natural next question: if calibrating the threshold helps, would a better embedding help more? So I fine-tuned one on my domain. The setup: all-MiniLM-L6-v2, OnlineContrastiveLoss on query/gold-chunk pairs, trained on the 14-document corpus. The result: Model Test MRR Test nDCG@10 Base 1.00 1.00 + Fine-tuned 1.00 1.00 Δ +0.00 +0.00 Zero lift. And that is the correct outcome, not a failed experiment. Here's the reasoning, because it's the whole point. The base model already scores a perfect MRR and nDCG@10 on this corpus. There is no headroom left to recover. The only ways to manufacture a "gain" from here would be dishonest ones: evaluate on the training set (and measure memorization, not retrieval), or artificially cripple the baseline so fine-tuning has something to fix. Reporting +0.00 is the honest read, and the honest read is that off-the-shelf embeddings already saturate this corpus. But the full result is more nuanced, and more useful. On a harder, opaque-jargon corpus — one where the base model genuinely struggles to map queries to the right chunks — the same fine-tuning gave +0.24 MRR. So the real conclusion isn't "fine-tuning doesn't work." It's: Fine-tuning helps when the base model doesn't already cover your vocabulary. When it does, you get nothing. Know which regime you're in before you spend the GPU hours. That's the value of a null result. "+0.00" told me my corpus was already well-covered by a general-purpose embedder — which saved me from a fine-tuning pipeline I didn't need, and told me exactly when I would need one. Teams that reflexively bury negative results throw away findings like that and re-learn them the expensive way. Shipping it: the MCP server An engine nobody can plug in is a paper. RE-call ships as recall_mcp, an MCP (Model Context Protocol) server over stdio, so Claude — Desktop, Code, or any MCP client — can query its own memory directly as a tool. That closes the loop with the applied series. There are three layers: The human-editable memory — the plain markdown files you curate by hand (the two-file memory system from the Claude Code series). The retrieval engine — RE-call: hybrid search on Postgres, plus the honesty guards. The MCP server — how the agent reaches layer 2 at runtime, as a first-class tool. And the design principle carries straight over from the applied series: the honesty signals ride inside the tool's structured output. When the agent queries memory, the response isn't just a ranked list — every hit carries a trust verdict (ok / superseded / expired / …), a calibrated confidence, provenance, and validity, and the result carries gap_warning, freshness, and an explicit abstained + reason. The agent physically cannot get the answer without also getting "here's how much to trust it." Honesty isn't an advisory the model may ignore; it's baked into the shape of the response. Where the series lands Six parts ago I claimed self-recall is a different RAG problem — one about calibrated abstention, not ranking. Everything since served that one idea: Architecture (Part 2) — hybrid dense + sparse retrieval on nothing but Postgres, because agent memory doesn't need a dedicated vector DB. Guards (Part 3) — gap_warning, freshness, and anti-re-litigation, the three things a memory does that a search index doesn't. Evaluation (Part 4) — a false-confident rate measured alongside MRR, because the failure that matters is the one ranking metrics can't see. Findings (Parts 4–6) — hybrid + rerank earns its cost only on weak embedders; a hard-coded abstention threshold is a silent landmine; and fine-tuning is regime-dependent, worth exactly nothing on a corpus your base model already covers. Two of those findings are negative results. That's deliberate. In a domain about knowing your own limits, the honest nulls are the most valuable thing on the table — and everything here is public, reproducible, and covered by a 150-test suite whose 49 DB-touching tests run against real Postgres, so you don't have to take my word for any of it. Read it, run it, break it The whole engine is open source: RE-call (MIT). Clone it, point it at your own corpus, and check the calibration on your embedder before you trust any threshold — including mine. And if you came here from the applied track, Claude Code, Beyond the Prompt is where all of this gets used in anger: the memory an agent reads at the start of every session, backed by the engine you just read the internals of. Thanks for reading the whole way down. If you build on it — or find where I'm wrong — I want to hear about it. And that's not a rhetorical close: the comments on Part 1 already found where I was wrong, twice, and the fixes shipped as v0.3 — an entailment stage for the near-miss a threshold can't see, and write-time supersession that beats any timestamp. The receipts, with the commenters' names on them, are in the series follow-up. The finale of Retrieval-Augmented Self-Recall. Code: RE-call. Building agent memory, or hiring people who do? This series is the long-form version of my answer.

📰 Original Source

Read full article at Dev →

KhanList aggregates and links to publicly available news content. We do not host full articles from third-party sources. Always verify important information with original sources.