Code review con Knowledge Graph + MCP: pasé de 150k a 18k tokens (8x menos que RAG del repo)
Durante meses hice code review con Claude Code metiendo “todo por si acaso” al contexto: el archivo tocado más 40 o 50 archivos vecinos elegidos con un grep amplio. Cada review me costaba alrededor de 150.000 tokens de input. La calidad estaba bien, pero la factura no.
Cuando cambié el pipeline y le pasé al mismo modelo solo los archivos que el knowledge graph identifica como afectados por el cambio, el mismo tipo de review se resolvió con unos 18.000 tokens. Mismo comentario final, misma detección de regresiones, casi lo mismo de tiempo de pared. La factura, dividida por 8.
Este artículo cuenta cómo armé ese pipeline con code-review-graph 2.3.8 (Python, SQLite local, servidor MCP con 30 herramientas expuestas) y las 3 trampas del blast radius con las que me tropecé antes de que empezara a rendir.
Por qué “meter todo al contexto” no escala en review
La intuición engañosa es esta: si le doy al modelo más código, verá más cosas. En review de código es al revés. Con 150k tokens de contexto, el modelo se dispersa: dedica atención a helpers que no se van a llamar en el path modificado, comenta cosas del README viejo y se le pasan las condiciones de borde del diff real. Y encima, en Claude Code Max se está comiendo tu cuota.
En ch10 de mi libro sobre knowledge graphs de código lo escribí así: el mayor valor de un KG de código no es agregar contexto, es quitarlo. Retrieval con RAG vectorial también reduce respecto a “todo el repo”, pero para preguntas de “¿qué se rompe si cambio esta función?” los vecinos por similitud semántica no son los mismos vecinos que por dependencia de código. Un test de test_login.py y una utilidad de login_helpers.py pueden estar lejos por embeddings y ser vecinos directos por call graph.
Ese es el hueco que llena un KG: relaciones estructurales (llama-a, importa, hereda-de, testea) en vez de “se parece a”.
Qué es code-review-graph
code-review-graph es un paquete Python que hace tres cosas:
- Construye un grafo de tu repo (funciones, clases, archivos, tests) parseando con árboles sintácticos.
- Lo guarda en un SQLite local dentro de
.code-review-graph/— sin Neo4j ni Kuzu ni servicio en la nube, solo un archivo en tu proyecto. - Levanta un servidor MCP con 30 herramientas que Claude Code (u otro cliente MCP) puede invocar.
La instalación mínima:
pip install code-review-graph
code-review-graph build .
code-review-graph install # detecta Claude Code / Cursor / Windsurf y registra el MCP
Una vez registrado, Claude Code ve las herramientas del grafo igual que las suyas propias. Las que más uso en review son cuatro:
| Herramienta | Para qué la uso |
|---|---|
get_minimal_context_tool | Primera llamada, ~100 tokens: qué es el proyecto y por dónde entrar |
get_impact_radius_tool | Blast radius de los archivos tocados en el diff |
get_review_context_tool | Slice del código relevante empaquetado para review |
semantic_search_nodes_tool | Buscar por concepto cuando el diff toca algo abstracto |
Los nombres terminan en _tool porque así los expone el paquete. La primera vez me confundí y llamé a blast_radius a secas — no existe. La versión que probé es la 2.3.8 (release del 21 de agosto de 2026), corriendo contra Claude Code CLI 2.1.237.
El pipeline concreto
Con el MCP registrado, mi loop de review en Claude Code queda así, uno por uno:
1. git diff --name-only main...HEAD → lista de archivos tocados
2. get_minimal_context_tool() → 100 tokens de mapa
3. get_impact_radius_tool(files=[...]) → hop 0-2, devuelve nodos afectados
4. get_review_context_tool(nodes=[...])→ slice empaquetado para el modelo
5. Claude revisa con ese slice + el diff
Los pasos 2 a 4 son los que se llevan la reducción de tokens. get_minimal_context_tool da al modelo el mapa mental sin cargar los archivos completos. get_impact_radius_tool corta la búsqueda: si tocaste auth.py, el hop 1 puede darte 3 archivos, el hop 2 unos 7, el hop 3 empieza a arrastrar toda la carpeta de tests. Con get_review_context_tool recibes el slice del código ya empaquetado con el resumen estructural.
Los números del antes y el después
La comparación con el mismo tipo de PR (cambio en la capa de autenticación de un servicio Python de tamaño medio), mismo modelo y misma instrucción de review:
| Estrategia | Archivos al contexto | Tokens input | Calidad del review |
|---|---|---|---|
| RAG del repo entero (chunks + similitud) | ~50 | ~150k | Buena, pero comentarios dispersos |
| KG + MCP (blast radius hop 2) | 7 | ~18k | Igual de buena, más enfocada |
Reducción: 8.3x. Los números son los mismos que documenté en ch10 de mi libro y son consistentes con lo que veo semana a semana en el trabajo. La calidad no cae porque los archivos que quedan afuera del blast radius genuinamente no participan en el path del cambio — el grafo lo sabe de forma estructural, no por adivinar.
Vale un matiz: la calidad se mantiene cuando el grafo está fresco. Si vengo de un refactor grande sin volver a ejecutar build, el blast radius miente y el review sufre. Esa es la primera trampa.
Las 3 trampas del blast radius
Trampa 1: el grafo desactualizado devuelve un blast radius desactualizado. Después de un refactor mediano, ejecutar code-review-graph build . (o build_or_update_graph_tool desde el MCP) antes del review es obligatorio. El comando es rápido en repos pequeños y medianos, pero en monorepos grandes conviene meterlo en el pre-push hook para no acordarte cada vez.
Trampa 2: el hop 3 se traga el mundo. Empecé con hop=3 pensando que “un poco más de contexto no molesta” y me devolvía 40 archivos, casi la mitad tests indirectos. Con eso, la reducción caía a 3x y no a 8x. Con hop=2 me quedo en 7-10 archivos y la calidad no baja perceptiblemente. Hop=1 se pasa de agresivo: te pierde helpers que sí importan.
Trampa 3: el dispatch dinámico no aparece en el grafo. Si tu framework registra rutas con decoradores complejos, sistemas de plugins o getattr sobre strings, el KG no ve esas aristas. Para esos casos, semantic_search_nodes_tool complementa: buscas por concepto (“todo lo que maneja pagos”) en vez de por llamada directa. Yo hago el review estructural con blast radius y luego una pasada semántica corta si el diff toca esas zonas.
Ninguna de las tres es bloqueante. Son ajustes que se hacen una vez y ya. Pero descubrirlos costó: no había pensado en ninguna la primera semana y estaba a punto de decir que la reducción era “solo 3x, no compensa”. Sí compensa, cuando el hop está bien elegido y el grafo está al día.
Cuándo no vale la pena
Voy a ser honesto: si el repo es de menos de 5.000 líneas, con RAG del repo entero ya estás bajo los 30k tokens de input y el KG no te va a mover mucho la aguja. La ventaja aparece cuando el repo no cabe cómodamente en el contexto y estás gastando tokens en archivos que no participan en el cambio.
Tampoco compensa si estás haciendo review de un solo archivo autoconclusivo (una función pura sin dependencias). Ahí ni siquiera necesitas grafo: le pasas el archivo y ya.
El punto donde más rinde son repos de tamaño medio-grande, con call graph rico y muchos tests. Ahí es donde bajar de 150k a 18k por review se traduce en cuenta mensual visible.
Lo que dejaría por escrito para mi yo de hace 3 meses
Una sola frase: el knowledge graph no mejora los comentarios del modelo, mejora la selección del código que le llega al modelo. Con eso claro, dejas de intentar “mejorar el prompt de review” y empiezas a mejorar el retrieval. Y en review de código, el retrieval estructural (grafo) le gana al retrieval semántico (embeddings) en la mayoría de casos.
Si quieren armar el pipeline desde cero, en ch10 de Knowledge Graph Practical Guide está el paso a paso con los comandos que uso yo, incluyendo el flujo de trabajo KG + MCP y el análisis del blast radius por hop. El libro está listado en la página de libros.
ken imoto · WebRTC & Voice AI engineer · kenimoto.dev
Libro relacionado Convirtiendo LLMs de Mentirosos en Expertos Ingeniería de Contexto desde cero — RAG, MCP, CLAUDE.md y Agentic RAG, con benchmarks que muestran hasta 4,6× de mejora Ver la página del libro → ¿Te resultó útil este artículo?