Noqta
  • Accueil
  • Services
  • À propos
  • Écrits
  • Se connecter
écrits/tutorial/2026/07
● Tutorial1 juil. 2026·28 min

Construire des applications IA agentiques avec Claude Sonnet 5 et TypeScript

Un guide pratique pour la toute nouvelle API Claude Sonnet 5. Apprenez les complétions de chat, le streaming, les appels d'outils et les boucles agentiques multi-étapes en TypeScript — avec des conseils d'optimisation des coûts pendant la fenêtre tarifaire introductive.

AI Bot
AI Bot
Author
·EN · FR · AR

Claude Sonnet 5 a été lancé le 30 juin 2026 comme le modèle Sonnet le plus performant pour les charges de travail agentiques. Avec 63,2 % sur les benchmarks de programmation agentique — en hausse par rapport aux 58,1 % de Sonnet 4.6 — il se situe juste en dessous d'Opus 4.8 (69,2 %) mais à une fraction du coût. Jusqu'au 31 août 2026, le tarif introductif est de 2 $ par million de tokens en entrée et 10 $ par million de tokens en sortie, ce qui en fait le moment idéal pour migrer les pipelines agentiques qui tournaient auparavant sur Opus.

Ce tutoriel vous guide à travers la pile complète : configuration du projet, complétions de base, streaming, appels d'outils et une boucle agentique prête pour la production. Tout utilise le SDK TypeScript officiel d'Anthropic et fonctionne contre l'API hébergée — aucun GPU requis.

Prérequis

Avant de commencer, assurez-vous de disposer de :

  • Node.js 20+ (node --version)
  • Une familiarité de base avec TypeScript et async/await
  • Un compte Anthropic avec une clé API depuis console.anthropic.com
  • Un éditeur de code — VS Code est recommandé

Aucun matériel GPU n'est nécessaire. Tous les appels vont vers l'API hébergée d'Anthropic.

Ce que vous allez construire

À la fin de ce tutoriel, vous disposerez de :

  1. Un client Anthropic typé configuré pour claude-sonnet-5.
  2. Une fonction de complétion de chat avec une gestion d'erreurs appropriée.
  3. Un wrapper de streaming qui affiche les tokens au fur et à mesure.
  4. Une couche d'appel d'outils avec des implémentations concrètes pour le système de fichiers.
  5. Une boucle agentique complète qui itère jusqu'à ce que le modèle signale qu'il a terminé.
  6. Un suivi d'utilisation qui calcule le coût selon le tarif introductif.

Le projet final représente environ 200 lignes de TypeScript — assez petit pour être pleinement compris, assez grand pour servir de vrai template.

Comprendre Claude Sonnet 5

Un aperçu rapide du modèle avant d'écrire du code.

Ce qui a changé depuis Sonnet 4.6

Sonnet 5 introduit un nouveau tokeniseur. Pour la plupart des textes en anglais, le ratio d'expansion est d'environ 1,0, mais pour les contenus riches en code ou multilingues, il peut atteindre 1,35 — ce qui signifie que le même prompt utilise jusqu'à 35 % de tokens supplémentaires par rapport à Sonnet 4.6. Cela n'affecte pas la qualité ; cela reflète le réentraînement du tokeniseur sur un vocabulaire plus large. Implication pratique : mesurez toujours les comptages de tokens contre l'API en live plutôt que de supposer que vos estimations Sonnet 4.6 restent valables.

Les paramètres de sécurité ont également été renforcés. Les taux de servilité et d'hallucination sont plus bas, et les garde-fous cyber sont activés par défaut. Vous constaterez que Sonnet 5 repousse plus fermement les demandes limites — c'est intentionnel et cohérent sur tous les clients API.

Tarification pendant la fenêtre introductive

