Skip to content

You're working for a well-known car manufacturer who is looking at implementing LLMs into vehicles to provide guidance to drivers. You've been asked to experiment with integrating car manuals with an LLM to create a context-aware chatbot. They hope that this context-aware LLM can be hooked up to a text-to-speech software to read the model's response aloud.

As a proof of concept, you'll integrate several pages from a car manual that contains car warning messages and their meanings and recommended actions. This particular manual, stored as an HTML file, mg-zs-warning-messages.html, is from an MG ZS, a compact SUV. Armed with your newfound knowledge of LLMs and LangChain, you'll implement Retrieval Augmented Generation (RAG) to create the context-aware chatbot.

Before you start

In order to complete the project you will need to create a developer account with OpenAI and store your API key as a secure environment variable. Instructions for these steps are outlined below.

Create a developer account with OpenAI

  1. Go to the API signup page.

  2. Create your account (you'll need to provide your email address and your phone number).

  3. Go to the API keys page.

  4. Create a new secret key.

  1. Take a copy of it. (If you lose it, delete the key and create a new one.)

Add a payment method

OpenAI sometimes provides free credits for the API, but this can vary depending on geography. You may need to add debit/credit card details.

This project should cost much less than 1 US cents with gpt-4o-mini (but if you rerun tasks, you will be charged every time).

  1. Go to the Payment Methods page.

  2. Click Add payment method.

  1. Fill in your card details.

Add an environmental variable with your OpenAI key

  1. In the workbook, click on "Environment," in the top toolbar and select "Environment variables".

  2. Click "Add" to add environment variables.

  3. In the "Name" field, type "OPENAI_API_KEY". In the "Value" field, paste in your secret key.

  1. Click "Create", then you'll see the following pop-up window. Click "Connect," then wait 5-10 seconds for the kernel to restart, or restart it manually in the Run menu.
#Run this cell to install the necessary packages
import subprocess
import pkg_resources

def install_if_needed(package, version):
    '''Function to ensure that the libraries used are consistent to avoid errors.'''
    try:
        pkg = pkg_resources.get_distribution(package)
        if pkg.version != version:
            raise pkg_resources.VersionConflict(pkg, version)
    except (pkg_resources.DistributionNotFound, pkg_resources.VersionConflict):
        subprocess.check_call(["pip", "install", f"{package}=={version}"])

#install_if_needed("langchain-core", "0.3.18")
#install_if_needed("langchain-openai", "0.2.8")
#install_if_needed("langchain-community", "0.3.7")
#install_if_needed("unstructured", "0.14.4")
#install_if_needed("langchain-chroma", "0.1.4")
#install_if_needed("langchain-text-splitters", "0.3.2")
# Set your API key to a variable
import os
openai_api_key = os.environ["OPENAI_API_KEY"]

# Import the required packages
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_community.document_loaders import UnstructuredHTMLLoader
from langchain_openai import OpenAIEmbeddings
from langchain_core.runnables import RunnablePassthrough
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_chroma import Chroma
# Load the HTML as a LangChain document loader
loader = UnstructuredHTMLLoader(file_path="data/mg-zs-warning-messages.html")
car_docs = loader.load()
print(car_docs)
""" from Guides: How to approach the project
1. Split the document
2. Store the embeddings
3. Create a retriever
4. Initialize the LLM and prompt template
5. Define RAG chain
6. Invoke RAG chain
"""

#1 Split the document
# Define variables
chunk_size = 300
chunk_overlap = 100

# separators  defaults to ["\n\n", "\n", " ", ""]
# Split the HTML
splitter = RecursiveCharacterTextSplitter(
    chunk_size=chunk_size,
    chunk_overlap=chunk_overlap,
    separators=['.'])

docs = splitter.split_documents(car_docs)
print(docs)
#2 Store the embeddings - Embed and store the document chunks for retrieval

# Storing embeddings in a Chroma vector database
embedding_function = OpenAIEmbeddings(api_key=openai_api_key, model='text-embedding-3-small')

vectorstore = Chroma.from_documents(
    docs,
    embedding=embedding_function,
    persist_directory=os.getcwd()
)
#3 Create a retriever - Create a retriever to retrieve relevant documents from the vector store

# Create a Chroma retriever
retriever = vectorstore.as_retriever(
    search_type="similarity",
    search_kwargs={"k": 3}
)
#4 Initialize the LLM and prompt template - Define an LLM and create a prompt template to set up the RAG workflow

# Initialize LLM
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0, api_key=openai_api_key)	

# Define a chat prompt template
prompt_template = ChatPromptTemplate.from_template("You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.\nQuestion: {question} \nContext: {context} \nAnswer:")
#5 Define the RAG chain - Define RAG chain to connect to the retriever, question, prompt, and LLM

# Defining the RAG chain using LangChain Expression Language LCEL
rag_chain = ({"context": retriever, "question": RunnablePassthrough()}
            | prompt_template
            | llm)
#6 Invoke RAG chain - Invoke your chain with the user query to answer

# Assuming rag_chain is properly initialized and configured with the API key
user_query = "The Gasoline Particular Filter Full warning has appeared. What does this mean and what should I do about it?"

answer = rag_chain.invoke(user_query).content
print(answer)