Skip to main content

Antes de que el modelo adivine: Galadriel y el contexto que necesitan los agentes de IA

Updated 13 min readMarkdown
Antes de que el modelo adivine: Galadriel y el contexto que necesitan los agentes de IA

Un índice local que ayuda a Cursor, GitHub Copilot y otros agentes a entender cómo está conectado un proyecto antes de modificarlo.

Cuando trabajamos con herramientas como Cursor o GitHub Copilot, solemos hacer preguntas como estas:

  • ¿Dónde está implementada esta funcionalidad?
  • ¿Qué clases dependen de este componente?
  • Si modifico este contrato, ¿qué otros archivos podrían verse afectados?
  • ¿Existe alguna dependencia circular?
  • ¿Hay archivos que aparentemente no utiliza nadie?

Los modelos de IA pueden ayudarnos a responder estas preguntas. El problema es que no siempre tienen suficiente contexto sobre nuestro repositorio. Pueden encontrar archivos, interpretar fragmentos de código y proponer cambios, pero también pueden asumir relaciones que no existen, pasar por alto dependencias o sugerir modificaciones sin conocer todas sus consecuencias.

Y cuando eso ocurre, el problema no es necesariamente el modelo. Muchas veces, simplemente no tiene suficiente información sobre el proyecto.

Antes de pedirle a un agente que modifique nuestro código, deberíamos darle una forma de entender cómo está construido.

Esa es la idea detrás de Galadriel.

¿Qué es Galadriel?

Galadriel es una herramienta de inteligencia estructural de código (Local Code Intelligence) que analiza un repositorio, construye un índice local y permite consultar las relaciones entre sus archivos.

Su objetivo es sencillo: proporcionar información verificable sobre la estructura de un proyecto para que los agentes de programación puedan trabajar con mayor contexto.

Galadriel no escribe código, no ejecuta modelos de lenguaje y tampoco necesita enviar nuestro repositorio a un servicio externo.

Construye un índice en nuestra propia máquina, dentro de .galadriel/espejo.db, y expone esa información mediante una interfaz que pueden consumir herramientas como Cursor y GitHub Copilot.

En lugar de pedirle al modelo que intente descubrir por sí solo cómo está organizado todo el proyecto, podemos darle acceso a información estructural previamente analizada.

Hay tres preguntas que resumen buena parte de lo que ofrece:

Pregunta Comando Para qué sirve
¿Dónde está? galadriel search Buscar información en el repositorio.
¿Qué relación tiene? galadriel relate Consultar las relaciones de un archivo.
¿Qué podría verse afectado? galadriel impact Explorar dependencias e impacto de un cambio.

Además, permite visualizar grafos, detectar ciclos, revisar posibles archivos sin referencias y consultar estadísticas del índice.

La diferencia importante es que Galadriel no pretende reemplazar el razonamiento del modelo. Le proporciona información sobre la cual puede razonar.

Un índice, no otro modelo de IA

Es importante entender qué hace Galadriel y qué no hace.

No es un LLM. No utiliza embeddings ni necesita una base de datos vectorial para recuperar información. Tampoco intenta reemplazar las capacidades de los servidores de lenguaje de cada tecnología.

Su funcionamiento se puede entender en cuatro pasos:

  1. Analiza el repositorio. Recorre los archivos que reconoce y extrae información relevante.
  2. Construye un índice. Guarda fragmentos y relaciones en una base de datos SQLite local.
  3. Expone consultas. Permite buscar archivos, consultar relaciones, explorar dependencias y analizar impactos.
  4. Entrega contexto al agente. Mediante MCP, Cursor o GitHub Copilot pueden consultar esa información durante una conversación.

El modelo sigue siendo responsable de interpretar la solicitud, razonar y proponer una solución. Galadriel aporta información estructural para reducir las suposiciones.

Por ejemplo, si le pedimos a un agente que modifique Student.java, puede consultar primero qué archivos están relacionados con esa clase y cuáles podrían verse afectados.

Así, la conversación deja de depender exclusivamente de lo que el modelo consiga inferir leyendo archivos individualmente.

Cuatro proyectos reales, cuatro escenarios diferentes

Para probar Galadriel 1.0.0 utilicé cuatro repositorios de tecnologías y estructuras distintas.

Los siguientes resultados corresponden a índices generados localmente el 1 de noviembre de 2026.

