【Agent Harness】Gliding Horse 最新进化:从“能学习”到“可验证的自主进化”

Gliding Horse 最新进化:从“能学习”到“可验证的自主进化”

摘要:本文深入解析 Gliding Horse 从 v0.1.5 到最新代码的核心升级——如何将 AI Agent 从“能学习”推向“可验证的自主进化”。文章围绕持续学习闭环、执行效果契约、双编排统一、强类型上下文模型、可观测性、安全加固、工作区感知、TUI 交付验证等八大模块展开,揭示“把智能变成可验证的智能”这一核心命题背后的工程实践与设计哲学。
关键词:AI Agent;自主进化;可验证智能;持续学习;PDCA 编排;JSON-LD DAG;强类型上下文;可观测性;安全加固;Rust 系统工程

Gliding Horse 一直在构建一套完整的智能体系。之前的文章里,我们聊过动态 PDCA 编排、四层记忆、技能图谱自进化、因果引擎、硬约束安全门禁……这些能力让 Agent 从“执行指令”迈向了“理解领域”。

但一个系统不仅要“有能力”,更要“能力可验证”。如果 Agent 说自己在学习,但晋升策略时用的是不完整的证据,那学习就只是幻觉;如果 Agent 说任务完成了,但交付物根本没生成,那编排就形同虚设;如果 Agent 在进化,但没有任何痕迹可追溯,那进化就只是个黑箱。

这次从 v0.1.5 到最新代码的迭代,围绕一个核心命题展开:把“智能”变成“可验证的智能”

一、持续学习闭环:从“记录经验”到“可验证的自主进化”

Gliding Horse 的技能图谱一直支持基于使用记录自动生成演化建议。但之前的演化更多是“记录”层面的——系统知道哪些技能用得好、哪些用得差,但如何基于这些数据做出可靠、可回溯、可回退的进化决策,缺乏一套严格的治理机制。

这次升级引入了完整的持续学习闭环

mermaid diagram

核心是 ConstrainedPolicy(受约束策略) 三臂结构:

  • baseline 臂:当前使用的稳定策略,作为对照基线。
  • shadow 臂:新策略在后台“影子运行”,观察其表现但不实际生效。
  • active 臂:经过验证后正式生效的策略。

策略从 shadow 晋升到 active 需要满足严格的晋升条件:必须匹配独立的 pair/task 身份、seed、模型配置、工作区快照和目标编排模式。重复或不完整的证据无法制造晋升——系统不会因为“跑了几次看起来还行”就贸然切换策略。

同时,evolution_delta_gate 对已批准的候选施加受限状态机:它从不自行应用图变更、修改索引或扩展权限,所有进化动作都必须经过审批、验证、提交的完整流程。learning_health 则是一个纯观测模块——只报告学习是否在健康方向演进,不调参、不重试、不改权限。

这意味着 Gliding Horse 的学习能力从“记录经验”升级为“可验证的自主进化”:每一次策略变更都有完整的证据链,每一个晋升都经得起回溯审查,每一次回退都有明确的触发条件。

二、执行效果与恢复契约:让“完成”不再是一句口号

之前有一个真实案例:Agent 完成一个复杂任务后报告成功,但工作区里零文件产出。这暴露了一个根本问题——Agent 的“完成”缺乏客观的效果验证。

这次升级在内核层新增了领域中立的执行效果契约

  • EffectPolicy:跟踪每一个动作的实际效果,通过 before/after 内容清单精确归因变更。它排除了 build/__pycache__.venv/ 等目录,避免把编译缓存误判为有效产出。
  • 无效果尾部检测:如果 Agent 执行了大量操作但没有任何实质性工作区效果,系统会主动识别并提取“残留工作”,而不是让它静默通过。
  • 验证新鲜度:CA(检查 Agent)的验证仅当成功读取发生在目标最近变更之后才有效。这防止了“早期读取”或“纯叙述式响应”被当作有效验证。
  • 结构化恢复协议:当 CA 报告失败时,它会提供证据与范围,SA 将其转换为恢复决策,递归执行有界,不会无限重试。

mermaid diagram

这套机制让“任务完成”从一个主观判断变成了可验证的客观事实:有实质产出、有新鲜验证、有完整证据链。

下面用一段 Rust 伪代码展示 EffectPolicy 的核心实现思路——如何通过 before/after 内容清单精确归因变更,并排除 build/ 等噪声目录:

use std::collections::HashMap;
use std::path::{Path, PathBuf};

/// 单个文件的变更记录:before/after 内容清单
#[derive(Debug, Clone)]
struct FileChange {
    path: PathBuf,
    before_hash: Option<String>, // None 表示文件原本不存在(新增)
    after_hash: Option<String>,  // None 表示文件被删除
}

