Créer un adaptateur NVIDIA NeMo Fabric
Construisez selon le contrat southbound publié. Gardez l'adaptateur léger : laissez NeMo Fabric posséder la planification et le comportement côté consommateur, et laissez l'adaptateur posséder uniquement la traduction des cibles et l'état du cycle de vie.
Lire le Contrat
Lisez le contrat d'adaptateur actuel avant de modifier le code. Commencez par l'aperçu, choisissez une forme d'intégration, puis suivez les étapes numérotées de descripteur, configuration, exécution, résultats, enregistrement et vérification. Lisez la page custom-agent quand la cible charge des agents ou des workflows définis par l'application. Lisez la page optionnelle de streaming natif OpenAI uniquement quand l'adaptateur déclare cette capacité.
Utilisez les JSON Schemas du contrat d'adaptateur validés ou les schemas installés avec la version NeMo Fabric correspondante pour les formes exactes sur le fil. Ne reconstruisez pas un schema à partir d'exemples ni ne copiez les listes de champs dans le code de l'adaptateur.
Établir la Limite
Établissez la limite de l'adaptateur avant de définir son descripteur :
- Identifiez l'implémentation de l'adaptateur et son
adapter_idstable. - Choisissez un adaptateur harness, un adaptateur de framework partagé avec cibles enregistrées, ou un adaptateur custom-agent dédié.
- Réutilisez un adaptateur partagé entre des agents personnalisés quand le framework fournit une sémantique de chargement et d'invocation stable. Utilisez un adaptateur dédié quand l'agent lui-même est la seule limite d'exécution non ambiguë.
- Énumérez les champs normalisés que la cible peut réellement appliquer.
- Séparez les
harness.settingsau niveau de l'adaptateur, lesworkflow.settingspar cible, et lesextensionstypées. - Gardez l'installation, la préparation de l'environnement, l'orchestration Relay, la planification des appelants, et l'enrichissement des résultats consommateur en dehors de l'adaptateur.
Si le comportement demandé ne peut pas être exprimé par le contrat actuel, signalez l'écart. Ne consommez pas silencieusement un champ northbound non supporté ni ne le cachez dans une extension non liée.
Définir le Descripteur d'abord
Créez un *.fabric-adapter.json autonome avant d'implémenter la traduction des cibles :
- Définissez la
contract_versionactuelle, unadapter_idglobalement stable,adapter_kind, et la liaison au runner. - Déclarez uniquement les champs
config.acceptsnormalisés que l'implémentation applique. - Déclarez
mcp.auth.oauth2oumcp.auth.service_accountuniquement quand l'adaptateur implémente le mode d'authentification MCP correspondant. - Publiez les
settings_schema,model_schema,tool_definition_schema, etextension_schemasfermés où applicable. Utilisezmodel_schemauniquement pour la compatibilité modèle/fournisseur statique et les paramètres de modèle ; gardez la validité des credentials et la disponibilité du fournisseur dans la validation au démarrage. - Déclarez les exigences d'exécution et les sorties de télémétrie sans valeurs secrètes.
- Laissez les drapeaux de capacité optionnels à false sauf si le runtime NeMo Fabric installé expose et teste cette opération de l'adaptateur. Définissez
capabilities.streaminguniquement quand l'adaptateur implémente le streaming natif OpenAI Chat Completions viainvoke_openai_stream. Le streaming ATOF basé sur Relay est indépendant et ne nécessite pas cette capacité.
Si l'adaptateur charge des cibles enregistrées, énumérez leurs types dans target_types. Créez un *.fabric-target.json par cible. L'enregistrement de cible possède son adapter_id, le point d'entrée spécifique au type, et le schema des paramètres de workflow. Il utilise la même contract_version que le descripteur d'adaptateur.
Validez les schemas de descripteur sans importer le code de l'adaptateur. Gardez toutes les références de schema locales au document descripteur ; ne dépendez pas de références HTTP ou fichier.
Empaqueter les Métadonnées de Découverte
Installez le descripteur à l'emplacement standard des données partagées. Pour setuptools :
[tool.setuptools.data-files]
"share/nemo-fabric/adapters/acme" = ["acme.fabric-adapter.json"]
"share/nemo-fabric/targets/acme" = ["email.fabric-target.json"]
Dépendez de nemo-fabric-adapter-contract pour les dataclasses de bibliothèque standard typées. Installez son extra pydantic optionnel uniquement pour l'interopérabilité Pydantic. Ajoutez nemo-fabric-adapters-common uniquement si l'adaptateur choisit son cycle de vie ou les helpers Relay. Un adaptateur minimaliste ne devrait pas dépendre du runtime NeMo Fabric.
Pour un adaptateur TypeScript, dépendez de nemo-fabric-adapter-contract. Importez les types de descripteur, configuration, runtime-context, request, et result depuis la racine du package, correspondant à l'espace de noms de modèle unique du package Python. Les types TypeScript ne valident pas les données reçues d'une limite de processus ou réseau ; validez les valeurs non fiables contre les JSON Schemas inclus avec le package.
Mapper AgentConfig
Acceptez un AgentConfig validé et traduisez chaque champ déclaré une seule fois à la limite de l'adaptateur :
- Résolvez les rôles de modèle nommés en clients ou paramètres de modèle natifs à la cible.
- Appliquez les instructions normalisées et les limites d'exécution uniquement quand elles sont déclarées.
- Convertissez les serveurs MCP, les définitions d'outils, la politique d'outils, et les skills en construits natifs à la cible.
- Résolvez les points d'entrée de workflow et les paramètres de construction lors de
startdans l'environnement des tâches. - Lisez l'identité, l'environnement, les artifacts, et la télémétrie depuis
RuntimeContext, pas depuis les paramètres de workflow.
Rejetez les valeurs non supportées avec des codes d'erreur stables et sûrs. Ne consignez pas les configs complètes, les valeurs d'environnement, les en-têtes, les credentials, ou les entrées utilisateur arbitraires.
Utilisez des modèles d'extension typés et publiez leurs schemas au point d'extension de descripteur exact. Ne traitez jamais extensions comme une échappatoire dictionnaire non vérifiée.
Implémenter le Cycle de Vie
Implémentez exactement un start, zéro ou plusieurs opérations invoke ordonnées, et un stop pour chaque runtime NeMo Fabric.
- Construisez et conservez l'état de la cible dans
start. - Acceptez
AgentRunRequestetRuntimeContext, puis retournez unAgentRunResultdepuisinvoke. - Rendez
stopsûr après un démarrage partiel et une invocation échouée. - Isolez l'état mutable entre les runtimes indépendants.
- Si le descripteur déclare
capabilities.streaming, implémentezasync invoke_openai_stream(request, context, emit). Exécutez la cible exactement une fois, attendezemit(chunk)uniquement pour le profilopenai.chat_completions.chunk/v1, et retournez unAgentRunResult. Chaque chunk nécessite unidetmodelnon vides, un entiercreatednon négatif, le discriminateur exactchat.completion.chunk, et deschoicesstructurellement valides. Une invocation qui n'émet aucun chunk est valide. - N'ajoutez pas de méthode de streaming d'adaptateur pour
Runtime.invoke_stream()basé sur Relay ; exécutezinvokeordinaire et utilisez le contexte de télémétrie fourni.
Pour le streaming OpenAI natif, le SDK possède le transport HTTP de loopback authentifié avec encadrement NDJSON en chunks. L'hôte commun valide le transport, supprime ses credentials de la charge utile de l'adaptateur, et fournit le callback emit. Ne conservez pas ou consignez les credentials de flux, n'écrivez pas les chunks sur stdout, n'ajoutez pas d'encadrement SSE, et ne renvoyez pas d'autres profils d'événements natifs à la cible.
Pour un adaptateur Python qui opte pour l'hôte commun :
from nemo_fabric_adapter_contract.models import AgentConfig
from nemo_fabric_adapter_contract.models import AgentRunRequest
from nemo_fabric_adapter_contract.models import AgentRunResult
from nemo_fabric_adapter_contract.models import AgentRunStatus
from nemo_fabric_adapter_contract.models import RuntimeContext
from nemo_fabric_adapters.common import lifecycle
class TargetRuntime:
async def start(self, payload):
config: AgentConfig = payload["config"]
...
async def invoke(
self,
request: AgentRunRequest,
context: RuntimeContext,
) -> AgentRunResult:
native = await self.target.run(request.input)
return AgentRunResult(
status=AgentRunStatus.SUCCEEDED,
output={"response": native.text},
)
async def invoke_openai_stream(self, request, context, emit):
async for chunk in self.target.stream(request.input):
await emit(chunk)
return AgentRunResult(
status=AgentRunStatus.SUCCEEDED,
output={"response": self.target.final_text},
)
async def stop(self):
...
def main() -> None:
lifecycle.serve(TargetRuntime, config_loader=AgentConfig.from_mapping)
L'hôte commun décode l'enveloppe de cycle de vie interne avant d'appeler l'adaptateur et encode son résultat terminal ensuite. Le code de l'adaptateur ne parse pas l'enveloppe de transport et n'en déduit pas l'échec à partir des champs à l'intérieur d'output. Retournez AgentRunStatus.FAILED avec un AgentRunError quand la cible se termine avec un résultat échoué. Levez une exception quand l'adaptateur ne peut pas produire un résultat terminal normalisé.
Gérer les Agents Personnalisés
Pour un adaptateur de framework partagé, sélectionnez la cible enregistrée avec FabricConfig.workflow.target_id. Utilisez le spec.entrypoint.kind du descripteur de cible d'adaptateur sélectionné pour la sémantique de résolution au niveau de l'adaptateur et ref pour l'identité de la fabrique. Validez workflow.settings contre le spec.settings_schema de cette cible.
- Définissez uniquement les types de point d'entrée que l'adaptateur partagé résout sans ambiguïté. Le contrat v1alpha2 ne définit pas un catalog global de kinds.
- Mappez une intention
factorydéclarée à la fabrique native correspondante à la cible. La référence du NeMo Agent Toolkit actuelle mappefabric.agent.reactà sa fabrique de workflow ReAct. - Fournissez aux fabriques un contexte de construction défini par l'adaptateur contenant des valeurs natives déjà résolues ; ne nécessitez pas que les agents personnalisés parsent
FabricConfigouAgentConfig. - Utilisez un adaptateur dédié sans point d'entrée de workflow artificiel quand l'adaptateur sélectionné identifie déjà un agent possédé par l'application.
Comparez l'adaptateur partagé NeMo Agent Toolkit avec l'exemple LangGraph dédié avant de choisir la limite de custom-agent.
Valider Avant la Passation
Effectuez ces vérifications avant de passer un adaptateur :
- Installez la wheel construite dans un environnement d'adaptateur isolé.
- Confirmez la découverte sous
share/nemo-fabricet inspectez les descripteurs de cible et d'adaptateur résolus dansFabric().plan(...). - Exercez une config normalisée acceptée et le rejet pour les champs non supportés et chaque schema déclaré.
- Exécutez
doctor(...)avec les exigences manquantes et satisfaites. - Testez start, succès, échec de cible, sortie malformée, invocation répétée, stop, nettoyage de démarrage partiel, nettoyage EOF, et isolation à deux runtimes.
- Si le streaming OpenAI natif est revendiqué, testez les flux vides et multi-chunks, les enregistrements malformés et surdimensionnés, les chunks invalides, les décalages de séquence et d'identité, un enregistrement final manquant, fermeture anticipée du consommateur sans annulation, un résultat terminal séparé, un tour actif, et exactement une invocation de cible.
- Testez la corrélation Relay séparément si le support de télémétrie est revendiqué.
- Signalez la version du package de l'adaptateur, la version du contrat, le résultat du profil requis, et chaque capacité optionnelle comme supportée ou non supportée.
Ne revendiquez pas la conformité NeMo Fabric automatisée jusqu'à ce que la suite de conformité publiée existe et que la version exacte de l'adaptateur la passe.