Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Áttekintés
Ez az útmutató a Szemantic Kernel 1.34-es verziójában bevezetett főbb vektortár-frissítéseket ismerteti, amelyek a vektortár implementációjának jelentős átdolgozását jelentik a .NET SDK-val való összhangban, és egységesebb, intuitívabb API-t biztosítanak. A módosítások mindent semantic_kernel.data.vector alá vonnak össze, és javítják az összekötő architektúráját.
Főbb fejlesztések összefoglalása
-
Egyesített mezőmodell: Az egy
VectorStoreFieldosztály több mezőtípust cserél le - Integrált beágyazások: Közvetlen beágyazás generálása vektormező-specifikációkban
- Egyszerűsített keresés: A keresési függvények egyszerű létrehozása közvetlenül a gyűjteményeken
-
Konszolidált struktúra: Minden a
semantic_kernel.data.vectoréssemantic_kernel.connectorsalatt - Továbbfejlesztett szövegkeresés: Továbbfejlesztett szövegkeresési képességek egyszerűsített összekötőkkel
-
Elavulás: A régiek
memory_storeselavultak az új vektortároló-architektúra javára
1. Integrált beágyazások és vektortároló-modellek/mezők frissítései
A vektortároló-modell definiálásának számos módosítása van, a legnagyobb az, hogy mostantól támogatjuk az integrált beágyazásokat közvetlenül a vektortároló meződefinícióiban. Ez azt jelenti, hogy ha egy vektornak szánt mezőt ad meg, a mező tartalma automatikusan beágyazódik a megadott beágyazási generátorral, például az OpenAI szövegbeágyazási modelljével. Ez leegyszerűsíti a vektormezők létrehozásának és kezelésének folyamatát.
A mező definiálásakor három dologról kell gondoskodnia, különösen pydantikus modell használatakor:
-
gépelés: A mező valószínűleg három típussal fog rendelkezni:
list[float],strvagy valami más a beágyazási generátor bemenetéhez, ésNoneamikor a mező nincs beállítva. -
alapértelmezett érték: A mezőnek rendelkeznie kell egy alapértelmezett értékkel, például
Nonevagy valami mással, hogy ne legyen hiba agetvagysearchrekordok lekérésekorinclude_vectors=Falsemostani alapértelmezettként.
Itt két probléma merül fel: az első az, hogy amikor egy osztályt dekorálunk vectorstoremodel-val, akkor a mező első típus annotációját használjuk a VectorStoreField osztály type paraméterének kitöltésére. Ezért fontos megbizonyosodni arról, hogy az első típus annotáció helyes típusú legyen a létrehozásra kerülő vektortároló gyűjteményhez, amely gyakran list[float]. Alapértelmezés szerint a get és search metódusok alaphelyzetben nem tartalmazzák az include_vectors elemet az eredményekben, így a mező alapértelmezett értékre szorul, és a típusmegadásnak ennek kell megfelelnie. Ennélfogva gyakran megengedett a None, és az alapértelmezett érték a None. A mező létrehozásakor a beágyazandó értékek ebbe a mezőbe kerülnek, gyakran sztringek, így ezeket str is bele kell foglalni. Ennek a változásnak az az oka, hogy nagyobb rugalmasságot biztosít a beágyazott és az adatmezőkben ténylegesen tárolt adatok esetében, ez egy gyakori beállítás lenne:
from semantic_kernel.data.vector import VectorStoreField, vectorstoremodel
from typing import Annotated
from dataclasses import dataclass
@vectorstoremodel
@dataclass
class MyRecord:
content: Annotated[str, VectorStoreField('data', is_indexed=True, is_full_text_indexed=True)]
title: Annotated[str, VectorStoreField('data', is_indexed=True, is_full_text_indexed=True)]
id: Annotated[str, VectorStoreField('key')]
vector: Annotated[list[float] | str | None, VectorStoreField(
'vector',
dimensions=1536,
distance_function="cosine",
embedding_generator=OpenAITextEmbedding(ai_model_id="text-embedding-3-small"),
)] = None
def __post_init__(self):
if self.vector is None:
self.vector = f"Title: {self.title}, Content: {self.content}"
Figyelje meg a post_init metódust, amely egy beágyazott értéket hoz létre, amely több, mint egyetlen mező. A három típus is jelen van.
Előtte: Külön mezőosztályok
from semantic_kernel.data import (
VectorStoreRecordKeyField,
VectorStoreRecordDataField,
VectorStoreRecordVectorField
)
# Old approach with separate field classes
fields = [
VectorStoreRecordKeyField(name="id"),
VectorStoreRecordDataField(name="text", is_filterable=True, is_full_text_searchable=True),
VectorStoreRecordVectorField(name="vector", dimensions=1536, distance_function="cosine")
]
Utána: Egyesített VectorStoreField integrált beágyazásokkal.
from semantic_kernel.data.vector import VectorStoreField
from semantic_kernel.connectors.ai.open_ai import OpenAITextEmbedding
# New unified approach with integrated embeddings
embedding_service = OpenAITextEmbedding(
ai_model_id="text-embedding-3-small"
)
fields = [
VectorStoreField(
"key",
name="id",
),
VectorStoreField(
"data",
name="text",
is_indexed=True, # Previously is_filterable
is_full_text_indexed=True # Previously is_full_text_searchable
),
VectorStoreField(
"vector",
name="vector",
dimensions=1536,
distance_function="cosine",
embedding_generator=embedding_service # Integrated embedding generation
)
]
Kulcsmódosítások a meződefinícióban
-
Egymezős osztály:
VectorStoreFieldaz összes korábbi mezőtípust lecseréli -
Mezőtípus specifikációja: Paraméter használata
field_type: Literal["key", "data", "vector"], ez lehet pozícióparaméter, ezértVectorStoreField("key")érvényes. -
Továbbfejlesztett tulajdonságok:
-
storage_namebeállításkor a vektortároló mezőneveként lett hozzáadva, ellenkező esetben anameparaméter lesz használva. -
dimensionsa vektormezők kötelező paramétere. -
distance_functionésindex_kindmindkettő választható, és ha nincs megadva, akkorDistanceFunction.DEFAULTilletveIndexKind.DEFAULTértékre lesznek beállítva, és csak vektormezők esetén minden vektortároló implementációja rendelkezik logikával, amely alapértelmezett értéket választ az adott tárolóhoz.
-
-
Tulajdonság átnevezése:
-
property_typetype_→ attribútumként éstypekonstruktorokban -
is_filterable→is_indexed -
is_full_text_searchable→is_full_text_indexed
-
-
Integrált beágyazások: Közvetlenül a vektormezőkhöz adható hozzá
embedding_generator, vagy beállíthatja magát aembedding_generatorvektortároló-gyűjteményt, amelyet az adott tároló összes vektormezője használ. Ez az érték elsőbbséget élvez a gyűjteményszintű beágyazási generátorral szemben.
2. Új módszerek üzletekben és gyűjteményekben
Továbbfejlesztett áruházi felület
from semantic_kernel.connectors.in_memory import InMemoryStore
# Before: Limited collection methods
collection = InMemoryStore.get_collection("my_collection", record_type=MyRecord)
# After: Slimmer collection interface with new methods
collection = InMemoryStore.get_collection(MyRecord)
# if the record type has the `vectorstoremodel` decorator it can contain both the collection_name and the definition for the collection.
# New methods for collection management
await store.collection_exists("my_collection")
await store.ensure_collection_deleted("my_collection")
# both of these methods, create a simple model to streamline doing collection management tasks.
# they both call the underlying `VectorStoreCollection` methods, see below.
Továbbfejlesztett gyűjteményi felület
from semantic_kernel.connectors.in_memory import InMemoryCollection
collection = InMemoryCollection(
record_type=MyRecord,
embedding_generator=OpenAITextEmbedding(ai_model_id="text-embedding-3-small") # Optional, if there is no embedding generator set on the record type
)
# If both the collection and the record type have an embedding generator set, the record type's embedding generator will be used for the collection. If neither is set, it is assumed the vector store itself can create embeddings, or that vectors are included in the records already, if that is not the case, it will likely raise.
# Enhanced collection operations
await collection.collection_exists()
await collection.ensure_collection_exists()
await collection.ensure_collection_deleted()
# CRUD methods
# Removed batch operations, all CRUD operations can now take both a single record or a list of records
records = [
MyRecord(id="1", text="First record"),
MyRecord(id="2", text="Second record")
]
ids = ["1", "2"]
# this method adds vectors automatically
await collection.upsert(records)
# You can do get with one or more ids, and it will return a list of records
await collection.get(ids) # Returns a list of records
# you can also do a get without ids, with top, skip and order_by parameters
await collection.get(top=10, skip=0, order_by='id')
# the order_by parameter can be a string or a dict, with the key being the field name and the value being True for ascending or False for descending order.
# At this time, not all vector stores support this method.
# Delete also allows for single or multiple ids
await collection.delete(ids)
query = "search term"
# New search methods, these use the built-in embedding generator to take the value and create a vector
results = await collection.search(query, top=10)
results = await collection.hybrid_search(query, top=10)
# You can also supply a vector directly
query_vector = [0.1, 0.2, 0.3] # Example vector
results = await collection.search(vector=query_vector, top=10)
results = await collection.hybrid_search(query, vector=query_vector, top=10)
3. Továbbfejlesztett keresési szűrők
Az új vektortároló implementáció a sztringalapú FilterClause-objektumokról a hatékonyabb és típusbiztosabb lambdakifejezésekre vagy hívható szűrőkre kerül.
Előtte: FilterClause-objektumok
from semantic_kernel.data.text_search import SearchFilter, EqualTo, AnyTagsEqualTo
from semantic_kernel.data.vector_search import VectorSearchFilter
# Creating filters using FilterClause objects
text_filter = SearchFilter()
text_filter.equal_to("category", "AI")
text_filter.equal_to("status", "active")
# Vector search filters
vector_filter = VectorSearchFilter()
vector_filter.equal_to("category", "AI")
vector_filter.any_tag_equal_to("tags", "important")
# Using in search
results = await collection.search(
"query text",
options=VectorSearchOptions(filter=vector_filter)
)
Utána: Lambda Kifejezés Szűrők
# When defining the collection with the generic type hints, most IDE's will be able to infer the type of the record, so you can use the record type directly in the lambda expressions.
collection = InMemoryCollection[str, MyRecord](MyRecord)
# Using lambda expressions for more powerful and type-safe filtering
# The code snippets below work on a data model with more fields then defined earlier.
# Direct lambda expressions
results = await collection.search(
"query text",
filter=lambda record: record.category == "AI" and record.status == "active"
)
# Complex filtering with multiple conditions
results = await collection.search(
"query text",
filter=lambda record: (
record.category == "AI" and
record.score > 0.8 and
"important" in record.tags
)
)
# Combining conditions with boolean operators
results = await collection.search(
"query text",
filter=lambda record: (
record.category == "AI" or record.category == "ML"
) and record.published_date >= datetime(2024, 1, 1)
)
# Range filtering (now possible with lambda expressions)
results = await collection.search(
"query text",
filter=lambda record: 0.5 <= record.confidence_score <= 0.9
)
Migrálási tippek szűrőkhöz
-
Egyszerű egyenlőség:
filter.equal_to("field", "value")váliklambda r: r.field == "value" -
Több feltétel: Több szűrőhívás helyett operátorokat tartalmazó
and/orlánc -
Címke/tömb tartalmazás:
filter.any_tag_equal_to("tags", "value")válik belőlelambda r: "value" in r.tags - Továbbfejlesztett képességek: Tartománylekérdezések, összetett logikai logika és egyéni predikátumok támogatása
4. A keresési függvények létrehozásának megkönnyítése
Előző: Keresési függvény létrehozása a VectorStoreTextSearch használatával
from semantic_kernel.connectors.in_memory import InMemoryCollection
from semantic_kernel.data import VectorStoreTextSearch
collection = InMemoryCollection(collection_name='collection', record_type=MyRecord)
search = VectorStoreTextSearch.from_vectorized_search(vectorized_search=collection, embedding_generator=OpenAITextEmbedding(ai_model_id="text-embedding-3-small"))
search_function = search.create_search(
function_name='search',
...
)
Utána: Közvetlen keresési funkció létrehozása
collection = InMemoryCollection(MyRecord)
# Create search function directly on collection
search_function = collection.create_search_function(
function_name="search",
search_type="vector", # or "keyword_hybrid"
top=10,
vector_property_name="vector", # Name of the vector field
)
# Add to kernel directly
kernel.add_function(plugin_name="memory", function=search_function)
5. Az összekötő átnevezi és importálja a módosításokat
Elérésiút-összevonás
# Before: Scattered imports
from semantic_kernel.connectors.memory.azure_cognitive_search import AzureCognitiveSearchMemoryStore
from semantic_kernel.connectors.memory.chroma import ChromaMemoryStore
from semantic_kernel.connectors.memory.pinecone import PineconeMemoryStore
from semantic_kernel.connectors.memory.qdrant import QdrantMemoryStore
# After: Consolidated under connectors
from semantic_kernel.connectors.azure_ai_search import AzureAISearchStore
from semantic_kernel.connectors.chroma import ChromaVectorStore
from semantic_kernel.connectors.pinecone import PineconeVectorStore
from semantic_kernel.connectors.qdrant import QdrantVectorStore
# Alternative after: Consolidated with lazy loading:
from semantic_kernel.connectors.memory import (
AzureAISearchStore,
ChromaVectorStore,
PineconeVectorStore,
QdrantVectorStore,
WeaviateVectorStore,
RedisVectorStore
)
Összekötőosztály átnevezése
| Régi név | Új név |
|---|---|
| AzureCosmosDBforMongoDB* | CosmosMongo* |
| AzureCosmosDBForNoSQL* | CosmosNoSql* |
6. A szövegkeresés fejlesztései és a Bing-összekötő eltávolítása
A Bing-összekötő el lett távolítva és továbbfejlesztett szövegkeresési felület
A Bing szöveges keresési összekötő el lett távolítva. Migrálás alternatív keresési szolgáltatókra:
# Before: Bing Connector (REMOVED)
from semantic_kernel.connectors.search.bing import BingConnector
bing_search = BingConnector(api_key="your-bing-key")
# After: Use Brave Search or other providers
from semantic_kernel.connectors.brave import BraveSearch
# or
from semantic_kernel.connectors.search import BraveSearch
brave_search = BraveSearch()
# Create text search function
text_search_function = brave_search.create_search_function(
function_name="web_search",
query_parameter_name="query",
description="Search the web for information"
)
kernel.add_function(plugin_name="search", function=text_search_function)
Továbbfejlesztett keresési módszerek
Előtte: Három különböző keresési módszer különböző visszatérési típusokkal
from semantic_kernel.connectors.brave import BraveSearch
brave_search = BraveSearch()
# Before: Separate search methods
search_results: KernelSearchResult[str] = await brave_search.search(
query="semantic kernel python",
top=5,
)
search_results: KernelSearchResult[TextSearchResult] = await brave_search.get_text_search_results(
query="semantic kernel python",
top=5,
)
search_results: KernelSearchResult[BraveWebPage] = await brave_search.get_search_results(
query="semantic kernel python",
top=5,
)
Utána: Egységes keresési módszer kimenet típusparaméterrel
from semantic_kernel.data.text_search import SearchOptions
# Enhanced search results with metadata
search_results: KernelSearchResult[str] = await brave_search.search(
query="semantic kernel python",
output_type=str, # can also be TextSearchResult or anything else for search engine specific results, default is `str`
top=5,
filter=lambda result: result.country == "NL", # Example filter
)
async for result in search_results.results:
assert isinstance(result, str) # or TextSearchResult if using that type
print(f"Result: {result}")
print(f"Metadata: {search_results.metadata}")
7. Régi memóriatárolók elavulása
Az összes régi memóriatárolót áthelyezték MemoryStoreBase-ból semantic_kernel.connectors.memory_stores-ba, és elavultként van megjelölve. A legtöbbjük a VectorStore és a VectorStoreCollection alapján egyenértékű új implementációval rendelkezik, amely a következő helyen semantic_kernel.connectors.memorytalálható: .
Ezek az összekötők teljesen el lesznek távolítva:
AstraDBMilvusUsearch
Ha ezek közül bármelyikre szüksége van, vegye át a kódot az elavult modulból és a semantic_kernel.memory mappából, vagy implementálja saját vektortár-gyűjteményét az új VectorStoreCollection osztály alapján.
Ha a GitHub visszajelzései alapján nagy az igény, megfontoljuk, hogy visszahozzuk őket, de egyelőre nem tartjuk fenn őket, és a jövőben el lesznek távolítva.
Migrálás SzemanticTextMemory-ból
# Before: SemanticTextMemory (DEPRECATED)
from semantic_kernel.memory import SemanticTextMemory
from semantic_kernel.connectors.ai.open_ai import OpenAITextEmbeddingGenerationService
embedding_service = OpenAITextEmbeddingGenerationService(ai_model_id="text-embedding-3-small")
memory = SemanticTextMemory(storage=vector_store, embeddings_generator=embedding_service)
# Store memory
await memory.save_information(collection="docs", text="Important information", id="doc1")
# Search memory
results = await memory.search(collection="docs", query="important", limit=5)
# After: Direct Vector Store Usage
from semantic_kernel.data.vector import VectorStoreField, vectorstoremodel
from semantic_kernel.connectors.in_memory import InMemoryCollection
# Define data model
@vectorstoremodel
@dataclass
class MemoryRecord:
id: Annotated[str, VectorStoreField('key')]
text: Annotated[str, VectorStoreField('data', is_full_text_indexed=True)]
embedding: Annotated[list[float] | str | None, VectorStoreField('vector', dimensions=1536, distance_function="cosine", embedding_generator=OpenAITextEmbedding(ai_model_id="text-embedding-3-small"))] = None
# Create vector store with integrated embeddings
collection = InMemoryCollection(
record_type=MemoryRecord,
embedding_generator=OpenAITextEmbedding(ai_model_id="text-embedding-3-small") # Optional, if not set on the record type
)
# Store with automatic embedding generation
record = MemoryRecord(id="doc1", text="Important information", embedding='Important information')
await collection.upsert(record)
# Search with built-in function
search_function = collection.create_search_function(
function_name="search_docs",
search_type="vector"
)
Memória plug-in migrálása
Ha olyan beépülő modult szeretne használni, amely adatokat is menthet, egyszerűen létrehozhatja az alábbi módon:
# Before: TextMemoryPlugin (DEPRECATED)
from semantic_kernel.core_plugins import TextMemoryPlugin
memory_plugin = TextMemoryPlugin(memory)
kernel.add_plugin(memory_plugin, "memory")
# After: Custom plugin using vector store search functions
from semantic_kernel.functions import kernel_function
class VectorMemoryPlugin:
def __init__(self, collection: VectorStoreCollection):
self.collection = collection
@kernel_function(name="save")
async def save_memory(self, text: str, key: str) -> str:
record = MemoryRecord(id=key, text=text, embedding=text)
await self.collection.upsert(record)
return f"Saved to {self.collection.collection_name}"
@kernel_function(name="search")
async def search_memory(self, query: str, limit: int = 5) -> str:
results = await self.collection.search(
query, top=limit, vector_property_name="embedding"
)
return "\n".join([r.record.text async for r in results.results])
# Register the new plugin
memory_plugin = VectorMemoryPlugin(collection)
kernel.add_plugin(memory_plugin, "memory")
Áttelepítési ellenőrzőlista vektorkereséshez
1. lépés: Importálás frissítése
- [ ] A memóriatárolók importálásának lecserélése vektortároló-ekvivalensekre
- [ ] Frissítse a mezők importálását
VectorStoreFieldhasználatával - [ ] Bing-összekötő importjainak eltávolítása
2. lépés: Meződefiníciók frissítése
- [ ] Konvertálás egyesített
VectorStoreFieldosztályra - [ ] Tulajdonságnevek frissítése (
is_filterable→is_indexed) - [ ] Integrált beágyazási generátorok hozzáadása vektormezőkhöz
3. lépés: Gyűjtemény használatának frissítése
- [ ] Memóriaműveletek cseréje vektortároló metódusokkal
- [ ] Szükség esetén új kötegműveletek használata
- [ ] Új keresési függvény létrehozása
4. lépés: A keresés implementálásának frissítése
- [ ] A manuális keresési függvények cseréje a következőre:
create_search_function - [ ] Szövegkeresés frissítése új szolgáltatók használatára
- [ ] Hibrid keresés implementálása, ahol előnyös
- [ ] Áttérés a
FilterClausekifejezésekről alambdakifejezésekre a szűréshez
5. lépés: Elavult kód eltávolítása
- [ ] A
SemanticTextMemoryhasználatának eltávolítása - [ ] Függőségek eltávolítása
TextMemoryPlugin
Teljesítmény- és funkcióelőnyök
Teljesítménybeli fejlesztések
- Kötegelt műveletek: Az új batch upsert/delete metódusok javítják az átviteli sebességet
- Integrált beágyazások: Kiküszöböli a különálló beágyazási létrehozási lépéseket
- Optimalizált keresés: A beépített keresési függvények minden üzlettípushoz optimalizálva vannak
Funkciófejlesztések
- Hibrid keresés: Kombinálja a vektor- és szövegkeresést a jobb eredmények érdekében
- Speciális szűrés: Továbbfejlesztett szűrőkifejezések és indexelés
Fejlesztői élmény
- Egyszerűsített API: Kevesebb osztály és módszer a tanuláshoz
- Konzisztens felület: Egységes megközelítés az összes vektortárolóban
- Jobb dokumentáció: Példák és migrálási útvonalak törlése
- Időtálló: A .NET SDK-val összhangban a platformfüggetlen fejlesztés érdekében
Következtetés
A fent tárgyalt vektortároló-frissítések jelentős javulást jelentenek a Szemantikus Kernel Python SDK-ban. Az új egységes architektúra jobb teljesítményt, továbbfejlesztett funkciókat és intuitívabb fejlesztői élményt biztosít. Bár a migrálás megköveteli az importálás frissítését és a meglévő kód újrabontását, a karbantarthatóság és a funkcionalitás előnyei miatt ez a frissítés erősen ajánlott.
A migrálással kapcsolatos további segítségért tekintse meg a címtár frissített samples/concepts/memory/ mintáit és az átfogó API-dokumentációt.