# AI 代理交接：让活跃会话安全过夜

AI 代理交接失败，往往是因为离岗工程师交接的是一段描述，而不是责任。说一句「代理还在处理部署」，几乎无法为下一位工程师提供有效信息。他们需要知道哪个进程仍拥有权限，可以访问什么，哪个请求在等待人工处理，证据保存在哪里，以及如何停止或恢复这项工作。

棘手之处在于，即使没有人盯着终端，代理也可能继续执行操作。它可能拥有活跃的 SSH 连接、持久运行的后台任务、环境中的令牌、等待笔记本电脑上有人处理的审批提示，或者一项稍后才会显现的部分远程变更。好的交接会把这些内容转化为边界清晰的运行状态。糟糕的交接则只是转移不确定性，却把它称为连续性。

## 交接需要责任记录，而不是聊天摘要

可用的交接应分别记录权限和状态，因为两者的失效方式不同。状态告诉接班工程师代理已经做了什么，以及计划做什么。权限告诉他们代理仍然能做什么。团队通常会记录前者，却遗漏后者，这正是一次看似无害的继续运行最终变成未经审核的生产写入的原因。

趁离岗工程师还可以检查机器并解释决策时，就写好记录。不要等有人被告警叫醒后，再凭记忆重建交接内容。一份包含准确标识符的短文档，胜过一篇充满自信却缺少细节的长篇叙述。

为每次活跃运行记录以下信息：

- 代理进程 ID、会话 ID、工作目录和启动时间。
- 离岗的负责人、接班负责人，以及责任变更的时间。
- 预期任务、最近完成的外部操作，以及下一项拟执行的外部操作。
- 所有可访问的目标，例如主机别名、API 基础 URL、代码仓库、工单或部署环境。
- 停止命令、恢复命令和证据位置。

不要写「拥有测试环境访问权限」，如果你可以写成「进程 4182 可以通过获批会话 S-204 调用测试环境部署 API」。宽泛的标签会隐藏决定接班人能否安全继续操作的细节。

责任记录还必须明确说明每次运行的处理方式：继续、暂停、取消，或操作前检查。「监控」不算一种处理方式，因为它让下一位工程师自行猜测是否有权介入。

只有当接班工程师确认了记录，并且能自行找到正在运行的进程时，交接才算完成。发到繁忙频道中的消息只是送达，不是责任转移。如果没有人接收责任，且工作允许，离岗工程师应暂停工作或撤销外部权限。

## 更换负责人前，先找出仍在生效的权限

没有找到会话，就无法转移它的控制权。先查看本地进程树，再检查连接、环境暴露情况，以及在当前终端之外创建的任务。代理界面可能显示任务已完成，但子进程、终端复用器面板或 SSH 主连接仍然活跃。

在 macOS 或 Linux 上，可以从简单命令开始，并把输出保存到交接证据中。将示例标识符替换成实际的代理进程或账户。

```sh
ps -axo pid,ppid,user,lstart,command | grep -E '[a]gent|[c]laude|[m]cp'
pgrep -P 4182 -alf
lsof -nP -p 4182
```

第一条命令会返回类似这样的进程行：

```text
4182  901 alex  Tue Mar 18 22:14:07 2025  agent-runner --task deploy-api
```

第二条命令会显示子进程，第三条会显示打开的文件和网络端点。留意继承的 shell、打开的 Unix 套接字、TCP 连接、本地凭据文件，以及连接到审批助手的管道。不要把包含秘密的命令输出粘贴到工单中。应将它保存在获批的事故记录中，或者遮盖敏感值，同时保留文件路径和连接细节。

SSH 需要单独检查，因为它的连接模型可能超出单条命令的生命周期。OpenSSH 的 `ssh_config` 手册说明，`ControlPersist` 可以在初始客户端退出后继续保持主连接。这种行为有助于重复执行命令，但在交接时意味着「命令已结束」并不能证明远程访问已经终止。

检查主套接字和转发进程：

```sh
ps -axo pid,ppid,command | grep '[s]sh'
find ~/.ssh -type s -name '*control*' -print
lsof -nP -iTCP -sTCP:ESTABLISHED | grep '[s]sh'
```

