LLM
Implémenter la capacité LLM — chat, complétion, streaming, estimation des tokens, découverte dynamique de modèles.
Pour les fournisseurs de modèles d'IA (OpenAI, Anthropic, …). Implémente le chat / la complétion / le streaming et expose optionnellement un estimateur de tokens et un récupérateur de modèles dynamique.
Définir la capacité
import type { LLMCapabilityConfig } from "@scrydon/sdk-authoring/extensions/capabilities/llm";
const llmCapability: LLMCapabilityConfig = {
models: [
{
id: "my-model-v1",
pricing: { input: 3.0, output: 15.0 }, // per 1M tokens
contextWindow: 128000,
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: true,
nativeStructuredOutputs: true,
},
},
],
runtime: {
async executeRequest(request, executor, logger) {
const response = await fetch("https://api.example.com/v1/chat", {
method: "POST",
headers: {
Authorization: `Bearer ${request.apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: request.model,
messages: request.messages,
temperature: request.temperature,
}),
});
return await response.json();
},
},
tokenEstimator: {
avgCharsPerToken: 4,
estimate(text) {
return { count: Math.ceil(text.length / 4), confidence: "medium" };
},
},
// Top-level on LLMCapabilityConfig — not nested under a wrapper.
async fetchModels(config) {
// A request that gets no response (DNS, refused connection, a
// certificate that cannot be verified) throws a classified failure.
// A non-OK response is returned, so decide what best-effort means here.
const response = await fetchDiscoveryEndpoint("https://api.example.com/v1/models", {
headers: { Authorization: `Bearer ${config.apiKey}` },
});
if (!response.ok) return STATIC_MODELS;
const data = await response.json();
return data.models.map((m: any) => ({ id: m.id }));
},
};fetchDiscoveryEndpoint provient de
@scrydon/sdk-authoring/extensions/extension-failure. N'enveloppez pas la requête
de listage dans un catch générique qui renvoie votre liste statique ou [] : un point
de terminaison qui n'a jamais répondu fait aussi échouer chaque appel de modèle sur cette connexion,
et l'avaler revient à certifier des modèles que personne ne peut appeler. Lorsque la découverte lève une erreur, la
plateforme conserve les models statiques que vous avez déclarés, marque le fournisseur avec un
discoveryFailure qui nomme le point de terminaison et la cause, et affiche cette raison
à côté de la connexion dans Paramètres → Plateforme → Extensions. Une réponse
que le serveur a choisi d'envoyer (un 404, un 401) est à vous de l'interpréter.
Lorsque vous connaissez la valeur qui corrigerait l'échec, indiquez-la sous forme
structurée, pas seulement dans le texte :
endpointUnreachableError(endpoint, cause, { remedy, suggestedConfig: { field, value } })
nomme l'un des champs de point de terminaison de votre extension et la valeur à y
mettre. La plateforme vérifie cette valeur comme si un administrateur l'avait saisie
(une URL https sans identifiants, présente dans la liste d'autorisation de sortie
de l'organisation) et, si elle est acceptée, la propose comme correction en un clic
à côté de l'échec. Une valeur refusée est ignorée ; l'échec reste affiché.
L'intégrer dans une famille de modèles
Un LLM est une FAMILLE DE MODÈLES, pas un membre de toolkit. defineModels({ family: "llm" }) porte le runtime, la liste des modèles, le modèle par défaut et les capacités par défaut de la famille dans un seul élément fourni — c'est aussi ce que lit le sélecteur de modèles de la plateforme :
export default defineExtension({
// ...
provides: {
models: [
defineModels({
id: "my-service-llm",
name: "My Service",
family: "llm",
runtime: llmCapability,
defaultModel: "my-model-v1",
capabilities: {
toolUsageControl: true,
nativeStructuredOutputs: true,
},
models: [
{
id: "my-model-v1",
pricing: { input: 3.0, output: 15.0, updatedAt: "2026-01-15" },
capabilities: { temperature: { min: 0, max: 2 } },
contextWindow: 128000,
},
],
}),
],
},
});Les capabilities de la famille définissent les valeurs par défaut de chacun de ses modèles, y compris les modèles renvoyés par la découverte dynamique avec un identifiant extension/model. Les champs capabilities propres à un modèle remplacent ces valeurs champ par champ ; une valeur explicite false remplace donc une valeur true définie au niveau de la famille. Les identifiants de modèles inconnus n'héritent d'aucune capacité.
La découverte dynamique ne déduit pas les capacités à partir du nom du modèle. Ne déclarez que les comportements que l'adaptateur du fournisseur peut garantir pour tous les modèles découverts, et utilisez les déclarations propres au modèle lorsque la prise en charge varie selon le modèle.
Benchmarks
| Benchmark | Direction |
|---|---|
| MMLU | plus élevé est meilleur |
| HumanEval | plus élevé est meilleur |
| GPQA | plus élevé est meilleur |
Ajoutez benchmarks à vos entrées de modèles et l'interface les affichera aux côtés du nom du modèle, de la fenêtre de contexte et des tarifs.
Hébergement d'exécution et sélection du modèle
Les archives LLM implémentent l'adaptateur fournisseur, mais seul l'hôte de capacités de la plateforme Scrydon l'invoque. Les applications envoient les messages, les schémas d'outils, les options de génération et un modèle facultatif. La plateforme résout la cible, sélectionne une connexion admissible limitée à l'environnement actif, charge l'archive sélectionnée, applique la DLP LLM, comptabilise l'utilisation et renvoie un résultat normalisé.
Le sélecteur de modèle du workflow commence par Par défaut. Cette option n'enregistre aucun remplacement de modèle et délègue à platform.defaultLlmExtension ; choisir un modèle remplace uniquement le modèle de ce workflow. Les connexions et identifiants sont configurés dans les paramètres de la plateforme, limités à l'environnement actif, et ne sont jamais sélectionnés ni stockés par un bloc LLM. /api/providers rejette les champs apiKey, oauthCredentialId et binding fournis par l'appelant.