My prompts to LLMs for input sometimes lead to a stream of code and explanatory notes that I don't want. It's tempting to try and fix things in media res but I usually start over. This affects me in a couple of ways: I feel bad that I've wasted resources through my carelessness; the mess I've created takes the edge off my enthusiasm.
This typically happens when I'm working on a small project; something that might require a few files, and a handful of functions. And disaster can strike at any moment. I ask for tests but forget to mention that I'm using vitest now and not jest, or I fail to stipulate that I want to be asked before adding dependencies. Myriad unread lines spool down the screen.
Then I remembered the ball of thread Ariadne gave to Theseus.
The thread
Thread: The record of an interaction between a developer and an LLM. Contains the thread prompt used to initialise the interaction and a collection of snapshots.
I will use a thread to encapsulate the interactions I have with LLMs.
My thread is a simply structured record written in JSON. Here's part of a thread I set up to explore how to build a simple RSS feed generator:
The project
We start with some information about the project, the sort of things you'd expect to find in any prompt: title, description and definition. A title helps when discussing the project. The definition will depend on what kind of project it is. At this stage, it's a prototype and I pick from one of five types: conceptual, vertical, horizontal, functional and visual. (Here is a longer list of prototype types).
The project and prototype details go in the thread prompt. It will govern the entire interaction related to the project. In nature, it sits somewhere between a one off prompt and a system prompt.
Thread prompt: Used to initialise a thread. Contains project-specific details, rules on how an LLM should interact and how it should format periodic summaries (snapshots).
Interaction guidelines
The next thing I add to the thread prompt are the interaction guidelines; ground rules or guidelines for the LLM to follow during the interaction. I include an explicit direction: "The LLM should follow these guidelines throughout" so that their purpose is clear.
Rules govern things like whether the LLM should show code by default. Two are particularly effective for pacing the LLM's response:
confirmBeforeAdvancing
explainOneConceptAtATime
They cause the LLM to break solutions down into steps and iterate over them.
Here's my updated thread. The thread prompt has been fleshed out to include our rules, terms and I've add a new, top-level, field, snapshots:
The snapshot
Snapshot: A specific interaction state representative of progress to date. A snapshot should conform to the snapshot schema.
The snapshot is how I keep track of what's going on.
Whenever I want a summary of the interaction to date, need to slow things down, or want to record where I am before changing direction, I ask the LLM for a snapshot.
I keep a record of snapshots by copying and pasting them into the snapshots array in my thread.
The snapshot schema describes what these summaries should look like. I've written it in JSON because I find it easy to parse but it could be in YAML or Markdown (it makes no difference to the LLM).
You'll notice the snapshot has a copy of the project and prototype objects. This reminds the developer and the LLM of the purpose of the chat as well as making the snapshot portable.
Artefacts
I now have a thread which contains details of my project, interaction guidelines, and a snapshots array for tracking progress. Where should I put it?
It makes sense to keep the thread in the project itself but separate from the source code. I prefer to put the thread in a dedicated folder, artefacts, which is where I'll also add files I add to the interaction (e.g. examples of expected outputs) as well as code or designs generated by the LLM.
That's it. The thread initialises my interaction with the LLM. I flip between the chat and the project using the files in artefacts as a buffer. Working there, away from the distractions and temptations of the chat interface, I am self-reliant.
Workflow
How does Ariadne's Thread work in practice? Here's a step-by-step guide to creating a thread for a small project:
- Create your project (I use VS Code)
- Add an artefacts folder
- Create a new thread prompt in artefacts with project details, interaction rules and how you want the LLM to write snapshots
- Open a new chat and upload the thread
- Add any files used during the interaction to artefacts, including those generated by the LLM
- When you need a summary of progress to date, ask for a snapshot and add it to the snapshots array
- Use the snapshots and LLM responses inside artefacts to think over what you are doing before working on source code away from the distractions of a chat interface
Example - Building a simple RSS feed generator with Claude
I used Ariadne's Thread to create a simple RSS feed generator. In the artefacts folder you will find a thread, an example of an RSS feed which I added to the chat, and an rss-generator file with code from the LLM. Because I'd asked Claude to proceed incrementally, it returned small numbered chunks of code (1-4) which I evaluated and refactored before using in the source code.
Notice that inside the project definition I added requirements and setup fields. Specifying how I want modules to be imported is a simple way to avoid incompatible code and frustration.
Conclusion
In order not to get lost in the maze of dead-ends and wrong turns caused by muddled thinking, I struck on the metaphor of the thread which Ariadne gave to Theseus to help him navigate the labyrinth.
Creating a thread has the effect of making me think more carefully before starting a new project. Its structure and documentation afford me better oversight and - if I ask an LLM to assist me - the means to moderate our interaction.
Author: Daniel Hartley
This article was published on 10th March 2025.
Terms
- Thread
- The record of an interaction between a developer and an LLM. Contains the thread prompt used to initialise the interaction and a collection of snapshots.
- Thread prompt
- Used to initialise a thread. Contains project-specific details, rules on how an LLM should interact and how it should format periodic summaries (snapshots).
- Snapshot
- A specific interaction state representative of progress to date. A snapshot should conform to the snapshot schema.
Reference
- Ariadne
- Ariadne's Thread
- Prototype types
- The Risks Of Human Overreliance On Large Language Models For Critical Thinking by Duenas and Ruiz
- Human Creativity in the Age of LLMs by Kumar et al.
- Generative AI’s Impact on Critical Thinking: Revisiting Bloom’s Taxonomy by Chahna Gonsalves
- The Death of the Stubborn Developer by Steve Yegge
Potential improvements
I asked Claude to suggest potential improvements. It touched on many ideas we've discussed on this topic, and issues that my colleague, JP, has raised.
Looking at potential improvements for the Ariadne's Thread approach, I see several opportunities to enhance its effectiveness:
- Version Control Integration - The current implementation relies on manually copying snapshots into the thread. Integrating with Git or another version control system could automate this process, creating commits at each snapshot and maintaining a more reliable history.
- Structured Feedback Loop - Adding a dedicated section in the thread for tracking which LLM suggestions worked well and which didn't could improve future interactions. This "lessons learned" component would help refine prompts over time.
- Collaborative Extensions - The approach seems optimized for solo developers. Adding support for team-based workflows, perhaps with role-specific guidelines for different team members, would make it more versatile for larger projects.
- Templating System - While the article mentions a prototype generator, a more robust templating system for different project types (web app, CLI tool, data pipeline, etc.) would save time and standardize interactions across similar projects.
- Visualization Tools - A simple UI to visualize the thread's progression could help identify patterns in the development process, showing where the most iterations occurred or where progress stalled.
- Metrics and Analytics - Adding quantitative measures like time spent per development phase or the ratio of LLM-generated code that makes it to production could provide insights for process improvement.
- Cross-LLM Compatibility - The approach could be extended to work seamlessly across different LLMs, possibly with adapter patterns to normalize the interaction patterns between different AI systems.
- Context Window Management - As projects grow, they can exceed the context window of many LLMs. A mechanism to intelligently summarize or partition the thread while maintaining critical context would be valuable.
- Privacy Controls - For sensitive projects, a filtering mechanism to control what information is shared with the LLM would enhance security.
- Machine-Readable Output Format - While JSON is a good start, a more strictly defined schema would enable programmatic processing of threads, potentially allowing for automated analysis or integration with other development tools.
Claude 3.7 Sonnet