Unified batch enrichment: single API call per product#50
Conversation
Extracts product context building into an injectable service behind ProductContextBuilderInterface. Includes visible/searchable attribute filtering, value truncation, and array/empty value exclusion. Refs: #44 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements structured JSON output using OpenAI response_format with json_schema. Scales max_completion_tokens by attribute count. Returns empty array on parse failure to signal fallback to individual calls. Refs: #44 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces per-attribute enrichAttribute() loop with batch-oriented three-phase execute(): collectPending checks cache and gathers work, generate makes a single batch API call with individual fallback, record persists enrichments and applies values to the product. Refs: #44 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wires ProductContextBuilderInterface preference, adds context_value_max_length config field (default: 500) to the Advanced Settings group. Refs: #44 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
8c7fbb4 to
a4a2342
Compare
|
Hey @rhoerr, before I do anything with this I want to surface the tension and save it for our next sync. The work is real: 31 new tests, a clean collect → generate → record split, and the hybrid fallback is smart. ~80% API cost reduction is a big claim and it's plausible for stores enriching at scale. What I'm stuck on:
Not a rejection, just things I want to talk through in our sync. There's probably a version where batch is flag-gated per store (or per attribute group) and the cache accounts for partial hits, which would get us most of the upside without regressing #46's cache design. Let's chat. |
Summary
ProductContextBuilderservice that builds AI context from visible/searchable product attributes with configurable max-length truncationgenerateBatch()toAiClientInterface/OpenAiClientusing OpenAI Structured Outputs (response_format: json_schema) to generate all attribute values in a single API call per productEnricherinto three phases (collect → generate → record) with automatic fallback to individualgenerate()calls if batch failsDesign
Replaces per-attribute API calls with a single batch call per product, reducing API costs ~80% and improving content consistency across attributes. The batch schema enforces typed responses via OpenAI's
json_schemaresponse format withstrict: true.Falls back gracefully: if batch returns empty (parse error, API failure), each attribute is retried individually via the existing
generate()method.Test Plan
ProductContextBuilder(visible/searchable filtering, truncation, empty/null/array handling)OpenAiClientbatch helpers (schema building, prompt assembly, JSON parsing)Enricher(batch, cache hit/miss, partial cache, fallback, approval, deferred, overwrite)Refs: #44
🤖 Generated with Claude Code