groot 4cfdac042d
All checks were successful
release-tag / release-image (push) Successful in 1m35s
Update GLPI-Knowledge
2026-07-28 14:35:03 +02:00
2026-07-27 17:32:35 +02:00
2026-07-28 14:35:03 +02:00
2026-07-27 17:32:35 +02:00
2026-07-28 14:35:03 +02:00
2026-07-27 17:32:35 +02:00
2026-07-27 17:32:35 +02:00
2026-07-28 05:42:22 +02:00
2026-07-28 14:35:03 +02:00
2026-07-27 17:32:35 +02:00
2026-07-27 19:18:36 +02:00
2026-07-28 05:42:22 +02:00
2026-07-28 14:35:03 +02:00
2026-07-27 21:27:42 +02:00
2026-07-27 21:27:42 +02:00
2026-07-27 17:32:35 +02:00
2026-07-27 17:32:35 +02:00
2026-07-28 14:35:03 +02:00
2026-07-27 19:18:36 +02:00
2026-07-28 14:35:03 +02:00
2026-07-28 14:35:03 +02:00

GLPI AI Agent (Go + Ollama)

Produktionsorientierter, bewusst policy-gesteuerter Ticket-Agent für GLPI 11. Er liest neue/geänderte Tickets über die GLPI High-Level API, schlägt eine Kategorie vor, sucht freigegebene Wissenseinträge und kann nach mehreren harten Sicherheitsprüfungen eine erste Antwort schreiben.

Sicherheitsmodell

  • DRY_RUN=true ist der Default.
  • AUTO_REPLY=false ist der Default.
  • Das LLM erhält keine GLPI-Tools und kann keine Schreiboperation direkt auslösen.
  • Kategorie-IDs werden gegen die aus GLPI geladene Kategorie-Liste validiert.
  • Automatische Antworten stammen nicht aus freiem LLM-Text, sondern aus einem freigegebenen Knowledge-Dokument (auto_reply=true).
  • Die Knowledge-Suche ist fail-closed: Nur Quellen aus KNOWLEDGE_ALLOWED_SOURCES werden überhaupt geladen/indexiert.
  • Auto-Replies benötigen zusätzlich eine Quelle aus KNOWLEDGE_AUTO_REPLY_SOURCES sowie passende Sprach-/Stil-Metadaten.
  • Endnutzer-Antworten werden zentral mit konfigurierter Anrede, Grußformel und Signatur gerahmt.
  • Vor einer Antwort werden Followups zweimal geprüft: vor der KI-Analyse und unmittelbar vor dem Schreiben.
  • Sobald irgendein Followup existiert, antwortet der Agent nicht.
  • Pro Ticket wird innerhalb eines Prozesses seriell gearbeitet; Polling/Webhook-Ereignisse werden dedupliziert.
  • GLPI-Schreibfehler werden nicht automatisch wiederholt, um Doppelwrites zu vermeiden.
  • Das Dashboard ist read-only und standardmäßig mit HTTP Basic Auth geschützt.
  • Audit-Trail: data/runs.jsonl.

Wichtige Grenze: Die zweite Followup-Prüfung minimiert Race Conditions, kann ohne einen atomaren Conditional-Write auf GLPI-Seite aber kein mathematisch vollständig atomisches "check-and-write" garantieren. Für einen einzelnen Agent-Prozess ist zusätzlich ein Ticket-Lock aktiv.

Voraussetzungen

  • GLPI 11.0.6+ empfohlen (API v2.3).
  • High-Level API in GLPI aktiviert.
  • OAuth Client in Setup > OAuth Clients mit Password Grant und api Scope.
  • Dedizierter GLPI-Servicebenutzer mit minimal nötigen Rechten: Tickets lesen, Kategorien lesen/ändern (falls genutzt), Followups lesen/hinzufügen (falls Auto-Reply genutzt).
  • Ollama mit Chat- und Embedding-Modell.

