STROMDAO Logo

Willi-Mako-Client: Technische Dokumentation und Implementierungsleitfaden

Vollständige technische Dokumentation für den Willi-Mako-Client. Open-Source-Node.js-Client für KI-gestützte Marktkommunikation in der Energiewirtschaft. Installation, API-Referenz und Best Practices.

Zuletzt aktualisiert: 16.11.2025 Lesezeit: 10 Minuten
#Willi-Mako #Node.js #API #Open Source #Technische Dokumentation #Installation

Willi-Mako-Client: Technische Dokumentation

Der Willi-Mako-Client ist ein Open-Source-Node.js-Client, der den Zugriff auf die umfassende Wissensbasis der Willi-Mako-Plattform ermöglicht. Entwickelt und gepflegt von der STROMDAO GmbH und der Community, bietet er eine moderne API für KI-gestützte Marktkommunikation in der Energiewirtschaft.

Überblick

Was ist der Willi-Mako-Client?

Der Willi-Mako-Client ist eine npm-Package, das Entwicklern und Energieversorgern ermöglicht:

  • Zugriff auf kurierte Wissensdatenbanken (willi-mako und willi-netz)
  • KI-gestützte Beantwortung komplexer energiewirtschaftlicher Fragen
  • Automatisierung von regulatorischen Analysen und Compliance-Checks
  • Integration in bestehende IT-Systeme und Workflows

Architektur-Überblick

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
┌─────────────────────────────────────────────────┐
│         Ihre Anwendung / IT-System              │
└────────────────┬────────────────────────────────┘
                 │ npm install willi-mako-client
┌────────────────▼────────────────────────────────┐
│         Willi-Mako-Client (Node.js)             │
│  • Session Management                           │
│  • API Wrapper                                  │
│  • Error Handling                               │
└────────────────┬────────────────────────────────┘
                 │ RESTful API (HTTPS)
┌────────────────▼────────────────────────────────┐
│      Willi-Mako Cloud Platform                  │
│  • RAG-Pipeline (Retrieval-Augmented Gen.)      │
│  • Hybride Semantische Suche                    │
│  • LLM-Reranking                                │
│  • Reasoning-Pipeline                           │
└────────────────┬────────────────────────────────┘
┌────────────────▼────────────────────────────────┐
│           Wissensbasen                          │
│  • willi-mako (MaKo: GPKE, WiM, EDIFACT)       │
│  • willi-netz (Regulierung: EnWG, BNetzA)      │
│  • 1.000+ kuratierte Dokumente                 │
└─────────────────────────────────────────────────┘

Technologie-Stack

  • Client: Node.js 14+ / JavaScript / TypeScript-ready
  • Protokoll: RESTful API über HTTPS
  • Datenformat: JSON
  • Authentifizierung: JWT-basiert
  • Backend: Cloud-native (keine lokale Infrastruktur nötig)

Installation

Systemvoraussetzungen

Minimal:

  • Node.js 14.x oder höher
  • npm 6.x oder höher
  • Internet-Verbindung

Empfohlen:

  • Node.js 18.x LTS
  • npm 9.x
  • Docker (optional, für Containerisierung)

npm-Installation

1
2
3
4
5
6
7
8
# Standard-Installation
npm install willi-mako-client

# Oder mit Yarn
yarn add willi-mako-client

# Oder mit pnpm
pnpm add willi-mako-client

Erste Schritte

1. Account erstellen:

2. API-Zugang einrichten:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
const WilliMako = require('willi-mako-client');

// Client initialisieren
const client = new WilliMako({
  // Optional: Custom-Konfiguration
  apiUrl: 'https://api.willi-mako.de', // Standard-URL
  timeout: 30000, // 30 Sekunden Timeout
});

// Login mit E-Mail und Passwort
async function initialize() {
  try {
    await client.login('[email protected]', 'ihr-passwort');
    console.log('✓ Erfolgreich eingeloggt');
  } catch (error) {
    console.error('Login fehlgeschlagen:', error.message);
  }
}

initialize();

API-Referenz

Session-Management

client.login(email, password)

Authentifiziert den Client und erstellt ein Access-Token.

Parameter:

  • email (String): Registrierte E-Mail-Adresse
  • password (String): Passwort

Rückgabe: Promise

Beispiel:

1
2
const loginResult = await client.login('[email protected]', 'password123');
console.log('Session ID:', loginResult.sessionId);

client.createSession(options)

Erstellt eine neue Arbeitssession für zusammenhängende Anfragen.

Parameter:

  • options (Object, optional):
    • ttlMinutes (Number): Session-Lebensdauer in Minuten (Standard: 60)
    • preferences (Object): Session-spezifische Präferenzen
    • contextSettings (Object): Kontext-Konfiguration

Rückgabe: Promise

Beispiel:

