Entwicklung & Code
Model Context Protocol: Anwendungsbeispiel in TypeScript
Das KI-Unternehmen Anthropic, das 2021 von ehemaligen OpenAI-Mitarbeitern gegründet wurde, hat das Model Context Protocol (MCP) mit dem Ziel einer Standardisierung der Kommunikation zwischen Large Language Models und externen Datenquellen entwickelt. Beim sogenannten Tool Calling hat das LLM die Möglichkeit, auf vordefinierte Schnittstellen zuzugreifen. Diese lassen sich parametrisieren und erlauben so große Flexibilität. Die meisten LLM-Anbieter unterstützen dieses Feature. Jede Datenquelle braucht dabei eine Verknüpfung über eine eigene Funktion, was in der Regel eine Anpassung am Programmcode erforderlich macht.
Sebastian Springer weckt als Dozent für JavaScript, Sprecher auf zahlreichen Konferenzen und Autor die Begeisterung für professionelle Entwicklung mit JavaScript.
Das Model Context Protocol soll die Verknüpfung externer Datenquellen deutlich vereinfachen und es erlauben, externe Schnittstellen, Datenbanken, Unternehmenssysteme oder Dateisysteme ohne zusätzliche Anpassung direkt anzubinden. Dieser Artikel widmet sich den technischen Details der Funktionsweise des MCP und zeigt anhand eines konkreten Beispiels mit dem MCP-TypeScript-SDK, wie eine Integration in eine Applikation gelingen kann.
Die zentrale Anlaufstelle für Ressourcen zum Thema MCP sind zum einen die offizielle Website des Projekts und zum anderen das GitHub-Repo. Dort stehen die Dokumentation, die Spezifikation und eine ganze Reihe von Software Development Kits (SDKs) für verschiedene Programmiersprachen wie Python, TypeScript, C# oder Kotlin zur Verfügung.
Die Architektur einer MCP-Applikation
Eine Applikation, die das MCP nutzt, besteht aus verschiedenen Komponenten:
- MCP-Server: Der Server ist die Stelle bei MCP, die ihre Funktionalität über das MCP zur Verfügung stellt. Das können Daten aus einer Datenbank, aber auch Suchergebnisse aus dem Internet sein. Die Schnittstellen des Servers sind exakt definiert und lassen sich von der Clientseite verwenden.
- MCP-Client: Die Gegenseite zum Server ist der Client. Er kommuniziert mit dem Server und führt die verfügbaren Operationen über die Schnittstellen aus. Dabei gibt es sowohl lesende als auch schreibende Operationen.
- MCP-Host: Die Applikation, mit der die Benutzer interagieren. Das kann eine Web-Applikation, eine klassische Desktop-Applikation (wie Claude Desktop), eine Entwicklungsumgebung (wie Cursor) oder ein eigener, auf Frameworks wie Langchain basierender Agent sein. In diese Applikation ist der Client eingebettet, sodass der Host nicht direkt über MCP mit dem Server, sondern über den Umweg des Clients kommuniziert.
MCP-Server
Ein MCP-Server kann direkt in eine Applikation integriert, aber auch, und das wird der häufigere Fall sein, ein eigenständiger Dienst sein. Die MCP-Initiative stellt eine Reihe von SDKs in unterschiedlichen Programmiersprachen bereit, die die Grundlage für die Serverimplementierung bilden. Der Server selbst ist modular aufgebaut und erlaubt verschiedene Transportmechanismen, über die er mit den Clients kommuniziert. Das TypeScript-SDK sieht aktuell die Transportmechanismen Streamable HTTP, SSE und stdio vor. Streamable HTTP und SSE basieren auf HTTP, wobei die MCP-Spezifikation vom 26.03.2025 den SSE-Transport als veraltet (deprecated) markierte und die Version vom 18.06.2025 (latest) SSE bereits nicht mehr erwähnt.
Ein MCP-Client kann die HTTP-basierten Transportmechanismen verwenden, um sich mit einem entfernten Server zu verbinden. Der stdio-Transport ist für lokale Anwendungen gedacht. Hierbei verbindet sich der Client über die Standard-Ein- und -Ausgabe mit dem Server. Dieser Weg arbeitet deutlich schneller, ist jedoch nur für die Verwendung auf einem System geeignet. Das Python-SDK definiert zusätzlich zu diesen Transporttypen noch weitere wie den ASGI-Transport (Asynchronous Server Gateway Interface), eine Schnittstelle aus der Python-Welt, die neben der Kommunikation über HTTP noch weitere Protokolle wie WebSockets oder benutzerdefinierte Protokolle unterstützt.
Die MCP-Spezifikation unterteilt die Features, die ein Server seinen Clients bietet, in drei Kategorien: Resources, Tools und Prompts.
Resources
Mit der Feature-Kategorie Resources stellt ein MCP-Server Daten zur Verfügung. Ein typisches Beispiel ist die Anbindung an eine Datenbank. Resources sollten Daten nur lesend zur Verfügung stellen, keine komplexen Berechnungen durchführen und keine Seiteneffekte wie Datenmanipulationen aufweisen. Sie sind parametrisierbar, um die Abfrage zu beeinflussen und eine höhere Flexibilität zu erreichen.
Die MCP-Spezifikation sieht vor, dass das Format [protocol]://[host]/[path]
Resources spezifiziert. Ein Beispiel könnte folgendermaßen aussehen: postgres://database/users
. Die Antwort auf eine Resources-Anfrage kann entweder im Textformat wie beispielsweise JSON oder als Binärdaten wie PDFs oder Bilder erfolgen.
Der MCP-Server stellt über den Endpunkt resources/list
eine Liste der verfügbaren Resources zur Verfügung. Jeder Datensatz weist mindestens die URL der jeweiligen Resource und einen menschenlesbaren Namen auf. Hinzu kommen noch eine optionale Beschreibung und ein ebenfalls optionaler MIME-Type, der das Format der Rückmeldung spezifiziert.
Die Spezifikation sieht nicht nur den lesenden Zugriff auf Ressourcen vor, sondern auch einen Benachrichtigungsmechanismus, über den der Server registrierte Clients über Änderungen der verfügbaren sowie Datenänderungen einer einzelnen Resource benachrichtigen kann.
Tools
Die Features der Kategorie Tools dürfen Berechnungen durchführen und Seiteneffekte aufweisen. Clients müssen berücksichtigen, dass eine Toolausführung im Vergleich zu einer Ressourcenabfrage länger dauern kann. Diese Werkzeuge können Funktionen sein, die aufgrund einer Eingabe eine bestimmte Ausgabe produzieren, aber auch Schnittstellen zu Datenbanken und anderen Systemen, um dort gespeicherte Informationen zu manipulieren. Ähnlich wie Resources können Clients auch die verfügbaren Tools eines Servers über einen Endpunkt auslesen. Dieser lautet tools/list
.
Die Beschreibung eines MCP-Tools ist etwas umfangreicher als die einer Resource. Sie enthält einen Namen und ein Input-Schema, um die Parameter des Tools zu beschreiben. Hinzu kommen noch dessen optionale Beschreibung und optionale Metadaten über die Tool-Annotations. Die Annotations liefern Clients beziehungsweise Hinweise für Entwicklerinnen und Entwicklern über das Verhalten eines Tools. Die meisten vordefinierten Annotations der MCP-Spezifikation sind Boolean-Werte. So sagt beispielsweise die readOnlyHint
-Annotation aus, dass das Tool sein Umfeld nicht modifiziert. Wie auch bei den Resources kann ein Client sich beim Server registrieren, um über Änderungen benachrichtigt zu werden.
Prompts
Prompts sind Vorlagen, die dem MCP-Host die Arbeit mit dem Large Language Model (LLM) erleichtern. Damit kann eine MCP-Applikation nicht nur die Kommunikation zwischen Client und Server, sondern auch zum LLM hin standardisieren. Bei einer Applikation, die ein Code-Review-Feature anbietet, dient der Prompt beispielsweise dazu, den zu überprüfenden Code korrekt einzubetten. Laut der MCP-Spezifikation besitzen die Prompt-Templates einen eindeutigen Namen. Zusätzlich sieht die Spezifikation noch die optionalen Felder description
für eine menschenlesbare Beschreibung und arguments
mit einer Liste der unterstützten Argumente des Schemas vor.
Die Prompt-Endpunkte eines MCP-Servers kommen ähnlich wie Tools zum Einsatz. Der Client fragt nach dem eindeutigen Identifier und übermittelt die benötigten Werte. Der Server antwortet mit dem Prompt, in den die Werte integriert sind, sodass der Client beziehungsweise die Host-Applikation den Prompt direkt verwenden kann.Für eine Liste aller verfügbaren Prompts bietet der MCP-Server den Endpunkt prompts/list
an.
Die SDKs, die die MCP-Initiative zur Verfügung stellt, implementieren die Spezifikation und dienen als Grundlage für die Implementierung von MCP-Servern und MCP-Clients. Das folgende Beispiel implementiert einen einfachen MCP-Server mit je einer Resource, einem Tool und einem Prompt mit dem TypeScript-SDK.
import {
McpServer,
ResourceTemplate,
} from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
const server = new McpServer({
name: 'mcp-server',
version: '1.0.0',
});
server.tool(
'currency-converter',
'Convert currency between EUR and USD',
{
amount: z.number(),
from: z.enum(['EUR', 'USD']),
to: z.enum(['EUR', 'USD']),
},
async ({ amount, from, to }) => {
const exchangeRate =
from === 'EUR' && to === 'USD'
? 1.1
: from === 'USD' && to === 'EUR'
? 0.91
: 1;
const convertedAmount = amount * exchangeRate;
return {
content: [
{
type: 'text',
text: `${amount} ${from} is ${convertedAmount.toFixed(2)} ${to}`,
},
],
};
}
);
server.resource(
'price-list',
new ResourceTemplate('price-list://products/{category}', {
list: undefined,
}),
async (uri, { category }) => {
const priceList = [
{ name: 'Apple', category: 'Fruit', price: 1.2 },
{ name: 'Banana', category: 'Fruit', price: 0.8 },
{ name: 'Carrot', category: 'Vegetable', price: 0.5 },
{ name: 'Bread', category: 'Bakery', price: 2.5 },
{ name: 'Milk', category: 'Dairy', price: 1.5 },
];
const filteredList =
category !== 'all'
? priceList.filter(
(item) => item.category.toLowerCase() === category.toLowerCase()
)
: priceList;
return {
contents: [
{
uri: uri.href,
text: JSON.stringify(filteredList),
json: filteredList,
},
],
};
}
);
server.prompt(
'get-product-description-prompt',
{
productName: z.string().describe('The name of the product.'),
length: z
.enum(['short', 'medium', 'long'])
.optional()
.describe('The desired length of the description.'),
},
async (input) => {
const { productName, length } = input;
let promptInstructions = `Please generate a compelling product description.`;
let promptCore = `The product is named "${productName}". `;
promptCore += `Focus on its general benefits and appeal. `;
let refinements = '';
if (length) {
let lengthGuidance = '';
if (length === 'short')
lengthGuidance = 'Keep it concise, around 1-2 sentences. ';
if (length === 'medium')
lengthGuidance = 'Aim for a paragraph of about 3-5 sentences. ';
if (length === 'long')
lengthGuidance =
'Provide a detailed description, potentially multiple paragraphs. ';
refinements += lengthGuidance;
}
const fullPrompt = `${promptInstructions}\n\nProduct Details:\n${promptCore}\n\nStyle and Constraints:\n${refinements.trim()}`;
return {
messages: [
{
role: 'user',
content: {
type: 'text',
text: fullPrompt,
},
},
],
};
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
Listing 1: MCP-Serverimplementierung
Die Grundlage für das Beispiel bildet das TypeScript-SDK, das mit dem Kommando npm install @modelcontextprotocol/sdk
installiert wird. Das Paket stellt mit der McpServer
-Klasse die Grundlage für die Serverimplementierung zur Verfügung. Auf der Server-Instanz sind die Methoden tool
, resource
und prompt
implementiert, die die Schnittstelle zur Registrierung der verschiedenen MCP-Features darstellen. Nachdem die Applikation alle Features registriert hat, ruft sie die connect
-Methode der Serverinstanz auf und übergibt ein Transport-Objekt. Das kann wie im Beispiel eine Instanz der StdioServerTransport
-Klasse für den Stdio-Transport sein oder auch eine Instanz der StreamableHTTPServerTransport
-Klasse für eine Remote-Schnittstelle über Streamable-HTTP. Alternativ dazu unterstützt das TypeScript-SDK auch noch die SSEServerTransport
-Klasse für Server Sent Events als Transportmethode.
Für die Implementierung der einzelnen Features des MCP-Servers gelten einige Regeln, die das SDK mit einer sehr strikten Schemavalidierung absichert. Folgt die Implementierung nicht diesen Regeln, lässt sich der Serverprozess nicht starten. Die Validierung stellt auch die Konsistenz der Argumente beim Aufruf sicher und spielt damit eine wichtige Rolle bei der Sicherheit in der Applikation.
Resource im Beispiel
Zur Definition von Resources sieht das SDK die resource
-Methode des Serverobjekts vor. Diese Methode akzeptiert die Bezeichnung der Resource, die zugehörige URL und eine Callback-Funktion, die das Ergebnis produziert. Die Callback-Funktion darf asynchron sein, sodass auch der Anbindung einer Datenbank nichts im Wege steht. Eine Besonderheit gibt es bei der Registrierung von Resources allerdings: Ist die URL als Zeichenkette angegeben, darf sie keine dynamischen Parameter enthalten. Für diesen Fall akzeptiert die resource
-Methode eine ResourceTemplate
-Instanz. Hier werden die Parameter im Pfad mit geschweiften Klammern gekennzeichnet. Die Callback-Funktion kann über ihr zweites Argument auf die Parameter der URL zugreifen und das Ergebnis entsprechend modifizieren.
Im Beispiel ist die Resource eine statische Preisliste für eine Reihe von Produkten. Sie trägt die Bezeichnung price-list
und ist über die URL price-list://products/{category}
erreichbar, wobei category
für eine Kategorie steht, nach der die Callback-Funktion die Datensätze filtert. Das TypeScript-SDK arbeitet mit Zod als Validierungsbibliothek und nutzt diese beispielsweise für die Überprüfung des Rückgabewerts der Resource-Callback-Funktion, sodass diese verpflichtend eine gewisse Struktur zurückgeben muss. Das contents
-Array im Rückgabewert kann eine Reihe von Objekten aufweisen, die mindestens über die Eigenschaften uri
und text
verfügen müssen. Zusätzlich akzeptiert das SDK noch weitere Eigenschaften wie json
, in der die Daten als JSON-Objekt vorliegen dürfen.
Entwicklung & Code
PyPI geht gegen Domain-Hijacking vor und prüft Mail-Adressen
Die Betreiber des Python Package Index (PyPI) gehen gegen Domain-Hijacking vor, um Lieferkettenangriffe zu erschweren. Dabei prüft das beliebte Python-Paketverzeichnis die Domains von Mail-Adressen der User-Accounts regelmäßig darauf, ob die Domänen noch einen Besitzer haben. Wenn nicht, wird dem Account die Verifizierung entzogen, was bereits über 1800 Mal der Fall war.
Mit diesem Verfahren verhindert PyPI, dass Angreifer eine aufgegebene Domain übernehmen, die E-Mail-Adresse des vorherigen Nutzers einrichten, bei PyPI das Passwort des mit der Mail-Adresse verbundenen Accounts zurücksetzen und sich einloggen. Dann haben sie Zugriff auf die dort veröffentlichten Python-Pakete und können Schadcode in diese einbauen, den andere Nutzer unbedarft installieren. Als Beispiel für einen derartigen Lieferkettenangriff nennt der Python-Blog das Hijacking des ctx-Pakets 2022, das andere User 27.000 Mal heruntergeladen haben.
Für die Prüfung nutzt PyPI die Karenzzeit von dreißig Tagen, in die Domains nach der Löschung gehen: die Redemption Grace Period (RGP). Dieser Status ist öffentlich gekennzeichnet, was PyPI nun täglich checkt und den betroffenen Mail-Adressen die Verifikation entzieht. Das bedeutet, dass Nutzer nicht einfach ein Passwort zurücksetzen können, sondern zusätzliche Belege vorlegen müssen, beispielsweise einen zweiten Faktor – wenn eingerichtet – oder eine Mitgliedschaft in anderen, nicht näher spezifizierten Diensten („via other services under the user’s control“).
In der Ankündigung schreibt PyPI, dass bei der initialen Prüfung im Juni 1500 Adressen die Verifikation verloren haben. Ausdrücklich nicht betroffen sind Domains, die regulär den Besitzer wechseln und nicht in eine Karenzzeit gehen.
PyPI entzieht täglich Mail-Adressen die Verifizierung (hier im Bild ohne die 1500 von der initialen Prüfung).
(Bild: PyPI)
PyPI empfiehlt allen Anwenderinnen und Anwendern, prinzipiell einen zweiten Faktor für den Login einzurichten und eine weitere Mail-Adresse von einer „glaubwürdigen Domain (zum Beispiel Gmail)“ anzugeben.
(who)
Entwicklung & Code
Event-Sourcing als perfekte Grundlage für KI
Wissen Sie, was mir aufgefallen ist? Derzeit wird sehr viel über Künstliche Intelligenz gesprochen. Eigentlich immer, wenn es darum geht, was man mit KI umsetzen könnte, steht die Frage im Raum: Welches Modell verwenden wir dafür? Das ist verständlich, da dies den Markt in gewisser Weise antreibt.
Golo Roden ist Gründer und CTO von the native web GmbH. Er beschäftigt sich mit der Konzeption und Entwicklung von Web- und Cloud-Anwendungen sowie -APIs, mit einem Schwerpunkt auf Event-getriebenen und Service-basierten verteilten Architekturen. Sein Leitsatz lautet, dass Softwareentwicklung kein Selbstzweck ist, sondern immer einer zugrundeliegenden Fachlichkeit folgen muss.
Meines Erachtens ist es jedoch die falsche Diskussion. Denn die Modelle sind letztlich nur Werkzeuge, nicht jedoch das Rohmaterial, mit dem gearbeitet wird. Das Rohmaterial sind die Daten. Ein Modell kann so leistungsfähig sein, wie es will: Wenn die Daten nicht gut sind, bringt es keinen Vorteil. Ein durchschnittliches Modell, das mit hochwertigen Daten trainiert wird, wird jedes Spitzenmodell schlagen, das auf minderwertigen Daten trainiert wurde.
In der Realität sind die Daten vieler Unternehmen jedoch genau das: minderwertig. Es spielt keine Rolle, wie intensiv über KI-Modelle diskutiert wird, wie viel Aufwand in Data Science investiert wird oder wie viele Data-Engineers und Data Scientists eingestellt werden. Am Ende nützt das alles nichts, wenn die Daten von schlechter Qualität sind. Es ist wie beim Kochen: Wenn die Zutaten verdorben oder abgelaufen sind, kann selbst die beste Köchin oder der beste Koch kein Fünf-Sterne-Menü daraus zubereiten. Das Ergebnis wird immer maßgeblich davon bestimmt, was ursprünglich an Material zur Verfügung steht. Letztlich lässt sich das auf die alte Formel „Garbage In, Garbage Out“ reduzieren.
Empfohlener redaktioneller Inhalt
Mit Ihrer Zustimmung wird hier ein externes YouTube-Video (Google Ireland Limited) geladen.
Event-Sourcing + KI: Das Fundament für bessere KI-Modelle // deutsch
Dennoch spricht kaum jemand darüber. Statt zu überlegen, wie man zu qualitativ hochwertigen Daten gelangt, beschäftigen sich viele Unternehmen primär damit, wie man Daten normalisiert, Features extrahiert, ob nun ReLU oder Sigmoid als Aktivierungsfunktion besser geeignet ist, ob man GPT, Claude, Gemini oder ein anderes Modell nutzen sollte. Das alles sind zweifellos legitime und wichtige Fragen.
Zu oft dienen sie jedoch als Ersatzdiskussion, um sich nicht mit dem eigentlichen Problem zu befassen: Wie gelangen wir zu guten Daten?
Das Problem mit den Daten
Was meine ich, wenn ich sage, dass die meisten Unternehmen keine guten Daten haben? Das beginnt mit etwas scheinbar Banalem: Daten sind oft nicht vollständig. Hier fehlt etwas, dort fehlt etwas, und teilweise muss man sich zusammenreimen, was sinnvoll passen könnte. Ebenso häufig tritt jedoch auch das Gegenteil auf: Es gibt zu viele Daten. Identische Daten liegen mehrfach vor – in verschiedenen Systemen, jedoch nicht in identischer Form. Sie sollten natürlich identisch sein, sind es in der Praxis jedoch nicht. Mitunter handelt es sich nur um Kleinigkeiten wie Schreibfehler, häufiger jedoch um gravierende Unterschiede.
Beispielsweise ist ein System der Ansicht, dass eine Nutzerin oder ein Nutzer selbstverständlich Zutritt zu einem sicherheitskritischen Bereich haben darf, während ein anderes System dies strikt verneint. Die Frage lautet dann: Wer hat recht? Diese Themen sind im Datenalltag an der Tagesordnung: Unvollständigkeit, Inkonsistenz, Fehler. Spricht man dies an, erhält man in der Regel zwei Arten von Reaktionen: Die erste ist technischer Natur – etwa die Aussage, man habe ein hervorragendes Master-Data-Management, als wäre dies die Lösung aller Probleme. Wäre es so einfach, gäbe es keine schlechten Daten. Die zweite Reaktion lautet:
„Das ist richtig, aber es ist jetzt halt so, und wir können es nicht ändern. Wir müssen versuchen, das Beste daraus zu machen.“
Da schließt sich dann der Kreis: Das Beste daraus zu machen funktioniert nämlich nur, wenn die Grundlage zumindest brauchbar ist. Wie bereits erwähnt: Die besten Data-Engineers, der beste Algorithmus oder das leistungsfähigste Modell nützen nichts, wenn die Ausgangsdaten minderwertig sind. Genau deshalb erzielen viele Unternehmen mit KI keine überzeugenden Ergebnisse – weil der beschriebene Zustand die Regel ist.
Und warum ist das so?
Es stellt sich also die Frage: Warum sind Daten so häufig von so schlechter Qualität? Eine wesentliche Erklärung ist, dass bei den im operativen Betrieb anfallenden Daten fast immer ein entscheidendes Element fehlt: der fachliche Kontext. Gespeichert wird nämlich allzu oft lediglich der Status quo, also das Ergebnis bereits abgeschlossener Geschäftsprozesse. Sie wissen beispielsweise, dass eine Kundin oder ein Kunde den Status „Premiumkunde“ hat, nicht jedoch, warum das so ist, seit wann das so ist oder wer das veranlasst hat. Sie wissen, dass ein Produkt heute 9,99 Euro kostet, nicht jedoch, ob dieser Preis kürzlich erhöht wurde, seit 20 Jahren stabil ist oder als letzter Versuch dient, das Produkt mit einem Kampfpreis am Markt zu halten. Sie wissen, dass eine Bestellung offen ist, nicht jedoch, wie oft sie geändert wurde oder wer sie ursprünglich ausgelöst hat.
Dieser fehlende Kontext ist ein erhebliches Problem. Ironischerweise ist „Kontext“ im Bereich der KI ein zentrales Thema – man spricht inzwischen sogar nicht mehr nur von „Prompt-Engineering“, sondern bereits von „Context-Engineering“. Wer mit einem Sprachmodell gearbeitet hat, weiß, wie entscheidend die Größe des sogenannten Context Window ist. Je mehr relevanten Kontext man einem Modell gibt, desto besser sind in der Regel die Antworten. Das Problem: Genau dieser Kontext fehlt oft vollständig in den Quelldaten. Trainiert man KI-Modelle auf dieser Basis, ist das Ergebnis so wenig sinnvoll, wie wenn man ChatGPT lediglich die Frage
„Worauf sollte ich achten?“
stellt – ohne weiteren Hintergrund.
Alter Wein in neuen Schläuchen
Tatsächlich ist das keineswegs ein neues Problem. Schon im Data Warehousing war es üblich, und man hatte sich damit arrangiert – meist jedenfalls. Bemerkenswert ist, dass damals genau dieselben inhaltlich wenig zielführenden Diskussionen geführt wurden: ob nun ein Star-Schema besser geeignet sei als herkömmliche Tabellen, ob Oracle besser als DB2 funktioniere oder welche technische Lösung sonst vorzuziehen sei. Es war dieselbe Diskussion, nur mit anderen Werkzeugen. Technische Detailfragen lassen sich leichter diskutieren, als sich mit dem fachlichen Kern des Problems auseinanderzusetzen. Das wäre wesentlich sinnvoller, erfordert jedoch, die eigene Komfortzone zu verlassen.
Das gilt weniger für Einzelpersonen, sondern eher für Unternehmen als Ganzes: Je größer ein Unternehmen ist, desto unflexibler wird es in der Regel und desto eher werden rein technische Diskussionen geführt. Hier schließt sich der Kreis wiederum zum Individuum: In großen Unternehmen wollen häufig viele Personen mitreden, die fachlich nicht ausreichend qualifiziert sind. Das ist seit jeher ein Problem und wird es wohl auch bleiben.
In der Vergangenheit konnte man dies oft ignorieren oder akzeptieren, da Data Warehousing und Online Transaction Processing (OLTP) nur Themen für große Unternehmen waren. Mit Künstlicher Intelligenz, den gestiegenen Erwartungen und der Demokratisierung des Themas wird es jedoch zunehmend dringlich – für große wie für kleine Unternehmen. Künftig wird es sich kein Unternehmen mehr leisten können, KI auf schlechten Daten zu trainieren, da die Erwartungshaltung heute eine völlig andere ist.
Warum das Thema an Relevanz gewinnt
Hinzu kommt, dass sich die Verbreitung und Relevanz dieser Themen drastisch verändert haben. KI war in den meisten Unternehmen selbst vor zehn Jahren bestenfalls ein Forschungsthema oder ein kleines Experiment am Rand. Man entwickelte vielleicht ein einfaches Machine-Learning-Modell, um interne Daten zu analysieren, oder ergänzte einige Regeln, um Prozesse zu automatisieren – mehr nicht. Funktionierte das Vorhaben, war es erfreulich, funktionierte es nicht, war dies kein Geschäftsrisiko.
Heute ist die Situation grundlegend anders: KI steht in vielen Unternehmen nicht mehr nur in der Innovationsabteilung als Punkt 17 auf einer Liste, sondern ist häufig ein zentrales Thema im Vorstand. Die Erwartungen sind hoch: Prozesse sollen automatisiert, Entscheidungen verbessert, Risiken minimiert, Umsätze gesteigert, Kundinnen und Kunden besser verstanden, individuelle Angebote ausgespielt werden – und das möglichst gleichzeitig und sofort. KI ist kein „nice to have“ mehr, sondern ein strategisch wichtiges Asset.
Gleichzeitig sind die technischen Möglichkeiten explodiert. Große Sprachmodelle, die noch vor wenigen Jahren wie Science-Fiction wirkten, sind heute frei verfügbar. Mit wenigen Klicks lässt sich in der Cloud ein Modell starten, das mehr Parameter besitzt als vor zehn Jahren alle Modelle einer gesamten Forschungsgruppe zusammen. Es gibt Open-Source-Modelle, ausgereifte Toolchains und stabile Bibliotheken, die Infrastruktur ist so günstig und skalierbar wie nie zuvor.
Noch nie war es so einfach, KI-Modelle zu entwerfen, zu entwickeln, zu trainieren, zu testen und produktiv zu nutzen. Diese Ausgangslage wirkt perfekt, verführt jedoch leicht zu der Annahme, dass mit wenigen Klicks alles erledigt sei: Man nimmt ein Modell, speist es mit beliebigen vorhandenen Daten, und schon entstehe ein sinnvoller Output. In der Realität funktioniert dies nicht. Schlechte Daten bleiben schlechte Daten, und sie führen zu schlechten Ergebnissen – unabhängig davon, wie gut das Modell ist.
Fehlende Transparenz heißt fehlendes Vertrauen
Als ob dies nicht schon problematisch genug wäre, verschärft ein weiterer Aspekt die Situation erheblich: Die Anforderungen an Erklärbarkeit, Nachvollziehbarkeit, Transparenz, Compliance und Auditierbarkeit steigen rasant. Es genügt nicht mehr, dass ein Modell einfach nur gute Ergebnisse liefert. Im Zweifelsfall muss nachvollziehbar begründet werden können, warum eine KI zu einer bestimmten Entscheidung gelangt ist. Es muss ersichtlich sein, welche Daten maßgeblich waren, ob diese vollständig, konsistent und korrekt waren. Der gesamte Weg der Daten – von der Quelle bis zum Output – muss nachvollziehbar sein.
Das ist nicht nur eine technische Spielerei, sondern in vielen Bereichen bereits Pflicht oder wird es in naher Zukunft werden: Im Finanzwesen besteht beispielsweise die regulatorische Vorgabe, die Entstehung eines Kredit-Scorings nachweisen zu können. In der Medizin muss erklärbar sein, wie eine Diagnose zustande kam. In der Versicherungsbranche ist darzulegen, wie eine Risikoeinstufung entstanden ist. Auch im staatlichen Bereich ist Transparenz nicht nur sinnvoll, sondern in höchstem Maße wünschenswert.
Stellen Sie sich vor, Sie sitzen in einem Audit oder in einem Gerichtsverfahren, und es wird gefragt:
„Können Sie uns genau zeigen, welche Daten dieses Modell zu dieser Entscheidung geführt haben?“
Wenn Sie das nicht können, weil es technisch nicht rekonstruierbar ist, dann entsteht ein gravierendes Problem. Häufig liegt das daran, dass Systeme die Historie nie gespeichert und den Kontext nie dokumentiert haben. Und genau hier stehen viele Unternehmen heute: Auf der einen Seite gibt es den größten Hype um KI aller Zeiten, mit enormen Anforderungen an Datenqualität, Kontext und Historie. Auf der anderen Seite verfügen nahezu alle Unternehmen über unzureichende Daten, die für ihre geplanten Vorhaben ungeeignet sind.
Ein endgültiger Verlust
Die Lücke zwischen dem, was erreicht werden soll, und dem, was die Daten hergeben, ist riesig – und sie schrumpft nicht. Untätigkeit verschärft sie sogar, da Systeme weiterlaufen und täglich mehr Kontext und Historie verloren geht. Es gibt kein automatisches Aufholen. Kurzum: Was heute nicht erfasst wird, ist unwiederbringlich verloren.
Das bedeutet: Wenn Sie davon ausgehen, dass KI in Ihrem Unternehmen in den kommenden Jahren eine größere Rolle spielen wird (und in welchem Unternehmen wäre das nicht der Fall?), dann sollte Ihre größte Sorge nicht der Einsatz eines bestimmten KI-Modells sein. Entscheidend ist vielmehr, wie Sie die Grundlage für eine belastbare Datenbasis schaffen. Diese sollte so schnell wie möglich aufgebaut werden, idealerweise sofort. Denn Daten, die heute nicht erfasst werden, stehen auch morgen keinem Modell der Welt mehr zur Verfügung. Dieser Verlust ist endgültig.
Die naheliegende Frage lautet: Wie könnte eine Lösung für dieses Problem aussehen? Was muss geschehen, oder was muss ein Unternehmen tun, um künftig über eine Datenbasis zu verfügen, auf der sich mit KI-Modellen präzise, verlässliche und nachvollziehbare Ergebnisse erzielen lassen? Die Antwort liegt nahe: Wir benötigen vollständigere Daten, die nicht nur den aktuellen Zustand abbilden, sondern auch den Weg dorthin. Historische Daten sind erforderlich, ebenso fachlicher Kontext. Es geht nicht nur darum, das „Was“ zu erfassen, sondern vor allem auch das „Warum“. Wir müssen wissen, was passiert ist, wann, durch wen und aus welchem Grund. Nur dann lassen sich aus diesen Daten aussagekräftige Muster ableiten, Abhängigkeiten verstehen und Vorhersagen treffen, die mehr sind als bloßes Raten.
Event-Sourcing als Grundlage
Genau das ist der Kern des Event-Sourcing. Falls Ihnen das Konzept nicht vertraut ist, hier eine kurze Zusammenfassung (alternativ empfehle ich Ihnen das Video „Event-Sourcing – das einzige Video, das Du brauchst“ als Einführung): Event-Sourcing ist ein Ansatz zur Datenspeicherung, bei dem nicht der Status quo abgelegt und von Zeit zu Zeit aktualisiert oder gelöscht wird. Stattdessen werden die einzelnen Schritte gespeichert – also die Veränderungen, die im Laufe der Zeit zum aktuellen Zustand geführt haben. Dies geschieht nicht als bloße Abfolge technischer Updates, sondern fachlich beschrieben, damit auch erkennbar ist, warum sich etwas verändert hat.
Vergleichbar ist das Vorgehen mit einem Girokonto: Die Bank speichert nicht nur den aktuellen Kontostand und verweist bei Nachfragen auf Unwissenheit, sondern führt ein fortlaufendes Protokoll aller Transaktionen. Daraus lässt sich der aktuelle Kontostand jederzeit berechnen.
Der entscheidende Vorteil besteht darin, dass sich zusätzlich zahlreiche andere Erkenntnisse gewinnen lassen, da die gesamte Entwicklung sichtbar bleibt. Ohne Event-Sourcing wären diese Informationen unwiederbringlich verloren, und auch Verfahren wie Change-Data-Capture (CDC) könnten sie nicht vollständig rekonstruieren, da sie nur erfassen, dass und wie sich Daten geändert haben – nicht jedoch warum. Liegt dieses „Warum“ jedoch vor, entstehen fachlich reichhaltige und semantisch wertvolle Daten, in denen sich Muster deutlich leichter erkennen lassen.
Dieses Prinzip lässt sich nicht nur auf Girokonten anwenden, sondern auf nahezu jede Domäne – also auch auf die Daten und Geschäftsprozesse Ihres Unternehmens. Statt Zustands-Snapshots zu speichern, werden die geschäftsrelevanten Ereignisse erfasst – lückenlos, chronologisch und unveränderlich. Genau wie bei der Bank kann daraus jederzeit der aktuelle Zustand berechnet werden. Die Historie lässt sich vollständig abspielen, analysieren, auf Teilzeiträume eingrenzen oder für Was-wäre-wenn-Szenarien nutzen.
Die Vergangenheit verstehen
Stellen Sie sich vor, Sie würden ein KI-Modell nicht auf aggregierten Enddaten trainieren, sondern auf den ursprünglichen Ereignissen. Das Modell könnte dann nicht nur erkennen, dass eine Kundin oder ein Kunde abgesprungen ist, sondern auch, welche Interaktionen, Bestellungen, Preisänderungen, Lieferverzögerungen oder andere Faktoren vorher stattgefunden haben. Auf dieser Grundlage lassen sich Muster viel einfacher und vor allem genauer identifizieren, die möglicherweise bei anderen Kundinnen und Kunden ebenfalls auftreten. Das eröffnet eine völlig neue Qualität der Analyse und Prognose.
Zudem können KI-Modelle nicht nur mit den aktuellen Daten trainiert werden, sondern auch aus der Sicht beliebiger Zeitpunkte in der Vergangenheit. Features lassen sich gezielter extrahieren, da die relevanten Variablen klarer erkennbar sind. Auch die Validierung der Modelle wird erleichtert, weil überprüft werden kann, ob Vorhersagen tatsächlich eingetroffen sind – diese Ergebnisse lassen sich nämlich ihrerseits auch wiederum als Events speichern.
Auf diese Weise kann ein Modell durch die fortlaufende Entwicklung sogar besser lernen, da alle Trainingsentscheidungen jederzeit nachvollzogen und hinterfragt werden können. Und dieses Prinzip funktioniert universell – in jeder Branche und für nahezu jede Software. Das bedeutet übrigens nicht, dass Event-Sourcing ausschließlich für den Einsatz mit Künstlicher Intelligenz geeignet wäre. Auch ohne KI bietet Event-Sourcing zahlreiche Vorteile. Wer jedoch ernsthaft den Einsatz von KI plant, findet darin die ideale Grundlage, da es genau das liefert, was KI am dringendsten benötigt und am seltensten erhält: fachlich vollständige, konsistente und kontextreiche Daten.
Aller Anfang ist schwer
Allerdings lässt sich Event-Sourcing nicht einfach per Schalter aktivieren. Wer es einführen möchte, muss einige typische Hürden überwinden. Diese sind zwar alle lösbar, erfordern jedoch Erfahrung. Ein häufiger Fehler besteht darin, pro forma Ereignisse zu definieren, die jedoch nicht fachlich durchdacht sind. Ereignisse wie „Bestellung created“, „Bestellung updated“ und „Bestellung deleted“ mögen formal korrekt erscheinen, bilden aber keine fachliche Realität ab.
Richtig wären Formulierungen wie „Bestellung aufgegeben“, „Bestellung freigegeben“ oder „Bestellung storniert“. Es geht darum, sich von rein technischen CRUD-Operationen zu lösen und hin zu fachlich getriebenen Begriffen zu kommen. Zwar ist dies vielen bekannt, in der Umsetzung wird es jedoch oft vernachlässigt – aus Gewohnheit oder mangels Erfahrung. Der Mehrwert bleibt so allerdings aus, da man inhaltlich in alten Denkmustern verharrt.
Ein weiterer Fehler besteht darin, die Definition der Ereignisse allein den Entwicklerinnen und Entwicklern zu überlassen. Diese verfügen häufig nicht über das notwendige Detailwissen zu fachlichen Abläufen, Auslösern und Relevanz. Hier ist die enge Zusammenarbeit mit den Fachabteilungen zwingend erforderlich. Häufig scheitert es dabei jedoch bereits an der Kommunikation – sei es, weil gar nicht miteinander gesprochen wird oder aneinander vorbei. Ohne ein echtes Verständnis der Fachlichkeit lohnt sich der Einstieg in Event-Sourcing nicht.
Die zweite Hürde ist der technische Umbau: Viele Unternehmen starten nicht auf der grünen Wiese, sondern verfügen über bestehende Systeme – in der Regel auf CRUD-Operationen ausgerichtet, andernfalls gäbe es das beschriebene Problem gar nicht. Diese Systeme sind oft mit zahlreichen weiteren Anwendungen integriert, verknüpft und verbunden. Eine vollständige Ablösung ist in der Regel nicht kurzfristig möglich. Es erfordert daher eine sorgfältige Planung, wie die Umstellung erfolgen kann. Dafür existieren bewährte Ansätze, die jedoch ebenfalls Erfahrung voraussetzen.
Diverse Herausforderungen, …
Die dritte Hürde betrifft die Infrastruktur: Event-Sourcing ist nicht einfach nur ein anderes Tabellendesign in der Datenbank, sondern ein grundsätzlich anderes Verständnis von Daten und Prozessen. Das hat Konsequenzen für die Softwarearchitektur und die Implementierung. Aufgabenstellungen unterscheiden sich deutlich von denen klassischer, relational geprägter Anwendungen. Die eingesetzte Datenbank muss zu diesem Ansatz passen. Wer seit Jahrzehnten eine relationale Datenbank wie PostgreSQL nutzt und diese auch für Event-Sourcing einsetzen möchte, trifft damit oft eine Fehlentscheidung. Nicht, weil PostgreSQL eine schlechte Datenbank wäre – ganz im Gegenteil –, sondern weil es sich um ein relationales Modell handelt, Event-Sourcing jedoch kein relationales Konzept ist. Ein Werkzeug wie PostgreSQL ist hervorragend, aber für diesen Anwendungsfall schlicht ungeeignet.
Sinnvoller ist es daher, eine auf Event-Sourcing spezialisierte Datenbank zu nutzen. An diesem Punkt entstehen häufig Diskussionen, warum dies notwendig sei, da es doch nur um das Speichern von Daten gehe. Solche Argumente zeigen meist, dass das Prinzip und das Konzept hinter Event-Sourcing noch nicht verstanden wurden – den Beteiligten ist dies jedoch oft nicht bewusst.
Schließlich gibt es noch eine kulturelle Hürde: Event-Sourcing erfordert ein grundlegendes Umdenken. Viele Menschen in Unternehmen sind es gewohnt, ausschließlich mit dem aktuellen Zustand zu arbeiten. Der Gedanke, die vollständige Historie zu speichern und auszuwerten, ist für sie ungewohnt und fremd. Zunächst muss daher ein Bewusstsein dafür geschaffen werden, warum es wertvoll ist, Ereignisse zu speichern, wie dies funktioniert, wie damit gearbeitet werden kann und wie sich dadurch möglicherweise auch der Blick auf die eigenen Prozesse verändert.
… die aber lösbar sind
Alle diese Hürden sind überwindbar, sie sind jedoch auch real. Werden sie ignoriert, entwickelt sich aus einer großen Chance schnell ein teures und frustrierendes Projekt, das nach kurzer Zeit niemand mehr weiterverfolgen möchte. Es ist deshalb wichtig, sich vorab mit diesen Punkten auseinanderzusetzen. Die technischen Herausforderungen, etwa bei der Infrastruktur, sind dabei meist das geringste Problem. Sobald klar ist, worauf es ankommt, wird auch der Mehrwert spezialisierter Event-Sourcing-Datenbanken deutlich.
Die weitaus größere Herausforderung besteht darin, das Umdenken in den Köpfen anzustoßen. Ein umfassender Umbau in einem einzigen Schritt ist daher selten erfolgreich. Sinnvoller ist es, zunächst ein kleines, klar abgegrenztes Teilproblem zu wählen und dieses gezielt zu bearbeiten. So können erste Erfahrungen gesammelt werden, Fehler bleiben überschaubar, und es entsteht ein sichtbares Ergebnis – ein „Leuchtturmprojekt“, das andere inspiriert.
Anstatt beispielsweise einen gesamten Onlineshop umzustellen, könnte man zunächst mit dem Check-out- und dem Rechnungsprozess beginnen. In einer Versicherung böte sich etwa die Schadensmeldung an. Entscheidend ist, dass die initiale Frage lautet: Welche Entscheidungen soll KI in diesem Bereich künftig unterstützen, und welche Fragen wollen Sie datengetrieben besser beantworten können? Diese Fokussierung verhindert, sich in einem generischen
„Wir machen jetzt alles mit Event-Sourcing.“
zu verlieren.
Echte interdisziplinäre Zusammenarbeit als Schlüssel
Anschließend gilt es, die fachlichen Hausaufgaben zu erledigen. Setzen Sie sich gemeinsam mit dem Fachbereich in mehreren Workshops zusammen und arbeiten Sie an realen Beispielen heraus, wie die Prozesse aussehen. Ob Sie dafür Event-Storming, Domain-Storytelling oder eine andere Methode verwenden, ist nebensächlich. Wichtig ist, dass ein gemeinsames Verständnis und eine gemeinsame Sprache entstehen. Sinnvoll ist es, diese Arbeit von einer Person moderieren zu lassen, die Erfahrung mit solchen Formaten hat. Das Ergebnis ist eine Modellierung – zunächst nicht der gesamten Domäne, sondern eines kleinen, überschaubaren MVP, auf dessen Basis ein erster Durchstich entwickelt werden kann.
Parallel dazu sollte die technische Vorbereitung erfolgen. Machen Sie sich mit einer Event-Sourcing-Datenbank vertraut. Wenn Sie die Anwendung nicht vollständig neu entwickeln möchten, kann ein passendes Framework wie beispielsweise OpenCQRS hilfreich sein.
Dass hier das Schlagwort „CQRS“ fällt, ist übrigens kein Zufall: Bei CQRS werden separate Datenmodelle für Schreib- und Lesevorgänge verwendet (siehe cqrs.com). Viele tun sich anfangs schwer damit, den Nutzen mehrerer Datenmodelle zu erkennen – zumal diese synchronisiert werden müssen. Spätestens im Zusammenhang mit KI wird der Vorteil deutlich, da verschiedene KI-Modelle unterschiedliche Datenmodelle erfordern können. Mit CQRS ist das unkompliziert möglich. Ohne CQRS wird es deutlich komplexer und in den meisten Fällen auch schlechter.
Von Events über Read Models zu Features
Wenn Sie diese Grundlagen geschaffen haben, verfügen Sie über eine hervorragende Basis für KI: Aus Ihrem Event-Store lässt sich einfach ein neues Lesemodell ableiten, mit dem Sie die benötigten Features erzeugen. Features sind letztlich nämlich nichts anderes als Funktionen über Ereignissequenzen. Sie können diese für jeden beliebigen Zeitpunkt erstellen, nachvollziehen, wie sie entstanden sind, aus welchen Ereignissen sie bestehen, und vieles mehr. Dadurch werden die Daten nachvollziehbar, transparent und versionierbar.
Wenn sich herausstellt, dass die extrahierten Features nicht geeignet sind, können Sie das Lesemodell verwerfen und ein anderes aufbauen – oder beide parallel betreiben. Sie können vergleichen, ob ein Modell besser oder schlechter arbeitet, und sowohl Online- als auch Offline-Modelle trainieren. Da alle Modelle aus denselben Ursprungsdaten – den Ereignissen – abgeleitet werden, ist sichergestellt, dass keine Diskrepanzen entstehen.
So lässt sich die Architektur Schritt für Schritt ausbauen. Steht der erste Service, kann der nächste folgen. Auf diese Weise werden aus dem Bestandssystem nach und nach einzelne Komponenten herausgelöst – ein Vorgehen, das als Strangler-Ansatz bekannt ist und mit dem ich sehr gute Erfahrungen gemacht habe. Dieses Vorgehen lässt sich allerdings nicht von heute auf morgen umsetzen. Ziel ist es jedoch, langfristig eine stabile und tragfähige Grundlage für die Zukunft zu schaffen.
Data-Mesh: Ein Konzept für Datenprodukte
Die Umsetzung erfolgt dabei nicht in einem zentralen KI-Team. Das fachliche Verständnis ist entscheidend, und dieses Wissen gehört in jedes einzelne Team. Ein klassisches Data-Warehouse im herkömmlichen Sinn gibt es in diesem Ansatz nicht mehr. Stattdessen entwickelt jedes Team eigene Daten- und KI-Produkte und stellt diese über APIs anderen Teams zur Verfügung. Das Ergebnis ist eine leichtgewichtige Variante des Data-Mesh-Ansatzes.
Dieses Thema wird oft unnötig verkompliziert und als riesiges Projekt dargestellt. Aus meiner Sicht handelt es sich im Kern um einige klare Regeln – vor allem die Erkenntnis, dass die Verantwortung für die Daten beim jeweiligen fachlichen Team liegen sollte.
Es gäbe noch zahlreiche weitere Aspekte, die in diesem Zusammenhang relevant sind. Für den Abschluss möchte ich jedoch auf einen zentralen Punkt eingehen: Wenn Sie wie beschrieben vorgehen, ist die wichtigste Veränderung nicht technischer, sondern kultureller Natur. Sie nehmen Kolleginnen und Kollegen, Teams und Führungskräften die Angst vor Event-Sourcing, indem Sie zeigen, dass es sich nicht um einen Sprung ins Ungewisse handelt, sondern um einen geordneten Weg mit vielen kleinen, aber sichtbaren Erfolgen:
- eine API, die Prozesse fachlich abbildet und verständlicher nutzbar ist,
- ein erstes Lesemodell, das dem Fachbereich einen direkten Nutzen bringt,
- ein erster KI-Anwendungsfall, der reproduzierbar und erklärbar ist und
- ein erstes Datenprodukt, das andere Teams nutzen können.
Diese Erlebnisse verändern die Haltung von „komplex und riskant“ hin zu „hilfreich und zuverlässig“.
Wenn Sie diesen Weg gehen – klein starten, die Domäne ernst nehmen, technische Leitplanken setzen, CQRS nutzen, auf Event-Sourcing setzen, Lesemodelle definieren, Daten über APIs bereitstellen, Qualität messbar machen und automatisieren sowie Governance schlank halten –, werden die Hürden auf handhabbare Aufgaben reduziert. Schritt für Schritt entsteht dann genau die Datenbasis, die Sie für KI benötigen: vollständig, kontextreich und nachvollziehbar. Selbst wenn der erste KI-Anwendungsfall später durch einen anderen ersetzt wird, bleibt das Fundament bestehen. Denn die Ereignisse sind die einzige Investition, die nicht veraltet.
Wenn Sie mehr über das Zusammenspiel von Event-Sourcing, CQRS, Data-Mesh und KI erfahren möchten, sei Ihnen an dieser Stelle abschließend noch die Webseite „Event Sourcing and AI“ empfohlen.
(rme)
Entwicklung & Code
programmier.bar: Accessibility mit Josefine Schaefer
Accessibility betrifft nicht erst mit Inkrafttreten des Barrierefreiheitsstärkungsgesetzes 2025 alle, die digitale Produkte entwickeln oder nutzen. In dieser Folge sprechen Dennis Becker und Jan Gregor Emge-Triebel mit Josefine Schaefer, Accessibility Engineer bei Storyblok, über praktische Wege, digitale Barrierefreiheit unkompliziert in die Entwicklungspraxis zu integrieren.
Josefine Schaefer teilt ihre Erfahrungen aus dem Arbeitsalltag und verrät, wie auch ohne Perfektionismus schnelle Erfolge möglich sind. Neben bekannten Standards wie den Web Content Accessibility Guidelines (WCAG) gibt sie konkrete Tipps und Ressourcen an die Hand, um Berührungsängste im Team abzubauen und Accessibility nachhaltig umzusetzen.
Empfohlener redaktioneller Inhalt
Mit Ihrer Zustimmung wird hier ein externer Inhalt geladen.
Die aktuelle Ausgabe des Podcasts steht auch im Blog der programmier.bar bereit: „Accessibility mit Josefine Schaefer„. Fragen und Anregungen gerne per Mail oder via Mastodon, Bluesky, LinkedIn oder Instagram.
(mai)
-
Datenschutz & Sicherheitvor 2 Monaten
Geschichten aus dem DSC-Beirat: Einreisebeschränkungen und Zugriffsschranken
-
Apps & Mobile Entwicklungvor 2 Monaten
Metal Gear Solid Δ: Snake Eater: Ein Multiplayer-Modus für Fans von Versteckenspielen
-
Online Marketing & SEOvor 2 Monaten
TikTok trackt CO₂ von Ads – und Mitarbeitende intern mit Ratings
-
Digital Business & Startupsvor 2 Monaten
10.000 Euro Tickets? Kann man machen – aber nur mit diesem Trick
-
UX/UI & Webdesignvor 2 Monaten
Philip Bürli › PAGE online
-
UX/UI & Webdesignvor 1 Tag
Der ultimative Guide für eine unvergessliche Customer Experience
-
Digital Business & Startupsvor 2 Monaten
80 % günstiger dank KI – Startup vereinfacht Klinikstudien: Pitchdeck hier
-
Social Mediavor 2 Monaten
Aktuelle Trends, Studien und Statistiken