<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>article Getting started with Databricks - Deploy an LLM chatbot using Databricks Vector Search and Foundation Model API in Get Started Guides</title>
    <link>https://community.databricks.com/t5/get-started-guides/getting-started-with-databricks-deploy-an-llm-chatbot-using/ta-p/80764</link>
    <description>&lt;DIV class="lia-message-template-content-zone"&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H1 id="Simple-RAG-Example-using-Vector-Search-and-the-Foundation-Model-API"&gt;Getting started with Databricks - Deploy an LLM chatbot using Databricks Vector Search and Foundation Model API&lt;/H1&gt;
&lt;P&gt;This guide demonstrates how to build a simple Retrieval-Augmented Generation (RAG) application using Databricks Vector Search, a vector database seamlessly integrated with Databricks' Foundation Model API (FMAPI) embedding models.&lt;/P&gt;
&lt;P&gt;RAG is a widely adopted architecture for creating natural-language interfaces that allow users to interact with organizational data effectively. This tutorial will walk you through setting up a vector index, loading text data, querying the database, building a prompt for a large language model (LLM), and finally querying the LLM using the FMAPI. All these steps can be completed in just 30 minutes.&lt;/P&gt;
&lt;P&gt;This is a beginner’s guide with hands-on instructions that you can follow in your own Databricks workspace. &lt;BR /&gt;&lt;BR /&gt;To learn more about how Databricks Vector Search works, refer to the documentation &lt;A href="https://docs.databricks.com/en/generative-ai/vector-search.html#how-does-vector-search-work" target="_self"&gt;here&lt;/A&gt;.&lt;BR /&gt;For more information on querying models via the Foundation Model APIs, see the documentation &lt;A href="https://docs.databricks.com/en/machine-learning/model-serving/score-foundation-models.html#query-foundation-models" target="_self"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H2 id="Setup"&gt;Setup&lt;/H2&gt;
&lt;P&gt;First, we will install the necessary libraries and set up a temporary catalog/schema/table for this example.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&lt;LI-CODE lang="python"&gt;In [ ]:
%pip install --upgrade databricks-vectorsearch databricks-genai-inference dbutils.library.restartPython()&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H3 id="Define-catalog,-table,-endpoint,-and-index-names"&gt;Define catalog, table, endpoint, and index names&lt;/H3&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline"&gt;
&lt;DIV class="cm-editor cm-s-jupyter language-python hljs"&gt;&lt;LI-CODE lang="markup"&gt;In [ ]:
CATALOG = "workspace" DB='vs_demo' SOURCE_TABLE_NAME = "documents" SOURCE_TABLE_FULLNAME=f"{CATALOG}.{DB}.{SOURCE_TABLE_NAME}"&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H3 id="Create-Catalog,-Schema,-and-Table"&gt;Create Catalog, Schema, and Table&lt;/H3&gt;
&lt;P&gt;A Databricks Vector Search Index is created from a Delta Table. The source Delta Table includes the data we ultimately want to index and search with the vector database. In this cell, we create the catalog, schema, and source table from which we will create the vector database.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&lt;LI-CODE lang="python"&gt;In [ ]:
# Set up schema/volume/table from pyspark.sql.types 

import StructType, StructField, StringType, ArrayType, FloatType spark.sql(f"CREATE SCHEMA IF NOT EXISTS {CATALOG}.{DB}") spark.sql( f"""CREATE TABLE IF NOT EXISTS {SOURCE_TABLE_FULLNAME} ( id STRING, text STRING, date DATE, title STRING ) USING delta TBLPROPERTIES ('delta.enableChangeDataFeed' = 'true') """ )
&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H2 id="Set-up-the-Vector-Database"&gt;Set up the Vector Database&lt;/H2&gt;
&lt;P&gt;Next, we set up the vector database. There are three key steps:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Initialize the vector search client&lt;/LI&gt;
&lt;LI&gt;Create the endpoint&lt;/LI&gt;
&lt;LI&gt;Create the index using the source Delta table we created earlier and the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;bge-large-en&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;embeddings model from the Foundation Model API&lt;/LI&gt;
&lt;/OL&gt;
&lt;H3 id="Initialize-the-Vector-Search-Client"&gt;Initialize the Vector Search Client&lt;/H3&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline"&gt;
&lt;DIV class="cm-editor cm-s-jupyter language-python hljs"&gt;&lt;LI-CODE lang="python"&gt;In [ ]:
from databricks.vector_search.client import VectorSearchClient vsc = VectorSearchClient()&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H3 id="Create-the-Endpoint"&gt;Create the Endpoint&lt;/H3&gt;
&lt;P&gt;The cell below will check if the endpoint already exists and create it if it does not.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&lt;LI-CODE lang="python"&gt;In [ ]:
VS_ENDPOINT_NAME = 'vs_endpoint' if vsc.list_endpoints().get('endpoints') == None or not VS_ENDPOINT_NAME in [endpoint.get('name') for endpoint in vsc.list_endpoints().get('endpoints')]: print(f"Creating new Vector Search endpoint named {VS_ENDPOINT_NAME}") vsc.create_endpoint(VS_ENDPOINT_NAME) else: print(f"Endpoint {VS_ENDPOINT_NAME} already exists.") vsc.wait_for_endpoint(VS_ENDPOINT_NAME, 600)
&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&lt;SPAN&gt;Create the Vector Index&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;P&gt;Now we can create the index over the Delta table we created earlier.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&lt;LI-CODE lang="python"&gt;In [ ]:
VS_INDEX_NAME = 'fm_api_examples_vs_index' 
VS_INDEX_FULLNAME = f"{CATALOG}.{DB}.{VS_INDEX_NAME}" 

