【Agent Harness】Gliding Horse 最新升级:把“智能闭环”真正跑通的一次深度优化
Gliding Horse 最新升级:把“智能闭环”真正跑通的一次深度优化
摘要:Gliding Horse 本次升级聚焦“智能闭环”的落地,重点打通记忆系统的一致性写入与预取链路、修复 SA 编排层的“假成功”问题、为安全门禁补充合规工具白名单,并新增日志实时镜像以消除长任务“无输出假死”。升级后各模块从“独立可用”走向“真正协同”,复杂任务状态如实反馈,长时间运行可观测。
关键词:Gliding Horse;智能闭环;记忆系统;预取引擎;SA 编排;安全门禁;可观测性;PDCA;DeepSeek;gRPC
Gliding Horse 一直在构建一套完整的智能体系:动态 PDCA 编排、四层记忆、技能图谱自进化、因果引擎、Hyperspace 向量检索、安全门禁……这些能力在之前的文章中都有详细介绍。
但一个系统不仅要“有”这些能力,更要让它们在实际运行中真正协同起来。如果安全门禁误伤了合规的验证工具,如果 Agent 明明报告“任务阻塞”却硬编码返回“成功”,如果记忆预取模块的事件总线根本没接上——那再好的模块也只是“存在”而已。
这次升级要解决的正是这些问题。它不追求新增多少模块,而是把已有的能力之间的“连接点”逐一打通,让整个系统的智能闭环真正运转起来。
一、记忆系统:让“写入即持久”和“预取即命中”成为现实
Gliding Horse 的四层记忆体系一直有 WriteThrough 和 WriteBack 两种写入策略。但在实际运行中,一致性引擎的 WriteThrough 钩子并没有完全发挥作用——关键标签的节点写入 L2 后,没有被即时刷入 L0,也没有触发 L3 投影缓存的失效。
这次修复把这条路彻底打通了。
关键改动是:Blackboard 新增了写钩子机制,ConsistencyEngine 在构造时注册钩子,携带 emphasis、confirmed_fact 等关键标签的节点在写入 L2 的瞬间就会被同步刷入 L0,同时失效 L3 投影缓存。这意味着任务关键中间结果即使进程崩溃也不会丢失,缓存一致性也更加严格。
下面是钩子注册与写入路径的关键代码:
// Blackboard 新增写钩子机制:写入节点时携带 tags,供一致性引擎拦截
impl Blackboard {
pub fn write_node_to_graph(
&mut self,
iri: &str,
tags: &[&str],
) -> Result<(), Error> {
// 触发写钩子,携带 tags + IRI,让 ConsistencyEngine 决定是否 WriteThrough
if let Some(hook) = &self.write_hook {
hook.on_write(iri, tags)?;
}
self.graph.insert(iri, tags)
}
}
// ConsistencyEngine 在构造时注册钩子,命中 critical_tags 即同步刷入 L0 并失效 L3 缓存
impl ConsistencyEngine {
pub fn new(blackboard: &mut Blackboard, l0: L0Store, l3: L3Cache) -> Self {
let ce = Self { l0, l3, critical_tags: vec!["emphasis", "confirmed_fact"] };
blackboard.register_write_hook(WriteHook::new(move |iri, tags| {
if tags.iter().any(|t| ce.critical_tags.contains(t)) {
ce.l0.persist(iri)?; // WriteThrough 即时刷入 L0
ce.l3.invalidate(iri); // 失效相关投影缓存
}
Ok(())
}));
ce
}
}
同时修复了一个隐蔽的线程泄漏:Oxigraph 的同步句柄在长跑进程中会无限堆积。现在 reap_finished_syncs 保持了句柄有界,clear() 会先刷 Oxigraph 再清空内存。
预取引擎终于“通电”了
记忆预取引擎(PrefetchEngine)一直是 Gliding Horse 的一个重要组件——它能根据任务意图主动预热相关上下文,让 LLM 首轮调用就命中高相关度数据。但之前有一个 P0 级别的缺陷:预取引擎的事件总线是孤立的,没有和系统的主 EventBus 共享。这意味着预取事件(MEMORY_PREFETCH、PREFETCH_REQUEST)虽然能发出,但没有任何消费者能收到。
这次修复把 Worker 和上层组件共享的主 EventBus 接入了预取引擎,并新增了 spawn_consumer 来实际消费预取事件。路径是这样的:
关键代码是把主 EventBus 接入预取引擎并启动消费者:
// 将 Worker 与上层组件共享的主 EventBus 接入预取引擎
impl PrefetchEngine {
pub fn connect(&mut self, bus: &EventBus) {
// 订阅主总线上的预取事件,避免事件发出后无人消费
bus.subscribe(EventKind::MemoryPrefetch, |evt| {
self.enqueue(evt.iri, evt.intent);
});
bus.subscribe(EventKind::PrefetchRequest, |evt| {
self.enqueue(evt.iri, evt.intent);
});
}
// 新增 spawn_consumer:真正消费预取队列,刷新知识图谱并排空队列
pub fn spawn_consumer(&self, bus: &EventBus) {
let worker = self.clone();
tokio::spawn(async move {
while let Some(req) = worker.queue.recv().await {
worker.refresh_kg(&req.iri).await; // 实体知识图谱刷新
bus.publish(EventKind::PrefetchDone, req); // 通知 L2 上下文已就绪
}
});
}
}
预取引擎现在能真正工作了:后续任务首次查询即可命中已预热的高相关度上下文,首轮 LLM 调用的时延和 Token 消耗都会降低。新增的 6 个单元测试锁定了这个行为,确保不再回归。
二、SA 编排:让“假成功”彻底消失
在复杂任务的执行中,我们发现了两个导致“任务显示成功但什么都没产出”的问题。
问题一:AA 的 finish 硬编码为 success
当 Agent 遇到阻塞情况(比如缺少任务规格、没有可交付物)时,它会在回复中明确输出 "Blocked: no task spec; zero deliverables; terminate" 这样的结论。但 AA 的 finish 动作此前硬编码 status: "success",导致即使 Agent 自己都认为任务失败了,系统仍然上报 ✅ SUCCESS。
修复方案是在 finish 动作中加入一个阻塞判定解析器:
fn detect_blocker_verdict(summary: &str) -> Option<&str> {
// 保守匹配显式阻塞措辞
// "no task spec" / "zero deliverables" / "cannot proceed" / "missing task spec" 等
// 命中返回 Some("failed"),否则返回 None
}
finish 动作现在用 detect_blocker_verdict(...).unwrap_or("success") 取代了硬编码。Agent 诚实报告阻塞时,系统就诚实反馈失败,SA 层的 PDCA 重试循环才能正常触发。
问题二:verify-first 周期被错误短路
AA 的 verify 动作被设计为“先检查再决定是否需要完整执行”。但此前无论检查结果如何,都硬编码返回 success,导致任务在仍需执行的情况下被提前终止。
修复后,verify_aa_needs_execution() 解析器会检查 AA 的结论中是否包含 8 个完成标记——缺失、含糊或否定结论一律视为“需要完整 PDCA 执行”。只有明确确认不需要执行时,才真正结束。
这两个修复的叠加效果是:复杂任务不再“假成功”,PDCA 重试真正生效,CLI 如实反馈真实状态。
三、安全门禁:在保护和可用之间找到平衡
Gliding Horse 的安全门禁(SecurityEngine)一直执行 fail-closed 原则。但之前有一个问题:AA 和 CA 在执行验证任务时需要调用 file_list、workspace_status、rag_search、kg_search 等只读巡检工具,而这些工具因为没有被注册为可执行技能,被安全门禁拒绝了。
这意味着合规审计的工作流被安全机制误伤了。
修复方案不是放松安全策略,而是补充白名单:将这些只读巡检工具显式映射到 file_read 能力,纳入安全引擎的合法调用范围。用户定义的技能和真正的未知工具仍然会被拒绝。回归测试 security_gate_allows_aa_ca_inspection_tools_with_whitelisted_file_read 锁定了这个行为。
四、可观测性:长任务不再“无输出假死”
之前 Gliding Code 在单任务模式下,所有日志先写入内存环形缓冲,任务结束后才一次性 dump。这导致长任务在 TUI 或流水线中表现为“完全无输出、疑似卡死”,用户中途终止后误判“什么都没生成”。
这次新增了日志实时镜像能力:LogBuffer 支持 set_mirror_to_stderr,单任务模式下每条日志实时写入 stderr。长任务逐行可见——时间戳连续推进、工具调用实时涌现,用户随时可以判断任务是否仍在推进、何时可以安全中断。
工作区监控器现在也注入了 L2 黑板引用,文件变更事件可以直接写入 L2,因果观测与文件变动监控的链路完整闭合。
五、其他优化
- DeepSeek Responses API 原生支持:网关层新增了对 DeepSeek v4-flash 的 Responses API 全链路支持,包括语义流事件解析和 reasoning 内容提取,同时保持对 Chat Completions 的完全兼容。
- gRPC L2 驱逐接口:远程管理端可以经 gRPC 触发 L2 驱逐,proto 已同步更新,运维对齐“本地自治、中心调度”架构。
- e2e 调度器测试:新增 209 行内存调度器全链路 e2e 测试,覆盖调度核心路径。
六、这次升级的本质
Gliding Horse 一直具备理解上下文变化、从执行中学习和自我修正的能力。这次升级不是“补课”,而是把已有的智能体系打磨得更精密、更可靠。
它修复了记忆系统的一致性闭环,接通了预取引擎的事件总线,消灭了编排层的“假成功”问题,补齐了安全门禁对合规工具的支持,还让长时间运行的任务变得可观测。
这些改进让 Gliding Horse 从“各模块都能独立工作”的阶段,迈入了“模块间真正协同”的新阶段。它不再只是一个功能齐全的工具箱,而是一台各个齿轮紧密咬合的机器。
Gliding Horse 已在 GitHub 开源:https://github.com/doiito/gliding_horse
浙公网安备 33010602011771号