Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Overzicht
In deze handleiding worden de belangrijkste vectorstore-updates beschreven die zijn geïntroduceerd in Semantische kernelversie 1.34, wat een aanzienlijke revisie van de vectoropslagimplementatie vertegenwoordigt die overeenkomt met de .NET SDK en een meer geïntegreerde, intuïtieve API biedt. De wijzigingen consolideren alles onder semantic_kernel.data.vector en verbeteren de architectuur van de connector.
Overzicht van belangrijke verbeteringen
-
Uniform veldmodel: Één
VectorStoreFieldklasse vervangt meerdere veldtypen - Geïntegreerde insluitingen: directe insluitingsgeneratie in vectorveldspecificaties
- Vereenvoudigd zoeken: Eenvoudig zoekfuncties rechtstreeks in verzamelingen maken
-
Geconsolideerde structuur: alles onder
semantic_kernel.data.vectorensemantic_kernel.connectors - Enhanced Text Search: Verbeterde zoekmogelijkheden voor tekst met gestroomlijnde connectors
-
Afschaffing: Oud
memory_storeswordt afgeschaft ten gunste van de nieuwe vectorarchiefarchitectuur
1. Geïntegreerde insluitingen en Vector Store-modellen/-velden worden bijgewerkt
Er zijn een aantal wijzigingen in de manier waarop u uw vectorarchiefmodel definieert, het grootste is dat we nu geïntegreerde insluitingen rechtstreeks in de definitie van het vectorarchiefveld ondersteunen. Dit betekent dat wanneer u een veld opgeeft als vector, de inhoud van dat veld automatisch wordt ingesloten met behulp van de opgegeven insluitingsgenerator, zoals het model voor het insluiten van tekst van OpenAI. Dit vereenvoudigt het proces van het maken en beheren van vectorvelden.
Wanneer u dat veld definieert, moet u ervoor zorgen dat er drie dingen zijn, met name wanneer u een Pydantic-model gebruikt:
-
typen: Het veld heeft waarschijnlijk drie typen,
list[float],strof iets anders voor de invoer voor de insluitingsgenerator, enNonevoor wanneer het veld niet ingesteld is. -
standaardwaarde: het veld moet een standaardwaarde van of iets anders hebben, zodat er geen fout optreedt bij het ophalen van
Nonerecords vangetofsearchwaarmeeinclude_vectors=Falsenu de standaardwaarde is.
Er zijn hier twee problemen: de eerste is dat bij het decoreren van een klasse met vectorstoremodel, het eerste type annotatie van het veld wordt gebruikt om de type parameter van de VectorStoreField klasse te vullen, dus u moet ervoor zorgen dat de eerste typeaantekening het juiste type is voor de vectorarchiefverzameling waarmee, vaak list[float], moet worden gemaakt. Standaard worden de get en search methoden niet opgenomen in de resultaten, dus het veld heeft een standaardwaarde nodig en moet het typen daar overeen mee stemmen, vandaar dat None vaak is toegestaan en de standaard is ingesteld op None. Wanneer het veld wordt gemaakt, bevinden de waarden die moeten worden ingesloten zich in dit veld, vaak tekenreeksen, dus moet str ook worden opgenomen. De reden voor deze wijziging is om meer flexibiliteit te bieden in wat is ingesloten en wat daadwerkelijk wordt opgeslagen in gegevensvelden. Dit is een algemene instelling:
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}"
Let op de post_init methode. Hiermee maakt u een waarde die wordt ingesloten. Dit is meer dan één veld. De drie typen zijn ook aanwezig.
Eerder: Afzonderlijke veldklassen
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")
]
Na: Unified VectorStoreField met geïntegreerde insluitingen
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
)
]
Belangrijke wijzigingen in velddefinitie
-
Klasse met één veld:
VectorStoreFieldvervangt alle vorige veldtypen -
Specificatie van veldtype: gebruik
field_type: Literal["key", "data", "vector"]parameter, dit kan een positionele parameter zijn, dusVectorStoreField("key")is geldig. -
Verbeterde eigenschappen:
-
storage_nameis toegevoegd. Wanneer deze is ingesteld, wordt deze gebruikt als de veldnaam in de vectoropslag; anders wordt de parameternamegebruikt. -
dimensionsis nu een vereiste parameter voor vectorvelden. -
distance_functionenindex_kindzijn beide optioneel en zullen respectievelijk worden ingesteld opDistanceFunction.DEFAULTenIndexKind.DEFAULTindien niet opgegeven, en alleen voor vectorvelden heeft elke implementatie van een vectorarchief een logica die een Standaard voor dat archief kiest.
-
-
Eigenschaphernoemingen:
-
property_type→type_als een kenmerk entypein constructors -
is_filterable→is_indexed -
is_full_text_searchable→is_full_text_indexed
-
-
Geïntegreerde insluitingen: Voeg rechtstreeks toe
embedding_generatoraan vectorvelden. U kunt ook deembedding_generatorverzameling vectoropslag zelf instellen, die wordt gebruikt voor alle vectorvelden in dat archief. Deze waarde heeft voorrang op de insluitingsgenerator op verzamelingsniveau.
2. Nieuwe methoden voor winkels en verzamelingen
Verbeterde winkelinterface
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.
Verbeterde verzamelingsinterface
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. Verbeterde filters voor zoeken
De implementatie van de nieuwe vectoropslag verandert van string-gebaseerde FilterClause-objecten naar krachtigere en typeveilige lambda-expressies of aanroepbare filters.
Eerder: FilterClause-objecten
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)
)
Na: Lambda-uitdrukkingfilters
# 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
)
Migratietips voor filters
-
Eenvoudige gelijkheid:
filter.equal_to("field", "value")wordtlambda r: r.field == "value" -
Meerdere voorwaarden: Koppelen met
and/oroperators in plaats van meerdere filteroproepen -
Tag/matrix-insluiting:
filter.any_tag_equal_to("tags", "value")wordtlambda r: "value" in r.tags - Verbeterde mogelijkheden: ondersteuning voor bereikquery's, complexe booleaanse logica en aangepaste predicaten
4. Verbeterd gemak van het maken van zoekfuncties
Voor: Zoekfunctie maken met VectorStoreTextSearch
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',
...
)
Na: Direct Search-functie maken
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. Naam van connector wijzigen en wijzigingen importeren
Consolidatie van importpad
# 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
)
Het hernoemen van connectorklassen
| Oude naam | Nieuwe naam |
|---|---|
| AzureCosmosDBforMongoDB* | CosmosMongo* |
| AzureCosmosDBForNoSQL* | CosmosNoSql* |
6. Verbeteringen in tekstzoeken en Bing Connector verwijderd
Bing-connector verwijderd en verbeterde zoekinterface voor tekst
De Bing-tekstzoekconnector is verwijderd. Migreren naar alternatieve zoekproviders:
# 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)
Verbeterde zoekmethoden
Voor: Drie afzonderlijke zoekmethoden met verschillende retourtypen
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,
)
Na: Geünificeerde zoekmethode met uitvoertypeparameter
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. Afschaffing van oude geheugenarchieven
Alle oude geheugens, gebaseerd op MemoryStoreBase, zijn verplaatst naar semantic_kernel.connectors.memory_stores en zijn nu als verouderd verklaard gemarkeerd. De meeste daarvan hebben een equivalente nieuwe implementatie op basis van VectorStore en VectorStoreCollection, die te vinden zijn in semantic_kernel.connectors.memory.
Deze connectors worden volledig verwijderd:
AstraDBMilvusUsearch
Als u een van deze nog steeds nodig hebt, moet u de code van de afgeschafte module en de semantic_kernel.memory map overnemen of uw eigen vectorarchiefverzameling implementeren op basis van de nieuwe VectorStoreCollection klasse.
Als er een grote vraag is op basis van github-feedback, overwegen we ze terug te brengen, maar voorlopig worden ze niet onderhouden en worden ze in de toekomst verwijderd.
Migratie van SemanticTextMemory
# 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"
)
Migratie van geheugeninvoegtoepassing
Wanneer u een invoegtoepassing wilt hebben die ook informatie kan opslaan, kunt u dat eenvoudig maken:
# 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")
Controlelijst voor migratie voor vectorzoekopdrachten
Stap 1: Importbewerkingen bijwerken
- [ ] Import van geheugenopslag vervangen door vector store-equivalenten
- [ ] Veldimporten bijwerken zodat ze
VectorStoreFieldgebruiken. - [ ] Verwijder de imports van de Bing-connector
Stap 2: Velddefinities bijwerken
- [ ] Converteren naar uniforme
VectorStoreFieldklasse - [ ] Eigenschapsnamen bijwerken (
is_filterable→is_indexed) - [ ] Geïntegreerde insluitingsgeneratoren toevoegen aan vectorvelden
Stap 3: Gebruik van verzameling bijwerken
- [ ] Geheugenbewerkingen vervangen door vectoropslagmethoden
- [ ] Nieuwe batchbewerkingen gebruiken indien van toepassing
- [ ] Nieuwe zoekfunctie maken implementeren
Stap 4: Zoekuitvoering bijwerken
- [ ] Handmatige zoekfuncties vervangen door
create_search_function - [ ] Tekst zoeken bijwerken om nieuwe providers te gebruiken
- [ ] Hybride zoekopdracht implementeren waar nuttig
- [ ] Migreren van
FilterClausenaarlambdaexpressies voor filteren
Stap 5: Afgeschafte code verwijderen
- [ ] Verwijder
SemanticTextMemorygebruik - [ ] Afhankelijkheden verwijderen
TextMemoryPlugin
Voordelen van prestaties en functies
Prestatieverbeteringen
- Batchbewerkingen: Nieuwe methoden voor batch-upserten en -verwijderen verbeteren de doorvoer
- Geïntegreerde Embeddings: Elimineert de aparte stappen voor embedding-generatie.
- Geoptimaliseerd zoeken: ingebouwde zoekfuncties zijn geoptimaliseerd voor elk winkeltype
Functieverbeteringen
- Hybride zoekopdracht: combineert vector- en tekstzoekopdrachten voor betere resultaten
- Geavanceerd filteren: Verbeterde filterexpressies en indexering
Ontwikkelaarservaring
- Vereenvoudigde API: Minder klassen en methoden om te leren
- Consistente interface: geïntegreerde benadering in alle vectorarchieven
- Betere documentatie: Duidelijke voorbeelden en migratiepaden
- Toekomstbestendig: afgestemd op .NET SDK voor consistente platformoverschrijdende ontwikkeling
Conclusie
De updates voor vectoropslag die hierboven worden besproken, vertegenwoordigen een aanzienlijke verbetering in de Semantische Kernel Python SDK. De nieuwe geïntegreerde architectuur biedt betere prestaties, verbeterde functies en een intuïtievere ontwikkelaarservaring. Tijdens de migratie moeten de importbewerkingen en het herstructureren van bestaande code worden bijgewerkt, maar de voordelen in onderhoudbaarheid en functionaliteit maken deze upgrade ten zeerste aanbevolen.
Raadpleeg de bijgewerkte voorbeelden in de samples/concepts/memory/ map en de uitgebreide API-documentatie voor aanvullende hulp bij migratie.