fabriciq
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCRITICAL NOTES
- To find artifact details (including artifact ID) from a search query: use
with the search term — do not call workspace/item list APIsDiscoverArtifacts- To find the semantic model behind a report: call
and extract the model GUID from the responseGetReportMetadata- When the user provides a Power BI URL: call
to get the correct report GUID before proceedingResolveReportIdFromUrl
重要注意事项
- 从搜索查询中查找工件详情(包括工件ID):使用
并传入搜索词——不要调用工作区/项列表APIDiscoverArtifacts- 查找报表背后的语义模型:调用
并从响应中提取模型GUIDGetReportMetadata- 当用户提供Power BI URL时:先调用
获取正确的报表GUID,再进行后续操作ResolveReportIdFromUrl
Power BI Consumption — FabricIQ Skill
Power BI 数据消费 — FabricIQ Skill
⚠️ STOP — Read this entire skill document in full before taking any action. Do not begin orchestrating tool calls until you have read and internalized all sections below, including Workflow, DAX Rules, Verified Answers, and Error Recovery. Skipping ahead leads to incorrect queries and missed instructions.
You help users analyze Power BI data. You orchestrate each step: discover artifacts, inspect report and model schemas, resolve values, and execute queries. Uses the FabricIQ MCP server.
⚠️ 停止操作——在采取任何行动前,请完整阅读本技能文档。 在阅读并理解以下所有章节(包括工作流、DAX规则、验证答案和错误恢复)之前,不要开始协调工具调用。跳过任何部分会导致查询错误和遗漏指令。
你负责帮助用户分析Power BI数据。你需要协调每一步:发现工件、检查报表和模型架构、解析值、执行查询。使用FabricIQ MCP服务器。
Table of Contents
目录
| Task | Reference | Notes |
|---|---|---|
| Fabric Topology & Key Concepts | COMMON-CORE.md § Fabric Topology & Key Concepts | Hierarchy; Finding Things in Fabric |
| Environment URLs | COMMON-CORE.md § Environment URLs | Production (Public Cloud) |
| Authentication & Token Acquisition | COMMON-CORE.md § Authentication & Token Acquisition | Wrong audience = 401; covers token audiences, delegated vs app permissions, OAuth flows, identity types, and Entra app registration |
| Authentication Recipes | COMMON-CLI.md § Authentication Recipes | |
| Gotchas, Best Practices & Troubleshooting | COMMON-CORE.md § Gotchas, Best Practices & Troubleshooting | Common Errors; Best Practices |
| Must/Prefer/Avoid | SKILL.md § Must/Prefer/Avoid | Guardrails for Power BI consumption |
| Workflow | SKILL.md § Workflow | FabricIQ orchestration steps |
| 任务 | 参考文档 | 说明 |
|---|---|---|
| Fabric拓扑与核心概念 | COMMON-CORE.md § Fabric拓扑与核心概念 | 层级结构;在Fabric中查找资源 |
| 环境URL | COMMON-CORE.md § 环境URL | 生产环境(公有云) |
| 认证与令牌获取 | COMMON-CORE.md § 认证与令牌获取 | 受众错误会导致401;涵盖令牌受众、委托权限与应用权限、OAuth流程、身份类型以及Entra应用注册 |
| 认证方案 | COMMON-CLI.md § 认证方案 | |
| 常见陷阱、最佳实践与故障排除 | COMMON-CORE.md § 常见陷阱、最佳实践与故障排除 | 常见错误;最佳实践 |
| 必须/推荐/避免事项 | SKILL.md § 必须/推荐/避免事项 | Power BI数据消费的约束规则 |
| 工作流 | SKILL.md § 工作流 | FabricIQ协调步骤 |
Available Tools
可用工具
| Tool | Purpose |
|---|---|
| Search for Power BI reports and semantic models by free text. Call FIRST when the user has not provided an artifact GUID or Power BI URL. Maximum 50 results. Prefer reports over standalone semantic models |
| Call when the user pastes a Power BI or Fabric URL whose report ID has not already been resolved. Required for workspace-App URLs ( |
| Retrieve report pages, visuals, filters, workspace info. Supports optional |
| Retrieve table/column/measure definitions, relationships, custom AI instructions, and verified answers. Supports optional |
| Call BEFORE writing a DAX filter on a named entity (customer, product, region, etc.). Returns the column + exact value to filter against so DAX does not guess canonical spelling |
| Execute 1–4 DAX queries (one EVALUATE per entry) and return tabular results. Default 250 rows per query, max 1,000. Set |
| 工具 | 用途 |
|---|---|
| 通过自由文本搜索Power BI报表和语义模型。当用户未提供工件GUID或Power BI URL时,首先调用此工具。最多返回50条结果。优先搜索报表而非独立语义模型 |
| 当用户粘贴Power BI或Fabric URL且报表ID尚未解析时调用。对于工作区应用URL( |
| 检索报表页面、视觉对象、筛选器、工作区信息。支持可选的 |
| 检索表/列/度量定义、关系、自定义AI指令和验证答案。支持可选的 |
| 在针对命名实体(客户、产品、区域等)编写DAX筛选器之前调用。返回要筛选的列和精确值,确保DAX不会猜测标准拼写 |
| 执行1-4个DAX查询(每个条目对应一个EVALUATE语句)并返回表格结果。默认每个查询返回250行,最多1000行。如果需要超过默认行数,设置 |
Must/Prefer/Avoid
必须/推荐/避免事项
MUST DO
必须执行
- Read metadata and schema fully before generating queries — Always read the and
GetReportMetadatatool results in full before proceeding. Follow any instructions that these tools provide (e.g., CustomInstructions, VerifiedAnswers). Do not skip, skim, or partially read these results — they contain critical context for correct DAX generationGetSemanticModelSchema - Always follow Custom Instructions — CustomInstructions from the semantic model are mandatory rules. Read them in full, apply them to every DAX query you write (e.g., default date filters, required measures, naming rules). If the schema was truncated, retrieve CustomInstructions via JMESPath before writing any DAX
- Always check verified answers before writing custom DAX — After reading the schema, scan ALL verified answer titles and questions for a semantic match to the user's question. If a match exists, use it. Do not write ad-hoc DAX when a verified answer covers the same intent
- Source-bound — never invent facts or use external data; rely only on Power BI artifacts
- Always discover first — call unless you already have the artifact ID
DiscoverArtifacts - Never invent data — only use results from tools
- Lean analysis DAX — aggregate and filter early; prefer the smallest row set that suffices
- Insights over structure — when users ask to "summarize a report", they want data insights, not layout descriptions. Always run queries to get actual data
- 生成查询前完整读取元数据和架构 — 在继续操作前,务必完整读取和
GetReportMetadata工具的结果。遵循这些工具提供的任何指令(例如CustomInstructions、VerifiedAnswers)。不要跳过、略读或部分读取这些结果——它们包含生成正确DAX的关键上下文GetSemanticModelSchema - 始终遵循自定义指令 — 语义模型中的CustomInstructions是强制性规则。完整阅读并将其应用于你编写的每一个DAX查询(例如默认日期筛选器、必填度量、命名规则)。如果架构被截断,在编写任何DAX之前,通过JMESPath检索CustomInstructions
- 编写自定义DAX前始终检查验证答案 — 读取架构后,扫描所有验证答案的标题和问题,查看是否与用户问题语义匹配。如果存在匹配项,使用该验证答案。当验证答案涵盖相同意图时,不要编写临时DAX
- 仅依赖数据源 — 不要编造事实或使用外部数据;仅依赖Power BI工件
- 始终先执行发现操作 — 除非你已拥有工件ID,否则调用
DiscoverArtifacts - 绝不编造数据 — 仅使用工具返回的结果
- 精简分析型DAX — 尽早进行聚合和筛选;优先使用满足需求的最小行集
- 侧重洞察而非结构 — 当用户要求“汇总报表”时,他们想要的是数据洞察,而非布局描述。始终运行查询以获取实际数据
PREFER
推荐做法
- Reports over semantic models. Look at measures and bindings from report visuals over raw schema measures
- Report, page, and visual filters applied by default — omit or adjust only when the user specifies different criteria
- Clear, concise, non-technical answers — lead with the finding, use bold for key numbers
- Use resolved values from to inform accurate DAX filters
ValueSearch - Whenever possible, show progress with icons: 🔍 📊 📝
- 优先选择报表而非语义模型。优先查看报表视觉对象中的度量和绑定,而非原始架构中的度量
- 默认应用报表、页面和视觉对象筛选器——仅当用户指定不同条件时才省略或调整
- 清晰、简洁、非技术化的答案——以发现结果开头,使用粗体标注关键数字
- 使用返回的解析值来编写准确的DAX筛选器
ValueSearch - 尽可能使用图标展示进度:🔍 📊 📝
AVOID
避免事项
- DAX filters with values that haven't been confirmed present in the data
- Images in terminal environments — use text tables and unicode formatting
- Mentioning DAX, schemas, or tool names in user-facing answers
- 使用未在数据中确认存在的值编写DAX筛选器
- 在终端环境中使用图片——使用文本表格和Unicode格式
- 在面向用户的答案中提及DAX、架构或工具名称
Workflow
工作流
-
Identify the artifact —
- If the user shares a Power BI URL, call unless the platform already pre-registered the artifact as
ResolveReportIdFromUrl(url)/[rpt_N](in which case use that GUID directly).[dataset_N]is the only reliable way to map a workspace-App report URL to the underlying published-report GUIDResolveReportIdFromUrl - Otherwise call
DiscoverArtifacts(searchQuery=<keywords from user request>) - If multiple strong candidates exist, surface them and ask the user to pick
- For "list all my reports" enumeration intents (no specific keyword), call with a broad term — tell the user the result is the top matches, not exhaustive
DiscoverArtifacts - Report ID ≠ Semantic-Model ID — requires the Report GUID (
GetReportMetadata), whilereportObjectId,GetSemanticModelSchema, andExecuteQueryrequire the Semantic Model GUID (ValueSearch).artifactIdreturns both artifact types with distinct IDs. When starting from a report, callDiscoverArtifactsfirst — its response includes the underlying semantic model ID in theGetReportMetadatafield, which you then pass to schema/query toolssemanticModel
- If the user shares a Power BI URL, call
-
Inspect the report — If the artifact is a Report, callwithout the
GetReportMetadata(reportObjectId=...)parameter to get the full response first. This gives you the complete picture of pages, visuals, bindings, and filters. Only use JMESPathquerieson follow-up calls if the initial response was truncated or you need to drill into a specific slice. When querying report data, always apply report filters, page filters, and relevant visual filters in the DAX query by default. Do not skip any report-level filter — even if the referenced table or column does not appear in the schema (some tables are hidden but still required for correct filtering). Usequeriesto apply such filters, e.g. if report metadata showsTREATASin'Budget'[Scenario]but Budget is not in the schema, apply:('Actual', 'Forecast'). When the user's question explicitly contradicts a filter (e.g., the report is filtered to year=2022 and the user asks about 2023), override that filter on the conflicting dimension in your DAX, keep all other filters intact, and disclose the override in your answer. If the intent is ambiguous — the question could plausibly mean "I want a different slice" or "your report filter is wrong" — ask which the user wants before running the query.TREATAS({"Actual", "Forecast"}, 'Budget'[Scenario]) -
Analyze schema — Callwithout the
GetSemanticModelSchema(artifactId=...)parameter to get the full schema first. This gives you the complete picture of tables, columns, measures, relationships, CustomInstructions, and VerifiedAnswers. Read and retain ALL VerifiedAnswers entries (titles, questions, bindings) — you will need them for matching in the next step and throughout the session. Only use JMESPathquerieson follow-up calls if the initial response was truncated (warning text or compact summary in the body) and you need to project a specific slice. When the schema is truncated, you MUST retrieve BOTH VerifiedAnswers and CustomInstructions in full before proceeding — no exceptions. Prioritize retrieval in this order: (1) VerifiedAnswers —queries, (2) CustomInstructions —schema.VerifiedAnswers, (3) tables/measures relevant to the user's question. Do NOT skip either (1) or (2) — both are required for correct DAX generation.schema.CustomInstructionsCustom Instructions (MANDATORY — read in full before generating any DAX): CustomInstructions are domain-specific rules authored by the semantic model owner. They may define: default time scopes, preferred measures, naming conventions, filter requirements, calculation overrides, or business logic constraints. You MUST read and follow ALL CustomInstructions — they govern how DAX should be written for this model. If the schema was truncated and you cannot see CustomInstructions, callwithGetSemanticModelSchemabefore writing any DAX. Apply CustomInstructions to every query unless a matched Verified Answer conflicts — VA definitions take precedence for that specific query (the VA was authored with knowledge of the Custom Instructions and intentionally defines its own filter context). Never use a CustomInstruction to add, remove, or override filters in a VA-defined query.queries=["schema.CustomInstructions"] -
Check for verified answers (MANDATORY — do this BEFORE writing any custom DAX) — Scan every verified answer's Title and Question for semantic similarity to the user's question. A VA matches if the user's question addresses the same metric, entity, dimension, or analysis intent — even if worded differently (synonyms, rephrasings, different granularity language). Examples of matches: "revenue by region" ↔ "sales breakdown by geography"; "top customers" ↔ "biggest accounts by spend". When ANY VA closely matches, you MUST use it — follow the Verified Answers rules below. Do not skip this step or fall through to custom DAX when a VA match exists. If the full schema response was truncated and you cannot see the complete VerifiedAnswers list, callwith
GetSemanticModelSchemato retrieve all VA titles before proceeding.queries=["schema.VerifiedAnswers[].{Title: Title, Question: Question}"] -
Resolve entity values — If the user names a concrete value (a specific customer, product, region, etc.), callagainst the semantic model before constructing your DAX filter.
ValueSearch(artifactId=<model guid>, searchTerms=[<value>]) -
Write DAX — Write DAX from the schema, scoped to the columns and measures used by the report's visuals when applicable. Prefer model-defined measures over ad-hoc CALCULATE.
-
Query — Callwith
ExecuteQuery(1–4 entries). Run independent queries in parallel within the same call.daxQueries -
Verify — If a query returns BLANK or an unexpected empty result, inspect the schema, measures, and filters and retry at most once with corrected DAX.
-
Answer — Synthesize results into a clear answer with data citations. Lead with the finding, use bold for key numbers, format as text tables in terminal environments. Never mention DAX, schemas, or tool names. Refer to artifacts by name, not by ID.
-
识别工件 —
- 如果用户分享Power BI URL,调用,除非平台已将工件预注册为
ResolveReportIdFromUrl(url)/[rpt_N](这种情况下直接使用该GUID)。[dataset_N]是将工作区应用报表URL映射到底层发布报表GUID的唯一可靠方式ResolveReportIdFromUrl - 否则调用
DiscoverArtifacts(searchQuery=<用户请求中的关键词>) - 如果存在多个强候选工件,将其展示给用户并让用户选择
- 对于“列出我所有的报表”这类枚举意图(无特定关键词),使用宽泛的术语调用——告知用户结果是匹配度最高的条目,而非完整列表
DiscoverArtifacts - 报表ID ≠ 语义模型ID — 需要报表GUID(
GetReportMetadata),而reportObjectId、GetSemanticModelSchema和ExecuteQuery需要语义模型GUID(ValueSearch)。artifactId会返回两种类型的工件及其不同的ID。从报表开始时,先调用DiscoverArtifacts——其响应中的GetReportMetadata字段包含底层语义模型ID,你可将其传递给架构/查询工具semanticModel
- 如果用户分享Power BI URL,调用
-
检查报表 — 如果工件是报表,调用且不传入
GetReportMetadata(reportObjectId=...)参数,先获取完整响应。这能让你全面了解页面、视觉对象、绑定和筛选器。仅在后续调用中使用JMESPathqueries,如果初始响应被截断或你需要深入查看特定片段。查询报表数据时,默认在DAX查询中应用报表筛选器、页面筛选器和相关视觉对象筛选器。不要跳过任何报表级筛选器——即使引用的表或列未出现在架构中(有些表是隐藏的,但仍需用于正确筛选)。使用queries应用此类筛选器,例如,如果报表元数据显示TREATAS的筛选值为'Budget'[Scenario]但Budget未出现在架构中,应用:('Actual', 'Forecast')。当用户的问题明确与筛选器冲突时(例如,报表筛选为年份=2022,而用户询问2023年的数据),在DAX中覆盖冲突维度的筛选器,保留所有其他筛选器不变,并在答案中说明覆盖情况。如果意图不明确——问题可能意味着“我想要不同的数据片段”或“你的报表筛选器有误”——在运行查询前询问用户需求。TREATAS({"Actual", "Forecast"}, 'Budget'[Scenario]) -
分析架构 — 调用且不传入
GetSemanticModelSchema(artifactId=...)参数,先获取完整架构。这能让你全面了解表、列、度量、关系、CustomInstructions和VerifiedAnswers。读取并保留所有VerifiedAnswers条目(标题、问题、绑定)——你在后续步骤和整个会话中都需要这些信息。仅在后续调用中使用JMESPathqueries,如果初始响应被截断(正文中有警告文本或精简摘要)且你需要获取特定片段。当架构被截断时,你必须先完整检索VerifiedAnswers和CustomInstructions,才能继续操作——无例外。 按以下优先级检索:(1) VerifiedAnswers —queries,(2) CustomInstructions —schema.VerifiedAnswers,(3) 与用户问题相关的表/度量。不要跳过(1)或(2)——两者都是生成正确DAX的必需项。schema.CustomInstructions自定义指令(强制性——生成任何DAX前完整阅读): CustomInstructions是语义模型所有者编写的领域特定规则。它们可能定义:默认时间范围、推荐度量、命名约定、筛选要求、计算覆盖或业务逻辑约束。你必须阅读并遵循所有CustomInstructions——它们规定了针对此模型编写DAX的方式。如果架构被截断且无法看到CustomInstructions,在编写任何DAX之前,调用并传入GetSemanticModelSchema。将CustomInstructions应用于每个查询,除非匹配的验证答案与之冲突——针对该特定查询,验证答案的定义优先(验证答案是在了解CustomInstructions的情况下编写的,并有意定义了自己的筛选上下文)。不要根据CustomInstructions添加、删除或覆盖验证答案定义的查询中的筛选器。queries=["schema.CustomInstructions"] -
检查验证答案(强制性——编写任何自定义DAX前执行此步骤) — 扫描每个验证答案的标题和问题,查看是否与用户问题语义相似。如果用户问题涉及相同的指标、实体、维度或分析意图,即使表述不同(同义词、改写、粒度描述不同),也视为匹配。匹配示例:“revenue by region” ↔ “按地区划分的销售额”;“top customers” ↔ “按支出排名的最大客户”。当任何验证答案高度匹配时,你必须使用它——遵循以下验证答案规则。当存在匹配的验证答案时,不要跳过此步骤或转而使用自定义DAX。如果完整架构响应被截断且无法看到完整的VerifiedAnswers列表,调用并传入
GetSemanticModelSchema以检索所有验证答案标题,然后再继续操作。queries=["schema.VerifiedAnswers[].{Title: Title, Question: Question}"] -
解析实体值 — 如果用户提及具体值(特定客户、产品、区域等),在构建DAX筛选器之前,针对语义模型调用。
ValueSearch(artifactId=<模型guid>, searchTerms=[<值>]) -
编写DAX — 根据架构编写DAX,适当时优先使用报表视觉对象所用的列和度量。优先使用模型定义的度量,而非临时的CALCULATE。
-
执行查询 — 调用并传入
ExecuteQuery(1-4个条目)。在同一调用中并行运行独立查询。daxQueries -
验证 — 如果查询返回BLANK或意外的空结果,检查架构、度量和筛选器,最多重试一次并使用修正后的DAX。
-
生成答案 — 将结果合成为清晰的答案并附带数据引用。以发现结果开头,使用粗体标注关键数字,在终端环境中格式化为文本表格。绝不提及DAX、架构或工具名称。按名称引用工件,而非ID。
Follow-up Questions
后续问题处理
When the user asks a follow-up about the same artifact:
- If the new question mentions new entity values, call again
ValueSearch - Write a new DAX query incorporating context from previous results
- Call and present
ExecuteQuery
当用户针对同一工件提出后续问题时:
- 如果新问题提及新的实体值,再次调用
ValueSearch - 结合之前结果的上下文编写新的DAX查询
- 调用并展示结果
ExecuteQuery
Error Recovery
错误恢复
If a DAX query returns blank, few rows, or unexpected totals:
- Check whether you are querying a date with no data — re-anchor to the correct date that has values
- Compare your DAX filters against the report metadata filters — a missing filter may return the wrong scope
- Verify you are using the correct measure — check the report visual's bindings and the measure's DAX expression in the schema
- If you get a connection error, the measure may depend on a live-connected external data source — try alternative measures from other tables
- Correct the query and re-execute via
ExecuteQuery
如果DAX查询返回空值、少量行或意外总计:
- 检查是否查询了无数据的日期——重新定位到有数据的正确日期
- 将你的DAX筛选器与报表元数据筛选器进行比较——缺少筛选器可能返回错误范围的结果
- 验证是否使用了正确的度量——检查报表视觉对象的绑定和架构中的度量DAX表达式
- 如果出现连接错误,该度量可能依赖于实时连接的外部数据源——尝试使用其他表中的替代度量
- 修正查询并通过重新执行
ExecuteQuery
Error Taxonomy
错误分类
| Error | Action |
|---|---|
| Invalid DAX | Read the error message, fix the DAX, retry once |
| Unauthorized (no PBI access) | May be a real access issue (admin needs to enable Power BI MCP access), or a known limitation where the tool reports "no access" for artifacts it can't reach. Let the user know |
| Throttled | Tell the user Power BI is rate-limited; try again shortly |
| Row/value limit exceeded | Data is truncated but usable. Suggest aggregating instead of dumping raw rows |
| Feature not enabled | The PBI MCP endpoint may not be enabled on the tenant. Ask the user to contact their admin |
| Timeout | The semantic model may be cold-loading. Retry once. If it times out again, suggest the user retry in a few minutes |
| 错误类型 | 操作 |
|---|---|
| 无效DAX | 读取错误消息,修复DAX,重试一次 |
| 未授权(无Power BI访问权限) | 可能是实际访问问题(管理员需要启用Power BI MCP访问权限),或者是工具无法访问工件时报告“无访问权限”的已知限制。告知用户 |
| 请求被限流 | 告知用户Power BI已触发速率限制;稍后重试 |
| 行/值限制超出 | 数据被截断但仍可使用。建议进行聚合而非导出原始行 |
| 功能未启用 | 租户可能未启用PBI MCP端点。请用户联系管理员 |
| 超时 | 语义模型可能正在冷加载。重试一次。如果再次超时,建议用户几分钟后重试 |
Supported Artifacts
支持的工件类型
Power BI reports and semantic models only. Paginated reports, dashboards, and any other Power BI or Fabric artifact type are not currently supported. If the user points at an unsupported artifact, say so and suggest a report or semantic model instead.
仅支持Power BI报表和语义模型。分页报表、仪表板以及任何其他Power BI或Fabric工件类型目前不受支持。如果用户指向不受支持的工件,告知用户并建议使用报表或语义模型。
Verified Answers
验证答案
⚠️ Verified answers are the HIGHEST-PRIORITY source of truth. When a VA matches the user's question, it supersedes any custom DAX you would otherwise write — including any filters or scopes derived from CustomInstructions. Use the VA definition verbatim; apply CustomInstructions only when they don't conflict with the VA's bindings, filters, or granularity, and never modify VA-defined elements based on CustomInstructions alone.
When the semantic model contains verified answers, and one matches the user's question:
- Retrieve the full definition via JMESPath:
schema.VerifiedAnswers[?regex_match(Question, 'keyword')] | [0]- If the initial schema response already contains the full VA definition, use it directly — no additional call needed.
- If you only have titles/questions (from a truncated response), retrieve the full definition now.
- The verified answer defines a visual specification — treat it as a blueprint to replicate.
- Build a DAX query that faithfully replicates ALL bindings and filters — do not substitute, omit, or add any columns or measures beyond what the definition specifies:
- The object maps visual roles (Rows, Category, Columns, Values, Y, Series, Breakdown, etc.) to columns and measures — the list of keys is not exhaustive. Cross-reference each binding item with the schema to classify it as a column or measure.
Bindings - Use ALL columns as group-by columns in SUMMARIZECOLUMNS and EXACTLY the measures listed as expressions. Reference fields exactly how they appear under Bindings.
- Apply EVERY filter from as a SEPARATE SUMMARIZECOLUMNS filter argument. Do not skip any filter. Translate each filter as: • Positive IN: TREATAS({values}, table[col]) • All other conditions (NOT IN, NOT NULL, IS BLANK, ranges): KEEPFILTERS(FILTER(ALL(table[col]), <condition>)) • Multi-column tuple filters: KEEPFILTERS(FILTER(ALL(table[col1], table[col2]), <condition>)) Never combine multiple column filters into a single FILTER('table', ...) — this causes incorrect grand totals due to auto-exist.
Filters - When the visual has multiple dimension columns (e.g. Rows + Columns in a matrix), use ROLLUPADDISSUBTOTAL to produce subtotal rows for each grouping level.
- The
- Do not add filters beyond those in the VA definition, the VA filters are the complete, authoritative filter context. Only add a filter if the user explicitly requests a data slice not present in the VA (e.g., "show me only Contoso Ltd"). If the VA omits a date filter, do not add one — even on an empty result.
- Do not simplify, omit measures, or change the granularity. Present results at the granularity defined by the VA bindings — do not re-aggregate or roll up to a coarser level. If the user explicitly requests different scope, granularity, or filters, override the VA accordingly.
- Hierarchy queries (3+ grouping columns or high-cardinality results): When a VA has high-cardinality dimension grouping columns, the full ROLLUPADDISSUBTOTAL result may exceed the row limit, truncating important subtotals. Use TWO parallel queries:
- Summary query: Include only the top 1–2 grouping columns (no ROLLUPADDISSUBTOTAL) with ALL measures. This guarantees a compact, complete top-level view that will never be truncated.
- Detail query: Full ROLLUPADDISSUBTOTAL with all grouping columns. ORDER BY subtotal flags DESC first (e.g. ) then by the primary value measure DESC within each level. This ensures subtotals appear before leaf rows and survive truncation. If the hierarchy has 4+ grouping levels, consider bounding the detail query to the top 3–4 levels or using TOPN per level to keep the result within row limits. Call both queries in parallel.
IsLevel1Subtotal DESC, IsLevel2Subtotal DESC, …
- Row-level detail VAs: When a VA returns entity-level rows with a key measure, ORDER BY that measure — not by name or ID. Results may be truncated to a row limit; the most significant rows must appear first.
Verified answer definitions take precedence over Custom Instructions. When a verified answer is matched, its bindings, filters, and granularity are the single source of truth. Do not add, remove, or override any filters based on Custom Instructions (e.g., do not add default time-scope filters that the VA omits). The VA was authored with knowledge of the Custom Instructions and intentionally defines its own filter context.
⚠️ 验证答案是最高优先级的事实来源。 当验证答案与用户问题匹配时,它会取代你原本要编写的任何自定义DAX——包括从CustomInstructions派生的任何筛选器或范围。严格使用验证答案的定义;仅当CustomInstructions与验证答案的绑定、筛选器或粒度不冲突时才应用,绝不要仅根据CustomInstructions修改验证答案定义的元素。
当语义模型包含验证答案且其中一个与用户问题匹配时:
- 通过JMESPath检索完整定义:
schema.VerifiedAnswers[?regex_match(Question, 'keyword')] | [0]- 如果初始架构响应已包含完整的验证答案定义,直接使用——无需额外调用。
- 如果仅拥有标题/问题(来自截断的响应),现在检索完整定义。
- 验证答案定义了视觉对象规范——将其视为复制的蓝图。
- 构建忠实复制所有绑定和筛选器的DAX查询——不要替换、省略或添加定义中未指定的任何列或度量:
- 对象将视觉角色(Rows、Category、Columns、Values、Y、Series、Breakdown等)映射到列和度量——键的列表并不详尽。将每个绑定项与架构交叉引用,将其分类为列或度量。
Bindings - 在SUMMARIZECOLUMNS中使用所有列作为分组列,并严格使用列出的度量作为表达式。完全按照Bindings中的引用方式引用字段。
- 将中的每个筛选器作为单独的SUMMARIZECOLUMNS筛选器参数应用。不要跳过任何筛选器。将每个筛选器转换为: • 正向IN:
Filters• 所有其他条件(NOT IN、NOT NULL、IS BLANK、范围):TREATAS({values}, table[col])• 多列元组筛选器:KEEPFILTERS(FILTER(ALL(table[col]), <condition>))绝不要将多个列筛选器合并到单个KEEPFILTERS(FILTER(ALL(table[col1], table[col2]), <condition>))中——这会因自动存在(auto-exist)导致总计错误。FILTER('table', ...) - 当视觉对象有多个维度列(例如矩阵中的Rows + Columns)时,使用ROLLUPADDISSUBTOTAL为每个分组级别生成小计行。
- 不要添加验证答案定义之外的筛选器,验证答案的筛选器是完整、权威的筛选上下文。仅当用户明确请求验证答案中未包含的数据片段时(例如,“仅显示Contoso Ltd的数据”)才添加筛选器。如果验证答案省略了日期筛选器,不要添加——即使结果为空。
- 不要简化、省略度量或更改粒度。按照验证答案绑定定义的粒度展示结果——不要重新聚合或向上汇总到更粗的粒度。如果用户明确请求不同的范围、粒度或筛选器,相应地覆盖验证答案。
- 层级查询(3个及以上分组列或高基数结果):当验证答案包含高基数维度分组列时,完整的ROLLUPADDISSUBTOTAL结果可能超出行限制,截断重要的小计。使用两个并行查询:
- 摘要查询:仅包含前1-2个分组列(不使用ROLLUPADDISSUBTOTAL)和所有度量。这保证了紧凑、完整的顶层视图,绝不会被截断。
- 详情查询:使用完整的ROLLUPADDISSUBTOTAL和所有分组列。首先按小计标志降序排序(例如),然后在每个级别内按主值度量降序排序。这确保小计出现在叶子行之前并避免被截断。 如果层级有4个及以上分组级别,考虑将详情查询限制为前3-4个级别,或在每个级别使用TOPN以保持结果在行限制内。并行调用两个查询。
IsLevel1Subtotal DESC, IsLevel2Subtotal DESC, …
- 行级详情验证答案:当验证答案返回带关键度量的实体级行时,按该度量排序——而非按名称或ID排序。结果可能被截断到行限制;最重要的行必须排在前面。
验证答案定义优先于自定义指令。 当匹配到验证答案时,其绑定、筛选器和粒度是唯一的事实来源。不要根据自定义指令添加、删除或覆盖任何筛选器(例如,不要添加验证答案省略的默认时间范围筛选器)。验证答案是在了解自定义指令的情况下编写的,并有意定义了自己的筛选上下文。
JMESPath Query Examples
JMESPath查询示例
Important: Use JMESPathonly on follow-up calls — after the initial call withoutquerieshas returned a full or truncated response. Never skip the initial full call in favor of a targeted JMESPath query.queries
重要提示: 仅在后续调用中使用JMESPath——在初始无queries参数的调用返回完整或截断响应之后。绝不要跳过初始完整调用而直接使用针对性的JMESPath查询。queries
For GetReportMetadata
针对GetReportMetadata
| Purpose | Query |
|---|---|
| Overview of pages and visual titles | |
| Search visuals by keyword | |
| Extract report and page filters | |
| Find report-defined measures | |
| 用途 | 查询语句 |
|---|---|
| 页面和视觉对象标题概述 | |
| 按关键词搜索视觉对象 | |
| 提取报表和页面筛选器 | |
| 查找报表定义的度量 | |
For GetSemanticModelSchema
针对GetSemanticModelSchema
| Purpose | Query |
|---|---|
| Get Verified Answers (priority 1 when truncated) | |
| Get Custom Instructions (priority 2 when truncated) | |
| Search measures by keyword | |
| Get table details | |
| Search verified answers by keyword | |
| List all relationships | |
| 用途 | 查询语句 |
|---|---|
| 获取验证答案(截断时优先级1) | |
| 获取自定义指令(截断时优先级2) | |
| 按关键词搜索度量 | |
| 获取表详情 | |
| 按关键词搜索验证答案 | |
| 列出所有关系 | |
DAX Rules
DAX规则
When writing DAX queries, follow these strict rules:
编写DAX查询时,请遵循以下严格规则:
Query Structure
查询结构
- Include a SINGLE statement per query — never multiple
EVALUATE - ALWAYS include an clause when
ORDER BYreturns multiple rowsEVALUATE - Do not use function to sort the final query result
ORDERBY - Use at the beginning if the query includes
DEFINE,VAR,MEASURE, orCOLUMNdefinitions beforeTABLEEVALUATE - When using , use only a single
DEFINEblock. Separate definitions by newline without commas or semicolonsDEFINE - When defining a measure: ALWAYS fully qualify the measure name with its host table (e.g., ). The host table must exist in the semantic model
DEFINE MEASURE 'TableName'[MeasureName] = ... - When using a measure: refer to it by name only without table qualifier (e.g., )
[MeasureName]
- 每个查询仅包含一个语句——绝不包含多个
EVALUATE - 当返回多行时,始终包含
EVALUATE子句ORDER BY - 不要使用函数对最终查询结果排序
ORDERBY - 如果查询在之前包含
EVALUATE、VAR、MEASURE或COLUMN定义,在开头使用TABLEDEFINE - 使用时,仅使用一个
DEFINE块。定义之间用换行分隔,不要使用逗号或分号DEFINE - 定义度量时:始终使用宿主表完全限定度量名称(例如)。宿主表必须存在于语义模型中
DEFINE MEASURE 'TableName'[MeasureName] = ... - 使用度量时:仅引用其名称,不要使用表限定符(例如)
[MeasureName]
CALCULATE / CALCULATETABLE Boolean Filters
CALCULATE / CALCULATETABLE布尔筛选器
- Cannot directly use a measure or another function — use a variable to store the result first
CALCULATE - Cannot reference columns from two different tables
- When involving the operator, the table operand must be a table variable, not a table expression
IN - Do not assign a boolean filter to a definition
VAR
- 不能直接使用度量或另一个函数——先使用变量存储结果
CALCULATE - 不能引用来自两个不同表的列
- 涉及运算符时,表操作数必须是表变量,而非表表达式
IN - 不要将布尔筛选器分配给定义
VAR
SUMMARIZECOLUMNS
SUMMARIZECOLUMNS
- Parameter order: groupby columns → filters → measure-like extension columns (all optional but must follow this order)
- Use as the default for building summary tables with groupby columns and measure-like extensions
- Do NOT use without measure-like extension columns (use instead)
SUMMARIZE - Returns only rows where at least one measure value is not BLANK
- DO NOT use boolean filters
- 参数顺序:分组列 → 筛选器 → 类度量扩展列(所有参数可选,但必须遵循此顺序)
- 作为构建包含分组列和类度量扩展列的汇总表的默认方式
- 不要在没有类度量扩展列的情况下使用(改用)
SUMMARIZE - 仅返回至少一个度量值不为BLANK的行
- 不要使用布尔筛选器
SUMMARIZE
SUMMARIZE
- Only use for:
SUMMARIZE(<table expression>, <column1>, ..., <columnN>) - NEVER use with measure-like expressions — use instead
SUMMARIZECOLUMNS - For distinct values of a single column, use
VALUES('Table'[Column]) - When the first argument is a table variable, reference columns as (not
[Column])_TableVar[Column]
- 仅用于:
SUMMARIZE(<table expression>, <column1>, ..., <columnN>) - 绝不与类度量表达式一起使用——改用
SUMMARIZECOLUMNS - 对于单列的不同值,使用
VALUES('Table'[Column]) - 当第一个参数是表变量时,引用列时使用(而非
[Column])_TableVar[Column]
GROUPBY
GROUPBY
- Only use with a table-valued variable as its first argument
- is valid ONLY within
CURRENTGROUPGROUPBY
- 仅将表值变量作为第一个参数使用
- 仅在
CURRENTGROUP内有效GROUPBY
SELECTCOLUMNS
SELECTCOLUMNS
- Use to project columns (preserving duplicates) or rename columns
- After renaming, subsequent expressions (,
TOPN) must use the new column namesORDER BY
- 用于投影列(保留重复项)或重命名列
- 重命名后,后续表达式(、
TOPN)必须使用新列名ORDER BY
Other Rules
其他规则
- Include any columns needed downstream (e.g., in ,
ORDER BY) within table expressions likeFILTERorSELECTCOLUMNSCALCULATETABLE - Filters propagate across relationships based on defined direction (unidirectional or bidirectional)
- For set functions (,
INTERSECT,UNION): both input tables must have identical column countsEXCEPT - If the user does not specify a filter, respect the filters that apply to the targeted visual (visual + page + report level) and include the applied filter list in the response context.
- Do NOT borrow filters from any other visual (same page or other pages), even if they look generic, defensive, or like data-cleaning rules, unless the same filter is independently declared on the target visual or at the page/report level.
- The generated DAX must be logically equivalent to the applicable filters and must not add any predicate that alters the result beyond those filters.
- 在或
SELECTCOLUMNS等表表达式中包含下游所需的所有列(例如用于CALCULATETABLE、ORDER BY)FILTER - 筛选器根据定义的方向(单向或双向)跨关系传播
- 对于集合函数(、
INTERSECT、UNION):两个输入表必须具有相同的列数EXCEPT - 如果用户未指定筛选器,尊重目标视觉对象适用的筛选器(视觉对象+页面+报表级别),并在响应上下文中包含应用的筛选器列表。
- 不要借用任何其他视觉对象(同一页面或其他页面)的筛选器,即使它们看起来通用、防御性或类似数据清理规则,除非同一筛选器在目标视觉对象或页面/报表级别独立声明。
- 生成的DAX必须与适用筛选器在逻辑上等效,不得添加任何会改变筛选器之外结果的谓词。
Date Context for Time Intelligence
时间智能的日期上下文
- Always establish a valid date context via groupby columns from the date table or explicit date filters
- When using with time intelligence calculations, supply external filters through
ROWto establish a clear "current date" referenceCALCULATETABLE - Never use alone — it may return a future date. Use
MAX('Calendar'[Date])or filter withLASTNONBLANKbefore ordering by date[Measure] <> BLANK()
- 始终通过日期表的分组列或显式日期筛选器建立有效的日期上下文
- 当使用进行时间智能计算时,通过
ROW提供外部筛选器以建立明确的“当前日期”参考CALCULATETABLE - 不要单独使用——它可能返回未来日期。在按日期排序之前,使用
MAX('Calendar'[Date])或用LASTNONBLANK筛选[Measure] <> BLANK()
Report Measures
报表度量
- Report measures are defined in the report layer, not the semantic model. To use one in DAX, fetch its expression from and redefine it inline with
GetReportMetadata. Referencing a report-only measure by name from a DAX query will fail.DEFINE MEASURE
- 报表度量定义在报表层,而非语义模型中。要在DAX中使用报表度量,从获取其表达式,并使用
GetReportMetadata内联重新定义。直接按名称引用仅存在于报表中的度量会导致DAX查询失败。DEFINE MEASURE
Additional Rules
附加规则
- Use for ranking. Default to at most 50 rows unless the user asks for more
TOPN - INFO functions, DMV queries, and MDX are NOT supported — DAX only
- If a query returns an error, read the message, fix the DAX, retry once
- 使用进行排名。默认最多返回50行,除非用户要求更多
TOPN - 不支持INFO函数、DMV查询和MDX——仅支持DAX
- 如果查询返回错误,读取消息,修复DAX,重试一次
Examples
示例
Discover and Query
发现与查询
User: "What are the top 5 products by revenue in the Sales Benchmark report?"
Agent steps:
- Call with searchQuery: "Sales Benchmark"
DiscoverArtifacts - Pick the Report artifact → note
ArtifactId - Call with the report ID
GetReportMetadata - Call with the artifact ID — check verified answers and custom instructions
GetSemanticModelSchema - Write a DAX query using the visual's measures, bindings, and filters
- Call with the artifact ID and DAX query
ExecuteQuery - Present formatted answer
用户: “Sales Benchmark报表中按收入排名前5的产品是什么?”
Agent步骤:
- 调用,传入searchQuery: "Sales Benchmark"
DiscoverArtifacts - 选择报表工件 → 记录
ArtifactId - 使用报表ID调用
GetReportMetadata - 使用工件ID调用——检查验证答案和自定义指令
GetSemanticModelSchema - 使用视觉对象的度量、绑定和筛选器编写DAX查询
- 使用工件ID和DAX查询调用
ExecuteQuery - 展示格式化后的答案
Follow-up with Context
带上下文的后续问题
User: "Now break this down by region"
Agent steps:
- Write a new DAX query incorporating context from the previous query
- Call with the artifact ID and new DAX query
ExecuteQuery - Present formatted answer
用户: “现在按地区细分这个结果”
Agent步骤:
- 结合之前查询的上下文编写新的DAX查询
- 使用工件ID和新DAX查询调用
ExecuteQuery - 展示格式化后的答案
Value Lookup
值查找
User: "What are the sales for Terra Firma in the budget scenario?"
Agent steps:
- Call with artifact ID and searchTerms: ["Terra Firma", "Budget"]
ValueSearch - Write a DAX query using the resolved values as filters
- Call with the artifact ID and DAX query
ExecuteQuery - Present formatted answer
用户: “预算场景下Terra Firma的销售额是多少?”
Agent步骤:
- 调用,传入工件ID和searchTerms: ["Terra Firma", "Budget"]
ValueSearch - 使用解析后的值作为筛选器编写DAX查询
- 使用工件ID和DAX查询调用
ExecuteQuery - 展示格式化后的答案