Capstone

CAPSTONE: End-to-End Memory System

Step 1 — Fact schema design (do this on paper/doc first, not code)

0%

complete

4 sections·~2 min read·1 expanded

For your agent use case, fill out this table completely before writing any code:

Fact typeExampleExpected lifespanWhat counts as a contradictionAuthoritative source
(fill in)(fill in)(fast/slow decay)(define precisely)(who/what can override this fact)

Do this for every fact type that matters in your agent use case — aim for 5-10 rows. This table is the actual design documentation; everything else in this module is just executing against it.

# Skeleton pulling together Modules 5, 6, 7, 8

def ingest_turn(conversation_turn, user_id):
    # Module 5: extract facts
    facts = extract_facts(conversation_turn)
    
    for fact in facts:
        # Module 5: route against existing memory
        similar = get_similar_facts(fact["fact"], user_id=user_id)
        decision = route_fact(fact["fact"], similar)
        apply_decision(decision, fact, user_id)
        
        # Module 6: also extract into the graph if it's a relational fact
        if is_relational(fact):
            graph_data = extract_graph(fact["fact"])
            add_to_graph(graph_data, user_id)

def retrieve_for_query(query, user_id):
    # Module 7: hybrid retrieval
    semantic_results = vector_search(query, user_id)
    keyword_results = bm25_search(query, user_id)
    graph_results = graph_search(query, user_id)
    return fuse_results(semantic_results, keyword_results, graph_results)

Fill in each function using the code you already built in Modules 5-7 — the capstone is integration work, not new concepts.

Using the mini-benchmark from Module 11's exercise:

def evaluate(test_cases):
    correct = 0
    for case in test_cases:
        ingest_conversation(case["conversation"], user_id="eval_user")
        result = retrieve_for_query(case["query"], user_id="eval_user")
        if case["expected_fact"] in result:
            correct += 1
    return correct / len(test_cases)

score = evaluate(your_test_cases)
print(f"Retrieval accuracy: {score:.1%}")

Track this score as you tune your extraction prompts, routing logic, and retrieval fusion weights — this number is your objective feedback signal for whether changes actually help.

Wire your memory pipeline into an actual agent loop (even a simple LangChain agent) for your agent use case, run at least 20 real or realistic conversations through it, and manually inspect every case where retrieval returned something wrong, stale, or missing. Update your fact schema (Step 1) based on real failures — this iteration loop, not the initial design, is where the product actually gets good.