# 13 - 运行结果状态与可续跑契约(三产品统一) > // Logan.Li > 权威语义契约:opsxcli / aiops(backend/pkg/agentcli)/ opsxshell 共用。 > 本文档先诚实于**现状**,并标明**目标态**;代码实现以契约为准后续对齐。 > 权威副本与 opsxcli `docs/13-运行结果状态与可续跑契约.md` 同步维护;本目录其它文档链到本文。 > 配套:`09-三产品定位与执行边界.md`、opsxcli `12-Agent运行边界与安全基线.md`。 --- ## 1. 统一运行结果状态(RunOutcome) 所有面向用户/上游的 Agent 运行结束,必须能归入下列之一(禁止用「看起来像完成了」掩盖预算耗尽): | 状态 | 含义 | 用户感知 | |------|------|----------| | `completed` | 在预算内达成任务目标,给出可用最终答案 | 正常完成 | | `incomplete` | **未完成**:因预算/超时/连接等原因主动或被迫停住,但已有部分轨迹可续 | 「步骤没跑完」——应可续跑或加预算 | | `failed` | 不可恢复错误(协议坏、鉴权失败、不可重试的工具致命错等) | 失败,需改输入/环境 | | `cancelled` | 用户/上游主动取消 | 已取消 | | `awaiting_confirm` | 安全策略要求人工确认后才能继续 | 等待确认 | ### 1.1 `incomplete` 必须可区分原因(IncompleteReason) | reason | 典型触发 | |--------|----------| | `max_steps` | 触达 MaxIterations / MAX_AGENT_STEPS | | `context_budget` | 上下文裁剪/窗口不足导致无法安全继续本轮 | | `tool_timeout` | 工具执行超时 | | `llm_timeout` | LLM/流式读超时 | | `connection_lost` | SSH/网络会话中断 | | `safety_abort` | 安全控制器中止(非「等待确认」) | **规则**:触顶步数预算 → 必须是 `incomplete` + `max_steps`,**不得**伪装成 `completed`,也**不宜**仅抛「任务未能完成」而无结构化状态(目标态)。 --- ## 2. 「可续跑」(Resumable)定义 ### 2.1 什么才算真·续跑 **必须同时满足**: 1. **持久化 tool 轨迹**:assistant `tool_calls` 与对应 tool observation(含 `tool_call_id`)已落盘; 2. **引擎注入**:下次 `Run` / `RunStream` / `continueTask` 把历史 messages(或等价 prior)注入 Agent 上下文,从中断点继续推理与工具调用。 仅恢复 TUI/UI 聊天泡泡、仅 `Load` 会话元数据、或不注入引擎的「回放」,**不算** resume。 ### 2.2 借鉴要点(oh-my-pi / pi,勿照搬实现) | 思想 | 对我们的含义 | |------|----------------| | resume 切换会话后重建 agent context(含中断 turn 的 abort 合成) | Load 后必须重建可喂给 LLM 的 messages | | fork = 新会话身份 + 复制轨迹 | 续跑可同会话续,或 fork 新会话隔离实验 | | compaction / handoff | 上下文不够时摘要保真,而非静默丢 tool observation | | retry 与 compaction 分轨 | 超时/限流可重试;窗口溢出走压缩/incomplete,不混为一谈 | | session lifecycle status(interrupted 等) | 与 `incomplete` 对齐,列表/UI 可区分 | --- ## 3. 步数预算语义 | 原则 | 说明 | |------|------| | 默认值是**预算**不是质量承诺 | opsxcli/aiops 默认 16、opsxshell `MAX_AGENT_STEPS=12` 只表示「这一趟最多走几步」 | | 触顶 = `incomplete` | 不是「覆盖 90% 场景所以算完成」 | | 目标态 | 支持:加大预算续跑、同会话 resume、显式 `continue`;可选任务级 checkpoint | --- ## 4. 文档 vs 实现对照表(现状 / 目标) ### 4.1 opsxcli | 能力 | 现状(2026-09) | 目标 | |------|-----------------|------| | MaxIterations 默认 16 | 触顶硬失败「任务未能完成」 | `incomplete`/`max_steps` + partial + 可续 | | resume / TUI load | 主要恢复 UI;`Run`/`RunStream` 重置 messages;真·Agent 续跑未接通 | Load → 注入 messages;每轮持久化 | | SaveToolResult | 有接口,生产路径基本无调用 | 每轮 tool 结果必写 | | ensureToolMessageIntegrity | 一轮多 tool 时可能丢 observation(前一条须为 assistant) | 按 `tool_call_id` 整组保留(对齐 aiops) | | EstimateMessages | 忽略 ToolCalls;MaxContextTokens 默认 6000 | 计入 ToolCalls/结果;按模型窗口配置 | | RunStream 自适应检查点 | 未接入(仅 Run 有) | Run/RunStream 行为一致 | | ToolTimeout | 默认 60s | 分层超时;长工具可心跳/提高上限 | ### 4.2 aiops(backend/pkg/agentcli) | 能力 | 现状 | 目标 | |------|------|------| | MaxIterations=16 | 同样硬停 | 同契约:`incomplete` + 可续 | | tool integrity | 已按 `tool_call_id` 整组保留(优于 opsxcli) | 保持;成为三产品参考实现 | | 续聊 | `resumeSession`→`convHistory`→`continueTask(prior)` 已有 | 补齐结构化 `incomplete` 原因与 UI/API 暴露 | | ToolTimeout / MaxContext | 120s / 8000 | 与契约字段对齐;预算可配置 | ### 4.3 opsxshell | 能力 | 现状 | 目标 | |------|------|------| | AiTerminalPanel `MAX_AGENT_STEPS=12` | 触顶抛错 | `incomplete`/`max_steps`;可续或提示加预算 | | 执行边界 | 绑当前 SSH `connectionId` | **保持**;不引入跨入口通用远程执行器 | ### 4.4 三产品边界(不变) 不得共享「可跨入口自由切换」的通用远程执行器。统一的是**结果状态与续跑语义**,不是执行平面。详见 aiops `09-三产品定位与执行边界.md`。 --- ## 5. 建议对外字段(目标态 API/事件,非现状承诺) ```text run_outcome: completed | incomplete | failed | cancelled | awaiting_confirm incomplete_reason?: max_steps | context_budget | tool_timeout | llm_timeout | connection_lost | safety_abort resumable: bool # 是否满足 §2.1 steps_used / steps_budget session_id / run_id partial_summary?: string # 触顶时的已有进展摘要(可选) ``` 可观测事件:在现有 `done`/`error` 之外,目标态增加明确的 `incomplete` phase/type,避免全部打成 error。 --- ## 6. 文档索引 | 产品 | 落点 | |------|------| | opsxcli | 本文;`06`/`10`/`03`/`12`;`README.md` | | aiops | `docs/ai-agent/` 链到本文副本或相对链接;`00`/`03`/`06`/`09` | | opsxshell | `docs/01-AI-Agent步数预算与incomplete.md` | --- *文档版本: v1.0 | 2026-09-18 CST | 先 docs 后代码*