Proyecto Archivos Fragmentos Relaciones
Ejemplos de módulos Java 25 70 79 43
Destaka Android (Kotlin) 93 374 295
Microservicios Order/Product (.NET) 95 511 131
API de estudiantes (Quarkus) 16 77 7

No se trata de ejemplos inventados para producir grafos atractivos. Son repositorios reales que permiten observar cómo Galadriel interpreta diferentes estructuras y relaciones.

Veamos algunos casos.

1. Java 25: entender módulos y detectar ciclos

El primer escenario utiliza un proyecto con módulos de Java.

En este repositorio tenemos varios módulos relacionados con un servicio de pagos. Por ejemplo, los módulos de tarjeta, Yape y tienda dependen de una API común: com.joedayz.pagos.api.

Galadriel puede identificar estas relaciones y agruparlas mediante:

galadriel scan
galadriel graph --modules

El resultado permite visualizar las dependencias entre módulos, en lugar de limitarse a mostrar imports individuales.

También preparé un escenario didáctico con dos módulos que se requieren mutuamente:

module com.joedayz.a {
    requires com.joedayz.b;
}

Y en el otro módulo:

module com.joedayz.b {
    requires com.joedayz.a;
}

Esto genera una dependencia circular.

Podemos detectarla con:

galadriel cycles

El resultado identifica el ciclo:

com.joedayz.a → com.joedayz.b → com.joedayz.a

También podemos consultar el impacto de modificar una clase compartida como MedioPago.java:

galadriel impact \
  04-servicios/src/com.joedayz.pagos.api/com/joedayz/pagos/api/MedioPago.java

Esto permite explorar qué archivos están relacionados con esa modificación.

Un detalle interesante es que Galadriel también contempla el análisis incremental. Si un archivo cambia o se mueve, el índice puede actualizar sus relaciones sin necesidad de reconstruir todo desde cero.

cd ejemplos-modulos
galadriel scan
galadriel graph --modules
galadriel cycles
galadriel impact 04-servicios/src/com.joedayz.pagos.api/com/joedayz/pagos/api/MedioPago.java

2. Kotlin: entender la estructura de una aplicación Android

El segundo escenario es Destaka Android, una aplicación desarrollada con Kotlin y Jetpack Compose.

Aquí no tenemos módulos Java definidos mediante module-info.java. La organización del proyecto gira alrededor de una Activity, componentes de interfaz, ViewModels, modelos y rutas.

Por eso, en este caso, el grafo de archivos resulta mucho más útil que el grafo de módulos.

Podemos consultar las relaciones de MainActivity y DestakaApp:

galadriel scan

galadriel relate \
  app/src/main/java/pe/joedayz/destaka/MainActivity.kt

Una de las cosas que podemos observar es cómo MainActivity utiliza DestakaApp y el tema visual de la aplicación.

A su vez, DestakaApp se relaciona con diferentes pantallas, sus ViewModels y otros componentes de la aplicación.

Esto permite entender mejor cómo se distribuye la responsabilidad entre los archivos.

También podemos consultar qué ocurriría si modificamos el tema visual:

galadriel impact \
  app/src/main/java/pe/joedayz/destaka/ui/theme/DestakaTheme.kt \
  --depth 2

El resultado permite explorar el impacto a más de un nivel de profundidad.

En este repositorio también se identificó un ciclo entre AppResult.kt y AppError.kt.

Y algo interesante: la consulta unused no encontró código huérfano en este escenario.

cd destaka-android
galadriel scan
galadriel relate app/src/main/java/pe/joedayz/destaka/ui/theme/DestakaTheme.kt
galadriel impact app/src/main/java/pe/joedayz/destaka/ui/theme/DestakaTheme.kt --depth 2
galadriel unused

3. .NET: seguir una dependencia entre microservicios a través de un contrato

El tercer escenario utiliza dos servicios desarrollados en C#: OrderService y ProductService.

Ambos se comunican mediante gRPC y comparten un contrato definido en un archivo Protocol Buffers:

product.proto

Este archivo declara, entre otras cosas:

option csharp_namespace = "ProductService.Grpc";

service ProductGrpc {
    // ...
}

El cliente de OrderService utiliza el cliente gRPC generado a partir de ese contrato.

Lo interesante es que Galadriel puede identificar la relación entre los proyectos a través del archivo .proto, sin depender de las clases C# generadas durante la compilación.

