For the complete documentation index, see llms.txt. This page is also available as Markdown.

LLM Integration

Integrate LLMs into your pipelines ..

Overview - LLM

Everything hinges on making a clean POST request to Ollama's /api/generate endpoint at http://localhost:11434. This is a local REST API, so there's no external dependency, no API key, and no network latency.

The request payload structure is:

{
  "model": "llama3.2:3b",
  "prompt": "Your instruction here...",
  "stream": false,
  "format": "json",
  "keep_alive": "30m",
  "options": {
    "temperature": 0.1,
    "num_predict": 300,
    "num_ctx": 2048,
    "num_thread": 0
  }
}

Parameters:

model — Which Ollama model to invoke. The workshops use llama3.2:3b as the default: compact enough to run on CPU-only hardware but capable enough for structured tasks. You can scale up to llama3.1:8b for harder problems at the cost of speed.

stream: false — This is critical for PDI. Streaming sends tokens incrementally, which is great for chat UIs but useless in an ETL row-by-row context. Setting this to false tells Ollama to generate the entire response, then return it as one complete JSON object — which is what PDI needs to write into a field.

format: "json" — Forces the model's output to be valid JSON. Without this, the model might add conversational preamble, markdown fences, or explanations around its JSON answer, all of which break downstream parsing.

keep_alive — This is the single biggest performance optimization for batch processing. By default Ollama unloads the model from memory after each request. Reloading takes 10–30 seconds depending on model size and disk speed. Setting keep_alive: "30m" keeps the model resident in RAM across all rows in a batch run, turning a multi-hour job into a fraction of that time.

temperature: 0.1 — Controls randomness. Values near 0 produce near-deterministic output, meaning the same review will produce the same sentiment classification on repeated runs. This is essential for reproducible ETL — you don't want results changing every time the pipeline runs.

num_predict: 300 — Caps the maximum tokens generated. This prevents runaway generation, protects processing time, and avoids unexpectedly large response payloads overwhelming downstream steps.

When PDI's REST Client step receives the Ollama response, it comes back as a single JSON object with two categories of fields: the content fields that contain the actual result, and the performance/telemetry fields that tell you how the inference went.

The response field is a string containing JSON, not a nested object - which is why the pipeline requires two separate JSON Input steps: one to extract $.response from the Ollama wrapper, and a second to parse the actual model output into structured fields.

The response payload structure is:

Content Fields

model — Confirms which model actually processed the request. This is useful as a sanity check, especially in pipelines where the model name is injected via a PDI variable. If you're getting unexpected results, checking this field confirms whether the right model was used.

created_at — The UTC timestamp of when the response was generated. Useful for logging and auditing, particularly if you're persisting results to a database and need to track when the enrichment was applied.

response — This is the only field you actually care about for downstream processing. It contains the LLM's generated output as a string. Importantly, even when you pass "format": "json" in the request, Ollama still wraps the model's JSON output inside this string field rather than embedding it as a native JSON object. That's why the pipeline needs a JSON Input step to extract $.response first, then a second parsing pass to read the actual model output.