Beim Start lädt der Agent /api.php/doc.json und prüft, ob die erwarteten Kernrouten vorhanden sind. Dadurch schlägt ein API-Mismatch früh und sichtbar fehl. Die mitgelieferten Tests laufen gegen HTTP-Mocks; eine echte GLPI-Instanz konnte in dieser Build-Umgebung nicht angebunden werden, daher ist der Shadow-Mode auf deiner Installation vor Live-Schreibzugriff zwingend.

Start nativ unter Windows / PowerShell

Für einen nativen Windows-Start nicht die Docker-Pfade /app/data, /app/knowledge oder den Docker-Hostnamen ollama verwenden. Die mitgelieferte .env.example enthält deshalb jetzt native, plattformneutrale Defaults:

DATA_DIR=./data
KNOWLEDGE_DIR=./knowledge
OLLAMA_URL=http://localhost:11434

Einmalig:

Copy-Item .env.example .env
# Danach .env mit den echten GLPI-Zugangsdaten bearbeiten.
ollama pull qwen3:8b
ollama pull embeddinggemma

Start:

.\run.ps1

run.ps1 lädt .env, startet immer aus dem Projektverzeichnis und erkennt zur Migration auch alte Docker-Werte. Beispielsweise wird ein vorhandenes KNOWLEDGE_DIR=/app/knowledge beim nativen Windows-Start auf <Projekt>\knowledge umgesetzt und mit einer Warnung ausgegeben. Das Datenverzeichnis wird bei Bedarf erstellt; ein fehlendes Knowledge-Verzeichnis führt zu einer verständlichen Fehlermeldung statt zu einem Panic.

Docker Compose überschreibt diese drei nativen Werte im Container weiterhin explizit mit /app/data, /app/knowledge und http://ollama:11434.

Start mit Docker Compose

cp .env.example .env
$EDITOR .env

docker compose up -d ollama
docker compose exec ollama ollama pull qwen3:8b
docker compose exec ollama ollama pull embeddinggemma

docker compose up -d --build agent

Dashboard: http://127.0.0.1:8080/

Vor dem ersten Live-Betrieb unbedingt mehrere Tage/Wochen im Shadow Mode lassen:

DRY_RUN=true
AUTO_CATEGORY=true
AUTO_REPLY=false

Danach zunächst nur Kategorieänderungen:

DRY_RUN=false
AUTO_CATEGORY=true
AUTO_REPLY=false

Erst nach Auswertung der Audit-Daten einzelne KB-Einträge mit auto_reply=true freigeben und anschließend:

AUTO_REPLY=true
GLPI_AGENT_USER_ID=123

GLPI-Endpunkte

Default ist GLPI_API_VERSION=v2.3. Der Client verwendet:

  • OAuth: POST /api.php/token
  • Tickets: /api.php/v2.3/Assistance/Ticket
  • Followups: /api.php/v2.3/Assistance/Ticket/{id}/Timeline/Followup
  • Kategorien: /api.php/v2.3/Dropdowns/ITILCategory
  • OpenAPI-Prüfung: /api.php/doc.json

Die OpenAPI-Dokumentation deiner Installation ist die maßgebliche Quelle, weil GLPI die API-Dokumentation dynamisch aus Core und aktivierten Plugins erzeugt.

Wissensbasis, Quellen und Kommunikationspolicy

Jede Datei in knowledge/ ist JSON und trägt eine explizite Herkunft sowie Kommunikations-Metadaten:

{
  "id": "KB-128",
  "title": "GlobalProtect Gateway nicht erreichbar",
  "text": "Beschreibung, Fehlermeldungen, Voraussetzungen ...",
  "answer": "Bitte trennen Sie die bestehende VPN-Verbindung vollständig und starten Sie den VPN-Client anschließend neu.",
  "auto_reply": true,
  "min_score": 0.92,
  "categories": [22],
  "keywords": ["GlobalProtect", "Gateway not responding"],
  "source": "internal-kb",
  "source_uri": "kb://network/vpn/128",
  "language": "de-DE",
  "communication_style": "formal"
}

