> your AI agent picks dependencies from memory; give it dated facts — try starlog.dev ↗ vet your agent's deps ↗ vibe-coding is fine. vibe-importing isn’t. — try starlog.dev ↗ vibe-importing isn’t fine ↗ your agent has never seen your private packages — try starlog.dev ↗ facts for private packages ↗ a linter for the dependencies your AI agent picks — try starlog.dev ↗ a linter for agent deps ↗

Back to Articles

Graphify: Teaching AI Assistants to Query Your Codebase Like a Database

[ View on GitHub ]

Graphify: Teaching AI Assistants to Query Your Codebase Like a Database

Hook

Your AI coding assistant reads the same file seventeen times during a conversation because it has no memory of what connects to what. Graphify fixes this by intercepting file operations at the platform level and routing questions through a knowledge graph first.

Context

AI coding assistants are surprisingly inefficient at navigating codebases. Ask Claude Code "what calls this function?" and it'll grep through every file, burning context tokens and API time. Ask it ten related questions and it repeats the search ten times—no shared understanding, no architectural memory. This happens because assistants treat codebases as flat filesystems, not interconnected systems.

The typical solution is RAG (Retrieval-Augmented Generation): chunk code into embeddings, vector search for relevant pieces, pass matches to the LLM. But vector similarity is terrible at precise relationship queries. Searching for "authentication dependencies" returns files that mention authentication, not the actual call graph. You get semantic proximity when you need structural traversal. Graphify takes a different approach: parse everything (code, SQL schemas, Terraform configs, markdown docs) into a knowledge graph of entities and relationships, then teach your AI assistant to query the graph before touching files. The result is architectural awareness baked into every conversation.

Technical Insight

Platform Integration

Python/JS/Go/etc

SQL

Terraform

Leiden

PageRank

Intercept file ops

Rewrite to query

Source Code Files

Tree-sitter AST Parser

File Type Router

Parallel LLM Extraction

Postgres Introspection

Resource Mapping

Entity & Relationship Merge

Graph Analysis Engine

Community Detection

Node Ranking

Unified Knowledge Graph

Export Layer

Interactive HTML/vis.js

JSON API

Markdown Reports

PreToolUse Hooks

AI Assistant Tools

Claude Code Agent

Codex multi_agent

Factory Droid Task

System architecture — auto-generated

Graphify's architecture hinges on a clever trick: PreToolUse hooks that intercept your AI assistant's file operations. On platforms like Claude Code and Codex, these hooks fire before the assistant executes Bash commands or reads files. When the assistant plans to grep for imports or scan directories, the hook rewrites the plan to try graphify query first. The assistant doesn't know it's happening—the graph becomes a transparent caching layer.

The extraction pipeline is three stages. First, tree-sitter parses source files into ASTs for 20+ languages (Python, JavaScript, Go, Rust, Java, etc.). For a Python file, it extracts classes, functions, imports, and decorators. For SQL schemas, it connects live to Postgres via DSN and introspects tables, columns, foreign keys, and indexes. For Terraform, it maps resources and data sources. Everything becomes nodes and edges.

Second, parallel LLM extraction. Each file or chunk gets sent to the configured model (Claude, GPT-4, Gemini) with a schema-constrained prompt: "Extract entities and relationships from this code." Platform-specific parallelism keeps this fast. Claude Code dispatches Agent tools for concurrent extractions. Codex uses its multi_agent=true feature. Factory Droid spawns Task subagents. A medium codebase might spawn 50 parallel extraction tasks, merging results into a central graph structure.

Here's what extraction looks like under the hood (simplified example from the codebase):

# Extraction prompt sent to LLM for each chunk
extraction_schema = {
    "entities": [
        {"name": "string", "type": "class|function|table|variable", 
         "file": "string", "line": "int"},
    ],
    "relationships": [
        {"source": "entity_name", "target": "entity_name", 
         "type": "calls|imports|inherits|references"}
    ]
}

# Parallel dispatch on Claude Code via Agent tool
for file_chunk in codebase_chunks:
    agent_task = {
        "tool": "Agent",
        "prompt": f"Extract entities from {file_chunk.path}",
        "context": file_chunk.content,
        "schema": extraction_schema
    }
    dispatch(agent_task)

