# Claude Code / Hermes-Agent 参考分析 对 Claude Code (`/home/fmq/program/claudecode/src/`) 和 Hermes-Agent (`libs/hermes-agent/`) 源码的全面架构分析,记录对 AstroResearch Agent 系统的参考价值与改进方向。 > 分析日期: 2026-06-22 | 最后更新: 2026-06-23 ## 实施状态 | 优先级 | 改进项 | 状态 | 涉及文件 | |--------|--------|------|---------| | P0 | Context Overflow 自动修复 | ✅ 已完成 | `error_recovery.rs` (+150 行) | | P0 | StreamingExecutor 真正流式调度 | ✅ 已完成 | `streaming_executor.rs` (重写 ~400 行) | | P0 | Executor 集成分区器(批次串行/并行) | ✅ 已完成 | `executor.rs` (Phase 3 重写 + 2 个提取函数) | | P1 | 工具并发分区 `partition_tool_calls` | ✅ 已完成 | `partitioner.rs` (+2 测试) | | P1 | PermissionRequest / PermissionDenied Hooks | ✅ 已完成 | `hooks/types.rs`, `traits.rs`, `dispatch.rs`, `mod.rs` | | P1 | Auto-mode Classifier | ⏳ 待定 | — | | P2 | Self-improving Skills(模式检测 + 自动创建 + Curator) | ✅ 已完成 | `skills/pattern_detector.rs` + `curator.rs` + `SkillCreator` | | P2 | Coordinator Mode | ✅ 已完成 | `src/agent/coordinator/` | | P2 | UserPromptSubmit / PreCompact / PostCompact Hook | ✅ 已完成 | `hooks/types.rs`, `dispatch.rs` | | P3 | FTS5 跨 session 搜索 | ✅ 已完成 | `agent_sessions_fts` + `agent_messages_fts` | | P3 | Tool `defer_loading` / `classifier_summary` | ✅ 已完成 | `tools/mod.rs` | | P3 | 模型回退策略 | ✅ 已完成 | `error_recovery.rs` (LLM_FALLBACK_MODEL/LLM_FALLBACK_CHAIN) | | P3 | Session Memory Compaction | ✅ 已完成 | `memory/mod.rs` (extract_memories_from_compaction) | --- ## 目录 1. [总体评估](#1-总体评估) 2. [工具并发执行模型](#2-工具并发执行模型) 3. [Permission 系统](#3-permission-系统) 4. [Hooks 系统](#4-hooks-系统) 5. [Error Recovery / 重试系统](#5-error-recovery--重试系统) 6. [Tool 定义系统](#7-tool-定义系统) 8. [Memory 持久化](#8-memory-持久化) 9. [Coordinator / Multi-Agent](#9-coordinator--multi-agent) 10. [Hermes-Agent 的独特贡献](#10-hermes-agent-的独特贡献) 11. [优先级排序 —— 建议实施路线](#11-优先级排序--建议实施路线) --- ## 1. 总体评估 ### 1.1 参考项目概览 | 维度 | Claude Code | Hermes-Agent | AstroResearch | |------|-------------|-------------|---------------| | 语言 | TypeScript (Node.js) | Python (3.11+) | Rust (Axum) | | 定位 | 终端 IDE 编程助手 | 通用 AI 个人助手 | 天文科研 Agent | | Agent 循环 | 流式 `query()` generator | 同步 `while` 循环 | 流式 ReAct 循环 | | 工具注册 | 手动 import + `getAllBaseTools()` | 文件系统自动发现 | 手动 `ToolRegistry::new()` | | 工具接口 | `Tool` — ~70 个方法 | `handler(args) -> JSON string` | `AgentTool` trait — ~10 个方法 | | 权限系统 | 6 层优先级 + Classifier + 沙箱 | 无内置 | 3 层规则 + PermissionChecker | | Hooks | 27 种事件,6 种 hook 类型 | PluginManager 生命周期 | 15 种事件,2 种 hook 类型 | | 子代理 | `AgentTool` + Fork + Worktree 隔离 | `delegate_task` + 子 AIAgent | `SubAgentTool` + 独立 ReAct | | 多 Agent | Coordinator 模式 + Swarm/Team | Kanban 工作队列 | Team 系统 (lead/teammate) | | 持久化 | 文件系统 Markdown + cost tracker | SQLite (FTS5) + SessionDB | SQLite + MEMORY.md | | 上下文压缩 | 微压缩 + 自动压缩 + 手动压缩 | ContextCompressor | 4 层压缩 (微/snip/auto/aggro) | ### 1.2 核心结论 AstroResearch 的 Agent 系统架构本身就是**对标 Claude Code 设计的**——`StreamingToolExecutor`、 `PermissionChecker`、`HookRegistry` 都明确标注了参考来源。当前差距主要是**实现深度**而非**设计方向**。 Claude Code 的参考价值在**工程细节**:流式调度的时机选择、Overflow 的自动修复、Classifier 的并行化设计。Hermes-Agent 的独特价值在**自我进化**(Self-improving Skills)和**多 Profile 隔离**。 --- ## 2. 工具并发执行模型 ### 2.1 对比 | 特性 | Claude Code | AstroResearch (当前) | |------|-------------|---------------------| | 流式调度 | tool_use 到达**立即**开始执行 | tool_use 全部收集,`flush()` 批量执行 | | 并发分区 | `partitionToolCalls()` 自动分组连续只读工具并行 | `ToolPartitioner` 存在但基本未使用 | | Sibling Abort | Bash 错误 → 级联取消兄弟工具,有专用 `siblingAbortController` | `AbortReason::SiblingError` + 广播通道存在,取消逻辑不完整 | | Progress 流式 | `pendingProgress` 即时 yield,`progressAvailableResolve` 唤醒等待 | `execute_with_progress` 有通道,`getCompletedResults` 未检查 | | 中断行为 | `interruptBehavior()` 区分 `cancel` vs `block` | `InterruptBehavior` 枚举存在但未在 Executor 中使用 | ### 2.2 Claude Code 的分区逻辑 ```typescript // src/services/tools/toolOrchestration.ts // 自动将连续只读工具分组并行,写工具独立串行 function partitionToolCalls(toolUseMessages, toolUseContext): Batch[] { return toolUseMessages.reduce((acc, toolUse) => { const tool = findToolByName(toolUseContext.options.tools, toolUse.name) const parsedInput = tool?.inputSchema.safeParse(toolUse.input) const isConcurrencySafe = parsedInput?.success ? (() => { try { return Boolean(tool.isConcurrencySafe(parsedInput.data)) } catch { return false } })() : false if (isConcurrencySafe && acc[acc.length - 1]?.isConcurrencySafe) { acc[acc.length - 1].blocks.push(toolUse) // 合并到当前批次 } else { acc.push({ isConcurrencySafe, blocks: [toolUse] }) // 新批次 } return acc }, []) } ``` 关键点: - **输入感知**的并发安全判断:同一工具可能因参数不同而安全属性不同 - 并发安全的工具**连续分组**——不打断写入顺序 - 非并发安全的工具**独占执行**——等上一个完成后才启动下一个 ### 2.3 Claude Code 的 StreamingToolExecutor 核心逻辑 ``` 文件: src/services/tools/StreamingToolExecutor.ts (531 行) 状态机: Queued → Executing → Completed → Yielded 生命周期: 1. addTool(block) — LLM 流产生 tool_use 时立即调用 2. processQueue() — 检查 concurrency 条件,启动可执行工具 3. executeTool(tool) — 创建子 AbortController,调用 runToolUse generator 4. getCompletedResults() — 按序 yield 结果(非阻塞) 5. getRemainingResults() — 等待未完成工具(async generator) 关键设计: - siblingAbortController: 父 AbortController 的子节点 Bash 错误 → siblingAbortController.abort('sibling_error') → 取消所有兄弟 但 toolAbortController 的 abort 会向上冒泡到父 AbortController - progressAvailableResolve: Promise resolver 用于唤醒等待 progress 的 getRemainingResults - 中断行为: 'cancel' 工具被用户中断时生成 REJECT_MESSAGE; 'block' 工具不受影响 ``` ### 2.4 AstroResearch 的现状(2026-06-22 更新) ``` 文件: src/agent/runtime/streaming_executor.rs (~400 行,已重写) 已实现: ✅ TrackedTool 状态机 (Queued/Executing/Completed/Yielded) ✅ Sibling Abort 广播通道(broadcast::channel + tokio::select! 竞速) ✅ on_tool_use / flush / next_result 接口 ✅ 输出截断 ✅ 真正的流式调度 — on_tool_use 中对并发安全工具立即 spawn tokio task ✅ 非并发安全工具独占执行 — executing_non_concurrent 标志阻塞后续启动 ✅ 并发取消 — tokio::select! 在工具执行和 Sibling Abort 之间竞速 ✅ 输入感知的并发安全判断 — 通过 tool_registry.get().is_concurrency_safe(&args) ✅ ToolContext 实现 Clone(支持 per-task 复制上下文) 与 Claude Code 的对齐: - 核心理念一致:addTool → 立即 processQueue - Sibling Abort 机制等效:broadcast::Sender + subscribe - collectCompletedTasks 使用 JoinHandle::is_finished() 做非阻塞检查 ``` ### 2.5 已实施改进(2026-06-22) **✅ P0: 真正的流式调度** — 已完成 `on_tool_use` 中对并发安全工具立即 `tokio::spawn`,非并发安全工具标记 `executing_non_concurrent` 并阻塞后续启动,直到独占工具完成。 **✅ P0: Executor 集成分区器** — 已完成 `src/agent/runtime/executor.rs` Phase 3 从「所有非拒绝工具单一 `FuturesUnordered` 无差别并发」 改为「`ToolPartitioner` 分区 → 逐批次执行」: - 并行批次内 `FuturesUnordered` 并发 - 串行批次内逐个执行(非并发安全工具独占) - 提取 `execute_single_tool()` 和 `process_single_result()` 两个辅助函数 **✅ P1: 并发分区器** — 已完成 `src/agent/runtime/partitioner.rs` 新增 2 个测试(`run_bash`、`file_write` 打断并发批)。 ### 2.6 原始建议(已过时) ```rust // 建议在 on_tool_use 中对并发安全的工具立即 spawn pub fn on_tool_use(&mut self, call_id: String, name: String, args: Value) -> bool { let is_concurrency_safe = /* 判断 */ let idx = self.tracked.len(); self.tracked.push(tool); if is_concurrency_safe && self.can_execute_now() { let handle = tokio::spawn(/* 执行 */); self.tracked[idx].handle = Some(handle); true } else { false } } ``` **P1: 并发分区** ```rust /// 将 tool_use 列表分区为 (并发安全批次, 非并发安全单例) fn partition_tool_calls(calls: &[PreparedCall], registry: &ToolRegistry) -> Vec { calls.iter().fold(Vec::new(), |mut acc, call| { let is_safe = registry.get(&call.tool_name) .map(|t| t.is_concurrency_safe(&call.args)) .unwrap_or(false); if is_safe && acc.last().map_or(false, |b: &Batch| b.concurrent) { acc.last_mut().unwrap().calls.push(call.clone()); } else { acc.push(Batch { concurrent: is_safe, calls: vec![call.clone()] }); } acc }) } ``` --- ## 3. Permission 系统 ### 3.1 对比 | 特性 | Claude Code | AstroResearch (当前) | |------|-------------|---------------------| | 规则来源分层 | 6 层优先级:policy > project > user > plugin > flag > command | 单一规则列表 | | 规则行为 | Allow / Deny / Ask | Allow / Deny / Ask ✅ | | Classifier 自动模式 | 两阶段(快速 + 思考),并行于 hooks 启动 | 无 | | 拒绝追踪 | 带时间窗口的限流回退 (DenialTracker) | 简单计数 | | 沙箱集成 | `shouldUseSandbox()` + `sandbox-adapter` | 无沙箱概念 | | 决策溯源 | 每条 PermissionDecisionReason 记录完整来源链 | 只返回 Allow/Deny/Ask | | 权限模式 | 5 种:default, acceptEdits, bypassPermissions, dontAsk, plan | 4 种 ✅ | ### 3.2 Claude Code 的 Permission 决策管道 ``` 1. validateInput() — Zod schema 验证 2. runPreToolUseHooks() — Session hooks(用户配置的) 3. canUseTool — 检查 deny 规则 4. resolveHookPermissionDecision() — Allow 规则 5. [auto mode] Classifier — 两阶段分类器(Haiku) 6. [default mode] 用户弹窗 — 交互式确认 7. PermissionDecisionReason — 记录决策来源 ``` 每个决策都烙印 `PermissionDecisionReason`: ``` rule | mode | subcommandResults | permissionPromptTool | hook | asyncAgent | sandboxOverride | classifier | workingDir | safetyCheck | other ``` ### 3.3 Classifier 系统(最值得借鉴) Claude Code 的 auto-mode classifier 是一个**独立的小模型调用**(Haiku),在后台并行运行: ``` Auto Mode 决策流程: ┌──────────────────────────────────────────────┐ │ 1. startSpeculativeClassifierCheck() │ │ └─ 并行于 PreToolUse hooks 启动 │ │ 2. 两阶段分类: │ │ ├─ Fast: 简单模式匹配(秒级) │ │ └─ Thinking: 深度分析(复杂命令时) │ │ 3. 结果: Allow / Deny / Ask + confidence │ │ 4. DenialTracker: 连续 Deny 后 fallback 用户 │ └──────────────────────────────────────────────┘ ``` AstroResearch 目前没有 auto-mode——所有非白名单工具都需要用户交互确认。 ### 3.4 建议改进 **P1: Auto-mode Classifier** ```rust /// Auto-mode 分类器 — 使用廉价模型在后台预分类工具调用 pub struct AutoClassifier { llm: LlmClient, // 使用廉价模型(如 Haiku 级别 provider) cache: LruCache, } #[derive(Debug)] pub struct ClassificationResult { pub decision: PermissionResult, pub confidence: f64, pub reason: String, } impl AutoClassifier { /// 在工具执行前异步预分类(不阻塞用户) pub async fn preclassify( &self, tool_name: &str, args: &Value, context: &str, // 从 CLAUDE.md 和当前对话提取 ) -> ClassificationResult { // 构建精简 prompt: // "You are a security classifier. Evaluate this tool call: // Tool: {tool_name} // Args: {args} // Context: {context} // Respond: ALLOW|DENY|ASK " todo!() } } ``` **P1: PermissionRequest / PermissionDenied Hook 事件** 这两个事件对科研场景的审计至关重要: ```rust // 在 hooks/types.rs 中添加 pub enum HookEvent { // ... 现有事件 ... /// 权限请求前触发(可阻止或修改) PermissionRequest, /// 权限被拒绝后触发(审计日志) PermissionDenied, } ``` --- ## 4. Hooks 系统 ### 4.1 对比 | 特性 | Claude Code | AstroResearch (当前) | |------|-------------|---------------------| | Hook 类型 | 6 种:command, prompt, agent, http, callback, function | 2 种:sync AgentHook + async AsyncAgentHook | | 匹配器 | simple / pipe-separated / regex | glob + 精确匹配 | | if 条件 | `preparePermissionMatcher()` — Bash 上有 tree-sitter | 无 | | 输出协议 | JSON `{continue, decision, reason, suppressOutput, hookSpecificOutput}` | 直接返回值 | | 超时 | 每个 hook 独立超时(默认 10min) | 统一 `DEFAULT_HOOK_TIMEOUT` | | 事件数量 | 27 种 | ~15 种 | | 来源 | config + plugin + SDK + session + function | registry + session | ### 4.2 Claude Code 的 27 种 Hook 事件 ``` 生命周期类: SessionStart, Setup, SubagentStart, SubagentStop, SessionEnd, Stop, StopFailure 用户交互类: UserPromptSubmit, Elicitation, ElicitationResult, PermissionRequest, PermissionDenied 工具执行类: PreToolUse, PostToolUse, PostToolUseFailure 上下文类: PreCompact, PostCompact, InstructionsLoaded 环境监控类: FileChanged, CwdChanged, ConfigChange Swarm/Team 类: TeammateIdle, TaskCreated, TaskCompleted UI 类: Notification, StatusLine, FileSuggestion ``` ### 4.3 AstroResearch 缺失的关键事件 | 缺失事件 | 用途 | 优先级 | 状态 | |---------|------|--------|------| | `UserPromptSubmit` | 用户提交 prompt 前拦截(自动上下文注入) | P2 | ⏳ | | `Notification` | 长时间操作完成通知 | P1 | ⏳ | | `PermissionRequest` | 权限弹窗前触发 | P1 | ✅ 已实现 | | `PermissionDenied` | 权限被拒绝后记录审计 | P1 | ✅ 已实现 | | `PreCompact` | 上下文压缩前机会(保存重要信息) | P2 | ⏳ | | `PostCompact` | 上下文压缩后通知(更新外部状态) | P2 | ⏳ | ### 4.4 已实施改进(2026-06-22) **✅ P1: PermissionRequest / PermissionDenied 事件** — 已完成 新增类型(`src/agent/hooks/types.rs`): - `HookEvent::PermissionRequest` / `HookEvent::PermissionDenied` - `PermissionRequestContext` — 携带 `current_decision`、`permission_mode`、`is_subagent` - `PermissionDeniedContext` — 携带 `reason`、`source` (Rule/Classifier/User/Timeout) - `PermissionRequestAction` — Continue / Override / InjectContext - `PermissionDecision` / `PermissionDenialSource` 枚举 新增 trait 方法(`src/agent/hooks/traits.rs`): - `AgentHook::on_permission_request()` → `PermissionRequestAction` - `AgentHook::on_permission_denied()` → void (审计日志) 新增调度方法(`src/agent/hooks/dispatch.rs`): - `HookRegistry::run_on_permission_request()` — 并行调用,第一个 Override 生效 - `HookRegistry::run_on_permission_denied()` — fire-and-forget 审计 ### 4.5 原始建议(部分已过时) 原建议的 context 设计已被更完善的实现替代: } ``` **P2: 支持 command 类型 hook** ```rust /// Command 类型 hook — 执行外部 shell 命令处理事件 pub struct CommandHook { command: String, // 如 "python3 audit.py" timeout: Duration, // 默认 10min shell: HookShell, // Bash | PowerShell } ``` --- ## 5. Error Recovery / 重试系统 ### 5.1 对比 | 特性 | Claude Code | AstroResearch (当前) | |------|-------------|---------------------| | 重试结构 | Generator 模式,yield 系统消息直到不可重试 | ErrorRecovery 枚举 + 简单决策 | | 退避算法 | 指数 + 25% jitter,可配置上限(32s 默认,5min 持久) | 固定退避 | | 错误分类 | `shouldRetry()` 检查 15+ 种错误,每种不同策略 | 8 步分类管线 | | 529 Overloaded | 3 次重试 → 模型回退(Opus→Sonnet)→ 持久化重试 | 无模型回退 | | Context Overflow | 解析 "X + Y > Z",自动调整 max_tokens + 1000 安全缓冲 | 只分类不修复 | | 持久化重试 | 无限重试 + 30s 心跳 | 无 | | Fast Cooldown | 429/529 在 fast mode → retry-after <20s → 10min cooldown | N/A | ### 5.2 Context Overflow 自动修复(最值得借鉴) Claude Code 的做法: ```typescript // src/services/api/withRetry.ts // 解析 Anthropic API 的错误消息: // "input length and max_tokens exceed context limit: 180000 + 32000 > 200000" // → 计算安全的 max_tokens = 200000 - 180000 - 1000(safety) = 19000 function parseContextOverflowError(errorMessage: string) { const match = errorMessage.match( /input length and max_tokens exceed context limit: (\d+) \+ (\d+) > (\d+)/ ); if (match) { const [, inputLen, maxTokens, contextLimit] = match.map(Number); const newMaxTokens = contextLimit - inputLen - SAFETY_MARGIN; if (newMaxTokens > MIN_TOKENS) { return { shouldRetry: true, adjustedMaxTokens: newMaxTokens }; } } return { shouldRetry: false }; } ``` ### 5.3 已实施改进(2026-06-22) **✅ P0: Context Overflow 自动修复** — 已完成 新增公共 API(`src/agent/runtime/error_recovery.rs`): - `ContextOverflowInfo` — 从错误消息解析的数值结构体 - `parse_context_overflow()` — 支持 Anthropic/OpenAI/通用三种格式 - `calculate_safe_max_tokens()` — `context_limit - input_length - SAFETY_MARGIN(1000)` - `RecoveryStep::AdjustMaxTokens { new_max_tokens }` — 恢复管线第 0 步 - `extract_three_numbers()` — 正则匹配 "A + B > C" 模式(使用已有 `regex` crate) `AgentRuntime` 集成(`src/agent/runtime/mod.rs`): ```rust let overflow_info = error_recovery::parse_context_overflow(&e_str); while let Some(recovery_step) = recovery.try_recover(&error_kind, overflow_info.as_ref()) { // AdjustMaxTokens 优先于 AggressiveCompact,仅无空间时才回退到压缩 } ``` 12 个新增测试覆盖 Anthropic/OpenAI/Generic 格式、边界条件、恢复优先级。 ### 5.4 原始建议(部分已过时) **P1: 模型回退策略** ```rust /// 模型回退链 — 529/Overloaded 时自动降级 pub struct ModelFallback { chain: Vec, } #[derive(Debug, Clone)] pub enum ModelTier { Primary(String), // 如 "claude-opus-4-8" Fallback(String), // 如 "claude-sonnet-4-6" Emergency(String), // 如 "claude-haiku-4-5" } ``` --- ## 6. Tool 定义系统 ### 7.1 对比 | 特性 | Claude Code `Tool` | AstroResearch `AgentTool` trait | |------|----------------------|-------------------------------| | 并发安全 | `isConcurrencySafe(input)` — 输入感知 ✅ | `is_concurrency_safe(args)` — ✅ | | 语义标记 | `isReadOnly()` / `isDestructive()` / `isConcurrencySafe()` | `causes_sibling_abort()` / `interrupt_behavior()` | | 权限逻辑 | `checkPermissions()` — 工具自己决定权限 | 集中在 PermissionChecker | | 分类器输入 | `toAutoClassifierInput()` — 精简信息 | 无 | | 延迟加载 | `shouldDefer` / `alwaysLoad` — 减小 prompt | 无 | | 搜索提示 | `searchHint` — 帮助 ToolSearch 匹配 | 无 | | UI 渲染 | `renderToolUseMessage/Result/Progress/Error` (6 种) | 前端独立处理 | | 中断行为 | `interruptBehavior()` — cancel vs block | `interrupt_behavior()` ✅ | | 输出大小 | `maxResultSizeChars` — 超限存磁盘 | env var 全局配置 | | 权限匹配器 | `preparePermissionMatcher()` — 工具级模式匹配 | HookMatcher | ### 7.2 Claude Code 的 `buildTool()` Factory ```typescript // 每个工具通过 buildTool 创建,自动填充安全默认值 const myTool: Tool = buildTool({ name: 'MyTool', inputSchema: z.object({ ... }), async call(input, context, toolUseId) { ... }, // 以下都有安全默认值,按需覆盖: // isEnabled: true (可根据 permission mode 禁用) // isConcurrencySafe: false // isReadOnly: false // isDestructive: false // checkPermissions: {behavior: 'allow'} (最宽松) // toAutoClassifierInput: '' (不参与分类) // shouldDefer: false (立即加载) // interruptBehavior: 'block' (不可中断) }) ``` ### 7.3 建议改进 **P2: 为 AgentTool trait 添加方法** ```rust pub trait AgentTool: Send + Sync { // ... 现有方法 ... /// 返回用于 auto-mode 分类器的精简摘要 fn classifier_summary(&self, args: &Value) -> String { format!("{}", self.name()) } /// 是否是只读操作(与并发安全不同——glob 是 readonly 但不能和 bash 并发) fn is_readonly(&self) -> bool { false } /// 是否需要延迟加载工具描述(大工具可延迟以减小 prompt) fn defer_loading(&self) -> bool { false } } ``` **P3: 工具 allow/deny 列表** 参考 Claude Code 的做法,AstroResearch 已有 `subagent_allowed_tools`,可扩展: ```rust // 为子代理/异步代理定义工具过滤策略 pub struct ToolFilterPolicy { /// 全局禁止(不计代理类型) pub all_agent_disallowed: Vec, /// 自定义代理禁用(不能 spawn 子代理 + 编辑文件的代理) pub custom_agent_disallowed: Vec, /// 异步代理白名单(只读子集) pub async_agent_allowed: Vec, } ``` --- ## 7. Memory 持久化 ### 8.1 对比 AstroResearch 与 Claude Code 在 Memory 设计上高度相似(都是文件系统 frontmatter markdown + `MEMORY.md` 索引),差距很小。 Claude Code 多了: - **Team Memory**: 共享给团队的记忆(AstroResearch 有 team 系统但无 team memory) - **Session Memory compaction**: 压缩时自动通过 LLM 提取记忆到文件 ### 8.2 建议改进 **P3: Session Memory Compaction** 压缩时自动提取记忆: ```rust /// 在 compact.rs 的 auto_compact 过程中提取 session memory pub async fn extract_session_memory( llm: &LlmClient, messages: &[ChatMessage], ) -> Vec { // 用专门的小 prompt 让 LLM 从对话中提取可持久化的记忆 // 返回候选记忆列表,由 MemoryManager 做 dedup + 衰减 } ``` --- ## 8. Coordinator / Multi-Agent ### 9.1 Claude Code 的 Coordinator Mode ``` Coordinator Mode 架构: ┌─────────────────────────────────────────────────┐ │ Coordinator (Coordinator System Prompt) │ │ Tools: Agent, SendMessage, TaskStop, │ │ SyntheticOutput (仅 4 个) │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Worker 1 │ │ Worker 2 │ │ Worker 3 │ │ │ │ (async) │ │ (async) │ │ (async) │ │ │ │ standard │ │ standard │ │ standard │ │ │ │ tools │ │ tools │ │ tools │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ Worker 结果以 返回 │ │ Coordinator 做 Synthesis → 下一轮 Workers │ └─────────────────────────────────────────────────┘ ``` ### 9.2 关键设计点 1. **Coordinator 只看到 4 个工具**——它不能直接读文件或执行 bash,只能编排 Workers 2. **Workers 全异步**——Coordinator 不等待,结果以 `` XML 注入 3. **Continue-vs-Spawn 决策矩阵**: - 新任务与已有 Worker 上下文重叠 <30% → 创建新 Worker - 新任务是对已有 Worker 的跟进 → `SendMessage` 继续 4. **Worker prompt 写法规范**:自包含(self-contained),包含完整 spec,明确交付物 ### 9.3 AstroResearch 的现状 AstroResearch 现已实现 Coordinator Mode(`src/agent/coordinator/`,2026-06-23), 包含 4 个 meta-tools(delegate_task / check_task / task_stop / synthesize) + WorkerPool + SubAgentRunner。Team 的平级通信仍然可用,Coordinator 提供层级编排。 ### 9.4 建议改进 **P2: Coordinator Mode — 已实现** ✅ ``` 实现架构: src/agent/coordinator/ ├── mod.rs # CoordinatorRuntime, CoordinatorConfig ├── tools.rs # 4 meta-tools: delegate_task, check_task, task_stop, synthesize ├── worker_pool.rs # WorkerPool: 异步 Worker 生命周期管理 └── runner.rs # SubAgentRunner: Worker 执行器 用户请求 → Coordinator 做任务分解 → 并行 Worker 执行 (delegate_task, async) → 结果综合 (synthesize) → 减少单 Agent 的步骤数和 token 消耗 关键实现: 1. Coordinator system prompt: 仅暴露 4 个 meta-tools,屏蔽文件/bash 操作 2. WorkerPool + SubAgentRunner: 异步并发 Worker 管理 3. 子代理结果以结构化格式注入 `` 4. 综合阶段由 Coordinator 的 synthesize 工具处理 ``` --- ## 9. Hermes-Agent 的独特贡献 ### 10.1 文件位置 `/home/fmq/program/AstroResearch/libs/hermes-agent/` ### 10.2 Hermes-Agent vs Claude Code 架构对比 | 关注点 | Hermes-Agent | Claude Code | |--------|-------------|-------------| | 语言 | Python 3.11+ | TypeScript (Node.js 20+) | | Agent 循环 | 同步 `while` 循环 | 异步 `query()` generator | | 工具注册 | 文件系统自动发现 (`tools/*.py`) | 手动 import + `getAllBaseTools()` | | 工具接口 | `handler(args) -> JSON string` | `Tool` — ~70 方法 | | 状态管理 | SQLite (SessionDB + FTS5) | 内存 `AppState` React store | | Plugin 系统 | PluginManager + 生命周期 hooks | Plugin loader + MCP 集成 | | Profile 隔离 | 多 profile + 独立 `HERMES_HOME` | 单 profile | | 子代理 | 子 `AIAgent` 实例 | `LocalAgentTask` + `runAgent()` | | Swarm/Team | Kanban 工作队列 | `InProcessTeammateTask` + coordinator | | 上下文压缩 | `ContextCompressor` | `compact/` 服务 | | MCP 支持 | `mcp_tool.py` + catalog | 完整的 `services/mcp/` | | 定位 | 个人 AI 助手(自我改进、记忆、跨平台) | 编程 AI 助手(终端集成、文件操作) | ### 10.3 Hermes-Agent 的核心架构 ``` hermes-agent/ ├── run_agent.py # AIAgent 类 (~11k LOC) — 核心入口 ├── model_tools.py # 工具编排层 (~2.7k LOC) ├── toolsets.py # 工具集定义 ├── hermes_state.py # SessionDB — SQLite + FTS5 ├── cli.py # HermesCLI 类 (~11k LOC) │ ├── agent/ # Agent 内部 │ ├── conversation_loop.py # 主循环 │ ├── turn_context.py # 每轮上下文 dataclass │ ├── system_prompt.py # 三层 System Prompt │ ├── prompt_builder.py # Prompt 片段构建 │ ├── memory_manager.py # 记忆编排 │ ├── context_compressor.py # 上下文压缩 │ ├── tool_executor.py # 工具执行分发 │ ├── tool_guardrails.py # 安全 guardrails │ └── curator.py # 后台 Skill 生命周期管理 │ ├── tools/ # 工具实现(自动发现) │ ├── registry.py # ToolRegistry(discover_builtin_tools) │ ├── delegate_tool.py # 子代理 spawn │ ├── skills_tool.py # Skill 管理 │ └── cronjob_tools.py # Cron 调度 │ └── hermes_cli/ # CLI 子系统 ├── plugins.py # PluginManager + 生命周期 hooks └── profiles.py # 多 Profile 隔离 ``` ### 10.4 最值得借鉴的 Hermes 特性 **Self-improving Skills** ``` 工作流: 1. Agent 在科研中反复使用某流程 (如: 搜索某类天体 → 下载论文 → RAG → 总结) 2. Agent 自动检测重复模式 3. Agent 创建 Skill 保存该流程 4. Curator 管理 Skill 生命周期 5. 下次相似查询直接加载 Skill,无需重新探索 AstroResearch 现已完整实现 Self-improving Skills(2026-06-22): - `skills/pattern_detector.rs` — 自动检测重复工具调用序列模式 - `skills/curator.rs` — Curator 管理 Skill 生命周期(质量评分、清理、pinned、seed_record、CuratorRunner) - `skills.rs: SkillCreator` — Agent 自主创建 SKILL.md 文件 - `skills.rs: SelfImprovePipeline` — 一站式管道(检测 → 创建 → 质量审查) ``` **Session FTS5 搜索** ```python # Hermes 的 SessionDB 使用 SQLite FTS5 实现跨 session 搜索 class SessionDB: def search_sessions(self, query: str) -> List[Session]: """全文本搜索所有历史会话""" return self.db.execute( "SELECT * FROM sessions WHERE sessions MATCH ?", (query,) ) ``` AstroResearch 现已实现 FTS5 全文搜索(2026-06-23): - `agent_sessions_fts` + `agent_messages_fts` SQLite FTS5 虚拟表 - `search_history` Agent 工具提供跨会话全文本搜索能力 ### 10.5 实施成果 **P2: Self-improving Skills — 已实现** ✅ ``` 1. Pattern Detector (自动检测) ✅ - src/agent/skills/pattern_detector.rs — 子序列匹配识别重复工具调用模式 - 阈值: 3 次相似序列 → 候选 Skill 2. Skill Creator (Agent 自主创建) ✅ - src/agent/skills.rs: SkillCreator — 生成 SKILL.md 文件(kebab-case 命名 + YAML frontmatter) - src/agent/skills.rs: SelfImprovePipeline — 一站式管道(检测 → 创建 → 审查) 3. Curator (管理生命周期) ✅ - src/agent/skills/curator.rs — 质量评分、清理候选、pinned 保护 - seed_record + NEW_SKILL_GRACE_PERIOD_DAYS=7 — 新 Skill 锚定时钟 - CuratorRunner — 后台空闲触发审查(paused/idle/interval 三重检查) ``` --- ## 10. 优先级排序 —— 建议实施路线 按价值/投入比排序: | 优先级 | 改进项 | 来源 | 状态 | 价值 | 预估投入 | 依赖 | |--------|--------|------|------|------|---------|------| | **P0** | Context Overflow 自动修复 | Claude Code | ✅ | 减少 ~50% LLM 调用失败 | ~30 行 | 无 | | **P0** | StreamingExecutor 真正的流式调度 | Claude Code | ✅ | 减少 30-50% 工具执行延迟 | ~200 行 | 无 | | **P0** | Executor 集成分区器(批次串行/并行) | Claude Code | ✅ | 修复非安全工具错误并发 | ~300 行 | ToolPartitioner | | **P1** | 工具并发分区 `partition_tool_calls` | Claude Code | ✅ | 批量只读操作 3-5x 加速 | ~100 行 | 无 | | **P1** | PermissionRequest / PermissionDenied Hook 事件 | Claude Code | ✅ | 安全审计能力 | ~100 行 | 无 | | **P1** | Auto-mode Classifier(廉价模型预分类) | Claude Code | ⏳ | 消除 80%+ 权限弹窗 | ~300 行 | LLM client 支持 | | **P2** | Self-improving Skills(Agent 保存成功流程) | Hermes | ✅ | 科研场景独特价值 | ~500 行 | Skills 系统 | | **P2** | Coordinator Mode(层级多 Agent 编排) | Claude Code | ✅ | 复杂任务效果提升 | ~800 行 | SubAgent + Team | | **P2** | UserPromptSubmit / PreCompact / PostCompact Hook | Claude Code | ✅ | Hook 系统完善 | ~200 行 | 无 | | **P3** | FTS5 跨 session 搜索 | Hermes | ✅ | 历史研究可复用 | 中 | SQLite 迁移 | | **P3** | Tool `defer_loading` / `classifier_summary` | Claude Code | ✅ | 减小 tool schema prompt | ~50 行 | 无 | | **P3** | 模型回退策略 (Model Fallback) | Claude Code | ✅ | 提高可用性 | ~200 行 | ErrorRecovery | | **P3** | Session Memory Compaction | Claude Code | ✅ | 自动化记忆提取 | ~300 行 | MemoryManager + Compact | ### 实施进度(2026-06-22) 1. **P0 项 — 全部完成** ✅ - Context Overflow 自动修复(`error_recovery.rs`) - StreamingExecutor 真正流式调度(`streaming_executor.rs` 重写) - Executor 集成分区器(`executor.rs` Phase 3 重写) 2. **P1 项 — 部分完成** - ✅ 工具并发分区 - ✅ PermissionRequest / PermissionDenied Hook 事件 - ⏳ Auto-mode Classifier — 需要设计讨论 3. **P2 项 — 全部完成** ✅(2026-06-23) - ✅ Coordinator Mode(`src/agent/coordinator/`: 4 meta-tools + WorkerPool + SubAgentRunner) - ✅ UserPromptSubmit Hook Event(第 13 个生命周期事件) 4. **P3 项 — 全部完成** ✅(2026-06-23) - ✅ FTS5 跨会话搜索(`agent_sessions_fts` + `agent_messages_fts` + `search_history` 工具) - ✅ Tool defer_loading / classifier_summary - ✅ 模型回退策略(`LLM_FALLBACK_MODEL` / `LLM_FALLBACK_CHAIN`) - ✅ Session Memory Compaction Bridge(`extract_memories_from_compaction`) --- ## 附录 A: Claude Code 关键源码索引 | 文件 | 用途 | 与 AstroResearch 对应 | |------|------|----------------------| | `src/Tool.ts` | Tool 类型 + buildTool factory | `src/agent/tools/mod.rs` | | `src/tools.ts` | 工具注册 + assembleToolPool | `ToolRegistry::new()` | | `src/services/tools/toolExecution.ts` | 工具执行管道 | `executor.rs` | | `src/services/tools/toolOrchestration.ts` | 并发分区 + 批量执行 | `partitioner.rs` + `executor.rs` | | `src/services/tools/StreamingToolExecutor.ts` | 流式工具执行 | `streaming_executor.rs` | | `src/services/api/withRetry.ts` | 错误重试 + 退避 | `error_recovery.rs` | | `src/services/api/claude.ts` | API 流式调用 | `streaming.rs` | | `src/constants/prompts.ts` | System Prompt 构建 | `system_prompt.rs` | | `src/utils/hooks.ts` | Hook 执行引擎 (5022 行) | `hooks/dispatch.rs` | | `src/utils/permissions/permissions.ts` | 权限逻辑 | `permission.rs` | | `src/utils/permissions/yoloClassifier.ts` | Auto-mode 分类器 | 无 (建议新增) | | `src/tools/AgentTool/runAgent.ts` | 子代理执行引擎 | `subagent.rs` | | `src/tools/AgentTool/AgentTool.tsx` | 子代理编排 | `tools/subagent.rs` | | `src/coordinator/coordinatorMode.ts` | Coordinator 模式 | 无 (建议参考) | | `src/memdir/memdir.ts` | Memory 文件系统 | `memory/mod.rs` | | `src/skills/loadSkillsDir.ts` | Skill 加载 | `skills.rs` | ## 附录 B: Hermes-Agent 关键源码索引 | 文件 | 用途 | 与 AstroResearch 对应 | |------|------|----------------------| | `run_agent.py` | AIAgent 核心类 | `runtime/mod.rs` | | `agent/conversation_loop.py` | Agent 主循环 | `runtime/mod.rs` (ReAct loop) | | `agent/system_prompt.py` | 三层 System Prompt | `system_prompt.rs` | | `agent/context_compressor.py` | 上下文压缩 | `compact.rs` | | `agent/memory_manager.py` | 记忆编排 | `memory/mod.rs` | | `agent/curator.py` | Skill 生命周期管理 | 无 (建议参考) | | `tools/registry.py` | 工具自动发现 | `tools/mod.rs` | | `tools/delegate_tool.py` | 子代理 | `subagent.rs` | | `hermes_state.py` | SessionDB + FTS5 | `api/agent.rs` (sessions) | | `hermes_cli/plugins.py` | PluginManager | 无 | | `hermes_cli/profiles.py` | 多 Profile 隔离 | 无 | | `model_tools.py` | 工具编排 | `executor.rs` | ## 附录 C: 变更日志 ### 2026-06-22 — 首轮实施 **P0: Context Overflow 自动修复** - `src/agent/runtime/error_recovery.rs`: +150 行 - 新增 `ContextOverflowInfo`、`parse_context_overflow()`、`calculate_safe_max_tokens()` - 新增 `RecoveryStep::AdjustMaxTokens`、`extract_three_numbers()` - 12 个新增测试(Anthropic/OpenAI/Generic 格式 + 边界 + 恢复优先级) - `src/agent/runtime/mod.rs`: AgentRuntime 集成调用点 - `Cargo.lock`: 无新增依赖(使用已有 `regex` crate) **P0: StreamingExecutor 真正流式调度** - `src/agent/runtime/streaming_executor.rs`: 重写 ~400 行(原 316 行) - `on_tool_use` 中对并发安全工具立即 `tokio::spawn` - `tokio::select!` 在工具执行和 Sibling Abort 之间竞速 - `collect_completed_tasks()` 使用 `JoinHandle::is_finished()` 非阻塞检查 - `executing_non_concurrent` 标志实现独占执行 - `src/agent/tools/mod.rs`: `ToolContext` 添加 `Clone` derive **P0: Executor 集成分区器** - `src/agent/runtime/executor.rs`: Phase 3 重写 + 2 个提取函数 - Phase 3a: 构建非拒绝工具的 (原索引, PreparedCall) 映射 - Phase 3b: `ToolPartitioner::partition()` 分区 - Phase 3c: 逐批次执行(并行批次 `FuturesUnordered`,串行批次逐个执行) - 提取 `execute_single_tool()` 和 `process_single_result()` 辅助函数 - `src/agent/runtime/partitioner.rs`: +2 测试(`run_bash`、`file_write` 打断并发批) **P1: PermissionRequest / PermissionDenied Hook 事件** - `src/agent/hooks/types.rs`: +80 行 - 新增 `HookEvent::PermissionRequest`、`HookEvent::PermissionDenied` - 新增 `PermissionRequestContext`、`PermissionDeniedContext` - 新增 `PermissionRequestAction`、`PermissionDecision`、`PermissionDenialSource` - `src/agent/hooks/traits.rs`: +20 行 - `AgentHook::on_permission_request()`、`AgentHook::on_permission_denied()` - `src/agent/hooks/dispatch.rs`: +120 行 - `run_on_permission_request()` (并行调用,第一个 Override 生效) - `run_on_permission_denied()` (fire-and-forget 审计) - `src/agent/hooks/mod.rs`: 更新 re-exports ### 2026-06-22 — Self-improving Skills **P2: Self-improving Skills(模式检测 + 自动创建 + Curator)** - `src/agent/skills/pattern_detector.rs`: +420 行 - `PatternDetector` — 从 `agent_messages` DB 表扫描工具调用序列 - `DetectedPattern` — 跨 session 重复模式(携带出现次数、置信度、指纹) - 滑动窗口子序列提取 + Jaccard 相似度去重 + 超序列包含检测 - 8 个单元测试(子序列提取、指纹、去重、Jaccard 计算) - `src/agent/skills/curator.rs`: +700 行 - `Curator` — Skill 生命周期管理(Active → Inactive → Stale → Deprecated) - `SkillQuality` — 基于调用次数和新鲜度的质量评分(对数 + 指数衰减) - `CuratorReport` — 分析报告 + 清理建议列表 - `archive_stale_skills()` — 将过期 skill 移动到归档目录 - `CuratorRunner` — 后台空闲触发审查(`should_run_now()` + `record_activity()` 心跳) - 12 个单元测试(5 种生命周期状态 + 质量评分 + 清理候选 + pinned + runner) - `src/agent/skills.rs`: +230 行 - `SkillCreator` — 将 `DetectedPattern` 转为 SKILL.md 文件(kebab-case 命名 + YAML frontmatter) - `SelfImprovePipeline` — 一站式管道(检测 → 创建 → 质量审查) - `SelfImproveResult` — 管道结果(patterns_found + skills_created + curator_report) - `SkillFrontmatter` + `SkillMeta` 增加 `pinned` 字段 ### 2026-06-22 — Hermes Curator 特性补齐 **Pinned Skills(不可清理)** - `src/agent/skills.rs`: `SkillFrontmatter.pinned` + `SkillMeta.pinned` — YAML `pinned: true` - `src/agent/skills/curator.rs`: `evaluate_quality(pinned)` — 强制 Active + min_score 0.8;`analyze` 过滤 pinned 不进入 cleanup_candidates **Seed Record(新 Skill 锚定时钟)** - `src/agent/skills/curator.rs`: `evaluate_quality` 对无统计记录 skill 设置 `days_since_last_use=Some(0)`(等效刚创建),`NEW_SKILL_GRACE_PERIOD_DAYS=7` 防止立即 stale **CuratorRunner(后台空闲触发审查)** - `src/agent/skills/curator.rs`: `CuratorRunner` 结构体 + `should_run_now()`(paused/idle/interval 三重检查)+ `record_activity()` 心跳 + `run_once()` + `spawn()` tokio 后台任务 + `pause()`/`resume()` - 5 个新增测试(pinned_always_active、pinned_not_in_cleanup、seed_record、runner_paused、runner_idle) ### 2026-06-23 — Phase 6: Coordinator Mode + UserPromptSubmit Hook **Coordinator Mode 协调者模式** - `src/agent/coordinator/`: 新目录,4 个 meta-tools(delegate_task / check_task / task_stop / synthesize)+ WorkerPool + SubAgentRunner - Coordinator system prompt 层级编排 Workers(仅暴露 4 个管理工具,不暴露文件/bash) - Workers 全异步执行,结果以结构化格式注入 Coordinator - Continue-vs-Spawn 决策矩阵(上下文重叠度 <30% → 新 Worker) **UserPromptSubmit Hook Event** - `src/agent/hooks/types.rs`: 新增 `UserPromptSubmit` variant(第 13 个生命周期事件) - `src/agent/hooks/dispatch.rs`: `dispatch()` 新增事件分派 ### 2026-06-23 — Phase 7: P3 优化 **Tool defer_loading / classifier_summary** - `src/agent/tools/mod.rs`: `ToolDef.defer_loading` 字段 — LLM 初次调用时不发送完整 schema,仅发送 summary;Bash/Read 工具标记 defer_loading **Model Fallback 模型回退策略** - `src/agent/runtime/error_recovery.rs`: `LLM_FALLBACK_MODEL` + `LLM_FALLBACK_CHAIN` env vars — 主模型故障时自动回退到备选模型链 **Session Memory Compaction Bridge** - `src/agent/memory/mod.rs`: `extract_memories_from_compaction()` — 在 compaction 自动摘要后从摘要文本提取记忆写入 MemoryManager **FTS5 跨会话搜索** - `agent_sessions_fts` + `agent_messages_fts` SQLite FTS5 虚拟表 - `search_history` Agent 工具 — 全文本搜索历史会话和消息