Show HN: Rubi – A knowledge graph that cuts how much Claude Code re-reads A study of 284 real Claude Code sessions found that 71% of cost went to re-reading context and 97% came from sessions that grew past 150k tokens, according to the developer of Rubi, a knowledge graph and context manager for AI coding agents. Rubi, built as a standard MCP server that also runs in Codex, Gemini CLI, Cursor, GitHub Copilot and local models, compacts sessions early with saved handoffs and builds a code map plus a temporal knowledge graph searched via BM25, Personalized PageRank and Reciprocal Rank Fusion; an A/B benchmark of 90 sessions reported 37% fewer steps, 37% less context re-read and 17% less time, with billed cost down 6% in short cold-start sessions. Writing memory after every answer raised cost 15% in short sessions, so Rubi's default was changed to write less often. A knowledge graph and context manager for AI coding agents. Claude, Codex, Gemini, Cursor, Copilot and local models. Shorter sessions, organized projects, fewer tokens. Check your usage https://huggingface.co/spaces/YuriBedran/rubi · Live demo https://yuribedran.github.io/rubi/ · Walkthrough 5-walkthrough-a-week-with-rubi · Results 4-results · Install & test 7-install · The theory 2-background-the-ideas-in-plain-words AI coding assistants are billed for every token they read, and in a long conversation they re-read the whole history on every message. Analyzing 284 real Claude Code sessions , we found that 71% of the cost was spent re-reading context and 97% came from sessions that grew past 150k tokens . Claude was not doing more work. It was carrying more weight. Rubi attacks the problem from two sides: 1. Keep sessions short without losing the thread. It compacts early, saves a handoff before each compaction and restores it right after. 2. Make the project easy to find your way around, so less reading is needed. It builds a map of the code imports and centrality via PageRank and a temporal knowledge graph of decisions, bugs, gotchas and concepts. The graph is written by Claude itself, at the moment it already holds that knowledge in context, and searched with a hybrid of BM25, Personalized PageRank and Reciprocal Rank Fusion, within a token budget. Relevant knowledge is recalled automatically on every request, before Claude starts exploring. Everything is plain markdown inside the project .rubi/ , opens as an Obsidian graph, and runs locally with zero dependencies. It was built for Claude Code and, because its core is a standard MCP server, it also runs in Codex, Gemini CLI, Cursor, GitHub Copilot, Windsurf, Cline, OpenCode, Continue, Goose and Zed , with hosted or local models see the table codex-gemini-cli-cursor-copilot-and-other-agents . Results. Two studies, reported as measured, including what did not work: | Study | Result | |---|---| | Early compaction, replayed on 284 real sessions | ≈37% lower total cost simulation on real context curves | | A/B benchmark, 90 sessions, reading a mature graph | −37% steps, −37% context re-read, −17% time ; billed cost −6% in short cold-start sessions | | Same, projected onto the real cost mix 71% cache reads | ≈26% lower cost projection, not yet measured | | A/B benchmark, writing memory after every answer | +15% cost in short sessions, so the default was changed to write less often | A language model does not "remember" a conversation. Every time you send a message, the entire conversation so far is sent again: your requests, Claude's answers, and every file it read and every command it ran. That bundle is the context . In plain words. Imagine a consultant who, before answering each new question, re-reads the whole meeting transcript from the start. Message 10 is cheap. Message 500 means re-reading 499 pages first. So the cost of a session is not proportional to the number of messages but to the sum of the context sizes . If the context grows by a roughly constant amount per message, that sum grows with the square of the session length. Anthropic's prompt caching stores the beginning of the context so that re-reading it costs about 10% of the normal input price. It is a real discount, and in our data it worked: 99% cache hit rate . But 10% of a million tokens, on every message, for hundreds of messages, is still most of the bill. When the cache expires for example after a pause , the whole context is written to it again at a higher price. Rubi ships a token X-ray that reads Claude Code's local transcripts. On 30 days of real usage: | Finding 284 sessions, 30 days | | |---|---| | Share of cost that was re-reading context cache reads | 71% | | Share of cost from sessions that grew past 150k tokens | 97% | | Sessions that reached ~1 million tokens | 68 | | Context loaded before the first message median | 48k | | Tool whose outputs weighed most in the context | Bash 15% , then Read 4% | | Times the cache expired mid-session and was rewritten | 197 | Two conclusions drove the design: - Sessions are too long. Claude Code only compacts near the model's limit, and with a 1M-token model that is very late. - Claude spends a lot of effort finding its way around. A large share of the context is file reads and searches that rediscover how the project works, every new session. Rubi combines well-known techniques from information retrieval, graph theory and recent research on memory for language models. Each one below gets a plain-words explanation and a pointer to the original work. A graph is just things nodes connected by relationships edges . In Rubi the nodes are files, modules, decisions, bugs, gotchas and concepts, and the edges are "file A imports file B", "this decision is about login.ts", "this bug is related to Checkout", "this decision replaces that one". In plain words. A folder of notes is like a pile of index cards: you only find a card if you guess the word written on it. A graph is like a city map : from where you are, you can see what's next door. Ask about "finishing a purchase" and a plain search finds nothing, because no note says "purchase". With Rubi, Claude adds the related word checkout to the search section 2.9 , the graph finds the concept Checkout , sees that it is linked to a gotcha called "Coupon applied twice" and to the file cupom.ts , and brings those along. You get the trap you were about to fall into, even though you never typed its name. That is the difference: search finds what matches your words; a graph also finds what is connected to them. In code, connections are everything: who imports whom, which decision affects which file, which bug came back where. When you search, something has to decide which results come first. BM25 Robertson & Zaragoza, 2009 is the classic answer used by search engines: a word counts more if it is rare in the collection and frequent in the document, with diminishing returns so repetition doesn't win. Rubi uses it for the textual part of the search, with accent folding, camelCase splitting PaymentError → payment , error and light Portuguese/English stemming. PageRank Brin & Page, 1998 , the algorithm behind early Google, says a page is important if important pages link to it. Applied to code: a file is central if many files import it, especially central ones. Rubi computes PageRank over the import graph to tell Claude, in one line, which files are the backbone of the project. This is the same idea as Aider's repo map . Personalized PageRank Haveliwala, 2002 is PageRank that "starts" from a few chosen nodes and spreads outward, so you get what is important relative to your question . HippoRAG Gutiérrez et al., 2024 showed this works remarkably well as long-term memory for language models, inspired by how the hippocampus links memories. Rubi seeds it with the nodes that matched your words and lets relevance flow through the graph, discounting "hub" files that everything touches. Text, exact file and function names, and graph proximity each produce their own ranked list. Reciprocal Rank Fusion Cormack et al., 2009 merges them with a simple rule: each list gives every item 1 / 60 + position , and the scores are added. It is robust, needs no tuning, and is what ai-memory also uses. Microsoft's GraphRAG Edge et al., 2024 showed the value of summarizing a knowledge graph at several levels. Rubi keeps three: | Level | File | Size | When it's read | |---|---|---|---| | 0 | mapa.md | ~500 tokens | at the start of every session | | 1 | modulos/