# Merge results into NetworkX graph
for result in extraction_results:
    for entity in result['entities']:
        graph.add_node(entity['name'], **entity)
    for rel in result['relationships']:
        graph.add_edge(rel['source'], rel['target'], type=rel['type'])

Third, graph analysis. Graphify runs PageRank to find "god nodes" (central entities like config loaders or database clients). It applies Leiden community detection to identify architectural modules—clusters of tightly connected entities that form natural boundaries. It calculates betweenness centrality to surface "surprising connections": low-degree nodes that bridge unrelated modules, often the coupling points that cause maintenance pain.

The query interface is intentionally simple. No Cypher, no graph QL. Just natural language processed by the assistant:

# Queried through your AI assistant automatically via PreToolUse hooks
graphify query "what depends on the User table"
# Returns: AuthService.login, ProfileController.show, EmailQueue.send

graphify query "trace the login API call"
# Returns: POST /login -> AuthController.create -> AuthService.verify -> UserRepository.find -> users table

graphify query "find god nodes"
# Returns ranked list: DatabaseClient (PageRank: 0.23), ConfigLoader (0.18), Logger (0.15)

Platform integration happens through skill registration. On Claude Code, you run graphify install claude, which writes .claude/skills/graphify/SKILL.md with instructions and hook definitions. The PreToolUse hook watches for Bash, Read, or Glob tool invocations. When it sees a file search, it injects a graph query suggestion before execution. This is more sophisticated than RAG—the assistant consults structured relationships, not fuzzy embeddings.

The export formats serve different personas. graph.html generates an interactive vis.js visualization for human exploration—click nodes to see connections, filter by entity type, zoom into modules. graph.json exports raw NetworkX data for CI scripts or custom tooling. The --callflow-html flag generates Mermaid flowcharts for architecture documentation. You can pipe graphify query output to markdown for automated architecture decision records.

Gotcha

The biggest limitation is LLM-based extraction trustworthiness. Graphify has no ground truth verification—if the extraction model hallucinates a relationship ("AdminService calls PaymentProcessor" when it doesn't), that phantom edge pollutes every downstream query. With GPT-4 or Claude 3.5, accuracy is decent for mainstream languages. With smaller models or niche languages, expect noise. There's no diff-checking or confidence scoring, so you can't distinguish high-certainty edges from guesses.

Cost scales brutally with codebase size. A 10,000-file monorepo might generate 5,000 extraction prompts at ~2k tokens each. With Claude 3.5 Sonnet pricing ($3 per million input tokens), that's $30 for a single index build. Every time you re-run graphify extract, you pay again—there's no incremental update mechanism. The tool doesn't detect which files changed since the last run or reuse existing graph data. For CI integration or frequent re-indexing, costs spiral fast.

Platform support fragmentation creates a two-tier experience. Claude Code and Codex get transparent PreToolUse interception—the graph just works, every conversation. Cursor, Aider, and OpenClaw rely on markdown skill files that the assistant might ignore if it's focused elsewhere. You're relying on prompt adherence, not platform guarantees. The tool also ships with no semantic search. Queries are string matching against entity names and relationship types. Searching for "authentication logic" only works if something is named AuthService or authenticate(). There's no embedding layer to handle synonyms or conceptual similarity.

Verdict

Use if: You're heavily invested in AI coding assistants (Claude Code, Codex, or Cursor) and your team asks architectural questions constantly ("what depends on this table?", "trace this API call"). The PreToolUse hook on supported platforms is genuinely useful—your assistant automatically consults the graph before grepping, which is faster and more accurate for relationship queries. Also use this if you're documenting infrastructure (SQL schemas, Terraform configs, Kubernetes manifests) alongside application code and need cross-artifact visibility. Platform teams mapping cloud architecture will find value in unified graphs spanning code, databases, and infra-as-code. Skip if: You're working with low-context models that can't afford the skill overhead, need semantic search over exact entity matching, or can't justify the upfront extraction cost (budget $30-$100+ for medium-to-large codebases per index). Also skip if you need incremental updates—Graphify is a point-in-time snapshot tool, not a living system that tracks changes. For semantic codebase search, use Sourcegraph or Continue.dev instead. For free IDE-native dependency graphs, stick with built-in tools like VS Code's references or JetBrains' call hierarchies.