Fabric data agent: five sources, 25 rows and English only

Fabric data agent: five sources, 25 rows and English only

Leia este artigo em português

The demo is always the same and it always works. Someone points the agent at a lakehouse, asks “what was quarterly revenue by region” in English, and the answer comes back formatted, with the right table, in four seconds. The room approves. Three weeks later the pilot has seven sources that had to go in and only five that fit, a director asking why the report is cut off at twenty-five rows, and an analyst in São Paulo discovering that the same question in Portuguese comes back worse than in English. None of that is a defect. It is all documented — it just was not on the slide.

The fine print A data agent is not a search box on steroids. It is a component with an entry contract: a set of conditions that have to be true before it answers anything, and that no prompt, instruction or insistence will renegotiate. Knowing that contract is the difference between designing a solution that fits the product and discovering the limit once the pilot has already become a commitment to the business.

What is the Fabric data agent entry contract?

The Fabric data agent is a generally available Microsoft Fabric artifact that turns a natural-language question into a query over your data. It is not a copilot: a copilot comes preconfigured and helps you write code inside the product; the data agent is an item you configure, publish and share, and that other systems can invoke from outside.

The entry contract is what it demands from the environment before it exists, and what it hands back afterwards. Four blocks:

  • Data surface — which sources it accepts, how many, and how granularly you choose what it sees.
  • Output shape — how much it returns per answer, in which language, and in which mode of operation.
  • Identity and permission — which identity the query runs under, and the minimum permission each source requires.
  • Boundary — what leaves your capacity’s region, and what governance can stop.

This article is the direct sequel to the vector index does not inherit the table’s permission, where the Fabric data agent appeared as a governance route in the choice between RAG and text-to-SQL. There the question was which route has the right permission model. Here it is the question that comes before: what has to be true for that route to work at all.

The problem it solves

The problem is one of sequence. Almost every data agent design I meet in the field starts from the wrong question — what questions will the agent answer? — when the question that orders the project is what does it accept, and what can it hand back?.

Getting that backwards produces three kinds of expensive, predictable rework:

  1. The architecture draws eight sources. The product accepts five. Someone will have to consolidate, and consolidating sources is a data engineering project, not a configuration tweak.
  2. The use case is an operational report. The answer is capped at twenty-five rows and twenty-five columns. The agent was designed for conversation, not extraction — and extraction was exactly what the business asked for.
  3. The audience is Brazilian. Documented support is for English. That does not stop a question in Portuguese, but it changes what you can promise about quality, and it has to be written into the design.

None of those three is a technical surprise. All three are documentation read afterwards instead of beforehand.

Diagram in two bands. The top band, called the entry contract, shows the six source categories the Fabric data agent accepts, with the limit of five per agent: SQL grouping lakehouse, warehouse, SQL Database and mirrored databases and generating T-SQL; eventhouse with a KQL database generating KQL; semantic model generating DAX; graph model in preview generating GQL; ontology in preview with its native language; and an Azure AI Search index in preview, built in Azure AI Foundry over unstructured content, answering through natural language plus search. A note recalls that in a lakehouse you select tables, not files. The middle band, called the output contract, shows the path of a question in four steps: it arrives in English, runs under the asking user's Entra ID identity with RLS and CLS, the router picks the source and validates the query against the approved schema, and read-only execution returns at most twenty-five rows by twenty-five columns. A third band marks the boundaries: a paid F2 or higher capacity with source and agent in the same region, processing and storage outside the region when the capacity sits outside the European Union and the United States, and Purview policies that can truncate or block the answer. At the foot, the conclusion: the agent does not renegotiate the contract by prompt.
What goes in on the left and what comes out on the right. None of the grey boxes is configurable by instruction: they are the product.

