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.
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.
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.
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
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.
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
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.
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.
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+19187420560depending 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.
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!).
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.
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:
- 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
- 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
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.