然后提出一个比「它是否还连着」更重要的问题：远端现在还能执行什么？本地客户端消失后，远程构建仍可能继续。部署命令可能已经应用了一项变更，却在报告下一项之前失败。决定是否恢复前，先记录远程任务 ID、部署记录或服务状态。

不要把开放端口等同于恶意活动。但每个无法解释的开放通道都应视为尚未解决的权限问题。接班工程师必须弄清它、关闭它，或将其升级处理。

## 待处理审批必须有明确去向和过期时间

待处理审批只是拟执行的操作，不是离岗工程师留下的预约。接班人不应接手一个审批提示，只看到一句「如果出现就点一下」。这句话要求他们在没有上下文的情况下替某个决定背书。

每个待处理请求都应附带五项信息：

1. 确切操作，包括方法和目标。「更新服务」不够具体。「向 production-api 的部署端点发送 POST 请求」才足以开始核查。
2. 操作原因，以及导致它成为必要操作的条件。
3. 预期结果，以及确认结果的可观察证据。
4. 请求必须过期并重新生成的截止时间。
5. 有权批准或拒绝请求的指定人员。

缺少这些信息的审批应当过期。重新发起请求的成本低于从盲目写入中恢复。在平静的班次中，这条规则可能显得过于繁琐。等到审批卡撑过笔记本锁屏、重新连接和事故范围变化之后，它就会显得理所当然。

不要借交接扩大审批权限。离岗工程师有权批准测试环境变更，并不意味着接班工程师就有权批准生产环境中的相同变更。请求等待期间，范围可能已经发生变化。人在操作前，应重新检查目标、请求内容和当前事故状态。

时间安排也很重要。如果工具可以在代理生成请求很久之后才提示操作，就应把过期时间纳入请求设计。过期审批可能作用于已经恢复、发生故障转移或被人工修改的系统。提示中描述的操作在技术上可能有效，但已经不再是正确的运维决策。

相比附上一份庞大的对话记录，我更推荐一份简短的审批说明。下一位工程师应该能在一分钟内回答三个问题：会发生什么，发生在哪里，以及为什么现在仍然需要发生？如果回答不了，就拒绝请求，让代理先检查当前状态，再提出新的操作。

## 会话所有权必须与秘密所有权分开

监督会话的人不需要拥有该会话能够使用的每一项凭据。混淆这两个角色，会造成一种常见且代价高昂的混乱：有人为了「交接方便」把令牌导出到 shell 配置文件中，结果令牌的生命周期超过了事故、工程师的职责，以及人们对它为何存在的记忆。

正确的转移只改变谁可以监督、批准、暂停或撤销操作。它不应通过聊天、笔记或代理提示词传递 API 令牌、SSH 私钥、浏览器 Cookie 或临时云凭据。接班人获得的是会话引用和操作所需的证据。执行操作的系统或服务继续保留秘密。

当离岗工程师留下一个打开的终端时，这种区别尤其重要。未锁定的 shell 不是合法的转移机制。它会把一堆继承状态交给下一位：导出的变量、命令历史、缓存凭据、shell 函数、端口转发和未完成的命令。其中一些状态可能有用，但没有任何一项能清楚地说明责任归属。

可以采用以下两种方式之一：

- 只有当当前操作已被理解、范围明确、接班工程师已经接收责任，并且停止操作会造成更糟糕的结果时，才继续使用现有会话。
- 当任务属于调查性质、权限范围较大、提示历史很重要，或代理已经闲置时，停止旧会话，由接班工程师启动新会话。

第二种方式通常比团队承认的更安全。人们抗拒它，是因为担心失去上下文。应将上下文保存在交接资料中，而不是保存在未经检查的进程里。新进程拥有清晰的审批边界，也能明确新负责人的责任。

对于使用 Sallyport 的团队，代理可以执行 HTTP 和 SSH 操作，却无需获得底层秘密，因此换班时可以转移监督责任，而不是转移凭据材料。其保险库锁定后会拒绝操作，为接班工程师提供一个明确的暂停点，让他们在授权任何继续操作前先进行审查。

不要把分离视为免疫。如果接班人可以批准会话中的操作，他们仍然需要遵守范围和证据方面的纪律。让秘密离开提示词，可以避免一类故障，但不能让不安全的请求变得安全。

