AI应用开发进阶(十):AI应用版本管理与A/B测试数据驱动优化
一、开场:怎么知道新版本更好
大家好,我是老金。
改了Prompt,效果变好还是变差?
换了模型,用户更喜欢吗?
数据说话。
今天聊聊版本管理和A/B测试。
二、版本管理
2.1 Prompt版本控制
# Prompt版本管理
class PromptRegistry:
"""Prompt注册表"""
def __init__(self):
self.versions = {}
def register(self, name: str, version: str, prompt: str, metadata: dict):
"""注册Prompt版本"""
if name not in self.versions:
self.versions[name] = {}
self.versions[name][version] = {
"prompt": prompt,
"metadata": metadata,
"created_at": datetime.now()
}
def get(self, name: str, version: str = None) -> str:
"""获取Prompt"""
if version is None:
# 获取最新版本
version = max(self.versions[name].keys())
return self.versions[name][version]["prompt"]
def list_versions(self, name: str) -> list:
"""列出所有版本"""
return [
{"version": v, **data}
for v, data in self.versions[name].items()
]
# 使用
registry = PromptRegistry()
# 注册新版本
registry.register(
name="summarize",
version="v2.1",
prompt="请用3句话总结:{text}",
metadata={
"author": "老金",
"model": "gpt-4",
"temperature": 0.7
}
)
2.2 模型版本管理
# 模型版本配置
MODEL_CONFIGS = {
"v1.0": {
"model": "gpt-3.5-turbo",
"temperature": 0.7,
"max_tokens": 1000,
"prompt_version": "v1.0"
},
"v1.1": {
"model": "gpt-3.5-turbo",
"temperature": 0.5, # 降低随机性
"max_tokens": 1500,
"prompt_version": "v1.1"
},
"v2.0": {
"model": "gpt-4",
"temperature": 0.7,
"max_tokens": 2000,
"prompt_version": "v2.0"
}
}
class VersionedModel:
"""版本化模型"""
def __init__(self, version: str):
self.config = MODEL_CONFIGS[version]
self.prompt = registry.get("summarize", self.config["prompt_version"])
async def generate(self, text: str) -> str:
"""生成"""
response = await openai.ChatCompletion.acreate(
model=self.config["model"],
messages=[{"role": "user", "content": self.prompt.format(text=text)}],
temperature=self.config["temperature"],
max_tokens=self.config["max_tokens"]
)
return response.choices[0].message.content
三、A/B测试
3.1 流量分配
import hashlib
class ABTest:
"""A/B测试"""
def __init__(self, test_id: str, variants: list, weights: list = None):
self.test_id = test_id
self.variants = variants
self.weights = weights or [1.0 / len(variants)] * len(variants)
def assign(self, user_id: str) -> str:
"""分配变体"""
# 哈希分配(保证同一用户始终分配到同一变体)
hash_val = hashlib.md5(
f"{self.test_id}:{user_id}".encode()
).hexdigest()
bucket = int(hash_val, 16) % 100
cumulative = 0
for i, weight in enumerate(self.weights):
cumulative += weight * 100
if bucket dict:
"""获取统计"""
stats = {}
for variant, metrics in self.metrics.items():
stats[variant] = {}
for name, values in metrics.items():
stats[variant][name] = {
"mean": np.mean(values),
"std": np.std(values),
"count": len(values)
}
return stats
def significance_test(self, metric: str) -> dict:
"""显著性检验"""
from scipy import stats
variants = list(self.metrics.keys())
if len(variants) != 2:
raise ValueError("只支持双变体检验")
a_values = self.metrics[variants[0]][metric]
b_values = self.metrics[variants[1]][metric]
t_stat, p_value = stats.ttest_ind(a_values, b_values)
return {
"variant_a": variants[0],
"variant_b": variants[1],
"t_statistic": t_stat,
"p_value": p_value,
"significant": p_value < 0.05
}
四、总结
最佳实践
- 版本控制:Prompt、模型、配置都要版本化
- 渐进发布:小流量→大流量
- 数据驱动:用A/B测试验证效果
- 快速回滚:发现问题立即回退
相关阅读
正文完