/// EffectPolicy:领域中立的执行效果契约
struct EffectPolicy {
    /// 需要排除的噪声目录(编译缓存、虚拟环境等)
    excluded_dirs: Vec<PathBuf>,
    /// 判定“无效果尾部”的阈值:连续 N 个动作无实质变更
    no_effect_tail_threshold: usize,
}

impl EffectPolicy {
    /// 判断某个路径是否应被排除(build/、__pycache__/、.venv/ 等)
    fn is_excluded(&self, path: &Path) -> bool {
        self.excluded_dirs.iter().any(|dir| {
            path.starts_with(dir)
        })
    }

    /// 核心归因逻辑:对比 before/after 内容清单,产出“有效变更集”
    fn attribute_changes(
        &self,
        before: &HashMap<PathBuf, String>,
        after: &HashMap<PathBuf, String>,
    ) -> Vec<FileChange> {
        let mut changes = Vec::new();

        // 1. 遍历 after:新增或内容变化的文件
        for (path, after_hash) in after {
            if self.is_excluded(path) {
                continue; // 排除 build/ 等噪声目录
            }
            let before_hash = before.get(path);
            if before_hash != Some(after_hash) {
                changes.push(FileChange {
                    path: path.clone(),
                    before_hash: before_hash.cloned(),
                    after_hash: Some(after_hash.clone()),
                });
            }
        }

        // 2. 遍历 before:被删除的文件
        for (path, before_hash) in before {
            if self.is_excluded(path) {
                continue;
            }
            if !after.contains_key(path) {
                changes.push(FileChange {
                    path: path.clone(),
                    before_hash: Some(before_hash.clone()),
                    after_hash: None,
                });
            }
        }

        changes
    }

    /// 无效果尾部检测:若最近 N 个动作均未产生有效变更,则触发“残留工作”提取
    fn detect_no_effect_tail(&self, recent_changes: &[Vec<FileChange>]) -> bool {
        // 触发条件:连续 no_effect_tail_threshold 个动作,有效变更集均为空
        recent_changes
            .iter()
            .rev()
            .take(self.no_effect_tail_threshold)
            .all(|changes| changes.is_empty())
    }
}

关键点说明

  • 排除目录is_excluded 在归因前先过滤 build/__pycache__.venv/ 等路径,避免把编译缓存误判为有效产出。
  • 精确归因attribute_changes 通过 before/after 的哈希对比,只保留真正发生变化的文件——新增、修改、删除都能被准确识别。
  • 无效果尾部触发条件detect_no_effect_tail 检查最近连续 N 个动作是否全部产生空变更集。一旦触发,系统会主动提取“残留工作”并交给恢复层处理,而不是让 Agent 的“空转”静默通过。

三、双编排统一:PDCA 和 JSON-LD DAG 共用同一引擎

Gliding Horse 一直支持两种编排模式:动态 PDCA 和显式的 JSON-LD DAG 工作流。之前它们走的是不同的执行路径。这次升级把它们统一到了同一个 SA→BizAgent 运行时上。

统一之后有一个重要的设计原则:PDCA 计划中的工具建议是“咨询性”的,而用户/应用显式指定的工具白名单是“权威性”的

之前有一个关键缺陷:模型生成的 PDCA tools_allowed 曾被错误地当作硬性能力上限,导致 DA(执行 Agent)只拿到搜索和读取工具,无法产出任何交付物。修复后,DA 可以正常调用写入工具,而用户指定的权限边界依然被严格尊重。

四、强类型上下文模型:让上下文装配可验证

这是这次升级中代码量最大的模块之一。context_model.rs 引入了 glidinghorse.role-context/v3glidinghorse.generated-agent-spec/v1 两个模式版本,定义了一套完整的上下文类型体系:

  • ContextFragmentKind — 上下文片段的种类
  • ContextSlot / ContextSlotSelector — 上下文槽位与选择器
  • ContextSourceKind / ContextScope — 来源与作用域
  • ContextFreshnessPolicy — 新鲜度策略
  • ContextTrustClass — 信任等级

这套模型让上下文的装配从“拼接字符串”升级为类型化装配:每个片段有明确的来源、作用域、新鲜度和信任等级,Agent 拿到的不再是一大坨文本,而是结构化的、可查询的上下文对象。

五、可观测性:每一次 LLM 交互都有迹可循

针对“无统一 trace、无请求-响应-工具因果关系”的问题,这次升级落地了三个关键模块:

  • llm/interaction.rsglidinghorse.llm-interaction/v6 模式,每次模型交互生成一条可观测的生命周期记录,包含消息/上下文类别收据。
  • execution_journal.rs:持久、隐私保护的执行日志——事件总线面向本地 UI 渲染(短暂),日志是其持久对应物(默认最小化隐私)。
  • learning_trajectory.rs:持久、隐私最小化的执行轨迹(标识符、有界工具元数据、独立验证结果),是“关于已完成任务的证据,而非可执行记忆”。