1
2
3
4
5
6
7
8
9
const session = await client.createSession({
  ttlMinutes: 120,
  preferences: {
    companiesOfInterest: ['Stadtwerke München', 'EnBW'],
    preferredTopics: ['GPKE', 'WiM']
  }
});

console.log('Session erstellt:', session.id);

client.getSession(sessionId)

Ruft Metadaten einer bestehenden Session ab.

Parameter:

  • sessionId (String): UUID der Session

Rückgabe: Promise

client.deleteSession(sessionId)

Löscht eine Session und alle zugehörigen Artefakte.

Parameter:

  • sessionId (String): UUID der Session

Rückgabe: Promise

Chat und Reasoning

client.chat(sessionId, message, options)

Stellt eine Frage im Chat-Modus (schnelle Antworten für einfache Fragen).

Parameter:

  • sessionId (String): ID der aktiven Session
  • message (String): Ihre Frage oder Anfrage
  • options (Object, optional):
    • contextSettings (Object): Kontext-Override
    • timelineId (String): Timeline-Verknüpfung

Rückgabe: Promise

Beispiel:

1
2
3
4
5
6
7
const response = await client.chat(
  session.id,
  'Welche Fristen gelten für UTILMD-Antworten nach GPKE?'
);

console.log('Antwort:', response.assistantMessage.content);
console.log('Quellen:', response.assistantMessage.metadata.contextSources);

client.reasoning(sessionId, query, options)

Führt mehrstufige Analyse durch (für komplexe strategische Fragen).

Parameter:

  • sessionId (String): ID der aktiven Session
  • query (String): Komplexe strategische Frage
  • options (Object, optional):
    • useDetailedIntentAnalysis (Boolean): Detaillierte Intent-Analyse
    • overridePipeline (Object): Custom Pipeline-Konfiguration
    • messages (Array): Konversations-Historie

Rückgabe: Promise

Beispiel:

1
2
3
4
5
6
7
8
const reasoning = await client.reasoning(
  session.id,
  'Welche Investitionsimplikationen hat §14a EnWG für mittelgroße Netzbetreiber mit 50.000 Kunden?',
  { useDetailedIntentAnalysis: true }
);

console.log('Synthese:', reasoning.synthesis);
console.log('Reasoning-Schritte:', reasoning.reasoningSteps);

Suche

client.semanticSearch(sessionId, query, options)

Führt hybride semantische Suche durch.

Parameter:

  • sessionId (String): ID der aktiven Session
  • query (String): Suchanfrage
  • options (Object, optional):
    • limit (Number): Max. Ergebnisse (1-100, Standard: 10)
    • alpha (Number): Hybrid-Gewichtung (0-1, Standard: 0.5)
    • outlineScoping (Boolean): Outline-basierte Filterung
    • excludeVisual (Boolean): Visuelle Inhalte ausschließen

Rückgabe: Promise

Beispiel:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const results = await client.semanticSearch(
  session.id,
  'MSCONS Nachrichtenformat Spezifikation',
  { limit: 5, alpha: 0.7 }
);

results.forEach(result => {
  console.log(`- ${result.title} (Score: ${result.score})`);
  console.log(`  Quelle: ${result.source}`);
});

Artefakt-Management

client.createArtifact(sessionId, artifact)

Speichert ein Ergebnis-Artefakt (Report, EDI-Nachricht, etc.).

Parameter:

  • sessionId (String): ID der aktiven Session
  • artifact (Object):
    • type (String): Artefakt-Typ (z.B. ‘compliance-report’, ’edifact-message’)
    • name (String): Menschen-lesbarer Name
    • mimeType (String): MIME-Type
    • content (String): Inhalt (UTF-8 oder Base64)
    • encoding (String): ‘utf8’ oder ‘base64’ (Standard: ‘utf8’)
    • description (String, optional): Beschreibung
    • metadata (Object, optional): Custom-Metadaten
    • tags (Array, optional): Tags für Suche

Rückgabe: Promise

Beispiel:

1
2
3
4
5
6
7
8
const artifact = await client.createArtifact(session.id, {
  type: 'compliance-report',
  name: 'GPKE Compliance Check Q4 2025',
  mimeType: 'application/pdf',
  content: pdfBase64,
  encoding: 'base64',
  tags: ['compliance', 'GPKE', 'Q4-2025']
});

Sandbox-Ausführung

client.executeScript(sessionId, script, options)

Führt JavaScript im sicheren Sandbox aus (für ETL, Validierung, etc.).

Parameter:

  • sessionId (String): ID der aktiven Session
  • script (String): JavaScript-Code
  • options (Object, optional):
    • timeoutMs (Number): Timeout in ms (100-60000)
    • metadata (Object): Audit-Metadaten
    • tags (Array): Tags

Rückgabe: Promise

