Démarrage rapide du SDK Agent Cortex Code

Ce chapitre vous guide à travers la création d’un agent AI qui lit un script de pipeline de données, trouve des bogues et les corrige automatiquement à l’aide du SDK Agent Cortex Code.

Ce que vous ferez :

  1. Configurer un projet avec le SDK Agent Cortex Code.

  2. Créer un script de pipeline de données avec quelques bogues.

  3. Exécuter un agent qui trouve et corrige les bogues sans intervention manuelle.

Conditions préalables

  • Node.js 22+ (pour TypeScript) ou Python 3.10+ (pour Python).

  • Connexion Snowflake configurée via les paramètres de connexion de la CLI Snowflake, généralement dans ~/.snowflake/connections.toml, avec ~/.snowflake/config.toml également pris en charge pour les configurations existantes (voir Configuration des connexions) :

    [my-connection]
    account = "myorg-myaccount"
    user = "myuser"
    authenticator = "externalbrowser"
    

Configuration

1. Installer la CLI Cortex Code

Installez la CLI :

curl -LsS https://ai.snowflake.com/static/cc-scripts/install.sh | sh

Vérifiez l’installation :

cortex --version

2. Configurer votre projet

Créez et accédez au répertoire du projet :

mkdir my-agent && cd my-agent

3. Installer le SDK

npm init -y
npm install cortex-code-agent-sdk

Créer un script de pipeline de données

Créez un script de pipeline de données contenant des bogues intentionnels à corriger par l’agent :

import json

def load_results(rows):
    """Load query results into a list of campaign dicts."""
    return [
        {
            "campaign": row["campaign_name"],
            "impressions": row["impressions"],
            "clicks": row["clicks"],
            "conversions": row["conversions"],
        }
        for row in rows
    ]

def compute_conversion_rate(results):
    """Add conversion_rate (conversions / clicks) to each campaign."""
    for row in results:
        row["conversion_rate"] = row["conversions"] / row["clicks"]  # Bug: ZeroDivisionError when clicks is 0
    return results

def format_report(results):
    """Return a JSON summary with total conversions and the top campaign."""
    total = sum(r["conversions"] for r in results)
    top = max(results, key=lambda r: r["conversion_rate"])  # Bug: crashes on empty list
    return json.dumps({"total_conversions": total, "top_campaign": top["campaign"]})

Ce code pose deux problèmes :

  1. computeConversionRate/compute_conversion_rate divise par clicks sans vérifier la présence de zéro, retournant NaN ou Infinity (TypeScript) ou générant une ZeroDivisionError (Python) pour les campagnes sans clics.

  2. formatReport/format_report appelle max/reduce sur la liste de résultats sans vérifier s’il est vide, ce qui génère une ValueError (Python) ou TypeError (TypeScript) lorsqu’il n’y a pas de lignes.

Créez un agent qui trouve et corrige les bogues

// agent.mjs
import { query } from "cortex-code-agent-sdk";

// Agentic loop: streams messages as the agent works
for await (const message of query({
  prompt: "Review report.ts for bugs in the data pipeline. Fix any issues you find.",
  options: {
    cwd: process.cwd(),
    connection: "my-connection",          // Snowflake CLI connection name
    allowedTools: ["Read", "Edit", "Bash"],  // Auto-approve these tools without prompting
  },
})) {
  // Print human-readable output
  if (message.type === "assistant") {
    for (const block of message.content) {
      if (block.type === "text") {
        process.stdout.write(block.text);  // Agent's reasoning
      } else if (block.type === "tool_use") {
        console.log(`Tool: ${block.name}`);  // Tool being called
      }
    }
  } else if (message.type === "result") {
    console.log(`\nDone: ${message.subtype}`);  // Final result
  }
}

