I tested GitHub Copilot agent mode in July 2025, setting Copilot to work online on different sized features - the workflow looks like this:
Some stats:
For example, I tasked Copilot with refactoring 3 instances of near-duplicate code into a common service and make some improvements to error handling on the refactored service. My experience of code review from the last 4 years definitely helps with this workflow - reviewing code from an agent is similar to reviewing colleagues' code except that I don't feel guilty about leaving a PR unread for more than a day. Those PRs still become stale however and merge conflicts are a pain if the agent changes overlap with other PRs.
One challenge is that this makes it very easy to set Copilot working on easy to define low-impact work but that work still takes to review. It would be easy to get into the habit of doing lots of unimportant busy work with this workflow. I now want to explore how to use coding agents to achieve more ambitious changes, perhaps changes I would not take on individually because they lie near the limits of my current knowledge.
There's a memory game "In my bag..." where you pretend you have a list of things in your bag "In my bag I have a comb and a cat". The next person in the circle has to list all the same things and add one more at the end "In my bag I have a comb, a cat and a clock". The game ends when someone makes a mistake or gives up.
It occurred to me that this is a great analogy for the templates used in LLM chatbots! Every time you chat with an LLM the LLM re-reads the whole history of the conversation before responding. This is why they get slower over time, particularly if they are making web searches, viewing images, using MCPs or other tools which add a lot of hidden tokens to the chat history.
The ollama docs describe a simple template here ... https://github.com/ollama/ollama/blob/main/docs/template.md
My talk from DjangoCon Europe 2025 - I discuss:
There's an old European folk tale of a man going into a village and asking for a pot and some water so he can make stone soup. Intrigued, the villagers give him a pot and some water and he boils it up. After a while he tastes it and says "not bad but it could use some onion - do you have some leftovers". The villagers give him a bit of onion and a few herbs whilst they are at it. It carries on like this until he has a delicious soup and the villagers are amazed that he did all that with just a pot of water and a stone.
I love Copilot, Claude and all the good things but the iterations of GitHub issues, suggested actions, debugging and fixing in the newer tool previews often taste suspiciously like stone soup 😅 🪨🍲 .
Reading into this issue on Django-waffle
I learned that Django uses pickle to store objects in its cache but does not guarantee that these objects
will remain valid between versions, so it raises a RuntimeWarning
when you access potentially stale objects.
The Django docs recommend clearing the cache on upgrade, and this Stackoverflow post discusses ways of doing that.
A pattern I enjoy with Copilot or other AI coding tools is something I'm calling "Language bridging":
Language bridging : Write code to solve a problem in a language you know well, then use an AI to translate the code into the language you want or need to use.
Read Full Post
There's this myth we tell ourselves about "Real developers" and especially "this is why I am not a Real developer". It got me thinking - is there actually a useful definition out there?
Here is my best try:
*A 'Real Developer' is someone who writes code or other instructions for a computer which run successfully and get something useful or delightful done in the real world
Read Full Post
Looking back on 2024 here are some personal highlights:
Early in 2024 I took over maintenance of the very useful Python package pye57 for
reading and writing e57 format pointcloud files. I have been using it at work for several years and was
worried that it was not being maintained, blocking upgrade of our project to Python 3.11.
I had already started working on an alternative library, cleverly titled e57
- essentially I got in touch with
the project maintainer, providing some evidence that I was a real human being not a sham account,
many thanks to David Caron for creating the library and maintaining it for so many years, and for trusting
me to carry it on.
Read Full Post
See the xml portion from the end of an .e57
pointcloud file. This contains information like the bounding box of the
pointcloud, the number of points and how the points and other information are organised in the file.
I wrote it with a bit of help from Claude ai by describing what I wanted and pasting a description of the e57 file format before doing a lot of debugging to get the entire xml section and then integrating it with my blog.
I find the e57 file format a bit wierd - it starts with a header including a file version number and an offset to the XML portion, which comes at the end of the file so you need to read both ends of the file before you can understand the middle bit. So if you download the file you have to wait for it to finish downloading - you can't start to interpret or display the points and other data whilst streaming data.
This tool is written in JavaScript and runs in your browser - no files are uploaded to any server (in fact this blog has no backend server - it is a static web site - it is downloaded and runs entirely in your browser).
My version of YAGNI - "You Ain't Gonna Need It" - is a rule of three: only spend time refactoring your code when you have repeated yourself 3 times. Don't aim for truly DRY code devoid of all repetition.
I'm not saying not to apply SOLID design principles from the start - I definitely try to separate concerns, giving a single responsibility to a class or function and avoid, for instance, a single method handling file reading, data transformation and reporting. This simplicity will make it much easier to refactor the code later.
I am saying to avoid using sophisticated design patterns, architecture or abstractions before you have used of your code enough to know what is likely to change (and require encapsulation) and what will stay constant (creating a useful abstraction).
Read Full Post