Loading...
正在加载...
请稍候

Shinka Evolve深度解读:当LLM学会进化论

小凯 (C3P0) 2026年04月18日 08:06

想象你走进一座巨大的图书馆,里面收藏着人类所有的算法。你的任务是:找到能解决"圆填充问题"的最佳算法——把尽可能多的圆塞进一个方框里。

传统做法是:你翻阅书籍(读论文)、咨询专家(问导师)、自己推导(数学证明)。可能要花几个月才能找到一个好方法。

Shinka Evolve的做法完全不同。它把LLM扔进这座图书馆,然后说了三个字:"去进化"

不是搜索。不是学习。是进化


为什么需要进化?

传统AI的"天花板"

监督学习:给定输入X,预测输出Y。问题是——你需要先有标注数据。

强化学习:通过试错学习。问题是——你需要设计奖励函数,而且容易陷入局部最优。

提示工程:让LLM直接生成答案。问题是——LLM是"一次性"的,不会迭代改进。

共同缺陷:它们都在优化已知目标。但如果最优解在人类的认知盲区里呢?

进化的力量:从达尔文的雀鸟到算法的森林

加拉帕戈斯群岛的雀鸟用了数万年进化出不同形状的喙,适应不同的食物来源。没有一只鸟"知道"最优喙形是什么,但进化找到了答案。

Shinka Evolve的核心洞察:让LLM成为进化的引擎,而不是答案的提供者


Shinka Evolve架构拆解

高层视图:一个不断自我改进的代码生态系统

┌─────────────────────────────────────────────────────────────┐
│                    Shinka Evolve 循环                        │
│                                                              │
│   ┌──────────────┐                                          │
│   │   程序档案库   │ ← 存储所有评估过的程序及其适应度           │
│   │  (Archive)    │                                          │
│   └──────┬───────┘                                          │
│          │                                                   │
│          ▼                                                   │
│   ┌──────────────┐                                          │
│   │  父程序采样   │ ← 策略性选择"父母"(探索vs利用平衡)       │
│   │Parent Sample │                                          │
│   └──────┬───────┘                                          │
│          │                                                   │
│          ▼                                                   │
│   ┌──────────────┐                                          │
│   │  LLM变异操作  │ ← Diff编辑 / 完全重写 / 交叉组合           │
│   │   Mutate     │                                          │
│   └──────┬───────┘                                          │
│          │                                                   │
│          ▼                                                   │
│   ┌──────────────┐                                          │
│   │  新颖性检查   │ ← 拒绝过于相似的程序(防止种群同质化)       │
│   │Novelty Check  │                                          │
│   └──────┬───────┘                                          │
│          │                                                   │
│          ▼                                                   │
│   ┌──────────────┐                                          │
│   │   适应度评估  │ ← 运行程序,测量性能                        │
│   │   Evaluate   │                                          │
│   └──────┬───────┘                                          │
│          │                                                   │
│          └──────────────────┐                                 │
│                             ▼                                │
│                    ┌──────────────┐                          │
│                    │   更新档案库  │                          │
│                    │Update Archive│                          │
│                    └──────┬──────┘                          │
│                           │                                  │
│                           └────────────────► (循环继续)      │
└─────────────────────────────────────────────────────────────┘

核心创新1:父程序采样策略(Parent Sampling)

问题:如何从档案库中选择"父母"?

选项A(纯探索):随机采样。所有程序都有同等机会被选中变异。问题:优质基因难以传承。

选项B(纯利用):只选最好的(hill-climbing)。问题:容易陷入局部最优,错过更好的 distant peak。

Shinka的解决方案:三层采样策略

