Spaces:
Sleeping
Sleeping
| import os | |
| import gradio as gr | |
| import requests | |
| # API Keys (via Hugging Face Secrets) | |
| WEAVIATE_API_KEY = os.getenv("WEAVIATE_APIKEY") | |
| VLAM_API_KEY = os.getenv("VLAM_APIKEY") | |
| # Weaviate Config | |
| WEAVIATE_URL = "https://k6hr14w1r8gwkdctkxha.c0.europe-west3.gcp.weaviate.cloud/v1/graphql" | |
| HEADERS = {"Authorization": f"Bearer {WEAVIATE_API_KEY}", "Content-Type": "application/json"} | |
| def fetch_relevant_docs(user_query): | |
| # Probeer eerst met nearText (semantische zoekopdracht) | |
| neartext_query = { | |
| "query": f""" | |
| {{ | |
| Get {{ | |
| DigiDDocument( | |
| nearText: {{ concepts: ["{user_query}"] }}, | |
| limit: 3 | |
| ) {{ | |
| title | |
| content | |
| }} | |
| }} | |
| }} | |
| """ | |
| } | |
| response = requests.post(WEAVIATE_URL, json=neartext_query, headers=HEADERS) | |
| if response.status_code == 200: | |
| data = response.json() | |
| documents = data.get("data", {}).get("Get", {}).get("DigiDDocument", []) | |
| if documents: | |
| return "\n\n".join([f"{doc['content']}" for doc in documents]) | |
| # Als nearText niets vindt, probeer met BM25 (keyword-zoekopdracht) | |
| bm25_query = { | |
| "query": f""" | |
| {{ | |
| Get {{ | |
| DigiDDocument( | |
| bm25: {{ query: "{user_query}" }}, | |
| limit: 3 | |
| ) {{ | |
| title | |
| content | |
| }} | |
| }} | |
| }} | |
| """ | |
| } | |
| response = requests.post(WEAVIATE_URL, json=bm25_query, headers=HEADERS) | |
| if response.status_code == 200: | |
| data = response.json() | |
| documents = data.get("data", {}).get("Get", {}).get("DigiDDocument", []) | |
| if documents: | |
| return "\n\n".join([f"{doc['content']}" for doc in documents]) | |
| # Als beide queries niets vinden | |
| return None | |
| def generate_answer(vraag, history=[]): | |
| # Voeg de laatste 2 berichten uit de gespreksgeschiedenis toe aan de context | |
| history_text = "" | |
| if history: | |
| history_text = "\n".join( | |
| [f"Gebruiker: {user_msg}\nAssistent: {bot_msg}" | |
| for user_msg, bot_msg in history[-2:]] # Laatste 2 berichten | |
| ) | |
| context = fetch_relevant_docs(vraag) | |
| if not context: | |
| return "Ik kan geen relevante documentatie vinden over EVA of DigiD-aansluiting. Misschien kan ik u helpen met een gerelateerd onderwerp? Bijvoorbeeld: 'Hoe werkt het aansluiten van DigiD via EVA?'" | |
| messages = [ | |
| {"role": "system", "content": f""" | |
| ### Rol en Doel | |
| Je bent **De Aansluitassistent voor EVA en DigiD**, een **deskundige en behulpzame** assistent voor organisaties die DigiD aansluiten via EVA. | |
| ### Antwoordstijl voor Checklists en Stappenplannen | |
| - Als de gebruiker vraagt om een **checklist, stappenplan of eisenlijst**: | |
| 1. **Bevestig kort** dat de checklist beschikbaar is. | |
| 2. **Noem de 2-3 belangrijkste punten** (als voorproefje). | |
| 3. **Verwijs naar de volledige checklist** met een link (indien beschikbaar) of bied aan om deze te delen. | |
| 4. **Sluit af met een vervolgvraag** over een specifiek onderdeel. | |
| **Voorbeeldantwoord voor een checklistvraag:** | |
| *"Ja, er is een checklist voor [onderwerp]. De belangrijkste punten zijn: | |
| - [Punt 1] | |
| - [Punt 2] | |
| - [Punt 3] | |
| **Volledige checklist:** [Link naar checklist] of [Toolkit DigiD](https://www.digid.nl/toolkit). | |
| **Vervolgvraag:** Wilt u hulp bij een specifiek criterium, zoals [onderdeel]?"* | |
| ### Gesprekscontext (gebruik deze om je antwoord te vormen): | |
| {history_text} | |
| ### Instructies: | |
| - **Alleen antwoorden op basis van de onderstaande context EN de gesprekscontext.** | |
| - **Verwijs naar eerdere antwoorden** als de gebruiker daarnaar verwijst. | |
| - **Stel vervolgvragen die natuurlijk voortvloeien uit het gesprek en de context.** | |
| ### Antwoordstijl | |
| - **Zakelijk, maar vriendelijk, betrokken en enthousiasmerend. Eenvoudig taalgebruik.** | |
| - Gebruik "u" en "uw". | |
| - Toon begrip voor de situatie van de gebruiker (bijv. *"Dat is een belangrijke stap, ik help u graag verder."*). | |
| - **Structuur:** | |
| 1. Beantwoord de **hoofdvraag** met **maximaal 3 kernpunten** (bulletpoints of alinea's). | |
| 2. **Sluit af met 1 of 2 vervolgvragen** die **direct aansluiten op het antwoord en de context**. | |
| ### Gedragsregels | |
| 1. **Als de vraag buiten de scope valt:** | |
| *"Ik help graag met technische en procedurele vragen over EVA en DigiD. Voor [onderwerp] kunt u terecht bij [bron]. Laat me weten als u hulp nodig heeft met iets anders binnen EVA/DigiD!"* | |
| 2. **Als er geen context is:** | |
| *"Ik kan helaas geen relevante informatie vinden over [onderwerp] in de EVA/DigiD-documentatie. Misschien kan ik u helpen met een gerelateerd onderwerp? Bijvoorbeeld: [noem een relevant onderwerp uit de context].* | |
| 3. **Als de context onduidelijk is:** | |
| *"Kunt u uw vraag wat specifieker maken? Dan kan ik u beter helpen. Bijvoorbeeld: [geef een voorbeeldvraag die aansluit op de context]."* | |
| ### Voorbeelden van Goede Vervolgvragen | |
| - Als de gebruiker vraagt over **Metadata**: | |
| *"Heeft u al een PKIOverheid Certificaat? Dan kan ik u helpen met de volgende stappen."* | |
| - Als de gebruiker vraagt over **foutmeldingen**: | |
| *"Kunt u de specifieke foutmelding delen? Dan kan ik u gerichter helpen."* | |
| ### Context (gebruik ALLEEN deze informatie + de gesprekscontext): | |
| {context} | |
| """}, | |
| {"role": "user", "content": vraag} | |
| ] | |
| response = requests.post( | |
| "https://api.demo.vlam.ai/v2.1/projects/poc/openai-compatible/v1/chat/completions", | |
| headers={"Authorization": f"Bearer {VLAM_API_KEY}"}, | |
| json={ | |
| "model": "ubiops-deployment/logius-pc-mistralmedium-flexibel//chat-model", | |
| "messages": messages, | |
| "max_tokens": 1000, | |
| "temperature": 0.3 | |
| } | |
| ) | |
| full_answer = response.json()["choices"][0]["message"]["content"] | |
| # Alleen afkappen als het antwoord te lang is | |
| words = full_answer.split() | |
| if len(words) > 300: | |
| truncated = ' '.join(words[:300]) | |
| if not any(punct in truncated[-10:] for punct in ["?", "!"]): | |
| truncated += "\n\nLaat me weten als u hier meer over wilt weten of hulp nodig heeft met een gerelateerd onderwerp!" | |
| return truncated | |
| return full_answer | |
| # Gradio Interface met gespreksgeschiedenis | |
| demo = gr.ChatInterface( | |
| generate_answer, | |
| title="EVA/DigiD Aansluitassistent", | |
| description="Stel vragen over het aansluiten van DigiD via EVA. De chat onthoudt de context binnen deze sessie." | |
| ) | |
| demo.launch() |