vss-search-archive

Par nvidia · skills

Utilisé pour exécuter une recherche de fusion VSS de niveau supérieur sur des vidéos archivées, ou pour ingérer des fichiers vidéo / flux RTSP à des fins de recherche. Non destiné aux questions-réponses ad hoc ou au sous-titrage en direct.

npx skills add https://github.com/nvidia/skills --skill vss-search-archive

Objectif

Exécuter la recherche de fusion VSS au niveau supérieur sur des vidéos archivées et ingérer de nouveaux clips / flux RTSP pour la recherche.

Prérequis

  • Déploiement VSS actif accessible sur $HOST_IP (voir vss-deploy-profile et references/).
  • Identifiants NGC dans $NGC_CLI_API_KEY et $NVIDIA_API_KEY pour les tirages d'images.
  • curl, jq et Docker disponibles sur l'appelant.

Instructions

Suivez les tables de routage et les flux de travail étape par étape ci-dessous. Chaque section se terminant par workflow, quick start ou flow est destinée à être exécutée de haut en bas. Le matériel de référence détaillé se trouve dans references/ et les scripts d'aide se trouvent dans scripts/ — appelez-les via run_script quand le skill pointe vers un script par nom.

Exemples

Les exemples complets travaillés sont conservés sous evals/ (chaque manifeste *.json contient un scénario exécutable) et en ligne dans les blocs curl par workflow ci-dessous. Exécutez une évaluation Tier-3 avec nv-base validate <this-skill-dir> --agent-eval pour les relire.

Limitations

  • Nécessite que le profil VSS correspondant / le microservice soit déployé et accessible depuis l'appelant.
  • Les modèles hébergés sur NGC et les NIMs peuvent être soumis à des limites de débit, des exigences de mémoire GPU et des restrictions de licence.
  • Les limites de concurrence, de mémoire GPU et de stockage dépendent du matériel hôte et du fichier compose du profil.

Dépannage

  • Erreur : l'appel REST retourne connexion refusée. Cause : microservice cible non exécuté. Solution : sondez /docs ou /health; redéployez via vss-deploy-profile ou le skill vss-deploy-* correspondant.
  • Erreur : HTTP 401/403 à partir des tirages NGC. Cause : NGC_CLI_API_KEY manquante/expirée. Solution : docker login nvcr.io et ré-exportez la clé avant de réessayer.
  • Erreur : conteneur OOM ou le modèle ne charge pas. Cause : mémoire GPU insuffisante pour le profil sélectionné. Solution : passez à une variante plus petite ou libérez les GPU via docker compose down.

Flux de travail de recherche vidéo

Fonctionnalité Alpha — non recommandée pour la production.

Recherchez des archives vidéo en langage naturel en utilisant les embeddings Cosmos Embed1. Nécessite le profil de recherche — déployez avec le skill vss-deploy-profile (-p search). Ces sources vidéo peuvent être des fichiers ingérés ou des flux RTSP.

Quand l'utiliser

  • « Trouver tous les cas de chariots élévateurs »
  • « Quand quelqu'un a-t-il accédé à la zone restreinte ? »
  • « Montrez-moi les gens près du quai de chargement »
  • « Chercher les véhicules entre 8h et 12h »
  • Toute recherche en langage naturel sur les archives vidéo
  • « Ingérer <fichier> pour la recherche » / « charger cette vidéo pour la recherche »
  • « Ajouter ce flux RTSP pour la recherche » / « enregistrer <rtsp_url> pour la recherche »

Prérequis de déploiement

