Frame Syntax
by Paweł Pieciukiewicz
← Notes

A Generated Trip to Öland — Building a Photographer's Guide with an AI Agent

AItravel guideÖlandphotographyCursor

Öland, mid-May, four days, GDN–VXO flight, a rental car, and intensive island touring. That was the initial trip plan — but what next?

I had only just heard of Öland. A quick Google Maps browse showed a long, narrow island with lighthouses, a bird reserve, and a crooked forest. That is not enough — you need research, or a guide.

I do not like classic travel guides. They always focus on lists of monuments, churches, and stock tourist attractions, plus a strange, selective pick of places to stay and eat.

Since I build software for a living, I thought: if I am clicking through pages anyway while planning a trip, why not vibecode the process — describe the requirements once and let an agent that can read the web and write files do the rest? Vibecoding here means exactly that: I state the intent, AI generates the project structure and content, I verify the output. A guide is text after all; LLMs generate text, and the knowledge needed to outline such a guide is publicly available.

The result of the first attempt: a 300-page PDF I no longer use — and a second system, described below and published on GitHub.

I am including a few photos in this post — they illustrate places I found thanks to the first version of the guide.

Goal and first approach

Goal: produce a digest of information about Öland tailored to what interests me, then review it, pick specific places, and read about them in primary sources.

At first glance it looks simple — spin up a project in an IDE, chat with an LLM about configuration, define the framework, requirements, and done. Maybe not a professional setup with an agent network, CLI, and full magical infrastructure, but a quick-and-dirty project.

The first version lived in a separate repository. Without going too deep into details, the basic workflow looked roughly like this:

**Stage Summary:**

1. **Stage -1: Guide Type Selection** — Declare guide type: NATURE, SIGHTSEEING, or CULTURE *(mandatory first step)*

2. **Stage 0: Tier Selection** — User selects workflow mode (S/M/E/L) based on region size and expertise

3. **Stage 1: Plan Creation** — Create coverage plan (broad or detailed, tier-dependent)

4. **Stage 2: Challenge Loop** — Iterate to fill gaps (intensity tier-dependent)

5. **Stage 3: Checklist Generation** — Convert plan to executable tasks

6. **Stage 4: Task Execution** — User-controlled file creation

7. **Stage 5: Review & Repair** — Final audit and fixes

**Tier Quick Reference:**

- **S (Speed):** <10 locations, skip broad research, 4-8h total

- **M (Discovery):** 10-25 locations, default workflow, 12-24h total

- **E (Expert):** User provides list, AI structures, 8-16h total

- **L (Deep):** >25 locations, multi-LLM challenge, 40-80h total

Those configuration files alone required context windows of 4,000–64,000 tokens, which translates into real money on every query. But fine, I thought… I built the guide; let’s see…

Rune stone at Eriksöre

Rune stone at Eriksöre

Nikon Z6 II, Nikkor Z 85 mm f/1.8 @ f/1.8, 1/6400 s. Rune stones are a treat for anyone hunting historical traces — building a guide for a history audience should come down to pointing at individual objects like this, not generic attractions.

Results (first iteration)

My requirements were fairly straightforward:

  • A guide with a strong photography focus
  • Natural, cultural, and sightseeing attractions
  • National parks, landscape parks, and reserves described in depth
  • Which plants and animals occur on the island (and where)
  • A nature calendar
  • Parking locations
  • Species names in Polish, Latin, and English
  • Online sources showcasing given places (local photographers, their portfolios, etc.)
  • Animal photos (where available under open licences)
  • And similar items
  • Output in PDF and MOBI

As it turned out, generating such a guide took a long time and instantly burned through the token quota, even though I avoided premium models — not to mention how many resources the project setup itself consumed. A single query with Claude Opus could eat 25% of the weekly limit. I also once tried a pay-as-you-go model — fortunately I only had $5 available, which was not enough to complete even one prompt.

The finished PDF ran to about 300 pages. It was incredibly useful for shaping the travel plan, but had major flaws, and I will definitely not use that project again.

My personal impressions after building that monster:

  • tables everywhere — wide species and topic lists
  • useful information on peak seasonality for certain animals and plants
  • a completely unreliable coordinate layer — the LLM hallucinates wildly here
  • an overwhelming amount of information, though in fairness that is what I asked for
  • a heavy, resource-hungry build process tied to poor project configuration
Lofta kustväg — stone cairns

Lofta kustväg — stone cairns