How it works — step by step

  1. Confirm the capacity. You need a paid F2 or higher Fabric capacity, or a Power BI Premium P1 or higher capacity with Fabric enabled. There is no data agent on an improvised capacity.
  2. Turn on the tenant switches. The Copilot and Azure OpenAI switch is mandatory. If your capacity’s region sits outside the European Union data boundary and outside the United States — Brazil’s case — the switches for processing and for storing outside the geographic region are mandatory too. Both, not one.
  3. Pick the sources. Up to five, in any combination across the six categories. Five semantic models is valid; two models, one lakehouse and one KQL database is valid too.
  4. Select the schema inside each source. On a SQL source you pick tables, views and functions. In a lakehouse those are tables, not files: a CSV or JSON has to be ingested first. Graph and ontology have no schema selection — the whole source goes in.
  5. Give it context. Agent instructions for routing, per-source instructions for query generation, and up to 100 example queries per source. The semantic model is the exception: examples are not supported there, and configuration happens on the Power BI side, in Prep for AI.
  6. Choose the runtime. Standard is the GA runtime and the default for production. Preview carries orchestration and routing changes before GA — and it is the only one that enables configurations such as topics and schema object descriptions. The runtime does not change which sources you can add, and model upgrades land on both equally.
  7. Publish. Publishing generates a read-only version, which is what everybody else consumes; you keep editing the draft without affecting current users. The description you write at publish time becomes the tool description advertised over MCP.
  8. Share the agent and the data. Sharing the agent is not enough: whoever asks needs permission on the source, because the query runs under their identity.
  9. Evaluate before calling it done. The evaluation SDK, in preview, runs a set of questions with expected answers and writes two tables — the summary and the step-by-step.

The six categories, and why five is the number that matters

The source list is where the documentation confuses people the most, and it pays to go to the right page. The per-resource page is the authoritative and most current one:

Category Artifact Generated language
SQL Lakehouse, Data Warehouse, SQL Database, Mirrored Databases T-SQL
Eventhouse Eventhouse KQL database KQL
Semantic model Power BI semantic models DAX
Graph (preview) Graph Model GQL
Ontology (preview) Fabric Ontology ontology-native
Azure AI Search (preview) Azure AI Search index natural language + search

Three readings that change a design:

First: “SQL” is a category, not a source. Lakehouse, warehouse, SQL Database and mirrored databases — Azure SQL, Cosmos DB, Snowflake — all come in through the same T-SQL door, via the SQL Analytics Endpoint. That stretches what fits inside the limit of five far more than the naive reading suggests.

Second: unstructured content does come in. The Azure AI Search index is a supported source, in preview, described as an index built in Azure AI Foundry over PDFs, text files and other enriched documents. You configure the search type, how many documents are retrieved per query — the recommendation is 3 to 20 — and the description that helps routing. Citations are automatic when the index carries a URL or file path field. Worth recording: I published the opposite here on 1 September, having read a table-of-contents rename as a feature removal. The article was corrected in both languages before this one shipped.

Third: it is not Microsoft Graph. The graph category is the Graph Model of Graph in Microsoft Fabric, queried with GQL — a labelled property graph inside Fabric. It is not the Microsoft 365 Microsoft Graph API. The confusion has a documented origin: the concepts page uses the bare name “Microsoft Graph”, and the sharing page calls it “Microsoft Graph in Fabric”. If your design planned to ask about email and calendars, that is a different product.

And five is not a licensing limit you can buy your way past. It is the artifact’s ceiling. If you need eight sources, the options are to consolidate upstream, split into two agents and orchestrate outside, or revisit the scope of the use case.

Twenty-five rows by twenty-five columns

This is the limit that sinks the most projects, because it never shows up in a demo — it shows up when someone tries to use the agent for what it is not.

The documentation is literal: responses are capped at a maximum of 25 rows and 25 columns, because the agent is designed for conversational insight, not for returning a complete dataset. And there is a second-order effect almost nobody anticipates: the conversation history contaminates the next question. If you asked “show all rows for this year” and got twenty-five, the follow-up may be answered over that already-truncated slice rather than over the whole dataset. The official recommendation for that case is to start a new chat session.

