2026-06-28 retrospectiva
Hoje deixei o trabalho de coletar Markdown para JSONL com Qwen em pausa e pensei em como buscar e extrair esses JSONL quando forem inseridos no banco de dados.
O programa de depuração de AST que criamos extrai blocos de código de projetos Godot. Com base nesses blocos, era necessário definir uma estratégia para buscar nos JSONL docs_chunks, api_mapping e label_prototypes que estavam no banco. Assim, documentamos estratégias de A a F e, no momento, adotamos a estratégia F.
Ainda estamos coletando Markdown para JSONL, então ainda não é possível inserir no banco e testar a busca com o retriever imediatamente. Por isso, hoje criei uma lista de 50 itens de checklist e pedi ao Qwen que gerasse um código Godot aleatório. Também criei JSONL correspondentes e não correspondentes, e verifiquei como o Qwen julgava quando enviávamos jsonl + prompt + chunk. Mesmo testando apenas 5 itens, percebi que essa tarefa exige mais esforço do que eu imaginava.
Plano de teste de 50 itens e a realidade
Inicialmente eu pretendia testar 50 funcionalidades do Godot hoje.
Mas, na prática, a realidade foi diferente. Primeiro compilei uma lista de 50 funcionalidades que costumam aparecer em Godot 3 como funções ou pequenos blocos de código, e organizei essa lista em um documento. Também preparei um modelo de prompt para verificar se o Qwen responde “sim” ou “não” com o devido pareamento de evidências ao receber jsonl + prompt + chunk.
Pensei que poderia criar e validar um por um. Contudo, para testar uma única funcionalidade era necessário gerar muitos JSONL.
Era preciso observar as três tabelas docs_chunks, api_mapping e label_prototypes, e para cada tabela criar JSONL relevantes e JSONL irrelevantes. Além disso, havia que separar casos em que a sintaxe era a mesma entre Godot 3 e Godot 4 e casos em que mudava entre versões.
Se a sintaxe fosse comum, bastava um único código para gerar JSONL de sucesso e de falha nas três tabelas. Caso contrário, era preciso criar códigos tanto para Godot 3 quanto para Godot 4. E, ao inserir JSONL criado para Godot 3 no código Godot 3, depois no código Godot 4, e vice‑versa, era necessário comparar os resultados.
No fim, hoje testei apenas cerca de 5 dos 50 itens. É muito menos do que o planejado, mas talvez seja melhor parar por aqui. Se eu tivesse tentado inserir manualmente todos os 50 e percebido que os critérios eram ambíguos, teria me enredado ainda mais.
Sintaxe comum vs. versão específica
Ao testar hoje, percebi que separar Godot 3 e Godot 4 em duas categorias distintas é mais difícil do que parece.
Algumas funcionalidades têm sintaxe quase idêntica em ambas as versões. Nesse caso, forçar a classificação como “exclusivo de Godot 3” ou “exclusivo de Godot 4” seria estranho. Se for sintaxe comum, devemos tratá‑la como tal e verificar se os JSONL relevantes e irrelevantes nas tabelas docs_chunks, api_mapping e label_prototypes são corretamente diferenciados.
Por outro lado, funcionalidades que mudam entre versões são mais complexas. Um JSONL criado para Godot 3 pode gerar “sim” também em código Godot 4, e vice‑versa, devido a alguns campos. Especialmente JSONL de migração, que contém tanto source quanto target, podem gerar resultados instáveis se baseados apenas em correspondência de strings.
Portanto, a partir de agora precisamos registrar separadamente “qual versão foi usada para criar o JSONL” e “qual versão do código está sendo avaliada”. Mesmo um “sim” precisa ser classificado como “sim por sintaxe comum” ou “sim ambíguo por mistura de source/target”.
É necessário registrar a fórmula F1-score
Se anotarmos apenas “sucesso” ou “falha”, será difícil identificar padrões depois.
A ideia que tive hoje não é calcular o F1‑score imediatamente, mas guardar o julgamento bruto para que, mais tarde, possamos analisar como precision e recall. Por exemplo, registrar quando deveria ter saído “sim” mas saiu “não”, quando deveria ter saído “não” mas saiu “sim”, quando a sintaxe comum gera “sim” nos dois lados, ou quando um JSONL de migração gera um “sim” ambíguo.
Acumulando esses registros, será mais fácil descobrir se o problema está no prompt, nos critérios de geração do JSONL ou no design dos campos das tabelas. Se continuarmos anotando tudo manualmente e de forma vaga, será complicado rastrear a origem de respostas inesperadas.
Mesmo testando apenas 5 itens hoje, já notei vários pontos ambíguos. A partir do sexto teste, talvez seja melhor ajustar a forma de registro e a estratégia de prompting antes de seguir com a estratégia de teste original.
Limitações dos testes manuais
Copiar prompts, colar blocos de código, inserir JSONL um a um e registrar as respostas do Qwen é extremamente ineficiente.
Fazer os primeiros manualmente ajudou a definir um padrão. Na prática, percebi que cada funcionalidade exige mais JSONL do que eu imaginava, que precisamos separar sintaxe comum de sintaxe específica de versão e que “sim” e “não” podem mudar de significado conforme o contexto.
Repetir esse processo para os 50 itens não é viável. Inserções manuais geram erros e dificultam a comparação posterior dos resultados.
Por isso, comecei a pensar em criar uma ferramenta de depuração: um interface onde se possa inserir o bloco de código, o tipo de tabela, a versão de geração do JSONL, a versão do código de teste, a resposta esperada e a resposta real, tudo em uma única tela, e que registre automaticamente as chamadas ao Qwen. Assim como visualizamos o fluxo AST → Retriever na web, seria ótimo ter um GUI ou página de depuração para repetir testes de pareamento de JSONL.
Reflexões sobre a geração de dados de teste para o chatbot Qwen
Hoje reflito sobre como criar dados de teste arbitrários usando o chatbot Qwen.
Eu queria um pequeno conjunto demo que pudesse “abalancar” o método de validação. Por exemplo, pedir ao Qwen que gere um bloco de código Godot 3, um bloco Godot 4 e JSONL relevantes e irrelevantes nas tabelas docs_chunks, api_mapping e label_prototypes.
O problema é que, se simplesmente pedirmos “crie JSONL correto e JSONL incorreto”, o resultado pode ficar muito misturado. Dependendo se a sintaxe é comum, exclusiva de Godot 3, exclusiva de Godot 4 ou envolve migração source/target, o “sim” ou “não” muda. Portanto, ao gerar dados aleatórios, devemos sempre especificar a versão de referência, a versão do código de teste, o tipo de tabela e a resposta esperada.
A lição de hoje é que precisamos definir com mais precisão tanto a forma de gerar dados de teste quanto o prompt usado ao Qwen, para que possamos distinguir se o chatbot está apenas “conectando” informações a partir do seu conhecimento ou realmente avaliando as evidências presentes nos JSONL.
Conclusão de hoje
Hoje não foi tanto um dia de testar uma grande quantidade, mas sim um dia em que confirmamos que a estratégia de busca Retriever e o experimento de correspondência JSONL baseado no chatbot Qwen exigem mais esforço do que esperávamos.
Inicialmente pensei que conseguiria fazer todos os 50 testes. No entanto, percebi que mesmo com apenas 5 testes já surgiam muitos problemas. Às vezes, o Godot 3 e o Godot 4 divergem completamente, mas há sintaxe comum, e casos como o JSONL de migração, onde source e target aparecem juntos, podem tornar a avaliação instável.
Portanto, o que precisamos agora não é simplesmente aumentar o número de testes, mas sim uma estrutura que registre adequadamente os resultados dos testes. É necessário anotar Versão de referência para geração do JSONL, Versão do código de verificação, Tipo de tabela, Resposta esperada, Resposta real e Motivo da ambiguidade. Assim, ao concluir os 50 testes, não será apenas uma impressão superficial, mas algo que pode ser analisado como padrão.
Comecei pensando que poderia simplesmente criar dados aleatórios e testar sem pensar muito, mas acabei percebendo a necessidade de gerar dados de teste com o chatbot Qwen, definir estratégias de prompt e até mesmo a necessidade de ferramentas de depuração que são chamadas automaticamente. A partir de amanhã, a partir do sexto teste, devo ajustar um pouco os critérios e primeiro encontrar maneiras de reduzir o fluxo de repetições manuais.