Confluence: KI-Wissensdatenbank für Teams
Kompletter Leitfaden zur Bereitstellung eines RAG-Assistenten auf Confluence. Verwandeln Sie Ihre Atlassian-Dokumentation in eine von KI abfragbare Wissensdatenbank.
Confluence: KI-Wissensdatenbank für Teams
Confluence ist das Rückgrat der Unternehmensdokumentation im Atlassian-Ökosystem. Millionen von Teams nutzen es zur Zentralisierung von Prozessen, technischen Leitfäden und strategischen Entscheidungen. Doch mit der Zeit werden selbst die am besten organisierten Wikis zu Labyrinthen, in denen Informationen verloren gehen. Mitarbeiter verbringen durchschnittlich 20% ihrer Zeit mit der Suche nach Informationen, von denen sie wissen, dass sie irgendwo existieren.
Ein RAG-Assistent verwandelt diese Dokumentenmasse in eine Konversationsschnittstelle. Anstatt durch komplexe Baumstrukturen zu navigieren, stellen Ihre Teams ihre Fragen in natürlicher Sprache und erhalten synthetisierte Antworten mit Quellen. Dieser Leitfaden beschreibt die Integration von Confluence + RAG von A bis Z.
Das Confluence-Problem im großen Maßstab
Häufige Symptome
Nach einigen Jahren der Nutzung zeigt Confluence wiederkehrende Herausforderungen:
- "Ich weiß, dass es irgendwo existiert": Die Information ist da, aber unauffindbar
- Labyrinthische Navigation: Zu viele Spaces, Unterseiten, Hierarchien
- Veralteter Inhalt: Nicht gepflegte Seiten, die die Ergebnisse verschmutzen
- Duplikation: Gleiche Informationen in mehreren Spaces
- Schwieriges Onboarding: Neue Mitarbeiter verlieren sich in der Dokumentation
Aufschlussreiche Zahlen
| Metrik | Unternehmensdurchschnitt |
|---|---|
| Zeitaufwand für Suche | 20% der Arbeitszeit |
| Nie aufgerufene Seiten | 60% nach 6 Monaten |
| Wiederholte Support-Fragen | 40% stehen in der Doku |
| Zufriedenheit Confluence-Suche | 3,2/10 |
Native Suche vs. RAG
| Kriterium | Confluence-Suche | RAG-Suche |
|---|---|---|
| Anfragetyp | Exakte Stichwörter | Natürliche Sprache |
| Ergebnis | Seitenliste | Direkte Antwort |
| Multi-Seiten | Nein | Synthetisiert mehrere Quellen |
| Kontext | Keiner | Gesprächsverlauf |
| Formate | Nur Text | Text + Tabellen + Code |
| Relevanz | Aktualität > Relevanz | Semantische Relevanz |
Architektur Confluence + RAG
Die Integration basiert auf drei Säulen: Extraktion über die Confluence-API, Vektorindexierung und Konversationsschnittstelle.
┌─────────────────────────────────────────────────────────────────────────┐
│ Architecture Confluence + RAG │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ CONFLUENCE PROCESSING VECTOR DB │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────┐ │
│ │ Espaces │────────────▶│ Parsing │─────────▶│ Qdrant │ │
│ │ │ │ HTML→MD │ │ │ │
│ │ - IT │ └──────┬───────┘ │ HNSW │ │
│ │ - RH │ │ │ Index │ │
│ │ - Produit │ ┌──────┴───────┐ └─────┬─────┘ │
│ │ - Tech │ │ Chunking │ │ │
│ └──────┬───────┘ │ 512 tokens │ │ │
│ │ └──────┬───────┘ │ │
│ ┌──────┴───────┐ │ │ │
│ │ REST API │ ┌──────┴───────┐ │ │
│ │ v2 │ │ Embeddings │ │ │
│ └──────────────┘ │ BGE-M3 │ │ │
│ └──────────────┘ │ │
│ │ │
│ QUERY PIPELINE │ │
│ ┌──────────────┐ ┌─────────────┐ ┌──────────────┐ │ │
│ │ Question │────▶│ Retrieval │◀────│ Reranker │◀──┘ │
│ │ employe │ │ Top-30 │ │ Top-5 │ │
│ └──────────────┘ └─────────────┘ └──────┬───────┘ │
│ │ │
│ ┌──────────────┐ ┌──────┴───────┐ │
│ │ Reponse │◀───│ LLM │ │
│ │ + Sources │ │ GPT-4/Claude│ │
│ └──────────────┘ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Datenfluss
- Extraktion: Der Connector fragt die Confluence API v2 ab, um die Seiten abzurufen
- Parsing: Das Confluence-HTML wird in sauberes Markdown konvertiert
- Chunking: Die Dokumente werden in Segmente von 512 Tokens aufgeteilt
- Embedding: Jeder Chunk wird mit BGE-M3 (mehrsprachig) vektorisiert
- Indexierung: Die Vektoren werden in Qdrant mit Metadaten gespeichert
- Retrieval: Die Fragen werden semantisch mit den Chunks abgeglichen
- Reranking: Ein zweites Modell verfeinert die Rangfolge
- Generierung: Das LLM synthetisiert die Antwort mit Zitaten
Vollständiger Confluence-Connector
Hier ist die Referenzimplementierung zur Extraktion von Confluence-Inhalten:
DEVELOPERpythonfrom atlassian import Confluence from bs4 import BeautifulSoup import hashlib from typing import Optional import re class ConfluenceConnector: def __init__(self, url: str, username: str, api_token: str): """ Initialisiert den Confluence-Connector. Args: url: URL der Instanz (z. B. https://company.atlassian.net) username: E-Mail-Adresse des Benutzers api_token: Atlassian-API-Token """ self.confluence = Confluence( url=url, username=username, password=api_token, cloud=True ) self.base_url = url def get_all_spaces(self) -> list: """Ruft alle zugänglichen Spaces ab.""" spaces = [] start = 0 limit = 50 while True: result = self.confluence.get_all_spaces( start=start, limit=limit, expand='description.plain' ) for space in result.get('results', []): spaces.append({ 'key': space['key'], 'name': space['name'], 'type': space.get('type', 'global'), 'description': space.get('description', {}).get('plain', {}).get('value', '') }) if len(result.get('results', [])) < limit: break start += limit return spaces def get_space_pages(self, space_key: str, include_archived: bool = False) -> list: """ Ruft alle Seiten eines Spaces ab. Args: space_key: Schlüssel des Spaces (z. B. 'IT', 'RH') include_archived: Archivierte Seiten einbeziehen Returns: Liste von für das RAG formatierten Dokumenten """ pages = [] start = 0 limit = 50 while True: try: result = self.confluence.get_all_pages_from_space( space_key, start=start, limit=limit, expand='body.storage,ancestors,version,metadata.labels' ) except Exception as e: print(f"Fehler Space {space_key}: {e}") break for page in result: # Archivierte Seiten filtern, falls gewünscht if not include_archived and page.get('status') == 'archived': continue doc = self._format_page(page, space_key) if doc and len(doc['content']) > 100: # Kurze Seiten ignorieren pages.append(doc) if len(result) < limit: break start += limit return pages def _format_page(self, page: dict, space_key: str) -> dict: """Formatiert eine Confluence-Seite als RAG-Dokument.""" # HTML-Inhalt extrahieren und bereinigen html_content = page.get('body', {}).get('storage', {}).get('value', '') text_content = self._html_to_markdown(html_content) # Hierarchischen Pfad (breadcrumb) erstellen ancestors = page.get('ancestors', []) path_parts = [a['title'] for a in ancestors] + [page['title']] breadcrumb = ' > '.join(path_parts) # Labels extrahieren labels = [ label['name'] for label in page.get('metadata', {}).get('labels', {}).get('results', []) ] # Hash, um Änderungen zu erkennen content_hash = hashlib.md5(text_content.encode()).hexdigest() # Version und Datum version = page.get('version', {}) return { "id": f"confluence_{page['id']}", "title": page['title'], "content": f"# {page['title']}\n\n**Pfad**: {breadcrumb}\n\n{text_content}", "metadata": { "source": "confluence", "source_type": "documentation", "space_key": space_key, "page_id": page['id'], "url": f"{self.base_url}/wiki/spaces/{space_key}/pages/{page['id']}", "breadcrumb": breadcrumb, "labels": labels, "version": version.get('number', 1), "last_updated": version.get('when'), "last_updated_by": version.get('by', {}).get('displayName'), "content_hash": content_hash } } def _html_to_markdown(self, html: str) -> str: """ Konvertiert das Confluence-HTML in sauberes Markdown. Behandelt die Besonderheiten des Confluence-Formats: - Makros (code, panel, note, warning) - Tabellen - Verschachtelte Listen - Links und Erwähnungen """ if not html: return "" soup = BeautifulSoup(html, 'html.parser') # Code-Makros verarbeiten for code_block in soup.find_all('ac:structured-macro', {'ac:name': 'code'}): language = code_block.get('ac:language', '') code_body = code_block.find('ac:plain-text-body') if code_body: code_text = code_body.get_text() code_block.replace_with(f"\n```{language}\n{code_text}\n```\n") # Panels und Notizen verarbeiten for panel in soup.find_all('ac:structured-macro', {'ac:name': ['panel', 'note', 'warning', 'info']}): panel_type = panel.get('ac:name', 'note') body = panel.find('ac:rich-text-body') if body: panel_text = body.get_text(separator='\n') panel.replace_with(f"\n> **{panel_type.upper()}**: {panel_text}\n") # Tabellen verarbeiten for table in soup.find_all('table'): rows = table.find_all('tr') if rows: md_table = self._table_to_markdown(rows) table.replace_with(md_table) # Überschriften verarbeiten for i in range(1, 7): for header in soup.find_all(f'h{i}'): header.replace_with(f"\n{'#' * i} {header.get_text()}\n") # Listen verarbeiten for ul in soup.find_all('ul'): items = ul.find_all('li', recursive=False) list_text = '\n'.join([f"- {li.get_text()}" for li in items]) ul.replace_with(f"\n{list_text}\n") for ol in soup.find_all('ol'): items = ol.find_all('li', recursive=False) list_text = '\n'.join([f"{i+1}. {li.get_text()}" for i, li in enumerate(items)]) ol.replace_with(f"\n{list_text}\n") # Endtext bereinigen text = soup.get_text(separator='\n') text = re.sub(r'\n{3,}', '\n\n', text) # Max. 2 Leerzeilen text = re.sub(r' +', ' ', text) # Mehrfache Leerzeichen return text.strip() def _table_to_markdown(self, rows) -> str: """Konvertiert eine HTML-Tabelle in Markdown.""" md_lines = [] for i, row in enumerate(rows): cells = row.find_all(['th', 'td']) cell_texts = [cell.get_text().strip().replace('|', '\\|') for cell in cells] md_lines.append('| ' + ' | '.join(cell_texts) + ' |') # Trennzeile nach dem Header hinzufügen if i == 0: md_lines.append('| ' + ' | '.join(['---'] * len(cells)) + ' |') return '\n' + '\n'.join(md_lines) + '\n' def get_page_comments(self, page_id: str) -> list: """Ruft die Kommentare einer Seite ab (optional).""" try: comments = self.confluence.get_page_comments( page_id, expand='body.storage', depth='all' ) return [ { 'author': c.get('author', {}).get('displayName', 'Unknown'), 'content': BeautifulSoup( c.get('body', {}).get('storage', {}).get('value', ''), 'html.parser' ).get_text(), 'date': c.get('created') } for c in comments.get('results', []) ] except: return [] class ConfluenceMultiSpaceConnector(ConfluenceConnector): """Erweiterung zur Verwaltung mehrerer Spaces mit Filterung.""" def get_all_documents( self, space_keys: list = None, exclude_spaces: list = None, labels_filter: list = None ) -> list: """ Ruft die Dokumente mehrerer Spaces ab. Args: space_keys: Liste der einzubeziehenden Spaces (None = alle) exclude_spaces: Auszuschließende Spaces labels_filter: Nur Seiten mit diesen Labels behalten Returns: Liste aller Dokumente """ all_docs = [] # Liste der Spaces abrufen spaces = self.get_all_spaces() for space in spaces: key = space['key'] # Spaces filtern if space_keys and key not in space_keys: continue if exclude_spaces and key in exclude_spaces: continue print(f"Indexierung Space: {space['name']} ({key})") pages = self.get_space_pages(key) # Nach Labels filtern, falls gewünscht if labels_filter: pages = [ p for p in pages if any(label in p['metadata']['labels'] for label in labels_filter) ] all_docs.extend(pages) return all_docs
Synchronisation und Aktualisierung
Die Synchronisation kann inkrementell (effizient) oder vollständig (Bereinigung) erfolgen:
DEVELOPERpythonfrom datetime import datetime, timedelta import schedule class ConfluenceSyncManager: def __init__(self, connector: ConfluenceConnector, indexer): self.connector = connector self.indexer = indexer self.last_sync = None self.sync_history = [] def sync_incremental(self, spaces: list = None): """ Inkrementelle Synchronisation. Verarbeitet nur die seit der letzten Sync geänderten Seiten. """ if spaces is None: spaces = [s['key'] for s in self.connector.get_all_spaces()] updated_count = 0 for space_key in spaces: pages = self.connector.get_space_pages(space_key) for page in pages: last_updated = page['metadata'].get('last_updated') if last_updated: updated_dt = datetime.fromisoformat( last_updated.replace('Z', '+00:00') ) if self.last_sync is None or updated_dt > self.last_sync: self.indexer.upsert_document(page) updated_count += 1 self.last_sync = datetime.now() self.sync_history.append({ 'timestamp': self.last_sync, 'type': 'incremental', 'documents_updated': updated_count }) print(f"Inkrementelle Sync: {updated_count} Dokumente aktualisiert") def sync_full(self, spaces: list = None): """Vollständige Synchronisation mit Ersetzung.""" docs = self.connector.get_all_documents() if spaces is None else [] if spaces: for space_key in spaces: docs.extend(self.connector.get_space_pages(space_key)) self.indexer.replace_all(docs) self.last_sync = datetime.now() self.sync_history.append({ 'timestamp': self.last_sync, 'type': 'full', 'documents_indexed': len(docs) }) print(f"Vollständige Sync: {len(docs)} Dokumente indexiert") def cleanup_deleted(self): """Löscht Dokumente, deren Seiten nicht mehr existieren.""" indexed_ids = self.indexer.get_all_ids() current_pages = set() for space in self.connector.get_all_spaces(): pages = self.connector.get_space_pages(space['key']) for page in pages: current_pages.add(page['id']) # IDs finden, die gelöscht werden sollen to_delete = indexed_ids - current_pages if to_delete: self.indexer.delete_documents(list(to_delete)) print(f"{len(to_delete)} veraltete Dokumente gelöscht") def start_confluence_sync_worker(sync_manager: ConfluenceSyncManager): """Startet den Synchronisations-Worker.""" # Inkrementelle Sync alle 15 Minuten schedule.every(15).minutes.do(sync_manager.sync_incremental) # Wöchentliche vollständige Sync schedule.every().sunday.at("02:00").do(sync_manager.sync_full) # Monatliche Bereinigung schedule.every(30).days.do(sync_manager.cleanup_deleted) while True: schedule.run_pending() time.sleep(60)
Optimierter System-Prompt für Confluence
DEVELOPERpythonCONFLUENCE_SYSTEM_PROMPT = """Du bist der Dokumentations-Assistent von {company_name}. Du hilfst den Mitarbeitenden, Informationen in unserem Confluence zu finden. ## Aufgabe - Antworte AUSSCHLIESSLICH auf Basis der Confluence-Dokumentation - Zitiere systematisch den Space und die Quellseite - Gib das Datum der letzten Aktualisierung an, falls relevant - Verweise auf den richtigen Ansprechpartner, wenn die Frage über die Doku hinausgeht ## Regeln 1. Erfinde niemals Informationen, die in der Dokumentation fehlen 2. Bevorzuge kürzlich aktualisierte Seiten 3. Weise darauf hin, wenn eine Information veraltet erscheint (> 1 Jahr) 4. Passe den Detailgrad an die Frage an ## Format - Zuerst die direkte Antwort - Details bei Bedarf - Quelle: [Space > Seite] (Datum) ## Verfügbare Dokumentation {context} """
Konkrete Anwendungsfälle
1. Interner IT-Support
Frage: "Wie konfiguriere ich das VPN für Homeoffice?"
RAG-Antwort:
So konfigurierst du das VPN:
- Lade den Cisco AnyConnect Client vom [internen Link] herunter
- Server: vpn.company.com
- Verwende deine Active-Directory-Zugangsdaten
- Für die 2FA nutze die Duo-App
Bei Problemen eröffne ein IT-Ticket über ServiceNow.
Quelle: [IT > Guide VPN Homeoffice] (vor 2 Monaten aktualisiert)
2. HR-Prozesse
Frage: "Wie läuft der Prozess für einen Fortbildungsantrag ab?"
RAG-Antwort:
Ablauf für einen Fortbildungsantrag:
- Bestimme die Fortbildung zusammen mit deiner Führungskraft
- Fülle das Formular F-RH-015 in Confluence aus
- Lass es von deinem Vorgesetzten und anschließend von HR genehmigen
- Budget: max. 2000 EUR/Jahr/Mitarbeiter
Bearbeitungszeit: 2-3 Wochen.
Quelle: [RH > Formation > Antragsverfahren] (Januar 2025)
3. Technische Dokumentation
Frage: "Wie deploye ich auf die Staging-Umgebung?"
RAG-Antwort:
Staging-Deployment:
DEVELOPERbash# 1. In 'develop' mergen git checkout develop && git pull && git merge feature/xxx # 2. Pipeline starten ./scripts/deploy.sh staging # 3. Prüfen curl https://staging.company.com/healthStaging-Zugang: beim DevOps-Team anfragen (#devops auf Slack).
Quelle: [Tech > DevOps > Deployment] (Dezember 2025)
Best Practices
Confluence für RAG strukturieren
| Praxis | Vorteil |
|---|---|
| Klare Hierarchie (max. 3 Ebenen) | Optimales Chunking |
| Beschreibende Titel | Bessere Suche |
| Standardisierte Labels | Einfache Filterung |
| Seitenvorlagen | Konsistentes Format |
| Kurze und fokussierte Seiten | Präzise Antworten |
Berechtigungen verwalten
Das RAG respektiert die Confluence-Berechtigungen:
- Dedizierten Service-Account mit Lesezugriff erstellen
- Auf öffentliche/interne Spaces je nach Anwendungsfall beschränken
- Vertrauliche Spaces niemals ohne Validierung indexieren
Qualitätsindikatoren
- Anteil der Antworten mit Quelle
- Fragen ohne Treffer (zur Doku hinzuzufügen)
- Am häufigsten zitierte Seiten
- Nutzerfeedback
Weiterführende Ressourcen
- Unternehmens-Wissensdatenbank - Säulenleitfaden
- Notion + RAG - Notion-Alternative
- SharePoint + RAG - Für Microsoft 365
- Slack Bot RAG - Suche in Unterhaltungen
- Einführung in RAG - Die Grundlagen
FAQ
Verbinden Sie Confluence mit Ailog
Verwandeln Sie Ihre Confluence-Dokumentation in einen intelligenten Assistenten. Ailog vereinfacht die Integration:
- Nativer Atlassian-Connector: Automatische Multi-Space-Synchronisation
- Semantische Suche: Finden Sie Informationen in natürlicher Sprache
- Berechtigungsrespektierung: Granularer Zugriff pro Space
- Versionshistorie: Vollständige Nachverfolgbarkeit
- Hosting in Frankreich: Native DSGVO-Konformität
Ailog kostenlos testen und Ihren Confluence-Assistenten in 15 Minuten bereitstellen.
Tags
Verwandte Artikel
Slack-Bot RAG: Intelligente Suche in Ihren Konversationen
Vollständiger Leitfaden zum Bereitstellen eines Slack-Bots mit RAG. Verwandeln Sie den Verlauf Ihrer Kanäle in eine von AI durchsuchbare Wissensdatenbank.
SharePoint + RAG: Ihre Microsoft 365-Dokumente nutzen
Umfassender Leitfaden, um SharePoint mit einem RAG-System zu verbinden. Machen Sie Ihre Microsoft 365-Dokumente per AI durchsuchbar mittels semantischer Suche.
Notion + RAG: Ihr Unternehmens-Wiki verbinden
Umfassender Leitfaden zur Integration von Notion als Wissensquelle für einen RAG-Chatbot. Synchronisierung, Indexierung, semantische Suche und praktische Anwendungsfälle.