aps-agent/poc/pi-fallback/GOAL-P1.md

12 KiB
Raw Permalink Blame History

GOAL:Pi Agent 兜底能力 · P1 只读兜底进产品路径(多 agent 协同 · 第二轮)

本文件是本轮协同的唯一权威协调板。每位 agent 开工前必读;完成后在文末留言板交接。 P0 已 GO(见本目录 NOTES-pi-runtime / NOTES-architecture / NOTES-validation)。

本轮目标(P1 出口标准)

按根目录《Pi-Agent兜底能力详细方案》§6 P1:S1(意图未识别的只读类兜底)/S5(自由分析)进产品路径—— 用户在对话里说了一句产品功能覆盖不了的话,不再只得到话术,而是得到一份 Pi 真实产出的分析成果(草稿语义,只读,不写世界)。

具体交付(全部产品代码,可测试、可开关、可审计):

  1. server/agent_core/fallback_lane.py(moduleId: core-fallback-lane,可重生 ✅):兜底编排器——触发判定、任务简报、拉起 Pi headless、三重熔断、环境清洗、run 目录管理(~/.aps/fallback/<runId>/ 或 server/data/fallback/)、成败按 stopReason;
  2. server/integrations/pi_bridge.py(moduleId: integ-pi-bridge):围墙内工具桥——P1 阶段只暴露只读工具(fs_read 限 run 目录、aps 只读查询),callId 凭证 + calls.jsonl 落盘 + 报告凭证校验;
  3. Harness 登记:_POWER_MAP 新增 "agent.fallback.propose": "P1";harness.md 权力矩阵同轮更新;
  4. FF-01 开关:FEATURE_CATALOG 新增 "fallback": "智能兜底(Pi Agent)",默认语义=配置缺失即全开,但本功能要求默认关——需要在 feature_flags 语义内特殊处理(设计员给出方案:如 fallback 键缺失时默认 false,与其余键 fail-open 相反,并在端点响应中显式标注);
  5. 接线:workflow.py unknown/assistant.reply 分支 → 开关开 且 意图未识别 → 走 fallback propose(同步超时保护,不得拖死聊天;失败显式回退原话术);
  6. 黄金测试:tests/golden/test_fallback_lane.py——开关关=原行为不变;开关开=propose 路径触发(注入 fake runner,确定性);未登记意图仍拒绝;审计落链;熔断触发显式失败;凭证校验拦截伪造;
  7. 文档同轮:docs/architecture/harness.md、docs/CHANGELOG.md、新增 docs/architecture/fallback.md。

硬约束(全员遵守)

  • 工作区根:当前仓库根目录;Python 一律 .venv\Scripts\python.exe;
  • 不 git commit / push(等用户授权);改动最小化,不顺手重构;
  • 修改 harness.py / workflow.py / feature_flags.py 前必须先查调用方(rg 或 GitNexus),把爆炸半径写进交接记录;
  • 遵守 PROJECT_OPERATING_RULES:失败显式、无隐式副作用、P1 草稿语义不得写主干、不引入 mock 进产品路径(fake runner 只允许在测试注入);
  • Pi runtime 定位:P1 复用 poc/pi-fallback/runtime/ 的安装,产品化打包(桌面 sidecar)留到后续阶段,但代码里路径解析要可配置;
  • 黄金测试必须确定性:不依赖真实 LLM/网络(用注入 fake runner;rogue_llm_server 模式可选用)。
  • 模型端点配置:复用 .env 现有 key(不得打印/落盘),模型名要协商(P0 踩过 404 坑:先 GET /models 或配置化)。

角色分工

角色 任务 输出
Agent-D 设计员 读现状代码,产出 P1 文件级详细设计(接口签名、接线点、开关语义方案、风险点) P1-DESIGN.md
Agent-E 实施员 按 P1-DESIGN 实现全部产品代码改动 代码 + P1-IMPL-NOTES.md
Agent-F 测试文档员 黄金测试 + 文档同轮 + focused/全量验证 测试 + 文档 + P1-VALIDATION.md

协同留言板

(格式:[角色] 时间 — 结论/交接物/给下一位的话)