Die aktive Source-Policy wird über die Umgebung festgelegt:

# Nur diese Quellen werden geladen, eingebettet und durchsucht.
KNOWLEDGE_ALLOWED_SOURCES=internal-kb,glpi-kb,vendor-docs

# Nur diese Teilmenge darf eine automatische Antwort auslösen.
KNOWLEDGE_AUTO_REPLY_SOURCES=internal-kb,glpi-kb

KNOWLEDGE_AUTO_REPLY_SOURCES muss eine Teilmenge von KNOWLEDGE_ALLOWED_SOURCES sein. Mit KNOWLEDGE_AUTO_REPLY_SOURCES=none kann die Quellenfreigabe für Auto-Replies vollständig deaktiviert werden. Dokumente aus nicht erlaubten Quellen werden nicht in die Suchmenge aufgenommen und damit auch nicht an Ollama übergeben. Ein Knowledge-Dokument ohne source führt absichtlich zu einem Startfehler, damit die Herkunft nicht implizit geraten wird.

GLPI Knowledge Base als echter Connector

Die GLPI-Wissensdatenbank kann jetzt direkt read-only synchronisiert werden. Der Agent ermittelt bei GLPI_KB_PATH=auto den lesbaren KnowbaseItem-Collection-Endpunkt aus /api.php/doc.json. GLPI selbst entscheidet anhand der Rechte des OAuth-Service-Accounts, welche Artikel sichtbar sind.

KNOWLEDGE_ALLOWED_SOURCES=internal-kb,glpi-kb
GLPI_KB_ENABLED=true
GLPI_KB_PATH=auto
GLPI_KB_SYNC_INTERVAL=10m
GLPI_KB_LIMIT=500
GLPI_KB_SOURCE=glpi-kb

Erfolgreich synchronisierte Artikel werden normalisiert, lokal unter DATA_DIR/glpi-kb-cache.json gecacht und in denselben RAG-Index wie lokale Knowledge-Dokumente aufgenommen. Unveränderte Dokumente behalten ihre gecachten Embeddings; nur neue oder geänderte Artikel werden erneut eingebettet. Fällt GLPI bei einem späteren Start/Sync aus, kann der zuletzt gespeicherte Cache weiter als read-only Wissensstand geladen werden.

GLPI-KB-Auto-Replies sind absichtlich separat gesperrt. Für eine Freigabe müssen alle Bedingungen erfüllt sein: glpi-kb ist in KNOWLEDGE_AUTO_REPLY_SOURCES, GLPI_KB_AUTO_REPLY=true, die GLPI-KB-Kategorie des Artikels steht in GLPI_KB_AUTO_REPLY_CATEGORY_IDS, und GLPI liefert eine Zuordnung dieser KB-Kategorie zu mindestens einer ITIL-Kategorie. Beispiel:

KNOWLEDGE_AUTO_REPLY_SOURCES=internal-kb,glpi-kb
GLPI_KB_AUTO_REPLY=true
GLPI_KB_AUTO_REPLY_CATEGORY_IDS=4,7

GLPI_KB_AUTO_REPLY_CATEGORY_IDS enthält Knowledge-Base-Kategorie-IDs aus GLPI, nicht Ticket-/ITIL-Kategorie-IDs. Ohne diese explizite Whitelist dienen GLPI-Artikel nur Recherche, RAG und Kategorie-Hinweisen.

Optional kann GLPI_KB_FILTER gesetzt werden, um die von GLPI gelieferte Collection zusätzlich serverseitig einzuschränken. Die konkrete Filtersyntax und verfügbare Felder stammen aus der OpenAPI-Dokumentation deiner installierten GLPI-Version.

Für die Kommunikation gelten zentrale Vorgaben:

