Logo Image

ZigNet: Come ho creato un server MCP per il linguaggio Zig in 1.5 giorni

ยท 12m ยท

Architettura ibrida di ZigNet che combina compilatore Zig e LLM

Lโ€™idea iniziale

Tutto รจ iniziato da una riflessione: โ€œBelle le AI, ma non stanno dietro allo sviluppo cosรฌ rapido di Zigโ€. Gli LLM normali mi davano suggerimenti scadenti, confondevano sintassi vecchie con quelle nuove, inventavano API inesistenti.

Mi sono chiesto: cosa costerebbe farmene una mia?

Le domande che mi frullavano in testa erano:

Dopo un poโ€™ di ricerca, ho realizzato che la soluzione non era necessariamente un LLM gigante che sa tutto di Zig, ma un sistema ibrido:

รˆ qui che entra in gioco il Model Context Protocol (MCP) di Anthropic. MCP mi permetteva di unire questi due mondi: dare a Claude accesso al compilatore Zig reale E a un modello specializzato, tutto in modo trasparente.

Lโ€™esplorazione: Quanto costa davvero un LLM custom?

Prima di buttarmi nel codice, ho fatto i compiti a casa. Ecco cosa ho scoperto:

Costo Hardware

Dimensioni modelli (la sorpresa)

Ho testato vari modelli base:

Llama3.2-3B     โ†’ 2GB quantizzato  โ†’ Veloce ma stupido con Zig
CodeLlama-7B    โ†’ 4GB quantizzato  โ†’ Confonde Zig con Rust
Qwen2.5-7B      โ†’ 4GB quantizzato  โ†’ Ottimo! Capisce giร  Zig decentemente
Mistral-7B      โ†’ 4GB quantizzato  โ†’ Buono ma non eccelle
DeepSeek-33B    โ†’ 16GB quantizzato โ†’ Overkill per il mio use case

La rivelazione: Non serve GPT-4! Un 7B ben addestrato รจ piรน che sufficiente per un dominio specifico come Zig.

Il piano ibrido

Invece di cercare di insegnare TUTTO al modello, ho diviso le responsabilitร :

CompitoSoluzionePerchรฉ
Validazione sintassizig ast-check100% accurato, zero training
Formattazionezig fmtStandard ufficiale, deterministico
DocumentazioneLLM fine-tunedServe creativitร  e contesto
Fix suggerimentiLLM fine-tunedRichiede comprensione semantica
Type checkingzig ast-checkIl compilatore sa meglio

Questo approccio ha ridotto drasticamente i requisiti:

Perchรฉ Zig ha bisogno di ZigNet

Zig รจ un linguaggio giovane e in rapida evoluzione. Le sue caratteristiche uniche come comptime, la gestione degli errori esplicita e i generici lo rendono potente ma anche complesso da analizzare. Gli LLM tradizionali:

ZigNet risolve questi problemi integrando direttamente il compilatore Zig ufficiale.

Lโ€™architettura: Semplice ma efficace

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                 Claude / MCP Client                โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                     โ”‚ MCP Protocol (JSON-RPC)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚            ZigNet MCP Server (TypeScript)          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚              Tool Handlers                   โ”‚  โ”‚
โ”‚  โ”‚  - analyze_zig: Analisi sintattica e tipi    โ”‚  โ”‚
โ”‚  โ”‚  - compile_zig: Formattazione del codice     โ”‚  โ”‚
โ”‚  โ”‚  - get_zig_docs: Documentazione AI-powered   โ”‚  โ”‚
โ”‚  โ”‚  - suggest_fix: Suggerimenti intelligenti    โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                โ–ผ                                   โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚        Zig Compiler Integration              โ”‚  โ”‚
โ”‚  โ”‚  - zig ast-check (validazione sintassi/tipi) โ”‚  โ”‚
โ”‚  โ”‚  - zig fmt (formatter ufficiale)             โ”‚  โ”‚
โ”‚  โ”‚  - Multi-versione (0.13, 0.14, 0.15)         โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                โ–ผ                                   โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚     Fine-tuned LLM (Qwen2.5-Coder-7B)        โ”‚  โ”‚
โ”‚  โ”‚  - 13,756 esempi di training                 โ”‚  โ”‚
โ”‚  โ”‚  - Specializzato su idiomi Zig moderni       โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Decisione chiave #1: Usare il compilatore ufficiale