if not VS_INDEX_FULLNAME in [index.get("name") for index in vsc.list_indexes(VS_ENDPOINT_NAME).get('vector_indexes', [])]:
    try:
        # set up an index with managed embeddings
        print("Creating Vector Index...")
        i = vsc.create_delta_sync_index_and_wait(
            endpoint_name=VS_ENDPOINT_NAME,
            index_name=VS_INDEX_FULLNAME,
            source_table_name=SOURCE_TABLE_FULLNAME,
            pipeline_type="TRIGGERED",
            primary_key="id",
            embedding_source_column="text",
            embedding_model_endpoint_name="databricks-bge-large-en"
        )
    except Exception as e:
        if "INTERNAL_ERROR" in str(e):
            # Check if the index exists after the error occurred
            if VS_INDEX_FULLNAME in [index.get("name") for index in vsc.list_indexes(VS_ENDPOINT_NAME).get('vector_indexes', [])]:
                print(f"Index {VS_INDEX_FULLNAME} has been created.")
            else:
                raise e
        else:
            raise e
else:
    print(f"Index {VS_INDEX_FULLNAME} already exists.")&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&lt;SPAN&gt;There are a few key points to note about the specific configuration we used in this case:&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;We used&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;pipeline_type="TRIGGERED"&lt;/CODE&gt;. This requires us to use the index's&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;sync()&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;method to manually sync the source Delta table with the index. We could, alternatively, use&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;pipeline_type="CONTINUOUS"&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;which will automatically keep the index in sync with the source table with only seconds of latency. This approach is more costly, though, as a compute cluster must be provisioned for the continuous sync streaming pipeline.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;We specified&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;embedding_model_endpoint_name="databricks-bge-large-en"&lt;/CODE&gt;. We can use any embedding model available via model serving; this is the name of the pay-per-token Foundation Model API version of&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;databricks-bge-large-en&lt;/CODE&gt;. By passing an&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;embedding_source_column&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;embedding_model_endpoint_name&lt;/CODE&gt;, we configure the index such that it will automatically use the model to generate embeddings for the texts in the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;text&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;column of the source table. We do not need to manually generate embeddings.&lt;/P&gt;
&lt;P&gt;If, however, we did want to manage embeddings manually, we could include the following arguments instead:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE&gt;  embedding_vector_column="&amp;lt;embedding_column&amp;gt;",
  embedding_dimension=&amp;lt;embedding_dimension&amp;gt;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;In the latter approach, we include a column for embeddings in the source delta table and embeddings are&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;EM&gt;not&lt;/EM&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;computed automatically from the text column.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 id="Set-up-some-example-texts"&gt;Set up some example texts&lt;/H2&gt;
&lt;P&gt;Now we set up some example texts to index.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&lt;LI-CODE lang="python"&gt;# Some example texts
from datetime import datetime


smarter_overview = {"text":"""
S.M.A.R.T.E.R. Initiative: Strategic Management for Achieving Results through Efficiency and Resources
Introduction
The S.M.A.R.T.E.R. Initiative, standing for "Strategic Management for Achieving Results through Efficiency and Resources," is a groundbreaking project aimed at revolutionizing the way our organization operates. In today's rapidly changing business landscape, achieving success demands a strategic approach that leverages resources effectively while optimizing efficiency. The S.M.A.R.T.E.R. Initiative is designed to do just that.

Background
As markets evolve and competition intensifies, organizations must adapt to stay relevant and profitable. Traditional methods of operation often become inefficient and costly. The S.M.A.R.T.E.R. Initiative was conceived as a response to this challenge, with the primary goal of enhancing strategic management practices to achieve better results.

Objectives
1. Resource Optimization
One of the key objectives of the S.M.A.R.T.E.R. Initiative is to optimize resource allocation. This involves identifying underutilized resources, streamlining processes, and reallocating resources to areas that contribute most to our strategic goals.

2. Efficiency Improvement
Efficiency is at the core of the S.M.A.R.T.E.R. Initiative. By identifying bottlenecks and improving processes, we aim to reduce operational costs, shorten project timelines, and enhance overall productivity.

3. Strategic Alignment
For any organization to succeed, its activities must be aligned with its strategic objectives. The S.M.A.R.T.E.R. Initiative will ensure that every action and resource allocation is in sync with our long-term strategic goals.

4. Results-driven Approach
The ultimate measure of success is results. The S.M.A.R.T.E.R. Initiative will foster a results-driven culture within our organization, where decisions and actions are guided by their impact on our bottom line and strategic objectives.

Key Components
The S.M.A.R.T.E.R. Initiative comprises several key components:

1. Data Analytics and Insights
Data is the foundation of informed decision-making. We will invest in advanced data analytics tools to gain insights into our operations, customer behavior, and market trends. These insights will guide our resource allocation and strategy.

2. Process Automation
Automation will play a vital role in enhancing efficiency. Routine and repetitive tasks will be automated, freeing up our workforce to focus on more strategic activities.

3. Performance Metrics and KPIs
To ensure that our efforts are aligned with our objectives, we will establish a comprehensive set of Key Performance Indicators (KPIs). Regular monitoring and reporting will provide visibility into our progress.

4. Training and Development
Enhancing our workforce's skills is essential. We will invest in training and development programs to equip our employees with the knowledge and tools needed to excel in their roles.

Implementation Timeline
The S.M.A.R.T.E.R. Initiative will be implemented in phases over the next three years. This phased approach allows for a smooth transition and ensures that each component is integrated effectively into our operations.

Conclusion
The S.M.A.R.T.E.R. Initiative represents a significant step forward for our organization. By strategically managing our resources and optimizing efficiency, we are positioning ourselves for sustained success in a competitive marketplace. This initiative is a testament to our commitment to excellence and our dedication to achieving exceptional results.

As we embark on this journey, we look forward to the transformative impact that the S.M.A.R.T.E.R. Initiative will have on our organization and the benefits it will bring to our employees, customers, and stakeholders.
""", "title": "Project Kickoff", "date": datetime.strptime("2024-01-16", "%Y-%m-%d")}

