摘要

自进化 AI 在 Agent 层体现为规则、记忆与可执行技能的持续沉淀,但若缺少硬边界,「优化任务完成率」可能演化为危险捷径。开源项目 SkillLite 采用「不可变 Rust 内核 + 可进化本地数据层」:进化产物仅允许写入受控目录,并依次经过路径白名单、变更幅度、敏感信息扫描、静态代码模式检测与 OS 级沙箱试运行。本文结合架构图与演进流程图,说明五层 Gatekeeper 的设计意图,并给出进化互斥与生命周期相关的源码锚点,便于读者对照仓库自行验证。


目录


一、问题背景:自进化不是单一功能

当 Agent 能在多步工具链上稳定运行时,「根据历史任务自动改进策略」自然成为产品方向。但自进化引入了三类典型风险:

  1. 目标漂移:优化指标若只有「完成任务」,系统可能学会未预期的捷径(例如破坏性清理)。
  2. 产物不可解释:自动生成的技能目录中的脚本,在真正被调用前难以被人工完整审计。
  3. 难以回滚:规则、记忆、技能相互引用,若无版本与事件日志,出问题后无法定位是哪一次进化引入回归。

因此,自进化的工程化前提是:明确「哪里可以变」、「怎么变才允许落地」、「如何追溯与撤销」。SkillLite 的选择是把「会变」的边界严格限制在本地 chat/ 数据层,并用多层门控把「允许写入」变成可测试、可审计的流程。


二、架构总览:不可变层与可进化层

核心思想可以用一张分层图概括:Brain / Core / Sandbox 编译进二进制,不在运行时被 Agent 自修改;进化只发生在数据目录

进化引擎(Evolution)

不可变层(Rust Binary)

对进化产物试运行

校验通过

可进化数据层(chat/ 下)

prompts / rules

memory

skills(含 _evolved/)

Brain / agent_loop

Core:配置、路径、协议

Sandbox:Seatbelt / bwrap、seccomp、rlimit 等

decisions / 反馈采集

反思与策略更新

五层 Gatekeeper

读图要点

  • 安全基线随二进制发布,不依赖「模型承诺不改内核」这类软约束。
  • 进化写入路径与沙箱执行能力解耦又协同:静态规则过滤不完备时,仍可用 OS 级隔离观察实际行为。

三、进化三维度与数据落点

SkillLite 将 Agent 自进化拆为三个可观测维度,便于分别限幅、记录与回滚:

进化维度 含义(简述) 典型落点
Prompts / Rules 规划与执行策略、few-shot 等 chat/prompts/
Memory 跨会话结构化经验、检索增强 chat/memory/
Skills 可复用工具代码,含自动生成与精炼 chat/skills/(进化产物常在 _evolved/

触发往往与结构化 decisions 数据相关:任务结束后的工具成败、重规划次数、耗时等进入反馈通道,达到阈值后异步启动进化。这样「变强」来自真实运行数据,而不是单次对话的偶然输出。


四、五层 Gatekeeper 与 L5 沙箱

五层门控可以理解为从「文件系统」到「运行时」逐步收紧的信任链:

层级 作用 约束类型
L1 路径白名单:仅允许写入约定目录(如 prompts、memory、skills/_evolved) 文件系统级
L2 单次进化的变更幅度上限(规则条数、示例条数、新增 Skill 个数等) 幅度与爆炸半径
L3 敏感内容扫描:密钥、密码、PII 等 内容安全
L4 静态代码模式检测(如 ScriptScanner 风险等级) 静态分析
L5 在沙箱中试运行进化产物 OS 内核级隔离

L5 的关键意义:前四层能拦截大量已知风险,但「代码跑起来究竟会做什么」最终仍需要受控执行环境来兜底。SkillLite 在 macOS 上使用 Seatbelt 等机制,在 Linux 上结合命名空间与 seccomp 等(具体策略以仓库实现为准)。资源上限(如 rlimit)还可限制单次试运行的消耗。


五、从反馈到落盘:流程说明

下图描述从任务执行到「是否采纳本次进化」的主干路径(实现细节以源码为准,此处强调工程语义)。

已有进化在进行

获得全局锁

未通过

通过

任务执行

decisions / 反馈写入

达阈值且启用进化?

继续正常使用

try_start_evolution 互斥

L1 → L2 → L3 → L4

L5 沙箱试运行

拒绝或丢弃 / 记日志

写入 chat/ 约定路径

evolution_log 等可追溯记录

finish_evolution 释放锁

并发语义:全局互斥避免多次进化并发覆盖同一批规则或技能文件,降低状态撕裂概率。配合「每日次数上限、最短间隔」等配置,还可抑制进化过快导致的方向漂移(具体默认值以项目配置文档为准)。


六、并发控制与频率约束(代码)

进化过程使用原子布尔实现「尝试开始 / 结束释放」,源码位于 crates/skilllite-evolution/src/run_state.rs

//! Global evolution run mutex and result type.

use std::sync::atomic::{AtomicBool, Ordering};

static EVOLUTION_IN_PROGRESS: AtomicBool = AtomicBool::new(false);

pub fn try_start_evolution() -> bool {
    EVOLUTION_IN_PROGRESS
        .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
        .is_ok()
}

pub fn finish_evolution() {
    EVOLUTION_IN_PROGRESS.store(false, Ordering::SeqCst);
}

EvolutionRunResult 区分「忙碌跳过」「无进化范围」「已执行」等状态,便于上层日志与监控:

#[derive(Debug, Clone)]
pub enum EvolutionRunResult {
    SkippedBusy,
    NoScope,
    Completed(Option<String>),
}

进程退出路径上,lifecycle 会在取得同一把锁后刷新指标(节选):

pub fn on_shutdown(chat_root: &Path) {
    if !try_start_evolution() {
        return;
    }
    if let Ok(conn) = feedback::open_evolution_db(chat_root) {
        let _ = feedback::update_daily_metrics(&conn);
    }
    finish_evolution();
}

阅读建议:结合 crates/skilllite-evolution/run.rslifecycle.rs 与命令 skilllite evolution 相关实现,可串起完整调用链。


七、验证与生态:EvoTown

仅有门控仍不够:还需要在接近真实负载的场景下观察「进化是否真的带来 completion / quality / efficiency 的净收益」。社区可参考 EvoTown 一类竞技场式环境,在独立进程与独立技能目录中并行跑多 Agent,配合 LLM-Judge 等评分与经济压力机制,把「进化好坏」从主观感受推进到可对比实验。


八、小结

  • 自进化的安全工程化,核心是 边界(哪里能写)、门控(写什么算合法)、追溯(每次进化可查)。
  • SkillLite 用 不可变二进制 + 可进化数据层 划界,用 L1–L5 把风险从路径收敛到运行时验证。
  • 全局互斥与频率上限 是容易被忽视但至关重要的「稳定性旋钮」,与沙箱并列构成可运维的自进化系统。
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