Todos os artigos

SDK OpenAI Python: base_url Carpe Diem, chave cdm_, custo real

·Por Carpe Diem Team — Lumen Labs·6 min de leitura
tutorielguidetechnicalai
Um único filamento de ouro que se separa em dezenas de fios rumo a sólidos geométricos, fundo preto.

Este tutorial serve para chamar a Carpe Diem a partir de um script Python, com o SDK OpenAI que já usa: chat, lista de modelos, mudança de modelo, streaming, leitura do custo. Instala-se só um pacote, openai==3.36.0, num venv. Depois bastam dois campos: base_url para https://carpe-diem.xyz/api/operator/v1 e uma chave cdm_. O nosso ensaio de 22 de outubro de 2026 obteve pong de llama-3.3-70b por 524 micro-USDC; o mesmo cliente listou 392 modelos.

Filamento de ouro que se separa rumo a uma constelação de sólidos geométricos, fundo preto.

Ilustração gerada com seedream-v5-lite na Carpe Diem.

O que precisa

Nada além de Python, um venv, o SDK OpenAI fixado e uma chave Carpe Diem. Sem CLI Carpe Diem, sem SDK próprio.

  • Uma conta Carpe Diem com créditos ou uma conta prepaid, e uma chave cdm_ (separador API Keys do painel do comprador).
  • Python 3.10 ou superior (o pacote openai==3.36.0 exige-o).
  • pip num venv, para fixar openai==3.36.0.

No fim poderá: enviar um chat.completions.create (passo 3), listar identificadores via models.list() (passo 3), ler x-carpe-cost-usdc-micro (passo 4), passar de llama-3.3-70b para claude-haiku-5-5 ao mudar uma cadeia (passo 5) e fazer streaming de um haiku (passo 6).

Passo 1: criar uma chave cdm_

Abra Credits & keys, separador API Keys. As chaves começam por cdm_ e são mostradas uma só vez. Escolha como a chave paga (Credits ou Prepaid), um nome se quiser, depois Create a key.

Credits: saldo de utilização, 1 crédito = 0,01 $, sem levantamento. Prepaid: uma conta que detém; o protocolo só cobra o custo de cada chamada, levantamento possível. Ambos liquidam em USDC na Base (guia, §4.1). Uma terceira via, x402, paga a partir de uma wallet sem chave cdm_; este tutorial não a cobre.

Separador API Keys do painel: campo de nome, Credits ou Prepaid, botão Create a key.

Copie-a de imediato para um gestor de segredos: não voltará a ser mostrada. Na shell do tutorial:

export OPENAI_API_KEY=cdm_your_key_here

Para testar um modelo sem código, resta o Create Hub.

Passo 2: instalar openai 3.36.0

python3 -m venv .venv
.venv/bin/pip install openai==3.36.0

Não testámos outra versão do pacote. O cliente OpenAI envia POST /chat/completions sob base_url. Na Carpe Diem, base_url já deve incluir /v1:

https://carpe-diem.xyz/api/operator/v1

Não https://carpe-diem.xyz/api/operator: é o URL do adaptador Anthropic, outro protocolo. O guia SDK indica-o no topo da página, mesmo acima do exemplo Python OpenAI.

Página SDK da Carpe Diem: Base URL https://carpe-diem.xyz/api/operator/v1 e o início do exemplo Python.

Passo 3: enviar a primeira mensagem

Ficheiro hello.py (o cliente é recriado aí, como em cada excerto):

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://carpe-diem.xyz/api/operator/v1",
    api_key=os.environ["OPENAI_API_KEY"],
)

response = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[{"role": "user", "content": "Reply with the exact word: pong"}],
    max_tokens=16,
)

print(response.choices[0].message.content)
print("model:", response.model)
print("usage:", response.usage)
.venv/bin/python hello.py

Saída obtida:

pong
model: llama-3.3-70b
usage: CompletionUsage(completion_tokens=2, prompt_tokens=1675, total_tokens=1677, …)

Dois tokens de saída, mas 1675 de entrada por uma frase de seis palavras. Nas nossas duas chamadas a llama-3.3-70b com este prompt, foram facturados 1675 e depois 1695 tokens de entrada (2714 no Haiku). A origem deste preâmbulo não está documentada. max_tokens=16 limita só a saída.

Para verificar que um id existe antes de escrever o resto:

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://carpe-diem.xyz/api/operator/v1",
    api_key=os.environ["OPENAI_API_KEY"],
)

models = client.models.list()
ids = sorted(m.id for m in models.data)
print("count:", len(ids))
print("has llama-3.3-70b:", "llama-3.3-70b" in ids)
print("has claude-haiku-5-5:", "claude-haiku-5-5" in ids)

Saída: 392 identificadores, ambos True. models.list() chama GET /v1/models com a mesma chave: não é preciso um segundo cliente.

Passo 4: ler o custo da chamada

O corpo JSON do SDK não transporta o preço. A Carpe Diem coloca-o nos cabeçalhos HTTP, em micro-USDC (1 USDC = 1 000 000 micro-USDC), fora do streaming. Está documentado no guia SDK, tabela dos cabeçalhos X-Carpe-*. with_raw_response expõe-nos; raw.parse() devolve o objeto habitual.

Ficheiro cost.py:

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://carpe-diem.xyz/api/operator/v1",
    api_key=os.environ["OPENAI_API_KEY"],
)