smarter_kpis = {"text": """S.M.A.R.T.E.R. Initiative: Key Performance Indicators (KPIs)
Introduction
The S.M.A.R.T.E.R. Initiative (Strategic Management for Achieving Results through Efficiency and Resources) is designed to drive excellence within our organization. To measure the success and effectiveness of this initiative, we have established three concrete and measurable Key Performance Indicators (KPIs). This document outlines these KPIs and their associated targets.

Key Performance Indicators (KPIs)
1. Resource Utilization Efficiency (RUE)
Objective: To optimize resource utilization for cost-efficiency.

KPI Definition: RUE will be calculated as (Actual Resource Utilization / Planned Resource Utilization) * 100%.

Target: Achieve a 15% increase in RUE within the first year.

2. Time-to-Decision Reduction (TDR)
Objective: To streamline operational processes and reduce decision-making time.

KPI Definition: TDR will be calculated as (Pre-Initiative Decision Time - Post-Initiative Decision Time) / Pre-Initiative Decision Time.

Target: Achieve a 20% reduction in TDR for critical business decisions.

3. Strategic Goals Achievement (SGA)
Objective: To ensure that organizational activities align with strategic goals.

KPI Definition: SGA will measure the percentage of predefined strategic objectives achieved.

Target: Achieve an 80% Strategic Goals Achievement rate within two years.

Conclusion
These three KPIs, Resource Utilization Efficiency (RUE), Time-to-Decision Reduction (TDR), and Strategic Goals Achievement (SGA), will serve as crucial metrics for evaluating the success of the S.M.A.R.T.E.R. Initiative. By tracking these KPIs and working towards their targets, we aim to drive efficiency, optimize resource utilization, and align our actions with our strategic objectives. This focus on measurable outcomes will guide our efforts towards achieving excellence within our organization.""",
"title": "Project KPIs", "date": datetime.strptime("2024-01-16", "%Y-%m-%d")}
     &lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H3 id="Chunk-the-texts"&gt;Chunk the texts&lt;/H3&gt;
&lt;P&gt;Typically, when using a vector database for retrieval-augmented generation (RAG) tasks, we break the texts apart into smaller (and sometimes overlapping) chunks to return focused and relevant information without returning an excessive amount of text.&lt;/P&gt;
&lt;P&gt;In the code below, we break the sample texts above into shorter overlapping text chunks.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline"&gt;
&lt;DIV class="cm-editor cm-s-jupyter language-python hljs"&gt;&lt;LI-CODE lang="python"&gt;import re

def chunk_text(text, chunk_size, overlap):
    words = text.split()
    chunks = []
    index = 0

    while index &amp;lt; len(words):
        end = index + chunk_size
        while end &amp;lt; len(words) and not re.match(r'.*[.!?]\s*$', words[end]):
            end += 1
        chunk = ' '.join(words[index:end+1])
        chunks.append(chunk)
        index += chunk_size - overlap

    return chunks

chunks = []
documents = [smarter_overview, smarter_kpis]

for document in documents:
    for i, c in enumerate(chunk_text(document["text"], 150, 25)):
        chunk = {}
        chunk["text"] = c
        chunk["title"] = document["title"]
        chunk["date"] = document["date"]
        chunk["id"] = document["title"] + "_" + str(i)

        chunks.append(chunk)&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&lt;SPAN&gt;Insert the text chunks into the source delta table&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;P&gt;Now we save the chunks, along with some metadata (a document title, date, and a unique id) to the source delta table.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline"&gt;
&lt;DIV class="cm-editor cm-s-jupyter language-python hljs"&gt;&lt;LI-CODE lang="python"&gt;from pyspark.sql.types import StructType, StructField, StringType, ArrayType, FloatType, DateType

schema = StructType(
    [
        StructField("id", StringType(), True),
        StructField("text", StringType(), True),
        StructField("title", StringType(), True),
        StructField("date", DateType(), True),
    ]
)

if chunks:
    result_df = spark.createDataFrame(chunks, schema=schema)
    result_df.write.format("delta").mode("append").saveAsTable(
        SOURCE_TABLE_FULLNAME
    )
     &lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H2 id="Sync-the-Vector-Search-Index"&gt;Sync the Vector Search Index&lt;/H2&gt;
&lt;P&gt;Because we specified&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;pipeline_type="TRIGGERED"&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;when configuring the Delta Index, we still need to manually tell the index to sync with the delta table. This will take a few minutes.&lt;/P&gt;
&lt;P&gt;This will not work if the index is not ready yet. We use the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;wait_until_ready&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;method to wait until the index is ready.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline"&gt;
&lt;DIV class="cm-editor cm-s-jupyter language-python hljs"&gt;&lt;LI-CODE lang="python"&gt;In [ ]:
# Sync 

index = vsc.get_index(endpoint_name=VS_ENDPOINT_NAME, index_name=VS_INDEX_FULLNAME) index.sync()&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H2 id="Query-the-Vector-Index"&gt;Query the Vector Index&lt;/H2&gt;
&lt;P&gt;Now that we have added our text chunks to the source delta table and synced it with the Vector Search index, we're ready to query the index! We do this with the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;index.similarity_search()&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;method.&lt;/P&gt;
&lt;P&gt;The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;columns&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;argument takes a list of the columns we want returned; in this case, we request the text and title columns.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;NOTE&lt;/STRONG&gt;: If the cell below does not return any results, wait a couple of minutes and try again. The index may still be syncing.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&lt;LI-CODE lang="python"&gt;In [ ]:
# query

 index.similarity_search(columns=["text", "title"], query_text="What is the TDR Target for the SMARTER initiative?", num_results = 3)&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline"&gt;
&lt;DIV class="cm-editor cm-s-jupyter language-python hljs"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H2 id="Answering-Questions-about-the-Output"&gt;Answering Questions about the Output&lt;/H2&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline"&gt;
&lt;DIV class="cm-editor cm-s-jupyter language-python hljs"&gt;&lt;LI-CODE lang="python"&gt;from databricks_genai_inference import ChatSession

chat = ChatSession(model="databricks-meta-llama-3-70b-instruct",
                   system_message="You are a helpful assistant.",
                   max_tokens=128)&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&lt;SPAN&gt;First, let's ask a question&lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;EM style="color: #1b3139; font-family: inherit;"&gt;without&lt;/EM&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;RAG.&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline"&gt;
