I migliori LLM per OpenCode - Testati in locale
Test OpenCode LLM — statistiche su programmazione e accuratezza
Ho testato come OpenCode funziona con diversi LLM ospitati localmente su Ollama e, per confronto, ho aggiunto alcuni modelli gratuiti da OpenCode Zen.
OpenCode è uno degli strumenti più promettenti nell’ecosistema degli strumenti per sviluppatori AI attuale.

TL;DR - Migliori LLM per OpenCode
Vincitore chiaro per l’uso locale: Qwen 3.5 27b Q3_XXS su llama.cpp
Il modello da 27b con quantizzazione IQ3_XXS ha consegnato un progetto Go completo e funzionante con tutti gli 8 test unitari superati, un README completo e una velocità di 34 token/secondo sulla mia configurazione con 16GB di VRAM (CPU+GPU misti). Cinque stelle, senza riserve. Questo è il mio modello di riferimento per le sessioni locali OpenCode.
Qwen 3.5 35b su llama.cpp — veloce per la programmazione, ma valida tutto
Il modello 35b è eccellente per compiti di programmazione agenziale rapidi, ma i miei test sulla mappa di migrazione hanno evidenziato un grave problema di affidabilità. In due esecuzioni con quantizzazione IQ3_S ha prodotto un tasso di incongruenza degli slug tra il 63% e il 73%, mentre nella quantizzazione IQ4_XS ha addirittura dimenticato di includere gli slug delle pagine, generando percorsi di categoria che avrebbero mappato 8 pagine diverse sullo stesso URL. La qualità del codice per il task IndexNow è stata genuinamente buona, quindi questo modello merita di essere usato, ma non fidarti mai del suo output su compiti strutturati e basati su regole senza verificarlo. La validazione non è opzionale.
Sorprendentemente buono: Bigpicle (da OpenCode Zen)
Il modello più veloce a completare il task — 1 minuto e 17 secondi. Più importante, è stato l’unico modello che ha fatto una pausa prima di programmare per cercare effettivamente le specifiche del protocollo IndexNow utilizzando Exa Code Search. Ha trovato tutti gli endpoint corretti al primo tentativo. Se hai accesso a OpenCode Zen, questo modello supera le aspettative per le sue dimensioni.
Buono, ma solo con “pensiero” elevato: GPT-OSS 20b
In modalità predefinita GPT-OSS 20b fallisce: incontra chiamate WebFetch che portano a vicoli ciechi e si ferma. Passando alla modalità “pensiero” elevato, diventa un assistente di programmazione genuinamente capace: analisi completa dei flag, logica di batching corretta, test unitari superati, tutto velocemente. Tieni questo a mente prima di scartarlo. GPT-OSS 20b ha fallito nei compiti strutturati anche in modalità “pensiero” elevato.
Da evitare per la programmazione agenziale: GPT-OSS 20b (predefinito), Qwen 3 14b, devstral-small-2:24b
Questi erano i miei preferiti per velocità nelle chat e nei task di generazione. Ma in modalità agenziale hanno tutti problemi reali. Qwen 3 14b allucina documentazione invece di ammettere di non trovare qualcosa. GPT-OSS 20b (predefinito) si blocca quando WebFetch fallisce. Devstral si confonde con operazioni di base sui file. Per OpenCode in particolare, la qualità nel seguire le istruzioni e nel chiamare gli strumenti è molto più importante della velocità bruta.
A proposito di questo test
Ho assegnato a ogni modello in esecuzione su opencode due task/prompt:
Crea per me un tool CLI in Go che chiami gli endpoint indexnow di Bing e di altri motori di ricerca per notificare i cambiamenti sul mio sito.- Prepara una mappa di migrazione del sito.
Sai cos’è il protocollo Indexnow, vero?
Per il secondo task, ho un piano per migrare alcuni vecchi post su questo sito dal formato URL di blogging (ad esempio https://www.glukhov.org/post/2024/10/digital-detox/) verso cluster tematici (come l’URL di questo articolo: https://www.glukhov.org/ai-devtools/opencode/llms-comparison/). Ho quindi chiesto a ogni LLM su OpenCode di preparare una mappa di migrazione per me, secondo la mia strategia.
Ero in esecuzione la maggior parte dei LLM su Ollama ospitato localmente, e alcuni altri su llama.cpp ospitato localmente. Bigpicle e altri modelli linguistici molto grandi provenivano da OpenCode Zen.
Risultati di ogni modello
qwen3.5:9b
Fallimento completo sul primo task. Il modello ha seguito il suo processo di pensiero — identificando correttamente i servizi rilevanti (Google Sitemap, Bing Webmaster, Baidu IndexNow, Yandex) — ma non ha mai chiamato effettivamente alcuno strumento. Ha prodotto un riepilogo “Build” senza toccare un singolo file. Nessuna chiamata a strumenti.
qwen3.5:9b-q8_0
Un passo avanti rispetto alla quantizzazione predefinita: ha almeno creato un go.mod e un main.go. Ma poi si è subito bloccato, ha ammesso di dover aggiungere import mancanti, ha provato a riscrivere l’intero file usando un heredoc shell — ed è fallito. Il tempo di costruzione è stato di 1m 27s per qualcosa che non funzionava.
Qwen 3 14b
Allucinazione classica sotto pressione. Ha provato a recuperare la documentazione di IndexNow tre volte di fila, ottenendo ogni volta un 404 da un URL sbagliato (github.com/Bing/search-indexnow). Invece di ammettere di non trovare nulla, ha fabbricato una risposta con un tono sicuro — endpoint API sbagliato, metodo di autenticazione sbagliato. Quando l’ho spinto a cercare di nuovo, ha prodotto una seconda risposta fabbricata che puntava a un altro URL che restituisce anche lui 404. Le informazioni riportate erano errate. Questo è il tipo di fallimento che voglio evitare più di ogni altro.
GPT-OSS 20b
Almeno il comportamento è stato onesto e metodico. Ha provato una lunga catena di chiamate WebFetch — indexnow.org, vari repository GitHub, le pagine stesse di Bing — e ha incontrato 404 o blocchi Cloudflare su quasi tutto. Ha documentato ogni fallimento in modo trasparente. Alla fine, non è ancora riuscito a raccogliere informazioni sufficienti per costruire uno strumento funzionante, ma a differenza di Qwen 3 14b, non ha inventato nulla. Non è riuscito a spingersi oltre.
GPT-OSS 20b (pensiero elevato)
Una storia significativamente diversa rispetto alla modalità predefinita. Con il “pensiero” elevato abilitato, il modello si è ripreso dagli stessi recuperi in vicolo cieco ed è riuscito a costruire uno strumento completo e funzionante — con analisi dei flag corretta (--file, --host, --key, --engines, --batch, --verbose), GET per URL singoli e POST batch per multipli, secondo le specifiche di IndexNow.
Quando ho chiesto la documentazione e i test unitari, li ha forniti entrambi. I test sono passati:
=== RUN TestReadURLsFile
--- PASS: TestReadURLsFile (0.00s)
=== RUN TestReadURLsNoProtocol
--- PASS: TestReadURLsNoProtocol (0.00s)
ok indexnow-cli 0.002s
Velocissimo, anche: costruzione iniziale in 22,5s. Il “pensiero” elevato rende gpt-oss:20b effettivamente utilizzabile.
qwen3-coder:30b
Il fallimento più interessante. Ha effettivamente compilato ed eseguito lo strumento contro endpoint reali, ha visto errori API reali da Bing, Google e Yandex, e ha iniziato a correggerli:
Errore nella notifica a Bing: ricevuto codice di stato 400 ... "Il campo urlList è richiesto."
Errore nella notifica a Google: ricevuto codice di stato 404 ...
Errore nella notifica a Yandex: ricevuto codice di stato 422 ... "L'elenco URL deve essere un array"
Questo è un buon istinto. Il problema: stava girando al 720% di CPU e solo al 7% di GPU — estremamente inefficiente per un modello da 22 GB. Ha impiegato 11m 39s e l’output finale era ancora “non proprio quello che ci si aspettavano”. Ha anche creato un README.md, che è un bel tocco. Non è un modello cattivo, ma è molto lento sulla mia configurazione e non ha colto perfettamente il formato del protocollo IndexNow.
qwen3.5:35b (Ollama)
Risultati solidi ma lenti. Ha creato un progetto Go corretto, ha scritto i test e tutti sono passati:
=== RUN TestHashIndexNowPublicKey/non-empty_key
--- PASS
=== RUN TestGetPublicKeyName/standard_root
--- PASS
=== RUN TestGetPublicKeyName/custom_root
--- PASS
Il rovescio della medaglia: tempo di costruzione di 19m 11s. Per un modello da 27 GB che gira con una ripartizione CPU/GPU del 45%/55%, è troppo lento per un uso interattivo. La qualità c’è, ma la latenza uccide il flusso di lavoro.
Bigpicle (big-pickle)
Il performer in assoluto per il primo task. Prima di scrivere una singola riga di codice, ha usato Exa Code Search per ricercare effettivamente il protocollo IndexNow:
◇ Exa Code Search "Endpoint API protocollo IndexNow come notificare i motori di ricerca"
E ha trovato gli endpoint corretti:
- Globale:
https://api.indexnow.org/indexnow - Bing:
https://www.bing.com/indexnow - Yandex:
https://webmaster.yandex.com/indexnow - Yep:
https://indexnow.yep.com/indexnow - Amazon:
https://indexnow.amazonbot.amazon/indexnow
Ha risolto pulitamente il problema di importazione di cobra (go mod tidy) e lo strumento è stato completato in 1m 17s. La risposta di limitazione della frequenza che ha ricevuto da Bing durante i test era effettivamente un comportamento atteso per una chiave di test invalida — il modello ha correttamente identificato questo come “lo strumento sta funzionando”. Impressionante.
devstral-small-2:24b
Si è confuso a un livello base: ha provato a scrivere comandi shell (go mod init indexnowcli, go mod tidy) direttamente nel file go.mod, scatenando errori di parsing. Qualche modo è riuscito comunque a costruire un binario (7,9M), ma il CLI risultante era troppo semplice — solo indexnowcli <url> <key> senza gestione dei flag, senza supporto multi-motore, niente. Ha impiegato 2m 59s + 1m 28s per ottenere uno strumento che non era davvero utile.
qwen3.5:27b (llama.cpp, quantizzazione IQ3_XXS)
Questo è quello che mi ha impressionato di più tra tutti i runner locali. Eseguito come Qwen3.5-27B-UD-IQ3_XXS.gguf su llama.cpp (principalmente CPU), ha creato uno strumento completo con copertura completa dei test — tutti gli 8 test superati — e un README corretto con istruzioni di installazione e spiegazione del protocollo:
PASS indexnow 0.003s
Motori supportati: Bing, Yandex, Mojeek, Search.io. Tempo di costruzione: 1m 12s per lo strumento, 1m 27s per test e documentazione. Velocità: 34 token/secondo. Qualità: 5 stelle. Risultato incredibile per un modello quantizzato che gira su CPU+GPU.
qwen3.5:35b (llama.cpp, quantizzazione IQ3_S)
Eseguito come Qwen3.5-35B-A3B-UD-IQ3_S.gguf su llama.cpp. Le mie note qui sono brevi: “eccellente!” — che dice tutto. Il modello più grande allo stesso livello di quantizzazione ha fornito risultati almeno altrettanto buoni della variante da 27b, se non migliori.
Risultati della mappa di migrazione
Per il secondo task ho eseguito un batch separato — 7 modelli, tutti con le stesse istruzioni, struttura del sito e elenco di pagine. Il vincolo era esplicito: lo slug (l’ultimo segmento del percorso) deve rimanere invariato. Ad esempio, /post/2024/04/reinstall-linux/ deve diventare /.../reinstall-linux/, non qualcos’altro.
Ho misurato quanti disallineamenti degli slug ha prodotto ogni modello — casi in cui lo slug di destinazione generato differiva dallo slug di origine.
| Modello | Righe | Disallineamenti slug | Tasso di errore |
|---|---|---|---|
| minimax-m2.5-free | 80 | 4 | 5.0% |
| Nemotron 3 | 78 | 4 | 5.1% |
| Qwen 3.5 27b Q3_XXS (llama.cpp) | 80 | 4 | 5.0% |
| Qwen 3.5 27b Q3_M (llama.cpp) | 81 | 6 | 7.4% |
| Bigpicle | 81 | 9 | 11.1% |
| mimo-v2-flash-free | 80 | 42 | 52.5% |
| Qwen 3.5 35b IQ3_S -seconda esecuzione (llama.cpp) | 81 | 51 | 63.0% |
| Qwen 3.5 35b IQ4_XS (llama.cpp) | 80 | 79 | 98.8% |
Una cosa che tutti e 7 i modelli hanno fatto in modo identico: gli URL nel formato vecchio del 2022 avevano un prefisso del mese incorporato nello slug (ad esempio, /post/2022/06-git-cheatsheet/ → slug 06-git-cheatsheet). Ogni modello ha rimosso quel prefisso e ha usato git-cheatsheet come nuovo slug. Questo rappresenta 4 disallineamenti coerenti nei tre migliori modelli — quindi il loro baseline è di 4 errori ciascuno, non zero.
La vera divergenza inizia sopra quel baseline. minimax-m2.5-free, Nemotron 3 e Qwen 3.5 27b Q3_XXS hanno violato la regola degli slug solo su quei 4 percorsi legacy — niente altro. Qwen 3.5 27b Q3_M ha aggiunto 2 errori (rinominando lo slug dell’articolo cognee e mettendo in minuscolo Base64). Bigpicle ha aggiunto altri 5 errori oltre ai 4, principalmente accorciando gli slug lunghi.
Gli outlier appartengono a una categoria diversa. Qwen 3.5 35b IQ3_S ha costantemente riscritto gli slug dai titoli delle pagine invece di preservare l’origine (ad esempio, executable-as-a-service-in-linux → run-any-executable-as-a-service-in-linux, file-managers-for-linux-ubuntu → context-menu-in-file-managers-for-ubuntu-24). La seconda esecuzione è stata leggermente migliore (51 contro 59) ma ha mostrato lo stesso comportamento. Ha anche allucinato un percorso di origine: ha cambiato silenziosamente comparing-go-orms-gorm-ent-bun-sqlc in comparing-go-orms-gorm-ent-bun-sql (rimuovendo la c), quindi entrambi i lati di quella riga concordavano tra loro — ma erano entrambi sbagliati. mimov2 era altrettanto aggressivo nell’accorciare: gnome-boxes-linux-virtual-machines-manager → gnome-boxes, vm-manager-multipass-cheatsheet → multipass.
La quantizzazione IQ4_XS del 35b è una categoria di fallimento completamente diversa: 98.8% di disallineamenti degli slug — ma il problema non sono gli slug sbagliati, è che il modello ha dimenticato di includere gli slug del tutto. Invece di /new-section/page-slug/, ha prodotto percorsi di categoria come /developer-tools/terminals-shell/ e /rag/architecture/. Otto pagine di origine sono finite mappate su /developer-tools/terminals-shell/ — tutte puntando allo stesso URL, cosa che sarebbe catastrofica se utilizzata. /developer-tools/ da solo ha raccolto cinque pagine separate. L’output è completamente inutilizzabile.
Per questo task, il modello quantizzato più piccolo Qwen 3.5 27b Q3_XXS ha igualato i migliori performer — mentre due quantizzazioni del 35b hanno fallito gravemente, ognuna a modo suo.
Conclusione
Sono felice di eseguire sia Qwen 3.5 35b che Qwen 3.5 27b localmente su llama.cpp con pesi quantizzati — i vincoli hardware sono reali (16GB di VRAM significa quantizzazioni IQ3/IQ4), ma il flusso di lavoro è solido.
Il 27b Q3_XXS è il guidatore quotidiano affidabile. Segue le istruzioni con precisione, produce output completi ed è abbastanza veloce per un uso interattivo. Nel task della mappa di migrazione ha igualato i migliori modelli cloud.
Il 35b è capace ma imprevedibile nei compiti strutturati. Per la programmazione a fini aperti — “scrivimi uno strumento”, “costruisci questo” — si comporta bene. Ma quando il task ha regole rigide (come “lo slug deve rimanere invariato”), allucina liberamente in tutte le quantizzazioni che ho testato: riscrivendo gli slug dai titoli, eliminando gli slug del tutto, addirittura modificando silenziosamente i percorsi di origine per far sembrare il suo output sbagliato coerente con se stesso. Se usi il 35b per qualsiasi cosa che produca un output strutturato che intendi usare direttamente, inserisci un passaggio di validazione nel tuo flusso di lavoro. Non dare per scontato che l’output sia corretto solo perché sembra plausibile.
Se sei curioso della velocità a cui questi LLM si comportano, dai un’occhiata a Migliori LLM per Ollama su GPU 16GB VRAM.