Add the rest of the output contract to it:

Limit Value What it rules out
Sources per agent 5 A design with many origins and no consolidation
Rows × columns per answer 25 × 25 Extraction, operational reporting, export
Language English Promising equivalent quality in Portuguese
Query type read-only An agent that writes, fires a notebook or a job
Example queries per source 100 Teaching the agent by sheer volume of examples
Model choice not configurable Swapping in an LLM of your own
Region same as the source capacity Source in one region, agent in another

That last row deserves emphasis because it fails quietly on paper and loudly in production: the agent cannot execute a query when the source workspace’s capacity is in a different region from the agent workspace’s capacity. A lakehouse in one region and the agent in another is not a latency question. It is a query that does not run.

Read-only, incidentally, is structural and not a setting you relax: it generates only read queries in SQL, DAX and KQL, and it does not trigger anomaly detection, notebooks or any write workflow — even where the eventhouse has those integrations available.

English only, and what that means in practice

The documented sentence is that the agent does not currently support non-English languages, and that for optimal performance questions, instructions and example queries should be in English.

That is not an interface language block. It is a declaration of quality scope, and it has practical consequences in three places that stay under your control:

  • Agent instructions and per-source instructions are written by you. Write them in English.
  • The example queries are yours. In English.
  • The table and column descriptions — including the ones coming from Prep for AI on the semantic model — feed query generation. In English.

What remains in Portuguese is the end user’s question, and that is precisely the part you do not control. In a bank or an insurer in Brazil, this turns into a communication requirement: the agent answers, but the design does not promise parity. I have watched that point become a trust crisis for not having been said in the first meeting.

The identity belongs to the asker, and so does the permission

Here the product gets it right, and the mechanism is worth understanding because it is the main governance argument in favour of this route.

There is no Azure OpenAI key to manage: Fabric uses a Microsoft-managed Azure OpenAI Assistant and handles authentication for you. Data access, on the other hand, runs under the Microsoft Entra ID identity of whoever asks, with their permissions. The agent reads schema and runs queries only where the user has access, and it honours RLS and CLS.

The minimum permission per source is documented, and the semantic model detail tends to surprise people:

Source Minimum permission to query via the agent
Power BI semantic model Read on the model — no workspace role, no Build
Lakehouse Read on the item, plus table access where enforced
Warehouse Read, with SELECT on the relevant tables
KQL database Reader role on the database
Ontology Read on the ontology and on the source bound to it
Graph in Fabric Read on the graph item and the underlying data

Below that, the query fails or returns empty — and returning empty is the dangerous behaviour, because it looks like an answer.

Above all of that sits a precedence order the product declares: organizational intent (tenant policies), then role-based intent (workspace governance), then developer intent (your instructions and examples), and last user intent (the question). When layers conflict, the higher one wins. An instruction that tries to bypass read-only mode or reach a source outside scope is refused or redirected — that is not a behavioural promise, it is declared precedence.

Then there is the Purview layer: DLP on the Data Warehouse is generally available, and access restriction policies are in preview for KQL database, SQL Database and warehouse. The practical effect is that an answer can come back truncated or blocked by policy, and the user will see an incomplete answer without knowing why. That belongs in the agent’s communication, not only in the design.

The full path, the way I draw it on a whiteboard:

question (in English)
     │
     ├─ user identity in Entra ID  ── not the agent's identity
     │
     ├─ precedence: organization > role > developer > user
     │
     ├─ routing across the added sources (max. 5)
     │      ├─ SQL            → NL2SQL   → T-SQL
     │      ├─ eventhouse     → NL2KQL   → KQL
     │      ├─ semantic model → NL2DAX   → DAX
     │      ├─ Graph Model    → NL2GQL   → GQL
     │      ├─ ontology       → ontology-native
     │      └─ AI Search      → search over the Foundry index
     │
     ├─ validation: the query only touches the approved schema
     │
     ├─ read-only execution, with the user's RLS and CLS
     │
     └─ answer: max. 25 rows × 25 columns
            └─ Purview DLP and access restriction may truncate