&lt;DIV class="cm-editor cm-s-jupyter language-python hljs"&gt;&lt;LI-CODE lang="python"&gt;chat.reply("What is the TDR Target for the SMARTER initiative?")
chat.last&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&lt;SPAN&gt;As you can see, its response has nothing to do with the documents we processed above.&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;P&gt;Now let's see what kind of reply we get when we provide context from vector search.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&lt;LI-CODE lang="python"&gt;# reset history
chat = ChatSession(model="databricks-meta-llama-3-70b-instruct",
                   system_message="You are a helpful assistant. Answer the user's question based on the provided context.",
                   max_tokens=128)

# get context from vector search
raw_context = index.similarity_search(columns=["text", "title"],
                        query_text="What is the TDR Target for the SMARTER initiative?",
                        num_results = 3)

context_string = "Context:\n\n"

for (i,doc) in enumerate(raw_context.get('result').get('data_array')):
    context_string += f"Retrieved context {i+1}:\n"
    context_string += doc[0]
    context_string += "\n\n"

chat.reply(f"User question: What is the TDR Target for the SMARTER initiative?\n\nContext: {context_string}")
chat.last&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;P&gt;It is now able to answer based on the provided context.&lt;/P&gt;
&lt;H3 id="Congratulations!-Demo-complete."&gt;Congratulations! Your chatbot is ready.&lt;/H3&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&lt;SPAN&gt;Additional information&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H2 id="Using-the-UI"&gt;Using the UI&lt;/H2&gt;
&lt;P&gt;Most of the Vector Database management steps above can be done via the UI: you can&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/generative-ai/create-query-vector-search.html#create-a-vector-search-endpoint-using-the-ui" target="_blank" rel="noopener"&gt;create an endpoint&lt;/A&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/generative-ai/create-query-vector-search.html#create-index-using-the-ui" target="_blank" rel="noopener"&gt;create an index&lt;/A&gt;, sync the index, and more via the UI in the Databricks Catalog Explorer.&lt;/P&gt;
&lt;H2 id="Experimenting-in-the-AI-Playground"&gt;Experimenting in the AI Playground&lt;/H2&gt;
&lt;P&gt;The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/large-language-models/ai-playground.html" target="_blank" rel="noopener"&gt;Databricks AI Playground&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;provides a GUI for quickly experimenting with LLMs available via the FMAPI, enabling you to compare the outputs of those models and determine which model best serves your needs.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;</description>
    <pubDate>Thu, 15 Aug 2024 17:53:44 GMT</pubDate>
    <dc:creator>DatabricksGuide</dc:creator>
    <dc:date>2024-08-15T17:53:44Z</dc:date>
    <item>
      <title>Getting started with Databricks - Deploy an LLM chatbot using Databricks Vector Search and Foundation Model API</title>
      <link>https://community.databricks.com/t5/get-started-guides/getting-started-with-databricks-deploy-an-llm-chatbot-using/ta-p/80764</link>
      <description>&lt;DIV class="lia-message-template-content-zone"&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H1 id="Simple-RAG-Example-using-Vector-Search-and-the-Foundation-Model-API"&gt;Getting started with Databricks - Deploy an LLM chatbot using Databricks Vector Search and Foundation Model API&lt;/H1&gt;
&lt;P&gt;This guide demonstrates how to build a simple Retrieval-Augmented Generation (RAG) application using Databricks Vector Search, a vector database seamlessly integrated with Databricks' Foundation Model API (FMAPI) embedding models.&lt;/P&gt;
&lt;P&gt;RAG is a widely adopted architecture for creating natural-language interfaces that allow users to interact with organizational data effectively. This tutorial will walk you through setting up a vector index, loading text data, querying the database, building a prompt for a large language model (LLM), and finally querying the LLM using the FMAPI. All these steps can be completed in just 30 minutes.&lt;/P&gt;
&lt;P&gt;This is a beginner’s guide with hands-on instructions that you can follow in your own Databricks workspace. &lt;BR /&gt;&lt;BR /&gt;To learn more about how Databricks Vector Search works, refer to the documentation &lt;A href="https://docs.databricks.com/en/generative-ai/vector-search.html#how-does-vector-search-work" target="_self"&gt;here&lt;/A&gt;.&lt;BR /&gt;For more information on querying models via the Foundation Model APIs, see the documentation &lt;A href="https://docs.databricks.com/en/machine-learning/model-serving/score-foundation-models.html#query-foundation-models" target="_self"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H2 id="Setup"&gt;Setup&lt;/H2&gt;
&lt;P&gt;First, we will install the necessary libraries and set up a temporary catalog/schema/table for this example.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&lt;LI-CODE lang="python"&gt;In [ ]:
%pip install --upgrade databricks-vectorsearch databricks-genai-inference dbutils.library.restartPython()&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H3 id="Define-catalog,-table,-endpoint,-and-index-names"&gt;Define catalog, table, endpoint, and index names&lt;/H3&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline"&gt;
&lt;DIV class="cm-editor cm-s-jupyter language-python hljs"&gt;&lt;LI-CODE lang="markup"&gt;In [ ]:
CATALOG = "workspace" DB='vs_demo' SOURCE_TABLE_NAME = "documents" SOURCE_TABLE_FULLNAME=f"{CATALOG}.{DB}.{SOURCE_TABLE_NAME}"&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H3 id="Create-Catalog,-Schema,-and-Table"&gt;Create Catalog, Schema, and Table&lt;/H3&gt;
&lt;P&gt;A Databricks Vector Search Index is created from a Delta Table. The source Delta Table includes the data we ultimately want to index and search with the vector database. In this cell, we create the catalog, schema, and source table from which we will create the vector database.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&lt;LI-CODE lang="python"&gt;In [ ]:
# Set up schema/volume/table from pyspark.sql.types 

