自我演化系统(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)
- 内核绝对不变,保护集不可逾越:
- 演化回路绝对禁止修改内核。内核包括:默认 ALC 的共享契约(
Cordis、Tether.Core.Contracts、Tether.Typert及 Service Definition 程序集)、治理面(权限审批、沙箱、会话持久化、包准入)、以及演化系统自身(控制器、评测器、账本、影子验证程序等)。 - 演化相关组合行(
evolution-controller、evolution-evaluator等)全部纳入PluginProtection保护集,任何定制或接管尝试均直接被准入闸拒绝。
- 演化回路绝对禁止修改内核。内核包括:默认 ALC 的共享契约(
- 人只做两件事:
- 在对话中自然表达想法;
- 首次需要新权限时进行一次性授权(One-time Human Approval)。
- 选型、写代码、离线测试、影子验证、上线和观察期监控全部由系统自动闭环。
- 可解释、可度量、代际可退:
- 每次演化生成独立的代(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