done — A boolean that signals whether generation completed. When true, the response is complete. When false, the model was interrupted or is still streaming (which shouldn't happen in PDI since you set stream: false, but worth checking during error handling).

done_reason — Explains why generation stopped. The value "stop" means the model reached a natural conclusion — it finished what it was saying. Other possible values include "length" (generation was cut off because it hit the num_predict token limit) and "load" (model was freshly loaded). If you see "length" in production, it means your responses are being truncated and you need to increase num_predict.

Performance / Telemetry Fields

All duration values are expressed in nanoseconds, so divide by 1,000,000,000 to get seconds.

total_duration — The wall-clock time for the entire request from when Ollama received it to when it returned the response. This is what you'd use to track end-to-end latency per record. In the sentiment analysis example, this was ~3.1 seconds for a short review.

load_duration — How long it took to load the model into memory before inference began. When keep_alive is working correctly and the model is already resident in RAM, this value drops to near zero for subsequent requests. If you see load_duration remaining high across all rows, it means the model is being reloaded on every request, which is a sign your keep_alive setting isn't being applied.

prompt_eval_count — The number of tokens in your input prompt. This is the tokenized length of everything you sent to the model. Monitoring this field is important for prompt optimization — the workshops show how cutting prompt length by 50% cuts processing time proportionally. If prompt_eval_count is unexpectedly high, your prompt likely has verbose instructions that can be trimmed.

prompt_eval_duration — How long the model spent processing (encoding) your prompt before it started generating the response. This is the "reading the question" phase. It's typically much shorter than eval_duration.

eval_count — The number of tokens in the generated response. This is your output token count. If this number is hitting your num_predict ceiling (e.g., exactly 300 when you set num_predict: 300), that's a strong signal that your responses are being truncated and you need to raise the limit or shorten your expected output schema.

eval_duration — How long the model spent actually generating the response tokens. This is almost always the dominant cost in total_duration. On CPU-only hardware, token generation speed is the bottleneck — typically the workshops see about 2.1 seconds of generation time for an 18-token response, which gives you a rough tokens-per-second figure for capacity planning.

context — An array of integers representing the internal token IDs that make up the conversation state. This is the model's "memory" of the exchange encoded as token references. For single-turn ETL tasks you can completely ignore this field. It only becomes relevant if you're building multi-turn conversation pipelines where you want to pass context back to the model in subsequent requests to maintain continuity.

Anatomy of a Good Prompt

The prompt is the only interface between your ETL data and the LLM. PDI handles reading, routing, and writing data - but the quality of what the model returns is entirely determined by how well you wrote the prompt. A vague prompt produces unpredictable output that breaks your JSON parser. A well-engineered prompt produces the same structured response every time, making the downstream pipeline reliable.

Using the sentiment analysis workshop as a concrete example, here's the prompt that gets constructed inside the Modified JavaScript Value step for each row:

And the PDI JavaScript that builds it:

Every element of this prompt is doing specific work.

The instruction is a verb, not a question.** "Analyze sentiment" is a direct command. Phrasing it as "Can you tell me the sentiment of this review?" wastes tokens and invites a conversational response rather than structured output.

The data is clearly delimited.** Wrapping the review text in quotes separates it visually and semantically from the instruction. Without this, the model can conflate the instruction with the data, especially for reviews that contain imperative language.

The schema is shown, not described.** Rather than writing "return a JSON object with a field called sentiment that can be positive, negative, or neutral", the prompt shows the exact JSON structure. The model pattern-matches against the example and fills in the values, which is far more reliable than parsing a verbal description of what you want.

Value constraints are embedded inline.** Specifying -1.0 to 1.0 for score and 0-100 for confidence directly in the schema means you don't need a separate instruction section. The model sees the range at the exact point where it needs to apply it.


The Cost of Verbosity

The Data Quality workshop makes this concrete. Here's the verbose version of a data cleaning prompt:

The verbose version uses roughly 120 tokens. The optimized version uses around 60. On a batch of 1,000 records running on CPU-only hardware at 23 seconds per record, that difference compounds into real time savings. The model doesn't need to be spoken to politely - it needs to be spoken to precisely.

Gotcha 1: ${VARIABLE} syntax doesn't work inside JavaScript strings.

This is the most common failure mode in the workshops and it produces a completely silent error. When you write:

PDI does not substitute the variable. The string ${MODEL_NAME} is sent literally to Ollama, which either returns a 400 Bad Request or — worse — tries to find a model named ${MODEL_NAME} and fails silently. The correct approach is always getVariable():

The ${PARAM} syntax only works in XML-based step configuration fields, not in JavaScript code blocks.


Gotcha 2: The model adds text around your JSON even with format: "json".

Even when you set "format": "json" in the Ollama request, some models — particularly on certain prompts — will wrap their JSON in markdown code fences or add a sentence before it:

If your JSON Input step tries to parse the full response field directly, it will fail because the surrounding text makes it invalid JSON. The defensive fix used in the workshops is to scan for the first { and last } in the response string and extract only that substring:

This makes your parser robust to model verbosity regardless of which model or version you're running.


Gotcha 3: Silent truncation when num_predict is too low.

If the model's response hits the num_predict token ceiling mid-generation, Ollama stops and returns whatever was generated so far. The done_reason field will say "length" instead of "stop", but if you're not logging that field, you'll never know.

The symptom is malformed JSON arriving at your parser - the object opens but never closes - which your error handler catches and routes to the failure path. The fix is to monitor eval_count in your output and raise num_predict if it consistently hits the ceiling.


Gotcha 4: Asking for too many fields degrades accuracy.

It's tempting to extract everything you might ever want in a single prompt. The NER workshop covers 10 entity types (PERSON, ORGANIZATION, LOCATION, DATE, PRODUCT, MONEY, CONTACT, ID, TECHNOLOGY, POSITION) simultaneously.

This works for NER because entity classification is a well-defined task. But for analytical prompts - asking for sentiment, tone, intent, key phrases, competitive mentions, urgency, and a summary all at once - models tend to fill in fields speculatively rather than accurately. If accuracy matters more than throughput, it's worth splitting complex prompts into focused single-purpose calls, even at the cost of additional API round trips.


Gotcha 5: Not escaping special characters in the source data.

When review text or customer data contains quotes, backslashes, or newlines, they can break your JavaScript string concatenation and produce a malformed JSON payload before it even reaches Ollama. A review like "Best product I've ever bought — 5 stars!" is fine, but one containing "He said \"amazing\" and I agree" will break the string if not handled. The fix is to sanitize input text before embedding it in the prompt:

This is especially important for free-text fields pulled from customer-facing systems where you have no control over what users type.

Select a workshop:

Sentiment Analysis

Workflow

sentiment_analysis_optimized
  1. Verify Ollama Installation.

Run through the following steps to build sentiment_analysis_optimized.ktr:

What is Sentiment Analysis?

Sentiment Analysis is the process of computationally identifying and categorizing opinions expressed in text to determine whether the writer's attitude toward a particular topic, product, or service is positive, negative, or neutral.

Example Input:

Example Output (Sentiment Analysis):

Why is Sentiment Analysis Important?

Business Applications:

  1. Customer Feedback Analysis - Automatically categorize thousands of reviews to identify satisfaction trends

  2. Brand Monitoring - Track public sentiment about your brand across social media and review sites

  3. Product Improvement - Identify which features customers love and which need improvement

  4. Customer Support Prioritization - Route angry customers to experienced support agents first

  5. Market Research - Understand customer opinions about competitor products

  6. Crisis Detection - Quickly identify negative sentiment spikes that require immediate attention

Real-World Example: A company receives 10,000 product reviews per month. Manual analysis would take weeks. With sentiment analysis:

  • Instant categorization: 7,500 positive, 1,800 neutral, 700 negative

  • Identify issues: Negative reviews mention "battery life" 450 times → product team investigates

  • Measure satisfaction: 75% positive sentiment score → track over time

  • Prioritize responses: Route the 200 most negative reviews to customer service

Types of Sentiment

1. Polarity (Basic)

  • Positive: "This product is amazing!"

  • Negative: "Terrible quality, waste of money"

  • Neutral: "The product arrived on Tuesday"

2. Granular Sentiment (Scored)

  • Very Positive: +0.8 to +1.0 ("Best purchase ever!")

  • Positive: +0.3 to +0.7 ("Good value for money")

  • Neutral: -0.2 to +0.2 ("It works as described")

  • Negative: -0.7 to -0.3 ("Not what I expected")

  • Very Negative: -1.0 to -0.8 ("Complete garbage, requesting refund")

3. Emotion-Based Sentiment (Advanced)

  • Joy: "So happy with this purchase!"

  • Anger: "This company has the worst customer service!"

  • Frustration: "Why doesn't this feature work properly?"

  • Disappointment: "Expected better quality for the price"


How LLMs Improve Sentiment Analysis

Traditional Methods (Rule-Based/ML):

Problems with Traditional Methods:

❌ Can't handle context: "This isn't bad" → Detected as negative (contains "bad")

❌ Misses sarcasm: "Oh great, another software bug" → Detected as positive (contains "great")

❌ Ignores negation: "Not good at all" → Detected as positive (contains "good")

❌ Limited to trained categories

❌ Requires extensive labeled training data


LLM-Based Sentiment Analysis:

Advantages of LLMs:

✅ Understands context and nuance

✅ Detects sarcasm and irony

✅ Handles negation correctly

✅ Provides explanations and reasoning

✅ Extracts key phrases automatically

✅ Works in multiple languages (multilingual models)

✅ No training data required (zero-shot learning)

✅ Customizable output format (JSON, XML, etc.)


Sentiment Analysis Output Components

In this workshop, our LLM will extract:

1. Sentiment Classification

  • Category: positive, negative, or neutral

  • Example: "sentiment": "positive"

2. Sentiment Score

  • Numeric value from -1.0 (very negative) to +1.0 (very positive)

  • Example: "score": 0.9 (strongly positive)

3. Confidence Level

  • How certain is the LLM about this classification (0-100%)

  • Example: "confidence": 95 (very confident)

  • Low confidence (<60%) might indicate mixed or ambiguous sentiment

4. Key Phrases

  • Important words/phrases that influenced the sentiment

  • Example: ["exceeded expectations", "incredible battery", "blazing fast"]

  • Useful for identifying specific strengths or weaknesses

5. Summary

  • One-sentence summary of the review's main point

  • Example: "Customer extremely satisfied with laptop performance and battery life"

  • Helps quickly understand what the review is about


Use Cases in This Workshop

We'll analyze 3 customer reviews with varying sentiments:

Review 1 (Positive):

Review 2 (Negative):

Review 3 (Neutral/Mixed):

Expected Results

After running this workshop's transformation, you'll have:

  • Original review text

  • AI-determined sentiment (positive/negative/neutral)

  • Numeric score (-1.0 to 1.0)

  • Confidence percentage

  • Key phrases extracted

  • One-sentence summary

All in a structured CSV file ready for analysis, visualization, or database import!

Key Takeaways

  1. Sentiment analysis automatically categorizes opinions in customer feedback

  2. LLMs provide context-aware analysis that traditional methods can't match

  3. Structured JSON output makes results easy to process in ETL pipelines

  4. Confidence scores help identify reviews that need manual review

  5. Key phrases identify specific strengths and weaknesses

  6. Scalable processing - analyze thousands of reviews in minutes

Ollama API Endpoint

Ollama provides a REST API at http://localhost:11434

Key Endpoint: /api/generate

Sample Request Format

Parameters:

  • model: Which LLM model to use

  • prompt: The instruction/question for the model

  • stream: false for complete responses (true for streaming)

  • format: "json" to request JSON-formatted output

Sample Response Format

The actual LLM output is in the response field.

  1. Test the API manually, enter this command:

Response from sentiment analysis

The Response Structure

This is a successful response from the Ollama API. Here's what each part means:

Main Fields:

  • "model": "llama3.2:3b" - Confirms which model processed your request (Llama 3.2 with 3 billion parameters)

  • "created_at" - Timestamp when the response was generated

  • "response" - This is the actual AI-generated answer:

    The AI correctly identified the review as positive with a maximum confidence score of 1 (on the -1 to 1 scale you requested)

  • "done": true - Request completed successfully

  • "done_reason": "stop" - Model finished naturally (not cut off due to length limits)

Performance Metrics:

  • "total_duration": 3131161470 - Total time: ~3.1 seconds (in nanoseconds)

  • "load_duration": 220384685 - Model loading: ~0.2 seconds

  • "prompt_eval_count": 64 - Your prompt used 64 tokens

  • "prompt_eval_duration": 115063978 - Processing prompt: ~0.1 seconds

  • "eval_count": 18 - Response generated 18 tokens

  • "eval_duration": 2088187708 - Generating response: ~2.1 seconds

context

The array of numbers represents the internal token IDs used by the model - you can ignore this unless you're doing advanced work with conversation history.

Summary

The API successfully analyzed "This product is amazing! Best purchase ever." and correctly returned:

  • Sentiment: Positive

  • Score: 1.0 (maximum positivity)

The whole process took about 3 seconds. This is exactly what you'd use in your PDI transformation to get sentiment analysis results!

PDI - Transformation

Sentiment Analysis

Run through the following steps to build sentiment_analysis_optimized.ktr:

CSV file input

Read customer_reviews.csv

  1. Examine the customer reviews dataset.

The dataset contains:

  • review_id: Unique identifier

  • customer_name: Customer who wrote the review

  • product: Product being reviewed

  • review_text: The actual review content (this is what we'll analyze)

  • date: Review date

  1. Double-click on the CSV file input step to review settings:

  • Configuration:

    • File path: ${INPUT_FILE} (parameter, defaults to ../data/customer_reviews.csv)

    • Delimiter: comma (,)

    • Enclosure: double quote (")

    • Header row: Yes

    • Encoding: UTF-8

  • Output Fields: review_id, customer_name, product, review_text, date

The transformation uses the INPUT_FILE parameter for flexibility. You can override this when running:

Modified JavaScript Value

Construct the JSON payload for Ollama API.

  1. Double-click on the Modified JavaScript Value to review settings:

Build your prompt

Step Type: Modified Java Script Value

  • Purpose: Construct the JSON payload for Ollama API

  • Key Logic:

Output Fields: prompt_text, json_payload

PDI Parameter Resolution in JavaScript:

PDI parameters work differently depending on where you use them:

Location
Syntax
Works?
Example

XML tags

${PARAM}

✅ YES

<url>${OLLAMA_URL}/api/generate</url>

JavaScript strings

"${PARAM}"

❌ NO

var x = "${MODEL_NAME}"; stays literal

JavaScript code

getVariable()

✅ YES

var x = getVariable("MODEL_NAME", "default");

Correct JavaScript approach:

Incorrect approach (common mistake):

Prompt Engineering Tips:

  • Be explicit about the desired output format

  • Provide clear examples when possible

  • Request structured data (JSON) for easier parsing

  • Specify value ranges and types

REST Client

The REST client transformation step enables you to consume RESTful services.

Representational State Transfer (REST) is a key design idiom that embraces a stateless client-server architecture in which web services are viewed as resources and can be identified by their URLs.

You can escape input field data by using the Calculator step and the Mask XML content from string A or Escape HTML content function.

  1. Double-click on the REST client step to review settings:

POST request to Ollama

Use the REST Client step, not the generic HTTP Client step. The REST Client is specifically designed for REST APIs and handles POST requests properly.

  1. Add a "REST Client" step

  2. General Tab:

    • Application type: TEXT PLAIN

    • HTTP method: POST

    • URL: ${OLLAMA_URL}/api/generate

    • Body field: json_payload

  3. Headers Tab:

    • Add: Content-Type = application/json

    • Add: Accept = application/json

  4. Settings Tab:

    • Result field name: llm_response

    • HTTP status code field: response_code

    • Response time: response_time

    • Socket timeout: 300000

    • Connection timeout: 30000

Common Issues & Solutions:

Issue
Cause
Solution

405 Method Not Allowed

Using HTTP Client instead of REST Client

Change step type to REST Client

400 Bad Request

PDI parameters not resolved in JavaScript

Use getVariable() in JavaScript

Timeout errors

Socket timeout too low

Increase to 300000ms (5 minutes)

Connection refused

Ollama not running

Run curl http://localhost:11434/api/tags

Important Notes:

✅ LLM inference takes 20-30 seconds per review - this is normal

✅ Set socket timeout to at least 300000ms (5 minutes)

✅ Always check response_code field (should be 200)

✅ Use REST Client step, not HTTP Client

✅ Test Ollama API with curl before running transformation

JSON Input

This step extracts the actual LLM-generated content from Ollama's response wrapper.

Parse the LLM's JSON output into separate fields.

  1. Double-click on the JSON Input step to review settings:

Parse the llm_response field
  • Configuration:

    • Source: Field value (llm_response)

    • JSON field path: $.response

    • Output field: sentiment_json

JSON Input

Parse the LLM's JSON output into separate fields

  1. Double-click on JSON input step to review settings:

Extract sentiment fields
  • Configuration:

    • Source: Field value (sentiment_json)

    • JSON paths:

      • $.sentiment → sentiment (String)

      • $.score → score (Number, format: #.##)

      • $.confidence → confidence (Integer)

      • $.key_phrases → key_phrases (String)

      • $.summary → summary (String)

Text file output

Save enriched data to CSV

  1. Double-click on Text fle output to review settings:

Output results
  • Configuration:

    • File name: ../datasets/sentiment_results

    • Extension: .csv

    • Add date: Yes

    • Add time: Yes

    • Format: DOS (Windows line endings)

    • Encoding: UTF-8

    • Include header: Yes

    • Fields: All original fields + sentiment fields

RUN the transformation

The transformation has been optimzed to execute on minimal spec machines.

  1. Before you RUN the transformation, you will need to set the parameters.

  2. Double-click anywhere on the canvas to display the transformatiom properties:

Transformation Parameters

The transformation uses these parameters for flexibility:

Basic Transformation (sentiment_analysis.ktr)

Parameter
Default Value
Description

OLLAMA_URL

http://localhost:11434

Ollama API endpoint

MODEL_NAME

llama3.2:3b

Model to use for analysis

INPUT_FILE

../data/customer_reviews.csv

Input data path

Optimized Transformation (sentiment_analysis_optimized.ktr)

Parameter
Default Value
Description

OLLAMA_URL

http://localhost:11434

Ollama API endpoint

MODEL_NAME

llama3.2:3b

Model to use for analysis

INPUT_FILE

../data/customer_reviews.csv

Input data path

KEEP_ALIVE

30m

Keep model in memory (5m/15m/30m/60m)

STEP_COPIES

4

Parallel copies (set to CPU cores - 1)

Parameter Details:

  • KEEP_ALIVE: Controls how long Ollama keeps the model loaded in memory

    5m = 5 minutes (minimal memory usage)

    15m = 15 minutes (balanced)

    30m = 30 minutes (recommended - prevents reload overhead)

    60m = 60 minutes (for heavy workloads)

  • STEP_COPIES: Number of parallel processing threads for the "Call Ollama API" step

    Recommended: CPU cores - 1 (e.g., 8 cores = set to 4)

    Higher = faster processing but more memory usage

    Default: 4 (good for most systems)

  • File Path Note: The default INPUT_FILE parameter points to ../data/customer_reviews.csv. Make sure your data files are in the data/ folder, not datasets/.


Performance Notes

Processing Time

  • 3 reviews: ~69 seconds (~23 sec/review)

  • Expected for 100 reviews: ~38 minutes (at 23 sec/review)

  • Optimized version (parallel): Expected 3-4x faster

Recommendations

  1. For testing: Use small datasets (3-10 reviews)

  2. For production: Use optimized version with parallel processing

  3. Adjust STEP_COPIES: Set to (CPU cores - 1) for optimal performance

  4. Model choice:

    • llama3.2:1b = faster, less accurate

    • llama3.2:3b = balanced (recommended)

    • llama2:7b = slower, more accurate


Results

Input Data

Output Data with Sentiment Analysis

Review
Customer
Product
Sentiment
Score
Confidence
Result

1

Sarah Johnson

Laptop Pro 15

positive

0.9

90%

✅ Correct

2

Mike Chen

Wireless Mouse

negative

-0.6

80%

✅ Correct

3

Emily Rodriguez

USB-C Hub

neutral

-0.33

70%

✅ Correct

View the complete results at: ~/LLM-PDI-Integration/workshops/workshop-01-sentiment-analysis/datasets/sentiment_results_optimized_timestamp.csv

Data Quality

Traditional Solutions vs LLM Approach:

Approach
Pros
Cons

Regex/Rules

Fast, deterministic

Brittle, requires constant updates

Data Quality Tools

Comprehensive

Expensive, complex setup

Manual Cleaning

Accurate

Doesn't scale

LLM Approach

Flexible, intelligent, handles edge cases

Requires LLM infrastructure

Workflow

data_quailty_optimized
  1. Verify Ollama Installation

  1. Run through the following steps to build data_quality_optimized.ktr:

Understanding Data Quality Challenges

Step 1: Examine the Raw Data

Navigate to the workshop folder and review the sample data:

Sample Records:

Data Quality Issues Identified:

Customer
Name Issue
Email Issue
Phone Issue
Address Issue
Company Issue

1001

Lowercase

Mixed case

Dots separator

Lowercase, abbreviations

Lowercase

1002

All caps

Incomplete domain

Valid format

Good

Mixed case

1005

Good

Missing domain

Dashes

Abbreviations

Good

1010

Good

Valid

Parentheses

Lowercase

Good

Step 2: Define Quality Standards

Our target output standards:

Field
Standard Format
Example

Name

Title Case

John Smith

Email

lowercase@domain.com or INVALID

jsmith@gmail.com

Phone

+1-555-123-4567

+1-555-123-4567

Address

Street, City, State ZIP

123 Main St Apt 5, New York, NY

Company

Proper Business Name

Acme Corp

Step 3: Traditional vs LLM Approach

Common Data Quality Problems:

  • Inconsistent name formatting (john smith vs JOHN SMITH vs John Smith)

  • Invalid or malformed email addresses

  • Multiple phone number formats (+1-555-123-4567 vs 555.123.4567 vs (555) 123-4567)

  • Incomplete or inconsistent addresses

  • Company name variations (ACME CORP vs Acme Corp vs acme corp)

Solution Comparison:

Approach
Pros
Cons
Example

Regex/Rules

Fast, deterministic

Brittle, requires constant updates for edge cases

phone.replace(/[^\d]/g, '')

Data Quality Tools

Comprehensive features

Expensive ($20K-$50K+), complex setup (weeks)

Informatica, Talend DQ

Manual Cleaning

100% accurate

Doesn't scale, labor intensive

Excel find/replace

LLM Approach

Flexible, intelligent, handles edge cases

Requires LLM infrastructure

"Clean and standardize this data..."

Ollama API Endpoint

Ollama provides a REST API at http://localhost:11434

Key Endpoint: /api/generate

Sample Request Format

Key Parameters:

  • model: llama3.2:3b - Smaller, faster model optimized for structured tasks

  • prompt: Compact instructions with example format

  • stream: false - Get complete response at once

  • keep_alive: "5m" - Keep model loaded for 5 minutes (faster subsequent requests)

  • temperature: 0.1 - Low randomness for consistent formatting

  • num_predict: 300 - Limit output tokens

Sample Response Format

Response Fields:

  • response: Contains the cleaned JSON data (as a string)

  • done: true when generation is complete

  • prompt_eval_count: Input tokens processed (85 tokens)

  • eval_count: Output tokens generated (45 tokens)

  • Total tokens: 130 tokens per record

  1. Test the API manually, enter this command:

Expected Response:

Notice:

  • Name converted to Title Case

  • Email marked as INVALID (incomplete domain @company)

  • Phone already in correct format

  • Address capitalized and formatted

  • Company name preserved (already correct)

PDI Transformation

data_quality

Run through the following steps to build data_quality_optimized.ktr:

CSV file input

x

x

x

x

JSON input

Creates the LLM prompt from input data

Input: Raw customer fields (name, email, phone, address, company_name) Output: llm_prompt (string)

x

x

Build Optimized Prompt (Modified Java Script Value)

JavaScript code:

Prompt Optimization Techniques:

❌ Removed: Verbose explanations ("Clean and standardize this customer record...")

❌ Removed: Detailed field descriptions ("Full Name in Title Case")

✅ Kept: Clear format example in JSON

✅ Kept: Abbreviated field labels to reduce tokens

Result: 50% shorter → 50% faster processing

x

x

x

Modifed JavaScript value

Wraps the prompt into Ollama API request format.

Input: llm_prompt (from Step 2) + transformation parameters

Output: request_body (JSON string ready for API)

Why separate? Handles API-specific configuration (model, temperature, keep_alive). Separates prompt logic from API plumbing.

  1. Double-click on the MJV - Build JSON prompt - to review the settimgs:

Build API request

Build JSON Request (Modified Java Script Value)

Use getVariable() for Parameters

Why getVariable()?

  • "${MODEL_NAME}"DOES NOT WORK in JavaScript strings (stays literal)

  • getVariable("MODEL_NAME", "llama3.2:3b")WORKS (resolves to actual value)

REST Client

The REST client transformation step enables you to consume RESTful services.

Representational State Transfer (REST) is a key design idiom that embraces a stateless client-server architecture in which web services are viewed as resources and can be identified by their URLs.

You can escape input field data by using the Calculator step and the Mask XML content from string A or Escape HTML content function.

  1. Double-click on the REST client step to review settings:

Call Ollama API

Call Ollama API (Parallel) - REST Client

Configuration:

  • Step Type: REST Client (Rest)

  • Method: POST

  • URL: ${OLLAMA_URL}/api/generate

  • Body Field: request_body

  • Application type: TEXT PLAIN

  • Result Fields:

    • Name: api_response

    • Code: result_code

    • Response time: response_time

  • Headers: (leave empty - REST Client auto-adds Content-Type)

  • Step Copies: ${STEP_COPIES} → Default: 4 (parallel processing)

Step 7: Write Enhanced Data (Text File Output)

Configuration:

  • Filename: ../data/customer_data_enhanced_optimized

  • Extension: .csv

  • Add date: Y (adds _20260227)

  • Add time: Y (adds _134529)

  • Result: customer_data_enhanced_optimized_20260227_134529.csv

  • Fields: customer_id, enhanced_name, enhanced_email, enhanced_phone, enhanced_address, enhanced_company

Transformation Parameters

Basic Transformation (data_quality_enhancement.ktr)

Parameter
Default Value
Description

OLLAMA_URL

http://localhost:11434

Ollama API endpoint

MODEL_NAME

llama3.2:3b

Model to use for data cleaning

INPUT_FILE

../data/customer_data_raw.csv

Input data path

Optimized Transformation (data_quality_enhancement_optimized.ktr)

Parameter
Default Value
Description

OLLAMA_URL

http://localhost:11434

Ollama API endpoint

MODEL_NAME

llama3.2:3b

Model to use (llama3.2:3b recommended)

INPUT_FILE

../data/customer_data_raw.csv

Input data path

KEEP_ALIVE

5m

Keep model in memory (5m/15m/30m/60m)

STEP_COPIES

4

Parallel API calls (set to CPU cores - 1)

Parameter Tuning Guide:

CPU Cores
STEP_COPIES
Expected Throughput

4 cores

4

1.0-1.2 rec/sec

8 cores

6-8

1.5-2.0 rec/sec

16 cores

12-14

2.5-3.5 rec/sec

Tested Configuration (Verified Working ✅)

Test Environment:

  • OS: Ubuntu 22.04 Linux

  • PDI: 11.0.0.0-237

  • Ollama: Latest

  • Model: llama3.2:3b

  • CPU: 4 cores

  • RAM: 16GB

Verified Parameters: