ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

ZenML Slack Alerter 集成指南:从管道向 Slack 频道发送消息与人工审批

ZenML Slack Alerter 集成指南:从管道向 Slack 频道发送消息与人工审批 ZenML Slack Alerter 集成指南从管道向 Slack 频道发送消息与人工审批【免费下载链接】zenmlZenML : One AI Platform from Pipelines to Agents. https://zenml.io.项目地址: https://gitcode.com/GitHub_Trending/ze/zenmlZenML 的 Alerter 组件用于在管道与步骤运行过程中向聊天工具发送通知而SlackAlerter正是这一能力的 Slack 实现它可以让你的 Pipeline 直接把消息发布到指定的 Slack 频道甚至在关键节点如模型部署前发起提问并等待人工审批Human-in-the-Loop。读完本文你将掌握从零创建 Slack App、在 ZenML 中注册并挂载 alerter、通过post()/ask()及预置步骤实现通知与审批的完整实战方案。什么是 ZenML Alerter 与 SlackAlerter在 ZenML 中Alerter 是与 Orchestrator、Artifact Store 等并列的 Stack 组件类型。其抽象基类定义在 src/zenml/alerter/base_alerter.py 中BaseAlerter所有 alerter 的基类声明了两个核心方法post(message, params)向聊天服务发布一条消息返回布尔值表示是否成功ask(question, params)发布一条消息并等待审批常用于「部署前请人来确认」的场景返回True表示已批准。BaseAlerterFlavor与BaseAlerterConfig分别定义组件 flavor 与配置的基类。SlackAlerter继承自BaseAlerter具体实现位于 src/zenml/integrations/slack/alerters/slack_alerter.py底层使用官方slack-sdkZenML 要求版本为slack-sdk3.30.0见 src/zenml/integrations/slack/init.py调用 Slack Web API。第一步准备 Slack 工作区与 Slack App使用SlackAlerter的前提是拥有一个 Slack 工作区Workspace以及一个用于收发的频道Channel。进入 Slack API 控制台创建 Slack App选择 From scratch并把它安装Install到你的工作区App 中需要启用一个 Bot。在 App 的OAuth Permissions选项卡下的Scopes中为 Bot Token 授予以下权限chat:write允许向频道发送消息channels:read允许读取频道信息用于校验频道 IDchannels:history允许读取频道历史消息这是ask()轮询用户回复所必需的。如果你需要使用ask()功能等待审批必须把 App 的 Bot 邀请进目标频道既可以在频道内直接使用/invite命令也可以通过频道设置界面添加。注意App 创建后可能需要一段时间才会在工作区注册完成、出现在可选应用列表中请耐心等待片刻。第二步在 ZenML 中注册 Slack Alerter安装 Slack 集成首先安装 ZenML 的 Slack 集成zenml integration install slack -y安装完成后SlackAlerter及预置步骤、flavor 即被注册到 ZenML。创建密钥推荐并注册组件官方推荐的做法是把 Slack Token 存为 ZenML Secret然后在注册 alerter 时用{{secret_name.key}}语法引用避免在配置中明文暴露敏感信息zenml secret create slack_token --oauth_tokenSLACK_TOKEN zenml alerter register slack_alerter \ --flavorslack \ --slack_token{{slack_token.oauth_token}} \ --slack_channel_idSLACK_CHANNEL_ID两个占位参数的含义SLACK_CHANNEL_ID频道 ID可在频道详情Channel details中找到通常以C....开头SLACK_TOKENBot 的 OAuth Token可在 Slack App 设置的OAuth Permissions选项卡中复制xoxb-开头。从源码看slack_token在配置类中被声明为SecretField见 src/zenml/integrations/slack/flavors/slack_alerter_flavor.py 中的SlackAlerterConfigZenML 会自动对其实施脱敏与密钥管理。另外旧的default_slack_channel_id配置项已被弃用会自动迁移到slack_channel_id。校验配置SlackAlerterConfig.is_valid属性会在组件注册/使用时自动校验配置它用slack_sdk的WebClient调用auth_test()验证 Token 有效性并在配置了slack_channel_id时调用conversations_info()验证频道存在性。若 Slack 集成未安装校验会跳过并返回True。挂载到 Stack注册完成后把 alerter 加入你的 Stack 并设为 activezenml stack register ... -al slack_alerter --set此后Client().active_stack.alerter即返回该SlackAlerter实例。第三步在管道中直接使用post()与ask()最直接的用法是在 step 中通过 Client 获取 active stack 的 alerter然后调用其方法from zenml import pipeline, step from zenml.client import Client step def post_statement() - None: Client().active_stack.alerter.post(Step finished!) step def ask_question() - bool: return Client().active_stack.alerter.ask(Should I continue?) pipeline(enable_cacheFalse) def my_pipeline(): # Step using alerter.post post_statement() # Step using alerter.ask ask_question() if __name__ __main__: my_pipeline()注意ask()在发生错误时默认返回False详见下方实现分析请勿把异常场景误判为「用户拒绝」。第四步使用自定义 Settings 切换频道SlackAlerterSettings支持两个运行时属性slack_channel_id可选与timeout默认 300 秒。你可以在 step 的settings中覆盖它们from zenml import pipeline, step from zenml.client import Client # 例如通过 settings 指定另一个频道 ID。但如果你要用 ask 功能 # 请确保你的 App 已被邀请进该频道。 step(settings{alerter: {slack_channel_id: YOUR_SLACK_CHANNEL_ID}}) def post_statement() - None: alerter Client().active_stack.alerter alerter.post(Posting to another channel!) pipeline(enable_cacheFalse) def my_pipeline(): # Using alerter.post post_statement() if __name__ __main__: my_pipeline()频道解析的优先级对应_get_channel_id()的实现逻辑调用时传入的SlackAlerterParameters.slack_channel_id当前 step 的运行时 settings 中的slack_channel_id组件配置SlackAlerterConfig.slack_channel_id。若三者均未设置会抛出ValueError提示你至少指定一处。类似地timeout也遵循「settings 优先、config 兜底」的规则_get_timeout_duration()。第五步用SlackAlerterParameters与SlackAlerterPayload精细控制消息除了基础参数Slack 集成还提供了两个扩展类同样定义在 slack_alerter.pySlackAlerterPayload携带pipeline_name、step_name、stack_name三个可选字段用于在消息中自动填充管道上下文信息SlackAlerterParameters继承自BaseAlerterStepParameters字段包括slack_channel_id本次调用的频道 IDapprove_msg_options/disapprove_msg_options自定义批准/拒绝关键词列表payloadSlackAlerterPayload实例include_format_blocks默认True是否自动附加格式化 Blockblocks完全自定义的 Slack Block Kit 结构List[Dict]。示例一附带管道信息的消息from zenml import pipeline, step, get_step_context from zenml.client import Client from zenml.integrations.slack.alerters.slack_alerter import ( SlackAlerterParameters, SlackAlerterPayload ) # Displaying pipeline info step def post_statement() - None: params SlackAlerterParameters( payloadSlackAlerterPayload( pipeline_nameget_step_context().pipeline.name, step_nameget_step_context().step_run.name, stack_nameClient().active_stack.name, ), ) Client().active_stack.alerter.post( messageThis is a message with additional information about your pipeline., paramsparams ) # Formatting with blocks and custom approval options step def ask_question() - bool: message :tada: Should I continue? (Y/N) my_custom_block [ { type: header, text: { type: plain_text, text: message, emoji: True } } ] params SlackAlerterParameters( blocksmy_custom_block, approve_msg_options[Y], disapprove_msg_options[N], ) return Client().active_stack.alerter.ask(questionmessage, paramsparams) step def process_approval_response(approved: bool) - None: if approved: print(User approved! Continuing with operation...) # Your logic here else: print(User declined. Stopping operation.) pipeline(enable_cacheFalse) def my_pipeline(): post_statement() approved ask_question() process_approval_response(approved) if __name__ __main__: my_pipeline()内部 Block 生成逻辑_create_blocks()决定最终发送的 Slack Block若params.blocks非空直接使用你的自定义 Block日志提示 Using custom blocks否则若params.payload存在自动生成默认 Block一个包含 Pipeline、Step、Stack 信息mrkdwn字段并附带 ZenML 图标的 Section以及一个包含消息正文的 Section若两者皆无返回空列表此时消息以纯文本text形式发送。第六步使用预置步骤快速接入如果你只需要最简单的「发消息/问问题」能力Slack 集成自带两个开箱即用的 step无需手写Client().active_stack.alerter逻辑from zenml import pipeline, step from zenml.integrations.slack.steps.slack_alerter_post_step import ( slack_alerter_post_step ) from zenml.integrations.slack.steps.slack_alerter_ask_step import ( slack_alerter_ask_step, ) step def process_approval_response(approved: bool) - None: if approved: print(Operation approved!) else: print(Operation declined.) pipeline(enable_cacheFalse) def my_pipeline(): slack_alerter_post_step(Posting a statement.) approved slack_alerter_ask_step(Asking a question. Should I continue?) process_approval_response(approved) if __name__ __main__: my_pipeline()这两个 step 的实现位于 slack_alerter_post_step.py 与 slack_alerter_ask_step.py它们会校验当前 active stack 的 alerter 确实是SlackAlerter类型否则抛出RuntimeError避免误配其他 alerter flavor 时静默失败当params.include_format_blocks为真时自动从 step 上下文填充SlackAlerterPayloadpipeline 名、step 名、stack 名分别调用alerter.post(...)/alerter.ask(...)并返回布尔结果。仓库中 tests/integration/examples/slack/pipelines/ask_pipeline.py 展示了真实的组合用法训练 SVC 模型并评估后把测试准确率格式化成消息调用slack_alerter_ask_step询问是否部署将审批结果作为deploy_decision传给mlflow_model_deployer_step——这正是「模型部署前人工审批」的经典模式。默认响应关键词与ask()行为ask()与slack_alerter_ask_step默认识别以下关键词定义在 slack_alerter.py 的模块级常量中批准Approvalapprove、LGTM、ok、yes拒绝Disapprovaldecline、disapprove、no、reject行为要点ask()返回布尔值True表示批准False表示拒绝或超时关键词匹配不区分大小写实现中会把用户回复strip().lower()后与opt.lower()比对因此LGTM、lgtm、Lgtm都有效在超时时间内未收到有效回复返回False默认超时为 300 秒5 分钟可通过timeout配置。底层轮询机制ask()的实现slack_alerter.ask值得注意用chat_postMessage把问题发到频道并从响应中取出消息时间戳ts进入轮询循环以ts为oldest调用conversations_history拉取该时间点之后的消息逐条检查文本是否命中批准/拒绝关键词每次轮询间隔 1 秒直到达到_get_timeout_duration()的超时上限全程捕获SlackApiError与通用异常并记录日志出错时返回False——这正是文档中「出错默认返回 False」警告的源码依据。同时这也解释了为什么ask()需要channels:history权限。常见问题与排错建议App 已创建但频道里看不到等待应用注册完成或重新安装 App 到工作区确认 Bot 已被邀请进目标频道。post()返回False查看日志中的 Slack API error如not_in_channel、invalid_auth、missing_scope核对 Token 与权限范围是否与上文一致。ask()一直等到超时确认频道内有channels:history权限、Bot 在频道内且回复文本与关键词完全匹配会先转小写。配置校验失败利用SlackAlerterConfig.is_valid的auth_test/conversations_info校验信息检查 Token 是否有效、频道 ID 是否以C开头。小结SlackAlerter为 ZenML 管道提供了两条清晰的通信通道post()用于单向通知如 step 完成、训练结束ask()用于需要人工介入的审批如模型部署前的确认。结合 ZenML Secret 管理 Token、settings 覆盖频道与超时、SlackAlerterParameters/SlackAlerterPayload定制消息内容以及开箱即用的预置 step你可以在不写一行 Slack API 调用的情况下把「通知 审批」能力完整嵌入 ML 管道。相关源码可进一步阅读 slack_alerter.py、slack_alerter_flavor.py 与集成测试示例 ask_pipeline.py。【免费下载链接】zenmlZenML : One AI Platform from Pipelines to Agents. https://zenml.io.项目地址: https://gitcode.com/GitHub_Trending/ze/zenml创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进