Knowledge Compiler
Claude Code could read our code but not understand it: every question meant opening dozens of files. I built a system that learns each service the way a new engineer would, from the code, the tickets and the data, links them into one knowledge graph and keeps learning after every release. Claude Code now answers from the graph.
- Status
- Team tool
- Role
- Designed the architecture and built it on my own initiative, using Claude Code
- Where
- i2c Inc.
- Stack
- Python
- Claude Agent SDK
- Kotlin
- IntelliJ PSI
- Podman
- Neo4j
- Qdrant
- OpenAI embeddings
- MCP
- Scope
- Many services, linked into one graph
- Isolation
- One Podman container per service
- Access
- Read-only, enforced by account permissions
- Updates
- Re-learns what changed after each release
- Set up and walk the code: The service is built in its own Podman container. Through the headless IntelliJ worker, the agent follows callers, callees and inheritance, one flow at a time.
- Look things up: Tickets, wiki pages and sample data explain what the code alone cannot. Every account is read-only.
- Build on what is known: The agent asks the retrieval server what earlier services already taught it, and links to it.
- Resolve and store: A resolver reconciles the findings; the graph gains nodes, relationships and embeddings.
- Answer across services: Claude Code queries the graph through the retrieval server over MCP, and gets answers that follow calls and shared tables across services.
The problem
Once Multi-Manager’s Bitbucket integration gave Claude access to our repositories, it could answer questions about the code, but only by reading it. A simple question meant opening dozens of files, and across many services it lost track of which one owned what.
How a service is learned
Each service is learned inside its own Podman container, where it is cloned, configured and built the way a developer would set it up. The Knowledge Compiler, an agent written in Python on the Claude Agent SDK, then works through it.
- A custom IntelliJ worker, written in Kotlin on the IntelliJ Gradle plugin and PSI analysis, runs headless and is exposed to the agent over MCP. It gives the agent the analysis a developer has in the IDE: callers and callees, inheritance and every usage of a symbol.
- Starting at the entry points, the agent reads the code one flow at a time: a sub-flow, a decision, a branch.
- When something is unclear, it checks Jira, Confluence and Bitbucket for the intent behind the code, and the database for the sample data behind a query.
- While it reads, it asks the retrieval server what earlier services already taught it, and builds on that instead of learning it again.
Read-only by design
The agent cannot change anything, and that is enforced at the source rather than by instructions to the model. Its accounts in Bitbucket, Jira and Confluence have no write permission, and its database user and its SSH and SFTP accounts are read-only.
Writing the graph
Before anything is stored, a resolver agent reconciles what was found and keeps the result as deterministic as possible. The output is graph nodes and relationships in Neo4j, with OpenAI embeddings in Qdrant for questions that do not name anything exactly.
One graph across services
Services are learned one at a time and linked as they are added. A call from one service to another joins them through the method signature, and a shared table or column joins every service that uses it. Claude Code can follow a question across service boundaries and down to the data, through the retrieval server over MCP.
Keeping up with releases
The Knowledge Compiler runs on a schedule. For each service it records the commit it learned from. After a release it compares that commit with the new history, works through only what changed and updates the graph, so the answers follow the code as it moves.
Outcome
- Services are learned one by one and linked into one graph, which follows the code after each release.
- Questions that needed many file reads are answered from the graph.
What I took from it
Giving the agent a developer’s tools, the IDE’s code analysis, the tickets and sample data, mattered more than giving it more of the code.