Nikon Z6 II, Nikkor Z 100–400 mm f/4.5–5.6 VR S @ f/5.6, 280 mm, 1/2000 s. A curious spot right next to a quarry — people drive here in droves to stack tall cairns from stones. Blå Jungfrun island in the background.

Rebuilding the guide

I visited the island in May. Here I focus on the tool I built after the trip and want to refine for future journeys.

Above all, I do not want one enormous output file — small thematic guides that are easy to absorb. Merging them into a whole is a separate problem for later; I can always add a merge step.

Orchids and windmills on the fields of Öland

Orchids and windmills

Nikon Z6 II, Nikkor Z 14–30 mm f/4 S @ f/10, 19 mm, 1/640 s. The first version of the guide decided to focus on these — rightly so: orchids bloom in mid-May, and there are windmills everywhere.

Single orchid on an Öland meadow

Orchid

Nikon Z6 II, Nikkor Z 85 mm f/1.8 @ f/1.8, 1/8000 s. A single flower from the fields of Öland — in mid-May one of the island's most photogenic landscape motifs.

MLP

In IT we have MVP — Minimum Viable Product. I talk about MLP — Minimum Likable Product: a baseline version of something you actually want to use, not just something that “works”.

How do you find the right granularity? I do not know, but I assume a single guide should match one narrow topic — usually a photography genre, e.g.:

  • Urbex
  • Wildlife
  • Macro
  • Travel
  • Street
  • Landscape
  • etc.

So a guide for a street photographer, a macro photographer, and so on. In the repository, one such guide is a topic: region + audience, e.g. olands_island_landscape. The same mechanism works outside photography — you can define an audience with any interests (or rather, any reader profile).

Hypothesis: a narrow topic (landscape or history) also narrows the sources the AI must search, so less noise and less encyclopaedia at once — even if token usage does not drop dramatically. I will not measure it; I will judge by feel.

The project currently supports guides for two audiences: landscape (including seascape, etc.) and history — traces of ancient cultures and traditions. The rest of the list (wildlife, macro…) I deliberately defer; some first-iteration requirements (nature calendar, MOBI) are not included either.

Stack

There are many environments for a project like this; I chose Cursor because I am evaluating its capabilities myself.

Second assumption: automatic model selection; premium models only when Auto gives weak results.

Third: guides must work with Obsidian — plain Markdown with [[wikilink]] links, no closed format.

Fourth: the agent has persistent rules in the repository (AGENTS.md, runbook in docs/) so I do not repeat every session that we are building a travel guide, not a blog post.

Method

Another hypothesis: even though I use developer tools, a project like this can be designed and run by someone outside IT — provided they have the patience to talk to an agent and verify files. You will need Python, a terminal, and an agent environment (e.g. Cursor), so a little technical literacy helps.

Almost all work inside the project is done by AI. I intervene in content requirements, approve the site list, check coordinates, and occasionally run premium models (e.g. Gemini) to validate consistency.

I issue commands in English; guide content is in English too. Separately I define an auxiliary language (Polish in my case) — e.g. species names in Polish and Latin alongside English in the reader-facing text.

Finished guides stay local on disk (topics/ is in .gitignore) — research does not land on GitHub automatically unless you publish it yourself.

Twisted oaks in Trollskogen forest

Trollskogen

Nikon Z6 II, Nikkor Z 85 mm f/1.8 @ f/1.8, 1/400 s. A forest where gnarled oaks look like works of art — exactly the kind of place that made it into the landscape guide.

Stage 1 — setup

Project definition and setup are a critical stage. A thoughtful concept from the start beats patching a poorly defined project.

I started with a project description and collaborative work with an LLM in agent mode on file structure. I am not pasting the whole conversation here, but the idea is:

I wanted the AI to know from the outset that it is creating a travel guide, not an encyclopaedia or a blog post. A specific reader profile — e.g. landscape photographer — I define separately in audience files (the audiences/ directory in the repository), instead of typing it ad hoc in every chat.

I described the concept, goals, output artifacts, and we agreed on directory structure. The agent walks me through the process, but LLMs tend to confabulate — you must verify files and push back.

The project is built on audiences with requirement inheritance. The first usable setup has three levels:

  • Photographer (root) — technical requirements (PDF, CSV map) and general content requirements shared by guides in this branch.
  • Landscape photographer — inherits from the Photographer audience; adds sunset potential assessment, parking, local photographers’ portfolios, and more.
  • History and culture enthusiast — a separate audience for content (runes, burial sites, UNESCO, forts); inherits format and technical rules from the Photographer root.