Invece di scrivere un parser custom (come fanno molti language server), ho deciso di usare direttamente il compilatore Zig:

// src/zig/executor.ts
export class ZigExecutor {
  async analyze(code: string): Promise<AnalysisResult> {
    // Salva il codice in un file temporaneo
    const tempFile = await this.createTempFile(code);
    
    // Usa zig ast-check per l'analisi
    const result = await execAsync(
      `${this.zigPath} ast-check ${tempFile}`
    );
    
    // Parsa l'output del compilatore
    return this.parseCompilerOutput(result);
  }
}

Vantaggi:

Decisione chiave #2: Multi-versione intelligente

Gli sviluppatori Zig usano versioni diverse. ZigNet gestisce automaticamente:

// src/zig/manager.ts
export class ZigManager {
  async getZigExecutable(version?: string): Promise<string> {
    // Prima controlla se Zig รจ installato nel sistema
    const systemZig = await this.findSystemZig();
    if (systemZig && (!version || systemZig.version === version)) {
      return systemZig.path;
    }
    
    // Altrimenti scarica la versione richiesta
    return this.downloadZig(version || 'latest');
  }
}

Il sistema di cache รจ intelligente:

Decisione chiave #3: LLM fine-tuned per Zig

Per le funzionalitร  avanzate (documentazione e suggerimenti), ho addestrato un modello specifico:

# scripts/train-qwen-standard.py
def prepare_dataset():
    """13,756 esempi da repository Zig reali"""
    examples = []
    
    # 97% codice da GitHub (Zig 0.13-0.15)
    for repo in zig_repos:
        examples.extend(extract_zig_patterns(repo))
    
    # 3% documentazione ufficiale
    examples.extend(parse_zig_docs())
    
    return train_test_split(examples)

Il processo di fine-tuning:

  1. Base model: Qwen2.5-Coder-7B-Instruct (migliore comprensione di Zig nei benchmark)
  2. Tecnica: QLoRA 4-bit (training efficiente su RTX 3090)
  3. Dataset: Focus su idiomi moderni (comptime, generici, error handling)
  4. Output: Modello quantizzato Q4_K_M (~4GB per inference locale)

Le sfide tecniche affrontate

Sfida #1: Gestione degli errori del compilatore

Il compilatore Zig รจ verboso. Ho dovuto parsare output complessi:

// Un errore tipico di Zig
error: expected type 'i32', found '[]const u8'
    const x: i32 = "hello";
             ^~~

// Il parser deve estrarre:
// - Tipo di errore
// - Posizione (linea, colonna)
// - Tipi coinvolti
// - Suggerimenti contestuali

Sfida #2: Performance dellโ€™LLM

Lโ€™inference di un modello 7B puรฒ essere lenta. Ottimizzazioni implementate:

// src/llm/session.ts
export class LLMSession {
  private model: LlamaModel;
  private contextCache: Map<string, LlamaContext>;
  
  async suggest(code: string, error: string) {
    // Riusa contesti per query simili
    const cacheKey = this.getCacheKey(code, error);
    let context = this.contextCache.get(cacheKey);
    
    if (!context) {
      context = await this.model.createContext({
        contextSize: 2048,  // Limitato per velocitร 
        threads: 8,          // Parallelizzazione
      });
    }
    
    // Prompt engineering specifico per Zig
    const prompt = this.buildZigPrompt(code, error);
    return context.evaluate(prompt);
  }
}

Risultati:

Sfida #3: Testing end-to-end

Come testare un sistema che dipende da compilatore + LLM?

// tests/e2e/mcp-integration.test.ts
describe('ZigNet E2E Tests', () => {
  // Test deterministici (sempre eseguiti)
  test('analyze_zig - syntax error', async () => {
    const result = await mcp.call('analyze_zig', {
      code: 'fn main() { invalid syntax }'
    });
    expect(result.errors).toContain('expected');
  });
  
  // Test LLM (skip automatico se modello non presente)
  test('suggest_fix - type mismatch', async () => {
    if (!modelAvailable()) {
      console.log('Skipping LLM test - model not found');
      return;
    }
    
    const result = await mcp.call('suggest_fix', {
      code: 'var x: i32 = "hello";',
      error: 'type mismatch'
    });
    
    // Verifica che suggerisca almeno una fix valida
    expect(result.suggestions).toContainValidZigCode();
  });
});

