LLM neural network blending into traditional code circuit board
Workflow Automation Design Pattern

LLMs & Traditional Code
Complementary Roles in Automation

The most robust automated pipelines assign each component to the layer best suited for it — language models for reasoning and discovery, deterministic code for precision and enforcement.

The Core Division of Labour

LLMs and traditional code are not competitors — they occupy fundamentally different roles in a well-designed pipeline. Understanding where each excels prevents the subtle failures that arise from asking either layer to do the other's job.

◆ LLM Layer

Reasoning & Discovery

Language models excel at understanding context, ambiguity, and natural language. They interpret intent, synthesise information from unstructured sources, make judgment calls, and reduce ambiguity — turning fuzzy inputs into structured outputs that deterministic code can act on.

◆ Code Layer

Precision & Enforcement

Traditional code enforces business rules with binary correctness. It validates, filters, calculates, routes, and executes — tasks where the answer is either right or wrong, and where reliability and auditability are non-negotiable.

Typical pipeline flow — LLM reduces ambiguity, code acts on the result:
LLM
Interpret Input
Understand intent from natural language or unstructured data
LLM
Discover & Classify
Find the right resource, entity, or category via reasoning
Code
Extract & Validate
Parse structured data, check constraints, verify correctness
Code
Execute & Enforce
Apply business rules, route, sync, and audit the result

Domain-by-Domain Examples

Across every automation domain, the same pattern recurs: the LLM handles the parts that require understanding; code handles the parts that require precision.

📄

Data Extraction & Validation

Processing documents, invoices, resumes, and medical records

Task 🔵 LLM handles… 🟢 Code handles…
Invoice processing Identify which section is the line-items table; interpret ambiguous column headers Parse the identified table with a CSV/regex parser; validate that totals add up arithmetically
Resume parsing Understand that "Sr. SWE @ Google (2019–present)" means Senior Software Engineer at Google Extract dates with a date-parsing library; calculate tenure in months; normalise job title to a taxonomy
Medical records Interpret "Pt c/o SOB x3d" as shortness of breath for three days; map clinical shorthand to concepts Validate ICD-10 codes against a lookup table; flag out-of-range lab values; enforce required field presence
🔀

Classification & Routing

Customer support triage, content moderation, email prioritisation

Task 🔵 LLM handles… 🟢 Code handles…
Support triage Classify a free-text complaint into category (billing, technical, returns) and sentiment Route to the correct queue; apply SLA timers; trigger escalation rules based on category + priority
Content moderation Judge whether an ambiguous post violates community guidelines given context and intent Apply deterministic blocklists for known slurs; rate-limit flagging; log every decision to an audit trail
Email prioritisation Determine urgency and intent from free-text email body; identify action required Sort inbox by priority score; deduplicate threads; apply calendar-based rules; trigger reminders
✍️

Code & Document Generation

SQL generation, contract drafting, automated reporting

Task 🔵 LLM handles… 🟢 Code handles…
SQL generation Translate "show me top customers by revenue last quarter" into a SQL query Validate the query against the schema before running; sanitise against injection; enforce row-level access controls
Contract drafting Draft narrative clauses based on deal parameters, jurisdiction, and negotiation history Fill dates, party names, and dollar amounts from structured data; validate all required fields are present
Report generation Write the executive summary and key insights; frame findings in context Calculate the underlying metrics; generate charts; assemble and paginate the final PDF
🔍

Search & Retrieval (RAG Pipelines)

Enterprise knowledge search, legal research, e-commerce product search

Task 🔵 LLM handles… 🟢 Code handles…
Enterprise search Rewrite a vague user question into precise search terms; synthesise an answer from retrieved chunks Perform the vector similarity search; apply access-control filters; rank results by recency and relevance score
Legal research Identify which retrieved case excerpts are actually relevant to the argument being made Retrieve cases from a citation database; enforce jurisdiction and date-range filters; deduplicate results
Product search Interpret "something warm for a winter hike under $100" as a semantic product query Apply the price filter; check real-time inventory status; sort by margin and relevance score
🏢

CRM & Lead Enrichment

Contact enrichment, meeting automation, expense processing

Task 🔵 LLM handles… 🟢 Code handles…
Contact enrichment Find the correct website for a person by name; confirm their identity on the page via context Scrape phone/location with regex from the verified page; compute confidence scores; sync fields to CRM via API
Meeting notes Extract action items, owners, and deadlines from messy transcript text Create tasks in the project management tool via API; set due dates; assign owners by name-matching against the user directory
Expense processing Determine whether an expense is business-justified from a free-text description and context Apply per-category spending limits; calculate totals; flag policy violations; route for approval

⚡ The Two-Question Decision Rule

Is correctness ambiguous or context-dependent?

If the answer depends on understanding meaning, intent, or nuance — and a human expert would need to read and reason about it — assign it to the LLM layer.

Is correctness binary and verifiable?

If the answer is either right or wrong, can be checked against a schema, rule, or calculation, and must be auditable — assign it to the code layer.

What Each Layer Should Own

