AI & Agents · Data Engineering

Prompt Engineering Tutorial for Data Engineers

The quality of a prompt determines the quality of the output far more than the model version in most data workflows. This guide covers the techniques that actually move the needle — chain-of-thought reasoning, few-shot patterns, structured output constraints, role grounding, and schema injection — with real examples scoped specifically to SQL generation, DAX, pipeline orchestration, and agent tool design.

Quick Answer

The five prompt engineering techniques with the highest ROI for data work are: role assignment (tell the model it is a senior data engineer); chain-of-thought (instruct it to reason step by step before producing SQL or DAX); few-shot examples (show two or three correct transformations first); schema grounding (paste the actual table schema into the prompt); and structured output (require JSON or YAML when the result feeds another system). Combining all five in one prompt produces dramatically better results than any single technique alone.

📅 Updated: June 2026 ⏱ ~14 min read ✍️ A.J., Data Engineering Researcher 🔗 Reference: OpenAI Prompt Engineering

What Prompt Engineering Actually Is

Prompt engineering is the practice of designing input instructions that reliably guide an AI model toward a specific output — the right structure, reasoning depth, format, and accuracy — rather than hoping the model infers your intent from vague or incomplete instructions.

For data engineers specifically, this matters because the same underlying model produces radically different SQL quality depending on whether you tell it to “write a query” versus providing the table schema, a worked example, a reasoning instruction, and a JSON output constraint. The model’s knowledge of SQL is constant — what changes is how much of that knowledge is directed toward your actual problem.

TechniqueWhat It DoesBest For
Role AssignmentSets the model’s persona and expertise level before any taskAll data tasks — apply by default
Chain-of-ThoughtForces step-by-step reasoning before a final answerComplex SQL, DAX logic, schema decisions
Few-ShotProvides worked examples the model replicatesTransformations, data quality checks, naming conventions
Schema GroundingInjects actual table/column definitions into contextAny query or model generation against a known schema
Structured OutputConstrains response to JSON, YAML, or CSVAny output feeding another system or pipeline
Negative ConstraintsExplicitly rules out unwanted approachesAvoiding deprecated syntax, enforcing style standards

Role Assignment — Set the Expertise Level First

Role assignment is the cheapest technique with the highest baseline improvement: one sentence at the start of a prompt that tells the model what kind of expert it is operating as. This shifts the model’s response distribution toward expert-level vocabulary, reasoning depth, and awareness of edge cases in that domain.

You are a senior data engineer with 10 years of experience building
production pipelines on Microsoft Fabric and Azure Synapse.
You write T-SQL that is efficient, well-commented, and handles
NULL values and edge cases explicitly.

Task: Write a query that calculates 30-day rolling average revenue
per customer, excluding customers with fewer than 5 transactions
in the window.

Without the role preamble, the same task produces working SQL that often misses NULL handling, uses suboptimal window function patterns, and skips edge case coverage. With it, the model defaults to production-grade habits.

📌
Match the Role to the Task

Role specificity compounds the benefit. “You are a data engineer” is weaker than “You are a senior analytics engineer specializing in dbt on Microsoft Fabric who follows the three-layer staging/intermediate/marts pattern.” The more specific the role, the more the model can infer about unstated preferences — like preferring CTEs over subqueries, or including model descriptions in schema.yml.

Chain-of-Thought — Force Reasoning Before the Answer

Chain-of-thought (CoT) prompting instructs the model to reason step by step before producing a final answer. Without this instruction, language models tend to jump directly to an output — which works for simple tasks but fails on anything requiring multi-step logic. With it, the model decomposes the problem first, and the final answer reflects that decomposition.

The simplest CoT trigger is three words appended to any instruction: “Think step by step.” For data engineering tasks, a more specific reasoning scaffold produces more reliable results:

You are a senior data engineer specializing in Power BI DAX.

Task: Write a DAX measure for year-over-year revenue growth percentage.

Before writing the DAX, reason through these steps:
1. What base measure does this depend on?
2. What date intelligence function is needed?
3. Is DIVIDE safer than the division operator here? Why?
4. What should this return when there is no prior year data?

Then write the final measure.

The model’s reasoning output is itself useful — it surfaces assumptions that would otherwise be hidden inside the final expression. If step 4 produces a wrong assumption (“return 0 when prior year is blank”) you can correct it before the DAX is written, rather than debugging a silently wrong measure later.

