Semantic Kernel (SK) helps assemble the services behind an AI application. For Q&A over PDFs, a kernel connects chat completion and text embeddings to semantic memory backed by a Chroma vector store. section 10.3.3
The workflow extracts PDF text, saves it to memory, and reuses an existing vector-database collection when available. Configuration includes Azure endpoints and keys, model deployments, and a local persistence directory. section 10.3.3
Listing 10.3 Q&A over my PDFs: SK using Chroma
async def main():
# Setup Semantic Kernel
kernel = sk.Kernel()
kernel.add_service(AzureChatCompletion(
service_id="chat_completion",
deployment_name=AOAI_MODEL,
endpoint=AOAI_ENDPOINT,
api_key=AOAI_KEY,
api_version=API_VERSION))
kernel.add_service(AzureTextEmbedding(
service_id="text_embedding",
deployment_name=AOAI_EMBEDDINGS,
endpoint=AOAI_ENDPOINT,
api_key=AOAI_KEY))
# Specify the type of memory to attach to SK.
# Here we will use Chroma as it is easy to run it locally
# You can specify location of Chroma DB files.
store = ChromaMemoryStore(persist_directory=PERSIST_DIR)
memory = SemanticTextMemory(storage=store,
embeddings_generator = kernel.get_service("text_embedding"))
kernel.add_plugin(TextMemoryPlugin(memory), "TextMemoryPluginACDB")
await load_vector_db(memory, VECTOR_DB)
while True:
prompt = check_prompt(input('Ask a question against
the PDF (type "quit" to exit):'))
# Query the memory for most relevant match using
# search_async specifying relevance score and
# "limit" of number of closest documents
result = await memory.search(collection=VECTOR_DB,
limit=3, min_relevance_score=0.7, query=prompt)
if result:
print(result[0].text)
else:
print("No matches found.")
print("-" * 80)
if __name__ == "__main__":
asyncio.run(main())
See the kernel setup that registers Azure chat and embedding services, then attaches Chroma-backed semantic memory. section 10.3.3