import StructType, StructField, StringType, ArrayType, FloatType spark.sql(f"CREATE SCHEMA IF NOT EXISTS {CATALOG}.{DB}") spark.sql( f"""CREATE TABLE IF NOT EXISTS {SOURCE_TABLE_FULLNAME} ( id STRING, text STRING, date DATE, title STRING ) USING delta TBLPROPERTIES ('delta.enableChangeDataFeed' = 'true') """ )
&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H2 id="Set-up-the-Vector-Database"&gt;Set up the Vector Database&lt;/H2&gt;
&lt;P&gt;Next, we set up the vector database. There are three key steps:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Initialize the vector search client&lt;/LI&gt;
&lt;LI&gt;Create the endpoint&lt;/LI&gt;
&lt;LI&gt;Create the index using the source Delta table we created earlier and the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;bge-large-en&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;embeddings model from the Foundation Model API&lt;/LI&gt;
&lt;/OL&gt;
&lt;H3 id="Initialize-the-Vector-Search-Client"&gt;Initialize the Vector Search Client&lt;/H3&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline"&gt;
&lt;DIV class="cm-editor cm-s-jupyter language-python hljs"&gt;&lt;LI-CODE lang="python"&gt;In [ ]:
from databricks.vector_search.client import VectorSearchClient vsc = VectorSearchClient()&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H3 id="Create-the-Endpoint"&gt;Create the Endpoint&lt;/H3&gt;
&lt;P&gt;The cell below will check if the endpoint already exists and create it if it does not.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&lt;LI-CODE lang="python"&gt;In [ ]:
VS_ENDPOINT_NAME = 'vs_endpoint' if vsc.list_endpoints().get('endpoints') == None or not VS_ENDPOINT_NAME in [endpoint.get('name') for endpoint in vsc.list_endpoints().get('endpoints')]: print(f"Creating new Vector Search endpoint named {VS_ENDPOINT_NAME}") vsc.create_endpoint(VS_ENDPOINT_NAME) else: print(f"Endpoint {VS_ENDPOINT_NAME} already exists.") vsc.wait_for_endpoint(VS_ENDPOINT_NAME, 600)
&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&lt;SPAN&gt;Create the Vector Index&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;P&gt;Now we can create the index over the Delta table we created earlier.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&lt;LI-CODE lang="python"&gt;In [ ]:
VS_INDEX_NAME = 'fm_api_examples_vs_index' 
VS_INDEX_FULLNAME = f"{CATALOG}.{DB}.{VS_INDEX_NAME}" 

if not VS_INDEX_FULLNAME in [index.get("name") for index in vsc.list_indexes(VS_ENDPOINT_NAME).get('vector_indexes', [])]:
    try:
        # set up an index with managed embeddings
        print("Creating Vector Index...")
        i = vsc.create_delta_sync_index_and_wait(
            endpoint_name=VS_ENDPOINT_NAME,
            index_name=VS_INDEX_FULLNAME,
            source_table_name=SOURCE_TABLE_FULLNAME,
            pipeline_type="TRIGGERED",
            primary_key="id",
            embedding_source_column="text",
            embedding_model_endpoint_name="databricks-bge-large-en"
        )
    except Exception as e:
        if "INTERNAL_ERROR" in str(e):
            # Check if the index exists after the error occurred
            if VS_INDEX_FULLNAME in [index.get("name") for index in vsc.list_indexes(VS_ENDPOINT_NAME).get('vector_indexes', [])]:
                print(f"Index {VS_INDEX_FULLNAME} has been created.")
            else:
                raise e
        else:
            raise e
else:
    print(f"Index {VS_INDEX_FULLNAME} already exists.")&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&lt;SPAN&gt;There are a few key points to note about the specific configuration we used in this case:&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;We used&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;pipeline_type="TRIGGERED"&lt;/CODE&gt;. This requires us to use the index's&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;sync()&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;method to manually sync the source Delta table with the index. We could, alternatively, use&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;pipeline_type="CONTINUOUS"&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;which will automatically keep the index in sync with the source table with only seconds of latency. This approach is more costly, though, as a compute cluster must be provisioned for the continuous sync streaming pipeline.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;We specified&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;embedding_model_endpoint_name="databricks-bge-large-en"&lt;/CODE&gt;. We can use any embedding model available via model serving; this is the name of the pay-per-token Foundation Model API version of&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;databricks-bge-large-en&lt;/CODE&gt;. By passing an&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;embedding_source_column&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;embedding_model_endpoint_name&lt;/CODE&gt;, we configure the index such that it will automatically use the model to generate embeddings for the texts in the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;text&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;column of the source table. We do not need to manually generate embeddings.&lt;/P&gt;
&lt;P&gt;If, however, we did want to manage embeddings manually, we could include the following arguments instead:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE&gt;  embedding_vector_column="&amp;lt;embedding_column&amp;gt;",
  embedding_dimension=&amp;lt;embedding_dimension&amp;gt;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;In the latter approach, we include a column for embeddings in the source delta table and embeddings are&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;EM&gt;not&lt;/EM&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;computed automatically from the text column.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 id="Set-up-some-example-texts"&gt;Set up some example texts&lt;/H2&gt;
&lt;P&gt;Now we set up some example texts to index.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&lt;LI-CODE lang="python"&gt;# Some example texts
from datetime import datetime