COMMUNICATION_LANGUAGE=de-DE
COMMUNICATION_STYLE=formal
COMMUNICATION_SALUTATION=Guten Tag,
COMMUNICATION_CLOSING=Mit freundlichen Grüßen
COMMUNICATION_SIGNATURE=IT-Service

Ein Auto-Reply ist nur erlaubt, wenn language und communication_style des freigegebenen Knowledge-Dokuments exakt zur aktiven Policy passen. Das Feld answer enthält nur den fachlich freigegebenen Nachrichtentext; Anrede, Grußformel und Signatur werden von der Go-Policy zentral ergänzt. Damit kann das Modell diese Kommunikationsvorgaben nicht überschreiben.

categories begrenzt Auto-Reply auf die angegebenen Zielkategorien. Eine leere Liste bedeutet keine zusätzliche Kategorie-Einschränkung. min_score kann die globale Schwelle je Artikel verschärfen.

Bei aktiviertem RAG erzeugt Ollama Embeddings über /api/embed; der Cache landet in data/embeddings.json. Für Ticket und Knowledge wird dasselbe Embedding-Modell verwendet.

Operativer Kontext: Changes, Major Incidents, Uptime Kuma und Geräte

Der Agent kann vor der LLM-Entscheidung zusätzliche read-only Betriebsdaten einsammeln. Diese Daten werden normalisiert und als Fakten in den Prompt aufgenommen; das Modell erhält keine direkten Zugangsdaten und keine zusätzlichen Schreibwerkzeuge.

Change Calendar

CHANGE_CALENDAR_ENABLED=true
GLPI_CHANGE_PATH=/Assistance/Change
GLPI_CHANGE_FILTER=
GLPI_CHANGE_LIMIT=100
CHANGE_LOOKBACK=48h
CHANGE_LOOKAHEAD=24h

Der Agent lädt Changes im konfigurierten Zeitfenster, berechnet eine deterministische Relevanz zum Ticket (u. a. Tickettext, verknüpfte Geräte/Standorte) und übergibt höchstens die relevantesten Einträge an Ollama. GLPI_CHANGE_PATH wird beim Start gegen /api.php/doc.json geprüft. Bei einer Installation mit abweichender Route oder Filter-Syntax muss die Konfiguration an das OpenAPI-Schema der eigenen Instanz angepasst werden.

Aktive Major Incidents

MAJOR_INCIDENTS_ENABLED=false
GLPI_MAJOR_INCIDENT_FILTER=
GLPI_MAJOR_INCIDENT_LIMIT=20

Major Incidents werden bewusst nicht automatisch aus beliebigen Tickets erraten. Sie sind eine explizit vom Betreiber definierte Teilmenge der GLPI-Tickets. Erst wenn GLPI_MAJOR_INCIDENT_FILTER die in deiner Umgebung gültige Filterdefinition enthält, sollte MAJOR_INCIDENTS_ENABLED=true gesetzt werden. Ein zum aktuellen Ticket relevanter Major Incident blockiert standardmäßig einen normalen Auto-Reply; die Kategorieanalyse darf weiterlaufen.

Beispiel-Idee (die konkrete Syntax muss zu deinem GLPI-OpenAPI-Schema passen): ein Filter auf eine dedizierte Kategorie, Priorität/Impact oder ein eigenes Kennzeichen für Major Incidents.

Aktuelle Störungen mit Uptime Kuma

Für interne Uptime-Kuma-Instanzen ist der authentifizierte Prometheus-Endpunkt der empfohlene Modus:

UPTIME_KUMA_ENABLED=true
UPTIME_KUMA_URL=https://uptime.example.org
UPTIME_KUMA_MODE=metrics
UPTIME_KUMA_API_KEY=CHANGE_ME
UPTIME_KUMA_TIMEOUT=10s
UPTIME_KUMA_MAX_ISSUES=20

Der Client liest ausschließlich /metrics, verwendet den Uptime-Kuma-API-Key als HTTP-Basic-Auth-Passwort und gibt nur Monitore weiter, die nicht UP sind. Der API-Key wird nicht an Ollama übergeben.

