inemaSEO 5 — With Agents: Claude Code and Codex Doing the Repetitive Work|INEMA.CLUB-PRO

Lesson 3 · 18 min

Extraction through the subscription and the check that discards

Listing pages, news article bodies, page summaries: the agent writes from a source, in batches. The risk is that it embellishes and makes things up. Here you call the model through the subscription, in read-only mode, read the first JSON in the reply, and run everything through a check that discards the made-up item.

Start the lesson
A quality-control technician sorts samples into two steel trays, comparing each one against a reference sheet.

In this lesson you will

  1. 1The Codex call in read-only mode, no API
  2. 2Why read only the first JSON in the reply
  3. 3The check: title, words, and numbers in the source
  4. 4Discarding is not losing: it keeps the batch clean

Goal: call Codex or Claude through the subscription to extract from a source and discard, without fixing, any item that fails the check.

01From the source to an item that can go live

Tap each block.

Click each block in the diagram to see what it does.

The model can rewrite and organize; the check ensures it didn't create facts.

02How INEMA does it in batches

Tap each step.

1. The call

INEMA's news text generator calls Codex with the request through standard input, a read-only sandbox, an ephemeral session, and output to a file. Close the input after sending the request: otherwise the process keeps waiting.

In Claude Code, the same request runs in the project folder, with AGENTS.md forbidding writes outside the output folder.

03The call, the first JSON, and the check on the batch

pedido.txt = extractive prompt (course 2, lesson 5) + the source text. valida-ficha.mjs is a template that uses the validar_extracao.mjs library.

Calling Codex through the subscription (read-only)
codex exec --skip-git-repo-check --ephemeral --sandbox read-only -C "$PWD" -o saida.txt - < pedido.txt
node valida-ficha.mjs fonte.txt saida.txt
valida-ficha.mjs (template)
// passes each item of the listing page through the check (uses validar_extracao.mjs as a library)
import fs from 'node:fs'
import { apoiada, numerosNaFonte, tituloNaFonte } from './validar_extracao.mjs'
const [fonteArq, fichaArq] = process.argv.slice(2)
const fonte = fs.readFileSync(fonteArq, 'utf8')
const ficha = JSON.parse(fs.readFileSync(fichaArq, 'utf8'))
let validos = 0
for (const m of ficha.estrutura || []) {
  const ok = tituloNaFonte(m.titulo, fonte) && numerosNaFonte(m.detalhe || '', fonte)
  console.log(`${ok ? '✓' : '✗ descarta'}  módulo: ${m.titulo}`)
  if (ok) validos++
}
for (const campo of ['aprende', 'publico', 'constroi']) {
  for (const f of ficha[campo] || []) {
    const ok = apoiada(f, fonte) && numerosNaFonte(f, fonte)
    console.log(`${ok ? '✓' : '✗ descarta'}  ${campo}: ${f}`)
  }
}
console.log(validos >= 3 ? `ficha enriquecida (${validos} módulos válidos)` : `não publica como enriquecida (${validos} módulos válidos)`)
primeiroJson (from the INEMA text generator)
function primeiroJson(txt) {
  const ini = txt.indexOf('{')
  let prof = 0, str = false, esc = false
  for (let i = ini; i < txt.length; i++) {
    const c = txt[i]
    if (str) { if (esc) esc = false; else if (c === '\\') esc = true; else if (c === '"') str = false; continue }
    if (c === '"') str = true
    else if (c === '{') prof++
    else if (c === '}' && --prof === 0) return JSON.parse(txt.slice(ini, i + 1))
  }
  throw new Error('JSON incompleto')
}
Example from the repository
$ node valida-ficha.mjs fonte.txt saida.txt
✓  módulo: Módulo 1: Preparar o barro
✓  módulo: Módulo 2: Centralizar no torno
✓  módulo: Módulo 3: Abrir e levantar a peça
✓  módulo: Módulo 4: Acabamento e secagem
✓  aprende: Amassar, tirar o ar e pesar as bolas de argila.
✓  publico: quem nunca sentou num torno e quer fazer as primeiras peças utilitárias.
✓  constroi: copos e tigelas simples, prontos para esmaltar.
ficha enriquecida (4 módulos válidos)

Excerpt. The source was the sample page of a wheel-throwing ceramics course, with 4 modules and "8 encontros de 3 horas".

04Practice: an extraction with a check

Pick an item on your site that has its own page with text.

E1 · Extract through the subscription

30 min

Save the page text in fonte.txt, build the pedido.txt with the extractive prompt, and run the Codex call (or the same request in Claude Code). Repeat with a free-form request, "de forma atraente" (in an attractive way), to compare.

Done when: you have saida.txt and saida-livre.txt, both in JSON, and no API key was used.

E2 · Run the check

20 min

Copy validar_extracao.mjs and valida-ficha.mjs into the folder and run them on both outputs. Write down what was discarded and why.

Done when: a note lists each discarded item with the reason (title, words, or number outside the source), and only the listing page with 3 or more valid modules is marked for publishing.

05Test what you learned

The explanation appears after your answer.

Question 1 of 4

What is the read-only sandbox option in the Codex call for?skill

06To take with you

Subscription, read-onlycodex exec with a read-only sandbox, an ephemeral session, and output written to a file.
First JSONOne bad answer can't bring down the whole batch.
Discard, don't fixTitle, words, and numbers are checked against the source; anything that fails is dropped.
2026 yardstickNon-commodity content comes from the real page's first-hand data, not from a more "attractive" text.

Going further

Previous lessonNext lesson