Skip to content
Development
Agent

agent-memory

Learn how to use chat history and memory with Agent Framework

From plugin
dotnet-skills
46650 skills50 agents
Install
$ npx -y skills add managedcode/dotnet-skills --agent claude-code

How it fires

How this agent gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.

Context preview

The summary Claude sees to decide when to auto-load this agent.

Learn how to use chat history and memory with Agent Framework

Agent definition

agent-memory.md
title: Agent Chat History and Memory
description: Learn how to use chat history and memory with Agent Framework
zone_pivot_groups: programming-languages
author: markwallace
ms.topic: reference
ms.author: markwallace
ms.date: 09/24/2025
ms.service: agent-framework

Agent Chat History and Memory

Agent chat history and memory are crucial capabilities that allow agents to maintain context across conversations, remember user preferences, and provide personalized experiences. The Agent Framework provides multiple features to suit different use cases, from simple in-memory chat message storage to persistent databases and specialized memory services.

::: zone pivot="programming-language-csharp"

Chat History

Various chat history storage options are supported by Agent Framework. The available options vary by agent type and the underlying service(s) used to build the agent.

The two main supported scenarios are:

  • **In-memory storage**: Agent is built on a service that doesn't support in-service storage of chat history (for example, OpenAI Chat Completion). By default, Agent Framework stores the full chat history in-memory in the `AgentThread` object, but developers can provide a custom `ChatMessageStore` implementation to store chat history in a third-party store if required.
  • **In-service storage**: Agent is built on a service that requires in-service storage of chat history (for example, Azure AI Foundry Persistent Agents). Agent Framework stores the ID of the remote chat history in the `AgentThread` object, and no other chat history storage options are supported.

In-memory chat history storage

When using a service that doesn't support in-service storage of chat history, Agent Framework defaults to storing chat history in-memory in the `AgentThread` object. In this case, the full chat history that's stored in the thread object, plus any new messages, will be provided to the underlying service on each agent run. This design allows for a natural conversational experience with the agent. The caller only provides the new user message, and the agent only returns new answers. But the agent has access to the full conversation history and will use it when generating its response.

When using OpenAI Chat Completion as the underlying service for agents, the following code results in the thread object containing the chat history from the agent run.

AIAgent agent = new OpenAIClient("<your_api_key>")
     .GetChatClient(modelName)
     .AsAIAgent(JokerInstructions, JokerName);
AgentThread thread = await agent.GetNewThreadAsync();
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate.", thread));

Where messages are stored in memory, it's possible to retrieve the list of messages from the thread and manipulate the messages directly if required.

IList<ChatMessage>? messages = thread.GetService<IList<ChatMessage>>();

> [!NOTE] > Retrieving messages from the `AgentThread` object in this way only works if in-memory storage is being used.

Chat history reduction with in-memory storage

The built-in `InMemoryChatMessageStore` that's used by default when the underlying service does not support in-service storage, can be configured with a reducer to manage the size of the chat history. This is useful to avoid exceeding the context size limits of the underlying service.

The `InMemoryChatMessageStore` can take an optional `Microsoft.Extensions.AI.IChatReducer` implementation to reduce the size of the chat history. It also allows you to configure the event during which the reducer is invoked, either after a message is added to the chat history or before the chat history is returned for the next invocation.

To configure the `InMemoryChatMessageStore` with a reducer, you can provide a factory to construct a new `InMemoryChatMessageStore` for each new `AgentThread` and pass it a reducer of your choice. The `InMemoryChatMessageStore` can also be passed an optional trigger event which can be set to either `InMemoryChatMessageStore.ChatReducerTriggerEvent.AfterMessageAdded` or `InMemoryChatMessageStore.ChatReducerTriggerEvent.BeforeMessagesRetrieval`.

The factory is an async function that receives a context object and a cancellation token.

AIAgent agent = new OpenAIClient("<your_api_key>")
    .GetChatClient(modelName)
    .AsAIAgent(new ChatClientAgentOptions
    {
        Name = JokerName,
        ChatOptions = new() { Instructions = JokerInstructions },
        ChatMessageStoreFactory = (ctx, ct) => new ValueTask<ChatMessageStore>(
            new InMemoryChatMessageStore(
                new MessageCountingChatReducer(2),
                ctx.SerializedState,
                ctx.JsonSerializerOptions,
                InMemoryChatMessageStore.ChatReducerTriggerEvent.AfterMessageAdded))
    });

> [!NOTE] > This feature is only supported when using the `InMemoryChatMessageStore`. When a service has in-service chat history storage, it is up to the service itself to manage the size of the chat history. Similarly, when using 3rd party storage (see below), it is up to the 3rd party storage solution to manage the chat history size. If you provide a `ChatMessageStoreFactory` for a message store but you use a service with built-in chat history storage, the factory will not be used.

Inference service chat history storage

When using a service that requires in-service storage of chat history, Agent Framework stores the ID of the remote chat history in the `AgentThread` object.

For example, when using OpenAI Responses with store=true as the underlying service for agents, the following code will result in the thread object containing the last response ID returned by the service.

AIAgent agent = new OpenAIClient("<your_api_key>")
     .GetOpenAIResponseClient(modelName)
     .AsAIAgent(JokerInstructions, JokerName);
AgentThread thread = await agent.GetNewThreadAsync();
Console.WriteLine(await agent.RunAsync("Tell me a joke abo
Read more
Ships withdotnet-skills

Stop explaining .NET to your AI. Start building. We've all been there: asking Claude to use Entity Framework, only to get EF6 patterns in a .NET 8 project. Explaining to Copilot that Blazor Server and Blazor WebAssembly aren't the same thing.

Get the whole plugin