When drafting a new blog post after some years, it’s mandatory to begin it with some form of mea culpa. I actually made a New Year’s resolution to start writing more blog posts; after the dissolution of my company last year, my head was stuffed with all sorts of technical knowledge I needed to share (and which, I felt, the world needed to hear). I even put together a spreadsheet of possible ideas, which, as I’m writing this down now, I should probably revisit. Some combination of “I got lazy” or “I got busy” or “I didn’t think anyone would care” prevented me from writing, though. (That’s not to say I haven’t been writing anywhere else: I just got “How to Keep Well in Wartime” published, and I’m still running Inch Press!)

I still also make endless side projects and maintain innumerable open source repos. To that end, I recently read something by Mitchell Hashimoto which began with this increasingly common disclaimer:

this was completely hand-written with no AI assistance

I’m not an AI-hater. I use it all day, every day, at my day job (and even wrote about on the company blog—more proof I still write!). I create shippable production code with it and experiments that never leave my terminal. I use it in my open source work to write commits, provide feedback, and generally automate tasks that are too convoluted to come up with in a bash or Ruby script. I don’t think any engineer can, or should, ignore AI. It’s a technology, and like all technologies, it’s here to stay (until something better comes along). It’s beneficial to the craft to understand how to work with it rather than spend time fighting against it.

Part of the reason I enjoy programming is because I like solving technical puzzles. And, part of the reason I like AI is because I can say “do X using Y because of Z,” while walking away to go brew a third cup of coffee or pet my cat or do anything other than sit at my desk, tip-tapping the solution out. When I was a teenager, I, like Lain, never wanted to leave the Internet. Now that I’m closer to the end of my life than its beginning, I want to experience as much as I can of the real world, as often as I can.

With age comes wisdom and worry. Whenever I use AI, I’m actually very concerned about the smoothing of my brain. The inherent irony of my usage outlined above is that the only reason I know about X using Y because of Z is because I accumulated twenty-something years of infernal knowledge for how to communicate with this damn beast made of rocks. I’m fine with letting go of the physical embodiment of programming, but the mental process is still something I look forward to sparring with.

I can say something similar about writing. When I engage with an AI to produce code, there is, to some extent, a deterministic goal I am hoping to achieve: the button should do this, the site should look like that. But when I engage with an AI to produce written words, the outcome is often calibrated to produce a response I didn’t decide on. That is to say: the AI knows all the tricks of “good content”—how to create a staccato sentence or how to produce dichotomastic statements to get the reader to feel a certain way. How the AI gets at that goal is often not how I would get at the goal; and because getting at a goal is one of the very points of writing, I often choose to write my own thoughts using my own hands.

At last, we’re coming to the point, which is a question I (and others) have been wondering, which Hashimoto’s note alludes to: how do you prove a human wrote something? Forget about the why or the value in it, just: how?

My answer to that is a project I called Semoi.[1] The idea is somewhat simple: what distinguishes humans typing from an LLM producing is time and effort. A human is slower, and a human’s digital fingerprints are quite literally that: the keystrokes it took to produce the text. Semoi is a plugin (currently only available for Obsidian) which tracks the length of time it took for a document to be written up. It also tracks the number of keystrokes it took to produce that document. When you’re done writing the piece, you send all that information to the Semoi server, which cryptographically signs and mints the information, proving that it hasn’t been tampered with.

You can then get a little image to paste in your blog somewhere proving that yes, indeed, you wrote the piece.

And of course you can share the link around if you so desire.

My theory goes like this: say a thousand word blog post is published. If an LLM wrote that piece of text, the time it took for it to do so would be on the order of seconds, not minutes. That’s one heuristic Semoi captures. Another is the series of keyup/keydown events that a human types. An LLM generated piece would simply be one copy-paste event—from the terminal to the editor—so one would expect that thousand-word piece to have thousands of individual characters (and events for each of those).

Is it foolproof? No. Is it extremely scientific? Also no. Is it a good idea? Well, I think so. You can see a presentation I gave of this system at my favorite event, WordHack.

One could work around Semoi by, for example, typing out a bunch of gibberish, leaving their editor open, and then pasting in an LLM generated texting and minting the proof. To which I would respond: why? That’s really pathetic.

No information about your text is ever sent to the server, and there’s no way to identify the author based on the minted certificate. All the server receives is a JSON blob of timestamps and keystroke events.

If Semoi never takes off, that’s completely fine! My GitHub repositories are gardens full of both flourishing and withered flowers. But it’s my sincere hope that in writing this post, it nudges someone else to think of an even better idea than this one. That’s another point of writing, after all.

  • From Lucia Joyce’s famous declaration: “C’est moi qui est l’artiste” ↩︎