Teaching Claude to add lenses
Every lens in the L-Mount lens table used to be added by hand. All of it: find the manufacturer’s spec sheet, pick out the weight and dimensions for the right mount, type the numbers into a YAML file, hunt down the launch price and release year, download a product photo, cut it out, convert it to a transparent PNG at the right size, put everything into the right folders, and check that nothing broke. Maybe twenty minutes per lens on a good day. There are over 170 lenses in the table now.
This week a new lens went in: the 7Artisans AF 40mm f/2.5. My part consisted of pasting a link and answering one question about whether a 90-gram lens counts as a pancake. (It does.) The rest happened on its own, and correctly. Getting from there to here was very informative for me because the interesting part is not “AI did it”. The interesting part is what it took to make AI do it reliably.
The manual years were not wasted
I want to defend the tedious phase first, because it’s tempting to see it as time I should have automated away sooner.
Doing everything by hand is why the site is structured the way it is. Every lens is a plain Markdown file with YAML frontmatter, readable and editable in any text editor, versioning (and diffable) in git, fixable in thirty seconds when e.g. a price turns out to be wrong. There is no database, no admin interface, no vendor. When you type weight: 670 into a file a few hundred times, you develop opinions: grams always rounded to whole numbers; f-stops written f/1.4, never F1.4; a slug format you can predict without looking it up. Those opinions hardened into conventions, and the conventions are what made everything that follows possible. At the same time, had I started with a “proper” database, I would have had to make many choices about formats and conventions without really having formed a proper opinion yet. Plus, I wanted to keep this whole site a static, fully self-contained and fast website with no external dependencies.
In short: if I had started with automation, I would have automated a mess.
AI, first attempt: not good
When I first tried to hand the job to AI, the results were unreliable in a particular, insidious way. The obvious things worked. Of course a large-language model like ChatGPT or Claude can read a product page and produce YAML. The problem was everything underneath: a weight quoted for the Sony E-mount version instead of the L-Mount one (they often differ, and press coverage almost always quotes the Sony numbers). A magnification ratio that the manufacturers often do not publish, filled in anyway because it looked plausible. Formats drifting (F2.8 here, f/2.8 there), a filter size as a string instead of a number.
None of these mistakes are dramatic. All of them are poison for a “database” whose whole point is that you can sort 160 lenses by a column and trust the comparison. A wrong number that looks right is worse than no number at all.
What actually worked: writing it down
The fix wasn’t a better prompt. It was sitting down with Claude and building what Claude Code calls a skill. It sounds fancier than it is. A skill is a folder in the repository containing instructions and tools: a Markdown file that explains the job, a schema document that defines every field with its type and unit, and a couple of small Python scripts.
We wrote it together, iteratively. I explained the conventions, Claude drafted the skill files, and each mistake in practice became a new rule in the instructions. This is what the flow looks like today:
The division of labor that emerged is the part I find genuinely interesting:
Everything that must never drift became a script. A scaffolding script builds the entry file and refuses to run if any required field is missing. It will not guess. A validator checks every entry against the schema: enums for brands and categories, metric units only, the image present and named correctly. Deterministic code, no model judgment involved.
Everything that needs judgment became a written rule. “Never invent a number — if a spec can’t be found, leave the field empty or ask.” “Multi-mount lenses: take the L-Mount figures from the per-mount chart, not the press release.” “Magnification is often unpublished — keep the key, leave the value empty, never estimate.” These read like notes to a new assistant, because that is exactly what they are. Every one of them exists because of a mistake made at some point.
Everything cheap got delegated. Scraping a spec sheet doesn’t need a big model, so the skill sends a smaller one to fetch pages and search for reviews. The results come back and get verified. Every review link is checked before it lands in the entry, because a search agent will occasionally attribute a YouTube review to the wrong channel with total confidence.
The pattern here is this: AI didn’t replace the manual process, it absorbed it. Everything I learned in the beginning had to be written down, had to settle, before the automation made send and deserved trust. The skill is essentially my accumulated experience, made executable. The second key learning was validation: it creates an iterative loop that makes it easier for the agent to converge on a desired, correct end result.
What’s left for me
The pleasant surprise is what my job has become: taste and judgment. Is this lens a pancake? Does a news article count as a review or is it just regurgitating a press release? Is the launch price the pre-order price or the street price?
And each entry still ends the same way it always has: the validator runs, the site builds, and I read the page before it goes live. Simple plain text files, checked into git. Here is the 40mm’s raw file as an example.
As I keep pointing out: this site has no tracking, no cookies, no referral links, no commercial interest. I am doing this because I want it for myself and it’s fun. And the reason it is fun is because I am learning new things all the time.
If curiosity killed the cat, I, apparently, am fueled by dead cats.
Featured image: the L-Mount system lineup, courtesy of l-mount.com.