filefunc — Un archivo, un concepto Image: AI generated

El problema

Los agentes de codigo IA (como Claude Code) navegan bases de codigo usando grep para encontrar archivos y read para abrirlos. La unidad de read es el archivo.

¿Que ocurre cuando un solo archivo contiene 20 funciones?

Se necesita un tipo CrossError → read
→ 19 funciones innecesarias vienen incluidas
→ Contaminacion de contexto

“Lost in the Middle” (Stanford, 2024) informo que el rendimiento del LLM cae mas de un 30% cuando la informacion relevante queda enterrada en medio del contexto. “Context Length Alone Hurts LLM Performance” (Amazon, 2025) descubrio que incluso tokens innecesarios en blanco causan una degradacion del 13.9-85%.

El estudio GSM-DC (Yang et al., EMNLP 2025) va un paso mas alla. A traves de experimentos controlados, demostro que el contexto irrelevante no solo “entierra” la informacion util, sino que degrada significativamente tanto la seleccion de rutas de razonamiento como la precision aritmetica del LLM. Que 19 funciones innecesarias vengan incluidas no es “desperdicio” — es “interferencia”.

La investigacion demostro que “cuanto mas corto el contexto, mejor”. Pero no existia una herramienta para dividir estructuralmente el codigo de modo que solo se cargue lo necesario.

filefunc llena ese vacio. Es una convencion de estructura de codigo y herramienta CLI para desarrollo de aplicaciones Go — servicios backend, herramientas CLI, generadores de codigo y validadores SSOT.


Principio fundamental

Un archivo, un concepto. Nombre del archivo = nombre del concepto.

Ya sea func, type, interface o un grupo de const — la regla es la misma. Todas las demas reglas derivan de este unico principio.

# Sin filefunc
read utils.go → 20 funcs, 19 innecesarias. Contexto contaminado.

# Con filefunc
read check_one_file_one_func.go → 1 func. Exactamente lo necesario.

No abrir 290 archivos innecesarios importa mas que seleccionar los 5-10 correctos. Un estudio de completado de codigo en ASE 2025 (Yusuf et al.) informo que la recuperacion a nivel de fragmento mejora la calidad del completado de codigo en un 6% respecto a la recuperacion a nivel de archivo, y en un 16% respecto a sin contexto. No es la cantidad de contexto lo que determina la calidad — es la granularidad.


El ciudadano de primera clase es el agente IA

La estructura de codigo de filefunc esta disenada para agentes IA, no para humanos.

Los agentes IA navegan con grep, no con ls. Ya sean 500 o 1000 archivos, un solo rg '//ff:func feature=validate' es suficiente. Mas archivos significa que cada archivo es mas pequeno — menos ruido por read. Mas archivos es en realidad mejor. Cao et al. (2026) informaron resultados experimentales que muestran que los agentes de codificacion procesan corpus de 3 billones de tokens mediante navegacion del sistema de archivos (ls, grep, read), superando a los modelos de contexto largo existentes en un 17.3%. La unidad de navegacion del agente IA es el archivo.

“¿No habra demasiados archivos?” — para humanos, si. Pero la incomodidad humana es un problema de la capa de vista (resuelto con extensiones IDE como plugins de VSCode). La estructura de filefunc no se compromete para adaptarse a los habitos de navegacion humanos.


La navegacion cambia

Tradicional

Solicitud del usuario
→ No se sabe que hay, asi que ls, find
→ Abrir archivos para entender la estructura
→ grep de nuevo para encontrar archivos relacionados
→ Abrir un archivo, 20 funcs, la mayoria irrelevantes
→ Costo de navegacion > tiempo de trabajo real

Con filefunc

Solicitud del usuario + codebook proporcionado
→ Construir consulta grep inmediatamente desde el codebook
→ read 20-30 archivos (cada uno 1 concepto, todo contexto valido)
→ Trabajar

Leer 30 archivos no es el problema si los 30 son contexto valido. El problema es leer 1 archivo y obtener ruido equivalente a 30 archivos.


El Codebook