Ce skill nécessite le profil VSS search en cours d'exécution sur l'hôte à $HOST_IP. Avant toute demande :

  1. Sondez la pile :

    curl -sf --max-time 5 "http://${HOST_IP}:8000/docs" >/dev/null \
      && curl -sf --max-time 5 "http://${HOST_IP}:9200/" >/dev/null

    (La deuxième vérification confirme qu'Elasticsearch est actif — unique au profil de recherche.)

  2. Si le sondage échoue, posez à l'utilisateur :

    « Le profil VSS search n'est pas en cours d'exécution sur $HOST_IP. Dois-je le déployer maintenant en utilisant le skill /vss-deploy-profile avec -p search ? »

    • Si oui → remettez au skill /vss-deploy-profile. Revenez ici une fois qu'il réussit.
    • Si non → arrêtez. N'exécutez pas ce skill contre une pile manquante ou avec le mauvais profil.

    (Si l'appelant vous a accordé une pré-autorisation explicite de déployer de façon autonome — par exemple la demande dit « pré-autorisé à déployer les prérequis », ou vous exécutez un harnais d'évaluation non-interactif avec cette permission — ignorez la confirmation et invoquez /vss-deploy-profile directement.)

  3. Si le sondage réussit, procédez.


Prérequis d'ingestion (requis avant tout /generate)

Pour qu'une source soit interrogeable, elle doit être ingérée via le backend de l'agent VSS, pas uniquement via VIOS. Les routes d'ingestion de l'agent possèdent le chargement VIOS + l'enregistrement RTVI-CV + le pipeline RTVI-embed comme une seule transaction ; un PUT VIOS nu ne stocke que les octets et ne les câble jamais dans Elasticsearch.

Confirmez d'abord que la source existe dans VIOS (étape 2 obligatoire du flux de travail). S'il manque, ingérez-la avec l'une des recettes ci-dessous avant de lancer /generate. Après la réussite de l'ingestion, la source apparaît dans sensor/list sous le nom que vous avez fourni et peut être référencée à partir de la requête en langage naturel que l'agent transmet à son décompositeur d'outil de recherche — vous n'avez PAS besoin de construire vous-même une charge utile video_sources structurée.

Chargement de fichier — flux universel à trois étapes

# 1. Demandez à l'agent l'URL de chargement par morceaux
URL=$(curl -s -X POST "http://${HOST_IP}:8000/api/v1/videos" \
  -H "Content-Type: application/json" \
  -d '{"filename": "<filename.mp4>"}' | jq -r .url)

# 2. POST par morceaux le fichier vers cette URL VST (l'interface diffuse les morceaux ; à partir d'un shell,
#    un POST multipart unique convient). La réponse du morceau final porte sensorId.
SENSOR=$(curl -s -X POST "$URL" \
  -F "file=@/path/to/<filename.mp4>;type=video/mp4" | jq -r .sensorId)

# 3. Dites à l'agent que le chargement est terminé — cela se déploie vers RTVI-CV + RTVI-embed
curl -s -X POST "http://${HOST_IP}:8000/api/v1/videos/${SENSOR}/complete" \
  -H "Content-Type: application/json" \
  -d '{"filename": "<filename.mp4>"}' | jq .

Attendez la réponse /complete (elle retourne chunks_processed > 0 une fois les embeddings arrivés). C'est seulement à ce moment que la vidéo est interrogeable.

La route PUT /api/v1/videos-for-search/{filename} dépréciée est également câblée pour les appelants hérités (coup unique, piloté par l'agent), mais son entrée OpenAPI est marquée deprecated. Préférez le flux à trois étapes ci-dessus pour les nouveaux travaux.

Flux RTSP — endpoint unique

curl -s -X POST "http://${HOST_IP}:8000/api/v1/rtsp-streams/add" \
  -H "Content-Type: application/json" \
  -d '{
    "sensor_url": "rtsp://<host>:<port>/<path>",
    "name": "<sensor-name>",
    "username": "",
    "password": "",
    "location": "",
    "tags": ""
  }' | jq .

La forme de la réponse est {status, message, error} — pas de sensorId (l'agent indexe le flux par le name que vous avez fourni). En cas d'échec à une étape, les étapes antérieures sont annulées. L'étape start_embedding_generation est envoi-et-vérification : un 2xx confirme que la demande a été acceptée et le pipeline d'embedding s'exécute en arrière-plan, pas que le flux est interrogeable. Les résultats de recherche commenceront à apparaître seulement après que suffisamment de morceaux arrivent dans Elasticsearch — interrogez avec une requête top_k faible après quelques secondes si vous avez besoin d'un signal de disponibilité.


Comment fonctionne la recherche

  1. Ingestion — Les fichiers arrivent via le flux universel à trois étapes de l'agent ; les flux RTSP via /api/v1/rtsp-streams/add. Les deux routes remettent la source à RTVI-CV (détection d'attributs) et RTVI-Embed (Cosmos Embed1) qui génère les embeddings vectoriels pour les segments vidéo.
  2. Indexation — Les embeddings sont stockés dans Elasticsearch via le pipeline Kafka.
  3. Requête — Les requêtes en langage naturel sont intégrées et mises en correspondance avec les vecteurs stockés par similarité.
  4. Résultats — Segments vidéo horodatés classés par pertinence, avec des liens de lecture de clips.

Cette recherche orchestrée par l'agent VSS peut mener à 3 comportements :

  • Attributs uniquement : quand le LLM décompose la requête et trouve uniquement des attributs d'apparence sans action (par ex. « personne portant une veste rouge »)
  • Embed uniquement : quand la requête n'a pas d'attributs extractibles (par ex. « montrez-moi les chariots élévateurs »)
  • Fusion : quand la requête a à la fois une action et des attributs (par ex., « personne en veste rouge qui court »), elle exécute d'abord la recherche embed, puis ré-classe à l'aide de la recherche d'attributs

Flux de travail obligatoire

En utilisant ce skill, TOUJOURS suivez ce flux de travail de haut niveau :

  1. Résolvez les entrées à partir des instructions utilisateur — ARRÊT FERME si $HOST_IP n'est pas explicitement fourni. Voir § Résolution des entrées ci-dessous. NE PAS choisir par défaut localhost, 127.0.0.1, l'hôte sur lequel l'agent lui-même s'exécute, ou toute autre supposition. NE PAS émettre une requête POST http://.../generate jusqu'à ce que l'utilisateur ait fourni un endpoint. Répondez à l'utilisateur avec une seule question demandant HOST_IP / l'endpoint de l'agent VSS et attendez.

  2. Résolvez la source — ARRÊT FERME avant tout appel /generate. Si la requête utilisateur référence un nom de vidéo / capteur spécifique (par ex. « la vidéo de l'aéroport », « warehouse_cam_3 », « sample warehouse »), vérifiez qu'il est réellement enregistré dans VIOS avant de lancer POST .../generate :

    curl -s "http://${HOST_IP}:30888/vst/api/v1/sensor/list" | jq '.[].name'

    Ensuite :

    • Si la source nommée (ou un nom correspondant clairement à la sous-chaîne) EST dans la liste → procédez à l'étape 3. Transmettez la requête en langage naturel de l'utilisateur littéralement — le propre décompositeur d'outil de recherche de l'agent (services/agent/src/vss_agents/tools/search.py) extrait video_sources de la prose donnée les sources disponibles, donc le skill n'a PAS besoin de construire une charge utile video_sources structurée.
    • Si la source nommée N'EST PAS dans la liste → ARRÊTEZ. NE lancez PAS /generate comme sondage. Répondez à l'utilisateur avec les noms des sources enregistrées et demandez s'il en signifiait une, s'il souhaite ingérer la source manquante (pointez-le vers Prérequis d'ingestion et exécutez la recette de fichier ou RTSP correspondante via le backend de l'agent, pas VIOS nu), ou s'il souhaite abandonner la requête. Attendez la clarification.
    • Si la requête ne nomme aucune source spécifique (« trouver les chariots élévateurs dans les vidéos ingérées », « chercher sur toutes les sources ») → ignorez la vérification de sous-chaîne, mais sensor/list doit toujours retourner non-vide (sinon aucune source n'est ingérée → ARRÊT FERME).
  3. Exécutez la/les recherche(s) via l'approche choisie

  4. Présentez les résultats à la requête utilisateur. Formatez la réponse comme un rapport d'inspection professionnel mais nommez-le Résultats de recherche vidéo : — Utilisez des en-têtes de section clairs

    • Organisez les constatations individuellement avec détails de soutien, et terminez par un résumé
    • Utilisez des tableaux où les comparaisons aident. Écrivez comme un rapport technique, pas un message de chat.
    • Si les résultats des critères sont non-nuls, alors en plus d'une colonne « Résultat critique » (« confirmé » | « rejeté » | « ignoré »), incluez une colonne « Critères » avec tous les critères de ce résultat de recherche ({criteria_n} : ✓ | ✗)
  5. CRITIQUE : Vérifiez les résultats et expliquez cela à l'utilisateur de manière concise. Si la recherche échoue, ou retourne des résultats inattendus (par ex. vidéos qui ne semblent pas correspondre à la requête utilisateur, zéro correspondances, zéro vidéos retournées, erreur, etc.), ARRÊTEZ. Ne procédez pas sans lire troubleshooting.md pour itérer avec des boucles de rétroaction jusqu'à ce que les résultats appropriés soient trouvés et présentés comme un rapport d'inspection professionnel.

  6. Vérifications finales :

    • TOUJOURS informez l'utilisateur que les vérifications finales et ultérieures peuvent être exécutées. Présentez ceci comme une Étape de vérification
    • UNIQUEMENT SI l'utilisateur accepte, téléchargez les captures d'écran en utilisant le screenshot_url des meilleurs candidats (scores de similarité les plus élevés) à partir des résultats de recherche (résultats JSON) vers /tmp. Lisez-les et vérifiez s'ils correspondent à la requête utilisateur

Résolution des entrées

Déduisez ces entrées uniquement à partir de la conversation ou de la requête utilisateur (aucun autre fichier sauf s'il est fourni). Si certaines ne peuvent pas être déduites, demandez à l'utilisateur immédiatement :

  • $HOST_IP : où s'exécute le backend de l'agent VSS

Pièges

  • TOUJOURS entrez dans l'étape de dépannage du flux de travail immédiatement si quelque chose d'inattendu se produit, lisez troubleshooting.md
  • Les requêtes fonctionnent mieux avec des descriptions visuelles concrètes (objets, actions, lieux). Augmentez les requêtes utilisateur si nécessaire pour améliorer la qualité des questions, en élargissant les détails potentiels
  • Le skill suppose que les sources vidéo sont déjà ingérées via le backend de l'agent (voir Prérequis d'ingestion). Il PEUT exécuter les recettes d'ingestion soutenues par l'agent quand l'utilisateur demande explicitement (« ingérer <fichier> pour la recherche », « ajouter <rtsp_url> pour la recherche ») ; il ne cherche PAS le système de fichiers local pour les fichiers que l'utilisateur n'a pas nommés, et il n'utilise PAS le chemin PUT nu-VIOS (aucun embedding n'est généré). L'étape 2 du flux de travail fait toujours de la confirmation « cette source existe dans VIOS » une précondition ferme avant /generate.
  • Utilisez le skill vss-query-analytics pour croiser les résultats de recherche avec les données d'incident/alerte

Recherche via API REST

Préférez cette approche API REST par défaut, sauf si l'utilisateur spécifie autrement.

# Considérez uniquement les sources vidéo fichier ingérées par défaut
curl -s -X POST http://${HOST_IP}:8000/generate \
  -H "Content-Type: application/json" \
  -d '{"input_message": "find all instances of forklifts"}' | jq .

Plus d'exemples

# Chercher par objet
curl -s -X POST http://${HOST_IP}:8000/generate \
  -H "Content-Type: application/json" \
  -d '{"input_message": "find vehicles in the parking lot"}' | jq .

# Chercher par action
curl -s -X POST http://${HOST_IP}:8000/generate \
  -H "Content-Type: application/json" \
  -d '{"input_message": "show me people running"}' | jq .

# Chercher par contexte temporel
curl -s -X POST http://${HOST_IP}:8000/generate \
  -H "Content-Type: application/json" \
  -d '{"input_message": "what happened at the entrance between 2pm and 3pm?"}' | jq .

# Considérer uniquement les sources RTSP avec le filtre `search_source_type`, c'est-à-dire les flux de caméra en direct
curl -s -X POST http://${HOST_IP}:8000/generate \
  -H "Content-Type: application/json" \
  -d '{"input_message": "find all instances of forklifts", "search_source_type": "rtsp"}' | jq .

Boutons de contrôle avancés

Si la requête utilisateur est ambiguë, l'utilisateur veut plus de conseils ou quand un contrôle fin est nécessaire, augmentez le input_message utilisateur en appelant explicitement certaines options en texte brut et en guidant l'agent dans la direction souhaitée. Axes de contrôle disponibles :

Axes Type Défaut Description
video sources string[] null Filtrer vers des caméras ou noms de capteurs spécifiques
top k int 10 Résultats max
minimum similarity float 0,0 Seuil de similarité min ; augmentez (par ex. 0,3) pour filtrer le bruit
critic usage bool true VLM vérifie chaque résultat et supprime les faux positifs
description string null Filtrer par métadonnées de caméra (par ex. localisation, catégorie) si les métadonnées sont disponibles

Choisissez et sélectionnez certaines de ces options d'ajustement. Ajustez-les selon les besoins pour la situation et la requête de l'utilisateur. Pour des exemples de modes de découverte exploitant ces options, voir discovery_modes.md.


Recherche via l'interface utilisateur de l'agent

Ouvrez http://${HOST_IP}:3000/ et tapez des requêtes en langage naturel :

find all instances of forklifts
show me people near the loading dock
when did a truck arrive at the gate?
find someone wearing a red jacket

Les résultats incluent des clips horodatés avec scores de similarité.

bump:1

Skills similaires