pi-multi-viewers
v0.10.4
Published
Multi-perspective analysis for Pi: fork the main session into N perspective agents over the meeting protocol.
Maintainers
Readme
pi-multi-viewers
多视角协同分析(Pi 插件):把当前 pi 会话 fork 成 N 个视角 agent,让它们带着你的真实上下文互相交锋,产出共识与分歧。
它想解决什么问题
需要考虑多种因素或者准则时,LLM 容易出现逐渐忽略其中一部分因素的问题。
对策是给每个因素一条独立的会话:一个视角 agent 只关注一个因素(效率 / 简单 / 铁律 / …), 各带一份视角任务书与独立发言配额,并且必须对其它视角的观点表态(认同或反驳,都要用自己的论据)。 这样只要这些会话存在,对应因素就不会被忽略——关注不靠提醒模型"别忘了 X", 而是让每个 X 有一个独立的载体。
讨论由代码驱动的 meeting 协议推进(发言配额 → 冻结 → 轮转表态 → 共识收束),
最终产出 result.md:共识结论 + 明确否决项(含理由与重估触发条件)+ 各自保留的分歧。
什么时候值得跑
当一个问题需要长思考、并且需要在长思考过程中保持若干个视角的关注时,可以尝试使用。
(反过来说:查一个事实、跑一条命令、一两分钟能自己确认的问题,直接问 pi 更快。)
代价
一次分析通常 12–35 分钟(3 视角、20–50 次唤醒,正常情况)。这个区间不含异常外溢: provider 连续失败或扩展异常时可能显著更久(历史场次里出现过 55 分钟与 73 分钟)。 它换来的不是"更快",而是"多几个独立立场 + 一份可复查的分歧记录"。
核心机制(2026-09-09/10 实测验证,见 docs/examples/first-experiment)
| 机制 | 说明 |
|---|---|
| session fork | 首唤由本地循环生成 fork 源文件(从主 session 裁剪/折叠,见下表),再用 pi --session <fork 源> --name <分析名>-<视角名> 打开——agent 携带发起分析的对话上下文(不是 pi --fork:那是全量拷贝且无法在尾部注入切换叙事) |
| fork 源模式 | --fork-mode budget(默认)/ compaction / full,见下表 |
| cwd = 主项目 | agent 进程直接读项目文件;work_dir 仅作消息交换区(绝对路径显式指定) |
| 视角注入 | --append-system-prompt ×2(协议 + 视角任务书) |
| 切换叙事 | fork 源尾部注入 2 对"停止旧任务 → 新任务说明"对话——显式切断历史叙事惯性 |
| 上下文三层 | fork 历史(自动)+ 主项目文件(自动)+ spec background.md(人工,可选边界约定) |
fork 源模式(--fork-mode)
| 模式 | 做法 | 适用 | |---|---|---| | budget(默认) | 按预算(约 80k est,示意值——权威口径见 docs/design.md §二)+ 折叠:丢 thinking、长参数截断、旧工具输出换省略标记 → 从尾部保留 | 长会话唯一可行形态 | | compaction | 从主 session 最后一个 compaction 边界起:内容原样(不折叠) | 中小会话,零信息损失 | | full | 全部条目 | 小会话 / 验证 |
为什么需要 budget(容量事实,2026-09-10 实测):fork 携带的是 session
原始条目,而主 pi 实际发送的上下文是被压缩过的(压缩层不在条目里)
——本仓库主 session 的原始条目约 930k tokens(口径:消息预算侧实测,
2026-09-10;随主会话增长漂移),加模型 384k completion 预留即超 1M 窗口,
provider 直接 400 拒绝(pi --fork 原生命令同样超窗)。budget 把基线压到
~80k est,首唤(唤醒 1 首请求)≈132k tokens,可正常进行(e2e 实测:
三视角约 12–35 分钟完整收敛——决定因素是扩展策略与唤醒数,区间与测点见
docs/design.md §二)。
安装
官方方式(npm):
pi install npm:pi-multi-viewers开发机(当前可用方式)——两步都要做,缺一不可:
pi install /root/pi-multi-viewers # ① 注册包(写 ~/.pi/agent/settings.json 的 packages)
cd ~/.pi/agent/npm && npm install file:/root/pi-multi-viewers --legacy-peer-deps # ② 建 node_modules 符号链接- ① 让 pi 发现包内资源(prompt 由
package.json的pi.prompts声明加载) - ② 让 prompt 里引用的固定路径
~/.pi/agent/npm/node_modules/pi-multi-viewers/scripts/mv.sh可达; 用npm install file:而非手建ln -s——手建是 extraneous 条目,后续任何npm install都会清掉它(上游两次实测教训) - 只支持用户级安装(项目级
.pi/npm/下 prompt 引用的固定路径不可达) - 改动 prompt 后 reload 生效(pi 从包实时读取;开发机 symlink 下改仓库即生效)
核验(不要用命令行长度判断):
readlink -f ~/.pi/agent/npm/node_modules/pi-multi-viewers # 应指向 /root/pi-multi-viewers
ls ~/.pi/agent/npm/node_modules/pi-multi-viewers/scripts/mv.sh用法
接口总表(pi 内 1 个 prompt + 3 个命令;终端侧另有等价 CLI):
| 入口 | 形态 | 作用 |
|---|---|---|
| /multi-viewers-setup | prompt | 建视角(建议 → 你定 → --set-viewer 落盘 → 给你审) |
| /multi-viewers "<主题>" | extension | 分析:prepare → 暂停点弹窗 → start → 交付观看命令 |
| /multi-viewers-finish | extension | 收尾:status → 确认 → cleanup(报告随清理打印并落盘) |
| /multi-viewers-say "<文本>" | extension | 插话(human 消息,各视角可见可回应) |
| /multi-viewers-config [<键> <值>] | extension | 查看/修改启动参数默认值(零 LLM) |
| scripts/mv.sh <子命令> | CLI | 终端侧等价入口(--prepare / --start / --status / --view / --say / --report / --wait / --cleanup / --viewers / --set-viewer)——pi 内命令内部也走它 |
按使用顺序:先 /multi-viewers-setup 建视角(一次就够),之后 /multi-viewers "<主题>" 跑分析,
分析进行中用 /multi-viewers-say 插话,结束后 /multi-viewers-finish 收尾。
后三个是 extension(流程完全由代码执行、零 LLM:跑命令、门禁弹窗、观看命令交付、状态判据
都走退出码/机器标记行,不靠 LLM 转述);setup 是 prompt——写视角是内容工作,本就需要 LLM 参与。
目录可以省略:--view/--say/--status/--report/--wait/--cleanup
不带目录时自动定位"本 session 当前分析"(只匹配 mv-<sessionId>-* 最新;未匹配
即报错退出、不猜目录——破坏性命令尤其不能猜;判据 = 含 repo.git)。传目录仍支持
(显式优先)。
这样路径不需要经过任何 LLM 记忆——此前命令都要求绝对路径,等于让主 pi
把长路径记在上下文里复用。
或命令行:
# 一次性准备:项目 cwd 下建 viewers/<视角名>.md(稳定视角资产,文件名即 agent 名)
# 写什么见下节「视角文件写什么」;本仓库 viewers/ 下是三个示例,形态可照抄
ls viewers/
# 每次:生成主题骨架(视角自动来自 viewers/*.md)
scripts/mv.sh --prepare "<主题>" # spec = question.md(+background.md)
scripts/mv.sh --start <spec目录> # 启动(自动挂载主 session;默认 budget 模式)
# 可选:--fork-mode compaction|budget|full(见上表;一般不调)
# 可选:--max-meeting 15 --max-rr 7 --stall-timeout 600
# (配额:建环境时固化进 protocol.json,之后不可改;meeting 配额是"每 agent")
# 可选:--extension-policy mc-tools|none|all(默认 mc-tools = 零扩展 + 两份只读工具入口:
# MC 的 ctx_search + pi 内置 MCP 的 web 检索等;none = 零扩展、零依赖;
# all = 走 pi 默认发现。MCP 那份是内置、恒在;MC 那份缺了则可见降级)
# 高级:--agents "a,b" 起一次性视角(不建 viewers/ 时用;prompt 入口不传它)
# 观看:--start 会输出可直接执行的 !! 流式观看命令(复制执行)
scripts/mv.sh --view # 一次性增量查看(主 pi 记录 HEAD 作下轮 --since)
# --follow 会打印【状态】(meeting/all-freezing/round-robin/concluded)
# 与【进度】(meeting 消耗/上限 | freezing 集合 | rr → 下一位)
# 结束时自动附【分析报告】(字段集以 docs/design.md「观测面契约」为准)
# 插话 / 状态 / 收尾(目录可省略——自动定位本 session 当前分析)
scripts/mv.sh --say "<文本>" # 插话(命令行形态;pi 内用 /multi-viewers-say)
scripts/mv.sh --status # 状态 + 路径(取值与含义以该命令输出为准)
scripts/mv.sh --report # 只读报告(流程/配额/进程/LLM/档位对照;本命令不落盘——cleanup 会留存一份)
scripts/mv.sh --cleanup # 收尾(result.md + 报告都留存到 <dir>-*.md/.txt)
scripts/mv.sh --viewers # 列出+校验当前项目 viewers/(只读;建视角时用)
scripts/mv.sh --set-viewer <名字> # 新建视角文件(正文从 stdin 读;只新建不覆盖)
scripts/mv.sh --set-default [<键> <值>] # 启动参数默认值(无参数=查看)启动参数与默认值
配额这类参数可以在跑之前设成默认值,之后每次生成 spec 都会沿用:
/multi-viewers-config max-meeting 20 # 设默认值(等价 mv.sh --set-default max-meeting 20)
/multi-viewers-config # 查看当前默认值(哪些来自配置文件、哪些是内置)取值优先级(后者覆盖前者):内置默认 → 你设的默认值 → spec/startup.md
(每次分析生成,你能看也能改 = 只影响本轮)→ --start 的显式 flag(临时覆盖一次)。
生效值与来源在启动时打印;运行期唯一权威始终是分析环境里的 protocol.json
(loop 每轮只读它,中途不可改)。
可设的键:max-meeting(meeting 阶段每 agent 发言配额,默认 15)、
max-rr(RR 轮次配额,默认 7)、stall-timeout(无进展超时秒数,默认 600)。
视角文件写什么(viewers/<视角名>.md)
建视角推荐走 /multi-viewers-setup(交互式:先给候选建议 → 你定建哪几个 →
--set-viewer 落盘 → 展示给你审);也可以手写,写完用 scripts/mv.sh --viewers
自查(列出并用代码判据校验名字与空正文)。
一个视角文件 = 一份视角说明,纯内容、无格式要求(无 frontmatter、 无需标题,文件名就是全部元数据)。三个要点(措辞经实验验证):
- 单一 lenses——写清这个 agent 用什么角度看(效率 / 简单化 / 安全 / 成本 / 用户体验 / ……),并要求"所有观点必须从该视角出发"
- 不越界——写明"其它视角由别的参与者负责,你不要越界展开" (不要列举具体是哪几个视角——参与者会变,列举就会过期)
- 交锋义务——写明"对其它视角的观点可以认同或反驳,但要用本视角的论据"
只写视角本身。以下由脚本从机制生成,不要写进视角文件(写进去必然 重复,且会与实际漂移):身份("你是 X")与参与者名单、消息格式与 frontmatter 字段、写文件路径、独立参与者纪律。
你是多视角分析中的"效率视角"参与者(agent 效率)。 ← ❌ 不要(脚本按文件名注入)
你的所有观点必须从运行效率角度出发:时间效率、运行效率…… ← ✅ 视角内容规范:≥2 个视角、内容非空、名字不含空白与路径分隔符、非 human、
≤32 字符——不合规在生成 spec 前就报错(零产物)。
以 . 开头的文件自动排除(不参与、不报错)——临时屏蔽某个视角时
改个名即可(如 效率.md → .效率.md)。
视角之间互补或对立都可以,对立产生的分歧正是多视角分析的价值。
复用的三种方式(都不需要把视角写进命令行)
| 想做的事 | 做法 |
|---|---|
| 长期复用 | 写好 viewers/X.md——每次分析自动带上 |
| 这一次想调 | --prepare 之后、--start 之前改 spec 的 agents/X.md 快照(改内容 / 删掉某个视角 / 加一个临时视角——删文件即剔除该参与者),不动资产 |
| 完全一次性(项目还没建 viewers/) | mv.sh --prepare "<主题>" --agents "a,b"(wrapper 高级用法) |
架构
与 pi-agents-helper(多方 讨论达成共识,agent 无主上下文)平行演化;共享 meeting 协议核心 (core/fs/engine),差异在初始化层。
meeting_core.py 纯判定(冻结级联/RR/聚合 + 状态机词汇常量)
meeting_fs.py git 层 + fork 源生成/裁剪 + 协议与产物常量
meeting_engine.py 唯一状态机(六分支)
meeting_loop.py Pi 薄壳(fork 首唤 + --session-id 续接 + 视角注入)
start_discussion.py 组合层:CLI 分发 + 环境创建/启动/清理
spec_gen.py spec 生成(question/骨架/viewers 快照/agent 定义 + pi 环境探测)
observability.py 观测(check_status / --report / --wait / loop 存活)
human_viewer/sayer human 插话通道依赖方向单向:core ← fs ← engine ← loop;start_discussion 组合
spec_gen / observability(两者只依赖底层,互不依赖、不反向依赖主文件)。
开发
./tests/run_tests.sh # 全量(`--force` 语义,本机 ~300s;指纹未变时 --reuse 毫秒级)
./tests/run_tests.sh --reuse # 指纹未变跳过设计文档:docs/design.md(fork 源模式与规模口径、决策记录)。
开发铁律与测试方法论:AGENTS.md + docs/test-methodology.md。
首次实验存档:docs/examples/first-experiment/。
自我审阅存档:docs/reviews/(本机制审阅自身实现的报告原文)。
