Skip to content

setup 闸门缺一档:允许 agent 提议一轮 setup,由用户按键确认 #39

Open

Description

@tt-a1i

问题

配置变更现在只有两档:要么模型完全改不了,要么用户手动粘一行 /openpi-setup ...。中间缺一档「模型提议、用户按一下确认」。

闸门本身是对的,不该动。现在的状态机(extensions/setup/index.ts:255):

type SetupEpisode = "idle" | "armed" | "active";

armed 只能由 /openpi-setup 命令进入(extensions/setup/index.ts:587),一轮结束后 configure_my_pi_setup 从工具面摘掉(hideConfigureTool,:264),并在工具返回里明确告诉模型不许再调、不许直接改配置文件(:170)。设计意图很清楚:配置写入必须由用户发起,模型不能悄悄重写 setup。这个保证要保留。

但代价在实践中不小。真实会话里的摩擦:agent 已经精确知道该改什么(reviewer 角色模型改成 seal/glm-5.3),却只能把命令打印出来让用户复制粘贴;一次会话里因为 footer 样式 + 三次角色模型调整,用户粘了 4 轮。每一轮的信息量都是「用户点头」,而不是「用户提供新信息」——那这一步就应该是一次按键,不是一次复制粘贴。

跟 #28 是同一类问题:闸门该在的地方在,但出口太窄。

提议

加一个常驻可见的小工具(名字待定,例如 request_openpi_setup),它不写任何配置:

request_openpi_setup(request: string)

行为:

  1. 用已有的 ctx.ui.confirm 弹确认,正文里展示逐字的 request 加上会被影响的当前配置行(不是模型自己的转述,避免用说服性措辞骗过点头)。
  2. 用户确认 → 走和 /openpi-setup 完全相同的路径:episode = "armed" + showConfigureTool(pi) + publishEpisode() + pi.sendUserMessage(prompt),即直接复用现有的 setupHandler(request)。
  3. 用户拒绝 → 工具返回 declined,且当轮不得重试。
  4. 非 TUI(!ctx.hasUI)走今天的行为:提示用户自己跑 /openpi-setup。

ctx.ui.confirm 已经是这套代码里的既有范式,而且同一个文件里已有先例:安装 pi-intercom 这个带副作用的动作就是 setup 流程中用 ctx.ui.confirm 让用户点头的(extensions/setup/index.ts:206)。这个提议只是把同一个模式用在「开一轮 setup」上。

保留的不变量

  • 没有任何配置写入可以绕过用户的显式动作:armed 仍然只能在用户确认之后到达,模型单方面到不了。
  • 一轮仍然只允许一次 configure_my_pi_setup(现有的 tool_execution_end / agent_settled 收尾逻辑不变,:295-305)。
  • 同时最多一个待确认请求,避免刷屏式追问。
  • 确认框展示字面参数,不展示模型的自由文本理由,或理由与字面 diff 并列。

考虑过但不采纳的替代方案

  • 让 configure_my_pi_setup 常驻可见:直接废掉「用户发起」这条保证,不行。
  • agent 检测到意图就自动 arm:等于模型自己决定开闸,与上一条同病。
  • 保持现状:在 agent 已经知道确切改动的场景下,每次都要用户复制粘贴;这正是本 issue 要消除的那部分摩擦。
  • 让 agent 把命令写进输入框(setEditorText)让用户按 Enter:比粘贴好一点,但会覆盖用户正在写的内容,而且仍然要用户读懂一条 slash 命令。确认框更直接。

验收

  • 用户说「reviewer 改成 X」→ agent 调 request_openpi_setup,用户按一下 → 配置生效,全程零复制粘贴。
  • 用户拒绝 → 配置不变,agent 不重试。
  • 非交互会话 → 行为与今天一致。
  • 模型无法在没有确认的情况下让 episode 离开 idle(加测试锁定)。

