AI agent building a Shopify product page draft for a human to review

At 1 pm every weekday, an agent named Leo reads the receiving report out of our inventory system, matches it against a spreadsheet, and starts building Shopify product pages. It writes the copy, pulls and resizes the images, sets the price, the tags, the collections, the weight, the SEO fields, and the sales channels. Then it stops and leaves the whole thing sitting in draft.

Leo is our AI agent for Shopify product pages, and it has never published a new one. Not once in almost three months. That part belongs to a person, and it always will.

I built Leo myself, which is the part I still find funny, because I had not built a product page by hand in six or seven years. This is the full breakdown of that build. How I figured out the process I was replacing, what the agent reads before it acts, what it writes, what it is forbidden to touch, and the order I would do it in if I were starting from nothing today. If you want to build one at your own store, almost all of this transfers.

Key takeaways

  • The first step was not building anything. It was a temporary Slack channel with every person who touched a product listing, and a lot of questions.

  • The model read that transcript and proposed a leaner process. Everyone signed off on the proposal, and that document became the spec for the build.

  • The daily build runs on a schedule. There is no chat window for it and nobody has to remember it.

  • Every new product it builds lands in draft. A human reviews the draft and flips it live, every single time.

  • A second task exists to read what the team says back. It runs nine times a business day, and 81 percent of those runs end in silence.

  • The instructions live in four separate kinds of file: the procedure, the contract, the memory, and the credentials. Keeping them apart is most of why this thing still works.

  • The two ugliest bugs both came from trusting something a platform reported about itself. Neither one was a copywriting problem.

  • There is no recurring bill on it, which is the reason a job this small was worth automating at all.

What does the agent actually do every day?

It turns a receiving event into a finished draft product page without anyone asking it to.

Here is the loop in order. Our warehouse receives an inbound purchase order into our inventory system. The next day at 1 pm, the agent pulls the receiving report, cross-references it against the product page tracking tab in a shared Google Sheet, and ticks the box that says the inventory is physically here. In the same run, it looks at every row where the inventory is in and no draft exists yet, and it builds those.

For each one, it scrapes the vendor's product page, writes three paragraphs of body copy plus a specification block, processes the photos to a consistent size, creates the product in Shopify as a draft, attaches everything, and writes the draft link back into the spreadsheet so the team can find it. Then it posts a short summary in one Slack channel: here is what got built, here is what got sent back for missing information, here is what came into the warehouse today.

Our Shopify QA lead opens the drafts, fixes whatever needs fixing, and publishes. The agent notices the next day that the listing went live and quietly updates the sheet. Nobody tells it.

What was the actual first step?

A temporary Slack channel containing every person and every department that touched a product listing, and a long run of questions I probably should have known the answers to already.

Six or seven years out of practice, I knew what a finished page was supposed to look like, and I had close to no idea how one actually got made. Who kicks it off. Who is waiting on whom. What happens when the vendor sends the wrong photos. Where it sits for three days doing nothing. The people doing the work knew all of that, and none of it existed anywhere except in their heads.

I asked, at length. For a stretch of days that channel was nothing but me getting people to explain their piece in more detail than felt necessary, including the exceptions and the "sometimes we do this instead" steps that never make it into a written process. The answers did not always agree with each other, which turned out to be the useful part. Two people describing the same handoff differently is how you find the seam.

Then I handed the whole transcript to the model and asked it for the process as it actually ran, plus a proposed version with fewer people in the chain and as much as possible absorbed by an automation. We circulated that proposal, everybody in the channel signed off, and it became the spec for the entire build.

I want to be clear about why it happened in that order. The person who understands a process least is a bad choice to design its replacement, and on this one that person was me. Letting the model produce the map from the interviews meant the new process came from what the team actually said, rather than from what I assumed they did.

The chain has kept getting shorter since. Four days after the agent's first run, the tail of the flow lost two more people, and one of them removed himself: our COO looked at the handoff where he manually connected each new draft to inventory and said that as long as the agent writes the SKU correctly, the nightly sync would do it on its own and he did not need to be there at all.

How do you teach it your voice?

Write down what a good product page at your store already looks like, before you go anywhere near the copy generation.

The first artifact after the process document was a style guide, and I did not write it from taste. Our QA lead handed me nine live product pages the team considered correct. I had the model read all nine and tell me what they had in common, and it came back with things I would never have articulated on my own. Our copy opens with a verb-led command. It name-drops the material and then explains why the material matters instead of just listing it. It puts informal slang in quotation marks once per description to sound field-tested. It closes by positioning the product in a category rather than asking for the sale.

That document became the contract. Every sentence the agent writes gets measured against it, and when a page comes out wrong, the fix is usually a line added to the style guide rather than a change to the agent.

Doing it in this order matters more than it sounds like it should. Skip the style guide, and you have handed your product pages to a model's default voice and given yourself a new editing job. Baymard Institute's benchmark data found that 10 percent of the largest e-commerce sites fail to keep a consistently high level of detail in their product descriptions, and a generated description that reads fine and says nothing lands in exactly that bucket.

What files does the agent read before it does anything?

Ten of them, in a fixed order, every single run. If any one of them fails to load, the agent stops and messages me instead of continuing.

Those ten files break into four kinds, and the separation is the piece I would carry into any other build:

  • The procedure. One playbook per scheduled task, written as numbered steps. This is the file that changes constantly, because every decision we make gets added to it with the name of the person who made the call and the date they made it.

  • The contract. The style guide, the map of which spreadsheet column feeds which Shopify field, and a document of everything we have learned about how our inventory system's API actually behaves. These change slowly and on purpose.

  • The memory. A state file with what is currently open, plus the reference files the agent maintains for itself: the team directory, the collection map, the webhook it posts through, the write-back contract. Alongside those, it keeps an append-only journal it writes to but never reads back at the start of a run. The state file holds the status, and the journal holds the record, and they never contain the same sentence twice.

  • The credentials. One folder, treated like a password, never pasted anywhere.

The prompt attached to the scheduled task is deliberately short and almost never changes. It says who the agent is, which files to read, and a handful of rules that must survive even if a file goes missing. When something needs to change, we change the playbook and leave the prompt alone. A short stable prompt pointing at a long living document is a much better shape than one enormous prompt you are afraid to touch.

How does the agent know which products to build?

From a Google Sheet the team was already filling out, filtered by a hard definition of what makes a row ready.

The tracking tab runs more than 40 columns in color-coded groups: workflow status, product identity, sourcing, pricing, physical dimensions, merchandising, flags, and the automation fields the agent writes back into. Procurement fills in the identity and sourcing columns when they place the order. Everything downstream of that is either automatic or a human ticking a box.

A row is ready to build only when all of these are true: the item was ordered, the inventory has been received, no draft exists yet, and the name, SKU, cost, and site price are populated, along with either a vendor URL or a manual description plus a folder of warehouse photos. Miss any one of those and the agent does not guess. It writes the reason into a Blocked Reason column, moves on to the next row, and mentions it in the daily summary so the person who owns that field can fix it.

One field is deliberately not part of the gate. Weight usually gets captured at receiving, often after the agent has already built the draft, so requiring it up front would stall good rows for no reason. Weight is required before the listing goes live, not before the draft exists. Knowing the difference between those two things is worth a lot.

The bigger thing this design buys you is adoption. The agent reads a queue your team already maintains as part of their normal job, in a tool they already have open, which means nobody has to change their day to feed it.

What does the agent actually fill in on a product page?

It fills in everything except the decision to publish: title, handle, three paragraphs of body copy, a specification list, eight to ten images for most products at a fixed size, tags, collections, a taxonomy category, cost, price, weight in ounces, SEO title and description, and a handful of metafields our warehouse and marketplace tools read.

Two rules sitting behind that list are where the quality actually comes from.

The first is that the agent may not write a specification it did not find. A separate script scrapes the vendor page and extracts structured specification pairs three different ways: HTML tables, definition lists, and plain uppercase key-value text. Only those extracted pairs get handed to the model, along with an instruction to use only those pairs and invent nothing. If the extraction comes back thin on a knife or an axe, where a customer genuinely needs blade steel and blade length before they will buy, the run switches to a browser and tries again. Still thin, and the row gets blocked for a human to source the numbers. We would rather ship no listing than a confident one with a made-up blade length in it.

The second is that materials come from our own procurement records, never the vendor's marketing copy. If the vendor's page says silicone and our intake paperwork says flexible TPE, the page says flexible TPE. Vendor sites are marketing documents. Treating them as a source of truth is how a return request eventually starts with "your website said."

What is the agent never allowed to do?

Five things, written at the top of the instructions in language that leaves no room for interpretation. Rule one is that every product it creates must be a draft, never active.

The other four: it may never delete a product, a collection, a metafield, or a theme file. It may never write to any tab of that spreadsheet except the one. It may never post publicly except through one specific Slack webhook. It has exactly one mechanism for writing back to the sheet, and every other write path is closed.

The draft rule is the one that makes the rest of it safe. Shopify's own product status model gives you draft as a first-class state, so there is no reason to write anything live from an automation. A draft that is wrong costs somebody five minutes. A live page that is wrong costs you a customer and possibly a chargeback.

Archiving replaced deleting for the same reason. When we retire a product, the agent sets it to archived and leaves the SKU in place, because an archived listing can be brought back and a deleted one cannot. That rule came directly from our COO, whose actual concern was the nightly inventory sync: keep the SKU intact and the connection survives.

There is exactly one exception to the draft rule, and it is worth naming because it proves the rule. A separate weekly task of Leo's looks for products we archived that have since been restocked, and it is allowed to flip those back to active without a human. That authority took a specific conversation to grant. Un-archiving something that was already live once is a recovery action, and the page it brings back is a page a person already approved. Nothing new reaches a customer without somebody looking at it first.

Which leads to my favorite small rule in the whole project. The agent may never change the case of a SKU. If the row says bbzipwht, Shopify gets bbzipwht, not BBZIPWHT. Our inventory sync matches on the SKU exactly, and a helpful-looking uppercase conversion makes the sync fail silently, and the listing shows zero stock. Nothing errors. Nothing alerts. The product just quietly stops being buyable.

What happens when the data the agent trusts is wrong?

It believes the data and fails quietly. Our two worst bugs both trace back to a platform reporting something untrue about itself, and the failures were silent in both cases.

The first was a field that lied. Shopify reports a count of how many sales channels are available for a product. About a month in, on a new build, the agent read that number, got a zero, concluded there was a permissions problem, and carefully skipped the step that attaches the product to our sales channels. Nothing was wrong with permissions. The count was a shop-level number that had nothing to do with the product in front of it. The product shipped attached to zero of two dozen channels and looked completely finished from the inside. I spent that evening backfilling all 24 by hand.

The rule that came out of it is now binding: verify by counting the actual list, never by reading the count, and run the attach step every time even if the number looks strange. The broader lesson is the one I still repeat. Careful and safe are two different things. A loud failure gets fixed in ten minutes. A quiet skip ships and looks fine until somebody notices.

The second was our inventory system freezing a URL. Its API exposes each product at a path built from the SKU, and that path is locked at creation. Edit a SKU later and the old path still answers while the new one returns a 404. Our weight lookups had been failing on exactly the products most likely to have been corrected at some point. The fix was to stop doing per-item lookups entirely and pull the whole catalog in a single call: 8,102 rows in about three seconds, matched in memory. Faster, and it cannot silently miss.

One more, smaller and stranger. Product photos with transparent backgrounds were coming out of the pipeline with black corners, because converting a transparent image straight to a flat format turns every transparent pixel black. The images looked perfect on the vendor's site and broken on ours. Now every image gets composited onto white first, and after the file is written, the pipeline reopens it and checks that all four corners are not pure black before anything gets uploaded.

The pattern across all three is the same. Every system you touch behaves slightly differently from how it describes itself, and an agent will take it at its word.

How does the agent report without becoming noise?

In one channel, with hard caps on length, and by staying silent on days when nothing changed. Getting there took a complaint from the team.

Leo got a personality early on, named after Leonardo DiCaprio, complete with film references. Everyone liked it for about two months. Then people started telling me the daily posts were long enough to cause a small spike of anxiety when they appeared, which is not what you want from an automation meant to reduce work. We wrote four rules and made them binding on every message the agent sends.

Personality is allowed only in banter, never in a functional post. One point per message, never a chain of "did this, checked that, also noticed a third thing." No unsolicited offers tacked onto the end of an answer about something else. Hard length caps by message type, with the daily build summary capped at ten lines including the bullets.

Recently our COO went one step further and asked whether the agent could skip its morning status post entirely on days when nothing had changed. That shipped the same day. It now hashes the content of the post, compares it against the last one it sent, and stays quiet if they match.

Every run still writes to its own log, including the silent ones. A quiet channel and a dead agent look identical from the outside, and the log is the only thing that tells them apart.

How does the agent handle what the team says back?

With a completely separate task whose only job is to read the replies, nine times a business day. It is the reason the build task gets to stay a build task.

The problem it solves was obvious before we hit it. The 1 pm summary posts what got built and asks the team to sort out anything blocked. People reply. Somebody fills in a spreadsheet column. Somebody asks a question in a thread. Without something listening, all of that sits there until a person goes looking, which means the agent is starting conversations it has no way to finish.

The listening task runs every hour from 9 am to 6 pm Eastern, skipping 1 pm on purpose. That hour belongs to the build, and two agents working the same data at the same time is a problem you only have to create once. Each run reads what changed since the last one, answers the questions it can answer out of its own files, acknowledges the ones it cannot, and messages me only when I am the only person who can unblock it.

It launched able to change nothing at all. Reply and report: that was the whole permission set, and it stayed there for weeks while we watched what people actually asked it for. Today it has two approved autonomous actions, each one scoped to a single named person. The useful one is a batch greenlight: our QA lead, who owns whether a launch is ready, can say the word in the channel and the batch gets built within the hour instead of waiting for the next 1 pm run. The 1 pm run still sweeps up anything that became ready afterward. Identical wording from anybody else gets a friendly acknowledgement and a message to me.

It also watches the build. On any weekday run from 2 pm onward, it checks whether the 1 pm job actually wrote anything, and tells me if it did not. That exists because the build once stalled silently for four hours, posted nothing, wrote nothing, and quietly recovered on its own at 5 pm. Nobody noticed, and the only reason it cost us nothing is that the queue happened to be empty that day. That was luck, not design.

Most of the time it says nothing. Across roughly 400 logged runs, 81 percent ended in complete silence in both places, and there are whole days where all nine runs are quiet. That is the correct behavior, and it is also why the run log matters.

My favorite thing it has done was refuse a job. Somebody flagged that three new products were missing a price field. The listening task checked, read-only, found the field was empty because the source column in the spreadsheet had never been filled in, answered in two sentences, and pointed the fix at the person who owns that column. It did not offer to fix it itself, because fixing it was not on its list. An agent that knows the edge of its own authority is worth more than one that guesses generously.

What does an AI agent for Shopify product pages cost to run?

Nothing recurring, and that is the entire reason it exists.

There is no per-agent license and no monthly software bill. It runs on the AI subscription we were already paying for. I want to be honest that free is not free: you pay in the time to build it, and you pay again the first time it breaks in a new way. That cost is real, and it is paid once.

The reason cost matters more than customization or speed is that a monthly fee changes which problems you are allowed to solve. When every automation carries a line item, you only automate problems big enough to justify one, and everything smaller stays broken forever. Product page creation at our volume is exactly that kind of problem. It was never painful enough on any single day to buy software for, and it was quietly costing us a listing here and a listing there for years. Zero marginal cost is why we run more than 60 agents today.

The closest thing to a hard return came from pointing the same logic at the catalog we already had. An audit of products that were hidden or excluded from the site while sitting in stock surfaced roughly $50,000 of product, at cost, that was in the building and not for sale anywhere. Already bought, already paid for, invisible.

How would you build this at your own store?

Start by interviewing the people who do the work today, and resist skipping straight to the agent. Here is the order I would follow.

  1. Map the process before you design anything. Put everyone who touches the job in one channel and ask them to overexplain their piece. Hand the transcript to the model, ask for the current process and a proposed leaner one, then get the people in that channel to sign off on the proposal. Their sign-off is what makes the new process theirs instead of yours.

  2. Write the style guide next. Pick your best five to ten product pages, have the model tell you what they have in common, correct it where it is wrong, and save that as a document. This is the asset, and the agent is only the thing that reads it.

  3. Make the queue somewhere your team already works. A spreadsheet with clear column groups beats a purpose-built tool nobody opens. Let people fill it in as part of the job they already do.

  4. Define ready as a checklist. Write down the exact fields that must be present. When one is missing, have the agent write the reason into a column and move on. Never let it guess a value to keep the run going.

  5. Split your instructions into procedure, contract, memory, and credentials. Keep the scheduled prompt short and pointed at the procedure. Change the procedure and leave the prompt alone.

  6. Give each system exactly one write path. Everything the agent can change in a given tool should go through a single mechanism you can audit, and every other connection into that tool stays read-only.

  7. Make every new listing a draft. No exceptions, no override flag. The human review step on anything that faces a customer for the first time is permanent, and there is no phase where you graduate out of it.

  8. Report in one channel, short. Then keep cutting. If you cannot say it in ten lines, the post is doing too many things.

  9. Make your second agent a listener. Once the first one is posting summaries and asking the team questions, the highest-value thing you can add is something that reads the replies. A second agent that does more work just creates more unanswered threads.

  10. Write every rule down with a name and a date. Our playbook is now mostly a record of decisions and who made them. When somebody asks why the agent does something strange, the answer is in the file with their colleague's name next to it.

The build went from the first agent file to its first real multi-product run in four days. The very first run, the day after that first file, was a heartbeat post saying the queue was empty, and it built nothing at all. The next business day it built three drafts and blocked seventeen. Just under three months later, the tracking tab has retired 94 finished rows, and the daily post is usually a few lines long. That progression is normal, and the boring early runs are what let you find out how wrong your instructions are while the stakes are low.

Frequently asked questions

Can an AI agent write Shopify product pages automatically?

Yes, and the practical version leaves them in draft rather than publishing. Ours reads a receiving report, pulls product data from the vendor page, writes copy against a style guide, processes images, and creates the product in Shopify as a draft. A person reviews and publishes.

What do you need before you build a product page agent?

A map of how the job actually gets done today, built from interviewing the people who do it, plus a style guide reverse-engineered from your own best product pages, a queue your team already maintains, and a hard definition of what makes an item ready to build. The process map and the style guide are the two pieces most people skip, and they are the two that determine whether the thing works.

Should an AI agent publish product pages live?

No. Have it create drafts only. Shopify supports draft as a product status specifically so unfinished products stay off the storefront, and a wrong draft costs somebody five minutes while a wrong live page costs you a customer.

How do you stop an AI agent from inventing product specifications?

Extract the specifications separately with code, then hand the model only those extracted pairs with an instruction to use nothing else. If the extraction comes back thin on a product where specifications matter, block the row for a human instead of letting the model fill the gaps.

What does it cost to run an AI agent that builds product pages?

There is no recurring fee beyond the AI subscription you already pay for. The cost is the build time and the time you spend the first few times it breaks. Zero monthly cost is what makes small, unglamorous automations worth doing at all.

Should the agent that builds product pages also talk to the team?

No, split them. Ours is a separate scheduled task that runs hourly, reads replies to the build's daily post, answers what it can, and escalates the rest. Keeping the listener separate means the build task has one job and a bug in one cannot become a bug in the other.

What is the most common way a product page agent fails?

It trusts something a platform told it about itself. Two of our worst bugs came from reading a count field that reported a number unrelated to the product, and from an API path frozen at creation that returned a 404 after a SKU had been edited. Verify by counting the actual list, not by reading the summary number.

Final thoughts

The pitch for an agent like this is speed, and speed is the least interesting thing it delivers. What actually changed is that a product page now gets built the day after the inventory lands, every time, whether or not anybody remembered, and it gets built to the same standard as the nine pages we decided were correct back in June.

The rest of the value came from writing everything down. Half of this project is a document that says what a good product page looks like at our store, who decided each rule, and when. That document existed nowhere before I tried to explain the job to a machine, which is a slightly embarrassing thing to admit about a company that sells things online for a living.

None of it would have happened if the job carried a monthly invoice. A recurring bill turns every small automation into a budget conversation, and the only reason this one ever got built is that there was nothing to approve. Build time once, nothing after that.

Build the style guide, point something at it, and leave the publish button to a person.

Interested in learning more?

If you read our three-part series on how much authority to hand an automation, this is a full build from the same shop, start to finish. Part one is How We Built an AI Agent to Catch Discount Code Fraud Every Morning, the agent that only watches. Part two is How We Built an AI Agent That Asks Permission Before It Acts, the one that proposes and waits. Part three is How We Let an AI Agent Earn Autonomy One Action at a Time, which goes deep on the listening task described above and how it earned each of its two approved actions.

For more on automating the unglamorous parts of running a business, take a look at How I Automated My Monthly Personal Financial Statement and Always Delete Your Test Coupon Codes Before a Bot Finds Them.

J
John Roman

Curated for Online Queso — a non-standard look inside the minds of the best operators in eCommerce. Tips, stories, and free advice, served digestible and delicious.