Server API e tool calling: integra ds4 con qualsiasi agente
Uno degli aspetti più potenti di ds4 è il server API. Non devi usare solo il CLI o l’agente nativo: puoi esporre DeepSeek V4 come servizio compatibile con gli standard del settore, in modo da collegarci qualsiasi agente o applicazione che parli OpenAI, Anthropic o Responses API.
Avviare il server
Section titled “Avviare il server”Il binario ds4-server viene compilato insieme a ds4. Per avviarlo con una configurazione di base:
./ds4-server --ctx 100000 --kv-disk-dir /tmp/ds4-kv --kv-disk-space-mb 8192Parametri fondamentali:
| Parametro | Esempio | Spiegazione |
|---|---|---|
--ctx | 100000 | Dimensione massima del contesto (in token) |
--kv-disk-dir | /tmp/ds4-kv | Directory per la cache KV su disco (capitolo 6) |
--kv-disk-space-mb | 8192 | Spazio massimo per la cache (8 GB) |
--host | 0.0.0.0 | Ascolta su tutte le interfacce (default: 127.0.0.1) |
--port | 8000 | Porta (default: 8000) |
--cors | – | Abilita header CORS per richieste da browser (non espone su LAN; usa anche --host 0.0.0.0) |
--power | 50 | Riduce l’uso della GPU (50% della potenza) |
Una volta avviato, il server risponde su http://localhost:8000 (o l’IP/porta configurata).
Endpoint supportati
Section titled “Endpoint supportati”ds4-server implementa quattro famiglie di API:
1. Elenco modelli (GET /v1/models)
Section titled “1. Elenco modelli (GET /v1/models)”Restituisce la lista dei modelli disponibili caricati dal server. Utile per verificare che il server sia vivo e quale modello è attivo.
curl http://localhost:8000/v1/models2. OpenAI Chat Completions (POST /v1/chat/completions)
Section titled “2. OpenAI Chat Completions (POST /v1/chat/completions)”L’endpoint più comune, usato da OpenCode, Pi e molti altri.
curl http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-v4-flash", "messages": [{"role": "user", "content": "Ciao, chi sei?"}], "stream": true }'Campi supportati:
messages,max_tokens/max_completion_tokenstemperature,top_p,top_k,min_p,seedstream,stream_options.include_usagetools,tool_choice
3. OpenAI Responses API (POST /v1/responses)
Section titled “3. OpenAI Responses API (POST /v1/responses)”Endpoint più recente, preferito da Codex CLI. Supporta il formato “reasoning” (thinking) nativamente.
curl http://localhost:8000/v1/responses \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-v4-flash", "input": "Spiega le reti neurali", "reasoning": {"effort": "high"} }'4. Anthropic-compatible (POST /v1/messages)
Section titled “4. Anthropic-compatible (POST /v1/messages)”Usato da Claude Code e altri client che parlano il formato Anthropic.
curl http://localhost:8000/v1/messages \ -H "Content-Type: application/json" \ -H "x-api-key: dsv4-local" \ -d '{ "model": "deepseek-v4-flash", "messages": [{"role": "user", "content": "Ciao"}], "max_tokens": 1000 }'Nota: l’API key non è verificata (puoi mettere qualsiasi stringa), ma deve essere presente. Il server non implementa autenticazione reale.
Altri endpoint
GET /v1/models/deepseek-v4-flash– dettagli del modello FlashPOST /v1/completions– completamenti non-chat (compatibilità OpenAI)
Tool calling: DSML e exact replay
Section titled “Tool calling: DSML e exact replay”Come anticipato nei capitoli 2 e 6, DeepSeek V4 utilizza il formato DSML per le chiamate a tool. Il server traduce automaticamente tra il formato standard OpenAI/Anthropic e DSML.
Flusso tipico con tool calling
- Il client invia una richiesta con
tools(definizione degli strumenti disponibili). - Il server converte le definizioni in DSML e le inietta nel prompt.
- Il modello genera un blocco DSML, ad esempio:
<tool_calls><get_weather>{"city": "Roma"}- Il server parseggia il DSML, lo converte in un oggetto tool call standard (OpenAI o Anthropic) e lo restituisce al client.
- Il client esegue il tool e invia il risultato in una nuova richiesta, includendo l’ID della tool call.
- Il server cerca l’esatta sequenza DSML che aveva generato per quella tool call (grazie alla mappa tool-id salvata in RAM e su disco) e la re-inietta nel prompt. La KV cache rimane valida.
Perché l’exact replay è fondamentale
Se il server riformattasse il risultato del tool in DSML in modo leggermente diverso (spazi, maiuscole, ordine dei campi), il prompt renderizzato cambierebbe e la KV cache non corrisponderebbe più. Si dovrebbe rifare il prefill da zero, con un forte aumento della latenza.
Con l’exact replay, invece, i byte originali vengono riutilizzati, e la conversazione procede velocemente.
Disabilitare l’exact replay (non raccomandato)
Se per qualsiasi motivo vuoi disabilitare l’exact replay (ad esempio per test), puoi usare:
./ds4-server --disable-exact-dsml-tool-replayIn questo caso, il server cadrà sempre sulla canonicalizzazione (deterministica) del DSML, che è meno efficiente ma ancora funzionante.
Integrazione con agenti popolari
Section titled “Integrazione con agenti popolari”Codex CLI
Section titled “Codex CLI”Codex CLI utilizza l’endpoint Responses API. Configura il file ~/.codex/config.toml (o la variabile d’ambiente):
[model_providers.ds4]name = "DS4"base_url = "http://127.0.0.1:8000/v1"wire_api = "responses"stream_idle_timeout_ms = 1000000Poi esegui:
codex --model deepseek-v4-flash -c model_provider=ds4Claude Code (Anthropic endpoint)
Section titled “Claude Code (Anthropic endpoint)”Crea uno script ~/bin/claude-ds4:
#!/bin/shunset ANTHROPIC_API_KEYexport ANTHROPIC_BASE_URL="http://127.0.0.1:8000"export ANTHROPIC_AUTH_TOKEN="dsv4-local"export ANTHROPIC_MODEL="deepseek-v4-flash"export ANTHROPIC_DEFAULT_SONNET_MODEL="deepseek-v4-flash"export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1exec claude "$@"Poi usa claude-ds4 come comando.
Pi (open-source agent)
Section titled “Pi (open-source agent)”Aggiungi un provider a ~/.pi/agent/models.json:
{ "providers": { "ds4": { "name": "ds4.c local", "baseUrl": "http://127.0.0.1:8000/v1", "api": "openai-completions", "apiKey": "dsv4-local", "compat": { "supportsStore": false, "supportsReasoningEffort": true, "thinkingFormat": "deepseek", "maxTokensField": "max_tokens" }, "models": [ { "id": "deepseek-v4-flash", "name": "DeepSeek V4 Flash (ds4.c local)", "reasoning": true, "contextWindow": 100000, "maxTokens": 384000 } ] } }}Poi imposta defaultProvider a ds4 in ~/.pi/agent/settings.json.
OpenCode
Section titled “OpenCode”Configura ~/.config/opencode/opencode.json:
{ "provider": { "ds4": { "name": "ds4.c (local)", "npm": "@ai-sdk/openai-compatible", "options": { "baseURL": "http://127.0.0.1:8000/v1", "apiKey": "dsv4-local" }, "models": { "deepseek-v4-flash": { "name": "DeepSeek V4 Flash (ds4.c local)", "limit": { "context": 100000, "output": 384000 } } } } }, "agent": { "ds4": { "description": "DeepSeek V4 Flash served by local ds4-server", "model": "ds4/deepseek-v4-flash", "temperature": 0 } }}Modalità thinking nel server
Section titled “Modalità thinking nel server”Il server adotta le seguenti regole per la modalità di ragionamento:
| Richiesta client | Modalità effettiva |
|---|---|
| Nessun parametro di thinking (default) | Thinking (normale) |
thinking: {"type":"disabled"} o think: false | Non-thinking |
reasoning_effort: "max" (OpenAI) + contesto sufficiente | Think Max (più profondo) |
reasoning_effort: "xhigh" | Thinking normale (non Max) |
Nota: Think Max viene applicato solo se il contesto è abbastanza grande (secondo la raccomandazione del modello). Altrimenti decade a thinking normale.
I parametri di sampling predefiniti nel server sono:
temperature = 1top_p = 1min_p = 0.05
Il min_p è un filtro di probabilità relativa: vengono considerati solo i token la cui probabilità è almeno min_p * max_probability. Funziona bene con temperature basse.
Streaming e tool call
Section titled “Streaming e tool call”Il server supporta lo streaming sia per il testo che per i tool call.
OpenAI chat streaming:
- Il reasoning (se presente) viene omesso dallo stream (o gestito separatamente a seconda del client).
- I tool call vengono inviati come
tool_calls[].function.argumentsdelta, con il primo chunk che contieneidename, e i successivi i frammenti JSON. - Al termine, viene inviato un chunk finale con
finish_reason.
Anthropic streaming:
- I blocchi di thinking sono inviati come eventi separati.
- I tool call sono inviati come blocchi
tool_usecompleti (non delta).
Responses streaming:
- Eventi
response.output_text.delta,response.function_call_arguments.delta, eresponse.completed/response.incomplete.
Performance e scalabilità
Section titled “Performance e scalabilità”Il server ha alcune caratteristiche importanti da conoscere:
- Una sola sessione attiva in memoria: Non possono essere elaborate richieste concorrenti su conversazioni diverse. Se arriva una seconda richiesta mentre la prima è in corso, la seconda aspetta in coda.
- Cache KV su disco (capitolo 6) mitiga questo limite: quando una richiesta con un prompt diverso sostituisce la sessione in memoria, la vecchia viene salvata su disco. Una successiva richiesta con lo stesso prompt la ripristinerà velocemente.
- Prefill e generazione serializzati: Il server non esegue batching di richieste indipendenti. Ogni richiesta viene processata una alla volta.
- Per applicazioni con molti utenti concorrenti, è meglio eseguire più istanze del server dietro un load balancer (ciascuna con il proprio modello caricato in memoria).
Esempi pratici
Section titled “Esempi pratici”Esempio 1: Chat semplice in streaming
Section titled “Esempio 1: Chat semplice in streaming”curl -N http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-v4-flash", "messages": [{"role": "user", "content": "Spiega il teorema di Pitagora"}], "stream": true }'Esempio 2: Tool calling (definizione di una funzione)
Section titled “Esempio 2: Tool calling (definizione di una funzione)”curl http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-v4-flash", "messages": [{"role": "user", "content": "Che tempo fa a Roma?"}], "tools": [{ "type": "function", "function": { "name": "get_weather", "description": "Ottieni il meteo di una città", "parameters": { "type": "object", "properties": { "city": {"type": "string"} }, "required": ["city"] } } }], "tool_choice": "auto" }'Il server risponderà con un oggetto tool call (non con testo normale). Il client dovrà eseguire la funzione e rinviare il risultato in un nuovo turno di conversazione.
Limitazioni e note
Section titled “Limitazioni e note”- Nessuna autenticazione: Chiunque possa raggiungere il server (anche via rete) può usarlo. Usa firewall o reverse proxy con autenticazione se necessario.
- Solo una sessione alla volta: Come detto, non è un server per uso multi-utente pesante.
- Tool call annidati non supportati: DeepSeek V4 non genera tool call dentro thinking o dentro altre tool call. Il server gestisce solo il caso piatto.
- Il modello potrebbe non chiamare i tool: Dipende dal prompt e dalle definizioni. A volte il modello ignora i tool e risponde direttamente.
Conclusione
Section titled “Conclusione”ds4-server è il ponte tra ds4 e l’ecosistema degli agenti di coding. Con la compatibilità OpenAI, Anthropic e Responses, puoi collegare praticamente qualsiasi cliente esistente. La cache KV su disco e l’exact replay dei tool call rendono l’esperienza fluida e veloce, nonostante la singola sessione attiva.
Consiglio pratico: Inizia con --ctx 100000 e --kv-disk-dir. La cache su disco migliora enormemente le prestazioni per conversazioni ripetute. Se hai problemi di memoria, riduci --ctx o usa --kv-disk-space-mb più basso.
💡 Verificare che il server sia vivo
Prima di configurare un agente, testa l’endpoint
/v1/models con
curl http://localhost:8000/v1/models. Dovresti ricevere un JSON
con i dettagli del modello caricato.
⚠️ L’API key non è verificata
Per compatibilità, il server accetta qualsiasi stringa come API key
(es.
dsv4-local). Non fare affidamento su questo per la sicurezza: usa
un reverse proxy con autenticazione se esponi il server su rete non fidata.