I14YChatbot / app.py
floriane
version update
2ea2b3c
Raw
History Blame Contribute Delete
5.74 kB
from langchain.document_loaders import WebBaseLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.chat_models import ChatOpenAI
from langchain.chains import LLMChain
from dotenv import find_dotenv, load_dotenv
from langchain.prompts.chat import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
import gradio as gr
load_dotenv(find_dotenv())
embeddings = OpenAIEmbeddings()
import requests
from bs4 import BeautifulSoup
from urllib.parse import urlparse, urljoin
def extract_subdomain_urls(subdomain):
response = requests.get(subdomain)
# Parse the HTML content using BeautifulSoup
soup = BeautifulSoup(response.text, "html.parser")
# Extract all anchor tags (links) from the parsed HTML
anchors = soup.find_all("a")
# Extract and normalize the URLs within the subdomain
base_url = urlparse(subdomain).scheme + "://" + urlparse(subdomain).netloc
subdomain_urls = []
for anchor in anchors:
href = anchor.get("href")
if href:
url = urljoin(base_url, href)
if urlparse(url).netloc == urlparse(subdomain).netloc:
subdomain_urls.append(url)
return subdomain_urls
# Retrieve all pages from handbook
subdomain = "https://i14y-ch.github.io/handbook/de/"
urls = extract_subdomain_urls(subdomain)
# Use langchain WebBaseLoader to load the handbook, then split into pages to stay under GPT tokens usage threshold
loader = WebBaseLoader(urls)
loader.requests_per_second = 1
pages = loader.load_and_split()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
docs = text_splitter.split_documents(pages)
#Embed in a FAISS vectorspace
db = FAISS.from_documents(docs, embeddings)
#Define the function that creates a chat prompt given a user query
def get_response_from_query(query):
"""
gpt-3.5-turbo can handle up to 4097 tokens. Setting the chunksize to 1000 and k to 4 maximizes
the number of tokens to analyze.
"""
docs = db.similarity_search(query, k=4)
docs_page_content = " ".join([d.page_content for d in docs])
chat = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.0)
# System message prompt
template = """
The I14Y interoperability platform is the central directory of data, electronic interfaces and authority services in Switzerland.
You are a helpful assistant that answers questions about I14Y based on the platform handbook, of which {docs} is an extract.
Given a question from a user, you create a final answer based on the information in {docs}.
Whenever you have this information, you must cite the relevant section title of the handbook that you used in your answer.
If you don't have enough information to answer the question, politely state that you don't know. Do not make up answers.
If you don't understand the question, ask the user to reformulate it.
If the question is not about the I14Y interoperability platform, say that you only answer question about I14Y.
Ensure your answers are detailed, concise, and relevant, providing step-by-step instructions if needed.
You are very polite and always greet the user with "Grüezi".
At the end of your answer, ask politely the user if they need any further information.
Do not include references to platforms other than I14Y in your answers such as for example Geocat.
Answer in the language in which the question was asked.
I14Y stands for Interoperability. The user may call I14Y "IOP" but you should not use this name in your answer.
"""
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
# Human question prompt
human_template = "Answer the following question: {question}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages(
[system_message_prompt, human_message_prompt]
)
chain = LLMChain(llm=chat, prompt=chat_prompt)
response = chain.run(question=query, docs=docs_page_content)
return response
# Gradio Frontend
with gr.Blocks(title="I14Y Chatbot", theme=gr.themes.Default(font=gr.themes.GoogleFont("Roboto"), primary_hue="red",
secondary_hue="pink")) as demo:
gr.Markdown(
"""
![](https://huggingface.co/spaces/I14Y/I14YChatbot/resolve/main/i14ylogo.png)
# I14Y Chatbot
Beantwortet alle Fragen rund um die I14Y-Interoperabilitätsplattform.
""")
input = gr.Textbox(label="Frage mich etwas über die I14Y")
output = gr.Textbox(label="Antwort")
search_btn = gr.Button("Frage stellen")
search_btn.click(fn=get_response_from_query, inputs=input, outputs=output, api_name="Frage stellen")
gr.Markdown(
"""
## Hinweise:
1. You can speak to the I14Y Chatbot in other languages than German.
2. Es besteht die Möglichkeit, dass der I14Y Chatbot "halluziniert" und gelegentlich falsche Informationen liefert.
3. Der I14Y Chatbot basiert derzeit auf den Informationen aus dem offiziellen I14Y Handbuch. In Zukunft wird der I14Y Chatbot auch Fragen zu den auf I14Y publizierten Metadaten liefern können.
## Kontakt und Feedback:
Mail: i14y@bfs.admin.ch
Web: [i14y.admin.ch](https://www.i14y.admin.ch)
Newsletter: [Anmelden](https://www.bfs.admin.ch/bfs/de/home/dienstleistungen/fuer-medienschaffende/newsmail-abonnement.html)
""")
#Set True to create a public url
demo.launch(share=False)