Effort de raisonnement
NouveauUn modèle qui raisonne renvoie son texte de raisonnement à côté de la réponse, dans un champ distinct. Sur les modèles open-weight hébergés, un champ de requête règle la profondeur avec laquelle le modèle raisonne avant de répondre.
POST https://api.shannon-ai.com/v1/chat/completions
from openai import OpenAI
client = OpenAI(api_key="YOUR_API_KEY", base_url="https://api.shannon-ai.com/v1")
response = client.chat.completions.create(
model="Kimi-K3-3BIT-REAP",
reasoning_effort="low",
messages=[{"role": "user", "content": "Is 221 a prime number?"}],
)
message = response.choices[0].message
print("Reasoning:", getattr(message, "reasoning_content", None))
print("Answer:", message.content)
print("Reasoning tokens:", response.usage.completion_tokens_details.reasoning_tokens) import OpenAI from "openai";
const client = new OpenAI({ apiKey: "YOUR_API_KEY", baseURL: "https://api.shannon-ai.com/v1" });
const response = await client.chat.completions.create({
model: "Kimi-K3-3BIT-REAP",
reasoning_effort: "low",
messages: [{ role: "user", content: "Is 221 a prime number?" }],
});
const message = response.choices[0].message;
console.log("Reasoning:", message.reasoning_content);
console.log("Answer:", message.content);
console.log("Reasoning tokens:", response.usage.completion_tokens_details.reasoning_tokens); curl https://api.shannon-ai.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "Kimi-K3-3BIT-REAP",
"reasoning_effort": "low",
"messages": [
{"role": "user", "content": "Is 221 a prime number?"}
]
}' La réponse porte le texte de raisonnement dans reasoning_content, la réponse dans content, et les tokens de raisonnement dans usage :
{
"id": "chatcmpl-2a6c8e0b4d1f4a3c9e7b5d3f1a8c6e4b",
"object": "chat.completion",
"created": 1791590400,
"model": "Kimi-K3-3BIT-REAP",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "No. 221 = 13 x 17, so it is not prime.",
"reasoning_content": "Try small primes. 221 / 13 = 17, so 221 = 13 x 17."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 14,
"completion_tokens": 43,
"total_tokens": 57,
"prompt_tokens_details": {"cached_tokens": 0},
"completion_tokens_details": {"reasoning_tokens": 27}
}
} Quels modèles raisonnent
| Modèle | Renvoie le texte de raisonnement | Applique le champ d'effort |
|---|---|---|
shannon-1.6-lite | — | — |
shannon-1.6-pro, shannon-2-lite, shannon-2-pro, shannon-3, shannon-3-pro, shannon-3.1, shannon-3.1-pro, shannon-coder-1 | Oui | — |
| Chaque modèle open-weight hébergé | Oui | Oui |
Ce sont les indicateurs capabilities.reasoning et capabilities.reasoning_effort que GET /v1/models renvoie pour chaque id. Une réponse ne porte du texte de raisonnement que si le modèle en a produit. Modèles et tarifs
Régler l'effort
Chaque point de terminaison a sa propre écriture de l'effort. Toutes choisissent l'un des mêmes quatre niveaux.
| Champ | Type | Par défaut | Description | Appliqué par |
|---|---|---|---|---|
reasoning_effort | string | high | /v1/chat/completions. La profondeur avec laquelle le modèle raisonne avant de répondre : off, low, medium ou high. | Modèles open-weight hébergés |
reasoning | object | string | /v1/chat/completions. La même valeur, sous la forme {"effort": "low"} ou d'une simple chaîne. Quand les deux champs sont envoyés, reasoning_effort l'emporte. | Modèles open-weight hébergés | |
reasoning.effort | string | high | /v1/responses. Écrit comme l'objet {"effort": "low"}. | Modèles open-weight hébergés |
thinking | object | /v1/messages. {"type": "enabled", "budget_tokens": n} ou {"type": "disabled"}. Le budget choisit l'un des niveaux ; voir le tableau plus bas. | Modèles open-weight hébergés |
{
"model": "Kimi-K3-3BIT-REAP",
"reasoning_effort": "low",
"messages": [{"role": "user", "content": "Is 221 a prime number?"}]
} {
"model": "Kimi-K3-3BIT-REAP",
"reasoning": {"effort": "low"},
"input": "Is 221 a prime number?"
} {
"model": "Kimi-K3-3BIT-REAP",
"max_tokens": 1024,
"thinking": {"type": "enabled", "budget_tokens": 2048},
"messages": [{"role": "user", "content": "Is 221 a prime number?"}]
} | Valeur | Aussi accepté | Effet |
|---|---|---|
off | none, minimal | Pas de raisonnement. La réponse ne porte aucun texte de raisonnement. |
low | Raisonnement bref. | |
medium | default | Profondeur moyenne. |
high | max | Le niveau le plus profond. C'est le niveau d'une requête qui n'envoie aucune valeur. |
- Les valeurs sont lues sans tenir compte des majuscules et des minuscules.
- La valeur
defaultsignifiemedium. Omettre le champ signifiehigh. - Les modèles Shannon (
shannon-*) fixent eux-mêmes leur profondeur à chaque requête ;GET /v1/modelsindiquereasoning_effort: falsepour eux.
Le budget de réflexion sur /v1/messages
Sur /v1/messages, le champ thinking choisit le niveau. budget_tokens désigne l'un des niveaux ci-dessus ; ce n'est pas une limite de tokens en soi. adaptive est lu comme enabled.
| Vous envoyez | Niveau |
|---|---|
{"type": "disabled"} | off |
{"type": "enabled", "budget_tokens": n} avec n jusqu'à 2,048 | low |
n de 2,049 à 8,192 | medium |
Un n plus grand, ou enabled sans budget_tokens | high |
Pas de champ thinking | high |
Où arrive le texte de raisonnement
Le texte de raisonnement est toujours séparé de la réponse. Chaque format a sa propre place pour lui :
| Point de terminaison | Sans streaming | Avec streaming |
|---|---|---|
/v1/chat/completions | choices[0].message.reasoning_content : une chaîne, ou null quand le modèle n'en a produit aucune. | Des chunks avec choices[0].delta.reasoning_content, avant les chunks avec delta.content. |
/v1/responses | Un élément d'output {"type": "reasoning", "summary": [{"type": "summary_text", "text": "…"}]} avant l'élément message. Pas d'élément quand il n'y a pas de raisonnement. | response.output_item.added avec un élément reasoning, puis des événements response.reasoning_summary_text.delta et un response.reasoning_summary_text.done. |
/v1/messages | Un premier bloc de contenu {"type": "thinking", "thinking": "…"}, puis le bloc text. Pas de bloc thinking quand il n'y a pas de raisonnement. | Un bloc de contenu thinking : content_block_start, des événements content_block_delta avec thinking_delta, content_block_stop. Le bloc de texte suit. |
{
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "No. 221 = 13 x 17, so it is not prime.",
"reasoning_content": "Try small primes. 221 / 13 = 17, so 221 = 13 x 17."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 14,
"completion_tokens": 43,
"total_tokens": 57,
"prompt_tokens_details": {"cached_tokens": 0},
"completion_tokens_details": {"reasoning_tokens": 27}
}
} {
"output": [
{
"id": "rs_6f0a2c4e8b1d4f3a9c7e5b3d1f8a6c4e",
"type": "reasoning",
"summary": [
{
"type": "summary_text",
"text": "Try small primes. 221 / 13 = 17, so 221 = 13 x 17."
}
]
},
{
"id": "msg_1b3d5f7a9c2e4b6d8f0a2c4e6b8d0f1a",
"type": "message",
"role": "assistant",
"status": "completed",
"content": [
{
"type": "output_text",
"text": "No. 221 = 13 x 17, so it is not prime.",
"annotations": []
}
]
}
],
"usage": {
"input_tokens": 14,
"input_tokens_details": {"cached_tokens": 0},
"output_tokens": 43,
"output_tokens_details": {"reasoning_tokens": 27},
"total_tokens": 57
}
} {
"content": [
{
"type": "thinking",
"thinking": "Try small primes. 221 / 13 = 17, so 221 = 13 x 17."
},
{"type": "text", "text": "No. 221 = 13 x 17, so it is not prime."}
],
"stop_reason": "end_turn",
"usage": {
"input_tokens": 14,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 0,
"output_tokens": 43
}
} Où regarder, par modèle :
| Modèles | Où arrive le texte |
|---|---|
| Modèles open-weight hébergés | Sur chaque point de terminaison, avec ou sans streaming. Une requête avec l'effort off, ou avec response_format / text.format, reçoit une réponse sans texte de raisonnement. |
shannon-3, shannon-3-pro, shannon-3.1, shannon-3.1-pro | Sur chaque point de terminaison, avec ou sans streaming, chaque fois que le modèle a produit du texte de raisonnement. |
shannon-2-lite, shannon-2-pro | /v1/chat/completions, sans streaming : dans message.reasoning_content. Avec streaming, dans une requête sans tools ni response_format : le flux porte des lignes de commentaire : thinking pendant que le modèle raisonne, puis les chunks de la réponse. /v1/messages, avec streaming : un bloc thinking avant le bloc de texte. |
shannon-1.6-pro, shannon-coder-1 | Dans les réponses en streaming et dans les réponses aux requêtes qui portent tools, chaque fois que le modèle a produit du texte de raisonnement. |
Sur /v1/responses, une réponse sans streaming porte l'élément reasoning pour la famille Shannon 3 et les modèles open-weight hébergés.
Lire un flux
Dans un flux, le texte de raisonnement vient en premier, dans ses propres deltas, et la réponse suit. Affichez ou stockez les deux séparément :
from openai import OpenAI
client = OpenAI(api_key="YOUR_API_KEY", base_url="https://api.shannon-ai.com/v1")
stream = client.chat.completions.create(
model="Kimi-K3-3BIT-REAP",
reasoning_effort="medium",
stream=True,
messages=[{"role": "user", "content": "Is 221 a prime number?"}],
)
for chunk in stream:
if not chunk.choices:
continue
delta = chunk.choices[0].delta
reasoning = getattr(delta, "reasoning_content", None)
if reasoning:
print(reasoning, end="", flush=True) # the reasoning text comes first
if delta.content:
print(delta.content, end="", flush=True) # then the answer import OpenAI from "openai";
const client = new OpenAI({ apiKey: "YOUR_API_KEY", baseURL: "https://api.shannon-ai.com/v1" });
const stream = await client.chat.completions.create({
model: "Kimi-K3-3BIT-REAP",
reasoning_effort: "medium",
stream: true,
messages: [{ role: "user", content: "Is 221 a prime number?" }],
});
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta ?? {};
if (delta.reasoning_content) process.stdout.write(delta.reasoning_content); // the reasoning text comes first
if (delta.content) process.stdout.write(delta.content); // then the answer
} curl -N https://api.shannon-ai.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "Kimi-K3-3BIT-REAP",
"reasoning_effort": "medium",
"stream": true,
"messages": [
{"role": "user", "content": "Is 221 a prime number?"}
]
}' Le premier chunk d'un modèle open-weight hébergé, raisonnement ou réponse, porte aussi delta.role: "assistant". Diffusion en continu
Tokens de raisonnement et facturation
Sur les modèles open-weight hébergés, les tokens de raisonnement sont des tokens de sortie : ils sont facturés au prix de sortie du modèle, et le décompte de sortie les inclut déjà. usage indique ici la part du raisonnement :
| Point de terminaison | Champ | Remarque |
|---|---|---|
/v1/chat/completions | usage.completion_tokens_details.reasoning_tokens | Déjà inclus dans completion_tokens. |
/v1/responses | usage.output_tokens_details.reasoning_tokens | Déjà inclus dans output_tokens. |
/v1/messages | usage.output_tokens | Raisonnement et réponse ensemble. Ce format n'a pas de décompte séparé. |
- Sur les modèles open-weight hébergés,
max_tokenslimite le texte de la réponse. Les tokens de raisonnement n'y sont pas comptés. - Comme le raisonnement est facturé comme de la sortie, le niveau d'effort est aussi un réglage de coût :
offne produit aucun token de raisonnement. - Les modèles Shannon renvoient
prompt_tokens,completion_tokensettotal_tokens(input_tokensetoutput_tokenssur/v1/messages) sans part de raisonnement, et facturent un prix unique par token. Modèles et tarifs
Le raisonnement dans la requête suivante
Vous n'avez pas besoin de renvoyer le raisonnement. Un bloc thinking ou un élément reasoning dans la conversation que vous envoyez n'est pas transmis au modèle, donc un tour de l'assistant peut revenir avec ou sans lui. Un bloc thinking a les deux champs type et thinking ; il n'a pas de signature.
Erreurs
| Statut | Type | Message | Quand |
|---|---|---|---|
400 | invalid_request_error | unknown reasoning effort '<value>'; expected off, low, medium or high | Un modèle open-weight hébergé a reçu une valeur hors de la liste, par exemple xhigh. Rien n'est prélevé sur votre solde. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | reasoning_effort n'est pas une chaîne. |
Les erreurs d'authentification, de solde et de serveur sont les mêmes que pour toute requête. Gestion des erreurs