Alternativ können bereits veröffentlichte Statusseiten gelesen werden:

UPTIME_KUMA_MODE=status_page
UPTIME_KUMA_STATUS_PAGES=it-services,network
UPTIME_KUMA_INCLUDE_MAINTENANCE=true

In diesem Modus liest der Agent /api/status-page/<slug> und /api/status-page/heartbeat/<slug> und berücksichtigt gepinnte Incidents, DOWN/PENDING-Monitore und optional Wartungen. Dieser Modus eignet sich nur für Informationen, die auf der betreffenden Statusseite ohnehin veröffentlicht werden dürfen.

Beziehungen zwischen Benutzer und Gerät

USER_DEVICE_CONTEXT_ENABLED=true
GLPI_USER_DEVICE_PATHS=/Assets/Computer
GLPI_USER_DEVICE_FILTER_TEMPLATE=user.id=={{user_id}}
GLPI_USER_DEVICE_LIMIT=20

Der Agent nutzt zunächst direkt am Ticket verknüpfte GLPI-Items. Zusätzlich werden soweit der Ticket-Response Requester-IDs enthält über die konfigurierten Asset-Routen dem Benutzer zugeordnete Geräte gelesen. Die Pfade werden beim Start gegen die OpenAPI-Dokumentation geprüft; die Filter-Syntax ist installationsabhängig und sollte im Shadow Mode verifiziert werden.

Die normalisierten Gerätedaten dienen u. a. dazu, Changes und Störungen besser zum Ticket zuzuordnen. Es werden keine Assets geändert.

Fail-closed Verhalten

CONTEXT_ENABLED=true
CONTEXT_TIMEOUT=12s
CONTEXT_RELEVANCE_MIN_SCORE=0.20
CONTEXT_BLOCK_AUTO_REPLY_ON_ERRORS=true
CONTEXT_BLOCK_AUTO_REPLY_ON_INCIDENT=true

Mit den sicheren Defaults gilt:

  • Fällt eine aktivierte Kontextquelle aus, wird der Lauf als unvollständig markiert und kein Auto-Reply gesendet.
  • Ein relevanter Major Incident oder eine relevante Uptime-Kuma-Störung blockiert einen normalen Standard-Auto-Reply.
  • Kategorieanalyse und Auditierung können trotzdem stattfinden.
  • Kontextquellen haben ausschließlich Leserechte.
  • Im Dashboard/Audit erscheinen pro Lauf die Anzahl der gefundenen Changes, Incidents, Uptime-Issues und Geräte sowie Warnungen bei unvollständigem Kontext.

Web- und Monitoring-Endpunkte

  • / Dashboard (Basic Auth)
  • /api/status Status JSON inklusive aktiver Sprache/Stil- und Quellenpolicy (Basic Auth)
  • /api/runs?limit=50 letzte Audit-Läufe (Basic Auth)
  • /healthz Prozess lebt
  • /readyz GLPI und Ollama erreichbar
  • /metrics Prometheus Textformat
  • POST /webhook/glpi optionaler Webhook-Eingang, geschützt durch X-Webhook-Secret

Das Polling bleibt immer aktiv und dient als Fallback. Der Webhook-Parser akzeptiert übliche Ticket-ID-Felder sowie Ticket-URLs; prüfe die konkrete Payload deiner GLPI-Webhook-Konfiguration im Shadow Mode.

Erklärbare Entscheidungen im Dashboard

Für den Shadow-/Einführungsbetrieb speichert jeder Lauf die rohe KI-Empfehlung getrennt von der Policy-Entscheidung. Das Modell liefert bei Kategorien nur noch id und confidence; ein eigenes change=true/false gibt es nicht mehr. Ob tatsächlich geändert werden darf, entscheidet ausschließlich Go anhand der aktuellen Kategorie, der bekannten GLPI-Kategorien und CATEGORY_CONFIDENCE.