The same system can extend beyond photography — different audience definitions suffice, without touching Python code (I treat audience definitions as configuration code).

Three phases instead of one prompt

The second version is not a “shorter prompt” but a three-phase process — the main difference from the first iteration:

PhaseWhat it doesOutput
1 — DiscoveryBroad regional research, candidate listsite_list.md — where I decide what we cover at all
2 — Deep divePer-site research with sourcesFiles _ai/research/<site>.md
3 — CompileAssembling reader-facing textMarkdown notes, index.md, optional PDF

Discovery and an approved site list first — only then deep research per location, then the guide. That limits scope, splits context into smaller chunks, and adds human gates: I approve the list, I review the PDF.

Stage 2 — first run

I had a system but did not know if it worked. I asked AI to generate guides, reviewed, gave feedback, ran again — in a loop.

Errors on the first run:

  • Images: AI verified that photos “exist on the internet”, created folders, and marked the topic complete. Only after tightening the audience spec: concrete URLs, CC licences, files on disk with an attribution table.
  • Rune stones: For the history audience, AI found generic attractions but did not search for individual objects. After feedback it wanted to add “rune stones” to the general historian audience — too abstract.

Stage 3 — evolution (map, export)

AI-generated guides are not typographically beautiful, but they are already usable. I had forgotten an in-the-field map.

You can add a map to the PDF, but I prefer Google My Maps on my phone — hence CSV export. I wrote to the agent roughly:

Rebuild the setup to also support creation of csv file which will contain coordinates and names of sites with their short descriptions.

The format must fit to the way how I can import it to mymaps.google.com. Focus also on categorizing the data in the way that I can assign icons to them or import as a layer. The output must be a single csv file.

First do changes in the setup, then based on already existing oland guides create files in respective projects.

CSV imports into My Maps; a layer column lets you assign icons (lighthouses, graves, alvar, etc.). Coordinates come from research sources or a fallbacks file — not from the model’s head. That is a direct answer to first-iteration hallucinations.

Medieval granite church in Källa

Church in Källa

Nikon Z6 II, Nikkor Z 14–30 mm f/4 S @ f/11, 30 mm, 1/1000 s. A medieval granite church — the kind of object a history audience should describe with context and source-verified coordinates, not from an LLM.

Results (second iteration)

Two thematic guides were produced for Öland:

TopicAudienceSites
Landscapelandscape photographer22
Historyhistory and culture enthusiast24 (including rune stone clusters)

That is still a fair number of pages combined, but not a 300-page monolith — each topic is a separate Markdown folder with index.md and links between notes.

Deliverables:

  • Obsidian-compatible notes in topics/<topic>/
  • PDF (guide.pdf) — Pandoc + headless Chrome/Edge
  • CSV for My Maps (guide_map.csv) — layers for icons
  • selected CC-licensed photos with attribution, where they could be downloaded legally

Still weak:

  • not every pin has perfect coordinates — some are parking-lot points from the fallbacks file, not the centre of the object
  • CC photos could not be fetched everywhere
  • the PDF is readable but not “book-quality” in layout

Some first-version requirements (full nature calendar, MOBI, species encyclopaedia) were deliberately dropped because I have not built a nature audience yet.

Takeaways

  1. Setup is expensive — a well-designed structure pays off on the second trip.
  2. Never trust coordinates from an LLM — sources and manual verification only.
  3. Smaller artifacts yield better accuracy.
  4. Audience definitions are code — you change them like config, not like chat.
  5. Human gates (site_list, pre-trip PDF review, in-the-field sanity check) are part of the system, not a failure of automation.

What now?

If you want to try it yourself — clone the repository:

github.com/pieciuk-dev/guide-generator

Read Getting started and go.

Note: you bear the cost of AI tokens and the consequences of running an LLM in agent mode on your own machine. You will need Python 3.10+ and a few optional tools (Pandoc, Chrome/Edge for PDF). If you can install software, an agent in Cursor will usually walk you through the rest of the setup.

Cursor requires registration and most likely a paid licence. Another environment with an agent that reads files and the terminal will work too — the project rules are not tied exclusively to Cursor.

In the field, always verify on site: opening hours, fees, reserve regulations. A guide is a starting point, not a guarantee.

If you want to contribute, create new audiences, or use the system for your own trip — go ahead. The project is open; interesting changes are welcome as PRs to main.