---
title: Strumento memoria
url: https://platform.claude.com/docs/it/agents-and-tools/tool-use/memory-tool
description: Consenti a Claude di archiviare e recuperare informazioni tra le conversazioni implementando le operazioni sui file dello strumento memoria nella tua applicazione.
---

Lo strumento memoria ("memory tool") consente a Claude di archiviare e recuperare informazioni tra le conversazioni in una directory di file di memoria. Claude può creare, leggere, aggiornare ed eliminare file che persistono tra le sessioni, accumulando conoscenza nel tempo senza mantenere tutto nella "context window" (finestra di contesto).

La memoria supporta il recupero del contesto just-in-time. Invece di caricare tutte le informazioni rilevanti in anticipo, un agente registra ciò che apprende nei file di memoria e li rilegge su richiesta. Questo mantiene il contesto attivo concentrato sul compito corrente, il che è importante per le sessioni di lunga durata che altrimenti sovraccaricherebbero la finestra di contesto. Consulta [Effective context engineering](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents) per il pattern più ampio.

Lo strumento memoria opera lato client: Claude richiede operazioni sui file e la tua applicazione le esegue. Tu controlli dove e come i dati vengono archiviati attraverso la tua infrastruttura.

<Note>
  Contattaci tramite il [modulo di feedback](https://forms.gle/YXC2EKGMhjN1c4L88) per condividere il tuo feedback su questa funzionalità.
</Note>

<Note>
  Per scoprire come la "zero data retention" (conservazione zero dei dati), o ZDR, si applica a questa funzionalità, consulta [API e conservazione dei dati](https://platform.claude.com/docs/it/manage-claude/api-and-data-retention).
</Note>

## Casi d'uso

* Mantenere il contesto del progetto tra più sessioni dell'agente
* Applicare le lezioni apprese da interazioni, decisioni e feedback passati a nuovi compiti
* Costruire una base di conoscenza nel tempo

## Come funziona

Quando lo strumento memoria è abilitato, Claude controlla automaticamente la sua directory di memoria prima di iniziare un compito. Mentre lavora, Claude archivia ciò che apprende in file sotto `/memories` e li rilegge nelle conversazioni successive per continuare il lavoro precedente.

Poiché lo strumento memoria è lato client, Claude richiede soltanto le operazioni di memoria. La tua applicazione esegue ogni richiesta su uno storage che controlli e restituisce il risultato in un blocco `tool_result` (vedi [Gestire le chiamate agli strumenti](https://platform.claude.com/docs/it/agents-and-tools/tool-use/handle-tool-calls)). Il percorso `/memories` è un prefisso che il tuo handler mappa su uno storage reale, come una directory per utente o chiavi in un database. La memoria risiede interamente nella tua applicazione. Una conversazione successiva continua dalla stessa memoria quando invia la stessa voce `tools` e il tuo handler serve lo stesso archivio. Per sicurezza, limita tutte le operazioni di memoria alla directory `/memories` (vedi [Protezione dal path traversal](https://platform.claude.com/docs/it/agents-and-tools/tool-use/memory-tool#path-traversal-protection)).

### Esempio: come funzionano le chiamate allo strumento memoria

Un'interazione tipica si presenta così:

**1. Richiesta dell'utente:**

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

**2. Claude controlla la directory di memoria:**

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

Claude chiama lo strumento memoria:

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

**3. La tua applicazione restituisce il contenuto della directory:**

```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 legge i file rilevanti:**

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

**5. La tua applicazione restituisce il contenuto del file:**

```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 usa la memoria per aiutare:**

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

Lo strumento memoria è disponibile su tutti i modelli Claude 4 e successivi. Per l'elenco completo degli strumenti forniti da Anthropic, consulta il [Riferimento degli strumenti](https://platform.claude.com/docs/it/agents-and-tools/tool-use/tool-reference).

## Per iniziare

L'uso dello strumento memoria richiede due passaggi:

1. Aggiungi lo strumento memoria alla tua richiesta. La voce `tools` `{"type": "memory_20250818", "name": "memory"}` è l'intera configurazione: il `name` deve essere `memory` e non devi definire uno schema di input per uno strumento fornito da Anthropic.
2. Implementa un handler lato client per ogni comando di memoria. Il tuo handler deve rifiutare i percorsi al di fuori di `/memories`, quindi leggi [Protezione dal path traversal](https://platform.claude.com/docs/it/agents-and-tools/tool-use/memory-tool#path-traversal-protection) prima di scriverlo.

## Utilizzo di 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>

## Implementare l'handler della memoria

La risposta di Claude a una richiesta come la precedente termina con un blocco `tool_use` che richiede un'operazione di memoria, come `view /memories`. La tua applicazione esegue l'operazione e restituisce il risultato in un blocco `tool_result`, quindi rinvia la conversazione affinché Claude possa continuare: è il [ciclo standard di uso degli strumenti](https://platform.claude.com/docs/it/agents-and-tools/tool-use/handle-tool-calls).

Quattro SDK forniscono helper per lo strumento di memoria che gestiscono l'interfaccia dello strumento e il ciclo. Crea una sottoclasse di `BetaAbstractMemoryTool` (Python e C#), usa `betaMemoryTool` (TypeScript) o implementa `BetaMemoryToolHandler` (Java) per basare la memoria sul tuo storage, come file su disco, un database, uno storage cloud o file crittografati. Python e TypeScript includono anche un'implementazione pronta all'uso basata sul filesystem locale, `BetaLocalFilesystemMemoryTool`. Gli helper e i tool runner si trovano nel namespace beta del tuo SDK, anche se lo strumento di memoria in sé non richiede un header beta. Gli SDK Go e Ruby non hanno un helper per la memoria, quindi quegli esempi eseguono autonomamente il ciclo di uso degli strumenti, mentre PHP racchiude la closure del tuo handler nel suo `BetaRunnableTool` generico. Tutti e tre usano un archivio in memoria che sostituirai con il tuo storage.

<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();

  // La tua sottoclasse di 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"
  )

  // Uno store in memoria che associa i percorsi dei file di memoria ai rispettivi contenuti.
  // In produzione usa il tuo sistema di archiviazione.
  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();

    // La tua implementazione di BetaMemoryToolHandler dei sei comandi di memoria
    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();

  // Uno store in memoria che associa i percorsi dei file di memoria ai rispettivi contenuti.
  // In produzione usa il tuo sistema di archiviazione.
  $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

  # Uno store in memoria che associa i percorsi dei file di memoria ai rispettivi contenuti.
  # In produzione, usa il tuo sistema di archiviazione.
  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>

Gli archivi in memoria negli esempi Go, PHP e Ruby li rendono autonomi: ciascuno smista le operazioni in base al campo `command` nell'`input` del blocco `tool_use` e restituisce le stringhe descritte in [Comandi dello strumento](https://platform.claude.com/docs/it/agents-and-tools/tool-use/memory-tool#tool-commands). Un handler di produzione necessita anche della [validazione dei percorsi](https://platform.claude.com/docs/it/agents-and-tools/tool-use/memory-tool#path-traversal-protection) che questi archivi dimostrativi omettono. Per gli esempi completi degli SDK, consulta:

* 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)

## Comandi dello strumento

La tua implementazione lato client deve gestire i seguenti comandi. Queste specifiche descrivono i comportamenti e le stringhe di ritorno consigliati: Claude legge qualsiasi testo contenuto nel risultato dello strumento, quindi puoi restituire stringhe diverse se la tua applicazione lo richiede.

### view

Mostra il contenuto di una directory o di un file con intervalli di righe opzionali:

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

`view_range` è opzionale e si applica alle visualizzazioni di file di testo: `[start_line, end_line]` restituisce quelle righe, e `[start_line, -1]` restituisce tutto da `start_line` fino alla fine del file.

#### Valori di ritorno

**Per le directory:** Restituisci un elenco che mostri file e directory con le relative dimensioni:

```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}
```

* Elenca i file fino a 2 livelli di profondità
* Mostra dimensioni leggibili (ad esempio, `5.5K`, `1.2M`)
* Esclude gli elementi nascosti (file che iniziano con `.`) e `node_modules`
* Usa un carattere di tabulazione tra la dimensione e il percorso

Il primo `view` di `/memories` su un archivio vuoto non è un errore. Se il tuo SDK include uno strumento di memoria basato sul filesystem locale, `BetaLocalFilesystemMemoryTool`, questo crea la radice della memoria prima della prima chiamata di Claude e restituisce l'intestazione dell'elenco seguita da un'unica riga con dimensione e percorso per la directory vuota stessa.

**Per i file:** Restituisci il contenuto del file con un'intestazione e i numeri di riga:

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

Formattazione dei numeri di riga:

* **Larghezza:** 6 caratteri, allineati a destra con riempimento di spazi
* **Separatore:** Carattere di tabulazione tra il numero di riga e il contenuto
* **Indicizzazione:** a partire da 1 (la prima riga è la riga 1)
* **Limite di righe:** I file con più di 999.999 righe devono restituire un errore: `"File {path} exceeds maximum line limit of 999,999 lines."`

**Output di esempio:**

```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 descrizione dello strumento di Claude indica inoltre che `view` visualizza i file immagine (`.jpg`, `.jpeg` e `.png`) e tronca la visualizzazione testuale dei file più lunghi di 16.000 caratteri. Aspettati chiamate `view` su percorsi di immagini e successive visualizzazioni per intervalli di file lunghi.

#### Gestione degli errori

* **Il file o la directory non esiste:** `"The path {path} does not exist. Please provide a valid path."`

### create

Crea un nuovo file:

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

#### Valori di ritorno

* **Successo:** `"File created successfully at: {path}"`

#### Gestione degli errori

* **Il file esiste già:** `"Error: File {path} already exists"`

La descrizione dello strumento di Claude dice che `create` "crea o sovrascrive" un file, quindi aspettati chiamate `create` su percorsi già esistenti. Restituire l'errore è il comportamento di riferimento, e sovrascrivere invece è una scelta di implementazione valida.

### str\_replace

Sostituisce del testo in un file:

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

`new_str` è opzionale per `str_replace`: quando viene omesso, `old_str` viene eliminato senza sostituzione.

#### Valori di ritorno

* **Successo:** `"The memory file has been edited."` seguito da un frammento del file modificato con i numeri di riga

#### Gestione degli errori

* **Il file non esiste:** `"Error: The path {path} does not exist. Please provide a valid path."`
* **Testo non trovato:** ``"No replacement was performed, old_str `\{old_str}` did not appear verbatim in {path}."``
* **Testo duplicato:** Quando `old_str` appare più volte, restituisci: ``"No replacement was performed. Multiple occurrences of old_str `\{old_str}` in lines: {line_numbers}. Please ensure it is unique"``

#### Gestione delle directory

Se il percorso è una directory, restituisci un errore "il file non esiste".

### insert

Inserisce del testo in una riga specifica:

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

`insert_text` viene inserito dopo la riga `insert_line`, e `0` inserisce all'inizio del file.

#### Valori di ritorno

* **Successo:** `"The file {path} has been edited."`

#### Gestione degli errori

* **Il file non esiste:** `"Error: The path {path} does not exist"`
* **Numero di riga non valido:** ``"Error: Invalid `insert_line` parameter: {insert_line}. It should be within the range of lines of the file: [0, {n_lines}]"``

#### Gestione delle directory

Se il percorso è una directory, restituisci un errore "il file non esiste".

### delete

Elimina un file o una directory:

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

#### Valori di ritorno

* **Successo:** `"Successfully deleted {path}"`

#### Gestione degli errori

* **Il file o la directory non esiste:** `"Error: The path {path} does not exist"`

#### Gestione delle directory

Elimina la directory e tutto il suo contenuto in modo ricorsivo. La descrizione dello strumento dice a Claude che non può eliminare la directory `/memories` stessa, quindi rifiuta un `delete` il cui percorso è la radice della memoria.

### rename

Rinomina o sposta un file o una directory:

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

#### Valori di ritorno

* **Successo:** `"Successfully renamed {old_path} to {new_path}"`

#### Gestione degli errori

* **L'origine non esiste:** `"Error: The path {old_path} does not exist"`
* **La destinazione esiste già:** Restituisci un errore (non sovrascrivere): `"Error: The destination {new_path} already exists"`

#### Gestione delle directory

Rinomina la directory. La descrizione dello strumento dice a Claude che non può rinominare la directory `/memories` stessa, quindi rifiuta un `rename` il cui `old_path` è la radice della memoria.

## Indicazioni per il prompting

Quando lo strumento memoria è presente nei `tools` della tua richiesta, l'API aggiunge automaticamente questa istruzione al "system prompt" (prompt di sistema). Non devi inviarla tu stesso:

```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 descrizione dello strumento di Claude gli dice già di mantenere organizzata la directory di memoria, quindi non devi ripetere quell'istruzione. Se Claude crea comunque file di memoria disordinati, puoi rafforzarla nel tuo 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.
```

Puoi anche guidare ciò che Claude scrive in memoria. Ad esempio: "Only write down information relevant to \<topic> in your memory system."

## Considerazioni sulla sicurezza

La tua applicazione esegue ogni operazione sui file richiesta da Claude, quindi queste protezioni sono tua responsabilità:

### Informazioni sensibili

Claude di solito rifiuta di scrivere informazioni sensibili nei file di memoria. Per garanzie più forti, aggiungi una validazione che rimuova i dati sensibili prima che il tuo handler scriva il file.

### Dimensione dello storage dei file

Tieni traccia delle dimensioni dei file di memoria e limita quanto un file può crescere. Considera di limitare quanti caratteri restituisce il comando `view`, e lascia che Claude sfogli il resto con `view_range`.

### Scadenza della memoria

Elimina periodicamente i file di memoria a cui non si accede da molto tempo.

### Protezione dal path traversal

<Warning>
  Un percorso malevolo come `/memories/../../secrets.env` può raggiungere file al di fuori della directory `/memories`. La tua implementazione deve validare ogni percorso in ogni comando per prevenire attacchi di directory traversal.
</Warning>

Considera queste protezioni:

* Valida che tutti i percorsi inizino con `/memories`
* Risolvi i percorsi nella loro forma canonica e verifica che rimangano all'interno della directory di memoria
* Rifiuta i percorsi contenenti sequenze come `../`, `..\\` o altri pattern di traversal
* Fai attenzione alle sequenze di traversal codificate in URL (`%2e%2e%2f`)
* Usa le utilità di sicurezza dei percorsi integrate nel tuo linguaggio (ad esempio, `pathlib.Path.resolve()` e `relative_to()` di Python)

## Gestione degli errori

Lo strumento memoria usa pattern di gestione degli errori simili a quelli dello [strumento editor di testo](https://platform.claude.com/docs/it/agents-and-tools/tool-use/text-editor-tool#handle-errors). I messaggi di errore di ciascun comando sono elencati in [Comandi dello strumento](https://platform.claude.com/docs/it/agents-and-tools/tool-use/memory-tool#tool-commands). Per restituire un errore a Claude, imposta `is_error` su `true` nel risultato dello strumento e inserisci il messaggio in `content`:

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

## Integrazione con il context editing

Lo strumento memoria si abbina al "context editing" (modifica del contesto) per gestire conversazioni di lunga durata. Per i dettagli, consulta [Context editing](https://platform.claude.com/docs/it/build-with-claude/context-editing).

## Utilizzo con la compattazione

Lo strumento memoria può anche essere abbinato alla [compattazione](https://platform.claude.com/docs/it/build-with-claude/compaction) ("compaction"), che riassume lato server il contesto più vecchio della conversazione. Il context editing cancella specifici risultati degli strumenti sul client. La compattazione riassume automaticamente l'intera conversazione sul server quando la conversazione si avvicina al limite della finestra di contesto.

Per gli agenti di lunga durata, considera di usare entrambi: la compattazione mantiene piccolo il contesto attivo senza contabilità lato client, e la memoria preserva le informazioni che devono sopravvivere al riassunto.

## Pattern di sviluppo software multisessione

Per i progetti software che si estendono su più sessioni dell'agente, imposta i file di memoria deliberatamente invece di scriverli ad hoc man mano che il lavoro procede. Il seguente pattern trasforma la memoria in un meccanismo di ripristino: ogni nuova sessione riprende dallo stato registrato dall'ultima.

### Come funziona il pattern

1. **Sessione di inizializzazione:** La prima sessione imposta i file di memoria prima che inizi qualsiasi lavoro sostanziale. Questo include un registro dei progressi (che traccia cosa è stato fatto e cosa viene dopo), una checklist delle funzionalità (che definisce l'ambito del lavoro) e un riferimento a qualsiasi script di avvio o inizializzazione di cui il progetto ha bisogno.

2. **Sessioni successive:** Ogni nuova sessione si apre leggendo quei file di memoria. Questo ripristina lo stato del progetto senza riesplorare la base di codice o ripercorrere le decisioni precedenti.

3. **Aggiornamento di fine sessione:** Prima che una sessione termini, aggiorna il registro dei progressi con ciò che è stato completato e ciò che rimane. Questo garantisce che la sessione successiva abbia un punto di partenza accurato.

### Principio chiave

Lavora su una funzionalità alla volta. Segna una funzionalità come completata solo dopo che una verifica end-to-end conferma che funziona, non quando il codice è scritto. Questo mantiene accurato il registro dei progressi da una sessione all'altra.

<Tip>
  Per un caso di studio dettagliato di questo pattern nella pratica, inclusi lo script di inizializzazione, la struttura del file dei progressi e il ripristino basato su git, consulta [Effective harnesses for long-running agents](https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents).
</Tip>

## Prossimi passi

<CardGroup cols={2}>
  <Card title="Strumento Bash" icon="terminal" href="https://platform.claude.com/docs/it/agents-and-tools/tool-use/bash-tool">
    Esegui comandi shell in una sessione bash persistente.
  </Card>

  <Card title="Context editing" icon="edit" href="https://platform.claude.com/docs/it/build-with-claude/context-editing">
    Gestisci automaticamente il contesto della conversazione man mano che cresce con il context editing.
  </Card>

  <Card title="Compattazione" icon="stack" href="https://platform.claude.com/docs/it/build-with-claude/compaction">
    Compattazione del contesto lato server per gestire conversazioni lunghe che si avvicinano ai limiti della finestra di contesto.
  </Card>

  <Card title="Riferimento degli strumenti" icon="book" href="https://platform.claude.com/docs/it/agents-and-tools/tool-use/tool-reference">
    Elenco degli strumenti forniti da Anthropic e riferimento per le proprietà opzionali di definizione degli strumenti.
  </Card>
</CardGroup>