Das Dashboard zeigt deshalb unter anderem:

  • aktuelle Kategorie mit ID und Name,
  • von der KI empfohlene Kategorie mit ID und Name,
  • KI-Confidence und konfigurierten Schwellwert,
  • expliziten Entscheidungsgrund wie category_confidence_below_threshold, category_already_correct oder category_written,
  • KI-Empfehlung für Auto-Reply samt Confidence und Reply-Schwellwert,
  • besten Knowledge-Treffer mit Score,
  • den ersten Policy-Blocker für einen Reply, z. B. fehlendes Knowledge, vorhandenes Followup, unvollständigen Kontext oder einen relevanten Incident,
  • die fachliche KI-Begründung separat von den technischen Policy-Codes.

Damit ist auch ein Lauf ohne Schreibaktion nachvollziehbar. Beispiel: „KI empfiehlt Active Directory (#17) mit 82 %, Schwellwert 90 % → nicht geändert“. Die JSON-Details stehen zusätzlich unter /api/runs?limit=50 zur Verfügung.

Keine Doppelantworten

Der Schreibpfad ist bewusst streng:

  1. Ticket laden.
  2. Followups laden. Existiert eines: Stop.
  3. Knowledge sowie read-only Betriebskontext (Changes, Major Incidents, Uptime Kuma, Benutzer/Geräte) laden.
  4. KI empfiehlt Kategorie-ID + Confidence und optional einen Knowledge-basierten Reply; Kontextdaten sind nur Fakten, keine ausführbaren Anweisungen.
  5. Policy Engine entscheidet deterministisch über Kategorieänderung und Reply und protokolliert jeden akzeptierten oder blockierten Gate-Grund.
  6. Optional Kategorie ändern.
  7. Direkt vor Auto-Reply Ticket und Followups erneut laden. Existiert jetzt ein Followup oder hat sich die Entscheidungsgrundlage geändert: Stop.
  8. Freigegebenen KB-Antworttext als Followup schreiben.

GLPI_AGENT_USER_ID wird bei AUTO_REPLY=true absichtlich verlangt, damit die Betreiberkonfiguration eindeutig einem dedizierten GLPI-Konto zugeordnet ist. Der aktuelle Code blockiert bei jedem vorhandenen Followup einschließlich eines früheren Agent-Followups und ist damit konservativer als nur "fremde" Antworten zu prüfen.

Produktionshinweise

  • Dashboard hinter Reverse Proxy mit TLS betreiben; Compose bindet Port 8080 absichtlich nur an 127.0.0.1.
  • GLPI über HTTPS anbinden. Plain HTTP wird standardmäßig abgelehnt (GLPI_ALLOW_INSECURE_HTTP=false).
  • .env niemals committen; besser Docker/Kubernetes Secrets oder systemd EnvironmentFile mit restriktiven Dateirechten verwenden.
  • Servicekonto nach Least-Privilege-Prinzip konfigurieren.
  • Für mehrere parallele Agent-Replikate muss die lokale Queue/State-Sperre durch einen verteilten Store/Lock (z. B. PostgreSQL/Redis) ersetzt werden. Die mitgelieferte Version ist für eine aktive Agent-Instanz ausgelegt.
  • Vor Live-Auto-Reply Tests mit echten anonymisierten Ticketmustern durchführen.
  • Knowledge-Antworten fachlich freigeben und versionieren.

Build & Tests

Das Projekt verwendet nur die Go-Standardbibliothek; damit gibt es keine Laufzeit-Abhängigkeiten im Agent-Binary.

make fmt
make test
make vet
make build

Docker troubleshooting: /app/data permission denied and slow Ollama

The Compose stack contains a one-shot agent-data-init service. It prepares the named agent-data volume for the non-root agent user before the agent starts. The agent also probes runs.jsonl at startup and exits immediately with a clear error if the volume is not writable.

For local LLMs, the default request budget is intentionally longer than a typical HTTP API call:

OLLAMA_TIMEOUT=10m
OLLAMA_NUM_PREDICT=256
OLLAMA_KEEP_ALIVE=10m
OLLAMA_THINK=false
OLLAMA_MAX_CONCURRENT=1

OLLAMA_NUM_PREDICT limits the maximum generated tokens for the small structured decision. OLLAMA_KEEP_ALIVE asks Ollama to keep the analysis model loaded between tickets. OLLAMA_THINK=false disables optional model thinking for this deterministic classification task. OLLAMA_MAX_CONCURRENT=1 serializes local Ollama inference even when multiple ticket workers are active, so queued requests do not consume their HTTP timeout while waiting for the model. On very slow CPU-only hosts, use a smaller local model and/or increase OLLAMA_TIMEOUT.

After upgrading an existing Compose deployment, recreate the stack so the init service runs:

docker compose down
docker compose build --no-cache agent agent-data-init
docker compose up -d

You do not need to delete agent-data; the init service fixes ownership on the existing named volume.

Human-in-the-loop-Lernen und Web-Knowledge-Base

Der Agent lernt nicht aus seinen eigenen Entscheidungen. Im Dashboard kann eine Kategorie eines verarbeiteten Tickets ausdrücklich bestätigt oder korrigiert werden. Diese menschlich bestätigten Beispiele werden in DATA_DIR/category-learning.json persistiert und bei ähnlichen Tickets als confirmed_examples an das Klassifikationsmodell übergeben. Zusätzlich werden Kategorie-Hinweise aus freigegebenen KB-Keywords und konservativen IT-Semantik-Hinweisen aufgebaut.

Konfiguration:

LEARNING_ENABLED=true
LEARNING_MAX_EXAMPLES=500
LEARNING_EXAMPLES_PER_CATEGORY=5

Das Dashboard zeigt außerdem den Status und die Anzahl der synchronisierten GLPI-KB-Artikel. Synchronisierte GLPI-Artikel sind read-only und als GLPI-Sync gekennzeichnet.

Das Dashboard enthält außerdem einen CRUD-Editor für interne Knowledge-Einträge. Er ist absichtlich nur bei authentifiziertem Dashboard aktiv:

WEB_ALLOW_ANONYMOUS=false
KNOWLEDGE_WEB_EDIT_ENABLED=true

Web-verwaltete Artikel landen nicht im statischen KNOWLEDGE_DIR, sondern unter DATA_DIR/knowledge-managed/. Dadurch kann knowledge/ weiterhin read-only aus Git/Image gemountet werden. Statische Artikel werden im Web angezeigt, können dort aber nicht überschrieben oder gelöscht werden. Neue bzw. im Web verwaltete Artikel werden nach dem Speichern sofort in den laufenden Such-/RAG-Store aufgenommen; ein Neustart ist nicht nötig.

Für stabilere Structured Outputs sind die empfohlenen Startwerte:

OLLAMA_NUM_PREDICT=768
OLLAMA_JSON_RETRIES=1

Bei unvollständigem/ungültigem JSON wird genau einmal erneut eine schema-konforme Antwort angefordert.

Deployment mit Gitea Container Registry unter Linux

Für ein bereits in Gitea gebautes Image ist docker-compose.registry.yml vorgesehen; lokal wird nichts gebaut.

export AGENT_IMAGE=gitea.example.de/organisation/glpi-ai-agent:latest
mkdir -p data knowledge
sudo chown 65532:65532 data
# knowledge bleibt absichtlich read-only; Web-KB landet unter data/knowledge-managed/
docker compose -f docker-compose.registry.yml pull
docker compose -f docker-compose.registry.yml up -d

Bei neuen Gitea-Builds genügt:

docker compose -f docker-compose.registry.yml up -d --pull always
Description
No description provided
Readme MIT 72 MiB
Languages
Go 83.5%
HTML 16%
PowerShell 0.3%
Makefile 0.1%