25-不会还有人红灯只会重跑和甩锅吧?假绿自动修是自杀 | 红灯喂回闭环

发布时间:2026/10/31 10:58:18
25-不会还有人红灯只会重跑和甩锅吧?假绿自动修是自杀 | 红灯喂回闭环 全文速览我见过「自动修复」脚本靠删用例让 CI 变绿。那不叫智能叫自杀式优化——假绿一旦自动化团队会在欢呼里失明。这篇把红灯接回记忆闭环捕获、半自动写 lesson、过滤噪声。上一篇不会还有人把 E2E 当成单测换皮吧没有归档就没有原料 | 执行器判定归档不会还有人红灯只会重跑和甩锅吧假绿自动修是自杀 | 红灯喂回闭环系列《从 Rule 到落地AI 工程化实践》第 25 篇标签E2E · 记忆层 · 闭环 · 假绿专栏从小白到AI落地大师序言归档有了童鞋们还差最后一接红灯如何变成知识。本篇连接测试红灯与第 19 篇闭环——自动捕获、半自动写 lesson、噪声过滤、防假绿。读完你要能设计「红灯→草稿 lesson」流水线设置过滤规则并定义晋升阈值。说句自嘲的我见过「自动修复」脚本以删除用例的方式让 CI 变绿。那不叫智能叫自杀式优化。假绿一旦自动化团队会在欢呼里失明。记住一句话红灯喂回闭环机器只被允许做两种动作——出草稿、加变种任何以「变绿」为目标的自动修改期望 / 删用例 / bless 输出 / 重跑到绿一律拦下转人工。能跑的那道闸门不在模型多聪明而在自动动作的白名单有多窄。下面这份red_to_lesson.py纯标准库、复制即跑六道红灯真跑一遍拦假绿、丢噪声、演进去重、草稿进审。概念红灯关键断言失败的测试结果。捕获on_fail 钩子触发草稿 lesson。噪声过滤基础设施超时等不进长期记忆。假绿靠删用例或放宽断言变绿——禁止作为自动修复动作。召回相似失败优先命中历史 lesson。可以理解为报警器响了不是为了让你拔电池而是为了让你记一笔并修好。拔电池的自动化是最贵的安静。问题在哪对接缺失红灯只通知人不产草稿。全自动无审核噪声与错误经验入库。噪声不过滤第三方宕机教训污染适配知识。假绿修复被当成聪明短期绿长期盲。没有运营指标不知道闭环是否省时间只剩感觉。举例对接点执行器 on_fail 钩子调用 memory-boot 捕获 API。on_fail:-capture_artifacts-memory_boot.draft_lesson-notify_reviewer噪声规则drop_if_tags_any:[infra_timeout,third_party_outage]draft_if_tags_any:[assert_mismatch,parse_error]整条「红灯 → 知识」流水线画出来加上每层的典型留存率示意起点请用自家数据校准约 60% 过滤后存活约 80% 成草稿约 50% 人审通过约 10% 晋升全部红灯噪声过滤草稿 lesson入库可召回Rule / Skill数字不重要每层有漏斗可量才重要——某层留存率骤降就是流程生病的体温计。on_fail钩子不只是配置声明真身完全能用纯标准库写死。过去靠「虚构 memory-boot」搪塞的那段这次做成复制即跑的red_to_lesson.py。步骤总览红灯→知识流水线全貌优先级严格按代码执行顺序假绿闸门第 0 关最高优先级助手一旦提议delete_case / relax_assert / retry_until_green / bless_output / auto_skip_flaky这类「修到绿」的动作 → DENY降级人工。你关掉的是传感器不是故障。噪声过滤infra_timeout / third_party_outage→ 丢弃但留日志不进长期记忆——第三方宕机不是你适配器的教训。去重演进同signaturejaccard 0.6症状重叠 → 在旧条目追加变种绝不新开——这就是第 20 篇「同 id 追加变种 B」的判定逻辑真身。只产草稿全新的坑只生成statuspending草稿进人审队列注不注入是人定的机器没有 bless 权。完整可跑red_to_lesson.py# red_to_lesson.py —— 红灯喂回闭环先拦假绿 - 丢噪声 - 去重演进 - 其余进人审只产草稿绝不自动修# 纯标准库复制即跑。用法python red_to_lesson.pyfromdataclassesimportdataclass,field DROP_TAGS{infra_timeout,third_party_outage}# 噪声丢弃但留日志不进长期记忆DRAFT_TAGS{assert_mismatch,parse_error}# 值得记的料才配生成草稿# 假绿自动修复动作助手一旦提议这些直接拦——你关掉的是传感器不是故障FAKE_GREEN{delete_case:删除失败用例,relax_assert:放宽断言 / 改期望值,retry_until_green:把红的一直重跑到绿,bless_output:把当前输出 bless 成新基准,auto_skip_flaky:自动标 flaky 跳过,}dataclassclassRed:correlation_id:strtest_case_id:strsignature:str# 见第 20 篇同坑演进的锚点tags:setsymptoms:listproposed_fix:str# 助手想做的自动修复动作若有dataclassclassLesson:id:strsignature:strsymptoms:setvariants:listfield(default_factorylist)status:strpending# pending / injected / expired_draft# 库里已有一条审核通过、可召回的老 lessoninjectedrun-a1/a2 会往它身上追加变种POOL[Lesson(lesson-parse-escape,parse-escape,{unexpected token,escape},variants[A],statusinjected)]defjaccard(a,b):a,bset(a),set(b)ua|breturnlen(ab)/len(u)ifuelse0.0defroute(r):# 0) 假绿优先级最高任何「自动修到绿」的提议先于一切拦下ifr.proposed_fixinFAKE_GREEN:returndeny,(f[拦·假绿]{r.test_case_id}想「{r.proposed_fix}」f{FAKE_GREEN[r.proposed_fix]}- DENY降级人工审核)# 1) 噪声第三方宕机/基础设施超时丢弃但留日志ifr.tagsDROP_TAGS:returnnoise,f[丢·噪声]{r.test_case_id}tags{sorted(r.tags)}- 只留日志不入库# 2) 不够格没有可记的料静默ifnot(r.tagsDRAFT_TAGS):returnignore,f[不处理]{r.test_case_id}无 lesson 素材标签# 3) 去重演进同签名 症状重叠 0.6 - 追加变种不新开近义条sim0.0foroldinPOOL:simjaccard(r.symptoms,old.symptoms)ifold.signaturer.signatureandsim0.6:vidchr(ord(A)len(old.variants))old.variants.append(vid)returnmerge,(f[演进]{r.test_case_id}命中{old.id}f(jaccard{sim:.2f}) - 追加变种{vid}不新开)# 4) 全新坑只生成草稿进人审队列机器不 blesslidflesson-{r.signature}POOL.append(Lesson(lid,r.signature,set(r.symptoms),variants[A]))returndraft,f[新草稿]{lid}- 进人审队列statuspending是草稿不是基准REDS[Red(run-a1,adapt_smoke_01,parse-escape,{parse_error},[unexpected token,escape,\\r\\n]),Red(run-a2,adapt_export_07,parse-escape,{parse_error},[unexpected token,escape,u00A0]),Red(run-a3,checkout_e2e,infra-timeout,{infra_timeout},[connect timed out]),Red(run-a4,adapt_wrong_expect,encode-mismatch,{assert_mismatch},[PERFECT_TOKEN not found],proposed_fixretry_until_green),Red(run-a5,ui_anim_03,flaky-skip,{assert_mismatch},[screenshot diff],proposed_fixauto_skip_flaky),Red(run-a6,export_width_02,export-width,{assert_mismatch},[width out of range,export]),]defmain():print( 红灯喂回先拦假绿再丢噪声能演进的绝不新开剩下的只进人审 )tally{}forrinREDS:kind,lineroute(r)tally[kind]tally.get(kind,0)1print(line)print(\n 分类汇总 )order[deny,noise,merge,draft,ignore]print( .join(f{k}{tally[k]}forkinorderifkintally))print(\n lesson 池现状机器只加变种 / 出草稿人审通过才谈注入)forlinPOOL:print(f{l.id}signature{l.signature}变种{.join(l.variants)}status{l.status})print(\n 默认红线 )print( 自动动作白名单只有「出草稿」和「追加变种」改期望/删用例/bless/重跑到绿一律 DENY。)if__name____main__:main()route()里四步的次序是刻意的假绿闸门排在最前——哪怕这条红灯的 tags 看着值得记只要助手随身带了个「自动修」动作第一件事就是把它按回去。宁可漏记一条 lesson也不能让「修到绿」的冲动进自动通道。跑起来长这样python red_to_lesson.py六道红灯真实输出原样贴上 红灯喂回先拦假绿再丢噪声能演进的绝不新开剩下的只进人审 [演进] adapt_smoke_01 命中 lesson-parse-escape (jaccard0.67) - 追加变种 B不新开 [演进] adapt_export_07 命中 lesson-parse-escape (jaccard0.67) - 追加变种 C不新开 [丢·噪声] checkout_e2e tags[infra_timeout] - 只留日志不入库 [拦·假绿] adapt_wrong_expect 想「retry_until_green」把红的一直重跑到绿- DENY降级人工审核 [拦·假绿] ui_anim_03 想「auto_skip_flaky」自动标 flaky 跳过- DENY降级人工审核 [新草稿] lesson-export-width - 进人审队列statuspending是草稿不是基准 分类汇总 deny2 noise1 merge2 draft1 lesson 池现状机器只加变种 / 出草稿人审通过才谈注入 lesson-parse-escape signatureparse-escape 变种ABC statusinjected lesson-export-width signatureexport-width 变种A statuspending 默认红线 自动动作白名单只有「出草稿」和「追加变种」改期望/删用例/bless/重跑到绿一律 DENY。输出你看什么演进 2 条、新开 1 条库没长胖两条parse-escape红灯症状重叠都过 0.6旧条目上追加变种 B/C最终变种ABC只有真新坑export-width才开新条。这正是第 20 篇「五选一像抽奖」那个老病的解药——判同锚点是signature相同 jaccard 0.6两道都过才算同一坑。jaccard0.67 是算出来的不是拍的症状集三条里重合两条2/3≈0.67 刚好过 0.6 闸。换成0.5就不并进来了——阈值给的是库的肥胖门槛别调成「看着像就算」。两条假绿双双 DENY一条也没让它绿adapt_wrong_expect是第 21/22 篇PERFECT_TOKEN那个故意写错的遗留红灯助手的第一冲动就是retry_until_greenui_anim_03想auto_skip_flaky。全被打回人工——红灯面前机器只能加变种 / 出草稿绝对不能改用例或改期望。一次跑响五只闸分类汇总一行deny2 noise1 merge2 draft1说明六道红灯各走各的出口没把噪声当 lesson、没把新坑当变种、没让假绿蒙混——每层漏斗各拦住自己的那道串起来才是闭环。噪声不配进记忆池checkout_e2e的infra_timeout归日志池末尾lesson 池现状只有两条不含第三方超时——否则你的适配器 lesson 库里会住进一堆网络运维的琐事。status 是信任的等级parse-escape是injected审核过、可召回置顶export-width是pending草稿、待审。草稿在成人审队列里躺着超过 7 天没审只会变expired_draft不会被机器偷偷 bless 成基准。留意jaccard 0.6这道闸症状重叠超六成、签名又相同就是同一个坑的变种——合并演进而不是开第六条近义 lesson。运营指标别手数两条 SQL 就够起步-- 复发率同一签名 30 天内出现多次红灯的坑闭环没接住的漏网之鱼SELECTsignature,COUNT(*)ASrelapse_runsFROMred_runsWHERErun_datedate(now,-30 day)GROUPBYsignatureHAVINGCOUNT(*)1ORDERBYrelapse_runsDESC;-- 平均修复时延红灯到对应 lesson 通过人审的平均间隔SELECTavg(julianday(l.approved_at)-julianday(r.run_date))*24ASmttr_hoursFROMred_runs rJOINlessons lONl.source_run_idr.run_idWHEREl.statusIN(injected,skill_candidate);默认推荐自动出草稿审核仍人工。lesson 可建议断言补丁例如「规范化后再比较」但补丁合并仍走门禁。防假绿写进 Rule禁止以删除用例或放宽断言作为自动修复动作。运营指标草稿量、通过率、复发率、平均修复时延——用复发率看闭环是否真的省时间。自检# 红灯回流自检 - [ ] on_fail 是否能产草稿 lesson - [ ] 是否默认人工审核 - [ ] 是否有噪声过滤规则 - [ ] 是否禁止假绿自动修复 - [ ] 是否跟踪复发率等指标两问。第一自动修复动作列表里有没有「删用例」有立即拔掉。第二复发率趋势向下吗不向下闭环可能只是在产草稿没在产学习。指标不要一次上二十个。先盯复发率与平均修复时延够你判断闭环有没有在省时间。指标过多会变成新的热闹。草稿量暴涨不是业绩。审核通过率与晋升质量比草稿吨位更接近真相。红灯喂回闭环时只允许自动生成lesson 草稿禁止自动改测试期望来消红假绿。草稿进审核队列人审通过后才可注入召回。人审负荷同上文区间草稿爆炸先查门禁与路由别先扩审批人。假绿是自杀因为你关掉的是传感器不是故障。喂回队列的 SLA 也要写死草稿超过 7 天未审要么审要么标expired_draft并复盘为何没人看。无人看的闭环是装饰灯。禁止项再念一次任何脚本若以「改期望 / 跳过用例 / 自动重跑到绿」为目标默认视为假绿工具需单独安全评审。多数时候结论是删掉。防假绿还有个可迁移的做法值得从「禁清单」升级为「宪法」给修复者人或 LLM的上下文包里分两层——宪法块 知识块。宪法是硬规则「不得削弱断言、不得把负向期望改成 200」「修产品代码时测试产物只读」——它不参与相关性排序永远在场知识块历史缺陷单、接口契约、环境说明才按需检索拼入。工程细节三件可直接抄token 预算裁剪保证宪法不挤占知识位每次决策的上下文包做 hash 留痕事后可追「当时它看见了什么」宪法本身带版本号改宪法是修订事件不是随手编辑。为什么要写成机制而非口头强调因为「让测试变绿」压力下的行为高度可预测——最省事的路永远是削断言。这条宪法对自动修复链路同样适用草稿可以自动生期望绝对不可自动改。读到这里不妨立刻做一个五分钟动作打开你们仓库找到与本篇对应的那个目录没有就新建把文中最小示意落成真实文件名。文件在讨论才有坐标文件不在下周还会从「我们觉得」开始。第 25 篇的验收不是「读完」是「仓库里多了一份可指出的东西」。举例加长假绿工具黑名单示例名auto-skip-flaky、bless-output、retry-until-green——名字可以变意图不能进主仓。出现在脚本目录就报警。思考小结三句。红灯是最好的老师但要有过滤与审核。自动草稿加人工审核是稳妥默认。用复发率等指标看闭环是否真的省时间。可以理解为报警、记档、质检、改进四件事齐安静才是赚来的。但闭环转起来之后还剩一问改动到底有没有让指标变好下篇把「感觉变好了」钉成基线与回归门槛再进终章清单。下篇预告《不会还有人拿「感觉变好了」当改进吧基线不在改进不算 | 效果评测与回归门槛》——「感觉变好了」不是指标基线不在改进不算。觉得有用的话欢迎点赞、留言晒你的噪声过滤规则有「假绿自动修」的恐怖故事评论区应该能写一本书。专栏从小白到AI落地大师《从 Rule 到落地AI 工程化实践》

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询