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_turn(thread.rs:2617)派生一个执行 run_turn_internal(thread.rs:2681)的任务,其内部是一个 loop{}:
- 按需执行上下文压缩(见下);
- 构造 completion 请求并流式调用模型;
- 处理模型返回的工具调用(支持通过
FuturesUnordered并行执行多个工具调用); - 若本轮产生了工具结果则继续循环。
终止条件(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_ix,thread.rs:4246),并设有MIN_COMPACTION_CONTEXT_WINDOW = 80_000token 的下限(小上下文模型不做压缩)。压缩本身是一次独立的 LLM 调用,使用COMPACTION_PROMPT(已存档artifacts/compaction_prompt.txt)——要求模型输出 Goal / State / Context / Next / Pitfalls 五段式交接摘要,结果作为Message::Compaction标记插入线程。 - 会话持久化:本地 SQLite(
sqlez库)持久化整条线程(ThreadsDatabase/DbThread,db.rs),含完整消息历史与草稿输入(Thread.draft_prompt)。 - 长期/项目记忆:
ProjectContext/RulesFileContext(prompt_store/src/prompts.rs)按 worktree 加载首个匹配的规则文件,RULES_FILE_NAMES常量列出 9 种识别格式:.rules、.cursorrules、.windsurfrules、.clinerules、.github/copilot-instructions.md、AGENT.md、AGENTS.md、CLAUDE.md、GEMINI.md;另有独立的跨项目个人级~/AGENTS.md(user_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/Output、kind()、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 道准入闸门(否则被静默丢弃):
assets/settings/default.json中 profile 的工具白名单;- 权限 UI 完整性测试;
tool_feature_flag_enabled特性开关判定。
代表性工具文件(crates/agent/src/tools/):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,以及一组 LSP 驱动工具: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。
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.txt、summarize_thread_prompt.txt、summarize_thread_detailed_prompt.txt,均已存档并核实内容,如压缩提示词即为 Goal/State/Context/Next/Pitfalls 五段式要求)。
Router / 编排(任务分解、多 agent、子 agent)
两层机制:
- 线程内子 agent:
spawn_agent工具(spawn_agent_tool.rs)派生Thread::new_subagent,与父线程共享 project/templates/context-server-registry,但不继承父线程消息历史(调用时必须给出自包含的上下文),仅返回子 agent 的最终消息;支持并行委派与通过session_id复用会话。 - 跨进程外部 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-skill(crates/agent_skills/builtin/create-skill/SKILL.md),本身是一个”教你写 skill”的元 skill。注:这套体系与另一套完全独立的 Extension 系统(crates/extension*,管语言/主题/MCP-server-extension/agent-server-extension)正交,本次未深入。
自进化能力(自我改进 / 学习型记忆 / eval 驱动纠错)
两种截然不同的机制:
- Zeta 编辑预测模型:存在真实的离线 eval 驱动数据修正闭环。
edit_prediction_cli(epCLI,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.rs中ZetaFormat枚举的详细版本历史(V0112MiddleAtEnd→ … →V0608QwenMultiRegions等)是这条持续迭代的代码级证据。 - Chat/coding agent 本身:未发现自动化自我改进机制——没有 agent 根据轨迹结果自动重写自己 prompt/工具的证据;
experimental_system_prompt.hbs与生产版并存这一事实提示的是人工、非自动化的提示迭代。
可观测性(日志 / trace 格式)
dev: Open ACP Logs(crates/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 Profile(
agent_profile.rs):三个内置档位write/ask/minimal,各自在设置中有显式工具白名单;进入受限/不受信工作区时 profile 会自动降级为minimal(Thread.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.rs的ZetaFormat枚举是一份与 Zeta 系列模型共同演进的、带版本号和日期的 prompt 格式历史(V0112MiddleAtEnd…V0608QwenMultiRegions及更新版本),包含针对特定基座模型定制的格式变体(如V0331SeedCoderModelPy、V0608QwenMultiRegions对应 Qwen 的 FIM token)。Zeta2PromptInput/Zeta3PromptInput结构体把 LSP 派生的syntax_ranges、related_files、active_buffer_diagnostics,以及用户同意标志(can_collect_data、in_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/zetaHF 数据集,用于微调下一版 Zeta——这与edit_prediction_cli的Score/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 条)
- 完全开源、可源码验证:与 Claude Code / Cursor / Windsurf 等闭源二进制不同,Zed 的整个 agent 循环、工具协议、沙箱策略、prompt 模板均在公开仓库中可读可验证——本 dossier 的每条结论都可回溯到具体文件/行号,而非从行为推断。
- ACP 作为多 agent 编排的第一公民:多数 harness 的”多 agent”停留在同进程内的子 agent 委派(本仓库的
spawn_agent也是如此),但 Zed 额外建了一套跨进程 JSON-RPC 协议(ACP),把 Claude Code、Codex、Gemini CLI 等外部竞品 agent 接进同一套 UI/权限/沙箱基础设施中作为对等体运行,这是”Parallel Agents”的真正实现方式,在同类 harness 中未见先例。 - 两套”模型协同设计”完全分离:通用编码/对话能力保持模型无关(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.rscrates/agent/src/agent.rscrates/agent/src/tools.rscrates/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.rscrates/agent/src/sandboxing.rscrates/agent/src/thread_store.rs、crates/agent/src/db.rscrates/agent/src/templates/system_prompt.hbs、experimental_system_prompt.hbscrates/agent_settings/src/agent_settings.rs、crates/agent_settings/src/agent_profile.rscrates/agent_settings/src/prompts/compaction_prompt.txt、summarize_thread_prompt.txt、summarize_thread_detailed_prompt.txtcrates/agent_settings/src/user_agents_md.rscrates/agent_skills/agent_skills.rs、crates/agent_skills/builtin/create-skill/SKILL.mdcrates/agent_servers/src/acp.rs、crates/agent_servers/src/custom.rscrates/acp_tools/src/acp_tools.rscrates/telemetry/src/telemetry.rscrates/prompt_store/src/prompts.rscrates/project/src/trusted_worktrees.rscrates/edit_prediction_cli/(~20 个文件)crates/zeta_prompt/src/zeta_prompt.rscrates/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.txt、artifacts/summarize_thread_detailed_prompt.txt— 线程标题/摘要生成提示词artifacts/ai-improvement-doc.md— 官方”Feedback and Training Data”文档页全文(CloakBrowser 抓取)
注:zed-repo/(clone 出的完整仓库,107MB)未入库,可用上述 commit SHA 重新 clone 复现。