Agent Memory for .NET: What to Store and Retrieve
Building an AI agent in .NET means choosing what to keep in conversation history, what to put in a retrieval store, and what to keep outside the application entirely. Here is how to separate the three and avoid mixing them up.
Updated 5 min read
A .NET agent application typically handles three kinds of memory: the conversation history the model uses to understand earlier turns, reference material it retrieves to answer specific questions, and the durable record of project decisions and progress that outlasts any single run. Each kind has different storage requirements, different lifetimes, and different owners.
Mixing these three in the same store creates maintenance problems and makes the system harder to debug. Tools like fenbs serve the third category specifically: a shared project record that people and connected AI tools can read and update, independent of any .NET deployment.
Conversation state
Conversation state is the message history from the current session. The agent includes it in each model call so the model can refer to earlier turns. In a .NET application, this is typically a list of message objects that you pass to the chat completion API.
Conversation state is short-lived. It matters during the session and has limited value afterward. The primary management task is keeping it within the model's context window (the maximum text the model can process at once). Common approaches include keeping the last N messages, summarizing older ones, or removing messages below a relevance threshold.
In Semantic Kernel for C#, ChatHistory is the standard class for managing conversation state. In Microsoft.Extensions.AI, the IChatClient interface accepts a list of chat messages. Both let you control which messages to include in each call.
Retrieved reference material
Retrieved reference material is content the agent fetches from an external source to answer a specific question. The source might be a document store, a vector database (which stores text as numerical embeddings for semantic search), a relational database, or an API. The agent retrieves it on demand, uses it for the current turn, and may not need it again.
In .NET, retrieval is typically implemented as a tool or plugin call. The agent calls the tool with a query, the tool retrieves relevant content from the store, and the content is included in the model's context. Azure AI Search, Qdrant, and Cosmos DB are common backends for .NET applications.
Retrieved material is a read path, not a write path. The agent reads from the store but does not write decisions or progress back to it. That write path needs a different store with different access controls.
Durable work records
Durable work records are the decisions people made, the tasks currently in progress, the standing rules, and where the last session stopped. These are not model-generated. People own them and review them. They must survive application restarts, deployment changes, and model upgrades.
The mistake to avoid is writing durable facts into the same store as conversation state or retrieved material. Conversation state gets trimmed as sessions grow long. Retrieved material gets rebuilt or re-indexed when the document changes. Neither storage pattern is appropriate for facts that must remain stable and attributable.
Testing each memory layer in isolation
Before combining all three memory types in a single agent, test each one independently. Conversation state: run a session, read the last message back from the history object, confirm the type and content match what you put in. Retrieval: call the retrieval function with a known query and confirm the result matches the expected document. Durable context: write a task to the external store, read it back, confirm the content is intact.
Testing in isolation makes diagnosis straightforward. When an agent produces an unexpected response, the question is which layer provided the wrong information. If you can rule out each layer independently, the failure path is short. If all three are tested only together, a bug in one layer hides inside the combined behavior of all three.
In .NET, unit tests for memory layers are most useful when the storage implementation is injectable. An interface over the storage backend lets tests verify behavior against a controlled, in-memory data set without requiring a running database or an external service. Integration tests then confirm the full layer works against the real backend. Run both sets as part of the same build to catch regressions in either layer before they reach production.
When fenbs does not fit
fenbs does not connect to Microsoft Teams or store documents. If your .NET application needs to query proprietary internal documents, use a retrieval store like Azure AI Search with appropriate access controls. fenbs is for the project record: tasks, decisions, and progress.
Use fenbs for shared project context in .NET applications
Add the project's active tasks and decisions to fenbs. Connect any supported AI tool over MCP from Integrations. The agent reads the project context at session start without requiring access to your .NET deployment or its internal stores.
Create a free accountFree for one person · No credit card · Works with Claude, ChatGPT, Cursor and more
How to do this with fenbs
- Create a free account and add the project your .NET agent application supports.
- Add the active tasks, decisions, and standing rules. These are the facts every session needs that are not stored in conversation history or document indexes.
- In your .NET application, add a tool or startup call that loads the fenbs project context via MCP at Integrations before the agent begins.
- At session end, write the completed work, decisions made, and next steps back to fenbs through the same MCP connection.
- Use a separate retrieval store for reference documents. Fenbs handles the project record; the retrieval store handles the content.
For the architecture behind separating these memory types, see what is agent memory and agent memory vs RAG. For the MCP connection pattern, see agent memory MCP.