Spaces:
Runtime error
Runtime error
| 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( | |
| """ | |
|  | |
| # 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) | |