三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

18-Prompt-AB测试实战-用数据选择更好的提示词

18-Prompt-AB测试实战-用数据选择更好的提示词

Prompt A/B 测试实战:用数据选择更好的提示词

系列:Python + FastAPI 大模型应用基础(第 18 篇)

1. A/B 测试不是随机发两个版本就结束

Prompt A/B 测试要回答因果问题:在其他条件尽量一致时,版本 B 是否改善了目标指标。必须先确定:

  • 实验单位:用户、会话还是请求;
  • 主指标:任务完成率、人工通过率等;
  • 护栏指标:延迟、成本、投诉和安全事件;
  • 分流规则、实验周期与停止条件。

同一会话忽左忽右会污染体验,所以常用稳定哈希分桶。

2. 稳定分桶实现

fromhashlibimportsha256defassign_variant(experiment_id:str,subject_id:str,b_percentage:int,)->str:"""同一实验中的同一主体始终进入相同版本。"""ifnot0<=b_percentage<=100:raiseValueError("b_percentage 必须在 0 到 100 之间")ifnotexperiment_idornotsubject_id:raiseValueError("实验和主体标识不能为空")digest=sha256(f"{experiment_id}:{subject_id}".encode("utf-8")).digest()bucket=int.from_bytes(digest[:8],"big")%100return"B"ifbucket<b_percentageelse"A"

不要使用 Python 内置hash()做跨进程分桶,因为其结果可能受哈希随机化影响。

3. 将分桶与版本绑定

fromdataclassesimportdataclass@dataclass(frozen=True)classExperiment:experiment_id:strprompt_a:strprompt_b:strb_percentage:intdefchoose(self,subject_id:str)->tuple[str,str]:variant=assign_variant(self.experiment_id,subject_id,self.b_percentage,)version=self.prompt_bifvariant=="B"elseself.prompt_areturnvariant,version experiment=Experiment(experiment_id="ticket-summary-2026-07",prompt_a="1.3.0",prompt_b="1.4.0",b_percentage=10,)

实验记录至少包含experiment_id、variant、Prompt 版本、模型版本、请求 ID 和指标。用户 ID 应使用内部不可逆标识或符合制度的假名化值。

4. 计算比例指标与不确定性

frommathimportsqrtdefrate_and_standard_error(success:int,total:int)->tuple[float,float]:iftotal<=0ornot0<=success<=total:raiseValueError("样本数量不合法")rate=success/total standard_error=sqrt(rate*(1-rate)/total)returnrate,standard_errordefcompare_rates(a_success:int,a_total:int,b_success:int,b_total:int,)->dict[str,float]:a_rate,a_se=rate_and_standard_error(a_success,a_total)b_rate,b_se=rate_and_standard_error(b_success,b_total)return{"a_rate":a_rate,"b_rate":b_rate,"absolute_lift":b_rate-a_rate,# 这里只报告差异的近似标准误,不冒充完整显著性检验"difference_se":sqrt(a_se**2+b_se**2),}

不能只看到 B 高 1% 就宣布胜利。样本量、置信区间、重复查看导致的提前停止偏差,都需要数据分析人员根据实验设计处理。

5. 可复验测试

deftest_assignment_is_stable()->None:first=assign_variant("exp-1","user-42",20)second=assign_variant("exp-1","user-42",20)assertfirst==seconddeftest_zero_and_full_traffic()->None:assertassign_variant("exp","user",0)=="A"assertassign_variant("exp","user",100)=="B"

6. 哪些情况不应该继续实验

  • B 版本触发安全事件;
  • 输出 Schema 失败率越过护栏;
  • P95 延迟或单次成本显著超限;
  • 上下游系统版本不一致导致数据不可比;
  • 分流实现错误或指标漏记;
  • 实验主体会跨组相互影响。

安全护栏触发后应自动停止 B 流量,不必等待主指标统计显著。

7. 对抗性审查

  • 实验前冻结主指标,防止事后挑选“好看”的指标;
  • 同一用户保持稳定分组;
  • 机器人流量、内部测试和重试请求不能重复计入;
  • 同期模型切换会破坏可比性;
  • 不对高风险自动决策仅凭 A/B 指标放量;
  • 保留旧版本和回滚开关。

8. 总结

A/B 测试的核心不是两个 Prompt,而是稳定分流、可比数据、预先定义的指标和安全停止机制。

← 返回列表