smarter_overview = {"text":"""
S.M.A.R.T.E.R. Initiative: Strategic Management for Achieving Results through Efficiency and Resources
Introduction
The S.M.A.R.T.E.R. Initiative, standing for "Strategic Management for Achieving Results through Efficiency and Resources," is a groundbreaking project aimed at revolutionizing the way our organization operates. In today's rapidly changing business landscape, achieving success demands a strategic approach that leverages resources effectively while optimizing efficiency. The S.M.A.R.T.E.R. Initiative is designed to do just that.

Background
As markets evolve and competition intensifies, organizations must adapt to stay relevant and profitable. Traditional methods of operation often become inefficient and costly. The S.M.A.R.T.E.R. Initiative was conceived as a response to this challenge, with the primary goal of enhancing strategic management practices to achieve better results.

Objectives
1. Resource Optimization
One of the key objectives of the S.M.A.R.T.E.R. Initiative is to optimize resource allocation. This involves identifying underutilized resources, streamlining processes, and reallocating resources to areas that contribute most to our strategic goals.

2. Efficiency Improvement
Efficiency is at the core of the S.M.A.R.T.E.R. Initiative. By identifying bottlenecks and improving processes, we aim to reduce operational costs, shorten project timelines, and enhance overall productivity.

3. Strategic Alignment
For any organization to succeed, its activities must be aligned with its strategic objectives. The S.M.A.R.T.E.R. Initiative will ensure that every action and resource allocation is in sync with our long-term strategic goals.

4. Results-driven Approach
The ultimate measure of success is results. The S.M.A.R.T.E.R. Initiative will foster a results-driven culture within our organization, where decisions and actions are guided by their impact on our bottom line and strategic objectives.

Key Components
The S.M.A.R.T.E.R. Initiative comprises several key components:

1. Data Analytics and Insights
Data is the foundation of informed decision-making. We will invest in advanced data analytics tools to gain insights into our operations, customer behavior, and market trends. These insights will guide our resource allocation and strategy.

2. Process Automation
Automation will play a vital role in enhancing efficiency. Routine and repetitive tasks will be automated, freeing up our workforce to focus on more strategic activities.

3. Performance Metrics and KPIs
To ensure that our efforts are aligned with our objectives, we will establish a comprehensive set of Key Performance Indicators (KPIs). Regular monitoring and reporting will provide visibility into our progress.

4. Training and Development
Enhancing our workforce's skills is essential. We will invest in training and development programs to equip our employees with the knowledge and tools needed to excel in their roles.

Implementation Timeline
The S.M.A.R.T.E.R. Initiative will be implemented in phases over the next three years. This phased approach allows for a smooth transition and ensures that each component is integrated effectively into our operations.

Conclusion
The S.M.A.R.T.E.R. Initiative represents a significant step forward for our organization. By strategically managing our resources and optimizing efficiency, we are positioning ourselves for sustained success in a competitive marketplace. This initiative is a testament to our commitment to excellence and our dedication to achieving exceptional results.

As we embark on this journey, we look forward to the transformative impact that the S.M.A.R.T.E.R. Initiative will have on our organization and the benefits it will bring to our employees, customers, and stakeholders.
""", "title": "Project Kickoff", "date": datetime.strptime("2024-01-16", "%Y-%m-%d")}

smarter_kpis = {"text": """S.M.A.R.T.E.R. Initiative: Key Performance Indicators (KPIs)
Introduction
The S.M.A.R.T.E.R. Initiative (Strategic Management for Achieving Results through Efficiency and Resources) is designed to drive excellence within our organization. To measure the success and effectiveness of this initiative, we have established three concrete and measurable Key Performance Indicators (KPIs). This document outlines these KPIs and their associated targets.

Key Performance Indicators (KPIs)
1. Resource Utilization Efficiency (RUE)
Objective: To optimize resource utilization for cost-efficiency.

KPI Definition: RUE will be calculated as (Actual Resource Utilization / Planned Resource Utilization) * 100%.

Target: Achieve a 15% increase in RUE within the first year.

2. Time-to-Decision Reduction (TDR)
Objective: To streamline operational processes and reduce decision-making time.

KPI Definition: TDR will be calculated as (Pre-Initiative Decision Time - Post-Initiative Decision Time) / Pre-Initiative Decision Time.

Target: Achieve a 20% reduction in TDR for critical business decisions.

3. Strategic Goals Achievement (SGA)
Objective: To ensure that organizational activities align with strategic goals.

KPI Definition: SGA will measure the percentage of predefined strategic objectives achieved.

Target: Achieve an 80% Strategic Goals Achievement rate within two years.

Conclusion
These three KPIs, Resource Utilization Efficiency (RUE), Time-to-Decision Reduction (TDR), and Strategic Goals Achievement (SGA), will serve as crucial metrics for evaluating the success of the S.M.A.R.T.E.R. Initiative. By tracking these KPIs and working towards their targets, we aim to drive efficiency, optimize resource utilization, and align our actions with our strategic objectives. This focus on measurable outcomes will guide our efforts towards achieving excellence within our organization.""",
"title": "Project KPIs", "date": datetime.strptime("2024-01-16", "%Y-%m-%d")}
     &lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H3 id="Chunk-the-texts"&gt;Chunk the texts&lt;/H3&gt;
&lt;P&gt;Typically, when using a vector database for retrieval-augmented generation (RAG) tasks, we break the texts apart into smaller (and sometimes overlapping) chunks to return focused and relevant information without returning an excessive amount of text.&lt;/P&gt;
&lt;P&gt;In the code below, we break the sample texts above into shorter overlapping text chunks.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline"&gt;
&lt;DIV class="cm-editor cm-s-jupyter language-python hljs"&gt;&lt;LI-CODE lang="python"&gt;import re

def chunk_text(text, chunk_size, overlap):
    words = text.split()
    chunks = []
    index = 0

    while index &amp;lt; len(words):
        end = index + chunk_size
        while end &amp;lt; len(words) and not re.match(r'.*[.!?]\s*$', words[end]):
            end += 1
        chunk = ' '.join(words[index:end+1])
        chunks.append(chunk)
        index += chunk_size - overlap

    return chunks

chunks = []
documents = [smarter_overview, smarter_kpis]

for document in documents:
    for i, c in enumerate(chunk_text(document["text"], 150, 25)):
        chunk = {}
        chunk["text"] = c
        chunk["title"] = document["title"]
        chunk["date"] = document["date"]
        chunk["id"] = document["title"] + "_" + str(i)

        chunks.append(chunk)&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&lt;SPAN&gt;Insert the text chunks into the source delta table&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;P&gt;Now we save the chunks, along with some metadata (a document title, date, and a unique id) to the source delta table.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline"&gt;
&lt;DIV class="cm-editor cm-s-jupyter language-python hljs"&gt;&lt;LI-CODE lang="python"&gt;from pyspark.sql.types import StructType, StructField, StringType, ArrayType, FloatType, DateType

schema = StructType(
    [
        StructField("id", StringType(), True),
        StructField("text", StringType(), True),
        StructField("title", StringType(), True),
        StructField("date", DateType(), True),
    ]
)

