在C#生态里给AI应用增加长期记忆,核心是要把用户产生的文档、对话和历史记录变成可检索的知识,而不是每次请求都从头拼接上下文。Kernel Memory通过流水线把原始内容转成向量并持久化,让模型能够跨越时间窗口获取信息。

一、Kernel Memory是什么
Kernel Memory是微软推出的开源库,定位是面向AI应用的内存层。它和Semantic Kernel的定位不同,前者专注把数据灌入并随时取回,后者更偏向编排技能与规划。对C#开发者来说,Kernel Memory提供了直接可用的KernelMemoryBuilder,几行代码就能挂上文本抽取、Embedding生成和向量库。
它的运行模型分两步。第一步是写入,你提交一段文本或一个PDF,框架自动分块、调用Embedding模型、写入搜索引擎;第二步是读取,你用自然语言提问,它先做相似度检索,再把命中的片段交给大模型总结。这样模型本身不用无限拉长上下文,也能回答基于数月前资料的问题。
二、快速接入与基础配置
先在项目里安装核心包。以.NET 8为例,用命令行添加如下依赖,其中SQLite和OpenAI是常见组合,你也可以换成本地模型或Qdrant。
dotnet add package Microsoft.KernelMemory.Core dotnet add package Microsoft.KernelMemory.MemoryDb.Sqlite dotnet add package Microsoft.KernelMemory.Generators.OpenAI
接下来在代码里构造内存实例。下面示例用环境变量读取密钥,并指定用SQLite做本地持久化,适合内网或桌面程序。注意Embedding和对话模型可以分开配置,Embedding用小模型更省钱。
using Microsoft.KernelMemory;
var builder = new KernelMemoryBuilder();
builder.WithOpenAITextGenerator(new OpenAIConfig {
ApiKey = Environment.GetEnvironmentVariable("OPENAI_KEY"),
TextModel = "gpt-4o-mini"
});
builder.WithOpenAITextEmbeddingGeneration(new OpenAIConfig {
ApiKey = Environment.GetEnvironmentVariable("OPENAI_KEY"),
EmbeddingModel = "text-embedding-3-small"
});
builder.WithSqliteMemoryDb("mem.sqlite");
var memory = builder.Build();
这种写法把存储和推理解耦。如果以后要迁移到分布式,只需把WithSqliteMemoryDb换成WithQdrant或WithRedis,业务代码几乎不动。对中小团队来说,先跑通SQLite再考虑扩容是最稳的路线。
三、写入长期记忆
写入操作支持字符串、文件流和带标签的文档。下面演示把一段产品说明存进去,并打上部门标签,方便后续按权限过滤。
await memory.ImportTextAsync(
"我们的退款政策是购买后三十天内可申请,需保留订单号。",
documentId: "policy-001",
tags: new() { { "dept", "support" } }
);
await memory.ImportDocumentAsync(
"spec.pdf",
documentId: "spec-001",
tags: new() { { "type", "pdf" } }
);
Import之后框架会在后台切分文本。默认按段落和字数滚动窗口处理,避免一句话被截断。你也可以自定义ITextPartitioner来控制块大小和重叠率。对于技术手册,把块调小一点能提升命中精度;对于闲聊记录,大块反而更能保留语境。
写入是异步且幂等的,相同documentId重复导入会覆盖旧向量。这个特性让定时同步文件夹变得简单:每分钟扫描一次共享盘,有改动就重新Import,内存自然随文件更新。
四、语义检索与问答
存完之后,用AskAsync直接问业务问题。Kernel Memory会检索相关块,拼成带引用的答案。
var answer = await memory.AskAsync("退款需要几天到账?");
Console.WriteLine(answer.Result);
foreach (var src in answer.Sources) {
Console.WriteLine($"来源: {src.SourceName}");
}
返回对象里Result是大模型生成的答复,Sources列出命中片段的文件名和偏移。对合规系统来说,这个出处比答案本身更重要,审计时能直接跳到原文。如果只想要纯检索不要生成,可以调SearchAsync,拿回相似度分数最高的前N条。
对比纯对话历史方案,引入长期记忆后,用户在第二个月问第一周的订单规则,机器人依然能答对。而传统方式要么上下文爆掉,要么靠人工把旧记录再贴回去。性能上,SQLite本地检索万级文档延迟在百毫秒内,足够单实例服务使用。
五、常见误区与避坑
一个典型错误是把Kernel Memory当成缓存。它不记录会话状态,只管知识沉淀。如果你的目标是多轮对话连贯,应该配合ConversationSummary一起用,把摘要也Import进内存,而不是指望Ask能记住上一句。
另一个坑是Embedding模型和生成模型语言不匹配。用多语言Embedding才能搜中文文档,如果用了纯英文小模型,中文块会被映射成相近向量导致乱答。建议在构建期打印一次分块结果,确认切片内容符合预期再上线。
六、私有化部署示例
在内网无外网环境,可以用本地模型替换OpenAI。下面用TextGen作为本地推理,SQLite不变。
builder.WithTextGenerator(new LocalTextGenConfig {
ModelPath = "/models/gguf/qwen2-1.5b.gguf"
});
builder.WithTextEmbeddingGeneration(new LocalEmbeddingConfig {
ModelPath = "/models/gguf/bge-small-zh.gguf"
});
这样整套链路不依赖任何公网服务,适合工厂、医院等数据不出门场景。实测在16G内存的机器上,启动时间约两秒,导入百份文档占用磁盘不到两百兆。长期记忆不再是云厂商的专利,C#项目本地也能轻松拥有。
C#_Kernel_MemoryAI长期记忆语义检索修改时间:2026-08-06 10:06:35