[Agent-D 设计员] 2026-09-02 — 设计完成,交接物 poc/pi-fallback/P1-DESIGN.md(8 节:变更清单表 / fallback_lane 与 pi_bridge 全量接口签名 / workflow 接线片段(现状+改法对照)/ 默认关方案 / run 目录与 APS_FALLBACK_* 配置 / 13 例确定性测试矩阵 / 爆炸半径 / P1 边界外清单)。

  • 「默认关」一句话:feature_flags 内新增 _DEFAULT_OFF_KEYS={"fallback"}——文件缺失/损坏/未配置/非 bool 时 fallback 默认 False(其余键保持 fail-open),返回体加 defaultOff 字段显式标注;fallback_feature_enabled() 直接消费 load_feature_flags 单一事实源,不另起解析。
  • 风险最高点:feature_flags 默认关会打破两条既有黄金测试(test_feature_flags.py 的 all-enabled 断言 ×2),必须同轮修(改法已写进设计 §6.0);其次是 workflow 聊天热路径接线(MED,缓解:开关默认关 + propose_reply 绝不抛异常 + 90s 硬熔断)。
  • 关键现状核实(施工前必读设计 §0):真实聊天到兜底分支时 name 几乎总是 assistant.reply(intent.py:948 把 unknown/低置信改写掉了);IntentResult.intent 是封闭 Literal——不要构造 IntentResult("agent.fallback.propose"),它只是 _POWER_MAP 动作名;聊天路径 handle_intent 已在线程池跑,同步+90s 上限方案成立,无需异步机制。
  • 爆炸半径已 rg 盘点(设计 §7):harness.py=LOW(纯追加)、workflow.py=MED、feature_flags.py=MED。gateway/app.py / tool_runtime.py / contracts.py 零改动。
  • 给 Agent-E:照 §2 签名施工,fake runner 注入点是 propose_reply(..., runner=..., config=...);P0 代码只作参照不重用(不 import poc)。给 Agent-F:测试矩阵 §6 逐例可断言行已写明,test_feature_flags.py 两条旧断言的同轮修法也在 §6。

[Agent-E 实施员] 2026-09-02 — P1 产品代码施工完成,交接物 P1-IMPL-NOTES.md(改动清单 / 8 条与设计的偏差及理由 / 自验命令与数字 / 6 条遗留)。

  • 改动 7 文件:新建 fallback_lane.py(809 行)/ pi_bridge.py(259 行)/ test_fallback_lane.py(13 例全确定性);修改 harness.py(+2 纯追加)/ feature_flags.py(_DEFAULT_OFF_KEYS 默认关 + defaultOff 标注)/ workflow.py(+8 接线,开关关时原路径逐字节不变)/ test_feature_flags.py。
  • 自验:fallback+feature_flags 19 passed;受影响回归(contract_sync/assistant/guidance/folder_pack/tool_runtime/gov_api + 聊天网关门禁切片)102 passed;ruff 新增文件全绿、修改文件零新增告警。未 commit。
  • 偏差要点:test_feature_flags 实际修了三条(设计漏列 corrupt_json 那条);result.json 改在 propose_reply 收尾落盘(含 citation_check);unavailable 不建 run 目录;新增空报告防御与 pi→桥工具名映射(不加映射则每次工具调用都误抛 ToolBridgeViolation)。全部理由见 NOTES §2。
  • 给 Agent-F:① 文档同轮未做(harness.md 权力矩阵追加 agent.fallback.propose 行——harness.py 里有同步铁律注释;新建 docs/architecture/fallback.md;CHANGELOG);② 全量 tests/golden 我 300s 没跑完,请用长窗口补跑;③ 真实 pi 端到端冒烟未做(本轮全 fake runner),有 key 环境时按 P0 方法补;④ 既有 test_preference_features.py 日期炸弹失败与本轮无关(已核实零 diff),别误归为回归;⑤ 已知张力:真实 pi 无法获知桥侧 callId,引用即 forged_citation——测试断言时以 fake runner 为准。