if chunks:
    result_df = spark.createDataFrame(chunks, schema=schema)
    result_df.write.format("delta").mode("append").saveAsTable(
        SOURCE_TABLE_FULLNAME
    )
     &lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H2 id="Sync-the-Vector-Search-Index"&gt;Sync the Vector Search Index&lt;/H2&gt;
&lt;P&gt;Because we specified&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;pipeline_type="TRIGGERED"&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;when configuring the Delta Index, we still need to manually tell the index to sync with the delta table. This will take a few minutes.&lt;/P&gt;
&lt;P&gt;This will not work if the index is not ready yet. We use the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;wait_until_ready&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;method to wait until the index is ready.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline"&gt;
&lt;DIV class="cm-editor cm-s-jupyter language-python hljs"&gt;&lt;LI-CODE lang="python"&gt;In [ ]:
# Sync 

index = vsc.get_index(endpoint_name=VS_ENDPOINT_NAME, index_name=VS_INDEX_FULLNAME) index.sync()&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H2 id="Query-the-Vector-Index"&gt;Query the Vector Index&lt;/H2&gt;
&lt;P&gt;Now that we have added our text chunks to the source delta table and synced it with the Vector Search index, we're ready to query the index! We do this with the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;index.similarity_search()&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;method.&lt;/P&gt;
&lt;P&gt;The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;columns&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;argument takes a list of the columns we want returned; in this case, we request the text and title columns.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;NOTE&lt;/STRONG&gt;: If the cell below does not return any results, wait a couple of minutes and try again. The index may still be syncing.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&lt;LI-CODE lang="python"&gt;In [ ]:
# query

 index.similarity_search(columns=["text", "title"], query_text="What is the TDR Target for the SMARTER initiative?", num_results = 3)&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline"&gt;
&lt;DIV class="cm-editor cm-s-jupyter language-python hljs"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H2 id="Answering-Questions-about-the-Output"&gt;Answering Questions about the Output&lt;/H2&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline"&gt;
&lt;DIV class="cm-editor cm-s-jupyter language-python hljs"&gt;&lt;LI-CODE lang="python"&gt;from databricks_genai_inference import ChatSession

chat = ChatSession(model="databricks-meta-llama-3-70b-instruct",
                   system_message="You are a helpful assistant.",
                   max_tokens=128)&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&lt;SPAN&gt;First, let's ask a question&lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;EM style="color: #1b3139; font-family: inherit;"&gt;without&lt;/EM&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;RAG.&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-CodeMirrorEditor jp-Editor jp-InputArea-editor" data-type="inline"&gt;
&lt;DIV class="cm-editor cm-s-jupyter language-python hljs"&gt;&lt;LI-CODE lang="python"&gt;chat.reply("What is the TDR Target for the SMARTER initiative?")
chat.last&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&lt;SPAN&gt;As you can see, its response has nothing to do with the documents we processed above.&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;P&gt;Now let's see what kind of reply we get when we provide context from vector search.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-CodeCell jp-Notebook-cell jp-mod-noOutputs"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&lt;LI-CODE lang="python"&gt;# reset history
chat = ChatSession(model="databricks-meta-llama-3-70b-instruct",
                   system_message="You are a helpful assistant. Answer the user's question based on the provided context.",
                   max_tokens=128)

# get context from vector search
raw_context = index.similarity_search(columns=["text", "title"],
                        query_text="What is the TDR Target for the SMARTER initiative?",
                        num_results = 3)

context_string = "Context:\n\n"

for (i,doc) in enumerate(raw_context.get('result').get('data_array')):
    context_string += f"Retrieved context {i+1}:\n"
    context_string += doc[0]
    context_string += "\n\n"

