Site Logo
Published on

Acervo on pause — when the idea is good but the implementation falls short

Authors

This post was hard to write. After five versions, benchmarks, my own fine-tune and months of work, I decided to pause Acervo.

Not because the idea is wrong. I'm still convinced that compressing knowledge into a graph and activating only what's relevant by semantic proximity is the right direction — the v0.5 numbers (21x efficiency vs a tool-using agent) back that up. The problem is something else: the way I tried to implement it just isn't good enough.


The real problem: dynamic conversations

The v0.5 benchmarks told a partial story. On indexed projects, with more or less predictable questions, the pipeline worked well. But when I used it in real conversations — the kind that jump between topics, circle back, correct something said three turns ago, mix two projects in the same sentence — Acervo started losing context data consistently.

And it makes sense once you look at how it's built. The S1→S2→S3 pipeline depends on every turn decomposing cleanly: extract entities, activate nodes via BFS, assemble context. When the conversation is dynamic, that decomposition breaks on several fronts:

  • S1 extracts per turn, with no memory of the flow. If an important fact is built up across three messages ("that project...", "yeah, the task one", "it uses Postgres now"), no single turn contains the full information, and the graph ends up with fragments or without the fact at all.
  • The BFS needs a correct seed. In dynamic conversation, the current turn's topic often doesn't match any label in the graph — implicit references, pronouns, things left unsaid. No seed, no activation, and the LLM answers without context.
  • Corrections accumulate instead of replacing. I had already documented this in v0.5: "I switched from SQLite to PostgreSQL" adds PostgreSQL but doesn't remove SQLite. In a long, living conversation, the graph fills up with contradictory states.

Each of these has patches on its own. But the sum made me see that this isn't a patching problem: it's structural. I'm trying to rebuild, every turn, from outside the model, a conversational state that the model already handles internally far better than I do.


The solution I don't know how to build (yet)

The direction I believe is right is to stop fighting the context from the outside and work closer to the model: improve, or outright build, a different style of KV-cache. Instead of re-injecting compressed text every turn and praying the extractor doesn't drop anything, maintain and manipulate the model's attention state more intelligently — compress it, prune it, reuse it across turns without losing what matters.

There's active research in that direction and the results are promising. But let's be honest: implementing something like that seriously isn't writing another Python pipeline on top of an API. It means getting into the guts of inference — attention, memory, quantization, the whole stack I've been using as a black box until now.

And that's the point: I don't know how to do it yet. I could keep iterating fine-tunes of the extractor and squeezing out percentage points on benchmarks, but I'd be optimizing the wrong implementation. I'd rather stop, seriously study machine learning engineering, and come back to Acervo when I have the tools to attack the actual problem instead of its symptoms.

So Acervo goes on pause. Not dead — paused. The code, the model and the training data remain public and open source.


In the meantime: Graphify

The good news is nobody has to wait for me. There's a project built on ideas very similar to Acervo's, already mature and usable today: Graphify.

The premise will sound familiar if you've been following this series: turn a codebase — with its docs, SQL schemas, configs and PDFs — into a queryable knowledge graph. A real graph you traverse, not embeddings with probabilistic retrieval. The same conceptual bets I'd been making with Acervo, better executed:

  • Local, deterministic parsing with tree-sitter for ~40 languages. Zero LLM calls for code extraction: nothing leaves your machine. Where I depended on a fine-tune that extracted "almost always" correctly, they use the AST directly.
  • Relationships with provenance. Every edge is tagged as EXTRACTED (explicit in the code) or INFERRED (resolved by the tool). It's the elegant answer to the phantom-entity problem I was attacking with quality specs in YAML.
  • Community detection with Leiden clustering to identify subsystems, and "god nodes" to surface the most connected concepts.
  • Natural-language queries (graphify query), connection tracing between any two entities (graphify path), and it works as a skill for Claude Code, Cursor, Codex and friends, with MCP support for persistent graph access.
  • Open source, dual-licensed Apache 2.0 / MIT.

If anything in the Acervo series resonated with you — the idea that a project's context lives better in a graph than in a vector store — go try it. It's the version of that idea that already works.


What I'm taking with me

Five versions of Acervo taught me more than any course: what an extraction pipeline is, how to fine-tune with LoRA, how to design benchmarks that don't lie to themselves, and — the most expensive lesson — how to recognize when the problem in front of you is deeper than the tools you have.

See you on the other side of machine learning engineering.