为什么 External Agent 无法继承你的上下文
Zed 托管线程;Agent 拥有其他一切
最具定义性的一句话在文档的第一段:“Zed 在 Agent Panel 和 Threads Sidebar 中托管线程,而 External Agent 通常拥有自己的运行环境、身份验证、模型选择、工具和原生配置。”
这是一个清晰的架构划分,它解释了几乎所有的意外情况。面板是 Zed 的。对话列表是 Zed 的。Agent 是一个通过 ACP 进行通信的独立进程,它带来了自己的一切。
边界表用“取决于”回答了大多数问题
Zed 发布了一个配置边界表。请按字面意思阅读,包括那些留有余地的词:
| 能力 | External Agent 线程中的行为 |
|---|---|
| 模型/服务商配置 | “通常由 External Agent 拥有” |
| 身份验证/API 密钥/订阅 | “通常由 External Agent 拥有” |
| Zed Agent 配置集 (profiles) | “除非集成另有说明,否则不适用” |
| Zed Skills | “不作为 Zed Skills 适用” |
| 原生 agent 技能/指令 | “取决于 agent” |
| Zed MCP 服务器 | “可能会通过 ACP 转发” |
| 原生 MCP 配置 | “也可能被 agent 读取” |
| 工具权限 | “Zed ACP/工具转发权限可能适用;原生工具权限取决于 agent” |
有两行是明确否定的:Zed Agent 配置集不适用,且 Zed Skills 不作为 Zed Skills 适用。其他所有内容都是“通常”、“可能”或“取决于 agent”。
这并不是为了模糊而模糊。Zed 无法承诺第三方进程会如何处理配置文件,因此它拒绝做出承诺。但这意味着对于“我的指令会被读取吗?”这个问题,从 Zed 的角度来看确实是未知的,你必须针对每个 agent 进行确认。
即使是你敢打包票的一个文件也留有余地
Claude Agent 部分写道:“Claude 特定的文件(如 CLAUDE.md)可能会被 Claude Agent 直接读取。”
可能会。 而不是“会被”。原因同样是架构上的——agent 通过其自身的运行环境读取自己的配置,因此你的文件是否被读取取决于该 agent 是如何启动的,以及它将什么视为其工作目录。这与为什么 agent 会忽略你的指令文件中提到的普遍问题属于同一类。
凭据和远程项目又增加了一层复杂性
“保存在本地钥匙串中的 Zed LLM 服务商 API 密钥不会自动等同于 External Agent 的凭据。”对于远程工作:“External Agent 可能会在本地、远程或通过其自身的登录流程读取凭据。”
因此,为 Zed Agent 配置的 Anthropic API 密钥“不会自动配置 Claude Agent”,而 Cursor 订阅“也不会配置 Zed 的 LLM 服务商设置”。每个 agent 都需要自行进行身份验证。
人们尝试过的方法
假设 Zed Skills 可以沿用。 它们不能——表格写得很清楚。为 Zed Agent 编写的 Skills 在外部 agent 线程中无法作为 Zed Skills 使用,而该 agent 是否有自己的等效功能则“取决于 agent”。
设置 Zed Agent 配置集并期望它能约束外部 agent。 配置集“除非集成另有说明,否则不适用”。这里的工具权限尤其值得检查,因为原生工具权限取决于 agent,而不是你的 Zed 配置。
在 Zed 中配置一次 MCP 就觉得大功告成。 Zed MCP 服务器“可能会通过 ACP 转发”,原生 MCP 配置“也可能被 agent 读取”。两个“可能”,这意味着实际的应对方法是测试而不是假设——这是 MCP 层在设计上是无状态的 的一种变体。
导入旧线程并期望实现无缝衔接。 Zed 可以从配置的外部 agent 导入现有线程,这是一个真实的功能:“Zed 通过 ACP 连接到每个选定的 agent,并添加你历史记录中尚未包含的会话。”但请注意你得到的是什么——“导入的线程是归档条目;打开一个以恢复它并从你离开的地方继续”——并注意什么被跳过了:“没有关联工作目录的会话会被跳过。”
得出 Zed External Agents 完全没有上下文的结论。 如果你只看否定行,这是可以理解的,但这是错误的。每个外部 agent 都有自己的指令系统、自己的记忆(如果有的话)以及自己的原生配置——关键在于这些是属于 agent 的,而不是 Zed 的。上下文是存在的,它只是不来自编辑器。
通过统一使用一个 agent 来解决问题。 这确实有效,但这也放弃了你最初安装 External Agents 的初衷。该功能的存在是为了让你能针对一个任务启动 Claude Agent 线程,针对另一个任务启动 Codex 线程;为了避免维护两个指令层而缩减为单个 agent,等于是为灵活性付出了代价却不去使用它。
将相同的指令文件复制到每个 agent 的位置。 这是显而易见的权宜之计,大概能维持一个月。然后,其中一个副本得到了修正,而其他副本没有,结果你就会在同一个编辑器中看到两个 agent 对你的规范产生自信的分歧——而且没有任何报错,因为每个 agent 都在忠实地读取它被赋予的文件。
解决方法:确定每个 Agent 读取什么,然后将共享的部分放在两者都能访问的地方
步骤 1:测试边界,而不是凭空推断
对于你使用的每个外部 agent,进行一次刻意的探测,而不是盲目相信表格中任何一个方向的含糊之词。
在你认为 agent 会读取的文件中放入一条独特且无害的指令——例如特定的格式偏好、一个无意义的变量名偏好,任何你会注意到的内容。从 Agent Panel 启动一个外部 agent 线程,并提出一个问题,其答案能够揭示该指令是否生效。
对每个层级分别进行此操作:agent 自身的指令文件、原生 MCP 配置,以及 agent 原生支持的任何技能。你最终会得到一个简短的、针对每个 agent 的表格,记录在你的设置中哪些是真正起作用的,这是 Zed 文档无法为你编写的内容,因为它取决于 agent 是如何安装和启动的。
顺便检查一下工作目录。Zed 的线程导入会跳过“没有关联工作目录的会话”,这强烈暗示了工作目录在此集成中起着关键支撑作用——而且指令文件的发现通常是相对于它的。
步骤 2:原生配置每个 agent 自己的层级
一旦你知道了 agent 会读取什么,就在那里进行配置,而不是在 Zed 中。
对于 Claude Agent,这意味着它自己的身份验证(在 Claude Agent 线程中运行 /login)和 Claude 原生配置。对于 Codex,这意味着“取决于安装的版本和环境,使用 ChatGPT 登录、Codex API 密钥、OpenAI API 密钥或 Codex 原生配置”。对于 Gemini CLI,使用它自己的 Google 或 Vertex AI 登录。对于 OpenCode,使用它自己的身份验证、模型选择和订阅行为。对于 Poolside,运行 pool login。Zed 将这些都归为 agent 拥有,而对抗这种架构最快的方式就是试图在编辑器中对其进行集中管理。
如果你正在开发一个 ACP agent 或运行一个不在注册表中的 agent,Custom Agents 路径会在你的设置文件中添加一个 agent_servers 条目——同样的边界规则也适用于它。
步骤 3:将两个 agent 都需要的知识放在两者之外
步骤 1 和步骤 2 让每个 agent 都能正常工作。但它们会让你不得不维护 N 个平行的指令层(每个 agent 一个),且它们都在描述同一个项目。
这就是多 agent 编辑器的实际成本,这并不是 Zed 的 bug——它是“External Agent 拥有其原生配置”这一事实的必然结果。唯一能将这 N 个副本合并为一个的方法,是一个不属于任何 agent 的存储库。
一个记忆层可以做到这一点。它既不是 Zed 设置,也不是 agent 配置,因此它不在乎边界表的哪一行适用。MemoryLake 只需三步即可完成设置。
步骤 1:创建 API 密钥
登录并在你的仪表盘中生成一个 API 密钥。因为该凭据属于你而不是某个 agent,所以它避开了 Zed 文档中提到的身份验证碎片化问题——Zed 钥匙串密钥、Claude Agent 身份验证和 Codex 身份验证都是独立的,而这个密钥与它们都无关。