Field note — A.J., UIG Data Lab

CoT is especially valuable for DAX because DAX evaluation order is counterintuitive — row context, filter context, and context transition produce behaviors that seem wrong until the engine’s reasoning is made explicit. Asking the model to reason about context transition before writing a CALCULATE expression catches the class of errors that cause “correct-looking” DAX to produce wrong aggregations in a matrix.

Few-Shot Prompting — Teach by Example

Few-shot prompting provides two to five worked examples inside the prompt before asking the model to handle a new case. The examples establish the expected input-output pattern — format, vocabulary, naming conventions, reasoning structure — and the model replicates that pattern for the new input without needing explicit rules about every constraint.

This is particularly effective for tasks with a consistent structure: SQL transformations following a house style, dbt model naming conventions, data quality rule generation, or Power BI measure patterns.

Convert each source column description into a dbt staging model
column entry with name, description, and data_tests.

Example 1:
Source: customer_id — unique integer identifier for each customer
Output:
  - name: customer_id
    description: "Surrogate primary key for the customer."
    data_tests:
      - unique
      - not_null

Example 2:
Source: order_status — varchar, one of: placed, shipped, delivered, cancelled
Output:
  - name: order_status
    description: "Current fulfilment status of the order."
    data_tests:
      - not_null
      - accepted_values:
          values: ['placed', 'shipped', 'delivered', 'cancelled']

Now convert this:
Source: total_amount_usd — decimal(10,2), revenue value, must be non-negative
⚠️
Two Examples Is Usually Enough

More than five examples provides diminishing returns and consumes context window space that could hold schema definitions or reasoning instructions. Two examples that clearly demonstrate the pattern — especially where the two examples differ in a meaningful way, like one with accepted_values and one without — teach the model more efficiently than five nearly-identical examples.

Schema Grounding — Give the Model the Actual Table

Schema grounding means injecting the actual table and column definitions from your data model into the prompt. Without it, the model generates SQL against imagined column names — it will hallucinate plausible-sounding names that do not exist in your schema. With it, the model is constrained to columns that actually exist.

Use only the columns defined in the schema below. Do not reference
any column not explicitly listed.

Schema:
Table: fct_orders
  - order_id         INT       NOT NULL  -- Primary key
  - customer_id      INT       NOT NULL  -- FK to dim_customers
  - order_placed_at  TIMESTAMP NOT NULL  -- UTC order submission time
  - status           VARCHAR   NOT NULL  -- placed|shipped|delivered|cancelled
  - gross_revenue    DECIMAL(12,2)       -- Pre-refund order value USD
  - net_revenue      DECIMAL(12,2)       -- Post-refund order value USD

Table: dim_customers
  - customer_id      INT       NOT NULL  -- Primary key
  - customer_email   VARCHAR   NOT NULL
  - acquisition_date DATE      NOT NULL
  - country_code     CHAR(2)   NOT NULL

Task: Write a query showing monthly net revenue by country for the
last 12 complete months, excluding test orders (status = 'test'),
ordered by month descending then revenue descending.

The inline comments on each column carry the same information a good data dictionary would — business meaning, not just data type. This is the schema pattern that produces the most accurate SQL because the model can distinguish gross_revenue from net_revenue correctly based on the inline descriptions, rather than guessing from column names alone.

Structured Output — Constrain to Machine-Readable Format

Structured output prompting instructs the model to return its response in a specific machine-readable format — JSON, YAML, CSV, or XML — rather than natural language prose. This is required for any workflow where the model’s output feeds into another system: a data pipeline, an API call, a configuration generator, or an agent tool.

The most reliable pattern is to provide a JSON schema directly in the prompt alongside an instruction to return valid JSON only, with no additional text or markdown fences:

Extract the following fields from the pipeline log excerpt below
and return them as a valid JSON object matching this schema exactly.
Do not include any explanation, markdown, or text outside the JSON.

Schema:
{
  "pipeline_name": "string",
  "run_id": "string",
  "status": "success | failed | skipped",
  "duration_seconds": number,
  "rows_processed": number | null,
  "error_message": "string | null"
}

Log excerpt:
[2026-06-10 14:22:01] Pipeline: ingest_orders_daily | RunId: r-4892
Duration: 142s | Rows: 84,391 | Result: SUCCESS
Use API-Level JSON Mode Where Available

