---
title: Outil de mémoire
url: https://platform.claude.com/docs/fr/agents-and-tools/tool-use/memory-tool
description: Permettez à Claude de stocker et de récupérer des informations d'une conversation à l'autre en implémentant les opérations de fichiers de l'outil de mémoire dans votre application.
---

L'outil de mémoire permet à Claude de stocker et de récupérer des informations d'une conversation à l'autre dans un répertoire de fichiers de mémoire. Claude peut créer, lire, mettre à jour et supprimer des fichiers qui persistent entre les sessions, accumulant ainsi des connaissances au fil du temps sans tout conserver dans la « context window » (fenêtre de contexte).

La mémoire prend en charge la récupération de contexte juste-à-temps. Plutôt que de charger toutes les informations pertinentes dès le départ, un agent consigne ce qu'il apprend dans des fichiers de mémoire et les relit à la demande. Cela permet de garder le contexte actif concentré sur la tâche en cours, ce qui est important pour les sessions de longue durée qui, autrement, satureraient la fenêtre de contexte. Consultez [Effective context engineering](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents) pour découvrir le modèle plus général.

L'outil de mémoire fonctionne côté client : Claude demande des opérations de fichiers, et votre application les exécute. Vous contrôlez où et comment les données sont stockées via votre propre infrastructure.

