PT ▾
Obter chave de API

Exemplo Python da API DeepSeek: Chat, Streaming, Ferramentas

Uma configuração de api python deepseek precisa apenas do pacote openai oficial, uma base URL, uma chave e um ID de modelo. Os exemplos abaixo cobrem uma requisição simples, streaming, modo JSON, chamada de ferramentas e tentativas de novo, todos contra um endpoint compatível com OpenAI.

Atualizado

Slab de terminal transmitindo tokens de dados brilhantes para um bloco de servidor, representando chamadas de API Python

Pontos principais

  • Instale openai, defina base_url para https://api.deepseekapi.top/v1 e modelo para uncensored.
  • Streaming, modo JSON e chamada de ferramentas funcionam através dos parâmetros normais do SDK.
  • Lide com HTTP 429 lendo Retry-After e tente novamente.
  • O preço é $0,15 por 1M de tokens de entrada e $0,50 por 1M de tokens de saída.

Instale e envie uma primeira requisição

Este serviço não é a API oficial da DeepSeek. É um endpoint hospedado e compatível com OpenAI que executa um único modelo de pesos abertos, ID uncensored, operado por um provedor independente. Como segue o formato OpenAI, o SDK Python padrão funciona sem alterações além da URL e chave.

pip install openai

Obtenha uma chave na página da chave de API. Após o cadastro, você pode reivindicar $0,50 de crédito de teste com um clique, sem cartão, válido por 7 dias. Armazene a chave em uma variável de ambiente em vez do arquivo de origem:

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)

Os dois números de uso são a base para sua cobrança. Multiplique-os pelos preços para ver o custo de qualquer chamada: tokens de entrada vezes $0,15 e tokens de saída vezes $0,50, cada um dividido por 1.000.000.

Usando o cliente assíncrono

Para servidores web e qualquer coisa que lide com muitos usuários, use o cliente assíncrono. Ele tem os mesmos parâmetros que o síncrono e é uma mudança pronta para usar na maioria dos códigos.

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())

O semáforo está definido para 8 porque essa é a concorrência de uma chave completa. Em uma chave de teste, use 2. Sem um limite, uma explosão de tarefas produzirá erros concurrency mesmo que cada requisição seja válida.

Respostas em streaming

Defina stream=True e o endpoint envia eventos enviados pelo servidor. Cada bloco contém um pequeno trecho de texto em delta.content. Solicitar o uso significa que o último bloco relata a contagem de tokens.

# 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)

Dois detalhes confundem as pessoas. O último bloco de uso pode ter uma lista choices vazia, por isso o loop verifica chunk.choices primeiro. E uma solicitação em streaming mantém seu slot de concorrência até o fim do streaming, então saia dos loops de forma limpa e feche streams que você abandonar. Uma chave completa permite 8 requisições simultâneas; uma chave de teste permite 2.

Modo JSON

Para saída que um programa irá analisar, use response_format com json_object. Também inclua a palavra JSON no prompt e descreva a estrutura desejada. O modelo precisa dessa instrução; a flag sozinha não fornece um esquema.

# 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"])

Mantenha um try/except ao redor de json.loads. Se uma resposta for cortada por um limite de tokens, ela não será analisada, então evite um max_tokens pequeno com JSON. Definir temperature para 0 e um seed torna as re-execuções mais repetíveis, pois ambos são passados.

Chamada de funções

A API aceita tools e tool_choice, e retorna tool_calls na mensagem do assistente. Você mesmo executa a função e envia o resultado de volta como uma mensagem com 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)

Sempre analise arguments de forma defensiva. É uma string JSON produzida pelo modelo, e uma string malformada é possível. Valide antes de agir, especialmente se a função tocar arquivos ou um banco de dados.

Erros, limites e tentativas de novo

