)
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?!久赓M下載鏈接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps項目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel創作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考