The MentisDB Agent Memory Cookbook

Patterns and recipes for building AI agents that remember

3.3 Retrieval Tuning

Start with ranked search defaults. Tune only when you have a failing query and a known expected memory. Most production improvements come from better filters and graph expansion, not from inventing a new ranking pipeline.

The pattern

fn tune_ranked_retrieval() -> io::Result<()> {
    let dir = tempfile::tempdir()?;
    let adapter = BinaryStorageAdapter::for_chain_key(dir.path(), "cookbook-tuning");
    let mut chain = MentisDb::open_with_storage(Box::new(adapter))?;

    chain.upsert_agent(
        "retrieval-agent",
        Some("Retrieval Agent"),
        Some("memory-team"),
        Some("Tunes ranked search requests"),
        None,
    )?;

    let decision = chain.append_thought(
        "retrieval-agent",
        ThoughtInput::new(
            ThoughtType::Decision,
            "Cache invalidation should happen after webhook delivery is acknowledged.",
        )
        .with_concepts(["cache", "webhooks"])
        .with_importance(0.9),
    )?.index;

    chain.append_thought(
        "retrieval-agent",
        ThoughtInput::new(
            ThoughtType::Summary,
            "Webhook delivery drives downstream cache refresh; do not refresh early.",
        )
        .with_refs(vec![decision])
        .with_concepts(["cache", "webhooks"])
        .with_importance(0.85),
    )?;

    let query = RankedSearchQuery::new()
        .with_text("When should cache refresh happen after webhook work?")
        .with_filter(
            ThoughtQuery::new()
                .with_types(vec![ThoughtType::Decision, ThoughtType::Summary])
                .with_concepts_any(["cache"]),
        )
        .with_graph(RankedSearchGraph::new().with_max_depth(2).with_include_seeds(true))
        .with_reranking(20)
        .with_limit(5);

    assert!(query.enable_reranking);
    assert_eq!(query.rerank_k, 20);

    let result = chain.query_ranked(&query);
    assert!(result.total_candidates >= 1);
    assert!(result
        .hits
        .iter()
        .any(|hit| hit.thought.content.contains("Cache invalidation")));
    Ok(())
}
Debugging rule: do not tune blindly. Save a small eval set of queries, expected thought ids, and acceptable ranks before changing retrieval knobs.