AI Agent 需要的不只是终端,而是可恢复的持久化会话

2026-07-30 12 预计阅读时间: 1 分钟
来源: my.oschina.net AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:8 分钟

Harness 概念提出者宣布创业,瞄准的是一个正在变得具体的基础设施缺口:交互式开发、CI 自动化和多个 AI Agent 并行执行,目前各自维护进程、工作目录与日志,但它们本质上都在操作同一种东西,即一段可以持续运行、断线重连、转交控制权的开发会话。

为什么普通终端不够用

人类使用终端时,可以记住刚才执行过什么、当前目录在哪里,以及某个失败是否值得重试。AI Agent 没有这种天然连续性。一旦模型调用结束、网络连接中断或调度器重新分配任务,终端里的隐含状态就可能丢失。

一个面向 Agent 的持久化会话至少需要保存以下信息:

  • 稳定的会话 ID,而不是依赖某次 SSH 或 WebSocket 连接
  • PTY、环境变量、当前目录和仍在运行的子进程
  • 标准输入输出记录,以及可以按位置继续读取的事件流
  • 工作区、Git 分支和构建产物之间的对应关系
  • 当前控制者、租约期限、权限和密钥使用范围
  • 超时、退出码、资源消耗与人工接管记录

这里要区分两个概念。终端持久化意味着客户端断开后进程仍然运行;任务持久化则意味着主机重启后,系统还能根据日志、检查点和工作区恢复任务。tmux 能解决前者的一部分,却不能单独解决后者。

把开发、CI 和 Agent 放进同一种会话模型

统一会话体系的价值,不是让所有工具共享一个巨大的 shell,而是让它们遵守同一套生命周期协议。例如,一次会话可以依次经历:

created -> running -> waiting_for_input -> detached -> resumed -> completed
                                      \-> cancelled
                                      \-> expired

开发者可以在本地创建会话,Agent 接手执行测试,CI 在同一工作区验证结果;遇到需要判断的错误时,会话进入 waiting_for_input,再由人类附加终端处理。控制权可以变化,但会话 ID、输出记录和文件状态保持连续。

并行 Agent 则不应直接写入同一个工作目录。更稳妥的边界是“一项任务一个会话、一个 Git worktree、一个资源配额”。共享仓库历史没有问题,共享未提交文件通常会制造覆盖和竞态。

可以这样实践:用 tmux 做一个最小原型

下面的脚本不是来源中产品的接口,而是一个可运行的本地原型。它用 tmux 保持进程,用目录保存日志,并为会话提供 startrunattachtailstop 操作。

运行前需要安装 tmux。将下面内容保存为 agent-session,然后执行 chmod +x agent-session

#!/usr/bin/env bash
set -euo pipefail

STATE_DIR="${AGENT_SESSION_HOME:-$HOME/.agent-sessions}"
mkdir -p "$STATE_DIR"

usage() {
  echo "usage: $0 {start|run|attach|tail|list|stop} [name] [args...]" >&2
  exit 2
}

validate_name() {
  [[ "$1" =~ ^[A-Za-z0-9._-]+$ ]] || {
    echo "invalid session name: $1" >&2
    exit 2
  }
}

command="${1:-}"
case "$command" in
  start)
    name="${2:-}"; workspace="${3:-$PWD}"
    [[ -n "$name" ]] || usage
    validate_name "$name"
    workspace="$(cd "$workspace" && pwd)"
    session="agent-$name"
    log_file="$STATE_DIR/$name.log"

    tmux new-session -d -s "$session" -c "$workspace"
    printf -v log_command 'cat >> %q' "$log_file"
    tmux pipe-pane -o -t "$session" "$log_command"
    printf '%s\n' "$workspace" > "$STATE_DIR/$name.workspace"
    echo "started $name in $workspace"
    ;;
  run)
    name="${2:-}"; shift 2 || true
    [[ -n "$name" && "$#" -gt 0 ]] || usage
    validate_name "$name"
    tmux send-keys -t "agent-$name" -- "$*" C-m
    ;;
  attach)
    name="${2:-}"; [[ -n "$name" ]] || usage
    validate_name "$name"
    exec tmux attach-session -t "agent-$name"
    ;;
  tail)
    name="${2:-}"; [[ -n "$name" ]] || usage
    validate_name "$name"
    touch "$STATE_DIR/$name.log"
    exec tail -f "$STATE_DIR/$name.log"
    ;;
  list)
    tmux list-sessions -F '#S #{session_created_string}' 2>/dev/null || true
    ;;
  stop)
    name="${2:-}"; [[ -n "$name" ]] || usage
    validate_name "$name"
    tmux kill-session -t "agent-$name"
    ;;
  *) usage ;;
esac

可以先用普通命令验证会话确实能在客户端退出后继续运行:

./agent-session start build "$PWD"
./agent-session run build 'while true; do date; sleep 5; done'
./agent-session tail build

Ctrl+C 只会退出日志查看,后台循环仍在运行。执行 ./agent-session attach build 可以接管终端,执行 ./agent-session stop build 才会结束会话。

并行任务可以结合 Git worktree 隔离:

git worktree add ../project-agent-a -b agent/a
git worktree add ../project-agent-b -b agent/b

./agent-session start agent-a ../project-agent-a
./agent-session start agent-b ../project-agent-b

./agent-session run agent-a 'npm test'
./agent-session run agent-b 'npm run lint'

接入真实 Agent 时,可以把 npm test 替换成团队使用的 Agent CLI,但不要把未经审查的模型输出直接拼接成高权限 shell 命令。命令参数、工作目录和环境变量都应经过策略校验。

从原型走向生产系统

生产级持久化终端还需要处理 tmux 没有覆盖的问题:主机故障恢复、跨节点调度、输出背压、密钥轮换、文件快照、审计保留和租约冲突。尤其需要防止两个 Agent 同时获得写控制权,或已经取消的任务继续占用凭据。

落地时可以按以下顺序推进:

  1. 先统一会话 ID、状态机和日志格式,不急着统一所有执行环境。
  2. 为每个 Agent 分配独立 worktree、容器或虚拟机,并设置 CPU、内存和执行时间上限。
  3. 将终端输出写入追加式事件流,同时把重要结果保存为结构化产物。
  4. 使用短期凭据和命令策略,默认阻止访问宿主机、生产网络与全局密钥。
  5. 设计人工接管流程,明确接管后 Agent 是暂停、只读还是继续运行。
  6. 用故障演练验证断网、模型超时、进程僵死和节点重启后的行为。

持久化终端真正要统一的不是界面,而是执行上下文。只有当会话可以被定位、观察、暂停、恢复和审计时,交互式开发、CI 与 AI Agent 才可能安全地使用同一套基础设施。


相关推荐