Semantic Kernel 架构决策实录:为何 Entity Framework 不被采纳为 Vector Store 连接器(ADR 0051 深度解析)
Semantic Kernel 架构决策实录为何 Entity Framework 不被采纳为 Vector Store 连接器ADR 0051 深度解析【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel本篇文章基于 Semantic Kernel 仓库中的架构决策记录ADR0051-entity-framework-as-connector.md 展开完整还原一次关键的技术调研过程Entity Framework 能否作为统一的 Vector Store向量存储连接器接入 Semantic Kernel。你将看到新版向量存储设计对连接器的六项硬性要求、EF 在集合创建、键管理、向量映射、测试、.NET 兼容性上的真实局限以及最终不引入 EF 连接器、按数据库逐个添加连接器这一决策背后的完整推理链条同时结合仓库源码验证这一决策在后续版本中的落地形态。决策背景EF 的诱惑与新版 Vector Store 设计为什么 Entity Framework 曾被认真考虑Entity Framework 是 .NETC#生态中成熟的现代对象关系映射ORM框架它允许开发者用统一的高层数据访问层跨多种数据库构建整洁、可移植的数据层包括 SQL Database本地与 Azure、SQLite、MySQL、PostgreSQL、Azure Cosmos DB 等并原生支持 LINQ 查询、变更跟踪change tracking、更新与 Schema 迁移migrations。对 Semantic Kernel 而言EF 最诱人的价值在于多数据库支持理论上一个Entity Framework 连接器就能同时充当通往多种数据库的枢纽从而简化这些数据库集成的开发与维护成本。这正是 ADR 中Context and Problem Statement部分的核心问题是否值得投入建设Microsoft.SemanticKernel.Connectors.EntityFramework新设计对连接器的要求对应 ADR 0050在评估时Semantic Kernel 正处于向量存储抽象从实验性IMemoryStore走向正式化设计的阶段参见姊妹 ADR 0050-updated-vector-store-design.md。新版设计中集合管理与记录管理被拆分核心接口为IVectorStoreRecordCollectionTKey, TRecord其中与数据库集合collection/schema/table打交道的四个方法是CollectionExistsAsync判断集合是否存在CreateCollectionAsync创建集合CreateCollectionIfNotExistsAsync不存在则创建DeleteCollectionAsync删除集合这组方法要求连接器能够以编程方式、以统一语义管理集合的生命周期。而正是这一要求与 Entity Framework 的现实能力产生了第一处冲突。六大技术障碍逐项剖析障碍一集合创建Collection Creation没有跨数据库的统一抽象在 Entity Framework 中通过编程方式创建集合即 Schema/Table在生成环境是不被推荐的做法。官方推荐的两条路径是Code-First使用 Migrations迁移管理 SchemaDatabase-First使用反向工程Reverse Engineering又称 scaffolding从现有数据库生成模型。编程式 Schema 创建仅被推荐用于测试/本地场景参见EnsureCreated相关文档。更麻烦的是不同数据库的创建流程差异巨大。典型反例是MongoDB EF Core Provider它既不支持 Schema 迁移也不支持 database-first / model-first 模式集合会在首次插入文档时自动创建如果集合尚不存在。这意味着IVectorStoreRecordCollectionTKey, TRecord中的CreateCollectionAsync一族方法在 EF 中找不到一套能覆盖大多数数据库的集合管理抽象。对这类场景官方建议要么依赖自动创建机制要么为每种数据库单独处理集合创建——例如 MongoDB 建议直接使用 MongoDB C# Driver。结论集合管理操作的跨数据库不一致是 EF 无法契合新 Vector Store 设计的第一个硬伤。障碍二键管理Key Management无法统一由于并非所有数据库都支持相同的键类型EF 连接器不可能定义一套对所有数据库都有效的键类型集合。务实的选择是只支持标准类型如string再针对特定数据库做类型转换以符合其键约束。但这恰恰抹掉了统一连接器的优势键管理仍然要为每种数据库单独实现等于把差异化工作从数据库连接器层搬回了EF 连接器层却没有换来任何抽象收益。障碍三向量类型ReadOnlyMemoryT不受原生支持这是最直接的技术阻断点。Semantic Kernel 绝大多数连接器使用ReadOnlyMemoryfloat承载 Embedding 向量而Entity Framework 开箱即用地不支持该类型。尝试映射时会产生如下运行时错误The property {Property Name} could not be mapped because it is of type ReadOnlyMemoryfloat?, which is not a supported primitive type or a valid entity type. Either explicitly map this property, or ignore it using the [NotMapped] attribute or by using EntityTypeBuilder.Ignore in OnModelCreating.规避手段存在但不完美可以改用byte[]类型或编写显式类型映射来支持ReadOnlyMemoryT。例如pgvector包已经这样做了通过自定义VectorTypeMapping完成映射但这种映射是否能在不同数据库上通用并不明确——它很可能是数据库特定的。障碍四测试成本被严重低估用 SQLite 编写 EF 连接器的单元/集成测试不能证明该集成在其他 EF 支持的数据库上可用。每个数据库都实现了一组属于自己的 EF 功能子集feature set因此为了保证连接器覆盖主流使用场景必须针对每种数据库分别编写单元/集成测试。这意味着一个连接器、一套测试的规模效应并不成立测试矩阵会成倍扩张。障碍五.NET 兼容性冲突EF 的版本策略与 Semantic Kernel 的兼容性目标正面冲突无法使用最新版 Entity Framework Core 并同时面向 .NET Standard 开发最后一个支持 .NET Standard 的 EF Core 版本是 5.0评估时最新为 8.0。因此 EF 连接器只能面向 .NET 8.0而当时其他 SK 连接器同时面向net8.0与netstandard2.0两个目标框架。另一个选项是使用Entity Framework 6它可以同时面向net8.0与netstandard2.0但 EF6已不再被积极开发EF Core 提供的新特性不会再回填到 EF6 中。两头不讨好选 EF Core 牺牲兼容面选 EF6 牺牲演进性。障碍六与既有 SK 数据库连接器的重叠Semantic Kernel 已有多条数据库集成且这些数据库同样被 EF 支持于是产生三选一的局面| 方案 | 说明 | 代价 | | - | - | - | | EF 连接器 数据库连接器并存 | 同时维护Microsoft.SemanticKernel.Connectors.EntityFramework与Microsoft.SemanticKernel.Connectors.MongoDB等 | 两者必须产出完全一致的结果需要补齐同一套单元/集成测试任何逻辑修改都要同步到两个连接器 | | 只保留 EF 连接器 | 移除既有数据库连接器 | 对存量客户是破坏性变更且需额外工作确保 EF 覆盖与旧连接器完全相同的功能面 | | 只保留数据库连接器 | 已有则无需额外工作没有但重要则新增 | 若连接器尚不存在需要单独实现 |EF 与 SK 的数据库支持对照矩阵核心表格以下表格来自 ADR 原文仅列出支持向量搜索的数据库注意同一数据库引擎可能存在多个由不同厂商维护的 EF 集成例如 MySQL 就有 Oracle 维护版与 Pomelo Foundation Project 维护版两个 EF NuGet 包| Database Engine | Maintainer / Vendor | Supported in EF | Supported in SK | Updated to SK memory v2 design | | - | - | - | - | - | | Azure Cosmos | Microsoft | Yes | Yes | Yes | | Azure SQL and SQL Server | Microsoft | Yes | Yes | No | | SQLite | Microsoft | Yes | Yes | No | | PostgreSQL | Npgsql Development Team | Yes | Yes | No | | MongoDB | MongoDB | Yes | Yes | No | | MySQL | Oracle | Yes | No | No | | Oracle DB | Oracle | Yes | No | No | | Google Cloud Spanner | Cloud Spanner Ecosystem | Yes | No | No |此外Semantic Kernel 额外支持的向量数据库连接器还包括Azure AI Search、Chroma、Milvus、Pinecone、Qdrant、Redis、Weaviate。这张表格揭示了一个关键事实EF 支持的向量数据库SK 几乎都已有或即将有原生连接器EF 覆盖面中 SK 缺失的部分MySQL、Oracle DB、Google Cloud Spanner恰好是 SK 当前不提供向量连接器的数据库。决策选项与最终结论ADR 给出了两个候选方案新增Microsoft.SemanticKernel.Connectors.EntityFramework连接器不新增 EF 连接器而是在需要时为单个数据库逐个新增连接器。最终决策是方案 2。决策理由可归纳为四点EF Provider 对集合管理操作的支持不统一需要编写数据库特定代码来处理键与对象映射这些因素会使得 EF 连接器不可靠且无法真正抽象底层数据库没有抽象只有转发EF 支持、而 SK 尚无向量存储连接器的数据库数量极少投入产出比极低逐一新增数据库连接器反而能精确贴合各数据库的特性。决策的后续验证仓库中的实际走向该决策2024-08 提出在后续版本演进中得到了清晰的印证可在当前仓库中直接查验1. 独立的数据库连接器按需落地而非 EF 统一连接器。在 dotnet/src/VectorData 目录下可以看到按数据库组织的独立目录Chroma、Milvus、Pinecone、Qdrant、Redis、Weaviate、AzureAISearch、MongoDB、SqlServer、PgVector、SqliteVec、CosmosNoSql、CosmosMongoDB、InMemory 等。其中 MongoDB 与 SqlServer 等连接器的 README 明确说明其代码已迁移至各自的维护方仓库如 MongoDB 官方维护的mongodb/mongo-mevd-provider、CommunityToolkit 的 AI 仓库印证了每个数据库由各自生态维护独立连接器的演化方向。同时dotnet/Directory.Packages.props 中可以看到Npgsql、CommunityToolkit.VectorData.PgVector、Testcontainers.MongoDB等按数据库引用的依赖而非统一的 EF Core 依赖。2. EF 并未被 Semantic Kernel 抛弃而是回归它擅长的定位。仓库中存在 dotnet/src/Plugins/Plugins.StructuredData.EntityFramework它并非向量存储连接器而是基于Entity Framework 6.5的结构化数据访问插件Microsoft.SemanticKernel.Plugins.StructuredData.EntityFramework目标框架为net10.0;net8.0;net462。其项目文件中的注释EntityFramework 6.5 is not compatible with .Net Standard 2.0恰好印证了 ADR 中关于 EF 与 .NET Standard 兼容性的分析对应的架构决策见 0068-structured-data-connector.md。也就是说EF 被用于让 AI 通过插件访问关系型结构化数据而不是作为向量存储的统一抽象——这与 ADR 0051 的结论完全一致。3. 集合管理的工程现实在代码中可见。ADR 0050 的最终设计Option 6采用了IVectorStore作为工厂返回IVectorStoreCollectionTKey, TRecord的形态集合创建与记录管理分离。向量数据连接器多数已外迁的事实也从侧面说明集合创建这类数据库强相关能力天然应该由各数据库连接器自行实现而不是由一个试图统一一切的 ORM 层承担。启示给连接器设计者的三条经验回顾整份 ADR可以提炼出对任何统一连接器方案都适用的判断准则抽象的价值取决于差异是否被真正吸收。EF 表面上统一了多数据库访问但集合管理、键类型、向量类型映射这些核心差异并没有被吸收只是被转移到了 EF 连接器内部抽象因此名存实亡。统一测试一套、到处运行是伪命题。每个数据库实现的是 EF 功能子集的不同切片SQLite 上的绿色测试无法背书 MongoDB 上的行为测试矩阵随数据库数量线性甚至超线性扩张。兼容性策略本身就是技术债的源头。当候选技术无法同时满足目标框架矩阵.NET Standard 2.0与长期演进EF Core 而非 EF6时采纳它意味着要么收缩支持面要么绑定到停止演进的分支——两者都不可接受。对 Semantic Kernel 而言这个决策最终换来了更可靠、更贴合各数据库特性的连接器体系需要向量检索时按数据库选用对应的专用连接器需要结构化数据操作时EF 作为插件出现在它最擅长的关系型数据场景中。进一步阅读完整的调研论证见 docs/decisions/0051-entity-framework-as-connector.md向量存储设计背景见 docs/decisions/0050-updated-vector-store-design.mdEF 结构化数据插件的后续落地见 docs/decisions/0068-structured-data-connector.md 与 dotnet/src/Plugins/Plugins.StructuredData.EntityFramework向量数据连接器清单见 dotnet/src/VectorData。【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考