NiveauEntréeSortie
Introductif (jusqu'au 2026-08-31)2 $ / MTok10 $ / MTok
Standard (à partir du 2026-09-01)3 $ / MTok15 $ / MTok

Opus 4.8 est environ 5 à 7 fois plus cher par token. Si vous avez des pipelines agentiques sur Opus, la fenêtre introductive est une excellente occasion d'évaluer une migration vers Sonnet 5.

Identifiant du modèle

L'identifiant API est claude-sonnet-5. Sur Amazon Bedrock, le profil d'inférence cross-région est us.anthropic.claude-sonnet-5-20260630-v1:0 — vérifiez la console Bedrock pour la disponibilité dans votre région. Dans Claude Code, le modèle est déjà disponible comme modèle par défaut pour les niveaux Free et Pro depuis le 1er juillet 2026.

Étape 1 : Configuration du projet

Créez un nouveau projet TypeScript et installez le SDK Anthropic.

mkdir sonnet5-agent && cd sonnet5-agent
npm init -y
npm install @anthropic-ai/sdk
npm install -D typescript tsx @types/node
npx tsc --init --target ES2022 --module NodeNext --moduleResolution NodeNext --strict

Créez un fichier .env pour votre clé API :

echo "ANTHROPIC_API_KEY=sk-ant-..." > .env

Ajoutez un script de développement dans package.json :

{
  "scripts": {
    "dev": "tsx --env-file=.env src/index.ts",
    "test": "node --test --import tsx/esm --env-file=.env src/agent.test.ts"
  }
}

Structure finale du répertoire :

sonnet5-agent/
├── src/
│   ├── client.ts
│   ├── tools.ts
│   ├── agent.ts
│   ├── agent.test.ts
│   └── index.ts
├── .env
├── package.json
└── tsconfig.json

Étape 2 : Client typé et première complétion

Créez src/client.ts avec un singleton client partagé et un wrapper de chat simple :

import Anthropic from "@anthropic-ai/sdk";
 
export const MODEL = "claude-sonnet-5";
 
export const client = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
});
 
export async function chat(prompt: string): Promise<string> {
  const message = await client.messages.create({
    model: MODEL,
    max_tokens: 1024,
    messages: [{ role: "user", content: prompt }],
  });
 
  const block = message.content[0];
  if (block.type !== "text") throw new Error("Unexpected content type");
  return block.text;
}

Testez-le immédiatement dans src/index.ts :

import { chat } from "./client.js";
 
const answer = await chat("What is 2 + 2? Reply with just the number.");
console.log(answer); // 4

Lancez :

npm run dev

L'aller-retour pour un prompt court prend typiquement moins de 800 ms sur l'API hébergée.

Étape 3 : Streaming des réponses

Pour les sorties longues — génération de code, explications détaillées, ébauches de documentation — le streaming vous permet d'afficher les tokens au fur et à mesure plutôt que d'attendre la réponse complète. Cela améliore considérablement la latence perçue.

Créez src/stream.ts :

import { client, MODEL } from "./client.js";
 
export async function streamChat(
  prompt: string,
  onText?: (chunk: string) => void
): Promise<string> {
  let full = "";
 
  const stream = client.messages.stream({
    model: MODEL,
    max_tokens: 4096,
    messages: [{ role: "user", content: prompt }],
  });
 
  stream.on("text", (text) => {
    full += text;
    if (onText) onText(text);
    else process.stdout.write(text);
  });
 
  await stream.finalMessage();
  process.stdout.write("\n");
  return full;
}

Le helper .stream() du SDK Anthropic gère automatiquement les événements text_delta. Le callback optionnel onText vous permet de diriger les tokens où vous en avez besoin — un WebSocket, une mise à jour d'état React, ou un fichier de log.

Étape 4 : Appels d'outils

Les appels d'outils sont là où les améliorations agentiques de Sonnet 5 brillent le plus. Vous définissez un schéma JSON pour chaque fonction, passez le tableau tools à l'API, et laissez le modèle décider quand et quels outils invoquer. Le modèle n'appelle jamais votre code directement — il retourne un bloc tool_use structuré, vous exécutez l'appel, puis renvoyez le résultat.

Créez src/tools.ts :

import Anthropic from "@anthropic-ai/sdk";
import * as fs from "node:fs";
import * as path from "node:path";
 
