Skip to content

Research: cut write-path LLM calls — relation inference is O(N) per atom #96

Description

@nikita-rulenko

Research ticket — no code yet. Find the cheapest way to build a memory without weakening edge quality or pushing cost onto the (LLM-free) read path.

The cost today

Per add_memory that extracts N atoms, the write path makes:

Stage LLM calls Notes
Extraction / atomization 1 one call over the whole input (+1 retry only on bad JSON)
Dedup decision 0–1 already batched (decide_batch); gated exact/cosine dups skip the LLM
infer_relations 0–N one call PER ATOM (Phase D, concurrent but still N calls; each retried before #95)

So total ≈ 1 + 1 + N. A 5-fact write ≈ 7 calls. The only term that scales with content is relation inference — that's the target.

Constraints that shape the fix:

  • Reads are already LLM-free and edges are consumed only at read time — nothing on the write path needs the edges present the instant the write returns.
  • Canon: the writer pays so the reader flies — do not move cost to reads.
  • Golden reasoning_extraction causal contract (BECAUSE/IMPLIES on fresh writes) must still hold.

Three convergent levers (externally researched, sourced)

Lever 1 — Batch relation inference (N → 1)

One structured-output call over all new atoms × their candidate neighbours, numeric-indexed, chunked ~10–15 pairs/call, strict schema returning [{atom_idx, candidate_id, relation_type|null}].

  • BatchPrompt at batch=32 used 15.7% of the calls / 18–30% of tokens with accuracy flat-to-better; sweet spot 3–15 items/batch; reliability needs explicit indices + (optionally) permutation-vote + semantic grouping.
  • Strict structured output beats JSON-mode (JSON-mode can loop / emit an array under the wrong key — literally our infer_relations: array prompt under json_object mode → systematic 0-relations retry + silently lost edges (weak-model hostile) #95 bug).
  • Sources: BatchPrompt openreview.net/forum?id=Agyicd577r · OBP vldb.org/pvldb/vol18/p2172-zhang.pdf · structured-output agenta.ai/blog/the-guide-to-structured-outputs-and-function-calling-with-llms
  • Impact: O(N) → O(1). Keeps inference synchronous. Lowest-risk, highest-leverage.

Lever 2 — Route cheap edge types off the LLM entirely

  • RELATES_TO ← cosine similarity threshold (top-k gate; can't tell support from contradiction — negations embed close).
  • IS_A / PART_OF ← Hearst/connective pattern rules (high precision) — we already have a structural backstop.
  • explicit BECAUSE ← already handled by the connective backstop.
  • SUPPORTS / CONTRADICTS ← local NLI (cross-encoder/nli-deberta-v3-xsmall, already loaded for Atropos): entailment→SUPPORTS, contradiction→CONTRADICTS. This is the genuinely new lever. Caveats: O(n²) → must cosine-gate; small-model contradiction recall is weak → high threshold, drop low-confidence to neutral.
  • Only the residual implicit causal/logical edges (BECAUSE/IMPLIES with no explicit connective) escalate to Cerebras.
  • Do NOT route typing to a small ≤7B LLM — they are ≈random on fine-grained relation typing (DeepSeek-R1-Distill-7B ≈0.34 acc); NLI+rules is the correct cheap path.
  • Sources: LazyGraphRAG NLP-first microsoft.com/en-us/research/blog/lazygraphrag-setting-a-new-standard-for-quality-and-cost · NLI-for-edges + KG-embedding limits (inline in research notes).
  • Impact: shrinks — often empties — the batched LLM call, leaving only true implicit causality for Cerebras.

Lever 3 — Defer the residual causal inference to an async background batch

Ack the write after extract + dedup + store + embed; run the (now-small) implicit-causal inference in a background batch — Lachesis already exists as a background stitcher, reuse it.

  • Precedents: Mem0 add is async by design; GraphRAG builds the whole graph offline in batch (0 LLM at query); LazyGraphRAG defers all edge LLM work to query time.
  • Guard the one real failure mode (a reader hitting an un-enriched neighbourhood) with a freshness flag + lazy on-read materialization of just that neighbourhood. Keep dedup + contradiction synchronous (correctness-critical).
  • Sources: docs.mem0.ai/open-source/features/async-memory · microsoft.github.io/graphrag · Zep/Graphiti arxiv.org/html/2504.19413v1
  • Impact: relation LLM cost leaves the write critical path entirely (→ write = extract + dedup).

Recommended shape to prototype & measure

  1. Lever 1 first (batch infer) — biggest structural win, synchronous, contained blast radius.
  2. Add Lever 2 (NLI + cosine + rules routing) — reserve Cerebras for implicit causality only.
  3. Consider Lever 3 (defer) only if write-latency/cost is still a problem after 1+2, since it trades the "reader walks precomputed arrows" guarantee for a freshness window.

Net target: write-path LLM calls from 1 + 1 + N~2 flat (extract + dedup+batched-infer), or ~2 with relations fully deferred.

Success metrics (measure before committing)

  • LLM calls per write: O(1), not O(N).
  • $ / 1k atoms and write p50/p95 latency.
  • Edge precision/recall vs current — the reasoning_extraction golden contract must not regress; add a fixture that counts inferred edges before/after.
  • Read stays LLM-free; if Lever 3, quantify the enrichment-freshness window.

Non-goals / risks

  • Not touching the read path.
  • Not replacing extraction with LLM-free NLP (spaCy/FastGraphRAG) — extraction is ~75% of cost but quality-critical; keep 1 LLM extraction call.
  • Batching can degrade with size/position bias → indices + strict schema + bounded batch.
  • Async enrichment → eventual consistency → freshness flag + lazy materialization.

Research prompted 2026-07-05 after profiling showed infer_relations is O(N) per atom. Backed by 3 parallel web-research passes (batching / cheap-local-typing / async-defer) + FastThink synthesis.

Metadata

Metadata

Assignees

No one assigned

    Labels

    researchNeeds investigation before a design is chosen

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions