工作流详情
针对每个蒙特卡洛预防工作流程的详细分步说明。
这些引用自主要的 SKILL.md —— 请在时参考相关部分
执行工作流。
工作流 1:表格健康检查——在打开或编辑模型时
当用户打开 dbt 模型或提到一个表时,自动运行此序列:
1. search(query="<table_name>") → get the full MCON/table identifier 2. getTable(mcon="<mcon>") → schema, freshness, row count, importance score, monitoring status 3. getAssetLineage(mcon="<mcon>") → upstream sources, downstream dependents 4. getAlerts(created_after="<7 days ago>", created_before="<now>", table_mcons=["<mcon>"]) → active alerts为用户总结:
- 健康状况:最近更新,行数,是否被监控?
- 血统:N 个上游来源,M 个下游使用者(列出重要的)
- 警报:任何活动/未确认的事件 — 如果存在,请优先显示这些
- 风险信号(精简版):如果重要性评分很高、关键资产位于下游,或警报已触发,则标记——这些都表明在修改表格之前需要格外小心
当打开 dbt 模型文件时,提供的示例摘要:
“表
orders_status上次更新是在 2 小时前,共有 142K 行。它有 3 个下游依赖,包括order_status_snapshot(关键资产)。目前有 2 个活跃的新鲜度警报 —— 在修改此表之前需要格外小心。你希望我运行完整的变更影响评估吗?”
自动升级规则 — 完成上述步骤 1–4 后:
首先,检查用户是否表达了修改模型的意图
在此会话中(例如,提到更改,请求添加/编辑/修复某些内容)。
如果已经表达了变更意图且以下任何一项为真:
- 表上存在一个或多个活动/未确认的警报
- 一个或多个下游依赖项是关键资产
- 该表的重要性得分高于0.8
→ 在运行工作流 4 之前询问用户:
这是一个高度重要的表格,包含 [N 个活跃警报 / 关键资产]
依赖项 / 重要性得分 0.989]。你想让我运行完整的
在继续之前进行变更影响评估吗?(是/否)
→ 等待确认。如果是 → 执行工作流程 4。
如果没有 → 继续,但请注意:“应您的要求跳过影响评估。”
如果存在风险信号但未表达出改变意图:
→ 显示健康摘要并仅记录风险信号:
这是一个高重要性的表格,包含关键资产依赖项。当
你准备好做出改变时,说“运行影响评估”或者只是
描述你的更改,我会自动运行它。
→ 不要运行工作流4。不要询问有关运行工作流4的事情。
新模型创建变体
当用户正在创建新的 .sql dbt 模型文件(而不是编辑现有文件)时:
- 解析 SQL 中的所有 {{ ref(‘…’) }} 和 {{ source(‘…’, ‘…’) }} 调用
- 对于每个引用的表,运行标准的工作流程1健康检查:
search() → getTable() → getAlerts() - 展示综合的上游健康概况:
您的新模型引用了 N 个上游表。以下是它们的当前状态:- 列出每项:最后更新,活跃警报(如有),关键资产标志
- 将任何有活动警报的上游表标记为风险:
⚠️ <table_name> 有 个活跃警报 —— 你的新模型将继承此数据质量问题
跳过新模型的 getAssetLineage —— 它们还没有下游依赖。
对于新型号跳过工作流程4——没有现有的影响范围可供评估。
工作流 2:添加监视器——在添加新的转换逻辑时
有关详细的监视器创建指南——包括参数验证、字段类型兼容性检查以及常见错误预防——请参阅
monitor-creation技能 (skills/monitor-creation/SKILL.md)。下面的工作流程是针对在防护会话中“刚添加了一个列,提供监视器”的常见情况的快速路径。
当用户添加新列、筛选器或业务规则时,建议添加监控器。首先,根据新逻辑的功能选择监控器类型:
- New column with a row-level condition (null check, range, regex) → createValidationMonitorMac - New aggregate metric (row count, sum, average, percentile over time) → createMetricMonitorMac - Logic that should match another table or a prior time period → createComparisonMonitorMac - Complex business rule that doesn't fit the above → createCustomSqlMonitorMac然后运行相应的序列:
1. Read the SQL file being edited to extract the specific transformation logic: - Confirm the file path from conversation context (do not guess or assume) - If no file path is clear, ask the engineer: "Which file contains the new logic?" - Extract the specific new column definition, filter condition, or business rule - Use this logic directly when constructing the monitor condition in step 3 2. For validation monitors: getValidationPredicates() → show what validation types are available For all types: determine the right tool from the selection guide above 3. Call the selected create*MonitorMac tool: - createValidationMonitorMac(mcon, description, condition_sql) → returns YAML - createMetricMonitorMac(mcon, description, metric, operator) → returns YAML - createComparisonMonitorMac(source_table, target_table, metric) → returns YAML - createCustomSqlMonitorMac(mcon, description, sql) → returns YAML ⚠ If createValidationMonitorMac fails (e.g. column doesn't exist yet in the live table), fall back to createCustomSqlMonitorMac with an explicit SQL query instead. 3. Save the YAML to <project>/monitors/<table_name>.yml 4. Run: montecarlo monitors apply --dry-run (to preview) 5. Run: montecarlo monitors apply --auto-yes (to apply)重要 —monitors apply的 YAML 格式:
所有create*MonitorMac工具返回的 YAML 无法直接与montecarlo monitors apply兼容。将输出重新格式化为独立的监控器文件,并以montecarlo:作为根键。第二级键与监控器类型匹配:custom_sql:、validation:、metric:或comparison:。下面的示例显示了custom_sql:—— 对于其他监控器类型,请替换为相应的键。
# monitors/<table_name>.yml ← monitor definitions only, NOT montecarlo.ymlmontecarlo:custom_sql:-warehouse:<warehouse_name>name:<monitor_name>description:<description>schedule:interval_minutes:720start_time:'<ISO timestamp>'sql:<your validation SQL>alert_conditions:-operator:GTthreshold_value:0.0montecarlo.yml项目配置是项目根目录下的一个独立文件,只包含:
# montecarlo.yml ← project config only, NOT monitor definitionsversion:1namespace:<your-namespace>default_resource:<warehouse_name>请勿在监控定义文件中放置version:、namespace:或default_resource:。
工作流程3:警报分流——在调查活跃事件时
1. getAlerts( created_after="<start>", created_before="<end>", order_by="-createdTime", statuses=["NOT_ACKNOWLEDGED"] ) → list open alerts 2. getTable(mcon="<affected_table_mcon>") → check current table state 3. getAssetLineage(mcon="<mcon>") → identify upstream cause or downstream blast radius 4. getQueriesForTable(mcon="<mcon>") → recent queries that might explain the anomaly响应警报:
updateAlert(alert_id="<id>", status="ACKNOWLEDGED")— 确认它setAlertOwner(alert_id="<id>", owner="<email>")— 分配所有权createOrUpdateAlertComment(alert_id="<id>", comment="<text>")— 添加上下文
工作流程 4:变更影响评估 — 在修改模型之前必须进行
触发条件:任何明确表示要添加、重命名、删除或更改列、连接、筛选器或模型逻辑的意图。请立即执行——在编写任何代码之前——即使用户没有提出要求。
修复 bug 和回滚也需要进行影响评估
当用户说“修复”、“恢复”、“还原”或“撤销”时,运行此工作流程
在编写任何代码之前——即使更改看起来很小或很安全。
撤销列添加或更改连接逻辑的回退具有相同的
爆炸半径与原始变化相同。下游模型可能已经
适应“错误”的行为,这意味着修复本身可能会破坏它们。
特别注意:
- 是否还原会移除其他模型现在依赖的列
- 下游模型是否引用了被恢复的具体逻辑
- 活动警报是否可能与被撤销的更改有关
当用户准备重命名或删除列、修改连接条件、更改过滤器或重构模型逻辑时,运行此序列以在提交任何更改之前显示影响范围:
1. search(query="<table_name>") + getTable(mcon="<mcon>") → importance score, query volume (reads/writes per day), key asset flag 2. getAssetLineage(mcon="<mcon>") → full list of downstream dependents; for each, note whether it is a key asset 3. getTable(mcon="<downstream_mcon>") for each key downstream asset → importance score, last updated, monitoring status 4. getAlerts( created_after="<7 days ago>", created_before="<now>", table_mcons=["<mcon>", "<downstream_mcon_1>", ...], statuses=["NOT_ACKNOWLEDGED"] ) → any active incidents already affecting this table or its dependents 5. getQueriesForTable(mcon="<mcon>") → recent queries; scan for references to the specific columns being changed → use getQueryData(query_id="<id>") to fetch full SQL for ambiguous cases 5b. Supplementary local search for downstream dbt refs: - Search the local models/ directory for ref('<table_name>') (single-hop only) - Compare results against getAssetLineage output from step 2 - If any local models reference this table but are NOT in MC's lineage results: "⚠️ Found N local model(s) referencing this table not yet in MC's lineage: [list]" - If no models/ directory exists in the current project, skip silently - MC lineage remains the authoritative source — local grep is supplementary only 6. getMonitors(mcon="<mcon>") → which monitors are watching columns or metrics affected by the change风险等级评估
| Tier | Conditions |
|---|---|
| 🔴 High | Key asset downstream, OR active alerts already firing, OR >50 reads/day |
| 🟡 Medium | Non-key assets downstream, OR monitors on affected columns, OR moderate query volume |
| 🟢 Low | No downstream dependents, no active alerts, low query volume |
多模型更改
当用户在同一会话或同一领域中更改多个模型时
(例如,3 个时间序列模型,4 个关键性评分模型):
- 对所有已更改的表执行一次综合影响评估
- 去重下游依赖——如果两个被更改的表共享下游
依赖项,计算一次并注意它受到多个上游更改的影响 - 提供一个统一的爆炸半径报告,而不是 N 个单独的报告
- 如果组合的爆炸半径大于任意单个表,则升级风险等级
示例综合报告标题:
变更影响:时间序列领域的3个模型
下游综合爆炸半径:28 张表(去重后)
最高风险表:timeseries_detector_routing(22 个下游引用)
报告格式
## Change Impact: <table_name> Risk: 🔴 High / 🟡 Medium / 🟢 Low Downstream blast radius: - <N> tables depend on this model - Key assets affected: <list or "none"> Active incidents: - <alert title, status> or "none" Column exposure (for columns being changed): - Found in <N> recent queries (e.g. <query snippet>) Monitor coverage: - <monitor name> watches <metric> — will be affected by this change - If zero custom monitors exist → append: "⚠️ No custom monitors on this table. After making your changes, I'll suggest a monitor for the new logic — or say 'add a monitor' to do it now." Recommendation: - <specific callout, e.g. "Notify owners of downstream_table before deploying", "Coordinate with the freshness alert owner", "Add a monitor for the new column">如果风险为🔴高:
- 调用
getAudiences()以获取已配置的通知受众 - 在推荐中包括:“通知:<受众名称/渠道>”
- 主动建议:
- 通知下游关键资产的所有者(在活动警报上使用
setAlertOwner/createOrUpdateAlertComment) - 在部署之前为新逻辑添加监控(工作流 2)
- 在进行更改后运行
montecarlo monitors apply --dry-run以验证没有东西出问题
- 通知下游关键资产的所有者(在活动警报上使用
综合:将研究结果转化为代码建议
在呈现影响报告后,使用这些发现来指导你的代码建议。
不要先展示 MC 数据,然后再写代码,好像这些数据不存在一样。
明确将每个关键发现与具体建议相连接:
表上正在触发的活动警报:
→ 建议推迟或尽量缩小更改范围,直到警报解决
→ 解释:“这个表上有 N 条活动警报 — 现在进行此更改”
有加剧现有数据质量问题的风险下游主要资产:
→ 推荐防御性编码模式:空值保护,向后兼容的更改,
尽可能仅进行增量模式更改
→ 解释:“X 下游关键资产依赖此表——我建议
以[specific pattern]的方式编写此内容以避免破坏[specific dependent]受影响列上的监视器:
→ 说明该变更将影响监控覆盖范围
→ 建议在代码更改的同时更新监控(提供工作流程2)
→ 解释:“现有的 [column] 监视器需要更新为
解释这一变化正在添加新的输出列或逻辑:
→ 无论如何,在影响评估之后总是提供工作流程2
现有监控覆盖
→ 即使风险等级为🟢低,也不要跳过这一步
→ 明确地说:"这增加了新的输出逻辑——你希望我
为它生成一个监视器?我可以添加一个空检查、范围
验证,或自定义 SQL 规则。
→ 在继续编辑之前等待用户的回应高阅读量(>50 次阅读/天):
→ 对列重命名或删除建议格外小心
→ 建议向后兼容的过渡(添加新列,弃用旧列)
→ 解释:“这个表有 [N] 次读取/天——一个没有的列重命名”
过渡期会立即影响下游消费者列重命名,即使在 CTE 中:
→ 永远不要假设 CTE 内部重命名是安全的。始终检查:- 这个列是否直接出现在最终的 SELECT 中,或者
通过一个向最终 SELECT 提供数据的 CTE? - 如果是——视为破坏性更改。建议一个
向后兼容的过渡:添加正确命名的
列,暂时保留旧的,稍后移除
后续拉取请求。 - 如果确实是内部的,并且从未出现在输出中——请确认
在继续之前明确这一点。
→ 解释:"即使这个列在一个CTE中被定义,如果它
出现在最终 SELECT 中的表面是一个公共输出列 —
重命名它会破坏任何通过名称选择它的下游模型。
- 这个列是否直接出现在最终的 SELECT 中,或者
工作流 5:更改验证查询——在代码更改后
触发条件:仅限明确的工程师意图。当工程师说类似以下内容时激活:
- “生成验证查询”、“验证此更改”、“我已完成此更改”
- “让我测试这个”,“编写查询以检查这个”,“准备提交”
所需会话上下文 — 未同时具备请勿激活:
- 工作流 4(变更影响评估)已在本会话中针对此表运行
- 对同一表的
.sql或 dbt 模型文件进行了文件编辑
在文件编辑后不要自动激活。在工作流4或文件编辑后不要主动提供。工程师准备好时会提出请求。
这个工作流程的功能
使用会话中已有的上下文——Workflow 4 的发现、文件差异和getTable结果——生成 3 到 5 个针对性的 SQL 验证查询,直接测试此特定更改是否按预期执行。
这些不是通用模板。请利用来自 Workflow 4 上下文的变更语义:哪些列发生了变化以及原因,哪些业务逻辑受到影响,哪些下游模型依赖此表,以及存在哪些监控。对新的days_since_contract_start列的空值检查应验证对于具有contract_start_date的行,其值永远不为负,也永远不为空——而不仅仅是通用地检查空值。
步骤 1 — 从会话上下文中识别变化类型
根据工作流 4 的发现和文件差异,分类主要变化。一个变化可能涵盖多种类型——请分类主要类型并注明次要类型:
- 新列— 在 SELECT 中添加了一个新的输出列
- 筛选器更改— WHERE 子句、IN 列表或 CASE 条件已被修改
- 加入更改— JOIN 条件或连接目标已被修改
- 列重命名或删除— 现有输出列已被重命名或移除
- 参数更改— 硬编码的阈值、常量或数值已被更改
- 新模型— 文件是新创建的,尚不存在生产基线
步骤 2 — 从工作流程 4 确定仓库上下文
从会话上下文中已有的getTable结果中提取:
- 完全限定表名— 例如
analytics.prod_internal_bi.client_hub_master - 仓库类型— Snowflake, BigQuery, Redshift, Databricks
- 模式— 已解决,无需重新推导
根据仓库类型使用正确的 SQL 方言。主要区别:
| Warehouse | Date diff | Current timestamp | Notes |
|---|---|---|---|
| Snowflake | DATEDIFF('day', a, b) | CURRENT_TIMESTAMP() | QUALIFYsupported |
| BigQuery | DATE_DIFF(a, b, DAY) | CURRENT_TIMESTAMP() | Use subquery instead ofQUALIFY |
| Redshift | DATEDIFF('day', a, b) | GETDATE() | |
| Databricks | DATEDIFF(a, b) | CURRENT_TIMESTAMP() |
对于开发数据库,使用占位符<YOUR_DEV_DATABASE>并添加注释,指示工程师将其替换。不要猜测开发数据库的名称。
步骤 3 — 应用数据库定位规则(必填)
这些规则不可协商——违反它们会导致运行时查询失败:
- 仅在变更后存在的列或逻辑→ 仅限开发数据库。切勿在生产环境中查询尚不存在的列。
- 比较查询(前后对比)→ 包括生产和开发数据库
- 新模型(无生产基线)→ 所有查询仅限开发数据库
- 行数比较→ 始终包含,始终查询两个数据库
第4步 — 生成针对性的验证查询
无论更改类型如何,都应始终包括行数比较——这是表明发生了意外情况的基准信号。
然后根据需要验证的此更改类型生成特定于更改的查询。使用 diff 和工作流程 4 结果中的确切条件、列名和业务逻辑——不要使用通用占位符。每种更改类型的目标是:
新列:验证该列在应为非空的情况下是否非空(基于其业务含义),其取值范围是否合理,以及其分布是否符合底层数据。仅限开发查询。
过滤器更改:验证只有预期的行被重新分类——使用差异中的精确过滤逻辑生成前后计数,显示有多少行因新条件被添加或删除,以及分类发生变化的行的示例。示例有助于工程师确认正确的记录已移动。
连接变更:验证连接没有引入重复——对连接键进行唯一性检查是必要的。还要验证行数是否没有意外变化。查询开发环境以检查唯一性,查询两个数据库以检查行数。
列重命名或删除:验证旧列名在开发模式中已不存在,并且新列(如果已重命名)存在。还要验证引用旧列名的下游模型是否已被识别——如果可用,请使用工作流 4 的本地 ref() grep 结果。
参数或阈值更改:验证受更改影响的值的分布 —— 有多少行移动到新的阈值之上或之下,以及数量是否符合工程师的预期。查询两个数据库以比较更改前后的情况。
新模型:无法进行生产比较。请确认行数非零且合理,样本行看起来正确,关键列非空。仅查询开发环境。
步骤 5 — 为每个查询添加特定变更的上下文
对于每个查询,包括一个解释的 SQL 注释块:
- 查询正在检查的内容
- 针对这一具体变化,健康的结果是什么样的
- 什么会表明有问题
从工作流程4的发现中推导此上下文。使用变更的业务含义,而不是通用描述。例如,对于添加days_since_contract_start:
/* Null rate check: days_since_contract_start (new column, dev only) What to look for: - Null count should equal workspaces with no contract_start_date - All rows with contract_start_date should have a non-null, non-negative value - Values above 3650 (~10 years) are suspicious and may indicate a data issue */这就是这些查询与通用验证的区别——评论告诉工程师他们的具体更改中通过和失败的具体表现。
第6步 — 保存到本地文件
将所有生成的查询保存到:
validation/<table_name>_<YYYYMMDD_HHMM>.sql在文件顶部包含一个标题:
/* Validation queries for: <fully_qualified_table> Change type: <change type from Step 1> Generated: <timestamp> Workflow 4 risk tier: <tier from this session> Instructions: 1. Replace <YOUR_DEV_DATABASE> with your personal or branch database 2. Run the row count comparison first 3. Run change-specific queries to validate intended behavior 4. Unexpected results should be investigated before merging */然后告诉工程师:
“验证查询已保存到
validation/<table_name>_<timestamp>.sql。”
将<YOUR_DEV_DATABASE>替换为你的开发数据库,并在 Snowflake 中运行
或您首选的 SQL 客户端来验证更改是否按预期进行。
此工作流不执行的操作
- 不执行查询(阶段 2)
- 不需要仓库MCP连接
- 不生成蒙特卡洛笔记本 YAML
- 不会自动触发——仅在工程师明确请求时触发
- 如果此会话中工作流 4 尚未在此表上运行,则不会激活