<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: CIZO</title>
    <description>The latest articles on Forem by CIZO (@cizo).</description>
    <link>https://forem.com/cizo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3690067%2F12b7e93e-3c52-4a0b-b919-98e7e6f4267f.jpg</url>
      <title>Forem: CIZO</title>
      <link>https://forem.com/cizo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/cizo"/>
    <language>en</language>
    <item>
      <title>We Built an AI That Doesn't Guess: Architecture for Industrial Component Sourcing</title>
      <dc:creator>CIZO</dc:creator>
      <pubDate>Wed, 15 Apr 2026 10:55:30 +0000</pubDate>
      <link>https://forem.com/cizo/we-built-an-ai-that-doesnt-guess-architecture-for-industrial-component-sourcing-4kbn</link>
      <guid>https://forem.com/cizo/we-built-an-ai-that-doesnt-guess-architecture-for-industrial-component-sourcing-4kbn</guid>
      <description>&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnj7osw3ddg97v81tjbjv.png" alt=" " width="800" height="533"&gt;
&lt;/h2&gt;

&lt;p&gt;Most AI search systems follow a flow that looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Input → LLM → Results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a lot of domains, that's fine. Imprecise results in a playlist recommender or a content search tool are annoying. You try again.&lt;/p&gt;

&lt;p&gt;But &lt;a href="https://cizotech.com/how-we-built-an-ai-powered-industrial-sourcing-system/" rel="noopener noreferrer"&gt;we recently built an AI-powered sourcing system for industrial components&lt;/a&gt; — bolts, springs, fasteners — and in that domain, an imprecise result doesn't mean a slightly wrong recommendation. It means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wrong parameter → wrong part → real failure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we threw out the standard architecture and built something different. This post is a technical breakdown of what we built, why, and the design principles behind it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: AI Guesses. Always.
&lt;/h2&gt;

&lt;p&gt;When a user types a vague query into a standard AI search system, the LLM fills in the blanks. It has to — that's what it does. It infers, interpolates, and presents a confident output.&lt;/p&gt;

&lt;p&gt;Here's the failure mode we kept running into during initial testing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User input:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"High load spring for a small space"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;What an uncontrolled AI might assume:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load range: &lt;em&gt;something that seems high, based on training data patterns&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Material: &lt;em&gt;steel, probably&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Dimensions: &lt;em&gt;compact, probably&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Standard: &lt;em&gt;whatever seems relevant&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result looks technically formatted. The specs look plausible. But they were never validated against engineering constraints. The system guessed — and presented the guess with full confidence.&lt;/p&gt;

&lt;p&gt;In industrial procurement, this is the most dangerous type of error: &lt;strong&gt;the confident wrong answer.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Design Principle
&lt;/h2&gt;

&lt;p&gt;Early in this project, we had a realization that reframed the entire architecture:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI is excellent at understanding intent. AI is not reliable at making technical decisions.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These are two different cognitive tasks. We needed to split them — give AI the job it's genuinely good at, and give the deterministic system the job that requires precision.&lt;/p&gt;

&lt;p&gt;The architecture we landed on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Input
    ↓
[AI Layer] — Intent extraction only. No spec decisions.
    ↓
[Parameter Structuring Layer] — Engineering logic maps intent to valid ranges
    ↓
[Controlled Search Layer] — Searches using structured constraints, not raw NL
    ↓
[Validation Layer] — Every candidate checked before surfacing
    ↓
Precise Output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Layer-by-Layer Breakdown
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Layer 1: Natural Language Input
&lt;/h3&gt;

&lt;p&gt;Users express queries as engineers actually think on the floor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;"I need a corrosion-resistant bolt for outdoor use"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;"Spring for high load in a small space"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;"Fastener for vibration-heavy environment"&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No structured input required. No dropdowns or filter forms.&lt;/p&gt;




&lt;h3&gt;
  
  
  Layer 2: Intent Understanding — The AI's Actual Job
&lt;/h3&gt;

&lt;p&gt;This is the only layer where the LLM has autonomous authority — and it has one job: &lt;strong&gt;structured intent extraction.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For the query &lt;code&gt;"I need a corrosion-resistant bolt for outdoor use"&lt;/code&gt;, the AI extracts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"product_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bolt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"use_case"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"outdoor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"requirement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"corrosion_resistant"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. The AI does &lt;strong&gt;not&lt;/strong&gt; produce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Material specs&lt;/li&gt;
&lt;li&gt;ISO/DIN standards&lt;/li&gt;
&lt;li&gt;Dimensional ranges&lt;/li&gt;
&lt;li&gt;Final search filters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The AI interprets. Nothing else happens at this layer.&lt;/p&gt;




&lt;h3&gt;
  
  
  Layer 3: Parameter Structuring — Engineering Logic Takes Over
&lt;/h3&gt;

&lt;p&gt;This is the most important layer in the system.&lt;/p&gt;

&lt;p&gt;The extracted intent is passed to a structured parameter engine that maps intent to &lt;strong&gt;valid engineering possibilities&lt;/strong&gt; — not final values, but bounded ranges and candidate sets.&lt;/p&gt;

&lt;p&gt;For our bolt query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;use_case: outdoor + requirement&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;corrosion_resistant&lt;/span&gt;
&lt;span class="na"&gt;→ material_candidates&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Stainless&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Steel&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;A2"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Stainless&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Steel&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;A4"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;→ coating_candidates&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Zinc&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;plated&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(not&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;recommended&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;outdoor)"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hot-dip&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;galvanized"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;None&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(A4&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;self-resistant)"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;→ standard_candidates&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ISO&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;4017"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ISO&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;4018"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DIN&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;931"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DIN&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;933"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;→ exclusions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Carbon&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;steel&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;without&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;coating"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Aluminum&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(load&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;check&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;required)"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two rules this layer enforces absolutely:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;No parameter is ever assumed&lt;/strong&gt; — every value is derived from engineering rules or left as an open range&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Invalid combinations are excluded before search&lt;/strong&gt; — the system doesn't search for carbon steel outdoor bolts and then filter them out; it never includes them in the search space at all&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Layer 4: Controlled Search
&lt;/h3&gt;

&lt;p&gt;The search layer receives structured parameters — not the original natural language query. This is a deliberate architectural choice.&lt;/p&gt;

&lt;p&gt;Searching with raw NL queries allows semantic drift: the retrieval system surfaces items that are &lt;em&gt;linguistically related&lt;/em&gt; but &lt;em&gt;technically incompatible&lt;/em&gt;. Structured parameters eliminate this class of error entirely.&lt;/p&gt;

&lt;p&gt;Example search execution for the outdoor bolt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;search_params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;product_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bolt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;material&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stainless_a2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stainless_a4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;standard&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;iso_4017&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;din_933&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application_compatibility&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;outdoor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;exclusions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;carbon_steel_uncoated&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;catalog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;search_params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No fuzzy matching. No semantic retrieval on specs. Structured query against structured data.&lt;/p&gt;




&lt;h3&gt;
  
  
  Layer 5: Validation — Zero Tolerance
&lt;/h3&gt;

&lt;p&gt;Every candidate returned from Layer 4 goes through a validation pass before the user sees anything. This layer catches edge cases the parameter engine might have missed.&lt;/p&gt;

&lt;p&gt;Checks run per candidate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ Parameter compatibility (does this combination make engineering sense?)
✓ Standard compliance (does this part actually conform to the claimed standard?)
✓ Inventory / availability check (is this actually sourceable?)
✓ Constraint compatibility (no conflicts between specs)
✗ Reject if any check fails
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the layer that converts "probably right" into "confirmed right." Nothing passes without clearing all checks.&lt;/p&gt;




&lt;h3&gt;
  
  
  Layer 6: Output
&lt;/h3&gt;

&lt;p&gt;The user receives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exact matching components&lt;/li&gt;
&lt;li&gt;Full technical specifications&lt;/li&gt;
&lt;li&gt;Availability + stock data&lt;/li&gt;
&lt;li&gt;Compatible variations (e.g., same bolt in A4 vs A2)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No "this should work." Only: &lt;strong&gt;this is the correct part.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Cross-Cutting Systems
&lt;/h2&gt;

&lt;p&gt;Three systems run continuously across the full pipeline:&lt;/p&gt;

&lt;h3&gt;
  
  
  Pattern Learning Engine
&lt;/h3&gt;

&lt;p&gt;Stores validated parameter combinations from successful selections. When a query pattern is seen again, the system can reuse pre-validated mappings rather than re-deriving from scratch. Improves both speed and consistency over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Feedback &amp;amp; Correction Loop
&lt;/h3&gt;

&lt;p&gt;Incorrect matches (flagged by users or caught by monitoring) trigger rule updates in the parameter engine. The system gets more accurate with each correction, rather than repeating the same edge cases indefinitely.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quality Monitoring
&lt;/h3&gt;

&lt;p&gt;Tracks per-query accuracy, detects edge case clusters, and fires alerts when result quality metrics start to drift. Essential for maintaining reliability as the product catalog grows — an unchecked system will slowly degrade in accuracy without anyone noticing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Design Principles We'd Apply to Any Similar System
&lt;/h2&gt;

&lt;p&gt;After shipping this, here are the principles we'd carry forward to any AI system in a precision-critical domain:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Never let AI decide technical values autonomously&lt;/strong&gt;&lt;br&gt;
AI should narrow down possibilities; rules should finalize selections.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Structure before search&lt;/strong&gt;&lt;br&gt;
Never pass raw natural language directly to a search or retrieval layer. Always convert to structured parameters first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Validation is not optional&lt;/strong&gt;&lt;br&gt;
Every result must be verified before surfacing. This isn't overhead — it's the feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Separate intent understanding from technical decision-making&lt;/strong&gt;&lt;br&gt;
These are different cognitive tasks. Model your architecture to reflect that separation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Build for correction from day one&lt;/strong&gt;&lt;br&gt;
Your system will make mistakes. The question is whether it learns from them. Build feedback + correction loops before you need them.&lt;/p&gt;


&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Intent understanding&lt;/td&gt;
&lt;td&gt;OpenAI GPT-4o / Claude (via API)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;Node.js + Python&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parameter engine&lt;/td&gt;
&lt;td&gt;Custom rule-based system&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Validation&lt;/td&gt;
&lt;td&gt;Rules + AI-assisted checks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;PostgreSQL + catalog systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inventory&lt;/td&gt;
&lt;td&gt;API integrations (client-specific)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The stack is conventional. The architecture around it is what matters.&lt;/p&gt;


&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;The failure mode for most AI systems in high-stakes domains is the same:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The AI is given too much autonomy over decisions it can't make reliably.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The fix isn't a better model. It's a better architecture — one where AI does what it's genuinely good at (understanding language and intent), and deterministic systems do what they're genuinely good at (enforcing constraints and validating outputs).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI for understanding.
System for control.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're building AI for healthcare, manufacturing, logistics, fintech, or any domain where errors have real-world consequences — this separation isn't a nice-to-have. It's the thing that makes your system trustworthy in production.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built by the team at &lt;a href="https://cizotech.com" rel="noopener noreferrer"&gt;CIZO&lt;/a&gt; — we build production-grade AI systems, &lt;a href="https://cizotech.com/services/" rel="noopener noreferrer"&gt;mobile apps&lt;/a&gt;, and &lt;a href="https://cizotech.com/iot-app-development-services/" rel="noopener noreferrer"&gt;IoT solutions&lt;/a&gt;. Say hi: &lt;a href="mailto:hello@cizotech.com"&gt;hello@cizotech.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>industrialai</category>
      <category>engineeringsystems</category>
      <category>ecommerceai</category>
      <category>productsearch</category>
    </item>
    <item>
      <title>How We Architected an AI Engine That Generates 100+ Ad Creatives From a Single Brand Brief</title>
      <dc:creator>CIZO</dc:creator>
      <pubDate>Fri, 10 Apr 2026 06:23:10 +0000</pubDate>
      <link>https://forem.com/cizo/how-we-architected-an-ai-engine-that-generates-100-ad-creatives-from-a-single-brand-brief-3ppm</link>
      <guid>https://forem.com/cizo/how-we-architected-an-ai-engine-that-generates-100-ad-creatives-from-a-single-brand-brief-3ppm</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F96uddum24ur7u12bo6k4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F96uddum24ur7u12bo6k4.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A technical breakdown of the layered AI pipeline behind a scalable creative strategy system — and what developers can steal from it.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;We recently completed an internal AI platform for a performance marketing team managing multiple brands simultaneously. Their core problem was simple to state, hard to solve: &lt;strong&gt;they needed dozens of ad creative variations per campaign, but creative production was slow, manual, and impossible to scale.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The system we designed — an AI Creative Strategy Engine — now takes raw brand inputs and produces structured advertising assets (hooks, scripts, image ads, video concepts, UGC scripts) at volume. Here's how we built it, what architecture decisions we made, and what we'd do differently.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem Space
