Skip to main content

Langfuse + Memanto

Langfuse Langfuse records what went wrong. Memanto remembers the lesson. This integration connects them: failing spans, failed evaluations, and latency or cost anomalies become durable memories your agents can recall — instead of the same mistake being re-learned on every run.

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.
A real example — 812 observations collapsing to 2 memories:
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

Stored per Langfuse project in ~/.memanto/migrate/langfuse/config.json.
3

Preview, then sync

Run it again — you should see 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.
Credentials are a pair, supplied as one string:
See memanto migrate for the full option list.

From the UI

memanto uiMigrateLangfuse 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 global TracerProvider. 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

That is the only 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.
Then two lines:
That is the whole setup. No CLI, no config file, no decorators to add. The agent is created and activated automatically on the first write.
becomes:
Call attach() after Langfuse(). Before that, OpenTelemetry has only a ProxyTracerProvider, which cannot take a span processor — attach() raises with that explanation.

Configuring in code

Anything you would set with the CLI can be passed to attach() instead:
Precedence is code → stored profile → default (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

Only errors works with no configurationlevel 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.
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.
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.
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:
Operators: < <= > >= = != 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_end maps 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

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.
Check handler.stats(). captured: 0 means no span matched your settings — confirm with --discover. captured > 0, written: 0 means the flush failed:
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.
Your messages embed values the normalizer did not catch. Pin grouping to a stable field you control:
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>=3 in 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