b1babo
timeline
keywords
articles
targets
projects
about
b1babo

2026 All Rights Reserved.

  • 关于本站
  • 所有文章
  • 站点地图
  • RSS Feed

Powered by Next.js & Trilium

  • GEPA算法

GEPA 算法概述

b1babo
2026年4月19日
2026年4月19日

GEPA 算法概述

GEPA (Genetic-Pareto) 是一个用于优化文本组件(如 AI prompts、代码片段、配置参数等)的进化算法框架。它通过 LLM 的反思能力和 Pareto 高效搜索来迭代改进候选者。

为什么叫 "Genetic"(遗传)?

GEPA 的名称体现了它与遗传算法的深刻联系:

遗传算法概念GEPA 对应机制说明
种群Pareto 前沿候选者集合维护多个候选者,不是单一最优解
选择从 Pareto 前沿采样选择表现好的候选者作为父代
变异 Mutation反思突变LLM 基于反馈修改 prompt
交叉 Crossover系统感知合并组合两个候选者的优势模块
适应度分数 Score衡量候选者质量的指标
继承祖先累积改进新候选者继承所有祖先的改进
遗传算法:
种群 → 选择 → 交叉/变异 → 评估 → 新种群 → 重复

GEPA:
前沿 → 选择 → 合并/反思 → 评估 → 新前沿 → 重复
        ↓         ↓
      Pareto    LLM 智能变异

1. 种群: Pareto 前沿作为种群

# 遗传算法: population = [individual1, individual2, ...]
# GEPA: Pareto 前沿作为种群

pareto_front = {
    "sample_0": {candidate_1, candidate_3},  # 在样本0上最好
    "sample_1": {candidate_2},               # 在样本1上最好
}

2. 选择: 从前沿选择父代

# 遗传算法: 根据适应度概率选择
# GEPA: 从 Pareto 前沿选择

selector = ParetoCandidateSelector(rng=random.Random(0))
parent_idx = selector.select_candidate_idx(state)

3. 变异: 反思突变

# 遗传算法: 随机扰动基因
# GEPA: LLM 智能反思修改

# 反思突变: 基于反馈修改
new_candidate = propose_by_reflection(
    parent_candidate,
    reflective_dataset  # 失败案例 + 成功案例
)

# LLM 生成:
# "基于以下反馈,将 prompt 从 X 改为 Y 以提高准确率"

4. 交叉: 系统感知合并(无 LLM)

# 遗传算法: 交换两个个体的基因片段
# GEPA: 合并两个候选者的组件(纯规则,无 LLM)

# src/gepa/proposer/merge.py
child_candidate = merge_candidates(
    candidate_a,  # 擅长数学题
    candidate_b   # 擅长语文题
)

# ⚠️ 重要:合并不调用 LLM!
# 只是字符串比较和复制操作

具体示例:

# 进化历史
候选者 0 (祖先): {
    "system_prompt": "You are helpful.",
    "user_prompt": "Answer:"
}
              ↓ 反思改进
候选者 5 (候选A): {
    "system_prompt": "You are a math expert.",  # ← 改进了
    "user_prompt": "Answer the math:"           # ← 改进了
}
              ↓ 不同路径反思改进
候选者 8 (候选B): {
    "system_prompt": "You are helpful.",       # ← 未变
    "user_prompt": "Please provide reasoning:" # ← 改进了
}

# 合并候选5和候选8
候选者 12 (合并结果): {
    "system_prompt": "You are a math expert.",    # 来自候选5 (改进了)
    "user_prompt": "Please provide reasoning:"    # 来自候选8 (改进了)
}

合并逻辑 (核心代码):

# 从共同祖先开始
new_candidate = deepcopy(ancestor_candidate)

# 逐组件决定从哪个后代选择
for component_name in ["system_prompt", "user_prompt"]:
    ancestor_val = ancestor[component_name]
    id1_val = candidate_a[component_name]
    id2_val = candidate_b[component_name]

    if ancestor_val == id1_val and ancestor_val != id2_val:
        # A未改进,B改进了 → 选择B
        new_candidate[component_name] = id2_val
    elif ancestor_val == id2_val and ancestor_val != id1_val:
        # B未改进,A改进了 → 选择A
        new_candidate[component_name] = id1_val
    elif ancestor_val != id1_val and ancestor_val != id2_val:
        # 两者都改进了 → 选择分数更高的
        new_candidate[component_name] = (
            id1_val if score_a > score_b else id2_val
        )
    else:
        # 两者都一样 → 任选
        new_candidate[component_name] = id1_val

5. 继承: 祖史累积

# 每个候选者记录其进化历史
candidate = {
    "system_prompt": "...",
    "ancestry": [0, 1, 5, 12]  # 祖先索引
}

# 反思时可以看到所有祖先的改进历史
reflective_dataset = build_from_ancestry(candidate.ancestry)

核心概念

候选者 (Candidate)

候选者是 GEPA 优化过程中的基本单位,表示为 dict[str, str]:

candidate = {
    "system_prompt": "You are a helpful assistant...",
    "user_prompt": "Please answer the following question:",
    # 可以包含更多组件
}

类比神经网络:

  • 候选者 ≈ 权重参数 W
  • 优化目标 ≈ 找到最优的 prompt 文本

评分 (Score)

分数衡量候选者的性能:

  • 范围:[0.0, 1.0]
  • 越高越好(与神经网络的 loss 相反)
  • 在验证集上计算平均分数

类比神经网络:

  • Score ≈ 负 Loss 或 准确率
  • GEPA 最大化 score,神经网络最小化 loss

算法流程