&lt;/h2&gt;

&lt;p&gt;Performance marketing on Meta and TikTok is a volume game. You don't launch one ad — you launch 20–50 variations, let them compete, kill the losers, double down on winners, and repeat. The bottleneck was never strategy. It was &lt;strong&gt;production throughput&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The old workflow looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Brand Brief
    → Marketing Strategy Discussion (days)
    → Creative Team Brainstorming (days)
    → Copywriting &amp;amp; Script Writing (days)
    → Design / Video Production (days)
    → Limited Creative Variations (3–5)
    → A/B Testing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the time you had testable assets, the market had moved. And scaling this linearly — hiring more writers, more designers — was not a viable answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture: A Layered Intelligence System
&lt;/h2&gt;

&lt;p&gt;The key insight was to stop thinking about this as "AI helping humans write ads" and start thinking about it as &lt;strong&gt;a structured data pipeline where brand intelligence flows through transformation layers and emerges as deployable assets.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's the full system architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────┐
│              BRAND INPUTS                   │
│  Website · Product Info · Personas          │
│  Onboarding Forms · Call Transcripts        │
└──────────────────┬──────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────────┐
│         BRAND INTELLIGENCE LAYER            │
│  Brand Voice Extraction                     │
│  Product Positioning                        │
│  Audience Understanding                     │
│  Messaging Framework                        │
└──────────────────┬──────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────────┐
│        CREATIVE INTELLIGENCE LAYER          │
│  Angle Mining                               │
│  Hook Framework Generation                 │
│  Emotional Trigger Analysis                 │
│  Winning Ad Pattern Library                 │
└──────────────────┬──────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────────┐
│            STRATEGY ENGINE                  │
│  Generates: Ad Hooks · Video Scripts        │
│  Creative Briefs · Campaign Concepts        │
│  Content Angles                             │
└──────────────────┬──────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────────┐
│          GOVERNANCE / QA LAYER              │
│  Brand Consistency Check                    │
│  Messaging Validation                       │
│  Quality Scoring                            │
│  Structured Formatting                      │
└──────────────────┬──────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────────┐
│          CREATIVE GENERATION                │
│  Static Image Ads · Video Ads               │
│  UGC Scripts · Creative Variants            │
└──────────────────┬──────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────────┐
│     CAMPAIGN DEPLOYMENT + FEEDBACK LOOP     │
│  Ad Performance → Winning Creatives         │
│  → Influence Future Strategy Generation     │
└─────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer has &lt;strong&gt;one job&lt;/strong&gt;. Outputs are structured. Nothing flows to the next stage without passing validation. Let's break each one down.&lt;/p&gt;




&lt;h2&gt;
  
  
  Layer 1: Brand Intelligence Extraction
&lt;/h2&gt;

&lt;p&gt;This is the ingestion layer. We feed it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Brand website (scraped + chunked)&lt;/li&gt;
&lt;li&gt;Product documentation&lt;/li&gt;
&lt;li&gt;Customer personas&lt;/li&gt;
&lt;li&gt;Onboarding form responses&lt;/li&gt;
&lt;li&gt;Sales/marketing call transcripts (Whisper-transcribed)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The LLM task here is &lt;strong&gt;extraction and structuring&lt;/strong&gt;, not generation. The prompt engineering goal is to produce a stable, reusable brand object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"brand_voice"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Direct, empowering, slightly irreverent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"core_positioning"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Recovery tech for serious athletes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"audience_segments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"seg_01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Competitive weekend warriors"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"pain_points"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"DOMS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"slow recovery"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"missed training days"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"language_patterns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"grind"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bounce back"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next session"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"messaging_pillars"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Speed of recovery"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Science-backed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Used by pros"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"avoid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Medical claims"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Before/after framing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Aggressive pricing language"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This brand object persists and is referenced by every downstream layer. &lt;strong&gt;Consistency comes from the data model, not from re-prompting every time.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Layer 2: Creative Intelligence — Angle Mining
&lt;/h2&gt;

&lt;p&gt;Given the brand object, this layer generates a library of creative angles. An "angle" is a strategic lens through which to frame the product:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pain-first&lt;/strong&gt;: Lead with the problem (DOMS is killing your gains)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Social proof&lt;/strong&gt;: Lead with credibility (Used by 40,000 athletes)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Curiosity&lt;/strong&gt;: Lead with a surprising claim (Most foam rollers are doing it wrong)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aspirational&lt;/strong&gt;: Lead with the outcome (What if you recovered overnight?)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contrarian&lt;/strong&gt;: Challenge conventional wisdom (Ice baths might actually slow recovery)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each angle maps to a set of emotional triggers pulled from a pattern library built from high-performing historical ads (CTR, ROAS, thumbstop rate).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mine_angles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;brand_object&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern_library&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Returns ranked creative angles for a brand,
    scored against historical pattern performance.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;build_angle_mining_prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;brand_object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern_library&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;angles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse_structured_output&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;AngleSchema&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;rank_by_pattern_match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;angles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pattern_library&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Layer 3: Strategy Engine — Hook + Script Generation
&lt;/h2&gt;

&lt;p&gt;This is where volume happens. For each angle × audience segment combination, the engine generates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;3–5 ad hooks&lt;/strong&gt; (the first 3 seconds of a video or first line of copy)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full video scripts&lt;/strong&gt; (15s, 30s, 60s variants)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static ad copy&lt;/strong&gt; (headline + body + CTA combinations)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UGC creator briefs&lt;/strong&gt; (instructions for human creators)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The combinatorial math starts working in your favour here. With 5 angles × 3 audience segments × 4 hook variants = &lt;strong&gt;60 unique concepts from a single brand brief&lt;/strong&gt;, before you've touched image or video generation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prompt structure for hook generation:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;System:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;You&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;direct-response&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;copywriter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;specialising&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;paid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;social.&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;Output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ONLY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;valid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JSON.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;No&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;preamble.&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;User:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Given&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;brand&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;context:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;brand_object&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;And&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;creative&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;angle:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;And&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;audience&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;segment:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

      &lt;/span&gt;&lt;span class="err"&gt;Generate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ad&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;hooks.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Each&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;must:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;under&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;words&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;immediate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;interrupt&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;brand&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;voice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;exactly&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Trigger&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;emotional&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;lever:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;angle.trigger&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

      &lt;/span&gt;&lt;span class="err"&gt;Return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;as:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"rationale"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"video|static"&lt;/span&gt;&lt;span class="p"&gt;}]}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Layer 4: Governance / QA Layer
&lt;/h2&gt;

&lt;p&gt;This is the layer most teams skip. It is the layer that makes the system production-safe.&lt;/p&gt;

&lt;p&gt;Every piece of generated content passes through three checks:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Brand consistency scoring&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;score_brand_consistency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;brand_object&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Returns 0.0–1.0 score. Content below 0.75 is rejected and regenerated.
    Checks: voice match, avoid-list violations, pillar alignment.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Regulatory / compliance check&lt;/strong&gt;&lt;br&gt;
For this client: no unsubstantiated health claims, no before/after framing (platform policy), no superlatives without evidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Structured formatting validation&lt;/strong&gt;&lt;br&gt;
Output must conform to the asset schema before being written to the creative library. A video script without a defined hook segment, body, and CTA does not pass.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreativeAsset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Literal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;video_script&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;static_copy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ugc_brief&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;angle_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;segment_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;hook&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;cta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;brand_consistency_score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;approved&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rejected assets are automatically regenerated with failure reason injected into the prompt context. In practice, ~12% of first-pass outputs are rejected and regenerated successfully on retry.&lt;/p&gt;




&lt;h2&gt;
  
  
  Layer 5: Creative Generation
&lt;/h2&gt;

&lt;p&gt;Approved strategy outputs flow into generation:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Asset Type&lt;/th&gt;
&lt;th&gt;Tool / Model&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Static image ads&lt;/td&gt;
&lt;td&gt;DALL-E 3 / Stable Diffusion (finetuned on brand assets)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Short-form video&lt;/td&gt;
&lt;td&gt;Runway Gen-3 / Kling via API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UGC scripts&lt;/td&gt;
&lt;td&gt;Passed to human creator network as structured briefs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Variant expansion&lt;/td&gt;
&lt;td&gt;GPT-4o for copy variations on approved hooks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The creative generation layer is intentionally &lt;strong&gt;modular&lt;/strong&gt;. We wrap each provider behind an interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreativeGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Protocol&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;brief&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CreativeBrief&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GeneratedAsset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RunwayGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CreativeGenerator&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;brief&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CreativeBrief&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GeneratedAsset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Runway-specific implementation
&lt;/span&gt;        &lt;span class="bp"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StableDiffusionGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CreativeGenerator&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;brief&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CreativeBrief&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GeneratedAsset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# SD-specific implementation
&lt;/span&gt;        &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a better video model ships next month, you swap the implementation. The pipeline doesn't care.&lt;/p&gt;




&lt;h2&gt;
  
  
  Layer 6: The Feedback Loop
&lt;/h2&gt;

&lt;p&gt;This is the layer that turns a tool into a system that learns.&lt;/p&gt;

&lt;p&gt;After campaigns run, performance data (CTR, thumbstop rate, ROAS, hook retention) flows back and annotates the creative assets in the library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update_pattern_library&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;asset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CreativeAsset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CampaignMetrics&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Winning creatives (top quartile ROAS) are decomposed:
    - Angle type extracted
    - Hook structure tagged
    - Emotional trigger logged
    - Added to pattern library with performance weight
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;roas&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;WINNING_THRESHOLD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;decompose_winning_creative&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;pattern_library&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upsert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;roas&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pattern library is what the Creative Intelligence Layer (Layer 2) references. &lt;strong&gt;The system gets better at generating hooks with every campaign that runs.&lt;/strong&gt; This compounding loop is the actual product moat.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tech Stack Summary
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;LLM Backbone&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;        &lt;span class="s"&gt;GPT-4o (strategy/scripts) + Claude (QA/governance)&lt;/span&gt;
&lt;span class="na"&gt;Orchestration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;       &lt;span class="s"&gt;LangChain / custom pipeline runner&lt;/span&gt;
&lt;span class="na"&gt;Image Generation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;    &lt;span class="s"&gt;DALL-E 3 + Stable Diffusion (brand-finetuned)&lt;/span&gt;
&lt;span class="na"&gt;Video Generation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;    &lt;span class="s"&gt;Runway Gen-3 API&lt;/span&gt;
&lt;span class="na"&gt;Speech-to-Text&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;      &lt;span class="s"&gt;OpenAI Whisper (for call transcript ingestion)&lt;/span&gt;
&lt;span class="na"&gt;Data Layer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;          &lt;span class="s"&gt;PostgreSQL + pgvector (embeddings for pattern library)&lt;/span&gt;
&lt;span class="na"&gt;API Layer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;           &lt;span class="s"&gt;FastAPI&lt;/span&gt;
&lt;span class="na"&gt;Frontend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;            &lt;span class="s"&gt;Next.js (internal dashboard)&lt;/span&gt;
&lt;span class="na"&gt;Queue&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;               &lt;span class="s"&gt;Redis + Celery (async generation jobs)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What We Learned / What We'd Do Differently
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What worked well:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The brand object as a persistent, reusable data structure. Every layer referencing a single source of truth eliminated inconsistency.&lt;/li&gt;
&lt;li&gt;The governance layer. Building QA in as a pipeline stage (not a manual review step) was the right call for production safety.&lt;/li&gt;
&lt;li&gt;Modular generator interfaces. We've already swapped two models since launch without touching pipeline logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What we underestimated:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prompt versioning.&lt;/strong&gt; Prompt changes break downstream output schemas. Treat prompts like code — version control them, test them, deploy them deliberately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latency in multi-step pipelines.&lt;/strong&gt; When you chain 6 LLM calls sequentially, latency compounds. We ended up parallelising Layers 2 and 3 significantly and moving to async generation jobs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The cost of regeneration.&lt;/strong&gt; The 12% rejection-and-regeneration rate adds up. A tighter governance check earlier in the pipeline (pre-generation rather than post) would have been cheaper.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🔄 What we'd architect differently:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Move brand consistency scoring into the generation prompt context rather than as a post-generation filter. Prevention &amp;gt; correction.&lt;/li&gt;
&lt;li&gt;Build the feedback loop instrumentation in from sprint 1, not as a v2 feature. The pattern library is only as good as the data flowing into it.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Broader Point
&lt;/h2&gt;