Al ejecutar:

galadriel scan
galadriel graph --modules

Podemos observar una relación entre ambos proyectos:

OrderService ==> |2| ProductService

El peso representa las dos relaciones identificadas entre archivos de OrderService y el contrato de ProductService.

Ahora imaginemos que necesitamos modificar product.proto.

Podemos consultar el impacto:

galadriel impact \
  src/Services/ProductService/Protos/product.proto \
  --depth 2

La consulta permite encontrar los archivos relacionados con el contrato, incluyendo el cliente gRPC y los puntos de configuración de ambos servicios.

Esto resulta especialmente útil cuando trabajamos con arquitecturas distribuidas: un cambio puede comenzar en un contrato y terminar afectando componentes que viven en otro proyecto.

cd microservices-net-2026
galadriel scan
galadriel graph --modules
galadriel relate src/Services/OrderService/Clients/GrpcProductServiceClient.cs
galadriel impact src/Services/ProductService/Protos/product.proto --depth 2

4. Quarkus: relaciones que no siempre aparecen en los imports

El último escenario utiliza una API de estudiantes desarrollada con Quarkus.

Es un proyecto pequeño, pero permite mostrar una característica interesante.

Tenemos dos clases dentro del mismo paquete:

  • Student.java
  • Grade.java

La clase Student contiene una colección de notas:

List<Grade> grades;

Y Grade mantiene una referencia al estudiante:

Student student;

No necesitamos que una clase importe explícitamente a la otra para que exista una relación entre ellas. Ambas están en el mismo paquete y se referencian mediante sus tipos.

Galadriel puede reconocer esta relación y representarla en el grafo.

Podemos consultar:

galadriel scan
galadriel graph

También podemos buscar información sobre estudiantes y notas:

galadriel search "estudiante nota"

Y consultar qué archivos podrían verse afectados al modificar Student.java:

galadriel impact \
  src/main/java/edu/utp/quarkus/student/Student.java

En este caso, el resultado identifica relaciones con Grade, GradeResource y StudentResource.

Es un ejemplo pequeño, pero ilustra algo importante: conocer las dependencias de un proyecto no siempre consiste en buscar instrucciones import. También hay relaciones que se pueden inferir a partir de los tipos y de la estructura del código.

Galadriel y los agentes de programación

Hasta aquí hemos visto cómo consultar Galadriel desde la terminal.

Pero su verdadero potencial aparece cuando lo conectamos con un agente de programación.

Para ello utiliza MCP (Model Context Protocol).

MCP permite que aplicaciones como Cursor y GitHub Copilot accedan a herramientas externas. En este caso, Galadriel expone consultas sobre el repositorio para que el agente pueda utilizarlas durante una conversación.

Integración con Cursor

En Cursor podemos registrar Galadriel mediante el archivo .cursor/mcp.json.

Una configuración básica sería:

{
  "mcpServers": {
    "galadriel": {
      "command": "node",
      "args": [
        "/ruta/a/galadriel/dist/cli.js",
        "serve",
        "--workspace",
        "/ruta/al/repositorio"
      ]
    }
  }
}

Una vez configurado, Cursor podrá acceder a las herramientas expuestas por Galadriel:

  • search
  • relate
  • impact
  • graph
  • cycles
  • unused
  • advisories
  • stats

Integración con GitHub Copilot

También podemos utilizarlo desde GitHub Copilot Chat en Visual Studio Code.

En este caso, la configuración del editor se realiza mediante .vscode/mcp.json:

{
  "servers": {
    "galadriel": {
      "type": "stdio",
      "command": "node",
      "args": [
        "/ruta/a/galadriel/dist/cli.js",
        "serve",
        "--workspace",
        "/ruta/al/repositorio"
      ]
    }
  }
}

Después de guardar la configuración, podemos iniciar el servidor MCP y utilizar Copilot en modo Agent.

Un ejemplo de uso antes de un refactor

Imaginemos que necesitamos modificar Student.java.

En lugar de pedirle directamente al agente que implemente el cambio, podemos comenzar con una instrucción como esta:

Antes de editar Student.java, utiliza las herramientas impact y relate de Galadriel. No modifiques ningún archivo todavía. Identifica qué archivos están relacionados y cuáles podrían verse afectados por el cambio. Explícame los resultados antes de continuar.

