如何用Microsoft.Extensions.AI库构建问答系统?
摘要:本文介绍了如何基于Microsoft.Extensions.AI + Microsoft.Extensions.VectorData 一步一步地实现一个RAG(检索增强生成)应用,相信会对你有所帮助。如果你也是.NET程序
大家好,我是Edison。
之前我们了解Microsoft.Extensions.AI和Microsoft.Extensions.VectorData两个重要的AI应用核心库。基于对他们的了解,今天我们就可以来实战一个RAG问答应用,把之前所学的串起来。
前提知识点:向量存储、词嵌入、向量搜索、提示词工程、函数调用。
案例需求背景
假设我们在一家名叫“易速鲜花”的电商网站工作,顾名思义,这是一家从事鲜花电商的网站。我们有一些运营手册、员工手册之类的文档(例如下图所示的一些pdf文件),想要将其导入知识库并创建一个AI机器人,负责日常为员工解答一些政策性的问题。
例如,员工想要了解奖励标准、行为准备、报销流程等等,都可以通过和这个AI机器人对话就可以快速了解最新的政策和流程。
在接下来的Demo中,我们会使用以下工具:
(1) LLM 采用 Qwen2.5-7B-Instruct,可以使用SiliconFlow平台提供的API,你也可以改为你喜欢的其他模型如DeepSeek,但是建议不要用大炮打蚊子哈。
注册地址:点此注册
(2) Qdrant 作为 向量数据库,可以使用Docker在你本地运行一个:
docker run -p 6333:6333 -p 6334:6334 \
-v $(pwd)/qdrant_storage:/qdrant/storage \
qdrant/qdrant
(3) Ollama 运行 bge-m3 模型 作为 Emedding生成器,可以自行拉取一个在你本地运行:
ollama pull bge-m3
构建你的RAG应用
创建一个控制台应用程序,添加一些必要的文件目录 和 配置文件(json),最终的解决方案如下图所示。
在Documents目录下放了我们要导入的一些pdf文档,例如公司运营手册、员工手册等等。
在Models目录下放了一些公用的model类,其中TextSnippet类作为向量存储的实体类,而TextSearchResult类则作为向量搜索结果的模型类。
(1)TextSnippet
这里我们的TextEmbedding字段就是我们的向量值,它有1024维。
注意:这里的维度是我们自己定义的,你也可以改为你想要的维度数量,但是你的词嵌入模型需要支持你想要的维度数量。
public sealed class TextSnippet<TKey>
{
[VectorStoreRecordKey]
public required TKey Key { get; set; }
[VectorStoreRecordData]
public string? Text { get; set; }
[VectorStoreRecordData]
public string? ReferenceDescription { get; set; }
[VectorStoreRecordData]
public string? ReferenceLink { get; set; }
[VectorStoreRecordVector(Dimensions: 1024)]
public ReadOnlyMemory<float> TextEmbedding { get; set; }
}
(2)TextSearchResult
这个类主要用来返回给LLM做推理用的,我这里只需要三个字段:Value, Link 和 Score 即可。
public class TextSearchResult
{
public string Value { get; set; }
public string? Link { get; set; }
public double? Score { get; set; }
}
(3)RawContent
这个类主要用来在PDF导入时作为一个临时存储源数据文档内容。
public sealed class RawContent
{
public string? Text { get; init; }
public int PageNumber { get; init; }
}
在Plugins目录下放了一些公用的帮助类,如PdfDataLoader可以实现PDF文件的读取和导入向量数据库,VectorDataSearcher可以实现根据用户的query搜索向量数据库获取TopN个近似文档,而UniqueKeyGenerator则用来生成唯一的ID Key。
