← All posts

We Built claude-context's Architecture Ourselves in October 2025, and It Failed on Accuracy

claude-context is Zilliz's open source code search MCP server, around 11,800 stars, chunking along AST boundaries and serving hybrid BM25 and vector retrieval with Merkle tree incremental reindexing. The engineering is competent. We cannot credibly write a takedown of it, because we shipped the same architecture in October 2025, watched it fail on accuracy, and threw it away. This is what that cost us to learn.

We Built claude-context's Architecture Ourselves in October 2025, and It Failed on Accuracy

We Built claude-context’s Architecture Ourselves in October 2025, and It Failed on Accuracy

claude-context is Zilliz’s open source code search MCP server, sitting around 11,800 stars under an MIT licence. It chunks code along AST boundaries, embeds the chunks, and serves hybrid retrieval combining BM25 keyword matching with vector similarity, using a Merkle tree for incremental reindexing so only changed files get reprocessed.

The engineering is competent and the incremental indexing design in particular is nice work. This piece is not a takedown, because we are in no position to write one. We built the same architecture in October 2025, shipped it, watched it fail on accuracy, and threw it away. Everything below is what that failure cost us to learn.

Why AST chunking plus embeddings looks like the obvious answer

The reasoning is clean, and we believed it at the time. An AST gives you semantically meaningful boundaries, so chunks respect function and class edges instead of cutting mid statement. Embeddings let you retrieve by meaning instead of exact string match. BM25 catches the cases where somebody types an exact identifier. Merkle trees keep reindexing cheap as the repository moves underneath you.

Every step of that is defensible in isolation, which is precisely why so many teams arrive at it independently. The problem only shows up when you start asking real questions.

What embeddings actually measure

A vector embedding measures textual similarity rather than semantic similarity. Those two get conflated constantly, and they are not the same thing.

Ask where the seven day return policy is enforced. The retrieval returns files containing words resembling return, policy, seven and day. The code that implements the rule may be a comparison of two timestamps inside a validator, in a function named something like checkEligibility, with no comment and none of those words anywhere in the chunk. The correct answer scores badly. A constants file full of the word policy scores well.

Now try a relationship question. What breaks if we rename this field. There is no chunk in the index whose text resembles that question, because the answer is a property of the graph rather than of any single passage, and similarity search has nothing available to be similar to.

Now try a question that needs reasoning. Why do these two payment retries behave differently. Answering that requires holding two code paths side by side and comparing them, which is not a retrieval operation at all and cannot be turned into one.

This is the pattern that killed our version. Similarity retrieval works for questions whose answer is stated somewhere in words close to the question, and most real questions about a codebase are not that shape.

The privacy problem people miss

There is a deployment detail in claude-context worth flagging, because it decides whether large parts of the market can use it at all. By default it sends code chunks to a cloud embedding API.

For a bank, an insurer, a healthcare payer, a defence contractor or a public sector body, that is not a preference question to be weighed against convenience. Several jurisdictions make it a legal prohibition. A tool that ships source code to a third party embedding service cannot be deployed in those environments at any price, regardless of how good the retrieval turns out to be.

What we replaced it with

We spent about a month on research after the vector architecture failed, and landed on removing embeddings entirely.

ByteBell is a verification layer generated on top of a codebase of any size below 10 million files. Cheap open source models read every file once at indexing time. An agent detects the boundaries of classes, functions and every other language element, stores them separately, and then analyses each one in the context of its file, its module, its repository, and across every repository. That produces, for each file, what it does, why it exists in business terms, what users lose if it fails, the capabilities it provides, its edge cases, the contracts it provides, its preconditions, and the exact places where its behaviour is genuinely undecided. All of it goes into a graph database with a specification layer on top, in plain English, with the file and the line kept on every claim.

The difference is where the intelligence sits. An embedding is a compression of text into a vector, and no reasoning happened at the moment it was created. Our index is the output of a model that actually read the code and worked out what it was for, before any question existed to be asked of it.

That is why the return policy question now works. Nothing in the index resembles the phrase, and the layer knows that this validator enforces a seven day eligibility window, because a model read it and wrote that down at indexing time.

The questions that became possible

Once meaning is stored rather than similarity, a different class of question opens up. Which repositories are affected if we change the discount logic. Will this pull request break a downstream service before it merges. Trace an order from checkout to settlement across every repository. Which services consume this event. Which business rules does this function implement. How many engineering hours will this feature take, derived from the number and complexity of the affected components and the teams that own them.

We iterated on exactly this with a customer from January through the end of March 2026, getting things wrong, going back, fixing them and returning, until the architecture stopped needing to be rebuilt every few weeks.

What it costs

Indexing runs about $13 per 1,000 files, once, with only changed files re-derived on each commit. That is more expensive than computing embeddings, and it is the honest trade sitting at the centre of this design.

What it buys is on the other side of the ledger. On a traced run, tracing a change end to end across 32 impacted files in 4 repositories took 4 minutes 9 seconds and cost 0.89,againstroughly0.89, against roughly30 for the same work by brute force. A full test generation and review pass came to 87,001 tokens at $0.11. Accuracy of code holds above 93% while token spend falls by roughly 80%.

Vector retrieval is cheap per query, and you pay for it in wrong answers, retries and broken deploys, which is a real cost that simply never appears on the inference bill.

Deployment covers the case embeddings cannot. Hosted, dedicated hardware, or fully inside your own network, read only in all three, with your source never leaving your infrastructure on the second two. You bring your own model keys, including Anthropic, Gemini, OpenAI Codex, DeepSeek, Qwen, Z.ai or anything reachable through OpenRouter.

Where claude-context is the right choice

If you have one repository, you want fast semantic search over it, your questions are mostly of the form find me code that looks like this, and your code is not sensitive, it is free, well made and installs in minutes. Hybrid BM25 and vector retrieval is a sensible design for that job. The Merkle tree incremental indexing is genuinely good work, and more projects should copy it.

The honest limitation

Our index is derived by models and can be wrong in ways a deterministic pipeline cannot, and the first indexing pass on a large estate is a real cost and a real wait. Every claim carries a file and a line so nothing has to be taken on trust, and we re-derive on every commit, though there is a window after a push where a claim can lag the branch.

We also do not cover every language. Mojo is not indexed today.

This is what ByteBell builds

If you are choosing between these, do not evaluate retrieval tools by running keyword shaped queries at them, because similarity search is designed to win that test. Ask the question your product manager would ask, using the words they would use, about a rule that is implemented and never named. Whatever comes back is the honest measure of what the index actually stored.

ByteBell is the verifiable context layer for code. We run the LLM compiler pattern, a one time pass where a model reads every file and lowers it into a verifiable code IR capturing purpose, business context and cross repository relationships, on your own infrastructure through Docker, with your source never leaving your environment. Every engineer, on any copilot, queries the same representation through a single MCP url, and every agent edit is checked against it before it lands, using per file SHA-256 diffing so only what actually changed gets examined again. Across 46 Kubernetes ecosystem repositories and 150,000 files we measured roughly 10% higher accuracy at 70% lower cost, on about a fifth of the tokens.

www.bytebell.ai

All posts