Activity

  1. tt-a1i commented on Aug 20, 2026

    @tt-a1i
    CollaboratorAuthor

    修正提案:不要加常驻工具

    原提案里的 request_openpi_setup 是个常驻可见的工具,这点是错的。成本不在 token(一个 schema 约 100~150 token),而在两处:

    1. 与本包自己的架构冲突。capability discovery: adaptive 的全部目的就是只留 openpi_load_tools 可见、其余按需加载(extensions/shared/tool-surface.ts:66 的 OPENPI_CAPABILITY_GROUPS)。为一个可能一周用一次的能力加常驻工具,正好把这个模式想瘦的地方重新撑回去。
    2. 注意力成本大于 token 成本。常驻冷工具是又一个可能误触发的入口,稀释工具面。

    (prompt cache 反而不是问题:稳定常驻的工具在 prefix 里不变;真正伤缓存的是动态显隐,而 configure_my_pi_setup 现在每轮 episode 都在 patchOwnedTools 里显隐——extensions/setup/index.ts:259-268——这份代价已经在付了。)

    改为:复用 next-action suggestion 通道,零新工具

    extensions/suggestions/src/ui.ts:186-188:

    const accepted = this.state.accept();
    if (accepted) super.setText(accepted);

    → 接受一个建议时只是把文本填进编辑器、不提交,任何其他编辑交互都会 dismiss 它(同文件 :138 的注释写明了这个契约)。这正好就是我们要的第三档:

    • agent 已经知道确切改动时,把 /openpi-setup reviewer 用 seal/glm-5.3 作为 next-action 建议给出;
    • 用户 → 填入、Enter 执行 —— 两次按键,零复制粘贴;
    • 闸门完全不变:episode 仍然只能由用户真正提交 /openpi-setup 进入 armed,模型单方面到不了;
    • 零新工具、零常驻 token;
    • 非破坏性:suggestion 层本身设计成不覆盖用户正在写的内容,这也解决了原 issue 里我否掉 setEditorText 的那条理由。

    需要确认的实现细节:suggestion 目前由 predictNextAction 交给一个小模型预测(extensions/suggestions/index.ts:127-142),而这里我们要的是确定性的建议——agent 明确知道要改什么。所以要么给 suggestion 状态开一个「确定性建议」入口(由扩展直接 offer 而非模型预测),要么接受它作为预测的一种输入。前者更可靠。

    退而求其次:(A) 放进 capability group

    如果 suggestion 通道不适合承载确定性建议,那就把这个能力挂到一个 capability group 里(新增 setup,或并入 session),用 openpi_load_tools({ groups: ["setup"] }) 按需加载。平时零 token,罕见场景多一次工具调用,符合现有架构。

    两条路都比常驻工具好。原提案中关于保留闸门的部分(armed 只能在用户确认/提交后到达、一轮一次写入、确认展示字面参数)全部不变。

  2. tt-a1i commented on Aug 20, 2026

    @tt-a1i
    CollaboratorAuthor

    结论:关闭,不实施;保留本 Issue 作为设计记录

    经过进一步核对 OpenPI 当前实现、Pi 的动态工具机制,以及 Maka 的 Terminal-Bench 评测配置,我们决定不新增常驻的 request_openpi_setup 工具,也暂不把 setup 加入 Adaptive capability gateway。

    原问题是真实的:模型在普通对话中发现“可能需要修改 OpenPI 配置”时,无法自行打开一轮 setup,只能请用户输入 /openpi-setup。但当前提案会用一个常驻模型工具解决一个低频、强授权的配置动作,代价与 OpenPI 的整体设计方向不一致。

    一、配置能力与普通高级能力不是同一类东西

    OpenPI 的高级能力,如搜索、子代理、工作流、后台任务和会话操作,是任务执行能力;模型可以在用户授权的范围内判断何时使用。

    配置则不同。它会改变后续会话的持久化行为、权限、模型、并发或 UI 偏好。因此当前合同刻意规定:

    /openpi-setup
        ↓
    idle → armed → active
        ↓
    一次成功配置
        ↓
    idle,配置工具重新隐藏
    

    /openpi-setup 是用户签名的配置入口;configure_my_pi_setup 只在这个 episode 内出现。这个边界简单、可解释、可审计,也避免模型在普通任务里自行扩大持久化写权限。

    所以本 Issue 不应把 setup 降格为一种普通、可自动发现的 capability。

    二、Explicit 与 Adaptive 的最终分工

    模式 常驻模型工具 谁完成语义判断 适合场景
    Explicit 0 运行时只识别少量、确定性的直接能力表达;命中后在首个模型请求前加载工具 默认模式、工具面最小、已知能力的明确请求
    Adaptive 1 个 openpi_load_tools 主模型阅读完整任务后,自主决定是否加载搜索、子代理、工作流、后台任务或会话能力 用户希望模型主动选择高级能力
    Setup 普通 turn 为 0 用户通过 /openpi-setup 明确开启一轮配置授权 持久化配置变更

    这里需要把 Explicit 说准确:它不是完整的自然语言理解器,而是一条确定性的显式表达快速通道。它的价值是零常驻 schema、零额外分类模型调用,并能在首轮请求前加载已明确要求的能力;它不应该被不断扩展成一套关键词专家系统。

    Adaptive 才是语义更灵活的模式。openpi_load_tools 常驻后,主模型可以根据整个任务自行决定是否加载能力。若模型调用一次 gateway,通常会比直接预加载多一个父模型回合;这是获得开放语义判断所付出的明确成本。

    三件事无法同时成立:

    任意自然语言下的语义发现
    + 零常驻 schema
    + 零额外模型请求
    

    因此我们不再试图用更多正则、一个本地分类器或另一个隐藏模型调用去假装同时得到三者。

    三、为什么不采用本 Issue 的常驻 setup 工具

    1. 它破坏了配置写入必须由用户主动开启的边界。 即使最终还有 ctx.ui.confirm,普通任务中的模型也获得了持续发起配置流程的能力。
    2. 它给每一个普通请求增加模型可见 surface。 单个 schema 看起来不大,但 OpenPI 的目标是让基础路径尽可能接近 Pi,而不是让每个低频动作都拥有一枚常驻入口。
    3. 它与 Adaptive 的职责重复。 如果用户希望模型主动选择额外执行能力,应选择 Adaptive;不应再为每个特殊功能添加一枚常驻“请求入口”。
    4. setup 本身仍应保持例外。 即使处于 Adaptive,持久化配置也继续要求 /openpi-setup,不由 gateway 自动加载。
    5. 真实交互问题可以用更准确的提示解决。 当配置 episode 已结束而用户又想修改时,模型应明确提示再次执行 /openpi-setup ...,而不是猜测 /reload、重开会话或普通自然语言会重新 armed。

    这也取代了本 Issue 之前评论里提出的“确定性 next-action suggestion channel”:目前没有足够证据证明值得再增加一条产品机制。

    四、Maka 的 benchmark 做法支持“冻结任务相关 profile”

    这个判断也与 Maka 的公开 Terminal-Bench 方法一致,但需要准确理解它的含义。

    Maka 当前的九 harness 报告 PR apache/maka#3004 冻结了模型、89 道 Terminal-Bench 2.1 任务、reasoning 配置、官方 verifier 和各 harness 的运行合同。更详细的已合并评测 PR apache/maka#2208 中,Maka arm 固定使用版本化的 headless-coding-v1:

    • 固定 headless system prompt;
    • 关闭产品 identity、personalization、skills 和 workspace-memory fragments;
    • 移除 WebSearch、WebFetch、FetchURL;
    • 只保留 Bash、Read、Write、Edit、Glob、Grep,以及在 provider 支持时的 apply_patch 候选;
    • 固定上下文处理、隔离和评测参数。

    所以用户的判断是对的:Maka 并没有用普通交互产品中全部可发现的高级能力去跑这项 coding benchmark,而是冻结了与任务匹配的 headless profile。

    但这不代表评测只比较“裸模型”。Maka 的报告也明确保留各 harness 自己的原生 prompt、工具 schema、上下文和执行循环。它比较的是冻结后的完整 harness,而不是单组件消融实验。

    OpenPI 应采用同样清晰的原则:

    • 基础 coding benchmark 冻结为 Pi-native、Explicit、无高级 capability 调用的 profile;
    • 不因为产品支持子代理、工作流或后台任务,就把它们全部放进每一道基础编码题;
    • 如果要证明这些高级能力有价值,应另建真正需要委派、并行、长任务恢复或后台执行的任务集,并报告采用率、成功率、额外回合、token、wall time 和失败模式;
    • 不把“高级能力没有在基础 benchmark 中出现”误解成“高级能力没有产品价值”。

    五、暂不建设的方案

    本阶段明确不做:

    • 常驻 request_openpi_setup;
    • 把 setup 注册为 Adaptive capability group;
    • 继续扩张 Explicit 的关键词/正则表;
    • 用 BM25、embedding 或本地分类器自动决定加载能力;
    • 为能力发现增加一次隐藏的分类模型调用;
    • 为了 benchmark 分数把产品高级能力混入不需要它们的任务。

    这些方案不是永远禁止,而是目前没有证据证明收益高于复杂度和动态性能成本。

    六、保留的未来方向

    只有出现实际规模或评测证据时再考虑:

    1. Provider-native deferred tools:作为 provider 支持时的透明传输优化,改善已发现工具的注入与缓存;它不是第三种用户模式,也不能凭空发现完全不可见的工具。
    2. 可搜索 capability catalog:当能力从当前少数组扩展到几十组后,可给 Adaptive gateway 增加紧凑的 query 检索。检索只召回候选,最终是否加载仍由主模型决定,不能变成运行时自动路由器。
    3. 独立的高级能力 benchmark:专门验证模型是否会在无用户点名时正确采用子代理、工作流或后台任务,以及采用后是否真的提高成功率或降低成本。
    4. 显式 capability lease/命令面板:若未来真实使用数据显示用户频繁需要零常驻 surface 的精确授权,可以设计用户签名的一次性能力租约;不在本 Issue 中提前实现。

    最终产品合同

    • 默认继续使用 Explicit:基础路径最小,明确请求可走确定性快速通道。
    • 希望模型自主判断高级能力时,用户选择 Adaptive。
    • 两种模式下,持久化配置都只通过 /openpi-setup 开启。
    • Terminal-Bench 等基础 coding benchmark 使用冻结的 Explicit profile;高级能力另行测量。
    • 本 Issue 以 not planned 关闭,保留为“为什么不增加常驻 setup 请求工具”的设计依据。
  3. reopened this on Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions