<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sathish Panthagani</title>
    <description>The latest articles on DEV Community by Sathish Panthagani (@sathish_panthagani).</description>
    <link>https://dev.to/sathish_panthagani</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2656713%2F0ff56836-a8ee-48e8-9b67-c99f7ebe4828.jpg</url>
      <title>DEV Community: Sathish Panthagani</title>
      <link>https://dev.to/sathish_panthagani</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sathish_panthagani"/>
    <language>en</language>
    <item>
      <title>Build a Document QA generator with Langchain and Streamlit</title>
      <dc:creator>Sathish Panthagani</dc:creator>
      <pubDate>Wed, 22 Jan 2025 05:15:56 +0000</pubDate>
      <link>https://dev.to/sathish_panthagani/build-a-document-qa-generator-with-langchain-and-streamlit-1di0</link>
      <guid>https://dev.to/sathish_panthagani/build-a-document-qa-generator-with-langchain-and-streamlit-1di0</guid>
      <description>&lt;p&gt;In this post, I will be explaining about &lt;code&gt;with_structured_output&lt;/code&gt; api of langchain, which helps to output the response in the predefined output model.&lt;/p&gt;

&lt;p&gt;At the end of this blog, we will be building a tool which generates a multiple choice questions along answers from the PDF uploaded. I find it is easy to host the solution on streamlit, it has one click deployment hosted on their community cloud and it is Free.&lt;/p&gt;

&lt;p&gt;The demo app can be found &lt;a href="https://st-gen-ai-apps.streamlit.app/Questionaire_generator" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-requisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Groq API key to access LLM models - you can get one from &lt;a href="https://console.groq.com/keys" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Streamlit account to host the application&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Python experience&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Langchain - used to integrate LLM models&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;fitz - used to read the pdf file contents&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create a python virtual environment using venv with below command, read more about venv here
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;$ python -m venv .venv&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;activate virtual environment with below command
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;$ source &amp;lt;venv&amp;gt;/bin/activate&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a file requirements.txt with below packages.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;streamlit
streamlit-feedback
langchain
langchain-community
langchain-groq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Run pip install command to install the required packages.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;pip install -r requirements.txt&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;


&lt;h2&gt;
  
  
  Build Streamlit app
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create a file main.py and setup the basic streamlit app with below content
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import streamlit as st
st.set_page_config(
    page_title="Document Questionnaire generator",
    page_icon="📚",
    layout="centered",
    initial_sidebar_state="auto",
)
st.title('Document Questionnaire generator')
st.caption("🚀 A Streamlit chatbot powered by Groq")
st.write('Generate multiple choice questionnaire from a pdf file uploaded')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Save file and run below command to run the streamlit app.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;streamlit run main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;The application automatically opens in browser window at
&lt;a href="http://localhost:8501/" rel="noopener noreferrer"&gt;http://localhost:8501/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  initial streamlit app
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Now add file upload control from streamlit to enable upload pdf feature.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;file_bytes = st.file_uploader("Upload a PDF file", type=["pdf"])
Read the uploaded file and store the text content which we need to feed to LLM

import fitz

# Read the PDF
pages = []
pdf_document = fitz.open(stream=file_stream, filetype="pdf")
for page_num in range(len(pdf_document)):
    page = pdf_document.load_page(page_num)
    pages.append(page)

TEXT_CONTENT = " ".join(d.get_text() for d in pages)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Build LLM Model to generate question
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Now we have the text content read from the pdf file, so we can go ahead with building LLM to generate Question answers from a prompt.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;add below prompt to generate question and answers, we can also ask for number of questions generated.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# system prompt to generate questions
SYSTEM_PROMT =  """Generate {questions_count} multiple choice questions from the following text:
'''
{context}
'''
"""

SYSTEM_PROMT_FRMTD = SYSTEM_PROMT.format(context=TEXT_CONTENT, questions_count=NUM_QUESTIONS)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Invoke the LLM model from Groq,
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from langchain_groq import ChatGroq