┌─────────────────────────────────────────────────────────────────────────┐
│                     GEPA 进化算法主循环                                  │
│                 (Genetic-Pareto Evolutionary Loop)                       │
└─────────────────────────────────────────────────────────────────────────┘
                            │
                            ▼
                    ┌───────────────┐
                    │  初始化种群   │
                    │ seed_candidate│
                    └───────┬───────┘
                            │
                            ▼
                    ┌───────────────┐       ┌─────────────┐
                    │  选择 Selection│──────→│ 适应度评估  │
                    │  从前沿选择父代│       │ 更新前沿     │
                    └───────┬───────┘       └──────┬──────┘
                            │                      │
                            ▼                      │
        ┌──────────────────────────────────────────┘
        │
        ▼
┌─────────────────────────────────────────────────────────────┐
│                     进化循环 (双策略)                         │
│                                                             │
│  ┌────────────────────────────────────────────────────┐    │
│  │  策略 A: 反思变异 (Mutation)                       │    │
│  │                                                     │    │
│  │  1. 选择父代       ← 从 Pareto 前沿                 │    │
│  │  2. 评估父代       ← 在 minibatch 上测试            │    │
│  │  3. 反思分析       ← LLM 分析失败原因               │    │
│  │  4. 变异生成       ← LLM 生成改进版本               │    │
│  │  5. 适应度测试     ← 比较 minibatch 分数            │    │
│  └────────────────────────────────────────────────────┘    │
│                                                             │
│  ┌────────────────────────────────────────────────────┐    │
│  │  策略 B: 系统合并 (Crossover)                       │    │
│  │                                                     │    │
│  │  1. 选择两个父代   ← 从 Pareto 前沿                 │    │
│  │  2. 分析进化史     ← 比较组件改进记录               │    │
│  │  3. 智能合并       ← 组合优势组件                   │    │
│  │  4. 适应度测试     ← 在验证集上评估                 │    │
│  └────────────────────────────────────────────────────┘    │
│                                                             │
│  接受 → 验证集评估 → 更新 Pareto 前沿 (新一代种群)          │
│                                                             │
│              重复直到达到停止条件                            │
└─────────────────────────────────────────────────────────────┘
        │
        ▼
┌───────────────┐
│ 返回最优候选者 │
│ (种群中最适应) │
└───────────────┘

训练集 vs 验证集

用途训练集验证集
反思数据✅ 提供失败案例学习❌ 不用于反思
接受测试✅ 快速迭代❌ 不用于接受
最终评估❌ 防止过拟合✅ 真实性能
候选选择❌ 避免局部最优✅ Pareto 选择
result = gepa.optimize(
    seed_candidate={"prompt": "..."},
    trainset=train_data,      # 用于反思和接受测试
    valset=val_data,          # 用于 Pareto 前沿跟踪
    max_metric_calls=150
)

数据集格式

默认格式 (DefaultAdapter)

trainset = [
    {
        "input": "法国的首都是哪里?",
        "additional_context": {},  # 可选
        "answer": "巴黎"
    },
    {
        "input": "中国的首都是哪里?",
        "additional_context": {},
        "answer": "北京"
    }
]

自定义格式

DataInst 是泛型类型,可以根据需要自定义:

from gepa.adapters.generic_rag_adapter import RAGDataInst

trainset = [
    {
        "query": "What is machine learning?",
        "ground_truth_answer": "Machine learning is...",
        "relevant_doc_ids": ["doc_001", "doc_042"],
        "metadata": {"category": "AI"}
    }
]

停止条件

GEPA 支持多种停止条件:

# 方式 1: 最大评估次数
max_metric_calls=150

# 方式 2: 最大反思成本
max_reflection_cost=10.0  # USD

# 方式 3: 自定义停止条件
from gepa.utils import FileStopper, NoImprovementStopper

stop_callbacks = [
    FileStopper("gepa.stop"),              # 检测停止文件
    NoImprovementStopper(patience=10)       # 10 次无改进
]

两种 LLM 调用

每次迭代中,GEPA 会调用 LLM 两次:

1. Task LLM (评估/前向传播)

task_lm = "openai/gpt-4o-mini"  # 较小的模型

用于:

  • 生成预测值
  • 计算分数

2. Reflection LLM (反思/反向传播)

reflection_lm = "openai/gpt-4o"  # 更强的模型

用于:

  • 分析失败原因
  • 生成改进的 prompt

核心优势

特性GEPA传统方法
评估次数100-50010,000+ (RL)
可微性无需可微需要梯度
优化目标任何文本组件主要用于 prompts
可解释性人类可读的优化轨迹黑盒优化

下一步

  • 评估流程详解 - 了解 GEPA 如何评估候选者
  • 反思流程详解 - 了解 LLM 如何反思和改进
  • Pareto 前沿 - 了解多目标优化机制
  • 与神经网络对比 - 深入类比理解

本页目录

  • GEPA 算法概述
  • 为什么叫 "Genetic"(遗传)?
    • 1. 种群: Pareto 前沿作为种群
    • 2. 选择: 从前沿选择父代
    • 3. 变异: 反思突变
    • 4. 交叉: 系统感知合并(无 LLM)
    • 5. 继承: 祖史累积
  • 核心概念
    • 候选者 (Candidate)
    • 评分 (Score)
  • 算法流程
  • 训练集 vs 验证集
  • 数据集格式
    • 默认格式 (DefaultAdapter)
    • 自定义格式
  • 停止条件
  • 两种 LLM 调用
    • 1. Task LLM (评估/前向传播)
    • 2. Reflection LLM (反思/反向传播)
  • 核心优势
  • 下一步

评论