Beispiel:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const job = await client.executeScript(
  session.id,
  `
    const data = require('./data.json');
    const validRecords = data.filter(r => r.status === 'VALID');
    return { count: validRecords.length, records: validRecords };
  `,
  { timeoutMs: 5000 }
);

console.log('Job ID:', job.id);

client.getJob(jobId, options)

Ruft Status und Ergebnisse eines Sandbox-Jobs ab.

Parameter:

  • jobId (String): Job-ID
  • options (Object, optional):
    • includeLogs (Boolean): stdout/stderr einschließen (Standard: true)

Rückgabe: Promise

Beispiel:

1
2
3
4
5
6
7
const jobStatus = await client.getJob(job.id);

if (jobStatus.status === 'completed') {
  console.log('Ergebnis:', jobStatus.result);
} else if (jobStatus.status === 'failed') {
  console.error('Fehler:', jobStatus.stderr);
}

Anwendungsbeispiele

Beispiel 1: Regulatorische Impact-Analyse

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
const WilliMako = require('willi-mako-client');

async function analyzeRegulation() {
  const client = new WilliMako();
  await client.login(process.env.WILLI_EMAIL, process.env.WILLI_PASSWORD);
  
  const session = await client.createSession({
    preferences: {
      preferredTopics: ['EnWG', 'Regulierung']
    }
  });
  
  const analysis = await client.reasoning(
    session.id,
    `Analysiere die Auswirkungen von §14a EnWG auf Verteilnetzbetreiber:
     - Investitionsbedarf
     - Compliance-Anforderungen
     - Umsetzungsfristen
     - Risiken und Chancen`
  );
  
  // Artefakt speichern
  await client.createArtifact(session.id, {
    type: 'compliance-report',
    name: '§14a EnWG Impact-Analyse',
    mimeType: 'application/json',
    content: JSON.stringify(analysis, null, 2),
    tags: ['14a', 'EnWG', 'VNB']
  });
  
  console.log('Analyse abgeschlossen:', analysis.synthesis);
}

analyzeRegulation();

Beispiel 2: Automatisierte EDIFACT-Validierung

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
async function validateEDIFACT(ediMessage) {
  const client = new WilliMako();
  await client.login(process.env.WILLI_EMAIL, process.env.WILLI_PASSWORD);
  
  const session = await client.createSession();
  
  const validationScript = `
    const message = ${JSON.stringify(ediMessage)};
    
    // Validierungs-Logik
    const errors = [];
    
    if (!message.UNB) errors.push('Fehlender UNB-Header');
    if (!message.UNH) errors.push('Fehlende UNH-Segment');
    
    // Spezifische UTILMD-Validierung
    if (message.type === 'UTILMD') {
      if (!message.IDE) errors.push('IDE-Segment erforderlich für UTILMD');
    }
    
    return {
      valid: errors.length === 0,
      errors: errors,
      message: message
    };
  `;
  
  const job = await client.executeScript(session.id, validationScript);
  const result = await client.getJob(job.id);
  
  console.log('Validierung:', result.result);
  return result.result;
}

Beispiel 3: Continuous Compliance Monitoring

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const cron = require('node-cron');

// Täglich um 8:00 Uhr
cron.schedule('0 8 * * *', async () => {
  const client = new WilliMako();
  await client.login(process.env.WILLI_EMAIL, process.env.WILLI_PASSWORD);
  
  const session = await client.createSession();
  
  // Prüfe aktuelle regulatorische Updates
  const updates = await client.chat(
    session.id,
    'Welche neuen MaKo-Änderungen wurden in den letzten 24 Stunden veröffentlicht?'
  );
  
  if (updates.assistantMessage.metadata.contextSources > 0) {
    // Benachrichtigung senden
    await sendNotification({
      subject: 'Neue MaKo-Updates verfügbar',
      body: updates.assistantMessage.content
    });
  }
});

Best Practices

Performance-Optimierung

1. Session-Wiederverwendung:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// ✓ Gut: Session wiederverwenden
const session = await client.createSession({ ttlMinutes: 120 });
for (const question of questions) {
  await client.chat(session.id, question);
}

// ✗ Schlecht: Neue Session pro Anfrage
for (const question of questions) {
  const session = await client.createSession();
  await client.chat(session.id, question);
}

2. Batch-Verarbeitung:

1
2
3
// Parallel-Verarbeitung für unabhängige Anfragen
const promises = questions.map(q => client.chat(session.id, q));
const results = await Promise.all(promises);

3. Caching implementieren:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const cache = new Map();

async function getCachedAnswer(question) {
  if (cache.has(question)) {
    return cache.get(question);
  }
  
  const answer = await client.chat(session.id, question);
  cache.set(question, answer);
  return answer;
}

Error Handling

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const { WilliMakoError, NetworkError, AuthenticationError } = require('willi-mako-client');

