SDK
N'importe quel SDK OpenAI ou Anthropic fonctionne tel quel.
Shannon parle les formats OpenAI et Anthropic sur le réseau, donc vous utilisez tels quels les SDK officiels des deux. Vous changez trois valeurs dans le client : l'URL de base, la clé API et l'id du modèle. Le reste de votre code ne change pas.
Ce qu'il faut régler
| Réglage | SDK OpenAI | SDK Anthropic |
|---|---|---|
| URL de base | https://api.shannon-ai.com/v1 | https://api.shannon-ai.com |
| Clé API | Votre clé Shannon. Le SDK l'envoie comme Authorization: Bearer. | Votre clé Shannon. Le SDK l'envoie comme x-api-key. |
| Modèle | Un id de modèle publié, par exemple shannon-3. | Un id de modèle publié, par exemple shannon-1.6-lite. |
| Points de terminaison atteints | /v1/chat/completions, /v1/responses, /v1/models | /v1/messages, /v1/messages/count_tokens |
| Variables d'environnement | OPENAI_API_KEY et OPENAI_BASE_URL, lues par les SDK Python et JavaScript quand vous ne passez aucune valeur. | ANTHROPIC_API_KEY et ANTHROPIC_BASE_URL, lues par les SDK Python et TypeScript quand vous ne passez aucune valeur. |
Les deux URL de base diffèrent par /v1 : un SDK OpenAI ajoute /chat/completions à son URL de base, un SDK Anthropic ajoute /v1/messages. Un nom de modèle que Shannon ne publie pas reçoit la réponse 400 avec unknown model. Modèles et tarifs
Votre clé se trouve sur la page Clés et utilisation. Clés et utilisation
SDK OpenAI
Les SDK OpenAI officiels appellent POST /v1/chat/completions et POST /v1/responses. Chaque exemple envoie un message d'utilisateur et affiche la réponse.
# pip install openai
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="shannon-3",
messages=[{"role": "user", "content": "Hello, Shannon!"}],
)
print(response.choices[0].message.content) // npm install openai
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: "shannon-3",
messages: [{ role: "user", content: "Hello, Shannon!" }],
});
console.log(response.choices[0].message.content); // go get github.com/openai/openai-go/v3
package main
import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/option"
)
func main() {
client := openai.NewClient(
option.WithAPIKey("YOUR_API_KEY"),
option.WithBaseURL("https://api.shannon-ai.com/v1/"),
)
completion, err := client.Chat.Completions.New(context.TODO(), openai.ChatCompletionNewParams{
Model: "shannon-3",
Messages: []openai.ChatCompletionMessageParamUnion{
openai.UserMessage("Hello, Shannon!"),
},
})
if err != nil {
panic(err)
}
fmt.Println(completion.Choices[0].Message.Content)
} // Gradle: implementation("com.openai:openai-java:<version>")
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.chat.completions.ChatCompletion;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
OpenAIClient client = OpenAIOkHttpClient.builder()
.apiKey("YOUR_API_KEY")
.baseUrl("https://api.shannon-ai.com/v1")
.build();
ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.model("shannon-3")
.addUserMessage("Hello, Shannon!")
.build();
ChatCompletion completion = client.chat().completions().create(params);
completion.choices().get(0).message().content().ifPresent(System.out::println); // dotnet add package OpenAI
using System.ClientModel;
using OpenAI;
using OpenAI.Chat;
ChatClient client = new(
model: "shannon-3",
credential: new ApiKeyCredential("YOUR_API_KEY"),
options: new OpenAIClientOptions()
{
Endpoint = new Uri("https://api.shannon-ai.com/v1")
});
ChatCompletion completion = client.CompleteChat("Hello, Shannon!");
Console.WriteLine(completion.Content[0].Text); | Langage | Installation | Option d'URL de base | Source |
|---|---|---|---|
| Python | pip install openai | base_url | openai/openai-python |
| JavaScript / TypeScript | npm install openai | baseURL | openai/openai-node |
| Go | go get github.com/openai/openai-go/v3 | option.WithBaseURL | openai/openai-go |
| Java | com.openai:openai-java | baseUrl | openai/openai-java |
| .NET | dotnet add package OpenAI | OpenAIClientOptions.Endpoint | openai/openai-dotnet |
Chaque champ des deux points de terminaison est décrit sur leurs propres pages. Chat Completions API Responses
SDK Anthropic
Les SDK Anthropic officiels appellent POST /v1/messages. Ils exigent max_tokens à chaque appel, donc les exemples utilisent shannon-1.6-lite, qui l'applique. Chaque exemple affiche les blocs de texte de la réponse.
# pip install anthropic
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com",
)
message = client.messages.create(
model="shannon-1.6-lite",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Shannon!"}],
)
for block in message.content:
if block.type == "text":
print(block.text) // npm install @anthropic-ai/sdk
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-1.6-lite",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello, Shannon!" }],
});
for (const block of message.content) {
if (block.type === "text") console.log(block.text);
} // go get github.com/anthropics/anthropic-sdk-go
package main
import (
"context"
"fmt"
"github.com/anthropics/anthropic-sdk-go"
"github.com/anthropics/anthropic-sdk-go/option"
)
func main() {
client := anthropic.NewClient(
option.WithAPIKey("YOUR_API_KEY"),
option.WithBaseURL("https://api.shannon-ai.com/"),
)
message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
Model: "shannon-1.6-lite",
MaxTokens: 1024,
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock("Hello, Shannon!")),
},
})
if err != nil {
panic(err)
}
for _, block := range message.Content {
if block.Type == "text" {
fmt.Println(block.Text)
}
}
} // Gradle: implementation("com.anthropic:anthropic-java:<version>")
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
AnthropicClient client = AnthropicOkHttpClient.builder()
.apiKey("YOUR_API_KEY")
.baseUrl("https://api.shannon-ai.com")
.build();
MessageCreateParams params = MessageCreateParams.builder()
.model("shannon-1.6-lite")
.maxTokens(1024L)
.addUserMessage("Hello, Shannon!")
.build();
Message message = client.messages().create(params);
message.content().stream()
.flatMap(block -> block.text().stream())
.forEach(text -> System.out.println(text.text())); | Langage | Installation | Option d'URL de base | Source |
|---|---|---|---|
| Python | pip install anthropic | base_url | anthropics/anthropic-sdk-python |
| TypeScript | npm install @anthropic-ai/sdk | baseURL | anthropics/anthropic-sdk-typescript |
| Go | go get github.com/anthropics/anthropic-sdk-go | option.WithBaseURL | anthropics/anthropic-sdk-go |
| Java | com.anthropic:anthropic-java | baseUrl | anthropics/anthropic-sdk-java |
Le format Messages et ses différences sont sur la page de compatibilité Anthropic. Format anthropique
Ce sur quoi les SDK peuvent compter
- Un champ de requête que l'API n'utilise pas est accepté. Un champ que l'API connaît, envoyé avec un mauvais type, reçoit la réponse
422. - Les en-têtes de version et de beta que les SDK ajoutent (
anthropic-version,anthropic-beta,openai-beta) sont acceptés. Aucun n'est obligatoire. - Le
modeld'une réponse est l'id publié, donc vous pouvez le renvoyer tel quel. - Sur
/v1/messages, une réponse peut commencer par un blocthinking. Lisez les blocs de typetextau lieu de prendre le premier bloc. - Le streaming fonctionne avec les helpers de flux propres au SDK. L'utilisation arrive à la fin de chaque flux.
- Chaque réponse porte un en-tête
x-request-id. Envoyez votre proprex-request-idet la même valeur revient.
SDK de la communauté
Les clients écrits pour l'API OpenAI par d'autres auteurs fonctionnent de la même façon : donnez au client l'URL de base avec /v1, votre clé et un id de modèle Shannon. Ils sont maintenus par leurs auteurs, pas par Shannon.
| Langage | Installation | Client |
|---|---|---|
| Go | go get github.com/sashabaranov/go-openai | sashabaranov/go-openai |
| Ruby | gem install ruby-openai | alexrudall/ruby-openai |
| PHP | composer require openai-php/client | openai-php/client |
| Rust | cargo add async-openai | 64bit/async-openai |
Sans SDK
Vous n'avez pas besoin d'un SDK. Tout client HTTP capable d'envoyer du JSON fonctionne :
POSTavec un corps JSON et l'en-têteContent-Type: application/json. Sans lui, la requête reçoit la réponse415.- Votre clé dans
Authorization: Bearer <key>ou dansx-api-key: <key>. Les deux fonctionnent sur chaque point de terminaison. - Un corps jusqu'à 32 MiB.
- Avec
"stream": true, la réponse est un flux de server-sent events (text/event-stream). Lisez-la ligne par ligne et ne la mettez pas en tampon. - Une erreur est un corps JSON avec
error.typeeterror.message, accompagné du statut HTTP.
curl https://api.shannon-ai.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "shannon-3",
"messages": [{"role": "user", "content": "Hello, Shannon!"}]
}' import requests
response = requests.post(
"https://api.shannon-ai.com/v1/chat/completions",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"model": "shannon-3",
"messages": [{"role": "user", "content": "Hello, Shannon!"}],
},
)
response.raise_for_status()
print(response.json()["choices"][0]["message"]["content"]) const response = await fetch("https://api.shannon-ai.com/v1/chat/completions", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "shannon-3",
messages: [{ role: "user", content: "Hello, Shannon!" }],
}),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
console.log(data.choices[0].message.content); Pour les événements d'un flux et les types d'erreur, voir : Diffusion en continu Gestion des erreurs