Condividi tramite


Passaggio 4: Memoria e persistenza

Aggiungere contesto all'agente in modo che possa ricordare le preferenze utente, le interazioni passate o le conoscenze esterne.

Per impostazione predefinita, gli agenti archivieranno la cronologia delle chat in un InMemoryChatHistoryProvider o nel servizio di intelligenza artificiale sottostante, a seconda delle esigenze del servizio sottostante.

L'agente seguente usa OpenAI Chat Completion, che non supporta né richiede l'archiviazione della cronologia delle chat nel servizio, quindi crea e usa automaticamente un oggetto InMemoryChatHistoryProvider.

using System;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;

var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
    ?? throw new InvalidOperationException("Set AZURE_OPENAI_ENDPOINT");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";

AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(
        model: deploymentName,
        instructions: "You are a friendly assistant. Keep your answers brief.",
        name: "MemoryAgent");

Avvertimento

DefaultAzureCredential è utile per lo sviluppo, ma richiede un'attenta considerazione nell'ambiente di produzione. Nell'ambiente di produzione prendere in considerazione l'uso di credenziali specifiche ,ad esempio ManagedIdentityCredential, per evitare problemi di latenza, probe di credenziali indesiderate e potenziali rischi per la sicurezza dai meccanismi di fallback.

Per usare un personalizzato ChatHistoryProvider , è possibile passarne uno alle opzioni dell'agente:

using System;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;

var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
    ?? throw new InvalidOperationException("Set AZURE_OPENAI_ENDPOINT");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";

AIAgent agent = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .AsAIAgent(model: deploymentName, options: new ChatClientAgentOptions()
    {
        ChatOptions = new() { Instructions = "You are a helpful assistant." },
        ChatHistoryProvider = new CustomChatHistoryProvider()
    });

Usare una sessione per condividere il contesto tra le esecuzioni:

AgentSession session = await agent.CreateSessionAsync();

Console.WriteLine(await agent.RunAsync("Hello! What's the square root of 9?", session));
Console.WriteLine(await agent.RunAsync("My name is Alice", session));
Console.WriteLine(await agent.RunAsync("What is my name?", session));

Suggerimento

Vedere qui per un'applicazione di esempio eseguibile completa.

Definire un provider di contesto che archivia le informazioni utente nello stato sessione e inserisce istruzioni di personalizzazione:

class UserMemoryProvider(ContextProvider):
    """A context provider that remembers user info in session state."""

    DEFAULT_SOURCE_ID = "user_memory"

    def __init__(self):
        super().__init__(self.DEFAULT_SOURCE_ID)

    async def before_run(
        self,
        *,
        agent: Any,
        session: AgentSession | None,
        context: SessionContext,
        state: dict[str, Any],
    ) -> None:
        """Inject personalization instructions based on stored user info."""
        user_name = state.get("user_name")
        if user_name:
            context.extend_instructions(
                self.source_id,
                f"The user's name is {user_name}. Always address them by name.",
            )
        else:
            context.extend_instructions(
                self.source_id,
                "You don't know the user's name yet. Ask for it politely.",
            )

    async def after_run(
        self,
        *,
        agent: Any,
        session: AgentSession | None,
        context: SessionContext,
        state: dict[str, Any],
    ) -> None:
        """Extract and store user info in session state after each call."""
        for msg in context.input_messages:
            text = msg.text if hasattr(msg, "text") else ""
            if isinstance(text, str) and "my name is" in text.lower():
                state["user_name"] = text.lower().split("my name is")[-1].strip().split()[0].capitalize()

Creare un agente con il fornitore di dati di contesto:

client = FoundryChatClient(
    project_endpoint="https://your-project.services.ai.azure.com",
    model="gpt-4o",
    credential=AzureCliCredential(),
)

agent = Agent(
    client=client,
    name="MemoryAgent",
    instructions="You are a friendly assistant.",
    context_providers=[UserMemoryProvider()],
)

Eseguilo — l'agente ora ha accesso al contesto

session = agent.create_session()

# The provider doesn't know the user yet — it will ask for a name
result = await agent.run("Hello! What's the square root of 9?", session=session)
print(f"Agent: {result}\n")

# Now provide the name — the provider stores it in session state
result = await agent.run("My name is Alice", session=session)
print(f"Agent: {result}\n")

# Subsequent calls are personalized — name persists via session state
result = await agent.run("What is 2 + 2?", session=session)
print(f"Agent: {result}\n")

# Inspect session state to see what the provider stored
provider_state = session.state.get("user_memory", {})
print(f"[Session State] Stored user name: {provider_state.get('user_name')}")

Suggerimento

Vedere l'esempio completo per il file eseguibile completo.

Annotazioni

In Python la persistenza/memoria viene gestita dalle implementazioni di ContextProvider e HistoryProvider. BaseContextProvider e BaseHistoryProvider rimangono come alias deprecati ed InMemoryHistoryProvider è il provider di cronologia in memoria locale predefinito. RawAgent può aggiungere InMemoryHistoryProvider() automaticamente in casi specifici (ad esempio, quando si usa una sessione senza provider di contesto configurati e senza indicatori di storage lato server), ma questo non è garantito in tutti gli scenari. Se si vuole sempre la persistenza locale, aggiungere un elemento InMemoryHistoryProvider in modo esplicito. Assicurati anche che solo un fornitore di cronologia abbia load_messages=True, per evitare di integrare più archivi in un'unica chiamata.

È anche possibile aggiungere un archivio di controllo aggiungendo un altro provider di cronologia alla fine dell'elenco di context_providers con store_context_messages=True:

from agent_framework import InMemoryHistoryProvider
from agent_framework.mem0 import Mem0ContextProvider

memory_store = InMemoryHistoryProvider(load_messages=True) # add a history provider for persistence across sessions
agent_memory = Mem0ContextProvider("user-memory", api_key=..., agent_id="my-agent")  # add Mem0 provider for agent memory
audit_store = InMemoryHistoryProvider(
    "audit",
    load_messages=False,
    store_context_messages=True,  # include context added by other providers
)

agent = client.as_agent(
    name="MemoryAgent",
    instructions="You are a friendly assistant.",
    context_providers=[memory_store, agent_memory, audit_store],  # audit store last
)

Passaggi successivi

Approfondimento: