Generate Catalog Content with a Local AI Agent — No API Required

Date:

A repeatable pattern for AI-written descriptions, summaries, specs and FAQs across a directory or catalog — without an API key, an SDK dependency, or a per-token bill.

The short answer: local AI content generation means letting the AI coding agent you already run in your editor be the generator, wrapped in a small deterministic seam — export a grounded packet from your data, generate with a versioned prompt in-session, validate-ingest with the spec’s rules as code assertions. No API key, no SDK, no per-token bill, and every row is grounded and checked before it lands.

You have a few hundred (or a few thousand) items — products, courses, listings, ideally already sitting in a deliberate classification scheme — and you want good, consistent, AI-written content for each. The reflex is to wire up a model API: get a key, add an SDK, write a worker, watch the token meter. For an on-demand job at this scale, that’s a lot of moving parts and a recurring cost for something you’ll run occasionally.

There’s a simpler shape. If you already work with an AI coding agent in your editor/terminal, that agent is your generator. The “LLM call” is the agent itself, working in-session — no key, no SDK, no billing path in your codebase. The trick is to wrap it in a small, deterministic seam so the output is grounded, validated, and reproducible instead of vibes.

The seam: export → generate → validate-ingestThe agent produces a file. It never holds a connection to anything that matters.
1. Export

A file holding exactly the rows that need content, and nothing else. The agent never sees a connection string, so it cannot write anywhere.

2. Generate locally

A local agent reads that file and writes the prose. No API key, no per-token cost, and nothing leaves the machine it runs on.

3. Validate, then ingest

Nothing is trusted on arrival. Schema, length, banned wording and an originality check gate every row before a single one is written.

The seam is the whole design: the model's output is a FILE, never a write. Everything untrustworthy stops at the validator.

The seam: export → generate → validate-ingest

Three steps, one direction. Two of them are plain code; the middle one is the agent.

1. Export (code). For each item, assemble a grounded “packet” from your database — and only the fields the generator is allowed to use (the canonical facts, the source text, the real attributes). Write it to a work file. Compute a source_hash over exactly those inputs.

packets/<item-id>.json   →  { canonical fields, source text, source attributes, source_hash }Code language: HTML, XML (xml)

The packet is a contract: it says “here is everything you may ground on, and nothing else.”

2. Generate (the agent, in-session). The agent reads a packet and applies a versioned spec — a prompt that lives in your repo as a file. The prompt is the spec: it defines the structure that serves search, answer and generative engines, the tone, the word count, the banned phrases, the rules. The agent writes a result file. Because the spec is checked in and versioned, the job is reproducible in the way that matters: same spec, same inputs, same shape of output.

3. Ingest (code). Now the safety net. Run the spec’s rules as code assertions over each result:

  • Grounding / no fabrication — every fact in the output must trace back to the packet’s source. If the agent invented a spec value or a feature, the assertion fails and the row is rejected.
  • House-style — banned filler phrases, word-count bounds, required fields present, no broken encoding.
  • Structure — the right sections, valid JSON, scores in range.

Results that pass get written to your database. Results that fail get rejected or flagged for a regenerate. Generation is never trusted blind — the validators are the contract enforcement.

Generation is never trusted blind; the validators are the contract enforcement.

Why it works

  • No dependency, no key, no cost path. Nothing in your codebase imports a model SDK. The generation work is exactly what the agent already does for you.
  • The boundaries stay in code, so the system stays replay-safe and diffable. Export, validators, versioning, materiality — all deterministic. Only the prose synthesis is delegated, and the spec makes that part reproducible too.
  • It mirrors a clean data pipeline. Export = read; generate = transform; ingest = load with validation. The agent slots into the “intelligent step” that would otherwise be a human or an API worker.

Only the prose synthesis is delegated — everything else stays deterministic code.