&lt;p&gt;The system works because it was designed as a &lt;strong&gt;data pipeline&lt;/strong&gt;, not a chatbot with a marketing skin. Each layer has one responsibility, outputs are typed and validated, and the feedback loop creates compounding improvement over time.&lt;/p&gt;

&lt;p&gt;These are not novel engineering ideas — they are software engineering fundamentals applied to AI workflows. The teams shipping durable AI products are the ones who treat LLMs as components in a system, not as magic boxes that answer questions.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;At &lt;a href="https://cizotech.com" rel="noopener noreferrer"&gt;CIZO&lt;/a&gt;, we design and build AI-powered mobile applications — from architecture and LLM integration to deployment. If you're building an AI product and want to talk architecture, &lt;a href="https://cizotech.com/contact-us/" rel="noopener noreferrer"&gt;we're always up for a conversation&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;code&gt;#ai&lt;/code&gt; &lt;code&gt;#llm&lt;/code&gt; &lt;code&gt;#machinelearning&lt;/code&gt; &lt;code&gt;#showdev&lt;/code&gt; &lt;code&gt;#productivity&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cover image suggestion:&lt;/strong&gt; A dark diagram showing the 6-layer pipeline with glowing connectors — or a split showing "manual workflow" vs "AI pipeline" side by side.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>machinelearning</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Architecting a Zero-Touch AI Delivery System with Make.com, GPT-4 &amp; Google Workspace</title>
      <dc:creator>CIZO</dc:creator>
      <pubDate>Thu, 02 Apr 2026 13:54:49 +0000</pubDate>
      <link>https://forem.com/cizo/architecting-a-zero-touch-ai-delivery-system-with-makecom-gpt-4-google-workspace-4hp2</link>
      <guid>https://forem.com/cizo/architecting-a-zero-touch-ai-delivery-system-with-makecom-gpt-4-google-workspace-4hp2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; — We built a 5-workflow automation pipeline that triggers on Stripe payment, pulls user context from a data store, runs 15 sequential GPT-4 completions, assembles a branded Google Doc, and delivers it to the buyer — all in under 5 minutes, with zero manual intervention.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8kpxrxxd185qov3i3ve4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8kpxrxxd185qov3i3ve4.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  System Overview
&lt;/h2&gt;

&lt;p&gt;This is a production architecture breakdown of an AI-powered delivery system built for a personal brand products business. Two products, two independent pipelines, one shared data layer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Voice Form] ──► [3 x Make.com Workflows] ──► [Make.com Data Store + Airtable]
                                                          │
                        ┌─────────────────────────────────┤
                        │                                 │
              [Stripe: Playbook]               [Stripe: Content Machine]
                        │                                 │
              [Playbook Workflow]           [Content Machine Workflow]
                        │                                 │
              [15 x GPT-4 Completions]      [Whisper → GPT-4 → Leonardo AI]
                        │                                 │
              [Google Doc Assembly]         [Google Doc + Slides + Drive]
                        │                                 │
                  [Email Delivery]               [Email Delivery]
                        │                                 │
                  [Airtable Log]                 [Airtable Log]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Entry Point 1 — The Voice Form (Top of Funnel)
&lt;/h2&gt;