Blurring this boundary is the most common source of subtle pipeline failures — asking an LLM to be precise, or asking code to be flexible.

🔵 LLM Layer — Owns

  • Interpreting natural language and ambiguous inputs
  • Discovering the right entity, resource, or category
  • Synthesising answers from unstructured sources
  • Making judgment calls with incomplete information
  • Generating language: summaries, drafts, scripts, queries
  • Reducing ambiguity so downstream code can act

🟢 Code Layer — Owns

  • Extracting structured data with regex and parsers
  • Validating outputs against schemas and constraints
  • Enforcing business rules deterministically
  • Performing arithmetic and aggregations
  • Routing, scheduling, and triggering downstream actions
  • Logging, auditing, and maintaining an evidence trail
Real-World Case Study

How This Pattern Was Applied in Lead Intelligence Pro

Lead Intelligence Pro enriches sales contacts by automatically finding phone numbers, locations, company websites, pain points, competitors, ideal sales offers, and a lot more, for leads imported from GoHighLevel. The most instructive moment in building this pipeline was discovering what Claude could not reliably do — and what a few lines of deterministic code could.

🏢

The Problem: Enriching Personal-Email Contacts

When a contact with a personal email (e.g. drlancehoose@gmail.com) is submitted for enrichment, the system needs to find their phone number, city/state, and professional website — none of which are stored in the CRM. Personal emails carry no domain signal, so there is no obvious starting point. The first instinct was to ask Claude to find everything.

Phase 1: Asking Claude to Do It All

The initial approach gave Claude the contact's name, email, job title, and company name, then asked it to return a phone number and location directly from its web research.

⚠️ What Happened — Claude Couldn't Reliably Extract Structured Data

Claude is an excellent researcher but a poor structured-data extractor. When asked to return a phone number directly, it would frequently:

  • Return nothing — at first it would find the wrong website, or hallucinate one. When that was handled so that it would reliably find the correct website (took a lot of work just to get it able to do this!), it would fail to extract the phone number from the footer HTML, reporting it as unavailable
  • Hallucinate a number — it would confidently return a phone number that did not appear anywhere on the actual page
  • Return an inconsistent format — the same number would come back as (918) 742-0560, 918-742-0560, or +19187420560 depending on the run
  • Produce no confidence signal — there was no way to know whether the number came from the live website (which it didn't) or from Claude's training data

The root cause: Claude reads pages as rendered text. Phone numbers in footer HTML, structured address blocks, and schema.org markup are often invisible to it or get lost in the noise of the full page. Pattern-matching against raw HTML is not what language models are built for.

Phase 2: Splitting the Responsibility

The fix was to stop asking Claude to do the extraction entirely, and instead split the task along the natural boundary between reasoning and pattern-matching.

LLM Layer — What Claude Is Good At

Identity Discovery & Confirmation

Claude receives the contact's name, email, job title, and company name. It reasons about which professional website most plausibly belongs to this person - for example, concluding that "Lance Hoose, owner of a chiropractic wellness center in Tulsa" maps to drlancehoose.com — then visits the page to confirm the name appears on it. This is a judgment call that requires understanding context. Claude does it well (but only after it was trained within an inch of its life!).

Code Layer — What a Scraper Is Good At

Structured Data Extraction via Regex

Once Claude has identified and confirmed the correct URL, a deterministic server-side scraper (websiteScraper.ts) fetches the page and applies regex patterns to the raw HTML — targeting footer markup, structured address blocks, and schema.org JSON-LD. It either finds a phone number or it does not. No hallucination is possible. No format inconsistency. The result is binary and auditable.

Code Layer — Confidence & CRM Sync

Badge Assignment & GoHighLevel Write-Back

A computeConfidence() function assigns each field a badge based on its source: Verified (People Data Labs), Researched (server-scraped), or Inferred (LLM-generated). Fields are then written back to the contact in GoHighLevel via the REST API. All of this is deterministic — no LLM involvement after the URL is confirmed.

The Result — Before & After

The same contact record for Dr. Lance Hoose (chiropractor, Tulsa OK), with Claude doing all extraction vs. Claude finding the URL and the scraper extracting the data:

Claude Doing Everything
  • Phone — missing or hallucinated on repeated runs
  • Location — always incorrect
  • Website — correct (eventually)
  • No way to distinguish live-scraped from training-data values
  • Sales rep cannot trust the data without manually verifying
Claude + Code Scraper
  • Phone (918) 742-0560 — Researched, scraped from footer
  • Location Tulsa, OK — Researched, scraped from address block
  • Website drlancehoose.com — Researched, confirmed by Claude
  • Every value traceable to its source; confidence badges are accurate
  • Sales rep calls with confidence — the number is real
✅ The Lesson

Claude was never the right tool for extracting a phone number or location from a webpage — that was always a job for a regex pattern against raw HTML. Claude was the right tool for the part that required judgment: figuring out which website belonged to this person in the first place.

The moment we stopped asking the LLM to do the code's job, the pipeline became reliable. The skill is knowing where to draw the line.

LLMs & Traditional Code: Complementary Roles in Workflow Automation  ·  Lead Intelligence Pro