步骤 2:上传你的第一批记忆
放入你一直在重复的项目知识:规范、架构决策及其原因、领域术语,以及你在每个新线程中都会重复声明的固定偏好。任何你写进两个不同 agent 指令文件中的内容都是候选对象。

将每个 agent 真正特有的配置保留在它该在的地方。这里存放的是事实,而不是连接配置。
步骤 3:连接你的 AI 和 agent
将每个 agent 指向该存储库。在任务进行到一半时,从 Claude Agent 线程切换到 Codex 线程,不再意味着需要重新解释项目——这正是 Agent Panel 带来便利而边界却使其变得昂贵的地方。

这在实践中带来了什么改变
第一个改变是切换 agent 变得非常廉价。Zed 的核心卖点就是你可以为每个线程选择合适的 agent;只有在切换线程不意味着重新建立上下文的情况下,这才能发挥作用。而目前通常都需要重新建立。
第二个改变是边界表不再是意外的来源。当持久知识存在于外部时,那些留有余地的行就不那么重要了——你仍然关心身份验证和工具权限,但你不再关心某个特定的指令文件是否被读取,因为事实并不在其中。
第三个改变是线程导入变得真正有用。导入的线程作为归档条目出现,你打开它们即可继续;当项目知识存在于共享层中时,继续旧线程就不再取决于原始上下文中恰好有多少内容保留在记录中。这也是共享层通常有助于 跨 agent 记忆 的原因。
Zed 中 External Agent 线程的最佳实践
- 将边界表视为清单,而不是规范。 有两行是明确否定的;其余的是你通过测试确定的每个 agent 的实际情况。
- 针对每个 agent 配置身份验证,不要指望共享。 Zed 钥匙串密钥不会配置 Claude Agent;Cursor 订阅也不会配置 Zed 的服务商设置。
- 不要移植 Zed Skills。 它们在外部线程中不作为 Zed Skills 适用。请检查 agent 是否有原生等效功能。
- 验证 MCP 转发,而不是凭空假设。 Zed MCP 服务器可能会通过 ACP 转发,原生配置也可能被读取——两个“可能”值得进行一次测试。
- 注意工作目录。 没有工作目录的会话在导入时会被跳过,且指令发现通常依赖于它。
- 将导入的线程视为归档。 打开一个以恢复它;重新导入是安全的,因为历史记录中已有的线程会被跳过。
- 保持项目知识的单一权威来源。 如果一段内容同时存在于
CLAUDE.md和 Codex 指令文件中,那么它不应该存在于这两者中的任何一个。 - 更新后重新测试。 Codex 的身份验证选项会“取决于安装的版本和环境”而有所不同,这是一个强烈的信号,表明这些边界是会发生变化的。
结论
Zed 的 External Agents 文档之所以异常可信,恰恰是因为它们拒绝过度承诺。当一个独立的进程拥有自己的配置时,“通常”、“可能”和“取决于 agent”才是正确的答案,而假装并非如此只会把意外推迟发生。
实际的理解是:让每个 agent 拥有自己的连接配置,停止尝试在编辑器中对其进行集中管理,并将真正应该共享的唯一东西——你的团队对项目的了解——完全从 agent 中抽离出来。