{"id":757,"date":"2026-10-03T18:33:57","date_gmt":"2026-10-03T21:33:57","guid":{"rendered":"https:\/\/yellowkode.com\/blog\/como-ldraw-nova-agente-ia-modelos-lego-ldraw\/"},"modified":"2026-10-03T18:33:57","modified_gmt":"2026-10-03T21:33:57","slug":"como-ldraw-nova-agente-ia-modelos-lego-ldraw","status":"publish","type":"post","link":"https:\/\/yellowkode.com\/blog\/como-ldraw-nova-agente-ia-modelos-lego-ldraw\/","title":{"rendered":"Como o ldraw-nova faz um agente de IA desenhar modelos LEGO em linguagem LDraw"},"content":{"rendered":"<p>No dia 2 de outubro de 2026, <strong>anteloc<\/strong> publicou no GitHub o projeto <strong>ldraw-nova<\/strong>, apresentado como Show HN sob o t\u00edtulo <em>Made an open-source Lego AI generator<\/em>. O release 0.6.0 do ldraw-nova adiciona uma interface web em Docker que permite a agentes LLM produzir modelos LEGO constru\u00edveis em formato LDraw, com sa\u00eddas 3D, VR e Blender. O reposit\u00f3rio est\u00e1 sob licen\u00e7a AGPL-3.0 e descreve o projeto como ferramental de agente para constru\u00e7\u00e3o generativa de modelos LEGO, usando Astra e Opus 5.5, com Jev por tr\u00e1s.<\/p>\n<p>Interessa aqui n\u00e3o o fato de ter LEGO envolvido, mas a arquitetura. \u00c9 uma das poucas tentativas p\u00fablicas de fazer um agente projetar um objeto f\u00edsico passo a passo, usando uma linguagem textual como alvo intermedi\u00e1rio. Vou destrinchar como esse pipeline funciona.<\/p>\n<h2>O que \u00e9 LDraw e por que serve de alvo para LLM<\/h2>\n<p>LDraw \u00e9 um formato de arquivo texto para descrever modelos LEGO. Descrever pe\u00e7as e modelos LEGO em um ambiente virtual \u00e9 um desafio, e em 1995 James Jessiman desenvolveu esse sistema com o programa e formato LDraw. Um arquivo LDraw consiste em um comando por linha, e cada linha de refer\u00eancia de pe\u00e7a traz um padr\u00e3o bem direto. Pelo exemplo cl\u00e1ssico da documenta\u00e7\u00e3o da comunidade: o primeiro n\u00famero \u00e9 o tipo de linha (refer\u00eancia), o segundo \u00e9 a cor, os tr\u00eas seguintes s\u00e3o a posi\u00e7\u00e3o, os nove seguintes s\u00e3o a matriz 3&#215;3 de orienta\u00e7\u00e3o\/escala, e o nome .dat ao final \u00e9 a pe\u00e7a a renderizar naquela posi\u00e7\u00e3o e orienta\u00e7\u00e3o.<\/p>\n<p>Ou seja, cada linha \u00e9 uma instru\u00e7\u00e3o de montagem: cor, posi\u00e7\u00e3o no espa\u00e7o, rota\u00e7\u00e3o, qual pe\u00e7a. \u00c9 um formato que o pr\u00f3prio autor do ldraw-nova descreve, no post do Hacker News, como uma linguagem assembly, de baixo n\u00edvel, que descreve como juntar pe\u00e7as LEGO em modelos, uma instru\u00e7\u00e3o de posicionamento por vez. E para modelos maiores existe o MPD, que empacota v\u00e1rios submodelos num s\u00f3 arquivo: um arquivo MPD \u00e9 composto por blocos de c\u00f3digo LDraw separados por declara\u00e7\u00f5es 0 FILE ou 0 !DATA, cada bloco \u00e9 considerado um arquivo separado e pode ser referenciado pelos outros.<\/p>\n<p>Esse formato \u00e9 bom alvo para LLM por tr\u00eas motivos pr\u00e1ticos: \u00e9 texto puro UTF-8, tem gram\u00e1tica m\u00ednima (uma linha, uma pe\u00e7a), e existem ferramentas prontas (LDView, LeoCAD, LDCad) que renderizam o resultado sem ambiguidade. O problema \u00e9 que posicionar pe\u00e7a exige matrizes de rota\u00e7\u00e3o e c\u00e1lculo de coordenadas, e LLM \u00e9 notoriamente ruim em geometria de precis\u00e3o.<\/p>\n<h2>Como o agente contorna a matem\u00e1tica: plano, gerador, modelo<\/h2>\n<p>Aqui est\u00e1 o truque de arquitetura, e \u00e9 o que faz o projeto ser interessante independente do dom\u00ednio LEGO. O agente n\u00e3o escreve LDraw direto. Ele escreve <strong>um programa Python que escreve LDraw<\/strong>.<\/p>\n<p>O README \u00e9 expl\u00edcito sobre a cadeia: o agente produz um <code>plan.json<\/code> que descreve o modelo, submodelos e geometria. Com esse plano, ele gera um script <code>generate.py<\/code>. Esse script, quando executado, produz o arquivo <code>.mpd<\/code> em linguagem LDraw. O pr\u00f3prio autor compara isso a um compilador em etapas:<\/p>\n<pre><code>agente -> plan.json -> generate.py -> model.mpd\n<\/code><\/pre>\n<p>A analogia \u00fatil aqui \u00e9 a de um arquiteto que n\u00e3o sabe desenhar \u00e0 m\u00e3o livre. Em vez de desenhar a planta diretamente, ele escreve instru\u00e7\u00f5es para um estagi\u00e1rio com r\u00e9gua e esquadro: <em>pegue a pe\u00e7a 3001, gire 90 graus em Y, cole no canto superior esquerdo deste subm\u00f3dulo, repita cinco vezes deslocando duas unidades para a direita<\/em>. O arquiteto n\u00e3o precisa calcular as coordenadas finais, s\u00f3 descrever a regra. O estagi\u00e1rio (o script Python) resolve a aritm\u00e9tica sem errar casa decimal. A analogia quebra num ponto importante: o estagi\u00e1rio real teria senso espacial e avisaria se duas pe\u00e7as fossem colidir. O script Python s\u00f3 executa, por isso o ldraw-nova precisa de uma camada extra de verifica\u00e7\u00e3o de colis\u00e3o, que entra depois.<\/p>\n<p>Por que isso funciona melhor que gerar LDraw direto? O autor registra duas conclus\u00f5es no README, derivadas de tr\u00eas tentativas anteriores (ldbuilder-ai, py2bricks, py4bricks): a primeira, que <strong>dar ao agente ferramental para gerar c\u00f3digo Python que produz LDraw contorna a matem\u00e1tica de geometria<\/strong>, porque os modelos v\u00e3o melhor em gerar c\u00f3digo do que em gerar n\u00fameros. A segunda, que <strong>agentes aprendem melhor com c\u00f3digo Python que produz modelos do que com os modelos em si<\/strong>. Em outras palavras: ele troca o alvo de aprendizado de &#8220;sa\u00edda final&#8221; para &#8220;programa que gera a sa\u00edda final&#8221;. \u00c9 a mesma intui\u00e7\u00e3o por tr\u00e1s de program-of-thoughts, aplicada a CAD.<\/p>\n<h3>O loop de execu\u00e7\u00e3o do agente<\/h3>\n<p>O ciclo descrito no README tem passos definidos:<\/p>\n<ol>\n<li>O agente recebe um prompt.<\/li>\n<li>L\u00ea <code>instructions.md<\/code> e os documentos de refer\u00eancia sobre a linguagem LDraw e sobre constru\u00e7\u00e3o de modelos LEGO.<\/li>\n<li>Planeja o modelo: pe\u00e7as necess\u00e1rias, submodelos, est\u00e9tica.<\/li>\n<li>Entra num loop iterativo: renderiza imagens do modelo ou submodelo, inspeciona, ajusta posi\u00e7\u00e3o, volta a renderizar, at\u00e9 considerar que est\u00e1 pronto.<\/li>\n<\/ol>\n<p>O ferramental auxilia em tr\u00eas frentes: busca de pe\u00e7as adequadas e de modelos de exemplo para come\u00e7ar, detec\u00e7\u00e3o de colis\u00f5es e v\u00e3os para checar posicionamento, e renderiza\u00e7\u00e3o headless para o agente ver o que acabou de montar. Esse \u00faltimo ponto \u00e9 o que fecha o loop. Sem renderiza\u00e7\u00e3o e re-leitura por parte do pr\u00f3prio agente, ele estaria compondo \u00e0s cegas.<\/p>\n<h3>Busca sem\u00e2ntica de pe\u00e7as com rerank<\/h3>\n<p>A biblioteca oficial de pe\u00e7as LDraw tem milhares de arquivos .dat. Jogar isso tudo no contexto de um LLM \u00e9 invi\u00e1vel. O ldraw-nova resolve com uma camada de busca. As ferramentas usadas pelos agentes para encontrar pe\u00e7as adequadas e modelos de exemplo tiram proveito do jev-rerank, uma ferramenta de busca sem\u00e2ntica com re-ranking apoiada no modelo Jev System One da TypeSafe. Se o usu\u00e1rio tem uma chave TYPESAFE_API_KEY, o rerank funciona; se n\u00e3o, os agentes caem num fallback de FTS (Full Text Search), que pode render modelos piores.<\/p>\n<p>Na pr\u00e1tica: o agente descreve em linguagem natural o que precisa (&#8220;pe\u00e7a angular de 2&#215;2 para asa de nave&#8221;), a camada sem\u00e2ntica traz os candidatos mais prov\u00e1veis, o rerank reordena, e s\u00f3 os top-K entram no contexto do agente. \u00c9 RAG cl\u00e1ssico aplicado a cat\u00e1logo de pe\u00e7as.<\/p>\n<h2>O que isso significa na pr\u00e1tica<\/h2>\n<p>Para rodar, o fluxo \u00e9 relativamente direto. Precisa de dois reposit\u00f3rios irm\u00e3os: ldraw-nova e ldraw-nova-docker, que traz a configura\u00e7\u00e3o Docker e a web app. Clone os dois na mesma tag (atualmente v0.6.0), build do Docker leva um tempo e consome cerca de 5 GB de disco, e sobe com <code>docker compose up -d<\/code>. A interface responde em <code>https:\/\/localhost:8443<\/code> (self-signed, necess\u00e1rio para VR no Quest 3) ou em <code>http:\/\/localhost:8765<\/code>.<\/p>\n<p>O que sai do pipeline, segundo o README: c\u00f3digo-fonte em LDraw, visualizadores 3D no navegador, intera\u00e7\u00e3o VR no Meta Quest 3, um arquivo glTF (.glb) edit\u00e1vel no Blender com metainforma\u00e7\u00e3o em Custom Properties, e o hist\u00f3rico completo da conversa e do racioc\u00ednio do agente. Esse \u00faltimo item \u00e9 o que mais interessa para quem quer estudar o comportamento: d\u00e1 para auditar cada decis\u00e3o.<\/p>\n<p>Um exemplo de linha LDraw renderizada por um gerador seria assim:<\/p>\n<pre><code># coloca a pe\u00e7a 3001 (brick 2x4) na cor 4 (vermelho),\n# na posi\u00e7\u00e3o x=0, y=-24, z=0, com matriz identidade\n1 4 0 -24 0 1 0 0 0 1 0 0 0 1 3001.dat\n<\/code><\/pre>\n<p>O script Python gerado pelo agente emite dezenas ou centenas dessas linhas, com as coordenadas j\u00e1 resolvidas por la\u00e7os e c\u00e1lculos no pr\u00f3prio Python, n\u00e3o por o LLM ter adivinhado os n\u00fameros.<\/p>\n<p>A ideia de usar o agente como fonte de c\u00f3digo que resolve problemas estruturados tem paralelo em outras \u00e1reas. No StartAtende, meu agente de suporte no WhatsApp, o agente n\u00e3o s\u00f3 responde: ele vira fonte de decis\u00e3o de produto. O ponto comum \u00e9 tratar a sa\u00edda do LLM como insumo para um sistema determin\u00edstico mais embaixo, n\u00e3o como resposta final.<\/p>\n<h2>Onde quebra<\/h2>\n<p>O pr\u00f3prio README \u00e9 honesto sobre as limita\u00e7\u00f5es da vers\u00e3o atual, e vale ler com cuidado. VR no Quest 3 tem problemas de manuseio de modelo e de performance. A gera\u00e7\u00e3o \u00e9 lenta. S\u00f3 modelos caros, de ponta, conseguem produzir modelos grandes e corretos, e o autor lista a adapta\u00e7\u00e3o para modelos menores (Luna, Haiku) como trabalho pendente. Fam\u00edlias inteiras de modelos ainda v\u00e3o mal: naves espaciais geradas n\u00e3o s\u00e3o boas, minifiguras ainda n\u00e3o est\u00e3o bem suportadas, e a constru\u00e7\u00e3o a partir de manuais funciona parcialmente, melhor se as p\u00e1ginas do manual forem passadas como imagens.<\/p>\n<p>Tem um ponto que vi comentado em discuss\u00f5es sobre o reposit\u00f3rio e que o pr\u00f3prio autor sinaliza: o autor ainda n\u00e3o construiu fisicamente um modelo, atualmente s\u00f3 verifica colis\u00e3o, n\u00e3o verifica estabilidade f\u00edsica. Ou seja: o fato do software dizer &#8220;pe\u00e7a encaixa aqui sem colidir&#8221; n\u00e3o significa que o modelo n\u00e3o vai desabar quando montado em pe\u00e7as reais. Valida\u00e7\u00e3o geom\u00e9trica n\u00e3o \u00e9 valida\u00e7\u00e3o estrutural.<\/p>\n<p>Nenhuma m\u00e9trica oficial de velocidade ou par\u00e2metros aparece no release inicial, e os n\u00fameros que circulam em discuss\u00f5es externas n\u00e3o s\u00e3o do autor. Nenhuma velocidade ou contagem de par\u00e2metros oficial aparece no release inicial; relatos iniciais mencionam tempos entre 4 e 12 segundos para modelos simples de 50 a 200 pe\u00e7as, mas tratar isso como benchmark seria exagero: s\u00e3o n\u00fameros de usu\u00e1rios, sem metodologia descrita.<\/p>\n<p>Depend\u00eancia externa importante: a parte interessante da busca de pe\u00e7as depende da API da TypeSafe. Sem a chave, o fallback \u00e9 FTS, que o pr\u00f3prio autor admite poder piorar os modelos. Ent\u00e3o o projeto \u00e9 open-source, mas o caminho feliz exige uma conta de terceiro.<\/p>\n<h2>O que n\u00e3o d\u00e1 para afirmar ainda<\/h2>\n<p>N\u00e3o d\u00e1 para dizer que esse mesmo padr\u00e3o (<em>agente gera gerador em Python que produz artefato final em DSL<\/em>) funciona melhor que gerar o artefato final direto em todos os casos. O autor afirma isso para LDraw a partir de tr\u00eas tentativas pessoais anteriores, n\u00e3o a partir de estudo controlado. \u00c9 uma hip\u00f3tese defens\u00e1vel e intuitiva, mas \u00e9 hip\u00f3tese.<\/p>\n<p>Tamb\u00e9m n\u00e3o d\u00e1 para afirmar quais prompts rendem quais modelos sem rodar. O reposit\u00f3rio lista fam\u00edlias (ve\u00edculos, naves, Technic, m\u00f3dulos), mas o grau de sucesso varia por fam\u00edlia e por modelo, e o pr\u00f3prio autor diz que naves ainda saem ruins.<\/p>\n<p>N\u00e3o encontrei na documenta\u00e7\u00e3o detalhe sobre quais partes exatas do racioc\u00ednio ficam no agente e quais ficam no c\u00f3digo Python gerado. O README descreve o fluxo em alto n\u00edvel. Para entender quem faz o qu\u00ea, \u00e9 preciso ler o <code>instructions.md<\/code> e o conte\u00fado da pasta <code>prompts\/<\/code>.<\/p>\n<h2>Como testar isso voc\u00ea mesmo<\/h2>\n<p>Caminho m\u00ednimo para experimentar sem compromisso:<\/p>\n<ol>\n<li>Clone os dois reposit\u00f3rios na mesma tag: <code>git clone --branch v0.6.0 https:\/\/github.com\/anteloc\/ldraw-nova.git<\/code> e o <code>ldraw-nova-docker<\/code> ao lado.<\/li>\n<li>Reserve 5 GB de disco e rode <code>docker compose build<\/code> dentro de <code>ldraw-nova-docker<\/code>. \u00c9 demorado, deixe rodando.<\/li>\n<li>Suba com <code>docker compose up -d<\/code> e abra <code>http:\/\/localhost:8765<\/code> no navegador.<\/li>\n<li>Antes de qualquer prompt, abra a pasta <code>examples\/<\/code> do reposit\u00f3rio principal e leia um dos arquivos <code>.plan.json<\/code> junto com o <code>generate.py<\/code> e o <code>.mpd<\/code> correspondentes. \u00c9 o jeito mais r\u00e1pido de entender a cadeia plano-gerador-modelo em concreto.<\/li>\n<li>Experimente um prompt simples (um objeto pequeno, uma d\u00fazia de pe\u00e7as) antes de pedir algo grande. Se tiver chave TypeSafe, configure em Settings; se n\u00e3o, aceite que o fallback FTS pode piorar o resultado.<\/li>\n<li>Depois de gerar, abra o <code>.mpd<\/code> no LeoCAD ou LDView para inspecionar. Compare a lista de pe\u00e7as que o agente planejou com o que ele realmente colocou. \u00c9 a\u00ed que se v\u00ea onde a valida\u00e7\u00e3o de colis\u00e3o pegou e onde deixou passar.<\/li>\n<\/ol>\n<p>O que vale levar deste projeto, independente de LEGO interessar ou n\u00e3o: usar o LLM para escrever o <em>gerador<\/em> em vez do <em>artefato<\/em> \u00e9 um padr\u00e3o replic\u00e1vel em qualquer dom\u00ednio onde o resultado final exige precis\u00e3o num\u00e9rica e o processo tem regras bem definidas. CAD \u00e9 um caso. Infraestrutura declarativa \u00e9 outro. Vale observar como o ldraw-nova amadurece esse padr\u00e3o.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Como o ldraw-nova usa agentes de IA para gerar modelos LEGO: do prompt ao arquivo LDraw, passando por plano JSON e gerador Python.<\/p>\n","protected":false},"author":2,"featured_media":756,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-757","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/posts\/757","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/comments?post=757"}],"version-history":[{"count":0,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/posts\/757\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/media\/756"}],"wp:attachment":[{"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/media?parent=757"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/categories?post=757"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/yellowkode.com\/blog\/wp-json\/wp\/v2\/tags?post=757"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}