Esempio Python API DeepSeek: chat, streaming, strumenti
Una configurazione API DeepSeek in Python richiede solo il pacchetto openai ufficiale, un URL base, una chiave e un ID del modello. Gli esempi seguenti coprono una richiesta semplice, lo streaming, la modalità JSON, la chiamata di strumenti e i tentativi, tutti contro un endpoint compatibile con OpenAI.

Punti chiave
- Installa openai, poi imposta base_url su https://api.deepseekapi.top/v1 e il modello su uncensored.
- Lo streaming, la modalità JSON e la chiamata di strumenti funzionano tramite i parametri normali dell'SDK.
- Gestisci l'HTTP 429 leggendo Retry-After e riprovando.
- Il prezzo è $0,15 per 1 milione di token di input e $0,50 per 1 milione di token di output.
Installa e invia una prima richiesta
Questo servizio non è l'API ufficiale DeepSeek. È un endpoint ospitato e compatibile con OpenAI che esegue un modello a pesi aperti, ID uncensored, gestito da un provider indipendente. Poiché segue il formato OpenAI, l'SDK Python standard funziona senza modifiche oltre all'URL e alla chiave.
pip install openai
Ottieni una chiave dalla pagina della chiave API. Dopo la registrazione puoi richiedere $0,50 di credito di prova con un clic, senza carta, valido per 7 giorni. Memorizza la chiave in una variabile d'ambiente piuttosto che nel file sorgente:
export API_KEY="YOUR_KEY"
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.deepseekapi.top/v1",
api_key=os.environ["API_KEY"],
)
resp = client.chat.completions.create(
model="uncensored",
messages=[
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "Explain list comprehensions in two sentences."},
],
temperature=0.7,
)
print(resp.choices[0].message.content)
print(resp.usage.prompt_tokens, resp.usage.completion_tokens)
I due numeri di utilizzo sono quelli su cui vieni fatturato. Moltiplicali per i prezzi per vedere il costo di qualsiasi chiamata: token di input per $0,15 e token di output per $0,50, ciascuno diviso per 1.000.000.
Utilizzo del client asincrono
Per server web e tutto ciò che gestisce molti utenti, usa il client asincrono. Ha gli stessi parametri di quello sincrono ed è una modifica pronta all'uso nella maggior parte del codice.
import asyncio
import os
from openai import AsyncOpenAI
client = AsyncOpenAI(
base_url="https://api.deepseekapi.top/v1",
api_key=os.environ["API_KEY"],
)
sem = asyncio.Semaphore(8)
async def ask(prompt):
async with sem:
r = await client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": prompt}],
)
return r.choices[0].message.content
async def main():
prompts = ["Define idempotent.", "Define monotonic.", "Define pure function."]
answers = await asyncio.gather(*(ask(p) for p in prompts))
for a in answers:
print(a)
asyncio.run(main())
Il semaforo è impostato a 8 perché quella è la concorrenza di una chiave completa. Su una chiave di prova usa 2. Senza un limite, un burst di attività produrrà errori concurrency anche se ogni richiesta è valida.
Risposte in streaming
Imposta stream=True e l'endpoint invia eventi inviati dal server. Ogni chunk trasporta un piccolo pezzo di testo in delta.content. Richiedere l'utilizzo significa che l'ultimo chunk segnala i conteggi dei token.
# client = OpenAI(base_url="https://api.deepseekapi.top/v1", ...) as above
stream = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": "Write a haiku about debugging."}],
stream=True,
stream_options={"include_usage": True},
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
if chunk.usage:
print("\n", chunk.usage.prompt_tokens, chunk.usage.completion_tokens)
Due dettagli creano difficoltà. L'ultimo chunk di utilizzo può avere un elenco choices vuoto, motivo per cui il ciclo controlla chunk.choices prima. E una richiesta in streaming mantiene il suo slot di concorrenza fino alla fine dello streaming, quindi esci pulitamente dai cicli e chiudi gli stream che abbandoni. Una chiave completa consente 8 richieste concorrenti; una chiave di prova ne consente 2.
Modalità JSON
Per un output che un programma analizzerà, usa response_format con json_object. Includi anche la parola JSON nel prompt e descrivi la forma che desideri. Il modello ha bisogno di quella istruzione; il flag da solo non fornisce uno schema.
# client = OpenAI(base_url="https://api.deepseekapi.top/v1", ...) as above
import json
resp = client.chat.completions.create(
model="uncensored",
messages=[
{"role": "system", "content": "Reply with JSON only: {\"title\": str, \"tags\": [str]}"},
{"role": "user", "content": "Summarize: a guide to caching HTTP responses."},
],
response_format={"type": "json_object"},
temperature=0,
)
data = json.loads(resp.choices[0].message.content)
print(data["title"], data["tags"])
Racchiudi json.loads in un try/except. Se una risposta viene interrotta da un limite di token non verrà analizzata, quindi evita un piccolo max_tokens con JSON. Impostare temperature a 0 e un seed rende le riesecuzioni più riproducibili, poiché entrambi vengono passati.
Chiamata di funzioni
L'API accetta tools e tool_choice, e restituisce tool_calls nel messaggio dell'assistente. Eseguisci la funzione tu stesso e invia il risultato indietro come messaggio con role: "tool".
# client = OpenAI(base_url="https://api.deepseekapi.top/v1", ...) as above
import json
tools = [{
"type": "function",
"function": {
"name": "add",
"description": "Add two numbers.",
"parameters": {
"type": "object",
"properties": {"a": {"type": "number"}, "b": {"type": "number"}},
"required": ["a", "b"],
},
},
}]
messages = [{"role": "user", "content": "What is 17.5 plus 24.25?"}]
first = client.chat.completions.create(
model="uncensored", messages=messages, tools=tools, tool_choice="auto"
)
msg = first.choices[0].message
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = args["a"] + args["b"]
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": str(result),
})
final = client.chat.completions.create(
model="uncensored", messages=messages, tools=tools
)
print(final.choices[0].message.content)
else:
print(msg.content)
Analizza sempre arguments in modo difensivo. È una stringa JSON prodotta dal modello ed è possibile una stringa malformata. Validala prima di agire su di essa, specialmente se la funzione tocca file o un database.
Errori, limiti e ritentativi
Una richiesta oltre un limite restituisce HTTP 429. Il codice di errore ti dice quale limite: rate_limited per le richieste al minuto (300 su una chiave completa, 60 su una chiave di prova) e concurrency per troppe contemporaneamente. In caso di sovraccarico temporaneo ottieni anche 429 con Retry-After: 5. L'SDK genera openai.RateLimitError.
# client = OpenAI(base_url="https://api.deepseekapi.top/v1", ...) as above
import time
import openai
def ask(prompt, tries=4):
for attempt in range(tries):
try:
r = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": prompt}],
)
return r.choices[0].message.content
except openai.RateLimitError as e:
wait = int(e.response.headers.get("Retry-After", 5))
time.sleep(wait * (attempt + 1))
raise RuntimeError("still rate limited")
print(ask("Name three Python web frameworks."))
Se invii molte richieste, limita il tuo parallelismo con un semaforo o un pool di thread con 8 worker, o 2 con una chiave di prova. In questo modo eviti errori di concurrency invece di riprovare attraverso di essi.
Lettura delle intestazioni
Ogni risposta trasporta X-Request-Id, X-Balance-USD, X-RateLimit-Limit-Requests e X-RateLimit-Limit-Concurrency. L'SDK li espone attraverso la risposta grezza:
# client = OpenAI(base_url="https://api.deepseekapi.top/v1", ...) as above
raw = client.chat.completions.with_raw_response.create(
model="uncensored",
messages=[{"role": "user", "content": "ping"}],
)
print(raw.headers.get("X-Balance-USD"), raw.headers.get("X-Request-Id"))
completion = raw.parse()
Registrare l'ID della richiesta con ogni errore rende le domande di supporto molto più facili da rispondere. Le richieste fallite o rifiutate non vengono addebitate.
Mantenere viva una conversazione
L'API è senza stato. Non ricorda le richieste precedenti, quindi una chat multi-turno significa che invii l'intera cronologia ogni volta. Tieni un elenco e aggiungilo:
# client = OpenAI(base_url="https://api.deepseekapi.top/v1", ...) as above
history = [{"role": "system", "content": "You are a helpful tutor."}]
def chat(user_text):
history.append({"role": "user", "content": user_text})
r = client.chat.completions.create(model="uncensored", messages=history)
reply = r.choices[0].message.content
history.append({"role": "assistant", "content": reply})
return reply
print(chat("What is a closure?"))
print(chat("Show me one in Python."))
Ogni turno reinvia tutto, quindi i token di input crescono di turno in turno. Taglia i messaggi vecchi una volta che l'elenco diventa lungo, o chiedi al modello di riassumere la parte iniziale e di sostituirla. Con una finestra di 100.000 token hai molto spazio, ma il conto cresce con la cronologia, quindi un elenco tagliato è più economico.
Scelta dei valori di campionamento
Usa temperature da 0 a 0,3 per codice ed estrazione, circa 0,7 per chat generale, e più alto per la narrativa. top_p, stop, seed e le penalità di frequenza e presenza vengono passate, quindi si comportano come descritto nella documentazione di OpenAI. Modifica un parametro alla volta e confronta.
Pianificazione dei costi e del contesto
La finestra di contesto è di 100.000 token, prompt più completamento, e il limite del corpo è di 8 MB. Il completamento può usare tutto ciò che rimane della finestra, e max_tokens è facoltativo. Impostarlo è comunque una buona pratica per i lavori batch.
Un esempio pratico: un batch di 1.000 riassunti, ciascuno con 1.500 token di input e 200 token di output.
- Input: 1.000 × 1.500 = 1.500.000 token, che è 1,5 × $0,15 = $0,225
- Output: 1.000 × 200 = 200.000 token, che è 0,2 × $0,50 = $0,10
- Totale: $0,325
La tariffazione è a consumo da credito prepagato, senza abbonamento, e il credito non scade mai. I ricarichi vanno da $20 a $500 in importi interi, con +5% da $50, +10% da $100 e +15% da $200, pagabili con carta o cripto. Vedi la pagina prezzi, e la documentazione avvio rapido per esempi curl e Node. Se devi solo individuare la tua chiave, la panoramica chiave API la copre.
I prompt non sono usati per l'addestramento. Il servizio è solo testo: nessuna immagine, audio, embedding o fine-tuning, quindi non pianificare attorno a quegli endpoint.
Altre guide
Domande e risposte
Ho bisogno di una libreria speciale DeepSeek?
No. Installa il pacchetto openai, imposta base_url su https://api.deepseekapi.top/v1 e usa l'ID del modello uncensored. Questa non è l'API ufficiale DeepSeek.
L'SDK Python supporta lo streaming qui?
Sì. Imposta stream=True e aggiungi stream_options con include_usage per ottenere i conteggi dei token nell'ultimo chunk.
Come gestisco un errore 429?
Cattura openai.RateLimitError, leggi l'intestazione Retry-After e attendi prima di riprovare. Il codice di errore ti dice se è stato rate_limited o concurrency.
Posso provare senza pagare?
Sì. Dopo la registrazione, un clic nella pagina della chiave API aggiunge $0,50 di credito di prova, valido per 7 giorni, senza bisogno di carta.
La tua chiave è a un modulo di distanza
Crea un account, copia la chiave, modifica l'URL di base. È tutta la configurazione.