Talegorithm hai 2 días
pai
achega
47baefc131
Modificáronse 1 ficheiros con 467 adicións e 0 borrados
  1. 467 0
      agent/docs/comparison-with-claude-code.md

+ 467 - 0
agent/docs/comparison-with-claude-code.md

@@ -0,0 +1,467 @@
+# Agent 架构对比:Cyber Agent vs Claude Code
+
+> 对比 **Cyber Agent**(本项目)与 **Claude Code v2.1.88**(非官方重建,仅供研究)的架构设计异同,目标是找到可借鉴的设计思路,以及两者各自的取舍。
+
+---
+
+## 总览
+
+| 维度 | Cyber Agent | Claude Code |
+|------|-------------|-------------|
+| **语言/运行时** | Python / asyncio | TypeScript / Bun + Node.js |
+| **定位** | 嵌入式 Agent 框架,供程序集成调用 | 面向开发者的交互式 CLI 工具 |
+| **LLM 接入** | 多 Provider(OpenRouter / Gemini / Anthropic 等) | 仅 Claude API |
+| **持久化** | 文件系统(JSONL + JSON),消息树结构 | 内存中维护会话,JSONL 转录为副产品 |
+| **多 Agent** | 递归子 Trace,独立持久化,可跨设备 | Coordinator-Worker,内存中,不持久化 |
+| **计划管理** | 原生 GoalTree(结构化、持久化、周期注入) | 无原生计划结构(TodoWriteTool 扁平备忘录) |
+| **记忆层次** | 三层(Trace / Knowledge / Skill),Agent 主动写入 | 二层(CLAUDE.md / 历史压缩),人工维护 |
+| **权限系统** | 预设白/黑名单(工具级) | 规则引擎(参数级 glob 匹配 + 交互审批) |
+| **可观测性** | REST + WebSocket,结构化事件流 | 终端 UI + OpenTelemetry,无外部 API |
+| **UI 层** | 无终端 UI | 自研 Ink 终端框架(251KB) |
+
+---
+
+## 核心结构类比
+
+```
+Cyber Agent              Claude Code
+───────────────────      ───────────────────────
+Trace                ↔   QueryEngine          (执行容器)
+AgentRunner.loop     ↔   queryLoop            (while true 循环)
+FileSystemTraceStore ↔   recordTranscript     (持久化)
+GoalTree             ↔   TodoWriteTool        (计划管理,差距显著)
+KnowHub + Reflect    ↔   CLAUDE.md            (跨任务记忆,差距显著)
+```
+
+---
+
+## 一、执行容器:Trace vs QueryEngine
+
+两者都是"单次执行会话"的容器,跨 turn 维护消息历史和统计数据。
+
+| 维度 | Trace | QueryEngine |
+|------|-------|-------------|
+| **生命周期** | 持久化到文件系统 | 内存中,session 结束消失 |
+| **消息结构** | 消息树(`parent_sequence`,支持 Rewind) | 线性数组 `Message[]` |
+| **显式状态** | `running / completed / failed / stopped` | 无 |
+| **计划结构** | GoalTree(持久化,周期注入) | 无 |
+| **唯一标识** | `trace_id`(UUID,可跨设备引用) | 无专用 ID |
+| **子执行单元** | 所有子 Agent 都是 Trace,结构统一 | AgentTool 各自独立,无统一模型 |
+| **记忆去重** | `head_sequence` 管理主路径,消息树自动过滤 | `loadedNestedMemoryPaths` 防止 CLAUDE.md 重复注入 |
+
+`loadedNestedMemoryPaths` 和 `head_sequence` 解决了相似的问题(防止重复处理),但层次完全不同:前者是内容级去重,后者是结构级的消息主路径管理。
+
+**核心差异**:Cyber Agent 把 Agent 执行视为持久化的、可被外部观测的**任务**;Claude Code 更偏向交互式**会话**,持久化是副产品而非一等公民。
+
+---
+
+## 二、Agent 循环:AgentRunner.loop vs queryLoop
+
+两者都是 `while true` → 调 LLM → 执行工具 → 继续 的循环,但在五个维度上有实质差异。
+
+### 2.1 循环状态的管理方式
+
+queryLoop 用一个**整体替换**的 `State` 对象管理跨迭代状态,所有 `continue` 点都是 `state = { ...newState }`:
+
+```typescript
+// queryLoop 的每个 continue 点——必须声明完整的下一轮状态
+state = {
+  messages: [...messagesForQuery, ...assistantMessages, recoveryMessage],
+  maxOutputTokensRecoveryCount: maxOutputTokensRecoveryCount + 1,
+  hasAttemptedReactiveCompact,   // 显式保留
+  maxOutputTokensOverride: undefined,  // 显式重置
+  pendingToolUseSummary: undefined,    // 显式重置
+  stopHookActive,
+  turnCount,
+  transition: { reason: 'max_output_tokens_recovery', attempt: 2 },
+}
+continue
+```
+
+这带来三个好处:
+
+1. **消灭"隐式携带"bug**:每个 continue 点必须声明每个字段,想沿用旧值也要显式写出来,不可能因为"忘了重置"而静默出错。
+2. **每个 continue 路径自描述**:不需要追踪前面的赋值历史,任意找一个 continue 块就能知道下一轮的完整状态。
+3. **`transition` 字段:零成本可观测性**:记录每次 continue 的原因(源码注释明说是专为测试设计的):
+
+```typescript
+transition: { reason: 'next_turn' }
+transition: { reason: 'max_output_tokens_recovery', attempt: 2 }
+transition: { reason: 'reactive_compact_retry' }
+transition: { reason: 'stop_hook_blocking' }
+transition: { reason: 'collapse_drain_retry' }
+```
+
+测试可以直接断言 `state.transition.reason === 'reactive_compact_retry'`,而不必解析消息内容推断"压缩是否发生了"。**这个字段也是天然的 debug 信息**:任何时候 dump 出 state 就能知道循环目前处于哪个恢复阶段。
+
+注意:`state.messages` **不是** API payload。实际发给 API 的是 `prependUserContext(messagesForQuery, userContext)`,其中 `messagesForQuery` 是 `state.messages` 经过多层变换(compact 边界过滤 → 工具结果截断 → microcompact → autocompact)后的结果。State 本身不落盘,只有 queryLoop yield 出来的 Message 才被 QueryEngine 记录到 transcript。
+
+AgentRunner 当前直接在迭代内修改变量,没有这个整体替换的抽象。
+
+### 2.2 工具执行时机(最大差异)
+
+queryLoop 有 `StreamingToolExecutor`(feature gate),工具在模型**还在流式输出期间**就并发开始执行:
+
+```
+模型流式输出:  [tool1 完整] ── [tool2 完整] ── [tool3 完整] ── 流结束
+StreamingExecutor: └→ 立即开始执行  └→ 立即开始执行  └→ 立即开始执行
+                        ↓ 执行完立即 yield 结果,不等流结束
+```
+
+工具执行时间被完全"藏"在模型输出时间里。AgentRunner 等 LLM response 完整后才执行工具。
+
+### 2.3 循环内多层恢复路径
+
+queryLoop 内置了多条恢复路径,全部通过 `state = next; continue` 在**循环内**动态触发:
+
+```
+prompt_too_long → 1. context_collapse drain(轻量,清空 staged collapses)
+               → 2. reactive compact(重新压缩,LLM 调用)
+               → 失败 → 暴露错误,return
+
+max_output_tokens → 1. 升级到 64k(maxOutputTokensOverride,一次机会)
+                 → 2. 多轮文本恢复(最多 3 次,注入 meta 消息)
+                 → 3. 耗尽 → 暴露错误,return
+
+模型降级(FallbackTriggeredError)→ 切换 fallbackModel,丢弃已有输出,重试
+
+stop hook blocking → 注入 hook 错误消息,continue
+```
+
+AgentRunner 的恢复(`_heal_orphaned_tool_calls`)发生在进入循环**之前**(`_build_history` 阶段),不是循环内的动态恢复。
+
+### 2.4 周期性上下文注入
+
+AgentRunner **主动、周期性**注入 GoalTree + Collaborators:
+```python
+if iteration % 10 == 0:
+    inject_context(goal_tree, collaborators)
+```
+
+queryLoop 的记忆是**被动消费**的:`startRelevantMemoryPrefetch` 在每轮开头触发异步预取,settled 且本轮尚未消费时才注入为 attachment。没有强制周期,也没有计划结构注入。
+
+### 2.5 Hooks:外部介入点
+
+这是两个系统差距最大的维度之一。
+
+**Cyber Agent `context_hooks`**:每 10 轮调用一次,返回 markdown 字符串注入为上下文。功能是**只读注入**,无法阻断或修改任何事物。
+
+**CC hooks**:覆盖 25+ 事件,三种执行模式(shell / HTTP / TypeScript 回调),每个事件有专用的双向契约:
+
+| 维度 | Cyber Agent `context_hooks` | CC hooks |
+|------|---------------------------|---------|
+| **事件数量** | 1(周期注入) | 25+(全生命周期) |
+| **工具生命周期** | 无 | PreToolUse / PostToolUse / PostToolUseFailure / PermissionDenied |
+| **loop 控制** | 无 | Stop hook block → `stopHookActive=true` → 强制 continue |
+| **修改输入/输出** | 无 | PreToolUse 改 toolInput;PostToolUse 改 MCP 输出 |
+| **阻断执行** | 无 | PreToolUse deny;PostToolUse preventContinuation |
+| **执行模式** | Python 函数 | shell / HTTP / TypeScript callback / postSampling |
+| **会话级注册** | 随 AgentRunner 传入 | `addFunctionHook()`,Map-based,O(1),高并发友好 |
+
+三个最重要的 hook 事件在 loop 上下文里:
+
+- **PreToolUse**:在权限检查之前调用,可 `allow`/`deny`/`ask` + 修改 toolInput。允许外部系统做"无人值守的审批代理",比交互弹窗更适合自主运行场景。
+- **Stop hook**:每轮结束时调用,若返回 block,则 `state.transition = 'stop_hook_blocking'`,loop 强制再 continue 一轮。这是"外部系统驱动 Agent 继续工作"的接入点。
+- **UserPromptSubmit**:用户消息进队列时调用,可注入 `additionalContext` 或改写消息本体。比 `context_hooks` 的定时注入更精确(每次用户输入时触发,而非每 10 轮)。
+
+### 2.6 工具摘要的异步隐藏
+
+queryLoop 在工具执行完毕后 fire-and-forget 一个 Haiku 摘要任务,**不等它**,Promise 存入 `nextPendingToolUseSummary`,下一轮迭代开头才 await:
+
+```typescript
+// 工具执行完毕后立即触发(不阻塞当前轮)
+nextPendingToolUseSummary = generateToolUseSummary({...})
+
+// 下一轮迭代开头取结果——此时 Haiku ~1s 早已完成
+const summary = await pendingToolUseSummary
+```
+
+Haiku 摘要的延迟被下一轮 5-30s 的 API 调用时间完全吸收。AgentRunner 没有对应机制。
+
+---
+
+## 三、持久化与消息结构
+
+### Cyber Agent:消息树(非破坏性)
+
+每条 Message 有 `sequence`(全局递增)和 `parent_sequence`,构成树结构:
+
+```
+正常执行:   1 → 2 → 3 → 4 → 5
+Rewind 到3:             3 → 6 → 7    (4,5 自动脱离主路径)
+压缩 1-3:   8(summary,parent=None) → 6 → 7
+侧分支:     5 → 6(reflection) → 7   (不在主路径)
+             5 → 8(summary, 主路径)
+```
+
+`trace.head_sequence` 始终指向主路径头,`build_llm_messages` 沿链回溯,侧分支自动被过滤。所有历史永久保留,Rewind 是非破坏性操作。
+
+### Claude Code:线性历史(有损压缩)
+
+消息以数组形式存在内存中,转录文件是 append-only JSONL。没有树结构,压缩是破坏性的(原始消息不再恢复)。QueryEngine 维护完整的 `mutableMessages`,queryLoop 内的 `state.messages` 在压缩后被替换为压缩后版本。
+
+**关键差异**:Cyber Agent 是非破坏性时间旅行;Claude Code 是有损折叠。代价是 Cyber Agent 存储开销更高,查询需要沿链回溯。
+
+---
+
+## 四、计划管理
+
+### Cyber Agent:原生 GoalTree
+
+GoalTree 是一等公民,有独立数据模型(`Goal`)、专用工具(`goal`)、持久化(`goal.json`)和周期注入机制:
+
+```
+1. [in_progress] 分析代码架构
+   1.1. [completed] 读取项目结构
+   1.2. [in_progress] 分析核心模块
+        1.2.1. [pending] 分析 runner.py
+        1.2.2. [pending] 分析 tool_registry.py
+```
+
+- Goal 与 Message 关联(`msg.goal_id`),压缩以 Goal 为粒度
+- 每 10 轮自动注入,模型始终知道自己在做什么
+- 支持 `focus` / `done`(附 summary)/ `abandon`(附原因)
+
+### Claude Code:TodoWriteTool(扁平备忘录)
+
+扁平的待办列表,markdown 文本,格式由模型自行决定。无层级结构,无与消息的关联,不跨 session 持久化,不参与压缩粒度决策。
+
+**结论**:这是两个系统差距最大的维度之一。GoalTree 是架构级方案,TodoWriteTool 是临时补丁。
+
+---
+
+## 五、记忆系统
+
+### Cyber Agent:三层记忆,Agent 主动写入
+
+```
+Layer 3: Skills(技能库)
+  Markdown 文件,领域知识和操作规范,启动时注入 system prompt
+        ▲ 归纳
+Layer 2: Knowledge(知识库)
+  数据库 + 向量索引(KnowHub),语义检索按需注入
+        ▲ 提取(Reflect 机制)
+Layer 1: Trace(任务状态)
+  当前任务的工作记忆:Messages + GoalTree
+```
+
+- **Reflect**:执行完成后触发侧分支 Agent,分析历史,调用 `knowledge_save` 结构化入库
+- **跨任务学习**:知识从一个 Trace 提取后,下一个 Trace 可语义检索复用
+
+### Claude Code:二层记忆,人工维护
+
+```
+Layer 2: CLAUDE.md(持久指令)
+  项目/用户级 Markdown,自动发现(目录树遍历),注入 system prompt
+
+Layer 1: Session 历史(工作记忆)
+  当前对话历史(内存),超长时自动压缩折叠
+```
+
+跨 session 保留的内容只有写入 CLAUDE.md 的部分,Agent 本身不会主动提炼知识。
+
+### 记忆组织轴的根本差异
+
+| | Claude Code | Cyber Agent |
+|--|-------------|-------------|
+| **组织轴** | 人为定义的实体(用户、项目) | 执行本身涌现的语义主题 |
+| **边界划定者** | 人(目录结构、项目边界) | Agent(`type` + `tags` + `scopes`) |
+| **谁来写记忆** | 人(或由 Claude 辅助人写 CLAUDE.md) | Agent 自身(Reflect 触发后主动入库) |
+
+Claude Code 的记忆是**静态附加的上下文**,边界由人预先划定。Cyber Agent 的记忆可以从**执行本身涌现**,围绕"自主执行的任务"或"跨任务的全局线索"(如某类 bug 的修复模式)自然积累。
+
+---
+
+## 六、上下文压缩
+
+### Cyber Agent:两级压缩 + 侧分支(非破坏性)
+
+**Level 1(Goal 完成压缩,零 LLM 成本)**:以 Goal 为粒度,completed goal 的消息折叠为 `long_term_memory` 摘要,确定性,无额外 API 调用。
+
+**Level 2(LLM 侧分支压缩)**:`POST /compact` 触发,在 Trace 末尾创建 `branch_type="compression"` 侧分支,压缩结果作为 summary 消息插入主路径。原始消息保留在侧分支,可审计。
+
+控制参数:`RunConfig(goal_compression="none"|"on_complete"|"on_overflow")`
+
+### Claude Code:多层被动触发(有损)
+
+每轮迭代前依次经过:`HISTORY_SNIP` → `microcompact` → `CONTEXT_COLLAPSE` → `autocompact`(token 接近阈值时触发)。触发后用摘要模型折叠历史,原始消息丢失。`prompt_too_long` 错误时进入 reactive compact(最后手段)。
+
+| 方面 | Cyber Agent | Claude Code |
+|------|-------------|-------------|
+| 压缩粒度 | Goal 级(语义边界) | 全量历史折叠 |
+| 压缩成本 | Level 1 零成本;Level 2 LLM 成本 | 始终有 LLM 成本 |
+| 压缩可逆性 | ✅ 侧分支,原始消息保留 | ❌ 有损折叠,原始丢失 |
+| 触发时机 | 主动(on_complete / on_overflow) | 被动(超限后)+ 手动 |
+
+---
+
+## 七、多 Agent 协作
+
+### Cyber Agent:递归 Trace + 跨设备协议
+
+```
+主 Agent(Trace A)
+    ├── agent(task="研究X")           → 子 Trace B(独立持久化,可单独续跑)
+    │    └── agent(task="分析子模块") → 子 Trace C(递归)
+    └── agent(agent_url="https://remote/", task="...")
+         → 远程 Trace(agent://remote/xxx,跨设备)
+```
+
+- **explore 模式**:`task: List[str]` 触发 `asyncio.gather()` 并行多 Agent
+- **evaluate 工具**:专用评估 Agent,从 GoalTree 自动注入评估标准
+- **续跑子 Agent**:`agent(continue_from=sub_trace_id)` 可续跑被中断的子 Agent
+
+### Claude Code:Coordinator-Worker(内存中)
+
+```
+Coordinator Agent
+    ├── AgentTool(subagent_type="worker") → Worker 1(内存,非持久化)
+    ├── AgentTool(subagent_type="worker") → Worker 2
+    └── SendMessageTool(to=agent_id)      → 向活跃 Worker 发消息
+```
+
+Worker 以 `<task-notification>` XML 上报状态,通过 `SendMessageTool` 持续对话。
+
+| 方面 | Cyber Agent | Claude Code |
+|------|-------------|-------------|
+| 子 Agent 持久化 | ✅ 独立 Trace | ❌ 内存中 |
+| 续跑子 Agent | ✅ `continue_from` | ✅ `SendMessageTool` |
+| 跨设备协作 | ✅ `agent_url` + 远程 Trace ID | ❌ 不支持 |
+| 并行执行 | ✅ explore 模式 | ✅ 多 Worker 并行 |
+| 评估反馈循环 | ✅ evaluate 工具 | ❌ 无原生评估工具 |
+
+---
+
+## 八、工具系统
+
+### 工具定义
+
+**Cyber Agent(装饰器,轻量):**
+```python
+@tool(description="执行 shell 命令")
+async def bash(command: str, ctx: ToolContext) -> ToolResult:
+    return ToolResult(
+        output=result.stdout,
+        long_term_memory=f"Ran: {command}",  # 压缩后保留的摘要
+    )
+```
+
+**Claude Code(接口,功能丰富):** 每个工具实现约 15 个方法:`call`、`description`、`checkPermissions`、`isReadOnly`、`isConcurrencySafe`、`prompt`(注入 system prompt 的说明)、`renderToolResultMessage`(UI 渲染)等。接口更重,但权限检查、并发安全标记、进度报告、UI 渲染都内置其中。
+
+### ToolResult 双层记忆(Cyber Agent 特有)
+
+```python
+ToolResult(
+    output="<10K tokens 完整内容>",      # 第一次给 LLM 完整内容
+    long_term_memory="提取了 10000 字符", # 之后只看摘要
+    include_output_only_once=True
+)
+```
+
+大输出只在首次注入完整内容,后续轮次自动替换为摘要,有效节约 context window。Claude Code 没有对应机制。
+
+### Bash 安全(Claude Code 更精细)
+
+Cyber Agent 通过 `AgentPreset.denied_tools` 黑名单控制,粒度是整个工具。
+
+Claude Code 有独立的 102KB 安全分析器(`bashSecurity.ts`):
+- 命令语义分析(参数级,不只是工具名匹配)
+- 路径白名单(工作目录 + 额外允许目录)
+- 破坏性命令检测(rm -rf, dd, mkfs 等)
+- 模式匹配规则:`"Bash(git *)"` 自动允许所有 git 命令
+
+---
+
+## 九、权限系统
+
+### Cyber Agent:静态预设(工具级)
+
+```python
+AgentPreset(
+    allowed_tools=["read", "glob", "grep"],
+    denied_tools=["write", "edit", "bash"],
+)
+```
+
+工具级粒度,静态配置,无动态审批。适合离线/批量 Agent 场景。
+
+### Claude Code:规则引擎(参数级)+ 交互审批
+
+- 规则格式:`"Bash(git *)"` 支持 glob 模式匹配到参数级
+- 三种规则:alwaysAllow / alwaysDeny / alwaysAsk
+- 权限模式:default(交互)/ auto(ML 分类器)/ bypass
+- **规则自动学习**:用户选择"始终允许"后自动写入配置,构建个性化规则库
+- 企业远程策略:通过 managed settings 下发权限规则
+
+适合面向开发者的交互式场景。
+
+---
+
+## 十、可观测性
+
+### Cyber Agent:结构化事件流(服务视角)
+
+- **WebSocket** `/api/traces/{id}/watch`:实时推送所有 Message 事件
+- **REST API**:查询 Trace、Messages(main_path / all)、GoalTree
+- **GoalTree 统计**:每个 Goal 有 `self_stats` 和 `cumulative_stats`(token、cost、duration)
+- **全历史可查**:包括 rewind 旧路径、侧分支
+
+### Claude Code:终端 UI + 遥测(工具视角)
+
+- **Ink 终端 UI**:实时 spinner、CoordinatorTaskPanel
+- **OpenTelemetry**:结构化日志(懒加载)
+- **无外部 API**:不暴露 HTTP 接口
+
+**关键差异**:Cyber Agent 从架构上是**服务**,天然可集成监控;Claude Code 是**工具**,可观测性服务于操作者自己。
+
+---
+
+## 总结:差异与互补
+
+### Cyber Agent 的架构优势
+
+| 优势 | 价值 |
+|------|------|
+| **消息树 + Rewind** | 非破坏性时间旅行,支持回溯,全历史可审计 |
+| **GoalTree** | 结构化计划,与消息关联,驱动细粒度压缩 |
+| **Knowledge + Reflect** | 跨任务知识积累,Agent 主动从经验中学习 |
+| **记忆组织轴** | 围绕执行语义积累,不依赖人为划定边界 |
+| **evaluate 工具** | 内置评估-反馈循环,Agent 可自我校正 |
+| **ToolResult 双层记忆** | 精细的 context 节约机制 |
+| **跨设备 Agent 协作** | 分布式 Agent 网络,协议级支持 |
+| **Context Injection Hooks** | 灵活的外部事件注入(A2A IM、监控告警等) |
+| **服务化 API** | REST + WebSocket,天然可集成、可观测 |
+
+### 值得从 Claude Code 借鉴的设计
+
+| 设计 | 价值 |
+|------|------|
+| **Loop State 整体替换 + transition 字段** | 消灭"隐式携带"bug;transition 记录每次 continue 的原因,可用于测试断言和 debug,扩展后也可通过 WebSocket 推出去实现循环级可观测性 |
+| **流式工具并发执行** | 工具在模型流式输出期间就开始执行,延迟藏在模型输出时间里 |
+| **循环内多层恢复路径** | prompt_too_long / max_tokens / 模型降级等错误在循环内动态恢复,无需重启 |
+| **工具摘要异步隐藏** | Haiku 摘要在工具执行后 fire-and-forget,延迟藏在下一轮 API 调用时间里 |
+| **Bash 语义级安全分析** | 参数级权限控制,远比工具级黑名单精准,生产环境自主运行时重要 |
+| **ToolSearch 延迟加载** | 工具数量大时按需加载描述,节约 system prompt token |
+| **权限规则自动学习** | "始终允许"自动写入配置,构建个性化规则库 |
+| **工具生命周期 hooks(PreToolUse / PostToolUse)** | 在工具执行前后插入外部逻辑:审批代理(PreToolUse allow/deny)、MCP 输出改写(PostToolUse updatedMCPToolOutput)、失败后通知(PostToolUseFailure)。Cyber Agent 目前对工具执行无介入点 |
+| **Stop hook(loop 控制)** | 每轮结束时调用,可返回 block 强制 loop 再 continue 一轮(`transition='stop_hook_blocking'`)。这是"外部事件驱动 Agent 继续"的最直接接入点 |
+| **UserPromptSubmit hook** | 用户消息进队列时触发,可注入 `additionalContext` 或改写消息。比 `context_hooks` 定时注入更精确,也更适合做"收到外部信号时注入上下文"的触发器 |
+| **工具结果自动存档(toolResultStorage)** | 每个工具声明 `maxResultSizeChars`,超限时自动写入磁盘临时文件,API 收到 preview(前 2000 字节)+ 文件路径,模型可按需用 FileReadTool 读回完整内容。与 Cyber Agent 的 `long_term_memory`(手动摘要、原始内容丢弃)互补:这是零开发者工作量的兜底层,防止意外大输出撑爆 context,且原始内容可恢复 |
+
+---
+
+## 待办:值得引入的改进
+
+| 优先级 | 改进项 | 说明 |
+|--------|--------|------|
+| ★★★ | **Loop State 整体替换 + transition 字段** | 将 AgentRunner loop 的跨迭代变量收拢为一个整体替换的 State 对象;每个 continue 点声明完整下一轮状态,消灭"忘记重置某字段"的隐患。新增 `transition` 字段记录每次 continue 的原因(`tool_use` / `compressed` / `healed_orphan` 等),可直接用于测试断言,也可通过 WebSocket 推出去作为循环级可观测事件 |
+| ★★★ | **工具结果自动存档** | 每个工具声明 `max_result_size`(字符数),超限时自动写入临时文件,给模型 preview(前 N 字节)+ 文件路径,模型可用 `read` 工具读回完整内容。与现有 `long_term_memory`(开发者手写精炼摘要)互补:这是零开发者工作量的兜底层,防止 `bash` 大输出、`webfetch` 整页 HTML 等意外撑爆 context |
+| ★★☆ | **工具并发执行** | 单次 LLM 响应包含多个 tool_use 时,用 `asyncio.gather()` 并行执行,而非顺序执行。对"同时读取多个文件"等场景延迟改善明显 |
+| ★★☆ | **工具摘要异步隐藏** | 工具执行完毕后 fire-and-forget 启动摘要生成(用小模型),不阻塞当前轮,下一轮迭代开头取结果。摘要延迟藏在下一次 LLM 调用时间里,对用户零感知 |
+| ★★☆ | **工具生命周期 hooks** | 在 `ToolRegistry` / `AgentRunner` 层面引入 `pre_tool_use` / `post_tool_use` / `post_tool_use_failure` 三个事件。最高价值用例:① `pre_tool_use` 实现无人值守审批代理(尤其对 `bash` 危险命令);② `post_tool_use_failure` 触发外部通知或重试策略;③ `post_tool_use` 对特定 MCP 工具的输出做后处理 |
+| ★★☆ | **Stop hook + Loop 控制接入点** | 在每轮 loop 结束时(得到 `stop_reason='end_turn'`)触发一个 hook,如果返回 block 则注入消息并 continue。这让外部系统(监控、测试框架)可以在运行时"插入"下一步指令,而无需重新发起整个对话 |
+| ★☆☆ | **循环内多层恢复路径** | 目前 `_heal_orphaned_tool_calls` 在进入循环前执行。可考虑将更多恢复逻辑移入循环内(context 超限时自动触发压缩并 continue,而非报错退出) |
+
+---
+
+*对比基于 Cyber Agent 文档(`architecture.md`)与 Claude Code v2.1.88 npm 包 source map 分析(非官方重建,仅供研究),生成日期:2026-04-02。*