raw = client.chat.completions.with_raw_response.create(
    model="llama-3.3-70b",
    messages=[{"role": "user", "content": "Reply with the exact word: pong"}],
    max_tokens=16,
)

headers = raw.headers
print("x-carpe-cost-usdc-micro:", headers.get("x-carpe-cost-usdc-micro"))
print("x-carpe-input-tokens:", headers.get("x-carpe-input-tokens"))
print("x-carpe-output-tokens:", headers.get("x-carpe-output-tokens"))
print("x-carpe-available-credits:", headers.get("x-carpe-available-credits"))
print("x-carpe-cached-tokens:", headers.get("x-carpe-cached-tokens"))

response = raw.parse()
print("text:", response.choices[0].message.content)
print("usage:", response.usage)

Cabeçalhos lidos nesta chamada:

  • x-carpe-cost-usdc-micro: 524
  • x-carpe-input-tokens: 1675
  • x-carpe-output-tokens: 2
  • x-carpe-available-credits: o seu saldo restante, em créditos
  • x-carpe-cached-tokens: ausente (None no SDK)

524 micro-USDC. À tarifa 0,311 $ / 1,24 $ por milhão de tokens (31,1 / 124 cr/M em /models, 1 crédito = 0,01 $), 1675 × 0,311 $ / M + 2 × 1,24 $ / M = 523 micro-USDC. 523 calculados, 524 debitados: o montante parece arredondado para o micro-USDC superior.

Passo 5: mudar de modelo com uma string

O mesmo cliente, outro identificador. O catálogo público mostra os preços em créditos por milhão (1 crédito = 0,01 $): llama-3.3-70b a 31,1 / 124 cr/M, claude-haiku-5-5 a 4,5 / 22,2 cr/M.

Catálogo Models: llama-3.3-70b a 31,1 / 124 cr/M e claude-haiku-5-5 a 4,5 / 22,2 cr/M.

Ficheiro switch_model.py:

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://carpe-diem.xyz/api/operator/v1",
    api_key=os.environ["OPENAI_API_KEY"],
)

for model in ("llama-3.3-70b", "claude-haiku-5-5"):
    raw = client.chat.completions.with_raw_response.create(
        model=model,
        messages=[{"role": "user", "content": "Reply with the exact word: pong"}],
        max_tokens=16,
    )
    text = raw.parse().choices[0].message.content
    print(model)
    print("  text:", text)
    print("  cost-usdc-micro:", raw.headers.get("x-carpe-cost-usdc-micro"))
    print("  in:", raw.headers.get("x-carpe-input-tokens"), "out:", raw.headers.get("x-carpe-output-tokens"))

Ambos responderam pong. Nesta segunda execução, llama-3.3-70b custou 530 micro-USDC por 1695 + 2 tokens, da mesma ordem que os 524 / 1675 do passo 4. A claude-haiku-5-5 foram debitados 14 micro-USDC, com 2714 + 4 tokens nos cabeçalhos. À tarifa do catálogo 4,5 / 22,2 cr/M, esses tokens dariam cerca de 123 micro-USDC: o desvio não está explicado (não lemos x-carpe-cached-tokens nesta chamada). O valor a reter é o do cabeçalho, não o cálculo à mão.

Os identificadores copiam-se a partir de /models. llama-3.3-70b-typo não foi reescrito para llama-3.3-70b: cole o id da ficha.

Passo 6: ligar o streaming

Mantenha o teste chunk.choices: o guia SDK usa-o, e um chunk sem choices faria falhar chunk.choices[0].

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://carpe-diem.xyz/api/operator/v1",
    api_key=os.environ["OPENAI_API_KEY"],
)

stream = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[{"role": "user", "content": "Write a haiku about the sea."}],
    max_tokens=64,
    stream=True,
)

for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
print()

Texto recebido, token a token:

Crashing waves ascend
Foam kisses the sandy shore
Ocean's gentle song

Em streaming, X-Carpe-Cost-Usdc-Micro não é enviado (doc SDK). Para acompanhar o custo, fique na chamada sem streaming.

Se não funcionar

401 AUTH_REQUIRED. Com OPENAI_API_KEY=cdm_invalid, o SDK lançou openai.AuthenticationError: Error code: 401 - {'error': 'Unauthorized', 'code': 'AUTH_REQUIRED'}. Chave incompleta, mal copiada, ou variável de ambiente não exportada nesta shell. Um export num terminal não chega a um IDE aberto a partir da Dock.

400 MODEL_ERROR. model="llama-3.3-70b-typo" devolveu: This model is no longer available upstream. Try a newer version of the same model. A mensagem fala de uma retirada a montante; aqui era um erro de digitação. Verifique o id em /models ou via client.models.list().

URL sem /v1. Ver o passo 2.

Ir mais longe

O mesmo base_url com /v1 substituído por /router envia a chamada ao router ao melhor preço: a mesma chave, o mesmo corpo. Não repetimos o hello.py em /router neste teste.

Para um agente no terminal em vez de um script, já ligámos o OpenCode: Kimi K3 e Claude Fable no OpenCode.

Para um modelo sem escrever hello.py, abra o Create Hub e depois volte a colar o id em model=.

Teste de 22 outubro 2026 com openai==3.36.0 e uma chave de teste com saldo. Os excertos são os que correram aqui.