&lt;p&gt;Before any purchase, users complete a Tally voice form. This is the data collection layer — it captures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name, email, phone&lt;/li&gt;
&lt;li&gt;Niche and area of expertise&lt;/li&gt;
&lt;li&gt;Goals and target audience&lt;/li&gt;
&lt;li&gt;Tone of voice preferences&lt;/li&gt;
&lt;li&gt;Platform focus (LinkedIn, Instagram, YouTube, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On submission, &lt;strong&gt;three Make.com workflows fire simultaneously:&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Workflow 1 — Data Store Write
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Trigger: Tally form webhook
Action:  Write all form fields to Make.com Data Store
Key:     user_email (used as lookup key at purchase time)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Workflow 2 — Airtable CRM Upsert
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Trigger: Tally form webhook
Action:  Search Airtable for existing record by email
         → If found: UPDATE record with new form data
         → If not found: CREATE new record
Status:  Set to "New User" or "User Updated"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Workflow 3 — Additional Data Processing
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Trigger: Tally form webhook
Action:  Supplementary processing and storage logic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why split into 3 workflows?&lt;/strong&gt;&lt;br&gt;
Separation of concerns. Each workflow has a single responsibility. If Airtable goes down, the data store write still succeeds. Easier to debug, easier to extend.&lt;/p&gt;


&lt;h2&gt;
  
  
  Entry Point 2 — Stripe Payment Webhooks
&lt;/h2&gt;

&lt;p&gt;Both main pipelines are payment-triggered. Stripe fires a &lt;code&gt;checkout.session.completed&lt;/code&gt; webhook into Make.com when a purchase completes.&lt;/p&gt;

&lt;p&gt;Each product has its own dedicated webhook endpoint → its own Make.com scenario. This keeps the pipelines fully independent — a failure in one never affects the other.&lt;/p&gt;


&lt;h2&gt;
  
  
  Pipeline 1 — The Playbook Workflow
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Step 1: User Validation &amp;amp; Context Retrieval
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Search Airtable by email → validate user exists
2. GET from Make.com Data Store using email as key
   → Retrieves all voice form answers stored at top of funnel
3. GET brand archetype reference doc from Google Docs
   → Used as a reference document in AI prompts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 2: 15 Sequential GPT-4 Completions
&lt;/h3&gt;

&lt;p&gt;This is the core of the Playbook pipeline. Each completion generates one section of the brand strategy document.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;For each completion:
  1. Build prompt (user context + archetype reference + section instructions)
  2. POST to OpenAI /v1/chat/completions
  3. Parse and format response
  4. Sleep buffer (avoid rate limits)
  5. Store output variable for Google Doc assembly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The 15 sections generated:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Section&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Tone of Voice&lt;/td&gt;
&lt;td&gt;How the user communicates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Niche of Genius&lt;/td&gt;
&lt;td&gt;Their specific expertise area&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Claim to Fame&lt;/td&gt;
&lt;td&gt;Unique credibility statement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Tagline&lt;/td&gt;
&lt;td&gt;One-line brand statement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Buyer Persona&lt;/td&gt;
&lt;td&gt;Ideal client profile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Buyer Journey&lt;/td&gt;
&lt;td&gt;Client journey stages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Sales Navigator&lt;/td&gt;
&lt;td&gt;Strategic sales positioning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Keywords&lt;/td&gt;
&lt;td&gt;SEO &amp;amp; content keywords&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;About Section&lt;/td&gt;
&lt;td&gt;3-part bio combining all sections&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;LinkedIn Bio&lt;/td&gt;
&lt;td&gt;Platform-optimised profile copy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;YouTube Bio&lt;/td&gt;
&lt;td&gt;Channel description&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Instagram Bio&lt;/td&gt;
&lt;td&gt;150-character profile copy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;Facebook Bio&lt;/td&gt;
&lt;td&gt;Page description copy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;Brand Archetype&lt;/td&gt;
&lt;td&gt;Personality archetype classification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;Content Pillars&lt;/td&gt;
&lt;td&gt;Core content themes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Key prompt engineering consideration:&lt;/strong&gt;&lt;br&gt;
Each completion receives the outputs of previous completions as context. By completion 9 (About Section), the prompt includes tone of voice, niche, claim to fame, tagline, and buyer persona — creating a coherent, internally consistent document.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 3: Google Doc Assembly
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Copy branded Google Doc template (via Drive API)
2. Use Docs API to replace placeholder tokens with AI outputs
   e.g. {{TONE_OF_VOICE}} → generated content
3. Set document sharing permissions
4. Store Doc URL in Airtable record
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 4: Delivery &amp;amp; CRM Update
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Send delivery email with Google Doc link
2. Update Airtable record:
   - status: "Playbook Delivered"
   - playbook_url: [doc link]
   - delivered_at: [timestamp]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pipeline 2 — The Content Machine Workflow
&lt;/h2&gt;

&lt;p&gt;More complex than the Playbook. Involves file handling, transcription, multi-modal AI, and Drive folder management.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1: Email Validation
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Trigger: Tally form submission (video upload + contact details)
Action:  Search Airtable by email → validate and link to existing record
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 2: File Routing Logic
&lt;/h3&gt;

&lt;p&gt;The system handles three input types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;file_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;video/*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;CloudConvert&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;video&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;MP3&lt;/span&gt;
  &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt; &lt;span class="n"&gt;Whisper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MP3&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;transcript&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;

&lt;span class="n"&gt;ELSE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;file_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;audio/*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt; &lt;span class="n"&gt;Whisper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;audio&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;transcript&lt;/span&gt; &lt;span class="nf"&gt;text &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;skip&lt;/span&gt; &lt;span class="n"&gt;conversion&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;ELSE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;transcript_provided&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="n"&gt;Use&lt;/span&gt; &lt;span class="n"&gt;provided&lt;/span&gt; &lt;span class="n"&gt;transcript&lt;/span&gt; &lt;span class="nf"&gt;directly &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;skip&lt;/span&gt; &lt;span class="n"&gt;conversion&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;transcription&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this matters architecturally:&lt;/strong&gt; Different buyers submit different file types. The routing logic means the pipeline handles all cases gracefully without requiring users to pre-convert anything.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Playbook PDF Processing (Optional)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IF user has Playbook PDF:
  1. Upload PDF to OpenAI Files API
  2. Extract content via file retrieval
  3. Delete file from OpenAI (cleanup)
  4. Use extracted content as brand reference in content prompts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the cross-product integration point — The Content Machine uses The Playbook's content to generate brand-consistent output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: GPT-4 Content Generation
&lt;/h3&gt;

&lt;p&gt;Six content outputs, each with a dedicated generation pass and an emoji-cleaning pass:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pass 1:  AI Content Strategy Overview    → Formatter → Emoji clean
Pass 2:  Newsletter Article              → Formatter → Emoji clean
Pass 3:  Blog Post                       → Formatter → Emoji clean
Pass 4:  Hashtag Set                     → Formatter → Emoji clean
Pass 5:  LinkedIn Carousel Copy          → Formatter → Emoji clean
Pass 6:  [Additional output]             → Formatter → Emoji clean
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why the emoji cleaning pass?&lt;/strong&gt;&lt;br&gt;
GPT-4 frequently inserts emojis in content outputs by default. For professional brand copy destined for a Google Doc, this needs stripping. A dedicated cleaning completion is cleaner than prompt engineering alone.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 5: Google Drive Folder Management
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Search Airtable for existing Drive folder ID for this user
   IF exists: use existing folder IDs
   IF not exists:
     → Create main folder: "[User Name] - CIZO Content"
     → Create subfolder: "Outputs"
     → Store folder IDs in Airtable for future runs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;The folder ID persistence pattern&lt;/strong&gt; is important. Users can resubmit videos for new content packages. On second and subsequent runs, the system finds the existing folder and adds to it rather than creating duplicates.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 6: Asset Generation &amp;amp; Upload
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Leonardo AI: Generate custom image from content theme prompt
2. Download image from Leonardo CDN
3. Upload image to user's Google Drive output folder
4. Upload MP3 audio to Google Drive output folder
5. Create LinkedIn carousel in Google Slides:
   a. Copy branded Slides template
   b. Apply custom brand colours via Slides API
   c. Populate slide content with carousel copy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 7: Google Doc Assembly &amp;amp; Delivery
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Copy branded Google Doc template
2. Populate with all generated content sections
3. Insert carousel link + image reference
4. Insert headshot if uploaded
5. Create Airtable record logging all output URLs and folder IDs
6. Generate short URL via Short.cm API
7. Send delivery email with short URL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Data Layer — Airtable CRM Schema
&lt;/h2&gt;

&lt;p&gt;Every user interaction updates a central Airtable record. The key fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Users Table&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="s"&gt;├── email (primary key)&lt;/span&gt;
&lt;span class="s"&gt;├── name, phone&lt;/span&gt;
&lt;span class="s"&gt;├── niche, goals, tone_preferences&lt;/span&gt;
&lt;span class="s"&gt;├── status [New User | Updated | Playbook Delivered | Content Delivered]&lt;/span&gt;
&lt;span class="s"&gt;├── playbook_url&lt;/span&gt;
&lt;span class="s"&gt;├── drive_folder_id&lt;/span&gt;
&lt;span class="s"&gt;├── drive_output_folder_id&lt;/span&gt;
&lt;span class="s"&gt;├── content_doc_url&lt;/span&gt;
&lt;span class="s"&gt;├── created_at, updated_at, delivered_at&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;drive_folder_id&lt;/code&gt; field is what enables the repeatable content system — once set, it persists across all future Content Machine runs for that user.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Architecture Decisions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Make.com Data Store as session cache&lt;/strong&gt;&lt;br&gt;
Rather than re-querying Airtable for form data at purchase time, the data store acts as a fast key-value cache keyed by email. Lower latency, simpler lookup, independent of CRM availability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Sleep buffers between GPT-4 completions&lt;/strong&gt;&lt;br&gt;
With 15 sequential completions in the Playbook workflow, rate limit management is critical. Sleep modules between completions prevent 429 errors without requiring retry logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. File cleanup after OpenAI Files API use&lt;/strong&gt;&lt;br&gt;
PDFs uploaded to OpenAI's Files API are deleted immediately after content extraction. This keeps the account clean, avoids storage costs, and is better practice from a data minimisation perspective.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Independent webhook endpoints per product&lt;/strong&gt;&lt;br&gt;
Stripe webhooks route to separate Make.com scenarios per product. This means product-specific logic changes never risk breaking the other pipeline, and each can be tested and deployed independently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Folder ID persistence in Airtable&lt;/strong&gt;&lt;br&gt;
Storing Drive folder IDs after first creation turns a stateless workflow into a stateful one — without a database. The CRM becomes the state store.&lt;/p&gt;




&lt;h2&gt;
  
  
  Failure Modes &amp;amp; Considerations
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Handling&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;User buys without completing voice form&lt;/td&gt;
&lt;td&gt;Airtable record missing → system creates one with payment data only; AI outputs will be less personalised&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI rate limit hit&lt;/td&gt;
&lt;td&gt;Sleep buffers reduce likelihood; Make.com retry logic handles transient failures&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CloudConvert job fails&lt;/td&gt;
&lt;td&gt;Workflow errors out; Make.com error handler can notify admin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Drive API quota&lt;/td&gt;
&lt;td&gt;Unlikely at this scale; monitor via Google Cloud Console&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Duplicate purchase (same email)&lt;/td&gt;
&lt;td&gt;Airtable upsert handles gracefully; new doc created and linked&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Estimated Build Scope
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Phase                    Hours
─────────────────────────────
Architecture design      6–8
Prompt engineering       8–10
Make.com workflow build  12–16
CRM schema &amp;amp; logic       4–6
Google Workspace APIs    6–8
Testing &amp;amp; QA             8–12
─────────────────────────────
Total                    44–60 hrs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What Would You Do Differently?
&lt;/h2&gt;

&lt;p&gt;A few things worth considering if rebuilding this today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Replace Make.com with a custom Node.js service&lt;/strong&gt; for the 15-completion Playbook workflow — more control over retry logic, error handling, and execution time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add a webhook queue&lt;/strong&gt; (e.g. via Inngest or Quirrel) between Stripe and Make.com to handle burst traffic gracefully&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stream GPT-4 outputs&lt;/strong&gt; rather than waiting for full completion on each pass — would reduce total pipeline latency significantly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Abstract the Google Doc templating&lt;/strong&gt; into a reusable service — currently tightly coupled to specific template IDs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;The core insight here isn't the tools — it's the architecture pattern: &lt;strong&gt;capture context early, trigger on payment, personalise at generation time, deliver automatically.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That pattern is reusable across a wide range of product businesses. Anywhere personalised document delivery is the bottleneck, this approach applies.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built by the engineering team at &lt;a href="https://cizotech.com/" rel="noopener noreferrer"&gt;CIZO&lt;/a&gt; — we &lt;a href="https://cizotech.com/ai-ml-mobile-app-development-services/" rel="noopener noreferrer"&gt;build AI-powered mobile apps&lt;/a&gt; and automation systems. Open to questions in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>automation</category>
      <category>architecture</category>
      <category>openai</category>
    </item>
    <item>
      <title>Building an AI System That Generates UGC Ads in Minutes (Multi-Model Orchestration Explained)</title>
      <dc:creator>CIZO</dc:creator>
      <pubDate>Tue, 24 Mar 2026 14:08:36 +0000</pubDate>
      <link>https://forem.com/cizo/building-an-ai-system-that-generates-ugc-ads-in-minutes-multi-model-orchestration-explained-4jf6</link>
      <guid>https://forem.com/cizo/building-an-ai-system-that-generates-ugc-ads-in-minutes-multi-model-orchestration-explained-4jf6</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frrap19siah2jaxkipc79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frrap19siah2jaxkipc79.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating ad creatives is still one of the slowest parts of growth.&lt;/p&gt;

&lt;p&gt;Even today, the workflow looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Find UGC creators&lt;/li&gt;
&lt;li&gt;Ship products&lt;/li&gt;
&lt;li&gt;Wait for content&lt;/li&gt;
&lt;li&gt;Edit and publish&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This takes days (sometimes weeks).&lt;/p&gt;

&lt;p&gt;We wanted to change that.&lt;/p&gt;

&lt;p&gt;So we built a system that generates UGC-style video ads in under a minute using multiple AI models working together.&lt;/p&gt;

&lt;p&gt;This post breaks down how we built it — from architecture to attribution fixes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem We Were Solving
&lt;/h2&gt;

&lt;p&gt;We saw three major bottlenecks:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Creative Production Doesn’t Scale&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every new ad required a full production cycle.&lt;br&gt;
This limits testing and slows down iteration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. AI Tools Are Fragmented&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most tools solve one part:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Image generation&lt;/li&gt;
&lt;li&gt;Video generation&lt;/li&gt;
&lt;li&gt;Script generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But not the entire pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Attribution Was Broken&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We found:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Duplicate install events&lt;/li&gt;
&lt;li&gt;Conflicting SDK signals&lt;/li&gt;
&lt;li&gt;Inflated metrics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which made optimization unreliable.&lt;/p&gt;

&lt;h2&gt;
  
  
  System Overview
&lt;/h2&gt;

&lt;p&gt;We didn’t build “an AI feature.”&lt;/p&gt;

&lt;p&gt;We built a multi-model AI pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core Components:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scenario API → Generates product visuals &amp;amp; variations&lt;/li&gt;
&lt;li&gt;Creatify API → Converts assets into video ads&lt;/li&gt;
&lt;li&gt;Custom Orchestration Layer → Manages flow, timing, and output&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Pipeline (Step-by-Step)
&lt;/h2&gt;

&lt;p&gt;Here’s what happens when a user generates an ad:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User uploads a product image&lt;/li&gt;
&lt;li&gt;Selects an AI actor&lt;/li&gt;
&lt;li&gt;Scenario API generates visual assets&lt;/li&gt;
&lt;li&gt;Creatify API renders video&lt;/li&gt;
&lt;li&gt;Orchestration layer combines everything&lt;/li&gt;
&lt;li&gt;Final ad is delivered&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All of this happens in under a minute.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hard Part: Orchestration
&lt;/h2&gt;

&lt;p&gt;The real challenge wasn’t calling APIs.&lt;/p&gt;

&lt;p&gt;It was managing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Async Processing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each AI model responds at different times.&lt;br&gt;
We had to design a system that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Waits intelligently&lt;/li&gt;
&lt;li&gt;Handles failures gracefully&lt;/li&gt;
&lt;li&gt;Keeps latency low&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Output Consistency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Different models → different outputs.&lt;/p&gt;

&lt;p&gt;We needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Consistent visuals&lt;/li&gt;
&lt;li&gt;Cohesive storytelling&lt;/li&gt;
&lt;li&gt;Usable final ads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This required normalization and validation layers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Speed Constraints&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Target: &amp;lt; 60 seconds generation time&lt;/p&gt;

&lt;p&gt;This meant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parallel processing where possible&lt;/li&gt;
&lt;li&gt;Efficient retries&lt;/li&gt;
&lt;li&gt;Minimal blocking operations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Fixing Attribution (Critical Layer)
&lt;/h2&gt;

&lt;p&gt;While building the creative engine, we discovered a bigger issue:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The data layer was broken.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Issues:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Meta SDK + AppsFlyer conflicts&lt;/li&gt;
&lt;li&gt;Duplicate events&lt;/li&gt;
&lt;li&gt;Incorrect install tracking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We rebuilt the attribution system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set AppsFlyer as the single source of truth&lt;/li&gt;
&lt;li&gt;Removed conflicting signals&lt;/li&gt;
&lt;li&gt;Fixed event mapping:
`- start_trial&lt;/li&gt;
&lt;li&gt;purchase`&lt;/li&gt;
&lt;li&gt;Enabled proper postbacks&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Result:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Clean tracking&lt;/li&gt;
&lt;li&gt;Accurate reporting&lt;/li&gt;
&lt;li&gt;Better campaign optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Product Layer: Hiding Complexity
&lt;/h2&gt;

&lt;p&gt;Even with all this complexity, the product had to feel simple.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UX Principles:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minimal steps&lt;/li&gt;
&lt;li&gt;Fast feedback (instant previews)&lt;/li&gt;
&lt;li&gt;No technical configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The goal:&lt;/strong&gt;&lt;br&gt;
Hide complexity. Deliver power.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;UGC ads generated in minutes&lt;/li&gt;
&lt;li&gt;Unlimited creative variations&lt;/li&gt;
&lt;li&gt;Faster testing cycles&lt;/li&gt;
&lt;li&gt;Up to 96% cost reduction&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Takeaway
&lt;/h2&gt;

&lt;p&gt;Most people think AI products are about models.&lt;/p&gt;

&lt;p&gt;They’re not.&lt;/p&gt;

&lt;p&gt;They’re about systems.&lt;/p&gt;

&lt;p&gt;AI models generate outputs.&lt;br&gt;
Orchestration creates value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This project wasn’t just about automation.&lt;/p&gt;

&lt;p&gt;It was about building:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A scalable creative engine&lt;/li&gt;
&lt;li&gt;A reliable attribution system&lt;/li&gt;
&lt;li&gt;A product that improves performance marketing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're building with AI, focus less on individual models&lt;br&gt;
and more on how they work together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full Case Study
&lt;/h2&gt;

&lt;p&gt;If you want the full breakdown (business + product + impact):&lt;br&gt;
👉 &lt;a href="https://cizotech.com/we-built-an-ai-that-creates-ugc-ads-in-minutes/" rel="noopener noreferrer"&gt;We Built an AI That Creates UGC Ads in Minutes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s Discuss
&lt;/h2&gt;

&lt;p&gt;Curious how others are handling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-model orchestration?&lt;/li&gt;
&lt;li&gt;AI latency issues?&lt;/li&gt;
&lt;li&gt;Attribution challenges?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop your thoughts 👇&lt;/p&gt;

</description>
      <category>ai</category>
      <category>growth</category>
      <category>marketingstrategy</category>
      <category>adtech</category>
    </item>
    <item>
      <title>We Built AI That Qualifies Real Estate Leads in 5 Minutes</title>
      <dc:creator>CIZO</dc:creator>
      <pubDate>Fri, 20 Mar 2026 10:09:49 +0000</pubDate>
      <link>https://forem.com/cizo/we-built-ai-that-qualifies-real-estate-leads-in-5-minutes-3jpo</link>
      <guid>https://forem.com/cizo/we-built-ai-that-qualifies-real-estate-leads-in-5-minutes-3jpo</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqvgdk1atx4k9q79yeu3s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqvgdk1atx4k9q79yeu3s.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most real estate systems don’t have a lead problem.&lt;/p&gt;

&lt;p&gt;They have a response problem.&lt;/p&gt;

&lt;p&gt;Leads come in from ads.&lt;br&gt;
But no one calls them fast enough.&lt;/p&gt;

&lt;p&gt;We recently built an AI system that fixes this — by calling and qualifying leads within minutes.&lt;/p&gt;

&lt;p&gt;Here’s how we designed it.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Real Problem Wasn’t Lead Quality
&lt;/h2&gt;

&lt;p&gt;Our client generates buyer leads through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Meta (Facebook) ads&lt;/li&gt;
&lt;li&gt;Google ads&lt;/li&gt;
&lt;li&gt;TikTok ads&lt;/li&gt;
&lt;li&gt;Website forms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On paper, everything looked good.&lt;/p&gt;

&lt;p&gt;But in reality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leads weren’t being called quickly&lt;/li&gt;
&lt;li&gt;Agents made only 1–2 attempts&lt;/li&gt;
&lt;li&gt;Many leads were marked as “unreachable”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And there was no way to verify any of it.&lt;/p&gt;
&lt;h2&gt;
  
  
  What We Needed to Solve
&lt;/h2&gt;

&lt;p&gt;We weren’t trying to &lt;a href="https://cizotech.com/" rel="noopener noreferrer"&gt;build a smart AI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We needed a system that could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call leads within 5 minutes&lt;/li&gt;
&lt;li&gt;Ask basic qualification questions&lt;/li&gt;
&lt;li&gt;Record outcomes in the CRM&lt;/li&gt;
&lt;li&gt;Follow up if there’s no response&lt;/li&gt;
&lt;li&gt;Create accountability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simple. Fast. Reliable.&lt;/p&gt;
&lt;h2&gt;
  
  
  The System We Built
&lt;/h2&gt;

&lt;p&gt;Here’s the workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lead enters CRM
   ↓
Trigger automation
   ↓
AI voice call placed
   ↓
Lead answers → qualification
   ↓
No answer → SMS fallback
   ↓
CRM updated with outcome
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every lead goes through this flow automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Voice Call (Core Layer)
&lt;/h2&gt;

&lt;p&gt;We used an AI voice agent to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confirm if the buyer is still interested&lt;/li&gt;
&lt;li&gt;Check if they already have an agent&lt;/li&gt;
&lt;li&gt;Ask availability for a follow-up call&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Key decision:&lt;br&gt;
Keep calls under 3 minutes&lt;/p&gt;

&lt;p&gt;This isn’t a sales call.&lt;br&gt;
It’s just qualification.&lt;/p&gt;
&lt;h2&gt;
  
  
  Deterministic Qualification Logic
&lt;/h2&gt;

&lt;p&gt;Instead of “AI guessing,” we used strict rules:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qualified if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Still looking to buy&lt;/li&gt;
&lt;li&gt;Not working with another agent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Not qualified if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not interested&lt;/li&gt;
&lt;li&gt;Already signed with an agent&lt;/li&gt;
&lt;li&gt;Requested no contact&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This made the system predictable and reliable.&lt;/p&gt;
&lt;h2&gt;
  
  
  SMS Fallback Layer
&lt;/h2&gt;

&lt;p&gt;If the call is not answered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The system sends an automated SMS&lt;/li&gt;
&lt;li&gt;Asks for a convenient callback time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures:&lt;br&gt;
Every lead gets at least one touchpoint&lt;/p&gt;
&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;p&gt;We didn’t overcomplicate it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CRM: GoHighLevel&lt;/li&gt;
&lt;li&gt;Voice AI: VAPI&lt;/li&gt;
&lt;li&gt;Text-to-Speech: ElevenLabs&lt;/li&gt;
&lt;li&gt;Automation: Make.com&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each tool had a clear role.&lt;br&gt;
No unnecessary layers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture Breakdown&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GoHighLevel (Trigger)
   ↓
Make.com (Orchestration)
   ↓
VAPI (Voice Call)
   ↓
AI Conversation
   ↓
Result वापस → CRM update
   ↓
Optional SMS fallback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key was orchestration — not just AI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Design Principles&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Speed &amp;gt; Intelligence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A fast response beats a perfect response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Short Conversations Win&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Long AI calls reduce engagement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Log Everything&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every attempt is recorded in the CRM.&lt;/p&gt;

&lt;p&gt;This solves:&lt;br&gt;
“I never got the lead” problem&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Consistency Over Creativity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Same logic. Every time. No variation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Changes
&lt;/h2&gt;

&lt;p&gt;Instead of selling:&lt;/p&gt;

&lt;p&gt;Raw leads&lt;br&gt;
The business can now sell:&lt;/p&gt;

&lt;p&gt;AI-qualified conversations&lt;br&gt;
That’s a completely different value proposition.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We’re Building Next
&lt;/h2&gt;

&lt;p&gt;Phase 2 includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live call transfer to agents&lt;/li&gt;
&lt;li&gt;Smart agent routing&lt;/li&gt;
&lt;li&gt;Call tracking &amp;amp; recordings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Goal:&lt;br&gt;
Convert instantly when intent is high&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;This isn’t about AI replacing agents.&lt;/p&gt;

&lt;p&gt;It’s about fixing the first 5 minutes —&lt;br&gt;
where most deals are lost.&lt;/p&gt;

&lt;h2&gt;
  
  
  If You’re Building Something Similar
&lt;/h2&gt;

&lt;p&gt;If you're working on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lead generation systems&lt;/li&gt;
&lt;li&gt;CRM automation&lt;/li&gt;
&lt;li&gt;AI voice workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Focus less on “AI intelligence”&lt;br&gt;
and more on response speed + system design.&lt;/p&gt;

&lt;p&gt;That’s where the real impact is.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>programming</category>
      <category>automation</category>
    </item>
    <item>
      <title>Automating Cabinet Design: Converting Architectural Drawings into 3D Models with AI</title>
      <dc:creator>CIZO</dc:creator>
      <pubDate>Fri, 13 Mar 2026 09:42:30 +0000</pubDate>
      <link>https://forem.com/cizo/automating-cabinet-design-converting-architectural-drawings-into-3d-models-with-ai-5a55</link>
      <guid>https://forem.com/cizo/automating-cabinet-design-converting-architectural-drawings-into-3d-models-with-ai-5a55</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe2q71zn1cq99fw4p7fhl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe2q71zn1cq99fw4p7fhl.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Architectural drawings already contain everything needed to build cabinet layouts.&lt;/p&gt;

&lt;p&gt;Dimensions.&lt;br&gt;
Cabinet placements.&lt;br&gt;
Appliance spacing.&lt;/p&gt;

&lt;p&gt;But most of this information exists in PDF drawings, which are designed for humans, not machines.&lt;/p&gt;

&lt;p&gt;When cabinet designs move into production, someone usually needs to manually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;interpret the drawing&lt;/li&gt;
&lt;li&gt;rebuild the layout in CAD&lt;/li&gt;
&lt;li&gt;generate a 3D model&lt;/li&gt;
&lt;li&gt;verify measurements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That process is slow and repetitive.&lt;/p&gt;

&lt;p&gt;We recently worked on a system designed to automate this workflow by &lt;a href="https://cizotech.com/building-an-ai-system-that-converts-architectural-drawings-into-3d-models/" rel="noopener noreferrer"&gt;converting cabinet drawings directly into structured 3D data&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The interesting part wasn’t the AI model itself.&lt;/p&gt;

&lt;p&gt;It was building the pipeline that makes the automation reliable.&lt;/p&gt;
&lt;h2&gt;
  
  
  System Architecture
&lt;/h2&gt;

&lt;p&gt;The system converts cabinet drawings into 3D models through a multi-stage pipeline.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PDF Drawing
   ↓
PDF → High Resolution Images
   ↓
View Region Detection
   ↓
Cabinet Detection (YOLO)
   ↓
Measurement Extraction (LLM + OCR)
   ↓
Coordinate Mapping
   ↓
3D Geometry Generation
   ↓
AutoCAD DWG Export

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each stage handles a specific problem in the workflow.&lt;/p&gt;

&lt;p&gt;Breaking the system into modules made it easier to debug and improve accuracy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 — Converting PDF Drawings to Images
&lt;/h3&gt;

&lt;p&gt;Architectural PDFs are not ideal inputs for computer vision models.&lt;/p&gt;

&lt;p&gt;They contain vector data mixed with annotations, layers, and text.&lt;/p&gt;

&lt;p&gt;To simplify processing, we convert each page into a high-resolution PNG image (300 DPI).&lt;/p&gt;

&lt;p&gt;Higher resolution improves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;text extraction accuracy&lt;/li&gt;
&lt;li&gt;detection performance&lt;/li&gt;
&lt;li&gt;line segmentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Small dimension labels become unreadable at lower resolutions, so image quality matters more than expected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 — View Region Detection
&lt;/h3&gt;

&lt;p&gt;A single architectural sheet usually contains multiple views:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;floor plans&lt;/li&gt;
&lt;li&gt;elevations&lt;/li&gt;
&lt;li&gt;section views&lt;/li&gt;
&lt;li&gt;cabinet details&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Processing the entire page creates too much noise.&lt;/p&gt;

&lt;p&gt;Instead, we segment the sheet into visual regions and classify them.&lt;/p&gt;

&lt;p&gt;The system prioritizes the base floor plan, which typically contains cabinet placement information.&lt;/p&gt;

&lt;p&gt;This step reduces false detections later in the pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 — Cabinet Detection Using YOLO
&lt;/h3&gt;

&lt;p&gt;Once the relevant region is identified, we run an object detection model.&lt;/p&gt;

&lt;p&gt;We trained a YOLO model to detect cabinet-related objects such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;base cabinets&lt;/li&gt;
&lt;li&gt;upper cabinets&lt;/li&gt;
&lt;li&gt;tall cabinets&lt;/li&gt;
&lt;li&gt;appliances&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each detection returns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bounding box coordinates&lt;/li&gt;
&lt;li&gt;confidence score&lt;/li&gt;
&lt;li&gt;object label&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Low-confidence detections are filtered out before moving to the next stage.&lt;/p&gt;

&lt;p&gt;This step establishes where cabinets exist in the layout.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4 — Extracting Measurements
&lt;/h3&gt;

&lt;p&gt;Detection tells us where cabinets are, but not their size.&lt;/p&gt;

&lt;p&gt;Cabinet drawings include dimension annotations like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;30"
2'-6"
34 1/2"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These values may appear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rotated&lt;/li&gt;
&lt;li&gt;overlapping other text&lt;/li&gt;
&lt;li&gt;connected via leader lines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Traditional OCR struggles with this.&lt;/p&gt;

&lt;p&gt;Instead, we combine OCR with a vision-enabled LLM.&lt;/p&gt;

&lt;p&gt;For each detected cabinet, the system:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Crops the region around the cabinet&lt;/li&gt;
&lt;li&gt;Sends the image to a vision model&lt;/li&gt;
&lt;li&gt;Requests structured measurements&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cabinet_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;34.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"depth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To prevent errors, we added validation rules.&lt;/p&gt;

&lt;p&gt;If measurements fall outside expected cabinet ranges, the result is flagged for manual review.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5 — Coordinate and Scale Detection
&lt;/h3&gt;

&lt;p&gt;Architectural drawings use scale references such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1/8" = 1'-0"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without interpreting this scale, cabinet positions remain in pixel space.&lt;/p&gt;

&lt;p&gt;The system identifies the scale marker and converts pixel distances into real-world coordinates.&lt;/p&gt;

&lt;p&gt;Each cabinet receives an X/Y/Z position relative to the drawing origin.&lt;/p&gt;

&lt;p&gt;This allows the layout to be reconstructed accurately in 3D space.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6 — Generating the 3D Layout
&lt;/h3&gt;

&lt;p&gt;Once we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cabinet detections&lt;/li&gt;
&lt;li&gt;measurements&lt;/li&gt;
&lt;li&gt;real-world coordinates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;we can generate 3D geometry.&lt;/p&gt;

&lt;p&gt;We implemented a viewer using Three.js where each cabinet becomes a parametric 3D object.&lt;/p&gt;

&lt;p&gt;This step is less about visualization and more about validating the pipeline.&lt;/p&gt;

&lt;p&gt;Architects can quickly review the generated layout and correct any misdetections.&lt;/p&gt;

&lt;p&gt;The goal isn’t perfect automation.&lt;/p&gt;

&lt;p&gt;It’s reducing manual modeling work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7 — Exporting to AutoCAD
&lt;/h3&gt;

&lt;p&gt;The final stage converts the generated geometry into DWG files.&lt;/p&gt;

&lt;p&gt;Using the AutoCAD SDK, the system exports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cabinet blocks&lt;/li&gt;
&lt;li&gt;correct dimensions&lt;/li&gt;
&lt;li&gt;real-world coordinates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If upstream data is correct, the export works reliably.&lt;/p&gt;

&lt;p&gt;Interestingly, this stage turned out to be one of the simplest parts of the system.&lt;/p&gt;

&lt;p&gt;Most of the complexity lies in interpreting drawings correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges We Encountered
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Drawings Are Inconsistent
&lt;/h3&gt;

&lt;p&gt;Architectural drawings vary widely depending on the designer.&lt;/p&gt;

&lt;p&gt;Annotation styles, measurement formats, and layout conventions are rarely standardized.&lt;/p&gt;

&lt;p&gt;The system needs to handle a wide range of variations.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Measurement Ambiguity
&lt;/h3&gt;

&lt;p&gt;Dimension labels are not always placed directly next to objects.&lt;/p&gt;

&lt;p&gt;They may refer to multiple cabinets or entire cabinet groups.&lt;/p&gt;

&lt;p&gt;Resolving these relationships requires contextual reasoning.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Legacy Drawings
&lt;/h3&gt;

&lt;p&gt;Older scanned drawings introduce additional problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;blurred lines&lt;/li&gt;
&lt;li&gt;noisy backgrounds&lt;/li&gt;
&lt;li&gt;overlapping annotations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These reduce detection accuracy significantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current System Status
&lt;/h2&gt;

&lt;p&gt;The system is currently an MVP under active development.&lt;/p&gt;

&lt;p&gt;Performance is strong for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clean digital drawings&lt;/li&gt;
&lt;li&gt;modern architectural layouts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Edge cases remain for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scanned plans&lt;/li&gt;
&lt;li&gt;dense dimension annotations&lt;/li&gt;
&lt;li&gt;complex sheet compositions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even with these limitations, the system already provides meaningful time savings.&lt;/p&gt;

&lt;p&gt;Architects can start with a generated layout and correct it instead of creating it from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Projects like this highlight an important lesson about &lt;a href="https://cizotech.com/" rel="noopener noreferrer"&gt;AI systems&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The hardest part usually isn’t the model.&lt;/p&gt;

&lt;p&gt;It’s designing the workflow around it.&lt;/p&gt;

&lt;p&gt;Solving this problem required combining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;document processing&lt;/li&gt;
&lt;li&gt;computer vision&lt;/li&gt;
&lt;li&gt;LLM interpretation&lt;/li&gt;
&lt;li&gt;geometry generation&lt;/li&gt;
&lt;li&gt;CAD integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Individually, these technologies are powerful.&lt;/p&gt;

&lt;p&gt;Together, they create a system capable of automating a real engineering workflow.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>computervision</category>
      <category>automation</category>
    </item>
    <item>
      <title>Turning Cabinet Drawings into 3D Models with AI</title>
      <dc:creator>CIZO</dc:creator>
      <pubDate>Thu, 05 Mar 2026 09:46:24 +0000</pubDate>
      <link>https://forem.com/cizo/turning-cabinet-drawings-into-3d-models-with-ai-de6</link>
      <guid>https://forem.com/cizo/turning-cabinet-drawings-into-3d-models-with-ai-de6</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fla737a9v6ahey8k07of4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fla737a9v6ahey8k07of4.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Construction and cabinet manufacturing still rely heavily on PDF drawings.&lt;/p&gt;

&lt;p&gt;Designers create them.&lt;br&gt;
Clients approve them.&lt;br&gt;
But when production begins, someone still needs to manually convert those drawings into CAD models or 3D layouts.&lt;/p&gt;

&lt;p&gt;That process is slow.&lt;/p&gt;

&lt;p&gt;And repetitive.&lt;/p&gt;

&lt;p&gt;So we asked a simple question:&lt;/p&gt;

&lt;p&gt;Can AI convert cabinet drawings directly into usable 3D data?&lt;/p&gt;

&lt;p&gt;This project explores how we built a system that reads cabinet drawings from PDFs and converts them into structured geometry that can generate DWG and 3D models.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Real Problem
&lt;/h2&gt;

&lt;p&gt;Cabinet drawings contain a lot of useful information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Layout structure&lt;/li&gt;
&lt;li&gt;Cabinet boundaries&lt;/li&gt;
&lt;li&gt;Measurements&lt;/li&gt;
&lt;li&gt;Labels&lt;/li&gt;
&lt;li&gt;Door and drawer positions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But most of this information exists in visual form.&lt;/p&gt;

&lt;p&gt;Machines cannot easily interpret that.&lt;/p&gt;

&lt;p&gt;Traditional automation tools fail because they expect structured CAD data, not messy PDF drawings.&lt;/p&gt;

&lt;p&gt;So the challenge was:&lt;/p&gt;

&lt;p&gt;How do we convert visual architectural information into structured geometry?&lt;/p&gt;
&lt;h2&gt;
  
  
  System Overview
&lt;/h2&gt;

&lt;p&gt;The pipeline we designed combines computer vision, detection models, and language models.&lt;/p&gt;

&lt;p&gt;The workflow looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PDF is converted into images&lt;/li&gt;
&lt;li&gt;Computer vision detects cabinets and components&lt;/li&gt;
&lt;li&gt;Text extraction captures measurements&lt;/li&gt;
&lt;li&gt;LLM interprets dimensions and structure&lt;/li&gt;
&lt;li&gt;Structured geometry is generated&lt;/li&gt;
&lt;li&gt;DWG / 3D models are produced&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each step solves a specific problem.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1 — Detecting Cabinets with Computer Vision
&lt;/h3&gt;

&lt;p&gt;We trained a YOLO-based object detection model to identify cabinet components inside drawings.&lt;/p&gt;

&lt;p&gt;The model detects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Base cabinets&lt;/li&gt;
&lt;li&gt;Wall cabinets&lt;/li&gt;
&lt;li&gt;Tall cabinets&lt;/li&gt;
&lt;li&gt;Appliances&lt;/li&gt;
&lt;li&gt;Structural boundaries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why YOLO?&lt;/p&gt;

&lt;p&gt;Because it provides fast detection with high spatial accuracy, which is critical when working with architectural drawings.&lt;/p&gt;

&lt;p&gt;Once detected, the system extracts bounding boxes and spatial relationships between cabinets.&lt;/p&gt;

&lt;p&gt;This becomes the foundation for geometry reconstruction.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2 — Extracting Measurements
&lt;/h3&gt;

&lt;p&gt;Cabinet drawings include important measurements like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Width&lt;/li&gt;
&lt;li&gt;Height&lt;/li&gt;
&lt;li&gt;Depth&lt;/li&gt;
&lt;li&gt;Spacing between cabinets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We use OCR pipelines to extract measurement text from the drawing.&lt;/p&gt;

&lt;p&gt;But raw text is messy.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;W 36"
H 34 1/2"
D 24"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where AI interpretation becomes necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 — Using an LLM to Understand Dimensions
&lt;/h3&gt;

&lt;p&gt;The extracted text is passed to an LLM layer that converts ambiguous measurements into structured data.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Raw text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;36 W x 34.5 H x 24 D
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Converted into structured format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
 width: 36,
 height: 34.5,
 depth: 24
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LLM also resolves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;inconsistent labels&lt;/li&gt;
&lt;li&gt;missing context&lt;/li&gt;
&lt;li&gt;measurement formatting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This step turns visual annotations into reliable numerical data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4 — Reconstructing Cabinet Geometry
&lt;/h3&gt;

&lt;p&gt;Once we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cabinet detection&lt;/li&gt;
&lt;li&gt;dimensions&lt;/li&gt;
&lt;li&gt;layout relationships&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can generate structured cabinet geometry.&lt;/p&gt;

&lt;p&gt;Each cabinet becomes a parametric object like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cabinet {
  type: Base
  width: 36
  height: 34.5
  depth: 24
  position: (x,y)
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From this structure we can generate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;3D models&lt;/li&gt;
&lt;li&gt;AutoCAD DWG files&lt;/li&gt;
&lt;li&gt;manufacturing layouts&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 5 — Exporting CAD and 3D Models
&lt;/h3&gt;

&lt;p&gt;The final step converts structured geometry into formats used by design tools.&lt;/p&gt;

&lt;p&gt;Outputs include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DWG files&lt;/li&gt;
&lt;li&gt;3D cabinet assemblies&lt;/li&gt;
&lt;li&gt;layout visualizations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this stage, designers can directly open the results inside CAD software.&lt;/p&gt;

&lt;p&gt;What previously required hours of manual work can now be generated automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Challenges We Faced
&lt;/h2&gt;

&lt;p&gt;Building this system exposed several real-world problems.&lt;/p&gt;

&lt;h4&gt;
  
  
  Drawing Variability
&lt;/h4&gt;

&lt;p&gt;No two cabinet drawings are identical.&lt;/p&gt;

&lt;p&gt;Different designers use different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;annotation styles&lt;/li&gt;
&lt;li&gt;measurement formats&lt;/li&gt;
&lt;li&gt;symbols&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://cizotech.com/" rel="noopener noreferrer"&gt;AI system&lt;/a&gt; must handle high variation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaling and Measurement Accuracy
&lt;/h3&gt;

&lt;p&gt;Architectural drawings use scaled representations.&lt;/p&gt;

&lt;p&gt;We had to design logic that converts pixel measurements into real-world dimensions.&lt;/p&gt;

&lt;p&gt;Even small errors could break cabinet assembly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Spatial Relationships
&lt;/h3&gt;

&lt;p&gt;Cabinets are not isolated objects.&lt;/p&gt;

&lt;p&gt;They depend on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;walls&lt;/li&gt;
&lt;li&gt;appliances&lt;/li&gt;
&lt;li&gt;adjacent cabinets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The system must understand layout context, not just object detection.&lt;/p&gt;

&lt;h3&gt;
  
  
  What This Enables
&lt;/h3&gt;

&lt;p&gt;Automating cabinet interpretation unlocks several possibilities:&lt;/p&gt;

&lt;p&gt;Faster cabinet design workflows&lt;/p&gt;

&lt;p&gt;Automated CAD generation&lt;/p&gt;

&lt;p&gt;Reduced manual drafting work&lt;/p&gt;

&lt;p&gt;Faster manufacturing preparation&lt;/p&gt;

&lt;p&gt;In the future, systems like this could process entire architectural plans, not just cabinets.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Most industries still rely on documents created for humans, not machines.&lt;/p&gt;

&lt;p&gt;But with the right combination of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;computer vision&lt;/li&gt;
&lt;li&gt;detection models&lt;/li&gt;
&lt;li&gt;language models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;we can convert visual design documents into structured data pipelines.&lt;/p&gt;

&lt;p&gt;Cabinet drawings are just one example.&lt;/p&gt;

&lt;p&gt;The bigger opportunity lies in automating how machines read and understand design documents.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>computervision</category>
      <category>automation</category>
    </item>
    <item>
      <title>We Integrated JobTread + CompanyCam into a Daily Reporting Workflow. Timing Was the Hard Part.</title>
      <dc:creator>CIZO</dc:creator>
      <pubDate>Tue, 24 Feb 2026 16:13:19 +0000</pubDate>
      <link>https://forem.com/cizo/we-integrated-jobtread-companycam-into-a-daily-reporting-workflow-timing-was-the-hard-part-539o</link>
      <guid>https://forem.com/cizo/we-integrated-jobtread-companycam-into-a-daily-reporting-workflow-timing-was-the-hard-part-539o</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2xo4arkkknq4qkxpvjy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2xo4arkkknq4qkxpvjy.png" alt=" " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’ve built automations in the real world, you’ve probably had this moment.&lt;/p&gt;

&lt;p&gt;The workflow looks perfect in testing.&lt;br&gt;
The triggers fire.&lt;br&gt;
The messages appear.&lt;br&gt;
The demo is clean.&lt;/p&gt;

&lt;p&gt;Then production starts.&lt;/p&gt;

&lt;p&gt;And the system doesn’t “break.” It becomes unreliable.&lt;/p&gt;

&lt;p&gt;That’s what happened when we built an automation layer around &lt;strong&gt;JobTread&lt;/strong&gt; and &lt;strong&gt;CompanyCam&lt;/strong&gt; to produce daily job reports for leadership.&lt;/p&gt;

&lt;p&gt;The data already existed.&lt;/p&gt;

&lt;p&gt;Field teams were documenting work inside &lt;strong&gt;CompanyCam&lt;/strong&gt;. Job context lived in &lt;strong&gt;JobTread&lt;/strong&gt;. Photos and descriptions were already being captured.&lt;/p&gt;

&lt;p&gt;So on the surface, it looks like a simple problem.&lt;/p&gt;

&lt;p&gt;“Just summarize what’s already there.”&lt;/p&gt;

&lt;p&gt;But when you attempt that with naive event triggers, you discover the real problem isn’t summarization.&lt;/p&gt;

&lt;p&gt;It’s timing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why timing destroys most automations
&lt;/h2&gt;

&lt;p&gt;Most people build these workflows as a chain reaction.&lt;/p&gt;

&lt;p&gt;A photo gets uploaded → run the automation.&lt;br&gt;
A description is updated → run again.&lt;br&gt;
A job status changes → run again.&lt;/p&gt;

&lt;p&gt;This creates the illusion of “real-time reporting.”&lt;/p&gt;

&lt;p&gt;What it actually creates is reporting drift.&lt;/p&gt;

&lt;p&gt;The summary changes depending on when it runs. A late photo changes the output. A sync delay causes partial context. Two events fire close together and you generate duplicates. Leadership sees conflicting versions and stops trusting it.&lt;/p&gt;

&lt;p&gt;This is one of those automation failure modes that doesn’t show up as an error.&lt;/p&gt;

&lt;p&gt;Everything “works.”&lt;/p&gt;

&lt;p&gt;And that’s why it’s dangerous.&lt;/p&gt;

&lt;h2&gt;
  
  
  The design change that stabilized everything
&lt;/h2&gt;

&lt;p&gt;We stopped treating reporting as an event reaction.&lt;/p&gt;

&lt;p&gt;We treated it as a deliberate system artifact.&lt;/p&gt;

&lt;p&gt;That means we introduced a controlled activation model.&lt;/p&gt;

&lt;p&gt;Instead of “run whenever anything changes,” the system generates one report when the reporting window is considered ready.&lt;/p&gt;

&lt;p&gt;One job.&lt;br&gt;
One day.&lt;br&gt;
One report.&lt;/p&gt;

&lt;p&gt;If you’re used to automation thinking, this might feel like less automation.&lt;/p&gt;

&lt;p&gt;In practice, it’s more dependable automation.&lt;/p&gt;

&lt;p&gt;Because now you have a boundary.&lt;/p&gt;

&lt;p&gt;You know what moment counts as “report time.”&lt;br&gt;
You know what gets included.&lt;br&gt;
You know what’s ignored.&lt;br&gt;
You stop fighting late updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why structured AI output matters
&lt;/h2&gt;

&lt;p&gt;Once timing is controlled, the second thing that breaks trust is unstructured output.&lt;/p&gt;

&lt;p&gt;If you use AI as a generic summarizer, the output becomes a paragraph. That paragraph changes depending on phrasing. It may be accurate, but it’s not decision-ready.&lt;/p&gt;

&lt;p&gt;Operational reporting needs consistent sections.&lt;/p&gt;

&lt;p&gt;It needs to answer the same questions every day in roughly the same shape.&lt;/p&gt;

&lt;p&gt;So we treated the &lt;a href="https://cizotech.com/ai-product-development-services/" rel="noopener noreferrer"&gt;AI&lt;/a&gt; layer like a constrained renderer.&lt;/p&gt;

&lt;p&gt;Not a writer.&lt;/p&gt;

&lt;p&gt;We shaped the output around what leadership actually needs:&lt;/p&gt;

&lt;p&gt;What work was completed.&lt;br&gt;
What material was used.&lt;br&gt;
What issues happened.&lt;br&gt;
What’s blocked.&lt;br&gt;
What’s planned next.&lt;/p&gt;

&lt;p&gt;When output has structure, you get operational clarity.&lt;/p&gt;

&lt;p&gt;When output doesn’t, you get “AI text.” And people tune out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why delivery channel matters
&lt;/h2&gt;

&lt;p&gt;A lot of automations “work” but don’t get used because they land in the wrong place.&lt;/p&gt;

&lt;p&gt;If leadership has to log into another tool to see the report, it becomes optional. Optional becomes ignored.&lt;/p&gt;

&lt;p&gt;So the report had to land where leadership already operates.&lt;/p&gt;

&lt;p&gt;When reports arrive consistently in the same channel, people start building habits around them.&lt;/p&gt;

&lt;p&gt;That’s when automation stops being a novelty and becomes part of operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  The actual lesson
&lt;/h2&gt;

&lt;p&gt;Most automation tutorials teach you how to connect tools.&lt;/p&gt;

&lt;p&gt;Production automation is about controlling behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It’s about deciding:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When should the system generate a report?&lt;br&gt;
What counts as the reporting window?&lt;br&gt;
How do you prevent duplicates?&lt;br&gt;
What happens when data arrives late?&lt;br&gt;
How do you keep output stable?&lt;/p&gt;

&lt;p&gt;If you don’t answer those questions early, your automation will slowly collapse under timing variability.&lt;/p&gt;

&lt;p&gt;Not because the tools failed.&lt;/p&gt;

&lt;p&gt;Because the system never decided how it should behave when timing is imperfect.&lt;/p&gt;

&lt;p&gt;And timing is always imperfect.&lt;/p&gt;

&lt;p&gt;That’s what production teaches you.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>systemdesign</category>
      <category>ai</category>
      <category>software</category>
    </item>
    <item>
      <title>If Your AI Product Can’t Handle Deletion, It Can’t Handle Monetization</title>
      <dc:creator>CIZO</dc:creator>
      <pubDate>Tue, 17 Feb 2026 10:27:45 +0000</pubDate>
      <link>https://forem.com/cizo/if-your-ai-product-cant-handle-deletion-it-cant-handle-monetization-46ee</link>
      <guid>https://forem.com/cizo/if-your-ai-product-cant-handle-deletion-it-cant-handle-monetization-46ee</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc8dbk1pndvmo5kbkbvwq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc8dbk1pndvmo5kbkbvwq.png" alt=" " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There’s a structural issue most AI products ignore until it’s too late.&lt;/p&gt;

&lt;p&gt;Deletion.&lt;/p&gt;

&lt;p&gt;Not model quality. &lt;br&gt;
Not inference speed. &lt;br&gt;
Not embeddings.&lt;/p&gt;

&lt;p&gt;Deletion.&lt;/p&gt;

&lt;p&gt;While designing a monetized AI system recently, we ran into something that forced a complete rethink of the architecture.&lt;/p&gt;

&lt;p&gt;The product allowed users to:&lt;br&gt;
• Chat freely (ephemeral conversations for safety)&lt;br&gt;
• Pay to preserve meaningful interactions&lt;br&gt;
• Delete their account at any time&lt;br&gt;
• Expect compliance-grade data handling&lt;/p&gt;

&lt;p&gt;Individually, each requirement made sense.&lt;/p&gt;

&lt;p&gt;Together, they conflicted.&lt;/p&gt;

&lt;p&gt;Because the moment a user pays to preserve a conversation, you’ve created a retention contract.&lt;/p&gt;

&lt;p&gt;And if your deletion logic doesn’t respect that contract at the data layer, monetization becomes unstable.&lt;/p&gt;
&lt;h2&gt;
  
  
  Where Most Systems Go Wrong
&lt;/h2&gt;

&lt;p&gt;The naive implementation looks like this:&lt;br&gt;
• Store conversations in a table&lt;br&gt;
• Add a saved = true column&lt;br&gt;
• Add subscription checks in business logic&lt;br&gt;
• Prevent deletion via UI if needed&lt;/p&gt;

&lt;p&gt;It works during demos.&lt;/p&gt;

&lt;p&gt;It works in staging.&lt;/p&gt;

&lt;p&gt;It even works for the first few hundred users.&lt;/p&gt;

&lt;p&gt;Then:&lt;br&gt;
• TTL cleanup jobs run&lt;br&gt;
• Subscriptions expire&lt;br&gt;
• Account deletion triggers cascade rules&lt;br&gt;
• Compliance requests arrive&lt;br&gt;
• Billing records need audit consistency&lt;/p&gt;

&lt;p&gt;And suddenly, your “saved” boolean means nothing.&lt;/p&gt;

&lt;p&gt;Deletion is not a UI concern.&lt;/p&gt;

&lt;p&gt;It is a structural authority problem.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Architectural Separation That Fixes It
&lt;/h2&gt;

&lt;p&gt;The system only stabilized when we separated:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Interaction objects&lt;/li&gt;
&lt;li&gt;Materialized persistence&lt;/li&gt;
&lt;li&gt;Retention authority&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The flow became explicit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Message
 ↓
ConversationThread (ephemeral, TTL governed)
 ↓
Message (ephemeral)
 ↓
User selects “Save”
 ↓
ChronicleAsset (materialized snapshot)
 ↓
Entitlement (retention authority)
 ↓
DeletionRequest → Entitlement Check → Cascade Rules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The critical insight:&lt;br&gt;
Threads are not the retention boundary. &lt;br&gt;
ChronicleAssets are.&lt;/p&gt;

&lt;p&gt;Once you define that boundary, deletion and monetization stop fighting each other.&lt;/p&gt;

&lt;p&gt;Chronicle as a Materialized Snapshot&lt;/p&gt;

&lt;p&gt;A saved conversation cannot remain a mutable thread.&lt;/p&gt;

&lt;p&gt;It must become its own immutable artifact.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ChronicleAsset {
 chronicle_asset_id: UUID,
 source_thread_id: UUID,
 owner_user_id: UUID,
 snapshot_ref: ObjectStoreURI,
 created_at: timestamp,
 immutable: true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it structurally distinct from live interaction.&lt;/p&gt;

&lt;p&gt;Deletion can wipe threads safely.&lt;/p&gt;

&lt;p&gt;But ChronicleAssets are governed by entitlements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Entitlement as Retention Authority
&lt;/h2&gt;

&lt;p&gt;Monetization must be enforced by data-level ownership rules — not UI locks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Entitlement {
 entitlement_id: UUID,
 user_id: UUID,
 target_entity_type: "ChronicleAsset",
 target_entity_id: UUID,
 status: "active" | "expired" | "revoked",
 valid_until: timestamp
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deletion logic becomes:&lt;br&gt;
• If no entitlement → cascade delete&lt;br&gt;
• If active entitlement → preserve asset&lt;br&gt;
• If compliance override → apply regulated deletion&lt;/p&gt;

&lt;p&gt;Without this structure, monetization will eventually contradict deletion.&lt;br&gt;
And when that happens, engineers are forced to debug philosophy using production data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters for AI Systems Specifically
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://cizotech.com/" rel="noopener noreferrer"&gt;AI products&lt;/a&gt; are not just inference systems.&lt;/p&gt;

&lt;p&gt;They are:&lt;br&gt;
• Memory systems&lt;br&gt;
• Identity systems&lt;br&gt;
• Retention systems&lt;br&gt;
• Authority systems&lt;/p&gt;

&lt;p&gt;Deletion exposes whether those systems are coherent.&lt;/p&gt;

&lt;p&gt;If your architecture cannot formally define:&lt;br&gt;
• What is ephemeral&lt;br&gt;
• What is materialized&lt;br&gt;
• What entity enforces retention&lt;br&gt;
• What overrides deletion&lt;br&gt;
• What must remain auditable&lt;/p&gt;

&lt;p&gt;Then you don’t have a production AI system.&lt;/p&gt;

&lt;p&gt;You have a prototype with pricing.&lt;/p&gt;

&lt;p&gt;Monetization is not a feature.&lt;/p&gt;

&lt;p&gt;It is a retention boundary decision.&lt;/p&gt;

&lt;p&gt;And if your AI product cannot survive deletion logic, it won’t survive scale&lt;/p&gt;

</description>
      <category>ai</category>
      <category>systemdesign</category>
      <category>architecture</category>
      <category>saas</category>
    </item>
    <item>
      <title>When AI Systems Scale, Dashboards Start to Get in the Way</title>
      <dc:creator>CIZO</dc:creator>
      <pubDate>Tue, 10 Feb 2026 05:41:13 +0000</pubDate>
      <link>https://forem.com/cizo/when-ai-systems-scale-dashboards-start-to-get-in-the-way-2fm9</link>
      <guid>https://forem.com/cizo/when-ai-systems-scale-dashboards-start-to-get-in-the-way-2fm9</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fffgm6hh0evlnblselxnw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fffgm6hh0evlnblselxnw.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As AI moves from experiments into real production systems, teams start to encounter a familiar pattern. It doesn’t show up during early demos or pilot phases. It appears later — once AI is embedded into workflows that people rely on every day.&lt;/p&gt;

&lt;p&gt;At that point, dashboards often stop being the center of the system. Over time, they become a source of friction.&lt;/p&gt;

&lt;p&gt;This isn’t an argument against dashboards. It’s a description of what tends to happen as &lt;a href="https://cizotech.com/ai-ml-mobile-app-development-services/" rel="noopener noreferrer"&gt;AI-driven systems&lt;/a&gt; grow in complexity and decision frequency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dashboards Are a Natural Starting Point&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dashboards work well early on.&lt;br&gt;
They provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visibility into system state&lt;/li&gt;
&lt;li&gt;Aggregated metrics and trends&lt;/li&gt;
&lt;li&gt;A clear place for humans to make decisions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When decisions are infrequent or low-risk, this setup is efficient. Humans review information, apply judgment, and trigger actions. Many early AI systems fit comfortably into this model, which is why dashboards become the default choice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where the Model Starts to Break&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As systems mature, the work changes.&lt;br&gt;
Teams begin to see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More decisions per day&lt;/li&gt;
&lt;li&gt;Increasingly conditional logic&lt;/li&gt;
&lt;li&gt;Time-sensitive actions with downstream impact&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this stage, dashboards don’t fail technically. The data is still accurate. The issue is operational.&lt;/p&gt;

&lt;p&gt;People spend more time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monitoring screens&lt;/li&gt;
&lt;li&gt;Correlating signals across tools&lt;/li&gt;
&lt;li&gt;Acting as intermediaries between systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The system technically works — but human attention becomes the bottleneck.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From Monitoring to Execution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once decision volume crosses a certain threshold, teams usually stop asking how to visualize information better and start asking why someone needs to look at it at all.&lt;br&gt;
This is where the system begins to change shape.&lt;br&gt;
Instead of reporting state and waiting, parts of the system start to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trigger actions automatically&lt;/li&gt;
&lt;li&gt;Apply predefined rules&lt;/li&gt;
&lt;li&gt;Escalate exceptions&lt;/li&gt;
&lt;li&gt;Log outcomes for later review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dashboards don’t disappear, but they stop being the primary interface. Their role shifts toward oversight instead of direct control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agents as an Architectural Response&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This transition often introduces what are commonly called “agents.”&lt;br&gt;
In practice, these aren’t chatbots or unconstrained autonomous systems. They are bounded execution units designed to reduce coordination overhead.&lt;/p&gt;

&lt;p&gt;An agent typically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Has access to relevant context&lt;/li&gt;
&lt;li&gt;Applies defined decision logic&lt;/li&gt;
&lt;li&gt;Takes action or escalates&lt;/li&gt;
&lt;li&gt;Reports what happened&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agents emerge not because they’re trendy, but because dashboards alone don’t scale well once execution becomes the dominant concern.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Changes When Agents Take Over Execution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As agents move closer to the core workflow, several patterns tend to emerge:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fewer interfaces&lt;/strong&gt;
Teams stop adding dashboards for every edge case.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clearer accountability&lt;/strong&gt;
Decisions are automated, escalated, or logged explicitly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lower cognitive load&lt;/strong&gt;
Humans focus on exceptions instead of constant monitoring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More consistent behavior&lt;/strong&gt;
System outcomes depend less on who is watching at a given moment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dashboards still matter — they just stop being the system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Humans Don’t Disappear From the Loop&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;None of the systems we’ve seen aimed for full automation.&lt;br&gt;
Humans remain essential for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Oversight and review&lt;/li&gt;
&lt;li&gt;Handling ambiguous or novel cases&lt;/li&gt;
&lt;li&gt;Defining policies and constraints&lt;/li&gt;
&lt;li&gt;Evaluating whether automation still makes sense&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As systems mature, human involvement becomes less frequent but more intentional.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implications for Teams Building AI Systems&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A few practical lessons tend to follow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Design workflows around actions, not just views&lt;/li&gt;
&lt;li&gt;Treat dashboards as optional components, not architectural anchors&lt;/li&gt;
&lt;li&gt;Expect interfaces to evolve as decision complexity increases&lt;/li&gt;
&lt;li&gt;Avoid heavy UI investment before execution paths are clear&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not every system needs agents. But beyond a certain scale, dashboards alone rarely hold up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Designing for System Behavior, Not Interfaces&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This shift isn’t a prediction about the future of software. It reflects how systems already behave once AI moves from analysis to execution.&lt;/p&gt;

&lt;p&gt;As responsibility shifts from people to systems, interfaces naturally become secondary. Teams that recognize this early spend less time managing dashboards — and more time improving how decisions actually get made.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>systemdesign</category>
      <category>agents</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Architecting AI Systems Before Features Exist</title>
      <dc:creator>CIZO</dc:creator>
      <pubDate>Mon, 02 Feb 2026 11:13:46 +0000</pubDate>
      <link>https://forem.com/cizo/architecting-ai-systems-before-features-exist-2fbb</link>
      <guid>https://forem.com/cizo/architecting-ai-systems-before-features-exist-2fbb</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnon4pukz8xw46f6vunh1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnon4pukz8xw46f6vunh1.png" alt=" " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Architecting AI Systems Before Features Exist&lt;/p&gt;

&lt;p&gt;Most AI failures aren’t model failures.&lt;/p&gt;

&lt;p&gt;They’re system failures caused by optimizing for capability before control.&lt;/p&gt;

&lt;p&gt;Before features, we focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;isolating inference from orchestration&lt;/li&gt;
&lt;li&gt;defining behavior under uncertainty&lt;/li&gt;
&lt;li&gt;bounding system responses&lt;/li&gt;
&lt;li&gt;designing explicit override paths&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Accuracy metrics don’t capture stability.&lt;/p&gt;

&lt;p&gt;Highly sensitive systems react to noise.&lt;br&gt;
Stable systems absorb it.&lt;/p&gt;

&lt;p&gt;In production, consistency matters more than precision.&lt;/p&gt;

&lt;p&gt;That consistency comes from architecture, not training.&lt;/p&gt;

&lt;p&gt;Models will change.&lt;br&gt;
Policies will evolve.&lt;br&gt;
Usage will drift.&lt;/p&gt;

&lt;p&gt;Systems designed for replacement survive those changes.&lt;/p&gt;

&lt;p&gt;Systems designed for demos don’t.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>systemdesign</category>
      <category>machinelearning</category>
      <category>software</category>
    </item>
    <item>
      <title>Why High Accuracy Didn’t Save Our Real-Time AI System</title>
      <dc:creator>CIZO</dc:creator>
      <pubDate>Wed, 28 Jan 2026 17:32:03 +0000</pubDate>
      <link>https://forem.com/cizo/why-high-accuracy-didnt-save-our-real-time-ai-system-1eem</link>
      <guid>https://forem.com/cizo/why-high-accuracy-didnt-save-our-real-time-ai-system-1eem</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcci4np1anxx5xkfs7vyi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcci4np1anxx5xkfs7vyi.png" alt=" " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Accuracy was not the thing that broke our system.&lt;/p&gt;

&lt;p&gt;At least not in the way we expected.&lt;/p&gt;

&lt;p&gt;We were working on a real-time AI system that had to react to human movement during live sessions. The early versions looked great on paper. Accuracy metrics were strong. Benchmarks improved steadily.&lt;/p&gt;

&lt;p&gt;From a model perspective, everything was “working.”&lt;/p&gt;

&lt;p&gt;But once the system was used outside controlled conditions, problems started to appear.&lt;/p&gt;

&lt;p&gt;Lighting changed across sessions.&lt;br&gt;
Users moved slightly differently each time.&lt;br&gt;
Hardware behaved inconsistently over time.&lt;/p&gt;

&lt;p&gt;None of these were bugs. They were normal.&lt;/p&gt;

&lt;p&gt;The system, however, treated them like errors.&lt;/p&gt;

&lt;p&gt;Small variations triggered corrections.&lt;br&gt;
Feedback jittered.&lt;br&gt;
Outputs changed from moment to moment.&lt;/p&gt;

&lt;p&gt;Nothing was technically incorrect, but the behavior felt unreliable.&lt;/p&gt;

&lt;p&gt;That’s when we realized the real issue wasn’t accuracy.&lt;/p&gt;

&lt;p&gt;It was sensitivity.&lt;/p&gt;

&lt;p&gt;The system was reacting too quickly to noise. It was optimized to be precise frame-by-frame, but not stable across real usage.&lt;/p&gt;

&lt;p&gt;So we made a decision that felt wrong at first.&lt;/p&gt;

&lt;p&gt;We reduced model sensitivity.&lt;/p&gt;

&lt;p&gt;We smoothed signals over time.&lt;br&gt;
We raised confidence thresholds.&lt;br&gt;
We allowed small variations to pass without reaction.&lt;/p&gt;

&lt;p&gt;On paper, accuracy metrics dropped.&lt;/p&gt;

&lt;p&gt;In production, usability improved almost immediately.&lt;/p&gt;

&lt;p&gt;The system stopped overcorrecting.&lt;br&gt;
Outputs became predictable.&lt;br&gt;
Users trusted it more.&lt;/p&gt;

&lt;p&gt;What surprised us most was how quickly behavior changed once trust returned. Coaches used the system consistently. Sessions lasted longer. Adoption improved without changing anything else.&lt;/p&gt;

&lt;p&gt;This experience changed how we think about production AI.&lt;/p&gt;

&lt;p&gt;Accuracy metrics answer an important question:&lt;br&gt;
“How often is the model correct under expected conditions?”&lt;/p&gt;

&lt;p&gt;Production systems need to answer a different one:&lt;br&gt;
“How does the system behave when conditions are wrong?”&lt;/p&gt;

&lt;p&gt;If a system behaves inconsistently when inputs are noisy, users will stop trusting it — even if the model is technically accurate.&lt;/p&gt;

&lt;p&gt;This pattern shows up far beyond sports.&lt;/p&gt;

&lt;p&gt;In healthcare, overly sensitive systems create alert fatigue.&lt;br&gt;
In operations platforms, false positives cause teams to ignore signals.&lt;br&gt;
In real-time tools, unstable behavior breaks workflows.&lt;/p&gt;

&lt;p&gt;In all of these cases, consistency matters more than precision.&lt;/p&gt;

&lt;p&gt;The takeaway for anyone building production AI is simple:&lt;/p&gt;

&lt;p&gt;Accuracy matters.&lt;br&gt;
But predictable behavior matters more.&lt;/p&gt;

&lt;p&gt;If a system cannot tolerate noise, misuse, and imperfect conditions, it won’t survive contact with real users.&lt;/p&gt;

&lt;p&gt;Benchmarks don’t reveal that.&lt;br&gt;
Production does.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>systemdesign</category>
      <category>machinelearning</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