When calling models through an API (OpenAI, Anthropic, Azure OpenAI), use the response_format or tool_choice parameters to enforce structured output at the API level rather than relying solely on prompt instruction. Prompt-level instruction alone can still produce trailing text or malformed JSON in edge cases — API-level enforcement eliminates those failures for production pipelines.

Negative Constraints — Rule Out Unwanted Approaches

Negative constraints explicitly tell the model what not to do. This is distinct from just describing what you want — it rules out the specific failure modes the model defaults to when given a data task without constraints.

TaskCommon Default FailureNegative Constraint to Add
Write a SQL queryUses SELECT * even when specific columns were implied“Do not use SELECT *. List all columns explicitly.”
Generate dbt YAMLAdds placeholder descriptions like “This column stores X”“Do not write placeholder descriptions. Write specific business definitions or leave description blank.”
Write a DAX measureUses division operator instead of DIVIDE, producing divide-by-zero errors“Use DIVIDE() for all division. Do not use the / operator.”
Generate a Fabric pipeline configHardcodes environment-specific values like connection strings“Do not hardcode connection strings, workspace names, or environment-specific values. Use parameter references instead.”

Negative constraints are most powerful when combined with schema grounding and role assignment — the role sets baseline habits, the schema constrains the data layer, and negative constraints close the specific gaps between model defaults and your team’s standards.

Prompting for Agent Tool Use

When building AI agents that use tools — querying a semantic model via the Power BI MCP server, executing dbt commands, or reading OneLake files — the prompt design shifts from “produce a good answer” to “decide which tool to call, with what arguments, in what order.”

The critical differences in agent tool prompts are boundary clarity and error handling:

You are a data analyst agent with access to three tools:
- execute_query(model_id, dax_query): Runs DAX against a semantic model
- get_model_info(model_id): Returns available tables and measures
- summarize_results(data, question): Summarizes query results in plain English

Rules:
1. Always call get_model_info before execute_query for any new model_id.
2. Never construct a DAX query that references a table or measure not
   returned by get_model_info.
3. If execute_query returns an error, report the error to the user
   and stop — do not retry with a modified query.
4. Return only the summarize_results output to the user, never raw JSON.

User question: What was total net revenue for Q1 2026 by country?
Semantic model ID: 7f4a2b91-...
📌
Tool Boundary Rules Prevent Hallucination Chains

Without explicit rules like Rule 2 above, an agent that cannot find a country column in get_model_info will often proceed to write DAX referencing a hallucinated column name anyway. The negative constraint at the tool-routing level — “never reference a column not returned by get_model_info” — catches this before a bad query reaches the semantic model, rather than debugging a runtime error later.

The Combined Pattern — All Five Techniques in One Prompt

Each technique adds independent value. Combining them into a single prompt produces results that are qualitatively better than any single technique alone — the role sets habits, CoT forces reasoning, the example demonstrates the pattern, schema grounding prevents hallucination, and structured output makes the result usable downstream.

You are a senior analytics engineer at a retail company building
production dbt models on Microsoft Fabric Warehouse. You follow
the staging → intermediate → marts layer pattern and write
well-documented YAML with specific business-level descriptions.

Think step by step:
1. Identify the data type and business meaning of each column.
2. Determine which generic tests apply (unique, not_null, accepted_values, relationships).
3. Write a specific business description — not a placeholder.
4. Return valid YAML only. No markdown. No explanation outside the YAML.

Example:
Source: product_id INT NOT NULL (unique product identifier, FK to dim_products)
Output:
  - name: product_id
    description: "Surrogate key for the product. Foreign key to dim_products.product_id."
    data_tests:
      - not_null
      - relationships:
          to: ref('dim_products')
          field: product_id

Now generate the column YAML for all columns in this staging model:

Table: stg_returns
  - return_id         INT          NOT NULL  -- Unique return transaction identifier
  - order_id          INT          NOT NULL  -- FK to stg_orders
  - returned_at       TIMESTAMP    NOT NULL  -- UTC timestamp of return approval
  - reason_code       VARCHAR(20)  NOT NULL  -- One of: defective, wrong_item, changed_mind, other
  - refund_amount_usd DECIMAL(10,2)          -- Approved refund value, may be null if pending

