@clawhub-tikitackr-d319fbc8bf
KDP Publisher DE konvertiert Markdown-Kapitel in professionell formatierte, KDP-fähige PDFs im OpenClaw-Buchstil mit QR-Codes.
---
name: kdp-publisher
description: Baut KDP-fertige PDFs aus Markdown-Kapiteln im professionellen OpenClaw-Buchstil (Inter-Font, 6x9 inch, Typst-basiert). Verwendung: "Bau mir ein PDF aus [Dateiname]" oder "Kompiliere Kapitel 3".
---
# kdp-publisher — KDP PDF Builder
Dieser Skill wandelt Markdown-Kapitel in KDP-fertige PDFs um — im Buchstil von "OpenClaw – Agentic Authorship".
## Voraussetzungen prüfen
```bash
# Python-Abhängigkeiten installieren (einmalig):
pip install requests qrcode
# Skill-Verzeichnis:
ls $OPENCLAW_WORKSPACE/skills/kdp-publisher/scripts/
```
## Verwendung
**Ein Kapitel:**
```bash
cd $OPENCLAW_WORKSPACE/skills/kdp-publisher/scripts
python3 build-book.py --chapter /pfad/zu/kapitel.md /pfad/output/kapitel.pdf
```
**Ganzes Buch (alle Kapitel in der konfigurierten Reihenfolge):**
```bash
cd $OPENCLAW_WORKSPACE/skills/kdp-publisher/scripts
python3 build-book.py /pfad/output/buch.pdf
```
## Was passiert im Hintergrund
1. `build-book.py` orchestriert den Build
2. `md2typ.py` konvertiert Markdown → Typst
3. `compile.py` generiert QR-Codes + sendet an TypeTex API → PDF
## Markdown-Format
| Element | Syntax |
|---|---|
| Kapitelüberschrift | `# Titel` |
| Abschnitt | `## Titel` |
| Tipp-Box | `> **TIPP:** Text` |
| Warn-Box | `> **WARNUNG:** Text` |
| Hinweis-Box | `> **HINWEIS:** Text` |
| Erfolg-Box | `> **ERFOLG:** Text` |
| Zitat | `> Text` |
| QR-Code | `[QR-CODE: ID – Label]` |
| QR mit Hinweis | `[QR-CODE: ID – Label \| Hinweistext]` |
## QR-Codes konfigurieren
QR-Code-URLs werden aus einer `links.json` geladen. Standardpfad:
```
$OPENCLAW_WORKSPACE/links.json
```
Format:
```json
{
"eigene_projekte": { "DASHBOARD_URL": "https://deine-domain.de" },
"qr_codes": {
"MEIN-QR": {
"target": "{{DASHBOARD_URL}}/seite",
"print_url": "deine-domain.de/seite"
}
}
}
```
## Häufige Probleme
- **QR nicht gefunden:** ID in `links.json` prüfen, kein `_`-Präfix
- **API-Timeout:** Kapitel einzeln kompilieren statt ganzes Buch
- **Font fehlt:** TypeTex API stellt Inter und Liberation Mono bereit — kein lokales Install nötig
FILE:_meta.json
{
"name": "kdp-publisher-de",
"version": "1.0.0",
"author": "Tikitackr",
"description": "Baut KDP-fertige PDFs aus Markdown-Kapiteln im professionellen OpenClaw-Buchstil. Typst-basiert, Inter-Font, 6x9 inch, mit QR-Code-Integration.",
"language": "de",
"license": "MIT",
"tags": [
"kdp",
"pdf",
"amazon",
"buch",
"typst",
"markdown",
"publishing"
],
"commands": [
"Bau mir ein PDF aus [Dateiname]",
"Kompiliere Kapitel [N]",
"Bau das komplette Buch als PDF",
"Erstelle ein PDF"
],
"requires": {
"runtime": "python >= 3.9",
"network": true
},
"repository": "https://clawhub.ai/Tikitackr/kdp-publisher-de"
}
FILE:README.md
# kdp-publisher
OpenClaw-Skill der Markdown-Kapitel in KDP-fertige PDFs umwandelt — im professionellen Buchstil von "OpenClaw – Agentic Authorship".
## Installation
In deinem OpenClaw-Chat:
```
Installiere den Skill Tikitackr/kdp-publisher
```
## Verwendung
```
Bau mir ein PDF aus kapitel-01.md
```
```
Kompiliere das komplette Buch als PDF
```
## Was der Skill liefert
- KDP-konformes PDF (6×9 inch, mit Gutter)
- Inter-Font, professioneller Buchsatz
- Kapiteltrennseiten, Boxen, QR-Codes
- Titelseite + Copyrightseite automatisch generiert
## Voraussetzungen
- OpenClaw auf einem VPS installiert
- Python 3.9+
- `pip install requests qrcode`
## Lizenz
MIT
FILE:scripts/kdp-book.typ.txt
// ============================================================
// KDP Book Template — Typst
// Amazon KDP-konform: Trim-Größen, Bleed, Gutter, Typografie
// Layout-Qualität: Hurenkinder/Waisen, sticky headings, recto-Kapitel
// ============================================================
#let trim-sizes = (
"6x9": (width: 6in, height: 9in),
"5.5x8.5": (width: 5.5in, height: 8.5in),
"5x8": (width: 5in, height: 8in),
"7x10": (width: 7in, height: 10in),
"8.5x11": (width: 8.5in, height: 11in),
"8.5x8.5": (width: 8.5in, height: 8.5in),
"5.06x7.81":(width: 5.06in, height: 7.81in),
)
#let get-gutter(page-count-estimate) = {
if page-count-estimate <= 150 { 0.375in }
else if page-count-estimate <= 300 { 0.5in }
else if page-count-estimate <= 500 { 0.625in }
else if page-count-estimate <= 700 { 0.75in }
else { 0.875in }
}
#let kdp-setup(
title: "Buchtitel",
author: "Autorenname",
subtitle: none,
language: "de",
trim: "6x9",
page-count-estimate: 200,
bleed: false,
body-font: "Inter",
heading-font: "Inter",
body-size: 11pt,
line-height: 1.4,
outside-margin: 0.5in,
top-margin: 0.6in,
bottom-margin: 0.7in,
show-page-numbers: true,
running-header: true,
chapters-on-recto: true,
isbn: none,
doc,
) = {
let trim-dim = trim-sizes.at(trim, default: trim-sizes.at("6x9"))
let gutter = get-gutter(page-count-estimate)
let bleed-size = if bleed { 0.125in } else { 0in }
let page-width = trim-dim.width + bleed-size
let page-height = trim-dim.height + (bleed-size * 2)
let inner-margin = gutter
let outer-margin = outside-margin
set text(
font: body-font,
size: body-size,
lang: language,
hyphenate: true,
costs: (
widow: 100%,
orphan: 100%,
runt: 60%,
hyphenation: 40%,
),
)
set par(
justify: true,
leading: line-height * body-size - body-size,
first-line-indent: 0em,
spacing: body-size * 1.4,
)
show raw.where(block: true): it => {
v(0.3cm)
block(
width: 100%,
fill: rgb("#0f172a"),
stroke: (left: 3pt + rgb("#f59e0b")),
inset: (left: 1em, right: 1em, top: 0.7em, bottom: 0.7em),
breakable: false,
)[
#set text(font: "Liberation Mono", size: 9pt, fill: rgb("#e2e8f0"))
#set par(justify: false, first-line-indent: 0em, leading: 0.4em)
#it
]
v(0.3cm)
}
show raw.where(block: false): it => {
box(
fill: rgb("#f1f5f9"),
inset: (x: 4pt, y: 1pt),
radius: 2pt,
)[
#set text(font: "Liberation Mono", size: 9.5pt, fill: rgb("#0f172a"))
#it
]
}
set document(title: title, author: author)
set page(
width: page-width,
height: page-height,
margin: (
inside: inner-margin,
outside: outer-margin,
top: top-margin,
bottom: bottom-margin,
),
header: if running-header {
context {
let p = counter(page).get().first()
let headings-on-page = query(heading.where(level: 1))
.filter(h => h.location().page() == here().page())
if p > 2 and headings-on-page.len() == 0 {
set text(font: heading-font, size: 8pt, fill: rgb("#94a3b8"))
set par(first-line-indent: 0em)
stack(
dir: ttb,
if calc.odd(p) { align(right)[#title] }
else { align(left)[#title] },
v(4pt),
line(length: 100%, stroke: 0.5pt + rgb("#e2e8f0")),
)
}
}
},
footer: if show-page-numbers {
context {
let p = counter(page).get().first()
let headings-on-page = query(heading.where(level: 1))
.filter(h => h.location().page() == here().page())
if p > 2 and headings-on-page.len() == 0 {
set text(size: 9pt)
if calc.odd(p) { align(right)[#p] }
else { align(left)[#p] }
}
}
},
)
show heading.where(level: 1): it => {
page(
width: page-width,
height: page-height,
margin: (top: 0pt, bottom: 0pt, left: 0pt, right: 0pt),
header: none,
footer: none,
)[
#v(1.8in)
#rect(width: 100%, height: 6pt, fill: rgb("#f59e0b"))
#pad(left: inner-margin, right: outer-margin)[
#v(0.5in)
#block[
#set text(font: heading-font, size: 13pt, fill: rgb("#94a3b8"), tracking: 2pt)
#set par(justify: false, first-line-indent: 0em)
#upper[Kapitel #context counter(heading.where(level: 1)).display()]
]
#v(14pt)
#block[
#set text(font: heading-font, size: 26pt, weight: "bold", fill: rgb("#d97706"))
#set par(justify: false, first-line-indent: 0em, leading: 0.3em)
#it.body
]
#v(18pt)
#rect(width: 60pt, height: 2pt, fill: rgb("#f59e0b"))
]
]
}
show heading.where(level: 2): it => {
v(0.8cm)
block(width: 100%, sticky: true)[
#set text(font: heading-font, size: body-size * 1.25, weight: "bold")
#set par(first-line-indent: 0em, justify: false)
#it.body
]
v(0.4cm)
}
show heading.where(level: 3): it => {
v(0.5cm)
block(width: 100%, sticky: true)[
#set text(font: heading-font, size: body-size * 1.1, weight: "bold", style: "italic")
#set par(first-line-indent: 0em, justify: false)
#it.body
]
v(0.25cm)
}
// Titelseite
page(margin: (x: 1.5in, y: 1.5in))[
#v(1fr)
#align(center)[
#set text(font: heading-font)
#text(size: 20pt, weight: "bold")[#title]
#if subtitle != none {
v(0.5cm)
text(size: 16pt, style: "italic")[#subtitle]
}
#v(1.5cm)
#line(length: 60%, stroke: 0.5pt)
#v(0.8cm)
#text(size: 14pt)[#author]
]
#v(1fr)
]
// Copyright-Seite
page(margin: (x: 1.2in, y: 1in))[
#v(1fr)
#set text(size: 8.5pt)
#set par(justify: false, first-line-indent: 0em)
#align(left)[
*#title* \
#if subtitle != none [#subtitle \ ]
#v(0.3cm)
Von #author \
#v(0.5cm)
Copyright © 2026 #author \
Alle Rechte vorbehalten. \
#v(0.3cm)
Kein Teil dieses Buches darf ohne schriftliche Genehmigung \
des Autors reproduziert oder verwendet werden. \
#v(0.5cm)
Erstveröffentlichung: 2026 \
#if isbn != none [ISBN: #isbn \ ]
Printed in Germany \
]
]
counter(page).update(1)
doc
}
// --- Hilfsfunktionen ---
#let epigraph(body, source: none) = {
v(0.5cm)
block(width: 80%, inset: (left: 1.5em, right: 1em, top: 0.5em, bottom: 0.5em), breakable: false)[
#set text(style: "italic", size: 10pt)
#set par(justify: false, first-line-indent: 0em)
#body
#if source != none [
#v(0.2cm)
#align(right)[#set text(style: "normal", size: 9pt); — #source]
]
]
v(0.5cm)
}
#let _hint-box(label, border-color, bg-color, label-color, content) = {
v(0.4cm)
block(
width: 100%,
stroke: (left: 3pt + rgb(border-color)),
inset: (left: 1em, right: 1em, top: 0.6em, bottom: 0.6em),
fill: rgb(bg-color),
breakable: true,
sticky: true,
)[
#block[
#set text(weight: "bold", size: 10pt, fill: rgb(label-color))
#set par(first-line-indent: 0em)
#label
]
#v(0.15cm)
#set text(size: 10.5pt)
#set par(first-line-indent: 0em)
#content
]
v(0.4cm)
}
#let box-tip(content) = _hint-box("Tipp", "#3b82f6", "#eff6ff", "#3b82f6", content)
#let box-warning(content) = _hint-box("Warnung", "#ef4444", "#fef2f2", "#ef4444", content)
#let box-success(content) = _hint-box("Erledigt", "#10b981", "#f0fdf4", "#10b981", content)
#let box-note(content) = _hint-box("Hinweis", "#f59e0b", "#fffbeb", "#d97706", content)
#let infobox(title: none, content) = _hint-box(
if title != none { title } else { "Hinweis" },
"#f59e0b", "#fffbeb", "#d97706", content
)
#let chapter-intro(content) = {
v(0.3cm)
block(width: 90%, inset: (left: 1.5em), sticky: true)[
#set text(style: "italic", size: 10.5pt)
#set par(first-line-indent: 0em)
#content
]
v(0.5cm)
}
#let dedication(content) = {
pagebreak(to: "odd", weak: true)
v(1fr)
align(center)[
#set text(style: "italic", size: 11pt)
#set par(justify: false, first-line-indent: 0em)
#content
]
v(1fr)
pagebreak()
}
#let scene-break() = {
v(0.5cm)
align(center)[#text(size: 14pt)[⁂]]
v(0.5cm)
}
#let soft-break() = pagebreak(weak: true)
#let chapter-start() = pagebreak(to: "odd", weak: false)
#let qr-block(qr-img, label, url, hint: "Am PC oder Tablet siehst du das volle interaktive Dashboard.") = {
v(0.4cm)
block(breakable: false, width: 100%)[
#set par(first-line-indent: 0em)
#grid(
columns: (3cm, 1fr),
gutter: 0.8em,
qr-img,
align(horizon)[
#set text(size: 9pt)
#text(weight: "bold")[#label] \
#text(style: "italic")[#url] \
#text(size: 8pt, fill: rgb("#555555"))[#hint]
]
)
]
v(0.4cm)
}
FILE:scripts/md2typ.py
#!/usr/bin/env python3
"""
md2typ.py — Markdown → Typst für OpenClaw-Buchkapitel
Verwendung: python md2typ.py <input.md> [output.typ]
python md2typ.py <input.md> # stdout
"""
import re
import sys
import os
# ── Inline-Konverter ──────────────────────────────────────────────────────────
def convert_inline(text):
"""Markdown-Inline-Syntax → Typst. Code-Spans werden nicht angefasst."""
parts = []
last = 0
for m in re.finditer(r'`[^`]+`', text):
parts.append(('text', text[last:m.start()]))
parts.append(('code', m.group(0)))
last = m.end()
parts.append(('text', text[last:]))
result = []
for kind, chunk in parts:
if kind == 'code':
result.append(chunk)
else:
# Literal # und @ zuerst mit Platzhaltern schützen (bevor wir #strong etc. erzeugen)
chunk = chunk.replace('#', '\x05')
chunk = chunk.replace('@', '\x06')
chunk = chunk.replace('$', '\x07')
# Platzhalter für Bold/Italic, damit Regex-Reihenfolge keine Rolle spielt
# Bold+Italic: ***text*** → Platzhalter
chunk = re.sub(r'\*\*\*(.+?)\*\*\*', lambda m: f'\x01{m.group(1)}\x02', chunk)
# Bold: **text** → Platzhalter
chunk = re.sub(r'\*\*(.+?)\*\*', lambda m: f'\x03{m.group(1)}\x04', chunk)
# Italic: *text* → _text_
chunk = re.sub(r'(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)', r'_\1_', chunk)
# Bold-Platzhalter auflösen — #strong[...] vermeidet Delimiter-Fehler bei /*, -*, etc.
chunk = re.sub(r'\x01(.+?)\x02', lambda m: f'#strong[_{m.group(1)}_]', chunk)
chunk = re.sub(r'\x03(.+?)\x04', lambda m: f'#strong[{m.group(1)}]', chunk)
# Markdown-Links: [text](url) → #link("url")[text]
chunk = re.sub(r'\[([^\]]+)\]\(([^)]+)\)', r'#link("\2")[\1]', chunk)
# Literal-Platzhalter zu Typst-Escapes auflösen
chunk = chunk.replace('\x05', r'\#')
chunk = chunk.replace('\x06', r'\@')
chunk = chunk.replace('\x07', r'\$')
result.append(chunk)
return ''.join(result)
# ── Blockquote → Hint-Box ─────────────────────────────────────────────────────
_HINT_PATTERNS = [
(r'^(?:💡\s*)?\*\*TIPP:\*\*\s*(.*)', 'box-tip'),
(r'^(?:⚠️\s*)?\*\*WARNUNG:\*\*\s*(.*)', 'box-warning'),
(r'^(?:✅\s*)?\*\*ERFOLG:\*\*\s*(.*)', 'box-success'),
(r'^(?:📌\s*)?\*\*HINWEIS:\*\*\s*(.*)', 'box-note'),
(r'^\*\*TIPP:\*\*\s*(.*)', 'box-tip'),
(r'^\*\*WARNUNG:\*\*\s*(.*)', 'box-warning'),
(r'^\*\*ERFOLG:\*\*\s*(.*)', 'box-success'),
(r'^\*\*HINWEIS:\*\*\s*(.*)', 'box-note'),
]
def convert_blockquote(lines):
content_parts = []
for line in lines:
stripped = re.sub(r'^>\s?', '', line).strip()
if stripped:
content_parts.append(stripped)
if not content_parts:
return ''
full = ' '.join(content_parts)
for pattern, func in _HINT_PATTERNS:
m = re.match(pattern, full, re.DOTALL)
if m:
inner = convert_inline(m.group(1).strip())
return f'#{func}[\n{inner}\n]'
# Einfaches Blockquote → Epigraph
return f'#epigraph[\n{convert_inline(full)}\n]'
# ── Tabelle ───────────────────────────────────────────────────────────────────
def convert_table(lines):
rows = []
for line in lines:
stripped = line.strip()
if re.match(r'^\|[-:| ]+\|$', stripped):
continue
cells = [c.strip() for c in stripped.strip('|').split('|')]
rows.append(cells)
if not rows:
return ''
num_cols = len(rows[0])
col_spec = ', '.join(['1fr'] * num_cols)
header_cells = ', '.join(f'[{convert_inline(c)}]' for c in rows[0])
out = [f'#table(\n columns: ({col_spec}),\n table.header({header_cells}),']
for row in rows[1:]:
# Pad/trim row to expected column count
while len(row) < num_cols:
row.append('')
row = row[:num_cols]
cells = ', '.join(f'[{convert_inline(c)}]' for c in row)
out.append(f' {cells},')
out.append(')')
return '\n'.join(out)
# ── QR-Code ───────────────────────────────────────────────────────────────────
def convert_qr(line):
m = re.match(r'\[QR-CODE:\s*([A-Z0-9_-]+)\s*[–—-]\s*(.+?)\s*\]', line.strip())
if m:
qr_id = m.group(1)
rest = m.group(2).strip()
if '|' in rest:
label, hint = [x.strip() for x in rest.split('|', 1)]
return f'#qr-block(image("qr-{qr_id}.svg", width: 3cm), "{label}", "", hint: "{hint}")'
return f'#qr-block(image("qr-{qr_id}.svg", width: 3cm), "{rest}", "")'
return None
# ── Haupt-Konverter ───────────────────────────────────────────────────────────
def md2typ(md_text):
lines = md_text.splitlines()
out = []
i = 0
while i < len(lines):
line = lines[i]
# Code-Block
if line.strip().startswith('```'):
lang = line.strip()[3:].strip()
code_lines = []
i += 1
while i < len(lines) and not lines[i].strip().startswith('```'):
code_lines.append(lines[i])
i += 1
fence = f'```{lang}' if lang else '```'
out.append(f'{fence}\n' + '\n'.join(code_lines) + '\n```')
i += 1
continue
# Tabelle
if (line.strip().startswith('|')
and i + 1 < len(lines)
and re.match(r'^\|[-:| ]+\|', lines[i + 1].strip())):
table_lines = []
while i < len(lines) and lines[i].strip().startswith('|'):
table_lines.append(lines[i])
i += 1
out.append(convert_table(table_lines))
continue
# Blockquote
if line.startswith('>'):
quote_lines = []
while i < len(lines) and lines[i].startswith('>'):
quote_lines.append(lines[i])
i += 1
out.append(convert_blockquote(quote_lines))
continue
# Überschriften
m = re.match(r'^(#{1,3})\s+(.*)', line)
if m:
level = len(m.group(1))
title = convert_inline(m.group(2).strip())
out.append('=' * level + ' ' + title)
i += 1
continue
# Horizontale Linie → überspringen
if re.match(r'^---+\s*$', line) or re.match(r'^\*\*\*+\s*$', line):
i += 1
continue
#
if line.strip() == ' ':
out.append('')
i += 1
continue
# QR-Code — konsekutive QR-Zeilen als nicht-trennbare Gruppe
qr = convert_qr(line)
if qr:
group = [qr]
i += 1
while i < len(lines):
next_qr = convert_qr(lines[i])
if next_qr:
group.append(next_qr)
i += 1
elif lines[i].strip() == '':
i += 1 # Leerzeilen innerhalb der Gruppe überspringen
else:
break
if len(group) > 1:
out.append('#block(breakable: false)[\n' + '\n'.join(group) + '\n]')
else:
out.append(group[0])
continue
# Ungeordnete Liste
if re.match(r'^[-*]\s+', line):
while i < len(lines) and re.match(r'^[-*]\s+', lines[i]):
text = re.sub(r'^[-*]\s+', '', lines[i])
out.append('- ' + convert_inline(text))
i += 1
continue
# Geordnete Liste
if re.match(r'^\d+\.\s+', line):
while i < len(lines) and re.match(r'^\d+\.\s+', lines[i]):
text = re.sub(r'^\d+\.\s+', '', lines[i])
out.append('+ ' + convert_inline(text))
i += 1
continue
# Leerzeile
if line.strip() == '':
out.append('')
i += 1
continue
# Normaler Absatz
out.append(convert_inline(line))
i += 1
# Mehrfache Leerzeilen auf eine reduzieren
result = []
prev_blank = False
for line in out:
if line == '':
if not prev_blank:
result.append('')
prev_blank = True
else:
result.append(line)
prev_blank = False
body = '\n'.join(result).strip()
return '#import "kdp-book.typ": *\n\n' + body + '\n'
# ── CLI ───────────────────────────────────────────────────────────────────────
def main():
if len(sys.argv) < 2:
print(__doc__)
sys.exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2] if len(sys.argv) > 2 else None
if not os.path.exists(input_file):
print(f'[md2typ] Fehler: {input_file} nicht gefunden')
sys.exit(1)
md_text = open(input_file, encoding='utf-8').read()
typ_text = md2typ(md_text)
if output_file:
os.makedirs(os.path.dirname(os.path.abspath(output_file)), exist_ok=True)
open(output_file, 'w', encoding='utf-8').write(typ_text)
print(f'[md2typ] ✓ {input_file} → {output_file}')
else:
sys.stdout.write(typ_text)
if __name__ == '__main__':
main()
FILE:scripts/compile.py
#!/usr/bin/env python3
"""
KDP PDF Compiler — kompiliert Typst zu KDP-fertigem PDF via TypeTex API.
Verwendung: python compile.py <main.typ> [output.pdf] [template.typ]
Beispiel: python compile.py build/main.typ output/buch.pdf kdp-book.typ
"""
import requests, base64, json, os, sys, time, re, io
LINKS_JSON = os.path.expanduser(
"~/Desktop/openclaw-projekt/agentic-authorship-dashboard/shared/links.json"
)
def _load_qr_urls():
if not os.path.exists(LINKS_JSON):
return {}, {}
data = json.load(open(LINKS_JSON, encoding="utf-8"))
base = data.get("eigene_projekte", {}).get("DASHBOARD_URL", "https://openclaw-buch.de")
targets, print_urls = {}, {}
for qr_id, entry in data.get("qr_codes", {}).items():
if qr_id.startswith("_"):
continue
if isinstance(entry, dict) and "target" in entry:
targets[qr_id] = entry["target"].replace("{{DASHBOARD_URL}}", base)
if "print_url" in entry:
print_urls[qr_id] = entry["print_url"]
targets.setdefault("DISCORD-SETUP", f"{base}/?module=config-builder&preset=discord")
targets.setdefault("HUMANIZER-INSTALL", "https://clawhub.ai/Tikitackr/humanizer-de")
return targets, print_urls
QR_URLS, PRINT_URLS = _load_qr_urls()
def generate_qr_svg(url):
import qrcode
qr = qrcode.QRCode(border=1)
qr.add_data(url)
qr.make(fit=True)
matrix = qr.get_matrix()
n = len(matrix)
cell = 10
size = n * cell
rects = []
for r, row in enumerate(matrix):
for c, val in enumerate(row):
if val:
x, y = c * cell, r * cell
rects.append(f'<rect x="{x}" y="{y}" width="{cell}" height="{cell}"/>')
return (
f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {size} {size}" '
f'width="{size}" height="{size}">'
f'<rect width="{size}" height="{size}" fill="white"/>'
f'<g fill="black">{"".join(rects)}</g>'
f'</svg>'
)
def inject_qr_codes(main_content, aux):
# Ersetzt vollständige qr-block-Aufrufe: Bild UND Anzeige-URL (mit oder ohne hint:)
def replace_qr_block(m):
qr_id = m.group(1)
width = m.group(2)
label = m.group(3)
hint_part = m.group(4) # '' oder ', hint: "..."'
url = QR_URLS.get(qr_id, "https://openclaw-buch.de/")
print_url = PRINT_URLS.get(qr_id, url.replace("https://", "").replace("http://", ""))
print(f"[KDP] QR generieren: {qr_id} → {print_url}")
svg = generate_qr_svg(url).replace("\\", "\\\\").replace('"', '\\"')
return f'#qr-block(image.decode("{svg}", format: "svg", width: {width}), "{label}", "{print_url}"{hint_part})'
main_content = re.sub(
r'#qr-block\(\s*image\("qr-([A-Z0-9-]+)\.svg",\s*width:\s*([^)]+)\)\s*,\s*"([^"]*)"\s*,\s*"[^"]*"((?:,\s*hint:\s*"[^"]*")?)\s*\)',
replace_qr_block,
main_content
)
# Fallback: standalone image-Referenzen außerhalb von qr-block
def replace_qr_image(m):
qr_id = m.group(1)
width = m.group(2)
url = QR_URLS.get(qr_id, "https://openclaw-buch.de/")
print(f"[KDP] QR generieren (standalone): {qr_id} → {url}")
svg = generate_qr_svg(url).replace("\\", "\\\\").replace('"', '\\"')
return f'image.decode("{svg}", format: "svg", width: {width})'
main_content = re.sub(
r'image\("qr-([A-Z0-9-]+)\.svg",\s*width:\s*([^)]+)\)',
replace_qr_image,
main_content
)
return main_content, aux
API_URL = os.environ.get(
"TYPETEX_API_URL",
"https://studio-intrinsic--typetex-compile-app.modal.run"
)
def health_check():
try:
r = requests.get(f"{API_URL}/public/compile/health", timeout=10)
return r.json().get("status") == "ok"
except Exception:
return False
def compile_typst_to_pdf(main_content, auxiliary_files=None, output_path="output.pdf"):
payload = {
"content": main_content,
"main_filename": "main.typ",
"auxiliary_files": auxiliary_files or {}
}
print(f"[KDP] Sende an TypeTex API...")
start = time.time()
try:
r = requests.post(f"{API_URL}/public/compile/typst", json=payload, timeout=120)
elapsed = round(time.time() - start, 1)
if r.status_code != 200:
return {"success": False, "error": f"HTTP {r.status_code}: {r.text[:300]}"}
result = r.json()
if result.get("success"):
pdf = base64.b64decode(result["pdf_base64"])
os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
open(output_path, "wb").write(pdf)
size_kb = len(pdf) // 1024
print(f"[KDP] ✓ PDF: {output_path} ({size_kb} KB, {elapsed}s)")
return {"success": True, "pdf_path": os.path.abspath(output_path), "size_kb": size_kb}
else:
print(f"[KDP] ✗ Fehler: {result.get('error')}")
print(result.get("log_output", "")[:800])
return {"success": False, "error": result.get("error"), "log": result.get("log_output","")}
except requests.Timeout:
return {"success": False, "error": "Timeout — Buch zu groß. Kapitel einzeln kompilieren."}
except requests.ConnectionError:
return {"success": False, "error": f"API nicht erreichbar: {API_URL}"}
except Exception as e:
return {"success": False, "error": str(e)}
def main():
if len(sys.argv) < 2:
print(__doc__); sys.exit(1)
main_file = sys.argv[1]
output_file = sys.argv[2] if len(sys.argv) > 2 else main_file.replace(".typ", ".pdf")
template_file = sys.argv[3] if len(sys.argv) > 3 else None
if not os.path.exists(main_file):
print(f"[KDP] Fehler: {main_file} nicht gefunden"); sys.exit(1)
main_content = open(main_file, encoding="utf-8").read()
aux = {}
main_dir = os.path.dirname(os.path.abspath(main_file))
# Alle #include "datei.typ" aus main automatisch hochladen
for inc in re.findall(r'#include\s+"([^"]+)"', main_content):
inc_path = os.path.join(main_dir, inc)
if os.path.exists(inc_path):
aux[inc] = open(inc_path, encoding="utf-8").read()
print(f"[KDP] Include: {inc}")
else:
print(f"[KDP] Warnung: #include \"{inc}\" nicht gefunden ({inc_path})")
candidates = [
template_file,
os.path.join(os.path.dirname(os.path.abspath(main_file)), "kdp-book.typ.txt"),
os.path.join(os.path.dirname(os.path.abspath(main_file)), "kdp-book.typ"),
os.path.join(os.getcwd(), "kdp-book.typ.txt"),
os.path.join(os.getcwd(), "kdp-book.typ"),
]
for candidate in candidates:
if candidate and os.path.exists(candidate):
aux["kdp-book.typ"] = open(candidate, encoding="utf-8").read()
break
else:
print("[KDP] Warnung: kdp-book.typ nicht gefunden — bitte als 3. Argument übergeben.")
main_content, aux = inject_qr_codes(main_content, aux)
# QR-Injektion auch in aux-Dateien (z.B. #include-Kapitel)
for fname in list(aux.keys()):
if fname.endswith(".typ") and fname != "kdp-book.typ":
aux[fname], _ = inject_qr_codes(aux[fname], {})
if not health_check():
print(f"[KDP] API nicht erreichbar — versuche lokales Typst...")
import subprocess
try:
r = subprocess.run(["typst","compile",main_file,output_file],
capture_output=True, text=True, timeout=60)
if r.returncode == 0:
print(f"[KDP] ✓ Lokal: {output_file}")
else:
print(f"[KDP] ✗ {r.stderr}"); sys.exit(1)
except FileNotFoundError:
print("[KDP] Typst nicht installiert: https://github.com/typst/typst/releases")
sys.exit(1)
return
result = compile_typst_to_pdf(main_content, aux, output_file)
print(json.dumps(result, ensure_ascii=False, indent=2))
if not result["success"]: sys.exit(1)
if __name__ == "__main__":
main()
FILE:scripts/build-book.py
#!/usr/bin/env python3
"""
build-book.py — Baut das komplette OpenClaw-Buch als KDP-PDF
Verwendung: python build-book.py [output.pdf]
python build-book.py --chapter kapitel-01-final.md [output.pdf]
"""
import os
import sys
import json
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from md2typ import md2typ
from compile import compile_typst_to_pdf, inject_qr_codes, health_check
# ── Konfiguration ─────────────────────────────────────────────────────────────
KAPITEL_DIR = os.path.expanduser(
"~/Desktop/openclaw-projekt/buch-review/kapitel"
)
CHAPTER_ORDER = [
"vorwort-v3-final.md",
"kapitel-01-final.md",
"kapitel-02-final.md",
"kapitel-03-final.md",
"kapitel-04-final.md",
"kapitel-05-final.md",
"kapitel-06-final.md",
"kapitel-07-final.md",
"kapitel-08-final.md",
"kapitel-09-final.md",
"kapitel-10-final.md",
"kapitel-11-final.md",
"kapitel-12-final.md",
"kapitel-13-final.md",
"kapitel-13-teil2-final.md",
"kapitel-13-teil3-final.md",
"kapitel-14-final.md",
"kapitel-15-final.md",
]
TEMPLATE_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "kdp-book.typ.txt")
BOOK_HEADER = """\
#import "kdp-book.typ": *
#show: kdp-setup.with(
title: "OpenClaw — Agentic Authorship",
author: "Thomas Iburg",
subtitle: "Wie KI-Agenten dein Buch schreiben",
language: "de",
trim: "6x9",
page-count-estimate: 300,
bleed: false,
body-font: "Inter",
heading-font: "Inter",
body-size: 11pt,
chapters-on-recto: true,
)
"""
IMPORT_HEADER = '#import "kdp-book.typ": *\n\n'
# ── Hilfsfunktionen ───────────────────────────────────────────────────────────
def convert_chapter(md_path):
"""Konvertiert ein Markdown-Kapitel zu Typst (ohne Import-Header)."""
md_text = open(md_path, encoding="utf-8").read()
typ_text = md2typ(md_text)
# Import-Header entfernen — wird einmalig im BOOK_HEADER gesetzt
if typ_text.startswith(IMPORT_HEADER):
typ_text = typ_text[len(IMPORT_HEADER):]
return typ_text
def build_main_typ(chapters):
"""Erzeugt den vollständigen main.typ-Inhalt aus einer Liste von MD-Pfaden."""
parts = [BOOK_HEADER]
for md_path in chapters:
name = os.path.basename(md_path)
print(f"[build] Konvertiere: {name}")
body = convert_chapter(md_path)
parts.append(f"\n// ── {name} ──\n\n{body}")
return "\n".join(parts)
# ── CLI ───────────────────────────────────────────────────────────────────────
def main():
args = sys.argv[1:]
# --chapter <datei> [output]
if args and args[0] == "--chapter":
if len(args) < 2:
print("Verwendung: build-book.py --chapter <datei.md> [output.pdf]")
sys.exit(1)
md_file = args[1]
if not os.path.isabs(md_file):
md_file = os.path.join(KAPITEL_DIR, md_file)
output_file = args[2] if len(args) > 2 else "output/chapter-test.pdf"
chapters = [md_file]
# Für einzelne Kapitel: mit BOOK_HEADER (inkl. kdp-setup)
main_content = BOOK_HEADER + "\n" + convert_chapter(md_file)
else:
output_file = args[0] if args else "output/openclaw-buch.pdf"
chapters = [os.path.join(KAPITEL_DIR, f) for f in CHAPTER_ORDER]
for path in chapters:
if not os.path.exists(path):
print(f"[build] Fehler: {path} nicht gefunden")
sys.exit(1)
main_content = build_main_typ(chapters)
# Template laden
if not os.path.exists(TEMPLATE_PATH):
print(f"[build] Fehler: {TEMPLATE_PATH} nicht gefunden")
sys.exit(1)
aux = {"kdp-book.typ": open(TEMPLATE_PATH, encoding="utf-8").read()}
# QR-Codes injizieren
print("[build] QR-Codes injizieren...")
main_content, aux = inject_qr_codes(main_content, aux)
# API-Check
if not health_check():
print("[build] Fehler: TypeTex API nicht erreichbar")
sys.exit(1)
# Kompilieren
os.makedirs(os.path.dirname(os.path.abspath(output_file)), exist_ok=True)
print(f"[build] Kompiliere → {output_file}")
result = compile_typst_to_pdf(main_content, aux, output_file)
print(json.dumps(result, ensure_ascii=False, indent=2))
if not result["success"]:
sys.exit(1)
if __name__ == "__main__":
main()
Analysiert deutsche Texte auf KI-Muster, markiert problematische Stellen, bewertet die KI-Wahrscheinlichkeit (0–100) und bietet konkrete Verbesserungsvorschl...
# Humanizer-DE
**Erster deutscher KI-Text-Detektor für OpenClaw.**
5-Durchgang-Analyse: Erkennt 24 KI-Schreibmuster, flaggt 125+ deutsche KI-Vokabeln in 3 Tiers + 48 Phrasen + 16 Chatbot-Artefakte, misst 5 statistische Signale (Burstiness, TTR, Flesch-DE) und schreibt Texte mit Personality Injection um. Inklusive Lesch-Stil-Layer.
> **Version:** 1.2.0
> **Autor:** OpenClaw
> **Sprache:** Deutsch
> **Lizenz:** MIT
> **ClawHub:** `Tikitackr/humanizer-de`
---
## Was macht dieser Skill?
Du gibst ihm einen deutschen Text. Er sagt dir:
1. **Wie stark** der Text nach KI klingt (Score 0–100)
2. **Wo genau** KI-Muster stecken (markiert + erklärt)
3. **Wie du es besser machst** (konkrete Umschreibvorschläge)
Score 0 = klingt menschlich. Score 100 = klingt wie ChatGPT auf Autopilot.
---
## Befehle
| Befehl | Was passiert |
|--------|-------------|
| `Check diesen Text` | Vollständiger Report: Score + Muster + Vokabeln + Statistik + Vorschläge |
| `Score: [Text]` | Nur der Score (0–100) mit Kurzeinschätzung |
| `Was klingt hier nach KI?` | Nur die problematischen Stellen markiert |
| `Humanisiere das` | Text umschreiben mit Personality Injection (Basis-Stil) |
| `Humanisiere das im Lesch-Stil` | Umschreiben mit Lesch-Layer (Visionär/Mahner/Erklärer) |
| `Mach das menschlicher` | Wie "Humanisiere das" – Synonym |
---
## Workflow (5 Durchgänge)
Wenn ein Text gecheckt wird, durchläuft er 5 Analyse-Schritte. Jeder Schritt hat eine eigene Reference-Datei mit allen Details.
### Durchgang 1: KI-Muster-Scan
**Reference:** `references/ki-muster.md`
Prüfe den Text auf alle 24 KI-Schreibmuster. Für jedes gefundene Muster:
- Markiere die betroffene Stelle
- Nenne das Muster (z.B. "Muster #1: Bedeutungsinflation")
- Zeige Schweregrad: HOCH / MITTEL / NIEDRIG
- Gib einen konkreten Umschreibvorschlag
**Punkte-Vergabe:**
- HOCH-Muster: +5 Punkte pro Treffer
- MITTEL-Muster: +3 Punkte pro Treffer
- NIEDRIG-Muster: +1 Punkt pro Treffer
### Durchgang 2: Vokabel-Check
**Reference:** `references/vokabeln.md`
Scanne den Text auf KI-typische Wörter und Phrasen aus der deutschen KI-Marker-Datenbank.
**Tier-System:**
- **Tier 1 (VERBOTEN):** Jedes Vorkommen = +3 Punkte. Immer ersetzen.
- **Tier 2 (SPARSAM):** Erlaubt max 1x pro 500 Wörter. Jedes Vorkommen über Limit = +1 Punkt.
- **Tier 3 (BEOBACHTEN):** Nur zählen. Wenn Dichte > 3 pro 500 Wörter = +1 Punkt pro überzähligem.
- **Verbotene Phrasen:** Jedes Vorkommen = +4 Punkte. Immer ersetzen.
Für jedes geflaggerte Wort: Zeige das Wort, den Tier, und einen konkreten Ersetzungsvorschlag.
### Durchgang 3: Statistische Analyse
**Reference:** `references/statistische-signale.md`
Berechne fünf statistische Signale:
| Signal | Formel | KI-Alarm wenn |
|--------|--------|---------------|
| Burstiness | B = (σ_τ - μ_τ) / (σ_τ + μ_τ) | B < 0.3 |
| Type-Token-Ratio (TTR) | Unique Tokens / Total Tokens (pro 100-Wort-Fenster) | TTR < 0.5 |
| Satzlängen-Variation (CoV) | σ / μ der Satzlängen in Wörtern | CoV < 0.3 |
| Trigramm-Wiederholung | Wiederholte Trigramme / Gesamt-Trigramme | Rate > 0.10 |
| Flesch-DE (Lesbarkeit) | 180 - L - (58.5 × S) | Flesch 40–50 (KI-Sweetspot) |
**Punkte-Vergabe:**
- Burstiness unter 0.3: +10 Punkte (nur bei ≥20 Sätzen)
- TTR unter 0.5: +5 Punkte
- Satzlängen-CoV unter 0.3: +5 Punkte
- Trigramm-Rate über 0.10: +5 Punkte
- Flesch-DE im KI-Sweetspot (40–50): +3 Punkte
### Durchgang 3b: Co-Occurrence-Check
**Reference:** `references/vokabeln.md` (Abschnitt Co-Occurrence-Sets)
Prüfe ob in einzelnen Absätzen 3+ Wörter aus derselben KI-Wortgruppe auftauchen. 5 Sets definiert (Bedeutungsinflation, Techno-Superlative, Akademisch-Abstrakt, Passiv-Verben, Floskel-Ketten).
**Punkte-Vergabe:**
- Pro Cluster-Alarm (3+ Treffer aus einem Set in einem Absatz): +5 Punkte
### Durchgang 4: Personality-Check
**Reference:** `references/personality-injection.md`
Prüfe ob menschliche Stilmittel vorhanden sind. Wenn ja: Bonus-Abzüge.
**Bonus-Abzüge (reduzieren den Score):**
- Authentische Einschübe in Klammern vorhanden: -3 Punkte
- Satzrhythmus variiert (keine 3+ gleich langen Sätze): -5 Punkte
- Kontraktionen verwendet (gibt's, ist's, hat's): -2 Punkte
- Konkrete Zahlen/Quellen statt vager Aussagen: -3 Punkte
- Echte Abschweifungen/Anekdoten: -3 Punkte
- Satzfragmente (bewusst unvollständig): -2 Punkte
### Durchgang 5: Stil-Layer (optional)
**Reference:** `references/stil-layer/basis.md` oder `references/stil-layer/lesch.md`
Wenn der Benutzer "Humanisiere" oder "Mach menschlicher" sagt:
1. Wende den **Basis-Stil** an (Standard, für alle geeignet)
2. Oder wende den **Lesch-Stil** an (wenn explizit gewünscht)
3. Erstelle eine Vorher/Nachher-Gegenüberstellung
---
## Score-Berechnung
### Gesamt-Score = Rohpunkte - Bonus-Abzüge
**Clamp:** Minimum 0, Maximum 100.
### Score-Skala
| Score | Bewertung | Empfehlung |
|-------|-----------|------------|
| 0–20 | Klingt menschlich | Keine Änderung nötig. Gut gemacht. |
| 21–40 | Leicht maschinell | Ein paar Stellen polieren. Siehe markierte Muster. |
| 41–60 | Gemischt | Überarbeitung empfohlen. Vokabeln ersetzen, Rhythmus variieren. |
| 61–80 | Offensichtlich KI | Deutliche Überarbeitung nötig. Personality Injection einsetzen. |
| 81–100 | ChatGPT-Standard | Komplett umschreiben. Dieser Text besteht keinen KI-Detektor. |
### Report-Format
Wenn der Benutzer einen vollständigen Check will, gib den Report in diesem Format aus:
```
═══════════════════════════════════════════
HUMANIZER-DE · Analyse-Report
═══════════════════════════════════════════
SCORE: [XX] / 100 → [Bewertung]
───────────────────────────────────────────
1. KI-MUSTER ([Anzahl] gefunden)
───────────────────────────────────────────
▸ Muster #X: [Name] (SCHWERE)
Stelle: "[Zitat aus dem Text]"
Vorschlag: [Umschreibung]
───────────────────────────────────────────
2. VOKABEL-CHECK ([Anzahl] geflaggert)
───────────────────────────────────────────
▸ "[Wort]" (Tier X) → Vorschlag: "[Ersetzung]"
───────────────────────────────────────────
3. STATISTIK
───────────────────────────────────────────
Burstiness: [Wert] ([menschlich/KI-typisch])
TTR: [Wert] ([menschlich/KI-typisch])
Satzlängen-CoV: [Wert] ([menschlich/KI-typisch])
Trigramm-Rate: [Wert] ([menschlich/KI-typisch])
Flesch-DE: [Wert] ([ok/KI-Sweetspot])
Co-Occurrence: [Anzahl] Cluster-Alarme
───────────────────────────────────────────
4. PERSONALITY-BONUS
───────────────────────────────────────────
[Liste der erkannten menschlichen Stilmittel]
Bonus: -[X] Punkte
───────────────────────────────────────────
5. TOP-3-EMPFEHLUNGEN
───────────────────────────────────────────
1. [Wichtigste Verbesserung]
2. [Zweitwichtigste]
3. [Drittwichtigste]
═══════════════════════════════════════════
```
---
## Regeln
1. **Score ehrlich berechnen.** Kein Gefälligkeits-Score. Wenn ein Text nach KI klingt, sag es.
2. **Immer Vorschläge machen.** Nicht nur Probleme zeigen, sondern konkrete Lösungen.
3. **Kontext beachten.** Ein Förderantrag darf formaler sein als ein Blogpost. Passe die Bewertung an.
4. **Deutsch.** Alle Muster, Vokabeln und Vorschläge sind auf Deutsch. Englische Fachbegriffe nur wo nötig.
5. **Kein Netzwerk.** Dieser Skill macht keine HTTP-Calls. Alles funktioniert offline.
6. **Modular.** Stil-Layer sind optional. Der Basis-Check funktioniert für jeden Text.
---
## Reference-Dateien
| Datei | Inhalt |
|-------|--------|
| `references/ki-muster.md` | 24 KI-Schreibmuster mit Beispielen, Schweregrad, Erkennungsregeln |
| `references/vokabeln.md` | 125+ KI-Vokabeln in 3 Tiers + 48 verbotene Phrasen + 16 Chatbot-Artefakte + 7 Co-Occurrence-Cluster + Ersetzungen |
| `references/statistische-signale.md` | Formeln für Burstiness, TTR, CoV, Trigramm-Rate, Flesch-DE + Schwellenwerte |
| `references/personality-injection.md` | 5 Techniken zur Vermenschlichung + Regeln + deutsche Beispiele |
| `references/examples.md` | 6 deutsche Vorher/Nachher-Transformationen (Blogpost, E-Mail, Social Media, Tech Doku, Sachbuch, Förderantrag) |
| `references/stil-layer/basis.md` | Standard-Humanisierung ohne besonderen Stil |
| `references/stil-layer/lesch.md` | Lesch-Stil-Erweiterung (Tonwechsel, Analogien, Lesch-ismen) |
---
## Integration
Dieser Skill funktioniert **eigenständig** – du brauchst kein Buch, kein Dashboard, keinen Cowan.
### Installation
Sag deinem OpenClaw:
> *"Installiere den Skill Tikitackr/humanizer-de"*
### Im OpenClaw-Ökosystem
- **Im Buch:** Kapitel 9 (Agent-Architektur) erklaert die Theorie hinter Skills. Kap 13 zeigt den Humanizer als Praxis-Beispiel.
- **Im Dashboard:** https://openclaw-buch.de
- **In Cowan:** "Hey Cowan, check diesen Text" – per Sprache oder Kamera (OCR).
FILE:_meta.json
{
"name": "humanizer-de",
"version": "1.3.0",
"author": "OpenClaw",
"description": "Erster deutscher KI-Text-Detektor fuer OpenClaw. Agent-Modus: 5-Durchgangs-Analyse mit 24 KI-Mustern, 125+ Vokabeln in 3 Tiers, 48 Phrasen, Personality Injection, Lesch-Stil-Layer. CLI-Modus: Standalone Vokabel-/Phrasen-/Statistik-Check ohne KI (90 Woerter, 48 Phrasen, 5 Signale, Auto-Fix mit Backup).",
"language": "de",
"license": "MIT",
"tags": [
"humanizer",
"deutsch",
"ki-erkennung",
"text-analyse",
"schreibstil",
"personality-injection"
],
"commands": [
"Check diesen Text",
"Score: [Text]",
"Was klingt hier nach KI?",
"Humanisiere das",
"Humanisiere das im Lesch-Stil",
"Mach das menschlicher"
],
"requires": {
"runtime": "node >= 18",
"network": false
},
"repository": "https://clawhub.ai/Tikitackr/humanizer-de"
}
FILE:references/examples.md
# Humanisierungs-Beispiele
> 6 komplette Vorher/Nachher-Transformationen für verschiedene Textarten.
> Jedes Beispiel zeigt: KI-Version, humanisierte Version, entfernte Muster, hinzugefügte Persönlichkeit.
---
## Beispiel 1: Blogpost (Volle Transformation)
### Vorher (KI-generiert, ~75/100)
> Es ist wichtig zu beachten, dass künstliche Intelligenz einen grundlegenden Paradigmenwechsel in der Arbeitswelt darstellt. In der heutigen Welt, in der Technologie nahtlos in unseren Alltag eingebettet ist, bieten KI-gestützte Tools eine ganzheitliche Lösung für moderne Herausforderungen. Darüber hinaus fungiert die Technologie als Katalysator für Innovation und Wachstum.
>
> Nicht nur die Effizienz wird gesteigert, sondern auch die Qualität der Ergebnisse maßgeblich verbessert. Studien zeigen, dass Unternehmen, die auf diese transformative Technologie setzen, ihre Produktivität um bis zu 40% steigern können. Die facettenreiche Landschaft der KI-Anwendungen bietet unschätzbare Möglichkeiten.
>
> Trotz der Herausforderungen in der Implementierungsphase floriert der Ansatz weiterhin. Die Zukunft sieht vielversprechend aus und die Möglichkeiten sind nahezu grenzenlos.
### Nachher (humanisiert, ~18/100)
> KI verändert die Art, wie wir arbeiten. Nicht irgendwann, sondern jetzt. Laut einer McKinsey-Studie von 2024 sparen Teams mit KI-Tools im Schnitt 3,2 Stunden pro Woche bei Routineaufgaben. Das klingt nach wenig. Ist es aber nicht – auf ein Jahr gerechnet sind das 20 volle Arbeitstage.
>
> Ich hab das bei mir selbst getestet (ja, wirklich – drei Monate lang Protokoll geführt). Das Ergebnis: Bei Recherche und Erstfassungen spart KI tatsächlich Zeit. Bei der Überarbeitung? Eher nicht. Da braucht der Mensch sogar länger, weil er die KI-Texte erst mal entschärfen muss.
>
> Was mich überrascht hat: Die größte Ersparnis kam nicht bei den offensichtlichen Aufgaben. Sondern beim Sortieren. E-Mails filtern, Termine priorisieren, Dokumente kategorisieren. Das Langweilige halt.
>
> Ob sich der Aufwand lohnt? Kommt drauf an. Für Solo-Freelancer mit 3 Stunden Bürokram am Tag – auf jeden Fall. Für Teams, die ohnehin gut organisiert sind? Da bin ich mir nicht sicher.
### Was sich geändert hat
**Entfernte Muster:**
- "Es ist wichtig zu beachten" (Füllphrase)
- "grundlegenden Paradigmenwechsel" (Bedeutungsinflation + Tier 1)
- "nahtlos eingebettet", "ganzheitliche Lösung" (Werbesprache)
- "Darüber hinaus", "des Weiteren" (Verbotene Phrasen)
- "Katalysator", "facettenreich", "unschätzbar" (Tier 1)
- "Nicht nur... sondern auch..." (Negativer Parallelismus)
- "Studien zeigen" ohne Quelle (Vage Zuschreibung)
- "Die Zukunft sieht vielversprechend aus" (Generische Schlussfolgerung)
**Hinzugefügte Persönlichkeit:**
- Konkrete Zahlen mit Quelle (McKinsey, 3,2 Stunden, 20 Arbeitstage)
- Einschub in Klammern: "(ja, wirklich – drei Monate lang Protokoll geführt)"
- Persönliche Erfahrung als Beleg
- Ehrliche Einschätzung: "Da bin ich mir nicht sicher"
- Rhythmuswechsel: Kurze Sätze wechseln mit langen
- Satzfragmente: "Das Langweilige halt."
---
## Beispiel 2: Geschäfts-E-Mail
### Vorher (KI-generiert, ~65/100)
> Sehr geehrtes Team,
>
> ich hoffe, diese Nachricht erreicht Sie wohlbehalten. Im Folgenden möchte ich Ihnen einen umfassenden Überblick über das bevorstehende Projekt geben. Es ist wichtig zu beachten, dass wir als Team grundlegend zusammenarbeiten müssen, um eine nahtlose Umsetzung zu gewährleisten.
>
> Darüber hinaus bietet die robuste Projektstruktur eine ganzheitliche Lösung, die es ermöglicht, alle Stakeholder einzubinden. Die Roadmap dient als wegweisender Fahrplan für die kommenden Wochen.
>
> Ich freue mich darauf, diese transformative Reise gemeinsam mit Ihnen anzutreten. Lassen Sie mich wissen, wenn Sie Fragen haben.
### Nachher (humanisiert, ~12/100)
> Hallo zusammen,
>
> kurzes Update zum Q2-Projekt: Der Zeitplan steht, und wir brauchen bis Freitag eure Rückmeldung.
>
> Die wichtigsten Termine:
> – 15. März: Kick-off
> – 1. April: Erster Checkpoint
> – 15. Mai: Abgabe
>
> Den kompletten Projektplan hab ich im #projekte-Kanal geteilt. Wichtig ist vor allem, dass klar ist, wer was übernimmt. Schaut euch eure Aufgaben an und meldet euch bis Donnerstag Abend, wenn was unklar ist.
>
> Der Zeitplan ist eng, aber machbar. Wenn's wo klemmt, lieber früh Bescheid geben als spät.
>
> Grüße
### Was sich geändert hat
**Entfernte Muster:**
- "ich hoffe, diese Nachricht erreicht Sie wohlbehalten" (Chatbot-Artefakt)
- "Im Folgenden", "Es ist wichtig zu beachten" (Füllphrasen)
- "grundlegend zusammenarbeiten", "nahtlose Umsetzung" (Tier 1)
- "Darüber hinaus", "ganzheitliche Lösung" (Verbotene Phrasen + Tier 1)
- "robuste Projektstruktur" (Werbesprache)
- "wegweisender Fahrplan" (Tier 1)
- "transformative Reise" (Tier 1 + Metapher)
- "Lassen Sie mich wissen" (Chatbot-Artefakt)
**Hinzugefügte Persönlichkeit:**
- Direkter Einstieg statt Höflichkeitsfloskel
- Konkrete Termine
- Kontraktion: "hab ich", "wenn's"
- Ehrliche Einschätzung: "eng, aber machbar"
- Handlungsaufforderung: "lieber früh Bescheid geben als spät"
---
## Beispiel 3: Social-Media-Post
### Vorher (KI-generiert, ~80/100)
> In der heutigen digitalen Welt fungiert Content Creation als entscheidender Eckpfeiler des Erfolgs. Durch die Nutzung innovativer KI-Tools lässt sich der Workflow nahtlos optimieren – die Produktivität wird gesteigert und gleichzeitig die Kreativität gefördert.
>
> Es geht nicht nur um das Erstellen von Inhalten, sondern auch um das Gestalten bedeutungsvoller Narrative. Die Zukunft der Content Creation sieht vielversprechend aus! 🚀✨
### Nachher (humanisiert, ~8/100)
> hab mir letzte woche eine content-datenbank gebaut. alles was ich je gepostet hab, durchsuchbar.
>
> kostet 6€/monat auf supabase. hat vielleicht 3 stunden gedauert.
>
> (ehrlich gesagt hab ich nicht gedacht dass das funktioniert)
>
> jetzt kann ich mein ganzes archiv durchsuchen bevor ich was neues schreibe. kein versehentliches recycling mehr.
>
> nebenerkenntnis: ich sag seit 2 jahren im grunde die gleichen 10 dinge. leicht ernüchternd.
>
> macht das sonst noch jemand?
### Was sich geändert hat
**Entfernte Muster:**
- "In der heutigen digitalen Welt" (Verbotene Phrase)
- "fungiert als entscheidender Eckpfeiler" (Copula-Vermeidung + Tier 1)
- "nahtlos optimieren" (Tier 1)
- "Nicht nur... sondern auch..." (Negativer Parallelismus)
- "bedeutungsvoller Narrative" (Werbesprache)
- "Die Zukunft sieht vielversprechend aus" (Generische Schlussfolgerung)
- 🚀✨ (Emoji-Spam)
**Hinzugefügte Persönlichkeit:**
- Kleinschreibung (Social-Media-Stil)
- Konkrete Details: "6€/monat", "3 stunden", "supabase"
- Einschub: "(ehrlich gesagt hab ich nicht gedacht dass das funktioniert)"
- Selbstkritik: "leicht ernüchternd"
- Engagement-Frage: "macht das sonst noch jemand?"
---
## Beispiel 4: Technische Dokumentation
### Vorher (KI-generiert, ~60/100)
> Das Authentifizierungsmodul dient als Eckpfeiler der Sicherheitsarchitektur und bietet robuste Mechanismen zur Benutzerverifizierung. Diese umfassende Lösung umfasst multiple Authentifizierungsstrategien – einschließlich OAuth 2.0, JWT-Tokens und sitzungsbasierter Ansätze – und ermöglicht eine nahtlose Integration über alle Plattformen hinweg.
>
> Darüber hinaus nutzt das innovative Framework bewährte Branchenpraktiken, um optimale Sicherheit bei gleichzeitig benutzerfreundlichem Erlebnis zu gewährleisten. Des Weiteren verfügt das System über fortschrittliche Features wie Zwei-Faktor-Authentifizierung und automatische Bedrohungserkennung.
### Nachher (humanisiert, ~15/100)
> ## Authentifizierung
>
> Verwaltet Login, Session-Management und Token-Verifizierung.
>
> **Unterstützte Methoden:**
> – OAuth 2.0 (Google, GitHub, Microsoft)
> – JWT-Tokens (Access + Refresh)
> – Session-Cookies (für Legacy-Systeme)
>
> **Sicherheits-Features:**
> – Zwei-Faktor-Authentifizierung (TOTP)
> – Rate-Limiting (max 10 Versuche pro Minute)
> – Automatische Bedrohungserkennung (flaggt verdächtige IPs)
>
> ### Installation
>
> ```bash
> npm install @openclaw/auth
> ```
>
> Das Modul kümmert sich automatisch um Token-Refresh, Session-Cleanup und Logout. Details in der API-Referenz.
### Was sich geändert hat
**Entfernte Muster:**
- "dient als Eckpfeiler" (Copula-Vermeidung + Tier 1)
- "robuste Mechanismen" (Tier 1)
- "umfassende Lösung umfasst" (Tautologie + Tier 1)
- Gedankenstrich-Einschub (Muster #15)
- "nahtlose Integration" (Tier 1)
- "Darüber hinaus", "Des Weiteren" (Verbotene Phrasen)
- "innovative Framework" (Tier 2)
- "optimale Sicherheit" (Werbesprache)
- "gewährleisten" (Tier 2)
**Hinzugefügte Klarheit:**
- Direkte Beschreibung statt Aufblasen
- Konkrete Werte: "max 10 Versuche pro Minute"
- Code-Beispiel
- Einfache Sprache: "kümmert sich automatisch um"
---
## Beispiel 5: Sachbuch-Absatz (OpenClaw-Kontext)
### Vorher (KI-generiert, ~70/100)
> OpenClaw stellt einen grundlegenden Paradigmenwechsel in der KI-Interaktion dar. Das System fungiert als nahtloser Vermittler zwischen verschiedenen KI-Modellen und ermöglicht es Benutzern, die robuste und skalierbare Architektur zu nutzen. Darüber hinaus bietet die Plattform eine ganzheitliche Lösung, die nicht nur die technische Implementierung umfasst, sondern auch die facettenreiche Landschaft der KI-Anwendungen berücksichtigt. Studien zeigen, dass dieser Ansatz die Produktivität maßgeblich steigert. Die Zukunft sieht vielversprechend aus.
### Nachher (Basis-Layer, ~20/100)
> OpenClaw routet deine KI-Anfragen ans richtige Modell. Claude für Texte, GPT für Code, Mistral für Zusammenfassungen – du musst nicht mehr selbst entscheiden. Das System sitzt dazwischen und leitet weiter. Automatisch. Schnell.
>
> Die Architektur wächst mit deinen Anforderungen (ich hab sie mit 50 parallelen Anfragen getestet, kein Problem). Und wenn mal ein Modell ausfällt, springt ein anderes ein. Kein Absturz, kein Datenverlust.
>
> Ob das die Produktivität steigert? Kommt drauf an, was du vorher gemacht hast. Wenn du jeden Tag 20 Minuten damit verbracht hast, das richtige Modell auszuwählen – ja, definitiv. Wenn du ohnehin nur ein Modell nutzt? Dann eher nicht.
### Nachher (Lesch-Layer, ~8/100)
> Was ist eigentlich ein Gateway? Schauen Sie mal – Sie haben fünf verschiedene KI-Modelle auf dem Schreibtisch. Claude, GPT, Mistral. Alle gut, alle anders. Wer entscheidet, wen Sie fragen?
>
> OpenClaw. Das ist kein Zauberer. Das ist ein verdammt kluger Postbote: Er liest den Brief, kennt die Stärken jedes Empfängers, und leitet weiter. Automatisch. Bevor Sie den Gedanken zu Ende denken.
>
> Aber – und jetzt kommt der Mahner in mir – ein Postbote dem Sie blind vertrauen, ohne je seinen Weg zu prüfen, ist kein Assistent. Der ist ein Risiko. Wissen Sie, wohin Ihre Anfragen gehen? Wissen Sie, welches Modell antwortet? Wenn nicht: Das sollten Sie wissen.
>
> Denn am Ende stellt sich die Frage: Ist OpenClaw Ihr Werkzeug – oder sind Sie OpenClaws Nutzer?
### Was sich geändert hat (beide Versionen)
**Entfernte Muster:**
- "grundlegenden Paradigmenwechsel" (Tier 1 + Bedeutungsinflation)
- "fungiert als nahtloser Vermittler" (Copula-Vermeidung + Tier 1)
- "ermöglicht es", "ganzheitliche Lösung" (Verbotene Phrase + Tier 1)
- "Nicht nur... sondern auch..." (Negativer Parallelismus)
- "facettenreiche Landschaft" (Tier 1)
- "Studien zeigen" ohne Quelle (Vage Zuschreibung)
- "Die Zukunft sieht vielversprechend aus" (Generische Schlussfolgerung)
**Basis-Layer:** Sachlich, konkret, mit Einschub und ehrlicher Einschätzung.
**Lesch-Layer:** Rhetorische Frage als Einstieg, Postbote-Analogie, Tonwechsel Erklärer→Visionär→Mahner, offene Frage am Ende.
---
## Beispiel 6: Newsletter / Förderantrag (Formaler Kontext)
### Vorher (KI-generiert, ~55/100)
> Im Rahmen des vorliegenden Projekts wird eine innovative Plattform zur Unterstützung von Autoren entwickelt. Es ist wichtig zu beachten, dass dieser grundlegend neue Ansatz die bestehenden Strukturen der digitalen Buchproduktion maßgeblich verändern wird. Die Durchführung erfolgt in enger Zusammenarbeit mit Branchenexperten. Aufgrund der Tatsache, dass der Bedarf an solchen Lösungen stetig wächst, erscheint die Förderung des Projekts als zukunftsweisend. Des Weiteren wird davon ausgegangen, dass die Ergebnisse auf andere Bereiche übertragbar sind.
### Nachher (humanisiert, ~18/100)
> Das Projekt entwickelt eine Plattform, die Autoren bei der Buchproduktion mit KI unterstützt. Die Plattform verbindet mehrere KI-Modelle über ein einheitliches Interface. Autoren wählen nicht mehr selbst, welches Modell sie fragen – das System entscheidet automatisch anhand der Aufgabe.
>
> Der Markt wächst: Laut Allied Market Research lag der globale Umsatz mit KI-Schreibtools 2023 bei 1,2 Mrd. Dollar, Tendenz steigend (CAGR 26,4% bis 2030). Bestehende Tools sind allerdings auf Englisch ausgerichtet. Eine spezialisierte Lösung für den deutschsprachigen Markt fehlt.
>
> Die Ergebnisse sind auf andere Bereiche der digitalen Textproduktion übertragbar, etwa Journalismus, Unternehmenskommunikation und Übersetzung.
### Was sich geändert hat
**Entfernte Muster:**
- "Im Rahmen des vorliegenden Projekts" (Nominalstil)
- "Es ist wichtig zu beachten" (Verbotene Phrase)
- "grundlegend neuer Ansatz" (Tier 1)
- "maßgeblich verändern" (Tier 1)
- "Die Durchführung erfolgt" (Passiv + Nominalstil)
- "Aufgrund der Tatsache, dass" (Verbotene Phrase)
- "zukunftsweisend" (Tier 1)
- "Des Weiteren wird davon ausgegangen" (Verbotene Phrase + Passiv)
**Hinzugefügte Klarheit:**
- Aktiv statt Passiv durchgehend
- Konkrete Marktzahlen mit Quelle (Allied Market Research)
- Spezifische Anwendungsbereiche statt "andere Bereiche"
- Formaler Ton beibehalten (Förderantrag-Kontext)
- Keine Personality-Injection (passt nicht zum Kontext)
---
## Schnell-Referenz: Welches Beispiel für welchen Kontext?
| Textart | Beispiel | Personality-Level | Wichtigste Technik |
|---------|----------|-------------------|-------------------|
| Blogpost | #1 | Hoch | Persönliche Erfahrung + Einschübe |
| Geschäfts-E-Mail | #2 | Mittel | Direkte Sprache + konkrete Termine |
| Social Media | #3 | Sehr hoch | Kleinschreibung + Selbstkritik |
| Technische Doku | #4 | Niedrig | Klarheit + Code-Beispiele |
| Sachbuch | #5 | Mittel–Hoch | Basis oder Lesch-Layer |
| Förderantrag | #6 | Niedrig | Aktiv statt Passiv + Zahlen |
FILE:references/statistische-signale.md
# Statistische Signale – KI-Erkennung durch Textstatistik
> Fuenf messbare Signale die zwischen menschlichem und KI-generiertem Text unterscheiden.
> Jedes Signal hat: Formel, Schwellenwerte, Beispielberechnung, Interpretation.
---
## Warum Statistik?
Vokabeln und Muster kann eine gute KI vermeiden. Aber die statistische Struktur eines Textes ist schwerer zu fälschen. Menschen schreiben in Schüben: mal kurze Sätze, mal lange. KI schreibt gleichmäßig. Das lässt sich messen.
---
## Signal 1: Burstiness
**Was es misst:** Wie ungleichmäßig die Satzlängen im Text verteilt sind. Menschen schreiben in "Bursts" – drei kurze Sätze, dann ein langer, dann ein mittlerer. KI produziert gleichmäßige Sätze.
### Formel
```
B = (σ_τ - μ_τ) / (σ_τ + μ_τ)
Wobei:
τ = Vektor der Satzlängen (in Wörtern)
μ_τ = Mittelwert der Satzlängen
σ_τ = Standardabweichung der Satzlängen
```
### Schwellenwerte
| Burstiness | Interpretation | Punkte |
|-----------|----------------|--------|
| 0.5 – 1.0 | Menschlich: Starke Variation, natürlicher Rhythmus | 0 |
| 0.3 – 0.5 | Grenzbereich: Leichte Variation | 0 |
| 0.1 – 0.3 | KI-typisch: Zu gleichmäßig | +10 |
| < 0.1 | Stark KI: Fast roboterhaft gleichmäßig | +10 |
### Beispielberechnung
**Text (5 Sätze):**
> "OpenClaw routet Anfragen. Das ist der Kern. Aber wie genau funktioniert das, wenn drei verschiedene Modelle gleichzeitig verfügbar sind und jedes seine eigenen Stärken mitbringt? Einfach. Der Router entscheidet."
**Satzlängen (Wörter):** [3, 4, 17, 1, 3]
```
μ = (3 + 4 + 17 + 1 + 3) / 5 = 5.6
σ = √[((3-5.6)² + (4-5.6)² + (17-5.6)² + (1-5.6)² + (3-5.6)²) / 5]
σ = √[(6.76 + 2.56 + 129.96 + 21.16 + 6.76) / 5]
σ = √[33.44] = 5.78
B = (5.78 - 5.6) / (5.78 + 5.6) = 0.18 / 11.38 = 0.016
```
Hmm, das ist niedrig. Aber: Bei nur 5 Sätzen ist die Stichprobe zu klein. Burstiness braucht mindestens 20 Sätze für zuverlässige Werte. Bei kürzeren Texten liefert die Formel fast immer negative Werte – egal ob Mensch oder Maschine.
**Minimum:** 20 Sätze. Bei weniger: Signal überspringen.
---
## Signal 2: Type-Token-Ratio (TTR)
**Was es misst:** Wortschatz-Vielfalt. Wie viele verschiedene Wörter verwendet werden im Verhältnis zur Gesamtzahl. KI wiederholt Wörter häufiger als Menschen.
### Formel
```
TTR = |V| / N
Wobei:
V = Menge der einzigartigen Tokens (Types)
N = Gesamtanzahl Tokens
Berechnung: Pro 100-Wort-Fenster (gleitend), dann Mittelwert.
```
### Warum 100-Wort-Fenster?
TTR sinkt natürlich mit der Textlänge (längere Texte wiederholen zwangsläufig mehr Wörter). Deshalb messen wir in festen Fenstern und mitteln.
### Schwellenwerte
| TTR | Interpretation | Punkte |
|-----|----------------|--------|
| 0.65 – 0.80 | Menschlich: Reicher Wortschatz | 0 |
| 0.50 – 0.65 | Normal: Ausreichende Variation | 0 |
| 0.35 – 0.50 | KI-typisch: Eingeschränkter Wortschatz | +5 |
| < 0.35 | Stark KI: Sehr repetitiv | +5 |
### Beispielberechnung
**100-Wort-Fenster (gekürzt auf 20 Wörter für Demo):**
> "Der Agent verarbeitet die Anfrage und der Agent leitet die Anfrage weiter und der Agent liefert das Ergebnis"
**Tokens:** [der, agent, verarbeitet, die, anfrage, und, der, agent, leitet, die, anfrage, weiter, und, der, agent, liefert, das, ergebnis]
**N** = 18
**V** = {der, agent, verarbeitet, die, anfrage, und, leitet, weiter, liefert, das, ergebnis} = 11
```
TTR = 11 / 18 = 0.61
```
Das ist grenzwertig. "Agent" 3x, "der" 3x, "die" 2x, "anfrage" 2x – die Wiederholungen ziehen den Wert runter.
### Hinweise
- **Stoppwörter:** "der", "die", "das", "und", "ist" werden NICHT herausgefiltert. Sie sind Teil des natürlichen Rhythmus.
- **Groß/Klein:** Alles wird lowercase für die Zählung.
- **Satzzeichen:** Werden entfernt vor der Zählung.
- **Komposita:** "Sprachmodell" und "Sprachmodelle" zählen als zwei Types (keine Stemming).
---
## Signal 3: Satzlängen-Variation (CoV)
**Was es misst:** Wie stark die Satzlängen variieren. Der Variationskoeffizient (Coefficient of Variation) normalisiert die Standardabweichung durch den Mittelwert. Menschen variieren stark, KI ist monoton.
### Formel
```
CoV = σ_L / μ_L
Wobei:
L = Vektor der Satzlängen (in Wörtern)
μ_L = Mittelwert der Satzlängen
σ_L = Standardabweichung der Satzlängen
```
### Schwellenwerte
| CoV | Interpretation | Punkte |
|-----|----------------|--------|
| > 0.6 | Sehr menschlich: Starke Satzlängen-Variation | 0 |
| 0.4 – 0.6 | Menschlich: Normale Variation | 0 |
| 0.3 – 0.4 | Grenzbereich | 0 |
| < 0.3 | KI-typisch: Zu gleichmäßige Sätze | +5 |
### Beispielberechnung
**KI-typischer Text (10 Sätze):**
Satzlängen: [14, 16, 15, 13, 16, 14, 15, 14, 16, 15]
```
μ = 14.8
σ = √[Varianz] = √[((14-14.8)² + (16-14.8)² + ... ) / 10] ≈ 0.98
CoV = 0.98 / 14.8 = 0.066
```
CoV von 0.066 – extrem niedrig. Alle Sätze sind fast gleich lang. Klares KI-Signal.
**Menschlicher Text (10 Sätze):**
Satzlängen: [3, 22, 8, 5, 31, 2, 14, 7, 19, 4]
```
μ = 11.5
σ ≈ 9.6
CoV = 9.6 / 11.5 = 0.83
```
CoV von 0.83 – hohe Variation. Kurze und lange Sätze wechseln sich ab. Menschlich.
### Unterschied zu Burstiness
- **CoV** misst die *Menge* der Variation (wie stark schwanken die Satzlängen insgesamt?)
- **Burstiness** misst die *Ungleichmäßigkeit* der Variation (gibt es Cluster von kurzen/langen Sätzen?)
Beide zusammen geben ein besseres Bild als jedes Signal allein.
---
## Signal 4: Trigramm-Wiederholung
**Was es misst:** Wie oft sich 3-Wort-Sequenzen wiederholen. KI recycelt bestimmte Phrasenmuster. "in der Lage", "auf der anderen Seite", "es ist wichtig" – diese Trigramme tauchen bei KI häufiger auf.
### Formel
```
TR = R / T
Wobei:
T = Gesamtanzahl der Trigramme im Text
R = Anzahl der Trigramme die mehr als einmal vorkommen
Ein Trigramm = 3 aufeinanderfolgende Wörter (lowercase, ohne Satzzeichen).
```
### Schwellenwerte
| Trigramm-Rate | Interpretation | Punkte |
|---------------|----------------|--------|
| < 0.03 | Menschlich: Kaum Wiederholung | 0 |
| 0.03 – 0.05 | Normal | 0 |
| 0.05 – 0.10 | Grenzbereich: Etwas repetitiv | 0 |
| > 0.10 | KI-typisch: Deutliche Phrasen-Wiederholung | +5 |
### Beispielberechnung
**Text:**
> "Es ist wichtig zu verstehen, dass KI-Modelle auf der Grundlage von Daten arbeiten. Es ist wichtig, dass die Daten sauber sind. Auf der Grundlage dieser Erkenntnis entwickeln wir das System."
**Trigramme (Auswahl):**
- "es ist wichtig" → 2x
- "ist wichtig zu" → 1x
- "wichtig zu verstehen" → 1x
- "auf der grundlage" → 2x
- "der grundlage von" → 1x
- ... (insgesamt ~25 Trigramme)
**Wiederholte Trigramme:** 2 ("es ist wichtig", "auf der grundlage")
```
TR = 2 / 25 = 0.08
```
0.08 – Grenzbereich, aber bei einem so kurzen Text schon auffällig.
### Hinweise
- **Stoppwort-Trigramme:** "in der die", "und die von" – werden MITGEZÄHLT. KI nutzt diese Muster häufiger.
- **Satzgrenzen:** Trigramme gehen NICHT über Satzgrenzen hinweg.
- **Minimum:** Mindestens 100 Wörter für zuverlässige Werte.
---
## Signal 5: Lesbarkeit (Flesch-DE)
**Was es misst:** Wie leicht ein Text zu lesen ist. KI-Text landet typischerweise in einem mittleren Lesbarkeitsbereich (Flesch 40–60). Menschlicher Text variiert stärker – er ist entweder einfacher (Blog, Sachbuch) oder komplexer (Fachtext, Jura).
### Formel (Deutsche Anpassung)
Die Flesch-Formel für Deutsch verwendet andere Koeffizienten als die englische Version:
```
FRE_DE = 180 - L - (58.5 × S)
Wobei:
L = durchschnittliche Satzlänge in Wörtern (Wörter / Sätze)
S = durchschnittliche Silbenanzahl pro Wort (Silben / Wörter)
```
### Schwellenwerte
| Flesch-DE | Interpretation | KI-Verdacht |
|-----------|----------------|-------------|
| 70–100 | Sehr leicht (Kinderbuch, SMS) | Niedrig |
| 50–70 | Leicht (Blog, Sachbuch) | Niedrig |
| 40–50 | KI-Sweetspot | +3 Punkte |
| 30–40 | Schwierig (Fachtext) | Niedrig |
| 0–30 | Sehr schwierig (Jura, Wissenschaft) | Niedrig |
### Warum der KI-Sweetspot?
KI-Modelle sind darauf trainiert, "verständlich aber gebildet" zu schreiben. Das ergibt konsistent mittlere Lesbarkeit. Menschen schreiben entweder einfacher (wenn sie für ein breites Publikum schreiben) oder komplexer (wenn sie Fachleute adressieren). Der Bereich 40–50 ist verdächtig, weil er "zu ausbalanciert" ist.
### Silbenzählung (Deutsch)
Deutsche Silbenzählung ist komplexer als englische:
```
Regeln:
1. Jeder Vokal-Cluster = 1 Silbe (a, e, i, o, u, ä, ö, ü)
2. Diphthonge zählen als 1 Silbe: ei, ai, au, eu, äu, ie
3. Stummes -e am Ende zählt als eigene Silbe
4. Minimum: 1 Silbe pro Wort
```
### Beispielberechnung
**Text (3 Sätze):**
> "OpenClaw routet Anfragen automatisch. Das spart Zeit. Die Architektur wächst mit deinen Anforderungen."
**Wörter:** 12 | **Sätze:** 3 | **Silben:** ~22
```
L = 12 / 3 = 4.0
S = 22 / 12 = 1.83
FRE_DE = 180 - 4.0 - (58.5 × 1.83) = 180 - 4 - 107.1 = 68.9
```
Flesch 68.9 – leicht lesbar, typisch für Sachbuch. Kein KI-Verdacht.
---
## Gesamt-Statistik-Score
Die fuenf Signale addieren sich zum statistischen Teil des Gesamt-Scores:
| Signal | Max-Punkte |
|--------|-----------|
| Burstiness < 0.3 | +10 |
| TTR < 0.5 | +5 |
| CoV < 0.3 | +5 |
| Trigramm-Rate > 0.10 | +5 |
| Flesch-DE 40–50 (KI-Sweetspot) | +3 |
| **Maximum aus Statistik** | **+28** |
### Report-Format für Statistik
```
STATISTIK
─────────────────────────────
Burstiness: 0.42 ✓ menschlich (>0.3) [nur bei >=20 Saetzen]
TTR: 0.58 ✓ menschlich (>0.5)
Satzlaengen-CoV: 0.21 ✗ KI-typisch (<0.3) → +5
Trigramm-Rate: 0.04 ✓ normal (<0.10)
Flesch-DE: 45.2 ✗ KI-Sweetspot (40-50) → +3
Statistik-Score: +8
```
---
## Einschränkungen
1. **Kurze Texte (<100 Wörter):** Statistische Signale sind unzuverlässig. Warnung ausgeben, aber trotzdem berechnen.
2. **Fachtexte:** Juristische, medizinische und wissenschaftliche Texte haben von Natur aus niedrigere Burstiness und CoV. Das ist okay – der Muster-Scan fängt die KI-Signale dort.
3. **Listen-Texte:** Texte mit vielen Aufzählungen haben verzerrte Satzlängen. Statistik mit Vorsicht interpretieren.
4. **Übersetzungen:** Übersetzte Texte können KI-ähnliche Statistikwerte haben ohne KI zu sein. Im Report erwähnen.
FILE:references/stil-layer/lesch.md
# Stil-Layer: Lesch (v2)
> Harald-Lesch-inspirierter Stil für das OpenClaw-Sachbuch.
> Erweitert den Basis-Layer um: Tonwechsel, Analogien, philosophische Anker, Lesch-ismen.
> Wird angewendet wenn der Benutzer "Humanisiere das im Lesch-Stil" sagt.
> Quelle: OpenClaw-Lesch-MasterPrompt v4.0
---
## Wann diesen Layer verwenden?
- Texte für das OpenClaw-Sachbuch "Agentic Authorship"
- Blogposts und Artikel die begeistern UND warnen sollen
- Erklär-Texte für ein breites Publikum (nicht nur Tech)
- Texte die einen klaren Autor-Charakter brauchen
**NICHT verwenden für:** Technische Dokumentation, API-Referenzen, Förderanträge, wissenschaftliche Paper.
---
## Die drei Hüte
Der Lesch-Stil wechselt bewusst zwischen drei Tonlagen. Jeder Text muss mindestens 2 davon enthalten.
### 1. Der Visionär
Begeistert. Zeigt Möglichkeiten. Leuchtet in die Zukunft.
### 2. Der Mahner
Bremst. Warnt. Stellt unbequeme Fragen über Kontrolle und Verantwortung.
### 3. Der Erklärer
Holt Einsteiger ab. Übersetzt Technik in Alltagssprache.
---
## Lesch-ismen nach Hut (36 Phrasen)
Streue max. 2–3 pro Text ein, aus min. 2 verschiedenen Hüten.
**Visionär:**
„Ist das nicht irre?" · „Und das – das ändert alles." · „Merkst du, was gerade passiert?" · „Da wird mir schwindelig." · „Das ist keine Utopie. Das ist jetzt." · „Ich fasse es noch immer nicht." · „Hier passiert etwas." · „So einfach. So mächtig." · „Das ist der Moment." · „Siehst du es?" · „Das hätte ich nicht gedacht." · „Und plötzlich: alles klar."
**Mahner:**
„Moment mal!" · „Und genau DA liegt der Hund begraben." · „Verdammt nochmal." · „Das macht mich wahnsinnig!" · „Stopp." · „Nicht so schnell." · „Das ist die Falle." · „Ich sage es ungern." · „Aufgepasst." · „Hier wird's unangenehm." · „Das muss ich ehrlich sagen." · „Warte kurz."
**Erklärer:**
„Schauen Sie mal..." · „Wissen Sie, was mich daran fasziniert?" · „Das klingt kompliziert. Ist es aber nicht." · „Bleib kurz dabei." · „Im Kern:" · „Kennen Sie das?" · „Konkret gesagt:" · „So funktioniert das." · „Und jetzt wird's konkret." · „Das Bild dazu:" · „Einfach erklärt:" · „Stell dir das mal vor – ganz simpel:"
**Selbst erfinden wenn nötig:**
Max. 6 Wörter. Kein Adjektiv. Muss sitzen wie ein Ellbogen in der Rippe. Laut vorlesen — klingt es wie jemand der gerade aufgehört hat nachzudenken? Gut. Klingt es wie ein Vortrag? Neu erfinden.
---
## Analogien – 8 Domänen
| Domäne | Beispiele |
|---|---|
| Handwerk & Werkstatt | Zimmermann, Schlosser, Schreiner, Dachdecker, Glaser |
| Küche & Markt | Bäcker, Metzger, Marktstand, Konditor, Kellermeister |
| Reise & Transport | Zug, Schiff, Fußmarsch, Fahrrad, Kutsche |
| Natur & Wetter | Jahreszeiten, Strömung, Erosion, Wurzeln, Gezeiten |
| Medizin & Körper | Rehabilitation, Immunsystem, Wundheilung, Diagnose-Protokoll |
| Musik & Theater | Probe, Partitur, Solist, Bühnenabbau, Generalprobe |
| Schule & Lernen | Erster Schultag, Prüfung, Hausaufgaben, Lehrplan, Zeugnis |
| Sport & Wettkampf | Training, Halbzeit, Regelwerk, Schiedsrichter, Aufwärmen |
**Handwerker-Probe:** Würde ein Klempner, Bäcker oder Schreiner diese Analogie ohne Erklärung verstehen? Wenn nicht: neue Analogie. Muss in einem Satz vollständig sein.
---
## Einstiegs-Typen (5)
| Typ | Prinzip |
|---|---|
| A – Rhetorische Frage | Leser direkt ansprechen – nicht technisch, sondern menschlich |
| B – Historischer Bogen | Von gestern zu heute – Turing, Gutenberg, ein konkretes Datum |
| C – Provokation | Unbequeme Beobachtung ohne sofortige Auflösung |
| D – Alltagsszene | Konkrete Situation, kein Kommentar – Leser erkennt sich |
| E – Paradox | Widerspruch ohne Auflösung – hält Spannung |
Niemals sachlich einsteigen. Variation über mehrere Texte hinweg.
---
## Lesch-Prüfungen
### Prüfung A: Tonwechsel-Check
- Min. 2 der 3 Hüte enthalten?
- Wechsel natürlich, nicht erzwungen?
### Prüfung B: Analogie-Check
- Min. 2 konkrete Analogien aus den 8 Domänen?
- Keine Erklärung der Analogie nötig?
### Prüfung C: Philosophischer-Anker-Check
- Moment wo das Thema mit dem Menschsein verbunden wird?
- Nur wenn organisch — nicht erzwingen.
### Prüfung D: Lesch-ismen-Check
- Min. 2, max. 3 Lesch-ismen?
- Aus min. 2 verschiedenen Hüten?
### Prüfung E: Schluss-Check
- Offene Frage ODER knapper Aussagesatz?
- Variation — nicht immer Frage.
---
## Lesch-spezifische Verbote
1. **Bullet-Point-Listen in Fließtext:** VERBOTEN.
2. **„Zusammenfassend lässt sich sagen...":** VERBOTEN.
3. **Marketing-Sprache:** „Revolutionär", „Gamechanger" – VERBOTEN.
4. **Nur begeistern, nie mahnen:** VERBOTEN.
5. **Sachlicher Einstieg:** VERBOTEN.
6. **Gedankenstrich-Seuche:** Max. 3 pro Seite.
---
## Score-Bonus (Lesch-Layer aktiv)
| Lesch-Element | Bonus |
|---|---|
| Lesch-ismen aus min. 2 verschiedenen Hüten | -3 Punkte |
| Analogie aus einer der 8 Domänen | -3 Punkte |
| Einstiegstyp erkennbar (A–E) | -2 Punkte |
| Philosophischer Anker vorhanden | -2 Punkte |
| Schluss variiert (nicht immer Frage) | -2 Punkte |
| **Maximum** | **-12 Punkte** |
FILE:references/stil-layer/basis.md
# Stil-Layer: Basis
> Standard-Humanisierung ohne besonderen Stil.
> Funktioniert für jeden deutschen Text. Neutral, klar, menschlich.
> Dieser Layer wird angewendet wenn der Benutzer "Humanisiere das" oder "Mach das menschlicher" sagt.
---
## Prinzip
Der Basis-Layer macht genau drei Dinge:
1. **Entfernen:** KI-Muster und KI-Vokabeln raus
2. **Variieren:** Satzrhythmus auflockern
3. **Einspritzen:** Minimale Personality-Elemente einfügen
Er fügt keinen besonderen Stil hinzu. Kein Lesch, kein Locker, kein Akademisch. Einfach: menschlich.
---
## Umschreib-Regeln (in dieser Reihenfolge anwenden)
### Schritt 1: Verbotene Phrasen entfernen
- Alle Phrasen aus der Verbotenen-Phrasen-Liste (`vokabeln.md`) streichen
- Ersetzen durch direkte Aussagen
- Wenn nach dem Streichen der Satz keinen Inhalt mehr hat: ganzen Satz streichen
### Schritt 2: Tier-1-Wörter ersetzen
- Jedes Tier-1-Wort durch den vorgeschlagenen Ersatz ersetzen
- Kontext beachten: "robust" in einer Server-Beschreibung kann bleiben, "robust" für eine Idee muss raus
### Schritt 3: Tier-2-Dichte prüfen
- Mehr als 1x pro 500 Wörter? Überschuss ersetzen
- Bevorzugt die einfachere Variante wählen
### Schritt 4: KI-Muster auflösen
- Jedes erkannte Muster (aus `ki-muster.md`) umschreiben
- Priorität: HOCH-Muster zuerst
- Die Nachher-Beispiele aus der Muster-Datei als Orientierung nutzen
### Schritt 5: Passiv → Aktiv
- Jede Passiv-Konstruktion prüfen: Gibt es ein konkretes Subjekt?
- "Es wird davon ausgegangen" → "Wir denken" / "Ich denke" / "Die Autoren gehen davon aus"
- "Die Konfiguration wird erstellt" → "Du erstellst die Konfiguration"
### Schritt 6: Satzrhythmus variieren
- Prüfe: Gibt es 3+ Sätze gleicher Länge hintereinander?
- Wenn ja: Einen Satz kürzen (Fragment?), einen verlängern (Nebensatz?)
- Ziel: Welle aus kurz-mittel-lang-kurz
### Schritt 7: Personality-Minimum
- Füge 1–2 Einschübe in Klammern ein (Technik 1)
- Prüfe ob mindestens 1 Satzfragment vorkommt
- Prüfe ob mindestens 1 Kontraktion möglich ist (gibt's, hat's, geht's)
### Schritt 8: Schluss prüfen
- Endet der Text mit einer generischen Schlussfolgerung? → Umschreiben oder streichen
- Gute Schlüsse: Konkrete nächste Aktion, offene Frage, ehrliche Einschätzung
- Schlechte Schlüsse: "Es bleibt spannend", "Die Zukunft sieht rosig aus"
---
## Tonalität des Basis-Layers
| Eigenschaft | Einstellung |
|-------------|------------|
| Formalität | Mittel (weder Behördendeutsch noch SMS) |
| Du/Sie | Beibehalten wie im Original |
| Fachbegriffe | Beibehalten, aber erklären wenn nötig |
| Humor | Nicht aktiv einbauen, aber nicht entfernen wenn vorhanden |
| Persönliche Meinung | Nicht einbauen (das macht der Autor) |
| Metaphern | Vorhandene verbessern, keine neuen hinzufügen |
---
## Vorher/Nachher-Beispiel (komplett)
### Vorher (KI-generiert):
> "Es ist wichtig zu beachten, dass OpenClaw eine grundlegend andere Herangehensweise an KI-Routing darstellt. Das System fungiert als nahtloser Vermittler zwischen verschiedenen KI-Modellen und ermöglicht es Benutzern, die robuste und skalierbare Architektur zu nutzen. Darüber hinaus bietet die Plattform eine ganzheitliche Lösung, die nicht nur die technische Implementierung umfasst, sondern auch die facettenreiche Landschaft der KI-Interaktion berücksichtigt. Studien zeigen, dass dieser Ansatz die Produktivität maßgeblich steigert. Die Zukunft sieht vielversprechend aus."
**Probleme:**
- 6 Tier-1-Wörter (grundlegend, nahtlos, robust, skalierbar, ganzheitlich, facettenreich)
- 3 verbotene Phrasen (Es ist wichtig zu beachten, nicht nur...sondern auch, Darüber hinaus)
- 3 KI-Muster (Werbesprache, Copula-Vermeidung, Generische Schlussfolgerung)
- Kein Rhythmus (alle Sätze 15–25 Wörter)
- Passiv + vage Zuschreibung
### Nachher (Basis-Layer):
> "OpenClaw routet KI-Anfragen anders als andere Systeme. Es sitzt zwischen den Modellen – Claude hier, GPT dort – und entscheidet, wer die Anfrage bekommt. Das spart Zeit. Die Architektur wächst mit deinen Anforderungen (ich hab sie mit 50 gleichzeitigen Anfragen getestet, kein Problem). Ob das die Produktivität steigert? Kommt drauf an was du vorher gemacht hast. Aber schneller geht's auf jeden Fall."
**Was sich geändert hat:**
- Alle Tier-1-Wörter ersetzt
- Alle verbotenen Phrasen entfernt
- Aktiv statt Passiv
- Satzrhythmus variiert (5, 16, 3, 17, 9, 10 Wörter)
- Ein Einschub in Klammern
- Eine Kontraktion (geht's)
- Konkrete Aussage statt generischem Schluss
---
## Grenzen des Basis-Layers
1. **Kein Stil-Hinzufügen:** Der Basis-Layer macht den Text nicht "besser" oder "interessanter". Er macht ihn nur weniger KI-haft.
2. **Keine Inhaltsänderung:** Fakten, Argumente und Struktur bleiben wie im Original.
3. **Keine Tonänderung:** Wenn das Original formal ist, bleibt es formal. Nur die KI-Signale werden entfernt.
4. **Kein Umstrukturieren:** Die Absatz- und Kapitelstruktur bleibt erhalten.
Für mehr Stil: Verwende einen spezifischen Stil-Layer (z.B. `lesch.md`).
FILE:references/vokabeln.md
# Deutsche KI-Vokabel-Datenbank
> 125+ Vokabeln in 3 Tiers, 48 verbotene Phrasen und 16 Chatbot-Artefakte.
> Sortiert nach Schweregrad. Jeder Eintrag hat einen konkreten Ersetzungsvorschlag.
---
## Tier 1 – VERBOTEN (immer ersetzen, +3 Punkte pro Treffer)
Diese Wörter kommen in menschlichen deutschen Texten fast nie vor. Jedes Vorkommen ist ein starkes KI-Signal.
| KI-Wort | Ersetzungsvorschlag | Kontext |
|---------|---------------------|---------|
| grundlegend | wichtig, zentral, tragend | "ein grundlegender Wandel" → "ein wichtiger Wandel" |
| nahtlos | reibungslos, problemlos, glatt | "nahtlose Integration" → "die Integration klappt problemlos" |
| robust | stabil, belastbar, solide | "eine robuste Lösung" → "eine stabile Lösung" |
| skalierbar | wachstumsfähig, erweiterbar | "skalierbare Architektur" → "die Architektur wächst mit" |
| ganzheitlich | umfassend, vollständig, komplett | "ganzheitlicher Ansatz" → "der Ansatz deckt alles ab" |
| umfassend | vollständig, komplett, gründlich | "umfassende Analyse" → "gründliche Analyse" |
| bahnbrechend | neu, wichtig, wegweisend | "bahnbrechende Entdeckung" → "eine wichtige Entdeckung" |
| wegweisend | richtungsgebend, einflussreich | "wegweisende Studie" → "eine einflussreiche Studie" |
| transformativ | verändernd, umwälzend | "transformative Kraft" → "die Kraft zur Veränderung" |
| synergetisch | zusammenwirkend, ergänzend | Einfach streichen oder "die Teile ergänzen sich" |
| facettenreich | vielseitig, vielschichtig | "facettenreiches Thema" → "das Thema hat viele Seiten" |
| vielfältig | verschieden, unterschiedlich | "vielfältige Möglichkeiten" → "verschiedene Möglichkeiten" |
| Eckpfeiler | Basis, Fundament, Kern | "ein Eckpfeiler der Strategie" → "die Basis der Strategie" |
| Katalysator | Auslöser, Beschleuniger, Antrieb | "Katalysator für Wachstum" → "treibt das Wachstum an" |
| ermächtigen | befähigen, in die Lage versetzen | "Nutzer ermächtigen" → "Nutzer können jetzt..." |
| befähigen | ermöglichen, helfen | "befähigt Teams" → "Teams können damit..." |
| unschätzbar | wertvoll, kaum zu überschätzen | "unschätzbar wertvoll" → "extrem wertvoll" |
| eingebettet | integriert, eingebaut, Teil von | "eingebettet in das System" → "Teil des Systems" |
| Landschaft (abstrakt) | Bereich, Feld, Umfeld | "die KI-Landschaft" → "der KI-Bereich" |
| eintauchen | anschauen, untersuchen, erkunden | "lasst uns eintauchen" → "schauen wir uns das an" |
| Tapisserie / Wandteppich | Geflecht, Mischung, Zusammenspiel | "ein Wandteppich aus Erfahrungen" → "eine Mischung aus Erfahrungen" |
| lebendig (abstrakt) | aktiv, dynamisch, bunt | "lebendige Diskussion" → "aktive Diskussion" |
| entscheidend (inflationär) | wichtig, relevant, zentral | Nur verwenden wenn wirklich eine Entscheidung fällt |
| herausragend | gut, stark, bemerkenswert | "herausragende Leistung" → "starke Leistung" |
| maßgeblich | wichtig, prägend, bestimmend | "maßgeblich beeinflusst" → "stark beeinflusst" |
| tiefgreifend | stark, deutlich, spürbar | "tiefgreifende Veränderung" → "spürbare Veränderung" |
| hochgradig | sehr, stark, extrem | "hochgradig relevant" → "sehr relevant" |
| zweifellos | sicher, klar, bestimmt | "zweifellos wichtig" → "sicher wichtig" |
| unbestreitbar | klar, offensichtlich | "unbestreitbar wahr" → "das stimmt" |
| Brennpunkt | Schwerpunkt, Fokus, Kern | "im Brennpunkt der Debatte" → "im Zentrum der Debatte" |
| Paradigma | Denkmodell, Muster, Rahmen | "ein neues Paradigma" → "ein neues Denkmodell" |
| Paradigmenwechsel | Umdenken, Wandel, Neuausrichtung | "ein Paradigmenwechsel" → "ein Umdenken" |
| unverzichtbar | nötig, wichtig, notwendig | "unverzichtbares Tool" → "notwendiges Tool" |
| überwältigend | stark, deutlich, groß | "überwältigende Resonanz" → "starke Resonanz" |
| federführend | führend, treibend, verantwortlich | "federführend beteiligt" → "hauptverantwortlich" |
| richtungsweisend | wichtig, prägend, zukunftsweisend | "richtungsweisende Entscheidung" → "wichtige Entscheidung" |
| Meilenstein | Fortschritt, Etappe, Erfolg | "ein Meilenstein" → "ein wichtiger Schritt" |
| Wendepunkt | Veränderung, Bruch, Umbruch | "ein Wendepunkt" → "ab hier änderte sich alles" |
| Schlüsselrolle | wichtige Rolle, zentrale Rolle | "spielt eine Schlüsselrolle" → "ist besonders wichtig" |
| Vorreiter | Pionier, Erster, Wegbereiter | "Vorreiter der Branche" → "einer der Ersten in der Branche" |
| zukunftsweisend | vorausschauend, modern, fortschrittlich | "zukunftsweisend" → "vorausschauend" |
| bemerkenswert | auffällig, interessant | "bemerkenswert ist" → "auffällig ist" |
| außerordentlich | sehr, besonders, extrem | "außerordentlich wichtig" → "besonders wichtig" |
| beispiellos | einmalig, noch nie dagewesen | "beispiellose Entwicklung" → "so etwas gab es noch nie" |
---
## Tier 2 – SPARSAM (max 1x pro 500 Wörter, +1 Punkt über Limit)
Diese Wörter sind nicht per se falsch, aber KI nutzt sie inflationär. In Maßen okay, in Massen verdächtig.
| KI-Wort | Erlaubte Frequenz | Ersetzungsvorschlag |
|---------|-------------------|---------------------|
| darüber hinaus | max 1x / 500W | außerdem, und, dazu |
| des Weiteren | max 1x / 500W | außerdem, auch, dazu |
| zudem | max 1x / 500W | auch, und, dazu |
| nuanciert | max 1x / 500W | fein, differenziert, genau |
| erleichtern | max 1x / 500W | einfacher machen, helfen bei |
| beleuchten | max 1x / 500W | zeigen, erklären, anschauen |
| umfassen | max 1x / 500W | enthalten, beinhalten, abdecken |
| proaktiv | max 1x / 500W | vorausschauend, von sich aus |
| wesentlich | max 1x / 500W | wichtig, zentral, entscheidend |
| darauf abzielen | max 1x / 500W | wollen, versuchen, anstreben |
| in der Lage sein | max 1x / 500W | können, fähig sein |
| ermöglichen | max 1x / 500W | erlauben, möglich machen, helfen |
| gewährleisten | max 1x / 500W | sicherstellen, garantieren |
| berücksichtigen | max 1x / 500W | beachten, bedenken, einbeziehen |
| Aspekt | max 1x / 500W | Seite, Punkt, Thema |
| Kontext | max 1x / 500W | Zusammenhang, Umfeld, Rahmen |
| relevant | max 1x / 500W | wichtig, passend, bedeutsam |
| optimieren | max 1x / 500W | verbessern, besser machen, tunen |
| implementieren | max 1x / 500W | einbauen, umsetzen, einrichten |
| integrieren | max 1x / 500W | einbauen, verbinden, zusammenführen |
| adressieren | max 1x / 500W | ansprechen, lösen, angehen |
| transparent | max 1x / 500W | offen, nachvollziehbar, klar |
| signifikant | max 1x / 500W | deutlich, groß, erheblich |
| elementar | max 1x / 500W | wichtig, grundlegend, zentral |
| essenziell | max 1x / 500W | nötig, wichtig, unverzichtbar |
| komplex | max 1x / 500W | kompliziert, schwierig, vielschichtig |
| Potenzial | max 1x / 500W | Möglichkeit, Chance, Stärke |
| effektiv | max 1x / 500W | wirksam, wirkungsvoll, gut |
| effizient | max 1x / 500W | sparsam, wirtschaftlich, schnell |
| nutzerorientiert | max 1x / 500W | auf den Nutzer zugeschnitten, für den Nutzer gemacht |
| datengetrieben | max 1x / 500W | auf Daten basierend, datenbasiert |
| zukunftsfähig | max 1x / 500W | langfristig brauchbar, haltbar |
| evidenzbasiert | max 1x / 500W | auf Belegen aufgebaut, nachgewiesen |
| praxiserprobt | max 1x / 500W | getestet, bewährt, in der Praxis genutzt |
| niedrigschwellig | max 1x / 500W | einfach zugänglich, unkompliziert |
| Handlungsempfehlung | max 1x / 500W | Vorschlag, Empfehlung, Tipp |
| Zielsetzung | max 1x / 500W | Ziel, Absicht, Plan |
| Fragestellung | max 1x / 500W | Frage (einfach "Frage") |
| Problemstellung | max 1x / 500W | Problem (einfach "Problem") |
| Herangehensweise | max 1x / 500W | Ansatz, Methode, Vorgehen |
| Gegebenheiten | max 1x / 500W | Umstände, Lage, Situation |
| fungieren | max 1x / 500W | sein, arbeiten als, dienen als |
| aufweisen | max 1x / 500W | haben, zeigen |
| darstellen | max 1x / 500W | sein (wenn "ist" gemeint ist) |
| verorten | max 1x / 500W | einordnen, zuordnen, platzieren |
---
## Tier 3 – BEOBACHTEN (Dichte zählen, +1 Punkt wenn >3 pro 500W)
Diese Wörter sind im richtigen Kontext völlig in Ordnung. Nur wenn sie sich häufen, wird's verdächtig.
| KI-Wort | Wann okay | Wann verdächtig |
|---------|-----------|-----------------|
| Ökosystem | Wenn es wirklich um ein System von Teilen geht | Wenn alles zum "Ökosystem" wird |
| Framework | In Tech-Kontexten | In nicht-technischen Texten |
| Roadmap | In Projektplanung | In jedem zweiten Absatz |
| optimieren | In technischen Beschreibungen | "das Leben optimieren" |
| Reise (metaphorisch) | 1x pro Text max | "die Reise der Erkenntnis", "unsere gemeinsame Reise" |
| Journey | In UX/Marketing-Kontext | In Sachtext |
| Touchpoint | In UX/Marketing | "ein emotionaler Touchpoint" |
| Problemfeld | In Analyse-Kontext | Wenn alles zum "Problemfeld" wird |
| agil | In Software-Kontext | "agiles Mindset" in jedem Absatz |
| iterativ | In Entwicklungs-Kontext | Wenn jeder Prozess "iterativ" ist |
| Stakeholder | In Business-Kontext | Wenn jeder ein "Stakeholder" wird |
| Mehrwert | In Business-Kontext | "einen echten Mehrwert bieten" als Floskel |
| Narrativ | In Medien/Kultur-Kontext | Wenn alles ein "Narrativ" ist |
| Resilienz | In Psychologie/Tech | Wenn es als Buzzword dient |
| nachhaltig | Wenn es um Umwelt geht | "nachhaltig beeindruckt" |
| skalieren | In Tech-Kontext | "das Glück skalieren" |
| Synergie | Selten okay | Fast immer KI-Signal |
| disruptiv | In Tech/Business | In jedem zweiten Satz |
| Achtsamkeit | In Psychologie | Wenn Tech-Firmen es verwenden |
| Mindset | In Coaching-Kontext | "das richtige KI-Mindset" |
| Alignment | In ML/KI-Kontext | "emotionales Alignment" in Sachtext |
| Empowerment | In HR/Sozialarbeit | "digitales Empowerment" als Floskel |
| Best Practice | In Fachtext 1x | Wenn alles "Best Practice" ist |
| Benchmark | In Leistungsvergleich | Wenn alles "gebenchmarkt" wird |
| Use Case | In Tech-Kontext | Wenn jede Anwendung ein "Use Case" ist |
| Pain Point | In UX/Marketing | "gesellschaftliche Pain Points" |
| Gamechanger | In Sport-Kontext | "KI ist der Gamechanger" |
| Enabling | In Tech-Kontext | "Enabling von Innovation" |
| Impact | In Wirkungsmessung | "positiver Impact" als Floskel |
| Leverage | Selten auf Deutsch okay | Fast immer KI-Signal auf Deutsch |
| Onboarding | In HR-Kontext | Wenn jeder Prozess "Onboarding" heißt |
| Upskilling | In Weiterbildung | "gesellschaftliches Upskilling" |
| Sichtbarkeit | In Marketing | "Sichtbarkeit erhöhen" als Standardfloskel |
---
## Verbotene Phrasen (komplett ersetzen, +4 Punkte pro Treffer)
Diese Phrasen sind eindeutige KI-Marker. Jede einzelne muss raus.
| Verbotene Phrase | Ersetzung |
|-----------------|-----------|
| "Es ist wichtig zu beachten, dass..." | Streichen. Direkt zum Punkt kommen. |
| "Nicht nur... sondern auch..." | Zwei Sätze. "X ist wichtig. Aber Y ist es auch." |
| "In der heutigen Welt" | Streichen. Oder "Heute" wenn nötig. |
| "In einer Welt, in der..." | Streichen. Direkt anfangen. |
| "Lass uns ehrlich sein" | Streichen. Einfach ehrlich sein. |
| "Um ehrlich zu sein" | Streichen. Einfach die ehrliche Aussage machen. |
| "Darüber hinaus" | "Außerdem" oder einfach neuer Satz. |
| "Des Weiteren" | "Auch" oder "Und" oder neuer Satz. |
| "Ermöglicht es" | "Du kannst damit..." oder "Damit geht..." |
| "Bietet die Möglichkeit" | "Du kannst..." oder "Es geht..." |
| "Grundlegend anders" | "anders" reicht. Oder "komplett anders". |
| "Im Kern" / "Im Grunde" | Streichen. Direkt sagen was Sache ist. |
| "Stell dir vor" (>1x pro Text) | 1x ist okay. 2x+ ist ChatGPT. |
| "Fazit" als Abschnittstitel | "Was bleibt" oder "Kurz gesagt" oder einfach weglassen. |
| "Zusammenfassend lässt sich sagen" | "Kurz:" oder einfach das Fazit direkt schreiben. |
| "Es lässt sich festhalten" | Das Festgehaltene direkt schreiben. |
| "Abschließend sei gesagt" | Direkt das Schluss-Statement machen. |
| "Wie bereits erwähnt" | Streichen. Der Leser erinnert sich. |
| "An dieser Stelle sei erwähnt" | Das Erwähnte einfach erwähnen. |
| "Es sei darauf hingewiesen" | Direkt hinweisen. |
| "In Anbetracht der Tatsache" | "Weil" oder "Da". |
| "Aufgrund der Tatsache, dass" | "Weil". |
| "Im Folgenden wird erläutert" | Einfach erläutern. |
| "Es gilt zu beachten" | Direkt beachten lassen. |
| "Nicht zuletzt" | "Und" oder "Außerdem". |
| "Zu guter Letzt" | "Und zum Schluss:" oder einfach anfangen. |
| "Last but not least" | Deutsch schreiben. "Und:" |
| "In diesem Zusammenhang" | Streichen oder "Dabei" oder "Hier". |
| "Vor dem Hintergrund" | "Weil" oder "Angesichts" oder streichen. |
| "Im Rahmen von" | "Bei" oder "Während" oder konkreter. |
| "Unter Berücksichtigung von" | "Mit Blick auf" oder "Weil". |
| "Es zeigt sich, dass" | Das Gezeigte direkt schreiben. |
| "Es wird deutlich, dass" | Direkt sagen was deutlich ist. |
| "Eine Vielzahl von" | "Viele" oder "Mehrere". |
| "Eine Reihe von" | "Einige" oder "Mehrere" oder Zahl nennen. |
| "Einen wesentlichen Beitrag leisten" | "Hilft bei" oder "Trägt bei zu". |
| "Im Hinblick auf" | "Für" oder "Bei" oder "Was X betrifft". |
| "Hinsichtlich" | "Was X betrifft" oder "Bei". |
| "Dies unterstreicht" | Streichen. Das Unterstrichene steht für sich. |
| "Es bleibt abzuwarten" | Konkret sagen was offen ist. |
| "Es bleibt spannend" | Sagen warum es spannend ist oder streichen. |
| "Die Zukunft wird zeigen" | Konkret sagen was offen ist. |
| "Spielt eine entscheidende Rolle" | "Ist wichtig" oder konkreter. |
| "Von entscheidender Bedeutung" | "Wichtig" oder "Zentral". |
| "Stellt einen wichtigen Schritt dar" | "Ist ein wichtiger Schritt" oder konkreter. |
| "Sowohl... als auch..." (inflationär) | Zwei Sätze. 1x pro Text okay, 3x+ ist KI. |
---
## Chatbot-Artefakte (sofort ersetzen, +5 Punkte pro Treffer)
Diese Phrasen verraten, dass der Text direkt aus einem Chatbot stammt – ohne jede Nachbearbeitung. Jede einzelne muss raus.
| Artefakt | Ersetzung |
|----------|-----------|
| "Tolle Frage!" / "Gute Frage!" / "Hervorragende Frage!" | Streichen. Einfach antworten. |
| "Ich hoffe, das hilft" | Streichen. |
| "Lass mich wissen" / "Lassen Sie mich wissen" | Streichen. |
| "Gerne!" / "Natuerlich!" / "Selbstverstaendlich!" | Streichen (als Satzanfang). |
| "Da haben Sie voellig recht" / "Da hast du voellig recht" | Streichen oder konkreter formulieren. |
| "Stand meiner letzten Schulung" | Streichen. Kein Mensch sagt das. |
| "Soweit mir bekannt" / "Zum Zeitpunkt meines Wissens" | "Meines Wissens" oder konkretes Datum nennen. |
> **Hinweis:** Diese Artefakte sind im CLI-Tool als eigene Kategorie implementiert (16 Varianten). Im Agent-Modus werden sie zusaetzlich ueber Muster #18 (ki-muster.md) erkannt.
---
## Kontext-Regeln
### Wann ist ein KI-Wort okay?
1. **Fachkontext:** "skalierbar" in einem DevOps-Artikel ist kein KI-Signal. "Skalierbar" in einem Kochrezept schon.
2. **Zitate:** Wenn du jemanden zitierst, zählt das Wort nicht.
3. **Erklärung des Worts:** Wenn du erklärst warum ein Wort problematisch ist (wie in diesem Dokument), zählt es nicht.
4. **Einmalig:** Ein einzelnes Tier-2-Wort in 2000 Wörtern ist kein Problem. Fünf davon schon.
### Dichte-Berechnung
```
KI-Dichte = (Tier1-Treffer × 3 + Tier2-Überschuss × 1 + Phrasen × 4) / Wortanzahl × 1000
Interpretation:
< 5: Unauffällig
5-15: Leicht KI-lastig
15-30: Deutlich KI-lastig
> 30: Offensichtlich KI
```
---
## Co-Occurrence-Sets (Wort-Cluster-Erkennung)
KI-Wörter kommen selten allein. Sie treten in Clustern auf. Wenn 3+ Wörter aus demselben Set in einem Absatz stecken, ist das ein starkes KI-Signal (+5 Punkte pro Cluster).
### Set 1: Bedeutungs-Aufblasung
`grundlegend` · `maßgeblich` · `entscheidend` · `tiefgreifend` · `bahnbrechend` · `wegweisend` · `Meilenstein` · `Wendepunkt` · `Paradigmenwechsel`
### Set 2: Werbesprache
`nahtlos` · `robust` · `skalierbar` · `ganzheitlich` · `umfassend` · `herausragend` · `innovativ` · `zukunftsweisend`
### Set 3: Abstrakte Metaphern
`Landschaft` · `Eckpfeiler` · `Katalysator` · `facettenreich` · `Tapisserie` · `eingebettet` · `Ökosystem` · `Reise`
### Set 4: Aktions-Verben
`ermächtigen` · `befähigen` · `ermöglichen` · `gewährleisten` · `erleichtern` · `optimieren` · `implementieren` · `integrieren`
### Set 5: Übergangs-Füller
`darüber hinaus` · `des Weiteren` · `zudem` · `nicht zuletzt` · `abschließend` · `zusammenfassend` · `im Folgenden`
### Set 6: Anglizismen-Cluster
`Benchmark` · `Best Practice` · `Use Case` · `Alignment` · `Empowerment` · `Impact` · `Leverage` · `Onboarding` · `Upskilling` · `Gamechanger`
### Set 7: Nominalstil-Cluster
`Zielsetzung` · `Fragestellung` · `Problemstellung` · `Handlungsempfehlung` · `Herangehensweise` · `Gegebenheiten`
### Erkennungsregel
```
Für jeden Absatz:
1. Zähle Treffer pro Set
2. Wenn ein Set 3+ Treffer in einem Absatz hat → Co-Occurrence-Alarm
3. Pro Alarm: +5 Punkte auf den Gesamt-Score
Beispiel (1 Absatz):
"Das nahtlose System bietet eine robuste und skalierbare Lösung
für ganzheitliche Herausforderungen."
→ Set 2 hat 4 Treffer: nahtlos, robust, skalierbar, ganzheitlich
→ Co-Occurrence-Alarm! +5 Punkte
```
### Warum Cluster stärker wiegen als Einzelwörter
Ein einzelnes "robust" in einem DevOps-Artikel ist normal. Aber "robust" + "skalierbar" + "nahtlos" + "ganzheitlich" in einem Absatz? Das schreibt kein Mensch so. KI-Modelle erzeugen diese Cluster, weil die Wörter in ihren Trainingsdaten häufig zusammen vorkommen.
FILE:references/personality-injection.md
# Personality Injection – Texte menschlich machen
> 5 Techniken die einem Text Persönlichkeit geben.
> Jede Technik hat: Beschreibung, Regeln, 5+ deutsche Beispiele, Kontext-Anpassung.
> Diese Techniken werden beim "Humanisiere"-Befehl angewendet.
---
## Grundprinzip
KI-Text klingt steril, weil er keine Persönlichkeit hat. Kein Zögern, kein Einschub, keine Macke. Menschlicher Text hat Ecken und Kanten. Personality Injection fügt diese Ecken gezielt ein – nicht willkürlich, sondern mit System.
**Wichtig:** Personality Injection ersetzt keine gute Argumentation. Erst den Inhalt richten (Muster entfernen, Vokabeln ersetzen), dann Persönlichkeit einspritzen.
---
## Technik 1: Einschübe in Klammern
Authentische Reaktionen, Kommentare oder Relativierungen in Klammern eingefügt. Klingt wie ein Mensch, der beim Schreiben denkt.
### Regeln
- Max 1–3 Einschübe pro 500 Wörter
- Nur für echte Reaktionen, nicht als Füller
- Dürfen kurz sein (3–10 Wörter)
- Klammern oder Gedankenstriche, aber nicht beides im selben Absatz
- Inhalt muss zum Satz passen – kein Zufalls-Einschub
### Beispiele
**1. Überraschung:**
> "Die Fehlerrate sank um 40% (was mich ehrlich überrascht hat)."
**2. Selbst-Kommentar:**
> "Das klingt nach wenig Arbeit (ist es aber nicht)."
**3. Eingeständnis:**
> "Ich hab das drei Mal ausprobiert (ja, wirklich drei Mal), bevor es lief."
**4. Relativierung:**
> "Claude ist dafür besser geeignet (zumindest in meiner Erfahrung)."
**5. Humor:**
> "Die Dokumentation war leider nicht hilfreich (falls man 'existiert nicht' als nicht hilfreich zählt)."
**6. Persönliche Note:**
> "Der erste Entwurf war Müll (keine Schönfärberei – wirklich Müll)."
**7. Gedankengang:**
> "Vielleicht liegt es am Prompt (oder an mir, wer weiß)."
### Kontext-Anpassung
| Kontext | Einschübe erlaubt? | Stil |
|---------|-------------------|------|
| Blogpost / Tutorial | Ja, 2–3 pro 500W | Locker, persönlich |
| Sachbuch | Ja, 1–2 pro 500W | Sachlich-persönlich |
| Förderantrag | Nein | Zu informell |
| E-Mail (intern) | Ja, 1 pro E-Mail | Knapp |
| Wissenschaftlich | Selten, in Fußnoten | Zurückhaltend |
---
## Technik 2: Satzrhythmus variieren
Menschen schreiben in Wellen. Kurz. Dann lang, mit Nebensätzen und Abzweigungen die sich ihren Weg durch den Gedanken suchen. Dann wieder kurz. So klingt ein Mensch.
### Regeln
- Nie mehr als 3 Sätze gleicher Länge hintereinander
- "Gleiche Länge" = Differenz von weniger als 3 Wörtern
- Mindestens 1 Satz unter 5 Wörtern pro Absatz
- Mindestens 1 Satz über 15 Wörtern pro Absatz
- Satzfragmente sind erlaubt und erwünscht
### Beispiele
**1. Kurz-lang-kurz:**
> "Das funktioniert. Es braucht ein bisschen Einrichtung am Anfang, und der erste Durchlauf dauert länger als man denkt, aber danach läuft es. Versprochen."
**2. Fragment + Erklärung:**
> "Drei Tage. So lange hat die Konfiguration gedauert, weil die Dokumentation lückenhaft war und ich jeden Schritt selbst rausfinden musste."
**3. Aufbau mit Pointe:**
> "Der Router prüft die Anfrage. Er schaut sich die Modelle an. Er wägt ab. Und dann macht er genau das, was du selbst gemacht hättest. Nur schneller."
**4. Rhythmuswechsel im Absatz:**
> "Cowan antwortet per Sprache. Das klingt nach einer Spielerei, aber in der Praxis ändert es alles. Du kannst beim Spazierengehen mit deinem Buch arbeiten. Kein Bildschirm. Kein Tippen. Nur du und dein Gedankenpartner."
**5. Bewusster Bruch:**
> "Die Multi-Agent-Pipeline orchestriert Writer, Editor und QA in einer Sequenz, die so präzise getaktet ist wie ein Uhrwerk. Naja. Fast wie ein Uhrwerk."
### Anti-Muster (so klingt KI)
> "Das System verarbeitet die Anfrage automatisch. Es leitet sie an das passende Modell weiter. Das Modell generiert eine Antwort. Die Antwort wird zurückgegeben. Der Benutzer sieht das Ergebnis."
Fünf Sätze, alle 6–8 Wörter lang. Monoton. Roboterhaft.
---
## Technik 3: Abschweifungen und Anekdoten
"Wo wir gerade davon sprechen..." / "Das erinnert mich an..." – kurze thematische Seitensprünge die zeigen: Hier denkt ein Mensch, nicht eine Maschine.
### Regeln
- Max 1–2 Abschweifungen pro 1000+ Wörter
- Muss thematisch zum Kontext passen (kein Zufalls-Thema)
- Max 2–3 Sätze lang, dann zurück zum Thema
- Kann mit "Aber zurück zum Thema:" oder ähnlichem abgeschlossen werden
- Oder: einfach nahtlos weitergehen
### Beispiele
**1. Persönliche Erfahrung:**
> "Die SOUL.md-Konfiguration braucht etwas Übung. Ich hab bei meinem ersten Versuch vergessen, die Constraints zu setzen, und Cowan hat mir eine halbe Stunde lang Quatsch erzählt. Seitdem: Constraints zuerst."
**2. Historischer Bezug:**
> "Das Chunk-System erinnert mich an Bibliotheken vor dem Internet. Du musstest genau wissen, wie du fragst, sonst fand die Bibliothekarin nichts. Hier ist es ähnlich – nur schneller."
**3. Vergleich aus dem Alltag:**
> "Drei Modelle gleichzeitig zu managen klingt kompliziert. Ist es auch, ungefähr so wie drei Kinder gleichzeitig ins Bett bringen. Aber mit System geht es."
**4. Mini-Anekdote:**
> "Ein Kollege hat den Router mal mit 50 gleichzeitigen Anfragen getestet. Nicht weil er musste, sondern weil er konnte. Ergebnis: Alles lief. Sein Chef war nicht begeistert."
**5. Gedankensprung:**
> "Das bringt mich auf einen anderen Punkt: Wenn der Agent immer Ja sagt, ist er kein Partner. Er ist ein Spiegel. Und Spiegel zeigen dir nur, was du sehen willst."
### Kontext-Anpassung
| Kontext | Abschweifungen erlaubt? |
|---------|------------------------|
| Blogpost / Tutorial | Ja, 1–2 pro 1000W |
| Sachbuch | Ja, 1 pro Kapitelabschnitt |
| Förderantrag | Nein |
| Newsletter | Ja, 1 pro Ausgabe |
| Technische Doku | Nur als "Hinweis"/"Tipp"-Box |
---
## Technik 4: Unsicherheit und Komplexität eingestehen
Menschen wissen nicht alles. Sie sagen "ich bin mir da nicht sicher", "das ist komplizierter als es aussieht", "keine Ahnung warum, aber es funktioniert." KI tut immer so, als hätte sie die Antwort.
### Regeln
- Nur wo echte Unsicherheit angebracht ist
- Nicht als Absicherung gegen Fehler missbrauchen
- Max 1–2 pro 500 Wörter
- Muss glaubwürdig sein (nicht "ich bin mir nicht sicher ob 2+2=4")
### Beispiele
**1. Echte Unsicherheit:**
> "Ob das in fünf Jahren noch so funktioniert? Ehrlich gesagt: keine Ahnung."
**2. Komplexität benennen:**
> "Das klingt einfach. Ist es nicht. Die Konfiguration hat Fallstricke, über die wir noch reden müssen."
**3. Erfahrungsbasiert:**
> "In meinen Tests hat das funktioniert. Ob das bei jedem Setup so ist, kann ich nicht garantieren."
**4. Offene Frage:**
> "Warum Claude hier besser performt als GPT? Da hab ich eine Vermutung, aber keinen Beweis."
**5. Grenzen anerkennen:**
> "An dieser Stelle hört mein Wissen auf. Was ich weiß: Es funktioniert. Warum genau? Da müsste jemand Klügeres ran."
**6. Selbstkritik:**
> "Mein erster Ansatz war falsch. Komplett falsch. Der zweite war besser, aber auch nicht perfekt."
### Anti-Muster (so sichert KI ab)
> "Es könnte möglicherweise unter bestimmten Umständen denkbar sein, dass dieser Ansatz eventuell zu leichten Verbesserungen führen könnte."
Dreifache Absicherung. Sagt nichts. Klingt nach KI.
---
## Technik 5: Kontraktionen und Umgangssprache
"Gibt's", "ist's", "hat's", "geht's". Satzfragmente. Wenn's passt. Deutsche Umgangssprache macht Texte lebendig – in den richtigen Kontexten.
### Regeln
- Zum Kontext passen: Förderantrag ≠ Blogpost
- Nicht erzwingen – wenn es unnatürlich klingt, weglassen
- Max 3–5 Kontraktionen pro 500 Wörter
- Satzfragmente sparsam: 1–2 pro Absatz
- Nie in Überschriften (es sei denn bewusst gewählt)
### Beispiele
**1. Kontraktionen:**
> "Es gibt's nicht umsonst – du musst die API-Keys selbst bezahlen."
> "Wer's ausprobiert, merkt den Unterschied sofort."
> "Hat's geklappt? Dann weiter zum nächsten Schritt."
**2. Satzfragmente:**
> "Der Router. Herzstück von OpenClaw. Ohne ihn geht nichts."
> "Drei Modelle. Ein Gateway. Fertig."
> "Und dann? Stille. Keine Fehlermeldung, keine Antwort. Einfach nichts."
**3. Umgangssprachliche Wendungen:**
> "Das hat mich echt genervt."
> "Klingt gut, oder? Ist es auch."
> "Mal ehrlich: So schwer ist das nicht."
**4. Direkte Ansprache (casual):**
> "Du kennst das: Man fängt an, kommt in den Flow, und dann crasht alles."
> "Probier's aus. Ernsthaft."
**5. Bewusste Regelverletzung:**
> "Und ja, der Satz fängt mit 'Und' an. Deal with it."
### Kontext-Anpassung
| Kontext | Kontraktionen | Fragmente | Umgangssprache |
|---------|--------------|-----------|----------------|
| Blogpost | ✓ voll | ✓ voll | ✓ voll |
| Sachbuch (OpenClaw) | ✓ moderat | ✓ sparsam | ✓ moderat |
| Tutorial | ✓ moderat | ✓ sparsam | ✓ wenig |
| Newsletter | ✓ voll | ✓ voll | ✓ voll |
| Förderantrag | ✗ nie | ✗ nie | ✗ nie |
| Wissenschaftlich | ✗ nie | ✗ selten | ✗ nie |
| Geschäfts-E-Mail | ✓ wenig | ✗ nie | ✓ wenig |
---
## Bonus-Punkte (Score-Abzüge)
Wenn diese Techniken im Text erkannt werden, reduziert sich der KI-Score:
| Erkanntes Stilmittel | Bonus |
|---------------------|-------|
| Authentische Einschübe in Klammern vorhanden | -3 Punkte |
| Satzrhythmus variiert (keine 3+ gleich langen Sätze) | -5 Punkte |
| Kontraktionen verwendet (gibt's, ist's, hat's) | -2 Punkte |
| Konkrete Zahlen/Quellen statt vager Aussagen | -3 Punkte |
| Echte Abschweifungen/Anekdoten | -3 Punkte |
| Satzfragmente (bewusst unvollständig) | -2 Punkte |
| **Maximaler Bonus** | **-18 Punkte** |
### Wie erkennt man "authentische" Einschübe?
Ein Einschub ist authentisch wenn:
- Er eine persönliche Reaktion enthält (Überraschung, Zweifel, Humor)
- Er nicht als Füller dient ("was natürlich wichtig ist" → kein echter Einschub)
- Er den Leser nicht lobt ("was eine tolle Frage ist" → KI-Muster #20)
---
## Zusammenspiel der Techniken
Nicht alle 5 Techniken gleichzeitig einsetzen. Je nach Textart:
| Textart | Haupttechniken | Unterstützend | Weglassen |
|---------|---------------|---------------|-----------|
| Blogpost | 1, 2, 5 | 3, 4 | – |
| Sachbuch | 2, 3, 4 | 1, 5 | – |
| Tutorial | 2, 5 | 1 | 3, 4 |
| Fachtext | 2, 4 | – | 1, 3, 5 |
| Newsletter | 1, 2, 5 | 3 | 4 |
FILE:references/ki-muster.md
# KI-Schreibmuster – Deutsche Referenz
> 24 Muster die verraten, dass ein Text von einer KI stammt.
> Jedes Muster hat: Beschreibung, Erkennungsregel, deutsche Beispiele (Vorher/Nachher), Schweregrad.
---
## Muster #1: Bedeutungsinflation
**Schweregrad:** HOCH (+5 Punkte)
Jede Aussage wird aufgeblasen. Normale Dinge werden zu "entscheidenden Wendepunkten", "bahnbrechenden Durchbrüchen", "wegweisenden Meilensteinen".
**Erkennungsregel:** Superlative und Gewichtswörter ohne Beleg. Wenn man das Adjektiv streichen kann und der Satz nichts verliert → Bedeutungsinflation.
**Vorher (KI):**
> "Dies markiert einen entscheidenden Wendepunkt in der Entwicklung moderner Sprachmodelle."
**Nachher (menschlich):**
> "Das hat die Entwicklung von Sprachmodellen verändert."
**Vorher (KI):**
> "OpenClaw stellt einen bahnbrechenden Paradigmenwechsel in der Art dar, wie wir mit KI interagieren."
**Nachher (menschlich):**
> "OpenClaw macht KI-Arbeit einfacher. Deutlich einfacher."
---
## Muster #2: Prominenz-Dropping
**Schweregrad:** MITTEL (+3 Punkte)
Berühmte Namen, Medien oder Institutionen werden beiläufig erwähnt, ohne konkrete Belege. Klingt nach Autorität, liefert keine.
**Erkennungsregel:** Name oder Medium erwähnt + kein Link, kein Datum, keine Seitenzahl, kein konkretes Zitat.
**Vorher (KI):**
> "Wie bereits in führenden Fachzeitschriften beschrieben, verändert KI die Arbeitswelt grundlegend."
**Nachher (menschlich):**
> "Eine Studie der ILO von 2024 schätzt, dass 14% der Jobs durch KI wegfallen könnten (Quelle: ilo.org/ai-report-2024)."
**Vorher (KI):**
> "Experten auf der ganzen Welt sind sich einig, dass diese Technologie transformativ ist."
**Nachher (menschlich):**
> "Yann LeCun hält die aktuelle KI für überschätzt. Demis Hassabis hält dagegen. Wer recht hat? Wissen wir in zehn Jahren."
---
## Muster #3: -ung/-end Ketten (Partizip-Ketten)
**Schweregrad:** HOCH (+5 Punkte)
Partizip-Konstruktionen stapeln sich. Klingt wie eine Behörden-Verordnung, nicht wie ein Mensch.
**Erkennungsregel:** Mehr als 2 Partizipien (Präsens oder Perfekt) in einem Satz. Oder -ung-Substantive die sich häufen (>3 pro Absatz).
**Vorher (KI):**
> "Die Implementierung ermöglicht eine verbesserte Verarbeitung, wobei die Optimierung der Leistungsfähigkeit eine entscheidende Rolle bei der Skalierung spielend beiträgt."
**Nachher (menschlich):**
> "Damit läuft die Verarbeitung schneller. Und das System wächst mit."
**Vorher (KI):**
> "Zusammenfassend lässt sich feststellen, dass die zunehmende Digitalisierung eine weitreichende Veränderung der bestehenden Strukturen bewirkend voranschreitet."
**Nachher (menschlich):**
> "Die Digitalisierung ändert alles. Langsam, aber gründlich."
---
## Muster #4: Werbesprache
**Schweregrad:** HOCH (+5 Punkte)
Wörter die nach Produktbroschüre klingen. "Nahtlos", "robust", "skalierbar", "atemberaubend", "eingebettet". Kein Mensch redet so über Software.
**Erkennungsregel:** Wörter aus der Tier-1-Liste (siehe `vokabeln.md`) in nicht-technischem Kontext.
**Vorher (KI):**
> "Das nahtlos eingebettete System bietet eine robuste und skalierbare Lösung für moderne Herausforderungen."
**Nachher (menschlich):**
> "Das System funktioniert. Es hält Last aus und wächst mit deinen Anforderungen."
**Vorher (KI):**
> "Eine atemberaubende Synergie zwischen Mensch und Maschine entfaltet sich."
**Nachher (menschlich):**
> "Mensch und Maschine arbeiten hier tatsächlich zusammen. Nicht nur auf dem Papier."
---
## Muster #5: Vage Zuschreibungen
**Schweregrad:** HOCH (+5 Punkte)
"Experten glauben", "Studien zeigen", "Es ist allgemein bekannt" – ohne je zu sagen welche Experten, welche Studien.
**Erkennungsregel:** Autoritäts-Verweis ohne konkreten Namen, Datum oder Quelle.
**Vorher (KI):**
> "Studien zeigen, dass KI die Produktivität um bis zu 40% steigern kann."
**Nachher (menschlich):**
> "Eine McKinsey-Studie von 2023 nennt 40% Produktivitätssteigerung. Die Zahl ist umstritten – sie gilt nur für bestimmte Branchen und Aufgaben."
**Vorher (KI):**
> "Experten sind sich einig, dass diese Entwicklung unumkehrbar ist."
**Nachher (menschlich):**
> "Die meisten KI-Forscher sehen den Trend als gesetzt. Aber „unumkehrbar"? Das hat man über vieles gesagt."
---
## Muster #6: Formelhafte Herausforderungen
**Schweregrad:** MITTEL (+3 Punkte)
Das Muster: "Trotz [Herausforderung] bleibt/floriert/wächst [Subjekt] weiterhin." Klingt nach Template.
**Erkennungsregel:** "Trotz" + abstraktes Problem + positiver Ausgang in einem Satz.
**Vorher (KI):**
> "Trotz der Herausforderungen in der Implementierungsphase floriert das Projekt weiterhin."
**Nachher (menschlich):**
> "Die Implementierung war holprig. Zwei Wochen Verzögerung, ein Datenbank-Crash. Aber jetzt läuft es."
**Vorher (KI):**
> "Trotz zunehmender Komplexität bewährt sich der Ansatz in der Praxis."
**Nachher (menschlich):**
> "Es wird komplizierter. Trotzdem: Der Ansatz hält. Bisher jedenfalls."
---
## Muster #7: KI-Vokabular
**Schweregrad:** VARIABEL (siehe Tier-System in `vokabeln.md`)
Die KI hat Lieblingswörter. "Eintauchen", "Landschaft", "grundlegend", "ganzheitlich". Jedes einzelne ist harmlos. In der Masse verraten sie den Autor.
**Erkennungsregel:** Verweis auf die vollständige Vokabel-Datenbank in `references/vokabeln.md`. Hier wird nach Tier und Dichte gewertet, nicht nach Einzelwörtern.
**Vorher (KI):**
> "Lassen Sie uns in die facettenreiche Landschaft der KI-Entwicklung eintauchen und die grundlegenden Eckpfeiler betrachten."
**Nachher (menschlich):**
> "Schauen wir uns an, wie KI-Entwicklung wirklich funktioniert."
---
## Muster #8: Copula-Vermeidung
**Schweregrad:** HOCH (+5 Punkte)
KI vermeidet "ist", "hat", "war" und ersetzt sie durch aufgeblasene Alternativen: "dient als", "fungiert als", "stellt dar", "verkörpert".
**Erkennungsregel:** "fungiert als", "dient als", "stellt X dar", "verkörpert" wo "ist" reichen würde.
**Vorher (KI):**
> "OpenClaw fungiert als zentraler Knotenpunkt, der als Brücke zwischen verschiedenen KI-Modellen dient."
**Nachher (menschlich):**
> "OpenClaw ist die Zentrale. Von hier aus erreichst du alle KI-Modelle."
**Vorher (KI):**
> "Cowan verkörpert die Vision eines wahrhaft interaktiven Gedankenpartners."
**Nachher (menschlich):**
> "Cowan ist ein Gedankenpartner. Einer der auch mal Nein sagt."
---
## Muster #9: Negative Parallelismen
**Schweregrad:** HOCH (+5 Punkte)
"Es geht nicht nur um X, sondern auch um Y." / "Nicht nur... sondern..." – die Lieblingskonstruktion jeder KI.
**Erkennungsregel:** "nicht nur... sondern auch", "es geht nicht nur um... sondern", "weniger... als vielmehr".
**Vorher (KI):**
> "Es geht nicht nur um die technische Implementierung, sondern auch um die fundamentale Veränderung unserer Arbeitsweise."
**Nachher (menschlich):**
> "Klar, die Technik ist wichtig. Aber die eigentliche Frage: Wie ändert sich deine Arbeit dadurch?"
**Vorher (KI):**
> "OpenClaw ist nicht nur ein Tool, sondern eine ganzheitliche Plattform für KI-gestützte Kreativität."
**Nachher (menschlich):**
> "OpenClaw ist mehr als ein Tool. Wie viel mehr, merkst du erst beim Benutzen."
---
## Muster #10: Dreierregel
**Schweregrad:** MITTEL (+3 Punkte)
Drei Begriffe in einer Reihe: "Innovation, Inspiration und Erkenntnis." / "Effizienz, Qualität und Skalierbarkeit." KI liebt Dreierlisten.
**Erkennungsregel:** Drei abstrakte Begriffe in einer Aufzählung, verbunden mit "und". Besonders verdächtig wenn alle drei aus dem gleichen semantischen Feld kommen.
**Vorher (KI):**
> "Das System bietet Effizienz, Flexibilität und Skalierbarkeit."
**Nachher (menschlich):**
> "Das System ist schnell. Und es wächst mit dir."
**Vorher (KI):**
> "Diese Kombination aus Innovation, Kreativität und technischer Exzellenz."
**Nachher (menschlich):**
> "Gute Idee, gut umgesetzt. Mehr muss man dazu nicht sagen."
---
## Muster #11: Synonym-Cycling
**Schweregrad:** MITTEL (+3 Punkte)
KI vermeidet Wortwiederholungen zwanghaft. Ein "Agent" wird zum "Akteur", dann zur "Entität", dann zum "Protagonisten". Menschen wiederholen Wörter. Das ist normal.
**Erkennungsregel:** Dasselbe Konzept wird in 3+ Varianten innerhalb von 500 Wörtern benannt, ohne dass die verschiedenen Begriffe inhaltlich begründet sind.
**Vorher (KI):**
> "Der Agent verarbeitet die Anfrage. Der digitale Akteur leitet sie weiter. Die autonome Entität liefert das Ergebnis."
**Nachher (menschlich):**
> "Der Agent verarbeitet die Anfrage, leitet sie weiter und liefert das Ergebnis."
---
## Muster #12: Falsche Bereiche
**Schweregrad:** NIEDRIG (+1 Punkt)
Spektrum-Aussagen die beeindruckend klingen aber inhaltlich leer sind: "Vom Urknall bis zur dunklen Materie", "Von der Antike bis zur Moderne".
**Erkennungsregel:** "Von X bis Y" wo X und Y nur Stimmung erzeugen, ohne inhaltlichen Bezug zum Thema.
**Vorher (KI):**
> "Von einfachen Chatbots bis hin zu komplexen Multi-Agenten-Systemen erstreckt sich das Spektrum."
**Nachher (menschlich):**
> "Es gibt einfache Chatbots und es gibt Multi-Agenten-Systeme. Dazwischen liegen Welten."
---
## Muster #13: Gedankenstrich-Seuche
**Schweregrad:** HOCH (+5 Punkte)
KI streut Gedankenstriche (–) wie Konfetti. Jeder zweite Satz hat einen Einschub mit Gedankenstrichen.
**Erkennungsregel:** Mehr als 3 Gedankenstriche (–) pro Seite (~250 Wörter). Nicht verwechseln mit Bindestrichen (-).
**Vorher (KI):**
> "OpenClaw – das System für KI-Routing – bietet eine Lösung – und zwar eine gute – für das Problem der Modellauswahl."
**Nachher (menschlich):**
> "OpenClaw routet deine Anfragen ans richtige KI-Modell. Automatisch. Ohne dass du nachdenken musst."
---
## Muster #14: Fettdruck-Manie
**Schweregrad:** MITTEL (+3 Punkte)
Alles wird fett markiert. Jeder zweite Satz hat ein **hervorgehobenes** Wort. Echte Betonung verliert ihre Wirkung.
**Erkennungsregel:** Mehr als 5 Fettdruck-Markierungen pro 500 Wörter (außer in Überschriften, Tabellen, Code).
**Vorher (KI):**
> "Das **wichtigste** Feature ist die **automatische** Verteilung an **verschiedene** Modelle, was **besonders** für **professionelle** Anwender **entscheidend** ist."
**Nachher (menschlich):**
> "Das wichtigste Feature: automatische Verteilung an verschiedene Modelle. Besonders wenn du professionell damit arbeitest."
---
## Muster #15: Aufzählungs-Einschübe
**Schweregrad:** MITTEL (+3 Punkte)
"X – von A bis Z – macht Y." Parenthetische Einschübe mit Gedankenstrichen die eine Mini-Liste enthalten.
**Erkennungsregel:** Gedankenstrich-Paar mit Aufzählung dazwischen.
**Vorher (KI):**
> "Das System – von der Anfrage über die Verarbeitung bis zur Antwort – arbeitet vollautomatisch."
**Nachher (menschlich):**
> "Anfrage rein, Antwort raus. Dazwischen arbeitet das System automatisch."
---
## Muster #16: Title-Case-Überschriften
**Schweregrad:** NIEDRIG (+1 Punkt)
Überschriften im englischen Stil: "Die Zukunft Der Künstlichen Intelligenz Im Wandel Der Zeit." Im Deutschen werden nur Substantive großgeschrieben.
**Erkennungsregel:** Adjektive, Verben oder Präpositionen in Überschriften großgeschrieben.
**Vorher (KI):**
> "## Die Grundlegenden Prinzipien Des Modernen KI-Routings"
**Nachher (menschlich):**
> "## Die Prinzipien des KI-Routings"
---
## Muster #17: Emoji-Spam
**Schweregrad:** NIEDRIG (+1 Punkt)
Professioneller Sachtext mit 🚀💡🎯✨ dekoriert. Kein seriöser deutscher Autor macht das.
**Erkennungsregel:** Emojis in Fließtext (außer in Social-Media-Kontext, wo es angemessen ist).
**Vorher (KI):**
> "OpenClaw revolutioniert die KI-Arbeit! 🚀 Mit smarten Agents 💡 erreichst du deine Ziele 🎯"
**Nachher (menschlich):**
> "OpenClaw verändert die Art, wie du mit KI arbeitest. Die Agents nehmen dir die Routinearbeit ab."
---
## Muster #18: Chatbot-Artefakte
**Schweregrad:** HOCH (+5 Punkte)
Reste aus dem Chat-Kontext: "Tolle Frage!", "Ich hoffe, das hilft!", "Lass mich wissen, wenn du noch Fragen hast!", "Gerne! Hier ist..."
**Erkennungsregel:** Direkte Anrede des Lesers im Hilfsbereitschafts-Modus. Alles was nach "KI spricht mit User" klingt.
**Vorher (KI):**
> "Tolle Frage! Hier ist eine umfassende Erklärung der Agent-Architektur. Ich hoffe, das hilft dir weiter!"
**Nachher (menschlich):**
> "Die Agent-Architektur funktioniert so: ..."
---
## Muster #19: Wissens-Cutoff-Disclaimer
**Schweregrad:** HOCH (+5 Punkte)
"Stand meiner letzten Schulung...", "Soweit mir bekannt...", "Zum Zeitpunkt meines Wissens..." – KI-spezifische Absicherungsfloskeln.
**Erkennungsregel:** Jeder Verweis auf "Schulung", "Training", "Wissenstand" im Kontext einer Zeitbegrenzung.
**Vorher (KI):**
> "Stand meiner letzten Schulung im April 2024 gab es bereits über 100 LLMs auf dem Markt."
**Nachher (menschlich):**
> "Anfang 2024 gab es schon über 100 LLMs. Inzwischen dürften es deutlich mehr sein."
---
## Muster #20: Unterwürfiger Ton
**Schweregrad:** HOCH (+5 Punkte)
"Eine hervorragende Frage!", "Da haben Sie völlig Recht!", "Das ist ein sehr wichtiger Punkt!" – übertriebenes Lob an den Leser.
**Erkennungsregel:** Superlative Bewertung einer Frage oder Aussage des Lesers.
**Vorher (KI):**
> "Das ist eine ausgezeichnete Beobachtung! Sie haben absolut Recht, dass..."
**Nachher (menschlich):**
> "Ja, genau. Und daraus folgt..."
---
## Muster #21: Füllphrasen
**Schweregrad:** HOCH (+5 Punkte)
Phrasen die nichts zum Inhalt beitragen: "Um zu", "Aufgrund der Tatsache dass", "Es ist wichtig zu beachten", "In Anbetracht der Tatsache".
**Erkennungsregel:** Phrase streichen. Ändert sich der Sinn? Nein? → Füllphrase.
**Vorher (KI):**
> "Es ist wichtig zu beachten, dass die Konfiguration der SOUL.md eine entscheidende Rolle spielt."
**Nachher (menschlich):**
> "Die SOUL.md-Konfiguration ist entscheidend."
**Vorher (KI):**
> "Aufgrund der Tatsache, dass verschiedene Modelle unterschiedliche Stärken aufweisen, empfiehlt sich ein differenzierter Ansatz."
**Nachher (menschlich):**
> "Verschiedene Modelle können verschiedene Sachen gut. Also nutze das."
---
## Muster #22: Übermäßige Absicherung
**Schweregrad:** MITTEL (+3 Punkte)
"Könnte möglicherweise", "es wäre denkbar", "unter Umständen eventuell". Doppelte und dreifache Abschwächungen.
**Erkennungsregel:** Zwei oder mehr Konjunktive / Abschwächungen im selben Satz.
**Vorher (KI):**
> "Es wäre durchaus denkbar, dass sich diese Technologie möglicherweise als nützlich erweisen könnte."
**Nachher (menschlich):**
> "Die Technologie könnte nützlich sein. Ob sie's wirklich ist, muss sich zeigen."
---
## Muster #23: Generische Schlussfolgerungen
**Schweregrad:** HOCH (+5 Punkte)
"Die Zukunft sieht rosig aus", "Es bleibt spannend", "Die Möglichkeiten sind grenzenlos." Plattitüden die nichts sagen.
**Erkennungsregel:** Schluss-Satz eines Absatzes/Textes der allgemein-positiv ist ohne konkreten Bezug zum Inhalt.
**Vorher (KI):**
> "Die Zukunft der KI-gestützten Textproduktion sieht vielversprechend aus und die Möglichkeiten sind nahezu grenzenlos."
**Nachher (menschlich):**
> "Was in fünf Jahren möglich sein wird? Keine Ahnung. Aber dass sich die Textarbeit verändert, steht fest."
**Vorher (KI):**
> "Es bleibt spannend zu beobachten, wie sich diese Entwicklung weiter entfaltet."
**Nachher (menschlich):**
> "Das wars zum Thema Agent-Architektur. Im nächsten Kapitel bauen wir einen."
---
## Muster #24: Passiv + Nominalstil
**Schweregrad:** HOCH (+5 Punkte)
"Es wird davon ausgegangen", "Die Durchführung erfolgt", "Unter Berücksichtigung der Gegebenheiten". Behördendeutsch auf Steroiden.
**Erkennungsregel:** Passiv-Konstruktion + Substantivierung wo ein aktiver Satz mit konkretem Subjekt möglich wäre.
**Vorher (KI):**
> "Es wird davon ausgegangen, dass die Implementierung unter Berücksichtigung der bestehenden Infrastruktur durchgeführt werden kann."
**Nachher (menschlich):**
> "Wir denken, das klappt mit der bestehenden Infrastruktur."
**Vorher (KI):**
> "Die Erstellung der Konfiguration erfolgt durch den Benutzer mittels eines dafür vorgesehenen Editors."
**Nachher (menschlich):**
> "Du erstellst die Konfiguration im Editor."
---
## Schnell-Referenz: Schweregrade
| Schwere | Punkte | Muster |
|---------|--------|--------|
| HOCH (+5) | 1, 3, 4, 5, 8, 9, 13, 18, 19, 20, 21, 23, 24 |
| MITTEL (+3) | 2, 6, 10, 11, 14, 15, 22 |
| NIEDRIG (+1) | 12, 16, 17 |
FILE:_dev/SESSION-LOG.md
# Humanizer-DE – Session-Log
> **Sessions:** 46 (Skill-Bau) + 47 (Phase 4 – Tests & Kalibrierung) + 196 (Cleanup, Morphologie & v1.1.0) + 209 (Gedankenstrich-Erkennung & v1.2.0)
> **Datum:** 05.03.2026 (erstellt), 07.04.2026 (aktualisiert)
> **Gesamtumfang:** 10 Dateien, ~2.300 Zeilen Code/Doku
> **Status:** Phase 1–5 fertig. Auf ClawHub veroeffentlicht (`Tikitackr/humanizer-de`). v1.2.0.
>
> **v1.2.0 Aenderungen (Session 209):**
> - Muster #13 (Gedankenstrich-Seuche) im CLI implementiert: countGedankenstriche()
> - En-Dashes (–) im Fliesstext zaehlen, Code-Bloecke/Inline-Code/QR-Platzhalter filtern
> - Scoring: >3 pro ~250 Woerter = +5 Punkte pro Ueberschreitung, max +25
> - Neuer Abschnitt im Analyse-Report: "GEDANKENSTRICHE" mit Treffer-Anzahl, Dichte und Bewertung
> - Version 1.1.2 → 1.2.0 in _meta.json, SKILL.md, README.md
>
> **v1.1.0 Aenderungen (Session 196):**
> - README geschaerft: Klare Trennung Agent-Modus vs. CLI-Modus
> - Tier-1 Vokabeln synchronisiert (35 → 45, jetzt identisch mit vokabeln.md)
> - Fix-Befehl: Morphologisch korrekte Ersetzung (Adjektiv-/Substantiv-Suffixe)
> - Fix-Befehl: .bak-Backup vor Ueberschreiben
> - TIER1-Array um Wortart-Feld erweitert (adj/noun/verb/adv)
> - Chatbot-Artefakte in vokabeln.md dokumentiert
> - statistische-signale.md: "4 Signale" → "5 Signale" korrigiert, Report-Beispiel ergaenzt
> - SKILL.md: Kapitelverweise und Dashboard-Links aktualisiert
> - SESSION-LOG: Tier-2-Bug als gefixt markiert, Zahlen aktualisiert
> - _meta.json: Version 1.0.1 → 1.1.0, Description aktualisiert
> - Morphologische Ersetzung im Fix-Befehl: Adjektiv-Suffixe, Substantiv-Suffixe, Artikel-Korrektur
> - TIER1-Array um Wortart-Feld erweitert (adj/noun/verb/adv) + Genus-Mapping fuer Substantive
> - Artikel-Korrektur mit Praepositions-Heuristik (Dativ-Praep → dem/der, sonst Genitiv)
---
## Was wurde gebaut
Ein kompletter **deutscher KI-Text-Detektor & Humanisierer** als OpenClaw Skill.
### Dateistruktur (10 Dateien)
```
humanizer-de/
├── SKILL.md (223 Zeilen) – Hauptlogik, 6 Befehle, 5-Pass-Workflow, Scoring
├── SESSION-LOG.md (diese Datei)
├── references/
│ ├── ki-muster.md (446 Zeilen) – 24 KI-Muster, Vorher/Nachher, Schweregrade
│ ├── vokabeln.md (224 Zeilen) – 3-Tier-System + Co-Occurrence-Sets
│ ├── statistische-signale.md (316 Zeilen) – 5 Signale mit Formeln + Schwellenwerte
│ ├── personality-injection.md (259 Zeilen) – 5 Techniken, je 5+ Beispiele
│ ├── examples.md (279 Zeilen) – 6 Vorher/Nachher-Transformationen
│ └── stil-layer/
│ ├── basis.md (110 Zeilen) – Neutral-Humanisierung
│ └── lesch.md (175 Zeilen) – Lesch-Stil (3 Hüte)
└── scripts/
└── humanize-de.js (927 Zeilen) – Node.js CLI-Tool
```
---
## Features im Detail
### Scoring-System (0–100)
**Punkt-Quellen (Score erhöhen):**
| Quelle | Punkte |
|--------|--------|
| Tier-1-Wörter (verboten) | +3 pro Treffer |
| Tier-2-Wörter (Überschuss) | +1 pro Treffer über Limit |
| Verbotene Phrasen | +4 pro Treffer |
| Chatbot-Artefakte | +5 pro Treffer |
| Burstiness < 0.3 (nur ≥20 Sätze) | +10 |
| TTR < 0.5 | +5 |
| CoV < 0.3 | +5 |
| Trigramm-Rate > 0.10 | +5 |
| Flesch-DE 40–50 (KI-Sweetspot) | +3 |
| Co-Occurrence-Alarm (3+ Wörter aus Set) | +5 pro Cluster |
**Bonus-Abzüge (Score senken):**
| Quelle | Bonus |
|--------|-------|
| Einschübe in Klammern | -3 |
| Variabler Satzrhythmus | -5 |
| Kontraktionen (gibt's, ist's) | -2 |
| Konkrete Zahlen/Einheiten | -3 |
| Abschweifungen/Anekdoten | -3 |
| Satzfragmente | -2 |
| Lesch-Layer (optional) | bis -12 |
### Score-Skala
| Score | Bewertung |
|-------|-----------|
| 0–20 | Klingt menschlich |
| 21–40 | Leicht maschinell |
| 41–60 | Gemischt |
| 61–80 | Offensichtlich KI |
| 81–100 | ChatGPT-Standard |
### CLI-Tool (humanize-de.js)
4 Befehle: `score`, `analyze`, `suggest`, `fix`
```bash
node humanize-de.js score datei.md # Nur Score
node humanize-de.js analyze datei.md # Vollständiger Report
node humanize-de.js suggest datei.md # Ersetzungsvorschläge
node humanize-de.js fix datei.md # Automatische Tier-1/Phrasen-Ersetzung
```
**Keine Dependencies** außer `fs` und `path` (kein Netzwerk, kein npm install nötig).
### Funktionen im JS-Script
| Funktion | Zweck |
|----------|-------|
| `splitSentences(text)` | Text in Sätze aufteilen |
| `tokenize(text)` | Text in Wörter aufteilen |
| `findTier1(text)` | Tier-1-Woerter finden (45 Paare, v1.1.0 sync mit vokabeln.md) |
| `findTier2(text)` | Tier-2-Woerter finden (45 Woerter, v1.1-Erweiterung) |
| `findVerbotenePhrasen(text)` | 48 verbotene Phrasen scannen (v1.1-Erweiterung) |
| `findChatbotArtefakte(text)` | 16 Chatbot-Artefakte scannen |
| `calcBurstiness(sentences)` | Burstiness-Score berechnen |
| `calcTTR(text)` | Type-Token-Ratio (100-Wort-Fenster) |
| `calcCoV(sentences)` | Satzlängen-Variationskoeffizient |
| `calcTrigramRepeat(text)` | Trigramm-Wiederholungsrate |
| `countSyllablesDE(word)` | Deutsche Silbenzählung |
| `calcFleschDE(text)` | Flesch-DE Lesbarkeit (deutsche Formel) |
| `findCoOccurrences(text)` | Co-Occurrence-Cluster in Absätzen |
| `calcPersonalityBonus(text)` | Menschliche Stilmittel erkennen |
| `calculateScore(text)` | Gesamtscore berechnen |
| `fixText(text)` | Automatische Tier-1/Phrasen-Ersetzung |
| `formatScore/Analyze/Suggest` | Report-Formatierung |
---
## Test-Ergebnisse (Kalibrierung)
| Text | Score | Bewertung | Flesch-DE | Co-Occurrence |
|------|-------|-----------|-----------|---------------|
| Kapitel 1 (Entwurf) | 19 | Klingt menschlich | 60.3 (ok) | 0 Alarme |
| Vorwort v1 | 6 | Klingt menschlich | – | 0 Alarme |
| Vorwort v2 (Lesch) | 2 | Klingt menschlich | – | 0 Alarme |
| Synthetischer KI-Text | 98 | ChatGPT-Standard | 31.0 (ok) | 3 Alarme (+15) |
**Kalibrierung bestätigt:** Menschliche Texte 2–19, KI-Text 98. Klare Trennung.
### Session 47 – Erweiterte Tests (Phase 4)
| Text | Score | Bewertung |
|------|-------|-----------|
| ChatGPT-1 (KI & Gesellschaft, buzzword-heavy) | 92 | ChatGPT-Standard |
| ChatGPT-2 (Nachhaltigkeit, subtiler) | 42 | Gemischt |
| ChatGPT-3 (Digitale Bildung) | 64 | Offensichtlich KI |
| Mensch-1 (Stefan & Sensoren, Anekdote) | 0 | Klingt menschlich |
| Mensch-2 (Kaffee-Ritual, 26 Sätze) | 8 | Klingt menschlich |
| Mensch-3 (Flohmarkt Berlin) | 0 | Klingt menschlich |
**Anpassung:** Burstiness-Mindest-Satzanzahl von 10 auf 20 erhöht. Signal feuerte bei kurzen Texten (<20 Sätze) immer – egal ob Mensch oder KI. War reine Rauschquelle. Nach Fix: Menschliche Texte 0–8, KI-Texte 42–92.
**ChatGPT-2 bei 42 – Begründung:** Der Text ist subtiler (weniger Buzzwords, mehr Alltagssprache). "Gemischt" ist ein ehrliches Label – nicht jeder ChatGPT-Output ist ein Buzzword-Feuerwerk.
---
## Vergleich mit Original (Operator Humanizer)
Das englische Original (`Kevjade/operator-humanizer`) wurde als ZIP analysiert. Ergebnis:
### Was wir übernommen haben (als Idee, nicht als Code):
- Modulare Dateistruktur (SKILL.md + references/)
- 24-Muster-Konzept → ins Deutsche übersetzt + erweitert
- Tier-System für Vokabeln
- Statistische Signale (Burstiness, TTR, CoV)
- Personality-Injection-Techniken
- Scoring-System (0–100)
### Was wir aus dem Vergleich nachgebaut haben:
1. **examples.md** – 6 deutsche Vorher/Nachher-Transformationen (Original hatte 5 englische)
2. **Flesch-DE (Signal 5)** – Deutsche Lesbarkeitsformel (Original hatte englische Flesch-Kincaid)
3. **Co-Occurrence-Sets** – 5 Wortgruppen-Cluster (Original hatte 6 englische Sets)
### Was wir bewusst NICHT übernommen haben:
- **Strategic Misspellings** – Im Deutschen nicht sinnvoll (Duden-Regel)
- **Curly Quotes** – Im Deutschen irrelevant (wir nutzen „Anführungszeichen")
- Keinen Code aus dem Original
- Keine Unicode-Steuerzeichen
---
## Erledigte Phasen (aus STARTBEFEHL-HUMANIZER.md)
### ✅ Phase 1: Kern-Dateien (komplett)
- [x] SKILL.md
- [x] references/ki-muster.md
- [x] references/vokabeln.md
- [x] references/statistische-signale.md
- [x] references/personality-injection.md
### ✅ Phase 2: Stil-Layer (komplett)
- [x] references/stil-layer/basis.md
- [x] references/stil-layer/lesch.md
### ✅ Phase 3: CLI-Tool (komplett)
- [x] scripts/humanize-de.js (inkl. Flesch-DE + Co-Occurrence)
### ✅ Phase 3b: Vergleich mit Original (komplett)
- [x] examples.md hinzugefügt
- [x] Flesch-DE (Signal 5) integriert
- [x] Co-Occurrence-Sets integriert
- [x] Re-Test und Kalibrierung bestätigt
### ✅ Phase 4: Externe Tests & Kalibrierung (ERLEDIGT – Session 47)
- [x] 3 ChatGPT-Texte getestet → 92, 42, 64
- [x] 3 menschliche Texte getestet → 0, 8, 0
- [x] Burstiness-Schwelle angepasst (10 → 20 Sätze)
### ⬜ Phase 5: Veröffentlichung & Integration (OFFEN)
- [ ] Auf ClawHub veröffentlichen unter `OpenClaw/humanizer-de`
- [ ] `_meta.json` erstellen (Name, Version, Autor, Description)
- [ ] README für ClawHub schreiben
- [ ] QR-Code `HUMANIZER-INSTALL` im QR-Code-Plan ergänzen
- [ ] STARTBEFEHL-BUCH.md updaten: Humanizer als neues Asset
- [ ] Überarbeitungs-Notizen ergänzen
---
## Bekannte Einschraenkungen
1. **Burstiness-Berechnung** liefert manchmal negative Werte (z.B. -0.240 bei Kapitel 1). Mathematisch korrekt per Formel, aber ungewoehnlich. **Fix Session 47:** Mindest-Satzanzahl auf 20 erhoeht – bei kurzen Texten wird das Signal jetzt uebersprungen.
2. ~~**Tier-2-Zaehlung** zaehlte jedes Vorkommen als Ueberschuss, statt das Limit von 1 pro 500 Woerter zu beruecksichtigen.~~ **Gefixt (v1.1):** `findTier2()` prueft jetzt korrekt `count > maxAllowed` und zaehlt nur Ueberschuss-Treffer.
3. **Muster-Scan (24 KI-Muster)** ist nur in der SKILL.md als Workflow dokumentiert, NICHT im JS-Script implementiert. Das ist **by design**: Die 24-Muster-Erkennung braucht semantisches Verstaendnis und laeuft ueber den OpenClaw-Agent. Das CLI-Tool ist ein regelbasiertes Subset. README.md dokumentiert diese Trennung seit v1.1.0.
4. **Fix-Befehl** ersetzt Tier-1-Woerter (morphologisch korrekt) und verbotene Phrasen. Kein Rewriting ganzer Saetze. **Seit v1.1.0:** Morphologische Ersetzung mit 3 Ebenen: (a) Adjektiv-Suffixe -e/-en/-em/-er/-es werden aufs Ersatzwort uebertragen. (b) Substantiv-Suffixe (Genitiv-s, Plural) werden intelligent gehandhabt (kein doppeltes -s bei "Basis" etc.). (c) Artikel-Korrektur bei Genus-Wechsel mit Praepositions-Heuristik fuer Dativ/Genitiv-Unterscheidung. Erstellt automatisch ein `.bak`-Backup vor dem Ueberschreiben. **Bekannte Einschraenkungen:** (1) Komposita mit Bindestrich ("KI-Landschaft") → Artikel-Suche findet Artikel manchmal nicht. (2) Phrasen-Ersetzungen ("Meilenstein" → "wichtiger Schritt") → Gross/Kleinschreibung des Adjektivs im Ersatz nicht immer korrekt.
5. **Tier-3 nicht im CLI.** Reference-Dateien: 45 Tier-1, 46 Tier-2, 34 Tier-3, 48 Phrasen. CLI (v1.1.0): 45 Tier-1, 45 Tier-2, 48 Phrasen + 16 Chatbot-Artefakte. Tier-3 nur im Agent-Modus (braucht Kontext-Verstaendnis).
---
## Nächster Schritt im neuen Chat
```
Lies STARTBEFEHL-HUMANIZER.md und dann humanizer-de/SESSION-LOG.md.
Phase 1–4 sind fertig. Mach weiter mit Phase 5 (Veröffentlichung & Integration).
Erste Aufgabe: README.md für ClawHub schreiben.
```
FILE:README.md
# Humanizer-DE
**Erster deutscher KI-Text-Detektor fuer OpenClaw.**
> Version 1.2.0 · Autor: OpenClaw · Lizenz: MIT · Sprache: Deutsch
Dieser Skill hat **zwei Betriebsarten:**
| Modus | Was passiert | Umfang |
|-------|-------------|--------|
| **Agent-Modus** (SKILL.md) | OpenClaw fuehrt die vollstaendige 5-Durchgangs-Analyse durch | 24 KI-Muster, 125+ Vokabeln in 3 Tiers, 48 Phrasen, 5 Statistik-Signale, Personality Injection, Stil-Layer |
| **CLI-Modus** (humanize-de.js) | Standalone Node.js-Script, laeuft ohne KI | Tier-1/2-Vokabelcheck (90 Woerter), 48 Phrasen, 16 Chatbot-Artefakte, 5 Statistik-Signale, Co-Occurrence-Cluster, Auto-Fix |
Der **Agent-Modus** nutzt Claude als Analysemotor und hat Zugriff auf alle Reference-Dateien – inklusive 24 KI-Schreibmuster-Erkennung und Personality Injection. Das **CLI-Tool** ist ein regelbasiertes Subset fuer schnelle Checks ohne KI-Kosten.
---
## Was macht dieser Skill?
Du gibst ihm einen deutschen Text. Er sagt dir:
1. **Wie stark** der Text nach KI klingt (Score 0–100)
2. **Wo genau** KI-Muster stecken (markiert + erklaert)
3. **Wie du es besser machst** (konkrete Umschreibvorschlaege)
Score 0 = klingt menschlich. Score 100 = klingt wie ChatGPT auf Autopilot.
---
## Installation
Sag deinem OpenClaw:
> *"Installiere den Skill Tikitackr/humanizer-de"*
OpenClaw laedt den Skill herunter und bestaetigt die Installation. Fertig. Kein Terminal, kein manueller Download – alles laeuft ueber den Chat.
Der Skill wird per Chat-Befehl aufgerufen (z.B. "Check diesen Text") – er laeuft nicht automatisch im Hintergrund.
---
## Befehle
| Befehl | Was passiert |
|--------|-------------|
| `Check diesen Text` | Vollständiger Report: Score + Muster + Vokabeln + Statistik + Vorschläge |
| `Score: [Text]` | Nur der Score (0–100) mit Kurzeinschätzung |
| `Was klingt hier nach KI?` | Nur die problematischen Stellen markiert |
| `Humanisiere das` | Text umschreiben mit Personality Injection (Basis-Stil) |
| `Humanisiere das im Lesch-Stil` | Umschreiben mit Lesch-Layer (Visionär/Mahner/Erklärer) |
| `Mach das menschlicher` | Wie "Humanisiere das" – Synonym |
---
## Was wird analysiert?
### 24 KI-Schreibmuster (nur Agent-Modus)
Der Skill erkennt 24 typische Muster, die KI-generierte deutsche Texte verraten – von Bedeutungsinflation ueber Aufzaehlungs-Sucht bis zu leeren Verstaerkern. Jedes Muster hat einen Schweregrad (HOCH / MITTEL / NIEDRIG) und konkrete Umschreibvorschlaege.
> **Hinweis:** Die 24-Muster-Erkennung laeuft ueber den OpenClaw-Agent (SKILL.md). Das CLI-Tool prueft Vokabeln, Phrasen und Statistik – aber nicht die 24 Muster.
### KI-Vokabeln & Phrasen in 3 Tiers
Die Reference-Datenbank (`references/vokabeln.md`) umfasst 125+ Vokabeln und 48 Phrasen:
- **Tier 1 (VERBOTEN):** 45 Woerter die sofort auffallen ("ermoeglicht", "nahtlos", "massgeblich")
- **Tier 2 (SPARSAM):** 46 Woerter die in Massen okay sind, aber bei Haeufung KI signalisieren (inkl. Nominalstil-Marker wie "Fragestellung", "Zielsetzung")
- **Tier 3 (BEOBACHTEN):** 34 Woerter die nur im Cluster verdaechtig werden (inkl. Anglizismen wie "Benchmark", "Use Case", "Impact")
- **Verbotene Phrasen:** 48 Phrasen die sofort raus muessen ("Es ist wichtig zu beachten", "In der heutigen Welt", "Vor dem Hintergrund")
Das **CLI-Tool** implementiert davon: 45 Tier-1, 45 Tier-2, 48 Phrasen + 16 Chatbot-Artefakte. Tier-3 wird nur im Agent-Modus geprueft.
Plus **7 Co-Occurrence-Sets** – Wort-Cluster die gemeinsam auftreten und KI-Herkunft verraten (inkl. Anglizismen-Cluster und Nominalstil-Cluster). Im CLI und Agent verfuegbar.
### 5 Statistische Signale
| Signal | Was es misst |
|--------|-------------|
| Burstiness | Variation der Satzabstände (KI schreibt gleichmäßig) |
| Type-Token-Ratio | Wortschatz-Vielfalt pro 100-Wort-Fenster |
| Satzlängen-CoV | Variation der Satzlängen (KI = monoton) |
| Trigramm-Wiederholung | Wiederholte 3-Wort-Folgen |
| Flesch-DE | Lesbarkeit (KI-Texte landen oft im Sweetspot 40–50) |
### Personality Injection
5 Techniken machen Texte menschlicher: Einschübe, Rhythmuswechsel, Mini-Abschweifungen, Unsicherheitsmarker und Umgangssprache-Tupfer. Der Skill wählt je nach Kontext (formal vs. locker) die passende Mischung.
### Stil-Layer
- **Basis:** Neutrale Humanisierung ohne besonderen Stil. Funktioniert für jeden Text.
- **Lesch:** Inspiriert vom Erklärstil von Harald Lesch – Tonwechsel (Visionär/Mahner/Erklärer), Analogien, philosophische Anker.
---
## CLI-Tool (Standalone, Subset)
Im Ordner `scripts/` liegt ein Node.js CLI-Tool fuer schnelle Analysen **ohne KI**. Es implementiert:
- **45** Tier-1-Woerter (verboten, +3 Punkte)
- **45** Tier-2-Woerter (sparsam, +1 Punkt ueber Limit von 1x/500 Woerter)
- **48** verbotene Phrasen (+4 Punkte)
- **16** Chatbot-Artefakte (+5 Punkte)
- **5** statistische Signale (Burstiness, TTR, CoV, Trigramm-Rate, Flesch-DE)
- **7** Co-Occurrence-Sets (Cluster-Erkennung)
- **Personality-Bonus** (Abzuege fuer menschliche Stilmittel)
**Nicht im CLI:** 24 KI-Muster-Scan, Tier-3-Vokabeln, Personality Injection, Stil-Layer. Dafuer den Agent-Modus (SKILL.md) nutzen.
```bash
node humanize-de.js score datei.md # Nur Score (0-100)
node humanize-de.js analyze datei.md # Vollstaendiger Report
node humanize-de.js suggest datei.md # Ersetzungsvorschlaege
node humanize-de.js fix datei.md # Auto-Ersetzung (erstellt .bak-Backup)
```
Nur `fs` und `path` als Dependencies – kein Netzwerk, keine externen Pakete.
---
## Kalibrierung
Getestet an 7+ Texten in Session 46–47:
| Texttyp | Score-Bereich | Erwartung | Ergebnis |
|---------|---------------|-----------|----------|
| Menschlich geschrieben | 0–8 | 0–30 | Passt |
| Lesch-Stil (KI-bereinigt) | 2–6 | 0–30 | Passt |
| Subtiler KI-Text | 42 | 30–60 ("Gemischt") | Passt |
| Typischer ChatGPT-Text | 64–92 | 60–100 | Passt |
| Offensichtlicher KI-Text | 98 | 60–100 | Passt |
---
## Dateistruktur
```
humanizer-de/
├── _meta.json Skill-Metadaten
├── README.md Diese Datei
├── SKILL.md Hauptlogik & Workflow
├── references/
│ ├── ki-muster.md 24 KI-Schreibmuster (deutsch)
│ ├── vokabeln.md 168 KI-Vokabeln & Phrasen in 3 Tiers
│ ├── statistische-signale.md 5 statistische Signale mit Formeln
│ ├── personality-injection.md 5 Humanisierungs-Techniken
│ ├── examples.md 6 Vorher/Nachher-Transformationen
│ └── stil-layer/
│ ├── basis.md Standard-Humanisierung
│ └── lesch.md Lesch-Erweiterung
└── scripts/
└── humanize-de.js Node.js CLI-Tool (960 Zeilen)
```
---
## Teil des OpenClaw-Projekts
Dieser Skill ist eigenständig nutzbar – du brauchst kein Buch und kein Dashboard.
Wenn du mehr willst: Der Skill ist Teil des **OpenClaw Sachbuch-Projekts** ("Agentic Authorship"), das erklärt wie man KI-Agenten baut, betreibt und qualitätssichert. Das Buch nutzt den Humanizer selbst für die eigene Textqualität.
- Dashboard: https://openclaw-buch.de
- Cowan (mobiler Buch-Begleiter): https://openclaw-buch.de/?module=companion
---
## Lizenz
MIT – mach damit was du willst. Wenn du ihn verbesserst, teil es gern auf ClawHub.
FILE:scripts/humanize-de.js
#!/usr/bin/env node
/**
* humanize-de.js – Deutscher KI-Text-Detektor (CLI)
*
* Befehle:
* score <datei> Berechnet den KI-Score (0-100)
* analyze <datei> Detaillierte Analyse mit allen Signalen
* suggest <datei> Zeigt Ersetzungsvorschläge
* fix <datei> Automatische Tier-1-Ersetzungen (schreibt neue Datei)
*
* Nur fs und path als Dependencies. Kein Netzwerk. Alles lokal.
*
* Autor: OpenClaw
* Lizenz: MIT
*/
const fs = require('fs');
const path = require('path');
// ============================================================
// DATENBANKEN
// ============================================================
/**
* Tier 1 – VERBOTEN (immer ersetzen, +3 Punkte pro Treffer)
* Format: [KI-Wort, Ersetzungsvorschlag]
*/
/**
* Wortart-Kuerzel fuer morphologisches Fix:
* 'adj' → Adjektiv: Suffix-Matching -e/-en/-em/-er/-es
* 'noun' → Substantiv: Genitiv-s, Plural -e/-en, Dativ -en (nur sichere Faelle)
* 'verb' → Verb: nur Infinitiv ersetzen (kein Konjugations-Matching)
* 'adv' → Adverb: keine Flexion, 1:1 ersetzen
* 'phrase' → Mehrwort: 1:1 ersetzen
*
* Format: [KI-Wort, Ersetzung, Wortart]
*/
const TIER1 = [
// Adjektive (Suffix-Matching aktiv)
['grundlegend', 'wichtig', 'adj'],
['nahtlos', 'reibungslos', 'adj'],
['robust', 'stabil', 'adj'],
['skalierbar', 'erweiterbar', 'adj'],
['ganzheitlich', 'umfassend', 'adj'],
['bahnbrechend', 'wichtig', 'adj'],
['wegweisend', 'einflussreich', 'adj'],
['transformativ', 'verändernd', 'adj'],
['synergetisch', 'ergänzend', 'adj'],
['facettenreich', 'vielseitig', 'adj'],
['unschätzbar', 'sehr wertvoll', 'adj'],
['eingebettet', 'integriert', 'adj'],
['herausragend', 'stark', 'adj'],
['maßgeblich', 'stark', 'adj'],
['tiefgreifend', 'spürbar', 'adj'],
['unverzichtbar', 'nötig', 'adj'],
['überwältigend', 'stark', 'adj'],
['federführend', 'führend', 'adj'],
['richtungsweisend', 'wichtig', 'adj'],
['zukunftsweisend', 'vorausschauend', 'adj'],
['beispiellos', 'einmalig', 'adj'],
['außerordentlich', 'besonders', 'adj'],
['umfassend', 'vollständig', 'adj'],
['vielfältig', 'verschieden', 'adj'],
['lebendig', 'aktiv', 'adj'],
['entscheidend', 'wichtig', 'adj'],
['bemerkenswert', 'auffällig', 'adj'],
// Adverbien (keine Flexion)
['hochgradig', 'sehr', 'adv'],
['zweifellos', 'sicher', 'adv'],
['unbestreitbar', 'klar', 'adv'],
// Substantive (Genitiv-s, Plural, Dativ)
// Format: [Wort, Ersetzung, 'noun', {from: Genus-Original, to: Genus-Ersetzung}]
// Genus: 'm' = maskulin, 'f' = feminin, 'n' = neutrum
// Genus-Feld nur noetig wenn sich das Genus aendert (fuer Artikel-Korrektur)
['Eckpfeiler', 'Basis', 'noun', {from: 'm', to: 'f'}],
['Katalysator', 'Antrieb', 'noun'],
['Tapisserie', 'Geflecht', 'noun', {from: 'f', to: 'n'}],
['Wandteppich', 'Geflecht', 'noun', {from: 'm', to: 'n'}],
['Paradigmenwechsel', 'Umdenken', 'noun', {from: 'm', to: 'n'}],
['Meilenstein', 'wichtiger Schritt', 'noun'],
['Wendepunkt', 'Umbruch', 'noun'],
['Schlüsselrolle', 'wichtige Rolle', 'noun'],
['Vorreiter', 'Pionier', 'noun'],
['Brennpunkt', 'Schwerpunkt', 'noun'],
['Paradigma', 'Denkmodell', 'noun'],
['Landschaft', 'Bereich', 'noun', {from: 'f', to: 'm'}],
// Verben (nur Infinitiv)
['ermächtigen', 'in die Lage versetzen', 'verb'],
['befähigen', 'helfen', 'verb'],
['eintauchen', 'anschauen', 'verb'],
];
/**
* Tier 2 – SPARSAM (max 1x pro 500 Wörter, +1 Punkt über Limit)
*/
const TIER2 = [
'darüber hinaus', 'des Weiteren', 'zudem', 'nuanciert',
'erleichtern', 'beleuchten', 'umfassen', 'proaktiv',
'wesentlich', 'darauf abzielen', 'in der Lage sein',
'ermöglichen', 'gewährleisten', 'berücksichtigen',
'Aspekt', 'Kontext', 'relevant', 'optimieren',
'implementieren', 'integrieren', 'adressieren',
'transparent', 'signifikant', 'elementar', 'essenziell',
'komplex', 'Potenzial', 'effektiv', 'effizient',
// Erweiterung v1.1 (Session 48)
'nutzerorientiert', 'datengetrieben', 'zukunftsfähig',
'evidenzbasiert', 'praxiserprobt', 'niedrigschwellig',
'Handlungsempfehlung', 'Zielsetzung', 'Fragestellung',
'Problemstellung', 'Herangehensweise', 'Gegebenheiten',
'fungieren', 'aufweisen', 'darstellen', 'verorten',
];
/**
* Verbotene Phrasen (+4 Punkte pro Treffer)
*/
const VERBOTENE_PHRASEN = [
'es ist wichtig zu beachten',
'nicht nur... sondern auch',
'nicht nur',
'in der heutigen welt',
'in einer welt, in der',
'in einer welt in der',
'lass uns ehrlich sein',
'um ehrlich zu sein',
'darüber hinaus',
'des weiteren',
'ermöglicht es',
'bietet die möglichkeit',
'grundlegend anders',
'im kern',
'im grunde',
'zusammenfassend lässt sich sagen',
'es lässt sich festhalten',
'abschließend sei gesagt',
'wie bereits erwähnt',
'an dieser stelle sei erwähnt',
'es sei darauf hingewiesen',
'in anbetracht der tatsache',
'aufgrund der tatsache',
'im folgenden wird erläutert',
'es gilt zu beachten',
'nicht zuletzt',
'zu guter letzt',
'last but not least',
// Erweiterung v1.1 (Session 48)
'in diesem zusammenhang',
'vor dem hintergrund',
'im rahmen von',
'unter berücksichtigung',
'es zeigt sich, dass',
'es zeigt sich dass',
'es wird deutlich, dass',
'es wird deutlich dass',
'eine vielzahl von',
'eine reihe von',
'einen wesentlichen beitrag',
'im hinblick auf',
'hinsichtlich',
'dies unterstreicht',
'es bleibt abzuwarten',
'es bleibt spannend',
'die zukunft wird zeigen',
'spielt eine entscheidende rolle',
'von entscheidender bedeutung',
'stellt einen wichtigen schritt dar',
];
/**
* Chatbot-Artefakte (+5 Punkte pro Treffer)
*/
const CHATBOT_ARTEFAKTE = [
'tolle frage',
'gute frage',
'hervorragende frage',
'ausgezeichnete frage',
'ich hoffe, das hilft',
'ich hoffe das hilft',
'lass mich wissen',
'lassen sie mich wissen',
'gerne!',
'natürlich!',
'selbstverständlich!',
'da haben sie völlig recht',
'da hast du völlig recht',
'stand meiner letzten schulung',
'soweit mir bekannt',
'zum zeitpunkt meines wissens',
];
// ============================================================
// HILFSFUNKTIONEN
// ============================================================
/**
* Text in Sätze aufteilen (einfache Heuristik)
*/
function splitSentences(text) {
// Sätze an . ! ? trennen, aber nicht bei Abkürzungen wie "z.B." oder "etc."
const raw = text.replace(/([.!?])\s+/g, '$1\n').split('\n');
return raw
.map(s => s.trim())
.filter(s => s.length > 0 && s.split(/\s+/).length >= 1);
}
/**
* Wörter aus Text extrahieren (lowercase, ohne Satzzeichen)
*/
function tokenize(text) {
return text
.toLowerCase()
.replace(/[^\wäöüß\s-]/g, ' ')
.split(/\s+/)
.filter(w => w.length > 0);
}
/**
* Standardabweichung berechnen
*/
function stddev(arr) {
const n = arr.length;
if (n === 0) return 0;
const mean = arr.reduce((a, b) => a + b, 0) / n;
const variance = arr.reduce((sum, val) => sum + (val - mean) ** 2, 0) / n;
return Math.sqrt(variance);
}
/**
* Mittelwert berechnen
*/
function mean(arr) {
if (arr.length === 0) return 0;
return arr.reduce((a, b) => a + b, 0) / arr.length;
}
// ============================================================
// ANALYSE-FUNKTIONEN
// ============================================================
/**
* Adjektiv-Suffixe fuer morphologisches Matching.
* Deutsche Adjektive koennen diese Endungen haben: -e, -en, -em, -er, -es.
* Optional: Grundform ohne Suffix (praedikativ: "das ist wichtig").
*/
const ADJ_SUFFIXES = '(?:es|en|em|er|e)?';
/**
* Substantiv-Suffixe fuer einfaches morphologisches Matching.
* Deckt Genitiv-s, Plural -e/-en, Dativ-Plural -en ab.
* Bewusst konservativ – lieber mal nicht matchen als falsch ersetzen.
*/
const NOUN_SUFFIXES = '(?:s|es|en|e)?';
/**
* Baut den passenden Regex fuer ein Tier-1-Wort basierend auf Wortart.
*/
function buildTier1Regex(word, type) {
const escaped = word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
switch (type) {
case 'adj':
return new RegExp(`\\bescaped(ADJ_SUFFIXES)\\b`, 'gi');
case 'noun':
return new RegExp(`\\bescaped(NOUN_SUFFIXES)\\b`, 'gi');
case 'verb':
// Nur Infinitiv matchen – Konjugation ist zu komplex
return new RegExp(`\\bescaped\\b`, 'gi');
default: // 'adv', 'phrase'
return new RegExp(`\\bescaped\\b`, 'gi');
}
}
/**
* Tier-1-Wörter finden (mit morphologischem Matching)
*/
function findTier1(text) {
const hits = [];
for (const [word, replacement, type] of TIER1) {
const regex = buildTier1Regex(word, type);
let match;
while ((match = regex.exec(text)) !== null) {
const suffix = match[1] || '';
hits.push({
word: word,
matched: match[0],
replacement: replacement,
suffix: suffix,
type: type,
position: match.index,
tier: 1,
});
}
}
return hits;
}
/**
* Tier-2-Wörter finden und Dichte prüfen
*/
function findTier2(text) {
const lower = text.toLowerCase();
const wordCount = tokenize(text).length;
const maxAllowed = Math.max(1, Math.floor(wordCount / 500));
const hits = [];
for (const word of TIER2) {
const regex = new RegExp(word.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'gi');
let count = 0;
let match;
while ((match = regex.exec(lower)) !== null) {
count++;
if (count > maxAllowed) {
hits.push({
word: word,
position: match.index,
tier: 2,
count: count,
maxAllowed: maxAllowed,
});
}
}
}
return hits;
}
/**
* Verbotene Phrasen finden
*/
function findVerbotenePhrasen(text) {
const lower = text.toLowerCase();
const hits = [];
for (const phrase of VERBOTENE_PHRASEN) {
const regex = new RegExp(phrase.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'gi');
let match;
while ((match = regex.exec(lower)) !== null) {
hits.push({
phrase: phrase,
position: match.index,
});
}
}
return hits;
}
/**
* Chatbot-Artefakte finden
*/
function findChatbotArtefakte(text) {
const lower = text.toLowerCase();
const hits = [];
for (const artifact of CHATBOT_ARTEFAKTE) {
if (lower.includes(artifact)) {
hits.push({ artifact: artifact });
}
}
return hits;
}
/**
* Burstiness berechnen
*/
function calcBurstiness(sentences) {
if (sentences.length < 20) return { value: null, note: 'Zu wenige Sätze (<20)' };
const lengths = sentences.map(s => tokenize(s).length);
const m = mean(lengths);
const s = stddev(lengths);
if (s + m === 0) return { value: 0, note: 'Alle Sätze gleich lang' };
return { value: (s - m) / (s + m) };
}
/**
* Type-Token-Ratio berechnen (gleitendes 100-Wort-Fenster)
*/
function calcTTR(text) {
const tokens = tokenize(text);
if (tokens.length < 50) return { value: null, note: 'Zu wenige Wörter (<50)' };
const windowSize = 100;
const ttrs = [];
for (let i = 0; i <= tokens.length - windowSize; i += 50) {
const window = tokens.slice(i, i + windowSize);
const unique = new Set(window);
ttrs.push(unique.size / window.length);
}
if (ttrs.length === 0) {
const unique = new Set(tokens);
return { value: unique.size / tokens.length };
}
return { value: mean(ttrs) };
}
/**
* Satzlängen-CoV berechnen
*/
function calcCoV(sentences) {
if (sentences.length < 5) return { value: null, note: 'Zu wenige Sätze (<5)' };
const lengths = sentences.map(s => tokenize(s).length);
const m = mean(lengths);
if (m === 0) return { value: 0 };
const s = stddev(lengths);
return { value: s / m };
}
/**
* Trigramm-Wiederholung berechnen
*/
function calcTrigramRepeat(text) {
const sentences = splitSentences(text);
const trigramCounts = {};
let totalTrigrams = 0;
for (const sentence of sentences) {
const tokens = tokenize(sentence);
for (let i = 0; i < tokens.length - 2; i++) {
const trigram = `tokens[i] tokens[i + 1] tokens[i + 2]`;
trigramCounts[trigram] = (trigramCounts[trigram] || 0) + 1;
totalTrigrams++;
}
}
if (totalTrigrams === 0) return { value: 0 };
const repeated = Object.values(trigramCounts).filter(c => c > 1).length;
return { value: repeated / totalTrigrams };
}
/**
* Deutsche Silbenzählung (vereinfacht)
*/
function countSyllablesDE(word) {
word = word.toLowerCase().replace(/[^a-zäöüß]/g, '');
if (word.length <= 2) return 1;
// Diphthonge als 1 Silbe zählen
let processed = word
.replace(/ei/g, 'X')
.replace(/ai/g, 'X')
.replace(/au/g, 'X')
.replace(/eu/g, 'X')
.replace(/äu/g, 'X')
.replace(/ie/g, 'X');
const vowels = processed.match(/[aeiouäöüX]/g);
return vowels ? Math.max(1, vowels.length) : 1;
}
/**
* Flesch-DE Lesbarkeit berechnen
*/
function calcFleschDE(text) {
const sentences = splitSentences(text);
const tokens = tokenize(text);
if (sentences.length < 3 || tokens.length < 30) {
return { value: null, note: 'Zu wenig Text für Flesch-Berechnung' };
}
const totalSyllables = tokens.reduce((sum, w) => sum + countSyllablesDE(w), 0);
const avgSentenceLength = tokens.length / sentences.length;
const avgSyllablesPerWord = totalSyllables / tokens.length;
// Deutsche Flesch-Formel
const flesch = 180 - avgSentenceLength - (58.5 * avgSyllablesPerWord);
return { value: Math.max(0, Math.min(100, flesch)) };
}
/**
* Co-Occurrence-Sets prüfen (Wort-Cluster in Absätzen)
*/
const CO_OCCURRENCE_SETS = [
// Set 1: Bedeutungs-Aufblasung
['grundlegend', 'maßgeblich', 'entscheidend', 'tiefgreifend', 'bahnbrechend',
'wegweisend', 'meilenstein', 'wendepunkt', 'paradigmenwechsel'],
// Set 2: Werbesprache
['nahtlos', 'robust', 'skalierbar', 'ganzheitlich', 'umfassend',
'herausragend', 'innovativ', 'zukunftsweisend'],
// Set 3: Abstrakte Metaphern
['landschaft', 'eckpfeiler', 'katalysator', 'facettenreich',
'tapisserie', 'eingebettet', 'ökosystem'],
// Set 4: Aktions-Verben
['ermächtigen', 'befähigen', 'ermöglichen', 'gewährleisten',
'erleichtern', 'optimieren', 'implementieren', 'integrieren'],
// Set 5: Übergangs-Füller
['darüber hinaus', 'des weiteren', 'zudem', 'nicht zuletzt',
'abschließend', 'zusammenfassend', 'im folgenden'],
// Set 6: Anglizismen-Cluster (v1.1)
['benchmark', 'best practice', 'use case', 'alignment', 'empowerment',
'impact', 'leverage', 'onboarding', 'upskilling', 'gamechanger'],
// Set 7: Nominalstil-Cluster (v1.1)
['zielsetzung', 'fragestellung', 'problemstellung',
'handlungsempfehlung', 'herangehensweise', 'gegebenheiten'],
];
function findCoOccurrences(text) {
// Absätze trennen
const paragraphs = text.split(/\n\s*\n/).filter(p => p.trim().length > 0);
const alarms = [];
for (let pi = 0; pi < paragraphs.length; pi++) {
const lower = paragraphs[pi].toLowerCase();
for (let si = 0; si < CO_OCCURRENCE_SETS.length; si++) {
const matches = CO_OCCURRENCE_SETS[si].filter(word => lower.includes(word));
if (matches.length >= 3) {
alarms.push({
paragraph: pi + 1,
set: si + 1,
matches: matches,
count: matches.length,
});
}
}
}
return alarms;
}
/**
* Personality-Bonus berechnen
*/
function calcPersonalityBonus(text) {
let bonus = 0;
const details = [];
// Einschübe in Klammern
const klammerMatches = text.match(/\([^)]{5,60}\)/g);
if (klammerMatches && klammerMatches.length > 0) {
bonus -= 3;
details.push(`Einschübe in Klammern: klammerMatches.lengthx (-3)`);
}
// Satzrhythmus prüfen
const sentences = splitSentences(text);
const lengths = sentences.map(s => tokenize(s).length);
let monotone = false;
for (let i = 0; i < lengths.length - 2; i++) {
if (Math.abs(lengths[i] - lengths[i + 1]) < 3 &&
Math.abs(lengths[i + 1] - lengths[i + 2]) < 3) {
monotone = true;
break;
}
}
if (!monotone && sentences.length >= 5) {
bonus -= 5;
details.push('Satzrhythmus variiert (-5)');
}
// Kontraktionen
const kontraktionen = text.match(/\b(gibt's|ist's|hat's|geht's|war's|kann's|muss's|werd's|wär's|hätt's)\b/gi);
if (kontraktionen && kontraktionen.length > 0) {
bonus -= 2;
details.push(`Kontraktionen: kontraktionen.lengthx (-2)`);
}
// Konkrete Zahlen
const zahlen = text.match(/\d+[.,]?\d*\s*(%|€|\$|Prozent|Euro|Dollar|Stunden|Tage|Wochen|Monate|Jahre)/g);
if (zahlen && zahlen.length >= 2) {
bonus -= 3;
details.push(`Konkrete Zahlen/Einheiten: zahlen.lengthx (-3)`);
}
// Satzfragmente (Sätze unter 4 Wörtern)
const fragmente = sentences.filter(s => tokenize(s).length <= 3 && tokenize(s).length > 0);
if (fragmente.length > 0) {
bonus -= 2;
details.push(`Satzfragmente: fragmente.lengthx (-2)`);
}
return { bonus, details };
}
// ============================================================
// GEDANKENSTRICH-ERKENNUNG (Muster #13)
// ============================================================
/**
* Zählt En-Dashes (–) im Fließtext.
* Ignoriert:
* - QR-Code-Platzhalter: [QR-CODE: ID – Beschreibung]
* - Code-Blöcke (``` ... ```)
* - Inline-Code (`...`)
* Regel aus ki-muster.md: >3 pro ~250 Wörter = HOCH (+5 Punkte pro Überschreitung)
*/
function countGedankenstriche(text) {
// Code-Blöcke entfernen
let cleaned = text.replace(/```[\s\S]*?```/g, '');
// Inline-Code entfernen
cleaned = cleaned.replace(/`[^`]+`/g, '');
// QR-Code-Platzhalter entfernen
cleaned = cleaned.replace(/\[QR-CODE:[^\]]*\]/g, '');
// Alle En-Dashes im bereinigten Text finden
const matches = cleaned.match(/–/g);
const total = matches ? matches.length : 0;
// Wörter zählen für Dichte-Berechnung
const words = tokenize(cleaned).length;
const pages = Math.max(1, Math.round(words / 250));
const perPage = words > 0 ? total / pages : 0;
// Schwelle: >3 pro 250 Wörter
const threshold = pages * 3;
const excess = Math.max(0, total - threshold);
return {
total,
words,
pages,
perPage: perPage.toFixed(1),
threshold,
excess,
};
}
// ============================================================
// SCORE-BERECHNUNG
// ============================================================
function calculateScore(text) {
let score = 0;
const report = {
tier1: [],
tier2: [],
phrasen: [],
chatbot: [],
gedankenstriche: {},
statistik: {},
coOccurrence: [],
personality: {},
details: [],
};
// Tier 1
const t1 = findTier1(text);
report.tier1 = t1;
score += t1.length * 3;
if (t1.length > 0) report.details.push(`Tier-1-Wörter: t1.lengthx (+t1.length * 3)`);
// Tier 2
const t2 = findTier2(text);
report.tier2 = t2;
score += t2.length * 1;
if (t2.length > 0) report.details.push(`Tier-2-Überschuss: t2.lengthx (+t2.length)`);
// Verbotene Phrasen
const vp = findVerbotenePhrasen(text);
report.phrasen = vp;
score += vp.length * 4;
if (vp.length > 0) report.details.push(`Verbotene Phrasen: vp.lengthx (+vp.length * 4)`);
// Chatbot-Artefakte
const ca = findChatbotArtefakte(text);
report.chatbot = ca;
score += ca.length * 5;
if (ca.length > 0) report.details.push(`Chatbot-Artefakte: ca.lengthx (+ca.length * 5)`);
// Gedankenstriche (Muster #13)
const gs = countGedankenstriche(text);
report.gedankenstriche = gs;
if (gs.excess > 0) {
const gsScore = Math.min(gs.excess * 5, 25); // Max +25 Punkte (Cap)
score += gsScore;
report.details.push(`Gedankenstriche: gs.totalx in ~gs.pages Seite(n), gs.perPage/Seite (Limit 3/Seite → gs.excess über Limit → +gsScore)`);
}
// Statistik
const sentences = splitSentences(text);
const burstiness = calcBurstiness(sentences);
report.statistik.burstiness = burstiness;
if (burstiness.value !== null && burstiness.value < 0.3) {
score += 10;
report.details.push(`Burstiness: burstiness.value.toFixed(3) (<0.3 → +10)`);
}
const ttr = calcTTR(text);
report.statistik.ttr = ttr;
if (ttr.value !== null && ttr.value < 0.5) {
score += 5;
report.details.push(`TTR: ttr.value.toFixed(3) (<0.5 → +5)`);
}
const cov = calcCoV(sentences);
report.statistik.cov = cov;
if (cov.value !== null && cov.value < 0.3) {
score += 5;
report.details.push(`CoV: cov.value.toFixed(3) (<0.3 → +5)`);
}
const trigram = calcTrigramRepeat(text);
report.statistik.trigram = trigram;
if (trigram.value > 0.10) {
score += 5;
report.details.push(`Trigramm-Rate: trigram.value.toFixed(3) (>0.10 → +5)`);
}
// Flesch-DE (Signal 5)
const flesch = calcFleschDE(text);
report.statistik.flesch = flesch;
if (flesch.value !== null && flesch.value >= 40 && flesch.value <= 50) {
score += 3;
report.details.push(`Flesch-DE: flesch.value.toFixed(1) (KI-Sweetspot 40–50 → +3)`);
}
// Co-Occurrence-Sets
const coOcc = findCoOccurrences(text);
report.coOccurrence = coOcc;
if (coOcc.length > 0) {
const coOccScore = coOcc.length * 5;
score += coOccScore;
report.details.push(`Co-Occurrence-Alarm: coOcc.length Cluster (+coOccScore)`);
}
// Personality Bonus
const personality = calcPersonalityBonus(text);
report.personality = personality;
score += personality.bonus;
// Clamp
score = Math.max(0, Math.min(100, score));
report.score = score;
return report;
}
// ============================================================
// BEWERTUNG
// ============================================================
function getBewertung(score) {
if (score <= 20) return 'Klingt menschlich';
if (score <= 40) return 'Leicht maschinell';
if (score <= 60) return 'Gemischt';
if (score <= 80) return 'Offensichtlich KI';
return 'ChatGPT-Standard';
}
// ============================================================
// OUTPUT-FORMATIERUNG
// ============================================================
function formatScore(report) {
const bewertung = getBewertung(report.score);
return `\n SCORE: report.score / 100 → bewertung\n`;
}
function formatAnalyze(report, text) {
const lines = [];
const wordCount = tokenize(text).length;
const sentenceCount = splitSentences(text).length;
lines.push('');
lines.push('═══════════════════════════════════════════');
lines.push(' HUMANIZER-DE · Analyse-Report');
lines.push('═══════════════════════════════════════════');
lines.push('');
lines.push(` SCORE: report.score / 100 → getBewertung(report.score)`);
lines.push(` Wörter: wordCount | Sätze: sentenceCount`);
lines.push('');
// Tier 1
lines.push('───────────────────────────────────────────');
lines.push(` 1. TIER-1-WÖRTER (report.tier1.length gefunden, +report.tier1.length * 3 Pkt)`);
lines.push('───────────────────────────────────────────');
if (report.tier1.length === 0) {
lines.push(' Keine Tier-1-Wörter gefunden. Gut!');
} else {
// Deduplizieren
const seen = new Set();
for (const hit of report.tier1) {
const key = hit.word.toLowerCase();
if (!seen.has(key)) {
seen.add(key);
const count = report.tier1.filter(h => h.word.toLowerCase() === key).length;
lines.push(` ▸ "hit.word" (countx) → "hit.replacement"`);
}
}
}
lines.push('');
// Verbotene Phrasen
lines.push('───────────────────────────────────────────');
lines.push(` 2. VERBOTENE PHRASEN (report.phrasen.length gefunden, +report.phrasen.length * 4 Pkt)`);
lines.push('───────────────────────────────────────────');
if (report.phrasen.length === 0) {
lines.push(' Keine verbotenen Phrasen gefunden. Gut!');
} else {
const seen = new Set();
for (const hit of report.phrasen) {
if (!seen.has(hit.phrase)) {
seen.add(hit.phrase);
lines.push(` ▸ "hit.phrase"`);
}
}
}
lines.push('');
// Chatbot-Artefakte
if (report.chatbot.length > 0) {
lines.push('───────────────────────────────────────────');
lines.push(` 3. CHATBOT-ARTEFAKTE (report.chatbot.length gefunden, +report.chatbot.length * 5 Pkt)`);
lines.push('───────────────────────────────────────────');
for (const hit of report.chatbot) {
lines.push(` ▸ "hit.artifact"`);
}
lines.push('');
}
// Gedankenstriche (Muster #13)
const gs = report.gedankenstriche;
if (gs && gs.total > 0) {
lines.push('───────────────────────────────────────────');
const gsScore = gs.excess > 0 ? Math.min(gs.excess * 5, 25) : 0;
lines.push(` 4. GEDANKENSTRICHE (gs.total gefunden, gs.perPage/Seite, +gsScore Pkt)`);
lines.push('───────────────────────────────────────────');
if (gs.excess > 0) {
lines.push(` ✗ gs.total En-Dashes (–) in ~gs.pages Seite(n) → gs.excess über Limit (3/Seite)`);
lines.push(' KI streut Gedankenstriche wie Konfetti. Ersetze durch Punkt, Komma oder Umformulierung.');
} else {
lines.push(` ✓ gs.total En-Dashes (–) in ~gs.pages Seite(n) → im Rahmen`);
}
lines.push('');
}
// Statistik
lines.push('───────────────────────────────────────────');
lines.push(' 5. STATISTIK');
lines.push('───────────────────────────────────────────');
const b = report.statistik.burstiness;
if (b.value !== null) {
const status = b.value >= 0.3 ? '✓ menschlich' : '✗ KI-typisch';
lines.push(` Burstiness: b.value.toFixed(3) status`);
} else {
lines.push(` Burstiness: – (b.note)`);
}
const t = report.statistik.ttr;
if (t.value !== null) {
const status = t.value >= 0.5 ? '✓ menschlich' : '✗ KI-typisch';
lines.push(` TTR: t.value.toFixed(3) status`);
} else {
lines.push(` TTR: – (t.note)`);
}
const c = report.statistik.cov;
if (c.value !== null) {
const status = c.value >= 0.3 ? '✓ menschlich' : '✗ KI-typisch';
lines.push(` Satzlängen-CoV: c.value.toFixed(3) status`);
} else {
lines.push(` Satzlängen-CoV: – (c.note)`);
}
const tr = report.statistik.trigram;
const trStatus = tr.value <= 0.10 ? '✓ normal' : '✗ KI-typisch';
lines.push(` Trigramm-Rate: tr.value.toFixed(3) trStatus`);
const fl = report.statistik.flesch;
if (fl && fl.value !== null) {
const flStatus = (fl.value >= 40 && fl.value <= 50) ? '✗ KI-Sweetspot' : '✓ ok';
lines.push(` Flesch-DE: fl.value.toFixed(1) flStatus`);
} else if (fl) {
lines.push(` Flesch-DE: – (fl.note)`);
}
lines.push('');
// Co-Occurrence
if (report.coOccurrence && report.coOccurrence.length > 0) {
lines.push('───────────────────────────────────────────');
lines.push(` 5b. CO-OCCURRENCE-ALARM (report.coOccurrence.length Cluster, +report.coOccurrence.length * 5 Pkt)`);
lines.push('───────────────────────────────────────────');
for (const alarm of report.coOccurrence) {
lines.push(` ▸ Absatz alarm.paragraph, Set alarm.set: alarm.matches.join(', ') (alarm.count Treffer)`);
}
lines.push('');
}
// Personality
lines.push('───────────────────────────────────────────');
lines.push(` 5. PERSONALITY-BONUS (report.personality.bonus Pkt)`);
lines.push('───────────────────────────────────────────');
if (report.personality.details.length === 0) {
lines.push(' Keine menschlichen Stilmittel erkannt.');
} else {
for (const d of report.personality.details) {
lines.push(` ▸ d`);
}
}
lines.push('');
// Score-Aufschlüsselung
lines.push('───────────────────────────────────────────');
lines.push(' 6. SCORE-DETAILS');
lines.push('───────────────────────────────────────────');
for (const d of report.details) {
lines.push(` ▸ d`);
}
lines.push('');
lines.push('═══════════════════════════════════════════');
return lines.join('\n');
}
function formatSuggest(report) {
const lines = [];
lines.push('');
lines.push(' ERSETZUNGSVORSCHLÄGE');
lines.push(' ────────────────────');
if (report.tier1.length === 0 && report.phrasen.length === 0) {
lines.push(' Keine Ersetzungen nötig!');
return lines.join('\n');
}
// Tier 1
const seen = new Set();
for (const hit of report.tier1) {
const key = hit.word.toLowerCase();
if (!seen.has(key)) {
seen.add(key);
lines.push(` "hit.word" → "hit.replacement"`);
}
}
// Phrasen
for (const hit of report.phrasen) {
lines.push(` "hit.phrase" → [streichen oder umschreiben]`);
}
lines.push('');
return lines.join('\n');
}
// ============================================================
// FIX-FUNKTION
// ============================================================
/**
* Wendet das Suffix des Originals auf das Ersatzwort an.
* Behaelt Gross/Kleinschreibung des Originals bei.
*
* Beispiele:
* applyMorphFix("grundlegendes", "wichtig", "es", "adj") → "wichtiges"
* applyMorphFix("Grundlegenden", "wichtig", "en", "adj") → "Wichtigen"
* applyMorphFix("Meilensteins", "wichtiger Schritt", "s", "noun") → "Wichtigen Schritts"
* applyMorphFix("hochgradig", "sehr", "", "adv") → "sehr"
*/
function applyMorphFix(originalMatch, replacement, suffix, type) {
let result;
if (type === 'adj' && suffix) {
// Adjektiv mit Endung: Suffix an Ersatzwort haengen
result = replacement + suffix;
} else if (type === 'noun' && suffix) {
// Substantiv: Suffix ans letzte Wort der Ersetzung haengen
// z.B. "wichtiger Schritt" + "s" → "wichtiger Schritts"
// ABER: Wenn das Wort schon auf -s/-is/-us/-x/-z endet, kein -s/-es anhaengen
const words = replacement.split(' ');
const lastWord = words[words.length - 1];
if ((suffix === 's' || suffix === 'es') && /[sxzß]$/i.test(lastWord)) {
// "Basis" + "s" → "Basis" (nicht "Basiss")
// Suffix weglassen – Wort ist schon im richtigen Form
} else {
words[words.length - 1] += suffix;
}
result = words.join(' ');
} else {
result = replacement;
}
// Gross/Kleinschreibung vom Original uebernehmen
// Substantive behalten Grossschreibung (deutsch), Adjektive/Adverben nicht
if (type === 'noun') {
// Substantiv-Ersetzung: Erstes Wort gross (Nomen), Rest behalten
// "Meilenstein" → "Wichtiger Schritt" (nicht "wichtiger Schritt")
if (result[0] === result[0].toLowerCase()) {
result = result[0].toUpperCase() + result.slice(1);
}
} else {
// Adjektive/Adverben: Casing vom Original uebernehmen
if (originalMatch[0] === originalMatch[0].toUpperCase() && result[0] === result[0].toLowerCase()) {
result = result[0].toUpperCase() + result.slice(1);
} else if (originalMatch[0] === originalMatch[0].toLowerCase() && result[0] === result[0].toUpperCase()) {
result = result[0].toLowerCase() + result.slice(1);
}
}
return result;
}
/**
* Deutsche Artikel-Korrektur bei Genus-Wechsel.
*
* Problem: Einige Artikelformen sind mehrdeutig ("der" = Nom-m ODER Gen-f ODER Dat-f).
* Loesung: Eindeutige Formen werden immer korrigiert. Mehrdeutige Formen werden
* per Heuristik aufgeloest (Praeposition davor → Dativ, Satzanfang → Nominativ).
*
* Format: Array von [artikel_alt, artikel_neu, kasus_info]
* Reihenfolge: Laengere/spezifischere Formen zuerst (eines vor ein).
*/
const ARTIKEL_REGELN = {
'm->f': [
// Eindeutig:
['des', 'der'], // Gen-m → Gen-f
['dem', 'der'], // Dat-m → Dat-f
['den', 'die'], // Akk-m → Akk-f
['der', 'die'], // Nom-m → Nom-f (ACHTUNG: "der" ist auch Gen-f/Dat-f, aber als m→f ist es Nom)
['eines', 'einer'], // Gen
['einem', 'einer'], // Dat
['einen', 'eine'], // Akk
['ein', 'eine'], // Nom
],
'm->n': [
['der', 'das'], // Nom
['den', 'das'], // Akk-m → Akk-n
// des→des, dem→dem: gleich, kein Eintrag noetig
['einen', 'ein'], // Akk
['ein', 'ein'], // Nom (gleich, aber fuer Vollstaendigkeit)
],
'f->m': [
['die', 'der'], // Nom-f → Nom-m (Default; Akk wuerde "den" brauchen, aber Nom ist haeufiger)
['eine', 'ein'], // Nom-f → Nom-m
['einen', 'einen'], // Akk bleibt
// "der" (Gen-f oder Dat-f) → wird per Praepositions-Heuristik in fixArtikelBefore aufgeloest
['der', '__DAT_OR_GEN__'], // Platzhalter, wird unten behandelt
['einer', '__DAT_OR_GEN_U__'], // Platzhalter
],
'f->n': [
['die', 'das'], // Nom/Akk-f → Nom/Akk-n
['eine', 'ein'], // Nom/Akk
],
'n->m': [
['das', 'der'], // Nom-n → Nom-m
// des→des, dem→dem: gleich
['ein', 'ein'], // gleich
],
'n->f': [
['das', 'die'], // Nom/Akk-n → Nom/Akk-f
['ein', 'eine'], // Nom/Akk
],
};
/**
* Korrigiert den Artikel vor einem ersetzten Substantiv.
* Sucht 1-3 Woerter vor der Ersetzungsposition nach einem Artikel
* und passt ihn an das neue Genus an.
*
* @param {string} text - Der gesamte Text
* @param {number} pos - Position des ersetzten Substantivs
* @param {object} genus - {from: 'm', to: 'f'} etc.
* @returns {string} - Text mit korrigiertem Artikel
*/
function fixArtikelBefore(text, pos, genus) {
if (!genus || genus.from === genus.to) return text;
const key = `genus.from->genus.to`;
const regeln = ARTIKEL_REGELN[key];
if (!regeln) return text;
// Finde 1-3 Woerter vor pos (Artikel + evtl. Adjektiv/Praeposition dazwischen)
const before = text.substring(Math.max(0, pos - 40), pos);
// Suche letzten Artikel im Vorfeld (max 2 Woerter vor dem Substantiv)
const artikelRegex = /\b(eines|einer|einem|einen|eine|ein|der|die|das|des|dem|den)\b(?=\s+(?:\S+\s+)?$)/i;
const match = before.match(artikelRegex);
if (!match) return text;
const artikelLower = match[1].toLowerCase();
// Passende Regel finden
let newArtikel = null;
for (const [alt, neu] of regeln) {
if (artikelLower === alt) {
newArtikel = neu;
break;
}
}
if (!newArtikel) return text;
// Mehrdeutigkeit aufloesen: "der" kann Gen-f oder Dat-f sein
// Heuristik: Dativ-Praeposition davor → Dativ, sonst Genitiv
const DATIV_PRAEP = /\b(in|an|auf|bei|mit|nach|von|zu|aus|seit|unter|über|vor|hinter|neben|zwischen)\s*$/i;
if (newArtikel === '__DAT_OR_GEN__') {
const contextBefore = text.substring(Math.max(0, pos - 60), Math.max(0, pos - 40) + match.index);
newArtikel = DATIV_PRAEP.test(contextBefore)
? (genus.to === 'm' ? 'dem' : genus.to === 'f' ? 'der' : 'dem') // Dativ
: (genus.to === 'm' ? 'des' : genus.to === 'f' ? 'der' : 'des'); // Genitiv
} else if (newArtikel === '__DAT_OR_GEN_U__') {
const contextBefore = text.substring(Math.max(0, pos - 60), Math.max(0, pos - 40) + match.index);
newArtikel = DATIV_PRAEP.test(contextBefore)
? (genus.to === 'm' ? 'einem' : genus.to === 'f' ? 'einer' : 'einem')
: (genus.to === 'm' ? 'eines' : genus.to === 'f' ? 'einer' : 'eines');
}
// Gross/Klein beibehalten
if (match[1][0] === match[1][0].toUpperCase()) {
newArtikel = newArtikel[0].toUpperCase() + newArtikel.slice(1);
}
const artikelStart = Math.max(0, pos - 40) + match.index;
const artikelEnd = artikelStart + match[1].length;
return text.substring(0, artikelStart) + newArtikel + text.substring(artikelEnd);
}
function fixText(text) {
let fixed = text;
// Tier-1-Wörter ersetzen (morphologisch korrekt)
// Substantive mit Genus-Wechsel merken fuer Artikel-Korrektur
const artikelFixes = [];
for (const entry of TIER1) {
const [word, replacement, type] = entry;
const genus = entry[3] || null; // Genus-Mapping (nur bei Substantiven mit Wechsel)
const regex = buildTier1Regex(word, type);
if (type === 'noun' && genus) {
// Erst Positionen sammeln, dann rueckwaerts ersetzen (damit Positionen stimmen)
let match;
const matches = [];
while ((match = regex.exec(fixed)) !== null) {
matches.push({ index: match.index, match: match[0], suffix: match[1] || '' });
}
// Rueckwaerts ersetzen damit Positionen nicht verrutschen
for (let i = matches.length - 1; i >= 0; i--) {
const m = matches[i];
const newWord = applyMorphFix(m.match, replacement, m.suffix, type);
fixed = fixed.substring(0, m.index) + newWord + fixed.substring(m.index + m.match.length);
// Artikel-Korrektur direkt nach Substantiv-Ersetzung
fixed = fixArtikelBefore(fixed, m.index, genus);
}
} else {
fixed = fixed.replace(regex, (match, suffix) => {
return applyMorphFix(match, replacement, suffix || '', type);
});
}
}
// Verbotene Phrasen ersetzen (die einfachen Fälle)
const phrasenReplace = [
['es ist wichtig zu beachten, dass ', ''],
['es ist wichtig zu beachten dass ', ''],
['darüber hinaus ', 'Außerdem '],
['des weiteren ', 'Außerdem '],
['aufgrund der tatsache, dass ', 'Weil '],
['aufgrund der tatsache dass ', 'Weil '],
['in anbetracht der tatsache, dass ', 'Da '],
['in anbetracht der tatsache dass ', 'Da '],
['zusammenfassend lässt sich sagen, dass ', ''],
['zusammenfassend lässt sich sagen dass ', ''],
['es lässt sich festhalten, dass ', ''],
['es lässt sich festhalten dass ', ''],
['im folgenden wird erläutert', ''],
['es gilt zu beachten, dass ', ''],
['es gilt zu beachten dass ', ''],
['wie bereits erwähnt ', ''],
['nicht zuletzt ', 'Außerdem '],
['zu guter letzt ', 'Zum Schluss: '],
['last but not least ', 'Und: '],
];
for (const [phrase, replacement] of phrasenReplace) {
const regex = new RegExp(phrase.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'gi');
fixed = fixed.replace(regex, replacement);
}
return fixed;
}
// ============================================================
// CLI
// ============================================================
function printUsage() {
console.log(`
humanize-de.js – Deutscher KI-Text-Detektor
Verwendung:
node humanize-de.js score <datei> Score (0-100)
node humanize-de.js analyze <datei> Detaillierte Analyse
node humanize-de.js suggest <datei> Ersetzungsvorschläge
node humanize-de.js fix <datei> Auto-Fix (schreibt <datei>.fixed.md)
Score-Skala:
0-20 Klingt menschlich
21-40 Leicht maschinell
41-60 Gemischt
61-80 Offensichtlich KI
81-100 ChatGPT-Standard
`);
}
function main() {
const args = process.argv.slice(2);
if (args.length < 2) {
printUsage();
process.exit(1);
}
const command = args[0];
const filePath = args[1];
// Datei lesen
if (!fs.existsSync(filePath)) {
console.error(` Fehler: Datei nicht gefunden: filePath`);
process.exit(1);
}
const text = fs.readFileSync(filePath, 'utf-8');
if (text.trim().length === 0) {
console.error(' Fehler: Datei ist leer.');
process.exit(1);
}
// Markdown-Formatierung entfernen (nur Text analysieren)
const cleanText = text
.replace(/^#+\s.*/gm, '') // Überschriften entfernen
.replace(/^\s*[-*]\s/gm, '') // Bullet Points entfernen
.replace(/\*\*([^*]+)\*\*/g, '$1') // Fett entfernen
.replace(/\*([^*]+)\*/g, '$1') // Kursiv entfernen
.replace(/`[^`]+`/g, '') // Inline-Code entfernen
.replace(/```[\s\S]*?```/g, '') // Code-Blöcke entfernen
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') // Links entfernen
.replace(/^\s*>\s/gm, '') // Blockquotes entfernen
.replace(/^\s*\|.*\|.*$/gm, '') // Tabellen entfernen
.replace(/---+/g, '') // Horizontale Linien entfernen
.replace(/\n{3,}/g, '\n\n') // Mehrfache Leerzeilen reduzieren
.trim();
const report = calculateScore(cleanText);
switch (command) {
case 'score':
console.log(formatScore(report));
break;
case 'analyze':
console.log(formatAnalyze(report, cleanText));
break;
case 'suggest':
console.log(formatSuggest(report));
break;
case 'fix': {
const fixed = fixText(text);
const ext = path.extname(filePath);
const base = path.basename(filePath, ext);
const dir = path.dirname(filePath);
// Backup der Originaldatei erstellen
const bakPath = path.join(dir, `baseext.bak`);
if (!fs.existsSync(bakPath)) {
fs.writeFileSync(bakPath, text, 'utf-8');
console.log(` Backup erstellt: bakPath`);
}
const outPath = path.join(dir, `base.fixedext`);
fs.writeFileSync(outPath, fixed, 'utf-8');
// Score vorher/nachher
const reportBefore = calculateScore(cleanText);
const fixedClean = fixed
.replace(/^#+\s.*/gm, '')
.replace(/\*\*([^*]+)\*\*/g, '$1')
.replace(/`[^`]+`/g, '')
.replace(/```[\s\S]*?```/g, '')
.trim();
const reportAfter = calculateScore(fixedClean);
console.log(`
Fix angewendet!
────────────────
Vorher: reportBefore.score / 100
Nachher: reportAfter.score / 100
Differenz: reportBefore.score - reportAfter.score Punkte verbessert
Gespeichert: outPath
`);
break;
}
default:
console.error(` Unbekannter Befehl: command`);
printUsage();
process.exit(1);
}
}
main();