Ce code comporte trois parties principales :

  1. query(): Le point d’entrée principal qui crée la boucle agentique. Il renvoie un itérateur asynchrone que vous pouvez utiliser dans la syntaxe de boucle asynchrone de votre langage pour lire les messages au fur et à mesure que l’agent travaille. Voir l’ensemble des API dans la référence TypeScript ou Python.

  2. invite : Ce que vous voulez que fasse l’agent. Il indique à l’agent quelle tâche effectuer.

  3. options Configuration de l’agent. connection spécifie quelle connexion CLI Snowflake avec laquelle s’authentifier. allowedTools spécifie quels outils sont approuvés automatiquement sans invite, et``disallowedTools`` peut bloquer complètement des outils. Les autres options incluent model, mcp_servers et d’autres encore.

La boucle de streaming s’exécute au fur et à mesure que l’agent réfléchit, appelle les outils, observe les résultats et décide des prochaines actions. Chaque itération produit un message : le raisonnement de l’agent, un appel d’outil, un résultat d’outil ou le résultat final. Le SDK gère l’orchestration.

Exécuter votre agent

node agent.mjs

Après l’exécution, consultez votre fichier de rapport. Vous verrez un code défensif gérant les résultats vides et les campagnes à zéro clic. Votre agent de manière autonome :

  1. A lu le fichier pour comprendre le code.

  2. A analysé la logique et identifié des cas limites susceptibles de crasher.

  3. A modifié le fichier pour ajouter une gestion des erreurs plus appropriée.

Conversation à plusieurs tours

Pour les sessions interactives où vous envoyez plusieurs invites avec un contexte partagé, utilisez l’API client :

import {
  createCortexCodeSession,
  type CortexCodeEvent,
} from "cortex-code-agent-sdk";

async function printResponse(stream: AsyncIterable<CortexCodeEvent>) {
  for await (const event of stream) {
    if (event.type === "assistant") {
      for (const block of event.content) {
        if (block.type === "text") process.stdout.write(block.text);
      }
    } else if (event.type === "result") {
      break;
    }
  }
}

const session = await createCortexCodeSession({
  cwd: process.cwd(),
  connection: "my-connection",
});

// First turn
await session.send("Summarize what report.ts does and what data it expects.");
await printResponse(session.stream());

// Second turn (same session, remembers context)
await session.send("Now add type annotations to each function.");
await printResponse(session.stream());

await session.close();

Essayer d’autres invites

Maintenant que votre agent est configuré, essayez différentes invites :

  • "Add comprehensive type hints to all functions in report.py"

  • "Write a SQL query that finds the top 10 campaigns by conversion rate"

  • "Add input validation to all functions in report.py"

  • "Create a README.md documenting the functions in report.py"

Concepts clés

Modes d’autorisation

Les modes d’autorisation contrôlent le niveau de surveillance humaine pour les appels d’outils :

Mode

Comportement

Cas d’utilisation

"bypassPermissions" (avec indicateur de sécurité)

Exécute chaque outil sans invite. Nécessite allowDangerouslySkipPermissions: true (TypeScript) ou allow_dangerously_skip_permissions=True (Python).

CI en sandbox, environnements entièrement fiables

"default"

Utilise les contrôles d’autorisation standard. Dans les sessions SDK, configurez allowedTools, disallowedTools, ou canUseTool pour contrôler les outils dont l’autorisation est vérifiée.

Workflows contrôlés avec une politique d’autorisation explicite

"autoAcceptPlans"

Approuve automatiquement les demandes de plan et les confirmations de sortie du plan. Ne contourne pas les autorisations ordinaires des outils.

Workflows spécialisés souhaitant que les approbations des plans soient effectuées automatiquement

"plan"

Commence dans la planification ; l’approbation de ExitPlanMode autorise l’exécution à se poursuivre et active ensuite les autorisations normales

Vérification du code, analyse

Pour un contrôle granulaire des appels d’outils individuels, utilisez le rappel canUseTool. Voir Gérer les approbations et les entrées utilisateur pour plus de détails.

Prochaines étapes