Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

运行生命周期

本章从用户视角出发,完整描述“用户发一条消息后,系统到底做了什么“。系统采用 SessionWorker(会话工作进程)模式——容器以 Deployment(部署)方式长驻运行,通过 WebSocket(网络套接字) 双向通道与 Backend 实时通信。


1. SessionWorker 核心特性

特性说明
K8s 资源类型Deployment(部署)+ Service(服务)→ 长驻 Pod
容器生命周期跨越多轮对话持续运行,按空闲策略自动回收
通信方式WebSocket 双向:Worker 启动后主动连接 Backend WS 端点,消息和事件通过同一持久连接传输
实时交互✅ 支持 agentcore 向用户提问、请求权限确认
流式输出✅ token 片段实时推送,用户即时看到推理过程
状态连续性内存中直接保持 + Worker 通过协议把 checkpoint 持久化到 Backend
安全机制非 root 运行、丢弃所有 capabilities、seccomp 限制

2. 首次启动:从用户消息到容器就绪

sequenceDiagram
    participant U as 用户
    participant H as Helper(本地前端)
    participant B as Backend(本地后端)
    participant K as K3s 编排器
    participant W as SessionWorker(长驻容器)

    rect rgb(230, 245, 255)
    Note over U,W: ① 创建会话
    U->>H: 选择智能体,开始对话
    H->>B: POST /api/v1/sessions
    B->>B: 创建 SessionRecord,初始化会话状态目录
    B-->>H: 返回 session_id
    end

    rect rgb(255, 245, 230)
    Note over U,W: ② 发送首条消息
    U->>H: 输入消息
    H->>B: POST /api/v1/runs
    Note over B: 校验会话 → 解析 Agent 包<br/>→ 合并 API 密钥 → 查库生成 run-context.json<br/>→ 组装 LaunchPlan
    end

    rect rgb(230, 255, 230)
    Note over B,W: ③ K3s 编排器创建资源
    B->>K: 提交 LaunchPlan
    K->>K: 渲染 Deployment + Service
    K->>W: 创建 ConfigMap(包文件)
    K->>W: 创建 Secret(API 密钥)
    K->>W: 创建 Deployment(Worker Pod)
    K->>W: 创建 Service(探针 + 备用端口)
    end

    rect rgb(255, 230, 255)
    Note over W: ④ Worker 启动流程
    W->>W: 创建工作目录
    W->>W: 写入运行时元数据文件
    W->>W: touch /tmp/agent-store-worker.ready
    W->>W: 注册 TERM 信号处理器
    W->>W: 启动心跳循环(每 30 秒)
    W->>W: 启动 agentcore 进程
    W->>B: 建立 WebSocket 连接 ws://backend/ws/workers/RUN_ID
    W->>B: WS state_change IDLE
    W->>W: 读取 /workspace/in/run-context.json
    Note over W: readinessProbe 通过 → Pod 就绪
    end

    rect rgb(230, 245, 255)
    Note over B,W: ⑤ 推送首条消息并返回结果
    B->>B: 检测到 Worker IDLE 且 WS 连接就绪
    B->>W: WS push_message(用户消息)
    W->>W: agentcore 调用大模型推理
    W-->>B: WS stream_chunk × N
    B-->>H: 转发流式内容
    H-->>U: 实时显示 AI 回复
    W->>B: WS message_response isComplete
    B->>B: 写入数据库
    end

3. 后续对话:Worker 已就绪

当 Worker 已处于 IDLE 状态时,后续消息无需重新创建 Deployment,延迟极低:

sequenceDiagram
    participant U as 用户
    participant H as Helper
    participant B as Backend
    participant W as Worker Pod

    U->>H: 继续对话
    H->>B: POST /api/v1/runs(同一 session_id)
    B->>B: 检测到 Worker 已就绪(IDLE)
    B->>W: WS push_message(新消息 + 更新的上下文)
    W->>W: agentcore 处理
    W-->>B: WS stream_chunk + message_response
    B-->>H: 转发
    H-->>U: 实时显示

    Note over U,W: 全程在 localhost,延迟在毫秒级

4. 交互式通信:agentcore 向用户提问

这是 SessionWorker 最重要的能力之一——agentcore 可以在执行过程中主动向用户发起请求

sequenceDiagram
    participant U as 用户
    participant H as Helper
    participant B as Backend
    participant W as Worker Pod

    Note over W: agentcore 执行工具前需要用户确认
    W->>B: WS ask_user 事件
    B->>B: 标记 Worker 状态 → WAITING_USER
    B->>H: WS 推送询问
    H->>U: 弹出确认对话框

    alt 用户同意
        U->>H: 点击"确认"
        H->>B: POST 用户回复
        B->>W: WS user_reply(用户确认)
        B->>B: 标记 Worker 状态 → BUSY
        W->>W: 继续执行
    else 用户拒绝
        U->>H: 点击"取消"
        H->>B: POST 用户拒绝
        B->>W: WS user_reply(用户拒绝)
        W->>W: 跳过该操作,继续推理
    end

