Langfuse + Memanto
One memory per signature
A thousand identical failures become one memory whose confidence reflects how often it happened — not a thousand near-duplicates.
Two ways in
A live SDK handler for instant capture from your app, and a CLI sync that reads the Langfuse API. They share a ledger, so running both is safe.
Idempotent
Re-running never duplicates. A recurring failure updates its memory in place; an unchanged one is skipped.
Your rules
Score names, value ranges, and what counts as slow or expensive are all project-specific — so you decide, and nothing is assumed on your behalf.
The core idea
Memanto performs no deduplication on write, so piping raw traces in would drown recall — one bad deploy could write thousands of near-identical memories. Instead, observations are grouped by error signature: the operation name plus a message with its volatile parts (ids, numbers, emails, IPs, paths, quoted strings) normalized away.Everything is rule-based — no LLM calls, no token cost. Grouping is a regex-normalized hash; confidence is
min(0.95, 0.60 + 0.15 × log₁₀(occurrences)), so 1 occurrence scores 0.60 and 100 scores 0.90.Which path do you want?
Most teams run both: the handler for instant error capture, and a periodic sync for the signals that only exist server-side.
Path 1 — CLI sync
No app changes. Works with any Langfuse version, including v2.1
Look at your project first
You cannot choose a latency budget or a score rule without seeing your own data.It reads your actual range and refuses to guess direction — Langfuse documents no convention for whether a higher score is better.
2
Save what you want captured
~/.memanto/migrate/langfuse/config.json.3
Preview, then sync
New: 0 · Unchanged: N. That is the ledger doing its job.Langfuse Cloud is regional and keys are not valid across regions. If your project is on US, pass
--host https://us.cloud.langfuse.com once (it is remembered) or set LANGFUSE_HOST. A region mismatch surfaces as 401 Invalid credentials.memanto migrate for the full option list.
From the UI
memanto ui → Migrate → Langfuse gives the same thing with checkboxes: Discover, capture toggles, threshold fields, Save settings, Preview, Sync now. It reads and writes the same config.json and the same ledger as the CLI.
Path 2 — Live SDK handler
Langfuse’s Python SDK (v3+) is built on OpenTelemetry and attaches its span processor to the globalTracerProvider. This package attaches a second one — so it sees every span your app already produces, with no extra instrumentation and no calls to the Langfuse API.
Install
memanto comes with it, and there is no server to run. Memories go straight to the Memanto cloud API from your process.
Quick start from nothing
You need one thing: a Moorcheh API key.Configuring in code
Anything you would set with the CLI can be passed toattach() instead:
errors). So a solo developer never touches the CLI, while a team can manage rules centrally with --save and each service just calls attach(agent_id=...). Bad settings raise at attach() rather than silently capturing nothing.
More control
Capture modes
Onlyerrors works with no configuration — level is the one field every Langfuse project populates the same way. Everything else stays inert, and says so, until you supply a rule or a budget.
Why low-score and success cannot work live
Why low-score and success cannot work live
Langfuse scores are attached after a trace finishes — nothing in the span carries them. The live handler logs a warning at startup if you enable them, rather than silently capturing nothing. Run
memanto migrate langfuse periodically to pick them up.Why costly is usually sync-only
Why costly is usually sync-only
Unless your app explicitly sets
cost_details on the observation, Langfuse computes cost server-side after ingestion — where a span processor cannot see it. Latency is different: it is on the span itself, so slow works live.Why percentile budgets are ignored live
Why percentile budgets are ignored live
A percentile needs a population to calibrate against. The sync has the whole pulled window; a single span does not. Give
slow an absolute latency_ms for live capture.Score rules
Langfuse scores can be Numeric, Categorical, Boolean, or Text, with user-defined names and ranges — and the docs state no convention for whether higher is better. So you state the direction:< <= > >= = != in. Run --discover to see your score names, types, and observed ranges first.
Memory shape
Everything without a schema slot — occurrence count, models, peak latency, total cost, sample trace ids, first/last seen — goes into a bounded
[Supporting data] footer, so nothing is lost.
The sync ledger
~/.memanto/migrate/langfuse/state.json maps each signature to the memory it wrote, scoped by Langfuse project and destination agent.
That scoping matters: a signature written to agent A tells you nothing about agent B, and two projects can produce identical signatures for unrelated faults. Without it, a sync would skip a write the destination never received.
Because the live handler and the CLI share this ledger, running both is safe — whichever gets there first writes, and the other sees it as already stored.
Configuration reference
Capture rules live in~/.memanto/migrate/langfuse/config.json, written by --save or the UI. Only runtime settings come from the environment:
Reliability
- Nothing runs on your hot path.
on_endmaps the span and buffers it; grouping and network I/O happen on a daemon thread. - Your app is never harmed. Every entry point swallows its own exceptions — a memory that fails to write will not break your application.
- Failed writes are retried, not dropped. A batch that fails is retained and retried; retrying is safe because reconciliation is idempotent. After 4 consecutive failures it is abandoned so a dead backend cannot fill memory.
- Bounded buffer. During a storm the buffer stops growing and drops are counted in
stats()["dropped"].
Troubleshooting
401 Invalid credentials
401 Invalid credentials
Langfuse Cloud is regional and keys are not valid across regions. If your project is on US, use
--host https://us.cloud.langfuse.com or set LANGFUSE_HOST.No memories appear from the SDK
No memories appear from the SDK
Check
handler.stats(). captured: 0 means no span matched your settings — confirm with --discover. captured > 0, written: 0 means the flush failed:A dry run shows New: 0
A dry run shows New: 0
That is correct — those signatures are already synced. Read Signatures and Unchanged instead. You only see
New on a project that has not been synced to that agent before.Warning: grouping barely collapsed anything
Warning: grouping barely collapsed anything
Your messages embed values the normalizer did not catch. Pin grouping to a stable field you control:
Titles contain <str> or <n>
Titles contain <str> or <n>
Those are normalization placeholders standing in for the volatile part of the message — they are the group’s identity. That is what lets a thousand variations collapse into one memory.
Requirements
- Python 3.10+
- A Moorcheh API key (free tier: 100K ops/month)
- For the live handler:
langfuse>=3in your application. The CLI sync works with any Langfuse version, including v2.
Verified end-to-end against langfuse 3.15.0 and 4.14.3. If your app is on langfuse v2 (the classic
trace()/generation() API), it predates the OpenTelemetry rewrite — use the CLI sync, or upgrade to v4 to use the live handler.Shared memory across integrations
langfuse-memanto talks to the same Moorcheh-backed Memanto agents as the sibling integrations, so memory written by one is recallable from the others when they share an agent_id:
Next steps
memanto migrate
Full option reference for the CLI sync, including every capture flag.
Memory Types Reference
What
error, learning, and observation mean, and how recall uses them.Agent Management
Create, activate, and switch the agents these memories land in.
Recall API
Read the captured memories back from your own code.
Links