Zed Agent

一句话定位

Zed 的 coding agent 是这份 harness 调研中少数完全开源、可源码级核实的样本——不同于 Claude Code / Cursor 等闭源二进制,zed-industries/zed 整仓公开,agent 循环、工具系统、prompt 模板、沙箱策略均可直接阅读。同时 Zed 自建了 ACP(Agent Client Protocol),把 Claude Code、Gemini CLI、Codex CLI、Cursor CLI 等外部 agent 作为对等体接入同一套 UI/权限/沙箱基础设施(“Parallel Agents” / “bring your own agent”),这是它与其他 harness 最大的架构差异点。

核心架构总览(目录结构关键路径 + 引用的 commit)

分析基于 commit eeff97950f7ccfd5b2f73b48f7267bd0df5e4bfb(2026-07-06 18:10:48 +0200,“Add license to tooling/lints crate (#60468)”),git clone --depth 1 直连 GitHub 拉取(未走代理,代理会破坏 git 的 TLS;CloakBrowser 抓取博客/文档页时代理 127.0.0.1:7897 正常)。仓库本体 107MB,未入库,可用该 SHA 复现。

关键 crate(均相对 zed-repo/):

crates/
├── agent/src/
│   ├── thread.rs (8210 行)         — Thread 核心状态对象、主循环、压缩、AgentTool trait
│   ├── agent.rs (6925 行)          — 原生 ACP agent server 装配、标题生成、遥测
│   ├── tools.rs (255 行)           — tools!{} 注册宏、ALL_TOOL_NAMES、3 道工具准入闸门
│   ├── tools/                      — ~23 个内置工具实现(见"工具体系")
│   ├── tool_permissions.rs (2417 行) — 硬编码安全规则、权限决策
│   ├── sandboxing.rs (1162 行)     — 沙箱策略胶水层
│   ├── thread_store.rs / db.rs     — SQLite 会话持久化
│   └── templates/*.hbs             — 系统提示 Handlebars 模板
├── agent_settings/src/
│   ├── agent_settings.rs (1818 行) / agent_profile.rs (309 行) — write/ask/minimal 三档 profile
│   └── prompts/*.txt               — compaction/summarize 提示词
├── agent_skills/agent_skills.rs (2187 行) — Skills 系统
├── agent_servers/src/acp.rs (5078 行), custom.rs — ACP 协议实现
├── acp_tools/src/acp_tools.rs       — ACP 日志实时查看器
├── telemetry/src/telemetry.rs (66 行) — 遥测事件宏
├── prompt_store/src/prompts.rs      — 规则文件加载(9 种格式)
├── project/src/trusted_worktrees.rs — 工作区信任模型
└── edit_prediction_cli/ (~18,890 行, ~20 files) — Zeta 训练数据流水线(ep CLI)
crates/zeta_prompt/src/zeta_prompt.rs — ZetaFormat 版本化 prompt 格式
crates/edit_prediction/src/edit_prediction.rs (3542 行) — Zeta 运行时消费端

Agent Loop(主循环 / 何时继续何时停)

Thread::run_turnthread.rs:2617)派生一个执行 run_turn_internalthread.rs:2681)的任务,其内部是一个 loop{}

  1. 按需执行上下文压缩(见下);
  2. 构造 completion 请求并流式调用模型;
  3. 处理模型返回的工具调用(支持通过 FuturesUnordered 并行执行多个工具调用);
  4. 若本轮产生了工具结果则继续循环。

终止条件(thread.rs:2972):end_turn = tool_results.is_empty() && early_tool_results.is_empty(),即模型这一轮不再产生任何工具调用时结束,发出 StopReason::EndTurn。其余终止路径:StopReason::Refusal(附带模型回退重试逻辑,thread.rs:2919-2969)、StopReason::MaxTokens,以及用户主动取消(cancellation_rx)。此外有一个”steering”机制(end_turn_at_next_boundary)允许 UI 在任务执行中途用排队消息打断循环,而不必等当前完整轮次结束。

记忆与上下文管理(压缩、长期记忆、会话持久化)

  • 自动压缩:当 AgentSettings.auto_compact.enabled 且活跃 token 数超过 max_input_tokens 的某一阈值比例时触发(compaction_message_target_ixthread.rs:4246),并设有 MIN_COMPACTION_CONTEXT_WINDOW = 80_000 token 的下限(小上下文模型不做压缩)。压缩本身是一次独立的 LLM 调用,使用 COMPACTION_PROMPT(已存档 artifacts/compaction_prompt.txt)——要求模型输出 Goal / State / Context / Next / Pitfalls 五段式交接摘要,结果作为 Message::Compaction 标记插入线程。
  • 会话持久化:本地 SQLite(sqlez 库)持久化整条线程(ThreadsDatabase/DbThreaddb.rs),含完整消息历史与草稿输入(Thread.draft_prompt)。
  • 长期/项目记忆ProjectContext/RulesFileContextprompt_store/src/prompts.rs)按 worktree 加载首个匹配的规则文件,RULES_FILE_NAMES 常量列出 9 种识别格式:.rules.cursorrules.windsurfrules.clinerules.github/copilot-instructions.mdAGENT.mdAGENTS.mdCLAUDE.mdGEMINI.md;另有独立的跨项目个人级 ~/AGENTS.mduser_agents_md.rs)。未发现 RAG / 向量记忆系统——记忆手段止于:(a) 线程内压缩摘要,(b) 规则文件注入,(c) 完整可浏览/可恢复的 SQLite 历史,(d) 面向 edit-prediction(非 chat 记忆)的 LSP 派生 editable/context 范围。

工具体系(定义/调用协议/注册/权限)

Trait 化设计:AgentTool trait(thread.rs:4929),每个工具定义 NAME、经 schemars 派生 JSON-schema 的 Input/Outputkind()run()。通过 tools!{...} 宏(tools.rs)集中注册,宏在编译期强制无重名并生成 built_in_tools()。约 23 个内置工具,覆盖文件操作、LSP 工具(受 LspToolFeatureFlag 控制)、终端、fetch/web-search、skill 加载、子 agent 派生(spawn_agent_tool.rs)、MCP 透传。MCP server 的工具经 context_server_registry.rs 统一包装为 AnyAgentTool,ID 格式 mcp:<server_id>:<tool_name>

tools.rs 中的代码注释明确写出新工具必须通过的 3 道准入闸门(否则被静默丢弃):

  1. assets/settings/default.json 中 profile 的工具白名单;
  2. 权限 UI 完整性测试;
  3. tool_feature_flag_enabled 特性开关判定。

代表性工具文件(crates/agent/src/tools/):spawn_agent_tool.rscreate_thread_tool.rsskill_tool.rscontext_server_registry.rsterminal_tool.rsedit_file_tool.rsread_file_tool.rsgrep_tool.rsfind_path_tool.rsfetch_tool.rsweb_search_tool.rslist_agents_and_models_tool.rs,以及一组 LSP 驱动工具:go_to_definition_tool.rsfind_references_tool.rsget_code_actions_tool.rsapply_code_action_tool.rsrename_tool.rsdiagnostics_tool.rs

Prompt 设计(系统提示结构、动态组装)

系统提示是单一 Handlebars 模板(crates/agent/src/templates/system_prompt.hbs,19KB,已全文存档),条件化组装以下模块(已核实模板开头实际内容):

  • 固定身份声明(“You are the Zed coding agent running inside the Zed editor…“)+ Communication 风格准则(简洁直接、可标注不确定性、不过度道歉);
  • Formatting Responses(markdown、mermaid 图表规范,明确禁止 mermaid 内联 HTML 与自定义 classDef);
  • Tool Use 段,仅当 available_tools 非空时渲染({{#if (gt (len available_tools) 0)}}),内含并行工具调用指引、超时设置建议、“不要在 write_file/edit_file 后重复读取校验”等经验规则;
  • Task Execution(“坚持到任务真正解决才结束轮次”、“没有把握时才问用户”);
  • Searching and Reading(禁止猜测路径,按工具可用性条件渲染,如 {{#if (contains available_tools 'grep')}});
  • 之后依 NOTES.md 记录还包括:多 agent 委派段(仅当 spawn_agent 工具存在时渲染)、OS/shell/日期/worktree 信息、沙箱权限段(按 mac/Linux/Windows 分别渲染,仅当沙箱激活时)、模型名、Skills 目录(<available_skills> XML 块)、用户 AGENTS.md + 项目规则文件(XML 包裹)。

另存在一份并行的 experimental_system_prompt.hbs(12KB,已存档),推测用于人工 A/B 对比迭代提示结构(未发现自动化 A/B 框架代码)。压缩、线程标题生成、线程摘要各自有独立的短提示词文件(compaction_prompt.txtsummarize_thread_prompt.txtsummarize_thread_detailed_prompt.txt,均已存档并核实内容,如压缩提示词即为 Goal/State/Context/Next/Pitfalls 五段式要求)。

Router / 编排(任务分解、多 agent、子 agent)

两层机制:

  1. 线程内子 agentspawn_agent 工具(spawn_agent_tool.rs)派生 Thread::new_subagent,与父线程共享 project/templates/context-server-registry,但不继承父线程消息历史(调用时必须给出自包含的上下文),仅返回子 agent 的最终消息;支持并行委派与通过 session_id 复用会话。
  2. 跨进程外部 agent:Zed 自建的 ACP(Agent Client Protocol)——一个 JSON-RPC 协议(crates/agent_servers/src/acp.rs),让 Zed 的 UI/会话/权限/沙箱基础设施驱动外部 agent 二进制(Claude Code、Gemini CLI、Codex CLI、Cursor CLI,代码中常量 GEMINI_ID/CLAUDE_AGENT_ID="claude-acp"/CODEX_ID="codex-acp"/CURSOR_ID)作为与原生 agent 对等的角色接入。这是”Parallel Agents”(zed.dev/blog/parallel-agents,2026-04-22)与”bring your own agent”功能的真正技术底座。

“Parallel Agents” 本身只是这套底座之上的 UI 层(Threads 侧边栏:跨多个项目的多条独立可控 agent 线程),未发现更深的”planner”层——编排是扁平的(一个线程 ↔ N 个子 agent 线程 / N 个 ACP agent 连接),而非层级化的 planner-executor 架构。

Skill / 插件体系

.agents/skills/<name>/SKILL.md 约定(agent_skills.rs,2187 行),直接对标 Anthropic 的 Skills 格式:YAML frontmatter(name 需匹配目录名,正则 ^[a-z0-9]+(-[a-z0-9]+)*$description,可选 disable-model-invocation)。三种作用域按优先级覆盖:BuiltIn(编译进二进制,优先级最低)< Global~/.agents/skills/)< ProjectLocal<project>/.agents/skills/,可入版本控制)。通过专门的 skill 工具(skill_tool.rs)加载,渲染为 <skill_content> XML 信封,对恶意 skill 正文做转义/中和以防 prompt injection。容量上限:单个 SKILL.md 100KB(MAX_SKILL_FILE_SIZE),系统提示内 skill 描述目录总预算 50KB(MAX_SKILL_DESCRIPTIONS_SIZE),并发加载度 SKILL_IO_CONCURRENCY = 16

内置仅随包附带一个 skill:create-skillcrates/agent_skills/builtin/create-skill/SKILL.md),本身是一个”教你写 skill”的元 skill。注:这套体系与另一套完全独立的 Extension 系统(crates/extension*,管语言/主题/MCP-server-extension/agent-server-extension)正交,本次未深入。

自进化能力(自我改进 / 学习型记忆 / eval 驱动纠错)

两种截然不同的机制:

  • Zeta 编辑预测模型:存在真实的离线 eval 驱动数据修正闭环。edit_prediction_cliep CLI,18,890 行/约 20 个文件)定义子命令链 Read → LoadProject → Context → FormatPrompt → Predict → ParseOutput → Score → Qa → Repair → Distill → Synthesize → Split/FilterLanguages,其中 Score/Qa 是 LLM-as-judge 质量评估,Repair 对低质量预测重新生成,构成一条反哺模型微调(Qwen2.5-Coder-7B 基座)的数据修正循环。zeta_prompt.rsZetaFormat 枚举的详细版本历史(V0112MiddleAtEnd → … → V0608QwenMultiRegions 等)是这条持续迭代的代码级证据。
  • Chat/coding agent 本身未发现自动化自我改进机制——没有 agent 根据轨迹结果自动重写自己 prompt/工具的证据;experimental_system_prompt.hbs 与生产版并存这一事实提示的是人工、非自动化的提示迭代。

可观测性(日志 / trace 格式)

dev: Open ACP Logscrates/acp_tools/src/acp_tools.rs)是一个实时的、编辑器内置的 JSON-RPC 消息检查器,对任意 agent 连接(原生或外部 ACP agent)展示每一条 request/response/notification,MAX_DEBUG_BACKLOG_MESSAGES = 2000。另有结构化遥测事件(telemetry::event! 宏,crates/telemetry/src/telemetry.rs,66 行)在关键生命周期节点触发:"Agent Thread Completion"(每次模型调用尝试,含 thread_id/parent_thread_id/prompt_id/model/provider/attempt)、"Agent Thread Completion Usage Updated"(token 计数含 cache 读写)、"Agent Compaction Completed"(触发原因、压缩前后 token 数、重试次数、阈值)。这些事件流入 Zed 自有的 Snowflake 后端产品分析系统(据官方 Telemetry / AI-improvement 文档),与对话内容存储分离。

安全与权限(审批门、密钥管理)

分层设计:

  • 硬编码、不可覆盖的正则拒绝列表(tool_permissions.rs::HARDCODED_SECURITY_RULES),拦截灾难性终端命令(rm -rf /~$HOME...,含路径规范化以捕获绕过尝试)——代码注释明确写明此规则任何设置都无法覆盖
  • Agent Profileagent_profile.rs):三个内置档位 write/ask/minimal,各自在设置中有显式工具白名单;进入受限/不受信工作区时 profile 会自动降级为 minimalThread.profile_downgraded_for_restricted_workspace 字段)。
  • 逐次调用审批门ToolPermissionDecision::{Allow, Deny, Confirm} 形状的决策(decide_permission_from_settings),授权粒度可为”仅此次 / 本线程内 / 永久”(同构地体现在终端网络/文件系统升权的 sandbox_grants: ThreadSandboxGrants)。
  • 工作区信任trusted_worktrees.rs):类 VS Code 的信任阶梯(单文件 worktree < 目录 worktree < 路径覆盖信任),决定 LSP server(进而整个 agent 能力)是否被允许在给定文件夹运行。

沙箱与执行隔离

真实的操作系统级沙箱,而非仅停留在 prompt 规则层面:macOS 用 Seatbelt(sandbox-exec + 生成的 Scheme 风格策略文件,macos_seatbelt.rs);Linux 用 Bubblewrap(linux_bubblewrap.rs);Windows 用 WSL 内跑 Bubblewrap(windows_wsl.rs)。默认策略(sandboxing.rs/system_prompt.hbs):读不受限,写限制在 worktree 根目录 + 每线程临时目录内(即便有更宽的写入授权,.git 元数据始终受保护,见 sandbox_git_dirs),网络默认阻断,可按调用升级为特定主机白名单(allow_hosts)或完全开放(allow_all_hosts,经一个强制执行主机白名单的 HTTP/HTTPS 代理);unsandboxed: true 是需要用户显式批准的最终逃生舱(例如必须触碰 .git 的命令)。授权范围可分为单次调用 / 整个线程 / 永久(“always”)。

与模型的协同设计

仓库中最深的协同设计证据集中在 Zeta(Zed 自己的编辑预测小模型),而非通用 chat agent:

  • zeta_prompt.rsZetaFormat 枚举是一份与 Zeta 系列模型共同演进的、带版本号和日期的 prompt 格式历史(V0112MiddleAtEndV0608QwenMultiRegions 及更新版本),包含针对特定基座模型定制的格式变体(如 V0331SeedCoderModelPyV0608QwenMultiRegions 对应 Qwen 的 FIM token)。
  • Zeta2PromptInput/Zeta3PromptInput 结构体把 LSP 派生的 syntax_rangesrelated_filesactive_buffer_diagnostics,以及用户同意标志(can_collect_datain_open_source_repo)直接嵌入发往模型服务的 wire format。
  • 据官方文档,Zeta 是 Qwen/Qwen2.5-Coder-7B 的微调版本,权重开源于 huggingface.co/zed-industries/zeta,训练数据集公开于 huggingface.co/datasets/zed-industries/zeta
  • 通用 coding/chat agent 本身是模型无关的(通过 ACP / LLM-provider 设置自带模型),协同设计工作完全集中在这个小而快的编辑预测模型上,未见对通用 agent chat 模型的类似协同设计证据。

轨迹利用(session/trajectory 是否反哺训练/评测)

据官方文档(zed.dev/docs/ai/ai-improvement,“Feedback and Training Data”,已存档 artifacts/ai-improvement-doc.md):

  • 编辑预测数据:仅对在开源仓库中显式 opt-in 的用户,Zed 收集光标片段、近期编辑 diff、生成的预测结果、仓库 URL/git revision、buffer outline/diagnostics 到 Snowflake;定期做匿名化/去除密钥与 PII 的清洗后,汇入公开的 zed-industries/zeta HF 数据集,用于微调下一版 Zeta——这与 edit_prediction_cliScore/Qa/Repair/Distill 子命令是同一条数据修正循环。
  • Chat/agent 线程默认不收集;只有当用户显式对某次回复评分或提交反馈时,Zed 才会保留完整对话线程(消息 + AI 回复 + 元数据:模型、token 计数、时间戳)到 Snowflake,用途是”refine prompts, tools, and product behavior”——即反哺人工驱动的 prompt/工具迭代(对应仓库里并存的两份系统提示模板文件),而非自动化的 chat 模型微调。
  • Zed 托管的模型在零数据留存的供应商协议下运行,例外是”provider-designated models with safety retention”(例如 Anthropic 的 Mythos 级模型)——这是 Zed 与供应商协议层面的细节,非 Zed 一方的选择。

与同类 harness 的关键差异(1-3 条)

  1. 完全开源、可源码验证:与 Claude Code / Cursor / Windsurf 等闭源二进制不同,Zed 的整个 agent 循环、工具协议、沙箱策略、prompt 模板均在公开仓库中可读可验证——本 dossier 的每条结论都可回溯到具体文件/行号,而非从行为推断。
  2. ACP 作为多 agent 编排的第一公民:多数 harness 的”多 agent”停留在同进程内的子 agent 委派(本仓库的 spawn_agent 也是如此),但 Zed 额外建了一套跨进程 JSON-RPC 协议(ACP),把 Claude Code、Codex、Gemini CLI 等外部竞品 agent 接进同一套 UI/权限/沙箱基础设施中作为对等体运行,这是”Parallel Agents”的真正实现方式,在同类 harness 中未见先例。
  3. 两套”模型协同设计”完全分离:通用编码/对话能力保持模型无关(BYO model),但把协同设计的全部力气用在一个独立的小型编辑预测模型(Zeta)上,形成”大而通用的 agent 循环 + 小而深度协同的专用模型”的双轨结构;后续跨 harness 对比阶段可展开细化(本节先留概述)。

原始源码定位

  • repo: https://github.com/zed-industries/zed
  • commit/version analyzed: eeff97950f7ccfd5b2f73b48f7267bd0df5e4bfb(2026-07-06 18:10:48 +0200)
  • 关键文件列表(相对 zed-repo/):
    • crates/agent/src/thread.rs
    • crates/agent/src/agent.rs
    • crates/agent/src/tools.rs
    • crates/agent/src/tools/*.rs(spawn_agent_tool.rs、create_thread_tool.rs、skill_tool.rs、context_server_registry.rs、terminal_tool.rs、edit_file_tool.rs、read_file_tool.rs、grep_tool.rs、find_path_tool.rs、fetch_tool.rs、web_search_tool.rs、list_agents_and_models_tool.rs、go_to_definition_tool.rs、find_references_tool.rs、get_code_actions_tool.rs、apply_code_action_tool.rs、rename_tool.rs、diagnostics_tool.rs)
    • crates/agent/src/tool_permissions.rs
    • crates/agent/src/sandboxing.rs
    • crates/agent/src/thread_store.rscrates/agent/src/db.rs
    • crates/agent/src/templates/system_prompt.hbsexperimental_system_prompt.hbs
    • crates/agent_settings/src/agent_settings.rscrates/agent_settings/src/agent_profile.rs
    • crates/agent_settings/src/prompts/compaction_prompt.txtsummarize_thread_prompt.txtsummarize_thread_detailed_prompt.txt
    • crates/agent_settings/src/user_agents_md.rs
    • crates/agent_skills/agent_skills.rscrates/agent_skills/builtin/create-skill/SKILL.md
    • crates/agent_servers/src/acp.rscrates/agent_servers/src/custom.rs
    • crates/acp_tools/src/acp_tools.rs
    • crates/telemetry/src/telemetry.rs
    • crates/prompt_store/src/prompts.rs
    • crates/project/src/trusted_worktrees.rs
    • crates/edit_prediction_cli/(~20 个文件)
    • crates/zeta_prompt/src/zeta_prompt.rs
    • crates/edit_prediction/src/edit_prediction.rs

一手源存档(sources/)

/Users/zhao/projects/self-wiki/ai-research/sources/harness/zed-agent/ 下:

  • NOTES.md — 完整逐维度调研笔记(含精确文件路径/行号)
  • artifacts/system_prompt.hbs — 生产系统提示 Handlebars 模板(19KB,已核实实际内容)
  • artifacts/experimental_system_prompt.hbs — 并行的实验性系统提示模板(12KB)
  • artifacts/compaction_prompt.txt — 压缩交接提示词(已核实:Goal/State/Context/Next/Pitfalls 五段式)
  • artifacts/summarize_thread_prompt.txtartifacts/summarize_thread_detailed_prompt.txt — 线程标题/摘要生成提示词
  • artifacts/ai-improvement-doc.md — 官方”Feedback and Training Data”文档页全文(CloakBrowser 抓取)

注:zed-repo/(clone 出的完整仓库,107MB)未入库,可用上述 commit SHA 重新 clone 复现。