Booth — case file

Booth

PRD_EvalgenAgent · 14 nodes · HiringIn production

When a recruiter creates a new job in Zoho, turns the prose job description plus calibration notes into a structured must-have / nice-to-have rules row that the screening agent then reads — no engineer in the loop. — 146 tasks (140 completed, 4 failed) in the 30 days to 2026-08-10

PRD_EvalgenAgentno measured cost
1
Zoho Recruit webhook fires on job creation; code extracts the job fields
2
Fetch existing rows from the Baserow config table; code checks recency
3
AI converts the prose JD + calibration notes into must-have / nice-to-have criteria
4
Code builds the config row payload
5
Create or update the row in Baserow for the screening agent to read
Where the money goes · per run
Step typeCountRateSubtotal
Code / integration steps8$0.025$0.2
Model calls · standard tier3$0.1$0.3
Other3—$0
Rate-card estimate (standard tier)$0.5

Per run only one branch executes. CREATE path (new job): entry extraction $0.10 (std; webhook JSON payload, no document so no parse floor) + Code Executor 'extract job fields' $0.025 + Baserow_SearchRows $0.025 + 'generate eval' std model $0.10 + 'build row data' code $0.025 + baserow-create-row $0.025 = $0.30. UPDATE path adds 'check recency' + 'Get row id' + 'build row (2)' code ($0.075) and swaps in 'generate eval (2)' + baserow-update-row = $0.35. DROP path (stale updated_at) = $0.175. Rule_based conditions and the exit unbilled. The catalog has NO measured figure (cost_basis 'none'); the honest comparator is the menu module 'jd-to-criteria' at $0.325/item ($0.455 with intake) — the graph arithmetic $0.30-0.35 brackets the menu price exactly at the std tier, so no tier gap exists; at-cost billing would land 5-10x lower per the catalog meta_note.

Models seen in the graph: GEMINI_3_FLASH (preferredModel on both 'generate eval' AI steps, the entry node, and Baserow nodes); GPT4_1_MINI (preferredModel on one Code Executor, with GEMINI_25_FLASH fallback); GEMINI_3_FLASH (condition llmModel, rule_based); fallback chain GEMINI_3_PRO/GPT4_1/CLAUDE_4_SONNET; legacy preferred_model 'GPT40' on the Baserow write tools

Graph read: ama-solution/04-agents/booth-s-workspace-production/prd-evalgenagent/agent.json (14 nodes, snapshot 2026-08-10 — this is the post-2026-08-05 upsert rebuild)

What a copycat build should know
  • Idempotent upsert topology (the thing to copy): extract → SearchRows → count condition [==0: generate→build→CREATE | >0: check recency → should_write? (true: generate(2)→build(2)→get row id→UPDATE | false: Exit)] — survives Josef's trigger firing 3 events per job and out-of-order edits via a string-compared updated_at recency guard.
  • 8 of 14 nodes are code/integration: array indexing, payload building and the recency comparison are all deterministic Code Executors; AI does only the JD→must-have/nice-to-have judgment (one std node per branch). The Studio variable-picker cannot address results[0].id, hence the dedicated 'Get row id' code node.
  • Extraction inputs are LINKED fill, not AI fill — AI fill re-derived and truncated the same JD non-deterministically (1815/6591/1790/1581 chars across runs); linked fill from the declared entry payload schema plus a deterministic HTML strip fixed it (also the warning header of the fragment library file).
  • The update branch writes only Generated Eval + Eval Source Ts — it never blanks other row fields, so a re-fire can't destroy data the screening agent reads.
Lessons from the client record
  • Create-only writers duplicate rows under real triggers: every Zoho job edit made a new Baserow row, halting downstream CV screening; the upsert + recency guard closed it (CLI-5759, verified live: 91 tasks over 3 days produced only +7 rows).
  • 'check recency' fail-opened silently until the array-shape fix — CREATE/UPDATE tests passed by luck and only the DROP test exposed it; test the branch that should do NOTHING (ACTIVITY_LOG 2026-08-04).
  • Baserow single-select fields reject unknown options with HTTP 400 (Status held 5 legacy options) — drop fields downstream doesn't read rather than maintaining a picklist mirror (ACTIVITY_LOG 2026-08-02).
  • Baserow_SearchRows tool description contradicts its param description, and ai_fill makes the model coin-flip between filter shapes per run — pin filters via linked/code fill (CLIENT.md issue 19; same tool this agent calls).
Reusable fragments cut from this agent
  • hrgenerate eval03-projects/26-hr/02-resources/module-library/05-JD转结构化要求.md#1
  • hrgenerate eval (2)03-projects/26-hr/02-resources/module-library/05-JD转结构化要求.md#2
  • hrextract job fields03-projects/26-hr/02-resources/module-library/05-JD转结构化要求.md#3
  • hrcheck recency03-projects/26-hr/02-resources/module-library/05-JD转结构化要求.md#4
  • hrbuild row data03-projects/26-hr/02-resources/module-library/05-JD转结构化要求.md#5
  • hrGet row id03-projects/26-hr/02-resources/module-library/05-JD转结构化要求.md#6
Job description to criteriaZoho Recruit (webhook)Baserow

ama-solution/04-agents/booth-s-workspace-production/prd-evalgenagent/agent.json · solution-intelligence/content/agent-catalog.json · solution-intelligence/content/menu.json · sol-booth/CLIENT.md · sol-booth/ACTIVITY_LOG.md · ama-solution/03-projects/26-hr/02-resources/module-library/05-JD转结构化要求.md

Booth · PRD_EvalgenAgent5 stepscase analysed