chat.reply(f"User question: What is the TDR Target for the SMARTER initiative?\n\nContext: {context_string}")
chat.last&lt;/LI-CODE&gt;&lt;/DIV&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;P&gt;It is now able to answer based on the provided context.&lt;/P&gt;
&lt;H3 id="Congratulations!-Demo-complete."&gt;Congratulations! Your chatbot is ready.&lt;/H3&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;DIV class="jp-Cell jp-MarkdownCell jp-Notebook-cell"&gt;
&lt;DIV class="jp-Cell-inputWrapper"&gt;
&lt;DIV class="jp-Collapser jp-InputCollapser jp-Cell-inputCollapser"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="jp-InputArea jp-Cell-inputArea"&gt;
&lt;DIV class="jp-InputPrompt jp-InputArea-prompt"&gt;&lt;SPAN&gt;Additional information&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV class="jp-RenderedHTMLCommon jp-RenderedMarkdown jp-MarkdownOutput" data-mime-type="text/markdown"&gt;
&lt;H2 id="Using-the-UI"&gt;Using the UI&lt;/H2&gt;
&lt;P&gt;Most of the Vector Database management steps above can be done via the UI: you can&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/generative-ai/create-query-vector-search.html#create-a-vector-search-endpoint-using-the-ui" target="_blank" rel="noopener"&gt;create an endpoint&lt;/A&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/generative-ai/create-query-vector-search.html#create-index-using-the-ui" target="_blank" rel="noopener"&gt;create an index&lt;/A&gt;, sync the index, and more via the UI in the Databricks Catalog Explorer.&lt;/P&gt;
&lt;H2 id="Experimenting-in-the-AI-Playground"&gt;Experimenting in the AI Playground&lt;/H2&gt;
&lt;P&gt;The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/large-language-models/ai-playground.html" target="_blank" rel="noopener"&gt;Databricks AI Playground&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;provides a GUI for quickly experimenting with LLMs available via the FMAPI, enabling you to compare the outputs of those models and determine which model best serves your needs.&lt;/P&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;</description>
      <pubDate>Thu, 15 Aug 2024 17:53:44 GMT</pubDate>
      <guid>https://community.databricks.com/t5/get-started-guides/getting-started-with-databricks-deploy-an-llm-chatbot-using/ta-p/80764</guid>
      <dc:creator>DatabricksGuide</dc:creator>
      <dc:date>2024-08-15T17:53:44Z</dc:date>
    </item>
    <item>
      <title>Re: Getting started with Databricks - Deploy an LLM chatbot using Databricks Vector Search and Found</title>
      <link>https://community.databricks.com/t5/get-started-guides/getting-started-with-databricks-deploy-an-llm-chatbot-using/tac-p/117818#M16</link>
      <description>&lt;P&gt;Can we run this tutorial from a DataBricks Community account?&lt;/P&gt;&lt;P&gt;For example, I cannot find anything related to Unity Catalog and Vector in my community account.&lt;/P&gt;</description>
      <pubDate>Tue, 06 May 2025 07:50:28 GMT</pubDate>
      <guid>https://community.databricks.com/t5/get-started-guides/getting-started-with-databricks-deploy-an-llm-chatbot-using/tac-p/117818#M16</guid>
      <dc:creator>cchui</dc:creator>
      <dc:date>2025-05-06T07:50:28Z</dc:date>
    </item>
    <item>
      <title>Re: Getting started with Databricks - Deploy an LLM chatbot using Databricks Vector Search and Found</title>
      <link>https://community.databricks.com/t5/get-started-guides/getting-started-with-databricks-deploy-an-llm-chatbot-using/tac-p/118264#M17</link>
      <description>&lt;P&gt;If you want to try UC and Vector Search, you will need a paid Databricks workspace with UC enabled and proper compute access. See docs here&amp;nbsp;&lt;A href="https://docs.databricks.com/aws/en/data-governance/unity-catalog/get-started" target="_blank"&gt;https://docs.databricks.com/aws/en/data-governance/unity-catalog/get-started&lt;/A&gt;.&lt;/P&gt;</description>
      <pubDate>Wed, 07 May 2025 16:34:43 GMT</pubDate>
      <guid>https://community.databricks.com/t5/get-started-guides/getting-started-with-databricks-deploy-an-llm-chatbot-using/tac-p/118264#M17</guid>
      <dc:creator>sarahbhord</dc:creator>
      <dc:date>2025-05-07T16:34:43Z</dc:date>
    </item>
    <item>
      <title>Re: Getting started with Databricks - Deploy an LLM chatbot using Databricks Vector Search and Found</title>
      <link>https://community.databricks.com/t5/get-started-guides/getting-started-with-databricks-deploy-an-llm-chatbot-using/tac-p/125971#M21</link>
      <description>&lt;P&gt;Is there an updated version of this LLM Chatbot tutorial that brings in multi-agentic MCP or other trending tools?&lt;/P&gt;</description>
      <pubDate>Tue, 22 Jul 2025 09:34:52 GMT</pubDate>
      <guid>https://community.databricks.com/t5/get-started-guides/getting-started-with-databricks-deploy-an-llm-chatbot-using/tac-p/125971#M21</guid>
      <dc:creator>normk-sd</dc:creator>
      <dc:date>2025-07-22T09:34:52Z</dc:date>
    </item>
    <item>
      <title>Re: Getting started with Databricks - Deploy an LLM chatbot using Databricks Vector Search and Found</title>
      <link>https://community.databricks.com/t5/get-started-guides/getting-started-with-databricks-deploy-an-llm-chatbot-using/tac-p/140317#M30</link>
      <description>&lt;P&gt;&lt;SPAN&gt;Hi&amp;nbsp;&lt;A target="_blank" rel="noopener"&gt;@normk-sd&lt;/A&gt;&amp;nbsp;, Not sure what your exact requirements are, but we have a bunch of new notebooks around MCP and multi-agent systems.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;LangGraph/OpenAI MCP tool-calling agent:&lt;/P&gt;
&lt;P&gt;&lt;A href="https://docs.databricks.com/aws/en/generative-ai/mcp/managed-mcp" target="_blank"&gt;https://docs.databricks.com/aws/en/generative-ai/mcp/managed-mcp&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Multi-agent system with Genie:&lt;/P&gt;
&lt;P&gt;&lt;A href="https://docs.databricks.com/aws/en/notebooks/source/generative-ai/langgraph-multiagent-genie.html" target="_blank"&gt;https://docs.databricks.com/aws/en/notebooks/source/generative-ai/langgraph-multiagent-genie.html&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Multi-agent Supervisor:&lt;/P&gt;
&lt;P&gt;&lt;A href="https://docs.databricks.com/aws/en/generative-ai/agent-bricks/multi-agent-supervisor" target="_blank"&gt;https://docs.databricks.com/aws/en/generative-ai/agent-bricks/multi-agent-supervisor&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;See if either of these helps!&lt;/P&gt;</description>
      <pubDate>Tue, 25 Nov 2025 14:15:17 GMT</pubDate>
      <guid>https://community.databricks.com/t5/get-started-guides/getting-started-with-databricks-deploy-an-llm-chatbot-using/tac-p/140317#M30</guid>
      <dc:creator>KaushalVachhani</dc:creator>
      <dc:date>2025-11-25T14:15:17Z</dc:date>
    </item>
    <item>
      <title>Re: Getting started with Databricks - Deploy an LLM chatbot using Databricks Vector Search and Found</title>
      <link>https://community.databricks.com/t5/get-started-guides/getting-started-with-databricks-deploy-an-llm-chatbot-using/tac-p/152741#M34</link>
      <description>&lt;P&gt;Excellent use case with Vector search - Use this latest model =&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;model&lt;/SPAN&gt;&lt;SPAN&gt;=&lt;/SPAN&gt;&lt;SPAN&gt;"databricks-meta-llama-3-3-70b-instruct"&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/DIV&gt;</description>
      <pubDate>Tue, 31 Mar 2026 14:39:56 GMT</pubDate>
      <guid>https://community.databricks.com/t5/get-started-guides/getting-started-with-databricks-deploy-an-llm-chatbot-using/tac-p/152741#M34</guid>
      <dc:creator>Naveed</dc:creator>
      <dc:date>2026-03-31T14:39:56Z</dc:date>
    </item>
  </channel>
</rss>