## 恢复必须从遏制开始，而不是继续运行

当代理运行变得安静，或离岗工程师无法联系时，接班工程师首先应阻止新的外部变更。不要花十分钟试图恢复原来的对话上下文，却让后台进程继续写入。

恢复有两条线：保存证据，以及确认当前状态。如果进程或主机可能消失，应按这个顺序执行。将会话标识符、终端输出、任务定义、审批信息、进程列表和审计引用复制到事故记录中。然后根据系统的常规控制措施，停止、撤销或锁定操作路径。

完成遏制后，检查目标系统。代理声称调用失败，可信度低于目标侧记录。HTTP 超时可能意味着服务器拒绝请求、接受了一次请求，或接受请求后丢失了响应。没有幂等机制就重试，可能会重复执行操作。

使用目标系统自身的证据：

- 对于 API 写入，检查对象、变更记录、请求 ID 或幂等记录。
- 对于 SSH 操作，检查远程进程、服务状态、包管理器历史或部署标记。
- 对于代码变更，分别检查代码仓库差异、提交、CI 运行结果和部署状态。
- 对于排队操作，再提交任务前检查队列和工作进程状态。

重试请求和恢复操作并不是一回事。重试只是重复一次传输尝试。恢复则要先确认底层状态是否发生变化，再决定下一步。代理把超时描述成点击「再次运行」的邀请时，团队很容易混淆这两个概念。超时不是邀请。

恢复记录应写明最后一次可信观察，而不是代理最后说了什么。例如：「代理在请求部署 D42 后超时。部署服务记录显示 D42 正在两台实例上运行。新的提交已于 02:17 暂停。」这样，下一位操作人员就有了一个基于事实的恢复起点。

如果无法确认状态，就升级事故并限制权限。部署停滞通常可以容忍，但重复执行数据库迁移、重复支付或误删生产数据可能无法承受。

## 接受交接前，用证据核对记录

交接文档是操作人员的解释，审计记录则是系统记录行为的证据。两者都需要，但不能把它们视为同一回事。

接班工程师接受活跃会话前，应将责任记录与未经离岗工程师手工编辑的证据进行比较。检查会话起止时间、目标名称、操作顺序和审批处理方式。发现不一致时，要在有人继续运行前调查清楚。

哈希链有助于发现记录删除和重排。它不能证明意图、正确性或某次审批是否明智。明确说明这一限制是有益的。加密连续性回答的是「记录的序列是否保持完整」，而不是「我们是否应该发送那个请求」。

使用 Sallyport 时，团队可以用以下命令离线验证加密审计链：

```sh
sp audit verify
```

将验证结果与运行时间、检查过的日志范围一起保存到交接记录旁边。验证不需要访问保险库，这对接班工程师很有帮助，因为他们可以在解锁任何操作权限前检查记录是否连续。

不要养成把大段审计摘录复制到聊天中的习惯。即使日志不包含秘密，也经常包含敏感的运维元数据。应保存获批记录的引用，只引用解释交接所需的小段内容，并让接班工程师通过正常的事故路径访问记录。

审计检查还可以发现一个普通但严重的问题：工程师可能启动了两个任务相似的代理，却忘记了其中一个。进程列表显示当前还存在什么，审计序列显示每次运行已经尝试过什么。接受责任前，两者都要阅读。

## 即使没人记得这次事故，交接资料也应能正常工作

有用的资料应该让五分钟前还在睡觉的工程师做出安全决定。它不应要求对方翻阅数百条聊天消息，或重新打开一份没有边界的提示词记录。将资料放在事故记录附近，每次都使用相同的字段顺序，并在权限发生变化时更新。

可以从以下模板开始：

```text
事故或变更：
离岗负责人 / 接班负责人 / 转移时间：

代理运行：
- 会话 ID 和本地 PID：
- 工作区和任务引用：
- 当前状态：继续 | 暂停 | 取消 | 检查
- 最后确认的外部操作：
- 下一项拟执行的操作：

权限：
- 此运行可以访问的目标：
- 审批状态和过期时间：
- 会话撤销或停止方法：
- 凭据仍由谁持有：

证据：
- 活动或审计记录引用：
- 已检查的目标侧证据：
- 进程和连接捕获记录：

恢复：
- 已知的部分状态：
- 接班负责人可以执行的安全第一步：
- 升级负责人和触发条件：
```