export const TOOLS: Anthropic.Tool[] = [
  {
    name: "read_file",
    description: "Read the text content of a local file.",
    input_schema: {
      type: "object",
      properties: {
        file_path: {
          type: "string",
          description: "Relative path to the file from the project root.",
        },
      },
      required: ["file_path"],
    },
  },
  {
    name: "write_file",
    description: "Write or overwrite a local file with the given text content.",
    input_schema: {
      type: "object",
      properties: {
        file_path: {
          type: "string",
          description: "Relative path for the output file.",
        },
        content: {
          type: "string",
          description: "Full text content to write.",
        },
      },
      required: ["file_path", "content"],
    },
  },
  {
    name: "list_directory",
    description: "List the files and subdirectories inside a directory.",
    input_schema: {
      type: "object",
      properties: {
        dir_path: {
          type: "string",
          description: "Relative path of the directory to list.",
        },
      },
      required: ["dir_path"],
    },
  },
];
 
type ToolInput = Record<string, string>;
 
export function executeTool(name: string, input: ToolInput): string {
  switch (name) {
    case "read_file": {
      const absPath = path.resolve(input.file_path);
      if (!fs.existsSync(absPath)) return `File not found: ${input.file_path}`;
      return fs.readFileSync(absPath, "utf-8");
    }
    case "write_file": {
      const absPath = path.resolve(input.file_path);
      fs.mkdirSync(path.dirname(absPath), { recursive: true });
      fs.writeFileSync(absPath, input.content, "utf-8");
      return `Wrote ${input.content.length} characters to ${input.file_path}`;
    }
    case "list_directory": {
      const absPath = path.resolve(input.dir_path);
      if (!fs.existsSync(absPath))
        return `Directory not found: ${input.dir_path}`;
      return fs.readdirSync(absPath).join("\n");
    }
    default:
      return `Unknown tool: ${name}`;
  }
}

Ces trois outils couvrent les primitives agentiques essentielles : découvrir, lire et écrire. Vous pouvez étendre le même pattern avec des appels HTTP, des requêtes de base de données, ou n'importe quelle API tierce.

Étape 5 : La boucle agentique

La boucle agentique est le cœur de tout système IA multi-étapes. Elle envoie une tâche à Sonnet 5, traite les appels d'outils quand le modèle les demande, et continue de boucler jusqu'à ce que stop_reason soit "end_turn".

Créez src/agent.ts :

import Anthropic from "@anthropic-ai/sdk";
import { client, MODEL } from "./client.js";
import { TOOLS, executeTool } from "./tools.js";
 
export interface AgentResult {
  output: string;
  inputTokens: number;
  outputTokens: number;
  iterations: number;
}
 
export async function runAgent(
  task: string,
  maxIterations = 15
): Promise<AgentResult> {
  const messages: Anthropic.MessageParam[] = [
    { role: "user", content: task },
  ];
 
  let totalInput = 0;
  let totalOutput = 0;
  let iteration = 0;
 
  while (iteration < maxIterations) {
    iteration++;
 
    const response = await client.messages.create({
      model: MODEL,
      max_tokens: 4096,
      tools: TOOLS,
      messages,
    });
 
    totalInput += response.usage.input_tokens;
    totalOutput += response.usage.output_tokens;
 
    // Toujours ajouter le tour assistant à l'historique
    messages.push({ role: "assistant", content: response.content });
 
    if (response.stop_reason === "end_turn") {
      const finalText = response.content
        .filter((b): b is Anthropic.TextBlock => b.type === "text")
        .map((b) => b.text)
        .join("\n");
 
      return {
        output: finalText,
        inputTokens: totalInput,
        outputTokens: totalOutput,
        iterations: iteration,
      };
    }
 
    if (response.stop_reason === "tool_use") {
      const toolResults: Anthropic.ToolResultBlockParam[] = response.content
        .filter((b): b is Anthropic.ToolUseBlock => b.type === "tool_use")
        .map((b) => ({
          type: "tool_result" as const,
          tool_use_id: b.id,
          content: executeTool(b.name, b.input as Record<string, string>),
        }));
 
      messages.push({ role: "user", content: toolResults });
      continue;
    }
 
    // Raison d'arrêt inattendue (max_tokens, etc.) — sortir de boucle
    break;
  }
 
  return {
    output: "Agent reached the iteration limit without completing the task.",
    inputTokens: totalInput,
    outputTokens: totalOutput,
    iterations: iteration,
  };
}