典型场景

  • 删除文件前请求确认
  • 需要用户提供额外信息(如数据库连接串)
  • 执行高风险操作前的授权确认
  • 多选题或分支决策

5. 分阶段详解

阶段一:校验与准备(Backend 负责)

当 Backend 收到创建运行的请求后,依次执行:

  1. 校验 Session(会话):确认会话存在且未关闭
  2. 解析 agent package(智能体包):从包目录索引中读取开发者包
  3. 解析 RuntimeProfile(运行时配置模板):确定基础镜像和资源配额
  4. 合并 provider 配置:将 API 密钥从环境变量、运行时模板、本次请求三层合并
  5. 校验输入文件和挂载:确认文件存在,挂载路径在白名单内

阶段二:创建工作区(Backend 负责)

Backend 为本次运行创建独立的工作区目录:

workspaces/[run-id]/
  in/    ← 输入文件:附件 + run-context.json
  out/   ← 输出文件(SessionWorker 模式下主要通过回调返回)
  tmp/   ← 临时文件

同时从数据库中提取数据,生成 in/run-context.json(详见 输入输出流程)。

阶段三:组装 LaunchPlan(启动计划)

LaunchPlan 是整个运行的完整不可变描述

类别内容
身份与路由run_id、session_id、user_id、package_name
运行时与包镜像地址、容器入口、资源限制、Agent 包文件
文件与状态工作区路径、可选的本地缓存路径、checkpoint 恢复策略
编排策略卷后端类型(HostPath / PVC)、镜像模式、协议通道类型
交互配置worker_event_channel(事件通道)worker_idle_policy(空闲策略)
集群目标namespace、service account、是否真实提交

阶段四:K3s 编排器渲染和提交

编排器执行以下步骤:

  1. workload_worker.rs 组装 Deployment + Service 定义
  2. 容器暴露 8081 端口(control 控制端口)
  3. 配置 readiness/liveness 探针(检查 /tmp/agent-store-worker.ready 标记文件)
  4. 注入所有环境变量(事件通道、空闲策略、包信息、会话信息等)
  5. apply.rs 按顺序创建:ConfigMap → Secret → Service → Deployment
  6. 设置 OwnerReference(Deployment 拥有 Service、ConfigMap、Secret)

阶段五:容器内执行

graph TB
    START[Pod 启动] --> DIRS[创建工作目录]
    DIRS --> META[写入运行时元数据]
    META --> READY["创建 ready 标记<br/>/tmp/agent-store-worker.ready"]
    READY --> TRAP[注册 TERM 信号处理]
    TRAP --> BEAT[启动心跳循环]
    BEAT --> SERVE[建立 WebSocket 连接到 Backend]
    SERVE --> CTX[读取 run-context.json]
    CTX --> WAIT[等待 Backend 推送消息]
    WAIT --> RECV{收到消息}
    RECV -->|用户消息| INFER[调用大模型推理]
    RECV -->|用户回复| RESUME[恢复被暂停的执行]
    RECV -->|TERM 信号| DRAIN[优雅关闭]
    INFER --> NEED{需要用户输入?}
    NEED -->|是| ASK[WS 发送 ask_user 事件]
    ASK --> WAIT
    NEED -->|否| STREAM[流式推送 token]
    STREAM --> TOOLS[执行工具调用]
    TOOLS --> DBREQ{需要查库/写库?}
    DBREQ -->|是| SYNCREQ[发送 backend_query / backend_command]
    SYNCREQ --> DBRESP[等待 Backend 响应]
    DBRESP --> DONE[WS 发送 message_response]
    DBREQ -->|否| DONE
    DONE --> SAVE[发送 checkpoint_put 并等待 ACK]
    SAVE --> WAIT
    RESUME --> INFER
    DRAIN --> SAVE_EXIT[发送最终 checkpoint_put 后退出]

阶段六:状态回收

行为说明
结果写入Backend 实时接收协议事件,写入数据库
Worker 状态更新Backend 通过 K8s 状态观察 + 协议事件共同更新 Worker 生命周期状态
资源清理Worker DRAINING 后自动退出,K8s 清理 Deployment + Service + ConfigMap + Secret
会话连续性内存状态持续保持;checkpoint 通过协议写入 Backend 管理的数据库

各阶段的同步 / 异步定义

阶段语义说明
创建 Session同步需要立即返回 session_id
提交 Run混合API 返回 run_id 是同步,Worker 启动和执行是异步
K3s 创建资源异步Deployment 提交成功不代表 Pod 已立刻就绪
Worker 建立 WS 连接异步连接建立后由 state_change(IDLE) 告知 Backend
Backend 推送消息异步推送后结果稍后通过流式事件返回
Worker 查库 / 取 checkpoint同步必须等 Backend 响应才能继续
Worker 流式输出异步token 片段持续推送,不阻塞推理主循环
Worker 保存 checkpoint同步发送 checkpoint_put 后等待 ACK,确保状态可恢复
ask_user 交互混合发起提问异步,但业务流程暂停等待回复
空闲回收异步Backend / K8s 触发回收,Worker 稍后完成退出

