Reasoning step-by-step con DeepSeek-R1 7b in locale via opencode

DeepSeek-R1 7b lo apro quando devo capire qualcosa che non si risolve con una risposta sbrigativa. Non lo carico per generare codice né per riassunti veloci: lo carico per ragionare. Mi serve un interlocutore che, davanti a un log strano o a una scelta architetturale, espliciti i passaggi del proprio ragionamento dentro blocchi prima di buttare giù una conclusione. Quei blocchi sono spesso più utili della risposta finale, perché mi mostrano dove il modello sta facendo un’assunzione che potrei voler contestare prima ancora di leggere la sintesi.

Il modello è rilasciato da DeepSeek AI con licenza MIT, quindi è libero da vincoli d’uso. Lo tengo su un server Debian 12 nella mia rete locale, lo stesso che ospita altri modelli Ollama. La 7B in quantizzazione Q4_K_M occupa circa 5 GB di VRAM e gira comoda anche su una scheda di fascia media. La latenza non è il punto forte di questa famiglia di modelli, perché generano molti token di pensiero prima della risposta vera, ma per la qualità di ragionamento che restituisce è un compromesso che accetto volentieri.

I parametri base sono 7B, contesto nativo 32k che spingo a 16k effettivi via Modelfile per non esagerare con la VRAM, temperature di default a 0.6 (la lascio così, non ho mai trovato motivo di toccarla per come la uso).

Setup base con Ollama

Su Debian si installa con lo script ufficiale e si scarica il modello in un solo passaggio.


curl -fsSL https://ollama.com/install.sh | sh
sudo systemctl enable --now ollama
ollama pull deepseek-r1:7b
ollama run deepseek-r1:7b

Una volta entrato in chat, il modello inizia ogni risposta con un blocco ... che contiene il ragionamento esplicito. Conviene lasciarlo visibile durante l’analisi e nasconderlo solo quando si vuole una risposta sintetica da incollare altrove. Per task lunghi alzo num_ctx: parto dal Modelfile esistente e ne creo una variante.


ollama show deepseek-r1:7b --modelfile > /tmp/r1.Modelfile

Dopo aver aggiunto PARAMETER num_ctx 16384 al file, costruisco la variante con ollama create deepseek-r1-long -f /tmp/r1.Modelfile e la tengo a parte per le sessioni di analisi più impegnative, in modo da non sprecare VRAM per tutto il resto della giornata.

Setup avanzato con opencode

opencode lo uso come TUI agentica: la finestra di chat è più comoda della shell di ollama run, mi permette di dare al modello accesso ai file di un progetto, e mantiene la cronologia. Lo collego al server Ollama locale tramite endpoint OpenAI-compatible, che Ollama espone di default su /v1.


{
  "provider": {
    "ollama-local": {
      "npm": "@ai-sdk/openai-compatible",
      "options": {
        "apiKey": "ollama",
        "baseURL": "http://localhost:11434/v1"
      },
      "models": {
        "deepseek-r1:7b": { "name": "DeepSeek R1 7B" }
      }
    }
  }
}

Salvato il file, mi posiziono nella cartella del progetto e apro la sessione.


cd ~/Documenti/progetti/analisi-log
opencode . --model ollama-local/deepseek-r1:7b

Dentro la TUI passo i file rilevanti come contesto e il modello li tiene presenti per tutta la sessione, senza che debba riallegare niente a ogni messaggio.

Un esempio di sessione reale

Ieri sera alle 23 stavo cercando di capire perché una migration Django in un progetto interno andava in errore solo sul database di staging, mai in locale, sempre con un messaggio criptico su una foreign key che si rifiutava di essere creata. Avevo davanti il dump dello schema, il file della migration generata dal makemigrations, e il traceback intero. Ho aperto opencode nella cartella del progetto, ho dato in contesto i tre file e ho chiesto a DeepSeek-R1 di ragionare ad alta voce su cosa potesse causare quel comportamento solo in staging.

Il blocco ha messo in fila le ipotesi una per una: differenza di engine InnoDB tra le due istanze, charset diverso, una migration precedente non applicata davvero, una constraint dichiarata su una colonna che nel dump aveva tipo BIGINT mentre nella nuova migration era INT. Ha scartato le prime tre con argomenti che potevo verificare e si è concentrato sulla quarta, indicandomi esattamente quale tabella e quale colonna controllare. Ho aperto il dump, ho confermato il mismatch di tipo, ho corretto la migration con una operazione esplicita di alter sulla colonna, e in dieci minuti il problema era chiuso. Il valore del ragionamento esplicito sta proprio qui: mi fa risparmiare i giri morti dietro a ipotesi sbagliate.

Cosa fa bene

Quando il problema richiede di mettere in fila ipotesi e scartarle con un argomento, DeepSeek-R1 7b dà il meglio. Lo trovo utile per debug di errori non ovvi, per decisioni di architettura su scala piccola (scegliere tra due pattern di retry, capire dove mettere un lock), per analisi di log dove serve ricostruire una sequenza causale. Il fatto che il ragionamento sia esplicito e contestabile vale tantissimo.

Cosa fa meno bene

Per task brevi è sovradimensionato: produce sempre il blocco di pensiero, anche per una domanda da due righe, e il tempo di risposta totale lievita. Su task strettamente di codice è meno preciso di un modello specializzato come Qwen2.5-Coder, perché il suo focus è il reasoning e non la generazione. Su prompt molto lunghi (oltre 10k token) la qualità del ragionamento cala vistosamente, e conviene spezzare il problema invece di buttargli tutto in pasto.

Privacy: tutto resta sul mio host

DeepSeek-R1 gira interamente sul mio server: nessun provider terzo coinvolto, nessun upload, nessuna telemetria. Ollama si lega su 127.0.0.1:11434 e non parla con l’esterno. I log stanno in ~/.ollama/logs/ e li cancello quando voglio con un rm, senza alcuna policy esterna da rileggere. Rispetto ai servizi cloud, dove ogni prompt e ogni risposta passano per server di terzi (e in qualche caso possono finire dentro pipeline di training o retention prolungata), qui l’analisi resta dentro l’host: i log che gli passo per ragionare non escono mai dalla mia rete. La licenza MIT di DeepSeek-R1 è la più permissiva possibile, posso integrarlo dove voglio senza altri vincoli.

In pratica

DeepSeek-R1 7b è il modello che apro per ragionare ad alta voce su un problema poco chiaro. Quando devo invece scrivere o rivedere codice passo a Qwen2.5-Coder, per domande generiche e veloci sul laptop mi appoggio a qwen3:8b, e per risposte brevi sul Mac Mini tengo Gemma3 4B. Tenere a portata modelli con vocazioni diverse cambia parecchio il modo in cui affronto i problemi durante una sessione di lavoro lunga.


Immagine generata con Cloudflare Workers AI / FLUX.