Strategia di testing:

Integrazione con Claude: La magia MCP

Lโ€™integrazione รจ sorprendentemente semplice:

// claude_desktop_config.json
{
  "mcpServers": {
    "zignet": {
      "command": "npx",
      "args": ["-y", "zignet"]
    }
  }
}

Una volta configurato, lโ€™esperienza utente รจ naturale:

Tu: "Analizza questo codice Zig per errori"
[incolli il codice]

Claude: [usa analyze_zig automaticamente]
"Ho trovato 2 errori:
1. Linea 5: Type mismatch - variabile 'x' si aspetta i32 ma hai passato []const u8
2. Linea 12: Funzione 'prozess' non definita, forse intendevi 'process'?"

Tu: "Puoi formattarlo secondo lo standard?"

Claude: [usa compile_zig]
"Ecco il codice formattato con zig fmt:
[codice pulito e formattato]"

Lezioni apprese

1. Non serve un LLM gigante

La mia piรน grande scoperta: per un dominio specifico come Zig, un modello 7B ben addestrato batte un GPT-4 generico. รˆ questione di specializzazione, non di dimensioni.

2. Ibrido > Puro ML

Combinare strumenti deterministici (compilatore) con ML (suggerimenti) dร  il meglio di entrambi i mondi: accuratezza dove serve, creativitร  dove aiuta.

3. Il costo รจ accessibile

Fine-tuning su consumer hardware? Fattibile!

4. Riusa gli strumenti esistenti

Il compilatore Zig fa giร  tutto quello che serve per validazione. Perchรฉ reinventare la ruota quando puoi concentrarti su quello che manca davvero?

5. Lโ€™UX รจ tutto

Gli utenti non devono sapere che cโ€™รจ un sistema ibrido dietro. Deve essere trasparente e โ€œmagicoโ€.

6. Test separati per componenti deterministici e stocastici

I test del compilatore sono sempre riproducibili. I test LLM possono variare - pianifica di conseguenza.

7. Open Source dal giorno 1

Pubblicare il codice mi ha forzato a mantenere standard alti e documentazione chiara. Inoltre, la community Zig รจ fantastica per il feedback.

Statistiche del progetto

Conclusioni

ZigNet dimostra che non servono GPT-4 o cluster da $100k per avere AI specializzata. Con un approccio ibrido intelligente puoi ottenere risultati eccellenti:

La chiave รจ stata capire che non dovevo sostituire tutto con ML, ma solo le parti dove lโ€™AI aggiunge valore reale:

  1. Identificare cosa puรฒ essere deterministico (validazione โ†’ compilatore)
  2. Identificare cosa richiede โ€œintelligenzaโ€ (suggerimenti โ†’ LLM)
  3. Scegliere il modello giusto (Qwen2.5-7B, non GPT-4)
  4. Training mirato (13k esempi Zig, non miliardi generici)
  5. Integrazione seamless (MCP fa la magia)

Il risultato? Un sistema che:

Se stai pensando โ€œvorrei un LLM specializzato per X ma costa troppoโ€, ripensaci. Con lโ€™approccio giusto, probabilmente te la cavi con meno di quanto pensi.

Il codice รจ completamente open source. Se sei curioso di vedere come funziona davvero un sistema ibrido deterministico/stocastico, dai unโ€™occhiata:

Pacchetto per VSCode: https://marketplace.visualstudio.com/items?itemName=Fulgidus.zignet
Repository: github.com/fulgidus/zignet
Modello: huggingface.co/fulgidus/zignet-qwen2.5-coder-7b

Hai domande? Vuoi fare qualcosa di simile per un altro linguaggio? Apri una issue su GitHub o contattami. Il progetto รจ WTFPL - fai letteralmente quello che vuoi con il codice!


P.S.: La prossima volta che qualcuno ti dice che servono milioni per fare AI custom, mostragli ZigNet. A volte basta una GPU gaming, un weekend libero, e la voglia di provare. Il futuro dellโ€™AI specializzata รจ accessibile a tutti. ๐Ÿš€