2026-06-28 Reflexión
Hoy dejé corriendo el proceso de recopilar Markdown a JSONL con Qwen y pensé en cómo buscar y extraer esos JSONL cuando los insertara más tarde en la base de datos.
El programa de depuración de AST que habíamos creado extrae fragmentos de código de un proyecto Godot. Con base en esos fragmentos, necesitábamos una estrategia para buscar y recuperar los JSONL de docs_chunks, api_mapping, label_prototypes que están en la base de datos. Por eso dividimos la estrategia de búsqueda de la A a la F, la documentamos y, por ahora, hemos adoptado la estrategia F.
Actualmente todavía estamos recopilando Markdown a JSONL, por lo que es difícil probar inmediatamente la inserción en la base de datos y la búsqueda con un recuperador. Así que hoy creé una lista de 50 elementos de verificación y le pedí a Qwen que generara código Godot aleatorio. También generé JSONL que coincidían y que no coincidían con ese código, y probé cómo Qwen los juzgaba cuando se le enviaban jsonl + prompt + chunk. Con solo cinco pruebas pude notar que esta tarea requiere más trabajo del que imaginaba.
Plan de pruebas de 50 ítems y la realidad
Inicialmente pensé en probar las 50 funciones de Godot hoy.
Pero la práctica demostró que la teoría y la realidad difieren. Primero hice una lista de 50 funciones que suelen aparecer en Godot 3 como unidades de función o pequeños bloques de código, y la organicé en un documento. También preparé una plantilla de prompt para verificar, al enviar jsonl + prompt + chunk, si Qwen juzgaba correctamente la coincidencia con “sí” o “no”.
Al principio parecía que bastaría con crear y verificar cada una por separado. Sin embargo, para probar una función había que generar muchos JSONL.
Se necesitaba revisar las tres tablas docs_chunks, api_mapping, label_prototypes, y para cada tabla crear JSONL relevantes y JSONL irrelevantes. Además, había que distinguir entre casos donde la sintaxis es la misma en Godot 3 y Godot 4 y casos donde varía según la versión.
Si la sintaxis es común, se puede usar un solo código como referencia y colocar los JSONL de éxito y de fracaso de las tres tablas para validar. En cambio, si la sintaxis no es común, hay que crear tanto código de Godot 3 como de Godot 4. Luego, al insertar los JSONL creados para Godot 3 en código de Godot 3, en código de Godot 4, y viceversa, se deben comparar los resultados.
Al final solo probé alrededor de 5 de los 50 ítems. Es mucho menos que lo planeado, pero quizá fue sabio detenerse aquí. Si hubiéramos intentado procesar los 50 manualmente, habríamos descubierto que los criterios eran ambiguos y nos habríamos enredado mucho más.
Sintaxis común y criterios por versión
Lo que más resaltó durante las pruebas de hoy fue lo difícil que es dividir simplemente Godot 3 y Godot 4.
Algunas funciones tienen una sintaxis casi idéntica en ambas versiones. En esos casos es absurdo intentar forzar una distinción entre “solo Godot 3” o “solo Godot 4” basándose en un único fragmento de código. Si la sintaxis es común, se debe tratar como tal y verificar que los JSONL relevantes e irrelevantes de docs_chunks, api_mapping y label_prototypes se separen correctamente.
En cambio, las funciones que difieren entre versiones son más complejas. Un JSONL creado bajo el criterio de Godot 3 puede producir un “sí” incluso con código de Godot 4, y viceversa, a veces por algunos campos específicos. En particular, los JSONL de migración incluyen tanto la fuente como el objetivo, por lo que una simple coincidencia de cadena puede producir resultados inestables.
Por eso, en adelante debemos registrar por separado “qué versión se usó para crear el JSONL” y “qué versión del código se está evaluando”. Incluso un “sí” debe distinguirse entre un “sí” legítimo por sintaxis común y un “sí” ambiguo derivado de una mezcla de cadenas source/target.
Necesitamos registrar en formato F1‑score
Si solo anotamos los resultados como “éxito” o “fracaso”, será difícil observar patrones más adelante.
La idea de hoy no es calcular directamente el F1‑score, sino guardar los resultados crudos de juicio para poder analizarlos después como precision y recall. Por ejemplo, registrar si se obtuvo un “sí” cuando debería haber sido “no”, o viceversa; si en una sintaxis común ambos lados deberían dar “sí”; o si un JSONL de migración produjo un “sí” ambiguo.
Al acumular esta información, podremos later identificar si el problema está en el prompt, en los criterios de generación del JSONL o en el diseño de los campos de cada tabla. Si seguimos anotando de forma manual y desordenada, será mucho más difícil rastrear por qué se obtuvo una respuesta determinada.
Incluso con solo 5 pruebas hoy, ya se observaron varios puntos ambiguos. Por eso, a partir de la sexta prueba, será necesario ajustar primero el método de registro y la estrategia de prompting antes de seguir con la estrategia de pruebas original.
Limitaciones de las pruebas manuales
Copiar prompts, pegar fragmentos de código, insertar JSONL uno por uno y volver a registrar la respuesta de Qwen es extremadamente ineficiente.
Hacer los primeros casos a mano ayudó a establecer criterios. Al hacerlo, descubrí que incluso una sola función requiere muchos JSONL, que hay que separar sintaxis común de sintaxis específica por versión, y que los significados de “sí” y “no” varían según el contexto.
Sin embargo, repetir este proceso para los 50 ítems no es factible. Al introducir datos manualmente es fácil cometer errores y comparar resultados después se vuelve complicado.
Por eso, en el futuro pienso crear una herramienta de depuración que permita ingresar el fragmento de código, el tipo de tabla, la versión usada para generar el JSONL, la versión del código de prueba, la respuesta esperada y la respuesta real en una sola pantalla, y que registre automáticamente los resultados de la llamada a Qwen. Así como antes revisábamos el flujo AST‑Retriever en la web, sería ideal poder repetir las pruebas de coincidencia de JSONL en una GUI o página de depuración.
Reflexiones sobre la generación de datos de prueba para el chatbot Qwen
Lo que reflexioné hoy fue el proceso de crear datos de prueba arbitrarios con el chatbot Qwen.
Lo que quería era un pequeño conjunto de demostración que pudiera poner a prueba el método de validación. Por ejemplo, pedir al chatbot Qwen que genere un fragmento de código de Godot 3, otro de Godot 4, y los JSONL relevantes e irrelevantes que correspondan a los formatos docs_chunks, api_mapping y label_prototypes.
El problema es que si simplemente le pido “genera JSONL correctos e incorrectos”, la respuesta puede quedar demasiado mezclada. Dependiendo de si la sintaxis es común, exclusiva de Godot 3, exclusiva de Godot 4 o involucra migración source‑target, los “sí” y “no” varían. Por eso, al crear datos arbitrarios, también hay que especificar la versión base, la versión del código de prueba, el tipo de tabla y la respuesta esperada.
Lo que aprendí es que debemos definir con mayor precisión tanto la forma de generar datos de prueba arbitrarios como los prompts para el chatbot Qwen. Así podremos verificar si Qwen está simplemente completando con su conocimiento o si está juzgando basándose únicamente en la evidencia textual presente en los JSONL.
Conclusión del día
Hoy no fue tanto un día de probar una gran cantidad, sino más bien un día en que confirmé que la estrategia de búsqueda Retriever y el experimento de emparejamiento JSONL basado en el chatbot Qwen requieren más trabajo de lo que esperaba.
Al principio pensé que podría realizar las 50 pruebas. Sin embargo, con solo 5 ya aparecían suficientes problemas. A veces Godot 3 y Godot 4 divergen completamente, pero también hay sintaxis común, y casos como el JSONL de migración, donde source y target aparecen juntos, hacen que el juicio sea inestable.
Por lo tanto, lo que se necesita ahora no es simplemente aumentar el número de pruebas, sino una estructura que registre adecuadamente los resultados de las pruebas. Hay que anotar la versión de criterio de generación de JSONL, la versión del código de inspección, el tipo de tabla, la respuesta esperada, la respuesta real y la razón de ambigüedad. Así, incluso al completar las 50 pruebas, no será solo una impresión superficial, sino que se podrá observar un patrón.
Hoy comencé pensando que bastaría con crear datos aleatorios y probar sin mayor reflexión, pero al final descubrí la necesidad de generar datos de prueba con el chatbot Qwen, de diseñar una estrategia de prompts y de contar con una herramienta de depuración que se invoque automáticamente. A partir de mañana, a partir de la sexta prueba, cambiaré ligeramente los criterios y buscaré primero una forma de reducir el flujo de repeticiones manuales.