El agente puede consultar el índice y utilizar esa información como parte de su análisis.

Si Galadriel identifica relaciones con Grade, GradeResource y StudentResource, el agente dispone de una referencia concreta para evaluar el cambio.

Esto no garantiza que el modelo tome siempre la decisión correcta, pero sí le proporciona información adicional para evitar algunas de las suposiciones habituales.

La idea es sencilla:

El modelo razona. Galadriel aporta evidencia sobre la estructura del proyecto.

¿Y qué pasa con LSP?

Galadriel también incorpora un servidor LSP (Language Server Protocol) que permite consultar relaciones a nivel de archivo.

Por ejemplo, podemos consultar qué archivos importa uno determinado y qué archivos lo referencian.

Sin embargo, es importante entender su alcance: el análisis de Galadriel trabaja a nivel de archivo, no llega al nivel de métodos o símbolos como lo hacen los servidores de lenguaje especializados.

Por eso, no pretende reemplazar el servidor de Java, Kotlin o C# que utilizamos habitualmente en nuestro IDE.

Ambos pueden complementarse.

Un servidor de lenguaje aporta información detallada sobre el código de una tecnología. Galadriel aporta una vista estructural del repositorio que también puede incluir otros elementos, como archivos .proto o enlaces relativos en documentación Markdown.

Lo que Galadriel no pretende hacer

Prefiero dejar claros algunos límites de la herramienta.

Galadriel no es un asistente de programación autónomo. Tampoco es una solución que entienda cualquier lenguaje con el mismo nivel de profundidad.

Algunas consideraciones de la versión 1.0.0:

  • No ejecuta modelos de lenguaje ni calcula embeddings.
  • No envía información del repositorio a Internet.
  • Los avisos de dependencias utilizan un catálogo local definido por el usuario; no consultan bases de vulnerabilidades en línea ni generan CVE por su cuenta.
  • Go, Python, Ruby, Rust, PHP, SQL y shell pueden indexarse para búsquedas, pero no generan relaciones de import en esta versión.
  • No indexa documentos PDF ni videos.
  • La consulta unused debe interpretarse con criterio. Puede señalar scripts, migraciones u otros archivos que no tienen referencias directas, pero que siguen siendo necesarios para el proyecto.

El índice se almacena localmente en .galadriel/. Por esa razón, conviene agregar esa carpeta al .gitignore del repositorio.

La intención es mantener el análisis en nuestra máquina y no introducir información adicional en el control de versiones.

¿Cómo probar Galadriel?

Galadriel 1.0.0 requiere Node.js 22 o superior.

El proyecto utiliza TypeScript y SQLite con FTS5, mediante better-sqlite3.

Puedes obtener el código desde GitHub:

https://github.com/joedayz/galadriel

Para instalar la versión 1.0.0 desde el repositorio:

git clone https://github.com/joedayz/galadriel.git

cd galadriel

git checkout v1.0.0

npm install

npm run build

npm link

Después, desde el repositorio que quieras analizar:

galadriel scan

Y puedes comenzar explorando:

galadriel search "nombre de una funcionalidad"

galadriel graph

galadriel cycles

galadriel stats

El repositorio incluye más información sobre los comandos y las opciones disponibles.

Una idea para trabajar mejor con IA

Estamos entrando en una etapa en la que los agentes de programación pueden leer, modificar, probar y hasta desplegar software.

Pero darles más autonomía no significa necesariamente darles más contexto.

Un agente puede generar código en segundos y, aun así, no entender completamente las consecuencias de modificar una clase, un contrato o una dependencia compartida.

Creo que una parte importante de la ingeniería de software en esta nueva etapa consiste precisamente en construir mecanismos que ayuden a los agentes a conocer el entorno en el que trabajan.

Galadriel nace de esa idea.

No busca reemplazar al desarrollador, al arquitecto ni al modelo de IA. Busca aportar una pieza que considero necesaria: una representación consultable y verificable de cómo está conectado nuestro código.

Porque antes de modificar un sistema, deberíamos entenderlo.

Y antes de dejar que un agente tome decisiones sobre nuestro código, deberíamos darle contexto suficiente para hacerlo.


Galadriel 1.0.0

Código fuente: https://github.com/joedayz/galadriel

Licencia: Apache 2.0

Enjoy!

Joe

No comments yet. Be the first to comment.