# Claw Code Agent 架构逆向分析报告 本文基于只读分析仓库源码撰写,目标不是介绍如何使用,而是回答这个项目作为一个 Agent 系统是如何被构造出来的。 --- ## 1. 总体定位 ### 1.1 这个项目本质上是什么 这个项目本质上是一个 **agentic coding runtime**,而不是单纯的 workflow engine,也不只是一个 tool harness。 更准确地说,它处在三者交叉区: - **最核心身份**:Claude Code / Codex 风格的本地 coding agent runtime - **承载方式**:以 Python 实现的 agent loop + tool harness - **扩展方式**:外挂了大量 runtime 子系统,例如 search、MCP、plan、task、team、workflow、worktree、plugin、hook policy 因此它不是一个“纯工作流系统”。workflow 在这里是一个被 agent 调用的能力域,而不是系统唯一中心。系统中心仍然是 `LocalCodingAgent` 的多轮模型-工具循环,见 `src/agent_runtime.py:103`、`src/agent_runtime.py:358`。 ### 1.2 核心抽象是什么 这个项目有几个关键抽象: - **Agent**:`LocalCodingAgent`,真正的 orchestrator,负责 prompt 构建、loop、工具调用、budget、session 持久化,见 `src/agent_runtime.py:103` - **Session**:`AgentSessionState`,维护系统消息、用户上下文、assistant/tool transcript 以及 mutation lineage,见 `src/agent_session.py:89` - **Tool**:`AgentTool` + `ToolExecutionContext`,以 OpenAI function calling 风格对工具进行 schema 化和执行,见 `src/agent_tools.py:44`、`src/agent_tools.py:73` - **Prompt Context**:`PromptContext` / `AgentContextSnapshot`,把工作目录、git 状态、CLAUDE.md、各种 runtime 状态拼进模型上下文,见 `src/agent_prompting.py:15`、`src/agent_context.py:40` - **StoredAgentSession`**:把完整 transcript、tool_calls、usage、file_history、plugin_state 持久化到 `.port_sessions/agent/*.json`,见 `src/session_store.py:53` 换句话说,它不是围绕“任务节点图”来设计的,而是围绕: 1. 当前 session 里有哪些上下文 2. 当前模型要不要发起 tool call 3. tool result 如何再次喂回模型 4. 何时 compact / stop / persist ### 1.3 与 Claude Code / Codex 的相似点与差异 #### 相似点 - 典型 **LLM-driven tool loop**:模型产出 tool call,runtime 执行工具,再把结果作为 `tool` message 回灌 - 以 **workspace / repository** 为中心,强依赖文件系统、git 状态、shell、搜索 - 支持 **系统提示词 + repo memory** 注入,尤其是 `CLAUDE.md` - 有 **多轮对话 session**、resume、context compaction、权限 gating - 支持 **Agent 子代理 / delegation** #### 差异点 - 比 Claude Code / Codex 更“runtime platform 化”:这里塞了大量本地 runtime 子系统,如 `task_runtime`、`plan_runtime`、`team_runtime`、`workflow_runtime`、`remote_runtime`、`mcp_runtime` - “skills” 实现较轻:当前更像 prompt-template / slash-command bridge,而不是成熟的按需 markdown 技能系统 - 权限模型相对简化:主要是 CLI 启动时布尔权限 + policy deny,而不是更细粒度的人机交互审批流 - 可观测性是“有 transcript / event / file_history 基础设施,但 UI 和诊断链条尚未完全产品化” 结论上,这个项目像是: > 一个以 coding agent loop 为中心、向外扩张成通用本地 agent runtime 平台的 Python 实现。 --- ## 2. Agent Loop ### 2.1 主循环入口 真实入口是 `LocalCodingAgent.run()`,它生成 `session_id`、scratchpad 目录,然后进入 `_run_prompt()`,见: - `src/agent_runtime.py:358` - `src/agent_runtime.py:413` 恢复会话则走 `resume()`,它把持久化 session 反序列化成 `AgentSessionState`,并补充 file history replay 与 compaction replay,见 `src/agent_runtime.py:376`。 ### 2.2 每轮如何观察当前状态 Agent 的“观察”不是通过一个单独的 observe() 函数完成,而是在 loop 外预构建 session,并在每轮前做上下文压力处理: 1. **启动时构建 prompt context** - `build_prompt_context()` -> `build_context_snapshot()` - 汇总 cwd、platform、git status、scratchpad、CLAUDE.md bundle、各 runtime summary - 见 `src/agent_runtime.py:240` 左右、`src/agent_prompting.py:30`、`src/agent_context.py:71` 2. **构建初始 session** - `build_session()` 使用 system prompt parts + user_context/system_context 生成 session - `AgentSessionState.create()` 会插入: - `system` message - `user_context reminder` - 当前用户 prompt - 见 `src/agent_runtime.py:255` 左右、`src/agent_session.py:97` 3. **每轮前的状态整理** - `_microcompact_session_if_needed()` - `_snip_session_if_needed()` - `_compact_session_if_needed()` - `_preflight_prompt_length()` - 见 `src/agent_runtime.py:527-547` 因此,“观察当前状态”既包括文件系统 / git / runtime summary,也包括自身历史 transcript 的压缩后视图。 ### 2.3 如何构造上下文 上下文构造分两层: #### 第一层:环境与 memory 采样 `src/agent_context.py` 负责采样: - cwd、shell、platform、date - git status snapshot,见 `src/agent_context.py:279` - scratchpad directory,见 `src/agent_context.py:197` - `CLAUDE.md` / `.claude/CLAUDE.md` / `CLAUDE.local.md` / `.claude/rules/*.md` bundle,见 `src/agent_context.py:313-372` - plugin / hook policy / MCP / remote / search / account / ask_user / config / LSP / plan / task / team / workflow / worktree 的 runtime summary,见 `src/agent_context.py:205-275` #### 第二层:系统提示词装配 `build_system_prompt_parts()` 会拼接: - system instructions - doing tasks guidance - tool usage guidance - agent guidance - plugin / MCP / search / account / ask-user / config / LSP / plan / task / team / hook policy guidance - session-specific permission guidance - simple env info 见 `src/agent_prompting.py:75-119`。 也就是说,这个项目的上下文不是“只把聊天记录喂给模型”,而是: > transcript + injected local memory + runtime summaries + environment facts + permissions hints ### 2.4 如何决定下一步行动 行动选择主要由模型驱动。 每轮中 runtime 做的事情是: 1. 把 `session.to_openai_messages()` 和 `tool_specs` 发给模型,见 `src/agent_runtime.py:1153-1157` 2. 从返回中解析: - 普通 assistant content - tool calls - finish_reason - usage 3. 若无 tool call,则视作模型选择直接回答 4. 若有 tool call,则 runtime 执行这些工具,再把工具结果回灌到 session 真正的“决策”是模型自己通过 OpenAI tool calling 选择的,而不是 runtime 用规则树规划下一步。 因此 loop 属于: - **外层固定流程** - **内层模型驱动的动态行动选择** ### 2.5 如何调用工具 工具定义为 `AgentTool`,带: - `name` - `description` - JSON Schema 参数定义 `parameters` - `handler` 见 `src/agent_tools.py:73-111`。 每轮把所有工具变成 OpenAI function spec: - `tool_specs = [tool.to_openai_tool() for tool in self.tool_registry.values()]` - 见 `src/agent_runtime.py:463` 模型返回 tool call 后,主循环在 `src/agent_runtime.py:808-1119` 中执行: - 创建一个 tool message 占位 `session.start_tool(...)` - 记录 `tool_start` event - 应用 plugin / hook policy preflight - 执行 delegate / Skill / 普通 tool - 以 `serialize_tool_result()` 将结果序列化成 JSON 字符串写回 transcript ### 2.6 工具结果如何回到模型上下文 工具结果通过 `session.finalize_tool(...)` 变成一个 `role='tool'` 的 message,内容是: ```json { "tool": "...", "ok": true/false, "content": "...", "metadata": {...} } ``` 见: - `src/agent_tools.py:1248` - `src/agent_runtime.py:1037-1047` 下一轮模型调用时,`session.to_openai_messages()` 会把这些 tool messages 一并送回模型。因此工具结果不是旁路状态,而是标准 transcript 的一部分。 ### 2.7 什么时候停止 停止条件有多类: - **模型正常回答且无 tool_calls**:结束,见 `src/agent_runtime.py:764-806` - **finish_reason = length/max_tokens**:自动注入 continuation prompt,再继续一轮,见 `src/agent_runtime.py:766-783` - **budget exceeded**:停止,见 `src/agent_runtime.py:500-525`、`552-581`、`733-762` - **prompt too long / preflight fail**:停止或先 compact 再试,见 `src/agent_runtime.py:543-605` - **backend error**:停止,见 `src/agent_runtime.py:703-725` - **达到 `max_turns`**:停止,见 `src/agent_runtime.py:1121-1146` ### 2.8 loop 是固定流程还是模型驱动 结论: - **loop 骨架是固定的 runtime state machine** - **每轮内的动作内容是模型驱动的** 固定部分是: 1. 整理上下文 2. 预算检查 3. 调模型 4. 若 tool_calls 则执行工具 5. 把工具结果写回 transcript 6. 进入下一轮或停止 动态部分是: - 调什么工具 - 调多少个工具 - 是继续观察、修改还是直接回答 --- ## 3. Context / Memory ### 3.1 是否有短期上下文 有。短期上下文就是当前 `AgentSessionState.messages`。 其中包含: - system prompt - user context reminder - user / assistant / tool messages - mutation metadata 见 `src/agent_session.py:89-148`。 ### 3.2 是否有长期记忆 有,但不是向量数据库式长期记忆,而是 **文件化长期记忆**: - `~/.claude/CLAUDE.md` - 向上目录搜索的 `CLAUDE.md` - `.claude/CLAUDE.md` - `CLAUDE.local.md` - `.claude/rules/*.md` 这些文件会在 session 创建时被 bundle 进 `user_context['claudeMd']`,见 `src/agent_context.py:205-207`、`313-372`。 因此它支持“repo memory / instruction memory”,但不支持自动写回、检索式 memory store 或 embedding memory。 ### 3.3 是否有 conversation history 有,而且比较完整: - 运行时 transcript:`AgentSessionState.messages` - 持久化 transcript:`StoredAgentSession.messages` - resume 后会恢复完整历史,见 `src/session_store.py:53-115` 工具调用、usage、message metadata 也一起保存。 ### 3.4 是否有压缩 / summarize / compaction 有,而且这是一个比较成熟的部分。 机制分三层: - **microcompact**:时间驱动的小型压缩,清理旧 tool results,见 `src/agent_runtime.py:113-115 import`、`src/agent_runtime.py:527-533` - **snip**:把早期消息 tombstone 化为短摘要,见 `src/agent_runtime.py:533-537` 与 `_snip_session_pass` - **compact**:调用 `compact_conversation()` 生成更正式的压缩摘要,见 `src/agent_runtime.py:538-547`、`src/agent_runtime.py:1240` 前后逻辑 此外还有: - prompt too long 时的 **reactive compaction retry** - resume 时的 **compaction replay** 见 `src/agent_runtime.py:3042-3142`。 ### 3.5 是否有外部文件作为 memory 有,且非常明显: - `CLAUDE.md` 系列 - `.claude/rules/*.md` - 各类 workspace state 文件:config、plan、task、team、workflow、worktree 等 runtime manifest/state 文件 不过严格说,后者更多是 “runtime state injection”,不是纯 memory。 ### 3.6 是否支持类似 CLAUDE.md / AGENTS.md / skills 的持久知识 #### CLAUDE.md 支持,且是当前唯一成熟的一类持久知识注入。 #### AGENTS.md **不原生支持 `AGENTS.md` 作为 memory bundle**。当前 memory 发现逻辑只搜索 `CLAUDE.md`、`CLAUDE.local.md` 和 `.claude/rules/*.md`,见 `src/agent_context.py:355-372`。 #### skills 只支持“bundled skills”: - 在 Python 代码里硬编码 skill 元数据和 prompt builder - 通过 `Skill` 工具或 `/skills` 暴露 不支持从工作区扫描 markdown skill 文档并按需加载。 ### 3.7 当前设计局限 1. **长期记忆是纯文件注入,不是检索式 memory** - 规模大时容易塞满 prompt - 没有 relevance ranking 2. **只识别 CLAUDE.md 家族,不识别 AGENTS.md** - 对多代理协作约束不够统一 3. **resume 依赖 transcript replay,不是真正的 semantic memory** - 历史很多时仍然会发生 compaction 丢失细节 4. **runtime summaries 很多,但上下文管理是“全量摘要注入”** - 不是 query-time selective loading 5. **task / plan / workflow 已有,但未形成强约束的 workspace memory layout** - 更像多个离散 runtime,而不是统一的 task-memory 文件系统 --- ## 4. Tools / Actions ### 4.1 工具能力概览 核心工具能力包括: - **文件系统** - `list_dir` - `read_file` - `write_file` - `edit_file` - `notebook_edit` - **搜索与代码理解** - `glob_search` - `grep_search` - `LSP` - `tool_search` - **Shell** - `bash` - **Web / Search** - `web_fetch` - `web_search` - search provider 管理工具 - **计划 / 任务** - `update_plan` - `plan_get` - task runtime 相关工具 - **Human gate** - `ask_user_question` - **扩展 runtime** - `mcp_*` - `remote_*` - `workflow_*` - `worktree_*` - `account_*` - `config_*` - **Agent 特有** - `Agent` / `delegate_agent` - `Skill` tool registry 定义入口在 `src/agent_tools.py:210`。 ### 4.2 工具 schema 怎么定义 每个工具是一个 `AgentTool`: - `name` - `description` - `parameters`(JSON Schema) - `handler` 见 `src/agent_tools.py:73-111`。 它通过 `to_openai_tool()` 转成 OpenAI-compatible function calling schema,见 `src/agent_tools.py:80-88`。 ### 4.3 工具调用怎么执行 模型返回 tool call 后,runtime 会: 1. 解析 tool call,见 `src/openai_compat.py:273-298` 2. 在 loop 中逐个消费,见 `src/agent_runtime.py:808-1119` 3. 普通工具走 `execute_tool_streaming()` 或 `tool.execute()`,见 `src/agent_tools.py:181-207` 4. 特殊工具: - `Agent` / `delegate_agent` 走子代理执行,见 `src/agent_runtime.py:2214` - `Skill` 走 `_execute_skill()`,见 `src/agent_runtime.py:2059` ### 4.4 工具结果如何返回 工具结果统一封装为 `ToolExecutionResult`: - `name` - `ok` - `content` - `metadata` 然后 `serialize_tool_result()` 把它转成 JSON 字符串,塞入 tool message,见 `src/agent_tools.py:1248-1255`。 这意味着: - 对模型来说,工具结果是 transcript 中的标准 `tool` message - 对 runtime 来说,工具结果又带 `metadata`,可用于 file_history、policy event、plugin hook ### 4.5 是否有安全边界 有,但不是特别细粒度。 #### 文件边界 `_resolve_path()` 会强制路径位于 workspace root 内,防止越界,见 `src/agent_tools.py:1277-1288`。 #### 写权限边界 `write_file` / `edit_file` 受 `allow_file_write` 控制,见 `src/agent_tools.py:1291-1295`。 #### shell 权限边界 `bash` 受两层控制: - `allow_shell_commands` - `allow_destructive_shell_commands` 并有 destructive regex 阻断,比如 `rm`、`git reset --hard`、`git clean -fd` 等,见 `src/agent_tools.py:1298-1324`。 #### policy / hook deny workspace 可以通过 `.claw-policy.json` / `.codex-policy.json` / `.claw-hooks.json` 配置 deny_tools、deny_tool_prefixes 以及 hook message,见 `src/hook_policy.py:160-256`。 #### CLI 层 deny context 还有一个更轻的 `ToolPermissionContext`,可按名字或前缀过滤工具,见 `src/permissions.py:7-17`。 ### 4.6 这一层的架构评价 这个项目的 tools 层已经不是“几个本地 IO 工具”,而是: > 一个围绕 workspace 资源、外部 runtime 状态和 agent orchestration 展开的统一 action surface。 优点是扩展性强,缺点是工具域越来越大后,模型对何时该用哪个工具会变得更依赖 prompt guidance。 --- ## 5. Markdown / Workspace ### 5.1 是否支持 workspace-first 是,明显是 workspace-first 设计。 证据: - `ToolExecutionContext.root` 是工作区根,见 `src/agent_tools.py:45` - 所有文件工具都围绕 workspace root 做相对路径解析,见 `src/agent_tools.py:1277-1288` - context 注入围绕 cwd、git repo、worktree、scratchpad、additional_working_directories 展开,见 `src/agent_context.py:71-99` - 很多 runtime 都是 `from_workspace(cwd)` 初始化的 ### 5.2 是否适合让 Agent 维护 `.md` 文件作为任务记忆 适合,而且比很多 agent 框架更适合。 原因: - 已经原生支持 markdown 记忆文件注入(CLAUDE.md / rules) - 文件读写/编辑能力完整 - 有 plan / task runtime,可作为结构化状态 - 有 scratchpad directory,可作为会话级临时区 不足是它没有约定一个统一的 task-memory 目录布局。 ### 5.3 是否有任务目录 / workspace 概念 有 workspace 概念,但没有强约定的任务目录结构。 已有元素: - workspace root - additional working directories - scratchpad root / scratchpad directory - `.claude/` 作为本地 agent/runtime 元数据目录 但没有默认的: - `/tasks/{task_id}/...` - `/artifacts/...` - `/memory/...` ### 5.4 能否改造成 task directory layout 完全可以,而且改造成本不高。 一个可行布局: ```text /tasks/{task_id}/goal.md /tasks/{task_id}/memory/open_questions.md /tasks/{task_id}/memory/working_notes.md /tasks/{task_id}/artifacts/report.md /tasks/{task_id}/artifacts/commands.md /tasks/{task_id}/artifacts/findings.md ``` 最小改造方式: 1. 在 `task_runtime` 中给 task 增加 `task_root` 2. 在 `agent_context._load_memory_bundle()` 中把 `/tasks/{active_task}/memory/*.md` 纳入 memory discovery 3. 在 prompt context 中注入 `active task root` 4. 给 `update_plan` / task 工具增加 task-root 绑定 这样不需要重写 loop,只是增强 workspace memory layout。 --- ## 6. Skills ### 6.1 当前是否支持 skill 支持,但属于 **弱 skill 系统**。 当前 skill 机制分两部分: 1. **Bundled skills** - `BundledSkill` 定义 name / description / when_to_use / aliases / allowed_tools / get_prompt - 见 `src/bundled_skills.py:22-32` 2. **Skill tool** - `_execute_skill()` 优先查 bundled skill - 查不到再退回 slash command - 见 `src/agent_runtime.py:2059-2142` ### 6.2 是否有技能发现机制 有,但只对 bundled skill 生效: - `format_skills_for_system_prompt()` 把 skill 列表渲染进系统提示,帮助模型“知道”有哪些 skill,见 `src/bundled_skills.py:268-289` - GUI 也有 `/api/skills` 列表,见 `src/gui/server.py` 但它没有: - 从工作区扫描 skill 文件 - 从 skill 文档按需加载正文 - skill-level semantic retrieval ### 6.3 是否支持 progressive disclosure **严格说不支持。** 当前 bundled skill 更像: - 用户 / 模型选中 skill - skill 生成一段 prompt - prompt 立即进入模型上下文 并不是: - 先列 metadata - 决定是否需要 skill - 再按需读取 skill markdown 正文 - 只展开相关片段 因此它缺乏真正的 progressive disclosure。 ### 6.4 如果没有,应该如何扩展 建议做一个最小可行版 workspace skill system,不破坏现有 loop。 #### 最小改造方案 ##### 目录结构 ```text .claude/skills/ review/ skill.json SKILL.md data-agent/ skill.json SKILL.md python-debug/ skill.json SKILL.md ``` ##### metadata `skill.json` 示例: ```json { "name": "data-agent", "description": "Analyze datasets and produce structured markdown reports.", "when_to_use": "When the task involves CSV/JSON/table exploration, metric comparison, or report writing.", "aliases": ["data", "analysis"], "allowed_tools": ["read_file", "write_file", "edit_file", "glob_search", "grep_search", "bash"], "entry_markdown": "SKILL.md" } ``` ##### loading 时机 建议两阶段: 1. **session 初始化时只加载 metadata** - 像 bundled skill 一样列进 system prompt - 不把 `SKILL.md` 正文直接注入 2. **当模型选择 Skill 工具时再加载正文** - `Skill(skill="data-agent")` - runtime 读取对应 `SKILL.md` - 返回 skill prompt 或 `` 包装内容 ##### Agent 如何决定读取哪个 skill 沿用现有机制,最小改造即可: - 在 system prompt 里暴露 `name + description + when_to_use` - 模型自己决定是否调用 `Skill` - `Skill` 工具负责延迟读取 skill 正文 ##### 代码落点 最小改造建议: - 扩展 `src/bundled_skills.py` 为“bundled + discovered skills” - 或新建 `workspace_skills.py` - 在 `_execute_skill()` 中优先: 1. bundled skill 2. workspace discovered skill 3. slash command fallback 这个改法不会触碰 loop 主干,只是在 skill lookup 阶段增加一个来源。 --- ## 7. Policy / Human Gate ### 7.1 如何处理权限 当前权限机制主要有三层。 #### 第一层:启动时权限布尔开关 `AgentPermissions`: - `allow_file_write` - `allow_shell_commands` - `allow_destructive_shell_commands` 见 `src/agent_types.py:147-150`。 这是最直接的 runtime gate。 #### 第二层:workspace hook / policy `HookPolicyRuntime` 支持: - `trusted` - `managed_settings` - `safe_env_names` - `deny_tools` - `deny_tool_prefixes` - `before_prompt` - `after_turn` - `before_tool` - `after_tool` - `budget_overrides` 见 `src/hook_policy.py:10-22`。 #### 第三层:ask_user runtime 并不是所有危险动作都会自动弹确认框。当前“人工确认”更像一个工具能力: - `ask_user_question` 也就是说,模型可以选择向用户提问,但 runtime 本身不会像桌面 Codex 那样对每个危险动作自动出现审批 UI。 ### 7.2 哪些动作会请求用户确认 严格来说,**默认没有统一的自动确认拦截器**。 当前模式更像: - 文件写:如果没开 `allow_write`,直接拒绝 - shell:如果没开 `allow_shell`,直接拒绝 - destructive shell:如果没开 `--unsafe`,直接拒绝 - policy deny:直接拒绝 - ask-user:模型显式调用 `ask_user_question` 才会走人工澄清 因此它偏向: > hard gate / deny-first,而不是 ask-on-demand 审批流。 ### 7.3 哪些动作默认允许 默认允许的是安全读类能力,例如: - read - list - search - tool discovery - runtime status inspection 默认不允许的是: - 写文件 - shell - destructive shell 具体提示也被写进 system prompt,见 `src/agent_prompting.py:388-401`。 ### 7.4 是否有 deny / allow / ask 策略 有 `allow` 与 `deny`,但 `ask` 不是系统级统一策略。 - **allow**:CLI flag / runtime permissions - **deny**:hook policy deny_tools / deny_tool_prefixes - **ask**:只通过 `ask_user_question` 工具实现,非自动策略 ### 7.5 是否支持项目级规则 支持。 项目级规则来自: - `.claw-policy.json` - `.codex-policy.json` - `.claw-hooks.json` 并且会沿 cwd 向上目录发现,见 `src/hook_policy.py:160-187`。 ### 7.6 对数据 Agent 的不足 如果你们要做数据 Agent,这套 human gate 还有几个明显缺口: 1. **缺少按数据源级别的权限模型** - 没有“允许读 CSV 但不允许发网络请求”这种更细粒度策略 2. **没有结构化审批流** - 例如“将执行 SQL / 访问线上表 / 导出结果集”的 ask approval 缺位 3. **没有数据脱敏/泄露策略** - safe_env 只管环境变量,不管输出内容 4. **没有审计级 action classification** - tool 结果有 metadata,但没有“高风险数据出站/高风险变更”的统一标签体系 5. **policy 更偏 workspace engineering,而不是 data governance** 如果面向数据 Agent,建议增加: - data source allowlist - query approval policy - outbound redaction hook - result size limits - table/column sensitivity policy --- ## 8. Trace / Observability ### 8.1 是否记录每一轮模型输入输出 有记录,但“模型输入原文”不单独存为一条日志,而是可由 session transcript 和 system/user context 还原。 保存内容包括: - `messages` transcript - `system_prompt_parts` - `user_context` - `system_context` - `usage` - `turns` - `tool_calls` 见 `src/session_store.py:53-115`、`src/agent_runtime.py:3269-3345`。 模型输出则直接进入 `assistant` messages。 ### 8.2 是否记录工具调用 有,而且记录得比较细: - transcript 中的 assistant tool_calls - transcript 中的 tool result message - `events` 中的 `tool_start` / `tool_delta` / `tool_result` - `file_history` 中的摘要化变更记录 见 `src/agent_runtime.py:852-1119`。 ### 8.3 是否记录文件变更 有,`file_history` 是一个重要机制。 resume 时会把 file_history replay 成一个 `` 给模型,见: - `src/agent_runtime.py:2914-3040` 持久化时也会一起保存到 session json,见: - `src/session_store.py:66` - `src/agent_runtime.py:3333` 它不是完整 patch log,但已经记录: - action - path / changed_paths - snapshot ids - before/after preview - result preview ### 8.4 是否有 replay/debug 能力 有基础能力: - `agent-resume` - transcript 持久化 - file_history replay - compaction replay - GUI 可以展示 transcript 和 tool calls 但没有一个真正成熟的“调试控制台”或统一 trace viewer。 ### 8.5 现有 observability 的优点 优点: - 数据结构已经齐全:transcript、events、file_history、budget_state、plugin_state - session 是 JSON 文件,易于离线分析 - message metadata 里保留了 mutation lineage / revision 信息 这意味着系统已经具备做更强 observability 的底座。 ### 8.6 还缺什么 目前还缺: 1. **完整 prompt snapshot** - 现在有 system/user context 和 transcript,但缺“每轮实际发给模型的最终 payload”落盘 2. **turn-level structured trace** - 比如 `turn_03.json` - 包含 prompt size、tool candidates、selected tool calls、latency、errors 3. **统一 replay viewer** - 现在 resume 偏“继续工作” - 不是“回放调试” 4. **tool latency / error taxonomy** - 有 event,但缺统计聚合 5. **compaction provenance** - 已有 replay,但缺图形化 lineage/summary mapping ### 8.7 如果要补,怎么加 最小建议: #### 建议新增 trace 目录 ```text .port_sessions/traces/{session_id}/ turn_001.request.json turn_001.response.json turn_001.events.json turn_001.tools.json ``` #### 每轮保存这些内容 - request - rendered messages - tool specs - token budget snapshot - response - raw model response - parsed tool calls - finish_reason - tools - tool args - tool result - latency - events - 当前 turn 的 event list #### 代码落点 最合适挂点在: - `_query_model()` 前后 - tool loop `for tool_call in turn.tool_calls` - `_persist_session()` 这样能复用现有 `session_id` 和 `turn_index`。 --- ## 总结判断 这个项目已经具备一个完整 coding agent runtime 的主要骨架: - 有明确的 session 与 transcript 模型 - 有模型驱动的动态工具循环 - 有 context injection 与 memory bundle - 有 compaction / replay / resume - 有较丰富的本地工具和 runtime 子系统 但从“下一代 workspace-native agent platform”的角度看,它还有几个明显缺口: - skills 仍是 prompt-template 级,未形成 markdown-native progressive disclosure - policy 偏 deny/allow,不是强审批流 - memory 已经文件化,但没有统一 task directory layout - observability 有底座,缺一层真正可用的 trace 产品化视图 如果目标是把它改造成更强的“任务型数据 Agent / 文档驱动 Agent / workspace-memory-first Agent”,最值得优先补的不是 loop,而是三件事: 1. **workspace skill discovery + on-demand markdown loading** 2. **任务目录结构与 memory layout 约定** 3. **turn-level trace 持久化与 replay viewer** 这三项都可以在不重写 `LocalCodingAgent` 主循环的前提下增量演进。