Geração de texto
POST /chat/completions gera uma completion a partir de uma lista de mensagens. model e
messages são obrigatórios. temperature, max_tokens, top_p, stop, reasoning_effort e stream são
opcionais.
reasoning_effort define quanto um modelo de reasoning pensa antes de responder. Liste os modelos
para ver quais níveis cada um aceita e qual é o padrão, e veja a
referência de chat completions para os detalhes.
Qualquer campo que esta página não menciona é enviado ao modelo como está, então um parâmetro que seu modelo suporta e que esta documentação ainda não cobriu chega até ele normalmente.
Ver o prompt
Me ajude a configurar isto para usar a Bayle AI, uma API compatível com a OpenAI. Guia completo: https://docs.bayle.ai/pt-br/guides/text-generation/
Objetivo: adicionar chat completions da Bayle a este projeto, com streaming e function calling.
1. Ache ou crie o client da OpenAI deste projeto (Python ou Node, o que ele já usar) e aponte-o para a Bayle:
Python: OpenAI(api_key=os.environ["BAYLE_API_KEY"], base_url="https://api.bayle.ai")
Node: new OpenAI({ apiKey: process.env.BAYLE_API_KEY, baseURL: 'https://api.bayle.ai' })
2. Escolha um modelo: curl -s "https://api.bayle.ai/models?type=text" | jq -r '.data[] | select(.model_spec.capabilities.supportsFunctionCalling) | .id'
Me mostre a lista e deixe eu escolher o MODEL_ID. Use-o em tudo abaixo.
3. Adicione uma completion básica: client.chat.completions.create(model=MODEL_ID, messages=[system + user], temperature=0.7, max_tokens=200). A API não adiciona nenhuma mensagem de sistema própria, então envie a minha ou nenhuma.
4. Adicione streaming com stream=True. Leia todos os chunks, mas cuide do evento de uso: a lista `choices` dele vem vazia, então confira `chunk.choices` antes de ler `choices[0]`. Leia até o fim do stream; um status 200 não prova sucesso, porque uma falha pode chegar como um evento de erro dentro do stream.
5. Adicione function calling: passe `tools` (type "function", com name, description e `parameters` em JSON schema) e `tool_choice` ("auto", "required" ou um objeto nomeando uma função). Quando o modelo devolver tool calls, execute a função e envie o resultado de volta como uma mensagem de tool.
6. Teste: rode a chamada com streaming com o prompt "Count to five." e me mostre a saída. Se o function calling estiver ligado, pergunte "What's the weather in Lisbon?" com uma tool get_weather e me mostre a tool call.
Regras:
1. A base URL é https://api.bayle.ai exatamente como está escrita. Não acrescente nenhum caminho a ela.
2. Leia a key da variável de ambiente BAYLE_API_KEY. Nunca escreva a key em um arquivo que você criar, em um comando, em um commit nem no chat. Onde a ferramenta guarda a key na própria tela de configurações, me diga onde colar. Se BAYLE_API_KEY não estiver definida, pare e peça que eu crie uma key em https://chat.bayle.ai/developers e a exporte.
3. Pegue os ids de modelo só de GET https://api.bayle.ai/models (sem key). Nunca chute um.
4. Termine com uma requisição de teste de verdade, me mostre o resultado e liste os arquivos que você alterou.Uma completion básica
Seção intitulada “Uma completion básica”completion = client.chat.completions.create( model="MODEL_ID", messages=[ {"role": "system", "content": "You are terse."}, {"role": "user", "content": "Why is the sky blue?"}, ], temperature=0.7, max_tokens=200,)print(completion.choices[0].message.content)const completion = await client.chat.completions.create({ model: 'MODEL_ID', messages: [ { role: 'system', content: 'You are terse.' }, { role: 'user', content: 'Why is the sky blue?' }, ], temperature: 0.7, max_tokens: 200,})console.log(completion.choices[0].message.content)curl https://api.bayle.ai/chat/completions \ -H "Authorization: Bearer $BAYLE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "MODEL_ID", "messages": [ {"role": "system", "content": "You are terse."}, {"role": "user", "content": "Why is the sky blue?"} ], "temperature": 0.7, "max_tokens": 200 }'Mensagens de sistema
Seção intitulada “Mensagens de sistema”A API não adiciona nenhuma mensagem de sistema nem outras instruções próprias: uma requisição chega ao modelo com exatamente as mensagens que você envia. Você pode enviar a sua própria mensagem de sistema, como o exemplo acima faz, ou nenhuma.
O chat web da Bayle (chat.bayle.ai) é um cliente desta API e adiciona uma mensagem de sistema da Bayle às suas próprias requisições de conversa. Essa mensagem pertence ao chat, não à API: uma requisição que você envia para POST /chat/completions nunca a carrega.
Streaming
Seção intitulada “Streaming”Defina stream como true e a resposta passa a ser um text/event-stream em vez de um único
corpo JSON.
stream = client.chat.completions.create( model="MODEL_ID", messages=[{"role": "user", "content": "Count to five."}], stream=True,)for chunk in stream: delta = chunk.choices[0].delta.content if chunk.choices else None if delta: print(delta, end="", flush=True)const stream = await client.chat.completions.create({ model: 'MODEL_ID', messages: [{ role: 'user', content: 'Count to five.' }], stream: true,})for await (const chunk of stream) { process.stdout.write(chunk.choices[0]?.delta?.content ?? '')}curl -N https://api.bayle.ai/chat/completions \ -H "Authorization: Bearer $BAYLE_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "MODEL_ID", "messages": [{"role": "user", "content": "Count to five."}], "stream": true}'Como é o stream
Seção intitulada “Como é o stream”Uma linha data: por evento, cada uma carregando um objeto JSON, separadas por linhas em branco,
terminando com um marcador final data: [DONE].
data: {"id":"...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}
data: {"id":"...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"One"},"finish_reason":null}]}
data: {"id":"...","object":"chat.completion.chunk","choices":[],"usage":{"prompt_tokens":12,"completion_tokens":8,"total_tokens":20},"cost":{"usd":0.00002,"diem":0.0}}
data: [DONE]Duas coisas sobre o final de um stream valem a pena ser tratadas no seu código.
O penúltimo evento é um evento de uso: choices vem vazio e usage vem preenchido. Código
que assume que todo evento tem um choices[0] vai quebrar nele. Um SDK trata isso para você.
Se a geração falhar no meio do caminho, você recebe um evento de erro dentro do stream em vez de um corpo truncado. Ele carrega o mesmo envelope de erro de uma falha não-streaming, e chega antes do marcador final.
Function calling
Seção intitulada “Function calling”Passe tools, e opcionalmente tool_choice para direcionar a decisão.
completion = client.chat.completions.create( model="MODEL_ID", messages=[{"role": "user", "content": "What's the weather in Lisbon?"}], tools=[ { "type": "function", "function": { "name": "get_weather", "description": "Look up current weather for a city.", "parameters": { "type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"], }, }, } ], tool_choice="auto",)tool_choice aceita três formas: "auto", "required", ou um objeto nomeando uma função,
{"type": "function", "function": {"name": "get_weather"}}.
Ferramentas embutidas são indicadas só pelo tipo, sem corpo de função:
{"tools": [{"type": "web_search"}]}O content de uma mensagem pode ser um array de partes em vez de uma string. Misture texto e
imagens livremente.
completion = client.chat.completions.create( model="VISION_MODEL_ID", messages=[ { "role": "user", "content": [ {"type": "text", "text": "What is in this image?"}, {"type": "image_url", "image_url": {"url": "https://example.com/photo.jpg"}}, ], } ],)A url pode ser uma URL https pública ou uma data: URI, então um arquivo local funciona uma vez
codificado em base64:
import base64, pathlib
encoded = base64.b64encode(pathlib.Path("photo.jpg").read_bytes()).decode()image_part = {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{encoded}"}}Use um modelo cujo type suporte vision. Liste os modelos para achar um.