This single prompt uses all five techniques: role (senior analytics engineer with specific patterns), CoT (4 reasoning steps), few-shot (one worked example), schema grounding (actual column definitions with inline comments), and structured output (YAML only, no markdown). The result is production-ready dbt YAML that requires minimal editing.

Common Prompt Engineering Mistakes in Data Work

No Schema — Hallucinated Columns

Asking for SQL without providing the actual schema. The model generates plausible column names that may not exist. Always paste the schema.

No Output Constraint — Unparseable Response

Requesting JSON without instructing the model to return JSON only. The model wraps it in explanation text, breaking downstream parsing.

One Giant Prompt — Multiple Conflicting Tasks

Asking the model to write SQL, document it, and generate dbt tests in a single prompt with no structure. Break complex multi-step work into sequential prompts.

No Reasoning Instruction — Shallow Logic

Expecting the model to handle complex DAX context transition or multi-table joins correctly without asking it to reason first. Add CoT for any non-trivial logic.

⚠️

Generic Role — Missed Conventions

“You are a data engineer” is underspecified. Name the platform, the tooling, and the specific pattern the team follows to get convention-aware output.

⚠️

No Iteration — First Output Is Final

Treating the first response as complete. The best prompt engineering workflow is: generate → identify the gap → add a constraint → regenerate. Three passes typically produce production-ready output.

FAQ — ↑ AI & Agents · Data Engineering Prompt Engineering Tutorial

Prompt engineering is the practice of designing input instructions that reliably guide an AI model toward a specific output — the right structure, reasoning depth, format, and accuracy. It applies to any task where you interact with a language model: writing SQL, generating DAX, summarizing documents, extracting structured data, or orchestrating multi-step agent workflows. The quality of the prompt determines the quality of the output far more than the model itself in most cases.
Chain-of-thought (CoT) prompting instructs the model to reason step-by-step before giving a final answer. Adding a phrase like “Think step by step” or providing a worked example that shows reasoning steps causes models to decompose problems rather than jumping directly to an answer. This dramatically improves accuracy on multi-step tasks like SQL generation, DAX logic, schema design decisions, and data quality rule analysis.
Few-shot prompting means providing two to five worked examples inside the prompt before asking the model to handle a new case. The examples establish the expected input-output pattern — format, vocabulary, reasoning structure — and the model replicates that pattern for the new input. It is especially effective for tasks with a consistent structure: SQL transformations, data quality checks, pipeline configuration generation, and DAX measure patterns.
Structured output prompting instructs the model to return its response in a specific machine-readable format — JSON, YAML, CSV, or XML — rather than natural language prose. This is critical for any workflow where the model’s output feeds into another system: a data pipeline, an API call, a configuration generator, or an agent tool. The most reliable pattern is to provide a JSON schema directly in the prompt alongside an instruction to return valid JSON only, with no additional text or markdown fences.
The five most effective techniques are: (1) role assignment — tell the model it is a senior data engineer or SQL expert for the specific platform you use; (2) chain-of-thought — ask it to reason step by step before producing SQL or DAX; (3) few-shot examples — show two or three correct transformations before asking for a new one; (4) schema grounding — paste the actual table schema, column names, and data types into the prompt; and (5) structured output — require JSON or YAML output when the result feeds another system. Combining all five in one prompt produces significantly better results than using any one technique alone.
⚠ Accuracy Disclaimer

Prompt engineering techniques and tool behaviors are verified against official OpenAI, Microsoft Azure, and Google documentation through June 2026. AI model behavior varies by model version, temperature setting, and system configuration — treat all prompt patterns as starting points requiring validation against your specific model and use case. UIG Data Lab is an independent publication.

A.J. Data Engineering Researcher & Technical Writer · UIG Data LabAll articles →
A.J. researches and writes about data engineering, analytics architecture, Microsoft Fabric, and modern cloud data platforms. Coverage spans Microsoft Fabric, Power BI, Azure Data Engineering, Databricks, Snowflake, Apache Spark, dbt, Apache Airflow, and modern cloud data infrastructure. The focus is practitioner-level content that helps data professionals understand platform capabilities, evaluate technology decisions, optimize costs, and implement practical solutions using official documentation, product updates, community insights, and industry best practices.
Prompt EngineeringAI AgentsChain-of-ThoughtFew-ShotData EngineeringDAXMicrosoft FabricSQL

Scroll to Top