The four disciplines that make it trustworthy

  1. Ground everything. The packet defines the allowed inputs; the validator rejects anything that doesn’t trace to them. This is your defense against hallucinated facts — and, on commercial content, your defense against misleading-advertising liability.
  2. Validators as code, not faith. Encode the house-style as assertions in the ingest step. If a rule matters, it’s a test, not a hope.
  3. Materiality via source_hash. Gate regeneration on a hash of the grounded inputs. If a price or a count changed but the substance didn’t, don’t burn effort rewriting prose. Only regenerate when the inputs that the prose depends on actually changed.
  4. Version the spec. Stamp every generated row with the spec_version that produced it. Bumping the spec (v1 → v2) is a content migration — you regenerate the affected items — never an in-place edit of a spec you’ve already released. That keeps “which rule produced this text?” answerable forever.

Bumping the spec is a content migration, never an in-place edit.

Honest limits

  • Throughput is hands-on. You’re in the loop per batch; this isn’t a fire-and-forget cron at a million items. It shines at on-demand, hundreds-to-low-thousands scale.
  • House-style can drift across a big batch — which is exactly why the validators (banned words, length, structure) have to be strict. They catch the drift you won’t notice by eye.
  • Prose isn’t byte-identical across regenerations. “Same input + spec → same output” holds for the deterministic code, not for the wording. So the source_hash gates whether to regenerate, not output equality — and you review via validators, not a diff of the prose.
  • At large scale, reconsider — batching might become worth it, though as with any capacity question, measure where the real limit actually is before re-architecting. (Note that “batching” still doesn’t have to mean the paid API; it could be a local model. That’s a separate decision.)

Prose isn’t byte-identical across regenerations.

The takeaway

Delegate only the prose synthesis. Keep everything around it — the grounded inputs, the validators, the versioning, the materiality gate — in deterministic code. You get AI-quality content with none of the API ceremony, and a pipeline you can replay, diff, and trust.

Frequently Asked Questions

Do I need an API key or a paid plan to generate content this way?

No. The whole point is that the generator is the AI coding agent you already run in your editor or terminal — the generation happens in-session, so nothing in your codebase imports a model SDK, holds an API key, or accrues a per-token bill. You pay for the agent you already use, and nothing extra per item.

How is this different from just pasting prompts into a chatbot?

The difference is the deterministic seam around the agent. You export a grounded packet (only the fields the generator may use), the agent generates against a versioned prompt checked into your repo, and every result is validated as code on ingest — grounding, house-style, structure. Pasting into a chatbot gives you none of that: no grounding contract, no reproducibility, no automated rejection of a bad row. Here the validators are the contract, not your goodwill.

How do you stop the agent from inventing facts?

Grounding plus validation. The packet declares exactly what the agent is allowed to build on; the ingest step then asserts that every fact in the output traces back to that packet, and rejects anything that doesn’t. A fabricated spec value or invented feature fails the assertion and never reaches your database — generation is never trusted blind.

Does this scale to thousands of items?

It shines at on-demand, hundreds-to-low-thousands scale, where you stay in the loop per batch. Beyond that, throughput becomes hands-on and house-style can drift across a big run — which is exactly why the validators must be strict. At genuinely large scale, reconsider batching (which still needn’t mean the paid API — a local model is an option); measure the real bottleneck before you re-architect.

Share post:

Subscribe

Popular

More like this
Related

How to Merge Spreadsheets by URL (and Why Our Tool Reported 5 Misses That Weren’t)

Matching two spreadsheets on a URL column is the same job as matching a stock list to a price list by product code. It goes wrong in the same two places: how you clean the code, and how you count what didn't match.

Many-to-One: Why a Mapping Backlog Outgrows Its Target Taxonomy

You're mapping a messy source vocabulary onto a clean target taxonomy. The target has about 5,600 slots, so the job must be roughly 5,600 decisions — right? The backlog is already past 8,900, and still climbing.

The Fix That Didn’t Take: When a Content-Hash Gate Skips Your Code Change

You shipped a fix to how one field is computed, re-ran the pipeline across everything, and it reported a clean run. Then the consistency check still flags those records as wrong. The fix is in the code, the rebuild "ran" — and the records never changed. Your own optimisation skipped them.

Your Dedup Scan Is Over-Counting — Because It Forgot What You Already Fixed

The report said 80 duplicate groups still to resolve. You'd been resolving them for days. You run it again after a big batch and it *still* says 80-ish. The backlog isn't stubborn — the scan is counting work you already finished.