Building AI Agents That Write Content for Your Site
2026-07-21
My site tracks movies, shows, and games with ratings, posters, score badges, trailer links, and personal reviews. That's a lot of metadata per entry. Entering it all by hand is tedious. So I built an AI agent to do it for me.
Here's how it works and how you can build similar agents for your own projects.

The problem
Every review entry needs:
- Frontmatter (title, year, poster, genre, status, date)
- External IDs (TMDB, IMDb, Steam) for auto-fetched scores and metadata
- Score badges (IMDb, Rotten Tomatoes, Metacritic) with clickable links
- A trailer link from YouTube
- A personal review written in a consistent voice
That's roughly 15 data points per entry. Doing that manually for 50+ entries isn't fun. And maintaining it — updating scores when a movie's ratings change, or fixing broken poster URLs — is worse.
The solution: an agent workflow
I use opencode with a custom agent file that follows a 7-phase workflow:
- Existing file check — skip research if the
.mdxfile already exists - Research — web search for release year, poster, trailer, synopsis
- Confirmation — show me the URLs and description, ask if it matches
- Opinion gathering — ask 2-3 pointed questions about what I liked/disliked
- Write — generate the
.mdxfile with frontmatter and personal review - Polish — verify frontmatter fields, trim review text
- Verify — run
npx playwright test && npm run build
The key insight is that the agent isn't guessing — it's gathering real data from the web, confirming with me before writing, and then asking for my actual opinions rather than fabricating them.
Architecture
The review system uses file-based MDX storage, not a database. Each review is a .mdx file in content/reviews/{movies,shows,games}/:
---
title: The Dark Knight
year: 2008
rating: 9.5
status: watched
poster: https://...
date: 2026-07-17
tmdbId: 155
imdbId: tt0468569
rtUrl: https://www.rottentomatoes.com/m/the_dark_knight
metacriticUrl: https://www.metacritic.com/movie/the-dark-knight/
---
My take: Nolan crafted a superhero film that transcends the genre. Ledger's Joker is genuinely unsettling.Why file-based? Three reasons:
- Data survival — a corrupt SQLite file loses everything. MDX files are just text files tracked in git.
- Git history — every review has a full revision history. Rollback is
git revert. - Agent-friendly — agents create files. Creating
.mdxfiles is trivial for an AI coding assistant. Writing to a database requires tooling.
Build-time data fetching
Scores and metadata are auto-fetched at build time, not stored in frontmatter:
- OMDb API (
imdbId) — IMDb rating, RT score, Metacritic score, plot, director, runtime, MPAA rating - TMDB API (
tmdbId) — official trailer URL - Steam Store API (
steamId) — game description, developer, publisher, Metacritic score
The agent only needs to store the external IDs. Everything else resolves at build time. Results are cached in git-tracked JSON files (content/scores.json, content/tmdb-cache.json, content/steam-cache.json) and refreshed weekly via a GitHub Action.
The agent file itself
The agent instructions live in code-tools/review-agent.md. They get auto-loaded when I say "Create a review for {title}" thanks to behavioral triggers in the project's AGENTS.md:
| User says... | Agent file loaded |
|--------------------------------------|---------------------------|
| "Create a review for `{movie/show/game}`" | review-agent.md |
| "Create a blog post about `{topic}`" | blog-agent.md |
| "Create a branch / commit / push" | sourcecontrol.md |
This means the right instructions are always available without me thinking about it.
Key design patterns for your own agents
If you want to build similar agents for your codebase, here's what worked:
1. Be specific about file paths
Agents need to know exactly where files go. My agent doc includes the full directory structure:
| movie | `content/reviews/movies/` |
| show | `content/reviews/shows/` |
| game | `content/reviews/games/` |Without explicit paths, agents guess — and often guess wrong.
2. Include real examples
The agent doc has 7 complete frontmatter examples covering every combination (movie/show/game, full review/planned/watching). The agent mirrors the pattern that's closest to the current task.
3. Add confirmation gates at every decision point
My agent asks before:
- Researching (saves time if I already have the details)
- Writing (confirms it found the right title)
- Finalizing (lets me request edits)
Each gate is a simple yes/no in the terminal. It prevents the agent from wasting time on wrong assumptions.
4. Use build-time APIs for metadata
Storing scores and plot synopses in frontmatter is redundant and fragile. External APIs change, scores update, posters get replaced. By fetching at build time from canonical sources (OMDb, TMDB, Steam), the data is always fresh with zero agent effort.
The caches mean the same data isn't re-fetched on every build — only when the cache is stale (weekly cron) or when a new entry is added.
5. Include a verification step
Every agent workflow ends with running the test suite and a full build. This catches bad frontmatter, broken URLs, and rendering issues before they go live.
npx playwright test && npm run build6. Mirror existing patterns
My review-agent.md mirrors blog-agent.md — same structure (research → write → polish → verify), same conventions. This reduces cognitive load for both me and the agent. Once the pattern is established, adding a new agent type is mostly copy-paste.
7. Track opinions, don't generate them
The most important phase of my review agent is step 1.75: Opinion Gathering. The agent asks me 2-3 questions about what I thought of the movie before writing. It weaves my answers into the review rather than inventing a generic take.
This is the difference between a review that sounds like me and generic AI slop.
The result
The system works. Creating a new review takes about 3 minutes of interaction: confirm the title, answer a few questions, approve the draft. The agent handles research, file creation, metadata resolution, and verification.
And the architecture is resilient. If the Docker container dies, the SQLite database gets corrupted, or I accidentally delete node_modules, the review data is safe in git. Each .mdx file is a self-contained piece of content that can be edited, reviewed, and deployed independently.
Try it
If you're using opencode or a similar AI coding assistant, building custom agents is one of the most productive things you can do. Start with a single code-tools/ file that describes one workflow — like creating a review or a blog post. Define the file paths, include real frontmatter examples, add confirmation gates, and end with a verification step.
Iterate until the output is reliable, then rinse and repeat for the next workflow. The pattern scales: once you have a blog agent and a review agent, adding a "create a project showcase" agent is mostly copying the structure and changing the content type.