Two retirements that have already passed

If you designed an integration before August, check the calendar: 26 August 2026 was the date of two retirements that affect this agent.

The first is the Azure OpenAI Assistants API, deprecated on that date, with migration to the Microsoft Foundry agents service. The second is a consequence of the first: the Fabric data agent integration with Copilot in Power BI was retired the same day, because that was the orchestration layer holding it up.

The agent itself was not retired. What changed is where it is consumed from. The paths still standing: the native Fabric experience, Microsoft Foundry, Copilot Studio, Microsoft 365 Copilot and the MCP endpoint — which is the one that matters to whoever is building.

Publishing the agent turns it into an MCP server exposing a single tool: the agent itself. The endpoint is predictable:

https://api.fabric.microsoft.com/v1/mcp/workspaces/{WorkspaceId}/dataagents/{DataAgentId}/agent

Three traps on that surface. First: the URL only works after you publish — hand-building it against a draft agent returns an error even when the URL is correct. Second: it is not plain REST. The client has to follow the MCP flow — initialize, tools/list, tools/call — and the server does not support dynamic client registration or client identity metadata, so the client must obtain a Fabric token through its own flow and attach it to every request. Third, and this is the one the risk team will want in writing: consumed over MCP, the answer may leave Fabric’s compliance boundary and geographic region, falling under the terms of the MCP client you used. The same caveat applies to Foundry, Copilot Studio and Microsoft 365 Copilot.

When the documentation contradicts itself

The method is worth recording, because this topic has a trap in it. Two pages of the same documentation disagree today:

  • The per-resource page lists Azure AI Search as a source and calls the graph category Graph Model / GQL.
  • The concepts page, older, still writes “Microsoft Graph” in the flow and still lists, under limitations, that the agent does not support unstructured data such as .pdf, .docx or .txt files.

Both statements on the concepts page are residue. The rule I adopted and recommend: in a conflict, the per-resource page wins, because it is the one the product team updates on every surface change. And there is an objective signal to decide with — the revision date in the page footer. Concepts is from May; per-resource is from late August, revised in September.

Curiously, the prerequisite list on the creation, sharing and evaluation pages still enumerates a warehouse, a lakehouse, a semantic model, a KQL database, a mirrored database or an ontology — without the Azure AI Search index. It is the same lag, in the same place: the supporting text trails the surface.

Production best practices

  • Read the contract before designing the use case. Five sources, 25 × 25, English and read-only are architectural premises, not implementation details.
  • Treat the limit of five as a budget. Group under the SQL category whenever you can: four different databases already mirrored into Fabric spend less of the budget than they appear to.
  • Do not promise extraction. If the business needs the complete list, the deliverable is a report, an export or a pipeline — and the agent is there to explain the number, not to produce the spreadsheet.
  • Write every piece of configuration in English and record in the architecture document that questions in Portuguese are supported without declared parity.
  • Pin the standard runtime in production and keep the preview on a mirror agent, so you can evaluate an orchestration change before it reaches GA.
  • Publish with a description written for machines. It is read by orchestrators and MCP clients to decide when to call the agent. A vague description becomes bad routing.
  • Check the region before adding a source. Source capacity and agent capacity in different regions will not execute.
  • Share the agent and the data together. Whoever gets the link without permission on the source gets an empty answer, not an access error.
  • Evaluate with your own set and read the steps table. The summary tells you whether it was right; the _steps table tells you which way it went. They answer different questions.

The skeleton of an evaluation fits in a few lines, and it is the lowest barrier to entry for stopping the guesswork about quality:

from fabric.dataagent.evaluation import evaluate_data_agent