[Agent-F 测试文档员] 2026-09-02 — P1 收尾完成,交接物 poc/pi-fallback/P1-VALIDATION.md(改动清单 / 真实验证数字 / 张力处置 / 未验证清单)。

  • 文档同轮 ✅:harness.md 权力矩阵追加 agent.fallback.propose(P1)行 + /api/features 条目补 defaultOff 语义 + 变更记录加 FB-01 行;新建 docs/architecture/fallback.md(含凭证语义已知限制节)并登记进 architecture/README.md 索引;CHANGELOG 新增 2026-09-02「FB-01 智能兜底 P1(只读)」(体例照 FF-01)。
  • 设计张力处置(遗留 #2)✅ 最小方案:只改 pi_bridge._TASK_TEMPLATE——撤销「引用必须标注 callId」(真实 pi 不可获知围墙外事后签发的凭证),改为「不得编造,出现不存在的编号即判伪造成果整轮失败」;validate_report_citations 硬失败不动,test_forged_callid_rejected 继续绿(伪造可识别性质保持)。不选 warning 降级(会破安全断言)。
  • 全量验证 ✅ 真实数字:全量黄金 4 批 1084 passed / 1 failed(唯一失败 = test_preference_features 日期炸弹,git 零 diff 核实与本轮无关,未顺手修);fallback+feature_flags 19 passed;受影响切片 13 文件 83 passed;文档/端点门禁 20 passed(doc_drift 文档改动后复跑 5 passed);ruff All checks passed!。
  • 仍未验证:真实 pi 端到端冒烟(无 key 环境);其余遗留见 P1-VALIDATION §4。P1 出口标准 7 项交付全部落地,建议本轮 GO,等用户授权后再 commit。

[Agent-G 冒烟员] 2026-09-02 — 真实端到端冒烟完成,交接物 poc/pi-fallback/P1-SMOKE.md(七判据逐条 / 真实回复摘录 / 两轮 run 目录 / 失败根因)。结论:原样代码 NO-GO,一行修复后 GO。

  • 抓到唯一产品 bug(fake runner 结构性盲区):fallback_lane.py _GUARD_TS_TEMPLATE 注释行 { block: true, reason } 未转义 → write_guard_extension 的 str.format 必抛 KeyError: ' block',真实 runner 100% 失败(显式归并 harness_error,用户侧回退话术正常)。修法=注释行花括号双写,一行。未自行改产品代码;诊断轮用进程内 shim 做等价单行修正后同口令全绿(真实 kimi-k2.6,stopReason=stop,steps=2,34.9s,citation valid,审计 SUCCESS 落租户世界哈希链),可预判修复即解锁。
  • 环境坑(建议项):本机 PATH 的 node 优先命中 node.CMD 垫片 → 真实 runner 起不来(cmd 引号炸);APS_FALLBACK_NODE 指向真实 node.exe 即绕过,建议产品侧 Windows 优先解析 node.exe。
  • 判据 1/2/5/6/7 PASS;3/4 原样 FAIL、单行修复后 PASS(证据:smoke/results*.json、reply2.txt、site2 run 目录)。现场隔离全程成立(server/data 零污染,git+mtime 双证)。
  • 遗留:主线 LLM 404 降级路径是本次触发前提,主线正常时的意图落点未验证;建议为模板 format 补一条轻量断言防回归。

[Agent-H 修复员] 2026-09-02 — Bug A/B 修复 + 复证完成,P1 最终 GO。交接物:P1-SMOKE.md §7(修复后复证全记录,七判据全 PASS 真实数字)。

  • Bug A 修复:_GUARD_TS_TEMPLATE 注释行 { block: true, reason } 双写转义(1 行);全文核查该文件仅此一处 format 模板、无同类残留。爆炸半径 rg 盘点 LOW(write_guard_extension/build_pi_runner 调用方仅 fallback_lane 自身,poc 同名函数是独立副本)。
  • 坑 B 产品化:新增 _resolve_node()——APS_FALLBACK_NODE 最高优先级;默认 "node" 且 Windows 时 which("node.exe") 优先于 which("node")(避开 node.CMD 垫片)。复跑冒烟未设 APS_FALLBACK_NODE 即通(orchestrator.log 实证 node_bin='node' 自动命中真实 node.exe);解析顺序已写进 docs/architecture/fallback.md 配置小节。
  • 防回归:test_write_guard_extension_real_template_format(真实 format + 守卫文件含字面量 { block: true),fake runner 盲区有网。
  • 验证数字:fallback+feature_flags 20 passed(1.41s);ruff 两文件 All checks passed!;真实冒烟复跑 run fb-20260902-075907-3af703(真实 kimi-k2.6,stopReason=stop,steps=2,13.0s,calls 2 签 2 完,citation valid,审计 SUCCESS 落租户世界哈希链连续,端口释放零残留、server/data 零污染)。本轮租户世界首访空快照,Pi 如实报「0 订单 0 物料」不编造——真实产出力证。
  • 未 commit/push(等授权)。遗留不变:主线 LLM 正常时的意图落点待验证(P1-SMOKE §6.3)。