aps-agent/Pi-Agent兜底能力详细方案.md

16 KiB
Raw Blame History

Pi Agent 兜底能力 · 详细实施方案

版本 v2.0 · 2026-09-02 · 取代:Pi-Agent接入计划.md / Pi-Agent接入详细计划.md(那两份是"接入通道"定位,本方案是"全系统兜底能力"定位,范围显著扩大) 依据:plan.md §2.1/§2.2/§3、PROJECT_OPERATING_RULES.md、docs/architecture/harness.md、docs/architecture/skills.md、docs/architecture/overview.md 现状代码锚点:server/aps_domain/workflow.py:2875(当前 unknown 意图兜底 = 纯话术回复,无能力)、server/agent_core/harness.py(_POWER_MAP 62 项登记 + 未登记默认 P3 拒绝)、server/agent_core/tool_runtime.py(唯一执行入口)、server/agent_core/mcp_bus.py、server/agent_core/feature_flags.py(FF-01 开关机制)、apps/desktop/sidecar.cjs(子进程环境清洗/看门狗,Pi runtime 可直接复用这套模式)


1. 定位重述:什么是"兜底能力"

现状:用户说一句系统听不懂的话,走到 workflow.py:2875 的 assistant.reply/unknown 分支——LLM 回一段话术,事情没办成。已登记意图执行失败(求解器 fatal、数据缺字段、接口超时)也只有报错,没有自救。

目标态:Pi Agent 成为 APS 的通用能力后备层——产品化路径"不能办"或"办砸了"时,由 Pi 这个具备读/写/执行能力的通用智能体,在 Harness 划定的围墙内把事办成,并且全程可审计、可回滚、可熔断。

用户请求 → 意图管线
  ├─ 命中已登记意图 → 产品化路径(现状,快/稳/确定性)
  │     └─ 执行失败 ──┐
  └─ 未识别/未登记 ───┤
                      ▼
            【受治理的兜底车道 Governed Fallback Lane】
            Pi 分析任务 → 产出《执行计划草稿》(P1,只读可直通)
            → 确认卡呈人类审批 (P2 起)
            → 批准后 Pi 在沙箱内执行(工具桥只暴露登记过的能力)
            → 执行后世界状态 diff 验证 + 报告
            → 全程审计链 + 证据链 + 可回滚 checkpoint

一句话:Pi 是被 Harness 雇佣的临时工——有手艺,但进厂要登记、干活要批条、动设备要有人在场、出活要验收。

2. 与产品宪法的冲突分析与消解

这是本方案最关键的一节。兜底能力天然想"什么都能干",宪法要求"未经授权什么都不能干"。逐条消解:

宪法红线(PROJECT_OPERATING_RULES 原文) 表面冲突 消解设计
「动作必须经 _POWER_MAP 白名单登记,未登记默认 P3 拒绝」 兜底场景恰恰是"未登记意图" 新增 3 个元意图登记进 _POWER_MAP:agent.fallback.propose=P1(产出计划草稿,沙盒语义)、agent.fallback.execute=P2(执行已批准计划)、agent.fallback.execute.highrisk=P3(涉主干写/外部系统,逐字段人工确认或默认拒绝)。Pi 从未"直接做事",它做的事都被这三个登记动作包裹
「LLM 只有提议权」(tool_runtime) Pi 是 LLM 驱动的执行体 Pi 的计划是提议;执行走 /api/actions/confirm 唯一通道。Pi 能调用的工具本身就是经过登记的意图封装(见 §4.3 工具桥),物理上无法直写 store/DB
「不得引入未设计的隐式副作用」 Pi 自由执行副作用不可枚举 沙箱围墙(§4.2):文件系统圈禁在 run 专属目录、网络只通 APS loopback、shell 白名单、环境变量清洗(复用 sidecar.cjs 的 allowlist 模式)。墙内副作用显式枚举,墙外物理不可达
「写前必须建 checkpoints 成对快照」 Pi 执行前后状态未知 兜底车道强制执行前 checkpoint、执行后 world diff 验证报告,diff 摘要进确认卡和审计
「失败必须显式报告」 LLM 倾向"圆场" Pi 输出契约强制 `status: success
「mock/stub 不得进入产品路径」 Pi 可能"假装"调用了工具 工具桥每次调用返回真实调用凭证(callId),Pi 报告中引用 callId 可被审计对账;无 callId 支撑的成果声明判无效

3. 场景矩阵(10 类兜底场景 × 治理策略)

# 场景 触发条件 权力 治理策略 验证方式 Pi 干不了时的降级
S1 意图未识别(新说法/新需求口令) 意图管线产出 unknown propose=P1 / execute=P2 计划草稿确认卡必出 执行后 diff + 用户确认回执 退回话术 + "已记录需求"工单
S2 已登记意图执行失败(求解器 fatal、数据缺字段) handler 抛错/返回失败 P1 诊断只读 / 修复=P2 诊断报告直通;修复动作出卡 重跑原意图成功即为验证 显式报错原文 + 诊断附件
S3 新数据格式接入(客户给了没人写过 importer 的 Excel/CSV/JSON) data.import 解析失败或用户直接给文件 P2(导入写主干) 计划含字段映射表,确认卡呈现映射供审 导入后行数/金额对账 + 抽样比对 输出《手工整理指引》
S4 缺算法/策略(某工艺无现成排产策略) flex.schedule 无匹配 skill 或用户明示"试个新策略" P1(沙盒试排) 仅沙盒语义,产物为草稿版本 沙盒 KPI 对比基线版本 明确告知"超出兜底能力"
S5 ad-hoc 分析/报告("帮我看看哪条线最容易拖期") report.generate/data.analyze 覆盖不了的自由分析 P1 只读工具桥 + 沙盒计算 报告数字必须引用冻结快照字段(宪法既有规则) 返回原始数据 + 分析失败说明
S6 外部集成故障(MES/WMS 接口挂了,要手工补录/对数) integrations 调用失败告警 P2 补录动作逐笔出卡 与外部系统恢复后对账 生成待补录清单(Excel)交人工
S7 现场运维诊断(support 工程师查日志/修配置) 运维人员在运维入口显式发起 P2;改配置 P3 仅运维角色可见入口;全程录屏级审计 修复后健康检查绿 输出诊断报告 + 建议人工操作
S8 演示/售前救场 演示中任何上述场景 同对应场景 无特殊豁免(宪法) 同对应场景 话术降级
S9 批量数据处理(一次性清洗/转换 5000 行工单) 用户发起且无对应产品功能 P2 计划含抽样预览(前 20 行变换结果)出卡 全量校验规则 + 抽样人工确认 分批+断点,失败批次显式列出
S10 Pi 自身失败(模型不可用/超时/超预算/死循环/部分写入) 熔断器触发 — 超时(默认 10min)/步数(50)/token 预算三重熔断;部分写入由 checkpoint 回滚 回滚后 diff 为空即验证 显式失败报告 + 已回滚声明

矩阵结论:10 类场景中 S1/S2/S3/S5/S9 是价值主干(覆盖 80% 真实需求),S4/S6/S7 价值高但风险也高(放后期),S10 是必须设计的元场景。

4. 详细设计

4.1 组件清单(新增 4 个可重生模块 + 1 个外部进程)

组件 位置 moduleId 职责
FallbackLane 编排器 server/agent_core/fallback_lane.py(新增,~600 行) core-fallback-lane 触发判定 → 任务简报 → 调 Pi → 收计划 → 出卡 → 执行 → 验证 → 审计
Pi 工具桥 server/integrations/pi_bridge.py(新增,~400 行) integ-pi-bridge 向 Pi 暴露围墙内工具集(§4.3),每次调用发 callId 凭证
兜底验证器 server/agent_core/fallback_verify.py(新增,~300 行) core-fallback-verify 执行后 world diff、规则校验、报告生成(数字只许来自冻结快照)
熔断与预算 并入 fallback_lane(~150 行) 同上 超时/步数/token 三重熔断 + audit_alerts 联动
Pi runtime 进程 Node 进程(pi-agent-core headless 模式) — 被编排器以子进程拉起,生命周期管理复用 sidecar.cjs 的 SidecarManager 模式(端口/nonce/环境清洗/看门狗/日志轮转全套照搬)

4.2 沙箱围墙(自内向外四层)

L1 工具层:Pi 只能看见工具桥暴露的工具(§4.3),没有裸 fs/shell/net
L2 文件层:cwd 圈禁 ~/.aps/fallback/<runId>/(Web 态 server/data/fallback/<runId>/);
          可读注入区(用户上传文件副本)、可写工作区、产物出口目录三区分离
L3 网络层:仅允许 127.0.0.1:<gateway port>;模型 API 出口走 gateway 代理(可关)
L4 进程层:环境变量清洗(CONDA/Python 变量剥离,照搬 buildChildEnv)、
          父进程看门狗、taskkill 进程树回收、10MiB 日志轮转

说明:Pi 官方支持 Gondolin/Docker 沙箱,但工业现场 Windows 离线机器上 Docker 不可靠,故以 L1-L4 进程级围墙为主,Docker 沙箱作为 Web/服务器部署的可选加强项。

4.3 工具桥暴露面(围墙内 Pi 的全部"手艺")

工具 包装自 权力 说明
aps_invoke(intent, params) /api/agent/invoke(即 handle_intent) 随意图 Pi 写世界的唯一方式,内部仍过 _POWER_MAP/确认卡
aps_query(sql_like) master.query / data.analyze 只读集 P0 世界状态只读视图
knowledge_query(q) /api/rag/query(ragScopes 鉴权) P0 知识库
fs_read/fs_write(path) 沙箱 L2 三区 — 物理圈禁,越界即 EACCES
shell_run(cmd) 白名单(python 脚本、xlsx 处理等显式登记命令) — 每条命令正则白名单 + 参数审查
checkpoint_create() state checkpoints — Pi 可主动建回滚锚点
report_emit(md) fallback_verify — 产物唯一出口,强制走验证器

4.4 意图与权力登记(harness 变更)

# _POWER_MAP 新增 3 项(harness.md 权力矩阵同轮更新)
"agent.fallback.propose":  "P1",   # 产出执行计划草稿(沙盒语义,不写主干)
"agent.fallback.execute":  "P2",   # 执行已批准计划 → 确认卡
"agent.fallback.execute.highrisk": "P3",  # 涉外部系统/主干批量写 → 默认拒绝,白名单放行

确认卡内容(P2 出卡时必须冻结):计划步骤清单、每步工具与权力、预计影响面(目标实体清单)、evidenceRefs、执行前 checkpoint id、回滚方式。卡片上的承诺即执行上限——执行时逐步比对,Pi 偏离计划即熔断(计划外工具调用 → blocked)。

4.5 证据链与审计

  • 每次兜底运行:runId 贯穿 propose→confirm→execute→verify 全链;
  • Pi 每步工具调用:TOOL 审计(actor=pi-fallback:<runId>、callId、入参摘要、结果摘要);
  • 确认卡批准/拒绝:GATE 审计(既有机制);
  • 验证报告:REPORT 审计 + 产物落 ~/.aps/fallback/<runId>/report.md;
  • 全链可通过既有 /api/gov/audit 按 runId 过滤回放。

4.6 开关与熔断(复用 FF-01)

  • features.json 新增 "fallback": false——默认全关,现场按需开;开关本身 P2 确认卡管理;
  • 熔断三闸:单次运行超时 10min / 步数 50 / token 预算(可配);日维度累计预算;
  • 触发熔断 → 显式失败 + checkpoint 回滚 + audit_alerts 通知。

5. 部署形态(两个大坑,提前说)

形态 方案 坑
Web/服务器部署 docker-compose 增加 pi-runtime 服务(Node 22 + pi-agent-core) 小,标准做法
桌面端打包 PyInstaller sidecar 之外再加 Node runtime(~60-80MB)打进安装包,或做成可选组件首次使用时下载 ① 体积恶化(与 Tauri 瘦身诉求矛盾,两事更该串行决策);② 离线工厂没有模型 API 出口——兜底重度依赖 LLM,断网即瘫。对策:模型出口走 gateway 代理可配内网模型网关;无模型时 fallback 开关强制关闭且 UI 明示原因(失败显式,不装死)

6. 阶段计划(修订版,替代 v1.0 计划)

阶段 内容 工期 出口标准
P0 PoC 单场景 e2e 打穿:S5(ad-hoc 分析)。Python 编排器拉起 Pi headless → 计划 → 假确认 → 沙箱执行 → 报告。不碰产品路径,全部在 poc/ 4-5 人日 一个真实分析任务从发起到报告全链跑通;四层围墙验证有效(故意越狱测试被拒)
P1 只读兜底 S1(只读类)/S5/S9-只读部分 进产品路径;fallback_lane + pi_bridge 转正;agent.fallback.propose 登记;FF-01 开关接入 7 人日 意图未识别时用户能拿到"办成的事"而非话术;越狱/注入黄金测试 10 例全拦
P2 沙盒写兜底 S2/S3/S9 写路径;agent.fallback.execute=P2 出卡;checkpoint 强制 + diff 验证器;熔断三闸 10-12 人日 新格式 Excel 导入从"给文件"到"对账通过"全链路演示绿;计划偏离熔断测试通过
P3 高风险与运维 S4/S6/S7;execute.highrisk=P3;运维入口与角色门禁;集成故障对账流 7-10 人日 MES 断连补录场景验收;运维全程审计可回放
P4 评估与硬化 兜底质量 golden 集(30+ 场景用例:成功率/误写率/确认轮次/token 成本四指标);prompt 注入防护集(工单备注藏指令等 20 例);离线降级演练 8 人日 golden 集成功率 ≥85% 且误写率 0;注入集 100% 拦截
P5 验收发布 全量黄金(1071+ 基线)、桌面打包冒烟(含可选组件)、文档同轮、现场 runbook 5 人日 发布门禁全绿;康尼数据集真实验收
合计 41-47 人日(1 人约 8-10 周)

里程碑视图

W1      W2-3        W4-6          W7-8        W9-10     W11
[P0] → [P1 只读] → [P2 写兜底] → [P3 高风险] → [P4 硬化] → [P5 发布]
 ↑go/no-go  ↑已可演示价值   ↑核心能力闭环     ↑按需可裁剪   ↑质量门禁

7. 风险登记册(兜底定位特有)

# 风险 等级 对策
F1 非确定性:同一请求两次兜底结果不同 🔴 计划审批制(人看的是计划不是黑盒)+ golden 集回归 + 产物必须经验证器,不靠 Pi 自述
F2 Prompt 注入:订单备注/导入文件里藏"忽略之前指令" 🔴 注入防护 golden 集(P4);用户数据进 Pi 前包裹隔离标记;工具桥不认 Pi 的"用户已确认"自述——确认只信 gateway 会话内的真实确认卡
F3 部分写入:执行到一半熔断 🟡 checkpoint 强制前置 + 回滚验证(diff 为空才算回滚成功)
F4 成本失控:LLM token 烧穿预算 🟡 三闸熔断 + 日预算 + audit_alerts
F5 离线工厂无模型出口,兜底变废铁还误导用户 🟡 无模型时开关强制关 + UI 明示原因;支持内网模型网关地址配置
F6 Node runtime 进桌面包 🟡 可选组件化;与 Tauri 决策串行
F7 "兜底兜不住还装兜住"(LLM 圆场) 🔴 输出契约强制 status 字段 + callId 对账(§2 最后一行),圆场在网关层被物理判失败
F8 团队对"治理下通用智能体"的调试经验不足,问题定位难 🟡 全程 runId 可回放 + Pi trace 落盘;P0 即建立调试工具链
F9 范围蔓延:兜底太好用 → 产品化路径荒废 🟢 治理指标:兜底触发率应随产品化下降;触发率周报,高的场景反哺产品化立项

8. 与 v1.0 接入计划的关系

v1.0 的 /api/agent/ 适配层、Agent Token、MCP 总线登记全部保留——它们在本方案中变成工具桥的基础设施(aps_invoke 就是走那层面)。外向接入(人在 Pi 终端里用 APS)成为 P1 完成后的副产品,不再单独排期。

9. 三条决策建议

  1. 先 P0 后承诺:4-5 人日的 PoC 直接验证最危险的两个未知数(围墙有效性、计划审批可用性),PoC 不过则退回 v1.0 纯接入定位;
  2. S 场景分批上线:P2 之后每批场景单独灰度(FF-01 开关粒度到场景),不一锅端;
  3. 与 Tauri 串行已定,再强调一次:F6 意味着如果未来迁 Tauri,Node runtime 的打包方案要一起重设计。