El codebook ocupa la posicion mas importante en el diseno de filefunc. Viene antes que las reglas de anotacion. Un codebook bien disenado hace que las consultas grep sean precisas; grep preciso hace que la lista de read sea limpia.

# codebook.yaml
required:
  feature: [validate, annotate, chain, parse, codebook, report, cli]
  type: [command, rule, parser, walker, model, formatter, loader, util]

optional:
  pattern: [error-collection, file-visitor, rule-registry]
  level: [error, warning, info]

Las claves required deben estar presentes en cada anotacion //ff:func y //ff:type — no se permiten vacios, para garantizar la fiabilidad de grep. Las claves optional se usan solo cuando son relevantes.

El codebook es un mapa del proyecto para agentes IA. Sin el, el agente comienza a navegar sin conocer el vocabulario. Con el, el agente puede emitir inmediatamente consultas precisas como feature=validate o type=rule sin exploracion previa.

Usar un valor en una anotacion que no existe en el codebook es un ERROR. Normalizar el vocabulario a traves del codebook expone features faltantes, types duplicados y clasificaciones ambiguas. Los huecos deben ser visibles para ser gestionados. El codebook mismo tambien se valida — al menos una clave en required, sin valores duplicados, solo minusculas y guiones.


Anotaciones de metadatos

Cada archivo comienza con anotaciones en la parte superior, para que los metadatos puedan ser parseados desde las primeras lineas sin leer el cuerpo completo.