6. Worker 生命周期状态机

stateDiagram-v2
    [*] --> PENDING : Backend 创建 Deployment
    PENDING --> IDLE : Pod 就绪, ready 标记文件存在
    IDLE --> BUSY : Backend 通过 WS 推送消息
    BUSY --> WAITING_USER : agentcore 回调 ask_user
    WAITING_USER --> BUSY : 用户回复经 WS 推送
    BUSY --> IDLE : 任务完成
    IDLE --> DRAINING : 空闲超时, idle_ttl_seconds
    DRAINING --> [*] : 优雅关闭完成
    BUSY --> FAILED : 执行出错
    PENDING --> FAILED : Pod 启动失败
    IDLE --> FAILED : livenessProbe 失败
状态含义Backend 行为
PENDINGDeployment 已创建,Pod 尚未就绪等待,轮询 Pod 状态
IDLE容器就绪,等待消息可以推送新消息
BUSY正在执行用户请求接收流式事件,不发新消息
WAITING_USERagentcore 在等待用户回复转发询问给用户,等待回复
DRAINING空闲超时,正在优雅关闭不再推送消息,等待退出
FAILED容器启动或执行失败上报错误,可能需要重新创建

7. 空闲回收与优雅关闭

7.1 空闲策略(WorkerIdlePolicy)

为避免长驻容器浪费资源,通过空闲策略控制回收:

参数类型说明
idle_ttl_seconds必填空闲多少秒后自动关闭(如 300 = 5 分钟)
max_lifetime_seconds可选容器最大存活时间(如 3600 = 1 小时)

7.2 优雅关闭流程

当容器收到 TERM 信号时(空闲超时、手动取消或 K8s 重调度):

1. SIGTERM 信号到达
2. 写入时间戳到 /workspace/session/worker-draining.log
3. 删除 /tmp/agent-store-worker.ready 标记文件
4. readinessProbe 立即失败 → K8s 停止路由新请求到此 Pod
5. 当前任务完成(如果有),通过 `checkpoint_put` 把状态发给 Backend
6. 进程退出(exit 0)
7. K8s 等待 terminationGracePeriodSeconds(30 秒)后 SIGKILL

7.3 Worker 重启恢复

当用户在 Worker 关闭后继续对话,Backend 会自动创建新的 Deployment:

  1. 新 Worker 启动,Backend 从数据库读取会话历史和最近 checkpoint 摘要,生成 run-context.json
  2. Worker 建立 WebSocket 连接后,如需完整恢复数据,发送 checkpoint_get
  3. Backend 查询数据库并返回最新可用 checkpoint
  4. agentcore 根据返回结果恢复执行状态
  5. 从用户角度看,对话无缝继续

8. 多轮对话的连续性

8.1 内存级连续性

容器不退出期间,agentcore 在内存中保持:

  • 完整的对话上下文
  • 大模型的会话状态
  • 工具调用结果缓存

8.2 Backend 统一持久化

当前方案下,checkpoint 与会话状态的权威存储都在 Backend 管理的数据库中。

数据流如下:

sequenceDiagram
    participant W as Worker
    participant B as Backend
    participant DB as 数据库

    W->>B: checkpoint_put
    B->>DB: 写入 checkpoint / session state
    DB-->>B: 写入成功
    B-->>W: checkpoint_put_ack

恢复时则反过来:

sequenceDiagram
    participant W as Worker
    participant B as Backend
    participant DB as 数据库

    W->>B: checkpoint_get
    B->>DB: 查询最新 checkpoint
    DB-->>B: 返回 snapshot
    B-->>W: checkpoint_get_result

这意味着:

  • 容器内不需要直接打开数据库文件
  • 容器内不需要持有数据库连接信息
  • Backend 统一负责权限、审计和数据裁剪

本地文件目录仍然可以保留给缓存、日志、临时产物使用,但它不再是权威状态来源。


9. 会话的关闭与重新打开

操作效果数据影响
close(关闭)标记为已归档;Worker 收到 TERM 信号优雅退出历史、文件、状态目录全部保留
reopen(重开)恢复为活跃状态可继续发送消息,Worker 按需重新启动

10. 运行状态流转

stateDiagram-v2
    [*] --> PENDING : 创建 RunRecord
    PENDING --> SUBMITTED : K3s Deployment 创建成功
    PENDING --> PREVIEWED : dry-run 模式, 仅渲染 YAML
    SUBMITTED --> COMPLETED : Worker 回调 message_response
    SUBMITTED --> FAILED : 执行失败
    SUBMITTED --> CANCELLED : 用户取消
状态含义
PENDING已记录但未提交到 K3s
SUBMITTEDDeployment + Service 已创建或 Worker 已就绪
PREVIEWED只渲染了 YAML,未真正提交(dry-run 调试)
COMPLETED正常完成
FAILED执行出错
CANCELLED用户取消,已清理资源

下一步

了解了完整的生命周期后,请继续阅读 输入输出流程