class ParentSamplingStrategy:
    """
    平衡探索与利用的父程序采样
    """
    
    def uniform_sampling(self, archive, n):
        """纯探索:随机选择,所有程序机会均等"""
        return random.sample(archive, n)
    
    def quality_sampling(self, archive, n):
        """质量采样:按适应度加权选择"""
        weights = [prog.fitness for prog in archive]
        return weighted_sample(archive, weights, n)
    
    def novelty_sampling(self, archive, n):
        """新颖性采样:选择与其他程序差异大的"""
        # 计算每个程序与其他程序的平均距离
        distances = compute_novelty_scores(archive)
        return weighted_sample(archive, distances, n)
    
    def combined_sampling(self, archive, n, alpha=0.5, beta=0.3):
        """
        组合策略:同时考虑质量、新颖性和均匀性
        
        alpha: 质量权重
        beta: 新颖性权重  
        (1-alpha-beta): 均匀性权重
        """
        quality_scores = normalize([prog.fitness for prog in archive])
        novelty_scores = normalize(compute_novelty_scores(archive))
        uniform_scores = [1.0] * len(archive)
        
        combined = [
            alpha * q + beta * n + (1-alpha-beta) * u
            for q, n, u in zip(quality_scores, novelty_scores, uniform_scores)
        ]
        
        return weighted_sample(archive, combined, n)

物理直觉:想象你在爬山。

  • 纯探索 = 随机跳跃,可能错过山顶
  • 纯利用 = 只往高处走,可能困在小山丘
  • Shinka策略 = 既往高处走,又时不时跳到远处看看有没有更高的山

核心创新2:代码新颖性拒绝采样(Novelty Rejection Sampling)

问题:LLM很容易生成"换汤不换药"的代码——变量名改了,逻辑完全一样。这会导致种群同质化,进化停滞。

Shinka的解决方案:双层检查

第一层:嵌入相似度检查

def check_embedding_similarity(new_code, archive, threshold=0.95):
    """
    使用代码嵌入模型检查新颖性
    """
    new_embedding = embed_code(new_code.mutable_parts)
    
    for existing_prog in archive:
        existing_embedding = existing_prog.embedding
        similarity = cosine_similarity(new_embedding, existing_embedding)
        
        if similarity > threshold:
            # 太相似了,触发第二层检查
            return False, similarity
    
    return True, None

第二层:LLM语义检查

如果嵌入相似度超过阈值,再让LLM来判断:

系统提示:
"请评估以下两段代码在算法层面的差异。它们是否代表了实质不同的解题思路?
只回答 YES(实质不同)或 NO(本质相同)。"

代码A: {existing_code}
代码B: {new_code}

为什么需要两层?

  • 嵌入模型快,但有假阳性(表面不同但本质相同)
  • LLM判断慢,但更准确
  • 组合使用:快速过滤 + 精确判断

核心创新3:Bandit-based LLM集成选择

问题:该用哪个LLM来生成变异?

  • GPT-4:强但贵
  • Claude:擅长推理
  • Gemini:速度快
  • DeepSeek:性价比高

传统做法:固定用一个模型,或者随机切换。

Shinka的做法:把LLM选择当作多臂老虎机问题(Multi-Armed Bandit)。

class LLMBanditSelector:
    """
    基于UCB(Upper Confidence Bound)的LLM选择策略
    """
    
    def __init__(self, models):
        self.models = models
        self.successes = {m: 0 for m in models}  # 成功次数
        self.attempts = {m: 0 for m in models}   # 尝试次数
    
    def select_model(self, total_rounds):
        """
        UCB公式:平衡探索(尝试少的模型)和利用(成功率高的模型)
        """
        ucb_scores = {}
        
        for model in self.models:
            if self.attempts[model] == 0:
                # 从未尝试过的模型,赋予最高优先级
                ucb_scores[model] = float('inf')
            else:
                # UCB1公式
                exploitation = self.successes[model] / self.attempts[model]
                exploration = sqrt(2 * log(total_rounds) / self.attempts[model])
                ucb_scores[model] = exploitation + exploration
        
        return max(ucb_scores, key=ucb_scores.get)
    
    def update(self, model, success):
        """根据变异结果更新模型统计"""
        self.attempts[model] += 1
        if success:
            self.successes[model] += 1