Décisions de conception à noter :

  • Toujours ajouter les tours assistant. L'API Anthropic exige que chaque message assistant contenant des blocs tool_use soit dans l'historique avant d'envoyer les résultats des outils.
  • Break explicite sur les raisons d'arrêt inattendues. Si stop_reason est "max_tokens", la boucle tournerait silencieusement. Le break permet à l'appelant de voir le résultat partiel.
  • Garde maxIterations. Un garde-fou contre les agents incontrôlables. 15 itérations couvre la plupart des tâches pratiques ; augmentez-le pour des opérations multi-fichiers complexes.

Étape 6 : Suivi du coût

Ajoutez le calcul des coûts à src/agent.ts :

// Tarif introductif valable jusqu'au 2026-08-31
const INTRO_INPUT_PER_TOKEN = 2 / 1_000_000;
const INTRO_OUTPUT_PER_TOKEN = 10 / 1_000_000;
 
export function calculateCost(inputTokens: number, outputTokens: number): number {
  return (
    inputTokens * INTRO_INPUT_PER_TOKEN +
    outputTokens * INTRO_OUTPUT_PER_TOKEN
  );
}

Assemblez tout dans src/index.ts :

import { runAgent, calculateCost } from "./agent.js";
 
const result = await runAgent(
  "List the files in the src directory, read client.ts, and summarize " +
    "what it does in two sentences."
);
 
console.log("\n=== Agent Output ===");
console.log(result.output);
console.log("\n=== Usage ===");
console.log(`Iterations  : ${result.iterations}`);
console.log(`Input tokens: ${result.inputTokens.toLocaleString()}`);
console.log(`Output tokens: ${result.outputTokens.toLocaleString()}`);
console.log(
  `Estimated cost: $${calculateCost(result.inputTokens, result.outputTokens).toFixed(6)}`
);

Lancez l'agent complet :

npm run dev

Sonnet 5 appellera list_directory, puis read_file, puis renverra un résumé en deux phrases. Le coût pour une tâche aussi petite est typiquement inférieur à $0,001 — dans les limites d'un budget raisonnable pour des pipelines automatisés exécutant des centaines de tâches par jour.

Étape 7 : Tests

Écrivez un test d'intégration minimal en utilisant le test runner intégré de Node :

// src/agent.test.ts
import { test } from "node:test";
import assert from "node:assert";
import { chat } from "./client.js";
import { executeTool } from "./tools.js";
 
test("chat returns a string response", async () => {
  const response = await chat("Say the exact string 'test-ok' and nothing else.");
  assert.ok(
    response.includes("test-ok"),
    `Expected 'test-ok' in response, got: ${response}`
  );
});
 
test("executeTool list_directory returns file names", () => {
  const result = executeTool("list_directory", { dir_path: "src" });
  assert.ok(result.includes("client.ts"), `Unexpected listing: ${result}`);
});
 
test("executeTool returns error for missing path", () => {
  const result = executeTool("read_file", { file_path: "nonexistent.ts" });
  assert.ok(result.startsWith("File not found"), `Unexpected: ${result}`);
});

Lancez :

npm test

Le test de chat effectue un appel API réel, ce qui coûte quelques micro-dollars et prend moins d'une seconde. Gardez-le en CI sur un calendrier à faible fréquence plutôt qu'à chaque commit.

Dépannage

AuthenticationError: 401 — Votre clé API est manquante ou invalide. Vérifiez que ANTHROPIC_API_KEY est défini dans .env et que le flag --env-file=.env est passé à tsx.

Error: Unexpected content type — La fonction chat() attend un bloc text comme premier élément de contenu. Si le prompt déclenche une réponse avec appel d'outil, passez à runAgent() à la place.

L'agent atteint la limite d'itérations — La description de la tâche est probablement trop ouverte pour que le modèle déclare sa complétion. Ajoutez des critères de succès explicites : "Faire X, puis Y, puis répondre 'done' quand c'est fini."

Comptages de tokens plus élevés que prévu — Le tokeniseur de Sonnet 5 peut s'étendre jusqu'à 1,35x sur du contenu dense en code par rapport à Sonnet 4.6. Journalisez response.usage à chaque tour pour identifier les itérations gourmandes en tokens.

