自我演化系统(Self-Evolution Loop)

Tether 自我演化(Self-Evolution)是一套让 Agent 具备自我改造与能力扩充的闭环系统:从用户在对话里说出的一句自然语言想法出发,经历阶梯选型、提案冻结、受限离线构建、影子宿主验证、回放回归门禁,并在获得必要授权后热上线,最终通过观察期监视与代际账本兜底,出问题自动熔断回滚。 对应实现:src/Tether.Evolution*/ 与 apps/Tether.ShadowHost;跟踪 milestone v0.24 - Self-evolution(#459–#464)。

设计哲学与三大铁律

Tether 的演化架构建立在以下核心原则之上:

用户(在日常对话中):「compaction 太激进了,经常把我的核心要求压掉」
  │
  ▼ 受理(当前会话 Agent + evolve 工具 + 自我演化 Skill)
  │   意图澄清 → 检索已有能力 → 选定产物阶梯 → 编写提案(声明能力需求 + 冻结验收场景)
  ▼
演化控制器(Evolution Controller,内核治理面)
  │   核对用户消息真实锚定 → 提案合法性校验 → 哈希冻结(写入不可变提案入账)
  │   授权检查:已获授权 → 自动推进;请求新能力 → 弹出授权卡等待确认
  ▼
构建者(Builder Session:独立工作区会话,侧栏可见、用户可旁观或插话)
  │   编写代码 / 脚本 / 配置 → 本地初测与构建 → 调用 evolution_submit 提交评测
  ▼
评测器(Evaluator,内核)
  │   受限离线构建(macOS Seatbelt 隔离)→ 静态准入与 IL/AST 能力扫描
  │   影子宿主验证(apps/Tether.ShadowHost):执行冻结场景 + 运行时不变量自检 + 真实历史回放回归门禁
  ▼
控制器判定
  │   全部通过且在授权范围内 → 原子热上线(Profile CAS 事务替换)
  ▼
观察期监视(Probation Monitor)
  │   监视运行时生命周期事故(LifecycleIncident)、不变量异常、工具失败率与用户负反馈
  │   发现异常 → 自动熔断并回滚到上一代;平稳运行 → 演化成功定稿,写入不可变代际账本(Ledger)
  1. 内核绝对不变,保护集不可逾越:
    • 演化回路绝对禁止修改内核。内核包括:默认 ALC 的共享契约(Cordis、Tether.Core.Contracts、Tether.Typert 及 Service Definition 程序集)、治理面(权限审批、沙箱、会话持久化、包准入)、以及演化系统自身(控制器、评测器、账本、影子验证程序等)。
    • 演化相关组合行(evolution-controller、evolution-evaluator 等)全部纳入 PluginProtection 保护集,任何定制或接管尝试均直接被准入闸拒绝。
  2. 人只做两件事:
    • 在对话中自然表达想法;
    • 首次需要新权限时进行一次性授权(One-time Human Approval)。
    • 选型、写代码、离线测试、影子验证、上线和观察期监控全部由系统自动闭环。
  3. 可解释、可度量、代际可退:
    • 每次演化生成独立的代(Generation),完整快照、构建 digest、授权记录与验证回执持久化记入不可变账本(Ledger)。
    • 用户可随时查看每一代演化差异,并可通过 Web 界面或离线 CLI 一键回滚到任意历史代或恢复官方原版。

产物阶梯(Artifact Rungs)

自我演化遵循产物阶梯原则:能用低阶解决的不动高阶;越往高阶走,隔离和安全要求越严格。

阶梯产物形态典型用途生效机制运行环境
L0 知识Skill、AGENTS.md 片段软性改变行为习惯、操作规则下一轮会话自动加载提示词与上下文
L1 配置组合 Patch(启停行、改 config)、Hook 配置调节运行时参数、增加硬拦截CAS Patch 热生效宿主已有插件代码
L2 进程外脚本Hook 脚本(子进程)外部轻量校验、定制过滤脚本随 Hook 配置热生效子进程(受沙箱约束)
L3 进程内插件plugin-package-v1(C# 程序集 + 可选 Web 模块)新集成、替换内置能力、加管理面板ApplyLiveAsync 热装载宿主进程内(独立可收集 ALC)

对于 L3 进程内插件,演化支持三种目标方式:

  • 新建(New):从 SDK 模板(backend 或 fullstack)生成全新的外部插件项目,提供全新能力。
  • 派生(Derive):针对 35 个允许定制的一方插件,下载源码并修改后接管原组合行。
  • 重写接管(Reimplement):对于带组合行但因共享类型不可定制的核心插件(如 compaction),新插件直接引用官方契约,重新实现相同服务,通过 replaces: [{ name: original, with: my-plugin }] 原位接管原行。

提案驱动与哈希冻结

1. 用户消息严格锚定

为了杜绝通过模型幻觉、网页抓取内容或恶意工具返回内容伪造演进需求,演化系统实施严格的消息锚定机制:

  • 提案中的 idea 必须包含当前会话中的 sessionId 与 messageId,并附带用户发出的原始文本;
  • 控制器在受理时直接核验会话持久化存储,确认该消息确实存在且作者确为用户,否则直接拒绝受理。

2. 提案格式(proposal.yaml)

提案是演化契约的权威依据,结构包含以下核心维度:

schema: 1
id: evo-20260926-0003
idea:
  sessionId: 7f3c...
  messageId: m-0142
  text: "compaction 太激进了,经常把我刚说的要求压掉"
intent: 压缩时保留最近几轮用户指令的原文,并提高触发阈值
rung: L3
target:
  kind: reimplement
  replaces: [compaction]
whyNotLower: 现有配置项只能调阈值,保留指令原文需要改摘要逻辑
capabilities: [llm, session.read, "replaces:compaction"]
acceptance:
  scenarios:
    - name: retain-user-instructions
      input: "模拟高上下文压力对话"
      expect: "生成的 checkpoint 包含最新 3 轮完整用户指令"
  replay:
    extractor: compaction
    sample: 20
    comparator: { kind: judge, pass: "不差于基线的用例 ≥ 70%,且无劣质退化" }
  invariants: required
probation:
  minHours: 24
  minUses: 5
budget: { rounds: 12, tokens: 2000000, wallMinutes: 90 }

3. 验收标准预先入账与冻结

构建开始前,提案及其中的验收场景(Acceptance Scenarios)、回归测试方案、声明能力清单即被控制器哈希入账并冻结。

  • 构建者会话只能读冻结后的提案,不能修改验收场景,也不能修改声明能力清单;
  • 评测器仅依据冻结时的验收条件进行裁决,彻底防止模型“根据写不出的代码随意降级测试用例”。

能力模型与分级授权

由于进程内 C# 插件在运行时与宿主共享部分内存,系统引入了能力清单声明 + IL/AST 静态扫描 + 运行时能力门面的多重防护体系。

1. 运行时能力门面(IPluginCapabilities)

自产插件无法直接获取底层无鉴权的原始服务,必须通过 IPluginCapabilities 申请访问受控能力:

  • GetHttpClient(string domain):仅允许访问在能力清单中显式声明并获得用户批准的目标网络域名;
  • ResolveCredential(string credentialKey):仅允许读取授权范围内指定的凭据;
  • GetLlmClient():在配额限制和模型白名单内提供受控的推理能力。

2. 静态准入与能力扫描(Capability Scanner)

评测器在编译完成后,使用 System.Reflection.Metadata(PEReader)对生成的程序集进行深入的静态字节码扫描:

  • 核对程序集所调用的外部方法、类型引用以及 P/Invoke 声明;
  • 若检测到使用未经声明的高危命名空间(如裸 System.Net.Http、System.IO、反射或未授权本地系统调用),扫描器立即报告能力越界,直接判为评测失败并拒绝上线。

3. 一次性分级授权(One-time Human Approval)

  • 完全自治区间:产物仅使用当前已授予的权限集(例如纯算法处理、已授权域名的网络请求),且通过影子验证,系统自动上线并生成事后报告卡;
  • 人机协同区间:产物首次申请新权限(如访问新的外部域名、读取新的凭据、替换系统关键行),控制器暂停流程,并在前端弹出交互式授权卡,由用户显式点击确认后方可继续。

影子验证宿主与受限构建

为了确保自产代码绝不破坏现有系统运行,评测过程完全在隔离环境中完成。

1. 离线受限构建(Sandboxed Offline Build)

在 macOS 上通过 sandbox-exec 与精细配置的 Seatbelt Profile 运行 dotnet build:

  • 网络完全断开(拒绝外网请求,防止构建期依赖恶意拉取或遥测泄露);
  • 文件写入仅局限在临时构建工作区(/tmp 及指定的隔离沙箱根),只读访问必要 SDK 与系统程序集;
  • 产出构建产物的唯一散列摘要(Digest)。

2. 影子验证宿主(apps/Tether.ShadowHost)

评测器拉起一个全新的、隔离的宿主子进程:

  • 临时 Home 隔离:使用独立的临时主目录(OwnerOnlyTempDirectory),完全不接触用户的真实会话文件和配置;
  • 全真实插件栈装配:通过 BundleCatalogs.Create + AppBoot.StartAsync 启动包含待测产物的真实 Harness 实例;
  • 自动执行测试计划:按 plan.json 执行冻结的验收场景,核对状态转换和输出结果。

3. 三重安全门禁

[待测插件包]
     │
     ├─ 门禁 1: 冻结场景验证(验证新功能是否按预期工作)
     │
     ├─ 门禁 2: 运行时不变量自检(Tether.Invariants 保证无状态撕裂、无未处理异常、无内存泄漏)
     │
     └─ 门禁 3: 真实历史回放回归门禁(Replay Regression Gate,用历史会话抽样验证老能力不退化)
  • 回放回归门禁(Replay Regression Gate):从 ISessionEventStore 中抽取与该能力相关的历史真实会话样本(如历史压缩事件、工具调用上下文),在影子宿主中对新旧两代插件进行对照回放,经裁判比对,确保没有发生功能退化。

热上线、观察期与熔断回滚

1. CAS 原子热替换

验证通过后,控制器调用 PluginPackageManager.ApplyLiveAsync:

  • 利用 AssemblyLoadContext 的动态加载与 Cordis 的依赖注入图,在毫秒级内完成旧插件的反初始化与新插件的挂载;
  • 客户端无感刷新,无需重启主进程。

2. 观察期监视(Probation)

新插件上线后立即进入受保护的观察期(默认 24 小时或至少 5 次调用):

  • 演化观察器实时监视系统事件,监听 LifecycleIncident 事故、未捕获异常、以及工具失败率指标;
  • 用户在对话中表达负面反馈(例如“撤销刚才的改动”、“插件坏了”),控制器均能识别为回滚触发条件。

3. 熔断与自动回滚

一旦在观察期内触发熔断规则(如发生崩溃、不变量异常或失败率超标):

  • 控制器立即激活自动回滚机制,将插件版本还原为上一代(或官方原版);
  • 写入回滚事故记录到账本,并在会话中向用户诚实报告故障原因与回滚动作。

4. 代际不可变账本(Ledger)

每次成功的演化均记录为不可变代(Generation):

  • 存储路径:<home>/profiles/<profile>/evolution/ledger/
  • 保存完整的元数据:代数、时间戳、提案快照、构建 Digest、授权快照、评测证据 TRX 以及回滚引用。
  • 账本是审计和灾难恢复的权威来源。

运维与 CLI 命令

除了在 Web 界面的「演化控制面板」操作外,系统还提供离线 CLI 工具(即使 Web 服务未启动或异常也可直接使用):

# 查看所有演化目标与当前代数
tether evo list

# 查看特定演化的当前状态与观察期指标
tether evo status evo-20260926-0003

# 紧急回滚:将指定目标回退到上一代
tether evo rollback compaction

# 回滚到特定历史代
tether evo rollback compaction --to-generation 1

# 彻底清除自产插件,恢复官方内置实现
tether evo rollback compaction --original

# 安全控制:全局暂停演化(不接受新提案,保留观察与回滚)
tether evo pause

# 恢复演化能力(仅限人工执行)
tether evo resume

相关阅读

在 GitHub 上编辑此页