diff --git a/agent-framework/integrations/index.md b/agent-framework/integrations/index.md index 657becd3..ebef640f 100644 --- a/agent-framework/integrations/index.md +++ b/agent-framework/integrations/index.md @@ -62,6 +62,7 @@ Here is a list of existing providers that can be used. | Memory AI Context Provider | Release Status | | ------------------------------------------------------------------ | --------------- | | [Chat History Memory Provider](./chat-history-memory-provider.md) | Released | +| [Neo4j Memory Provider](./neo4j-memory.md) | Preview | ::: zone-end diff --git a/agent-framework/integrations/neo4j-memory.md b/agent-framework/integrations/neo4j-memory.md index f7e8947f..a0c0b05f 100644 --- a/agent-framework/integrations/neo4j-memory.md +++ b/agent-framework/integrations/neo4j-memory.md @@ -5,7 +5,7 @@ zone_pivot_groups: programming-languages author: retroryan ms.topic: article ms.author: westey -ms.date: 04/01/2026 +ms.date: 07/16/2026 ms.service: agent-framework --- @@ -30,7 +30,111 @@ The provider manages three types of memory: ::: zone pivot="programming-language-csharp" -This provider is not yet available for C#. See the Python tab for usage examples. +> [!NOTE] +> The .NET package (`AgentMemory`) is an independent, community-maintained .NET port of the Neo4j Labs memory provider — it is not an official Neo4j Labs package. See the [AgentMemory (.NET) repository](https://github.com/joslat/agent-memory-dotnet) for source and details. + +## Prerequisites + +- A Neo4j instance (self-hosted or [Neo4j AuraDB](https://neo4j.com/cloud/aura/)) +- An Azure OpenAI or Microsoft Foundry deployment (a chat model + an embedding model) +- Environment variables set: `NEO4J_URI`, `NEO4J_USERNAME`, `NEO4J_PASSWORD`, `AZURE_OPENAI_ENDPOINT` +- Azure CLI credentials configured (`az login`), or an API key +- .NET 8.0 or later + +## Installation + +```bash +dotnet add package AgentMemory +dotnet add package AgentMemory.AgentFramework +``` + +## Usage + +```csharp +using Azure.AI.OpenAI; +using Azure.Identity; +using Microsoft.Agents.AI; +using Microsoft.Extensions.AI; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using AgentMemory; +using AgentMemory.Abstractions.Services; +using AgentMemory.AgentFramework; +using AgentMemory.AgentFramework.Tools; + +var builder = Host.CreateApplicationBuilder(args); + +// Registers Core + Neo4j infrastructure in one call (reads NEO4J_URI / NEO4J_USERNAME / +// NEO4J_PASSWORD, falling back to local-dev defaults). Passing configureLlm opts in to +// LLM-backed entity/fact/preference extraction, using the IChatClient registered below. +builder.Services.AddNeo4jAgentMemory( + configureMemory: _ => { }, + configureNeo4j: neo4j => + { + neo4j.Uri = Environment.GetEnvironmentVariable("NEO4J_URI") ?? "bolt://localhost:7687"; + neo4j.Username = Environment.GetEnvironmentVariable("NEO4J_USERNAME") ?? "neo4j"; + neo4j.Password = Environment.GetEnvironmentVariable("NEO4J_PASSWORD") ?? "password"; + }, + configureLlm: _ => { }); + +// Any Microsoft.Extensions.AI-compatible chat + embedding client works +var azureClient = new AzureOpenAIClient( + new Uri(Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!), new DefaultAzureCredential()); +builder.Services.AddSingleton(azureClient.GetChatClient("gpt-4o-mini").AsIChatClient()); +builder.Services.AddSingleton(azureClient.GetEmbeddingClient("text-embedding-3-small").AsIEmbeddingGenerator()); + +// AutoExtractOnPersist builds the knowledge graph from every conversation turn +builder.Services.AddAgentMemoryFramework(options => +{ + options.AutoExtractOnPersist = true; + options.ContextFormat.IncludeEntities = true; + options.ContextFormat.IncludeFacts = true; + options.ContextFormat.IncludePreferences = true; +}); + +using var host = builder.Build(); +await using var scope = host.Services.CreateAsyncScope(); +var services = scope.ServiceProvider; + +// Bootstraps Neo4j schema/indexes on first run (idempotent) +await services.GetRequiredService().BootstrapAsync(); + +var memoryProvider = services.GetRequiredService(); +var memoryTools = services.GetRequiredService().CreateAIFunctions(); + +// WithMemoryOwnerScoping wraps the whole invocation — recall, the tool-calling loop, and +// persistence — in the owner scope set by WithMemoryIdentity below, so no manual +// BeginOwnerScope call is needed around RunAsync. +AIAgent agent = services.GetRequiredService().AsAIAgent(new ChatClientAgentOptions +{ + ChatOptions = new ChatOptions + { + Instructions = "You are a helpful assistant with persistent memory.", + Tools = [.. memoryTools], + }, + AIContextProviders = [memoryProvider], +}).WithMemoryOwnerScoping(services); + +var session = (await agent.CreateSessionAsync()) + .WithMemoryIdentity(userId: "user-123", sessionId: "session-1", applicationId: "my-app"); + +var response = await agent.RunAsync("Remember that I prefer window seats on flights.", session); +``` + +## Key features + +- **Bidirectional**: `Neo4jMemoryContextProvider` recalls relevant memory before each run and persists new memory after — no manual wiring needed +- **Entity extraction**: builds a knowledge graph from conversations with a configurable extraction pipeline (`AutoExtractOnPersist`) +- **Preference learning**: infers and stores user preferences, facts, and entities, recalled automatically by a brand-new `AgentSession` for the same user +- **Memory tools**: `MemoryToolFactory` exposes `AIFunction`s so the model can explicitly search, remember, and recall +- **Dependency-injection first**: registers via `AddNeo4jAgentMemory` (wires up Core + Neo4j internally) and `AddAgentMemoryFramework`, fitting naturally into Generic Host and ASP.NET Core apps +- **Beyond Agent Framework**: the same library also integrates with Semantic Kernel and MCP clients, and includes built-in OpenTelemetry observability + +## Resources + +- [AgentMemory (.NET) repository](https://github.com/joslat/agent-memory-dotnet) +- [NuGet package page](https://www.nuget.org/packages/AgentMemory) +- [Sample: Retail Assistant with AgentMemory](https://github.com/microsoft/agent-framework/tree/main/dotnet/samples/02-agents/AgentWithMemory/AgentWithMemory_Step06_MemoryUsingAgentMemory) ::: zone-end