# Two tables come out of this: <table_name> with the summary,
# <table_name>_steps with the step-by-step reasoning.
evaluation_id = evaluate_data_agent(
    df,                              # columns: question, expected_answer
    "AgentEvaluation",
    table_name="demo_evaluation_output",
    data_agent_stage="production",   # or "sandbox"
)

What has to be in place

The order below is causal, not chronological. Each stage depends on the previous one being true, and none of them has a deadline.

Foundation — authority over the data. The capacity is paid F2 or higher, the tenant switches are on with the decision about processing and storage outside the region taken in writing, the sources the agent will see sit in the same region as its capacity, and each consumer’s permission on the source has been checked — not permission on the agent, permission on the data.
It is in place when a user without access to the table gets an empty result by design, and someone can explain why without opening a ticket.

Production with context — semantics turning into decisions. The instructions, schema descriptions and example queries exist, are in English, and were written by someone who knows the business. The semantic model has been through Prep for AI. The agent is published, with a description an orchestrator can read, and the draft evolves separately from the published version.
It is in place when the same question, asked by two people from different areas, is routed to the right source with no extra instruction.

Scale and efficiency — the platform as a product. There is a versioned evaluation set, the steps table is consulted when someone complains, the production runtime is standard with a preview mirror, and MCP consumption went through a data boundary review before it existed in production.
It is in place when an orchestration change in the product is caught by your evaluation before it is caught by your users.

Frequently asked questions (FAQ)

Can the 25-row limit be raised?

Not by configuration. The cap belongs to the product and exists to keep the answer conversational. When you genuinely need the complete set, the path is a direct query on the source, a report or a pipeline — with the agent explaining the result rather than producing the file.

Does the Fabric data agent read PDFs?

Not directly. It does not open .pdf, .docx or .txt. The documented path is to index that content in Azure AI Search, with the index built in Azure AI Foundry, and add the index as a source. The difference matters: what comes in is the index, and the permission that counts there is the index’s.

So can I really ask in Portuguese?

You can, and an answer usually comes back. What the documentation states is that non-English languages are not supported and that optimal performance is in English. In an enterprise design that means: do not promise quality parity, and keep all configuration in English.

Do I need workspace permission to use a semantic model?

No. Interacting with a semantic model through the agent only requires Read on the model. Workspace roles and Build permission are not required for that path — Build is still needed to modify the model or use Prep for AI. And RLS and CLS keep applying.

Can the agent write to the data?

No. It generates read queries only and does not trigger notebooks, jobs or anomaly detection. If your case requires action, the data agent is the query step inside a larger flow — the action belongs to another component.

What is the difference between the standard and preview runtimes?

Standard is GA and changes rarely; preview receives orchestration, routing and query-generation changes ahead of GA, and it is the only place where configurations such as topics and schema object descriptions live. The runtime does not change which sources you can add, and language model upgrades land on both.

What exactly was retired on 26 August 2026?

The Azure OpenAI Assistants API and, as a consequence, the Fabric data agent integration with Copilot in Power BI. The agent remains available through the Fabric experience, Foundry, Copilot Studio, Microsoft 365 Copilot and the MCP endpoint.

Conclusion

A data agent is not judged by the answer it gives in a demo. It is judged by what it accepts and what it can hand back — and those two lists are short, public and not negotiable by prompt.

Five sources, twenty-five rows by twenty-five columns, English, read-only, same region, the asker’s identity. Whoever reads that list first designs a solution that fits. Whoever reads it later discovers the contract once it has already become a commitment — and at that point the conversation stops being technical.

In the previous article the conclusion was that the index does not inherit the table’s permission. This is the step before it, in the same idea: before arguing about what the agent inherits, check what it accepts.

Official references

👉 If you are designing a data agent on Fabric — especially in a bank or an insurer, with an audience that asks in Portuguese, read the entry contract before you close the scope.
Want to talk through data agents, product limits and governance on Fabric? Reach out on LinkedIn.

Leave a Reply