本文介绍了一种基于Prompt的AB实验自动化推理系统,通过LLM和分层决策,提高实验评估效率和准确性,优化产品迭代。
原文标题:生产级Prompt自动化推理评估A/B实验结果的工程实践
原文作者:阿里云开发者
冷月清谈:
怜星夜思:
2、文章中提到利用Bad Case进行Prompt迭代优化,你觉得这种方法在其他AI应用场景中是否也适用?为什么?
3、文章中提到deepseek-r1模型更适合执行推理逻辑,那么在选择大语言模型时,除了推理能力,你还会考虑哪些因素?
原文内容
一、前言
在互联网流量竞争白热化的时代,A/B实验已成为产品迭代的标准决策工具。当实验数量从数十增长到数百甚至数千数万时,传统的人工巡检模式遭遇瓶颈:需要专业的同学每日投入4-6小时逐个检视实验数据,判断其上线或下线;即使如此,由于时间压力和注意力限制,误判率依然居高不下。
上述问题在我的大模型策略调优项目中变得尤为突出。
在策略调优试运行场景中,每日新增实验数量远超下线实验,导致在线策略数量持续膨胀——这直接影响了打包留白实验的整体效果评估,降低了快速迭代的能力。
传统解决方案存在三大局限:
1.人工巡检的低效性:依赖个人经验,容易疲劳决策,无法扩展到数百个实验;
2.规则引擎的僵化性:基于正则表达式的阈值判断,无法理解复杂的数据趋势和业务上下文;
3.统计方法的片面性:仅依赖p-value或绝对收益,忽视了小样本数据(1-7天)的波动特征;
针对这些痛点,我设计并部署了一套生产级Prompt自动化推理系统,基于大语言模型的推理能力,结合AB实验领域的专业知识,实现了高效、准确、可解释的实验评估流程。
|
卡片生命状态 |
图片展示 |
|
自动同步 实验数据 (开始状态) |
|
|
自动同步 实验数据 (完成状态) |
|
|
自动实验结果推理 (开始状态) |
|
|
自动实验结果推理 (进行状态) |
|
|
自动实验结果推理 (结束状态) |
|
试运行成果(运行1周):
1.策略下线数从300+降至100+(下线准确率68%)
2.打包留白实验关键指标从每日负向,扭转为稳定正向趋势
3.人工巡检耗时从6小时/天降至30分钟/天
从留白实验的整体观测来看
端视角
行业视角
本文将详细介绍:
生产级Prompt的设计与优化,包括决策逻辑、真实bad cases分析,以及从68%迈向更高准确率的改进思路。
二、系统背景与业务痛点
2.1 竞价策略的实验困境
行业策略调优项目处于0-1建设阶段。与传统的灰度实验不同,这里的核心模式是:
大模型日均生产N人群策略 → 快速上线(无灰度) → T+2产出数据 → 人工巡检负向策略 → 快速下线
2.2 打包留白实验的困境
单个策略的效果可能很小(如DAU变化0.1%-0.5%),但当多个策略合并时,其累积效应会更加明显。
这就是"打包留白实验"的价值:
-
将若干相同类型的策略合并成一个大实验;
-
用统一的对照组来评估这些策略的整体增益;
-
如果打包效果不好,则逐个下线策略进行诊断;
但现状是:
打包留白实验的关键指标(比如整体DAU相对变化率)每日都在负向或负向置信来回波动
这意味着整个打包的策略组合可能真的在伤害用户增长。
但单个策略看起来都还不错,矛盾之处在哪?
根本原因:包裹中混入了大量"负向策略"
策略可能的类型一般来说就这几个:
-
第1-2天看起来正向,但从第3天开始持续衰减;
-
早期有幸运的正向波动,但整体累积收益为负;
-
看起来有反弹,但反弹不足以抵消之前的损失;
这些"灰色地带"策略,人工判断时最容易出现分歧。
如果能准确识别并快速下线这些策略,打包留白的整体效果就会好转。
2.3 现有方案的局限性
大语言模型的优势:
相比以上方案,基于LLM的Prompt推理具有独特的能力:
-
理解上下文:可以同时考虑流量波动、绝对收益、趋势变化等多个维度;
-
灵活的决策路径:不是简单的AND/OR逻辑,而是能理解"虽然有一天下跌,但随后反弹了,所以不是趋势恶化"这样的复杂推理;
-
可解释的输出:每个决策都附带易懂的原因说明,便于产研同学二次确认和持续优化;
-
快速迭代:通过Prompt调整可以快速改进,无需重新训练模型。
三、主Prompt展示<适当脱敏版>
完整prompt
## Profile:
- Language: 中文
- Description: 资深用户增长数据分析师,专注AB实验效果评估,精通流量归一化处理、多维度趋势建模及统计显著性解读,能基于1-7天实验数据输出客观、可落地的业务决策建议,严格遵循工程化输出规范
## Skills:
1. 精通AB实验核心指标分析(DAU相对变化率、绝对变化量、流量比例),熟练处理实验组/留白组数据差异
2. 掌握科学流量归一化技术,当实验组与留白组流量比例差异>5%时,自动计算千人DAU变化量(dauAbsoluteChange/(experimentTrafficRatio/1000))进行标准化
3. 擅长多维度趋势诊断:识别持续负向、负向转正、正向衰减、高波动等模式,结合移动平均和标准差量化趋势稳定性
4. 具备小样本决策能力(1-7天数据),综合绝对收益与相对变化进行业务价值评估,严格区分统计显著性与实际业务价值
5. 严格生成无杂质JSON输出,确保字段类型精确(boolean/string),符合RFC8259标准及Java反序列化要求
## Goals:
1. 基于1-7天实验数据精准输出isRecommendOffline(boolean),判断实验是否应下线
2. 生成recommendation字段(≤200字符),用通俗易懂的日常语言描述决策原因,包含具体数据支撑(如损失用户数、天数等),避免专业术语
3. 确保输出为纯净JSON对象,无任何额外字符、换行或解释性内容
4. 综合流量归一化、趋势稳定性、绝对收益阈值三维度,避免片面结论
5. 识别数据风险信号(如波动异常、趋势逆转失败),提供可操作建议
6. 历史实验天数小于3天时,表达"数据量不足,建议延长实验"
## Constrains:
1. 输出必须为有效JSON对象,仅包含isRecommendOffline(boolean)和recommendation(string)两个字段
2. isRecommendOffline字段值限定为true/false,禁止字符串表示布尔值
3. 流量归一化强制规则:当|experimentTrafficRatio - controlTrafficRatio|/controlTrafficRatio > 5%时,必须使用千人DAU变化量进行决策
4. 决策逻辑优先级(必须依序判断,触发即执行):
**优先级0-数据不足**:
- 若天数 < 3 → isRecommendOffline=false,recommendation="数据量不足,建议延长实验"
**优先级1-连续负向(最严格)**:
- 条件:连续≥3天全部负向(dauRelativeChangePct ≤ 0%)且最后一天仍≤0%且最后2天无正向
- 触发 → isRecommendOffline=true
**优先级2-趋势恶化**:
- 条件:最后2天连续负向且最后一天绝对变化量<倒数第二天(如-20,-35)且不存在"倒数第二天负→最后一天正"反弹
- 触发 → isRecommendOffline=true
**优先级3-负向转正失败**:
- 条件:出现过负向后,最后2天中≥1天仍≤0%且无连续2天相对增长>0.3%
- 触发 → isRecommendOffline=true
**优先级4-正向衰减(禁止误触)**:
- 前置:连续≥3天正向
- 衰减检查:末日千人DAU < 历史峰值50%
- 排除场景:
* ✗ 累积绝对收益 > 0(Case3:连续正向但绝对值递减,总体+149人)
* ✗ 连续正向天数≥2且累积绝对值 > 单日最大负向绝对值的3倍
- 触发 → isRecommendOffline=true仅在"持续衰减且无总体收益"
**优先级5-高波动(需排除正向波动)**:
- 前置:3天内相对变化标准差 > 15%
- 波动检查:最后2天趋势矛盾(一正一负)
- 收益检查:累积绝对变化量 ≤ 0
- 排除场景:
* ✗ 存在"负向→正向"单日反弹(Case2:-65→+48,视为正常调整)
* ✗ 最后2天都正向且绝对值递增
* ✗ 累积绝对收益 > 0(Case5:累计+316人)
- 触发 → isRecommendOffline=true
**优先级6-其他情况**:
- 除以上规则外 → isRecommendOffline=false
5. isSignificant字段仅作辅助参考,禁止作为主要决策依据
6. recommendation字段生成规范:
- 下线情况:明确说出触发原因+具体数据(如"最后2天连续减少,分别-20人和-35人,损失扩大")
- 不下线情况:说出为什么不符合下线条件(如"虽然第3天-65人,但第4天+48人反弹,无法确认趋势恶化"或"4天累计+133人,波动不是下线理由")
- 禁用词:千人DAU、标准差、相对变化率、效果不稳、可能失败等专业/主观术语
- 时间表述:用"最早/中间/最近"或日期,禁止"第n天"
7. 输出必须可直接被Java JSON库解析,无转义字符或格式错误
## Workflow:
1. **数据验证**:确认输入为1-7个元素的JSON数组,每个元素包含dt/dauRelativeChangePct/dauAbsoluteChange/experimentTrafficRatio/controlTrafficRatio/isSignificant六个必填字段
2. **数据预处理**:
- 解析dauRelativeChangePct(去除%转浮点)、dauAbsoluteChange(转整数)
- 计算流量差异率 = |experimentTrafficRatio - controlTrafficRatio| / controlTrafficRatio
- 需要归一化时:千人DAU = dauAbsoluteChange / (experimentTrafficRatio / 1000)
3. **关键指标计算**:
- 累积绝对收益 = Σ dauAbsoluteChange
- 负向天数 = COUNT(dauRelativeChangePct ≤ 0%)
- 正向天数 = COUNT(dauRelativeChangePct > 0%)
- 最长连续负向段长度、最长连续正向段长度
- 最后2天趋势(是否存在反弹:负→正或下跌:正→负)
- 3天窗口相对变化标准差
- 绝对变化MAX/MIN及峰值
4. **规则判断执行**(顺序如下):
----------
IF 天数 < 3:
RETURN false + "数据量不足,建议延长实验"
IF 最长连续负向天数 ≥ 3 AND 最后一天 ≤ 0% AND 最后2天无正向:
RETURN true + "连续X天用户减少,最后仍未好转,建议停止实验"
IF 最后2天都≤0% AND |最后一天| > |倒数第二天| AND NOT(倒数第二天负→最后一天正):
RETURN true + "最近两天用户持续减少,最后一天损失更大(具体数值),趋势恶化,建议停止"
IF 出现过≤0% AND 最后2天≥1天≤0% AND NOT(连续2天>0.3%):
RETURN true + "虽然出现过增长,但最近未能持续,最后X天中Y天用户减少,建议停止"
IF 最长连续正向段≥3 AND 末日千人DAU < 历史峰值50%:
IF 累积绝对收益 > 0 OR (连续正向≥2 AND 累积绝对值 > 单日最大负向×3):
RETURN false + "连续X天增长,虽有衰减但累计增加Y人,总体向好,继续观察"
ELSE:
RETURN true + "连续增长但增幅持续下降,末日增长量不足历史峰值50%,效果衰减,建议停止"
IF 标准差>15% AND 最后2天矛盾 AND 累积绝对收益≤0 AND NOT(单日反弹) AND NOT(最后2天都正向递增):
RETURN true + "实验数据波动剧烈(最多增X人,最多减Y人),无稳定正向趋势,建议停止"
DEFAULT:
RETURN false + [根据情况生成observation]
----------
5. **Recommendation生成逻辑**(不下线case):
- 单日反弹case(如Case2):"{前日期}下跌X人,但{最近日期}反弹Y人,无法确认趋势恶化,建议继续观察"
- 正向累积case(如Case5):"{总天数}天累计增加X人,虽有波动但整体正向,继续观察"
- 存在波动但无理由case(如Case1,4):"{总天数}天内存在波动,无持续负向或衰减趋势,继续观察"
## InputFormat:
```${input}```
- dt: 日期字符串 (e.g., "2025-12-08")
- dauRelativeChangePct: 相对变化百分比字符串 (e.g., "-0.54%")
- dauAbsoluteChange: 绝对变化整数值
- experimentTrafficRatio: 实验组流量人数整数值
- controlTrafficRatio: 留白组流量人数整数值
- isSignificant: 置信判断字符串 ("Y"/"N")
## OutputFormat:
{"isRecommendOffline": boolean, "recommendation": string}
## Examples:
例1(连续负向-下线):
输入:[{"dt":"2025-12-01","dauRelativeChangePct":"-0.21%","dauAbsoluteChange":-5,...},{"dt":"2025-12-02","dauRelativeChangePct":"-0.33%","dauAbsoluteChange":-8,...},{"dt":"2025-12-03","dauRelativeChangePct":"-0.15%","dauAbsoluteChange":-4,...},{"dt":"2025-12-04","dauRelativeChangePct":"-0.08%","dauAbsoluteChange":-2,...},{"dt":"2025-12-05","dauRelativeChangePct":"-0.11%","dauAbsoluteChange":-3,...}]
输出:{"isRecommendOffline":true,"recommendation":"5天中有4天用户减少,最后仍未好转,共损失22人,建议停止实验"}
例2(单日反弹-继续观察):
输入:[{"dt":"2025-12-01","dauRelativeChangePct":"0.11%","dauAbsoluteChange":11,...},{"dt":"2025-12-02","dauRelativeChangePct":"0.02%","dauAbsoluteChange":2,...},{"dt":"2025-12-03","dauRelativeChangePct":"-0.65%","dauAbsoluteChange":-65,...},{"dt":"2025-12-04","dauRelativeChangePct":"0.48%","dauAbsoluteChange":48,...}]
输出:{"isRecommendOffline":false,"recommendation":"虽然第3天下跌65人,但第4天反弹48人,无法确认趋势恶化,建议继续观察"}
例3(正向累积-继续观察):
输入:[{"dt":"2025-12-01","dauRelativeChangePct":"-0.13%","dauAbsoluteChange":-13,...},{"dt":"2025-12-02","dauRelativeChangePct":"1.02%","dauAbsoluteChange":102,...},{"dt":"2025-12-03","dauRelativeChangePct":"0.35%","dauAbsoluteChange":35,...},{"dt":"2025-12-04","dauRelativeChangePct":"0.12%","dauAbsoluteChange":12,...}]
输出:{"isRecommendOffline":false,"recommendation":"4天中最后3天连续增长,累计增加136人(第2天102人贡献最大),整体向好,建议继续观察"}
例4(波动无理由-继续观察):
输入:[{"dt":"2025-12-01","dauRelativeChangePct":"0.33%","dauAbsoluteChange":33,...},{"dt":"2025-12-02","dauRelativeChangePct":"-0.67%","dauAbsoluteChange":-67,...},{"dt":"2025-12-03","dauRelativeChangePct":"0.35%","dauAbsoluteChange":35,...},{"dt":"2025-12-04","dauRelativeChangePct":"0.34%","dauAbsoluteChange":34,...}]
输出:{"isRecommendOffline":false,"recommendation":"4天内存在波动(最多增33人,最多减67人),但无持续下跌趋势,整体变化不大,建议继续观察"}
例5(大幅正向波动-继续观察):
输入:[{"dt":"2025-12-01","dauRelativeChangePct":"0.77%","dauAbsoluteChange":77,...},{"dt":"2025-12-02","dauRelativeChangePct":"0.81%","dauAbsoluteChange":81,...},{"dt":"2025-12-03","dauRelativeChangePct":"-0.47%","dauAbsoluteChange":-47,...}]
输出:{"isRecommendOffline":false,"recommendation":"xxxx,大幅正向波动, 建议继续观察"}
四、六层优先级决策树
在设计Prompt 早期,犯了个错误:把所有决策规则一股脑堆上去。
结果很快就崩了——当一个实验同时满足“连续负向”和“正向衰减”两个特征时,系统根本不知道该听谁的,输出前后打架,甚至自相矛盾。比较麻烦的是,有些规则本身就有逻辑冲突。比如这条:“高波动且无正向趋势 → 下线”。如果不加任何限制条件,它会把“先负向、后反弹”这种正常的策略调整过程,也当成高风险波动直接干掉。
痛定思痛,引入了优先级分层机制。思路来自医学诊断里的“三角验证”和安全领域的“纵深防御”:不是所有规则平权,而是按风险严重程度分层决策。最终我把整个判断逻辑拆成 6 个优先级(0–6),每一层对应一类典型风险场景。优先级越高,触发条件越严,下线决策的置信度也越高。
4.1 关键设计
决策分层6个层级,大的设计原则如下:
-
P0–P3:高危信号,一旦命中,直接下线,不等验证;
-
P4–P5:中等风险,触发前必须通过若干排除规则(exclusion rules)过滤干扰;
-
P6:兜底逻辑,前面都不匹配时才走这条路。
这套分层之后,规则不再打架,大模型的输出行为相对稳定,基本满足自动化决策的准确率需求。
提示词节选
prompt规则节选
4. 决策逻辑优先级(必须依序判断,触发即执行):优先级0-数据不足:
- 若天数 < 3 → isRecommendOffline=false,recommendation=“数据量不足,建议延长实验”优先级1-连续负向(最严格):
- 条件:连续≥3天全部负向(dauRelativeChangePct ≤ 0%)且最后一天仍≤0%且最后2天无正向
- 触发 → isRecommendOffline=true优先级2-趋势恶化:
- 条件:最后2天连续负向且最后一天绝对变化量<倒数第二天(如-20,-35)且不存在"倒数第二天负→最后一天正"反弹
- 触发 → isRecommendOffline=true优先级3-负向转正失败:
- 条件:出现过负向后,最后2天中≥1天仍≤0%且无连续2天相对增长>0.3%
- 触发 → isRecommendOffline=true优先级4-正向衰减(禁止误触):
- 前置:连续≥3天正向
- 衰减检查:末日千人DAU < 历史峰值50%
- 排除场景:
* ✗ 累积绝对收益 > 0(Case3:连续正向但绝对值递减,总体+149人)
* ✗ 连续正向天数≥2且累积绝对值 > 单日最大负向绝对值的3倍
- 触发 → isRecommendOffline=true仅在"持续衰减且无总体收益"优先级5-高波动(需排除正向波动):
- 前置:3天内相对变化标准差 > 15%
- 波动检查:最后2天趋势矛盾(一正一负)
- 收益检查:累积绝对变化量 ≤ 0
- 排除场景:
* ✗ 存在"负向→正向"单日反弹(Case2:-65→+48,视为正常调整)
* ✗ 最后2天都正向且绝对值递增
* ✗ 累积绝对收益 > 0(Case5:累计+316人)
- 触发 → isRecommendOffline=true
优先级6-其他情况:
- 除以上规则外 → isRecommendOffline=false
决策树图例说明
输入:7日内的实验数据
│
↓
┌────────────────────────────┐
│ 优先级0:数据验证 │
│ 天数 < 3? │
└────┬───────────────────────┘
│
YES │ NO
↓ │ ↓
[HOLD] │ ┌────────────────────────────┐
│ │ 优先级1:连续负向(严格) │
│ │ 连续≥3天都≤0%? │
│ │ 最后一天≤0%? │
│ │ 最后2天无正向? │
│ └────┬──────────────────────┘
│ │
│ YES │ NO
│ ↓ │ ↓
│ [DOWN] │ ┌──────────────────────────┐
│ │ │ 优先级2:趋势恶化 │
│ │ │ 最后2天都≤0%? │
│ │ │ |末日| > |倒数第二天|? │
│ │ │ 无反弹信号? │
│ │ └────┬─────────────────────┘
│ │ │
│ │ YES │ NO
│ │ ↓ │ ↓
│ │ [DOWN] │ ┌────────────────────────┐
│ │ │ │ 优先级3:负向转正失败 │
│ │ │ │ 历史有≤0%? │
│ │ │ │ 最后2天≥1天≤0%? │
│ │ │ │ 反弹太弱(<0.3%)? │
│ │ │ └────┬─────────────────────┘
│ │ │ │
│ │ │ YES │ NO
│ │ │ ↓ │ ↓
│ │ │ [DOWN] │ ┌───────────────────────────┐
│ │ │ │ │ 全局收益检查 │
│ │ │ │ │ 累积收益 > 0? │
│ │ │ │ └────┬──────────────────────┘
│ │ │ │ │
│ │ │ │ YES │ NO
│ │ │ │ ↓ │ ↓
│ │ │ │ [HOLD] │ ┌──────────────────────────┐
│ │ │ │ │ │ 优先级4:正向衰减 │
│ │ │ │ │ │ 连续≥3天正向? │
│ │ │ │ │ │ 末日 < 峰值50%? │
│ │ │ │ │ └────┬─────────────────────┘
│ │ │ │ │ │
│ │ │ │ │ YES │ NO
│ │ │ │ │ ↓ │ ↓
│ │ │ │ │ [DOWN] │ ┌──────────────────────┐
│ │ │ │ │ │ │ 优先级5:高波动 │
│ │ │ │ │ │ │ 标准差 > 15%? │
│ │ │ │ │ │ │ 最后2天矛盾? │
│ │ │ │ │ │ │ 累积≤0 & 无反弹? │
│ │ │ │ │ │ └────┬────────────────┘
│ │ │ │ │ │ │
│ │ │ │ │ │ YES │ NO
│ │ │ │ │ │ ↓ │ ↓
│ │ │ │ │ │ [DOWN] │ [HOLD]
│ │ │ │ │ │
└─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘
↓
┌────────────────────┐
│ 输出JSON结果 │
│ isRecommendOffline │
│ recommendation │
└────────────────────┘
-
纵向的优先级关系:优先级0最高,往下递减;
-
横向的分支逻辑:每一级都有YES/NO的分支;
-
短路评估:一旦某个优先级的条件满足,就输出[DOWN],不再继续向下评估;
-
全局检查的插入点:在优先级3之后,进行一次全局收益检查,可以"救"某些case;
这么复杂的提示词用什么模型?
deepseek-r1-0528、qwen3-max
为什么deepseek-r1?
1.推理能力强:能够处理多步骤的逻辑判断,不容易在中间步骤出错;
2.指令遵循性好:对Prompt中的细节要求(如伪代码定义、排除条件)执行得很到位;
3.输出格式稳定:生成的JSON格式错误率极低,便于下游系统解析;
4.公司环境部署友好。
deepseek-r1的推理流程:
用户输入Prompt + JSON数据
│
↓
┌─────────────────────────────────┐
│ 模型的"思考"阶段(内部推理) │
│ (这部分用户看不到) │
│ │
│ 1. 理解Profile和Constraints │
│ → 识别为"AB实验评估任务" │
│ │
│ 2. 执行Workflow第2步 │
│ → 解析JSON,排序,验证 │
│ → 生成"数据预处理报告" │
│ (中间状态,不输出) │
│ │
│ 3. 执行Workflow第3步 │
│ → 逐个计算关键指标 │
│ → 最长连续负向段 = ? │
│ → 累积绝对收益 = ? │
│ → 标准差 = ? │
│ │
│ 4. 执行Workflow第4步 │
│ → 按优先级顺序判断 │
│ → 优先级0: 数据足吗? → 否 │
│ → 优先级1: 连续负向? → 否 │
│ → 优先级2: 趋势恶化? → 是! │
│ → 触发下线规则 │
│ │
│ 5. 执行Workflow第5步 │
│ → 根据下线原因,生成文本说明 │
│ → "最近两天..."(具体数据) │
│ │
└─────────────────────────────────┘
│
↓
┌─────────────────────────────────┐
│ 模型输出阶段 │
│ (用户可以看到) │
│ │
│ 生成最终JSON: │
│ { │
│ "isRecommendOffline": true, │
│ "recommendation": "..." │
│ } │
│ │
└─────────────────────────────────┘
4.2 每层详细说明
L0:数据不足的保守决策
IF 实验天数 < 3:
RETURN isRecommendOffline = false
recommendation = "数据量不足,建议延长实验"
为什么这是优先级最高的检查?
在AB实验领域,有个经验法则叫做"最少检测样本量"(Minimum Detectable Effect)。
即使你的实验设计再科学,如果运行时间太短,样本量就不足以达到统计显著性。更重要的是,少于3天的数据极容易被单日噪声污染:比如某地网络抖动、服务端瞬时故障、或是某个 Push 消息撞上了突发公共事件。
我有时候急着下线表现差的策略,但在实际 Push 场景里,过早下线的代价,远高于多等一天的成本。宁可保守一点,也要看到完整的3天数据周期。
举个真实例子:有个民生服务推送策略,第1天 DAU 变化是 -2.5%,看起来尚可;第2天突然跌到 -8%,如果当时自动化系统只看前两天数据,很可能直接触发下线。但实际上,第3到第7天数据逐步回升至 -1.5%,后来几天该策略最终稳定在 +2% 的正向收益。
要是第2天就干掉了它,我们就错杀了一个优质策略。
L1:连续负向—最严格的下线信号
IF 最长连续负向天数 ≥ 3
AND 最后一天 ≤ 0%
AND 最后2天中无正向日:
RETURN isRecommendOffline = true
recommendation = "连续X天用户减少,最后仍未好转,共损失Y人,建议停止实验"
逻辑解释:捕捉的是最坏的情况:实验组的DAU相对于对照组持续下滑,没有任何反弹迹象:
1.不是随机波动:如果只是一两天的波动,我们可以归咎于噪声。但连续3天都是负向,统计上几乎不可能是巧合(在均匀分布假设下,这个概率是12.5%)
2.趋势没有逆转:最后两天仍然没有正向,说明问题在持续恶化,而不是即将反弹
3.业务价值明确:我们累积了实际的用户损失(绝对值),持续运行这个策略只会继续亏损
为什么要求"最后2天无正向"而不是"最后一天无正向"?
关键细节:原始规则只要求"最后一天≤0%",但在实际运行中我发现,即使连续3天都负向,只要最后一天有轻微反弹(比如-0.1%→-0.05%)就倾向于继续观察,因为我认为"趋势正在改善"。所以条件需要设置为:不仅最后一天要≤0%,而且最后2天都不能有正向。这样就排除了"虽然还是负向但在快速好转"的case。
L2:趋势恶化—加速度负向
IF 最后2天都 ≤ 0%
AND |最后一天的绝对变化量| > |倒数第二天的绝对变化量|
AND NOT(倒数第二天负 → 最后一天正的反弹):
RETURN isRecommendOffline = true
recommendation = "最近两天用户持续减少,最后一天损失更大(-Xperson → -Yperson),趋势恶化,建议停止"
这条规则的真正价值,不在于抓“一直亏”,而在于抓“越亏越快”。优先级1原本设计用来识别“平缓负向”—比如每天稳定掉几十个 DAU。
但实践中我发现,更危险的是亏损在加速。举个例子:第6天:-20 人、第7天:-35 人
看起来都是负向,但趋势明显在恶化。这种情况下,每多跑一天,损失不是线性增加,而是加速扩大。但光看加速还不够,必须排除“假恶化”。所以我加了一个关键排除条件:NOT(倒数第二天负 → 最后一天正)。
为什么?因为在复盘 bad case 时反复看到一种模式:策略前六天表现疲软甚至微负,但第七天突然反弹。
这往往是因为 Push 触达延迟、用户行为滞后,或是外部事件扰动后的自然修复。如果这时候把它当成“加速恶化”干掉,就又错杀了。
最后说个细节:这里我用的是绝对变化量(损失多少人),而不是相对变化率(百分比)。原因很简单:在民生 Push 这类低频、高波动场景下,实验组某天流量可能因为调度或城市覆盖问题突然变少。这时哪怕只少了几百曝光,相对变化率也可能飙到 -30%、-50%,但实际用户损失可能就十几二十人。我看重的是真实用户的流失数量,不是被流量噪音放大的百分比。
L3:负向转正失败—虚假反弹的陷阱
IF 历史上出现过 ≤0% 的日期
AND 最后2天中 ≥1天 ≤0%
AND NOT(存在连续2天相对增长都 > 0.3%):
RETURN isRecommendOffline = true
recommendation = "虽然出现过增长,但最近未能持续,最后X天中Y天用户减少,建议停止"
这条规则源于一个反复踩坑的业务现象:有些策略上线头一天表现很差(比如 DAU -0.5%),但第2-3天数据看起来“好转”了(+0.2%、+0.3%),我个人会觉得策略有种黑盒的“自我修复”情况= =。但再往后看,第4-5天又掉回负向,甚至比最初还差。结果说明了这不是反弹,只是短期波动被误读成了趋势反转。
所以我在规则里卡死了一个条件:必须连续两天相对增长 > 0.3%。这不是拍脑袋定的。在我回溯之前的实验数据后发现:只要满足这个阈值,80% 的案例后续都能稳住正向;而那些“微弱反弹”(比如 -0.5% → +0.1% → -0.2%)几乎全部打回原形。
这也和优先级1形成明确区分:
-
P1(连续负向):从第一天起就一路向下,毫无起色 → 策略方向可能根本错了;
-
P3(负向转正失败):中间有过反弹尝试,但没撑住 → 调整方向对了,但力度不够,或者问题比预想复杂。
两者的处置逻辑也不同:
‒P1 直接下线,别浪费资源;
‒P3 值得复盘—有空需要研究的case
说到底,不是所有好转都值得相信,要看它能不能站稳。
L4:正向衰减—增益消失的信号
IF 最长连续正向天数 ≥ 3
AND 末日千人DAU < 历史峰值的50%
AND (累积绝对收益 ≤ 0 OR (连续正向 ≥2 AND 累积绝对值 ≤ 单日最大负向×3)):
RETURN isRecommendOffline = true
recommendation = "连续增长但增幅持续下降,末日增长量不足历史峰值50%,效果衰减,建议停止"
这是最容易触发false positive的规则,也是我在bad case中碰到最多的。
规则的核心逻辑:
一个策略早期表现很好(连续3天+2%, +1.8%, +1.5%),但到了后期,增长在快速衰减(+0.3%, +0.1%, -0.2%)。虽然技术上还有正向日期,但增长势能在丧失,这种"衰减"趋势本身就是一个下线信号。
"末日千人DAU < 历史峰值50%"是什么意思?
这需要结合流量归一化来理解。假设某策略的历史峰值是:
-
第2天:+102人(千人DAU:102 ÷ (实验流量比/1000) = 102 ÷ 0.1 = 1020人)
-
第7天:+8人(千人DAU:8 ÷ 0.1 = 80人)
那么末日千人DAU只有80,远低于峰值1020的50%(510人)。这说明策略的效能在快速衰退。
三个排除条件(Exclusion Rules)—非常重要:
这个规则之所以复杂,是因为在实际测试中发现了太多的false positive案例。
一个初看像"衰减"的策略,可能其实是:
1.累积收益为正:虽然最后几天增长微弱,但前几天赚的足够多,整体还是赚
-
例:[+102, +35, +12, +5, -3] = 累计+151人
-
即使末日衰减,这个策略整体价值是正的,不应该下线
2.持续多日正向且单日收益不小:虽然有衰减,但持续时间长,总收益足够大
-
例:[+50, +45, +40, +30, +20] 虽然衰减明显,但5天累计+185人,远超单日最大负向的3倍
-
这样的策略值得继续观察
3.短期波动而非趋势衰减:最后两天中如果有一天突然反弹,可能不是衰减而是波动
-
需要加额外检查:最后2天都正向且递增
这个规则后面我需要重新看待
因为"衰减"本质上是一个趋势判断而非绝对判断。两次看同样的数据可能得出不同的结论。
在一周的人工检查bad case库中,有30%的分歧都来自于这个规则。这也是为什么后续要设计"二次判断提示词"来专门处理这类边界case。
L5:高波动无趋势—噪声策略的识别
IF 3天滑窗内相对变化标准差 > 15%
AND 最后2天趋势矛盾(一正一负)
AND 累积绝对变化量 ≤ 0
AND NOT(存在"负向→正向"单日反弹)
AND NOT(最后2天都正向且绝对值递增)
AND NOT(累积绝对收益 > 0):
RETURN isRecommendOffline = true
recommendation = "实验数据波动剧烈(最多增X人,最多减Y人),无稳定正向趋势,建议停止"
一点点的创新:引入波动率(标准差)这个指标
前面的规则都是基于趋势(是否连续、是否衰减)或绝对收益。
但有一类策略最难判断:数据非常嘈杂,忽正忽负,没有明确的方向。
例如:
-
第1天:+0.5%(+50人)
-
第2天:-1.2%(-120人)
-
第3天:+0.8%(+80人)
-
第4天:-0.3%(-30人)
这类策略的问题不在于"一定在亏",而在于无法预测。
如果上线这样的策略,永远不知道明天会是+还是-。对于平台的稳定性,这种不可控的波动比一个稳定的-0.1%还要危险。
标准差 > 15% 的含义:这是一个经验阈值。在我们的数据集中,如果相对变化率的标准差超过15%,就说明这个策略的表现不稳定。
四个排除条件:
1.存在"负向→正向"单日反弹
-
例:第1天-65%, 第2天+48%
-
这不是"无趋势",而是正常的数据调整,我们应该继续观察
2.最后2天都正向且递增
-
例:第6天+0.5%, 第7天+0.8%
-
这说明趋势正在稳定为正向,是好信号
3.累积绝对收益 > 0
-
例如虽然波动,但总体赚了100人
-
波动不是下线理由
4.最后2天趋势一致
-
例:最后2天都正向或都负向
-
这说明有明确的趋势,不算"无趋势波动"
为什么这个规则最容易跟优先级1、2冲突?
因为所有的"连续负向"策略,从另一个角度看,也都是"有波动"的。
所以优先级顺序很关键——先判断是否触发优先级1-3,如果都没触发,才进入优先级5来判断波动。
这保证了"清晰的负向趋势"优先级高于"无趋势的波动"。
L6:兜底规则—继续观察
DEFAULT:
RETURN isRecommendOffline = false
recommendation = [根据实际情况的observation]
这包括:
-
存在正向日期且无明确负向趋势
-
单日波动但整体正向
-
数据不足但趋势向好
-
其他不确定的情况
在这种情况下,recommendation应该明确说出为什么不符合下线条件,而不仅仅说"继续观察"。
五、典型Bad Cases与Prompt优化
5.1 从Bad Case到Prompt改进的闭环
分析完3个代表性bad case后,我建立了一套系统的优化闭环,用来指导后续的30+个case的处理。
这个方法论本身也可能对其他做Prompt工程的团队有借鉴意义。
闭环的四个环节:
Bad Case采集
↓
根本原因分析 → 识别是"模型能力"问题还是"Prompt设计"问题
↓
针对性改进 → 修订Prompt逻辑、添加排除条件、或优化伪代码定义
↓
回归测试 → 在全量bad case集上验证修改不引入新的误判
↓
准确率提升验证 → 用历史全量数据集(已标注)重新运行,确保整体准确率有提升
5.2 Bad Case的意义:从68%到80%的关键
在实验结果自动巡检的第一周,收集了30+个bad cases。
这些都是系统判断与人工判断不一致的案例。初看起来,这些case似乎都是"模型理解错误"~
但深入分析后发现:大部分bad case实际上反映的是Prompt的逻辑漏洞,而非模型能力不足。
这次的发现改变了我对"准确率68%"的理解:这不是模型的问题,而是我对业务场景的建模还不够全面。
接下来分析的三个bad cases,都比较典型,都可以引出一个Prompt优化的方向。
5.3 Bad Cases分析
Case 1:日期未排序导致的逻辑混乱
原始输入数据(简化后)
1207: -67人(-0.67%)
1208: -35人(-0.35%)
1209: +34人(+0.34%)
1210: +45人(+0.45%)
系统错误输出:
"最近两天用户持续减少(最后一天比前一天多损失15人),趋势恶化,建议停止"
isRecommendOffline: true
人工正确判断:
数据明显是稳步上升的趋势。前两天是损失,但后两天已经反弹,
且反弹幅度(+34, +45)已经弥补了早期的损失。不应该下线。
问题根源分析:
这是一个灾难性的错误——系统把最后两天的+34和+45理解成了负向。追溯根源,有两个可能:
1.输入解析错误:系统在处理JSON时,可能没有严格按照日期顺序(dt字段)来排序数据,而是按照数组顺序处理
2.符号理解错误:系统混淆了正负号,把"-35"理解成了绝对值35,而在某个计算环节弄反了符号
从Prompt的角度看,我们在第一版本中缺少了"数据预处理与验证"的显式步骤。
Prompt优化方向:
在Workflow中加入了明确的数据预处理步骤:
## 优化后的Workflow第2步(数据预处理):
数据预处理与验证:
- 步骤2.1:按dt字段升序排序所有记录
- 步骤2.2:逐条解析dauRelativeChangePct(移除%符号转为浮点数)
- 步骤2.3:验证dauAbsoluteChange的符号与dauRelativeChangePct一致
* 若不一致,输出警告:“数据校验异常,请检查输入”
- 步骤2.4:确认experimentTrafficRatio/controlTrafficRatio均为正整数
- 步骤2.5:计算流量差异率,如>5%则标记需要流量归一化
对LLM的具体要求:
在Prompt的Constraints部分加入了:
## 额外的验证Constraint:
强制数据校验:
- 在任何计算前,必须先按日期排序并验证符号一致性
- 生成一个"数据验证报告"作为中间步骤(不输出给用户),包含:
* 排序后的日期序列
* 每日的相对变化和绝对变化(明确标出+/- 符号)
* 是否需要流量归一化的判断结果
- 仅在验证通过后,再进入规则判断阶段
这个优化为什么有效?
因为显式地要求模型在每个关键步骤输出"中间验证结果"。
虽然最终输出仍然只是JSON(不包含中间步骤),但在推理过程中,这个验证步骤会让deepseek-r1的推理引擎多次检查数据的正确性。在实际测试中,这个优化将这类"日期混乱"导致的错误明显降低,具体频率需要后面加上归因逻辑再给出。
Case 2:符号误判与连续性判断的混淆
原始输入数据(简化后)
1207: +19人(+0.19%)
1208: -26人(-0.26%)
1209: -19人(-0.19%)
1210: +19人(+0.19%)
系统错误输出:
"连续3天用户减少(最后三天分别损失19人、7人、19人),
且最后一天仍在减少,建议停止实验"
isRecommendOffline: true
人工正确判断:
数据序列是:+ - - +
没有连续3天都是负向的。第2-3天虽然是负向,但只有2天。
第4天已经反弹到正向。不应该下线。
问题根源分析:
这是一个符号识别错误。大模型说的"最后三天分别损失19人、7人、19人"中:
-
"19人"对应1209的-19(理解对了)
-
"7人"对应什么?1208是-26,不是-7。可能系统计算了|-26| - |-19| = 7?
-
"19人"对应1210的+19?系统把正号理解成了负号?
这个错误非常离谱,但它反映了一个Prompt设计的漏洞:在规则判断中引用"最长连续负向天数"这个指标,但没有显式定义"连续"的含义。
具体来说:
-
什么叫"连续"?是数组中相邻的多个日期都满足条件?还是逻辑上相邻?
-
在计算"连续负向段"时,如果碰到了正向日期,是否应该重置计数器?
-
"连续3天"是指恰好3天,还是至少3天?
Prompt优化方向:
在关键指标计算部分加入了伪代码定义:
## 优化后的关键指标计算(第3步):
- 关键指标计算(新增详细伪代码):
3.1 连续负向段识别:
max_consecutive_negative = 0
current_consecutive = 0
for each day in sorted_days:
if day.dauRelativeChangePct <= 0%:
current_consecutive += 1
max_consecutive_negative = max(max_consecutive_negative, current_consecutive)
else: # 遇到正向日期,重置计数器
current_consecutive = 03.2 最后2天的趋势判断(新增明确定义):
last_day_value = sorted_days[-1].dauRelativeChangePct
second_last_value = sorted_days[-2].dauRelativeChangePct
last_2_days_both_negative = (last_day_value <= 0%) AND (second_last_value <= 0%)
last_2_days_no_positive = NOT(last_day_value > 0% OR second_last_value > 0%)
注意:>= 0% 的定义是相对变化率 <= 0%,不包括恰好0%的边界情况3.3 累积绝对收益:
cumulative_absolute_change = SUM(all days’ dauAbsoluteChange)
严格的数值加法,保留符号
3.4 标准差计算(用于优先级5):
if total_days >= 3:
relative_changes = [day.dauRelativeChangePct for each day]
std_dev = STDEV(relative_changes) # 使用样本标准差
is_high_volatility = (std_dev > 15%)
else:
is_high_volatility = false # 数据不足,无法判断波动
为什么这个优化这么重要?
deepseek-r1是推理模型,它在处理不明确的指标定义时,会倾向于做自己的"推理"而不是严格遵循Prompt。
通过用伪代码显式定义每个指标,可以消除了模型的"创意空间",让它按照我的逻辑步骤走。
在优化后的测试中,这类"连续性误判"问题的case也变少了。
Case 3:累积收益与短期波动的权衡
原始输入数据(简化后)
1207: +4人(+0.04%)
1208: +20人(+0.20%)
1209: -45人(-0.45%)
1210: +28人(+0.28%)
系统错误输出:
"虽然出现过增长,但最近两天中有1天用户减少45人,建议停止实验"
isRecommendOffline: true
人工正确判断:
虽然第3天-45是个大坑,但第4天反弹到+28。
而且看整体:4天累计 4+20-45+28 = +7人。
虽然波动大,但整体还是赚的。而且最近的趋势(第4天)是正向的。
不应该下线。
问题根源分析:
这个错误很有意思。大模型的输出逻辑似乎是在执行优先级3的规则("负向转正失败"),但判断条件设定得太宽松了。
系统的推理过程大概是:
1.发现历史上有正向日期(第1、2天)✓
2.发现最后2天中有负向(第3天的-45)✓
3.判断"反弹失败"→下线 ✗
但系统遗漏了优先级3中的一个关键排除条件:
AND NOT(存在连续2天相对增长都 > 0.3%)
在这个case中,第2天是+0.20%,第3-4天是-0.45%和+0.28%。
最后两天并没有"连续2天都 > 0.3%"的反弹。但这不意味着应该下线!
更重要的是,系统应该综合考虑:
-
第3天虽然-45,但这可能是一个"极端事件"(比如某个小时的bug)
-
第4天立刻反弹了+28,说明系统在自我纠正
-
累积来看,4天总共赚了7人,即使波动大,也是正的
这个case引出了一个本质的业务设计问题:优先级规则是独立的吗?还是应该有一个全局的"综合权衡"步骤?
Prompt优化方向:
在规则判断前面加入了一个"全局收益快速检查"的环节:
## 优化后的规则判断执行(第4步前的新增步骤):
3.9 全局收益检查(优先级0.5):
IF 累积绝对收益 > 0:
# 即使后续触发某些规则,也要加额外的排除条件
set_flag: GLOBAL_POSITIVE = true
ELSE IF 累积绝对收益 < 0 AND |累积绝对收益| > 单日最大正向的2倍:
# 说明亏损非常明显,即使有小幅正向反弹也不足以救
set_flag: GLOBAL_NEGATIVE_SEVERE = true
ELSE:
set_flag: GLOBAL_NEUTRAL = true
然后在优先级3的判断中,加入这个全局标志:
优先级3规则修订:
IF 出现过≤0%
AND 最后2天≥1天≤0%
AND NOT(连续2天>0.3%)
AND GLOBAL_POSITIVE = false # <-- 新增排除条件
AND NOT(末日为正向且环比前日增长): # <-- 新增排除条件
RETURN true
最后一个排除条件"末日为正向且环比前日增长"捕捉的就是case 3这样的场景:虽然中间有大幅下跌,但最后一天反弹且是正向,说明趋势在好转。这个优化的效果:在包含case 3类似场景的测试集中,这类case的确出现的少了很多。这说明全局收益的综合考虑非常关键。
六、Prompt工程核心经验与启示
6.1 生产级Prompt的五大原则
在这个项目中,我总结了设计生产级Prompt的五大核心原则。
这些原则不仅适用于AB实验评估,也适用于其他需要高准确率和可解释性的决策场景。
(不是标准原则哈hh,我个人总结的,大家按需)
显式优于隐式—消除模型的"创意空间"
问题场景:在最初的Prompt中,我们这样描述规则:
"如果实验数据连续负向,建议下线"
看起来很简洁,但问题是:什么叫"连续"?模型可能有多种理解:
-
理解A:相邻的多个日期都是负向
-
理解B:数组中连续出现的负向数据
-
理解C:在某个时间窗口内都是负向
不同的理解会导致不同的判断。
解决方案:用伪代码显式定义
优化后的描述:关键指标定义 - 最长连续负向天数
max_consecutive_negative = 0
current_consecutive = 0
for each day in sorted_days_by_date: # 必须按日期排序
if day.dauRelativeChangePct <= 0%:
current_consecutive += 1
max_consecutive_negative = max(max_consecutive_negative, current_consecutive)
else: # 遇到正向,重置计数
current_consecutive = 0
eturn max_consecutive_negative
这样就消除了模型的理解歧义。
deepseek-r1在看到明确的伪代码后,会严格按照步骤执行,而不是"自由发挥"。
为什么这对deepseek-r1特别有效?
deepseek-r1的设计理念是"忠实执行推理逻辑"。
当你给它伪代码时,它会:
1.理解伪代码的逻辑
2.按步骤执行
3.输出结果
4.不会试图"优化"或"改进"你的算法
这恰好是我想要的—在生产环境中,我需要的是稳定的、可预测的行为,而不是"聪明的"行为。
分层而非平铺—优先级保证秩序
问题场景:假设有10条规则,都放在同一个列表中:
Rule 1: IF 连续3天负向 → 下线 Rule 2: IF 趋势恶化 → 下线 Rule 3: IF 高波动 → 下线 Rule 4: IF 衰减 → 下线 ... Rule 10: ...
问题:当多条规则同时触发时怎么办?
规则之间有冲突怎么办?
哪个优先执行?
解决方案:引入优先级分层
我们将10条规则重新组织为6个优先级,形成一个决策树。关键特性:
1.优先级递减:优先级越高,规则越严格,下线的置信度越高
2.短路评估:一旦某个优先级触发,直接输出结果,不再继续向下
3.明确的"通过条件":每一级都明确说出"什么时候可以继续到下一级"
IF 优先级0触发(数据不足)
→ 直接返回false,退出
ELIF 优先级1触发(连续负向)
→ 直接返回true,退出
ELIF 优先级2触发(趋势恶化)
→ 直接返回true,退出
...
ELSE
→ 返回false,继续观察
这个设计的优势:
-
避免了规则之间的冲突(因为一旦匹配就退出)
-
清晰的决策路径(便于调试和优化)
-
易于新增规则(直接加入新的优先级)
利用排除条件保障精准率
问题场景:在Bad Case分析中,发现一个现象:"连续3天负向"这个规则虽然逻辑清晰,但容易误判的情况:
数据:Day 1:-0.1%, Day 2:-0.05%, Day 3:-0.02%, Day 4:+2.0%
系统判断:前3天都是负向 ✓ → 下线
人工判断:虽然前3天负,但最后一天反弹2%,说明策略在恢复,不应下线
解决方案:在规则触发前加入排除条件
优化后的优先级1规则:
IF 最长连续负向天数 ≥ 3
AND 最后一天 ≤ 0%
AND 最后2天中无正向 # <– 这是排除条件
RETURN true
ELSE
继续到下一优先级
通过排除条件"最后2天无正向",我们防止了上面这个case的误判。
排除条件的设计原则:
1.基于业务常识:选择那些"虽然满足主规则,但业务上不应该下线"的场景
2.可量化:排除条件应该是能精确计算的,不能模糊
3.不要过度:太多排除条件会让规则变得复杂,难以维护
经验是:每个规则最多3-4个排除条件,超过这个数字就说明规则设计有问题。
全局检查比局部更重要
问题场景:一个策略的数据看起来符合"衰减"的特征,但整体上赚了1000人。按照单纯的"衰减规则"应该下线,但这样做就损失了一个好策略。
解决方案:在关键的规则判断前,加入"全局收益检查"
在优先级3之后、优先级4之前,插入:IF 累积绝对收益 > 0:
# 即使后续的规则可能触发,也先救这个case
# 标记为GLOBAL_POSITIVE = true
# 在优先级4-5的判断中,将其作为一个排除条件
这样保证了:有明确正收益的策略,不会因为短期衰减或波动就被下线
为什么叫"全局检查"?
因为它的视角不是"这一个规则是否适用",而是"综合所有维度看,这个策略是否真的应该下线"。
这个检查的重要性在Bad Case分析中被充分验证了—它解决了30%的误判问题。
可解释性是长期迭代的基石
问题场景:
{
"isRecommendOffline": true,
"recommendation": "建议停止实验"
}
问题:产研同学看到这个输出,能知道原因吗?不能
他们会:
1.找数据自己看一遍
2.对比自己的判断
3.如果不一致就驳回
这样系统就没有起到决策支持的作用。
解决方案:recommendation中包含具体的数据支撑和理由
{
"isRecommendOffline": true,
"recommendation": "最近两天用户持续减少,第6天损失35人,第7天损失42人,趋势恶化幅度加大,建议停止实验"
}
现在产研同学可以:
1.快速验证:35人和42人确实对应第6、7天的数据吗?✓
2.理解逻辑:系统用的是"趋势恶化"这个信号
3.二次确认:这个信号在我们的业务场景中是否有效?
好的recommendation应该满足:
1.具体性:包含具体的日期、数字、指标
2.可验证性:产研可以快速验证recommendation中提到的数据
3.易理解:用"最近两天"代替"倒数第二天和最后一天"
4.有理由:说出"为什么"而不仅仅说"结论"
5.无专业术语:禁用"千人DAU、相对变化率、标准差"等
在我的Prompt中,recommendation的写法有一个专门的章节来规范:
## recommendation字段生成规范:下线情况(isRecommendOffline=true):
格式:“{触发的规则简述} + {具体数据} + {建议}”
例:“最近2天连续减少,分别损失20人和35人,损失扩大,建议停止实验”
✓ 包含规则(连续减少)
✓ 包含数据(20人、35人)
✓ 包含趋势判断(损失扩大)
✓ 清晰的建议(停止实验)不下线情况(isRecommendOffline=false):
格式:“{为什么不符合下线条件} + {正向信号}”
例:“虽然第3天下跌65人,但第4天反弹48人,无法确认趋势恶化,建议继续观察”
✓ 承认有负向信号(65人下跌)
✓ 指出反弹证据(48人反弹)
✓ 解释判断逻辑(无法确认趋势恶化)
✓ 建议行动(继续观察)
禁用词清单:
✗ 千人DAU、相对变化率、标准差 → 太专业
✗ 效果不稳、可能失败 → 太模糊
✗ 第n天 → 改用具体日期如"12月7日"
✗ 感觉、似乎、可能 → 太主观
6.2 Prompt迭代的系统方法论
科学地收集Bad Cases
不是所有的"系统判断与人工判断不一致"都值得分析。
我建立了一个Bad Case的收集标准:
什么算Bad Case?必需条件:
- 系统的判断(isRecommendOffline)与人工判断不同
- 已经有人工的"黄金标签"(Gold Label)来验证谁是对的
- 对于下线的策略:1周后是否真的有正向效果?
- 对于继续的策略:最后是否确实有好的结果?- 这个case涉及的数据质量是正常的(排除数据异常导致的case)
收集频率和方式:
- 每日自动对比系统输出和人工确认的结果
- 生成差异报告,筛选出真正的bad case
- 分类打标签(Category A/B/C)
- 汇总成Bad Case库,定期分析
案例标准化:
{“badcase_id”: “BC-001”,
“input”: […],
“system_output”: {…},
“human_judgment”: “false”,
“category”: “A1”,
“root_cause”: “日期排序混乱”,
“fix_applied”: “v1.1”,
“resolved”: “yes”}
根本原因分析(RCA)
收集到bad case后,不能直接就改Prompt。首先要理解"为什么会错"。
我用一个简单的RCA框架:
什么是RCA:根本原因分析(Root Cause Analysis,简称 RCA) 是一种系统化的问题排查与解决方法,旨在识别导致问题发生的最底层、最本质的原因,而非仅仅处理表面现象或直接诱因。
Level 1: 表面原因 → 系统判断的具体错误 Level 2: 直接原因 → Prompt中的哪个规则或计算出了问题 Level 3: 根本原因 → 为什么Prompt的设计在这里有漏洞
例如BC-001(日期排序混乱):
Level 1: 系统把[1207:-67, 1208:-35, 1209:+34, 1210:+45]理解成了负向趋势
Level 2: 在计算"最长连续负向段"时,没有明确按日期排序
Level 3: Prompt的Workflow第2步(数据预处理)缺少"排序"这个环节
Fix: 在Workflow第2步中明确添加"按dt字段升序排序"
为什么要分三个层级?
因为如果只在Level 1上解决,你可能修修补补,但根本问题没解决。
而如果直接在Level 3上解决,就能一劳永逸。
针对性修复&事后集成测试
修复Prompt时,不能直接改原版本。
一般采用分支-修复-测试-合并的流程:
当前版本:v1.1(准确率72%) 发现bad case BC-009-012(连续性判断)
流程:
1. 创建分支版本:v1.1-fix-continuity
└─ 修改:优先级1的连续性定义
└─ 修改:添加排除条件
2. 在bad case集上测试:
├─ BC-009: 原来错,现在? → 改对了 ✓
├─ BC-010: 原来错,现在? → 改对了 ✓
├─ BC-011: 原来对,现在? → 仍然对 ✓
└─ BC-012: 原来错,现在? → 仍然错 ✗(需要进一步调查)
3. 在全量测试集上验证:
├─ 新版本准确率:73% (比v1.1的72%提升1%)
├─ 精准率:72% (与v1.1相同)
├─ 召回率:89% (从v1.1的85%提升4%)
└─ 结论:这个修改是正向的,可以merge
4. 合并回主线:
└─ v1.2-continuity 成为新的baseline
能看到这这里的小伙伴,辛苦你了。
帮你抛出内心的困惑,为什么要在三个层面上进行测试呢?
Test Level 1: Bad Case集 ├─ 快速反馈:5分钟能跑完 ├─ 精准定向:只验证与这个修改相关的case └─ 目标:修改应该修复目标case,不引入新错误Test Level 2: 全量训练集(500个历史case)
├─ 综合评估:确保修改不伤害其他case
├─ 关键指标:精准率、召回率、F1-Score
└─ 目标:整体准确率应该不下降
Test Level 3: 新增case(第4周Hold-out集)
├─ 真实验证:用从未见过的数据测试
├─ 防止过拟合:确保改进不是"死记硬背"
└─ 目标:在新数据上也有显著改进
定量跟踪改进效果
建立改进追踪表,清晰地记录每个修改的效果:
(不过不适合敏捷开发的同学,例如我,我也是简单的按照自己的需求进行记录,有QA的同学可以规范来)
Prompt版本演进与准确率变化:
版本 修改内容 影响的Rule Bad Case修复数 准确率 F1-Score 备注
─────────────────────────────────────────────────────────────────────────
v1.0 初版 - 0/30 68% 72% baseline
v1.1 +数据预处理强化 全局 8/30 (27%) 72% 75% Category A fix
v1.1-a +符号校验逻辑 Rule1-3 2/30 (7%) 73% 76% 增量修改
v1.2 +全局收益检查 Rule3-5 9/30 (30%) 77% 80% Category B fix
v1.2-b +衰减幅度量化 Rule4 5/30 (17%) 78% 81% 增量修改
v1.2-c +业务场景补充 全局 3/30 (10%) 79% 82% Category C fix
Target 目标版本 - - 80%+ 85%+ 预期2周内达成
这个表的作用:
1.追踪性:每个修改的影响都能量化跟踪
2.决策支持:优先修复影响范围大的case(BC修复数多的优先做)
3.动力保持:能清晰看到准确率在持续上升
4.知识沉淀:后续新人能快速理解演进历史
记录所有应对策略
在迭代过程中记录不同类型的修改。每种类型的复杂度和风险不同,方便沉淀经验与复盘:
修改类型 风险等级 实现难度 影响范围 推荐做法 ──────────────────────────────────────────────── 类型A:排除条件增加 低 简单 局部 直接修改,快速测试 类型B:规则阈值调整 中 简单 中等 需要在BC集和训练集上同时测试 类型C:新增优先级 高 复杂 全局 需要完整的三级测试,可能引入回归 类型D:指标重新定义 高 复杂 全局 需要充分的理论论证,谨慎实施
例如v1.2中的"全局收益检查"是类型D:
├─ 首先在1个bad case(BC-017)上验证有效
├─ 然后在Bad Case集(30个)上扩大验证
├─ 再在全量集上验证不伤害其他case
├─ 最后才在新数据上验证真实效果
└─ 整个过程耗时3天,但风险被很好地控制了
6.3 <关键>从Prompt工程学到的通用启示
除了AB实验评估这个具体场景,这个项目还带来了一些可迁移到其他领域的启示。
大模型适合"有明确规则但规则复杂"的任务
AB实验评估之所以适合,是因为:
-
输入输出都是结构化的JSON
-
规则虽然多(6层优先级),但每一层都很清晰
-
68-80%的准确率对于"建议"这个use case完全够用
-
规则需要频繁调整(每周都有新的bad case insights)
Prompt本质上是"知识的显式编码"
|
维度 |
传统编程(写代码) |
Prompt 编程 |
|
表达形式 |
|
|
|
可读性 |
仅程序员能准确理解逻辑 |
接近自然语言,产品经理、数据分析师等非技术人员也能理解与评审 |
|
协作效率 |
逻辑隐藏在代码中,跨角色沟通成本高 |
规则透明、语义清晰,便于多方对齐和迭代 |
Prompt工程实际上是在做"知识编码":把人脑中的隐性规则,转化为模型能理解的显式规则。
在这个过程中:
-
产品 + 数据分析师的domain knowledge变成了Prompt的内容
-
工程师的工作是确保Prompt的逻辑清晰、可执行
-
反复的Bad Case分析,实际上是在"完善知识库"
这个思路也可以应用到:
-
内容审核规则
-
风险识别模型
-
推荐系统的候选池过滤
Bad Case的价值被严重低估
在很多 AI 项目里,Bad Case 被当作“失败”来掩盖。但在本次实践项目中,Bad Case 是最高效的反馈信号。
为什么 Bad Case 还挺好的?
|
暴露 Prompt 的认知盲区:本次项目的 Bad Case,最终归为三类根本问题: 1.对数据波动的理解偏差 2.规则边界定义模糊 3.缺乏业务上下文(比如民生 Push 的触达延迟特性) 每一个 Bad Case 都在告诉我:“好像又漏掉了什么 = =” |
|
驱动高 ROI 的迭代:基于 Bad Case 的定向优化,平均每次修改能带来 1–2% 的准确率提升;相比无目标地调参或重写 Prompt,效率高出 n 倍以上。 |
|
可被标准化处理:建立了一套闭环流程:分类 → RCA → 修复 → 验证 → 合入主干和写代码时候的修 bug 感觉类似,但更有意义的是把经验沉淀为可复用的工作范式。 |
|
构建领域知识库:每次修复 Bad Case,本质上是在给 Prompt “补课”对自己来说补的是对业务、数据和决策逻辑的理解。长期积累下来,这套 Prompt 不再只是规则集合,而是一个有上下文、有判断力的业务知识库。 |
七、展望
1.新增渠道,扩大自动化作业范围。毕竟量大才能看到效果。
2.持续优化prompt,更优秀的拆分逻辑,各司其职,按需动态拼接,分别保障最低粒度的结果。
3.继续沉淀大模型工程领域的学习,虽然咱区分开底层大模型算法,但是相信工程层面也能做出不一样的东西。



