//ff:func feature=validate type=rule control=sequence
//ff:what F1: validates one func per file
//ff:why Primary citizen is AI agent. 1 file 1 concept prevents context pollution.
//ff:checked llm=gpt-oss:20b hash=a3f8c1d2
func CheckOneFileOneFunc(gf *model.GoFile) []model.Violation {
AnotacionContenidoRequerido
//ff:funcMetadatos de feature, type, control para archivos funcRequerido para archivos func
//ff:typeMetadatos de feature, type para archivos typeRequerido para archivos type
//ff:whatDescripcion de una linea — que hace esta funcion/tipoRequerido
//ff:whyPor que se construyo asi — razonamiento detras de la decisionOpcional
//ff:checkedFirma de verificacion LLM (auto-generada por llmc)Automatico

El formato es //ff:key key1=value1 key2=value2. Inmediatamente buscable con grep/ripgrep, y parseable por herramientas como pares clave-valor estructurados. Sigue el mismo patron que las directivas //go:generate y //go:embed de Go.

control — 1 func 1 control

control= es requerido para cada archivo func. El valor es uno de tres:

controlSignificadoLimite de profundidad
sequenceEjecucion secuencial2
selectionRamificacion (switch)2
iterationBucledimension + 1

Basado en el teorema de Bohm-Jacopini (1966): todo programa es una combinacion de sequence, selection e iteration. filefunc lo impone a nivel de funcion — una funcion, un flujo de control.

Las funciones con control=iteration tambien requieren dimension=. Esto especifica la dimensionalidad de los datos iterados. dimension=1 significa una lista plana (depth ≤ 2); dimension ≥ 2 requiere anidamiento de tipo nombrado (struct/interface).

filefunc tambien valida que la anotacion control coincida con el codigo real. Si control=selection no tiene switch, o control=sequence contiene un switch o loop, es un ERROR.


Pipeline de navegacion LLM

Las anotaciones actuan como un indice de busqueda — no se necesita infraestructura pesada como embeddings vectoriales.

1. Reduccion estructural (no necesita LLM, solo grep)
   Construir consulta grep basada en codebook
   → Extraer 20-30 archivos candidatos

2. Filtrado por metadatos (sin LLM, o modelo minimo)
   Leer solo la anotacion superior de cada archivo
   → Reducir a 5-10 via name/input/output/what

3. Trabajo de precision (LLM grande, contexto minimo)
   Full read de solo 5-10 archivos
   → Modificar o generar codigo

El contexto se reduce en cada etapa. Cuando el LLM grande se involucra, solo quedan los archivos verdaderamente necesarios.


CLI

validate — Validacion de reglas de estructura de codigo

filefunc validate                    # Directorio actual
filefunc validate /path/to/project   # Raiz del proyecto explicita
filefunc validate --format json

Requiere go.mod y codebook.yaml en la raiz del proyecto. Solo lectura. Sale con codigo 1 en caso de violacion.

chain — Rastreo de relaciones de llamada

filefunc chain func RunAll              # 1er grado (por defecto)
filefunc chain func RunAll --chon 2     # 2do grado (incluye funciones co-llamadas)
filefunc chain func RunAll --chon 3     # 3er grado (maximo)
filefunc chain func RunAll --child-depth 3   # Solo llamadas descendentes
filefunc chain func RunAll --parent-depth 3  # Solo llamadores ascendentes
filefunc chain feature validate         # Feature completa

Analisis AST en tiempo real. --chon es la distancia de relacion. 1er grado es llamador/llamado directo; 2do grado incluye funciones llamadas juntas.

El existente go callgraph realiza analisis estatico completo y produce miles de nodos. chain rastrea solo dentro del mismo feature. El feature del codebook es el nivel de zoom.

llmc — Verificacion LLM

filefunc llmc                           # Directorio actual
filefunc llmc --model qwen3:8b
filefunc llmc --threshold 0.9

Verifica que //ff:what coincida con el cuerpo de la funcion usando un LLM local (ollama). Puntuaciones de 0.0 a 1.0, umbral por defecto 0.8. Al pasar, //ff:checked llm=<modelo> hash=<hash> se escribe automaticamente. Si el cuerpo cambia, el hash cambia — se requiere re-verificacion.

Esto aborda el problema central de la deriva de anotaciones — //ff:what es lenguaje natural y no puede verificarse mecanicamente — usando un LLM pequeno. La restriccion de 1 file 1 func garantiza una correspondencia 1:1 a nivel de archivo, haciendo este enfoque viable.


Reglas

Reglas de estructura de archivos

ReglaEn violacion
Un func por archivo (nombre del archivo = nombre de la funcion)ERROR
Un type por archivo (nombre del archivo = nombre del tipo)ERROR
Metodos: 1 archivo 1 metodoERROR
init() no puede estar solo (debe estar con var o func)ERROR
Archivos _test.go pueden contener multiples funcsExcepcion
Grupos de const semanticamente cohesivos pueden compartir archivoExcepcion

Reglas de calidad de codigo

ReglaEn violacion
Profundidad de anidamiento: sequence=2, selection=2, iteration=dimension+1ERROR
Maximo 1000 lineas por funcERROR
Recomendado: sequence/iteration 100 lineas, selection 300 lineasWARNING

Los limites de profundidad de anidamiento varian segun el tipo de control. sequence y selection: depth 2. iteration: dimension + 1 — dimension=1 (lista plana) significa depth 2, dimension=2 (estructura anidada) significa depth 3. Combinado con el patron de early return de Go, la mayoria del codigo se ajusta comodamente dentro de estos limites.

selection (switch) tiende a tener cases mas largos, por lo que el conteo de lineas recomendado es 300.


.ffignore

Colocar un archivo .ffignore en la raiz del proyecto para excluir rutas de todos los comandos filefunc. Usa la misma sintaxis que .gitignore.

vendor/
*.pb.go
*_gen.go
internal/legacy/

Esto es para excluir codigo generado (protobuf, salida de codegen) o codigo externo vendorizado donde las reglas de filefunc no pueden aplicarse razonablemente.


Integracion con whyso

Porque func = file, el historial de cambios de una funcion se mapea exactamente al historial de cambios de su archivo.

whyso history check_ssac_openapi.go   # Historial de cambios de la funcion CheckSSaCOpenAPI

Cuando un archivo contiene multiples funciones, hay que buscar en los diffs para descubrir cual cambio. Con filefunc, cambio de archivo = cambio de funcion. Costo de rastreo cero.

Deteccion de acoplamiento implicito

whyso coupling check_ssac_openapi.go

Funciones modificadas juntas en la misma solicitud:
  check_response_fields.go  8 veces
  check_err_status.go       5 veces
  types.go                  4 veces

Si dos funciones siguen apareciendo juntas en las estadisticas de acoplamiento a pesar de no tener relacion explicita, es una senal de dependencia oculta. Podrian estar implementando la misma regla de negocio desde diferentes angulos, coincidiendo implicitamente en formatos sin una interface, o siempre rompiendose juntas.


Por que solo Go

La estructura de filefunc no se traduce facilmente a otros lenguajes. gofmt impone el formato de codigo, early return es idiomatico, no hay excepciones, y paquete = directorio. Extender a otros lenguajes requeriria una estrategia de imposicion estructural al nivel de gofmt. Eso esta fuera del alcance de filefunc.

Los casos de uso objetivo tambien son especificos: servicios backend, herramientas CLI, generadores de codigo, validadores SSOT. Bibliotecas de algoritmos, programacion de sistemas de bajo nivel y rutas criticas de rendimiento no son objetivos.


Resumen

En la era LLM, la estructura del codigo debe optimizarse para la eficiencia de navegacion IA, no para la conveniencia de navegacion humana. filefunc es el primer paso en esa transicion.

Un archivo, un concepto. Normalizar vocabulario con el codebook, adjuntar metadatos con anotaciones, encontrar el archivo exacto con un solo grep. No viene codigo innecesario cuando lees un archivo. La contaminacion de contexto se bloquea a nivel estructural.

Codigo: github.com/park-jun-woo/filefunc


Referencias

  • Nelson F. Liu, Kevin Lin, John Hewitt, Ashwin Paranjape, Michele Bevilacqua, Fabio Petroni, Percy Liang (2024). “Lost in the Middle: How Language Models Use Long Contexts.” Transactions of the Association for Computational Linguistics, vol. 12. Link
  • Yufeng Du, Minyang Tian et al. (2025). “Context Length Alone Hurts LLM Performance Despite Perfect Retrieval.” Findings of EMNLP 2025. Link
  • Minglai Yang, Ethan Huang, Liang Zhang, Mihai Surdeanu, William Yang Wang, Liangming Pan (2025). “How Is LLM Reasoning Distracted by Irrelevant Context?” EMNLP 2025 Main Conference. Link
  • Uswat Yusuf, Genevieve Caumartin, Diego Elias Costa (2025). “Beyond More Context: How Granularity and Order Drive Code Completion Quality.” ASE 2025. Link
  • Weili Cao, Xunjian Yin, Bhuwan Dhingra, Shuyan Zhou (2026). “Coding Agents are Effective Long-Context Processors.” arXiv preprint. Link
  • Han Li, Letian Zhu, Bohan Zhang et al. (2026). “ContextBench: A Benchmark for Context Retrieval in Coding Agents.” arXiv preprint. Link
  • Kishan Maharaj et al. (2026). “Robustness and Reasoning Fidelity of Large Language Models in Long-Context Code Question Answering.” arXiv preprint. Link
  • Carlos E. Jimenez, John Yang, Alexander Wettig, Shunyu Yao, Kexin Pei, Ofir Press, Karthik R. Narasimhan (2024). “SWE-bench: Can Language Models Resolve Real-World GitHub Issues?” ICLR 2024 (Oral). Link
  • Corrado Bohm, Giuseppe Jacopini (1966). “Flow Diagrams, Turing Machines, and Languages with Only Two Formation Rules.” Communications of the ACM, vol. 9, no. 5. Link
  • David L. Parnas (1972). “On the Criteria to Be Used in Decomposing Systems into Modules.” Communications of the ACM, vol. 15, no. 12. Link

Articulo relacionado: Ratchet Pattern — Como hacer que un agente termine el trabajo — El patron detras de filefunc. Ejecucion unidireccional basada en Verifier.

Articulo relacionado: El IQ del modelo importa menos que la topologia de feedback — Por que la estructura de feedback determina los resultados mas que el rendimiento del modelo.

Registro de cambios

  • 2026-03-16: Versión inicial