2026-09-08 00:07:26 +08:00
|
|
|
|
# Pi Agent 兜底能力发布与现场运行手册
|
|
|
|
|
|
|
|
|
|
|
|
> 角色:Agent-D(P5 发布实现)· 成文日期:2026-09-04
|
2026-09-08 11:24:04 +08:00
|
|
|
|
> 依据:`poc/pi-fallback/P4-P5-DESIGN.md` §5、`poc/pi-fallback/P4-P5-AUDIT.md`、`docs/architecture/fallback.md` 与当前代码。
|
2026-09-08 00:07:26 +08:00
|
|
|
|
> 本文只写运行与发布准备边界,不替代 `CHANGELOG.md`/`fallback.md`;那两份由主管统一更新。
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 启用前提与 fail-closed 开关
|
|
|
|
|
|
|
|
|
|
|
|
当前兜底形态是**本地 spawn runner**:Python 编排器在应用进程内拉起 Node + Pi CLI 子进程;没有已交付的独立 pi-runtime service。仓库 `poc/pi-fallback/runtime` 只是开发用安装,**不是发布产物**。启用前必须满足:
|
|
|
|
|
|
|
|
|
|
|
|
- 应用容器或部署机具备 Node(建议 22)与 Pi 制品,或显式配置 `APS_FALLBACK_PI_CLI`/`APS_FALLBACK_NODE`;
|
|
|
|
|
|
- 模型网关可由服务端访问,并配置 `LLM_BASE_URL`/`LLM_API_KEY`;
|
|
|
|
|
|
- 持久化目录可写且可长期保留 run/审计证据;
|
|
|
|
|
|
- P3 高风险场景使用前准备好 `fallback-highrisk.json` 与审批角色策略。
|
|
|
|
|
|
|
|
|
|
|
|
### 1.1 默认关
|
|
|
|
|
|
|
|
|
|
|
|
`server/agent_core/feature_flags.py` 的 `_DEFAULT_OFF_KEYS = {"fallback"}`。文件缺失、JSON 损坏、结构非法、取值非 bool、加载异常,全部回退 `fallback=False`。因此**未显式开启时不拉起 Pi 子进程**,聊天链路逐字节走原话术。
|
|
|
|
|
|
|
|
|
|
|
|
显式开启:
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{"version": 1, "features": {"fallback": true}}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
配置路径默认 `APS_FEATURES_PATH`,未设置时为 `path_under_data("features.json")`(Web 通常 `server/data/features.json`,桌面 `~/.aps/data/features.json`)。可用 `GET /api/features` 的 `defaultOff` 核对语义。
|
|
|
|
|
|
|
|
|
|
|
|
### 1.2 环境变量
|
|
|
|
|
|
|
|
|
|
|
|
| 变量 | 作用 | 默认 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| `APS_FALLBACK_DIR` | run 根目录 | `path_under_data("fallback")`(Web=`server/data/fallback`,桌面=`~/.aps/data/fallback`) |
|
|
|
|
|
|
| `APS_FALLBACK_PI_CLI` | Pi CLI 路径 | **代码默认回仓库 poc 路径,发布必须显式覆盖** |
|
|
|
|
|
|
| `APS_FALLBACK_PI_HOME` | Pi 配置目录 | `<fallback_root>/pi-home` |
|
|
|
|
|
|
| `APS_FALLBACK_NODE` | Node 可执行文件路径 | `node`(Windows 优先 `node.exe`;建议显式给绝对路径) |
|
|
|
|
|
|
| `APS_FALLBACK_MODEL` | 显式模型 | 空则 `GET {LLM_BASE_URL}/models` 协商,缓存 300s |
|
|
|
|
|
|
| `APS_FALLBACK_TIMEOUT_SEC` | 单次运行超时 | 90 |
|
|
|
|
|
|
| `APS_FALLBACK_MAX_STEPS` | 工具步数上限 | 30 |
|
|
|
|
|
|
| `APS_FALLBACK_MAX_OUTPUT_BYTES` | 输出体量上限 | 2 MiB |
|
|
|
|
|
|
| `APS_FALLBACK_EXEC_TIMEOUT_SEC` | 执行段预算 | 120 |
|
|
|
|
|
|
| `APS_FALLBACK_EXEC_MAX_STEPS` | 执行段步数 | 40 |
|
|
|
|
|
|
| `APS_FALLBACK_MAX_PLAN_STEPS` | 计划步骤上限 | 10 |
|
|
|
|
|
|
| `APS_FALLBACK_OPS_LOG_LINES` | S7 日志尾部行数 | 300 |
|
|
|
|
|
|
| `APS_FALLBACK_S6_MAX_CARDS` | S6 出卡全局封顶 | 20(白名单 `maxItemsPerRun` 优先) |
|
|
|
|
|
|
| `APS_FALLBACK_HIGHRISK_PATH` | P3 白名单路径 | `path_under_data("fallback-highrisk.json")` |
|
|
|
|
|
|
| `LLM_BASE_URL` | 模型网关地址 | 无默认,缺失即不可用 |
|
|
|
|
|
|
| `LLM_API_KEY` | 模型网关密钥 | 无默认,缺失即不可用;只进子进程环境,不打印不落盘 |
|
|
|
|
|
|
| `LLM_MODEL` | 期望模型 | 可选;不在清单时取第一项并记录协商说明 |
|
|
|
|
|
|
|
|
|
|
|
|
即使设置 `APS_FALLBACK_MODEL`,仍需 `LLM_BASE_URL`/`LLM_API_KEY`,因为 Pi 侧需要网关地址与密钥引用。P3 审批可能还涉及 `APS_APPROVAL_ROLE_POLICIES`(例如 `{"approval.approve":{"P3":["ops","admin"]}}`)。
|
|
|
|
|
|
|
|
|
|
|
|
## 2. Web/Docker 部署与 Pi 制品路径
|
|
|
|
|
|
|
|
|
|
|
|
### 2.1 现状
|
|
|
|
|
|
|
|
|
|
|
|
- Web/服务端部署当前是本地 spawn:Python 服务在本容器内启动 `node cli.js`;
|
|
|
|
|
|
- 现有 Dockerfile 只含 Python 与 `apps/web/dist`,**没有 Node/pi**;
|
|
|
|
|
|
- `packaging/k8s/deployment.yaml` 没有 `APS_FALLBACK_*`、Node/pi 相关配置;
|
|
|
|
|
|
- 因此镜像/Deployment 当前**不具备启用兜底的运行时**,只改环境变量无效。
|
|
|
|
|
|
|
|
|
|
|
|
### 2.2 Web/Docker 两态
|
|
|
|
|
|
|
|
|
|
|
|
主管裁决前,只记录两种可验收形态:
|
|
|
|
|
|
|
|
|
|
|
|
1. **Node + Pi 制品打进应用镜像或部署目录**:镜像/挂载卷提供固定版本 Node 与 Pi 制品,Python 通过 `APS_FALLBACK_PI_CLI`/`APS_FALLBACK_NODE` 指向;run 目录挂持久卷。这是“本地 spawn runner + 制品”形态。
|
|
|
|
|
|
2. **独立 pi-runtime service**:未来新增运行器协议与边界;**本轮不承诺已可用**,不得写入部署文档作为已完成能力。
|
|
|
|
|
|
|
|
|
|
|
|
镜像内建议 `APS_FALLBACK_DIR=/app/server/data/fallback`(或对应持久卷路径);容器临时层不适合保留审计/回放证据。缺少 Node/pi/模型时,功能保持显式失败,服务不得崩溃。
|
|
|
|
|
|
|
|
|
|
|
|
### 2.3 现场核对
|
|
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
Get-ChildItem -Recurse -LiteralPath "<镜像或部署目录>" -Filter cli.js |
|
|
|
|
|
|
Where-Object { $_.FullName -match 'pi-coding-agent' } |
|
|
|
|
|
|
Select-Object -First 10 FullName
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
发布清单必须能看到明确 Pi 制品;只看到仓库 poc 路径不能算“镜像已含 runtime”。
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 桌面可选组件与 sidecar env 边界
|
|
|
|
|
|
|
|
|
|
|
|
当前桌面默认包不含 Node/pi:
|
|
|
|
|
|
|
|
|
|
|
|
- `apps/desktop/package.json` 的 `extraResources` 只含 `web/dist` 与 PyInstaller sidecar;
|
|
|
|
|
|
- `packaging/aps-sidecar.spec` 只收 Python 模块,未收 Node/pi;
|
|
|
|
|
|
- `sidecar.cjs` 的 `CHILD_ENV_ALLOWLIST` 不含 `LLM_*`/`APS_FALLBACK_*`,因此当前 Electron sidecar 不能把模型/兜底环境传给 Python。
|
|
|
|
|
|
|
|
|
|
|
|
文档边界:**不声称桌面已内置启用 Pi 兜底**。未来若要桌面启用,至少需由主管拍板:
|
|
|
|
|
|
|
|
|
|
|
|
1. 是否把 Node + Pi 作为安装包内可选组件,或首次使用下载;
|
|
|
|
|
|
2. sidecar 环境 allowlist 是否扩展 `LLM_*`/`APS_FALLBACK_*`;
|
|
|
|
|
|
3. 组件签名、体积、无网络安装、升级/回滚验收(参照 `docs/development/packaging-smoke.md`);
|
|
|
|
|
|
4. 若迁 Tauri,Node runtime 方案与 Tauri 决策串行重设计。
|
|
|
|
|
|
|
|
|
|
|
|
本轮只给出可选组件边界与可复跑清单,不做“桌面默认可用”表述。
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 无模型、断网与 MES 断连处置
|
|
|
|
|
|
|
|
|
|
|
|
### 4.1 无模型/模型网关不可达
|
|
|
|
|
|
|
|
|
|
|
|
当前行为是**逐次显式失败**:
|
|
|
|
|
|
|
|
|
|
|
|
- 缺少 `LLM_BASE_URL`/`LLM_API_KEY`、Node/pi 不可解析、`GET /models` 超时/异常/空清单 → 回原话术并附 `unavailable:<原因>`;
|
|
|
|
|
|
- 写 FAILED 审计;不会自动把 `fallback` 置 false;
|
|
|
|
|
|
- 当前没有专门 UI 状态位“模型不可用已强制关闭”。
|
|
|
|
|
|
|
|
|
|
|
|
这与详细方案 F5 的“无模型 force-off + UI 明示”**不一致**,已在缺口表中列为待主管裁决项。运维处置:看失败原因,检查 Node/Pi/网关配置后重试;不打算启用时把 `features.json` 显式写回 false。
|
|
|
|
|
|
|
|
|
|
|
|
### 4.2 断网/超时
|
|
|
|
|
|
|
|
|
|
|
|
propose 默认 90s/30 步/2MiB,执行段默认 120s/40 步;任一超限即杀进程树、显式判败。成败只看事件流 `stopReason=stop` 且报告非空,不看进程退出码。网络不可达不阻塞聊天主链路。
|
|
|
|
|
|
|
|
|
|
|
|
### 4.3 MES 断连(S6)
|
|
|
|
|
|
|
|
|
|
|
|
- 在线路径不变:未声明 `offlineBooking` 时先推 MES 后落账,断连即显式失败并回滚;
|
|
|
|
|
|
- 离线落账必须双成立:计划 params 显式 `offlineBooking:true` **且** 出卡/执行端实时探测 MES `failed`;
|
|
|
|
|
|
- 双成立才本地落账并打 `syncStatus=PENDING_SYNC`,确认卡明示“本地落账待同步”;
|
|
|
|
|
|
- 审批窗口内 MES 已恢复 → 执行端拒绝/回滚;offlineBooking 不能用来绕过 MES 在线校验;
|
|
|
|
|
|
- 恢复后由人重新发起“对一下账”;探测仍失败则回复“尚未恢复”,不轮询、不猜;
|
|
|
|
|
|
- 对账为纯读:MATCH/DRIFT/MISSING,外部原文与 `reconcile-manifest.json` sha256 冻结,报告不写世界;
|
|
|
|
|
|
- PENDING_SYNC 自动补推属后续轮次,当前未实现。
|
|
|
|
|
|
|
|
|
|
|
|
## 5. run 目录、审计回放、checkpoint/回滚
|
|
|
|
|
|
|
|
|
|
|
|
根:`APS_FALLBACK_DIR` 或 `path_under_data("fallback")`。单个 run 目录形态:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
<fallback_root>/fb-YYYYMMDD-HHMMSS-xxxxxx/
|
|
|
|
|
|
├── inbox/ # snapshot.md / orders.csv / 集成状态 / ops 诊断 / external
|
|
|
|
|
|
├── work/ # Pi 子进程工作目录
|
|
|
|
|
|
├── outbox/ # report.md / plan.json / sandbox 产物 / reconcile 产物
|
|
|
|
|
|
├── events.jsonl
|
|
|
|
|
|
├── orchestrator.log
|
|
|
|
|
|
├── result.json
|
|
|
|
|
|
├── calls.jsonl
|
|
|
|
|
|
├── guard-<runId>.ts
|
|
|
|
|
|
├── execution.jsonl / execution.events.jsonl
|
|
|
|
|
|
└── outbox/reconcile-manifest.json # S6 对账证据冻结文件
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
审计关联:完成审计 rationale 含 `runId`;工具事件 actor=`pi-fallback:<runId>`;`evidence_refs=["fallback-run:<runId>"]`;S6 对账另含 `manifestSha256`。
|
|
|
|
|
|
|
|
|
|
|
|
回放现状:`GET /api/gov/audit` 只返回最近 `limit` 条,**没有服务端 runId 过滤参数**;GovConsole 无 runId 搜索/一键回放视图。当前可靠回放是“runId + run 目录文件 + sha256 + 客户端筛选审计”,不能写成系统现成 runId 回放功能。
|
|
|
|
|
|
|
|
|
|
|
|
P3-DESIGN 曾要求 S7 每 run 追加通用 `manifest.json`;当前源码只找到 S6 `reconcile-manifest.json` 写路径,**未发现通用 S7 manifest 写路径**,作为发布前缺口处理。
|
|
|
|
|
|
|
|
|
|
|
|
回滚/收尾:
|
|
|
|
|
|
|
|
|
|
|
|
- S6 逐笔独立确认卡/checkpoint,单笔拒绝不影响其他;
|
|
|
|
|
|
- S7 配置为整文档替换:tmp + 原子 replace + `.bak` + 回读校验;
|
|
|
|
|
|
- S4 沙盒不改主世界,校验前后世界指纹 + 零 `WORLD_WRITE`;
|
|
|
|
|
|
- 失败后不得残留 `_saga_cp.json` 或 Pi 进程。
|
|
|
|
|
|
|
|
|
|
|
|
## 6. 回归与验收命令(.venv\Scripts\python.exe)
|
|
|
|
|
|
|
|
|
|
|
|
Python 一律使用仓库 `.venv\Scripts\python.exe`;命令只验证,不 commit/push、不跑真实打包。
|
|
|
|
|
|
|
|
|
|
|
|
### 6.1 定向确定性 golden
|
|
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
.venv\Scripts\python.exe -m pytest `
|
|
|
|
|
|
tests/golden/test_fallback_lane.py `
|
|
|
|
|
|
tests/golden/test_fallback_execute.py `
|
|
|
|
|
|
tests/golden/test_fallback_highrisk.py `
|
|
|
|
|
|
tests/golden/test_fallback_offline_booking.py `
|
|
|
|
|
|
tests/golden/test_fallback_p3_attack.py `
|
|
|
|
|
|
tests/golden/test_feature_flags.py `
|
|
|
|
|
|
-q
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
P4 质量专项已交付并经主管复核(2026-09-04),命令:
|
|
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
.venv\Scripts\python.exe -m pytest tests/golden/test_fallback_p4_quality.py -q
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
主管复核结果:
|
|
|
|
|
|
|
|
|
|
|
|
- P4 质量:44 passed,结论与场景映射见 `poc/pi-fallback/P4-QUALITY-NOTES.md`;
|
|
|
|
|
|
- P4 注入:57 passed / 1 skipped,见 `poc/pi-fallback/P4-SECURITY-NOTES.md`;
|
|
|
|
|
|
- P4 离线:24 passed,见同一 security notes;
|
|
|
|
|
|
- 主管 8 文件联合(lane / execute / highrisk / p3_attack / offline_booking +
|
|
|
|
|
|
P4 quality / injection / offline):197 passed / 1 skipped in 51.87s;
|
|
|
|
|
|
- ruff:All checks passed;
|
|
|
|
|
|
- 汇总复核记录见 `poc/pi-fallback/P4-P5-VALIDATION.md`。
|
|
|
|
|
|
|
|
|
|
|
|
确定性门禁现可按上述结果勾选;真实 runtime/Docker/桌面打包、真实 smoke 与
|
|
|
|
|
|
发布批准仍以本手册其余边界与 `poc/pi-fallback/P5-RELEASE-NOTES.md` 为准。
|
|
|
|
|
|
|
|
|
|
|
|
### 6.2 S6/S7 真实冒烟(需真实 Node/Pi/LLM key)
|
|
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
.venv\Scripts\python.exe poc/pi-fallback/smoke/smoke_s6_reconcile.py setup
|
|
|
|
|
|
.venv\Scripts\python.exe poc/pi-fallback/smoke/smoke_s6_reconcile.py outage
|
|
|
|
|
|
.venv\Scripts\python.exe poc/pi-fallback/smoke/smoke_s6_reconcile.py recovery
|
|
|
|
|
|
.venv\Scripts\python.exe poc/pi-fallback/smoke/smoke_s6_reconcile.py control
|
|
|
|
|
|
.venv\Scripts\python.exe poc/pi-fallback/smoke/smoke_s6_reconcile.py finalize
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
.venv\Scripts\python.exe poc/pi-fallback/smoke/smoke_s7_ops.py setup
|
|
|
|
|
|
.venv\Scripts\python.exe poc/pi-fallback/smoke/smoke_s7_ops.py ops
|
|
|
|
|
|
.venv\Scripts\python.exe poc/pi-fallback/smoke/smoke_s7_ops.py control
|
|
|
|
|
|
.venv\Scripts\python.exe poc/pi-fallback/smoke/smoke_s7_ops.py finalize
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
冒烟收尾核对:无 `_saga_cp.json`、无 `server/data` 非预期残留、无残留 pi 进程。冒烟脚本会构造临时现场/CSV/假 MES,属验证设施,不是产品文件摄入能力。
|
|
|
|
|
|
|
|
|
|
|
|
### 6.3 已知未实现项与待裁决
|
|
|
|
|
|
|
|
|
|
|
|
1. P3 产品代码未提交;P3-VALIDATION 存在 GO/NO-GO 文档矛盾;
|
|
|
|
|
|
2. Pi runtime 未进 Docker/K8s/桌面发布包;仓库 poc 路径不是发布产物;
|
|
|
|
|
|
3. 桌面 sidecar 不允许 `LLM_*`/`APS_FALLBACK_*` 透传;
|
|
|
|
|
|
4. P4 注入/离线专项、P4 notes、P4-P5-VALIDATION 已交付并复核(注入 57 passed / 1 skipped、
|
|
|
|
|
|
离线 24 passed),不再作为“未交付/无结论”缺口;
|
|
|
|
|
|
5. P4-QUALITY-NOTES 已提供确定性集成功率/误写率/确认轮次/耗时与 cost_points 近似聚合,
|
|
|
|
|
|
产品层仍无统一指标导出、真实 token/cost 与 per-step 耗时;
|
|
|
|
|
|
6. 无 Pi usage/token/cost 解析、日预算/告警、触发率周报;
|
|
|
|
|
|
7. F5 无模型 force-off + UI 明示与现状不一致;
|
|
|
|
|
|
8. `/api/gov/audit` 无 runId 服务端过滤,GovConsole 无 runId 回放视图;
|
|
|
|
|
|
9. S4 真实冒烟未做;S6 超上限真实冒烟未做;S7 通用 manifest 写路径未见;
|
|
|
|
|
|
10. 全量 golden 基线数字口径过期(1071+ 等),需主管统一;
|
|
|
|
|
|
11. WMS 侧补录不在 P3 范围。
|