Hermes Intelligence Pipeline closes breakpoints in ZCLAW's existing intelligence components with 4 self-contained modules: Chunk 1 — Self-improvement Loop: - ExperienceStore (zclaw-growth): FTS5+TF-IDF wrapper with scope prefix - ExperienceExtractor (desktop/intelligence): template-based extraction from successful proposals with implicit keyword detection Chunk 2 — User Modeling: - UserProfileStore (zclaw-memory): SQLite-backed structured profiles with industry/role/expertise/comm_style/recent_topics/pain_points - UserProfiler (desktop/intelligence): fact classification by category (Preference/Knowledge/Behavior) with profile summary formatting Chunk 3 — NL Cron Chinese Time Parser: - NlScheduleParser (zclaw-runtime): 6 pattern matchers for Chinese time expressions (每天/每周/工作日/间隔/每月/一次性) producing cron expressions - Period-aware hour adjustment (下午3点→15, 晚上8点→20) - Schedule intent detection + task description extraction Chunk 4 — Trajectory Compression: - TrajectoryStore (zclaw-memory): trajectory_events + compressed_trajectories - TrajectoryRecorderMiddleware (zclaw-runtime/middleware): priority 650, async non-blocking event recording via tokio::spawn - TrajectoryCompressor (desktop/intelligence): dedup, request classification, satisfaction detection, execution chain JSON Schema migrations: v2→v3 (user_profiles), v3→v4 (trajectory tables)
26 KiB
Hermes Intelligence Pipeline Design
基于 Hermes Agent (Nous Research) 竞品分析,吸收 4 个核心理念到 ZCLAW 的详细设计方案。 架构方案:Pipeline Closure — 闭合现有管线断点,不引入新架构层。
Context
Hermes Agent 验证了"一个管家 + 记忆飞轮"的方向,其 4 个核心创新对 ZCLAW 发布后迭代有直接参考价值:
- 自我改进闭环 — 执行 → 评估 → 提取技能 → 改进 → 复用
- 用户建模 — 三层记忆栈 + 统一用户画像
- 自然语言 Cron — LLM 解析自然语言为定时任务
- 轨迹压缩 — 工具调用链 → 结构化 JSON → RL 基础
关键诊断: ZCLAW 缺的不是模块,是管线没接通。现有 PainAggregator、SolutionGenerator、Reflection、Heartbeat、MemoryExtractor 等组件已就位,但彼此断开。本设计闭合这些断点。
范围约束:
- 管家路由器(ButlerRouterMiddleware + SemanticSkillRouter 接通)由另一个会话推进,本设计标注为外部依赖
- 发布后迭代,不影响当前发布计划
- 4 个理念全部设计,按优先级排序:自我改进闭环 > 用户建模 > NL Cron > 轨迹压缩
总代码量估算: ~2200 行新增/修改(~1700 新增 + ~500 修改)
类型约定
本设计使用以下 ID 类型约定:
// 所有 Rust 原生结构体使用强类型
use uuid::Uuid;
use zclaw_types::{AgentId, SessionId};
// 为新实体定义类型别名(newtype wrapper 在 Tauri 命令层解包为 String)
type ExperienceId = String; // Uuid::new_v4().to_string()
type ProposalId = String; // 与现有 Proposal.id 一致
type TrajectoryId = String; // Uuid::new_v4().to_string()
Rust 内部结构体使用 AgentId、SessionId;Tauri 命令边界使用 String(Tauri serialize 要求)。
统一完成状态枚举
跨 Section 1/4 使用统一的完成状态:
/// 通用完成状态,所有 Outcome 枚举的基础
enum CompletionStatus {
Success,
Partial,
Failed,
Abandoned, // Section 1 不使用此变体(运行时约定,非编译时约束)
}
Section 1 的 Experience 使用 CompletionStatus(不含 Abandoned),Section 4 的 CompressedTrajectory 使用完整版。
Section 1: 自我改进闭环
目标
用户反馈痛点 → 自动识别 → 自动生成方案 → 方案成功后提取为可复用经验 → 下次类似问题直接复用。
数据流
用户消息 → PainAggregator(已有)
↓ confidence >= 0.7
SolutionGenerator(已有,改为自动触发)
↓ 生成 Proposal
等待用户反馈(成功/失败)
↓ 成功
ExperienceExtractor(新增)
↓ 生成结构化经验
ExperienceStore(新增,SQLite)
↓ 下次对话
MemoryMiddleware(已有)注入相关经验
关键断点修复
断点 1:PainAggregator → SolutionGenerator(未自动触发)
- 文件:
desktop/src-tauri/src/intelligence/pain_aggregator.rs - 当
confidence >= 0.7时,通过 Tauri event 自动调用butler_generate_solution - 新增
PainConfirmedEvent事件结构体
断点 2:方案结果反馈(无反馈机制)
- 新增
ProposalFeedback结构体 - 在聊天流中检测用户隐式反馈关键词("好了""解决了""没用")
- 新增 Tauri 命令
butler_submit_proposal_feedback
断点 3:成功方案 → 结构化经验(完全缺失)
- 新增
ExperienceExtractor:从成功方案中提取经验 - LLM 辅助提取(复用现有 LlmDriver),fallback 到模板提取
- 存入 VikingStorage(使用 scope 前缀
experience://{agent_id}/)
断点 4:经验复用(完全缺失)
- 扩展
MemoryMiddleware:用户新消息时,通过 VikingStorage 检索相关经验 - 使用 scope 过滤
experience://前缀 + TF-IDF 相关性匹配 - 相似度 > 阈值时,注入"过往经验"到 system prompt
- 格式:
[过往经验] 类似情况 X 做过 Y,结果是 Z
数据结构
// 新增文件:desktop/src-tauri/src/intelligence/experience.rs
use zclaw_types::AgentId;
use uuid::Uuid;
struct Experience {
id: ExperienceId,
agent_id: AgentId,
pain_pattern: String, // 触发模式(关键词摘要)
context: String, // 问题上下文
solution_steps: Vec<String>, // 解决步骤
outcome: CompletionStatus, // Success | Partial(经验只记录成功的)
source_proposal_id: Option<ProposalId>,
reuse_count: usize,
created_at: DateTime,
}
struct ProposalFeedback {
proposal_id: ProposalId,
outcome: CompletionStatus, // Success | Failed | Partial
user_comment: Option<String>,
detected_at: DateTime,
}
struct PainConfirmedEvent {
pain_point_id: String, // PainPoint.id (Uuid String)
pattern: String,
confidence: f32,
}
存储策略
经验存储在现有 VikingStorage 中,使用 scope 前缀区分:
// Experience 存储为 VikingStorage memory entry
scope: "agent://{agent_id}/experience/{pattern_hash}" // 遵循 OpenViking URI 约定
content: JSON(Experience) // 序列化的完整 Experience 结构体
为什么不用独立的 experiences + FTS5 表:
- VikingStorage 已有成熟的 FTS5 + TF-IDF + embedding 检索管道
- MemoryMiddleware 已与 VikingStorage 集成,增加 scope 前缀即可区分
- 避免维护两套独立的 FTS5 索引
独立的 experience_store.rs 文件负责 VikingStorage CRUD + scope 过滤,不创建新表。
迁移策略
不需要新数据库表或 schema 变更。经验数据通过 VikingStorage 的现有 memory 表存储,使用 scope 前缀区分。
错误处理
- ExperienceExtractor LLM 调用失败 → fallback 到模板提取(固定格式提取 solution_steps)
- ProposalFeedback 检测失败 → 不阻塞对话,静默跳过
- 经验注入失败 → MemoryMiddleware 记录 warn 日志,不注入,不影响正常对话
- 所有错误遵循代码库约定:非关键路径使用
log::warn!/log::error!,不阻塞主流程
测试计划
| 测试目标 | 文件位置 | 覆盖场景 |
|---|---|---|
| ExperienceExtractor | experience.rs 内联 #[cfg(test)] |
LLM 提取成功/failure fallback、模板提取 |
| ExperienceStore | experience_store.rs 内联 |
CRUD 往返、scope 过滤、VikingStorage 集成 |
| PainConfirmedEvent 触发 | pain_aggregator.rs 测试扩展 |
confidence >= 0.7 触发事件 |
| 经验注入 | MemoryMiddleware 测试 | 相关性过滤、token 限制、空结果处理 |
| ProposalFeedback 检测 | solution_generator.rs 测试扩展 |
隐式反馈关键词匹配 |
文件清单
| 文件 | 用途 | 预估行数 |
|---|---|---|
desktop/src-tauri/src/intelligence/experience.rs |
ExperienceExtractor + 逻辑 | ~250 |
crates/zclaw-growth/src/experience_store.rs |
VikingStorage scope CRUD | ~120 |
改动 pain_aggregator.rs |
自动触发 SolutionGenerator | ~30 |
改动 solution_generator.rs |
Proposal feedback 槽位 | ~40 |
改动 intelligence_hooks.rs |
新增 post-proposal-evaluation hook | ~50 |
| 改动 MemoryMiddleware | 经验注入逻辑(scope 过滤) | ~60 |
改动 crates/zclaw-memory/src/lib.rs |
导出新模块 | ~5 |
预估:~555 行新增/修改
Section 2: 用户建模
目标
从每次对话中持续提取用户特征,聚合为结构化画像,注入到路由和生成环节。
数据流
对话消息 → MemoryExtractor(已有)
↓
UserProfiler(新增)
↓ 聚合到 UserProfile
UserProfileStore(新增,SQLite)
↓
├→ ButlerRouter(外部依赖,另一个会话)
│ → 路由决策考虑用户偏好
└→ MemoryMiddleware(已有)
→ system prompt 注入用户画像摘要
设计决策
为什么新建 UserProfile 而不沿用 IdentityManager.user_profile?
现有 user_profile 是非结构化 markdown,无法做条件查询。Profile injection 已被有意禁用(identity.rs:291-298),因为它导致模型过度关注旧话题。需要结构化画像做相关性过滤后注入。
单用户桌面场景: 桌面版使用 "default_user" 作为 user_id(与 PainAggregator 一致),仅维护一条 UserProfile 记录。
数据结构
// 新增文件:crates/zclaw-memory/src/user_profile_store.rs
struct UserProfile {
user_id: String, // "default_user"(桌面版单用户)
// 静态属性(低频更新)
industry: Option<String>, // "医疗" "制造业"
role: Option<String>, // "行政主任" "厂长"
expertise_level: Option<Level>, // Beginner / Intermediate / Expert
communication_style: Option<CommStyle>, // Concise / Detailed / Formal / Casual
preferred_language: String, // "zh-CN"
// 动态属性(高频更新)
recent_topics: Vec<String>, // 最近 7 天的话题
active_pain_points: Vec<String>, // 当前未解决痛点
preferred_tools: Vec<String>, // 常用技能/工具
// 元数据
updated_at: DateTime,
confidence: f32, // 画像置信度
}
enum Level { Beginner, Intermediate, Expert }
enum CommStyle { Concise, Detailed, Formal, Casual }
聚合逻辑(UserProfiler)
- MemoryExtractor 输出 → 分类:已提取的记忆按
UserPreference/UserFact/AgentLesson分类 - 分类后聚合:
UserPreference→ 更新communication_style,preferred_toolsUserFact→ 更新industry,role,expertise_levelAgentLesson→ 更新recent_topics- PainAggregator 的活跃痛点 → 更新
active_pain_points
- 去重 + 衰减:相似属性合并,超过 30 天无佐证的属性降低 confidence
- 存储:单用户单条记录(upsert),SQLite
user_profiles表
注入逻辑
// 在 MemoryMiddleware 中新增
fn inject_user_profile(&self, ctx: &mut MiddlewareContext, profile: &UserProfile) {
// 只注入与当前话题相关的属性
let relevant = self.filter_by_relevance(profile, &ctx.user_input);
if relevant.is_empty() { return; }
// 格式化为简洁摘要,不超过 100 tokens
let summary = format_user_profile_summary(&relevant);
ctx.system_prompt.push_str(&summary);
}
关键约束: 注入内容不超过 100 tokens,只注入与当前话题相关的属性。
与管家路由器的协作(外部依赖)
当管家路由器接通后:
- ButlerRouterMiddleware 可读取 UserProfile.industry 和 role
- 路由时考虑用户背景
- 本设计只提供数据接口,路由逻辑由另一个会话处理
迁移策略
新增 user_profiles 表,通过 schema.rs 的 MIGRATIONS 数组递增版本。初始版本包含 CREATE TABLE + 默认 "default_user" 行。
// 在 schema.rs MIGRATIONS 数组新增
("CREATE TABLE IF NOT EXISTS user_profiles (...)", "DROP TABLE IF EXISTS user_profiles")
错误处理
- UserProfileStore 读写失败 →
log::warn!+ 返回 None,不阻塞对话 - UserProfiler 聚合失败 → 保留上次有效画像,不覆盖
- Profile 注入失败 → MemoryMiddleware 降级到无 profile 注入模式
- 所有操作遵循:非关键路径错误不阻塞主流程
测试计划
| 测试目标 | 文件位置 | 覆盖场景 |
|---|---|---|
| UserProfileStore | user_profile_store.rs 内联 |
CRUD 往返、upsert 去重、JSON 字段序列化 |
| UserProfiler 聚合 | user_profiler.rs 内联 |
分类正确性、去重、衰减、空输入 |
| Profile 注入 | MemoryMiddleware 测试扩展 | 相关性过滤、100 token 限制、空 profile |
| 迁移 | schema 测试 | 新建 + 升级路径 |
数据库 Schema
CREATE TABLE IF NOT EXISTS user_profiles (
user_id TEXT PRIMARY KEY,
industry TEXT,
role TEXT,
expertise_level TEXT, -- 'Beginner' | 'Intermediate' | 'Expert'
communication_style TEXT, -- 'Concise' | 'Detailed' | 'Formal' | 'Casual'
preferred_language TEXT DEFAULT 'zh-CN',
recent_topics TEXT, -- JSON array
active_pain_points TEXT, -- JSON array
preferred_tools TEXT, -- JSON array
confidence REAL DEFAULT 0.0,
updated_at TEXT NOT NULL
);
文件清单
| 文件 | 用途 | 预估行数 |
|---|---|---|
crates/zclaw-memory/src/user_profile_store.rs |
UserProfile 结构体 + SQLite CRUD | ~200 |
desktop/src-tauri/src/intelligence/user_profiler.rs |
聚合逻辑 | ~180 |
改动 MemoryMiddleware |
profile 注入(相关性过滤) | ~80 |
改动 intelligence_hooks.rs |
post-extraction 触发 UserProfiler | ~30 |
改动 crates/zclaw-memory/src/lib.rs |
导出新模块 | ~5 |
预估:~495 行新增/修改
Section 3: 自然语言 Cron
目标
用户说"每天早上9点提醒我查房" → 系统解析为 0 9 * * * → 自动创建定时任务。
数据流
用户消息(含时间意图)
↓
意图分类(ButlerRouter / 正则预检)
↓ 检测到"定时/提醒"意图
NlScheduleParser(新增,位于 zclaw-runtime)
↓ 解析为 ParsedSchedule
ScheduleConfirmDialog(新增)
↓ 用户确认 "每天早上9点 → 0 9 * * *"
SchedulerService(已有,位于 zclaw-kernel)
↓ 创建定时任务
TriggerManager(已有)
↓ 到时触发
Hand 执行(已有)
解析策略(三层 fallback)
Layer 1: 正则模式匹配(覆盖 80% 常见场景)
| 模式 | 示例 | Cron |
|---|---|---|
| 每天 + 时间 | 每天早上9点 | 0 9 * * * |
| 每周N + 时间 | 每周一上午10点 | 0 10 * * 1 |
| 工作日 + 时间 | 工作日下午3点 | 0 15 * * 1-5 |
| 每N小时 | 每2小时 | 0 */2 * * * |
| 每月N号 | 每月1号 | 0 0 1 * * |
| 相对时间 | 明天下午3点 | 一次性 ISO |
Layer 2: LLM 辅助解析(覆盖模糊/复杂表述)
- 使用 Haiku(~50 tokens 输入,~20 tokens 输出)
- 处理如"下个月开始每周二和周四提醒我"
Layer 3: 交互澄清(无法确定时)
- "我理解您想设置定时任务,请确认:..."
数据结构
// 新增文件:crates/zclaw-runtime/src/nl_schedule.rs
// 放在 runtime 层因为这是纯文本→cron工具,不依赖 kernel 协调
use zclaw_types::AgentId;
struct ParsedSchedule {
cron_expression: String, // "0 9 * * *"
natural_description: String, // "每天早上9点"
confidence: f32,
task_description: String, // "查房提醒"
task_target: TaskTarget,
}
/// 定时任务目标
enum TaskTarget {
Agent(AgentId), // 触发指定 agent
Hand(String), // 触发指定 hand(工具名)
Workflow(String), // 触发指定 workflow(名称)
}
enum ScheduleParseResult {
Exact(ParsedSchedule), // 高置信度,直接确认
Ambiguous(Vec<ParsedSchedule>), // 多种理解,需选择
Unclear, // 需要澄清
}
确认流程
- 用户说"每天早上9点提醒我查房"
- 解析为
{ cron: "0 9 * * *", desc: "查房提醒" } - 系统回复:"好的,我为您设置了:每天早上 9:00 提醒查房。确认吗?"
- 用户确认 → 调用已有
SchedulerService.create_trigger() - 用户修正 → 重新解析或手动编辑
迁移策略
不需要新数据库表。NlScheduleParser 是纯计算工具,输出通过现有 SchedulerService + TriggerManager 存储。
错误处理
- 正则匹配失败 → 尝试 Layer 2 LLM 解析
- LLM 解析失败 → 返回
ScheduleParseResult::Unclear,触发交互澄清 - 定时任务创建失败 → 向用户报告错误,建议手动设置
- 所有错误不阻塞对话流程
测试计划
| 测试目标 | 文件位置 | 覆盖场景 |
|---|---|---|
| 正则解析 | nl_schedule.rs 内联 |
10+ 中文时间表述模式、边界值、无效输入 |
| LLM fallback | mock 测试 | LLM 返回无效 cron 时的容错 |
| ParsedSchedule | 单元测试 | 序列化、字段完整性 |
| TaskTarget 枚举 | 单元测试 | 各变体匹配现有类型 |
| 确认流程 | 集成测试 | 完整 parse → confirm → create 链路 |
文件清单
| 文件 | 用途 | 预估行数 |
|---|---|---|
crates/zclaw-runtime/src/nl_schedule.rs |
NlScheduleParser + 中文模式库 | ~300 |
改动 intelligence_hooks.rs |
检测定时意图并触发解析 | ~40 |
| 改动 desktop store + component | 确认对话框交互 | ~150 |
改动 crates/zclaw-kernel/src/scheduler.rs |
接受 cron 字符串输入 | ~20 |
预估:~510 行新增/修改
Section 4: 轨迹压缩
目标
记录完整的工具调用链(用户请求 → 意图分类 → 技能选择 → 执行步骤 → 结果 → 用户满意度),压缩为结构化 JSON,作为未来 RL/改进的基础数据。
数据流
用户请求
↓
AgentLoop(已有)
↓ 每步通过中间件记录
TrajectoryRecorderMiddleware(新增,实现 AgentMiddleware trait)
↓ 异步写入 trajectory_events 表
↓ 会话结束时
TrajectoryCompressor(新增)
↓ 压缩为结构化 JSON
compressed_trajectories 表
↓ 可选
导出为 RL 训练数据格式
关键设计决策:TrajectoryRecorder 作为中间件
TrajectoryRecorder 实现 AgentMiddleware trait(来自 zclaw-runtime),利用现有中间件钩子:
before_completion→ 记录UserRequest步骤after_tool_call→ 记录ToolExecution步骤after_completion→ 记录LlmGeneration步骤 + 会话结束时触发压缩
为什么不用自定义 AgentLoop hook:
- 现有中间件系统已提供所有需要的钩子点
MiddlewareContext已暴露agent_id、session_id、user_input、input_tokens、output_tokens- 符合 Pipeline Closure 原则:不引入新架构层
优先级设置:600-799 范围(遥测类别),确保在业务中间件之后运行。注意现有 token_calibration 中间件已占用优先级 700,推荐使用 650。
数据结构
// 新增文件:crates/zclaw-memory/src/trajectory_store.rs
use zclaw_types::{AgentId, SessionId};
use uuid::Uuid;
/// 单条轨迹事件(细粒度,按步骤记录)
struct TrajectoryEvent {
id: TrajectoryId,
session_id: SessionId,
agent_id: AgentId,
step_index: usize,
step_type: TrajectoryStepType,
input_summary: String, // ≤200 字
output_summary: String, // ≤200 字
duration_ms: u64,
timestamp: DateTime,
}
enum TrajectoryStepType {
UserRequest, // 用户原始请求
IntentClassification, // 意图分类结果
SkillSelection, // 选择了哪个技能
ToolExecution, // 工具调用
LlmGeneration, // LLM 生成
UserFeedback, // 用户反馈
}
/// 压缩后的完整轨迹(会话结束时生成)
struct CompressedTrajectory {
id: TrajectoryId,
session_id: SessionId,
agent_id: AgentId,
request_type: String, // "data_report" "policy_query"
tools_used: Vec<String>, // ["researcher", "collector"]
outcome: CompletionStatus, // Success | Partial | Failed | Abandoned
total_steps: usize,
total_duration_ms: u64,
total_tokens: u32,
execution_chain: String, // JSON: [{step, tool, result_summary}]
satisfaction_signal: Option<SatisfactionSignal>,
created_at: DateTime,
}
enum SatisfactionSignal {
Positive, // "谢谢""很好""解决了"
Negative, // "不对""没用""还是不行"
Neutral, // 无明显信号
}
记录策略
低开销原则: 轨迹记录不能影响正常对话性能。
- 事件记录: 每步只存
step_type + input_summary(≤200字) + output_summary(≤200字) - 异步写入: 通过
tokio::spawn异步写入 SQLite,不阻塞主流程 - 压缩触发: 会话结束时(compactor flush 或 session close),异步压缩
- 保留策略: 压缩后删除原始事件(保留 7 天),压缩轨迹保留 90 天
压缩算法
fn compress(events: Vec<TrajectoryEvent>) -> CompressedTrajectory {
// 1. 提取关键步骤(跳过中间重试/错误恢复)
// 2. 合并连续相同类型的步骤
// 3. 生成 execution_chain JSON
// 4. 推断 outcome(最后一步是否成功 + 用户反馈信号)
// 5. 统计 token 用量和耗时
}
与自我改进闭环的协作
当 ExperienceExtractor 运行时:
- 查询
compressed_trajectories找到类似场景的历史轨迹 - 评估"这个方案上次用了几步?成功率多少?"
- 为经验提取提供数据支撑
未来 RL 扩展(本次不实施)
execution_chain可直接转换为 Atropos/GEPA 训练格式satisfaction_signal可作为 reward signal- RL 训练管道不在本次范围内
迁移策略
通过 schema.rs 的 MIGRATIONS 数组递增版本(使用 &[&str] 扁平数组格式,与现有代码一致),新增 trajectory_events 和 compressed_trajectories 两张表。
// 在 schema.rs MIGRATIONS 数组新增(扁平 &str 数组,无 down migration)
&[
"CREATE TABLE IF NOT EXISTS trajectory_events (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL,
...
);
CREATE TABLE IF NOT EXISTS compressed_trajectories (
...
);
CREATE INDEX IF NOT EXISTS idx_trajectory_session ON trajectory_events(session_id);",
]
错误处理
- TrajectoryRecorder 异步写入失败 →
log::warn!,不重试,丢弃单条事件 - TrajectoryCompressor 压缩失败 →
log::warn!,原始事件保留 7 天后自动清理 - 压缩轨迹查询失败 → ExperienceExtractor 降级到无历史数据模式
- 所有操作:非关键路径错误不阻塞对话
测试计划
| 测试目标 | 文件位置 | 覆盖场景 |
|---|---|---|
| TrajectoryStore CRUD | trajectory_store.rs 内联 |
插入/查询/删除、session 过滤 |
| 压缩算法 | trajectory_compressor.rs 内联 |
正常压缩、空事件、单步事件、合并去重 |
| TrajectoryRecorderMiddleware | 中间件测试 | before/after 钩子记录、空输入跳过 |
| 保留策略 | 集成测试 | 7 天清理、90 天清理 |
| 满意度检测 | 单元测试 | 正/负/中性关键词匹配 |
数据库 Schema
CREATE TABLE IF NOT EXISTS trajectory_events (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL,
agent_id TEXT NOT NULL,
step_index INTEGER NOT NULL,
step_type TEXT NOT NULL,
input_summary TEXT,
output_summary TEXT,
duration_ms INTEGER DEFAULT 0,
timestamp TEXT NOT NULL
);
CREATE INDEX idx_trajectory_session ON trajectory_events(session_id);
CREATE TABLE IF NOT EXISTS compressed_trajectories (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL,
agent_id TEXT NOT NULL,
request_type TEXT NOT NULL,
tools_used TEXT, -- JSON array
outcome TEXT NOT NULL, -- 'Success'|'Partial'|'Failed'|'Abandoned'
total_steps INTEGER DEFAULT 0,
total_duration_ms INTEGER DEFAULT 0,
total_tokens INTEGER DEFAULT 0,
execution_chain TEXT NOT NULL, -- JSON
satisfaction_signal TEXT, -- 'Positive'|'Negative'|'Neutral'|NULL
created_at TEXT NOT NULL
);
CREATE INDEX idx_ct_request_type ON compressed_trajectories(request_type);
CREATE INDEX idx_ct_outcome ON compressed_trajectories(outcome);
文件清单
| 文件 | 用途 | 预估行数 |
|---|---|---|
crates/zclaw-memory/src/trajectory_store.rs |
TrajectoryEvent + CompressedTrajectory + SQLite CRUD | ~250 |
crates/zclaw-runtime/src/middleware/trajectory_recorder.rs |
AgentMiddleware 实现 | ~150 |
desktop/src-tauri/src/intelligence/trajectory_compressor.rs |
压缩算法 | ~120 |
改动 crates/zclaw-memory/src/lib.rs |
导出新模块 | ~5 |
改动 crates/zclaw-kernel/src/kernel/mod.rs |
注册中间件(priority 650) | ~10 |
预估:~535 行新增/修改
总览
代码量汇总
| 理念 | 新增 | 修改 | 总计 | 优先级 |
|---|---|---|---|---|
| 自我改进闭环 | ~400 | ~155 | ~555 | P1 |
| 用户建模 | ~380 | ~115 | ~495 | P2 |
| 自然语言 Cron | ~320 | ~190 | ~510 | P3 |
| 轨迹压缩 | ~525 | ~15 | ~540 | P4 |
| 总计 | ~1625 | ~475 | ~2100 | — |
实施顺序和依赖关系
Section 1 (自我改进闭环) ← 立即开始
↓
Section 2 (用户建模) ← 可与 Section 1 并行,无强依赖
↓
Section 3 (NL Cron) ← 依赖 Section 2 的 UserProfile(可选)+ 管家路由器(外部)
↓
Section 4 (轨迹压缩) ← 可与 Section 1-3 并行,无依赖
Section 1 和 2 可以并行开发。Section 3 建议在管家路由器接通后实施。Section 4 完全独立。
外部依赖
- 管家路由器(ButlerRouterMiddleware + SemanticSkillRouter 接通)— 另一个会话推进
- 痛点数据持久化(内存 → SQLite)— 已在 pre-release strategy 中规划
intelligence_hooks.rs 管理
当前 intelligence_hooks.rs 约 281 行。本设计新增约 120 行钩子代码(Section 1: ~50, Section 2: ~30, Section 3: ~40)。
如果文件超过 400 行,应拆分为 hooks/ 子模块:
hooks/pain.rs— 痛点相关钩子hooks/profile.rs— 用户画像钩子hooks/schedule.rs— 定时任务意图检测hooks/mod.rs— 统一注册
验证方式
每个 Section 完成后的验证步骤:
- 自我改进闭环: 人工模拟痛点对话 → 验证自动生成方案 → 验证经验提取 → 验证经验复用注入
- 用户建模: 多轮对话 → 检查 UserProfile 各字段是否正确聚合 → 验证注入内容相关性
- NL Cron: 测试 10+ 种中文时间表述 → 验证 cron 输出 → 验证定时任务创建
- 轨迹压缩: 完整对话流程 → 检查 trajectory_events 记录 → 验证压缩结果 → 检查异步写入无阻塞
验证命令
# Rust 编译检查
cargo check --workspace --exclude zclaw-saas
# Rust 测试
cargo test --workspace --exclude zclaw-saas
# TypeScript 类型检查
cd desktop && pnpm tsc --noEmit
# 前端测试
cd desktop && pnpm vitest run