Formato Anthropic
POST /v1/messages accetta una richiesta nel formato Anthropic Messages e risponde nello stesso formato, in streaming o no. Usalo con l'SDK Anthropic e con gli strumenti costruiti su di esso, come Claude Code: imposta l'URL di base, usa la tua chiave API di Shannon e indica un id di modello Shannon.
POST https://api.shannon-ai.com/v1/messages
Punta l'SDK Anthropic sull'URL di base di Shannon. L'SDK aggiunge /v1/messages e invia la tua chiave nell'header x-api-key.
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com",
)
message = client.messages.create(
model="shannon-3",
max_tokens=1024,
messages=[{"role": "user", "content": "Say hello in one sentence."}],
)
for block in message.content:
if block.type == "text":
print(block.text) import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com",
});
const message = await client.messages.create({
model: "shannon-3",
max_tokens: 1024,
messages: [{ role: "user", content: "Say hello in one sentence." }],
});
for (const block of message.content) {
if (block.type === "text") console.log(block.text);
} curl https://api.shannon-ai.com/v1/messages \
-H "x-api-key: YOUR_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "shannon-3",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Say hello in one sentence."}]
}' La risposta è un messaggio il cui content è un elenco di blocchi. Riconosci i blocchi dal loro type: quando il modello ha ragionato, il primo blocco è thinking e il testo viene dopo.
{
"id": "msg_5f0c1e7a9b3d4c62a8e1f07d2b46c9a3",
"type": "message",
"role": "assistant",
"model": "shannon-3",
"content": [
{
"type": "thinking",
"thinking": "The user wants a greeting in one sentence. Keep it short and friendly."
},
{
"type": "text",
"text": "Hello, it is good to meet you."
}
],
"stop_reason": "end_turn",
"usage": {
"input_tokens": 1184,
"output_tokens": 46
}
} Header
| Header | Valore | Descrizione |
|---|---|---|
x-api-key | YOUR_API_KEY | La tua chiave API. In alternativa è accettato Authorization: Bearer YOUR_API_KEY. |
content-type | application/json | Obbligatorio. |
anthropic-version | 2023-06-01 | Accettato, non obbligatorio. L'SDK Anthropic invia 2023-06-01; la risposta ha lo stesso formato qualunque sia il valore. |
anthropic-beta | Accettato, non obbligatorio. | |
x-request-id | Facoltativo. Un tuo id per la richiesta. Torna invariato nella risposta; senza di esso la risposta contiene un id di 12 caratteri esadecimali. |
Campi della richiesta
Solo messages è obbligatorio. La colonna Applicato da indica i modelli su cui un campo cambia la risposta. I modelli open-weight ospitati sono i dodici id dell'elenco dei modelli; la famiglia Shannon 3 è shannon-3, shannon-3-pro, shannon-3.1 e shannon-3.1-pro. Modelli e prezzi
| Campo | Tipo | Default | Descrizione | Applicato da |
|---|---|---|---|---|
model | string | shannon-1.6-lite | Un id di modello Shannon dall'elenco dei modelli. Invialo a ogni richiesta. La corrispondenza non distingue maiuscole e minuscole. Qualsiasi altro nome restituisce 400 unknown model, quindi uno strumento che invia propri nomi di modello va impostato su un id Shannon. | Tutti i modelli |
messages | array | Obbligatorio. La conversazione, dal messaggio più vecchio, con i ruoli user e assistant. Vedi Messaggi e blocchi di contenuto più sotto. | Tutti i modelli | |
system | string | array | Istruzioni per il modello: una stringa oppure un array di blocchi di testo. Vedi System prompt più sotto. | Modelli open-weight ospitati, shannon-1.6-*, shannon-2-*, shannon-coder-1 | |
max_tokens | integer | 4096 | Limite massimo della risposta, in token. Facoltativo su questo endpoint; l'SDK Anthropic lo invia sempre. Un valore fuori dall'intervallo da 1 a 65,536 viene riportato dentro l'intervallo. È anche la quantità messa da parte dal tuo saldo mentre la richiesta è in corso. | Modelli open-weight ospitati, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 |
stream | boolean | false | true invia la risposta come server-sent events. Vedi Streaming più sotto. | Tutti i modelli |
temperature | number | Temperatura di campionamento. Sui modelli open-weight ospitati i valori sono mantenuti tra 0 e 2. | Modelli open-weight ospitati, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 | |
top_p | number | Campionamento nucleus. | Modelli open-weight ospitati | |
stop_sequences | array | Fino a 4 stringhe. La risposta termina prima della prima che compare. stop_reason resta end_turn. | Modelli open-weight ospitati | |
tools | array | I tool che il modello può chiamare, ciascuno come {"name", "description", "input_schema"}. Vedi Tool più sotto. | Tutti i modelli | |
tool_choice | object | {"type": "auto"} lascia decidere il modello, {"type": "any"} lo obbliga a chiamare un tool, {"type": "tool", "name": "…"} lo obbliga a chiamare quel tool. | Modelli open-weight ospitati | |
thinking | object | Quanto ragiona il modello prima di rispondere. Vedi Thinking più sotto. | Modelli open-weight ospitati | |
web_search | boolean | false | Un'aggiunta di Shannon al formato: true permette al modello di cercare sul web prima di rispondere. | shannon-1.6-*, shannon-2-*, famiglia Shannon 3 |
Senza max_tokens il valore è 4,096, e 65,536 su shannon-coder-1.
metadata, top_k, service_tier e i marcatori cache_control sui blocchi vengono accettati, così il codice client esistente funziona senza modifiche. Non cambiano la risposta; la prompt caching sui modelli open-weight ospitati è automatica.
Una risposta JSON secondo uno schema si richiede con response_format su Chat Completions e con text.format su Responses. Output strutturati
Una richiesta con system prompt e thinking
Questa richiesta invia un system prompt, un budget di thinking, una temperatura e una sequenza di stop. Usa un modello open-weight ospitato, che li applica tutti.
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com",
)
message = client.messages.create(
model="DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
max_tokens=4096,
system="You are a physics teacher. Answer in two sentences.",
thinking={"type": "enabled", "budget_tokens": 2048},
temperature=0.3,
stop_sequences=["\n\n"],
messages=[{"role": "user", "content": "Why is the sky blue?"}],
)
for block in message.content:
if block.type == "thinking":
print("reasoning:", block.thinking)
elif block.type == "text":
print("answer:", block.text)
print(message.usage) import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com",
});
const message = await client.messages.create({
model: "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
max_tokens: 4096,
system: "You are a physics teacher. Answer in two sentences.",
thinking: { type: "enabled", budget_tokens: 2048 },
temperature: 0.3,
stop_sequences: ["\n\n"],
messages: [{ role: "user", content: "Why is the sky blue?" }],
});
for (const block of message.content) {
if (block.type === "thinking") console.log("reasoning:", block.thinking);
if (block.type === "text") console.log("answer:", block.text);
}
console.log(message.usage); curl https://api.shannon-ai.com/v1/messages \
-H "x-api-key: YOUR_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"max_tokens": 4096,
"system": "You are a physics teacher. Answer in two sentences.",
"thinking": {"type": "enabled", "budget_tokens": 2048},
"temperature": 0.3,
"stop_sequences": ["\n\n"],
"messages": [{"role": "user", "content": "Why is the sky blue?"}]
}' Sui modelli open-weight ospitati usage riporta i token letti dalla prompt cache separatamente dagli altri token di input.
{
"usage": {
"input_tokens": 31,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 0,
"output_tokens": 62
}
} System prompt
system è una stringa oppure un array di blocchi di testo nella forma [{"type": "text", "text": "…"}]. I testi dei blocchi vengono uniti con un'interruzione di riga.
Viene applicato dai modelli open-weight ospitati, da shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro e shannon-coder-1. Con un id della famiglia Shannon 3, inserisci nel messaggio dell'utente le istruzioni che devono valere.
Messaggi e blocchi di contenuto
Un messaggio ha un role, user o assistant, e un content. content è una stringa oppure un array di blocchi.
| Blocco | Descrizione | Disponibile su |
|---|---|---|
{"type": "text", "text": "…"} | Testo. | Tutti i modelli |
{"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": "…"}}{"type": "image", "source": {"type": "url", "url": "…"}} | Un'immagine in un messaggio user, in base64 o tramite URL. | Famiglia Shannon 3, shannon-1.6-lite, shannon-1.6-pro e i modelli open-weight ospitati che prevedono l'input di immagini |
{"type": "document", "source": {"type": "base64", "media_type": "application/pdf", "data": "…"}} | Un documento (PDF, Word, PowerPoint o Excel) in un messaggio user, in base64 o tramite URL. | Famiglia Shannon 3 |
{"type": "tool_use", "id": "toolu_…", "name": "…", "input": {…}} | In un messaggio assistant: una chiamata a un tool fatta dal modello in una risposta precedente. | Tutti i modelli |
{"type": "tool_result", "tool_use_id": "toolu_…", "content": "…"} | In un messaggio user: il risultato di quella chiamata. content è una stringa oppure un elenco di blocchi di testo. | Tutti i modelli |
Puoi rimandare così com'è il content di una risposta precedente: i blocchi text e tool_use vengono letti, i blocchi thinking vengono saltati.
Sui livelli Shannon, immagini e documenti vengono letti dall'ultimo messaggio user. Dimensioni e limiti hanno una pagina propria. Immagini e file
Thinking
I modelli open-weight ospitati associano thinking a uno sforzo di ragionamento. Senza il campo lo sforzo è alto.
| Forma | budget_tokens | Effetto |
|---|---|---|
{"type": "disabled"} | Nessun ragionamento. La risposta non ha un blocco thinking. | |
{"type": "enabled", "budget_tokens": 2048} | ≤ 2,048 | Sforzo basso. |
{"type": "enabled", "budget_tokens": 8192} | ≤ 8,192 | Sforzo medio. |
{"type": "enabled", "budget_tokens": 16000} | > 8,192 | Sforzo alto. |
Un modello che ragiona restituisce il proprio ragionamento come blocco {"type": "thinking", "thinking": "…"} prima del testo. Anche i livelli Shannon che ragionano lo inviano.
Gli sforzi sono descritti nella loro pagina. Sforzo di ragionamento
Tool
Un tool è una funzione eseguita dal tuo codice. Descrivi ciascuno con un name, una description e un input_schema. Quando il modello vuole un tool, la risposta contiene un blocco tool_use e stop_reason è tool_use.
La definizione di un tool in tools:
[
{
"name": "get_weather",
"description": "Current weather for a city.",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string"
}
},
"required": [
"city"
]
}
}
] Il content di una risposta che lo chiama:
[
{
"type": "text",
"text": ""
},
{
"type": "tool_use",
"id": "toolu_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"name": "get_weather",
"input": {
"city": "Paris"
}
}
] Esegui il tool, poi invia di nuovo la richiesta con la chiamata e un blocco tool_result aggiunti a messages:
[
{
"role": "user",
"content": "What is the weather in Paris?"
},
{
"role": "assistant",
"content": [
{
"type": "tool_use",
"id": "toolu_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"name": "get_weather",
"input": {
"city": "Paris"
}
}
]
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"content": "{\"temperature_c\": 18, \"sky\": \"cloudy\"}"
}
]
}
] tool_choice
| Forma | Effetto | Applicato da |
|---|---|---|
{"type": "auto"} | Il modello decide se chiamare un tool. È il valore predefinito. | Tutti i modelli |
{"type": "any"} | Il modello deve chiamare uno dei tool. | Modelli open-weight ospitati |
{"type": "tool", "name": "…"} | Il modello deve chiamare il tool indicato. | Modelli open-weight ospitati |
Vengono letti solo i tool con un input_schema. La ricerca web non è un tool su questo endpoint: imposta il campo web_search.
Il ciclo dei tool è descritto per intero nella sua pagina. Chiamata di funzioni
La risposta
| Campo | Tipo | Descrizione | Inviato da |
|---|---|---|---|
id | string | msg_ seguito da 32 caratteri esadecimali. | Tutti i modelli |
type | string | Sempre message. | Tutti i modelli |
role | string | Sempre assistant. | Tutti i modelli |
model | string | L'id canonico del modello che ha risposto. | Tutti i modelli |
content | array | I blocchi della risposta, in quest'ordine: thinking se il modello ha ragionato, text, poi un tool_use per ogni chiamata a un tool. | Tutti i modelli |
stop_reason | string | Perché la risposta è terminata. Vedi i valori qui sotto. | Tutti i modelli |
usage | object | input_tokens e output_tokens. | Tutti i modelli |
sources | array | Solo su una richiesta con web_search: true la cui ricerca ha trovato qualcosa: i risultati dati al modello, ciascuno con index, title e url. [1] nella risposta è la voce con index 1. In uno stream arriva con l'evento message_delta. | shannon-1.6-*, shannon-2-*, famiglia Shannon 3 |
usage.cache_read_input_tokens | integer | cache_read_input_tokens è la parte del prompt letta dalla cache; input_tokens è il resto. cache_creation_input_tokens è sempre 0. | Modelli open-weight ospitati |
Blocchi della risposta
| Blocco | Descrizione |
|---|---|
{"type": "thinking", "thinking": "…"} | Il ragionamento del modello. Non c'è il membro signature. |
{"type": "text", "text": "…"} | Il testo della risposta. Può essere vuoto quando la risposta è una chiamata a un tool. |
{"type": "tool_use", "id": "toolu_…", "name": "…", "input": {…}} | Una chiamata a un tool. input è un oggetto JSON. Rimanda il risultato con lo stesso id. |
stop_reason
| stop_reason | Descrizione | Inviato da |
|---|---|---|
end_turn | Il modello ha concluso la risposta, oppure è comparsa una delle tue stop_sequences. | Tutti i modelli |
tool_use | La risposta contiene una o più chiamate a tool. | Tutti i modelli |
max_tokens | La risposta è stata troncata al limite di output. | Famiglia Shannon 3, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1, negli stream |
Streaming
Imposta stream su true per i server-sent events. Ogni frame ha una riga event: con il nome dell'evento e una riga data: con un oggetto JSON che ripete il nome in type. Gli helper di stream dell'SDK Anthropic leggono questi eventi per te:
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com",
)
with client.messages.stream(
model="shannon-3",
max_tokens=1024,
messages=[{"role": "user", "content": "Explain server-sent events in three sentences."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
message = stream.get_final_message()
print()
print(message.stop_reason, message.usage) import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com",
});
const stream = client.messages.stream({
model: "shannon-3",
max_tokens: 1024,
messages: [{ role: "user", content: "Explain server-sent events in three sentences." }],
});
stream.on("text", (text) => process.stdout.write(text));
const message = await stream.finalMessage();
console.log("\n", message.stop_reason, message.usage); curl -N https://api.shannon-ai.com/v1/messages \
-H "x-api-key: YOUR_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "shannon-3",
"max_tokens": 1024,
"stream": true,
"messages": [{"role": "user", "content": "Explain server-sent events in three sentences."}]
}' Gli eventi, nell'ordine in cui arrivano:
| Evento | Dati | Quando |
|---|---|---|
message_start | message | Sempre per primo. message contiene l'id, il ruolo, il modello, un content vuoto e un usage che parte da zero. |
content_block_start | index, content_block | Si apre un blocco. content_block è un blocco text o thinking vuoto, oppure un blocco tool_use con il suo id e name. |
content_block_delta | index, delta {"type": "thinking_delta", "thinking"} | Un frammento del ragionamento, per un blocco thinking. |
content_block_delta | index, delta {"type": "text_delta", "text"} | Un frammento della risposta, per un blocco text. |
content_block_delta | index, delta {"type": "input_json_delta", "partial_json"} | Gli argomenti di una chiamata a un tool, completi in un solo delta, per un blocco tool_use. |
content_block_stop | index | Il blocco con questo index è completo. |
message_delta | delta {stop_reason, stop_sequence}, usage | La fine della risposta: delta.stop_reason e l'usage della richiesta. |
message_stop | Sempre per ultimo. |
I blocchi sono numerati con index nell'ordine in cui si aprono, e un blocco è completo prima che si apra il successivo. Leggi ogni blocco in base al suo tipo, non al suo numero: uno stream può aprire prima un blocco text vuoto, poi il blocco thinking, e consegnare la risposta in un blocco text successivo.
event: message_start
data: {"type":"message_start","message":{"id":"msg_5f0c…","type":"message","role":"assistant","model":"shannon-3","content":[],"usage":{"input_tokens":0,"output_tokens":0}}}
event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: content_block_start
data: {"type":"content_block_start","index":1,"content_block":{"type":"thinking","thinking":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"thinking_delta","thinking":"Three sentences: what it is, how it is framed, why it is used."}}
event: ping
data: {"type": "ping"}
event: content_block_stop
data: {"type":"content_block_stop","index":1}
event: content_block_start
data: {"type":"content_block_start","index":2,"content_block":{"type":"text","text":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":2,"delta":{"type":"text_delta","text":"Server-sent events let a server push text over one HTTP reply."}}
event: content_block_stop
data: {"type":"content_block_stop","index":2}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":1190,"output_tokens":84}}
event: message_stop
data: {"type":"message_stop"} Keep-alive
| Inviato da | Descrizione |
|---|---|
Famiglia Shannon 3, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 | Un evento ping con i dati {"type": "ping"}, ogni 15 secondi. |
| Modelli open-weight ospitati | Una riga di commento : keepalive, ogni 15 secondi mentre il modello lavora. |
Uno stream che fallisce
Un errore dopo l'avvio dello stream è un evento error con lo stesso corpo di una risposta di errore: {"type": "error", "error": {"type", "message"}}. Gli eventi di chiusura, message_delta e message_stop, seguono comunque. Considera la risposta fallita e invia di nuovo la richiesta.
Errori
Gli errori usano il corpo di errore di Anthropic: type è error e l'oggetto error contiene un type e un message. La tabella elenca ciò che questo endpoint restituisce più spesso. L'elenco completo, con cosa riprovare, ha una pagina propria. Gestione errori
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "unknown model: no-such-model"
}
} | Stato | Tipo | Messaggio | Quando |
|---|---|---|---|
401 | authentication_error | Missing authenticationInvalid API key | Non è stata inviata alcuna chiave API, oppure la chiave è sconosciuta o revocata. |
400 | invalid_request_error | unknown model: <id> | model non è un id di modello Shannon. |
400 | invalid_request_error | No user message provided | Livelli Shannon: la richiesta non contiene testo dell'utente né tools. |
400 | invalid_request_error | <id> does not accept image input | È stata inviata un'immagine a un modello open-weight ospitato senza input di immagini. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | messages manca, oppure un campo ha il tipo JSON sbagliato. |
429 | rate_limit_error | Quota exceeded. Upgrade your plan at shannon-ai.com/plan | max_tokens è maggiore di ciò che resta del tuo saldo. |
429 | rate_limit_error | Too many requests. Retry in <n>s. | Flood protection: più di 120 richieste in un minuto sul tuo account. |
429 | rate_limit_error | Shannon Coder call quota reached. Upgrade your plan at shannon-ai.com/plan | shannon-coder-1: le chiamate Shannon Coder del tuo piano per la finestra attuale di 4 ore sono esaurite. |
500 | server_error | The model backend failed to answer. Please retry. | Il modello non ha prodotto una risposta. Invia di nuovo la richiesta. |
502 | api_error | The model backend failed to answer. Please retry. | Il modello non ha prodotto una risposta. Invia di nuovo la richiesta. |
Conteggio dei token
POST /v1/messages/count_tokens accetta lo stesso corpo di una richiesta di messaggio (model, system, messages, tools) e restituisce {"input_tokens": n}: il numero di token di input che verrebbero addebitati per la richiesta. Funziona per i modelli open-weight ospitati, è gratuito e non viene contato dalla flood protection.
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com",
)
count = client.messages.count_tokens(
model="DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
system="You are a physics teacher. Answer in two sentences.",
messages=[{"role": "user", "content": "Why is the sky blue?"}],
)
print(count.input_tokens) import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com",
});
const count = await client.messages.countTokens({
model: "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
system: "You are a physics teacher. Answer in two sentences.",
messages: [{ role: "user", content: "Why is the sky blue?" }],
});
console.log(count.input_tokens); curl https://api.shannon-ai.com/v1/messages/count_tokens \
-H "x-api-key: YOUR_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"system": "You are a physics teacher. Answer in two sentences.",
"messages": [{"role": "user", "content": "Why is the sky blue?"}]
}'
# {"input_tokens": 31} Il conteggio ha una pagina propria, con l'endpoint a testo semplice e i limiti. Conteggio dei token