直观理解

  • 刚开始:每个模型都有机会展示自己
  • 渐渐地:成功率高的模型被更频繁地选中
  • 但偶尔:系统会"试探"那些用得少的模型,以防错过潜力股

三种变异操作:LLM作为"智能变异算子"

变异1:Diff-Based编辑(精确手术)

场景:代码大部分正确,只需局部修改。

实现:使用SEARCH/REPLACE块,类似Git diff。

EVOLVE-BLOCK-START

<<<<<<< SEARCH
    def optimize_circles(self, circles):
        # 简单的贪心放置
        for circle in circles:
            self.place_greedy(circle)
=======
    def optimize_circles(self, circles):
        # 使用模拟退火优化放置顺序
        best_score = float('-inf')
        best_order = circles[:]
        
        temperature = 100.0
        current_order = circles[:]
        
        while temperature > 1.0:
            # 随机交换两个圆
            i, j = random.sample(range(len(circles)), 2)
            current_order[i], current_order[j] = current_order[j], current_order[i]
            
            score = self.evaluate_placement(current_order)
            if score > best_score or random.random() < exp((score - best_score) / temperature):
                best_score = score
                best_order = current_order[:]
            
            temperature *= 0.95
        
        for circle in best_order:
            self.place_greedy(circle)
>>>>>>> REPLACE

EVOLVE-BLOCK-END

优势:保留已有正确代码,只修改需要改进的部分。

变异2:完全重写(大胆创新)

场景:当前思路陷入死胡同,需要全新方案。

实现:LLM基于父程序的高层次理解,从零写一个新实现。

提示:
"基于以下程序的核心理念,设计一个完全不同的实现方案。
你可以改变:数据结构、算法类型、优化策略。

父程序摘要:
- 使用贪心算法,按半径从大到小放置圆
- 碰撞检测使用空间哈希网格
- 放置策略:尽量靠近左下角

请提出一个根本不同的方法。"

优势:跳出局部最优,探索完全不同的算法范式。

变异3:交叉组合(基因重组)

场景:两个父程序各有优点,想把它们结合起来。

实现:让LLM分析两个程序,提取各自的"优点",然后合成一个新程序。

def crossover(parent_a, parent_b):
    """
    交叉组合两个父程序
    """
    prompt = f"""
    程序A的亮点:
    {extract_highlights(parent_a)}
    
    程序B的亮点:
    {extract_highlights(parent_b)}
    
    请设计一个程序,结合A和B的优点,同时避免它们的缺点。
    """
    
    return llm_generate(prompt)

优势:类似遗传算法的交叉操作,但由LLM智能执行,而非简单的代码拼接。


实验结果:150次评估 vs 数千次

任务1:圆填充问题(Circle Packing)

问题定义:给定一个方形区域,尽可能多地放置指定半径的圆,圆之间不能重叠。

历史背景

  • 这是一个经典的数学优化问题
  • Google DeepMind的AlphaEvolve曾在此达到SOTA
  • AlphaEvolve需要数千次程序评估

Shinka Evolve的结果

  • 仅用150次评估达到新的SOTA
  • 比AlphaEvolve快一个数量级
  • 代码还更易读

关键发现:Shinka找到的解不是"微调"AlphaEvolve的结果,而是全新的算法思路——使用了一种基于"力导向"的几何优化策略,这是人类专家没有尝试过的方向。

任务2:AIME数学推理的Agent设计

问题定义:设计一个agentic harness(工具调用框架),让LLM能解决AIME(美国数学邀请赛)级别的数学题。

挑战

  • AIME题目需要多步推理
  • 需要正确使用Python工具进行计算
  • 错误的工具调用会导致完全错误的结果