<Note>
  Contactez-nous via le [formulaire de commentaires](https://forms.gle/YXC2EKGMhjN1c4L88) pour partager vos retours sur cette fonctionnalité.
</Note>

<Note>
  Pour savoir comment la « zero data retention » (rétention zéro des données), ou ZDR, s'applique à cette fonctionnalité, consultez [API et rétention des données](https://platform.claude.com/docs/fr/manage-claude/api-and-data-retention).
</Note>

## Cas d'utilisation

* Maintenir le contexte d'un projet sur plusieurs sessions d'agent
* Appliquer les enseignements tirés des interactions, décisions et retours passés à de nouvelles tâches
* Constituer une base de connaissances au fil du temps

## Fonctionnement

Lorsque l'outil de mémoire est activé, Claude vérifie automatiquement son répertoire de mémoire avant de commencer une tâche. Au fur et à mesure de son travail, Claude stocke ce qu'il apprend dans des fichiers sous `/memories` et les relit lors de conversations ultérieures pour poursuivre un travail antérieur.

Comme l'outil de mémoire fonctionne côté client, Claude ne fait que demander des opérations de mémoire. Votre application exécute chaque requête sur un stockage que vous contrôlez et renvoie le résultat dans un bloc `tool_result` (voir [Gérer les appels d'outils](https://platform.claude.com/docs/fr/agents-and-tools/tool-use/handle-tool-calls)). Le chemin `/memories` est un préfixe que votre gestionnaire fait correspondre à un stockage réel, tel qu'un répertoire par utilisateur ou des clés dans une base de données. La mémoire réside entièrement dans votre application. Une conversation ultérieure reprend à partir de la même mémoire lorsqu'elle envoie la même entrée `tools` et que votre gestionnaire sert le même magasin de données. Pour des raisons de sécurité, limitez toutes les opérations de mémoire au répertoire `/memories` (voir [Protection contre la traversée de chemin](https://platform.claude.com/docs/fr/agents-and-tools/tool-use/memory-tool#path-traversal-protection)).

### Exemple : fonctionnement des appels de l'outil de mémoire

Une interaction typique ressemble à ceci :

**1. Requête de l'utilisateur :**

```text wrap
"Help me respond to this customer service ticket."
```

**2. Claude vérifie le répertoire de mémoire :**

```text wrap
"I'll help you respond to the customer service ticket. Let me check my memory for any previous context."
```

Claude appelle l'outil de mémoire :

```json
{
  "type": "tool_use",
  "id": "toolu_01C4D5E6F7G8H9I0J1K2L3M4",
  "name": "memory",
  "input": {
    "command": "view",
    "path": "/memories"
  }
}
```

**3. Votre application renvoie le contenu du répertoire :**

```json
{
  "type": "tool_result",
  "tool_use_id": "toolu_01C4D5E6F7G8H9I0J1K2L3M4",
  "content": "Here're the files and directories up to 2 levels deep in /memories, excluding hidden items and node_modules:\n4.0K\t/memories\n1.5K\t/memories/customer_service_guidelines.xml\n2.0K\t/memories/refund_policies.xml"
}
```

**4. Claude lit les fichiers pertinents :**

```json
{
  "type": "tool_use",
  "id": "toolu_01D5E6F7G8H9I0J1K2L3M4N5",
  "name": "memory",
  "input": {
    "command": "view",
    "path": "/memories/customer_service_guidelines.xml"
  }
}
```

**5. Votre application renvoie le contenu du fichier :**

```json
{
  "type": "tool_result",
  "tool_use_id": "toolu_01D5E6F7G8H9I0J1K2L3M4N5",
  "content": "Here's the content of /memories/customer_service_guidelines.xml with line numbers:\n     1\t<guidelines>\n     2\t<addressing_customers>\n     3\t- Always address customers by their first name\n     4\t- Use empathetic language\n..."
}
```

**6. Claude utilise la mémoire pour vous aider :**

```text wrap
"Based on your customer service guidelines, I can help you craft a response. Please share the ticket details..."
```

L'outil de mémoire est disponible sur tous les modèles Claude 4 et ultérieurs. Pour la liste complète des outils fournis par Anthropic, consultez la [Référence des outils](https://platform.claude.com/docs/fr/agents-and-tools/tool-use/tool-reference).

## Premiers pas

L'utilisation de l'outil de mémoire se fait en deux étapes :

1. Ajoutez l'outil de mémoire à votre requête. L'entrée `tools` `{"type": "memory_20250818", "name": "memory"}` constitue l'intégralité de la configuration : le `name` doit être `memory`, et vous ne définissez pas de schéma d'entrée pour un outil fourni par Anthropic.
2. Implémentez un gestionnaire côté client pour chaque commande de mémoire. Votre gestionnaire doit rejeter les chemins situés en dehors de `/memories` ; lisez donc [Protection contre la traversée de chemin](https://platform.claude.com/docs/fr/agents-and-tools/tool-use/memory-tool#path-traversal-protection) avant de l'écrire.

## Utilisation de base

<CodeGroup>
  ```bash cURL
  curl https://api.anthropic.com/v1/messages \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d '{
      "model": "claude-opus-5-5",
      "max_tokens": 2048,
      "messages": [
        {
          "role": "user",
          "content": "Help me respond to this customer service ticket."
        }
      ],
      "tools": [{
        "type": "memory_20250818",
        "name": "memory"
      }]
    }'
  ```

  ```bash CLI
  ant messages create <<'YAML'
  model: claude-opus-5-5
  max_tokens: 2048
  tools:
    - type: memory_20250818
      name: memory
  messages:
    - role: user
      content: Help me respond to this customer service ticket.
  YAML
  ```

  ```python Python
  client = anthropic.Anthropic()

  message = client.messages.create(
      model="claude-opus-5-5",
      max_tokens=2048,
      messages=[
          {
              "role": "user",
              "content": "Help me respond to this customer service ticket.",
          }
      ],
      tools=[{"type": "memory_20250818", "name": "memory"}],
  )

  print(message)
  ```

  ```typescript TypeScript
  const anthropic = new Anthropic();

  const message = await anthropic.messages.create({
    model: "claude-opus-5-5",
    max_tokens: 2048,
    messages: [
      {
        role: "user",
        content: "Help me respond to this customer service ticket."
      }
    ],
    tools: [{ type: "memory_20250818", name: "memory" }]
  });

  console.log(message);
  ```

  ```csharp C#
  var client = new AnthropicClient();

  var message = await client.Messages.Create(
      new()
      {
          Model = Model.ClaudeOpus5_5,
          MaxTokens = 2048,
          Messages =
          [
              new()
              {
                  Role = Role.User,
                  Content = "Help me respond to this customer service ticket.",
              },
          ],
          Tools = [new MemoryTool20250818()],
      }
  );

  Console.WriteLine(message);
  ```

  ```go Go
  client := anthropic.NewClient()

  message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
  	Model:     anthropic.ModelClaudeOpus5_5,
  	MaxTokens: 2048,
  	Messages: []anthropic.MessageParam{
  		anthropic.NewUserMessage(anthropic.NewTextBlock("Help me respond to this customer service ticket.")),
  	},
  	Tools: []anthropic.ToolUnionParam{
  		{OfMemoryTool20250818: &anthropic.MemoryTool20250818Param{}},
  	},
  })
  if err != nil {
  	log.Fatal(err)
  }
  fmt.Println(message)
  ```

  ```java Java
  import com.anthropic.models.messages.MemoryTool20250818;
  // ...
    AnthropicClient client = AnthropicOkHttpClient.fromEnv();

    MessageCreateParams params = MessageCreateParams.builder()
      .model(Model.CLAUDE_OPUS_5_5)
      .maxTokens(2048L)
      .addTool(MemoryTool20250818.builder().build())
      .addUserMessage("Help me respond to this customer service ticket.")
      .build();

    Message message = client.messages().create(params);
    IO.println(message);
  ```

  ```php PHP
  $client = new Client();

  $message = $client->messages->create(
      model: Model::CLAUDE_OPUS_5_5,
      maxTokens: 2048,
      messages: [
          [
              'role' => 'user',
              'content' => 'Help me respond to this customer service ticket.',
          ],
      ],
      tools: [new MemoryTool20250818],
  );

  echo $message;
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  message = client.messages.create(
    model: Anthropic::Model::CLAUDE_OPUS_5_5,
    max_tokens: 2048,
    messages: [
      {
        role: "user",
        content: "Help me respond to this customer service ticket."
      }
    ],
    tools: [
      {
        type: "memory_20250818",
        name: "memory"
      }
    ]
  )
  puts message
  ```
</CodeGroup>

## Implémenter le gestionnaire de mémoire

La réponse de Claude à une requête comme la précédente se termine par un bloc `tool_use` qui demande une opération de mémoire, comme `view /memories`. Votre application exécute l'opération et renvoie le résultat dans un bloc `tool_result`, puis renvoie la conversation afin que Claude puisse continuer : il s'agit de la [boucle d'utilisation d'outils](https://platform.claude.com/docs/fr/agents-and-tools/tool-use/handle-tool-calls) standard.

Quatre SDK fournissent des utilitaires pour l'outil de mémoire qui gèrent l'interface de l'outil et la boucle. Créez une sous-classe de `BetaAbstractMemoryTool` (Python et C#), utilisez `betaMemoryTool` (TypeScript) ou implémentez `BetaMemoryToolHandler` (Java) pour adosser la mémoire à votre propre stockage, comme des fichiers sur disque, une base de données, un stockage cloud ou des fichiers chiffrés. Python et TypeScript fournissent également une implémentation prête à l'emploi basée sur le système de fichiers local, `BetaLocalFilesystemMemoryTool`. Les utilitaires et l'exécuteur d'outils se trouvent dans l'espace de noms bêta de votre SDK, même si l'outil de mémoire lui-même ne nécessite pas d'en-tête bêta. Les SDK Go et Ruby ne disposent pas d'utilitaire de mémoire ; ces exemples exécutent donc eux-mêmes la boucle d'utilisation d'outils, et PHP encapsule la closure de votre gestionnaire dans son `BetaRunnableTool` générique. Tous trois utilisent un stockage en mémoire que vous remplacez par votre propre stockage.

<CodeGroup exclude="shell">
  ```python Python
  import anthropic
  from anthropic.tools import BetaLocalFilesystemMemoryTool

  client = anthropic.Anthropic()
  memory = BetaLocalFilesystemMemoryTool(base_path="./memory")

  runner = client.beta.messages.tool_runner(
      model="claude-opus-5-5",
      max_tokens=1024,
      messages=[
          {
              "role": "user",
              "content": "Remember that customer Acme Corp prefers email follow-ups.",
          }
      ],
      tools=[memory],
  )

  final_message = runner.until_done()
  print(final_message.content)
  ```

  ```typescript TypeScript
  import Anthropic from "@anthropic-ai/sdk";
  import { betaMemoryTool } from "@anthropic-ai/sdk/helpers/beta/memory";
  import { BetaLocalFilesystemMemoryTool } from "@anthropic-ai/sdk/tools/memory/node";

  const client = new Anthropic();

  const backend = await BetaLocalFilesystemMemoryTool.init("./memory");
  const memory = betaMemoryTool(backend); // or pass your own handlers object

  const runner = client.beta.messages.toolRunner({
    model: "claude-opus-5-5",
    max_tokens: 1024,
    messages: [
      {
        role: "user",
        content: "Remember that customer Acme Corp prefers email follow-ups."
      }
    ],
    tools: [memory],
    max_iterations: 10
  });

  const finalMessage = await runner;
  console.log(finalMessage.content);
  ```

  ```csharp C#
  using Anthropic;
  using Anthropic.Helpers.Beta;
  using Anthropic.Models.Beta.Messages;

  var client = new AnthropicClient();

  // Votre sous-classe de BetaAbstractMemoryTool
  var memory = new FilesystemMemoryTool("./memories");

  var runner = client.Beta.Messages.ToolRunner(
      new MessageCreateParams
      {
          Model = Anthropic.Models.Messages.Model.ClaudeOpus5_5,
          MaxTokens = 1024,
          Messages =
          [
              new()
              {
                  Role = Role.User,
                  Content = "Remember that customer Acme Corp prefers email follow-ups.",
              },
          ],
      },
      [memory],
      maxIterations: 10
  );

  var finalMessage = await runner.RunUntilDoneAsync();
  Console.WriteLine(finalMessage);
  ```

  ```go Go
  package main

  import (
  	"context"
  	"encoding/json"
  	"fmt"
  	"log"
  	"slices"
  	"sort"
  	"strings"

  	"github.com/anthropics/anthropic-sdk-go"
  )

  // Un stockage en mémoire qui associe les chemins des fichiers de mémoire à leur contenu.
  // Utilisez votre propre stockage en production.
  var store = map[string]string{}

  type memoryCommand struct {
  	Command    string `json:"command"`
  	Path       string `json:"path"`
  	FileText   string `json:"file_text"`
  	OldStr     string `json:"old_str"`
  	NewStr     string `json:"new_str"`
  	InsertLine int    `json:"insert_line"`
  	InsertText string `json:"insert_text"`
  	OldPath    string `json:"old_path"`
  	NewPath    string `json:"new_path"`
  }

  func executeMemory(raw json.RawMessage) string {
  	var cmd memoryCommand
  	if err := json.Unmarshal(raw, &cmd); err != nil {
  		return "Error: invalid memory command"
  	}
  	switch cmd.Command {
  	case "view":
  		if content, ok := store[cmd.Path]; ok {
  			lines := strings.Split(strings.TrimSuffix(content, "\n"), "\n")
  			for i, line := range lines {
  				lines[i] = fmt.Sprintf("%6d\t%s", i+1, line)
  			}
  			return fmt.Sprintf("Here's the content of %s with line numbers:\n%s", cmd.Path, strings.Join(lines, "\n"))
  		}
  		if cmd.Path == "/memories" {
  			listing := []string{"1.0K\t/memories"}
  			for path := range store {
  				listing = append(listing, "1.0K\t"+path)
  			}
  			sort.Strings(listing[1:])
  			return fmt.Sprintf("Here're the files and directories up to 2 levels deep in %s, excluding hidden items and node_modules:\n%s", cmd.Path, strings.Join(listing, "\n"))
  		}
  		return fmt.Sprintf("The path %s does not exist. Please provide a valid path.", cmd.Path)
  	case "create":
  		store[cmd.Path] = cmd.FileText
  		return "File created successfully at: " + cmd.Path
  	case "str_replace":
  		content, ok := store[cmd.Path]
  		if !ok || !strings.Contains(content, cmd.OldStr) {
  			return fmt.Sprintf("No replacement was performed, old_str `%s` did not appear verbatim in %s.", cmd.OldStr, cmd.Path)
  		}
  		store[cmd.Path] = strings.Replace(content, cmd.OldStr, cmd.NewStr, 1)
  		return "The memory file has been edited."
  	case "insert":
  		content, ok := store[cmd.Path]
  		if !ok {
  			return fmt.Sprintf("Error: The path %s does not exist", cmd.Path)
  		}
  		lines := strings.Split(content, "\n")
  		if cmd.InsertLine < 0 || cmd.InsertLine > len(lines) {
  			return fmt.Sprintf("Error: Invalid `insert_line` parameter: %d. It should be within the range of lines of the file: [0, %d]", cmd.InsertLine, len(lines))
  		}
  		lines = slices.Insert(lines, cmd.InsertLine, strings.TrimSuffix(cmd.InsertText, "\n"))
  		store[cmd.Path] = strings.Join(lines, "\n")
  		return fmt.Sprintf("The file %s has been edited.", cmd.Path)
  	case "delete":
  		if _, ok := store[cmd.Path]; !ok {
  			return fmt.Sprintf("Error: The path %s does not exist", cmd.Path)
  		}
  		delete(store, cmd.Path)
  		return "Successfully deleted " + cmd.Path
  	case "rename":
  		if _, ok := store[cmd.OldPath]; !ok {
  			return fmt.Sprintf("Error: The path %s does not exist", cmd.OldPath)
  		}
  		if _, ok := store[cmd.NewPath]; ok {
  			return fmt.Sprintf("Error: The destination %s already exists", cmd.NewPath)
  		}
  		store[cmd.NewPath] = store[cmd.OldPath]
  		delete(store, cmd.OldPath)
  		return fmt.Sprintf("Successfully renamed %s to %s", cmd.OldPath, cmd.NewPath)
  	default:
  		return "Error: unknown command " + cmd.Command
  	}
  }

  func main() {
  	client := anthropic.NewClient()
  	tools := []anthropic.ToolUnionParam{{OfMemoryTool20250818: &anthropic.MemoryTool20250818Param{}}}
  	messages := []anthropic.MessageParam{
  		anthropic.NewUserMessage(anthropic.NewTextBlock("Remember that customer Acme Corp prefers email follow-ups.")),
  	}

  	for {
  		message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
  			Model:     anthropic.ModelClaudeOpus5_5,
  			MaxTokens: 1024,
  			Messages:  messages,
  			Tools:     tools,
  		})
  		if err != nil {
  			log.Fatal(err)
  		}
  		if message.StopReason != anthropic.StopReasonToolUse {
  			for _, block := range message.Content {
  				if block.Type == "text" {
  					fmt.Println(block.Text)
  				}
  			}
  			break
  		}
  		results := []anthropic.ContentBlockParamUnion{}
  		for _, block := range message.Content {
  			if block.Type == "tool_use" {
  				results = append(results, anthropic.NewToolResultBlock(block.ID, executeMemory(block.Input), false))
  			}
  		}
  		messages = append(messages, message.ToParam(), anthropic.NewUserMessage(results...))
  	}
  }
  ```

  ```java Java
  import com.anthropic.client.AnthropicClient;
  import com.anthropic.client.okhttp.AnthropicOkHttpClient;
  import com.anthropic.helpers.BetaMemoryToolHandler;
  import com.anthropic.helpers.BetaToolRunner;
  import com.anthropic.models.beta.messages.BetaMemoryTool20250818;
  import com.anthropic.models.beta.messages.BetaMessage;
  import com.anthropic.models.beta.messages.MessageCreateParams; // beta package, not models.messages
  import com.anthropic.models.beta.messages.ToolRunnerCreateParams;
  import com.anthropic.models.messages.Model;
  import java.nio.file.Path;

  void main() {
    AnthropicClient client = AnthropicOkHttpClient.fromEnv();

    // Votre implémentation BetaMemoryToolHandler des six commandes de mémoire
    BetaMemoryToolHandler handler = new FileSystemMemoryToolHandler(Path.of("memories"));

    MessageCreateParams createParams = MessageCreateParams.builder()
      .model(Model.CLAUDE_OPUS_5_5)
      .maxTokens(1024L)
      .addTool(BetaMemoryTool20250818.builder().build())
      .addUserMessage("Remember that customer Acme Corp prefers email follow-ups.")
      .build();

    ToolRunnerCreateParams runnerParams = ToolRunnerCreateParams.builder()
      .betaMemoryToolHandler(handler)
      .initialMessageParams(createParams)
      .maxIterations(10)
      .build();

    BetaToolRunner runner = client.beta().messages().toolRunner(runnerParams);
    for (BetaMessage message : runner) {
      IO.println(message);
    }
  }
  ```

  ```php PHP
  <?php

  use Anthropic\Beta\Messages\BetaMemoryTool20250818;
  use Anthropic\Client;
  use Anthropic\Lib\Tools\BetaRunnableTool;
  use Anthropic\Messages\Model;

  $client = new Client();

  // Un stockage en mémoire qui associe les chemins des fichiers de mémoire à leur contenu.
  // Utilisez votre propre stockage en production.
  $store = [];

  $memory = new BetaRunnableTool(
      definition: new BetaMemoryTool20250818,
      run: function (array $input) use (&$store): string {
          $path = $input['path'] ?? '';
          switch ($input['command']) {
              case 'view':
                  if (isset($store[$path])) {
                      $numbered = [];
                      foreach (explode("\n", preg_replace('/\n\z/', '', $store[$path])) as $i => $line) {
                          $numbered[] = sprintf("%6d\t%s", $i + 1, $line);
                      }
                      return "Here's the content of {$path} with line numbers:\n" . implode("\n", $numbered);
                  }
                  if ($path === '/memories') {
                      $listing = ["1.0K\t/memories"];
                      foreach (array_keys($store) as $stored) {
                          $listing[] = "1.0K\t{$stored}";
                      }
                      return "Here're the files and directories up to 2 levels deep in {$path}, excluding hidden items and node_modules:\n" . implode("\n", $listing);
                  }
                  return "The path {$path} does not exist. Please provide a valid path.";
              case 'create':
                  $store[$path] = $input['file_text'];
                  return "File created successfully at: {$path}";
              case 'str_replace':
                  $position = strpos($store[$path] ?? '', $input['old_str']);
                  if ($position === false) {
                      return "No replacement was performed, old_str `{$input['old_str']}` did not appear verbatim in {$path}.";
                  }
                  $store[$path] = substr_replace($store[$path], $input['new_str'] ?? '', $position, strlen($input['old_str']));
                  return 'The memory file has been edited.';
              case 'insert':
                  if (!isset($store[$path])) {
                      return "Error: The path {$path} does not exist";
                  }
                  $lines = explode("\n", $store[$path]);
                  if ($input['insert_line'] < 0 || $input['insert_line'] > count($lines)) {
                      return "Error: Invalid `insert_line` parameter: {$input['insert_line']}. It should be within the range of lines of the file: [0, " . count($lines) . "]";
                  }
                  array_splice($lines, $input['insert_line'], 0, [preg_replace('/\n\z/', '', $input['insert_text'])]);
                  $store[$path] = implode("\n", $lines);
                  return "The file {$path} has been edited.";
              case 'delete':
                  if (!isset($store[$path])) {
                      return "Error: The path {$path} does not exist";
                  }
                  unset($store[$path]);
                  return "Successfully deleted {$path}";
              case 'rename':
                  if (!isset($store[$input['old_path']])) {
                      return "Error: The path {$input['old_path']} does not exist";
                  }
                  if (isset($store[$input['new_path']])) {
                      return "Error: The destination {$input['new_path']} already exists";
                  }
                  $store[$input['new_path']] = $store[$input['old_path']];
                  unset($store[$input['old_path']]);
                  return "Successfully renamed {$input['old_path']} to {$input['new_path']}";
              default:
                  return "Error: unknown command {$input['command']}";
          }
      },
  );

  $runner = $client->beta->messages->toolRunner(
      maxTokens: 1024,
      messages: [['role' => 'user', 'content' => 'Remember that customer Acme Corp prefers email follow-ups.']],
      model: Model::CLAUDE_OPUS_5_5,
      tools: [$memory],
      maxIterations: 10,
  );

  $finalMessage = $runner->runUntilDone();
  print_r($finalMessage->content);
  ```

  ```ruby Ruby
  require "anthropic"

  client = Anthropic::Client.new
  TOOLS = [{type: "memory_20250818", name: "memory"}].freeze

  # Un stockage en mémoire qui associe les chemins des fichiers de mémoire à leur contenu.
  # Utilisez votre propre stockage en production.
  STORE = {}

  def execute_memory(input)
    path = input[:path]
    case input[:command]
    when "view"
      if STORE.key?(path)
        lines = STORE[path].chomp.split("\n", -1)
        lines = [""] if lines.empty?
        numbered = lines.each_with_index.map { |line, i| format("%6d\t%s", i + 1, line) }
        "Here's the content of #{path} with line numbers:\n#{numbered.join("\n")}"
      elsif path == "/memories"
        listing = ["1.0K\t/memories"] + STORE.keys.map { |stored| "1.0K\t#{stored}" }
        "Here're the files and directories up to 2 levels deep in #{path}, excluding hidden items and node_modules:\n#{listing.join("\n")}"
      else
        "The path #{path} does not exist. Please provide a valid path."
      end
    when "create"
      STORE[path] = input[:file_text]
      "File created successfully at: #{path}"
    when "str_replace"
      unless STORE.key?(path) && STORE[path].include?(input[:old_str])
        return "No replacement was performed, old_str `#{input[:old_str]}` did not appear verbatim in #{path}."
      end
      STORE[path] = STORE[path].sub(input[:old_str]) { input[:new_str].to_s }
      "The memory file has been edited."
    when "insert"
      return "Error: The path #{path} does not exist" unless STORE.key?(path)
      lines = STORE[path].split("\n", -1)
      lines = [""] if lines.empty?
      if input[:insert_line] < 0 || input[:insert_line] > lines.length
        return "Error: Invalid `insert_line` parameter: #{input[:insert_line]}. It should be within the range of lines of the file: [0, #{lines.length}]"
      end
      lines.insert(input[:insert_line], input[:insert_text].chomp)
      STORE[path] = lines.join("\n")
      "The file #{path} has been edited."
    when "delete"
      return "Error: The path #{path} does not exist" unless STORE.key?(path)
      STORE.delete(path)
      "Successfully deleted #{path}"
    when "rename"
      return "Error: The path #{input[:old_path]} does not exist" unless STORE.key?(input[:old_path])
      return "Error: The destination #{input[:new_path]} already exists" if STORE.key?(input[:new_path])
      STORE[input[:new_path]] = STORE.delete(input[:old_path])
      "Successfully renamed #{input[:old_path]} to #{input[:new_path]}"
    else
      "Error: unknown command #{input[:command]}"
    end
  end

  messages = [{role: "user", content: "Remember that customer Acme Corp prefers email follow-ups."}]
  loop do
    message = client.messages.create(
      model: Anthropic::Model::CLAUDE_OPUS_5_5,
      max_tokens: 1024,
      messages: messages,
      tools: TOOLS
    )
    unless message.stop_reason == :tool_use
      puts message.content
      break
    end
    tool_results = message.content.filter_map do |block|
      next unless block.type == :tool_use
      {type: "tool_result", tool_use_id: block.id, content: execute_memory(block.input)}
    end
    messages << {role: "assistant", content: message.content} << {role: "user", content: tool_results}
  end
  ```
</CodeGroup>

Les stockages en mémoire des exemples Go, PHP et Ruby les rendent autonomes : chacun effectue un aiguillage sur le champ `command` de l'`input` du bloc `tool_use` et renvoie les chaînes décrites dans [Commandes de l'outil](https://platform.claude.com/docs/fr/agents-and-tools/tool-use/memory-tool#tool-commands). Un gestionnaire de production nécessite également la [validation des chemins](https://platform.claude.com/docs/fr/agents-and-tools/tool-use/memory-tool#path-traversal-protection) que ces stockages de démonstration omettent. Pour les exemples complets propres aux SDK, consultez :

* Python : [examples/memory/basic.py](https://github.com/anthropics/anthropic-sdk-python/blob/main/examples/memory/basic.py)
* TypeScript : [examples/tools-helpers-memory.ts](https://github.com/anthropics/anthropic-sdk-typescript/blob/main/examples/tools-helpers-memory.ts)
* C# : [MemoryToolExample](https://github.com/anthropics/anthropic-sdk-csharp/tree/main/examples/MemoryToolExample)
* Java : [BetaMemoryToolExample.java](https://github.com/anthropics/anthropic-sdk-java/blob/main/anthropic-java-example/src/main/java/com/anthropic/example/BetaMemoryToolExample.java)

## Commandes de l'outil

Votre implémentation côté client doit gérer les commandes suivantes. Ces spécifications décrivent les comportements et les chaînes de retour recommandés : Claude lit le texte contenu dans votre résultat d'outil, quel qu'il soit ; vous pouvez donc renvoyer des chaînes différentes si votre application en a besoin.

### view

Affiche le contenu d'un répertoire ou d'un fichier avec des plages de lignes facultatives :

```json
{
  "command": "view",
  "path": "/memories/notes.txt",
  "view_range": [1, 10]
}
```

`view_range` est facultatif et s'applique aux affichages de fichiers texte : `[start_line, end_line]` renvoie ces lignes, et `[start_line, -1]` renvoie tout depuis `start_line` jusqu'à la fin du fichier.

#### Valeurs de retour

**Pour les répertoires :** renvoyez une liste qui affiche les fichiers et répertoires avec leur taille :

```text
Here're the files and directories up to 2 levels deep in {path}, excluding hidden items and node_modules:
{size}\t{path}
{size}\t{path}/{filename1}
{size}\t{path}/{filename2}
```

* Liste les fichiers jusqu'à 2 niveaux de profondeur
* Affiche des tailles lisibles par un humain (par exemple, `5.5K`, `1.2M`)
* Exclut les éléments cachés (fichiers commençant par `.`) et `node_modules`
* Utilise un caractère de tabulation entre la taille et le chemin

Le premier `view` de `/memories` sur un stockage vide n'est pas une erreur. Lorsque votre SDK fournit un outil de mémoire basé sur le système de fichiers local, `BetaLocalFilesystemMemoryTool`, celui-ci crée la racine de la mémoire avant le premier appel de Claude et renvoie l'en-tête de la liste suivi d'une seule ligne taille-et-chemin pour le répertoire vide lui-même.

**Pour les fichiers :** renvoyez le contenu du fichier avec un en-tête et des numéros de ligne :

```text wrap
Here's the content of {path} with line numbers:
{line_numbers}{tab}{content}
```

Formatage des numéros de ligne :

* **Largeur :** 6 caractères, alignés à droite avec un remplissage par des espaces
* **Séparateur :** caractère de tabulation entre le numéro de ligne et le contenu
* **Indexation :** à partir de 1 (la première ligne est la ligne 1)
* **Limite de lignes :** les fichiers de plus de 999 999 lignes doivent renvoyer une erreur : `"File {path} exceeds maximum line limit of 999,999 lines."`

**Exemple de sortie :**

```text
Here's the content of /memories/notes.txt with line numbers:
     1	Hello World
     2	This is line two
    10	Line ten
   100	Line one hundred
```

La description de l'outil fournie à Claude indique également que `view` affiche les fichiers image (`.jpg`, `.jpeg` et `.png`) et tronque l'affichage texte des fichiers de plus de 16 000 caractères. Attendez-vous à des appels `view` sur des chemins d'images et à des affichages par plages successifs pour les fichiers longs.

#### Gestion des erreurs

* **Le fichier ou le répertoire n'existe pas :** `"The path {path} does not exist. Please provide a valid path."`

### create

Crée un nouveau fichier :

```json
{
  "command": "create",
  "path": "/memories/notes.txt",
  "file_text": "Meeting notes:\n- Discussed project timeline\n- Next steps defined\n"
}
```

#### Valeurs de retour

* **Succès :** `"File created successfully at: {path}"`

#### Gestion des erreurs

* **Le fichier existe déjà :** `"Error: File {path} already exists"`

La description de l'outil de Claude indique que `create` « crée ou écrase » un fichier ; attendez-vous donc à des appels `create` sur des chemins qui existent déjà. Renvoyer l'erreur constitue le comportement de référence, et écraser le fichier à la place est un choix d'implémentation valide.

### str\_replace

Remplace du texte dans un fichier :

```json
{
  "command": "str_replace",
  "path": "/memories/preferences.txt",
  "old_str": "Favorite color: blue",
  "new_str": "Favorite color: green"
}
```

`new_str` est facultatif pour `str_replace` : lorsqu'il est omis, `old_str` est supprimé sans remplacement.

#### Valeurs de retour

* **Succès :** `"The memory file has been edited."` suivi d'un extrait de code du fichier modifié avec les numéros de ligne

#### Gestion des erreurs

* **Le fichier n'existe pas :** `"Error: The path {path} does not exist. Please provide a valid path."`
* **Texte introuvable :** ``"No replacement was performed, old_str `\{old_str}` did not appear verbatim in {path}."``
* **Texte en double :** lorsque `old_str` apparaît plusieurs fois, renvoyez : ``"No replacement was performed. Multiple occurrences of old_str `\{old_str}` in lines: {line_numbers}. Please ensure it is unique"``

#### Gestion des répertoires

Si le chemin est un répertoire, renvoyez une erreur « le fichier n'existe pas ».

### insert

Insère du texte à une ligne spécifique :

```json
{
  "command": "insert",
  "path": "/memories/todo.txt",
  "insert_line": 2,
  "insert_text": "- Review memory tool documentation\n"
}
```

`insert_text` est inséré après la ligne `insert_line`, et `0` insère au début du fichier.

#### Valeurs de retour

* **Succès :** `"The file {path} has been edited."`

#### Gestion des erreurs

* **Le fichier n'existe pas :** `"Error: The path {path} does not exist"`
* **Numéro de ligne invalide :** ``"Error: Invalid `insert_line` parameter: {insert_line}. It should be within the range of lines of the file: [0, {n_lines}]"``

#### Gestion des répertoires

Si le chemin est un répertoire, renvoyez une erreur « le fichier n'existe pas ».

### delete

Supprime un fichier ou un répertoire :

```json
{
  "command": "delete",
  "path": "/memories/old_file.txt"
}
```

#### Valeurs de retour

* **Succès :** `"Successfully deleted {path}"`

#### Gestion des erreurs

* **Le fichier ou le répertoire n'existe pas :** `"Error: The path {path} does not exist"`

#### Gestion des répertoires

Supprime le répertoire et tout son contenu de manière récursive. La description de l'outil indique à Claude qu'il ne peut pas supprimer le répertoire `/memories` lui-même ; rejetez donc un `delete` dont le chemin est la racine de la mémoire.

### rename

Renomme ou déplace un fichier ou un répertoire :

```json
{
  "command": "rename",
  "old_path": "/memories/draft.txt",
  "new_path": "/memories/final.txt"
}
```

#### Valeurs de retour

* **Succès :** `"Successfully renamed {old_path} to {new_path}"`

#### Gestion des erreurs

* **La source n'existe pas :** `"Error: The path {old_path} does not exist"`
* **La destination existe déjà :** renvoyez une erreur (n'écrasez pas) : `"Error: The destination {new_path} already exists"`

#### Gestion des répertoires

Renomme le répertoire. La description de l'outil indique à Claude qu'il ne peut pas renommer le répertoire `/memories` lui-même ; rejetez donc un `rename` dont le `old_path` est la racine de la mémoire.

## Conseils de prompting

Lorsque l'outil de mémoire est présent dans les `tools` de votre requête, l'API ajoute automatiquement cette instruction à l'invite système. Vous n'avez pas besoin de l'envoyer vous-même :

```text wrap
IMPORTANT: ALWAYS VIEW YOUR MEMORY DIRECTORY BEFORE DOING ANYTHING ELSE.
MEMORY PROTOCOL:
1. Use the `view` command of your `memory` tool to check for earlier progress.
2. ... (work on the task) ...
   - As you make progress, record status / progress / thoughts etc in your memory.
ASSUME INTERRUPTION: Your context window might be reset at any moment, so you risk losing any progress that is not recorded in your memory directory.
```

La description de l'outil de Claude lui indique déjà de garder le répertoire de mémoire organisé ; vous n'avez donc pas besoin de répéter cette instruction. Si Claude crée malgré tout des fichiers de mémoire désordonnés, vous pouvez la renforcer dans votre prompt :

```text wrap
Note: when editing your memory folder, always try to keep its content up-to-date, coherent and organized. You can rename or delete files that are no longer relevant. Do not create new files unless necessary.
```

Vous pouvez également orienter ce que Claude écrit en mémoire. Par exemple : « Only write down information relevant to \<topic> in your memory system. »

## Considérations de sécurité

Votre application exécute chaque opération de fichier demandée par Claude ; ces mesures de protection relèvent donc de votre responsabilité :

### Informations sensibles

Claude refuse généralement d'écrire des informations sensibles dans les fichiers de mémoire. Pour des garanties plus solides, ajoutez une validation qui supprime les données sensibles avant que votre gestionnaire n'écrive le fichier.

### Taille du stockage des fichiers

Surveillez la taille des fichiers de mémoire et plafonnez la taille maximale qu'un fichier peut atteindre. Envisagez de plafonner le nombre de caractères renvoyés par la commande `view`, et laissez Claude parcourir le reste avec `view_range`.

### Expiration de la mémoire

Supprimez périodiquement les fichiers de mémoire qui n'ont pas été consultés depuis longtemps.

### Protection contre la traversée de chemin

<Warning>
  Un chemin malveillant tel que `/memories/../../secrets.env` peut atteindre des fichiers situés en dehors du répertoire `/memories`. Votre implémentation doit valider chaque chemin dans chaque commande afin de prévenir les attaques par traversée de répertoire.
</Warning>

Envisagez ces mesures de protection :

* Validez que tous les chemins commencent par `/memories`
* Résolvez les chemins sous leur forme canonique et vérifiez qu'ils restent dans le répertoire de mémoire
* Rejetez les chemins contenant des séquences telles que `../`, `..\\` ou d'autres motifs de traversée
* Surveillez les séquences de traversée encodées en URL (`%2e%2e%2f`)
* Utilisez les utilitaires de sécurité des chemins intégrés à votre langage (par exemple, `pathlib.Path.resolve()` et `relative_to()` en Python)

## Gestion des erreurs

L'outil de mémoire utilise des modèles de gestion des erreurs similaires à ceux de l'[outil d'édition de texte](https://platform.claude.com/docs/fr/agents-and-tools/tool-use/text-editor-tool#handle-errors). Les messages d'erreur de chaque commande sont répertoriés dans la section [Commandes de l'outil](https://platform.claude.com/docs/fr/agents-and-tools/tool-use/memory-tool#tool-commands). Pour renvoyer une erreur à Claude, définissez `is_error` sur `true` dans le résultat de l'outil et placez le message dans `content` :

```json
{
  "type": "tool_result",
  "tool_use_id": "toolu_01C4D5E6F7G8H9I0J1K2L3M4",
  "content": "Error: The path /memories/notes.txt does not exist",
  "is_error": true
}
```

## Intégration avec l'édition de contexte

L'outil de mémoire s'associe à l'édition de contexte pour gérer les conversations de longue durée. Pour plus de détails, consultez [Édition de contexte](https://platform.claude.com/docs/fr/build-with-claude/context-editing).

## Utilisation avec la compaction

L'outil de mémoire peut également être associé à la [compaction](https://platform.claude.com/docs/fr/build-with-claude/compaction), qui résume côté serveur le contexte plus ancien de la conversation. L'édition de contexte efface des résultats d'outils spécifiques côté client. La compaction résume automatiquement l'ensemble de la conversation côté serveur lorsque celle-ci approche de la limite de la fenêtre de contexte.

Pour les agents de longue durée, envisagez d'utiliser les deux : la compaction maintient un contexte actif réduit sans tenue de registre côté client, et la mémoire préserve les informations qui doivent survivre au résumé.

## Modèle de développement logiciel multisession

Pour les projets logiciels qui s'étendent sur plusieurs sessions d'agent, configurez les fichiers de mémoire de manière délibérée plutôt que de les écrire au fil de l'eau à mesure que le travail avance. Le modèle suivant transforme la mémoire en mécanisme de reprise : chaque nouvelle session reprend à partir de l'état enregistré par la précédente.

### Fonctionnement du modèle

1. **Session d'initialisation :** la première session configure les fichiers de mémoire avant le début de tout travail substantiel. Cela comprend un journal de progression (qui suit ce qui a été fait et ce qui vient ensuite), une liste de contrôle des fonctionnalités (qui définit le périmètre du travail) et une référence à tout script de démarrage ou d'initialisation dont le projet a besoin.

2. **Sessions suivantes :** chaque nouvelle session commence par lire ces fichiers de mémoire. Cela restaure l'état du projet sans réexplorer la base de code ni retracer les décisions antérieures.

3. **Mise à jour de fin de session :** avant qu'une session ne se termine, elle met à jour le journal de progression avec ce qui a été accompli et ce qui reste à faire. Cela garantit que la session suivante dispose d'un point de départ précis.

### Principe clé

Travaillez sur une seule fonctionnalité à la fois. Ne marquez une fonctionnalité comme terminée qu'après qu'une vérification de bout en bout a confirmé qu'elle fonctionne, et non lorsque le code est écrit. Cela permet de garder le journal de progression exact d'une session à l'autre.

<Tip>
  Pour une étude de cas détaillée de ce modèle en pratique, incluant le script d'initialisation, la structure du fichier de progression et la reprise basée sur git, consultez [Effective harnesses for long-running agents](https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents).
</Tip>

## Étapes suivantes

<CardGroup cols={2}>
  <Card title="Outil Bash" icon="terminal" href="https://platform.claude.com/docs/fr/agents-and-tools/tool-use/bash-tool">
    Exécutez des commandes shell dans une session bash persistante.
  </Card>

  <Card title="Édition de contexte" icon="edit" href="https://platform.claude.com/docs/fr/build-with-claude/context-editing">
    Gérez automatiquement le contexte de la conversation à mesure qu'il s'accroît grâce à l'édition de contexte.
  </Card>

  <Card title="Compaction" icon="stack" href="https://platform.claude.com/docs/fr/build-with-claude/compaction">
    Compaction du contexte côté serveur pour gérer les longues conversations qui approchent des limites de la fenêtre de contexte.
  </Card>

  <Card title="Référence des outils" icon="book" href="https://platform.claude.com/docs/fr/agents-and-tools/tool-use/tool-reference">
    Répertoire des outils fournis par Anthropic et référence des propriétés facultatives de définition d'outils.
  </Card>
</CardGroup>
