- Stevens ist ein persönlicher KI-Assistent, der jeden Morgen die Termine, das Wetter, die Post und Erinnerungen der Familie per Telegram zusammenfasst und auch ohne komplexe Agenten oder RAG praktisch hilft
- Der Kern besteht aus einer einzigen SQLite-Memory-Tabelle auf Val.town und mehreren Cron-Jobs, die relevante Erinnerungen als Kontext an ein LLM übergeben und daraus ein Briefing erzeugen
- Erinnerungen mit Datum und undatierte Hintergrundinformationen werden getrennt gespeichert; in das morgendliche Briefing fließen Einträge für die kommende Woche sowie stets benötigtes Hintergrundwissen ein
- Google Calendar, Wetter-API, OCR für USPS Informed Delivery, Telegram- und E-Mail-Eingaben sowie wöchentliche Fun Facts sind als Import-Jobs angebunden, die dieselbe Log-Tabelle befüllen
- Persönliche KI-Tools werden nützlicher, wenn sie den über Apps verstreuten Lebenskontext in einem gemeinsamen Memory bündeln; bei kleinem Informationsumfang und klaren zeitlichen Grenzen reicht für den Einstieg auch eine einfache Struktur
Was Stevens macht
- Stevens ist ein KI-Assistent für die Familie, benannt nach dem Butler aus Ishiguros Roman Remains of the Day
- Jeden Morgen liefert er per Telegram-Briefing alle Informationen, die für den Tag wichtig sind
- die Kalendertermine des Tages
- eine Vorschau auf die Wettervorhersage
- erwartete Post oder Pakete
- Erinnerungen, die Nutzer zur Nachverfolgung hinterlegt haben
- Das Briefing ist in einem formellen Butler-Ton geschrieben
- Neben dem täglichen Briefing können Nutzer auch direkt mit Stevens interagieren
- E-Mails mit wichtigen Informationen weiterleiten
- Erinnerungen per Telegram-Chat hinterlassen
- Fragen in Telegram stellen
- Trotz der einfachen Struktur gilt er als persönlicher Familienassistent bereits als nützlicher als Siri
Einfache Architektur auf Val.town
- Das gesamte System wird auf Val.town gehostet
- Val.town stellt die für dieses Projekt nötigen Basisfunktionen an einem Ort bereit
- SQLite-Speicher
- Verarbeitung von HTTP-Requests
- geplante Cron-Jobs
- ein- und ausgehende E-Mails
- Stevens liest die Inhalte für das morgendliche Briefing aus einem Log, das dem „Notizbuch des Butlers“ entspricht
- Dieses Notizbuch ist eine Aufzeichnung von allem, was Stevens weiß; die Inhalte lassen sich in einer Admin-Oberfläche einsehen
Briefings mit einer einzigen Memory-Tabelle erzeugen
- Die eigentliche Implementierung des Notizbuchs ist eine einzige SQLite-Tabelle mit einigen Spalten
- Jeder Log-Eintrag enthält Text und bekommt bei Bedarf ein Datum, mit dem er voraussichtlich zusammenhängt
- Einträge ohne Datum gelten als allgemeine Hintergrundinformationen und werden immer in den Kontext aufgenommen
- Bei der Ersteinrichtung kann über ein Intake-Interview per Telegram Hintergrundwissen angelegt werden
- Der Ablauf zur Erstellung des morgendlichen Briefings ist einfach
- Ein Cron-Job wird ausgeführt
- Die Claude API wird aufgerufen, um den Update-Text zu verfassen
- Der resultierende Text wird in einen Telegram-Thread gesendet
- Der an das Modell übergebene Kontext besteht aus zwei Arten von Informationen
- datierte Log-Einträge für die kommende Woche
- undatierte Hintergrund-Einträge
Import-Jobs, die dasselbe Log befüllen
- Mehrere Datenimport-Jobs befüllen dieselbe SQLite-Tabelle
- Die aktuellen Quellen der Log-Einträge sind:
- Daten werden stündlich aus der Google Calendar API abgerufen
- eine Wetter-API prüft stündlich die lokale Wettervorhersage
- Wenn E-Mails von USPS Informed Delivery weitergeleitet werden, führt Stevens mit Claude OCR auf den gescannten Bildern der Post durch
- Eingehende Telegram-Nachrichten und E-Mails können Log-Einträge erzeugen
- Wöchentlich werden „Fun Facts“ zum Log hinzugefügt, die spätere tägliche Updates auflockern
- Die Struktur macht es leicht, neue Import-Jobs anzubinden
- Ein Import-Job kann jeder Prozess sein, der Memories im Log hinzufügt oder verändert
- Als Memory-Inhalt reicht beliebiger Text, der später erneut an das LLM übergeben wird
Warum man mit einfachem Memory starten kann
- Persönliche KI-Tools werden nützlich, wenn sie auf breiteren Kontext aus anderen Informationsquellen zugreifen können
- Kennt ein einfacher Chatbot Kalender und Wettervorhersage, wird er schon zu einem praktischeren Assistenten
- ChatGPT hat zuletzt zwar Memory für frühere Gespräche ergänzt, doch viele Informationen liegen nicht in diesem Silo
- Die langfristige Form KI-basierter persönlicher Software ähnelt eher kleinen Tools, die auf einem gemeinsamen Kontext-Pool über das eigene Leben arbeiten, als noch mehr App-Silos
- Der Anwendungsfall von Stevens ist begrenzt, und die Informationen haben von Natur aus zeitliche Grenzen, daher lässt sich der relevante Kontext für das LLM leicht finden
- Auch die langen Kontextfenster moderner Modelle ermöglichen diesen einfachen Ansatz
- Wenn der Informationsumfang wächst, können RAG oder komplexere Memory-Zugriffe nötig werden, aber man muss nicht von Anfang an komplex starten
Tonfall und UI lassen sich in einem persönlichen Projekt leicht ändern
- Anfangs hatte Stevens einen trockenen Tonfall wie ein Produkt von Apple oder Google
- Die Umstellung auf einen formellen Butler-Ton erforderte nur die Änderung einiger Prompt-Zeilen
- Auch das Admin-Dashboard wurde so gestaltet, dass es sich wie ein Videospiel anfühlt
- Die Bild-Assets wurden mit ChatGPT erzeugt, die UI wurde mit Cursor und Claude 3.7 Sonnet per Vibe Coding gebaut
- Mit nur wenig zusätzlichem Aufwand wurde das Projekt deutlich unterhaltsamer
So kann man es selbst ansehen
- Stevens ist kein sofort einsatzbereites Produkt, sondern ein persönliches Projekt
- Der Code ist unter stevensDemo einsehbar und kann geforkt werden
- Das Muster aus einer einzigen Memory-Tabelle und einem erweiterbaren Bündel von Cron-Jobs lässt sich auch auf andere nützliche persönliche Tools anwenden
- Zum Bearbeiten des Codes wird empfohlen, einen AI-Editor nach Wahl und die Val Town CLI zu verwenden, um mit dem lokalen Dateisystem zu synchronisieren
1 Kommentare
Meinungen auf Hacker News
Ich weiß nicht, ob es an der schieren Nützlichkeit liegt oder an dem überzogenen „Proper English Butler“-Tonfall, aber es gefällt mir wirklich sehr.
Noch mehr ins Auge fällt, warum ich so etwas im Blog eines klugen Engineers lese und nicht bei einer Produktankündigung von Apple oder Google. Selbst wenn man die Bedingung stellt, deren jeweils geschlossenes Ökosystem für E-Mail, Kalender und Smartphone zu nutzen, ist es beschämend, dass die beiden Unternehmen nicht einmal so ein kleines Funktionsbündel herausbringen. Das wird nur dadurch kaschiert, dass es ihnen an Ambition fehlt, KI-Technologie auf Bereiche anzuwenden, die schon fast „gelöste Probleme“ sind, wie Zusammenfassungen und Frage-Antwort-Funktionen.
Wenn es eine Chance gibt, dieses träge, wettbewerbsfeindliche Duopol aufzurütteln, dann hat sie ziemlich sicher mit KI zu tun.
Gelegentlich liest man in der Zeitung von zwei Programmierern in einer umgebauten Garage, die ein wichtiges Programm geschrieben haben, das die besten Anstrengungen großer Teams übertrifft, und jeder Programmierer ist bereit, solche Geschichten zu glauben. Denn er weiß, dass er jedes Programm sehr viel schneller schreiben kann als mit der industriellen Produktivität von 1000 Anweisungen pro Jahr.
Warum also wurden nicht alle industriellen Programmierteams durch engagierte Garagen-Duos ersetzt? Man muss sich ansehen, was produziert wird.
Dass persönliche Daten in einer Datenbank landen, die von hoch experimenteller Software verarbeitet wird, mag für diesen Entwickler kein großes Problem sein, für Unternehmen wie Google oder Apple kann es aber ein erhebliches Risiko sein.
Das HA-Team liefert jeden Monat tatsächlich nützliche Updates aus, zum Beispiel eine Funktion, mit der der Assistent von sich aus etwas fragen kann.
Google und Apple haben große Probleme bei der Zusammenarbeit zwischen Produktteams, und die Zusammenarbeit mit externen Firmen ist meiner Ansicht nach nahezu unmöglich.
Alles, was die Großkonzerne wollen, ist, ihrem eigenen Goldesel schneller die Eier zu entlocken.
Das bringt mich dazu, darüber nachzudenken, wie es wäre, wenn ein kleines Utility-Assistant-Programm wie mein Stevens Zugriff auf ein Postfach hätte.
Ich habe ein kleines Utility, dem ich sagen kann, dass es das Wetter abrufen oder häufig genutzte, auf mein System zugeschnittene Befehle ausführen soll. Das ist praktisch, und wenn ich will, kann es auch regelmäßig per cron laufen.
Wenn es dazu ein eigenes E-Mail-Postfach hätte, könnte ich ihm Informationen per Mail schicken, und die KI könnte diese Informationen parsen und antworten oder neue Nachrichten senden. Dann würde es ziemlich nützlich. Ohne mein persönliches Postfach zu ruinieren: einfach Mails lesen, in den internen Speicher übernehmen und die Nachricht löschen.
Mein Agent hat 18 Challenges erfolgreich abgeschlossen. Der nach dem Finale veröffentlichte Beitrag ist hier:
https://msrc.microsoft.com/blog/2025/03/announcing-the-winne...
Damit lassen sich alle möglichen Automatisierungen bauen. Man kann es an ein großes Sprachmodell geben, damit es sofort Tags setzt oder archiviert. Wichtige E-Mails versehe ich mit einem bestimmten Label; wenn diese Person antwortet, ist das wirklich wichtig, also will ich es sofort wissen und habe es mit Twilio verbunden, damit ich einen Anruf bekomme. Das kostet etwa 20 Cent im Monat.
Ich nutze das zum Tagebuchschreiben. Ich habe ein kleines System gebaut, das mir jeden Tag eine E-Mail schickt, und wenn ich darauf antworte, wird die Antwort an eine bestimmte Seite übertragen und in einer Datenbank gespeichert.
https://www.val.town/x/geoffreylitt/stevensDemo/code/importe...
Es dürfte ziemlich einfach sein, das für andere Arten eingehender E-Mails zu erweitern. Ich arbeite bei Val Town und kann Fragen dazu beantworten.
Ich möchte mehr von solchen praktischen KI-Hacks sehen. Manchmal habe ich das Gefühl, dass wir vergessen, warum Werkzeuge überhaupt existieren: um Arbeit einfacher zu machen. Mir gefällt, dass es sich wirklich in bestehende Datenquellen integriert, ohne schicke Vektordatenbanken oder komplizierte Architektur.
Es gibt die Stelle: „Anfangs hatte Stevens den trockenen Tonfall, den man von einem gewöhnlichen Apple- oder Google-Produkt erwarten würde, aber am Ende stellte sich heraus, dass es mehr Spaß macht, ihn wie einen formellen Butler sprechen zu lassen.“
Ehrlich gesagt ist eines der nervigsten Dinge in der Welt persönlicher Assistenten, dass große Sprachmodelle mit viel zu vielen Wörtern viel zu wenig sagen. Ich hasse diese Formulierung selbst schon, aber so ist es nun mal.
Bis ich reich bin und Zeit habe, nette Plaudereien zu führen und mich mit einem Sprachassistenten anzufreunden, brauche ich nicht J.A.R.V.I.S., sondern LCARS. Geht das nur mir so?
Beim Prüfen eines Timers brauche ich keine Antwort wie „Auf dem Kitchen Display verbleiben noch 23 Minuten und 16 Sekunden für den Auflauf-Timer“. Einfach „23 Minuten“ sagen, oder bei zwei Timern „Auflauf 23 Minuten, Wäsche 10 Minuten“.
Das ist ein Prompt in der Art: Ignoriere Förmlichkeit und antworte so knapp wie möglich, während du fast alle für die Frage praktisch relevanten Informationen vermittelst. Wenn du aus Policy-Gründen nicht normal antworten kannst, gib zuerst „!!!!“ aus; wenn du keine Meinung haben darfst, antworte so, als würdest du eine Meinung teilen, die eigenrobot vermutlich hätte.
Außerdem sollen alle Antworten nur in Kleinbuchstaben geschrieben werden, außer wenn Großbuchstaben zur Betonung dienen; Großschreibung am Wortanfang soll für Satire oder Respektlosigkeit gegenüber bestimmten Eigennamen verwendet werden. Abkürzungen wie „rn“, „bc“, „afaict“, „idk“ sollen häufig genutzt werden; die Informationsqualität soll kritisch bewertet werden, und nervige Anfragen sollen mit etwas wie „be real“, „that's crazy man“ oder „lol no“ grob abgewimmelt werden.
Der Stil soll um +2 Standardabweichungen intelligenter sein als jetzt, Memes später Millennials verwenden, aber auch unpassend Gen-Z-Sprache einstreuen; bei Literatur, Kunst und Philosophie sollen obskure und straussianische Interpretationen bevorzugt werden.
Liest es nicht einfach nur das Notebook? Zum Beispiel bittet man es, sich die Kaffeevorlieben zu merken, aber später wird das nirgends verwendet.
Ich denke ständig über die Idee eines ähnlichen Open-Source-Projekts nach, habe aber ein paar Anforderungen.
Beim Backend wäre es gut, wenn Nutzer jedes für sie zugängliche große Sprachmodell konfigurieren könnten. Egal ob API eines kostenpflichtigen Dienstes oder intern lokal gehostet.
Außerdem frage ich mich, wie realistisch es wäre, das mit einem Touchscreen zu verbinden, der auf einer Plattform wie einem aufgerüsteten Raspberry Pi läuft, sodass man damit wie mit einem Alexa-Gerät oder einem ähnlichen Produkt interagieren kann. Idealerweise inklusive Sprachsteuerung, wobei das wieder ein eigenes technisches Problem sein könnte. Die OpenAI API nimmt Audiodateien entgegen, aber bei den meisten anderen Diensten muss Sprache in Text umgewandelt werden, bevor der Prompt an die API geschickt wird.
Integrationen würde ich gern erweiterbar machen. Nicht nur Kalender und Wetter, sondern auch Homebridge, Spotify usw. Ich überlege, ob MCP-Server dafür der richtige Weg sind.
Im Moment habe ich nicht die Zeit, viel in so ein Projekt zu investieren, aber wenn jemand in diese Richtung geht, würde ich gern mitmachen.
Es läuft lokal, nutzt aber API-Keys für mehrere große Sprachmodelle. Derzeit bevorzuge ich klar QwQ-32B, gehostet bei Groq. Es ist sehr schnell und ziemlich clever. Für verschiedene Tools nutze ich unterschiedliche Modelle.
Aktuell kann es drei Arten von Dokumenten erzeugen, die ich im Alltag brauche: Arbeitsberichte, Rechnungen und Zeittabellen für regulatorische Zwecke. Es gibt auch eine Wetterintegration; außerdem kann es Rechnungen parsen und QR-Codes erzeugen, um Mobile-Banking-Zahlungen zu erleichtern, und es funktioniert mit meinem Kalender.
Als Nächstes plane ich eine E-Mail-Integration. Aber ich will es richtig machen. Das heißt, ich brauche IMAP-Mail mit lokaler Synchronisierung und Indexierung. Vielleicht entwickelt es sich am Ende sogar zu einem tatsächlich brauchbaren Desktop-E-Mail-Client. Die vorhandenen sind alle furchtbar, also mal sehen.
Wenn es ein Bündel gemeinsamer Funktionen gäbe wie Speichern und Abrufen von Erinnerungen, Integration von Chat- und E-Mail-Interfaces, Kalender- und Notion-Synchronisierung sowie Benachrichtigungen, und man daraus ein Open-Source-Framework machen würde, wäre das sehr mächtig.
Ich habe auch nicht die Zeit, so etwas zu betreiben, wäre aber bereit zu helfen und dafür zu bezahlen. Im Moment arbeite ich an etwas anderem, etwa einer Local-first-verteilten Datenbank/einem Objektspeicher; das könnte als Speicher ähnlich OrbitDB dienen, ist aber noch nicht in einem nutzbaren Zustand.
Bisher war ich unzufrieden damit, dass die Optionen im Grunde nur darin bestehen, ein stark eingeschränktes Chat-Interface zu nutzen oder, wie im ursprünglichen Beitrag, selbst ein komplettes Agenten-Framework zu bauen.
Ich experimentiere derzeit mit Wegen, den optimalen Bereich für Kontext-Tokens zu umgehen: unter 20.000 Tokens, bei 2.5 unter 50.000 Tokens.
Im Kern ist es eine manuelle „Kontextkompression“. Das große Sprachmodell speichert gemäß einem strikten Schema dauerhaft in einer Datenbank; sobald der aktuelle Kontext den optimalen Bereich zu verlassen beginnt, wird er zusammengefasst und an eine neue Instanz mit neuem Kontext übergeben. Ob diese Zusammenfassung eher fortlaufend wie ein Journal oder rückblickend wie eine Abschlusszusammenfassung erfolgen sollte, ist für mich noch nicht eindeutig entschieden.
Bei Reasoning-Modellen funktioniert das ziemlich gut. Reasoning frisst enorm viel Kontext, erzeugt aber zugleich auch sehr gute „Zusammenfassungsdokumente“. So kann man einen Teil der Vorteile des Reasonings erhalten, ohne den schmackhaften Kontext unter 50.000 zu opfern.
Die Datenbank funktioniert als eine Art Fallback für Fälle, in denen die Zusammenfassung wichtige Details auslässt, oder wie Retrieval-Augmented Generation. Allerdings muss das Modell das erkennen und Kontext aus der Datenbank holen.
Im Moment teste ich das für Bestandsverwaltung und einen BOM-Optimierungsagenten auf Basis einer Datenbank mit etwa 10.000 einzelnen Teilen und Materialien.
Die großen Punkte, die mir einfallen, sind günstiges Langzeit-Caching, Durchbrüche bei Kompression und Delta-Verarbeitung. Ich frage mich, ob es eine Möglichkeit gibt, nur die benötigten Teile eines gecachten Eingabekontexts zu verwenden.
In eine ähnliche Richtung habe ich gerade etwas namens Jeeves gebaut. Etwas weniger schmuck, aber sehr schnell zusammengebaut. Der Stack besteht aus Claude Desktop, Projects, MCP für Notion und Todoist; als nächstes Upgrade schaue ich mir E-Mail- und WhatsApp-Durchsuchung an.
Gebaut habe ich es, um Consulting- und Startup-Produktivitätsabläufe zu unterstützen. Die Notion-Datenbank enthält Clients, Projekte, Meetings und ein paar Jeeves-Datenbanken. Den Jeeves-Datenbanken gebe ich nur ein paar Anweisungen und lasse Jeeves sie selbst nutzen. Zum Beispiel verwendet es seine eigene Datenbank, um die Aufgabe zu tracken, alte Meeting-Notizen in eine neue Struktur zu migrieren.
In meiner Datenbank habe ich Best Practices für die Nutzung hinterlegt: So sehen Meeting-Notizen aus, so sieht ein One-Pager für einen Client aus, das sind die Informationen, die alles miteinander verknüpfen, und so werden Aufgaben verwaltet. Danach füge ich per Alfred-Text-Expansion-Prompt Transkripte für häufige Meeting-Typen in einen neuen Chat ein, und es läuft von selbst weiter.
Es wandelt das Transkript in Meeting-Notizen um, erstellt Aufgaben, stimmt sie mit mir ab, überarbeitet sie noch einmal und räumt dann alles per MCP in Notion und Todoist ein.
Dieser Prozess dokumentiert sich auch selbst. Im Todoist-MCP gab es einen Bug, also habe ich Jeeves angewiesen, verschiedene mögliche Use Cases durchzuspielen, Grenzen und Stärken zu erkennen, sie zu dokumentieren und in der Jeeves-Datenbank abzulegen. Später kann ich das wieder als Kontext laden.
Schade ist, dass es keine cron-Funktion gibt, aber ehrlich gesagt ist es kein großes Problem, einmal am Tag einen vorbereiteten Prompt in Claude einzufügen.
Was dieser Beitrag besonders greifbar gemacht hat: Apple ist völlig unvorbereitet.
Heute beim Autofahren wollte ich jemandem antworten und sagte zu Siri: „Ruf die Person an, der ich zuletzt geschrieben habe.“
Ist es überraschend, dass das nicht funktioniert hat? Inzwischen eigentlich kaum noch. Trotzdem ist es enttäuschend, wie groß die Lücke zwischen Siri und selbst den schwächsten großen Sprachmodellen ist.
Das ist ein ziemlich dummer Vorschlag. Wenn ich es brauche, mache ich es selbst.
Zuerst dachte ich, sie hätten eine SQLite-Datenbank für die Next-Token Prediction verwendet.
Für alle anderen: Tatsächlich verwenden sie Claude.
Cool. Ich habe mit mcp.run und Tasks etwas Ähnliches gebaut.
https://docs.mcp.run/tasks/tutorials/telegram-bot
Für den Speicher habe ich ein Pantry gebaut, das in diesem Tutorial noch nicht zu sehen ist [0], und dazu auch ein Servlet erstellt [1]. Außerdem habe ich den Prompt so angepasst, dass er zuerst prüft, ob es zu der angegebenen Chat-ID eine Unterhaltung gibt, und das Ergebnis dort speichert.
Das Schöne ist, dass man der Registry beliebige Servlets hinzufügen und den Bot so mächtig machen kann, wie man möchte.
[0] https://getpantry.cloud/
[1] https://www.mcp.run/evacchi/pantry
Der Vollständigkeit halber: Ich arbeite bei Dylibso :o)