Uma requisição acima do limite retorna HTTP 429. O código de erro indica qual limite: rate_limited para requisições por minuto (300 em uma chave completa, 60 em uma chave de teste) e concurrency para muitas ao mesmo tempo. Em sobrecarga temporária, você também recebe 429 com Retry-After: 5. O SDK lança 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 você enviar muitas requisições, limite seu próprio paralelismo com um semáforo ou um pool de threads de 8 workers, ou 2 em uma chave de teste. Isso evita erros concurrency em vez de tentar novamente através deles.

Lendo cabeçalhos

Cada resposta carrega X-Request-Id, X-Balance-USD, X-RateLimit-Limit-Requests e X-RateLimit-Limit-Concurrency. O SDK os expõe através da resposta bruta:

# 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()

Registrar o ID da requisição com cada falha torna as perguntas de suporte muito mais fáceis de responder. Requisições falhas ou recusadas não são cobradas.

Mantendo uma conversa

A API é stateless. Ela não lembra das requisições anteriores, então um chat multiturno significa que você envia todo o histórico toda vez. Mantenha uma lista e anexe a ela:

# 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."))

Cada turno reenvia tudo, então tokens de entrada crescem turno a turno. Remova mensagens antigas assim que a lista ficar longa, ou peça ao modelo para resumir a parte inicial e substitua-a. Com uma janela de contexto de 100.000 tokens, você tem bastante espaço, mas a conta cresce com o histórico, então uma lista reduzida é mais barata.

Escolhendo valores de amostragem

Use temperature 0 a 0,3 para código e extração, cerca de 0,7 para chat geral, e mais alto para ficção. top_p, stop, seed e as penalidades de frequência e presença são passadas, então elas se comportam conforme descrito na documentação OpenAI. Altere uma de cada vez e compare.

Planejamento de custo e contexto

A janela de contexto tem 100.000 tokens, incluindo prompt e resposta, e o limite do corpo é 8 MB. A resposta pode usar tudo o que sobrar da janela, e max_tokens é opcional. Definir esse valor ainda é uma boa prática para trabalhos em lote.

Um exemplo prático: um lote de 1.000 resumos, cada um com 1.500 tokens de entrada e 200 tokens de saída.

  • Entrada: 1.000 × 1.500 = 1.500.000 tokens, que é 1,5 × $0,15 = $0,225
  • Saída: 1.000 × 200 = 200.000 tokens, que é 0,2 × $0,50 = $0,10
  • Total: $0,325

O preço é pagamento por uso a partir de crédito pré-pago, sem assinatura, e o crédito nunca expira. Recarregamentos variam de $20 a $500 em valores inteiros, com +5% a partir de $50, +10% a partir de $100 e +15% a partir de $200, pagáveis por cartão ou cripto. Veja a página de preços, e a documentação de início rápido para exemplos curl e Node. Se você só precisa localizar sua chave, a visão geral da chave de API cobre isso.

Prompts não são usados para treinamento. O serviço é apenas texto: sem imagens, áudio, embeddings ou fine-tuning, então não planeje em torno desses endpoints.

Perguntas e respostas

Preciso de uma biblioteca especial para DeepSeek?

Não. Instale o pacote openai, defina base_url para https://api.deepseekapi.top/v1 e use o ID do modelo uncensored. Esta não é a API oficial da DeepSeek.

O SDK Python suporta streaming aqui?

Sim. Passe stream=True e adicione stream_options com include_usage para obter contagens de tokens no último chunk.

Como lidar com um erro 429?

Capture openai.RateLimitError, leia o cabeçalho Retry-After e aguarde antes de tentar novamente. O código de erro indica se foi rate_limited ou concurrency.

Posso testar sem pagar?

Sim. Após o cadastro, um clique na página da chave de API adiciona $0,50 de crédito de teste, válido por 7 dias, sem necessidade de cartão.

Sua chave está a um formulário de distância

Crie uma conta, copie a chave e altere a URL base. Essa é toda a configuração.

Obter chave de API