特定提示测试失败时,如何提醒到对的人

Dev.to ML 2026-08-13T18:49:19.643894

提示词测试套件是一种共享基础设施,覆盖多个团队的提示词。如果按测试文件的归属来分发失败通知,那么所有警报都会送到平台团队,而这些问题他们一个也修不了。

错误的分发依据

大多数 CI 系统默认会通知推送提交的人。对单元测试来说这没问题,但在这里行不通,原因很具体:提示词测试失败的原因往往和这次提交毫无关系。比如模型默认行为变了、某个供应商开始拒绝某类输入、共享检索索引被重建了。推送提交的人大概只有一半概率是正确收件人;另一半情况下,他们要花一个小时才发现问题并不在自己。

应该按产物来路由

失败的测试加载了某个提示词文件;这个文件有归属人,那才是应该通知的人。这种方式能正确处理基于提交者的规则会弄错的场景,因为它不关心测试为什么失败——谁拥有账单退款提示词,谁就该去看账单退款失败的问题,无论原因是什么。在共享测试套件下,这种方式也能正常工作:一个测试文件通过参数化覆盖两百个用例,可以分发给十五个不同的团队。这需要我们在构建「哪个提示词版本破坏了什么」的报告时做一次关联查询。如果运行过程没有记录每个用例加载的是哪个提示词,那就没有可用的路由依据,后面的一切都无从谈起。

复用已有的归属文件

大多数仓库已经通过 CODEOWNERS 维护了一份归属映射,这份文件因为把关代码评审而一直保持更新。复用它意味着只需要维护一份映射,而不是两份——而第二份映射往往很快就会过期。

# CODEOWNERS
prompts/ @acme/ai-platform
prompts/billing/ @acme/payments
prompts/billing/refund.md @acme/refunds-squad
prompts/support/ @acme/support-eng

实现查找时有一条规则很关键:GitHub 的 CODEOWNERS 采用「最后匹配者胜出」的规则,这与 .gitignore 以及大多数人凭记忆写出的路由表所习惯的「最先匹配」正好相反。如果查找逻辑返回第一个匹配项,那么所有账单失败都会发给平台团队,因为 prompts/ 排在最前面。正确的做法是按顺序遍历文件,保留最后一次命中的条目。

刻意地沿目录树向上回退:如果 prompts/billing/refund.md 没有对应的归属条目,那么最近的、带有归属条目的祖先目录就是所有者;如果仍无匹配,则把失败归给套件所有者,并附带一条“该文件无主”的说明。无主的提示词本身就是一种发现,应当让人看到,而不是被静默丢弃。

当没有可供路由的路径时一些失败并不涉及提示词文件,比如测试框架错误、夹具无法加载、服务商故障、cassette 不再匹配。对于这些情况,就给测试本身加上所有者标签。在 pytest 中,自定义标记是在项目配置的 markers 下注册的受支持机制,调用处读起来也很清晰:

# pyproject.toml

当特定提示测试失败时,通知正确的人

# [tool.pytest.ini_options]
# markers = ["owner(team): the team paged when this test fails"]
@pytest.mark.owner ( " ai-platform " )
def test_cassette_index_is_loadable ():
    ...

在报告钩子(reporting hook)里读取这个标记,把它挂到测试结果上。JavaScript 测试套件里没有同样稳定的对应物,所以更省事的路子是定一套命名约定:只要每个测试 ID 都以某个功能片段开头(正如“提示测试套件的命名约定”里讲的那样),路由表就是一张从该片段到团队名字的映射,完全不需要框架支持。

告警消息里必须有什么:假设接收人手里端着咖啡,只有十秒时间。有四件事决定他立刻处理还是关掉标签页:

告警消息里绝不能有的是渲染后的提示词和模型输出。这两者经常包含客户文本,而聊天频道的受众范围比这些文本原本所在的数据存储广得多。

不要发送其余十九条:任何告警方案的失败模式都是数量,提示词套件尤其擅长制造数量——一次糟糕的编辑就能同时放倒四十个参数化用例。三条规则能让告警不至于把人淹没。

查看原文