「安全第一步」这一行很有价值。写下一个能够收集状态、却不会增加影响范围的操作，例如检查部署记录、读取队列深度或比较服务版本。不要写「继续调查」，这句话没有任何操作边界。

资料还应说明代理启动后发生了什么变化。可能开始了发布冻结，数据库副本出现延迟，客户报告了某种现象，或者另一位工程师进行了人工修正。代理依据接收到的上下文行动，接班人则需要了解提示词开始后才出现的上下文。

语言要保持事实性。「代理似乎糊涂了」只能告诉接班人不要信任它，却没有提供任何可验证内容。「服务显示请求 ID 7f3 已被接受后，代理再次提出相同的 POST」则明确指出了重复风险，并提示下一步应检查什么。

## 忽视时间因素，换班就会产生授权空档

当离岗工程师心理上已经结束值班，但其会话仍能执行操作时，空档就出现了。如果接班工程师尚未接收责任、看不到审批状态，或以为代理只是在读取数据，空档会进一步扩大。在这段时间里，进程仍拥有权限，却没有一名专注于此的负责人。

常见的失败过程如下。值班结束时，工程师要求代理修复一次失败的部署。代理打开 SSH 连接，编辑配置文件，并等待重启服务的审批。工程师在聊天中写下「等待重启，应该没问题」，然后下线。

下一位工程师一小时后看到提示。在这段时间里，人工缓解措施改变了服务拓扑。此时待处理的重启会影响一个承载流量的节点，而上一位工程师并不知道这一点。审批描述的命令在技术上仍然有效，但支持该命令的实际情况已经变化。

这种失败不需要工具遭到入侵，也不一定源于粗心。问题在于把授权当成永久不变的东西，而运维上下文却一直在变化。审批应绑定到短期请求和当前负责人。当这两个条件都不成立时，会话就应失去权限。

设置明确的交接截止时间。如果接班工程师在该时间前没有接收会话，就暂停代理并使所有未处理审批失效。如果任务无法安全暂停，应在事故发生前的运行手册中写明这一事实，定义谁可以接收它，并设置直接的升级路径。不要等到换班时才发现例外。

有些团队让所有会话持续运行，因为重启代理需要时间。这种建议很受欢迎，因为它保留了本地上下文，也避免重新解释任务。但对于范围较大或权限不明确的任务，它是错误的。启动一个干净会话只需几分钟，远比解释一个负责人已经下线后仍修改系统的遗留进程便宜。

## 接班工程师应按固定顺序承担责任

交接发生时，注意力通常是分散的，因此接班工程师需要一套可重复的接收流程。这不是为平静日子准备的官僚流程，而是为了防止刚被告警叫醒的人在弄清哪些权限仍然有效前就批准操作。

按以下顺序执行：

1. 阅读当前事故状态和责任记录，然后确认离岗工程师与转移时间。
2. 找到指定的进程或会话，检查活跃连接、子进程和待处理请求。
3. 将记录与审计证据及目标侧状态进行比较。
4. 选择继续、暂停或取消。所有不再有明确且当前理由的待处理审批都应拒绝。
5. 记录责任接收、第一项安全操作和下一次检查时间。

顺序很重要。如果先批准、后检查，就已经接受了最大的风险。如果在保存会话记录前先检查目标，进程退出或机器重启时可能会丢失证据。固定顺序可以抵御「先让它运行起来再说」的自然冲动。

离岗工程师也有一项固定责任：在接班人接收责任或会话停止前保持可联系。如果覆盖时间在此之前结束，应升级处理，而不是悄悄留下一个仍在运行的代理。值班表指定的是具体负责人，不是寄希望于某个人会注意到提示。

在一次夜间故障迫使你面对问题之前，就把这些规则纳入事故流程。先在一份现有交接记录中加入责任字段，并要求每次代理运行都明确处理方式。第一次发现无法解释的 SSH 连接，或发现没有负责人的审批时，你找到的就是真实缺口，而不是理论风险。