此外,结构化日志支持滚动文件和脱敏处理,让长任务的调试和审计变得可行。

六、安全加固:18 项 P1/P2 全面落地

这次升级完成了审计报告中 P1/P2 共 18 项安全加固。挑几个重点:

加固项 内容
P1-1 删除跨 crate unsafe transmute,改为逐字段安全转换
P1-3 CLI 凭据不再写入进程环境,采用 env_clear + 安全白名单
P1-4 web_fetch SSRF 防护:限 HTTP(S)、逐跳 DNS/IP 校验、拒绝私网/链路本地、10MB 上限
P1-5 Shell/PowerShell 改 Tokio 子进程 + 有界并发;超时不重放;进程组异步终止
P1-6 MCP 全请求超时、JSON-RPC ID 匹配、notification 跳过、非 2xx 处理
P1-7 Worker durable inflight claim、任务隔离、启动恢复;API key 不持久化
P1-9 HTTP/gRPC 默认回环;远程监听强制 TLS 声明 + token;假状态改 501/UNIMPLEMENTED

此外,本期新增了 bash 工具 pkill/killall 自我保护(DA 清理进程不再误杀 agent 自身)和 opt-in unshare 沙盒(user/mount/pid/ipc/uts/net 命名空间,默认禁用保持兼容)。

七、工作区感知与内存持久性

工作区清单持久化是这次升级的另一个重点。基于 redb 嵌入式数据库 + SHA-256 内容指纹,系统现在可以持久化文件清单、有界变更历史、效果快照和任务级感知。这减少了对 file_list 和文件读取的冗余调用,并能区分“真实变更”和“无相关变更的 shell 命令”。

非工作区研究任务会禁用继承的工作区上下文,修复了跨任务污染问题。

内存方面,L0 引入了版本化信封、压缩/二进制存储、有界迁移与快速修复;L2 队列/刷写/驱逐、L3 投影边界、预取/一致性接线、时间线保留都做了增强。Hyperspace 新增了确定性的进程内词法索引(从持久 JSON-LD 载荷派生,作为缓存而非第二真源)和 snapshot envelope 双代恢复。

八、TUI 与交付验证

TUI 这次做了大幅增强:启动屏(阶段 + 耗时)、SA 推理从 SSE 增量合并为实时消息、延迟索引(接口先于后台索引出现)、Mermaid 渲染(基于 mermaid-rs-renderer)。

启动时间从约 5.5 秒降至约 0.1 秒(技能图拓扑去噪 + 持久恢复进度可见)。

Mermaid 交付验证工具是新增的一个有意思的能力:从归档 Markdown 中提取完整 Mermaid 代码块(非 Mermaid 围栏也被消费,防止示例被误认为交付图),有界文档 128KB/16 图/单图 16KB,并通过 render_validated_mermaid 做真实渲染验证。这意味着 Agent 生成的架构图会被真实渲染验证,而不是只做字符串存在性检查。

九、整体架构演进

mermaid diagram

十、验证数据

这次升级不是“写完就完了”——所有的能力都经过了完整的验证:

检查项 结果
核心库测试 1,535+ 项通过,0 失败
核心集成套件 97 项通过
Hyperspace Engine 单元 91 + 集成 15 通过
代码格式检查 通过
关键 Clippy 门 通过
命名空间/版本一致性 通过
实机复杂任务 调研+实现任务成功,产物验证通过

性能探针数据:L2 写 10.5µs · L3 冷投影 1.19ms · L0 读 6.0µs · HNSW 10K 4.3µs · Poincaré 4D 18ns——全部达标。

十一、这次升级的本质

Gliding Horse 一直在回答一个问题:如何让 AI Agent 从“聪明但散漫”变成“可靠且可依赖”。

这次升级的核心叙事是:把“智能”变成“可验证的智能”

学习不再是“记录经验”,而是有严格晋升条件的自主进化;完成不再是“Agent 说完成了”,而是有实质产出和新鲜验证的客观事实;进化不再是“黑箱调参”,而是有完整证据链和回退机制的治理化流程。

从 v0.1.5 到最新代码,29 个提交、228 个文件、超过 14 万行新增代码——这些数字背后,是 Gliding Horse 从一个“功能齐全的工具箱”向“各齿轮紧密咬合的机器”的持续进化。

如果你对 Agent 操作系统、Rust 系统工程、或者可验证的自主学习感兴趣,欢迎来 GitHub 看看:

👉 https://github.com/doiito/gliding_horse

项目还在快速迭代中,文档和示例正在持续补全。star 和 issue 都是最好的支持。

posted @ 2026-09-18 20:38  doiito  阅读(0)  评论(0)    收藏  举报