# Create a model
llm = ChatGroq(model="llama-3.1-70b-versatile", temperature=0, max_retries=2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Since we would need a questions with answers we will be using &lt;strong&gt;with_structured_output&lt;/strong&gt; api from langchain, this will output the results in a predefined structure so that it can be used for building an app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define the structure of the output model&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# TypedDict
class MCQuestion(TypedDict):
    """Multiple choice question."""
    text: Annotated[str, ..., "The text of the question"]
    options: Annotated[list[str], ..., "The options for the question"]
    answer: Annotated[Optional[int], None, "the answer for the question from the options"]

class MultipleQuestion(TypedDict):
    """List of multiple choice questions."""
    questions: Annotated[list[MCQuestion], ..., "List of multiple choice questions"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;And then invoke LLM model with the text content from PDF.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Cache the data so that it wont trigger the model to generate questions again
@st.cache_data
def call_llm(content: str) -&amp;gt; dict:
    """Call the model to generate questions."""
    # Generate questions
    structured_llm = llm.with_structured_output(MultipleQuestion)
    return structured_llm.invoke([SystemMessage(content=content)])


response = call_llm(SYSTEM_PROMT_FRMTD)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;store questions to streamlit session state as streamlit run entire code for every change and we might lost the data.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;st.session_state.questions = response.get("questions")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Once the questions are received from LLM output it can be presented in a multiple choice to the user and we can restrict user only after answering the question, once all questions are answered we can show a congratulations message.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for question in st.session_state.questions:
    answer_selected = st.radio(
        options=question.get("options"),
        label=question.get("text"),
        index=None)

    if not answer_selected:
        st.text('Please select an answer')
        st.stop()
    else:
        if question.get('options')[question.get('answer')] == answer_selected:
            st.text(f"✅ Correct! The answer is {answer_selected}")
        else:
            st.text('❌ Incorrect answer, please try again')
            st.stop()

st.balloons()
st.success('Congratulations! You have completed the questionnaire', icon="✔")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Once it tested working, you can push the code changes to GitHub.&lt;/p&gt;

&lt;p&gt;In Streamlit, you have an option to deploy them by selecting the repository from GitHub and the starter file. Read more about Streamlit &lt;a href="https://docs.streamlit.io/deploy/streamlit-community-cloud/deploy-your-app" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading and hope you enjoyed the article. You can find the code from Github which i have used in this article.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/sathish39893" rel="noopener noreferrer"&gt;
        sathish39893
      &lt;/a&gt; / &lt;a href="https://github.com/sathish39893/streamlit-apps" rel="noopener noreferrer"&gt;
        streamlit-apps
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      streamlit apps built using generative ai llms
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;streamlit-apps&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;streamlit apps built using generative ai llms&lt;/p&gt;

&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sathish39893/streamlit-apps" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>llm</category>
      <category>langchain</category>
      <category>streamlit</category>
    </item>
    <item>
      <title>Building a React.dev RAG chatbot using Vercel AI SDK</title>
      <dc:creator>Sathish Panthagani</dc:creator>
      <pubDate>Sun, 05 Jan 2025 19:12:42 +0000</pubDate>
      <link>https://dev.to/sathish_panthagani/building-a-reactdev-rag-chatbot-using-vercel-ai-sdk-4af1</link>
      <guid>https://dev.to/sathish_panthagani/building-a-reactdev-rag-chatbot-using-vercel-ai-sdk-4af1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this blog post, I'll share my journey of building a React.dev AI assistant which retrieves the info from react.dev website, and answers the prompt provided by the user. The main goal is to use the information available in &lt;a href="https://react.dev" rel="noopener noreferrer"&gt;react.dev&lt;/a&gt; website as knowledge base of the assistant. &lt;/p&gt;

&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js&lt;/strong&gt;: A React-based framework for server-side rendering and routing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ChatGPT&lt;/strong&gt;: A popular generative AI LLM used for the assistant&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vercel AI SDK&lt;/strong&gt;: The AI SDK is the TypeScript toolkit designed to help developers build AI-powered applications, follow more from their documentation &lt;a href="https://sdk.vercel.ai/docs/introduction" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supabase&lt;/strong&gt;: A Postgres database to store vector embeddings with pgvector extension.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind CSS&lt;/strong&gt;: A utility-first CSS framework that provides flexibility while keeping the UI clean and customisable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drizzle ORM&lt;/strong&gt;: This library provides utilities to interact with DB and run vector similarity search against vector db.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Prerequisites:
&lt;/h2&gt;

&lt;p&gt;This project requires below prerequisites to setup.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Supabase Database with Pgvector extension enabled - this will be used to store vector embeddings of the website content.&lt;/li&gt;
&lt;li&gt;Open AI API key - if you dont have an OpenAI API key - get one from &lt;a href="https://platform.openai.com/settings/organization/api-keys" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please follow this &lt;a href="https://supabase.com/docs/guides/database/extensions/pgvector?queryGroups=database-method&amp;amp;database-method=dashboard" rel="noopener noreferrer"&gt;link&lt;/a&gt; to enable pgvector extension for the database provisioned in supabase.&lt;/p&gt;




&lt;h2&gt;
  
  
  Project setup
&lt;/h2&gt;

&lt;p&gt;This project consists of &lt;strong&gt;Next.js&lt;/strong&gt;, &lt;strong&gt;Supabase&lt;/strong&gt;, and &lt;strong&gt;Tailwind CSS&lt;/strong&gt; as frontend UI, &lt;strong&gt;Vercel ai&lt;/strong&gt; as backend chat integration with OpenAI API. It uses &lt;strong&gt;cheerio&lt;/strong&gt; to scrap webpages and stores the embeddings in supabase pgvector database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating NextJS Project
&lt;/h3&gt;

&lt;p&gt;You can easily setup NextJS project by running following command or follow the instructions from NextJS from the (link)[&lt;a href="https://nextjs.org/docs/app/getting-started/installation" rel="noopener noreferrer"&gt;https://nextjs.org/docs/app/getting-started/installation&lt;/a&gt;]&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Follow the screen instructions and it will create a NextJS project with basic setup.&lt;/p&gt;
&lt;h3&gt;
  
  
  Installing required libraries
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @ai-sdk/openai ai drizzle-orm drizzle-zod zod @langchain/community
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Environment configuration
&lt;/h3&gt;

&lt;p&gt;Create a .env file in the root directory of your project to manage variables used in the project.&lt;/p&gt;

&lt;p&gt;Add the following variables, replacing the placeholders with the actual keys.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .env

OPENAI_API_KEY=YOUR_OPENAI_API_KEY
DATABASE_URL=YOUR_SUPABASE_DATABASE_URL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  RAG implementation
&lt;/h2&gt;

&lt;p&gt;The assistant is based on Retrieval-Augmented Generation(RAG) which uses knowledge base based on the content from react.dev website. You can read more about RAG (here)[&lt;a href="https://sdk.vercel.ai/docs/guides/rag-chatbot#what-is-rag" rel="noopener noreferrer"&gt;https://sdk.vercel.ai/docs/guides/rag-chatbot#what-is-rag&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;: get the website content scrapped using &lt;code&gt;cheerio&lt;/code&gt; plugin. The following code demonstrate the url as input and returns document content scrapped from the website.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'cheerio';
import { CheerioWebBaseLoader } from '@langchain/community/document_loaders/web/cheerio';
...
const pTagSelector = 'p';
const cheerioLoader = new CheerioWebBaseLoader(url, {
    selector: pTagSelector,
  });
const docs = await cheerioLoader.load();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;: Split the website content into multiple chunks so that embeddings can be generated easily with shorter text.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { RecursiveCharacterTextSplitter } from '@langchain/textsplitters';
...
const splitter = new RecursiveCharacterTextSplitter({
    chunkSize: 2000,
    chunkOverlap: 100,
  });
const allSplits = await splitter.splitDocuments(docs);
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;: generate the embeddings for each of the chunk and store them in vector db, so that it can be used to query from chat api.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const dbResult = await createResources(
    allSplits.map((doc) =&amp;gt; ({
      content: doc.pageContent,
      source: doc.metadata.source,
    }))
  );

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// actions/resources.ts
import { embed, embedMany } from 'ai';
import { openai } from '@ai-sdk/openai';

const embeddingModel = openai.embedding('text-embedding-ada-002');

export const generateEmbedding = async (value: string): Promise&amp;lt;number[]&amp;gt; =&amp;gt; {
  const input = value.replaceAll('\\n', ' ');
  const { embedding } = await embed({
    model: embeddingModel,
    value: input,
  });
  return embedding;
};

export const createResources = async (values: NewResourceParams[]) =&amp;gt; {
  try {
    for (const input of values) {
      const { content, source } = insertResourceSchema.parse(input);

      const embedding = await generateEmbedding(content);
      await db.insert(resources).values({
        content,
        source,
        embedding,
      });
    }

    return 'Resources successfully created and embedded.';
  } catch (error) {
    return error instanceof Error &amp;amp;&amp;amp; error.message.length &amp;gt; 0
      ? error.message
      : 'Error, please try again.';
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Chat API implementation
&lt;/h2&gt;

&lt;p&gt;once the knowledge base is built with react.dev website links, the document information get stored in supabase table. Using AI SDK, chat api can be implemented based their documentation available &lt;a href="https://sdk.vercel.ai/docs/guides/rag-chatbot#create-api-route" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;following is the sample code to stream text from server:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = streamText({
    model: openai('gpt-4o'),
    messages,
    system: `You are a helpful assistant. Check your knowledge base before answering any questions.
    Only respond to questions using information from tool calls.
    if no relevant information is found in the tool calls, respond, "Sorry, I don't know."`,
    tools: {
      getInformation: tool({
        description: `get information from your knowledge base to answer questions.`,
        parameters: z.object({
          question: z.string().describe('the users question'),
        }),
        execute: async ({ question }) =&amp;gt; findRelevantContent(question),
      }),
    },
  });

  return result.toDataStreamResponse();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;With the above Prompt, model will always looks for the knowledge base   and triggers the tool &lt;code&gt;getInformation&lt;/code&gt; which in turns executes function &lt;code&gt;findRelevantContent&lt;/code&gt;. This function queries vector db and executes cosine similarity to find matches and returns the relevant context to LLM. LLM then use the knowledge base info and then generate response to the user query.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const findRelevantContent = async (userQuery: string) =&amp;gt; {
  const userQueryEmbedded = await generateEmbedding(userQuery);
  const similarity = sql&amp;lt;number&amp;gt;`1 - (${cosineDistance(
    resources.embedding,
    userQueryEmbedded,
  )})`;
  const similarGuides = await db
    .select({ name: resources.content, similarity })
    .from(resources)
    .where(gt(similarity, similarityThreshold))
    .orderBy(t =&amp;gt; desc(t.similarity))
    .limit(4);
  return similarGuides;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Chat UI implementation
&lt;/h2&gt;

&lt;p&gt;AI SDK has AI SDK UI which is framework-agnostic toolkit, streamlining the integration of advanced AI functionalities into your applications. It contains &lt;code&gt;useChat&lt;/code&gt; hook which helps to integrate chat api (create earlier) with less effort.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/app/page.tsx

...
const { messages, input, handleInputChange, handleSubmit, error } = useChat({
    maxSteps: 10,
  });
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Once UI part is implemented, it can be tested using any of the questions from react.dev website.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fynt846qo0gsg1aimn4ds.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fynt846qo0gsg1aimn4ds.png" alt="React Chatbot" width="800" height="853"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;AI SDK has multiple features to integrate LLM directly to any of the react application without much hassle. It has utilities to for frontend and backend which makes it unique and easy to integrate.&lt;/p&gt;

&lt;p&gt;In this guide, I have covered process of RAG implementation using AI SDK which will be helpful to create a knowledge base for any of the website.&lt;/p&gt;

&lt;p&gt;A fully functional example of this project is included at the end of this article.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/sathish39893" rel="noopener noreferrer"&gt;
        sathish39893
      &lt;/a&gt; / &lt;a href="https://github.com/sathish39893/react-docs-ai-app" rel="noopener noreferrer"&gt;
        react-docs-ai-app
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      react chat bot with RAG on react docs from react.dev website
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;React Docs Generative AI chatbot&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;This chatbot is a generative AI chatbot that can answer questions about React documentation using RAG (retrieval augmented generation) pipeline.&lt;/p&gt;

&lt;p&gt;It is built using Next.js ai sdk and cheerio for web scraping and langchain to split the text into sentences. It uses drizzle ORM to store the embeddings of the scraped data and uses the embeddings to generate answers to the questions asked by the user.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting Started&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;First, run the development server:&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm run dev
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; or&lt;/span&gt;
yarn dev
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; or&lt;/span&gt;
pnpm dev
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; or&lt;/span&gt;
bun dev&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Open &lt;a href="http://localhost:3000" rel="nofollow noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; with your browser to see the result.&lt;/p&gt;
&lt;p&gt;This project uses &lt;a href="https://nextjs.org/docs/app/building-your-application/optimizing/fonts" rel="nofollow noopener noreferrer"&gt;&lt;code&gt;next/font&lt;/code&gt;&lt;/a&gt; to automatically optimize and load &lt;a href="https://vercel.com/font" rel="nofollow noopener noreferrer"&gt;Geist&lt;/a&gt;, a new font family for Vercel.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;


&lt;ul&gt;

&lt;li&gt;

&lt;strong&gt;Generative AI Chatbot&lt;/strong&gt;: The chatbot is built using Vercel's AI SDK and can answer questions about React documentation.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;RAG (retrieval augmented generation) pipeline&lt;/strong&gt;: The chatbot uses cheerio to…&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sathish39893/react-docs-ai-app" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>rag</category>
      <category>llm</category>
      <category>nextjs</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
