Why We Built This
We're two people building WOS, a long-term memory API for AI agents. The problem we kept running into: agents either forget everything between sessions, or you fix that by re-sending the full conversation history on every single call.
That gets expensive fast, and past a certain length, models don't even use all of it well anyway.
What It Actually Does
You store a user's memories once. On each query, WOS recalls only the relevant ones and hands you a small, bounded context, no matter how much history is behind it.
- Semantic Retrieval: No keyword matching (BM25), so it works perfectly across English, Korean, Japanese, etc.
- Bring Your Own Key: Use your own LLM key for generation; we only handle search and storage.
The Number That Mattered Most: 45x Cheaper
For a 100K-token history with 1,000 queries a month:
- Standard approach: ~$250/month in tokens.
- With WOS: ~$5.50/month.
The gap only grows as the history expands.
Language-Agnostic by Design
We deliberately left out any lexical/keyword matching. This means retrieval quality doesn't quietly degrade depending on what language someone happens to write in. We test this against a single store holding multiple languages at once, and it holds up.
Try It Out
You can explore the documentation and start using the API here:
Would love feedback!
Especially from anyone who's hit memory or context-length walls building their own agents. How are you handling long-term context today?
Top comments (6)
The 45x is real and it is measuring the easy thing. Cost is arithmetic on tokens, verifiable in one line. The claim that actually decides whether the product works, that selective retrieval preserves the answer, is the one the post does not touch, and it is not touchable by looking at outputs either. A plausible answer from an incomplete retrieval looks identical to a plausible answer from a complete one. That is the trap: full-history stuffing is expensive and dumb, but it has one virtue, it cannot silently omit. Bounded retrieval buys the cost saving with exactly that virtue. The agent now sees a small clean context and answers confidently whether or not the one memory that would have changed the answer scored just below your threshold.
So the number you are missing is the false-drop rate, and there is only one oracle for it: run the same query against full history and against bounded retrieval and measure where the answers diverge. Divergence is the cost of the cost saving, stated in the currency that matters. Without it, 45x is a fact about the bill and silence about the product.
One constructive piece, since your retriever already holds the signal. Do not just return the top-k, return the score gap between the last included memory and the first excluded one. A small gap means something relevant sat just under the line, which is the query where bounded retrieval is about to fail, and it is exactly the near-miss a winners-only retriever throws away. That gap is your completeness meter, and it is what lets the agent widen the window instead of answering confidently into a hole.
You nailed the part the post dodges. 45x is arithmetic on the bill; the number that decides the product is the false-drop rate, and you can't see it from outputs.
So we ran the oracle you're describing: same query against full history and against bounded retrieval, measured where they diverge. The surprising part is that full history isn't the omission-proof baseline. It silently drops too, just at the attention level instead of the storage level. On our long-history set it landed in the high 70s and lost exactly on the scattered-evidence questions (preference, temporal, multi-session), because the model never really attends to the one line buried in 100K tokens. Bounded retrieval with good delivery matched the oracle. We wrote up the shape of it at wontopos.com/research/delivery-gap. The headline there is the uncomfortable one: recall can sit near 99.6% and the answer still be wrong. That gap, not recall, is the wall.
Part of why bounded can be more complete is that we index at the sentence level, so a memory that a passage-level retriever would dilute below threshold gets surfaced on its own. That's aimed straight at your "scored just below the line" case.
And your completeness-meter idea is a genuinely good call. The retriever already holds that signal, so returning the gap between the last included and first excluded memory, so the agent can widen the window instead of answering confidently into a hole, is exactly the right shape. Putting it on the list. Thanks for the sharpest comment we've gotten.
Recall near-perfect and the answer still wrong is the more useful failure to have found than a low recall number would have been, because it isolates the mechanism. If the fact wasn't retrieved, the fix is retrieval. If the fact was retrieved and the answer still missed it, the fix is somewhere else entirely, and "somewhere else" is usually attention giving up on one line inside a pile of tokens it was never forced to individually account for.
Which suggests the completeness meter needs a second half, not just at the retrieval boundary but at the delivery boundary. You already have the gap between last-included and first-excluded memory. The matching signal on the other side is whether the final answer actually cites or is traceable to the memory that was delivered, not just whether it was present in context. A memory can sit in the prompt, present and correct, and still not be the thing the model's answer was actually grounded in. That's checkable the same way hallucination-grounding checks work elsewhere: does the claim in the output map back to a specific delivered memory, or is it free-floating. If delivery is clean, sentence-level, and the answer still isn't grounded in it, the 99.6-vs-wrong gap moves from "we don't know why" to "we can see it wasn't used," which is a very different debugging problem than "we don't know if it was there."
The scattered-evidence failure mode you named, preference, temporal, multi-session, has a common shape too: those are exactly the query types where the right answer requires combining multiple delivered memories rather than reading one, and combination is a harder ask of attention than lookup. Worth checking whether the delivery gap concentrates on single-memory-sufficient queries or on ones needing synthesis across several, because the fix looks different: better delivery for the first, explicit multi-hop scaffolding for the second.
Separating long-term memory from the agent’s full chat history makes sense, especially when context windows and costs become limiting factors.
How do you document changes to retention, recall ranking and deletion behavior? Those rules are important because developers need to know exactly what the API promised when their data was stored.
Is there a versioned public record where earlier policies and technical commitments remain available after updates?
Fair point, and the honest answer is that a versioned policy record doesn't exist yet.
Right now those rules are scattered across the docs. On deletion, it's a cascade: deleting a memory removes it and everything derived from it immediately, deleting a store removes all of it, and offsite backups age out on a fixed window, so a delete eventually clears there too. Memories have no TTL and never silently expire. Retrieval behavior is guaranteed at the level that matters to developers, even though the ranking internals are proprietary: semantic only, deterministic for the same store and query, superseded entries hidden by default. The API surface is versioned through the published OpenAPI spec.
But you're right that none of that answers the real question, "what did the API promise when my data was stored." So I'm going to put those rules in one dated policy file in a public repo, where changes land as commits and old versions stay readable. I run this company alone, so I'd rather promise that narrow thing and actually keep it than publish some sweeping policy page I can't maintain.
How's everyone actually handling long-term memory right now? Re-summarizing the whole history each session, a full RAG pipeline, something else?