async function robustQuery(question) {
  let retries = 3;
  
  while (retries > 0) {
    try {
      const result = await client.chat(session.id, question);
      return result;
      
    } catch (error) {
      if (error instanceof AuthenticationError) {
        // Re-authenticate
        await client.login(email, password);
        retries--;
        
      } else if (error instanceof NetworkError) {
        // Warte und versuche erneut
        await sleep(2000);
        retries--;
        
      } else {
        // Unbekannter Fehler
        throw error;
      }
    }
  }
  
  throw new Error('Max retries exceeded');
}

Sicherheit

1. Credentials niemals im Code:

1
2
3
4
5
6
7
8
9
// ✓ Gut: Umgebungsvariablen
const client = new WilliMako();
await client.login(
  process.env.WILLI_EMAIL,
  process.env.WILLI_PASSWORD
);

// ✗ Schlecht: Hardcoded credentials
await client.login('[email protected]', 'password123');

2. Token-Rotation:

1
2
3
4
// Token nach 1 Stunde erneuern
setInterval(async () => {
  await client.refreshToken();
}, 3600000);

3. Input-Validierung:

1
2
3
4
5
6
7
8
9
function sanitizeInput(userInput) {
  // Entferne potentiell gefährliche Zeichen
  return userInput
    .replace(/[<>]/g, '')
    .substring(0, 10000); // Max. Länge
}

const safeQuery = sanitizeInput(userInput);
await client.chat(session.id, safeQuery);

Integration Patterns

Express.js API

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const express = require('express');
const WilliMako = require('willi-mako-client');

const app = express();
app.use(express.json());

const client = new WilliMako();

app.post('/api/analyze', async (req, res) => {
  try {
    const { question } = req.body;
    
    const session = await client.createSession();
    const result = await client.reasoning(session.id, question);
    
    res.json({
      success: true,
      analysis: result.synthesis,
      sources: result.metadata.contextSources
    });
    
  } catch (error) {
    res.status(500).json({
      success: false,
      error: error.message
    });
  }
});

app.listen(3000);

Docker-Container

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .

ENV WILLI_EMAIL=""
ENV WILLI_PASSWORD=""

CMD ["node", "index.js"]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# docker-compose.yml
version: '3.8'

services:
  willi-mako-service:
    build: .
    environment:
      - WILLI_EMAIL=${WILLI_EMAIL}
      - WILLI_PASSWORD=${WILLI_PASSWORD}
      - NODE_ENV=production
    restart: unless-stopped
    ports:
      - "3000:3000"

AWS Lambda

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// lambda-handler.js
const WilliMako = require('willi-mako-client');

let client;
let session;

exports.handler = async (event) => {
  // Lazy initialization
  if (!client) {
    client = new WilliMako();
    await client.login(
      process.env.WILLI_EMAIL,
      process.env.WILLI_PASSWORD
    );
    session = await client.createSession();
  }
  
  const { question } = JSON.parse(event.body);
  const result = await client.chat(session.id, question);
  
  return {
    statusCode: 200,
    body: JSON.stringify(result)
  };
};

Troubleshooting

Häufige Probleme

Problem: “Authentication failed”

1
2
3
4
Lösung:
1. Überprüfen Sie E-Mail und Passwort
2. Stellen Sie sicher, dass Account aktiv ist
3. Prüfen Sie Firewall/Proxy-Einstellungen

Problem: “Session expired”

1
2
3
4
5
6
7
8
9
// Automatische Session-Erneuerung
async function ensureValidSession() {
  try {
    await client.getSession(session.id);
  } catch (error) {
    session = await client.createSession();
  }
  return session;
}

Problem: “Rate limit exceeded”

1
2
3
4
Lösung:
1. Implementieren Sie exponential backoff
2. Verwenden Sie Batch-Verarbeitung
3. Erwägen Sie Premium-Lizenz für höhere Limits

Debug-Modus

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
const client = new WilliMako({
  debug: true, // Aktiviert detailliertes Logging
  logLevel: 'verbose'
});

// Oder mit Winston-Logger
const winston = require('winston');
const logger = winston.createLogger({ /* config */ });

const client = new WilliMako({
  logger: logger
});

Weiterführende Ressourcen

Support

Community-Support (kostenlos):

  • GitHub Discussions
  • Stack Overflow (Tag: willi-mako)

Premium-Support (kostenpflichtig):

  • Dedicated Support-Kanal
  • SLA-garantierte Antwortzeiten
  • Direkter Kontakt zu STROMDAO-Entwicklern
  • Custom-Feature-Entwicklung

Kontakt: [email protected]


Letzte Aktualisierung: November 2025 | STROMDAO GmbH

Fragen zu unseren Geschäftsbedingungen?

Unser Team steht Ihnen gerne zur Verfügung.

Kontakt aufnehmen