Recherche Web intégrée
Définissez web_search: true et le modèle fonde sa réponse sur des résultats en direct.
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="shannon-3",
messages=[{"role": "user", "content": "What is the weather forecast for Lisbon this weekend?"}],
extra_body={"web_search": True}, # a Shannon field, so it goes in extra_body
)
print(response.choices[0].message.content) 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: "What is the weather forecast for Lisbon this weekend?" }],
web_search: true,
});
console.log(response.choices[0].message.content); 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": "What is the weather forecast for Lisbon this weekend?"}
],
"web_search": true
}' La réponse est une chat completion ordinaire avec deux ajouts. La réponse renvoie aux résultats de recherche par des numéros entre crochets, sources dit ce que représente chaque numéro, et annotations marque où chacun est cité :
{
"id": "chatcmpl-3e5a7c9b1d2f4a6c8e0b2d4f6a8c1e3b",
"object": "chat.completion",
"created": 1791590400,
"model": "shannon-3",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Saturday in Lisbon is forecast to be sunny with a high near 24 °C [1]. Sunday turns cloudy, with a chance of light rain in the afternoon [2].",
"reasoning_content": null,
"annotations": [
{
"type": "url_citation",
"url_citation": {
"start_index": 66,
"end_index": 69,
"url": "https://weather.example/lisbon/weekend",
"title": "Lisbon weather: weekend outlook"
}
},
{
"type": "url_citation",
"url_citation": {
"start_index": 137,
"end_index": 140,
"url": "https://forecast.example/pt/lisbon/sunday",
"title": "Sunday forecast for Lisbon"
}
}
]
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 2874,
"completion_tokens": 41,
"total_tokens": 2915
},
"sources": [
{
"index": 1,
"title": "Lisbon weather: weekend outlook",
"url": "https://weather.example/lisbon/weekend"
},
{
"index": 2,
"title": "Sunday forecast for Lisbon",
"url": "https://forecast.example/pt/lisbon/sunday"
},
{
"index": 3,
"title": "Portugal: the week ahead",
"url": "https://news.example/portugal/weather-week"
}
]
} Activer la recherche
La recherche est un champ de la requête, désactivé par défaut. Rien n'est recherché tant qu'une requête ne l'envoie pas.
| Champ | Type | Par défaut | Description | Appliqué par |
|---|---|---|---|---|
web_search | boolean | false | true lance une recherche web pour cette requête et donne les résultats au modèle avant qu'il réponde. | Chaque modèle Shannon sauf shannon-coder-1 |
| Point de terminaison | Recherche web | Comment |
|---|---|---|
/v1/chat/completions | Oui | "web_search": true dans le corps de la requête. |
/v1/messages | Oui | "web_search": true dans le corps de la requête. |
/v1/responses | — | Ce point de terminaison répond à partir du modèle seul. Utilisez l'un des deux ci-dessus pour une réponse avec recherche. |
Sur /v1/messages, le champ se place au niveau supérieur du corps, à côté de model et messages :
{
"model": "shannon-3",
"web_search": true,
"messages": [
{
"role": "user",
"content": "What is the weather forecast for Lisbon this weekend?"
}
]
} Ce que fait une requête avec recherche
- L'API cherche sur le web à partir du dernier message de l'utilisateur. Les tours précédents de la conversation donnent son contexte à la recherche.
- La recherche s'exécute à chaque requête qui envoie
web_search: true. Le modèle ne choisit pas s'il doit chercher. - Les résultats sont présentés au modèle comme des sources numérotées, et le modèle écrit sa réponse à partir d'eux.
- La réponse commence quand la recherche est terminée. Une requête en streaming n'envoie rien d'ici là, ni en-têtes ni événements, prévoyez donc une attente plus longue avant le premier chunk.
Ce que contient la réponse
- La réponse a la forme habituelle de son point de terminaison. La réponse est dans
choices[0].message.content(un bloctextsur/v1/messages). - Le texte peut porter des repères comme
[1]et[2]après les affirmations qu'ils appuient. Chaque numéro correspond à l'un des résultats lus par le modèle. sourcesnomme ces résultats : une entrée pour chaque résultat remis au modèle, avecindex,titleeturl. Le repère[1]est l'entrée dontindexvaut 1. Les résultats que la réponse ne cite pas sont aussi listés.- Sur
/v1/chat/completions, le message a aussiannotations, au format OpenAI : unurl_citationpour chaque source qu'un repère nomme, avecurl,title, ainsi questart_indexetend_index, la position du repère danscontentcomptée en caractères (la fin n'est pas incluse). - Dans un flux,
sourcesarrive avec le dernier chunk, et sur/v1/messagesavec l'événementmessage_delta. Les annotations arrivent dans un chunk juste avant le dernier, sous la formedelta.annotations. sourcesn'est présent que si la recherche de cette requête a trouvé quelque chose. Une réponse sans ce champ a été écrite sans résultats de recherche.
Comment les recherches sont comptées
Chaque forfait inclut un nombre de recherches par jour :
| Forfait | Recherches par jour |
|---|---|
| Gratuit | 3 |
| Plus | 30 |
| Standard | 50 |
| Pro | 60 |
- Une requête dont la recherche a trouvé quelque chose utilise une recherche de l'allocation du jour. Une recherche qui n'a rien trouvé n'en utilise aucune.
- Le chat et l'API partagent l'allocation du compte propriétaire de la clé.
- Le décompte repart de zéro chaque jour à 00:00 UTC.
- Les résultats de recherche sont des tokens d'entrée de la requête et sont facturés avec le reste du prompt.
Quand les recherches du jour sont épuisées
Une requête qui envoie web_search: true après la dernière recherche du jour n'est pas refusée. Elle reçoit une réponse sans recherche : le statut est 200 et la réponse n'a pas de sources.
La recherche comme outil personnel
web_search: true est le seul interrupteur de la recherche décrite ici. Une fonction que vous définissez dans tools et nommez web_search est un de vos propres outils : le modèle renvoie un appel, et votre code lance la recherche et renvoie le résultat.
Les types d'outil de recherche d'autres plateformes, comme web_search_20250305 sur /v1/messages ou {"type": "web_search"} sur /v1/responses, ne lancent pas de recherche ici.
Erreurs
La recherche web n'ajoute aucun code de statut ni type d'erreur. Une recherche qui ne trouve rien, ou un jour sans recherche restante, donne une réponse normale sans résultats de recherche. Toutes les autres erreurs sont les mêmes que pour une requête sans recherche. Gestion des erreurs