使用 .NET 9、Semantic Kernel 和 Ollama 实现本地 RAG 架构
- 作者

- 姓名
- Nino
- 职业
- Senior Tech Editor
在当今的软件开发领域,生成式人工智能(Generative AI)已成为不可忽视的核心力量。开发者们已经习惯了使用 ChatGPT 或 GitHub Copilot 来加速编码流程,但这种便利往往伴随着代价:对外部 API 供应商的深度依赖、按 Token 计费的高昂成本,以及对企业敏感数据泄露的担忧。为了解决这些痛点,本地化部署大语言模型(LLM)成为了众多企业的首选方案。虽然 n1n.ai 提供了极其稳定且高速的云端 API 聚合服务,但在某些极端隐私场景下,配合 Ollama 运行本地模型是实现“零泄露”的最佳路径。
本教程将带你深入了解如何使用 .NET 9 结合 Semantic Kernel 和 Ollama,在你的笔记本电脑上构建一个完整的检索增强生成(RAG)系统。通过这种方式,你可以让 AI 在完全离线的状态下,基于你的本地文档库进行问答。
什么是 RAG(检索增强生成)?
RAG 是一种设计模式,旨在解决大模型“幻觉”和知识滞后的问题。简单来说,RAG 不仅仅是向模型提问,而是在提问的同时,从你的私有数据源中提取相关的上下文(Context),并将这些信息一并交给模型。模型在回答时会优先参考这些“参考资料”,从而生成更准确、更具针对性的回复。
RAG 的核心流程包括:
- 文档向量化:将文本转换为多维空间的数学向量(Embedding)。
- 语义检索:根据用户的问题,在向量数据库中寻找最相似的文本片段。
- 提示词增强:将检索到的片段嵌入到 Prompt 中。
- 生成回复:模型基于增强后的 Prompt 给出答案。
如果你需要更强大的模型处理能力或更广泛的模型选择,n1n.ai 是一个理想的扩展平台,它能够无缝对接包括 DeepSeek-V3、Claude 3.5 Sonnet 和 OpenAI o3 在内的顶级模型。
技术栈准备
要运行本演示程序,你需要准备以下环境:
- .NET 9 SDK:提供最新的异步编程支持和性能优化。
- Ollama v0.9.5 或更高版本:用于在本地启动 Llama 3.2 模型。
- 硬件配置:建议至少配备 8GB 内存,如有 4GB 以上显存的 GPU 则体验更佳。
首先,通过命令行启动 Ollama 并拉取模型:
ollama serve
ollama run llama3.2
在 .NET 项目中,我们需要安装 Semantic Kernel 及其 Ollama 连接器。由于该连接器目前处于预览阶段,安装时需指定版本:
dotnet add package Microsoft.SemanticKernel
dotnet add package Microsoft.SemanticKernel.Connectors.Ollama --version 1.34.0-preview
核心实现步骤
1. 初始化 Semantic Kernel 与 Ollama 客户端
在 .NET 9 中,我们使用 OllamaApiClient 来连接本地服务。值得注意的是,Llama 3.2 既可以作为聊天模型,也可以直接作为嵌入(Embedding)模型使用,这大大简化了本地架构的复杂度。
[Experimental("SKEXP0070")]
public static async Task Main(string[] args)
{
// 初始化 Ollama 客户端,指向默认的本地端口 11434
using var ollamaClient = new OllamaApiClient(uriString: "http://localhost:11434", defaultModel: "llama3.2");
// 获取嵌入生成服务
var embeddingService = ollamaClient.AsTextEmbeddingGenerationService();
// 加载本地 Markdown 文档并进行向量化
var documentsPath = Path.Combine(AppContext.BaseDirectory, "docs");
var documentStore = await ImportDocumentsFromDirectoryAsync(documentsPath, embeddingService);
// 进入聊天循环
await ChatLoop(ollamaClient, embeddingService, documentStore);
}
2. 构建内存向量存储与余弦相似度算法
为了演示 RAG 的本质,我们手动实现一个简单的内存向量存储。其核心是“余弦相似度”(Cosine Similarity)计算,这是一种衡量两个向量在空间中夹角大小的算法。夹角越小,意味着语义越接近。
private static double CalculateCosineSimilarity(float[] vectorA, float[] vectorB)
{
double dotProduct = 0, magnitudeA = 0, magnitudeB = 0;
for (int i = 0; i < vectorA.Length; i++)
{
dotProduct += vectorA[i] * vectorB[i];
magnitudeA += vectorA[i] * vectorA[i];
magnitudeB += vectorB[i] * vectorB[i];
}
// 加上一个极小值防止除零错误
return dotProduct / (Math.Sqrt(magnitudeA) * Math.Sqrt(magnitudeB) + 1e-5);
}
3. 实现聊天循环与上下文注入
这是 RAG 最关键的部分。当用户输入问题时,程序会执行以下逻辑:
- 将问题转化为向量。
- 在内存库中查找相似度最高的两个文档片段。
- 如果最高相似度超过预设阈值(如 0.10),则将片段加入 Prompt。
private static async Task ChatLoop(OllamaApiClient client, ITextEmbeddingGenerationService embeddingService, InMemoryStore store)
{
var chatService = client.AsChatCompletionService();
var chatHistory = new ChatHistory("你是一个专业的文档分析助手,请优先根据提供的上下文回答问题。");
while (true)
{
Console.Write("User: ");
var input = Console.ReadLine();
// 1. 向量化用户问题
var queryVector = (await embeddingService.GenerateEmbeddingsAsync([input]))[0].ToArray();
// 2. 检索最相关的文档
var relevantDocs = store.GetTopMatches(queryVector, count: 2);
// 3. 构建临时 Prompt 历史
var tempHistory = new ChatHistory(chatHistory);
if (relevantDocs.Any(d => d.Score > 0.15))
{
var context = string.Join("\n", relevantDocs.Select(d => d.Text));
tempHistory.AddSystemMessage($"已知信息:\n{context}");
}
tempHistory.AddUserMessage(input);
// 4. 调用本地 Llama 3.2 生成答案
var response = await chatService.GetChatMessageContentAsync(tempHistory);
Console.WriteLine($"Assistant: {response.Content}\n");
chatHistory.AddUserMessage(input);
chatHistory.Add(response);
}
}
进阶建议:从本地原型到生产环境
虽然在笔记本上运行 RAG 非常酷,但当你需要处理成千上万份文档时,内存存储将难以为继。此时,你应该考虑以下优化方向:
- 引入向量数据库:使用 Qdrant 或 Milvus。Qdrant 可以通过 Docker 轻松启动:
docker run -p 6333:6333 qdrant/qdrant。它提供了持久化存储、高效的 HNSW 索引和过滤功能。 - 混合模型策略:在本地进行敏感数据的初步筛选,而对于复杂的逻辑推理,可以通过 n1n.ai 调用 OpenAI o1 或 Claude 3.5。这种“混合云”架构在性能和隐私之间达到了完美的平衡。
- 精细化分块(Chunking):不要一次性读取整个文件。建议将文档切分为 300-500 个字符的块,并保留一定的重叠(Overlap),以确保语义不被截断。
总结
通过 .NET 9、Semantic Kernel 和 Ollama 的组合,开发者可以在几分钟内搭建出一个功能完备的本地 RAG 系统。这不仅消除了对云端供应商的盲目依赖,还为处理敏感企业数据提供了安全屏障。随着本地硬件算力的提升,这种架构将成为未来企业级 AI 应用的主流趋势。
当然,当你需要更强大的 API 扩展能力或需要对比不同模型的输出质量时,n1n.ai 始终是你最可靠的合作伙伴,为你提供一站式的 LLM 访问体验。
在 n1n.ai 获取免费 API 密钥。