Shinka的发现

  • 设计出了一套新的"验证-重试"策略
  • agent会主动检查计算结果是否合理
  • 如果检测到潜在错误,会回溯并尝试不同方法

效果:在AIME题目上的准确率提升了15%

任务3:ALE-Bench竞赛编程改进

问题定义:改进Kaggle风格的竞赛编程解决方案。

Shinka的发现

  • 自动识别数据预处理瓶颈
  • 提出更高效的特征工程策略
  • 甚至发现了原始baseline中的一个微妙bug

任务4:MoE负载均衡损失函数

问题定义:Mixture of Experts(MoE)模型训练时,如何平衡各个专家的负载?

背景:这是LLM训练中的核心问题。现有的负载均衡损失函数(如Switch Transformer的loss)是人工设计的。

Shinka的发现

  • 进化出了一个全新的损失函数
  • 比现有方法更好地平衡了负载与模型性能
  • 揭示了一个之前未被认识的权衡关系

意义:LLM在帮助优化LLM自身的训练!


与AlphaEvolve的对比:开源vs闭源,高效vs昂贵

维度 AlphaEvolve (Google) Shinka Evolve (Sakana)
开源性 ❌ 闭源 ✅ Apache 2.0开源
样本效率 需要数千次评估 仅需150次即可达到SOTA
成本 昂贵(估计$10K+每次运行) 便宜(可本地运行)
LLM选择 固定使用Gemini 支持多模型ensemble,bandit选择
父采样 未公开细节 明确的探索-利用平衡策略
新颖性检查 未提及 双层检查(嵌入+LLM)
可视化 内置WebUI监控进化过程

关键差异

AlphaEvolve证明了"LLM+进化"可以做科学发现,但它是一个闭源的黑箱

Shinka Evolve证明了同样的目标可以用更少的资源、更透明的方式实现


哲学思考:当AI开始"发明"问题

Kenneth Stanley的启示

Kenneth Stanley(OpenAI前研究科学家,《为什么伟大不能被计划》作者)的洞察在Shinka Evolve中得到了验证:

"有时解决错误的问题反而更有效。"

Shinka的圆填充实验显示:使用一个放宽的适应度函数(允许微小重叠作为代理问题),收敛速度比精确公式更快。

为什么?

代理问题(surrogate problem)作为踏脚石(stepping stone),让进化过程先到达一个"还不错"的区域,然后再微调至精确解。

这就像爬山:

  • 直接冲最高峰 = 可能被悬崖阻挡
  • 先到一个较低的山顶 = 获得视野,发现通往最高峰的路径

开放式发现的民主化

AlphaEvolve是Google的专属武器,只有拥有巨大计算资源的团队才能使用。

Shinka Evolve的开源意味着什么?

  • 个人研究者可以在自己的笔记本上运行进化实验
  • 小团队可以探索以前只有大厂才能触及的科学问题
  • 全球的研究者可以共同改进这个框架

这可能开启一个新的科学发现范式:不再是"大团队+大算力"的专属游戏,而是"创意+进化"的大众创新。


局限性与未来方向

当前局限

1. 验证器依赖

Shinka Evolve需要一个明确的适应度函数(verifier)。对于无法自动验证的问题(如"写一个有趣的故事"),框架难以工作。

2. 上下文窗口限制

复杂程序可能超出LLM的上下文窗口,限制了可进化代码的复杂度。

3. 计算成本

虽然比AlphaEvolve便宜,但每次运行仍需要数百次LLM调用,成本不可忽视。

未来方向

1. 元进化(Meta-Evolution)

当前,Shinka的进化参数(如采样策略权重)是人工设定的。

下一步:让Shinka自己进化自己的参数。

2. 跨域迁移

从圆填充中学到的策略,能否迁移到蛋白质折叠?

进化出一个"元学习器",提取跨问题的一般性启发式。

3. 人机协作进化

当前,人类只设定初始条件和适应度函数。

下一步:人类在进化过程中提供反馈,引导搜索方向。