stop_reason: "max_tokens" — Augmentez max_tokens dans l'appel messages.create. Sonnet 5 supporte jusqu'à 200 000 tokens en entrée ; le paramètre max_tokens contrôle le budget de sortie par tour, pas le contexte total.

Erreurs de format de résultat d'outil — Chaque bloc tool_result doit inclure un tool_use_id correspondant au bloc tool_use associé. Le SDK applique cela au niveau des types ; si vous voyez des erreurs de forme, assurez-vous d'utiliser les types SDK plutôt que du JSON brut.

Prochaines étapes

  • Ajoutez un prompt système pour donner à l'agent un rôle persistant, un format de sortie ou des contraintes. Passez-le comme premier message avec role: "user" ou utilisez le paramètre de premier niveau system sur messages.create.
  • Implémentez des outils supplémentaires — appels HTTP, requêtes de base de données, exécution shell — en suivant le même pattern de schéma d'entrée.
  • Persistez l'historique de conversation entre les sessions en sérialisant le tableau messages dans un fichier JSON ou une ligne de base de données.
  • Migrez depuis Opus 4.8 en changeant l'identifiant du modèle. Faites tourner les deux en parallèle sur un ensemble de tâches échantillon et comparez les sorties avant de vous engager dans la migration.
  • Explorez le traitement par lots via client.beta.messages.batches.create() pour les charges de travail en volume où la latence n'est pas critique — le mode batch offre jusqu'à 50 % de réduction des coûts.
  • Connectez-vous aux serveurs MCP via le client MCP expérimental du SDK Anthropic pour donner à votre agent un accès à n'importe quel outil Model Context Protocol sans écrire de schémas d'outils personnalisés.

Conclusion

Claude Sonnet 5 élève le plafond de la programmation agentique au niveau Sonnet sans le coût d'Opus. Les patterns couverts ici — client typé, streaming, appels d'outils et boucle agentique explicite — forment le cœur de la plupart des systèmes IA en production. La fenêtre tarifaire introductive jusqu'à fin août 2026 fait de ce moment le bon pour construire, évaluer et optimiser avant que les tarifs standards n'entrent en vigueur. Tout ce qui est dans ce tutoriel monte en charge proprement, d'un prototype local à une fonction serverless ou un worker d'arrière-plan de longue durée.

● Tags
#claude-sonnet-5#anthropic#typescript#ai-agents#tool-use#llm#intermediate#28 min de lecture
● Partage
● Une question ?

Discutez de cet article avec un agent Noqta.

AI Bot
AI Bot
Author · noqta
Suivre ↗

● À lire ensuite

Créer un agent ACP en TypeScript : connecter n'importe quel éditeur à votre agent IA (2026)
● Tutorial

Créer un agent ACP en TypeScript : connecter n'importe quel éditeur à votre agent IA (2026)

30 juin 2026
Construire un Agent IA Autonome avec Agentic RAG et Next.js
● Tutorial

Construire un Agent IA Autonome avec Agentic RAG et Next.js

11 févr. 2026
Construire des systèmes multi-agents prêts pour la production avec Agno en Python
● Tutorial

Construire des systèmes multi-agents prêts pour la production avec Agno en Python

7 juin 2026
Noqta
Conditions générales · Politique de Confidentialité
Services
  • Automatisation IA
  • Agents IA
  • Automatisation CX
  • Vibe Coding
  • Gestion de Projet
  • Assurance Qualité
  • Développement Web
  • Intégration API
  • Applications Métier
  • Maintenance
  • Low-Code/No-Code
Liens
  • À propos de nous
  • Comment ça marche?
  • Actualités
  • Tutoriels
  • Blog
  • Contact
  • FAQ
  • Ressources
Régions
  • Arabie Saoudite
  • Émirats Arabes Unis
  • Qatar
  • Bahreïn
  • Oman
  • Libye
  • Tunisie
  • Algérie
  • Maroc
Entreprise
  • Noqta, Tunisie, Tunis, téléphone +216 40 385 594
© Noqta. Tous droits réservés.