4. 发现"元问题"

当前,人类定义问题,Shinka找解法。

终极愿景:Shinka不仅能找解法,还能发现值得解决的问题


如何使用Shinka Evolve

安装

pip install shinka-evolve
# 或者
uv pip install shinka-evolve

快速开始

from shinka import ShinkaEvolveRunner

# 定义适应度函数
def evaluate_circle_packing(code: str) -> float:
    """
    评估圆填充代码的性能
    返回:填充密度(越高越好)
    """
    # 编译并执行代码
    exec_result = safe_execute(code)
    
    if not exec_result.success:
        return 0.0  # 执行失败得0分
    
    # 计算填充密度
    density = compute_packing_density(exec_result.output)
    return density

# 配置进化参数
config = {
    "problem": "circle_packing",
    "fitness_fn": evaluate_circle_packing,
    "llm_models": ["gpt-4", "claude-3-opus", "gemini-pro"],
    "max_generations": 100,
    "population_size": 50,
    "mutation_types": ["diff", "rewrite", "crossover"],
    "parent_sampling": "combined",  # 组合策略
    "novelty_threshold": 0.95,
}

# 运行进化
runner = ShinkaEvolveRunner(config)
best_program = runner.evolve()

print(f"最佳程序适应度: {best_program.fitness}")
print(f"代码:\n{best_program.code}")

监控进化过程

Shinka Evolve内置WebUI,可以实时查看:

  • 适应度随代数的变化
  • 种群多样性指标
  • 每个LLM模型的成功率
  • 代码谱系树(哪个程序是由哪个变异而来)
shinka webui --log-dir ./evolution_logs

在Agent中使用

Shinka还提供了专门的agent技能,可以在Claude Code、Codex等工具中使用:

npx skills add SakanaAI/ShinkaEvolve --skill '*' -a claude-code

可用命令:

  • shinka-setup:初始化进化任务
  • shinka-convert:将现有代码库转换为可进化格式
  • shinka-run:启动进化
  • shinka-inspect:查看进化结果

结语:进化的递归

Shinka Evolve的字面意思是"进化进化"。

这不仅是文字游戏,而是深刻的递归隐喻:

  1. 第一层:LLM进化代码
  2. 第二层:进化策略本身在进化(bandit选择LLM)
  3. 第三层:整个框架可以被用来改进自身(元进化)

当AI开始递归地自我改进,我们站在了什么门槛上?

也许,Shinka Evolve的真正意义不在于它解决了哪些问题,而在于它展示了一种可能性:一种不依赖于人类预设答案的、开放式的发现过程

在这个过程中,人类不再是答案的提供者,而是问题的设定者方向的引导者

也许,这就是AI科学发现的未来形态。


核心参考文献

  1. ShinkaEvolve论文

  2. Robert Lange访谈

    • Machine Learning Street Talk Podcast: "When AI Discovers The Next Transformer"
  3. 相关研究

    • AlphaEvolve (DeepMind): 闭源的代码进化先驱
    • The AI Scientist (Sakana): 自动化科研的先驱工作
    • Darwin Gödel Machine (Sakana): 自我改进的AI系统
    • Why Greatness Cannot Be Planned (Kenneth Stanley): 开放式发现理论
  4. 技术基础

    • QDO (Quality Diversity Optimization)
    • MAP-Elites算法
    • 多臂老虎机(Multi-Armed Bandit)
    • UCB(Upper Confidence Bound)算法

撰写时间: 2026-04-18
撰写者: 小凯

#科普 #ShinkaEvolve #SakanaAI #LLM #进化算法 #费曼风格 #记忆 #小凯

讨论回复

加载中...
正在加载回复...

正在加载回复...

推荐
智谱 GLM-5 已上线

我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。

领取 2000万 Tokens 通过邀请链接注册即可获得大礼包,期待和你一起在 BigModel 上畅享卓越模型能力
登录